def evolve_cluster_in_galaxy(N, W0, Rinit, tend, timestep, M, R): R_galaxy=0.1 | units.kpc M_galaxy=1.6e10 | units.MSun converter=nbody_system.nbody_to_si(M_galaxy, R_galaxy) galaxy=new_plummer_model(10000,convert_nbody=converter) print "com:", galaxy.center_of_mass().in_(units.kpc) print "comv:", galaxy.center_of_mass_velocity().in_(units.kms) print len(galaxy) galaxy_code = BHTree(converter, number_of_workers=2) galaxy_code.parameters.epsilon_squared = (0.01 | units.kpc)**2 channe_to_galaxy = galaxy_code.particles.new_channel_to(galaxy) channe_to_galaxy.copy() galaxy_code.particles.add_particles(galaxy) inner_stars = galaxy.select(lambda r: r.length()<Rinit,["position"]) Minner = inner_stars.mass.sum() print "Minner=", Minner.in_(units.MSun) print "Ninner=", len(inner_stars) vc_inner = (constants.G*Minner/Rinit).sqrt() converter=nbody_system.nbody_to_si(Mcluster,Rcluster) stars=new_king_model(N,W0,convert_nbody=converter) masses = new_powerlaw_mass_distribution(N, 0.1|units.MSun, 100|units.MSun, -2.35) stars.mass = masses stars.scale_to_standard(converter) stars.x += Rinit stars.vy += 0.8*vc_inner cluster_code=ph4(converter, number_of_workers=2) cluster_code.particles.add_particles(stars) channel_to_stars=cluster_code.particles.new_channel_to(stars) system=bridge(verbose=False) system.add_system(cluster_code, (galaxy_code,)) system.add_system(galaxy_code, (cluster_code,)) system.timestep = 0.1*timestep times = quantities.arange(0|units.Myr, tend, timestep) for i,t in enumerate(times): print "Time=", t.in_(units.Myr) channe_to_galaxy.copy() channel_to_stars.copy() inner_stars = galaxy.select(lambda r: r.length()<Rinit,["position"]) print "Minner=", inner_stars.mass.sum().in_(units.MSun) system.evolve_model(t,timestep=timestep) plot_galaxy_and_stars(galaxy, stars) galaxy_code.stop() cluster_code.stop()
def test7(self): converter = nbody_system.nbody_to_si(units.MSun, units.parsec) code = Hermite(converter) stars = datamodel.Particles(keys=(1,2)) stars.mass = converter.to_si(1 | nbody_system.mass) stars.position = converter.to_si([ [0,0,0], [1.1, 0, 0], ]|nbody_system.length) stars.velocity = converter.to_si([ [0,0,0], [-0.5,1.5, 0], ]|nbody_system.speed) stars.radius = converter.to_si(0.55 | nbody_system.length) encounter_code = encounters.HandleEncounter( kepler_code = self.new_kepler_si(), resolve_collision_code = self.new_smalln_si(), interaction_over_code = None, G = constants.G ) encounter_code.small_scale_factor = 1.0 encounter_code.parameters.hard_binary_factor = 1 multiples_code = encounters.Multiples( gravity_code = code, handle_encounter_code = encounter_code, G = constants.G ) multiples_code.must_handle_one_encounter_per_stopping_condition = False multiples_code.singles.add_particles(stars) multiples_code.commit_particles() stopping_condition = multiples_code.stopping_conditions.encounter_detection stopping_condition.enable() end_time = converter.to_si(3.0|nbody_system.time) print end_time.as_quantity_in(units.Myr) multiples_code.evolve_model(end_time) self.assertTrue(stopping_condition.is_set()) print multiples_code.model_time.as_quantity_in(units.Myr) #self.assertAlmostRelativeEquals(multiples_code.model_time , 5.96955 | units.Myr, 4) self.assertEquals(len(stopping_condition.particles(0)), 1) model = stopping_condition.particles(0)[0] self.assertEquals(len(model.particles_before_encounter), 2) self.assertEquals(len(model.particles_after_encounter), 2) before = model.particles_before_encounter after = model.particles_after_encounter self.assertAlmostRelativeEquals(before.center_of_mass(), after.center_of_mass(), 7) self.assertAlmostRelativeEquals(before.center_of_mass_velocity(), after.center_of_mass_velocity(), 7) total_energy_before = before.kinetic_energy() + before.potential_energy(G=constants.G) total_energy_after = after.kinetic_energy() + after.potential_energy(G=constants.G) self.assertAlmostRelativeEquals(total_energy_before, total_energy_after, 7)
def test5(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = Huayno(convert_nbody) instance.initialize_code() particles = datamodel.Particles(2) self.assertEquals(len(instance.particles), 0) particles.mass = [15.0, 30.0] | units.kg particles.radius = [10.0, 20.0] | units.m particles.position = [[10.0, 20.0, 30.0], [20.0, 40.0, 60.0]] | units.m particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.m / units.s instance.particles.add_particles(particles) self.assertEquals(len(instance.particles), 2) instance.set_state(1, 16|units.kg, 20.0|units.m, 40.0|units.m, 60.0|units.m, 1.0|units.ms, 1.0|units.ms, 1.0|units.ms) curr_state = instance.get_state(1) for expected, actural in zip((16|units.kg, 20.0|units.m, 40.0|units.m, 60.0|units.m, 1.0|units.ms, 1.0|units.ms, 1.0|units.ms, 0 | units.m), curr_state): self.assertAlmostRelativeEquals(actural,expected) instance.set_state(1, 16|units.kg, 20.0|units.m, 40.0|units.m, 60.0|units.m, 1.0|units.ms, 1.0|units.ms, 1.0|units.ms , 20.0|units.m) curr_state = instance.get_state(1) for expected, actural in zip((16|units.kg, 20.0|units.m, 40.0|units.m, 60.0|units.m, 1.0|units.ms, 1.0|units.ms, 1.0|units.ms, 20 | units.m), curr_state): self.assertAlmostRelativeEquals(actural,expected)
def evolve_model(self): convert_nbody = nbody_system.nbody_to_si( 1.0 | units.MSun, 149.5e6 | units.km) hermite = Hermite(convert_nbody) hermite.initialize_code() hermite.parameters.epsilon_squared = 0.0 | units.AU**2 stars = self.new_system_of_sun_and_earth() earth = stars[1] sun = stars[0] Earth = blender.Primitives.sphere(10, 10, 0.1) # Make the earth avatar Sun = blender.Primitives.sphere(32, 32, 1) # Make the sun avatar hermite.particles.add_particles(stars) for i in range(1*365): hermite.evolve_model(i | units.day) hermite.particles.copy_values_of_all_attributes_to(stars) # update avatar positions: Earth.loc = ( 1*earth.position.value_in(units.AU)[0], 1*earth.position.value_in(units.AU)[1], earth.position.value_in(units.AU)[2]) Sun.loc = ( 1*sun.position.value_in(units.AU)[0], 1*sun.position.value_in(units.AU)[1], sun.position.value_in(units.AU)[2]) blender.Redraw() hermite.print_refs() hermite.stop()
def test4(self): print "Testing Pikachu evolve_model, 2 particles" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Pikachu, converter, **default_options) instance.initialize_code() instance.parameters.timestep = 0.0125 * math.pi * particles[0].x / particles[0].vy instance.parameters.rcut_out_star_star = 10.0 | units.AU instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test2(self): print "Test basic particle attributes and scale_to_standard - SI units" convert_nbody = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.parsec) particles = Particles(2) particles.position = [[-1, 0, 0], [1,0,0]] | units.parsec particles.velocity = [[-1, 0, 0], [1,0,0]] | units.parsec / units.Myr particles.mass = 0.5 | units.MSun self.assertAlmostRelativeEquals(particles.total_mass(), 1.0 | units.MSun) self.assertAlmostRelativeEquals(particles.kinetic_energy(), 1.0 * (0.5 | units.MSun) * (1 |units.parsec / units.Myr) **2 ) self.assertAlmostRelativeEquals(particles.potential_energy(), -constants.G * (0.5 | units.MSun) ** 2 / ([2,0,0] | units.parsec).length() ) self.assertAlmostRelativeEquals(particles.virial_radius(), 4.0 | units.parsec) particles.scale_to_standard(convert_nbody) self.assertAlmostRelativeEquals(particles.total_mass(), convert_nbody.to_si(1.0 | nbody_system.mass)) self.assertAlmostRelativeEquals(particles.kinetic_energy(), convert_nbody.to_si(0.25 | nbody_system.energy)) self.assertAlmostRelativeEquals(particles.potential_energy().as_quantity_in(units.J), convert_nbody.to_si(-0.5 | nbody_system.energy).as_quantity_in(units.J), 12) self.assertAlmostRelativeEquals(particles.virial_radius(), convert_nbody.to_si(1.0 | nbody_system.length)) particles.scale_to_standard(convert_nbody, virial_ratio=1) # unbound self.assertAlmostRelativeEquals(particles.kinetic_energy(), 0.5 * constants.G * (1 | units.MSun**2 / units.parsec), 13) self.assertAlmostRelativeEquals(particles.potential_energy(), -0.5 * constants.G * (1 | units.MSun**2 / units.parsec)) particles.scale_to_standard(convert_nbody, virial_ratio=0) # velocities zeroed self.assertAlmostRelativeEquals(particles.kinetic_energy(), 0 | units.J) self.assertAlmostRelativeEquals(particles.potential_energy(), -0.5 * constants.G * (1 | units.MSun**2 / units.parsec))
def run_capture(t_end_p=650.0, m0_p=0.58, m_ffp_p=7.5, e_bp_p=0.0, m_bp_p=0.1, a_bp_p=1.0, b_ffp_p=1.0, phi_bp_p=0.0, n_steps=10000, path='./m/', n_snapshots=500): """ Units: t_end_p(yr), m0_p(MSun), m_ffp_p(MJupiter), e_bp_p(None), m_bp_p(MJupiter), a_bp_p(AU), b_ffp(AU), phi_p(degrees) """ #Converter used in this program converter = nbody_system.nbody_to_si(1 | units.MSun, 5 | units.AU) #Conversion of units t_end, m0, m_ffp, e_bp, m_bp, a_bp, b_ffp, phi_bp = convert_units(converter, t_end_p, m0_p, m_ffp_p, e_bp_p, m_bp_p, a_bp_p, b_ffp_p, phi_bp_p) #Number of planets number_of_planets = 1 #Initial distance to the planet (x-cordinate) r_inf = 40.0*a_bp #Particle superset: star, FFP, planets bodies = get_bodies_in_orbit(m0, m_ffp, m_bp, a_bp, e_bp, phi_bp, b_ffp, r_inf) #Evolve time x,y,times,system_energies,max_energy_change,is_stable,b1_semimajor_axis, b1_eccentricity, b1_true_anomaly, b1_inclination, b1_long_asc_node, b1_arg_per, b2_semimajor_axis, b2_eccentricity, b2_true_anomaly, b2_inclination, b2_long_asc_node, b2_arg_per = evolve_gravity(bodies, number_of_planets, converter, t_end, n_steps, n_snapshots, path) name = 'm'+str(m0_p)+'_a'+str(a_bp_p)+'_b'+str(b_ffp_p)+'_p'+str(phi_bp_p) print '\nName:', name print 'Max Energy Change:', max_energy_change print 'Is Hill stable?:', is_stable print '\nBinary Star and FFP:' print 'semimajor_axis(AU) eccentricity true_anomaly inclination longitude_of_the_ascending_node argument_of_periapsis' print b1_semimajor_axis, b1_eccentricity, b1_true_anomaly, b1_inclination, b1_long_asc_node, b1_arg_per print '\nBinary Star and BP:' print 'semimajor_axis(AU) eccentricity true_anomaly inclination longitude_of_the_ascending_node argument_of_periapsis' print b2_semimajor_axis, b2_eccentricity, b2_true_anomaly, b2_inclination, b2_long_asc_node, b2_arg_per
def test3(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = ph4(convert_nbody) instance.initialize_code() particles = datamodel.Particles(2) self.assertEquals(len(instance.particles), 0) particles.mass = [15.0, 30.0] | units.kg particles.radius = [10.0, 20.0] | units.m particles.position = [[10.0, 20.0, 30.0], [20.0, 40.0, 60.0]] | units.m particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.m / units.s instance.particles.add_particles(particles) self.assertEquals(len(instance.particles), 2) instance.commit_particles() instance.particles.mass = [17.0, 33.0] | units.kg self.assertEquals(instance.get_mass(1), 17.0 | units.kg) self.assertEquals(instance.get_mass(2), 33.0 | units.kg) instance.cleanup_code() instance.stop()
def test10(self): particles = Particles(2) particles.position = [[1, 0, 0], [2,0,0]] | units.m particles.velocity = [[3, 0, 0], [4,0,0]] | units.m / units.s particles.mass = 1 | units.kg self.assertEquals(particles.total_mass(), 2 | units.kg) self.assertEquals(particles.total_momentum(), [7, 0, 0] | units.kg * units.m / units.s) self.assertEquals(particles.total_momentum(), particles.total_mass() * particles.center_of_mass_velocity()) self.assertEquals(particles.total_radius(), 0.5 | units.m) convert_nbody = nbody_system.nbody_to_si(1000 | units.kg, 1e-6 | units.m) numpy.random.seed(123) field = new_plummer_sphere(10000, convert_nbody) # small clump of particles, can be regarded as point mass self.assertAlmostRelativeEquals(particles.potential_energy_in_field(field), -constants.G * (1500 | units.kg**2 / units.m), 5) self.assertAlmostEquals(particles.potential_energy_in_field(field), -1.001142 | 1e-7 * units.kg * units.m**2 / units.s**2, 5) field.position *= ((5 | units.m) / field.position.lengths()).reshape((-1, 1)) # spherical shell around particles potential_energy = particles.potential_energy_in_field(field) particles.position += [0, 1, 2] | units.m # as long as particles remain inside the shell, the potential doesn't change self.assertAlmostEquals(particles.potential_energy_in_field(field), potential_energy, 5) particles.mass = [1, 2] | units.kg self.assertAlmostRelativeEquals(particles.potential(), -constants.G * ([2, 1] | units.kg / units.m)) self.assertAlmostRelativeEquals(particles.potential()[0], particles[0].potential()) self.assertAlmostRelativeEquals(particles.potential()[1], particles[1].potential())
def simulate_system_until(particles, end_time): convert_nbody = nbody_system.nbody_to_si( 1.0 | units.MSun, 149.5e6 | units.km) instance = Hermite(convert_nbody) instance.parameters.epsilon_squared = 0.0 | units.AU**2 instance.particles.add_particles(particles) t0 = 0 | units.day dt = 10 | units.day t = t0 earth = instance.particles[1] x_values = quantities.AdaptingVectorQuantity() y_values = quantities.AdaptingVectorQuantity() while t < end_time: instance.evolve_model(t) x_values.append(earth.x) y_values.append(earth.y) t += dt instance.stop() return x_values, y_values
def test18(self): print "Testing effect of ph4 parameter epsilon_squared" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) particles = datamodel.Particles(2) particles.mass = [1.0, 3.0037e-6] | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * particles.total_mass() / (1.0 | units.AU)).sqrt() particles.rotate(0.0, 0.0, math.pi / 4) particles.move_to_center() tan_initial_direction = particles[1].vy / particles[1].vx self.assertAlmostEquals(tan_initial_direction, math.tan(-math.pi / 4)) tan_final_direction = [] for log_eps2 in range(-5, 6, 2): instance = ph4(converter) instance.initialize_code() instance.parameters.epsilon_squared = 10.0 ** log_eps2 | units.AU ** 2 instance.parameters.timestep_parameter = 0.001 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() instance.evolve_model(0.25 | units.yr) tan_final_direction.append(instance.particles[1].velocity[1] / instance.particles[1].velocity[0]) instance.cleanup_code() instance.stop() # Small values of epsilon_squared should result in normal earth-sun dynamics: rotation of 90 degrees self.assertAlmostEquals(tan_final_direction[0], math.tan(math.pi / 4.0), 2) # Large values of epsilon_squared should result in ~ no interaction self.assertAlmostEquals(tan_final_direction[-1], tan_initial_direction, 2) # Outcome is most sensitive to epsilon_squared when epsilon_squared = d(earth, sun)^2 delta = [abs(tan_final_direction[i + 1] - tan_final_direction[i]) for i in range(len(tan_final_direction) - 1)] self.assertEquals(delta[len(tan_final_direction) // 2 - 1], max(delta))
def test11(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = FDPS(convert_nbody) particles = datamodel.Particles(2) self.assertEquals(len(instance.particles), 0) particles.mass = [15.0, 30.0] | units.kg particles.radius = [10.0, 20.0] | units.m particles.position = [[10.0, 20.0, 30.0], [20.0, 40.0, 60.0]] | units.m particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.m / units.s instance.particles.add_particles(particles) copyof = instance.particles.copy() self.assertAlmostEqual(30 | units.kg, copyof[1].mass, 6) copyof[1].mass = 35 | units.kg copyof.copy_values_of_all_attributes_to(instance.particles) self.assertAlmostEqual(35 | units.kg, instance.particles[1].mass, 6) instance.stop()
def test7(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = FDPS(convert_nbody) instance.commit_parameters() particles = datamodel.Particles(2) self.assertEquals(len(instance.particles), 0) particles.mass = [15.0, 30.0] | units.kg particles.radius = [10.0, 20.0] | units.m particles.position = [[10.0, 20.0, 30.0], [20.0, 40.0, 60.0]] | units.m particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.m / units.s instance.particles.add_particles(particles) instance.commit_particles() self.assertEquals(instance.get_mass(0), 15.0| units.kg) self.assertAlmostRelativeEquals(instance.get_position(0)[2], 30.0| units.m) self.assertEquals(len(instance.particles), 2) self.assertAlmostRelativeEquals(instance.particles.mass[1], 30.0 | units.kg) self.assertAlmostRelativeEquals(instance.particles.position[1][2], 60.0 | units.m) instance.cleanup_code() instance.stop()
def run_capture(t_end_p=650.0, m0_p=1.0, m_ffp_p=1.0, m_planets_p=[1.0], a_planets_p=[5.0], e_planets_p=[0.0], n_steps_p=10000, phi_p=0.0, b_p=5.0, iteration_number=1, n_snapshots_p=350): """ Units: t_end(yr), m0(MSun), m_ffp(MJupiter), m_planets(MJupiter), a_planets(AU), e_planets(None), n_steps(None), phi(degrees), b(AU) """ #Converter used in this program converter = nbody_system.nbody_to_si(1 | units.MSun, 5 | units.AU) #Conversion of units t_end, m0, m_ffp, m_planets, a_planets, e_planets, n_steps, phi, b = convert_units(converter, t_end_p, m0_p, m_ffp_p, m_planets_p, a_planets_p, e_planets_p, n_steps_p, phi_p, b_p) #Number of planets number_of_planets = len(e_planets) #Initial distance to the planet (x-cordinate) r_inf = 40.*max(a_planets) #Initialize planets planets = get_planets(m0,a_planets,m_planets,e_planets,phi) #Set the parabolic orbit of the ffp around the star star_and_ffp_in_orbit = get_ffp_in_orbit(m0, m_ffp, b, r_inf, get_parabolic_velocity(m0, m_ffp, b, r_inf, m_planets, a_planets, phi)) #Particle superset: star, FFP, planets bodies = ParticlesSuperset([star_and_ffp_in_orbit, planets]) #File to store results bodies_filename = './particles/'+str(iteration_number)+'.hdf5' #Evolve time x,y,times,energies,max_energy_change = evolve_gravity(bodies,number_of_planets,converter,t_end,n_steps,n_snapshots_p,bodies_filename) #plot_trajectory(x,y,number_of_planets) #plot_energy(times, energies) return max_energy_change
def test1(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) huayno = Huayno(convert_nbody) huayno.initialize_code() huayno.parameters.epsilon_squared = 0.0 | units.AU**2 stars = self.new_system_of_sun_and_earth() earth = stars[1] huayno.particles.add_particles(stars) huayno.evolve_model(365.0 | units.day) huayno.particles.copy_values_of_all_attributes_to(stars) position_at_start = earth.position.value_in(units.AU)[0] position_after_full_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(position_at_start, position_after_full_rotation, 6) huayno.evolve_model(365.0 + (365.0 / 2) | units.day) huayno.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 2) huayno.evolve_model(365.0 + (365.0 / 2) + (365.0 / 4) | units.day) huayno.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[1] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 3) huayno.cleanup_code() huayno.stop()
def test3(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) instance = Huayno(convert_nbody) instance.initialize_code() instance.parameters.epsilon_squared = 0.00001 | units.AU**2 stars = datamodel.Stars(2) star1 = stars[0] star2 = stars[1] star1.mass = units.MSun(1.0) star1.position = units.AU(numpy.array((-1.0,0.0,0.0))) star1.velocity = units.AUd(numpy.array((0.0,0.0,0.0))) star1.radius = units.RSun(1.0) star2.mass = units.MSun(1.0) star2.position = units.AU(numpy.array((1.0,0.0,0.0))) star2.velocity = units.AUd(numpy.array((0.0,0.0,0.0))) star2.radius = units.RSun(100.0) instance.particles.add_particles(stars) for x in range(1,2000,10): instance.evolve_model(x | units.day) instance.particles.copy_values_of_all_attributes_to(stars) stars.savepoint()
def test11(self): print "Testing saving/loading timestamp in NEMO" x = datamodel.Particles(2) convert = nbody_system.nbody_to_si(1 | units.kg, 2 | units.m) x.mass = [1.0, 2.0] | units.kg x.position = [[1,2,3], [3,5,6]] | units.m x.velocity = [[1,2,3], [3,5,6]] | units.m / units.s current_time = 1.0 | units.Myr io.write_set_to_file(x.savepoint(current_time), "time_test_unit.tsf","tsf", nbody_to_si_converter = convert) y = io.read_set_from_file("time_test_unit.tsf","tsf", nbody_to_si_converter = convert) self.assertAlmostEquals(current_time, y.previous_state().get_timestamp(), 8, in_units=units.Myr) self.assertAlmostEquals(x.mass, y.mass, 8) self.assertAlmostEquals(x.position, y.position,8) self.assertAlmostEquals(x.velocity, y.velocity,8) x = datamodel.Particles(2) x.mass = [1.0, 2.0] | nbody_system.mass x.position = [[1,2,3], [3,5,6]] | nbody_system.length x.velocity = [[1,2,3], [3,5,6]] | nbody_system.speed current_time = 1.0 | nbody_system.time io.write_set_to_file(x.savepoint(current_time), "time_test_unit.tsf","tsf") y = io.read_set_from_file("time_test_unit.tsf","tsf") self.assertAlmostEquals(current_time, y.previous_state().get_timestamp(), 8, in_units=nbody_system.time) self.assertAlmostEquals(x.mass, y.mass, 8) self.assertAlmostEquals(x.position, y.position,8) self.assertAlmostEquals(x.velocity, y.velocity,8) os.remove("time_test_unit.tsf")
def test19(self): converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.parsec) particles = datamodel.Particles(2) particles.mass = 100 | units.MSun particles.radius = 200 | units.RSun particles[0].position = [0,0,0] | units.parsec particles[1].position = [1,0,0] | units.parsec particles.velocity = [0,0,0] | units.km / units.s code = PhiGRAPE( converter, PhiGRAPEInterface.MODE_G6LIB, number_of_workers=2 ) code.initialize_code() stop_cond = code.stopping_conditions.collision_detection stop_cond.enable() code.particles.add_particles(particles) code.evolve_model( 0.08 | nbody_system.time) self.assertTrue(stop_cond.is_set())
def test1(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) smalln = SmallN(convert_nbody) smalln.initialize_code() smalln.dt_dia = 5000 stars = self.new_system_of_sun_and_earth() earth = stars[1] smalln.particles.add_particles(stars) smalln.evolve_model(365.0 | units.day) smalln.particles.copy_values_of_all_attributes_to(stars) position_at_start = earth.position.value_in(units.AU)[0] position_after_full_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(position_at_start, position_after_full_rotation, 6) smalln.evolve_model(365.0 + (365.0 / 2) | units.day) smalln.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 2) smalln.evolve_model(365.0 + (365.0 / 2) + (365.0 / 4) | units.day) smalln.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[1] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 3) smalln.cleanup_code() smalln.stop()
def test6(self): print "Test6: Testing SmallN parameters" convert_nbody = nbody_system.nbody_to_si(1.0 | units.yr, 1.0 | units.AU) instance = SmallN(convert_nbody) instance.initialize_code() value = instance.get_eta() self.assertEquals(0.14, value) self.assertAlmostEquals(0.14, instance.parameters.timestep_parameter) for x in [0.001, 0.01, 0.1]: instance.parameters.timestep_parameter = x self.assertAlmostEquals(x, instance.parameters.timestep_parameter) value = instance.get_time() self.assertEquals(0| units.yr, value) value = instance.get_gamma() self.assertEquals(1e-6, value) self.assertAlmostEquals(1e-6, instance.parameters.unperturbed_threshold) for x in [0.001, 0.01, 0.1]: instance.parameters.unperturbed_threshold = x self.assertAlmostEquals(x, instance.parameters.unperturbed_threshold) instance.stop()
def test2(self): print "Testing Adaptb parameters" convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Adaptb,convert_nbody) instance.initialize_code() #~ print instance.parameters self.assertEquals(instance.parameters.bs_tolerance, 1.0e-6) instance.parameters.bs_tolerance = 1.0e-9 self.assertEquals(instance.parameters.bs_tolerance, 1.0e-9) self.assertEquals(instance.parameters.epsilon_squared, 0.0 | units.m**2) instance.parameters.epsilon_squared = 1.0e-4 | nbody_system.length**2 self.assertEquals(instance.parameters.epsilon_squared, convert_nbody.to_si(1.0e-4 | nbody_system.length**2)) self.assertEquals(instance.parameters.word_length, 64) instance.parameters.word_length = 128 self.assertEquals(instance.parameters.word_length, 128) self.assertEquals(instance.parameters.dt_print, convert_nbody.to_si(0.1 | nbody_system.time)) instance.parameters.dt_print = 1.0e-4 | nbody_system.time self.assertEquals(instance.parameters.dt_print, convert_nbody.to_si(1.0e-4 | nbody_system.time)) self.assertEquals(instance.parameters.adaptb_output_directory, instance.output_directory + os.sep) instance.parameters.adaptb_output_directory = "./out" self.assertEquals(instance.parameters.adaptb_output_directory, "./out/") instance.parameters.adaptb_output_directory = instance.output_directory self.assertEquals(instance.parameters.adaptb_output_directory, instance.output_directory + os.sep) self.assertEquals(instance.parameters.time_limit_cpu, 3600.0 | units.s) instance.parameters.time_limit_cpu = 7200.0 | units.s self.assertEquals(instance.parameters.time_limit_cpu, 7200.0 | units.s) instance.stop()
def test4(self): print "Testing Adaptb evolve_model, 2 particles" particles = Particles(2) particles.mass = 0.5 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (1.0 | units.MSun) / (1.0 | units.AU)).sqrt() particles.move_to_center() convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Adaptb, convert_nbody) instance.initialize_code() instance.parameters.dt_print = 0.1 | units.yr instance.parameters.bs_tolerance = 1.0e-8 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 6) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 6) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 6) instance.cleanup_code() instance.stop()
def xtest07(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print "Testing effect of Sakura parameter epsilon_squared" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) particles = self.new_sun_earth_system() particles.rotate(0.0, 0.0, -math.pi / 4) particles.move_to_center() tan_initial_direction = particles[1].vy / particles[1].vx self.assertAlmostEquals(tan_initial_direction, math.tan(math.pi / 4)) tan_final_direction = [] for log_eps2 in range(-9, 10, 2): instance = Sakura(converter) instance.initialize_code() instance.parameters.epsilon_squared = 10.0 ** log_eps2 | units.AU ** 2 # instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() instance.evolve_model(0.25 | units.yr) tan_final_direction.append(instance.particles[1].velocity[1] / instance.particles[1].velocity[0]) instance.cleanup_code() instance.stop() # Small values of epsilon_squared should result in normal earth-sun dynamics: rotation of 90 degrees self.assertAlmostEquals(tan_final_direction[0], math.tan(3 * math.pi / 4.0), 2) # Large values of epsilon_squared should result in ~ no interaction self.assertAlmostEquals(tan_final_direction[-1], tan_initial_direction, 2) # Outcome is most sensitive to epsilon_squared when epsilon_squared = d(earth, sun)^2 delta = [abs(tan_final_direction[i + 1] - tan_final_direction[i]) for i in range(len(tan_final_direction) - 1)] self.assertEquals(delta[len(tan_final_direction) / 2 - 1], max(delta))
def test09(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print "Testing Sakura evolve_model and getters energy, plummer sphere, no SMBH" converter = nbody_system.nbody_to_si(1.0e2 | units.MSun, 1.0 | units.parsec) instance = Sakura(converter) # instance.parameters.timestep_parameter = 1.0/256 instance.initialize_code() # instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() numpy.random.seed(987654321) instance.particles.add_particles(new_plummer_model(100, convert_nbody=converter)) instance.commit_particles() kinetic_energy = instance.kinetic_energy potential_energy = instance.potential_energy self.assertAlmostRelativeEqual(kinetic_energy, 2.12292810174e37 | units.J, 10) self.assertAlmostRelativeEqual(potential_energy, -4.33511391248e37 | units.J, 10) initial_total_energy = kinetic_energy + potential_energy instance.evolve_model(0.1 | nbody_system.time) kinetic_energy = instance.kinetic_energy potential_energy = instance.potential_energy self.assertAlmostRelativeEqual(kinetic_energy, 2.1362368884e37 | units.J, 4) self.assertAlmostRelativeEqual(potential_energy, -4.34842269914e37 | units.J, 4) self.assertAlmostRelativeEqual(potential_energy + kinetic_energy, initial_total_energy, 4) instance.cleanup_code() instance.stop()
def test6b(self): print "Testing effect of Pikachu parameter epsilon_squared (using reset)" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) particles = self.new_sun_earth_system() particles.rotate(0.0, 0.0, math.pi/4) particles.move_to_center() tan_initial_direction = particles[1].vy/particles[1].vx self.assertAlmostEquals(tan_initial_direction, math.tan(-math.pi/4)) tan_final_direction = [] instance = self.new_instance_of_an_optional_code(Pikachu, converter, **default_options) instance.initialize_code() instance.parameters.timestep = 0.005 | units.yr for log_eps2 in range(-5,6,2): instance.parameters.epsilon_squared = 10.0**log_eps2 | units.AU ** 2 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() instance.evolve_model(0.25 | units.yr) tan_final_direction.append(instance.particles[1].velocity[1]/ instance.particles[1].velocity[0]) instance.reset() instance.cleanup_code() instance.stop() print tan_final_direction # Small values of epsilon_squared should result in normal earth-sun dynamics: rotation of 90 degrees self.assertAlmostEquals(tan_final_direction[0], math.tan(math.pi / 4.0), 2) # Large values of epsilon_squared should result in ~ no interaction self.assertAlmostEquals(tan_final_direction[-1], tan_initial_direction, 2) # Outcome is most sensitive to epsilon_squared when epsilon_squared = d(earth, sun)^2 delta = [abs(tan_final_direction[i+1]-tan_final_direction[i]) for i in range(len(tan_final_direction)-1)] self.assertEquals(delta[len(tan_final_direction)/2 -1], max(delta))
def test06(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print "Testing Sakura evolve_model, earth-sun system, no SMBH" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = Sakura(converter) instance.initialize_code() # instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(self.new_sun_earth_system()) instance.commit_particles() earth = instance.particles[1] position_at_start = earth.position.x instance.evolve_model(0.25 | units.yr) self.assertAlmostRelativeEqual(position_at_start, earth.position.y, 3) instance.evolve_model(0.5 | units.yr) self.assertAlmostRelativeEqual(position_at_start, -earth.position.x, 3) instance.evolve_model(1.0 | units.yr) self.assertAlmostRelativeEqual(position_at_start, earth.position.x, 3) instance.cleanup_code() instance.stop()
def test1(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) instance = PhiGRAPE(convert_nbody, **default_test_options)#, debugger="xterm") instance.initialize_code() instance.parameters.set_defaults() instance.parameters.initial_timestep_parameter = 0.001 instance.parameters.timestep_parameter = 0.001 stars = self.new_system_of_sun_and_earth() earth = stars[1] instance.particles.add_particles(stars) instance.commit_particles() position_at_start = earth.position.value_in(units.AU)[0] instance.evolve_model(365 | units.day) instance.particles.copy_values_of_all_attributes_to(stars) position_after_full_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(position_at_start, position_after_full_rotation, 2) instance.evolve_model(365.0 + (365.0 / 2) | units.day) instance.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 2) instance.evolve_model(365.0 + (365.0 / 2) + (365.0 / 4) | units.day) instance.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[1] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 3) instance.cleanup_code() instance.stop()
def test21(self): import pickle convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) hermite = Hermite(convert_nbody) encoded_interface = pickle.dumps(hermite,0) decoded_interface = pickle.loads(encoded_interface)
def test6(self): print "Test6: Testing Hermite parameters" convert_nbody = nbody_system.nbody_to_si(1.0 | units.yr, 1.0 | units.AU) instance = Hermite(convert_nbody) value = instance.get_eps2() self.assertEquals(0.0 | units.AU**2 , value) self.assertAlmostEquals(0.0 | units.AU**2, instance.parameters.epsilon_squared, in_units=units.AU**2) for x in [0.01, 0.1, 0.2]: instance.parameters.epsilon_squared = x | units.AU**2 self.assertAlmostEquals(x | units.AU**2, instance.parameters.epsilon_squared, in_units=units.AU**2) value = instance.get_dt_param() self.assertEquals(0.03 , value) self.assertAlmostEquals(0.03 , instance.parameters.dt_param) for x in [0.001, 0.01, 0.1]: instance.parameters.dt_param = x self.assertAlmostEquals(x, instance.parameters.dt_param) value = instance.get_dt_dia() self.assertAlmostEquals(1.0 | units.yr, value) self.assertAlmostEquals(1.0 | units.yr, instance.parameters.dt_dia, in_units=units.yr) for x in [0.1, 10.0, 100.0]: instance.parameters.dt_dia = x | units.yr self.assertAlmostEquals(x | units.yr, instance.parameters.dt_dia, in_units=units.yr) value = instance.get_begin_time() self.assertEquals(0.0| units.yr, value) self.assertAlmostEquals(0.0 | units.yr, instance.parameters.begin_time, in_units=units.yr) for x in [1.0, 10.0, 100.0]: instance.parameters.begin_time = x | units.yr self.assertAlmostEquals(x | units.yr, instance.parameters.begin_time, in_units=units.yr) instance.stop()
def test4(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = PhiGRAPE(convert_nbody, **default_test_options) instance.initialize_code() instance.parameters.set_defaults() particles = datamodel.Particles(2) self.assertEquals(len(instance.particles), 0) particles.mass = [15.0, 30.0] | units.kg particles.radius = [10.0, 20.0] | units.m particles.position = [[10.0, 20.0, 30.0], [20.0, 40.0, 60.0]] | units.m particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.m / units.s instance.particles.add_particles(particles) self.assertEquals(len(instance.particles), 2) instance.particles.mass = [17.0, 33.0] | units.kg self.assertEquals(instance.get_mass(1), 17.0| units.kg) self.assertEquals(instance.get_mass(2), 33.0| units.kg) instance.stop()
def iliev_test_5(N=10000, Ns=10, L=15. | units.kpc, dt=None): """ prepare iliev test and return SPH and simplex interfaces """ gas, sources = iliev_test_5_ic(N, Ns, L) conv = nbody_system.nbody_to_si(1.0e9 | units.MSun, 1.0 | units.kpc) sph = Fi(conv, use_gl=False, mode='periodic', redirection='none') sph.initialize_code() sph.parameters.use_hydro_flag = True sph.parameters.radiation_flag = False sph.parameters.self_gravity_flag = False sph.parameters.gamma = 1 sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = dt sph.parameters.verbosity = 0 sph.parameters.pboxsize = 2 * L sph.commit_parameters() sph.gas_particles.add_particles(gas) sph.commit_particles() # sph.start_viewer() rad = SimpleX(number_of_workers=1, redirection='none') rad.initialize_code() rad.parameters.box_size = 2 * L rad.parameters.hilbert_order = 0 rad.commit_parameters() gas.add_particles(sources) rad.particles.add_particles(gas) rad.commit_particles() return sph, rad
def test2(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) instance = Huayno(convert_nbody) instance.initialize_code() instance.parameters.epsilon_squared = 0.0 | units.AU**2 stars = self.new_system_of_sun_and_earth() earth = stars[1] instance.particles.add_particles(stars) for x in range(1, 2000, 10): instance.evolve_model(x | units.day) instance.particles.copy_values_of_all_attributes_to(stars) stars.savepoint() if HAS_MATPLOTLIB: figure = pyplot.figure() plot = figure.add_subplot(1, 1, 1) x_points = earth.get_timeline_of_attribute("x") y_points = earth.get_timeline_of_attribute("y") x_points_in_AU = map(lambda (t, x): x.value_in(units.AU), x_points) y_points_in_AU = map(lambda (t, x): x.value_in(units.AU), y_points) plot.scatter(x_points_in_AU, y_points_in_AU, color="b", marker='o') plot.set_xlim(-1.5, 1.5) plot.set_ylim(-1.5, 1.5) test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "huayno-earth-sun2.svg") figure.savefig(output_file) instance.cleanup_code() del instance
def test1(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) hermite = Hermite(convert_nbody) hermite.initialize_code() hermite.parameters.epsilon_squared = 0.0 | units.AU**2 hermite.parameters.end_time_accuracy_factor = 0.0 hermite.dt_dia = 5000 stars = self.new_system_of_sun_and_earth() earth = stars[1] hermite.particles.add_particles(stars) hermite.evolve_model(365.0 | units.day) hermite.particles.copy_values_of_all_attributes_to(stars) position_at_start = earth.position.value_in(units.AU)[0] position_after_full_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostRelativeEqual(position_at_start, position_after_full_rotation, 6) hermite.evolve_model(365.0 + (365.0 / 2) | units.day) hermite.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostRelativeEqual(-position_at_start, position_after_half_a_rotation, 3) hermite.evolve_model(365.0 + (365.0 / 2) + (365.0 / 4) | units.day) hermite.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[1] self.assertAlmostRelativeEqual(-position_at_start, position_after_half_a_rotation, 3) hermite.cleanup_code() hermite.stop()
def test6b(self): print "Testing effect of Pikachu parameter epsilon_squared (using reset)" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) particles = self.new_sun_earth_system() particles.rotate(0.0, 0.0, math.pi / 4) particles.move_to_center() tan_initial_direction = particles[1].vy / particles[1].vx self.assertAlmostEquals(tan_initial_direction, math.tan(-math.pi / 4)) tan_final_direction = [] instance = self.new_instance_of_an_optional_code( Pikachu, converter, **default_options) instance.initialize_code() instance.parameters.timestep = 0.005 | units.yr for log_eps2 in range(-5, 6, 2): instance.parameters.epsilon_squared = 10.0**log_eps2 | units.AU**2 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() instance.evolve_model(0.25 | units.yr) tan_final_direction.append(instance.particles[1].velocity[1] / instance.particles[1].velocity[0]) instance.reset() instance.cleanup_code() instance.stop() print tan_final_direction # Small values of epsilon_squared should result in normal earth-sun dynamics: rotation of 90 degrees self.assertAlmostEquals(tan_final_direction[0], math.tan(math.pi / 4.0), 2) # Large values of epsilon_squared should result in ~ no interaction self.assertAlmostEquals(tan_final_direction[-1], tan_initial_direction, 2) # Outcome is most sensitive to epsilon_squared when epsilon_squared = d(earth, sun)^2 delta = [ abs(tan_final_direction[i + 1] - tan_final_direction[i]) for i in range(len(tan_final_direction) - 1) ] self.assertEquals(delta[len(tan_final_direction) / 2 - 1], max(delta))
def test5(self): print("Testing MI6 evolve_model, 2 particles, no SMBH") particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() print(particles) converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = MI6(converter, **default_options) instance.initialize_code() instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test09(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print( "Testing Sakura evolve_model and getters energy, plummer sphere, no SMBH" ) converter = nbody_system.nbody_to_si(1.0e2 | units.MSun, 1.0 | units.parsec) instance = Sakura(converter, ) # instance.parameters.timestep_parameter = 1.0/256 instance.initialize_code() # instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() numpy.random.seed(987654321) instance.particles.add_particles( new_plummer_model(100, convert_nbody=converter)) instance.commit_particles() kinetic_energy = instance.kinetic_energy potential_energy = instance.potential_energy self.assertAlmostRelativeEqual(kinetic_energy, 2.12292810174e+37 | units.J, 10) self.assertAlmostRelativeEqual(potential_energy, -4.33511391248e+37 | units.J, 10) initial_total_energy = kinetic_energy + potential_energy instance.evolve_model(0.1 | nbody_system.time) kinetic_energy = instance.kinetic_energy potential_energy = instance.potential_energy self.assertAlmostRelativeEqual(kinetic_energy, 2.1362368884e+37 | units.J, 4) self.assertAlmostRelativeEqual(potential_energy, -4.34842269914e+37 | units.J, 4) self.assertAlmostRelativeEqual(potential_energy + kinetic_energy, initial_total_energy, 4) instance.cleanup_code() instance.stop()
def test4(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = BHTree(convert_nbody) instance.commit_parameters() index = instance.new_particle( 15.0 | units.kg, 10.0 | units.m, 20.0 | units.m, 30.0 | units.m, #1.0 | units.m/units.s, 1.0 | units.m/units.s, 3.0 | units.m/units.s 0.0 | units.m / units.s, 0.0 | units.m / units.s, 0.0 | units.m / units.s, 10.0 | units.m) instance.commit_particles() self.assertEquals(instance.get_mass(index), 15.0 | units.kg) self.assertEquals(instance.get_radius(index), 10.0 | units.m) instance.cleanup_code() instance.stop()
def test1(self): """test_starlab.test1 +---------------------------------------------------------------------+ | Particle tree of test_subub.dyn | | | | 0 16kg x=0 | | ,- . | | ,-' `._ | | _,' `. | | ,' `-. | | 1 8kg, x=-10 3 8kg, x=10 | | ,-' - ._ | | ,' ,' `. | | ,' ,' `._ | | ,' ,' `. | | 2 4kg, x=-15 4 4kg, x=5 5 4kg, x=15 | | . | | `._ | | `. | | ` | | 6 2kg, x=17 | | | +---------------------------------------------------------------------+ """ directory = os.path.dirname(__file__) convert_nbody = nbody_system.nbody_to_si(1|units.kg, 1|units.m) I = starlab.ParticlesFromDyn(os.path.join(directory, 'test_subsub.dyn')) All = I.Particles self.assertEquals(len(All), 7) self.assertEquals(len(All[0].descendents()),6) self.assertEquals(All[0].children().mass.value_in(nbody_system.mass)[0], 8.0) self.assertEquals(All[1].children().mass.value_in(nbody_system.mass)[0], 4.0) self.assertEquals(All[5].children().mass.value_in(nbody_system.mass)[0], 2.0)
def init_body_solar_disk_planetary(Ndisk, Mdisk, Rmin, Rmax): print 'Initializing...' #converter = nbody_system.nbody_to_si(1.|units.MJupiter, 1.|units.AU) # Initialize the solar system Sun_Jupiter = init_sun_jupiter() Sun = Sun_Jupiter[0] Jupiter = Sun_Jupiter[1] orbit = orbital_elements_from_binary(Sun_Jupiter, G=constants.G) a = orbit[2].in_(units.AU) e = orbit[3] hr = Hill_radius(a, e, Sun_Jupiter) # Initialize the proto-planetary disk np.random.seed(1) disk_converter = nbody_system.nbody_to_si(Sun.mass, Rmin) disk = ProtoPlanetaryDisk(Ndisk, convert_nbody=disk_converter, densitypower=1.5, Rmin=1.0, Rmax=Rmax / Rmin, q_out=1.0, discfraction=Mdisk / Sun.mass) disk_gas = disk.result # Initialize the sink particle sink = init_sink_particle(0. | units.MSun, hr, Jupiter.position, Jupiter.velocity) # Initizalize the passing star e = 1.2 Mstar = 2.0 | units.MSun pericenter = 200.0 | units.AU Pstar = init_passing_star(pericenter, e, Mstar) return Sun_Jupiter, disk_gas, sink, Pstar
def test7(self): print("Testing astro printing strategy with units printed") mass = 2.0 | 0.5 * units.MSun acc = (0.0097 | nbody_system.length) * (1 | units.Myr** -2).as_quantity_in(units.s**-2) position = [0.1, 0.2, 0.3] | nbody_system.length energy = 1e8 | units.erg temperature = 5000 | units.K pi = 3.14 | units.none converter = nbody_system.nbody_to_si(1.0 | units.kg, 1.0 | units.kpc) set_printing_strategy("astro") self.assertEqual(str(mass), "1.0 MSun") self.assertEqual(str(acc), "0.0097 length * Myr**-2") self.assertEqual(str(converter.to_si(acc)), "9.7 parsec * Myr**-2") self.assertEqual(str(converter.to_si(position)), "[100.0, 200.0, 300.0] parsec") self.assertEqual(str(energy), "10.0 J") self.assertEqual( str(constants.G)[:8], "0.004499450561351174 parsec**3 * MSun**-1 * Myr**-2"[:8]) self.assertEqual( str(constants.G)[-30:], "parsec**3 * MSun**-1 * Myr**-2") self.assertEqual(str(temperature), "5000 K") self.assertEqual(str(pi), "3.14 none") set_printing_strategy("astro", nbody_converter=converter) self.assertEqual(str(acc), "9.7 parsec * Myr**-2") set_printing_strategy("astro", ignore_converter_exceptions=False) self.assertRaises( AmuseException, str, acc, expected_message= "Unable to convert length * s**-2 to SI units. No nbody_converter given" ) set_printing_strategy("default")
def evolve_system_with_massloss(particles, mass_sequence, time_sequence, datahandler): """ Parameters ---------- particles: a two-body system mass_sequence: sequence of masses time_sequence: sequence of times datahandler: HDF5HandlerAmuse context manager """ h = datahandler intr = Hermite(nbody_to_si(particles.total_mass(), 1 | u.AU)) intr.particles.add_particles(particles) h.append(particles[0].period0, "period0") for mass, time in zip(mass_sequence, time_sequence): intr.particles.move_to_center() intr.evolve_model(time) intr.particles[0].mass = mass h.append(intr.particles.center_of_mass(), "CM_position") h.append(intr.particles.center_of_mass_velocity(), "CM_velocity") h.append(intr.particles.position, "position") h.append(intr.particles.velocity, "velocity") h.append(intr.particles.mass, "mass") h.append(intr.particles.kinetic_energy(), "kinetic_energy") h.append(intr.particles.potential_energy(), "potential_energy") h.append(intr.get_total_energy(), "total_energy") h.append(time, "time") h.append(semimajoraxis_from_binary(intr.particles), "sma") h.append(eccentricity_from_binary(intr.particles), "eccentricity") intr.stop()
def xtest07(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print("Testing effect of Sakura parameter epsilon_squared") converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) particles = self.new_sun_earth_system() particles.rotate(0.0, 0.0, -math.pi / 4) particles.move_to_center() tan_initial_direction = particles[1].vy / particles[1].vx self.assertAlmostEqual(tan_initial_direction, math.tan(math.pi / 4)) tan_final_direction = [] for log_eps2 in range(-9, 10, 2): instance = self.new_instance_of_an_optional_code( Sakura, converter, **default_options) instance.initialize_code() instance.parameters.epsilon_squared = 10.0**log_eps2 | units.AU**2 # instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() instance.evolve_model(0.25 | units.yr) tan_final_direction.append(instance.particles[1].velocity[1] / instance.particles[1].velocity[0]) instance.cleanup_code() instance.stop() # Small values of epsilon_squared should result in normal earth-sun dynamics: rotation of 90 degrees self.assertAlmostEqual(tan_final_direction[0], math.tan(3 * math.pi / 4.0), 2) # Large values of epsilon_squared should result in ~ no interaction self.assertAlmostEqual(tan_final_direction[-1], tan_initial_direction, 2) # Outcome is most sensitive to epsilon_squared when epsilon_squared = d(earth, sun)^2 delta = [ abs(tan_final_direction[i + 1] - tan_final_direction[i]) for i in range(len(tan_final_direction) - 1) ] self.assertEqual(delta[len(tan_final_direction) / 2 - 1], max(delta))
def evolve_cluster_and_cloud(Ncl, Mcl, Rcl, Ngas, Mgas, Rgas, d, v_inf, dt, filename, initial_sep=None): cluster, = read_set_from_file(filename, 'amuse', names=("cluster", )) filename = filename[:-4] + ".second_encounter.dat" nbody_converter = nbody_system.nbody_to_si(Mcl, Rcl) gas, gas_converter = create_giant_molecular_cloud(Ngas, Mgas, Rgas) cluster, gas, t_end = put_in_orbit(cluster, gas, d, initial_sep) print "t end", t_end gravity, hydro, bridge, channels = setup_codes(cluster, gas, nbody_converter, gas_converter) time = 0. | units.Myr write_set_to_file((cluster.savepoint(time), gas.savepoint(time)), filename, 'amuse', names=("cluster", "gas"), append_to_file=False) while time < (t_end - dt / 2.): time += dt print "evolving to", time bridge.evolve_model(time) channels.copy() write_set_to_file((cluster.savepoint(time), gas.savepoint(time)), filename, 'amuse', names=("cluster", "gas"))
def iliev_test_7(N=10000, Ns=10, L=6.6 | units.kpc, dt=1 | units.Myr, rad_parameters=dict()): rad_parameters["box_size"] = 2 * L gas, sources = iliev_test_7_ic(N, Ns, L) conv = nbody_system.nbody_to_si(1.0e9 | units.MSun, 1.0 | units.kpc) sph = Fi(conv, mode='periodic') sph.parameters.use_hydro_flag = True sph.parameters.radiation_flag = False sph.parameters.self_gravity_flag = False sph.parameters.gamma = 1 sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = dt / 2 sph.parameters.verbosity = 0 sph.parameters.periodic_box_size = 2 * L sph.gas_particles.add_particles(gas) print sph.parameters.timestep.in_(units.Myr) rad = SPHRay() #redirection='none') for x in rad_parameters: print x, rad_parameters[x] rad.parameters.__setattr__(x, rad_parameters[x]) # gas.u=100*gas.u rad.gas_particles.add_particles(gas) rad.src_particles.add_particles(sources) return sph, rad
def test4(self): convert_nbody = nbody_system.nbody_to_si(5.9742e24 | units.kg, 1e6| units.m) instance = interface.TwoBody(convert_nbody) p = datamodel.Particle() p.mass = 5.9742e24 | units.kg p.radius = 7.1e6 | units.m p.position = [0.,7.e6,-1.2124e7] | units.m p.velocity = [0.,2.6679e3,4.6210e3] | units.m/units.s instance.particles.add_particle(p) instance.evolve_model(3600.0 | units.s) dt = convert_nbody.to_si(instance.model_time) self.assertEqual(instance.particles[0].mass,5.9742e24 | units.kg) instance.particles[0].mass=0.8*5.9742e24 | units.kg instance.evolve_model(4000.0 | units.s) self.assertEqual(instance.particles.mass[0],0.8*5.9742e24 | units.kg) instance.stop()
def test3(self): convert_nbody = nbody_system.nbody_to_si(5.9742e24 | units.kg, 1e6 | units.m) instance = interface.TwoBody(convert_nbody) p = datamodel.Particle() p.mass = 5.9742e24 | units.kg p.radius = 7.1e6 | units.m p.position = [0., 7.e6, -1.2124e7] | units.m p.velocity = [0., 2.6679e3, 4.6210e3] | units.m / units.s instance.particles.add_particle(p) instance.evolve_model(3600.0 | units.s) dt = convert_nbody.to_si(instance.model_time) self.assertAlmostEqual(dt.value_in(units.s) / 2583.44780926, 1., 7) position = instance.particles[0].position self.assertAlmostEqual( ((position.x**2 + position.y**2 + position.z**2) / (7.1e6)**2).value_in(units.m**2), 1., 7) instance.stop()
def test5(self): print("CalculateFieldForParticles get_potential_at_point, with individual softening") epsilon = 0.5 | units.parsec convert = nbody_system.nbody_to_si(1.e5 | units.MSun, 1.0 | units.parsec) numpy.random.seed(12345) stars = new_plummer_model(100, convert_nbody=convert) stars.radius = epsilon * numpy.random.uniform(low=0.4, high=3.0, size=len(stars)) cluster = ExampleGravityCodeInterface(softening_mode="individual") cluster.particles.add_particles(stars) instance = bridge.CalculateFieldForParticles(particles=stars, softening_mode="individual") zeros = numpy.zeros(9) | units.parsec pos_range = numpy.linspace(-1.0, 1.0, 9) | units.parsec self.assertAlmostRelativeEqual( instance.get_potential_at_point(zeros, pos_range, zeros, zeros), cluster.get_potential_at_point(zeros, pos_range, zeros, zeros)) for a_calculate_field, a_code in zip( instance.get_gravity_at_point(zeros, pos_range, zeros, zeros), cluster.get_gravity_at_point(zeros, pos_range, zeros, zeros)): self.assertAlmostRelativeEqual(a_calculate_field, a_code, 12)
def test1(self): print("Bridge potential energy with code's epsilon_squared as softening length") convert = nbody_system.nbody_to_si(1.e5 | units.MSun, 1.0 | units.parsec) epsilon = 1.0e-2 | units.parsec test_class=ExampleGravityCodeInterface numpy.random.seed(12345) stars = new_plummer_model(100, convert_nbody=convert) cluster=test_class() cluster.parameters.epsilon_squared = epsilon**2 cluster.particles.add_particles(stars) first_half = stars.select_array(lambda x: (x > 0 | units.m), ['x'] ) second_half = stars - first_half cluster1 = system_from_particles(test_class, dict(), first_half, epsilon) cluster2 = system_from_particles(test_class, dict(), second_half, epsilon) bridgesys=bridge.Bridge() bridgesys.add_system(cluster1, (cluster2,) ) bridgesys.add_system(cluster2, (cluster1,) ) self.assertAlmostRelativeEqual(cluster.potential_energy, bridgesys.potential_energy) self.assertAlmostRelativeEqual(cluster.kinetic_energy, bridgesys.kinetic_energy)
def test4(self): convert_nbody = nbody_system.nbody_to_si(5.0 | units.kg, 10.0 | units.m) instance = Huayno(convert_nbody) instance.initialize_code() particles = datamodel.Particles(2) self.assertEqual(len(instance.particles), 0) particles.mass = [15.0, 30.0] | units.kg particles.radius = [10.0, 20.0] | units.m particles.position = [[10.0, 20.0, 30.0], [20.0, 40.0, 60.0]] | units.m particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.m / units.s instance.particles.add_particles(particles) self.assertEqual(len(instance.particles), 2) instance.particles.mass = [17.0, 33.0] | units.kg self.assertEqual(instance.get_mass(0), 17.0 | units.kg) self.assertEqual(instance.get_mass(1), 33.0 | units.kg)
def test_bhtree(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.kg, 1.0 | units.km) bhtree = BHTree(convert_nbody) bhtree.parameters.epsilon_squared = 10 | units.km**2 bhtree.parameters.timestep = 1.0 | units.s bhtree.parameters.opening_angle = 0.1 docstring = bhtree.parameters.__doc__ self.assertTrue( "smoothing parameter for gravity calculations (default value:125000.0 m**2)" in docstring) parameter_str_method_output = str(bhtree.parameters) self.assertTrue( "epsilon_squared: 10000000.0 m**2" in parameter_str_method_output) self.assertTrue("timestep: 1.0 s" in parameter_str_method_output) self.assertTrue("opening_angle: 0.1" in parameter_str_method_output)
def setup_cluster(nbodycode, N, Mcluster, Rcluster, Rinit, Vinit, parameters=[]): converter = nbody_system.nbody_to_si(Mcluster, Rcluster) stars = new_plummer_sphere(N, converter) stars.x += Rinit[0] stars.y += Rinit[1] stars.z += Rinit[2] stars.vx += Vinit[0] stars.vy += Vinit[1] stars.vz += Vinit[2] code = nbodycode(converter, number_of_workers=1) for name, value in parameters: setattr(code.parameters, name, value) code.particles.add_particles(stars) return code
def test6(self): print "Testing MI6 evolve_model, earth-sun system, no SMBH" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = MI6(converter, **default_options) instance.initialize_code() instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(self.new_sun_earth_system()) instance.commit_particles() earth = instance.particles[1] position_at_start = earth.position.x instance.evolve_model(0.25 | units.yr) self.assertAlmostRelativeEqual(position_at_start, earth.position.y, 3) instance.evolve_model(0.5 | units.yr) self.assertAlmostRelativeEqual(position_at_start, -earth.position.x, 3) instance.evolve_model(1.0 | units.yr) self.assertAlmostRelativeEqual(position_at_start, earth.position.x, 3) instance.cleanup_code() instance.stop()
def test26(self): print("test massless particles (negative time)") N=10 tend=-5.| units.yr numpy.random.seed(12345) conv=nbody_system.nbody_to_si(4.| units.MSun, 5.|units.AU) orbiters=plummer.new_plummer_model(N,conv) sun=datamodel.Particle(mass=1.|units.MSun) sun.position=[0,0,0]|units.AU sun.velocity=[0,0,0]|units.kms orbiters.mass*=0. a0,eps0=elements(sun.mass,orbiters.x,orbiters.y,orbiters.z, orbiters.vx,orbiters.vy,orbiters.vz) pos=dict() for inttype in [20,14]: code=Huayno(conv) code.parameters.inttype_parameter=inttype code.parameters.timestep_parameter=0.1 code.particles.add_particle(sun) orbiters2=code.particles.add_particles(orbiters) code.evolve_model(tend) a,eps=elements(sun.mass,orbiters2.x,orbiters2.y,orbiters2.z, orbiters2.vx,orbiters2.vy,orbiters2.vz) da=abs((a-a0)/a0) deps=abs(eps-eps0)/eps0 dev=numpy.where(da > 1.e-12)[0] self.assertEqual( len(dev),0) dev=numpy.where(deps > 1.e-12)[0] self.assertEqual( len(dev),0) pos[inttype]=[orbiters.x.value_in(units.AU),orbiters.y.value_in(units.AU),orbiters.z.value_in(units.AU)] self.assertAlmostEqual(pos[20][0],pos[14][0],12) self.assertAlmostEqual(pos[20][1],pos[14][1],12) self.assertAlmostEqual(pos[20][2],pos[14][2],12)
def generate_cluster(number_of_stars, mass_of_cluster, radius_of_cluster): # numpy.random.seed(1) if (mass_of_cluster > 0 | units.MSun): number_of_stars = int(mass_of_cluster.value_in(units.MSun)) * 5 salpeter_masses = new_salpeter_mass_distribution(number_of_stars) imf = salpeter_masses if (mass_of_cluster > 0 | units.MSun): print("sorted sampling salpeter IMF, total mass:", mass_of_cluster) imf_cumsum = imf.cumsum() pick_up_number = (imf_cumsum <= mass_of_cluster).sum() if (pick_up_number < number_of_stars): imf_pick_up = imf[:pick_up_number + 1] sorted_imf_pick_up = np.sort(imf_pick_up) if (sorted_imf_pick_up[pick_up_number] - mass_of_cluster < mass_of_cluster - sorted_imf_pick_up[pick_up_number - 1]): pick_up_number += 1 imf = sorted_imf_pick_up[:pick_up_number] number_of_stars = pick_up_number total_mass = imf.sum() convert_nbody = nbody_system.nbody_to_si(total_mass, radius_of_cluster | units.parsec) print("generate plummer model, N=", number_of_stars) particles = new_plummer_model(number_of_stars, convert_nbody) print("setting masses of the stars") particles.radius = 0.0 | units.RSun particles.mass = imf #particles.mass[0] = 40.0 |units.MSun #particles.mass[1] = 50.0 |units.MSun return particles, convert_nbody
def test5(self): print "Test new_particle_from_cluster_core - reuse_hop or not" converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.parsec) plummer = new_plummer_sphere(100, convert_nbody=converter) result = plummer.new_particle_from_cluster_core( unit_converter=converter, reuse_hop=True) # Hop wasn't stopped, will use same Hop instance: result = plummer.new_particle_from_cluster_core( unit_converter=converter, reuse_hop=True) nbody_plummer = new_plummer_sphere(100) # Hop wasn't stopped, unit_converters don't match: self.assertRaises( AttributeError, nbody_plummer.new_particle_from_cluster_core, expected_message= "Cannot combine units from different systems: m and length") result = plummer.new_particle_from_cluster_core( unit_converter=converter, reuse_hop=False) # Hop was stopped, new instance will be made with supplied unit_converter (None in this case): result = nbody_plummer.new_particle_from_cluster_core(reuse_hop=True) self.assertRaises( ConvertArgumentsException, plummer.new_particle_from_cluster_core, unit_converter=converter, #, expected_message= "error while converting parameter 'mass', error: Cannot express kg in mass, the units do not have the same bases" ) result = nbody_plummer.new_particle_from_cluster_core(reuse_hop=False) result = plummer.new_particle_from_cluster_core( unit_converter=converter, reuse_hop=False)
def test3b(self): # Same test as test3, but testing on the class, not instance # This makes sure the python 'help' functionality works on parameters parameter_definition = parameters.ModuleMethodParameterDefinition( "get_test", None, "test_name", "a test parameter", 11.0 | nbody_system.length ) class TestModule(BaseTestModule): x = 123 | units.m def get_test(self): return self.x def set_test(self, value): self.x = value o = TestModule() x = parameters.new_parameters_instance_with_docs([parameter_definition], o) self.assertTrue("test_name" in x.__class__.__doc__) self.assertTrue("a test parameter" in x.__class__.__doc__) self.assertTrue("default" in x.__class__.__doc__) self.assertTrue("11.0 length" in x.__class__.__doc__) convert_nbody = nbody_system.nbody_to_si(2.0 | units.m, 4.0 | units.kg) y = parameters.new_parameters_with_units_converted_instance_with_docs( x, convert_nbody.as_converter_from_si_to_generic() ) self.assertTrue("test_name" in y.__class__.__doc__) self.assertTrue("a test parameter" in y.__class__.__doc__) self.assertTrue("default" in y.__class__.__doc__) self.assertTrue("22.0 m" in y.__class__.__doc__)
def main(): assert is_mpd_running() seed = None nstars = 128 if len(sys.argv) > 1: stars = int(sys.argv[1]) with_units = len(sys.argv) > 2 if not with_units: mass_unit = nbody_system.mass length_unit = nbody_system.length else: mass_unit = units.MSun length_unit = units.parsec m_min = 0.1 | mass_unit m_max = 100 | mass_unit alpha = -2.35 r_vir = 1 | length_unit masses = new_salpeter_mass_distribution(nstars, m_min, m_max, alpha) m_tot = masses.sum() if not with_units: convert_nbody = None masses /= m_tot.value_in(nbody_system.mass) # scale to unit mass m_tot = 1 | nbody_system.mass else: convert_nbody = nbody_system.nbody_to_si(m_tot, r_vir) convert_nbody.set_as_default() print m_tot stars = new_plummer_model(nstars, convert_nbody, random_state=seed) stars.mass = masses LagrangianRadii(stars, verbose=True)
def test9(self): convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 149.5e6 | units.km) instance = PhiGRAPE(convert_nbody, **default_test_options)#, debugger="xterm") instance.initialize_code() instance.parameters.set_defaults() instance.parameters.initialize_gpu_once = 1 stars = self.new_system_of_sun_and_earth() earth = stars[1] instance.particles.add_particles(stars) instance.commit_particles() instance.evolve_model(365 | units.day) instance.particles.copy_values_of_all_attributes_to(stars) position_at_start = earth.position.value_in(units.AU)[0] position_after_full_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(position_at_start, position_after_full_rotation, 6) instance.evolve_model(365.0 + (365.0 / 2) | units.day) instance.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[0] self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 2) instance.evolve_model(365.0 + (365.0 / 2) + (365.0 / 4) | units.day) instance.particles.copy_values_of_all_attributes_to(stars) position_after_half_a_rotation = earth.position.value_in(units.AU)[1] #self.assertAlmostEqual(-position_at_start, position_after_half_a_rotation, 3) instance.cleanup_code() instance.stop()