def test8(self): """ testing orbital_elements_for_rel_posvel_arrays for extreme cases """ N = 3 mass1 = (1.2 * numpy.ones(N)) | units.MSun mass2 = (0.1, 0.05, 0.003) | units.MSun semi_major_axis = (1., 2., 3.) | units.AU eccentricity = (0., 0.5, 0.6) true_anomaly = (0., 0., 66.) inclination = (12., 0., 180.) longitude_of_the_ascending_node = ( 0., 0., 0., ) argument_of_periapsis = (0., 23., 90.) mass12 = [] rel_position = [] rel_velocity = [] for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements(*arg, G=constants.G) mass12.append(sun_and_comet[0].mass + sun_and_comet[1].mass) rel_position.append(sun_and_comet[1].position - sun_and_comet[0].position) rel_velocity.append(sun_and_comet[1].velocity - sun_and_comet[0].velocity) # to convert lists to vector quantities rel_pos = numpy.array( [vec_i.value_in(units.AU) for vec_i in rel_position]) | units.AU rel_vel = numpy.array( [vec_i.value_in(units.kms) for vec_i in rel_velocity]) | units.kms mass_12 = numpy.array([m_i.value_in(units.MSun) for m_i in mass12]) | units.MSun semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(rel_pos, rel_vel, mass_12, G=constants.G) rad_to_deg = 180. / numpy.pi for i in range(N): self.assertAlmostEqual(semi_major_axis[i].value_in(units.AU), semi_major_axis_ext[i].value_in(units.AU)) self.assertAlmostEqual(eccentricity[i], eccentricity_ext[i]) self.assertAlmostEqual(inclination[i], rad_to_deg * inclination_ext[i]) self.assertAlmostEqual( longitude_of_the_ascending_node[i], rad_to_deg * longitude_of_the_ascending_node_ext[i]) self.assertAlmostEqual(argument_of_periapsis[i], rad_to_deg * argument_of_periapsis_ext[i]) self.assertAlmostEqual(true_anomaly[i], rad_to_deg * ta_ext[i])
def test6(self): """ testing orbital_elements_for_rel_posvel_arrays for N particles with random orbital elements """ numpy.random.seed(666) N = 100 mass_sun = 1. | units.MSun mass1 = numpy.ones(N) * mass_sun mass2 = numpy.zeros(N) | units.MSun semi_major_axis = (-numpy.log(random.random(N))) | units.AU eccentricity = random.random(N) true_anomaly = 360. * random.random(N) - 180. inclination = 180 * random.random(N) longitude_of_the_ascending_node = 360 * random.random(N) - 180 argument_of_periapsis = 360 * random.random(N) - 180 comets = datamodel.Particles(N) for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements(*arg, G=constants.G) comets[i].mass = sun_and_comet[1].mass comets[i].position = sun_and_comet[1].position comets[i].velocity = sun_and_comet[1].velocity semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(comets.position, comets.velocity, comets.mass + mass_sun, G=constants.G) rad_to_deg = 180. / numpy.pi for i in range(N): self.assertAlmostEqual(semi_major_axis[i].value_in(units.AU), semi_major_axis_ext[i].value_in(units.AU)) self.assertAlmostEqual(eccentricity[i], eccentricity_ext[i]) self.assertAlmostEqual(inclination[i], rad_to_deg * inclination_ext[i]) self.assertAlmostEqual( longitude_of_the_ascending_node[i], rad_to_deg * longitude_of_the_ascending_node_ext[i]) self.assertAlmostEqual(argument_of_periapsis[i], rad_to_deg * argument_of_periapsis_ext[i]) self.assertAlmostEqual(true_anomaly[i], rad_to_deg * ta_ext[i])
def xtest10(self): """ testing orbital_elements_for_rel_posvel_arrays for N particles with random orbital elements, unitless """ numpy.random.seed(666) N = 100 mass_sun = 1. mass1 = numpy.ones(N) * mass_sun mass2 = numpy.zeros(N) semi_major_axis = (-numpy.log(random.random(N))) eccentricity = random.random(N) true_anomaly = 360. * random.random(N) - 180. inclination = 180 * random.random(N) longitude_of_the_ascending_node = 360 * random.random(N) - 180 argument_of_periapsis = 360 * random.random(N) - 180 comets = datamodel.Particles(N) for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements(*arg, G=1) comets[i].mass = sun_and_comet[1].mass comets[i].position = sun_and_comet[1].position comets[i].velocity = sun_and_comet[1].velocity semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(comets.position, comets.velocity, comets.mass + mass_sun, G=1) self.assertAlmostEqual(semi_major_axis, semi_major_axis_ext) self.assertAlmostEqual(eccentricity, eccentricity_ext) self.assertAlmostEqual(inclination, inclination_ext) self.assertAlmostEqual(longitude_of_the_ascending_node, longitude_of_the_ascending_node_ext) self.assertAlmostEqual(argument_of_periapsis, argument_of_periapsis_ext) self.assertAlmostEqual(true_anomaly, ta_ext)
def test7(self): """ testing orbital_elements_for_rel_posvel_arrays for the case of one particle """ numpy.random.seed(999) mass1 = 0.5 | units.MSun mass2 = 0.8 | units.MSun sem = 12. | units.AU ecc = 0.05 inc = 20. lon = 10. arg = 0.4 ta = 360. * random.random() - 180. binary = new_binary_from_orbital_elements(mass1, mass2, sem, ecc, ta, inc, lon, arg, G=constants.G) rel_pos = binary[1].position - binary[0].position rel_vel = binary[1].velocity - binary[0].velocity mass_12 = binary[1].mass + binary[0].mass sem_ext, ecc_ext, ta_ext, inc_ext, lon_ext, arg_ext = \ orbital_elements_for_rel_posvel_arrays(rel_pos, rel_vel, mass_12, G=constants.G) rad_to_deg = 180. / numpy.pi self.assertAlmostEqual(sem.value_in(units.AU), sem_ext.value_in(units.AU)) self.assertAlmostEqual(ecc, ecc_ext) self.assertAlmostEqual(inc, rad_to_deg * inc_ext) self.assertAlmostEqual(lon, rad_to_deg * lon_ext) self.assertAlmostEqual(arg, rad_to_deg * arg_ext) self.assertAlmostEqual(ta, rad_to_deg * ta_ext)
def test11(self): """ testing orbital_elements_for_rel_posvel_arrays for unbound orbits """ from amuse.community.kepler.interface import Kepler numpy.random.seed(66) N = 10 mass_sun = 1. | units.MSun mass1 = numpy.ones(N) * mass_sun mass2 = numpy.zeros(N) | units.MSun semi_major_axis = -1000. * (random.random(N)) | units.AU eccentricity = (1. + random.random(N)) * 10. - 9. inclination = numpy.pi * random.random(N) longitude_of_the_ascending_node = 2. * numpy.pi * random.random( N) - numpy.pi argument_of_periapsis = 2. * numpy.pi * random.random(N) - numpy.pi # kepler.initialize_from_elements initializes orbits with mean_anomaly=0 and true_anomaly=0 true_anomaly = 0. * (360. * random.random(N) - 180.) comets = datamodel.Particles(N) converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) kepler = Kepler(converter) kepler.initialize_code() for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): kepler.initialize_from_elements(mass=(mass1[i] + mass2[i]), semi=semi_major_axis[i], ecc=eccentricity[i]) ri = kepler.get_separation_vector() vi = kepler.get_velocity_vector() om = longitude_of_the_ascending_node[i] w = argument_of_periapsis[i] incl = inclination[i] a1 = ([numpy.cos(om), -numpy.sin(om), 0.0], [numpy.sin(om), numpy.cos(om), 0.0], [0.0, 0.0, 1.0]) a2 = ([1.0, 0.0, 0.0], [0.0, numpy.cos(incl), -numpy.sin(incl)], [0.0, numpy.sin(incl), numpy.cos(incl)]) a3 = ([numpy.cos(w), -numpy.sin(w), 0.0], [numpy.sin(w), numpy.cos(w), 0.0], [0.0, 0.0, 1.0]) A = numpy.dot(numpy.dot(a1, a2), a3) r_vec = numpy.dot(A, numpy.reshape(ri, 3, 1)) v_vec = numpy.dot(A, numpy.reshape(vi, 3, 1)) r = (0.0, 0.0, 0.0) | units.AU v = (0.0, 0.0, 0.0) | (units.AU / units.day) r[0] = r_vec[0] r[1] = r_vec[1] r[2] = r_vec[2] v[0] = v_vec[0] v[1] = v_vec[1] v[2] = v_vec[2] comets[i].mass = mass2[i] comets[i].position = r_vec comets[i].velocity = v_vec kepler.stop() semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(comets.position, comets.velocity, comets.mass + mass_sun, G=constants.G) for i in range(N): self.assertAlmostEqual(semi_major_axis[i].value_in(units.AU), semi_major_axis_ext[i].value_in(units.AU)) self.assertAlmostEqual(eccentricity[i], eccentricity_ext[i]) self.assertAlmostEqual(inclination[i], inclination_ext[i]) self.assertAlmostEqual(longitude_of_the_ascending_node[i], longitude_of_the_ascending_node_ext[i]) self.assertAlmostEqual(argument_of_periapsis[i], argument_of_periapsis_ext[i]) self.assertAlmostEqual(true_anomaly[i], ta_ext[i])
def main(options): starttime = clocktime.time() now = clocktime.strftime("%Y%m%d%H%M%S") # Read the initial conditions file provided. This uses "Giant Impact" units. mass_unit = options["unit_mass"] length_unit = options["unit_length"] converter = nbody_system.nbody_to_si(1 | mass_unit, 1 | length_unit) options["converter"] = converter time = options["time_start"] if options["verbose"] > 1: print "%d : Start reading particles" % (clocktime.time() - starttime) if len(sys.argv) >= 2: filename = sys.argv[1] ext = filename.split('.')[-1] if ext == "txt": data = open(filename, "r").readlines() time = converter.to_si(float(data[0]) | nbody_system.time) nparticles = int(data[1]) particles = Particles(nparticles) for n in range(nparticles): line = data[2 + n].split() number = int(line[0]) mass, radius, x, y, z, vx, vy, vz = map(float, line[1:]) particles[n].number = number particles[n].mass = converter.to_si(mass | nbody_system.mass) particles[n].radius = converter.to_si(radius | nbody_system.length) particles[n].position = converter.to_si( VectorQuantity(unit=nbody_system.length, array=[x, y, z])) particles[n].velocity = converter.to_si( VectorQuantity(unit=nbody_system.speed, array=[vx, vy, vz])) particles.position -= particles.center_of_mass() particles.velocity -= particles.center_of_mass_velocity() particles[0].type = "planet" particles[1:].type = "disc" rundir = "./runs/" + filename.split('/')[-1][:-4] elif ext == "hdf5": particles = read_set_from_file(filename, "amuse") rundir = "./runs/" + filename.split('/')[-1][:-5] else: print "Unknown filetype" exit() else: particles = initial_particles(10000) write_set_to_file( particles, "this_run.hdf5", "amuse", ) if options["verbose"] > 1: print "%d : Read particles" % (clocktime.time() - starttime) rundir += "-%s-%s" % ( now, options["gravity"], ) if options["rubblepile"]: rundir += "-rubblepile" backupdir = rundir + "/backups" plotdir = rundir + "/plots" try: os.makedirs(rundir) os.makedirs(backupdir) os.makedirs(plotdir) shutil.copy(sys.argv[0], rundir) except: #FIXME make a new dir in this case, to prevent overwriting old files # use a datetime stamp print "#directories already present" exit() particles[0].colour = "blue" particles[1:].colour = "black" kepler_time = converter.to_si( 2 * np.pi * ((1 | nbody_system.length)**3 / ((1 | nbody_system.mass) * nbody_system.G))**0.5) converter_earthunits = nbody_system.nbody_to_si(1 | units.MEarth, 1 | units.REarth) timestep_k2000 = (kepler_time / (2 * np.pi)) * (2**-9) options["timestep"] = timestep_k2000 if options["verbose"] > 1: print "%d : Starting gravity" % (clocktime.time() - starttime) # Start up gravity code if options["gravity"] == "Rebound": gravity = Rebound(converter, redirection="none") gravity.parameters.timestep = timestep_k2000 gravity.parameters.integrator = options["integrator"] gravity.parameters.solver = "compensated" #gravity.parameters.solver = "tree" #gravity.parameters.opening_angle2 = 0.25 #gravity.parameters.boundary = "open" #gravity.parameters.boundary_size = 10|units.REarth if options["whfast_corrector"]: gravity.parameters.whfast_corrector = options["whfast_corrector"] elif options["gravity"] == "Bonsai": #gravity = Bonsai(converter,redirection="none") gravity = Bonsai(converter, ) gravity.parameters.timestep = timestep_k2000 gravity.parameters.opening_angle = 0.5 #gravity.parameters.epsilon_squared = (0.1 * particles[-1].radius)**2 gravity.parameters.epsilon_squared = 0.0 | nbody_system.length**2 elif options["gravity"] == "Pikachu": #gravity = Bonsai(converter,redirection="none") gravity = Pikachu(converter, ) gravity.parameters.timestep = timestep_k2000 gravity.parameters.opening_angle = 0.5 #gravity.parameters.epsilon_squared = (0.1 * particles[-1].radius)**2 gravity.parameters.epsilon_squared = 0.0 | nbody_system.length**2 elif options["gravity"] == "ph4": if options["use_gpu"]: gravity = ph4(converter, mode="gpu", redirection="none") else: gravity = ph4(converter, redirection="none") elif options["gravity"] == "phigrape": if options["use_gpu"]: gravity = PhiGRAPE(converter, mode="gpu") else: gravity = PhiGRAPE(converter) elif options["gravity"] == "Hermite": gravity = Hermite(converter, number_of_workers=6) gravity.parameters.dt_min = timestep_k2000 gravity.parameters.dt_max = timestep_k2000 else: print "Unknown gravity code" exit() print gravity.parameters planetary_disc = Planetary_Disc(options) planetary_disc.add_integrator(gravity) planetary_disc.add_particles(particles) t_start = time plot_time = time backup_time = time timestep = timestep_k2000 #options["timestep"] plot_timestep = options["timestep_plot"] backup_timestep = options["timestep_backup"] t_end = options["time_end"] backup = 0 plot = 0 log_time = VectorQuantity([], units.s) log_kinetic_energy = VectorQuantity([], units.erg) log_potential_energy = VectorQuantity([], units.erg) log_angular_momentum = VectorQuantity([], units.AU**2 * units.MEarth * units.yr**-1) log = open(rundir + "/log.txt", 'w') log.write("#1 time = %s\n" % (converter_earthunits.to_si(1 | nbody_system.time))) log.write("#1 length = %s\n" % (converter_earthunits.to_si(1 | nbody_system.length))) log.write("#1 mass = %s\n" % (converter_earthunits.to_si(1 | nbody_system.mass))) log.write("#1 energy = %s\n" % (converter_earthunits.to_si(1 | nbody_system.energy))) log.write( "#Time N E_kin E_pot l2 M_disc a_mean a_sigma e_mean e_sigma inc_mean inc_sigma\n" ) log.write("#%s n %s %s %s %s %s %s\n" % ( units.s, nbody_system.energy, #s.erg, nbody_system.energy, #s.erg, (units.REarth**2 * units.MEarth * units.day**-1)**2, units.MEarth, units.REarth, units.REarth, )) log.flush() time += timestep_k2000 if options["verbose"] > 1: print "%d : Starting loop" % (clocktime.time() - starttime) while time < t_end: if time >= plot_time: if options["verbose"] > 1: print "%d : Making plot" % (clocktime.time() - starttime) plot_system( planetary_disc.particles, "%s/plot-%05i.png" % (plotdir, plot), ) plot += 1 plot_time += plot_timestep if time >= backup_time: if options["verbose"] > 1: print "%d : Making backup" % (clocktime.time() - starttime) planetary_disc.write_backup(filename="%s/savefile-%i.hdf5" % (backupdir, backup)) backup += 1 backup_time += backup_timestep if (time - planetary_disc.model_time) <= 0.5 * timestep: if options["verbose"] > 0: print "#Increasing timestep: %s - %s <= 0.5" % ( planetary_disc.model_time / planetary_disc.timestep, time / planetary_disc.timestep, ) time += timestep kinetic_energy = planetary_disc.kinetic_energy potential_energy = planetary_disc.potential_energy angular_momentum = planetary_disc.particles.total_angular_momentum( ) semimajor_axis, eccentricity, true_anomaly, inc, long_asc_node, arg_per_mat = orbital_elements_for_rel_posvel_arrays( planetary_disc.disc.position - planetary_disc.planet.position, planetary_disc.disc.velocity - planetary_disc.planet.velocity, planetary_disc.planet.mass, #total_masses, G=constants.G, ) #FIXME kinetic energy per particle #FIXME angular momentum per particle log.write("%s %i %s %s %s %s %s %s %s %s %s %s\n" % ( planetary_disc.model_time.value_in(units.s), len(planetary_disc.particles), converter_earthunits.to_nbody(kinetic_energy).value_in( nbody_system.energy), converter_earthunits.to_nbody(potential_energy).value_in( nbody_system.energy), (angular_momentum[0]**2 + angular_momentum[1]**2 + angular_momentum[2]**2).value_in( units.REarth**4 * units.MEarth**2 * units.day**-2), planetary_disc.disc.mass.sum().value_in(units.MEarth), semimajor_axis.mean().value_in(units.REarth), semimajor_axis.std().value_in(units.REarth), eccentricity.mean(), eccentricity.std(), inc.mean(), inc.std(), )) log.flush() else: if options["verbose"] > 0: print "#Not increasing timestep: %s - %s > 0.5" % ( planetary_disc.model_time / planetary_disc.timestep, time / planetary_disc.timestep, ) planetary_disc.evolve_model(time) gravity.stop() log.close()