def evolve_cluster_in_galaxy(N, W0, Rinit, tend, timestep, M, R): galaxy_code = MilkyWay_galaxy() converter = nbody_system.nbody_to_si(M, R) cluster_code = drift_without_gravity(convert_nbody=converter) bodies = new_king_model(N, W0, convert_nbody=converter) cluster_code.particles.add_particles(bodies) stars = cluster_code.particles.copy() stars.x += Rinit stars.vy = 0.8 * galaxy_code.circular_velocity(Rinit) channel = stars.new_channel_to(cluster_code.particles) channel.copy_attributes(["x", "y", "z", "vx", "vy", "vz"]) system = bridge(verbose=False) system.add_system(cluster_code, (galaxy_code, )) times = quantities.arange(0 | units.Myr, tend, 100 * timestep) for i, t in enumerate(times): print("Time=", t.in_(units.Myr)) system.evolve_model(t, timestep=timestep) x = system.particles.x.value_in(units.kpc) y = system.particles.y.value_in(units.kpc) cluster_code.stop() return x, y
def evolve_cluster_in_galaxy(N, W0, Rinit, tend, timestep, M, R): ###BOOKLISTSTART2### Rgal = 1. | units.kpc Mgal = 1.6e10 | units.MSun alpha = 1.2 galaxy_code = GalacticCenterGravityCode(Rgal, Mgal, alpha) cluster_code = make_king_model_cluster(BHTree, N, W0, M, R, parameters=[("epsilon_squared", (0.01 | units.parsec)**2)]) stars = cluster_code.particles.copy() stars.x += Rinit stars.vy = 0.8*galaxy_code.circular_velocity(Rinit) channel = stars.new_channel_to(cluster_code.particles) channel.copy_attributes(["x","y","z","vx","vy","vz"]) system = bridge(verbose=False) system.add_system(cluster_code, (galaxy_code,)) times = quantities.arange(0|units.Myr, tend, timestep) for i,t in enumerate(times): system.evolve_model(t,timestep=timestep) x = system.particles.x.value_in(units.parsec) y = system.particles.y.value_in(units.parsec) cluster_code.stop() ###BOOKLISTSTOP2### return x, y
def evolve_cluster_in_galaxy(N, W0, Rinit, tend, timestep, M, R): galaxy_code = MilkyWay_galaxy() converter = nbody_system.nbody_to_si(M, R) cluster_code = drift_without_gravity(convert_nbody=converter) bodies = new_king_model(N, W0, convert_nbody=converter) cluster_code.particles.add_particles(bodies) stars = cluster_code.particles.copy() stars.x += Rinit stars.vy = 0.8*galaxy_code.circular_velocity(Rinit) channel = stars.new_channel_to(cluster_code.particles) channel.copy_attributes(["x","y","z","vx","vy","vz"]) system = bridge(verbose=False) system.add_system(cluster_code, (galaxy_code,)) times = quantities.arange(0|units.Myr, tend, 100*timestep) for i,t in enumerate(times): print "Time=", t.in_(units.Myr) system.evolve_model(t, timestep=timestep) x = system.particles.x.value_in(units.kpc) y = system.particles.y.value_in(units.kpc) cluster_code.stop() return x, y
def gravity_hydro_bridge(gravity, hydro, t_end, dt): model_time = 0 | units.yr filename = "gravhydro.hdf5" #write_set_to_file(stars.savepoint(model_time), filename, 'amuse') #write_set_to_file(gas, filename, 'amuse') gravhydro = bridge.Bridge(use_threading=False) gravhydro.add_system(gravity, (hydro, )) gravhydro.add_system(hydro, (gravity, )) gravhydro.timestep = 2 * hydro.get_timestep() a_Jup = list() e_Jup = list() disk_size = list() # start evolotuion print 'Start evolving...' times = quantities.arange(0. | units.yr, t_end + dt, dt) while model_time < t_end: stars = gravity.local_particles orbit = orbital_elements_from_binary(stars, G=constants.G) a = orbit[2].value_in(units.AU) e = orbit[3] if model_time.value_in(units.yr) % 50 == 0: print "Time:", model_time.in_(units.yr), \ "ae=", a ,e a_Jup.append(a) e_Jup.append(e) model_time += gravhydro.timestep gravhydro.evolve_model(model_time) gravity.copy_to_framework() hydro.copy_to_framework() sink = hydro.local_particles[0] _ = hydro_sink_particles([sink], hydro.local_particles[1:]) Jupiter = gravity.local_particles[1] Jupiter.mass += sink.mass sink.position = Jupiter.position sink.radius = a * (1 - e) * ( (1.0 | units.MJupiter).value_in(units.MSun) / 3.)**(1. / 3.) | units.au gravity.copy_to_framework() hydro.copy_to_framework() write_set_to_file(stars.savepoint(model_time), filename, 'amuse') write_set_to_file(ism, filename, 'amuse') print "P=", model_time.in_(units.yr), gravity.particles.x.in_(units.au) gravity.stop() hydro.stop() return a_Jup, e_Jup, times
def evolve_cluster(cluster,mCut,dt,tend,mCluster,rCluster,dump=False,dump_dir='data_dump'): if dump: print('Will be saving data in:'+dump_dir) converter=nbody_system.nbody_to_si(mCluster,rCluster) # Splitting particle according to mass_cut low_mass_stars = cluster.select(lambda m: m < mCut,["mass"]) high_mass_stars = cluster.select(lambda m: m >= mCut,["mass"]) # Sanity checks print('Number of low-mass stars:',low_mass_stars.__len__()) print('Number of high-mass stars:',high_mass_stars.__len__()) # Making models and assigning particles code_tree = BHTree(converter) code_direct = ph4(converter) code_tree.particles.add_particles(low_mass_stars) code_direct.particles.add_particles(high_mass_stars) channel_from_code_tree = code_tree.particles.new_channel_to(low_mass_stars) channel_from_code_direct = code_direct.particles.new_channel_to(high_mass_stars) # Making bridge combined_gravity = bridge() combined_gravity.add_system(code_tree,(code_direct,)) combined_gravity.add_system(code_direct,(code_tree,)) combined_gravity.timestep = dt # Making first snapshot #plot_cluster(low_mass_stars,high_mass_stars,'t=0',save=True) # Evolving the model times = quantities.arange(0|units.Myr, tend, dt) mCut_str = str(mCut.value_in(units.MSun)) for i,t in enumerate(times): print "Time=", t.in_(units.Myr) channel_from_code_tree.copy() channel_from_code_direct.copy() combined_gravity.evolve_model(t, timestep=dt) snapshot_name = 't_'+str(t.in_(units.Myr)) plot_cluster(low_mass_stars,high_mass_stars,snapshot_name,save=True) time = str(t.value_in(units.Myr)) if dump: pkl.dump(low_mass_stars, open(dump_dir+'/t'+time+'_m'+mCut_str+'_low_mass.p', 'wb')) pkl.dump(high_mass_stars, open(dump_dir+'/t'+time+'_m'+mCut_str+'_high_mass.p', 'wb')) code_tree.stop() code_direct.stop()
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 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 evolve_cluster(cluster,mCut,dt,tend,mCluster,rCluster): converter=nbody_system.nbody_to_si(mCluster,rCluster) # Splitting particle according to mass_cut low_mass_stars = cluster.select(lambda m: m < mCut,["mass"]) high_mass_stars = cluster.select(lambda m: m >= mCut,["mass"]) # Sanity checks print('dynamical timescale:', cluster.dynamical_timescale().value_in(units.Myr)) print('Number of low-mass stars:',low_mass_stars.__len__()) print('Number of high-mass stars:',high_mass_stars.__len__()) #plot_cluster(low_mass_stars, high_mass_stars) # Making models and assigning particles code_tree = BHTree(converter) code_direct = ph4(converter) code_tree.particles.add_particles(low_mass_stars) code_direct.particles.add_particles(high_mass_stars) channel_from_code_tree = code_tree.particles.new_channel_to(low_mass_stars) channel_from_code_direct = code_direct.particles.new_channel_to(high_mass_stars) # Making bridge combined_gravity = bridge() combined_gravity.add_system(code_tree,(code_direct,)) combined_gravity.add_system(code_direct,(code_tree,)) combined_gravity.timestep = dt # Evolving the model time_series = [] half_mass_radii = [] core_radii = [] times = quantities.arange(0.|units.Myr, tend, dt) for i,t in enumerate(times): print "Time =", t.in_(units.Myr) channel_from_code_tree.copy() channel_from_code_direct.copy() time_series.append(t.value_in(units.Myr)) pos,coreradius,coredens=cluster.densitycentre_coreradius_coredens(converter) lr,mf=cluster.LagrangianRadii(converter) # outputs are radii, mass fractions half_mass_radii.append(lr[5].value_in(units.parsec)) # 5th argument attributes to half-mass radius core_radii.append(coreradius.value_in(units.parsec)) combined_gravity.evolve_model(t, timestep=dt) code_tree.stop() code_direct.stop() # Plotting results #plot_cluster(low_mass_stars, high_mass_stars) # Plotting radii plot_radii(time_series, half_mass_radii, x_label='time(Myr)', y_label='half-mass radius (pc)') plot_radii(time_series, core_radii, x_label='time(Myr)', y_label='core radius (pc)')
def test4(self): x = quantities.arange(0 | units.yr, 10 | units.yr, 1 | units.yr) y = (2.0 | units.km) * (x / (2.0 | units.yr))**2 + (20.0 | units.km) fit = quantities.polyfit(x, y, 2) self.assertEquals(len(fit), 3) self.assertEquals(fit[0].unit, units.km / units.yr**2) fit_values = quantities.polyval(fit, x) self.assertEquals(fit_values.shape, x.shape) self.assertEquals(y.unit, fit_values.unit) self.assertAlmostRelativeEquals(y, fit_values, 1)
def test4(self): x = quantities.arange(0 | units.yr, 10 | units.yr, 1 | units.yr) y = (2.0|units.km) * (x/ (2.0|units.yr))**2 + (20.0|units.km) fit = quantities.polyfit(x, y, 2) self.assertEquals(len(fit), 3) self.assertEquals(fit[0].unit, units.km/units.yr**2) fit_values = quantities.polyval(fit, x) self.assertEquals(fit_values.shape, x.shape) self.assertEquals(y.unit, fit_values.unit) self.assertAlmostRelativeEquals(y, fit_values, 1)
def evolve_cloud_in_galaxy(N, RinitA, RinitB, tend, timestep, MA, RA, MB, RB): Rgal = 1 | units.kpc Mgal = 7.22e9 | units.MSun alpha = 1.2 galaxy_code = GalacticCenterGravityCode(Rgal, Mgal, alpha) cloud_codeA = plummer_model_A(BHTree, N, MA, RA, parameters=[("epsilon_squared", (0.01 | units.parsec)**2)]) cloud_codeB = plummer_model_B(BHTree, N, MB, RB, parameters=[("epsilon_squared", (0.01 | units.parsec)**2)]) cloudA = cloud_codeA.particles.copy() cloudB = cloud_codeA.particles.copy() cloudA.x += RinitA cloudB.x += RinitB cloudA.vy = 0.01 * galaxy_code.circular_velocity(RinitA) cloudB.vy = 0.05 * galaxy_code.circular_velocity(RinitB) channelA = cloudA.new_channel_to(cloud_codeA.particles) channelA.copy_attributes(["x", "y", "z", "vx", "vy", "vz"]) channelB = cloudB.new_channel_to(cloud_codeB.particles) channelB.copy_attributes(["x", "y", "z", "vx", "vy", "vz"]) system = bridge(verbose=False) system.add_system(cloud_codeA, (galaxy_code, )) system.add_system(cloud_codeB, (galaxy_code, )) times = quantities.arange(0 | units.Myr, tend, timestep) for i, t in enumerate(times): system.evolve_model(t, timestep=timestep) x = system.particles.x.value_in(units.parsec) y = system.particles.y.value_in(units.parsec) cloud_codeA.stop() cloud_codeB.stop() return x, y
def evolve_cluster_in_galaxy(N, pot, Rinit, Vinit, tstart, tend, timestep, M, R): galaxy_code = galpy_profile(pot, tgalpy=tstart) cluster_code = setup_cluster(BHTree, N, Mcluster, Rcluster, Rinit, Vinit, parameters=[("epsilon_squared", (0.1 | units.parsec)**2), ("timestep", 0.1 | units.Myr), ("opening_angle", 0.6)]) stars = cluster_code.particles.copy() particles = [] channel_from_stars_to_cluster_code = stars.new_channel_to( cluster_code.particles, attributes=["x", "y", "z", "vx", "vy", "vz"]) channel_from_cluster_code_to_stars = cluster_code.particles.new_channel_to( stars, attributes=["x", "y", "z", "vx", "vy", "vz"]) system = bridge(verbose=False) system.add_system(cluster_code, (galaxy_code, )) system.add_system(galaxy_code) times = quantities.arange(0 | units.Myr, tend - tstart, timestep) for i, t in enumerate(times): if (t.value_in(units.Myr) % 10 < timestep.value_in(units.Myr)): print(t) particles.append([ cluster_code.particles.position, cluster_code.particles.velocity ]) system.evolve_model(t, timestep=timestep) particles.append( [cluster_code.particles.position, cluster_code.particles.velocity]) cluster_code.stop() return particles
def evolve_sun_jupiter(particles, tend, dt): SunJupiter = Particles() SunJupiter.add_particle(particles[0]) SunJupiter.add_particle(particles[1]) converter = nbody_system.nbody_to_si(particles.mass.sum(), particles[1].position.length()) gravity = ph4(converter) gravity.particles.add_particles(particles) channel_from_to_SunJupiter = gravity.particles.new_channel_to(SunJupiter) semi_major_axis = [] eccentricity = [] times = quantities.arange(0 | units.yr, tend, dt) for i, t in enumerate(times): print "Time=", t.in_(units.yr) channel_from_to_SunJupiter.copy() orbital_elements = orbital_elements_from_binary(SunJupiter, G=constants.G) a = orbital_elements[2] e = orbital_elements[3] semi_major_axis.append(a.value_in(units.AU)) eccentricity.append(e) gravity.evolve_model(t, timestep=dt) # Plot fig = plt.figure(figsize=(8, 6)) ax1 = fig.add_subplot(211, xlabel='time(yr)', ylabel='semi major axis (AU)') ax1.plot(times.value_in(units.yr), semi_major_axis) ax2 = fig.add_subplot(212, xlabel='time(yr)', ylabel='eccentriity') ax2.plot(times.value_in(units.yr), eccentricity) plt.show() gravity.stop()
def evolve_sun_jupiter(particles, tend, dt): SunJupiter = Particles() SunJupiter.add_particle(particles[0]) SunJupiter.add_particle(particles[1]) converter=nbody_system.nbody_to_si(particles.mass.sum(), particles[1].position.length()) gravity = ph4(converter) gravity.particles.add_particles(particles) channel_from_to_SunJupiter = gravity.particles.new_channel_to(SunJupiter) semi_major_axis = list() eccentricity = list() times = quantities.arange(0|units.yr, tend+dt, dt) for i,t in enumerate(times): #print "Time =", t.in_(units.yr) channel_from_to_SunJupiter.copy() orbital_elements = orbital_elements_from_binary(SunJupiter, G=constants.G) a = orbital_elements[2] e = orbital_elements[3] semi_major_axis.append(a.value_in(units.AU)) eccentricity.append(e) gravity.evolve_model(t, timestep=dt) gravity.stop() # save the data: times, semi_major_axis and eccentricity of Jupiter's orbit t_a_e = np.column_stack((times.value_in(units.yr), semi_major_axis, eccentricity)) np.savetxt('t_a_e.txt', t_a_e, delimiter=',') # make plots fig = plt.figure(figsize = (8, 6)) ax1 = fig.add_subplot(211, xlabel = 'time(yr)', ylabel = 'semi major axis (AU)') ax1.plot(times.value_in(units.yr), semi_major_axis) ax2 = fig.add_subplot(212, xlabel = 'time(yr)', ylabel = 'eccentriity') ax2.plot(times.value_in(units.yr), eccentricity) plt.show()
def evolve(cluster, cloud, t_end, dt_bridge, dt_diag): converter = nbody_system.nbody_to_si(1. | units.MSun, 1. | units.parsec) # Initialising the direct N-body integrator print('Setting up the gravity code and the hydro code...') gravity = ph4(converter) gravity.particles.add_particles(cluster) # Initialising the hydro code sph = Fi(converter, mode="openmp") sph.gas_particles.add_particles(cloud) #sph.parameters.use_hydro_flag = True #sph.parameters.radiation_flag = False #sph.parameters.gamma = 1 #sph.parameters.isothermal_flag = True #sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = dt_diag #sph.parameters.verbosity = 0 #sph.parameters.eps_is_h_flag = False # h_smooth is constant #eps = 0.1 | units.parsec #sph.parameters.gas_epsilon = eps #sph.parameters.sph_h_const = eps #cloud.h_smooth= eps print("cloud:", sph.gas_particles) plt.scatter( np.log10(sph.gas_particles.density.value_in(units.g / units.cm**3)), sph.gas_particles.pressure.value_in(units.kg / units.m / units.s**2), s=10) plt.show() # Building a bridge between hydro and grav print('Bridging...') grav_sph = bridge.Bridge(use_threading=False) grav_sph.add_system(gravity, (sph, )) grav_sph.add_system(sph, (gravity, )) grav_sph.timestep = dt_bridge # Setting up channels from code to cloud and cluster channel_from_grav_to_cluster = gravity.particles.new_channel_to(cluster) channel_from_sph_to_cloud = sph.gas_particles.new_channel_to(cloud) # Initializing 90 percent lagrangian radius lr9 = [] lr9.append(L9_radius(cloud, converter)) # Evolving print('Start evolving the molecular cloud...') times = quantities.arange(0. | units.Myr, t_end, dt_diag) for i, t in enumerate(times): print(t.in_(units.Myr)) grav_sph.evolve_model(t, dt_diag) channel_from_grav_to_cluster.copy() channel_from_sph_to_cloud.copy() plot_cloud_cluster(cluster, sph, title='{0}'.format(float(t.value_in(units.Myr))),\ L=400, vrange=[-5,1]) lr9.append(L9_radius(cloud, converter)) #print("cloud:", sph.gas_particles) #xx #plt.scatter(np.log10(sph.gas_particles.density.value_in(units.g/units.cm**3)), # sph.gas_particles.pressure.value_in(units.kg/units.m/units.s**2), s=10) plt.show() gravity.stop() sph.stop() return lr9
def gravity_hydro_bridge(gravity, hydro, sink, local_particles, Rmin, t_end=1000. | units.yr, dt=10. | units.yr): Sun_and_Jupiter, disk_gas = local_particles Mstar = 1.0 | units.MSun print 'Bridging...' # Build up the bridge between gravity and hydrodynamics grav_hydro = bridge.Bridge(use_threading=False) grav_hydro.add_system(gravity, (hydro, )) grav_hydro.add_system(hydro, (gravity, )) grav_hydro.timestep = dt # Set up channels for updating the particles channel_from_grav = gravity.particles.new_channel_to(Sun_and_Jupiter) channel_from_hydro = hydro.gas_particles.new_channel_to(disk_gas) channel_to_grav = Sun_and_Jupiter.new_channel_to(gravity.particles) channel_to_hydro = disk_gas.new_channel_to(hydro.gas_particles) # Preparing lists for data-recording a_Jup = [] e_Jup = [] disk_size = [] accreted_mass = [] accreted_mass.append((sink.mass).value_in(units.MJupiter)[0]) sink0_mass = 0 | units.MJupiter # Start evolution print 'Start evolving...' times = quantities.arange(0. | units.yr, t_end + 1 * dt, dt) model_time = 0.0 | units.yr while model_time <= t_end: # Save the data for plots orbit = orbital_elements_from_binary(Sun_and_Jupiter, G=constants.G) a = orbit[2].value_in(units.AU) e = orbit[3] lr9 = return_L9_radius(disk_gas, Mstar, Rmin | units.AU) a_Jup.append(a) e_Jup.append(e) disk_size.append(lr9) am = (sink.mass[0]).value_in(units.MJupiter) accreted_mass.append(am) # Plotting system print 'Time = %.1f yr:'%model_time.value_in(units.yr), \ 'a = %.2f au, e = %.2f,'%(a, e), \ 'disk size = %.2f au'%lr9 plot_map(hydro, Sun_and_Jupiter, '{0}'.format(int(model_time.value_in(units.yr))), show=False) # Evolve the bridge system for one step model_time += dt grav_hydro.evolve_model(model_time) channel_from_grav.copy() channel_from_hydro.copy() # Calculating accreted mass in new position Jupiter = gravity.particles[0] sink.position = Jupiter.position sink.radius = Hill_radius(a, e, Sun_and_Jupiter) | units.AU removed_particles = hydro_sink_particles(sink, disk_gas) Jupiter.mass += sink.mass - sink0_mass sink0_mass = sink.mass.copy() channel_to_grav.copy() channel_to_hydro.copy() gravity.stop() hydro.stop() return a_Jup, e_Jup, disk_size, times, accreted_mass
def test1(self): array = quantities.arange(0 | units.kg, 10 | units.kg, 1 | units.kg) self.assertEquals(len(array), 10) self.assertAlmostRelativeEquals(array, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | units.kg)
def evolve(cluster,cloud, converter_grav,converter_sph, t_end, dt_sph, dt_diag,\ sink=True, merge=False): with open(printout_file, 'a') as pf: pf.write('Setting up the gravity code and the hydro code...\n') '''# Initialising the direct N-body integrator gravity = ph4(converter_grav) gravity.particles.add_particles(cluster)''' # Initialising the hydro code sph = Fi(converter_sph, mode="openmp") sph.gas_particles.add_particles(cloud) sph.dm_particles.add_particles(cluster) sph.parameters.radiation_flag = False #sph.parameters.isothermal_flag = True #sph.parameters.integrate_entropy_flag = False #should we consider isothermal process or adiabatic one? sph.parameters.timestep = dt_sph #sph.parameters.eps_is_h_flag = False # h_smooth is constant #eps = 0.1 | units.parsec #sph.parameters.gas_epsilon = eps #sph.parameters.sph_h_const = eps #cloud.h_smooth= eps '''# Building a bridge between hydro and grav with open(printout_file, 'a') as pf: pf.write('Bridging...\n') grav_sph = bridge.Bridge(use_threading=False) grav_sph.add_system(gravity, (sph,)) grav_sph.add_system(sph, (gravity,)) grav_sph.timestep = dt_bridge''' # Setting up channels from code to cloud and cluster #channel_from_grav_to_cluster = gravity.particles.new_channel_to(cluster) channel_from_sph_to_cloud = sph.gas_particles.new_channel_to(cloud) channel_from_sph_to_cluster = sph.dm_particles.new_channel_to(cluster) # consider star formation if sink == True: with open(printout_file, 'a') as pf: pf.write('[Star formation is considered.]\n') stars = Particles(0) sph.dm_particles.add_particles(stars) density_threshold = Jeans_density(M=sph.gas_particles.mass.max()) sph.parameters.stopping_condition_maximum_density = density_threshold density_limit_detection = sph.stopping_conditions.density_limit_detection density_limit_detection.enable() if merge == True: merge_radius = 1e-4 | units.parsec # 1 pc = 206265 AU with open(printout_file, 'a') as pf: pf.write('[Star merging is considered.]\n') # Initialize data lists (Lagrangian radii and relative total energy) lr_cloud_list = [Lagrange_radii(cloud, converter_sph)] lr_cluster_list = [Lagrange_radii(cluster, converter_grav)] E0_cloud = get_energy(cloud) Etot0_cloud = E0_cloud[-1] E_cloud_list = [E0_cloud / Etot0_cloud] E0_cluster = get_energy(cluster) Etot0_cluster = E0_cluster[-1] E_cluster_list = [E0_cluster / Etot0_cluster] n_formed_star = [0] # Start Evolving! # unify the unit of times unit_time = units.Myr t_end = t_end.in_(unit_time) dt_diag = dt_diag.in_(unit_time) dt_sph = dt_sph.in_(unit_time) times = quantities.arange(0. | unit_time, t_end + dt_diag, dt_diag) with open(printout_file, 'a') as pf: pf.write('\nStart evolving the molecular cloud...\n') pf.write( f'End time = {t_end}; Diagnostic timestep = {dt_diag}; sph code timestep = {dt_sph}.\n' ) for i, t in enumerate(times): with open(printout_file, 'a') as pf: pf.write(f'---------- Time = {t.in_(units.Myr)} ----------\n') # calculate the dynamical(dyn), half-mass relaxation(rh), and free-fall(ff) timescales # of both the cloud and the cluster systems t_dyn_cloud, t_rh_cloud, t_ff_cloud = timescale(cloud, unit_time) t_dyn_cluster, t_rh_cluster, t_ff_cluster = timescale( cluster, unit_time) all_timescales = [ t_dyn_cloud, t_rh_cloud, t_ff_cloud, t_dyn_cluster, t_rh_cluster, t_ff_cluster ] | unit_time # check if the bridge timestep should be reduced if all_timescales.amax() < 10 * dt_sph: dt_sph_old = dt_sph dt_sph = all_timescales.amax() / 10. with open(printout_file, 'a') as pf: pf.write( f'Change the bridge timestep from {dt_sph_old} to {dt_sph}.\n' ) if sink == True: # make sure at this time, elements in 'stars' and 'sph.gas_particles' are the same resolve_sinks(sph, stars, cloud, density_threshold, t) # evolve for one diagnostic timestep #grav_sph.evolve_model(t, timestep=dt_bridge) sph.evolve_model(t, timestep=dt_sph) #channel_from_grav_to_cluster.copy() channel_from_sph_to_cloud.copy() channel_from_sph_to_cluster.copy() if len(stars) > 0: newstars = cluster.select_array( lambda birth_age: birth_age >= 0. | unit_time, ["birth_age"]) cluster.remove_particles(newstars) # merge two stars if they are too close to each other (distance < merge_radius) # typically we don't consider merging event since it is very rare given a reasonable merge radius if merge == True: merge_stars(sph, stars, merge_radius) with open(printout_file, 'a') as pf: pf.write('Number of stars in `cluster`= %d; in `stars` = %d; in `sph.dm_particles`= %d.\n'\ %(len(cluster), len(stars), len(sph.dm_particles))) # make snapshots plot_cloud_cluster(cluster, sph, stars, title='{0}'.format(float(t.value_in(units.Myr))),\ vrange=[-5,3]) # save data (energy will be added afterwards) lr_cloud = Lagrange_radii(cloud, converter_sph) lr_cloud_list.append(lr_cloud) lr_cluster = Lagrange_radii(cluster, converter_grav) lr_cluster_list.append(lr_cluster) E_cloud = get_energy(cloud, norm=Etot0_cloud) E_cloud_list.append(E_cloud) E_cluster = get_energy(cluster, norm=Etot0_cluster) E_cluster_list.append(E_cluster) n_formed_star.append(len(stars)) # save data instantaneously lr_data = np.concatenate( ([t.value_in(unit_time)], lr_cloud, lr_cluster)) E_data = np.concatenate(([t.value_in(unit_time)], E_cloud, E_cluster)) with open('lr_data.txt', 'a') as f_lr_data: f_lr_data.write(','.join(str(x) for x in lr_data) + '\n') with open('E_data.txt', 'a') as f_E_data: f_E_data.write(','.join(str(x) for x in E_data) + '\n') with open('formed_star_data.txt', 'a') as f_fs_data: f_fs_data.write('%f,%d\n' % (t.value_in(unit_time), len(stars))) with open(printout_file, 'a') as pf: pf.write(f'Finished.\n') #gravity.stop() sph.stop() return times.value_in( unit_time ), n_formed_star, lr_cloud_list, lr_cluster_list, E_cloud_list, E_cluster_list
def gravity_hydro_bridge(gravity, hydro, local_particles, Rmin, t_end=1000. | units.yr, dt=10. | units.yr): Sun_and_Jupiter, disk_gas = local_particles Mstar = gravity.particles[1].mass.in_(units.MSun) print 'Bridging...' # build up the bridge between gravity and hydrodynamics grav_hydro = bridge.Bridge(use_threading=False) grav_hydro.add_system(gravity, (hydro, )) grav_hydro.add_system(hydro, (gravity, )) #grav_hydro.timestep = dt # set up channels for updating the particles channel_from_grav = gravity.particles.new_channel_to(Sun_and_Jupiter) channel_from_hydro = hydro.gas_particles.new_channel_to(disk_gas) a_Jup = list() e_Jup = list() disk_size = list() # start evolotuion print 'Start evolving...' times = quantities.arange(0. | units.yr, t_end + 1 * dt, 2 * dt) model_time = 0.0 | units.yr while model_time <= t_end: # save the data for plots orbit = orbital_elements_from_binary(Sun_and_Jupiter, G=constants.G) a = orbit[2].value_in(units.AU) e = orbit[3] lr9 = return_L9_radius(disk_gas, Mstar, Rmin | units.AU) a_Jup.append(a) e_Jup.append(e) disk_size.append(lr9) if model_time.value_in(units.yr) % 50 == 0: print 'Time = %.1f yr:'%model_time.value_in(units.yr), \ 'a = %.2f au, e = %.2f,'%(a, e), \ 'disk size = %.2f au'%lr9 # evolve the bridge system for one step model_time += dt grav_hydro.evolve_model(model_time, timestep=2 * dt) channel_from_grav.copy() channel_from_hydro.copy() # add the 'sinked' mass to Jupiter & keep the sink particle along with Jupiter sink = hydro.particles[0] _ = hydro_sink_particles([sink], disk_gas) Jupiter = gravity.particles[1] Jupiter.mass += sink.mass sink.position = Jupiter.position sink.radius = a * (1 - e) * ( (1.0 | units.MJupiter).value_in(units.MSun) / 3.)**(1. / 3.) | units.au channel_from_grav.copy() channel_from_hydro.copy() gravity.stop() hydro.stop() return a_Jup, e_Jup, disk_size, times
def evolve(Sun_Jupiter, disk_gas, sink, Pstar, dt_gravity, dt_sph, dt_diagnostic, dt_bridge, tend): Sun = Sun_Jupiter[0] Jupiter = Sun_Jupiter[1] # Initialising the SPH code sph_converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) sph = Fi(sph_converter, mode="openmp") sph.gas_particles.add_particles(disk_gas) sph.dm_particles.add_particle(Sun) sph.dm_particles.add_particle(Jupiter) sph.dm_particles.add_particle(Pstar) # Set up channels for updating the particles sph_to_disk = sph.gas_particles.new_channel_to(disk_gas) sph_to_Sun_Jupiter = sph.dm_particles.new_channel_to(Sun_Jupiter) sph_to_Pstar = sph.dm_particles.new_channel_to(Pstar) Sun_Jupiter_to_sph = Sun_Jupiter.new_channel_to(sph.dm_particles) disk_to_sph = disk_gas.new_channel_to(sph.gas_particles) Pstar_to_sph = Pstar.new_channel_to(sph.dm_particles) # Preparing lists for data-recording a_Jup = [] e_Jup = [] disk_size = [] accreted_mass = [] accreted_mass.append((sink.mass).value_in(units.MJupiter)[0]) sink0_mass = 0 | units.MJupiter # Start evolution print 'Start evolving...' times = quantities.arange(0. | units.yr, tend, dt_diagnostic) for i, t in enumerate(times): # Save the data for plots orbit = orbital_elements_from_binary(Sun_Jupiter, G=constants.G) a = orbit[2].value_in(units.AU) e = orbit[3] lr9 = return_L9_radius(disk_gas, Sun_Jupiter[0].mass, Rmin) a_Jup.append(a) e_Jup.append(e) disk_size.append(lr9) # Plotting system print 'Time = %.1f yr:'%t.value_in(units.yr), \ 'a = %.2f au, e = %.2f,'%(a, e), \ 'disk size = %.2f au'%lr9 plot_map(sph, Sun_Jupiter, Pstar, 'distribution_plot_passing_star_full_hydro_4k/{0}.png'.format( int(t.value_in(units.yr))), show=False) # Evolve the bridge system for one step sph.evolve_model(t, dt_diagnostic) sph_to_disk.copy() sph_to_Sun_Jupiter.copy() sph_to_Pstar.copy() # Calculating accreted mass in new position sink.position = Jupiter.position sink.radius = Hill_radius(a, e, Sun_Jupiter) | units.AU removed_particles = hydro_sink_particles(sink, disk_gas) Jupiter.mass += sink.mass - sink0_mass accreted_mass.append((sink.mass).value_in(units.MJupiter)[0]) sink0_mass = sink.mass.copy() Sun_Jupiter_to_sph.copy() disk_to_sph.copy() Sun_Jupiter_to_sph.copy() Pstar_to_sph.copy() sph.stop() return times, a_Jup, e_Jup, disk_size, accreted_mass
def evolve(cluster,cloud, converter_grav,converter_sph, t_end, dt_sph, dt_diag,\ sink=True, merge=False): with open(printout_file, 'a') as pf: pf.write('Setting up the hydro code...\n') '''# Initialising the direct N-body integrator gravity = ph4(converter_grav) gravity.particles.add_particles(cluster)''' # Initialising the hydro code sph = Fi(converter_sph, mode="openmp") sph.gas_particles.add_particles(cloud) sph.dm_particles.add_particles(cluster) sph.parameters.radiation_flag = False #sph.parameters.isothermal_flag = True #sph.parameters.integrate_entropy_flag = False #should we consider isothermal process or adiabatic one? sph.parameters.timestep = dt_sph #sph.parameters.eps_is_h_flag = False # h_smooth is constant #eps = 0.1 | units.parsec #sph.parameters.gas_epsilon = eps #sph.parameters.sph_h_const = eps #cloud.h_smooth= eps '''# Building a bridge between hydro and gravity with open(printout_file, 'a') as pf: pf.write('Bridging...\n') grav_sph = bridge.Bridge(use_threading=False) grav_sph.add_system(gravity, (sph,)) grav_sph.add_system(sph, (gravity,)) grav_sph.timestep = dt_bridge''' # Setting up channels from code to cloud and cluster #channel_from_grav_to_cluster = gravity.particles.new_channel_to(cluster) channel_from_sph_to_cloud = sph.gas_particles.new_channel_to(cloud) channel_from_sph_to_cluster = sph.dm_particles.new_channel_to(cluster) # considers star formation if sink == True: with open(printout_file, 'a') as pf: pf.write('[Star formation is considered.]\n') # `stars` is initialized as a particle set for potential new stars forming in the cloud stars = Particles(0) sph.dm_particles.add_particles(stars) # set a density threshold (Jeans density) in the sph code density_threshold = Jeans_density(M=sph.gas_particles.mass.max()) with open('cloud_data.txt', 'a') as f_cd_data: f_cd_data.write('# Jeans density of the cloud = %.5e kg/m^3\n' % density_threshold.value_in(units.kg / units.m**3)) sph.parameters.stopping_condition_maximum_density = density_threshold density_limit_detection = sph.stopping_conditions.density_limit_detection density_limit_detection.enable() # considers star merging if merge == True: merge_radius = 1e-4 | units.parsec # 1 pc = 206265 AU with open(printout_file, 'a') as pf: pf.write('[Star merging is considered.]\n') # Initializing data lists lr_cloud_list = [Lagrange_radii(cloud, converter_sph)] lr_cluster_list = [Lagrange_radii(cluster, converter_grav)] E_norm = 1e42 | (units.kg * units.m**2 / units.s**2) E0_cloud = get_energy(cloud, E_norm) #Etot0_cloud = E0_cloud[-1] E_cloud_list = [E0_cloud] E0_cluster = get_energy(cluster) #Etot0_cluster = E0_cluster[-1] E_cluster_list = [E0_cluster] n_formed_star = [0] max_gas_density = [ sph.gas_particles.density.max().value_in(units.kg / units.m**3) ] # unify the unit of times unit_time = units.Myr t_end = t_end.in_(unit_time) dt_diag = dt_diag.in_(unit_time) dt_sph = dt_sph.in_(unit_time) times = quantities.arange(0. | unit_time, t_end + dt_diag, dt_diag) with open(printout_file, 'a') as pf: pf.write('\nStart evolving the molecular cloud...\n') pf.write( f'End time = {t_end}; Diagnostic timestep = {dt_diag}; Initial SPH timestep = {dt_sph}.\n' ) # Real start for evolution! for i, t in enumerate(times): with open(printout_file, 'a') as pf: pf.write(f'---------- Time = {t.in_(units.Myr)} ----------\n') # calculates the dynamical(dyn), half-mass relaxation(rh), and free-fall(ff) timescales # for both the cloud and the cluster t_dyn_cloud, t_rh_cloud, t_ff_cloud = timescale(cloud, unit_time) t_dyn_cluster, t_rh_cluster, t_ff_cluster = timescale( cluster, unit_time) all_timescales = [ t_dyn_cloud, t_rh_cloud, t_ff_cloud, t_dyn_cluster, t_rh_cluster, t_ff_cluster ] | unit_time shortest_ts = all_timescales.amin() dt_sph = np.round( (shortest_ts / 10.).value_in(unit_time), 2) | unit_time with open(printout_file, 'a') as pf: pf.write( 'Current evolve timestep: %.2f Myr; Shortest timescale: %.2f Myr.\n' % (dt_sph.value_in(unit_time), shortest_ts.value_in(unit_time))) # considers star information # (make sure that at this time, elements in 'stars' and 'sph.gas_particles' are the same) if sink == True: resolve_sinks(sph, stars, cloud, density_threshold, t) # evolve for one diagnostic timestep #grav_sph.evolve_model(t, timestep=dt_bridge) sph.evolve_model(t, timestep=dt_sph) #channel_from_grav_to_cluster.copy() channel_from_sph_to_cloud.copy() channel_from_sph_to_cluster.copy() # remove newly formed stars from `cluster` after using channels # (since both `stars` and `cluster` are added as dm_particles in sph, we have to distinguish them by `birth_age`) if len(stars) > 0: newstars = cluster.select_array( lambda birth_age: birth_age >= 0. | unit_time, ["birth_age"]) cluster.remove_particles(newstars) # merge two stars if they are too close to each other (distance < merge_radius) # typically we don't consider merging event since it is very rare given a reasonable merge radius if merge == True: merge_stars(sph, stars, merge_radius) # sanity check with open(printout_file, 'a') as pf: pf.write('Number of stars in `cluster`= %d; in `stars` = %d; in `sph.dm_particles`= %d.\n'\ %(len(cluster), len(stars), len(sph.dm_particles))) # make snapshots plot_cloud_cluster(cluster, sph, stars, title='{0}'.format(float(t.value_in(units.Myr))),\ vrange=[-5,3]) # save data lr_cloud = Lagrange_radii(cloud, converter_sph) lr_cloud_list.append(lr_cloud) lr_cluster = Lagrange_radii(cluster, converter_grav) lr_cluster_list.append(lr_cluster) E_cloud = get_energy(cloud, norm=E_norm) E_cloud_list.append(E_cloud) E_cluster = get_energy(cluster, norm=E_norm) E_cluster_list.append(E_cluster) n_formed_star.append(len(stars)) max_gas_density.append(sph.gas_particles.density.max().value_in( units.kg / units.m**3)) # save data instantaneously lr_data = np.concatenate( ([t.value_in(unit_time)], lr_cloud, lr_cluster)) E_data = np.concatenate(([t.value_in(unit_time)], E_cloud, E_cluster)) with open('lr_data.txt', 'a') as f_lr_data: f_lr_data.write(','.join(str(x) for x in lr_data) + '\n') with open('E_data.txt', 'a') as f_E_data: f_E_data.write(','.join(str(x) for x in E_data) + '\n') with open('cloud_data.txt', 'a') as f_cd_data: f_cd_data.write('%.2f,%d,%.5e\n'%(t.value_in(unit_time), len(stars),\ sph.gas_particles.density.max().value_in(units.kg/units.m**3))) with open(printout_file, 'a') as pf: pf.write(f'Finished.\n') #gravity.stop() sph.stop() return times.value_in(unit_time), n_formed_star, max_gas_density,\ lr_cloud_list, lr_cluster_list, E_cloud_list, E_cluster_list
def evolve(Sun_Jupiter, disk_gas, sink, Pstar, dt_gravity, dt_sph, dt_diagnostic, dt_bridge, tend): Sun = Sun_Jupiter[0] Jupiter = Sun_Jupiter[1] # Initialising the direct N-body integrator #gravity_converter = nbody_system.nbody_to_si(Jupiter.mass, Jupiter.position.length()) gravity_converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) gravity = ph4(gravity_converter) gravity.particles.add_particle(Jupiter) #gravity.particles.add_particle(Pstar) gravity.timestep = dt_gravity # Initialising the SPH code sph_converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) #sph_converter = nbody_system.nbody_to_si(Pstar.mass.sum(), Rmin) sph = Fi(sph_converter, mode="openmp") sph.gas_particles.add_particles(disk_gas) sph.dm_particles.add_particle(Sun) #sph.dm_ sph.dm_particles.add_particle(Pstar) sph.parameters.timestep = dt_sph print 'Bridging...' # Build up the bridge between gravity and hydrodynamics grav_sph = bridge.Bridge(use_threading=False) grav_sph.add_system(gravity, (sph, )) grav_sph.add_system(sph, (gravity, )) grav_sph.timestep = dt_bridge # Set up channels for updating the particles gravity_to_Jupiter = gravity.particles.new_channel_to(Sun_Jupiter) sph_to_disk = sph.gas_particles.new_channel_to(disk_gas) sph_to_Sun = sph.dm_particles.new_channel_to(Sun_Jupiter) sph_to_Pstar = sph.dm_particles.new_channel_to(Pstar) Jupiter_to_gravity = Sun_Jupiter.new_channel_to(gravity.particles) disk_to_sph = disk_gas.new_channel_to(sph.gas_particles) Sun_to_sph = Sun_Jupiter.new_channel_to(sph.dm_particles) Pstar_to_sph = Pstar.new_channel_to(sph.dm_particles) ''' gravity_to_Jupiter = gravity.particles.new_channel_to(Sun_Jupiter) gravity_to_Pstar = gravity.particles.new_channel_to(Pstar) sph_to_disk = sph.gas_particles.new_channel_to(disk_gas) sph_to_Sun = sph.dm_particles.new_channel_to(Sun_Jupiter) Jupiter_to_gravity = Sun_Jupiter.new_channel_to(gravity.particles) Pstar_to_gravity = Pstar.new_channel_to(gravity.particles) disk_to_sph = disk_gas.new_channel_to(sph.gas_particles) Sun_to_sph = Sun_Jupiter.new_channel_to(sph.dm_particles) ''' # Sanity checks: print('Sanity checks:') #print('Star coordinates (AU)',Pstar.x.value_in(units.AU), # Pstar.y.value_in(units.AU), # Pstar.z.value_in(units.AU)) print('Disk particle map saved to: initial_check_disk.png') #plot_map(sph, Sun_Jupiter, Pstar,'initial_check_disk.png',show=True) a_Jup = [] e_Jup = [] disk_size = [] accreted_mass = [] # start evolotuion print 'Start evolving...' times = quantities.arange(0. | units.yr, tend, dt_diagnostic) for i, t in enumerate(times): # Save the data for plots orbit = orbital_elements_from_binary(Sun_Jupiter, G=constants.G) a = orbit[2].value_in(units.AU) e = orbit[3] lr9 = return_L9_radius(disk_gas, Sun_Jupiter[0].mass, Rmin) a_Jup.append(a) e_Jup.append(e) disk_size.append(lr9) accreted_mass.append((sink.mass).value_in(units.MJupiter)[0]) # Plotting #print('Star coordinates (AU)',Pstar.x.value_in(units.AU), # Pstar.y.value_in(units.AU), # Pstar.z.value_in(units.AU)) print 'Time = %.1f yr:'%t.value_in(units.yr), \ 'a = %.2f au, e = %.2f,'%(a, e), \ 'disk size = %.2f au'%lr9 plot_map(sph, Sun_Jupiter, Pstar, 'distribution_plot_passing_star_grav/{0}.png'.format( int(t.value_in(units.yr))), show=False) # Evolve the bridge system for one step grav_sph.evolve_model(t, dt_diagnostic) gravity_to_Jupiter.copy() sph_to_disk.copy() sph_to_Sun.copy() sph_to_Pstar.copy() # Add the 'sinked' mass to Jupiter & keep the sink particle along with Jupiter removed_particles = hydro_sink_particles(sink, disk_gas) Jupiter = gravity.particles[0] Jupiter.mass += sink.mass sink.position = Jupiter.position sink.radius = Hill_radius(a, e, Sun_Jupiter) | units.AU Jupiter_to_gravity.copy() disk_to_sph.copy() Sun_to_sph.copy() Pstar_to_sph.copy() gravity.stop() sph.stop() return t, a_Jup, e_Jup, disk_size, accreted_mass
def evolve_cluster(cluster,mCut,dt,tend,mCluster,rCluster): print 'Start evolving the cluster with mCut =', mCut # timing t1 = time() converter=nbody_system.nbody_to_si(mCluster,rCluster) # split particle according to mass_cut low_mass_stars = cluster.select(lambda m: m < mCut,["mass"]) high_mass_stars = cluster.select(lambda m: m >= mCut,["mass"]) print 'Number of low-mass stars:', low_mass_stars.__len__() print 'Number of high-mass stars:', high_mass_stars.__len__() # make models and assigning particles code_tree = BHTree(converter) code_direct = ph4(converter) code_tree.particles.add_particles(low_mass_stars) code_direct.particles.add_particles(high_mass_stars) channel_from_code_tree = code_tree.particles.new_channel_to(low_mass_stars) channel_from_code_direct = code_direct.particles.new_channel_to(high_mass_stars) # make bridge combined_gravity = bridge() combined_gravity.add_system(code_tree,(code_direct,)) combined_gravity.add_system(code_direct,(code_tree,)) combined_gravity.timestep = dt # the initial total energy E0 = combined_gravity.potential_energy + combined_gravity.kinetic_energy # evolve the model times = quantities.arange(0.|units.Myr, tend+dt, dt) n_step = len(times) dE = np.empty(n_step) Qs = np.empty(n_step) for i,t in enumerate(times): if t.value_in(units.Myr)%1 == 0: print "Time =", t.in_(units.Myr) channel_from_code_tree.copy() channel_from_code_direct.copy() combined_gravity.evolve_model(t, timestep=dt) U = cluster.potential_energy() T = cluster.kinetic_energy() Et = U + T dE[i] = np.abs((E0-Et)/E0) Qs[i] = -T / U code_tree.stop() code_direct.stop() t2 = time() print 'Finished. Time cost: %.2f s'%(t2-t1) output_filename = 'ee_q_%.1f.txt'%mCut.value_in(units.MSun) with open(output_filename, 'w'): np.savetxt(output_filename, np.append(dE,Qs).reshape(2,n_step).transpose()) print 'Saved the data of energy error and virial ratios in', output_filename # plot energy plot_energy_error(times.value_in(units.Myr), dE, Qs, mCut) return dE[-1], Qs[-1], t2-t1
def evolve(cluster,cloud, converter_grav,converter_sph, t_end, dt_bridge, dt_diag,\ sink=False): with open('print_out.txt', 'a') as pf: pf.write('Setting up the gravity code and the hydro code...\n') converter = nbody_system.nbody_to_si(1. | units.MSun, 1. | units.parsec) # Initialising the direct N-body integrator #gravity = ph4(converter_grav) #gravity.particles.add_particles(cluster) # Initialising the hydro code sph = Fi(converter, mode="openmp") #sph.gas_particles.add_particles(cloud) sph.dm_particles.add_particles(cluster) #sph.parameters.use_hydro_flag = True sph.parameters.radiation_flag = False #sph.parameters.isothermal_flag = True #sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = dt_bridge #sph.parameters.verbosity = 0 #sph.parameters.eps_is_h_flag = False # h_smooth is constant #eps = 0.1 | units.parsec #sph.parameters.gas_epsilon = eps #sph.parameters.sph_h_const = eps #cloud.h_smooth= eps #print("cloud:", sph.gas_particles) #plt.scatter(np.log10(sph.gas_particles.density.value_in(units.g/units.cm**3)), # sph.gas_particles.pressure.value_in(units.kg/units.m/units.s**2), s=10) #plt.show() # Setting up channels from code to cloud and cluster #channel_from_grav_to_cluster = gravity.particles.new_channel_to(cluster) channel_from_sph_to_cluster = sph.dm_particles.new_channel_to(cluster) #channel_from_sph_to_cloud = sph.gas_particles.new_channel_to(cloud) ''' if sink == True: with open('print_out.txt','a') as pf: pf.write('star formation is considered\n') stars = Particles(0) sph.dm_particles.add_particles(stars) channel_from_sph_to_star = sph.dm_particles.new_channel_to(stars) density_threshold = Jeans_density(M=sph.gas_particles.mass.max()) sph.parameters.stopping_condition_maximum_density = density_threshold density_limit_detection = sph.stopping_conditions.density_limit_detection density_limit_detection.enable() merge_radius = 1e-2 | units.parsec # around 20 AU ''' # Initializing 90 percent lagrangian radius #lr_cloud = [] #lr_cloud.append(Lagrang_radii(cloud, converter)) lr_cluster = [] lr_cluster.append(Lagrang_radii(cluster, converter)) # Evolving with open('print_out.txt', 'a') as pf: pf.write('Start evolving the molecular cloud...\n') with open('l_radii.txt', 'w') as lr_txt: lr_txt.write('#lr0.2 cloud, lr0.5 cloud, lr0.9 cloud, lr0.2 cluster, lr0.5 cluster, lr0.9 cluster \n') times = quantities.arange(0.|units.Myr, t_end, dt_diag) for i,t in enumerate(times): with open('print_out.txt', 'a') as pf: pf.write(str(t.value_in(units.Myr))+' Myr\n') ''' if sink == True: # make sure at this time 'stars' and 'sph.gas_particles' are the same resolve_sinks(sph, stars, cloud, density_threshold, t) ''' sph.evolve_model(t, dt_diag) #gravity.evolve_model(t, dt_diag) #channel_from_grav_to_cluster.copy() channel_from_sph_to_cluster.copy() #channel_from_sph_to_cloud.copy() ''' if sink == True: merge_stars(sph, stars, merge_radius) ''' # make plots #plot_cloud_cluster(cluster, sph, title='{0}'.format(float(t.value_in(units.Myr))),\ # vrange=[-5,3]) plot_cluster(cluster, title='cluster_{0}'.format(float(t.value_in(units.Myr))),\ vrange=[-5,3]) #plot_cloud(sph, title='cloud_{0}'.format(float(t.value_in(units.Myr))),\ # vrange=[-5,3]) # save data (energy will be added afterwards) #lr_cloud.append(Lagrang_radii(cloud, converter)) lr_cluster.append(Lagrang_radii(cluster, converter)) #gravity.stop() sph.stop() return lr_cluster #lr_cloud