def test7(self): print "Test7: Testing effect of Huayno parameter epsilon_squared" convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) particles = datamodel.Particles(2) sun = particles[0] sun.mass = 1.0 | units.MSun sun.position = [0.0, 0.0, 0.0] | units.AU sun.velocity = [0.0, 0.0, 0.0] | units.AU / units.yr sun.radius = 1.0 | units.RSun earth = particles[1] earth.mass = 5.9736e24 | units.kg earth.radius = 6371.0 | units.km earth.position = [0.0, 1.0, 0.0] | units.AU earth.velocity = [2.0 * numpy.pi, -0.0001, 0.0] | units.AU / units.yr initial_direction = math.atan((earth.velocity[0] / earth.velocity[1])) final_direction = [] for log_eps2 in range(-9, 10, 2): instance = Huayno(convert_nbody) instance.initialize_code() instance.parameters.epsilon_squared = 10.0**log_eps2 | units.AU**2 instance.particles.add_particles(particles) instance.commit_particles() instance.evolve_model(0.25 | units.yr) final_direction.append( math.atan((instance.particles[1].velocity[0] / instance.particles[1].velocity[1]))) instance.stop() # Small values of epsilon_squared should result in normal earth-sun dynamics: rotation of 90 degrees self.assertAlmostEquals(abs(final_direction[0]), abs(initial_direction + math.pi / 2.0), 2) # Large values of epsilon_squared should result in ~ no interaction self.assertAlmostEquals(final_direction[-1], initial_direction, 2) # Outcome is most sensitive to epsilon_squared when epsilon_squared = d(earth, sun)^2 delta = [ abs(final_direction[i + 1] - final_direction[i]) for i in range(len(final_direction) - 1) ] self.assertEquals(delta[len(final_direction) // 2 - 1], max(delta))
def test24(self): print("test massless particles/ kepler integrator") N=20 tend=2.| 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=[12.3,1.,-.2]|units.AU sun.velocity=[10,50.,-20.]|units.kms orbiters.mass*=0. a0,eps0=elements(sun.mass,orbiters.x,orbiters.y,orbiters.z, orbiters.vx,orbiters.vy,orbiters.vz) orbiters.position+=sun.position orbiters.velocity+=sun.velocity 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).copy() orbiters2.position-=sun.position orbiters2.velocity-=sun.velocity 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]=[orbiters2.x.value_in(units.AU),orbiters2.y.value_in(units.AU),orbiters2.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 test22(self): print("Testing zero-mass test particles in Huayno, can be used for removing particles when inside recursive evolve loop") sun_and_earth = self.new_system_of_sun_and_earth() period = (4.0 * math.pi**2 * (1.0 | units.AU)**3 / (constants.G * sun_and_earth.total_mass())).sqrt() convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) huayno = Huayno(convert_nbody) huayno.parameters.epsilon_squared = 0.0 | units.AU**2 huayno.parameters.inttype_parameter = huayno.inttypes.SHARED8 test_particle = datamodel.Particle(mass=0|units.MSun, position=[4,0,0]|units.AU, velocity=[0,0,0]|units.kms) test_particle.vy = (constants.G * sun_and_earth.total_mass() / (4.0 | units.AU)).sqrt() sun_and_earth.add_particle(test_particle) huayno.particles.add_particles(sun_and_earth) huayno.evolve_model(period) self.assertAlmostRelativeEqual(huayno.particles[:2].x, sun_and_earth[:2].x, 13) huayno.evolve_model(1.25 * period) self.assertAlmostRelativeEqual(huayno.particles[1].y, sun_and_earth[1].x, 13) huayno.evolve_model(8.0 * period) self.assertAlmostRelativeEqual(huayno.particles.x, sun_and_earth.x, 8) huayno.stop()
def test25(self): print("test massless particles/ kepler integrator, smoothed") N = 10 tend = 20. | 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. eps = (5. | units.AU) e0 = energy(sun.mass, eps, orbiters) l0 = angular_momentum(orbiters) pos = dict() for inttype in [20, 14]: code = Huayno(conv) code.parameters.inttype_parameter = inttype code.parameters.timestep_parameter = 0.1 code.parameters.epsilon_squared = eps**2 code.particles.add_particle(sun) orbiters2 = code.particles.add_particles(orbiters) code.evolve_model(tend) e1 = energy(sun.mass, eps, orbiters2) l1 = angular_momentum(orbiters2) de, dl = abs((e1 - e0) / e0).max(), abs((l1 - l0) / l1).max() self.assertTrue(numpy.all(de < 1.e-8)) self.assertTrue(numpy.all(dl < 1.e-8)) pos[inttype] = [ orbiters2.x.value_in(units.AU), orbiters2.y.value_in(units.AU), orbiters2.z.value_in(units.AU) ] self.assertAlmostRelativeEqual(pos[20][0], pos[14][0], 4) # still not clear why 4 self.assertAlmostRelativeEqual(pos[20][1], pos[14][1], 4) self.assertAlmostRelativeEqual(pos[20][2], pos[14][2], 4)
def test6(self): print("Test6: Testing Huayno parameters") convert_nbody = nbody_system.nbody_to_si(1.0 | units.yr, 1.0 | units.AU) instance = Huayno(convert_nbody) (value, error) = instance.legacy_interface.get_eps2() self.assertEqual(0, error) self.assertEqual(0.0, value) self.assertAlmostEqual(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.assertAlmostEqual(x | units.AU**2, instance.parameters.epsilon_squared, in_units=units.AU**2) (value, error) = instance.legacy_interface.get_time() self.assertEqual(0, error) self.assertEqual(0.0, value) self.assertAlmostEqual(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.assertAlmostEqual(x | units.yr, instance.parameters.begin_time, in_units=units.yr) instance.stop()
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.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.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 timerun(N=1000, f_bin=1., tend=1. | nbody_system.time, inttype=Huayno.inttypes.HOLD_DKD, seed=12345678, logamin=-4): stars = plummer_w_binaries(N=N, f_bin=f_bin, seed=seed, logamin=logamin) code = Huayno() code.parameters.inttype_parameter = inttype code.parameters.timestep_parameter = 0.01 code.particles.add_particles(stars) E0 = code.kinetic_energy + code.potential_energy p0 = code.particles.total_momentum() t1 = time() code.evolve_model(tend) t2 = time() E = code.kinetic_energy + code.potential_energy p = code.particles.total_momentum() code.stop() return t2 - t1, abs(E0 - E) / E0, p0 - p
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 = [t_x[1].value_in(units.AU) for t_x in x_points] y_points_in_AU = [t_x1[1].value_in(units.AU) for t_x1 in 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) 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 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 test15(self): particles = plummer.new_plummer_model(512) expected_positions = None for mode in ["cpu", "openmp", "opencl"]: try: instance = Huayno(mode=mode, number_of_workers=1)#, debugger="xterm") except: print("Running huayno with mode=", mode, " was unsuccessful.") continue else: print("Running huayno with mode=", mode, "... ") instance.initialize_code() instance.parameters.epsilon_squared = 0.01 | nbody_system.length ** 2 instance.particles.add_particles(particles) instance.evolve_model(0.2 | nbody_system.time) instance.synchronize_model() if expected_positions is None: expected_positions = instance.particles.position else: self.assertAlmostRelativeEquals(expected_positions, instance.particles.position, 8) instance.stop()
def test29(self): instance = Huayno() instance.parameters.epsilon_squared = 0.0 | nbody_system.length**2 particles = datamodel.Particles(2) particles.position = ([0, 0, 0], [1, 0, 0]) | nbody_system.length particles.velocity = ([-1, 0, 0], [2, 0, 0]) | nbody_system.speed particles.radius = 0 | nbody_system.length particles.mass = 0.1 | nbody_system.mass instance.particles.add_particles(particles) instance.stopping_conditions.out_of_box_detection.enable() instance.parameters.stopping_conditions_out_of_box_size = 2 | nbody_system.length instance.parameters.stopping_conditions_out_of_box_use_center_of_mass = False instance.evolve_model(1 | nbody_system.time) self.assertTrue( instance.stopping_conditions.out_of_box_detection.is_set()) self.assertEqual( len(instance.stopping_conditions.out_of_box_detection.particles( 0)), 1) self.assertEqual( instance.stopping_conditions.out_of_box_detection.particles(0) [0].key, particles[1].key) instance.stop()
def binary_with_planet_run(m1=1. | units.MSun, m2=1. | units.MSun, m_planet=1 | units.MJupiter, r1=None, r2=None, r_planet=None, ecc_binary=0, P_binary=20 | units.day, ecc_planet=0., P_planet=1. | units.yr, pangle_planet=0., a_planet=None, tend=100. | units.yr, hostname=''): dEcrit = 1.e-6 three = binary_with_planet(m1=m1, m2=m2, m_planet=m_planet, r1=r1, r2=r2, r_planet=r_planet, ecc_binary=ecc_binary, P_binary=P_binary, ecc_planet=ecc_planet, a_planet=a_planet, pangle_planet=pangle_planet) convert = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) code = Huayno(convert, hostname=hostname) code.parameters.inttype_parameter = code.inttypes.SHARED10 code.parameters.timestep_parameter = .2 code.parameters.timestep = 100. | units.day dt = 10000. | units.day code.particles.add_particles(three) E0 = code.potential_energy + code.kinetic_energy a0, eps0, pangle0 = elements(three.total_mass(), code.particles.x[2], code.particles.y[2], code.particles.z[2], code.particles.vx[2], code.particles.vy[2], code.particles.vz[2]) t = 0. | units.day result = "stable" while (t < tend - dt / 2): t = t + dt code.evolve_model(t) E = code.potential_energy + code.kinetic_energy dE = abs(((E - E0) / E0)) a, eps, pangle = elements(three.total_mass(), code.particles.x[2], code.particles.y[2], code.particles.z[2], code.particles.vx[2], code.particles.vy[2], code.particles.vz[2]) if dE > dEcrit or a < 0.5 * a0 or a > 2. * a0: result = "unstable" if dE > dEcrit: result = "failed" break code.stop() return result, t, dE, a.in_(units.AU), eps, pangle
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, dtse_fac): import random from amuse.ext.solarsystem import get_position time_framework = 0 print "Initial masses:", M1, M2, M3 t_stellar = 4.0 | units.Myr triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) t0 = ctime.time() stellar.evolve_model(t_stellar) delta_t = ctime.time() - t0 time_framework += delta_t channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Masses at time T:", M1, M2, M3 # Inner binary tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1 + M2) else: Pin_0 = orbital_period(ain_0, M1 + M2) print 'ain_0 =', ain_0 print 'M1+M2 =', M1 + M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt = 0.1 * Pin_0 ma = 180 inc = 30 aop = 180 lon = 0 r, v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary r, v = get_position(M1 + M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) gravity = Huayno(converter) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() time = 0.0 | t_end.unit ts = t_stellar + time # begin when stars have formed after 4.0 Myr years ain, ein, aout, eout, iin, iout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, iin, \ "outer:", triple[2].mass, aout, eout, iout dt_diag = t_end / float( nsteps) # how often we want to save the generated data t_diag = dt_diag t = [time.value_in(units.Myr)] smai = [ain / ain_0] ecci = [ein / ein_0] smao = [aout / aout_0] ecco = [eout / eout_0] inci = [iin] inco = [iout] ain = ain_0 def advance_stellar(ts, dt): E0 = gravity.kinetic_energy + gravity.potential_energy ts += dt stellar.evolve_model(ts) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return ts, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_stellar_with_massloss( ts, time_framework, dt_massloss=15e-9 | units.Myr, max_massloss=3e-4 | units.MSun): # Scheme 3: dt 8*10^-7, dm = 2*10^-5 ( max_massloss = 0.0 | units.MSun # massloss over full gravtiational time step massloss0 #max_massloss= 3e-6 | units.MSun # massloss over full gravtiational time step massloss1 #max_massloss= 1e-6 | units.MSun # massloss over full gravtiational time step massloss2 E0 = gravity.kinetic_energy + gravity.potential_energy massloss = -1 | units.MSun mass_0 = numpy.sum(stellar.particles.mass) dt_stellar = 0 | units.Myr niter = 0 while massloss < max_massloss: ts += dt_massloss dt_stellar += dt_massloss # counter for full time niter += 1 t0 = ctime.time() stellar.evolve_model(ts) delta_t = ctime.time() - t0 time_framework += delta_t massloss = 2. * ( mass_0 - numpy.sum(stellar.particles.mass) ) # massloss over full gravtiational time step is x2 channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) print 'Tstellar:', dt_stellar, ', Total Mloss:', massloss, ' Niter:', niter return ts, time_framework, gravity.kinetic_energy + gravity.potential_energy - E0, dt_stellar def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg global_time = [] global_massloss = [] global_dmdt = [] while time < t_end: Pin = orbital_period(ain, triple[0].mass + triple[1].mass) dt = dtse_fac * Pin dt *= random.random( ) # time step is chosen random between 0 and 50*Pin if scheme == 1: ts, dE_se = advance_stellar(ts, dt) time = advance_gravity(time, dt) elif scheme == 2: time = advance_gravity(time, dt) ts, dE_se = advance_stellar(ts, dt) elif scheme == 3: # inital mass mass_init = stellar.particles.mass.sum() # perform step ts, dE_se = advance_stellar(ts, dt / 2) time = advance_gravity(time, dt) ts, dE = advance_stellar(ts, dt / 2) dE_se += dE # add right vlaues global_time = numpy.append(global_time, time.value_in(units.Myr)) global_massloss = numpy.append( global_massloss, mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) else: # our scheme is 4 # inital mass mass_init = stellar.particles.mass.sum() time_init = time.value_in(units.Myr) | units.Myr # get optimal dt to perform a time step without losing too much mass ts, time_framework, dE_se, dt_stellar = advance_stellar_with_massloss( ts, time_framework) # perform time step dt t0 = ctime.time() time = advance_gravity(time, dt_stellar * 2) ts, dE = advance_stellar(ts, dt_stellar) delta_t = ctime.time() - t0 time_framework += delta_t dE_se += dE # save everything global_time = numpy.append(global_time, time.value_in(units.Myr)) global_massloss = numpy.append( global_massloss, mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) global_dmdt = numpy.append( global_dmdt, (mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) / (time.value_in(units.Myr) - time_init.value_in(units.Myr))) if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time #, #print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", #print "E= ", Etot, "Q= ", Ekin/Epot, #print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, #print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout, iin, iout = get_orbital_elements_of_triple( triple) #print "Triple elements t=", (4|units.Myr) + time, \ # "inner:", triple[0].mass, triple[1].mass, ain, ein, \ # "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.Myr)) smai.append(ain / ain_0) ecci.append(ein / ein_0) smao.append(aout / aout_0) ecco.append(eout / eout_0) inci.append(iin) inco.append(iout) if eout > 1.0 or aout <= zero: print "Binary ionized or merged" break pyplot.close() data = numpy.array(zip(global_time, global_massloss, global_dmdt)) numpy.save('massloss0', data) return t, smai, ecci, smao, ecco, inci, inco, time_framework
def main_function(number_of_stars=1000, end_time=4.0e4 | units.yr, steps=100, number_of_workers=6, animate=True, save_animation=False, escape=False, Q=0.5, D=2.6, filename="default.mp4", use_huayno=False, use_tree=False): """ Simulates a cluster of stars with varying masses. Input: :param number_of_stars: Number of stars to simulate, default: 1000 :param end_time: Total time at which to stop in nbody_system.time units (I think), default 10 | nbody_system.time :param steps: Total number of steps to save, default: 1000 :param number_of_workers: Number of cores/threads to use, does nothing when using Huayno, default: 5 :param animate: Makes an animation of the stars at each step (size depends on star mass), default: True :param save_animation: Saves the animation as mp4 file, default: True :param Q: Kinectic to potential energy fraction (I think) default: 0.5 :param D: Measure of fragmentedness, must be between 1.5 and 3, default 2.6 :param filename: Determines the name of the mp4 file, default: "default.mp4" :param use_huayno: Use alternative Huayno gravity evolver, default: False :return: (array of position arrays at each time step, array of time at each time step) """ start_time = clock_time() particles = new_cluster(number_of_stars=number_of_stars, Q=Q, D=D) total_mass = particles.mass.sum() convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec) # Initialize gravity can use others for tests, but hermite is used if use_huayno: gravity = Huayno(convert_nbody, number_of_workers=number_of_workers / 2) elif use_tree: gravity = BHTree(convert_nbody, number_of_workers=1, epsilon_squared=0.05 | nbody_system.length**2) else: gravity = Hermite(convert_nbody, number_of_workers=number_of_workers / 2) gravity.parameters.epsilon_squared = 0.05 | nbody_system.length**2 # gravity.parameters.epsilon_squared = 0.15 | nbody_system.length ** 2 # Used to be this gravity.particles.add_particles(particles) from_gravity_to_model = gravity.particles.new_channel_to(particles) # particles.scale_to_standard() Cannot scale to standard if not using nbody_system units # Initialize the Evolution if not use_tree: stellar_evolution = SSE(number_of_workers=number_of_workers / 2) else: stellar_evolution = SSE(number_of_workers=number_of_workers - 1) stellar_evolution.particles.add_particles(particles) from_stellar_evolution_to_model = stellar_evolution.particles.new_channel_to( particles) from_stellar_evolution_to_model.copy_attributes( ["mass", "luminosity", "temperature"]) # Initial time (note * end_time for correct units) time = 0.0 * end_time # Save initial conditions and make arrays (lists) for each step total_energy_at_t0 = gravity.kinetic_energy + gravity.potential_energy save_positions = [particles.position] save_velocities = [particles.velocity] save_masses = [particles.mass] save_luminosities = [particles.luminosity] save_temperatures = [particles.temperature] times = [time] while time < end_time: time += end_time / steps # Evolve gravity gravity.evolve_model(time) from_gravity_to_model.copy() # Evolve stars stellar_evolution.evolve_model(time) from_gravity_to_model.copy() from_stellar_evolution_to_model.copy_attributes( ["mass", "luminosity", "temperature"]) # Save data save_positions.append(particles.position) save_velocities.append(particles.velocity) save_masses.append(particles.mass) save_luminosities.append(particles.luminosity) save_temperatures.append(particles.temperature) times.append(time) total_energy = gravity.kinetic_energy + gravity.potential_energy if np.abs( (total_energy - total_energy_at_t0) / total_energy_at_t0) > 0.001: print( "Warning! Total energy of the system is changing too significantly!" ) print "Time: %.4g" % time.number total_mass = particles.mass.sum() print total_mass if escape: escaped_stars_3d, escaped_stars_2d = find_escapees(particles) gravity.stop() stellar_evolution.stop() print "It took %.3g seconds clock time" % (clock_time() - start_time) if animate: make_animation(save_positions, save_luminosities, save_temperatures, times, save_animation=save_animation, filename=filename) if escape: return save_positions[-1], save_velocities[-1], save_masses[ -1], escaped_stars_3d, escaped_stars_2d else: return save_positions, save_velocities
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, integrator, t_stellar, dt_se, dtse_fac, interp): import random from amuse.ext.solarsystem import get_position numpy.random.seed(42) print("Initial masses:", M1, M2, M3) triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) # Evolve to t_stellar. stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print("t=", stellar.model_time.in_(units.Myr)) print("M=", stellar.particles.mass.in_(units.MSun)) print("R=", stellar.particles.radius.in_(units.RSun)) print("L=", stellar.particles.luminosity.in_(units.LSun)) print("T=", stellar.particles.temperature.in_(units.K)) print("Mdot=", \ -stellar.particles.wind_mass_loss_rate.in_(units.MSun/units.yr)) # Start the dynamics. # Inner binary: tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print('Pin =', Pin_0) print('ain_0 =', ain_0) print('M1+M2 =', M1+M2) print('Pin_0 =', Pin_0.value_in(units.day), '[day]') #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt_init = 0.01*Pin_0 ma = 180 inc = 60 aop = 180 lon = 0 r,v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt_init) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary: r,v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt_init) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print("T=", stellar.model_time.in_(units.Myr)) print("M=", stellar.particles.mass.in_(units.MSun)) print("Pout=", Pout.in_(units.Myr)) print('tK =', ((M1+M2)/M3)*Pout**2*(1-eout_0**2)**1.5/Pin_0) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) if integrator == 0: gravity = Hermite(converter) gravity.parameters.timestep_parameter = 0.01 elif integrator == 1: gravity = SmallN(converter) gravity.parameters.timestep_parameter = 0.01 gravity.parameters.full_unperturbed = 0 elif integrator == 2: gravity = Huayno(converter) gravity.parameters.inttype_parameter = 20 gravity.parameters.timestep = (1./256)*Pin_0 else: gravity = symple(converter) gravity.parameters.integrator = 10 #gravity.parameters.timestep_parameter = 0. gravity.parameters.timestep = (1./128)*Pin_0 print(gravity.parameters) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() # Note: time = t_diag = 0 at the start of the dynamical integration. dt_diag = t_end/float(nsteps) t_diag = dt_diag time = 0.0 | t_end.unit t_se = t_stellar + time print('t_end =', t_end) print('dt_diag =', dt_diag) ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print("Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout) t = [time.value_in(units.Myr)] Mtot = triple.mass.sum() mtot = [Mtot.value_in(units.MSun)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] if interp: # Create arrays of stellar times and masses for interpolation. times = [time] masses = [triple.mass.copy()] while time < t_end: time += dt_se stellar.evolve_model(t_stellar+time) channel_from_stellar.copy_attributes(["mass"]) times.append(time) masses.append(triple.mass.copy()) time = 0.0 | t_end.unit print('\ntimes:', times, '\n') # Evolve the system. def advance_stellar(t_se, dt): E0 = gravity.kinetic_energy + gravity.potential_energy t_se += dt if interp: t = t_se-t_stellar i = int(t/dt_se) mass = masses[i] + (t-times[i])*(masses[i+1]-masses[i])/dt_se triple.mass = mass #print 't_se =', t_se, 'masses =', mass else: stellar.evolve_model(t_se) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return t_se, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: if scheme == 1: # Advance to the next diagnostic time. dE_se = zero dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) elif scheme == 2: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, dt) time = advance_gravity(time, dt) elif scheme == 3: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) t_se, dE_se = advance_stellar(t_se, dt) elif scheme == 4: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, 0.5*dt) time = advance_gravity(time, dt) t_se, dE_se2 = advance_stellar(t_se, 0.5*dt) dE_se += dE_se2 elif scheme == 5: # Use the specified dt_se. dE_se = zero dt = dt_se if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: # For use with symple only: set up average mass loss. channel_from_stellar.copy_attributes(["mass"]) m0 = triple.mass.copy() stellar.evolve_model(t_se+dt) channel_from_stellar.copy_attributes(["mass"]) t_se = stellar.model_time m1 = triple.mass dmdt = (m1-m0)/dt for i in range(len(dmdt)): gravity.set_dmdt(i, dmdt[i]) time = advance_gravity(time, dt) else: print('unknown option') sys.exit(0) if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print("T=", time, end=' ') print("M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", end=' ') print("E= ", Etot, "Q= ", Ekin/Epot, end=' ') print("dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, end=' ') print("(dE[SE]=", dE_se/Etot, ")") Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print("Triple elements t=", t_stellar + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout) t.append(time.value_in(units.yr)) mtot.append(Mtot.value_in(units.MSun)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1 or aout <= zero: print("Binary ionized or merged") break gravity.stop() stellar.stop() return t, mtot, smai, ecci, smao, ecco
def evolution_of_the_cluster(self, cluster): ''' Function that makes de cluster evolution. input: cluster -> defined in an inertial frame (centered at the Galactic center) steps in this function: 1. From cluster, another cluster is defined in a rotating frame 2. The gravity code is initialized 3. The stellar evolution is initialized 4. the Galaxy model is constructed 5. The Galaxy and the cluster in the rotating frame are coupled via the Rotating Bridge 6. The evolution of the system is made 7. the cluster properties are transformed back to the inertial frame ''' cluster_in_rotating_frame = self.creation_cluster_in_rotating_frame( cluster) # N body code epsilon = self.softening(cluster) convert_nbody = nbody_system.nbody_to_si(cluster.mass.sum(), cluster.virial_radius()) gravity = Huayno(convert_nbody) gravity.parameters.timestep = self.dt_bridge / 3. gravity.particles.add_particles(cluster_in_rotating_frame) gravity.parameters.epsilon_squared = epsilon**2 channel_from_gravity_to_rotating_cluster = gravity.particles.new_channel_to( cluster_in_rotating_frame) channel_from_rotating_cluster_to_gravity = cluster_in_rotating_frame.new_channel_to( gravity.particles) #stellar evolution code se = SeBa() se.particles.add_particles(cluster_in_rotating_frame) channel_from_rotating_cluster_to_se = cluster_in_rotating_frame.new_channel_to( se.particles) channel_from_se_to_rotating_cluster = se.particles.new_channel_to( cluster_in_rotating_frame) # Galaxy model and Rotating bridge MW = self.galactic_model() system = Rotating_Bridge(self.omega_system, timestep=self.dt_bridge, verbose=False, method=self.method) system.add_system(gravity, (MW, ), False) system.add_system(MW, (), False) X = [] Y = [] T = [] #Cluster evolution while (self.time <= self.t_end - self.dt_bridge / 2): self.time += self.dt_bridge system.evolve_model(self.time) se.evolve_model(self.time) channel_from_gravity_to_rotating_cluster.copy_attributes( ['x', 'y', 'z', 'vx', 'vy', 'vz']) channel_from_se_to_rotating_cluster.copy_attributes([ 'mass', 'radius', 'luminosity', 'age', 'temperature', 'stellar_type' ]) channel_from_rotating_cluster_to_gravity.copy_attributes(['mass']) self.from_noinertial_to_cluster_in_inertial_frame( cluster_in_rotating_frame, cluster) time = self.time.value_in(units.Myr) cm = cluster.center_of_mass() # write data if ((time == 2) or (time == 50) or (time == 100) or (time == 150)): X.append((cluster.x - cm[0]).value_in(units.kpc)) Y.append((cluster.y - cm[1]).value_in(units.kpc)) T.append(time) gravity.stop() se.stop() return T, X, Y
def test_run(): three = binary_with_planet(m1=0.6897 | units.MSun, m2=0.20255 | units.MSun, m_planet=0.333 | units.MJupiter, r1=0.6489 | units.RSun, r2=0.22623 | units.RSun, r_planet=0.754 | units.RJupiter, ecc_binary=0.15944, P_binary=41.08 | units.day, ecc_planet=0.00685, a_planet=.7048 | units.AU, pangle_planet=0.) convert = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) code = Huayno(convert) code.parameters.inttype_parameter = code.inttypes.SHARED4 code.parameters.timestep_parameter = 0.1 # tend=100. | units.yr tend = 100. | units.day snapfreq = 1 dt = 10. | units.day # dt=convert.to_si( 1. | nbody_system.time).in_(units.day) code.particles.add_particles(three) x = AdaptingVectorQuantity() y = AdaptingVectorQuantity() z = AdaptingVectorQuantity() vx = AdaptingVectorQuantity() vy = AdaptingVectorQuantity() vz = AdaptingVectorQuantity() x.append(code.particles.x) y.append(code.particles.y) z.append(code.particles.z) vx.append(code.particles.vx) vy.append(code.particles.vy) vz.append(code.particles.vz) ts = [0.] E0 = code.potential_energy + code.kinetic_energy dE = [1.e-14] t = 0. | units.day i = 0 while (t < tend - dt / 2): i += 1 t = t + dt if i % snapfreq == 0: print t ts.append(t.value_in(units.day)) code.evolve_model(t) x.append(code.particles.x) y.append(code.particles.y) z.append(code.particles.z) vx.append(code.particles.vx) vy.append(code.particles.vy) vz.append(code.particles.vz) E = code.potential_energy + code.kinetic_energy dE.append(abs(((E - E0) / E0))) code.stop() a, eps, pangle = elements(three.total_mass(), x[:, 2], y[:, 2], z[:, 2], vx[:, 2], vy[:, 2], vz[:, 2]) x = x.value_in(units.AU) y = y.value_in(units.AU) a = a.value_in(units.AU) eps = eps print a[-1], eps[-1], pangle[-1] f = pyplot.figure(figsize=(8, 8)) pyplot.plot(x[:, 0], y[:, 0], 'r.') pyplot.plot(x[:, 1], y[:, 1], 'g.') pyplot.plot(x[:, 2], y[:, 2], 'b.') pyplot.xlim(-3, 3) pyplot.ylim(-3, 3) pyplot.xlabel('AU') pyplot.savefig('three_16b.eps') f = pyplot.figure(figsize=(8, 8)) pyplot.semilogy(ts, dE, 'g.') pyplot.xlabel('time (day)') pyplot.ylabel('dE/E0') pyplot.savefig('three_16b_eerr.eps') f = pyplot.figure(figsize=(8, 8)) pyplot.plot(ts, a, 'g.') pyplot.xlabel('time (day)') pyplot.ylabel('a (AU)') pyplot.savefig('three_16b_a.eps') f = pyplot.figure(figsize=(8, 8)) pyplot.plot(ts, eps, 'g.') pyplot.xlabel('time (day)') pyplot.ylabel('eccentricity') pyplot.savefig('three_16b_ecc.eps') f = pyplot.figure(figsize=(8, 8)) pyplot.plot(ts, pangle, 'g.') pyplot.xlabel('time (day)') pyplot.ylabel('long. of periapsis') pyplot.savefig('three_16b_pangle.eps')
def get_huayno(converter): instance = Huayno(converter) instance.initialize_code() instance.parameters.set_defaults() return instance
def _run_collision_with_integrator(self, inttype_parameter): particles = datamodel.Particles(7) particles.mass = 0.001 | nbody_system.mass particles.radius = 0.01 | nbody_system.length particles.x = [-101.0, -100.0, -0.5, 0.5, 100.0, 101.0, 104.0 ] | nbody_system.length particles.y = 0 | nbody_system.length particles.z = 0 | nbody_system.length particles.velocity = [[2, 0, 0], [-2, 0, 0] ] * 3 + [[-4, 0, 0]] | nbody_system.speed instance = Huayno() instance.parameters.inttype_parameter = inttype_parameter instance.particles.add_particles(particles) collisions = instance.stopping_conditions.collision_detection collisions.enable() instance.evolve_model(1.0 | nbody_system.time) self.assertTrue(collisions.is_set()) self.assertTrue(instance.model_time < 0.5 | nbody_system.time) self.assertEquals(len(collisions.particles(0)), 3) self.assertEquals(len(collisions.particles(1)), 3) self.assertEquals( len(particles - collisions.particles(0) - collisions.particles(1)), 1) self.assertEquals( abs(collisions.particles(0).x - collisions.particles(1).x) <= (collisions.particles(0).radius + collisions.particles(1).radius), [True, True, True]) sticky_merged = datamodel.Particles(len(collisions.particles(0))) sticky_merged.mass = collisions.particles( 0).mass + collisions.particles(1).mass sticky_merged.radius = collisions.particles(0).radius for p1, p2, merged in zip(collisions.particles(0), collisions.particles(1), sticky_merged): merged.position = (p1 + p2).center_of_mass() merged.velocity = (p1 + p2).center_of_mass_velocity() print instance.model_time print instance.particles instance.particles.remove_particles( collisions.particles(0) + collisions.particles(1)) instance.particles.add_particles(sticky_merged) instance.evolve_model(1.0 | nbody_system.time) print print instance.model_time print instance.particles self.assertTrue(collisions.is_set()) self.assertTrue(instance.model_time < 1.0 | nbody_system.time) self.assertEquals(len(collisions.particles(0)), 1) self.assertEquals(len(collisions.particles(1)), 1) self.assertEquals( len(instance.particles - collisions.particles(0) - collisions.particles(1)), 2) self.assertEquals( abs(collisions.particles(0).x - collisions.particles(1).x) <= (collisions.particles(0).radius + collisions.particles(1).radius), [True]) instance.stop()