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()
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 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)
sph_to_star = sph.particles.new_channel_to(sun) sph_to_disk = sph.particles.new_channel_to(disk_gas) lr9 = [] lr9.append(return_L9_radius(disk_gas, Mstar, Rmin | units.AU)) if overwrite: dt = t_end / float(n_steps) time = 0 | units.yr # Evolving the system while time < t_end: time += dt print('Time:', time) sph.evolve_model(time) #plot_map(sph,d_plot_dir+'test{0}.png'.format(time.value_in(units.yr)),show=False) sph_to_star.copy() sph_to_disk.copy() lr9.append(return_L9_radius(disk_gas, Mstar, Rmin | units.AU)) sph.stop() # Plotting the radius size pkl.dump(lr9, open('disk_radii/lr9_N4000.p', 'wb')) t = np.arange(0, (t_end + dt).value_in(units.yr), dt.value_in(units.yr)) plt.scatter(t, lr9) plt.xlabel('Time (years)') plt.ylabel('Disk size (AU)') plt.savefig('disk_radius_time_plot.png') plt.show()
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
def make_xyz(self): from amuse.community.fi.interface import Fi N=self.targetN target_rms=self.target_rms 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=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.periodic_box_size=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. minrms=1. i=0 while rms > target_rms: i+=1 t=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.*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) del sph return x,y,z
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 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
N_particles = 1000 # Number of SPH particles disk = ProtoPlanetaryDisk(N_particles, convert_nbody=converter, densitypower=1.5, Rmin=0.5, Rmax=100, q_out=1.) # Rmin and Rmax in AU disk_particles = disk.result # Disk particles disk_particles.h_smooth = 0.06 | units.au # Smoothing length # Rotate the disk 90 degrees around x axis disk = rotate(disk_particles, 90, 0, 0) # Start SPH code and add particles sph = Fi(converter) sph.gas_particles.add_particles( disk_particles) # Disk particles are added as gas particles sph.dm_particles.add_particles( stars[0]) # Star is added as dark matter particle # Evolve code in time steps t_end = 100 | units.yr dt = 1 | units.yr t = 0 | units.yr while t < t_end: t += dt print t sph.evolve_model(t)
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 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 make_xyz(self): from amuse.community.fi.interface import Fi N = self.targetN target_rms = self.target_rms 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 = 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.periodic_box_size = 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. minrms = 1. i = 0 while rms > target_rms: i += 1 t = 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. * 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) del sph return x, y, z
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