class comsystem(baseclass): def __init__(self,*args,**kwargs): self.particles_accessed=True self._particles=Particles(0) baseclass.__init__(self,*args,**kwargs) def evolve_model(self,*args,**kwargs): if self.particles_accessed: self.com_position=self._particles.center_of_mass() self.com_velocity=self._particles.center_of_mass_velocity() com_time=self.model_time self._particles.synchronize_to(self.overridden().particles) self._particles.new_channel_to(self.overridden().particles).copy_attributes(["mass","radius"]) self.overridden().particles.position=self._particles.position-self.com_position self.overridden().particles.velocity=self._particles.velocity-self.com_velocity self.overridden().evolve_model(*args,**kwargs) self.com_position+=self.com_velocity*(self.model_time-com_time) self.particles_accessed=False @property def particles(self): if not self.particles_accessed: self._particles=self.overridden().particles.copy() self._particles.position+=self.com_position self._particles.velocity+=self.com_velocity self.particles_accessed=True return self._particles
class comsystem(baseclass): def __init__(self, *args, **kwargs): self.particles_accessed = True self._particles = Particles(0) baseclass.__init__(self, *args, **kwargs) def evolve_model(self, *args, **kwargs): if self.particles_accessed: self.com_position = self._particles.center_of_mass() self.com_velocity = self._particles.center_of_mass_velocity() com_time = self.model_time self._particles.synchronize_to(self.overridden().particles) self._particles.new_channel_to( self.overridden().particles).copy_attributes( ["mass", "radius"]) self.overridden( ).particles.position = self._particles.position - self.com_position self.overridden( ).particles.velocity = self._particles.velocity - self.com_velocity self.overridden().evolve_model(*args, **kwargs) self.com_position += self.com_velocity * (self.model_time - com_time) self.particles_accessed = False @property def particles(self): if not self.particles_accessed: self._particles = self.overridden().particles.copy() self._particles.position += self.com_position self._particles.velocity += self.com_velocity self.particles_accessed = True return self._particles
def setup_particles_in_nbodycode(self): staggered_grid_shape = numpy.asarray(self.gridcode.grid.shape) + 2 corner0 = self.gridcode.grid[0][0][0].position corner1 = self.gridcode.grid[-1][-1][-1].position delta = self.gridcode.grid[1][1][1].position - corner0 print delta.prod() self.volume = delta.prod() staggered_corner0 = corner0 - delta staggered_corner1 = corner1 self.staggered_grid = Grid.create( staggered_grid_shape, staggered_corner1 - staggered_corner0 + delta) #self.staggered_grid.x += staggered_corner0.x #self.staggered_grid.y += staggered_corner0.x #self.staggered_grid.z += staggered_corner0.x #self.staggered_grid.p000 = 0.0 | mass #self.staggered_grid.p100 = 0.0 | mass #self.staggered_grid.p010 = 0.0 | mass #self.staggered_grid.p110 = 0.0 | mass #self.staggered_grid.p000 = 0.0 | mass #self.staggered_grid.p100 = 0.0 | mass #self.staggered_grid.p011 = 0.0 | mass #self.staggered_grid.p111 = 0.0 | mass #self.staggered_grid.p001 = 0.0 | mass #self.staggered_grid.p101 = 0.0 | mass self.normal_grid = Grid.create(self.gridcode.grid.shape, corner1 - corner0 + delta) particles = Particles(self.normal_grid.size) particles.mass = 0.0 | mass particles.x = self.grid.x.flatten() particles.y = self.grid.y.flatten() particles.z = self.grid.z.flatten() particles.vx = 0.0 | speed particles.vy = 0.0 | speed particles.vz = 0.0 | speed particles.radius = 0.0 | length self.nbodycode.particles.add_particles(particles) self.from_model_to_nbody = particles.new_channel_to( self.nbodycode.particles) self.nbodycode.commit_particles() self.particles = particles
def setup_particles_in_nbodycode(self): staggered_grid_shape = numpy.asarray(self.gridcode.grid.shape) + 2 corner0 = self.gridcode.grid[0][0][0].position corner1 = self.gridcode.grid[-1][-1][-1].position delta = self.gridcode.grid[1][1][1].position - corner0 print delta.prod() self.volume = delta.prod() staggered_corner0 = corner0 - delta staggered_corner1 = corner1 self.staggered_grid = Grid.create( staggered_grid_shape, staggered_corner1 - staggered_corner0 + delta) # self.staggered_grid.x += staggered_corner0.x # self.staggered_grid.y += staggered_corner0.x # self.staggered_grid.z += staggered_corner0.x # self.staggered_grid.p000 = 0.0 | mass # self.staggered_grid.p100 = 0.0 | mass # self.staggered_grid.p010 = 0.0 | mass # self.staggered_grid.p110 = 0.0 | mass # self.staggered_grid.p000 = 0.0 | mass # self.staggered_grid.p100 = 0.0 | mass # self.staggered_grid.p011 = 0.0 | mass # self.staggered_grid.p111 = 0.0 | mass # self.staggered_grid.p001 = 0.0 | mass # self.staggered_grid.p101 = 0.0 | mass self.normal_grid = Grid.create( self.gridcode.grid.shape, corner1 - corner0 + delta) particles = Particles(self.normal_grid.size) particles.mass = 0.0 | mass particles.x = self.grid.x.flatten() particles.y = self.grid.y.flatten() particles.z = self.grid.z.flatten() particles.vx = 0.0 | speed particles.vy = 0.0 | speed particles.vz = 0.0 | speed particles.radius = 0.0 | length self.nbodycode.particles.add_particles(particles) self.from_model_to_nbody = particles.new_channel_to( self.nbodycode.particles) self.nbodycode.commit_particles() self.particles = particles
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, integrator, t_stellar, dt_se, dtse_fac, interp): import random from amuse.ext.solarsystem import get_position numpy.random.seed(42) print("Initial masses:", M1, M2, M3) triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) # Evolve to t_stellar. stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print("t=", stellar.model_time.in_(units.Myr)) print("M=", stellar.particles.mass.in_(units.MSun)) print("R=", stellar.particles.radius.in_(units.RSun)) print("L=", stellar.particles.luminosity.in_(units.LSun)) print("T=", stellar.particles.temperature.in_(units.K)) print("Mdot=", \ -stellar.particles.wind_mass_loss_rate.in_(units.MSun/units.yr)) # Start the dynamics. # Inner binary: tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print('Pin =', Pin_0) print('ain_0 =', ain_0) print('M1+M2 =', M1+M2) print('Pin_0 =', Pin_0.value_in(units.day), '[day]') #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt_init = 0.01*Pin_0 ma = 180 inc = 60 aop = 180 lon = 0 r,v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt_init) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary: r,v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt_init) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print("T=", stellar.model_time.in_(units.Myr)) print("M=", stellar.particles.mass.in_(units.MSun)) print("Pout=", Pout.in_(units.Myr)) print('tK =', ((M1+M2)/M3)*Pout**2*(1-eout_0**2)**1.5/Pin_0) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) if integrator == 0: gravity = Hermite(converter) gravity.parameters.timestep_parameter = 0.01 elif integrator == 1: gravity = SmallN(converter) gravity.parameters.timestep_parameter = 0.01 gravity.parameters.full_unperturbed = 0 elif integrator == 2: gravity = Huayno(converter) gravity.parameters.inttype_parameter = 20 gravity.parameters.timestep = (1./256)*Pin_0 else: gravity = symple(converter) gravity.parameters.integrator = 10 #gravity.parameters.timestep_parameter = 0. gravity.parameters.timestep = (1./128)*Pin_0 print(gravity.parameters) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() # Note: time = t_diag = 0 at the start of the dynamical integration. dt_diag = t_end/float(nsteps) t_diag = dt_diag time = 0.0 | t_end.unit t_se = t_stellar + time print('t_end =', t_end) print('dt_diag =', dt_diag) ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print("Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout) t = [time.value_in(units.Myr)] Mtot = triple.mass.sum() mtot = [Mtot.value_in(units.MSun)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] if interp: # Create arrays of stellar times and masses for interpolation. times = [time] masses = [triple.mass.copy()] while time < t_end: time += dt_se stellar.evolve_model(t_stellar+time) channel_from_stellar.copy_attributes(["mass"]) times.append(time) masses.append(triple.mass.copy()) time = 0.0 | t_end.unit print('\ntimes:', times, '\n') # Evolve the system. def advance_stellar(t_se, dt): E0 = gravity.kinetic_energy + gravity.potential_energy t_se += dt if interp: t = t_se-t_stellar i = int(t/dt_se) mass = masses[i] + (t-times[i])*(masses[i+1]-masses[i])/dt_se triple.mass = mass #print 't_se =', t_se, 'masses =', mass else: stellar.evolve_model(t_se) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return t_se, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: if scheme == 1: # Advance to the next diagnostic time. dE_se = zero dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) elif scheme == 2: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, dt) time = advance_gravity(time, dt) elif scheme == 3: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) t_se, dE_se = advance_stellar(t_se, dt) elif scheme == 4: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, 0.5*dt) time = advance_gravity(time, dt) t_se, dE_se2 = advance_stellar(t_se, 0.5*dt) dE_se += dE_se2 elif scheme == 5: # Use the specified dt_se. dE_se = zero dt = dt_se if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: # For use with symple only: set up average mass loss. channel_from_stellar.copy_attributes(["mass"]) m0 = triple.mass.copy() stellar.evolve_model(t_se+dt) channel_from_stellar.copy_attributes(["mass"]) t_se = stellar.model_time m1 = triple.mass dmdt = (m1-m0)/dt for i in range(len(dmdt)): gravity.set_dmdt(i, dmdt[i]) time = advance_gravity(time, dt) else: print('unknown option') sys.exit(0) if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print("T=", time, end=' ') print("M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", end=' ') print("E= ", Etot, "Q= ", Ekin/Epot, end=' ') print("dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, end=' ') print("(dE[SE]=", dE_se/Etot, ")") Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print("Triple elements t=", t_stellar + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout) t.append(time.value_in(units.yr)) mtot.append(Mtot.value_in(units.MSun)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1 or aout <= zero: print("Binary ionized or merged") break gravity.stop() stellar.stop() return t, mtot, smai, ecci, smao, ecco
def main(): numpy.random.seed(42) evo_headstart = 0.0 | units.Myr dt_base = 0.001 | units.Myr dt = dt_base time = 0 | units.Myr time_end = 8 | units.Myr Tmin = 22 | units.K gas_density = 5e3 | units.amu * units.cm**-3 increase_vol = 2 Ngas = increase_vol**3 * 10000 Mgas = increase_vol**3 * 1000 | units.MSun # Mgas = Ngas | units.MSun volume = Mgas / gas_density # 4/3 * pi * r**3 radius = (volume / (pi * 4/3))**(1/3) radius = increase_vol * radius # 15 | units.parsec gasconverter = nbody_system.nbody_to_si(Mgas, radius) # gasconverter = nbody_system.nbody_to_si(1 | units.pc, 1 | units.MSun) # gasconverter = nbody_system.nbody_to_si(1e10 | units.cm, 1e10 | units.g) # NOTE: make stars first - so that it remains the same random # initialisation even when we change the number of gas particles if len(sys.argv) > 1: gas = read_set_from_file(sys.argv[1], "amuse") stars = read_set_from_file(sys.argv[2], "amuse") stars.position = stars.position * 3 else: # stars = new_star_cluster( # stellar_mass=1000 | units.MSun, effective_radius=3 | units.parsec # ) # stars.velocity = stars.velocity * 2.0 from amuse.datamodel import Particles Nstars = 100 stars = Particles(Nstars) stars.position = [0, 0, 0] | units.pc stars.velocity = [0, 0, 0] | units.kms stars.mass = new_kroupa_mass_distribution(Nstars, mass_min=1 | units.MSun).reshape(Nstars) # 25 | units.MSun gas = molecular_cloud(targetN=Ngas, convert_nbody=gasconverter).result # gas.velocity = gas.velocity * 0.5 gas.u = temperature_to_u(100 | units.K) # gas.x = gas.x # gas.y = gas.y # gas.z = gas.z # gas.h_smooth = (gas.mass / gas_density / (4/3) / pi)**(1/3) # print(gas.h_smooth.mean()) # gas = read_set_from_file("gas_initial.hdf5", "amuse") # gas.density = gas_density # print(gas.h_smooth.mean()) # exit() u_now = gas.u #print(gasconverter.to_nbody(gas[0].u)) #print(constants.kB.value_in(units.erg * units.K**-1)) #print((constants.kB * 6.02215076e23).value_in(units.erg * units.K**-1)) #print(gasconverter.to_nbody(temperature_to_u(10 | units.K))) #tempiso = 2.d0/3.d0*ui/(Rg/gmwvar/uergg) # print(nbody_system.length**2 / nbody_system.time**2) # print(gasconverter.to_si(1 | nbody_system.length**2 / nbody_system.time**2).value_in(units.kms**2)) # print(gasconverter.to_nbody(temperature_to_u(Tmin))) # Rg = (constants.kB * 6.02214076e23).value_in(units.erg * units.K**-1) # gmwvar = 1.2727272727 # uergg = nbody_system.length**2 * nbody_system.time**-2 # uergg = 6.6720409999999996E-8 # print(Rg) # print( # 2.0/3.0*gasconverter.to_nbody(temperature_to_u(Tmin))/(Rg/gmwvar/uergg) # ) # #tempiso, ui, Rg, gmwvar, uergg, udist, utime 1.7552962911187030E-018 2.5778500859241771E-003 83140000.000000000 1.2727272727272725 6.6720409999999996E-008 1.0000000000000000 3871.4231866737564 # u = 3./2. * Tmin.value_in(units.K) * (Rg/gmwvar/uergg) # print(u) # print( # 2.0/3.0*u/(Rg/gmwvar/uergg) # ) # print(u, Rg, gmwvar, uergg) # print(temperature_to_u(10 | units.K).value_in(units.kms**2)) u = temperature_to_u(20 | units.K) #print(gasconverter.to_nbody(u)) #print(u_to_temperature(u).value_in(units.K)) # exit() # gas.u = u | units.kms**2 # exit() # print(gasconverter.to_nbody(gas.u.mean())) # print(gasconverter.to_si(gas.u.mean()).value_in(units.kms**2)) # exit() gas.du_dt = (u_now - u_now) / dt # zero, but in the correct units # stars = read_set_from_file("stars.amuse", "amuse") # write_set_to_file(stars, 'stars.amuse', 'amuse', append_to_file=False) # stars.velocity *= 3 # stars.vx += 0 | units.kms # stars.vy += 0 | units.kms M = stars.total_mass() + Mgas R = stars.position.lengths().mean() converter = nbody_system.nbody_to_si(M, R) # exit() # gas = new_plummer_gas_model(Ngas, gasconverter) # gas = molecular_cloud(targetN=Ngas, convert_nbody=gasconverter).result # gas.u = temperature_to_u(Tmin) # gas = read_set_from_file("gas.amuse", "amuse") # print(stars.mass == stars.mass.max()) print(len(stars.mass)) print(len(stars.mass == stars.mass.max())) print(stars[0]) print(stars[stars.mass == stars.mass.max()]) mms = stars[stars.mass == stars.mass.max()] print("Most massive star: %s" % mms.mass) print("Gas particle mass: %s" % gas[0].mass) evo = SeBa() # sph = Fi(converter, mode="openmp") phantomconverter = nbody_system.nbody_to_si( default_settings.gas_rscale, default_settings.gas_mscale, ) sph = Phantom(phantomconverter, redirection="none") sph.parameters.ieos = 2 sph.parameters.icooling = 1 sph.parameters.alpha = 0.1 sph.parameters.gamma = 5/3 sph.parameters.rho_crit = 1e17 | units.amu * units.cm**-3 sph.parameters.h_soft_sinkgas = 0.1 | units.parsec sph.parameters.h_soft_sinksink = 0.1 | units.parsec sph.parameters.h_acc = 0.1 | units.parsec # print(sph.parameters) stars_in_evo = evo.particles.add_particles(stars) channel_stars_evo_from_code = stars_in_evo.new_channel_to( stars, attributes=[ "age", "radius", "mass", "luminosity", "temperature", "stellar_type", ], ) channel_stars_evo_from_code.copy() # try: # sph.parameters.timestep = dt # except: # print("SPH code doesn't support setting the timestep") sph.parameters.stopping_condition_maximum_density = \ 5e-16 | units.g * units.cm**-3 # sph.parameters.beta = 1. # sph.parameters.C_cour = sph.parameters.C_cour / 4 # sph.parameters.C_force = sph.parameters.C_force / 4 print(sph.parameters) stars_in_sph = stars.copy() # sph.sink_particles.add_particles(stars) # stars_in_sph = sph.sink_particles.add_particles(stars) channel_stars_grav_to_code = stars.new_channel_to( # sph.sink_particles, # sph.dm_particles, stars_in_sph, attributes=["mass"] ) channel_stars_grav_from_code = stars_in_sph.new_channel_to( stars, attributes=["x", "y", "z", "vx", "vy", "vz"], ) # We don't want to accrete gas onto the stars/sinks stars_in_sph.radius = 0 | units.RSun # stars_in_sph = sph.dm_particles.add_particles(stars) # try: # sph.parameters.isothermal_flag = True # sph.parameters.integrate_entropy_flag = False # sph.parameters.gamma = 1 # except: # print("SPH code doesn't support setting isothermal flag") gas_in_code = sph.gas_particles.add_particles(gas) # print(gasconverter.to_nbody(gas_in_code[0].u).value_in(nbody_system.specific_energy)) # ui = temperature_to_u(10 | units.K) # Rg = constants.kB * 6.02214179e+23 # gmwvar = (1.4/1.1) | units.g # uergg = 1.# | nbody_system.specific_energy # print("gmwvar = %s"%gasconverter.to_si(gmwvar)) # print("Rg = %s"% gasconverter.to_si(Rg)) # print("ui = %s"% gasconverter.to_si(ui)) # #print("uergg = %s"% gasconverter.to_nbody(uergg)) # print("uergg = %s" % gasconverter.to_si(1 | nbody_system.specific_energy).in_(units.cm**2 * units.s**-2)) # print("****** %s" % ((2.0/3.0)*ui/(Rg/gmwvar/uergg)) + "*****") # print(gasconverter.to_nbody(Rg)) # print((ui).in_(units.cm**2*units.s**-2)) # #exit() # sph.evolve_model(1 | units.day) # write_set_to_file(sph.gas_particles, "gas_initial.hdf5", "amuse") # exit() channel_gas_to_code = gas.new_channel_to( gas_in_code, attributes=[ "x", "y", "z", "vx", "vy", "vz", "u", ] ) # mass is never updated, and if sph is in isothermal mode u is not reliable channel_gas_from_code = gas_in_code.new_channel_to( gas, attributes=[ "x", "y", "z", "vx", "vy", "vz", "density", "pressure", "rho", "u", "h_smooth", ], ) channel_gas_from_code.copy() # Initialise values for density etc sph_particle_mass = gas[0].mass # 0.1 | units.MSun r_max = 0.1 | units.parsec wind = stellar_wind.new_stellar_wind( sph_particle_mass, mode="heating", r_max=r_max, derive_from_evolution=True, tag_gas_source=True, # target_gas=gas, # timestep=dt, ) stars_in_wind = wind.particles.add_particles(stars) channel_stars_wind_to_code = stars.new_channel_to( stars_in_wind, attributes=[ "x", "y", "z", "vx", "vy", "vz", "age", "radius", "mass", "luminosity", "temperature", "stellar_type", ], ) channel_stars_wind_to_code.copy() # reference_mu = 2.2 | units.amu gasvolume = (4./3.) * numpy.pi * ( gas.position - gas.center_of_mass() ).lengths().mean()**3 rho0 = gas.total_mass() / gasvolume print(rho0.value_in(units.g * units.cm**-3)) # exit() # cooling_flag = "thermal_model" # cooling = Cooling( cooling = SimplifiedThermalModelEvolver( # gas_in_code, gas, Tmin=Tmin, # T0=30 | units.K, # n0=rho0/reference_mu ) cooling.model_time = sph.model_time # cooling_to_code = cooling.particles.new_channel_to(gas start_mass = ( stars.mass.sum() + (gas.mass.sum() if not gas.is_empty() else 0 | units.MSun) ) step = 0 plotnr = 0 com = stars_in_sph.center_of_mass() plot_hydro_and_stars( time, sph, stars=stars, sinks=None, L=20, # N=100, filename="phantom-coolthermalwindtestplot-%04i.png" % step, title="time = %06.2f %s" % (time.value_in(units.Myr), units.Myr), gasproperties=["density", "temperature"], # colorbar=True, starscale=1, offset_x=com[0].value_in(units.parsec), offset_y=com[1].value_in(units.parsec), thickness=5 | units.parsec, ) dt = dt_base sph.parameters.time_step = dt delta_t = phantomconverter.to_si(2**(-16) | nbody_system.time) print("delta_t: %s" % delta_t.in_(units.day)) # small_step = True small_step = False plot_every = 100 subplot_factor = 10 subplot_enabled = False subplot = 0 while time < time_end: time += dt print("Gas mean u: %s" % (gas.u.mean().in_(units.erg/units.MSun))) print("Evolving to t=%s (%s)" % (time, gasconverter.to_nbody(time))) step += 1 evo.evolve_model(evo_headstart+time) print(evo.particles.stellar_type.max()) channel_stars_evo_from_code.copy() channel_stars_grav_to_code.copy() if COOLING: channel_gas_from_code.copy() cooling.evolve_for(dt/2) channel_gas_to_code.copy() print( "min/max temp in gas: %s %s" % ( u_to_temperature(gas_in_code.u.min()).in_(units.K), u_to_temperature(gas_in_code.u.max()).in_(units.K), ) ) if small_step: # Take small steps until a full timestep is done. # Each substep is 2* as long as the last until dt is reached print("Doing small steps") # print(u_to_temperature(sph.gas_particles[0].u)) # print(sph.gas_particles[0].u) old_dt = dt_base substeps = 2**8 dt = old_dt / substeps dt_done = 0 * old_dt sph.parameters.time_step = dt print("adjusted dt to %s, base dt is %s" % ( dt.in_(units.Myr), dt_base.in_(units.Myr), ) ) sph.evolve_model(sph.model_time + dt) dt_done += dt while dt_done < old_dt: sph.parameters.time_step = dt print("adjusted dt to %s, base dt is %s" % ( dt.in_(units.Myr), dt_base.in_(units.Myr), ) ) sph.evolve_model(sph.model_time + dt) dt_done += dt dt = min(2*dt, old_dt-dt_done) dt = max(dt, old_dt/substeps) dt = dt_base sph.parameters.time_step = dt print( "adjusted dt to %s" % sph.parameters.time_step.in_(units.Myr) ) small_step = False print("Finished small steps") # print(u_to_temperature(sph.gas_particles[0].u)) # print(sph.gas_particles[0].u) # exit() else: sph.evolve_model(time) channel_gas_from_code.copy() channel_stars_grav_from_code.copy() u_previous = u_now u_now = gas.u gas.du_dt = (u_now - u_previous) / dt channel_stars_wind_to_code.copy() wind.evolve_model(time) # channel_stars_wind_from_code.copy() if COOLING: channel_gas_from_code.copy() cooling.evolve_for(dt/2) channel_gas_to_code.copy() if wind.has_new_wind_particles(): subplot_enabled = True wind_p = wind.create_wind_particles() # nearest = gas.find_closest_particle_to(wind_p.x, wind_p.y, wind_p.z) # wind_p.h_smooth = nearest.h_smooth wind_p.h_smooth = 100 | units.au print("u: %s / T: %s" % (wind_p.u.mean(), u_to_temperature(wind_p.u.mean()))) # max_e = (1e44 | units.erg) / wind_p[0].mass # max_e = 10 * gas.u.mean() # max_e = (1.e48 | units.erg) / wind_p[0].mass # wind_p[wind_p.u > max_e].u = max_e # wind_p[wind_p.u > max_e].h_smooth = 0.1 | units.parsec # print(wind_p.position) print( "time: %s, wind energy: %s" % (time, (wind_p.u * wind_p.mass).sum()) ) print( "wind temperature: %s" % (u_to_temperature(wind_p.u)) ) print( "gas particles: %i (total mass %s)" % (len(wind_p), wind_p.total_mass()) ) # for windje in wind_p: # # print(windje) # source = stars[stars.key == windje.source][0] # windje.position += source.position # windje.velocity += source.velocity # # print(source) # # print(windje) # # exit() gas.add_particles(wind_p) gas_in_code.add_particles(wind_p) # for wp in wind_p: # print(wp) print("Wind particles added") if True: # wind_p.u.max() > gas_in_code.u.max(): print("Setting dt to very short") small_step = True # dt = 0.1 | units.yr h_min = gas.h_smooth.min() # delta_t = determine_short_timestep(sph, wind_p, h_min=h_min) # print("delta_t is set to %s" % delta_t.in_(units.yr)) # else: # small_step = True print( "time: %s sph: %s dM: %s" % ( time.in_(units.Myr), sph.model_time.in_(units.Myr), ( stars.total_mass() + ( gas.total_mass() if not gas.is_empty() else (0 | units.MSun) ) - start_mass ) ) ) # com = sph.sink_particles.center_of_mass() # com = sph.dm_particles.center_of_mass() com = stars.center_of_mass() print("STEP: %i step%%plot_every: %i" % (step, step % plot_every)) if step % plot_every == 0: plotnr = plotnr + 1 plot_hydro_and_stars( time, sph, # stars=sph.sink_particles, # stars=sph.dm_particles, stars=stars, sinks=None, L=20, # N=100, # image_size_scale=10, filename="phantom-coolthermalwindtestplot-%04i.png" % plotnr, # int(step/plot_every), title="time = %06.2f %s" % (time.value_in(units.Myr), units.Myr), gasproperties=["density", "temperature"], # colorbar=True, starscale=1, offset_x=com[0].value_in(units.parsec), offset_y=com[1].value_in(units.parsec), thickness=5 | units.parsec, ) # write_set_to_file(gas, "gas.amuse", "amuse", append_to_file=False) # write_set_to_file(stars, "stars.amuse", "amuse", append_to_file=False) elif ( subplot_enabled and ((step % (plot_every/subplot_factor)) == 0) ): plotnr = plotnr + 1 subplot += 1 plot_hydro_and_stars( time, sph, # stars=sph.sink_particles, # stars=sph.dm_particles, stars=stars, sinks=None, L=20, # N=100, # image_size_scale=10, filename="phantom-coolthermalwindtestplot-%04i.png" % plotnr, # int(step/plot_every), title="time = %06.2f %s" % (time.value_in(units.Myr), units.Myr), gasproperties=["density", "temperature"], # colorbar=True, starscale=1, offset_x=com[0].value_in(units.parsec), offset_y=com[1].value_in(units.parsec), thickness=5 | units.parsec, ) if subplot % subplot_factor == 0: subplot_enabled = False print( "Average temperature of gas: %s" % ( u_to_temperature(gas.u).mean().in_(units.K) ) ) return
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, dtse_fac): import random from amuse.ext.solarsystem import get_position print "Initial masses:", M1, M2, M3 t_stellar = 4.0|units.Myr triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Masses at time T:", M1, M2, M3 # Inner binary tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print 'ain_0 =', ain_0 print 'M1+M2 =', M1+M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt = 0.1*Pin_0 ma = 180 inc = 30 aop = 180 lon = 0 r, v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary r, v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) gravity = Hermite(converter) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() time = 0.0 | t_end.unit ts = t_stellar + time ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout dt_diag = t_end/float(nsteps) t_diag = dt_diag t = [time.value_in(units.Myr)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] ain = ain_0 def advance_stellar(ts, dt): E0 = gravity.kinetic_energy + gravity.potential_energy ts += dt stellar.evolve_model(ts) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return ts, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: Pin = orbital_period(ain, triple[0].mass+triple[1].mass) dt = dtse_fac*Pin dt *= random.random() if scheme == 1: ts, dE_se = advance_stellar(ts, dt) time = advance_gravity(time, dt) elif scheme == 2: time = advance_gravity(time, dt) ts, dE_se = advance_stellar(ts, dt) else: dE_se = zero #ts, dE_se = advance_stellar(ts, dt/2) time = advance_gravity(time, dt) #ts, dE = advance_stellar(ts, dt/2) #dE_se += dE if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time, print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", print "E= ", Etot, "Q= ", Ekin/Epot, print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", (4|units.Myr) + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.Myr)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1.0 or aout <= zero: print "Binary ionized or merged" break gravity.stop() stellar.stop() return t, smai, ecci, smao, ecco
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, dtse_fac): import random from amuse.ext.solarsystem import get_position print "Initial masses:", M1, M2, M3 t_stellar = 4.0|units.Myr triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Masses at time T:", M1, M2, M3 # Inner binary tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print 'ain_0 =', ain_0 print 'M1+M2 =', M1+M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt = 0.1*Pin_0 ma = 180 inc = 30 aop = 180 lon = 0 r, v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary r, v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) gravity = Hermite(converter) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() time = 0.0 | t_end.unit ts = t_stellar + time ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout dt_diag = t_end/float(nsteps) t_diag = dt_diag t = [time.value_in(units.Myr)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] ain = ain_0 def advance_stellar(ts, dt): E0 = gravity.kinetic_energy + gravity.potential_energy ts += dt stellar.evolve_model(ts) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return ts, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: Pin = orbital_period(ain, triple[0].mass+triple[1].mass) dt = dtse_fac*Pin dt *= random.random() if scheme == 1: ts, dE_se = advance_stellar(ts, dt) time = advance_gravity(time, dt) elif scheme == 2: time = advance_gravity(time, dt) ts, dE_se = advance_stellar(ts, dt) else: dE_se = zero #ts, dE_se = advance_stellar(ts, dt/2) time = advance_gravity(time, dt) #ts, dE = advance_stellar(ts, dt/2) #dE_se += dE if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time, print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", print "E= ", Etot, "Q= ", Ekin/Epot, print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", (4|units.Myr) + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.Myr)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1.0 or aout <= zero: print "Binary ionized or merged" break gravity.stop() stellar.stop() return t, smai, ecci, smao, ecco
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, integrator, t_stellar, dt_se, dtse_fac, interp): import random from amuse.ext.solarsystem import get_position numpy.random.seed(42) print "Initial masses:", M1, M2, M3 triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) # Evolve to t_stellar. stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "t=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "R=", stellar.particles.radius.in_(units.RSun) print "L=", stellar.particles.luminosity.in_(units.LSun) print "T=", stellar.particles.temperature.in_(units.K) print "Mdot=", \ -stellar.particles.wind_mass_loss_rate.in_(units.MSun/units.yr) # Start the dynamics. # Inner binary: tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print 'Pin =', Pin_0 print 'ain_0 =', ain_0 print 'M1+M2 =', M1+M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt_init = 0.01*Pin_0 ma = 180 inc = 60 aop = 180 lon = 0 r,v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt_init) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary: r,v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt_init) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) print 'tK =', ((M1+M2)/M3)*Pout**2*(1-eout_0**2)**1.5/Pin_0 converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) if integrator == 0: gravity = Hermite(converter) gravity.parameters.timestep_parameter = 0.01 elif integrator == 1: gravity = SmallN(converter) gravity.parameters.timestep_parameter = 0.01 gravity.parameters.full_unperturbed = 0 elif integrator == 2: gravity = Huayno(converter) gravity.parameters.inttype_parameter = 20 gravity.parameters.timestep = (1./256)*Pin_0 else: gravity = symple(converter) gravity.parameters.integrator = 10 #gravity.parameters.timestep_parameter = 0. gravity.parameters.timestep = (1./128)*Pin_0 print gravity.parameters gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() # Note: time = t_diag = 0 at the start of the dynamical integration. dt_diag = t_end/float(nsteps) t_diag = dt_diag time = 0.0 | t_end.unit t_se = t_stellar + time print 't_end =', t_end print 'dt_diag =', dt_diag ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t = [time.value_in(units.Myr)] Mtot = triple.mass.sum() mtot = [Mtot.value_in(units.MSun)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] if interp: # Create arrays of stellar times and masses for interpolation. times = [time] masses = [triple.mass.copy()] while time < t_end: time += dt_se stellar.evolve_model(t_stellar+time) channel_from_stellar.copy_attributes(["mass"]) times.append(time) masses.append(triple.mass.copy()) time = 0.0 | t_end.unit print '\ntimes:', times, '\n' # Evolve the system. def advance_stellar(t_se, dt): E0 = gravity.kinetic_energy + gravity.potential_energy t_se += dt if interp: t = t_se-t_stellar i = int(t/dt_se) mass = masses[i] + (t-times[i])*(masses[i+1]-masses[i])/dt_se triple.mass = mass #print 't_se =', t_se, 'masses =', mass else: stellar.evolve_model(t_se) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return t_se, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: if scheme == 1: # Advance to the next diagnostic time. dE_se = zero dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) elif scheme == 2: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, dt) time = advance_gravity(time, dt) elif scheme == 3: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) t_se, dE_se = advance_stellar(t_se, dt) elif scheme == 4: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, 0.5*dt) time = advance_gravity(time, dt) t_se, dE_se2 = advance_stellar(t_se, 0.5*dt) dE_se += dE_se2 elif scheme == 5: # Use the specified dt_se. dE_se = zero dt = dt_se if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: # For use with symple only: set up average mass loss. channel_from_stellar.copy_attributes(["mass"]) m0 = triple.mass.copy() stellar.evolve_model(t_se+dt) channel_from_stellar.copy_attributes(["mass"]) t_se = stellar.model_time m1 = triple.mass dmdt = (m1-m0)/dt for i in range(len(dmdt)): gravity.set_dmdt(i, dmdt[i]) time = advance_gravity(time, dt) else: print 'unknown option' sys.exit(0) if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time, print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", print "E= ", Etot, "Q= ", Ekin/Epot, print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", t_stellar + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.yr)) mtot.append(Mtot.value_in(units.MSun)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1 or aout <= zero: print "Binary ionized or merged" break gravity.stop() stellar.stop() return t, mtot, smai, ecci, smao, ecco
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, dtse_fac): import random from amuse.ext.solarsystem import get_position time_framework = 0 print "Initial masses:", M1, M2, M3 t_stellar = 4.0 | units.Myr triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) t0 = ctime.time() stellar.evolve_model(t_stellar) delta_t = ctime.time() - t0 time_framework += delta_t channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Masses at time T:", M1, M2, M3 # Inner binary tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1 + M2) else: Pin_0 = orbital_period(ain_0, M1 + M2) print 'ain_0 =', ain_0 print 'M1+M2 =', M1 + M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt = 0.1 * Pin_0 ma = 180 inc = 30 aop = 180 lon = 0 r, v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary r, v = get_position(M1 + M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) gravity = Huayno(converter) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() time = 0.0 | t_end.unit ts = t_stellar + time # begin when stars have formed after 4.0 Myr years ain, ein, aout, eout, iin, iout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, iin, \ "outer:", triple[2].mass, aout, eout, iout dt_diag = t_end / float( nsteps) # how often we want to save the generated data t_diag = dt_diag t = [time.value_in(units.Myr)] smai = [ain / ain_0] ecci = [ein / ein_0] smao = [aout / aout_0] ecco = [eout / eout_0] inci = [iin] inco = [iout] ain = ain_0 def advance_stellar(ts, dt): E0 = gravity.kinetic_energy + gravity.potential_energy ts += dt stellar.evolve_model(ts) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return ts, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_stellar_with_massloss( ts, time_framework, dt_massloss=15e-9 | units.Myr, max_massloss=3e-4 | units.MSun): # Scheme 3: dt 8*10^-7, dm = 2*10^-5 ( max_massloss = 0.0 | units.MSun # massloss over full gravtiational time step massloss0 #max_massloss= 3e-6 | units.MSun # massloss over full gravtiational time step massloss1 #max_massloss= 1e-6 | units.MSun # massloss over full gravtiational time step massloss2 E0 = gravity.kinetic_energy + gravity.potential_energy massloss = -1 | units.MSun mass_0 = numpy.sum(stellar.particles.mass) dt_stellar = 0 | units.Myr niter = 0 while massloss < max_massloss: ts += dt_massloss dt_stellar += dt_massloss # counter for full time niter += 1 t0 = ctime.time() stellar.evolve_model(ts) delta_t = ctime.time() - t0 time_framework += delta_t massloss = 2. * ( mass_0 - numpy.sum(stellar.particles.mass) ) # massloss over full gravtiational time step is x2 channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) print 'Tstellar:', dt_stellar, ', Total Mloss:', massloss, ' Niter:', niter return ts, time_framework, gravity.kinetic_energy + gravity.potential_energy - E0, dt_stellar def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg global_time = [] global_massloss = [] global_dmdt = [] while time < t_end: Pin = orbital_period(ain, triple[0].mass + triple[1].mass) dt = dtse_fac * Pin dt *= random.random( ) # time step is chosen random between 0 and 50*Pin if scheme == 1: ts, dE_se = advance_stellar(ts, dt) time = advance_gravity(time, dt) elif scheme == 2: time = advance_gravity(time, dt) ts, dE_se = advance_stellar(ts, dt) elif scheme == 3: # inital mass mass_init = stellar.particles.mass.sum() # perform step ts, dE_se = advance_stellar(ts, dt / 2) time = advance_gravity(time, dt) ts, dE = advance_stellar(ts, dt / 2) dE_se += dE # add right vlaues global_time = numpy.append(global_time, time.value_in(units.Myr)) global_massloss = numpy.append( global_massloss, mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) else: # our scheme is 4 # inital mass mass_init = stellar.particles.mass.sum() time_init = time.value_in(units.Myr) | units.Myr # get optimal dt to perform a time step without losing too much mass ts, time_framework, dE_se, dt_stellar = advance_stellar_with_massloss( ts, time_framework) # perform time step dt t0 = ctime.time() time = advance_gravity(time, dt_stellar * 2) ts, dE = advance_stellar(ts, dt_stellar) delta_t = ctime.time() - t0 time_framework += delta_t dE_se += dE # save everything global_time = numpy.append(global_time, time.value_in(units.Myr)) global_massloss = numpy.append( global_massloss, mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) global_dmdt = numpy.append( global_dmdt, (mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) / (time.value_in(units.Myr) - time_init.value_in(units.Myr))) if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time #, #print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", #print "E= ", Etot, "Q= ", Ekin/Epot, #print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, #print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout, iin, iout = get_orbital_elements_of_triple( triple) #print "Triple elements t=", (4|units.Myr) + time, \ # "inner:", triple[0].mass, triple[1].mass, ain, ein, \ # "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.Myr)) smai.append(ain / ain_0) ecci.append(ein / ein_0) smao.append(aout / aout_0) ecco.append(eout / eout_0) inci.append(iin) inco.append(iout) if eout > 1.0 or aout <= zero: print "Binary ionized or merged" break pyplot.close() data = numpy.array(zip(global_time, global_massloss, global_dmdt)) numpy.save('massloss0', data) return t, smai, ecci, smao, ecco, inci, inco, time_framework