def new_model(self): if self.seed is not None: numpy.random.seed(self.seed) vx_field=random_field(self.nf,self.power) vy_field=random_field(self.nf,self.power) vz_field=random_field(self.nf,self.power) vx_field,vy_field,vz_field=make_div_free(self.nf,vx_field,vy_field,vz_field) base_sphere=uniform_unit_sphere(self.targetN,base_grid=self.base_grid) x,y,z=base_sphere.make_xyz() self.actualN=len(x) vx=interpolate_trilinear(x,y,z,vx_field) vy=interpolate_trilinear(x,y,z,vy_field) vz=interpolate_trilinear(x,y,z,vz_field) mass=numpy.ones_like(x)/self.actualN vx=vx-vx.mean() vy=vy-vy.mean() vz=vz-vz.mean() Ep=3./5 self.internalE=Ep*self.ethep_ratio Ek=0.5*mass[0]*(vx**2+vy**2+vz**2).sum() vfac=sqrt(self.ekep_ratio*Ep/Ek) vx=vx*vfac vy=vy*vfac vz=vz*vfac Ek=0.5*mass[0]*(vx**2+vy**2+vz**2).sum() internal_energy=numpy.ones_like(x)*self.internalE return (mass,x,y,z,vx,vy,vz,internal_energy)
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 new_model(self): base_sphere=uniform_unit_sphere(self.targetN,base_grid=self.base_grid) x_uni,y_uni,z=base_sphere.make_xyz() self.actualN=len(x_uni) rad=numpy.sqrt(x_uni**2 + y_uni**2) phi=numpy.arctan2(y_uni,x_uni) n_vec=2000 phi_new_vec=numpy.linspace(-numpy.pi, numpy.pi, n_vec) phi_old_vec=phi_new_vec + self.rho_peturb*(numpy.sin(2.*phi_new_vec)/2.) phi_new=numpy.interp(phi,phi_old_vec,phi_new_vec) x=rad*numpy.cos(phi_new) y=rad*numpy.sin(phi_new) rad=numpy.sqrt(x**2 + y**2) phi=numpy.arctan2(y,x) vel=self.omega*rad vx=-vel*numpy.sin(phi) vy= vel*numpy.cos(phi) vz=0. mass=numpy.ones_like(x)/self.actualN Ep=3./5 self.internalE=Ep*self.ethep_ratio internal_energy=numpy.ones_like(x)*self.internalE return (mass,x,y,z,vx,vy,vz,internal_energy)
def new_sph_particles_from_stellar_wind(stars, mgas): new_sph = datamodel.Particles(0) for si in stars: Ngas = int(-si.Mwind / mgas) if Ngas == 0: continue Mgas = mgas * Ngas si.Mwind += Mgas add = datamodel.Particles(Ngas) add.mass = mgas add.h_smooth = 0.0 | units.parsec dx, dy, dz = uniform_unit_sphere(Ngas).make_xyz() add.x = si.x + (dx * si.radius) add.y = si.y + (dy * si.radius) add.z = si.z + (dz * si.radius) for ri in range(len(add)): r = add[ri].position - si.position r = r / r.length() v_wind = (constants.G * si.mass / (add[ri].position - si.position).length()).sqrt() add.u = 0.5 * (v_wind) ** 2 add.vx = si.vx + r[0] * si.terminal_wind_velocity add.vy = si.vy + r[1] * si.terminal_wind_velocity add.vz = si.vz + r[2] * si.terminal_wind_velocity new_sph.add_particles(add) return new_sph
def new_sph_particles_from_stellar_wind(stars, mgas): new_sph = datamodel.Particles(0) for si in stars: Ngas = int(-si.Mwind / mgas) if Ngas == 0: continue Mgas = mgas * Ngas si.Mwind += Mgas si.mass -= Mgas add = datamodel.Particles(Ngas) add.mass = mgas add.h_smooth = 0. | units.parsec dx, dy, dz = uniform_unit_sphere(Ngas).make_xyz() add.x = si.x + (dx * si.wind_radius) add.y = si.y + (dy * si.wind_radius) add.z = si.z + (dz * si.wind_radius) for ri in range(len(add)): r = add[ri].position - si.position r = r / r.length() v_wind = (constants.G * si.mass / (add[ri].position - si.position).length()).sqrt() add[ri].u = 0.5 * (v_wind)**2 add[ri].vx = si.vx + r[0] * si.terminal_wind_velocity add[ri].vy = si.vy + r[1] * si.terminal_wind_velocity add[ri].vz = si.vz + r[2] * si.terminal_wind_velocity new_sph.add_particles(add) return new_sph
def new_model(self): if self.seed is not None: numpy.random.seed(self.seed) vx_field = random_field(self.nf, self.power) vy_field = random_field(self.nf, self.power) vz_field = random_field(self.nf, self.power) vx_field, vy_field, vz_field = make_div_free(self.nf, vx_field, vy_field, vz_field) base_sphere = uniform_unit_sphere(self.targetN, base_grid=self.base_grid) x, y, z = base_sphere.make_xyz() self.actualN = len(x) vx = interpolate_trilinear(x, y, z, vx_field) vy = interpolate_trilinear(x, y, z, vy_field) vz = interpolate_trilinear(x, y, z, vz_field) mass = numpy.ones_like(x) / self.actualN vx = vx - vx.mean() vy = vy - vy.mean() vz = vz - vz.mean() Ep = 3. / 5 self.internalE = Ep * self.ethep_ratio Ek = 0.5 * mass[0] * (vx**2 + vy**2 + vz**2).sum() vfac = sqrt(self.ekep_ratio * Ep / Ek) vx = vx * vfac vy = vy * vfac vz = vz * vfac Ek = 0.5 * mass[0] * (vx**2 + vy**2 + vz**2).sum() internal_energy = numpy.ones_like(x) * self.internalE return (mass, x, y, z, vx, vy, vz, internal_energy)
def new_model(self): base_sphere = uniform_unit_sphere(self.targetN, base_grid=self.base_grid) x_uni, y_uni, z = base_sphere.make_xyz() self.actualN = len(x_uni) rad = numpy.sqrt(x_uni**2 + y_uni**2) phi = numpy.arctan2(y_uni, x_uni) n_vec = 2000 phi_new_vec = numpy.linspace(-numpy.pi, numpy.pi, n_vec) phi_old_vec = phi_new_vec + self.rho_peturb * ( numpy.sin(2. * phi_new_vec) / 2.) phi_new = numpy.interp(phi, phi_old_vec, phi_new_vec) x = rad * numpy.cos(phi_new) y = rad * numpy.sin(phi_new) rad = numpy.sqrt(x**2 + y**2) phi = numpy.arctan2(y, x) vel = self.omega * rad vx = -vel * numpy.sin(phi) vy = vel * numpy.cos(phi) vz = 0. mass = numpy.ones_like(x) / self.actualN Ep = 3. / 5 self.internalE = Ep * self.ethep_ratio internal_energy = numpy.ones_like(x) * self.internalE return (mass, x, y, z, vx, vy, vz, internal_energy)
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 new_sph_particles_from_stellar_wind(stars, mgas): new_sph = datamodel.Particles(0) for si in stars: p = si.position v = si.velocity Ngas = int(-si.Mwind / mgas) print("new Ngas=", si.mass, Ngas, end=' ') if Ngas == 0: continue Mgas = mgas * Ngas si.Mwind += Mgas # Ngas = 10 # mgas = Mgas/10. print("new Ngas=", Ngas, mgas) add = datamodel.Particles(Ngas) add.mass = mgas add.h_smooth = 0. | units.parsec dx, dy, dz = uniform_unit_sphere(Ngas).make_xyz() add.x = si.x + (dx * si.radius) add.y = si.y + (dy * si.radius) add.z = si.z + (dz * si.radius) for ri in range(len(add)): r = add[ri].position - p r = r / r.length() v_wind = (constants.G * si.mass / (add[ri].position - p).length()).sqrt() add.u = 0.5 * (v_wind)**2 v_wind = si.terminal_wind_velocity add.vx = v.x + r[0] * v_wind add.vy = v.y + r[1] * v_wind add.vz = v.z + r[2] * v_wind new_sph.add_particles(add) return new_sph
def __init__(self, targetN, convert_nbody = None, base_grid=None, rscale=1/1.695, mass_cutoff = 0.999, do_scale = False): self.targetN = targetN self.convert_nbody = convert_nbody self.rscale=rscale self.mass_frac=mass_cutoff self.do_scale = do_scale self.internal_energy = 0.25 / self.rscale self.base_sphere=uniform_unit_sphere(targetN,base_grid)
def __init__(self, targetN, convert_nbody=None, base_grid=None, rscale=1/1.695, mass_cutoff=0.999, do_scale=False): self.targetN = targetN self.convert_nbody = convert_nbody self.rscale = rscale self.mass_frac = mass_cutoff # self.do_scale = do_scale # self.internal_energy = 0.25 / self.rscale self.base_sphere = uniform_unit_sphere(targetN, base_grid)
def __init__(self, targetN, convert_nbody = None, base_grid=None, rscale=1/1.695, mass=1.,seed=345672,mass_frac=.999): numpy.random.seed(seed) self.targetN = targetN self.convert_nbody = convert_nbody self.rscale=rscale self.mass=mass self.mass_frac=mass_frac self.internal_energy=0.25*self.mass/self.rscale self.base_sphere=uniform_unit_sphere(targetN,base_grid)
def __init__(self, targetN, convert_nbody=None, base_grid=None, rscale=1 / 1.695, mass=1., seed=345672, mass_frac=.999): numpy.random.seed(seed) self.targetN = targetN self.convert_nbody = convert_nbody self.rscale = rscale self.mass = mass self.mass_frac = mass_frac self.internal_energy = 0.25 * self.mass / self.rscale self.base_sphere = uniform_unit_sphere(targetN, base_grid)
def iliev_test_5_ic(N=10000, Ns=10, L=15. | units.kpc): """ iliev test 5 particle distributions N= number of gas part Ns= number of sources (recommended to be order 10 for smoothrad distribution L=half boxsize """ mp = rhoinit*(2*L)**3/N # x,y,z=uniform_random_unit_cube(N).make_xyz() x, y, z = glass(N, target_rms=0.05) p = datamodel.Particles(N) p.x = L*x p.y = L*y p.z = L*z p.h_smooth = 0. | units.parsec p.vx = 0. | (units.km/units.s) p.vy = 0. | (units.km/units.s) p.vz = 0. | (units.km/units.s) p.u = uinit p.rho = rhoinit p.mass = mp p.flux = 0. | (units.s**-1) p.xion = 0. sources = datamodel.Particles(Ns) x, y, z = uniform_unit_sphere(Ns).make_xyz() sources.x = L*x*(1./N)**(1./3)/10 sources.y = L*y*(1./N)**(1./3)/10 sources.z = L*z*(1./N)**(1./3)/10 sources.rho = rhoinit/100. sources.flux = (5.e48/Ns) | (units.s**-1) sources.xion = 1. return p, sources
def random_positions(N, rmin, rmax): """ The particles start out in a random position between the surface of the star and the distance that the previously released particles have reached. This assumes that the current wind velocity is comparable to the previous wind velocity. Note that the stellar position is not added yet here. TODO: consider optimizing this by making a large pool once, and draw positions from that. """ random_positions = numpy.transpose(uniform_unit_sphere(N).make_xyz()) vector_lengths = numpy.sqrt((random_positions**2).sum(1)) unit_vectors = random_positions/as_three_vector(vector_lengths) distance = rmin + (vector_lengths * rmax) position = unit_vectors * as_three_vector(distance) return position, unit_vectors
def iliev_test_5_ic(N=10000, Ns=10, L=15. | units.kpc): """ iliev test 5 particle distributions N= number of gas part Ns= number of sources (recommended to be order 10 for smoothrad distribution L=half boxsize """ mp = rhoinit * (2 * L)**3 / N # x,y,z=uniform_random_unit_cube(N).make_xyz() x, y, z = glass(N, target_rms=0.05) p = datamodel.Particles(N) p.x = L * x p.y = L * y p.z = L * z p.h_smooth = 0. | units.parsec p.vx = 0. | (units.km / units.s) p.vy = 0. | (units.km / units.s) p.vz = 0. | (units.km / units.s) p.u = uinit p.rho = rhoinit p.mass = mp p.flux = 0. | (units.s**-1) p.xion = 0. sources = datamodel.Particles(Ns) x, y, z = uniform_unit_sphere(Ns).make_xyz() sources.x = L * x * (1. / N)**(1. / 3) / 10 sources.y = L * y * (1. / N)**(1. / 3) / 10 sources.z = L * z * (1. / N)**(1. / 3) / 10 sources.rho = rhoinit / 100. sources.flux = (5.e48 / Ns) | (units.s**-1) sources.xion = 1. return p, sources
def iliev_test_7_ic(N=10000, Ns=10, L=6.6 | units.kpc): print "Initializing iliev_test_7" mp = rhoinit * (2 * L)**3 / N Nc = ((rhoclump * 4 * constants.pi / 3 * (0.8 | units.kpc)**3) / mp) Nc = int(Nc) print Nc try: f = open("glass%9.9i.pkl" % N, "rb") x, y, z = cPickle.load(f) f.close() except: x, y, z = glass_unit_cube(N, target_rms=0.05).make_xyz() f = open("glass%9.9i.pkl" % N, "wb") cPickle.dump((x, y, z), f) f.close() sel = numpy.where(((x - (5. / 6.6))**2 + y**2 + z**2)**0.5 > (0.8 / 6.6))[0] x = x[sel] y = y[sel] z = z[sel] p = Particles(len(x)) print len(x) # set particles homogeneously in space p.x = L * x p.y = L * y p.z = L * z # set other properties p.h_smooth = 0. | units.parsec p.vx = 0. | (units.km / units.s) p.vy = 0. | (units.km / units.s) p.vz = 0. | (units.km / units.s) p.u = uinit p.rho = rhoinit p.mass = mp p.flux = 0. | (units.s**-1) p.xion = 0. | units.none sources = Particles(Ns) x, y, z = uniform_unit_sphere(Ns).make_xyz() if Ns == 1: x, y, z = 0., 0., 0. sources.x = L * x * (1. / N)**(1. / 3) / 10 sources.y = L * y * (1. / N)**(1. / 3) / 10 sources.z = L * z * (1. / N)**(1. / 3) / 10 sources.luminosity = (1.2e52 / Ns) | (units.s**-1) sources.SpcType = 1. clump = core.Particles(Nc) x, y, z = uniform_unit_sphere(Nc).make_xyz() clump.x = (5. | units.kpc) + (0.8 | units.kpc) * x clump.y = (0.8 | units.kpc) * y clump.z = (0.8 | units.kpc) * z clump.h_smooth = 0. | units.parsec clump.vx = 0. | (units.km / units.s) clump.vy = 0. | (units.km / units.s) clump.vz = 0. | (units.km / units.s) clump.u = uclump clump.rho = rhoclump clump.mass = mp clump.flux = 0. | (units.s**-1) clump.xion = 0. | units.none p.add_particles(clump) return p, sources
def mechanical_feedback(self): star_particles = self.star_particles.copy_to_memory() channel = self.particles.new_channel_to(star_particles) channel.copy_attributes(["x", "y", "z", "vx", "vy", "vz"]) channel.copy_attribute("mass", "grav_mass") del channel channel = self.star_particles_addition.new_channel_to(star_particles) channel.copy_attribute("Emech_last_feedback") del channel new_sph = datamodel.Particles(0) star_particles.dmass = star_particles.grav_mass - star_particles.mass star_particles.u = ( star_particles.Emech - star_particles.Emech_last_feedback) / star_particles.dmass if numpy.any((star_particles.Emech - star_particles.Emech_last_feedback) < zero): print "feedback error" raise Exception losers = star_particles.select_array(lambda x: x > self.mgas, ["dmass"]) while len(losers) > 0: add = datamodel.Particles(len(losers)) add.mass = self.mgas add.h_smooth = 0. | units.parsec dx, dy, dz = uniform_unit_sphere(len(losers)).make_xyz() add.x = losers.x + self.feedback_radius * dx add.y = losers.y + self.feedback_radius * dy add.z = losers.z + self.feedback_radius * dz add.vx = losers.vx add.vy = losers.vy add.vz = losers.vz add.u = self.feedback_efficiency * losers.u losers.grav_mass -= self.mgas losers.Emech_last_feedback += self.mgas * losers.u new_sph.add_particles(add) losers = star_particles.select_array( lambda x, y: x - y > self.mgas, ["grav_mass", "mass"]) print "gas particles added:", len(new_sph) if len(new_sph) == 0: return zero self.sph.gas_particles.add_particles(new_sph) feedback_energy_added = (new_sph.mass * new_sph.u).sum() self.total_feedback_energy = self.total_feedback_energy + feedback_energy_added channel = star_particles.new_channel_to(self.particles) channel.copy_attribute("grav_mass", "mass") del channel channel = star_particles.new_channel_to(self.star_particles_addition) channel.copy_attribute("Emech_last_feedback") del channel return feedback_energy_added