2017-08-02 7 views
1

J'ai un programme qui crée un système solaire, intègre jusqu'à ce qu'une rencontre rapprochée entre planètes adjacentes se produise (ou jusqu'à 10e + 9 ans), puis écrit deux points de données dans un fichier. L'essayer et sauf agit comme un drapeau lorsque les planètes se rapprochent trop. Ce processus est répété 16 000 fois. Tout cela est fait en important le module REBOUND, qui est un logiciel qui intègre le mouvement des particules sous l'influence de la gravité.Collecter de grandes quantités de données efficacement

for i in range(0,16000): 
    def P_dist(p1, p2): 
     x = sim.particles[p1].x - sim.particles[p2].x 
     y = sim.particles[p1].y - sim.particles[p2].y 
     z = sim.particles[p1].z - sim.particles[p2].z 
     dist = np.sqrt(x**2 + y**2 + z**2) 
     return dist 

    init_periods = [sim.particles[1].P,sim.particles[2].P,sim.particles[3].P,sim.particles[4].P,sim.particles[5].P] 

    try: 
     sim.integrate(10e+9*2*np.pi) 
    except rebound.Encounter as error: 
     print(error) 
     print(sim.t) 

    for j in range(len(init_periods)-1): 
     distance = P_dist(j, j+1) 
     print(j,":",j+1, '=', distance) 
     if distance <= .01: #returns the period ratio of the two planets that had the close enecounter and the inner orbital period between the two 
      p_r = init_periods[j+1]/init_periods[j] 
      with open('good.txt', 'a') as data: #opens a file writing the x & y values for the graph 
       data.write(str(math.log10(sim.t/init_periods[j]))) 
       data.write('\n') 
       data.write(str(p_r)) 
       data.write('\n') 

Si oui ou non il y a une rencontre dépend en grande partie sur une valeur aléatoire que j'ai assigné, et que la valeur aléatoire contrôle également combien de temps une simulation peut fonctionner. Par exemple, j'ai choisi la valeur aléatoire pour être un maximum de 9,99 et une rencontre rapprochée s'est produite à environ 11e + 8 ans (environ 14 heures). Les valeurs aléatoires vont de 2 à 10, et les rencontres rapprochées se produisent plus souvent sur le côté inférieur. À chaque itération, si une rencontre rapprochée se produit, mon code écrira dans le fichier où je pense qu'il pourrait prendre beaucoup de temps de simulation. Puisque la majorité de mon temps de simulation est occupé en essayant de trouver des rencontres rapprochées, je voudrais perdre du temps en trouvant un moyen de collecter les données nécessaires sans devoir ajouter au fichier chaque itération.

Étant donné que j'essaie de tracer les données collectées à partir de cette simulation, est-ce que créerait deux tableaux et produirait des données dans celles qui seraient plus rapides? Ou est-il un moyen de seulement écrire dans un fichier une fois, lorsque toutes les 16000 itérations sont terminées?

sim est une variable contenant toutes les informations sur le système solaire.

Ce n'est pas le code complet, j'ai omis la partie où j'ai créé le système solaire.

count = 0 
data = open('good.txt', 'a+') 
.... 
    if distance <= .01: 
     count+=1 
     while(count<=4570) 
      data.write(~~~~~~~) 
.... 
data.close() 
+1

Votre idée est correcte, mais la logique est fausse. Cette boucle while est infinie: 'count' est 1 lorsque vous entrez dans la boucle, et il ne change jamais. Vous avez seulement une boucle, mais deux façons de sortir: 'j> = len (périodes)' ou 'count> 4570'. L'un ou l'autre code les deux conditions dans votre en-tête de boucle, ou utilise le second pour «casser» de la boucle. – Prune

Répondre

1

Le problème n'est pas que vous écrivez chaque fois que vous trouvez une rencontre rapprochée. C'est que, pour chaque rencontre, vous ouvrez le fichier, écrivez un enregistrement de sortie, et fermez le fichier. Toute l'ouverture et l'ajout est lente. Essayez ceci, à la place: ouvrez le fichier une fois, et faites seulement un écrire par enregistrement.

# Near the top of the program 
data = open('good.txt', 'a') 
... 
    if distance <= .01: #returns the period ratio of the two planets that had the close enecounter and the inner orbital period between the two 
     # Write one output record 
     p_r = init_periods[j+1]/init_periods[j] 
     data.write(str(math.log10(sim.t/init_periods[j])) + '\n' + 
        str(p_r) + '\n') 
... 
data.close() 

Cela devrait fonctionner car les écritures seront mises en mémoire tampon et fonctionneront souvent en parallèle avec le prochain calcul.

+0

Super, une question de plus. J'ai décidé de réduire ma taille d'échantillon à 4570 rencontres rapprochées. Comme les rencontres rapprochées ne se produisent pas à chaque itération, j'ai trouvé un moyen de faire fonctionner le programme jusqu'à 4570 rencontres rapprochées. – dlsj

+1

C'est une déclaration, pas une question. Manquant un mot ou deux, peut-être? – Prune

+0

Dans ma publication la plus récente, j'ai téléchargé un bloc de code similaire au vôtre. Est-ce un moyen efficace d'obtenir la quantité de données dont j'ai besoin? – dlsj