def glass(N, target_rms=0.05): """ make glass for initial condition generation """ if target_rms < 0.001: print "warning: target_rms highly unlikely to succeed" L=1| nbody_system.length dt=0.01 | nbody_system.time x,y,z=uniform_random_unit_cube(N).make_xyz() vx,vy,vz=uniform_unit_sphere(N).make_xyz() p=datamodel.Particles(N) p.x=L*x p.y=L*y p.z=L*z p.h_smooth=0. * L p.vx= 0.1*vx | (nbody_system.speed) p.vy= 0.1*vy | (nbody_system.speed) p.vz= 0.1*vz | (nbody_system.speed) p.u= (0.1*0.1) | nbody_system.speed**2 p.mass=(8./N) | nbody_system.mass sph=Fi(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.parameters.artificial_viscosity_alpha = 1. sph.parameters.beta = 2. sph.commit_parameters() sph.gas_particles.add_particles(p) sph.commit_particles() # sph.start_viewer() t=0. | nbody_system.time rms=1. i=0 while rms > target_rms: t=t+(0.25 | nbody_system.time) sph.evolve_model(t) h=sph.particles.h_smooth.value_in(nbody_system.length) rho=h**(-3.) rms=rho.std()/rho.mean() print rms, target_rms x=sph.particles.x.value_in(nbody_system.length) y=sph.particles.y.value_in(nbody_system.length) z=sph.particles.z.value_in(nbody_system.length) sph.stop() return x,y,z
def glass(N, target_rms=0.05): """ make glass for initial condition generation """ if target_rms < 0.001: print "warning: target_rms highly unlikely to succeed" L = 1 | nbody_system.length dt = 0.01 | nbody_system.time x, y, z = uniform_random_unit_cube(N).make_xyz() vx, vy, vz = uniform_unit_sphere(N).make_xyz() p = datamodel.Particles(N) p.x = L * x p.y = L * y p.z = L * z p.h_smooth = 0. * L p.vx = 0.1 * vx | (nbody_system.speed) p.vy = 0.1 * vy | (nbody_system.speed) p.vz = 0.1 * vz | (nbody_system.speed) p.u = (0.1 * 0.1) | nbody_system.speed**2 p.mass = (8. / N) | nbody_system.mass sph = Fi(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.parameters.artificial_viscosity_alpha = 1. sph.parameters.beta = 2. sph.commit_parameters() sph.gas_particles.add_particles(p) sph.commit_particles() # sph.start_viewer() t = 0. | nbody_system.time rms = 1. # i = 0 while rms > target_rms: t = t + (0.25 | nbody_system.time) sph.evolve_model(t) h = sph.particles.h_smooth.value_in(nbody_system.length) rho = h**(-3.) rms = rho.std() / rho.mean() print rms, target_rms x = sph.particles.x.value_in(nbody_system.length) y = sph.particles.y.value_in(nbody_system.length) z = sph.particles.z.value_in(nbody_system.length) sph.stop() return x, y, z
def bb79_cloud_evolve(N=50000, Mcloud=1. | units.MSun, Rcloud=3.2e16 | units.cm, omega=1.56e-12 | units.rad / units.s, density_perturb=0.5, t_total=8.3e11 | units.s): # mean density of the cloud rho_uni = Mcloud / (4. / 3. * numpy.pi * Rcloud**3) print(" ** mean density = ", rho_uni.in_(units.g / units.cm**3)) # free fall time of the cloud t_ff = numpy.sqrt(3. * numpy.pi / (32. * units.constants.G * rho_uni)) print(" ** free-fall time = ", t_ff.in_(units.yr)) conv = nbody_system.nbody_to_si(Mcloud, Rcloud) sph = Fi(conv) # the initial conditions of BB79 parts_bb79 = bb79_cloud(targetN=N, omega=omega, rho_perturb=0.5, ethep_ratio=0.25, convert_nbody=conv, base_grid=body_centered_grid_unit_cube).result sph.gas_particles.add_particles(parts_bb79) sph.parameters.use_hydro_flag = True sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.gamma = 1 sph.parameters.verbosity = 0 sph.parameters.timestep = 0.1 * t_ff print( "**evolving to time: (end time = ~ {0:.3f} t_ff)".format(t_total / t_ff)) # setting snapshots to be plotted nplot = 10 if nplot > 1: plot_timestep = t_total / (nplot - 1) else: plot_timestep = t_total # evolution of the cloud for i in range(nplot): ttarget = i * plot_timestep t_tff = ttarget / t_ff sph.evolve_model(ttarget) plot_i = "bb79_rho_{0:03d}.png".format(i) tt_tff = "{0:.3f}".format(t_tff) title_i = "$%s\,t_{\mathrm{ff}}$" % (tt_tff) print("\t {0:.3f} t_ff -> {1}".format(t_tff, plot_i)) plot_sph_rho(sph, N=300, grid_size=0.025 | units.parsec, plot_name=plot_i, plot_title=title_i) sph.stop()
def bb79_cloud_evolve(N=50000, Mcloud=1. | units.MSun, Rcloud=3.2e16 | units.cm, omega=1.56e-12 | units.rad/units.s, density_perturb=0.5, t_total=8.3e11 | units.s): # mean density of the cloud rho_uni = Mcloud / (4./3.*numpy.pi*Rcloud**3) print(" ** mean density = ", rho_uni.in_(units.g/units.cm**3)) # free fall time of the cloud t_ff = numpy.sqrt(3.*numpy.pi / (32.*units.constants.G*rho_uni)) print(" ** free-fall time = ", t_ff.in_(units.yr)) conv = nbody_system.nbody_to_si(Mcloud, Rcloud) sph = Fi(conv) # the initial conditions of BB79 parts_bb79 = bb79_cloud(targetN=N, omega=omega, rho_perturb=0.5, ethep_ratio=0.25, convert_nbody=conv, base_grid=body_centered_grid_unit_cube).result sph.gas_particles.add_particles(parts_bb79) sph.parameters.use_hydro_flag = True sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.gamma = 1 sph.parameters.verbosity = 0 sph.parameters.timestep = 0.1*t_ff print( "**evolving to time: (end time = ~ {0:.3f} t_ff)".format(t_total/t_ff)) # setting snapshots to be plotted nplot = 10 if nplot > 1: plot_timestep = t_total / (nplot - 1) else: plot_timestep = t_total # evolution of the cloud for i in range(nplot): ttarget = i*plot_timestep t_tff = ttarget / t_ff sph.evolve_model(ttarget) plot_i = "bb79_rho_{0:03d}.png".format(i) tt_tff = "{0:.3f}".format(t_tff) title_i = "$%s\,t_{\mathrm{ff}}$" % (tt_tff) print("\t {0:.3f} t_ff -> {1}".format(t_tff, plot_i)) plot_sph_rho(sph, N=300, grid_size=0.025 | units.parsec, plot_name=plot_i, plot_title=title_i) sph.stop()
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
sun.vy = 0. | units.kms sun.vz = 0. | units.kms sph = Fi(convert) sph.parameters.use_hydro_flag = True sph.parameters.radiation_flag = False sph.parameters.self_gravity_flag = True sph.parameters.gamma = 1. sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = 0.125 | units.yr sph.gas_particles.add_particles(gas) sph.particles.add_particles(sun) sph.evolve_model(tend) L = 50 rho = make_map(sph, N=200, L=L) sph.stop() pyplot.figure(figsize=(8, 8)) pyplot.imshow(numpy.log10(1.e-5 + rho.value_in(units.amu / units.cm**3)), extent=[-L / 2, L / 2, -L / 2, L / 2], vmin=10, vmax=15) pyplot.title(tend) pyplot.xlabel('AU') pyplot.savefig('test.png') pyplot.show()
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 run_hydrodynamics(N=100, Mtot=1|units.MSun, Rvir=1|units.RSun, t_end=0.5|units.day, n_steps=10,\ vx = 0 |(units.RSun/units.day),\ vy = 0 |(units.RSun/units.day),\ vz = 0 |(units.RSun/units.day),\ plummer1=None, plummer2=None,\ bodyname = None): """ Runs the hydrodynamics simulation and returns a HydroResults instance. FUNCTION WALKTHROUGH: In the following explanation 'plummer1' and 'plummer2' are assumed to be hdf5 files written by the function write_set_to_file(). Case 1: If 'plummer1' and 'plummer2' are filenames of hdf5 files, then these two plummer spheres will be smashed together. Case 2: If only plummer1 is supplied, then it will evolve plummer1 with t_end timerange and n_steps steps. Case 3: If no plummers spheres are supplied, then it will generate a new plummer sphere using the default/supplied initial conditions. OUTPUT FILES: If 'results_out' is specified, the HydroResult instance is written to file in HDF5 format. This however does not use write_set_to_file() which writes the entire Particles class and its attributes to file at each dt, but uses write_to_hdf5() from the 'support' module which is tailored to writing HydroResults instances to file. This HDF5 contains all necessary data to plot the required plots of the assignment. In addition, the last snapshot of the Particles instance is written to file using write_set_to_file(), the latter file is written to the 'bodies' directory. Only the last snapshot is written to file because the history of a Particle set is not of interest when reloading them to smash plummer spheres. """ converter = nbody_system.nbody_to_si(Mtot, Rvir) fi = Fi(converter) if plummer1 and plummer2: eta_smash = 0.3 |units.day if plummer1 == plummer2: bodies1 = read_set_from_file(plummer1, format='hdf5') bodies2 = bodies1.copy() bodies2.key += 1 else: bodies1 = read_set_from_file(plummer1, format='hdf5') bodies2 = read_set_from_file(plummer2, format='hdf5') bodies1.move_to_center() bodies2.move_to_center() if vx.value_in(vx.unit) == 0 and vy.value_in(vy.unit) == 0 \ and vz.value_in(vz.unit) == 0: bodies1.x += -1 |units.RSun bodies2.x += 1 |units.RSun else: bodies1.x += (-1)*vx*eta_smash bodies2.x += 1*vx*eta_smash bodies1.vx += vx bodies2.vx += (-1)*vx bodies1.vy += vy bodies2.vy += (-1)*vy bodies1.vz += vz bodies2.vz += (-1)*vz bodies1.add_particles(bodies2) bodies = bodies1 elif plummer1 or plummer2: if plummer1: bodies = read_set_from_file(plummer1) else: bodies = read_set_from_file(plummer2) bodies.move_to_center() else: bodies = new_plummer_gas_model(N, convert_nbody=converter) fi.gas_particles.add_particles(bodies) fi_to_framework = fi.gas_particles.new_channel_to(bodies) fi.parameters.self_gravity_flag = True data = {'lagrangianradii':AdaptingVectorQuantity(),\ 'angular_momentum':AdaptingVectorQuantity(),\ 'time':AdaptingVectorQuantity(),\ 'positions':AdaptingVectorQuantity(),\ 'kinetic_energy':AdaptingVectorQuantity(),\ 'potential_energy':AdaptingVectorQuantity(),\ 'total_energy':AdaptingVectorQuantity() } mass_fractions = [0.10, 0.25, 0.50, 0.75] setattr(data['lagrangianradii'], 'mf', mass_fractions) data['radius_initial'], data['densities_initial'] = radial_density(\ fi.particles.x, fi.particles.mass, N=10, dim=1) timerange = numpy.linspace(0, t_end.value_in(t_end.unit),\ n_steps) | t_end.unit data['time'].extend(timerange) fi.parameters.timestep = t_end/(n_steps+1) widget = drawwidget("Evolving") pbar = pb.ProgressBar(widgets=widget, maxval=len(timerange)).start() for i, t in enumerate(timerange): fi.evolve_model(t) data['kinetic_energy'].append(fi.kinetic_energy) data['potential_energy'].append(fi.potential_energy) data['total_energy'].append(fi.total_energy) data['positions'].append(fi.particles.position) data['angular_momentum'].append(fi.gas_particles.\ total_angular_momentum()) data['lagrangianradii'].append(fi.particles.LagrangianRadii(\ unit_converter=converter,\ mf=mass_fractions)[0]) if t == timerange[-1] and bodyname: if os.path.dirname(bodyname) == '': filename = "bodies/"+bodyname fi_to_framework.copy() write_set_to_file(bodies.savepoint(t), filename, "hdf5") pbar.update(i) pbar.finish() data['radius_final'], data['densities_final'] = radial_density(\ fi.particles.x, fi.particles.mass, N=10, dim=1) fi.stop() results = HydroResults(data) return results
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 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 run_hydrodynamics(N=100, Mtot=1|units.MSun, Rvir=1|units.RSun, t_end=0.5|units.day, n_steps=10,\ vx = 0 |(units.RSun/units.day),\ vy = 0 |(units.RSun/units.day),\ vz = 0 |(units.RSun/units.day),\ plummer1=None, plummer2=None,\ bodyname = None): """ Runs the hydrodynamics simulation and returns a HydroResults instance. FUNCTION WALKTHROUGH: In the following explanation 'plummer1' and 'plummer2' are assumed to be hdf5 files written by the function write_set_to_file(). Case 1: If 'plummer1' and 'plummer2' are filenames of hdf5 files, then these two plummer spheres will be smashed together. Case 2: If only plummer1 is supplied, then it will evolve plummer1 with t_end timerange and n_steps steps. Case 3: If no plummers spheres are supplied, then it will generate a new plummer sphere using the default/supplied initial conditions. OUTPUT FILES: If 'results_out' is specified, the HydroResult instance is written to file in HDF5 format. This however does not use write_set_to_file() which writes the entire Particles class and its attributes to file at each dt, but uses write_to_hdf5() from the 'support' module which is tailored to writing HydroResults instances to file. This HDF5 contains all necessary data to plot the required plots of the assignment. In addition, the last snapshot of the Particles instance is written to file using write_set_to_file(), the latter file is written to the 'bodies' directory. Only the last snapshot is written to file because the history of a Particle set is not of interest when reloading them to smash plummer spheres. """ converter = nbody_system.nbody_to_si(Mtot, Rvir) fi = Fi(converter) if plummer1 and plummer2: eta_smash = 0.3 | units.day if plummer1 == plummer2: bodies1 = read_set_from_file(plummer1, format='hdf5') bodies2 = bodies1.copy() bodies2.key += 1 else: bodies1 = read_set_from_file(plummer1, format='hdf5') bodies2 = read_set_from_file(plummer2, format='hdf5') bodies1.move_to_center() bodies2.move_to_center() if vx.value_in(vx.unit) == 0 and vy.value_in(vy.unit) == 0 \ and vz.value_in(vz.unit) == 0: bodies1.x += -1 | units.RSun bodies2.x += 1 | units.RSun else: bodies1.x += (-1) * vx * eta_smash bodies2.x += 1 * vx * eta_smash bodies1.vx += vx bodies2.vx += (-1) * vx bodies1.vy += vy bodies2.vy += (-1) * vy bodies1.vz += vz bodies2.vz += (-1) * vz bodies1.add_particles(bodies2) bodies = bodies1 elif plummer1 or plummer2: if plummer1: bodies = read_set_from_file(plummer1) else: bodies = read_set_from_file(plummer2) bodies.move_to_center() else: bodies = new_plummer_gas_model(N, convert_nbody=converter) fi.gas_particles.add_particles(bodies) fi_to_framework = fi.gas_particles.new_channel_to(bodies) fi.parameters.self_gravity_flag = True data = {'lagrangianradii':AdaptingVectorQuantity(),\ 'angular_momentum':AdaptingVectorQuantity(),\ 'time':AdaptingVectorQuantity(),\ 'positions':AdaptingVectorQuantity(),\ 'kinetic_energy':AdaptingVectorQuantity(),\ 'potential_energy':AdaptingVectorQuantity(),\ 'total_energy':AdaptingVectorQuantity() } mass_fractions = [0.10, 0.25, 0.50, 0.75] setattr(data['lagrangianradii'], 'mf', mass_fractions) data['radius_initial'], data['densities_initial'] = radial_density(\ fi.particles.x, fi.particles.mass, N=10, dim=1) timerange = numpy.linspace(0, t_end.value_in(t_end.unit),\ n_steps) | t_end.unit data['time'].extend(timerange) fi.parameters.timestep = t_end / (n_steps + 1) widget = drawwidget("Evolving") pbar = pb.ProgressBar(widgets=widget, maxval=len(timerange)).start() for i, t in enumerate(timerange): fi.evolve_model(t) data['kinetic_energy'].append(fi.kinetic_energy) data['potential_energy'].append(fi.potential_energy) data['total_energy'].append(fi.total_energy) data['positions'].append(fi.particles.position) data['angular_momentum'].append(fi.gas_particles.\ total_angular_momentum()) data['lagrangianradii'].append(fi.particles.LagrangianRadii(\ unit_converter=converter,\ mf=mass_fractions)[0]) if t == timerange[-1] and bodyname: if os.path.dirname(bodyname) == '': filename = "bodies/" + bodyname fi_to_framework.copy() write_set_to_file(bodies.savepoint(t), filename, "hdf5") pbar.update(i) pbar.finish() data['radius_final'], data['densities_final'] = radial_density(\ fi.particles.x, fi.particles.mass, N=10, dim=1) fi.stop() results = HydroResults(data) return results
def glass(self): from amuse.community.fi.interface import Fi if self.target_rms < 0.0001: print "warning: target_rms may not succeed" if self.number_of_particles < 1000: print "warning: not enough particles" N = 2 * self.number_of_particles L = 1 | nbody_system.length dt = 0.01 | nbody_system.time x, y, z = self._random_cube(N) vx,vy,vz= self.random(N) p = Particles(N) p.x = L * x p.y = L * y p.z = L * z p.h_smooth = 0.0 | nbody_system.length p.vx = (0.1 | nbody_system.speed) * vx p.vy = (0.1 | nbody_system.speed) * vy p.vz = (0.1 | nbody_system.speed) * vz p.u = (0.1*0.1) | nbody_system.speed**2 p.mass = (8.0/N) | nbody_system.mass sph = Fi(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.0 sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = dt sph.parameters.verbosity = 0 sph.parameters.periodic_box_size = 2 * L sph.parameters.artificial_viscosity_alpha = 1.0 sph.parameters.beta = 2.0 sph.commit_parameters() sph.gas_particles.add_particles(p) sph.commit_particles() t = 0.0 | nbody_system.time rms = 1.0 minrms = 1.0 i = 0 while rms > self.target_rms: i += 1 t += (0.25 | nbody_system.time) sph.evolve_model(t) rho = sph.particles.rho.value_in(nbody_system.density) rms = rho.std()/rho.mean() minrms = min(minrms, rms) if (rms > 2.0*minrms) or (i > 300): print " RMS(rho) convergence warning:", i, rms, minrms if i > 100000: print "i> 100k steps - not sure about this..." print " rms:", rms break x = sph.particles.x.value_in(nbody_system.length) y = sph.particles.y.value_in(nbody_system.length) z = sph.particles.z.value_in(nbody_system.length) sph.stop() del sph return self._cutout_sphere(x, y, z)
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 run_molecular_cloud(N=100, Mcloud=100. | units.MSun, Rcloud=1. | units.parsec): conv = nbody_system.nbody_to_si(Mcloud,Rcloud) rho_cloud = 3.*Mcloud/(4.*numpy.pi*Rcloud**3) print rho_cloud tff = 0.5427/numpy.sqrt(constants.G*rho_cloud) print "t_ff=", tff.value_in(units.Myr), 'Myr' dt = 5.e-2 | units.Myr tend=1.0 | units.Myr # tend=2.0 | units.Myr parts=molecular_cloud(targetN=N,convert_nbody=conv, base_grid=body_centered_grid_unit_cube, seed=100).result sph=Fi(conv, number_of_workers=3) 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 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 parts.h_smooth= eps print 'eps-h flag', sph.get_eps_is_h(), sph.get_consthsm() expected_dt = 0.2*numpy.pi*numpy.power(eps, 1.5)/numpy.sqrt(constants.G*Mcloud/N) print "dt_exp=", expected_dt.value_in(units.Myr) print "dt=", dt print "eps=", sph.parameters.gas_epsilon.in_(units.parsec) sph.gas_particles.add_particles(parts) #grav=copycat(Fi, sph, conv) #sys=bridge(verbose=False) #sys.add_system(sph,(grav,),False) channel_from_sph_to_parts= sph.gas_particles.new_channel_to(parts) channel_from_parts_to_sph= parts.new_channel_to(sph.gas_particles) i=0 L=6 E0 = 0.0 ttarget = 0.0 | units.Myr plot_hydro(ttarget, sph, i, L) while ttarget < tend: ttarget=float(i)*dt print ttarget sph.evolve_model(ttarget, timestep=dt) E = sph.gas_particles.kinetic_energy()+sph.gas_particles.potential_energy() + sph.gas_particles.thermal_energy() E_th = sph.gas_particles.thermal_energy() if i==0: E0 = E Eerr = (E-E0)/E0 print 'energy=', E, 'energy_error=', Eerr, 'e_th=', E_th channel_from_sph_to_parts.copy() """ filename = 'm400k_r10pc_e01_'+ str(i).zfill(2) + '.dat' print filename parts_sorted = parts.sorted_by_attribute('rho') write_output(filename, parts_sorted, conv) """ plot_hydro(ttarget, sph, i, L) i=i+1 plot_hydro_and_stars(ttarget, sph, L) sph.stop() return parts
def run_molecular_cloud(N=100, Mcloud=100. | units.MSun, Rcloud=1. | units.parsec): conv = nbody_system.nbody_to_si(Mcloud, Rcloud) rho_cloud = 3. * Mcloud / (4. * numpy.pi * Rcloud**3) print rho_cloud tff = 0.5427 / numpy.sqrt(constants.G * rho_cloud) print "t_ff=", tff.value_in(units.Myr), 'Myr' dt = 5.e-2 | units.Myr tend = 1.0 | units.Myr # tend=2.0 | units.Myr parts = molecular_cloud(targetN=N, convert_nbody=conv, base_grid=body_centered_grid_unit_cube, seed=100).result sph = Fi(conv, number_of_workers=3) 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 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 parts.h_smooth = eps print 'eps-h flag', sph.get_eps_is_h(), sph.get_consthsm() expected_dt = 0.2 * numpy.pi * numpy.power(eps, 1.5) / numpy.sqrt( constants.G * Mcloud / N) print "dt_exp=", expected_dt.value_in(units.Myr) print "dt=", dt print "eps=", sph.parameters.gas_epsilon.in_(units.parsec) sph.gas_particles.add_particles(parts) #grav=copycat(Fi, sph, conv) #sys=bridge(verbose=False) #sys.add_system(sph,(grav,),False) channel_from_sph_to_parts = sph.gas_particles.new_channel_to(parts) channel_from_parts_to_sph = parts.new_channel_to(sph.gas_particles) i = 0 L = 6 E0 = 0.0 ttarget = 0.0 | units.Myr plot_hydro(ttarget, sph, i, L) while ttarget < tend: ttarget = float(i) * dt print ttarget sph.evolve_model(ttarget, timestep=dt) E = sph.gas_particles.kinetic_energy( ) + sph.gas_particles.potential_energy( ) + sph.gas_particles.thermal_energy() E_th = sph.gas_particles.thermal_energy() if i == 0: E0 = E Eerr = (E - E0) / E0 print 'energy=', E, 'energy_error=', Eerr, 'e_th=', E_th channel_from_sph_to_parts.copy() """ filename = 'm400k_r10pc_e01_'+ str(i).zfill(2) + '.dat' print filename parts_sorted = parts.sorted_by_attribute('rho') write_output(filename, parts_sorted, conv) """ plot_hydro(ttarget, sph, i, L) i = i + 1 plot_hydro_and_stars(ttarget, sph, L) sph.stop() return parts
sun.z = 0. | units.AU sun.vx = 0. | units.kms sun.vy = 0. | units.kms sun.vz = 0. | units.kms sph = Fi(convert) sph.parameters.use_hydro_flag = True sph.parameters.radiation_flag = False sph.parameters.self_gravity_flag = True sph.parameters.gamma = 1. sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = 0.125 | units.yr sph.gas_particles.add_particles(gas) sph.particles.add_particles(sun) sph.evolve_model(tend) L = 50 rho = make_map(sph, N=200, L=L) sph.stop() pyplot.figure(figsize=(8, 8)) pyplot.imshow(numpy.log10(1.e-5+rho.value_in(units.amu/units.cm**3)), extent=[-L/2, L/2, -L/2, L/2], vmin=10, vmax=15) pyplot.title(tend) pyplot.xlabel('AU') pyplot.savefig('test.png') pyplot.show()
def run_mc(N=5000,Mcloud=10000. | units.MSun,Rcloud=1. | units.parsec): conv = nbody_system.nbody_to_si(Mcloud,Rcloud) interaction_timestep = 0.01 | units.Myr time_end=0.36 | units.Myr parts=molecular_cloud(targetN=N,convert_nbody=conv, base_grid=body_centered_grid_unit_cube).result sph=Fi(conv) # need to turn off self gravity, the bridge will calculate this sph.parameters.self_gravity_flag=False # some typical Fi flags (just for reference, most are default values) sph.parameters.use_hydro_flag=True sph.parameters.isothermal_flag=True sph.parameters.integrate_entropy_flag=False sph.parameters.gamma=1 sph.parameters.verbosity = 0 # setting the hydro timestep is important # the sph code will take 2 timesteps every interaction timestep sph.parameters.timestep=interaction_timestep/2 sph.gas_particles.add_particles(parts) def new_code_to_calculate_gravity_of_gas_particles(): result = BHTree(conv) return result calculate_gravity_code=bridge.CalculateFieldForCodes( new_code_to_calculate_gravity_of_gas_particles, # the code that calculates the acceleration field input_codes = [sph] # the codes to calculate the acceleration field of ) bridged_system = bridge.Bridge() bridged_system.timestep=interaction_timestep bridged_system.add_system( sph, # the code to move the particles of [calculate_gravity_code] # the codes that provide the acceleration field ) fig=pyplot.figure(figsize=(12,12)) ncolumn=2 nrow=2 nplot=ncolumn*nrow grid_size = 3 | units.parsec extent = (grid_size * (-0.5, 0.5, -0.5, 0.5)).value_in(units.parsec) if nplot > 1: plot_timestep = time_end / (nplot - 1) else: plot_timestep = time_end for i in range(nplot): ttarget=i*plot_timestep print("evolving to time:", ttarget.as_quantity_in(units.Myr)) bridged_system.evolve_model(ttarget) rho=make_map(sph,N=200,grid_size=grid_size) subplot=fig.add_subplot(ncolumn,nrow,i+1) subplot.imshow( numpy.log10(1.e-5+rho.value_in(units.amu/units.cm**3)), extent = extent, vmin=1, vmax=5 ) subplot.set_title(ttarget.as_quantity_in(units.Myr)) sph.stop() pyplot.show()
def glass(self): from amuse.community.fi.interface import Fi if self.target_rms < 0.0001: print("warning: target_rms may not succeed") if self.number_of_particles < 1000: print("warning: not enough particles") N = 2 * self.number_of_particles L = 1 | nbody_system.length dt = 0.01 | nbody_system.time x, y, z = self._random_cube(N) vx,vy,vz= self.random(N) p = Particles(N) p.x = L * x p.y = L * y p.z = L * z p.h_smooth = 0.0 | nbody_system.length p.vx = (0.1 | nbody_system.speed) * vx[:N] p.vy = (0.1 | nbody_system.speed) * vy[:N] p.vz = (0.1 | nbody_system.speed) * vz[:N] p.u = (0.1*0.1) | nbody_system.speed**2 p.mass = (8.0/N) | nbody_system.mass sph = Fi(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.0 sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.timestep = dt sph.parameters.verbosity = 0 sph.parameters.periodic_box_size = 2 * L sph.parameters.artificial_viscosity_alpha = 1.0 sph.parameters.beta = 2.0 sph.commit_parameters() sph.gas_particles.add_particles(p) sph.commit_particles() t = 0.0 | nbody_system.time rms = 1.0 minrms = 1.0 i = 0 while rms > self.target_rms: i += 1 t += (0.25 | nbody_system.time) sph.evolve_model(t) rho = sph.particles.rho.value_in(nbody_system.density) rms = rho.std()/rho.mean() minrms = min(minrms, rms) if (rms > 2.0*minrms) or (i > 300): print(" RMS(rho) convergence warning:", i, rms, minrms) if i > 100000: print("i> 100k steps - not sure about this...") print(" rms:", rms) break x = sph.particles.x.value_in(nbody_system.length) y = sph.particles.y.value_in(nbody_system.length) z = sph.particles.z.value_in(nbody_system.length) sph.stop() del sph return self._cutout_sphere(x, y, z)
def run_mc(N=5000, Mcloud=10000. | units.MSun, Rcloud=1. | units.parsec): conv = nbody_system.nbody_to_si(Mcloud, Rcloud) interaction_timestep = 0.01 | units.Myr time_end = 0.36 | units.Myr parts = molecular_cloud(targetN=N, convert_nbody=conv, base_grid=body_centered_grid_unit_cube).result sph = Fi(conv) # need to turn off self gravity, the bridge will calculate this sph.parameters.self_gravity_flag = False # some typical Fi flags (just for reference, most are default values) sph.parameters.use_hydro_flag = True sph.parameters.isothermal_flag = True sph.parameters.integrate_entropy_flag = False sph.parameters.gamma = 1 sph.parameters.verbosity = 0 # setting the hydro timestep is important # the sph code will take 2 timesteps every interaction timestep sph.parameters.timestep = interaction_timestep / 2 sph.gas_particles.add_particles(parts) def new_code_to_calculate_gravity_of_gas_particles(): result = BHTree(conv) return result calculate_gravity_code = bridge.CalculateFieldForCodes( new_code_to_calculate_gravity_of_gas_particles, # the code that calculates the acceleration field input_codes=[sph] # the codes to calculate the acceleration field of ) bridged_system = bridge.Bridge() bridged_system.timestep = interaction_timestep bridged_system.add_system( sph, # the code to move the particles of [calculate_gravity_code ] # the codes that provide the acceleration field ) fig = pyplot.figure(figsize=(12, 12)) ncolumn = 2 nrow = 2 nplot = ncolumn * nrow grid_size = 3 | units.parsec extent = (grid_size * (-0.5, 0.5, -0.5, 0.5)).value_in(units.parsec) if nplot > 1: plot_timestep = time_end / (nplot - 1) else: plot_timestep = time_end for i in range(nplot): ttarget = i * plot_timestep print("evolving to time:", ttarget.as_quantity_in(units.Myr)) bridged_system.evolve_model(ttarget) rho = make_map(sph, N=200, grid_size=grid_size) subplot = fig.add_subplot(ncolumn, nrow, i + 1) subplot.imshow(numpy.log10(1.e-5 + rho.value_in(units.amu / units.cm**3)), extent=extent, vmin=1, vmax=5) subplot.set_title(ttarget.as_quantity_in(units.Myr)) sph.stop() pyplot.show()
def res_increase( gas=None, recalculate_h_density=False, seed=123, make_cutout=False, make_circular_cutout=False, circular_rmax=3000 | units.pc, x_center=None, y_center=None, width=None, res_increase_factor=85, ): numpy.random.seed(seed) if gas is None: if len(sys.argv) > 2: from amuse.io import read_set_from_file filename = sys.argv[1] res_increase_factor = int(sys.argv[2]) gas = read_set_from_file(filename, 'amuse') if hasattr(gas, "itype"): gas = gas[gas.itype == 1] del gas.itype else: from amuse.ic.gasplummer import new_plummer_gas_model converter = nbody_system.nbody_to_si(10000 | units.MSun, 10 | units.pc) filename = "test" gas = new_plummer_gas_model(10000, converter) res_increase_factor = 85 sph = Fi(converter, mode="openmp") gas_in_code = sph.gas_particles.add_particles(gas) gas.h_smooth = gas_in_code.h_smooth gas.density = gas_in_code.density sph.stop() write_set_to_file(gas, "old-%s" % filename, "amuse") print("old gas created") if make_circular_cutout: r2 = gas.x**2 + gas.y**2 cutout = gas[r2 <= circular_rmax**2] gas = cutout converter = nbody_system.nbody_to_si(gas.total_mass(), width) sph = Fi(converter, mode="openmp") gas_in_code = sph.gas_particles.add_particles(gas) gas.h_smooth = gas_in_code.h_smooth gas.density = gas_in_code.density sph.stop() if make_cutout: if (x_center is None or y_center is None or width is None): raise Exception("Need to set x_center, y_center and width!") cutout = gas.sorted_by_attribute("x") cutout = cutout[cutout.x - x_center < width / 2] cutout = cutout[cutout.x - x_center > -width / 2] cutout = cutout.sorted_by_attribute("y") cutout = cutout[cutout.y - y_center < width / 2] cutout = cutout[cutout.y - y_center > -width / 2] gas = cutout converter = nbody_system.nbody_to_si(gas.total_mass(), width) sph = Fi(converter, mode="openmp") gas_in_code = sph.gas_particles.add_particles(gas) gas.h_smooth = gas_in_code.h_smooth gas.density = gas_in_code.density sph.stop() # boundary = test_cutout.h_smooth.max() if res_increase_factor == 1: return gas original_number_of_particles = len(gas) new_number_of_particles = (res_increase_factor * original_number_of_particles) converter = nbody_system.nbody_to_si( gas.total_mass(), 1 | units.kpc, ) new_gas = Particles(new_number_of_particles) # new_gas.h_smooth = gas.h_smooth shells, particles_per_shell, shell_radii = find_shell_struct( res_increase_factor) relative_positions = pos_shift( shell_radii, particles_per_shell, res_increase_factor=res_increase_factor, ) relative_velocities = numpy.zeros( res_increase_factor * 3, dtype=float).reshape(res_increase_factor, 3) | gas.velocity.unit random_samples = 50 number_of_particles = len(gas) starting_index = 0 for r in range(random_samples): print("%i / %i random sample done" % (r, random_samples)) number_of_particles_remaining = len(gas) number_of_particles_in_sample = min( number_of_particles_remaining, int(1 + number_of_particles / random_samples)) gas_sample = gas.random_sample(number_of_particles_in_sample).copy() gas.remove_particles(gas_sample) end_index = (starting_index + number_of_particles_in_sample * res_increase_factor) new_gas_sample = new_gas[starting_index:end_index] psi = 2 * numpy.pi * numpy.random.random() theta = 2 * numpy.pi * numpy.random.random() phi = 2 * numpy.pi * numpy.random.random() relative_positions = rotated(relative_positions, phi, theta, psi) # print(len(gas_sample), len(new_gas_sample)) for i in range(res_increase_factor): new_gas_sample[i::res_increase_factor].mass = (gas_sample.mass / res_increase_factor) new_gas_sample[i::res_increase_factor].x = ( gas_sample.x + relative_positions[i, 0] * gas_sample.h_smooth) new_gas_sample[i::res_increase_factor].y = ( gas_sample.y + relative_positions[i, 1] * gas_sample.h_smooth) new_gas_sample[i::res_increase_factor].z = ( gas_sample.z + relative_positions[i, 2] * gas_sample.h_smooth) new_gas_sample[i::res_increase_factor].vx = ( gas_sample.vx + relative_velocities[i, 0]) new_gas_sample[i::res_increase_factor].vy = ( gas_sample.vy + relative_velocities[i, 1]) new_gas_sample[i::res_increase_factor].vz = ( gas_sample.vz + relative_velocities[i, 2]) new_gas_sample[i::res_increase_factor].density = gas_sample.density new_gas_sample[i::res_increase_factor].u = gas_sample.u starting_index += number_of_particles_in_sample * res_increase_factor new_gas.h_smooth = ((3 * new_gas.mass / (4 * pi * new_gas.density))**(1 / 3)) # sph = Fi(converter, mode="openmp", redirection="none") # new_gas_in_code = sph.gas_particles.add_particles(new_gas) # new_gas.h_smooth = new_gas_in_code.h_smooth # new_gas.density = new_gas_in_code.density # sph.stop() print("particles now have a mass of %s" % (new_gas[0].mass.in_(units.MSun))) return new_gas
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