예제 #1
0
    def evolve_model(self, model_time):

        start_time = time.time()

        density_limit_detection = self.code.stopping_conditions.density_limit_detection
        density_limit_detection.enable()

        model_time_old = self.code.model_time
        dt = model_time - model_time_old
        print("Evolve Hydrodynamics:", dt.in_(units.yr))

        if COOL:
            print("Cool gas for dt=", (dt / 2).in_(units.Myr))
            self.cooling.evolve_for(dt / 2)
            # print "...done."
        self.code.evolve_model(model_time)

        # print "gas evolved."
        while density_limit_detection.is_set():
            self.resolve_sinks()

            print("..done")
            self.code.evolve_model(model_time)
            self.channel_to_stars.copy()
            print("end N=", len(self.star_particles),
                  len(self.code.dm_particles))

        if COOL:
            print("Cool gas for another dt=", (dt / 2).in_(units.Myr))
            self.cooling.evolve_for(dt / 2)
            # print "...done."

        self.merge_stars()

        if len(self.star_particles) > 0:
            sinks = new_sink_particles(self.star_particles)
            sinks.accrete(self.gas_particles)
            for si in range(len(self.star_particles)):
                self.star_particles[si].Lx += sinks[si].angular_momentum[0]
                self.star_particles[si].Ly += sinks[si].angular_momentum[1]
                self.star_particles[si].Lz += sinks[si].angular_momentum[2]

            self.gas_particles.synchronize_to(self.code.gas_particles)
            # make sure that the accreted mass is copied to the Hydro code..+++
            self.channel_from_stars.copy()

        # self.code.evolve_model(model_time)
        print("final N=", len(self.star_particles),
              len(self.code.dm_particles))
        print("final Ngas=", len(self.gas_particles),
              len(self.code.gas_particles))
        self.channel_to_gas.copy()
        self.channel_to_stars.copy()
        print("final N=", len(self.star_particles),
              len(self.code.dm_particles))
        if len(self.star_particles) > 0:
            print("mean star mass:",
                  self.star_particles.mass.min().in_(units.MSun),
                  self.star_particles.mass.mean().in_(units.MSun),
                  self.star_particles.mass.max().in_(units.MSun))
예제 #2
0
    def test2(self):
        """ Test Spheroid sink accretion """
        particles = self.create_particle_grid()

        spheroid = sink.Spheroid([5., 4., 1.] | units.RSun)
        sink_particles = Particles(1,
                                   mass=10. | units.MSun,
                                   radius=0. | units.RSun,
                                   position=[[1., 1., 1.]] | units.RSun)
        sinks = new_sink_particles(sink_particles, shapes=spheroid)

        accreted = sinks.accrete(particles)
        self.assertEqual(len(accreted), 161)
        self.assertEqual(len(particles), 1839)
        self.assertEqual(accreted.x.max(), 4 | units.RSun)
        self.assertEqual(accreted.y.max(), 3 | units.RSun)
        self.assertEqual(accreted.z.max(), 0.5 | units.RSun)

        spheroid.dimensions[2] = 3 | units.RSun
        accreted = sinks.accrete(particles)
        self.assertEqual(len(accreted), 324)
        self.assertEqual(len(particles), 1515)
        self.assertEqual(accreted.x.max(), 4 | units.RSun)
        self.assertEqual(accreted.y.max(), 3 | units.RSun)
        self.assertEqual(accreted.z.max(), 2.5 | units.RSun)
        self.assertIsSubvector([3, 2, 2.5] | units.RSun, particles.position)
예제 #3
0
        def evolve_model(self, model_time):
            
            start_time = time.time()

            density_limit_detection = self.code.stopping_conditions.density_limit_detection
            density_limit_detection.enable()

            model_time_old=self.code.model_time
            dt=model_time - model_time_old
            print "Evolve Hydrodynamics:", dt.in_(units.yr)

            if COOL:
                print "Cool gas for dt=", (dt/2).in_(units.Myr)
                self.cooling.evolve_for(dt/2)
                #print "...done."
            self.code.evolve_model(model_time)
            
            #print "gas evolved."
            while density_limit_detection.is_set():
                self.resolve_sinks()

                print "..done"
                self.code.evolve_model(model_time)
                self.channel_to_stars.copy()
                print "end N=", len(self.star_particles), len(self.code.dm_particles)

            if COOL:
                print "Cool gas for another dt=", (dt/2).in_(units.Myr)
                self.cooling.evolve_for(dt/2)
                #print "...done."


            self.merge_stars()
                
            if len(self.star_particles)>0:
                sinks = new_sink_particles(self.star_particles)
	        sinks.accrete(self.gas_particles)
                for si in range(len(self.star_particles)):
                    self.star_particles[si].Lx += sinks[si].angular_momentum[0]
                    self.star_particles[si].Ly += sinks[si].angular_momentum[1]
                    self.star_particles[si].Lz += sinks[si].angular_momentum[2]

	        self.gas_particles.synchronize_to(self.code.gas_particles)
                # make sure that the accreted mass is copied to the Hydro code..+++
                self.channel_from_stars.copy()
                
            #self.code.evolve_model(model_time)
            print "final N=", len(self.star_particles),len(self.code.dm_particles)
            print "final Ngas=", len(self.gas_particles),len(self.code.gas_particles)
            self.channel_to_gas.copy()
            self.channel_to_stars.copy()
            print "final N=", len(self.star_particles),len(self.code.dm_particles)
            if len(self.star_particles)>0:
                    print "mean star mass:", self.star_particles.mass.min().in_(units.MSun), self.star_particles.mass.mean().in_(units.MSun), self.star_particles.mass.max().in_(units.MSun)
예제 #4
0
    def test2(self):
        print("Demonstrate new_sink_particles usage")
        cloud = Particles(100)
        cloud.mass = 1 | units.MSun
        cloud.position = [[0, 0, 0], [100, 100, 100], [200, 200, 200],
                          [300, 300, 300]] * 25 | units.parsec
        cloud.velocity = [[0, 0, 0], [1, 1, 1]] * 50 | units.km / units.s
        unit_converter = ConvertBetweenGenericAndSiUnits(
            1 | units.m, 1 | units.kg, 1 | units.s)
        sph_code = Stub(unit_converter)
        sph_code.parameters.stopping_condition_maximum_density = 1 | units.kg / units.m**3
        sph_code.gas_particles.add_particles(cloud)
        density_limit_detection = sph_code.stopping_conditions.density_limit_detection
        density_limit_detection.enable()

        sph_code.evolve_model(1 | units.Myr)
        self.assertTrue(density_limit_detection.is_set())
        self.assertEqual(len(density_limit_detection.particles()), 3)
        self.assertEqual(density_limit_detection.particles().position,
                         [[100, 100, 100], [200, 200, 200], [300, 300, 300]]
                         | units.parsec)
        print(density_limit_detection.particles())

        clumps = density_limit_detection.particles().copy()
        sph_code.gas_particles.remove_particles(clumps)

        sinks = new_sink_particles(clumps,
                                   sink_radius=1 | units.parsec,
                                   looping_over=self.looping_over)
        self.assertEqual(sinks.sink_radius, 1.0 | units.parsec)
        self.assertEqual(sinks.mass, 1.0 | units.MSun)
        self.assertEqual(sinks.position,
                         [[100, 100, 100], [200, 200, 200], [300, 300, 300]]
                         | units.parsec)
        self.assertEqual(len(sph_code.gas_particles), 97)
        self.assertAlmostRelativeEqual(
            sph_code.gas_particles.total_mass() + clumps.total_mass(),
            100 | units.MSun, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(),
                                       97 | units.MSun, 10)

        sinks.accrete(sph_code.gas_particles)
        self.assertAlmostRelativeEqual(sinks.mass, [25, 25, 25] | units.MSun,
                                       10)
        self.assertEqual(len(sph_code.gas_particles), 25)
        self.assertAlmostRelativeEqual(
            sph_code.gas_particles.total_mass() + clumps.total_mass(),
            100 | units.MSun, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(),
                                       25 | units.MSun, 10)
예제 #5
0
파일: test_sink.py 프로젝트: rjfarmer/amuse
    def test3(self):
        """ Test compound sink accretion """
        particles = self.create_particle_grid()

        shape = sink.Sphere(3.|units.RSun) | sink.Disc(*[5., 1.]|units.RSun)
        sink_particles = Particles(1, mass=10.|units.MSun, radius=0.|units.RSun, position=[[1., 1., 1.]]|units.RSun)
        sinks = new_sink_particles(sink_particles, shapes=shape)

        accreted = sinks.accrete(particles)
        self.assertEqual(len(accreted), 319)
        self.assertEqual(len(particles), 1681)
        self.assertEqual(accreted.x.max(), 4|units.RSun)
        self.assertEqual(accreted.y.max(), 4|units.RSun)
        self.assertEqual(accreted.z.max(), 2.5|units.RSun)
        self.assertIsSubvector([2, 2, 1]|units.RSun, particles.position)
예제 #6
0
파일: test_sink.py 프로젝트: Ingwar/amuse
    def test3(self):
        """ Test compound sink accretion """
        particles = self.create_particle_grid()

        shape = sink.Sphere(3.|units.RSun) | sink.Disc(*[5., 1.]|units.RSun)
        sink_particles = Particles(1, mass=10.|units.MSun, radius=0.|units.RSun, position=[1., 1., 1.]|units.RSun)
        sinks = new_sink_particles(sink_particles, shapes=shape)

        accreted = sinks.accrete(particles)
        self.assertEqual(len(accreted), 319)
        self.assertEqual(len(particles), 1681)
        self.assertEqual(accreted.x.max(), 4|units.RSun)
        self.assertEqual(accreted.y.max(), 4|units.RSun)
        self.assertEqual(accreted.z.max(), 2.5|units.RSun)
        self.assertIsSubvector([2, 2, 1]|units.RSun, particles.position)
예제 #7
0
def evolve_system(coupled_system, t_end, n_steps):
    times = (t_end * range(1, n_steps+1) / n_steps).as_quantity_in(units.day)
    
    sinks = new_sink_particles(coupled_system.codes[0].particles, sink_radius=5|units.RSun)
    
    for i_step, time in enumerate(times):
        sinks.accrete(coupled_system.gas_particles)
        coupled_system.evolve_model(time)
        print "   Evolved to:", time
        
        if i_step % 10 == 9:
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=06}_gas.amuse".format(i_step))
            write_set_to_file(coupled_system.gas_particles, snapshotfile, format='amuse')
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=06}_dm.amuse".format(i_step))
            write_set_to_file(coupled_system.dm_particles, snapshotfile, format='amuse')
    
    coupled_system.stop()
예제 #8
0
파일: test_sink.py 프로젝트: Ingwar/amuse
    def test2(self):
        """ Test Spheroid sink accretion """
        particles = self.create_particle_grid()

        spheroid = sink.Spheroid([5., 4., 1.]|units.RSun)
        sink_particles = Particles(1, mass=10.|units.MSun, radius=0.|units.RSun, position=[1., 1., 1.]|units.RSun)
        sinks = new_sink_particles(sink_particles, shapes=spheroid)

        accreted = sinks.accrete(particles)
        self.assertEqual(len(accreted), 161)
        self.assertEqual(len(particles), 1839)
        self.assertEqual(accreted.x.max(), 4|units.RSun)
        self.assertEqual(accreted.y.max(), 3|units.RSun)
        self.assertEqual(accreted.z.max(), 0.5|units.RSun)

        spheroid.dimensions[2] = 3 | units.RSun
        accreted = sinks.accrete(particles)
        self.assertEqual(len(accreted), 324)
        self.assertEqual(len(particles), 1515)
        self.assertEqual(accreted.x.max(), 4|units.RSun)
        self.assertEqual(accreted.y.max(), 3|units.RSun)
        self.assertEqual(accreted.z.max(), 2.5|units.RSun)
        self.assertIsSubvector([3, 2, 2.5]|units.RSun, particles.position)
예제 #9
0
파일: test_sink.py 프로젝트: Ingwar/amuse
    def test2(self):
        print "Demonstrate new_sink_particles usage"
        cloud = Particles(100)
        cloud.mass = 1 | units.MSun
        cloud.position = [[0, 0, 0], [100, 100, 100], [200, 200, 200], [300, 300, 300]]*25 | units.parsec
        cloud.velocity = [[0, 0, 0], [1, 1, 1]]*50 | units.km / units.s
        unit_converter = ConvertBetweenGenericAndSiUnits(1|units.m, 1|units.kg, 1|units.s)
        sph_code = Stub(unit_converter)
        sph_code.parameters.stopping_condition_maximum_density = 1 | units.kg / units.m**3
        sph_code.gas_particles.add_particles(cloud)
        density_limit_detection = sph_code.stopping_conditions.density_limit_detection
        density_limit_detection.enable()

        sph_code.evolve_model(1 | units.Myr)
        self.assertTrue(density_limit_detection.is_set())
        self.assertEqual(len(density_limit_detection.particles()), 3)
        self.assertEqual(density_limit_detection.particles().position,
            [[100, 100, 100], [200, 200, 200], [300, 300, 300]] | units.parsec)
        print density_limit_detection.particles()

        clumps = density_limit_detection.particles().copy()
        sph_code.gas_particles.remove_particles(clumps)

        sinks = new_sink_particles(clumps, sink_radius=1|units.parsec,looping_over=self.looping_over)
        self.assertEqual(sinks.sink_radius, 1.0 | units.parsec)
        self.assertEqual(sinks.mass, 1.0 | units.MSun)
        self.assertEqual(sinks.position,
            [[100, 100, 100], [200, 200, 200], [300, 300, 300]] | units.parsec)
        self.assertEqual(len(sph_code.gas_particles), 97)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass() + clumps.total_mass(), 100 | units.MSun, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), 97 | units.MSun, 10)

        sinks.accrete(sph_code.gas_particles)
        self.assertAlmostRelativeEqual(sinks.mass, [25, 25, 25] | units.MSun, 10)
        self.assertEqual(len(sph_code.gas_particles), 25)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass() + clumps.total_mass(), 100 | units.MSun, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), 25 | units.MSun, 10)
예제 #10
0
파일: test_sink.py 프로젝트: rjfarmer/amuse
    def test3(self):
        print("Demonstrate new_sink_particles usage (using Gadget2)")
        UnitLength = 1.0 | units.kpc
        UnitMass = 1.0e10 | units.MSun
        UnitVelocity = 1.0 | units.km / units.s
        convert_nbody = nbody_system.nbody_to_si(UnitLength, UnitMass)
        converter = ConvertBetweenGenericAndSiUnits(UnitLength, UnitMass, UnitVelocity)
        number_gas_particles = 1000
        gas = new_evrard_gas_sphere(number_gas_particles, convert_nbody, do_scale=True, seed=12345)

        sph_code = Gadget2(converter)
        sph_code.initialize_code()
        sph_code.parameters.stopping_condition_maximum_density = 10 * UnitMass / UnitLength**3
        sph_code.gas_particles.add_particles(gas)
        self.assertIsOfOrder(max(sph_code.gas_particles.density), UnitMass / UnitLength**3)

        density_limit_detection = sph_code.stopping_conditions.density_limit_detection
        density_limit_detection.enable()

        sph_code.evolve_model(10.0 | units.Myr)
        self.assertTrue(density_limit_detection.is_set())
        self.assertTrue(sph_code.model_time < 10.0 | units.Myr)
        print("density_limit exceeded at t =", sph_code.model_time.as_quantity_in(units.Myr))
        self.assertEqual(len(density_limit_detection.particles()), 1)
        self.assertTrue(density_limit_detection.particles().density >
                10 * UnitMass / UnitLength**3)

        clumps = density_limit_detection.particles().copy()
        sph_code.gas_particles.remove_particles(clumps)
        clumps_in_code = sph_code.dm_particles.add_particles(clumps)

        sinks = new_sink_particles(clumps_in_code,looping_over=self.looping_over)
        self.assertEqual(sinks.sink_radius, clumps.radius)
        self.assertAlmostRelativeEqual(sinks.mass, UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sinks.position, clumps.position, 10)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 1)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)
        self.assertEqual(set(sinks.get_attribute_names_defined_in_store()) - set(["sink_radius","lx","ly","lz"]),
            set(sph_code.particles.get_attribute_names_defined_in_store()))

        sinks.accrete(sph_code.gas_particles)
        self.assertAlmostRelativeEqual(sinks.mass, 3 * UnitMass / number_gas_particles, 10)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 3)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)

        sinks.accrete(sph_code.particles) # Nothing happens: gas already gone, and cannot accrete itself
        self.assertAlmostRelativeEqual(sinks.mass, 3 * UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)

        steps = 0
        while True:
            sph_code.evolve_model(sph_code.model_time + (0.1 | units.Myr))
            sinks.sink_radius = 4 * clumps_in_code.radius
            sinks.accrete(sph_code.gas_particles)
            steps += 1
            if density_limit_detection.is_set():
                break

        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 7)
        self.assertAlmostRelativeEqual(sinks.mass, 7 * UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)

        self.assertTrue(density_limit_detection.is_set())
        self.assertEqual(steps, 5)
        self.assertTrue(sph_code.model_time < 10.0 | units.Myr)
        print("density_limit exceeded at t =", sph_code.model_time.as_quantity_in(units.Myr))
        self.assertEqual(len(density_limit_detection.particles()), 5)
        self.assertTrue((density_limit_detection.particles().density >
                10 * UnitMass / UnitLength**3).all())

        clumps = density_limit_detection.particles().copy()
        sph_code.gas_particles.remove_particles(clumps)
        clumps_in_code = sph_code.dm_particles.add_particles(clumps)

        sinks.add_sinks(clumps_in_code, sink_radius=0.1|units.kpc)
        self.assertEqual(sinks[1:].sink_radius, 0.1 | units.kpc)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 12)
        self.assertAlmostRelativeEqual(sinks.mass[1:], UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sinks.position[1:], clumps.position, 10)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)

        sinks.accrete(sph_code.gas_particles)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 66)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass().as_quantity_in(units.MSun), UnitMass, 10)
        self.assertAlmostRelativeEqual(sinks.mass, [7.0, 13.0, 15.0, 9.0, 11.0, 11.0] * UnitMass / number_gas_particles, 10)
예제 #11
0
    def evolve_model(self):
        self.initialize_data()

        self.ism_code = Gadget2(self.converter, number_of_workers=self.n_core)#, debugger='gdb')
        self.ism_code.parameters.time_max = 1024*self.dt       
        self.ism_code.parameters.n_smooth = 64 
        self.ism_code.parameters.n_smooth_tol = 2./64.   
        self.ism_code.parameters.artificial_viscosity_alpha = 0.1 
        self.ism_code.parameters.epsilon_squared = (1. | units.AU)**2.

        self.all_particles = Particles()
        write_set_to_file(self.star, self.filename, "hdf5", append_to_file=False)
        write_set_to_file(self.all_particles, self.filename, "hdf5", append_to_file=False)
        
        self.initial_disc_particles = self.create_disc()
        self.all_particles.add_particles(self.initial_disc_particles)
        self.ism_code.gas_particles.add_particles(self.initial_disc_particles)
        
        #You can only add a sink after adding gas particles
        #starinsph refers to the corresponding particle set/id in the community code
        starinsph = self.ism_code.dm_particles.add_particles(self.star)
        #Use the build-in sink particle routine from amuse.ext.sink. Sink_radius needs to be defined manually otherwise the particle radius in gadget is taken,
        #which does not corresponding to the particle radius in the framework (since 'particles' in gadget do not have a radius, it is set to 0.01 | generic_unit_system.length
        #and corresponds to the gas gravitational smoothing epsilon.           
        sink = new_sink_particles(starinsph, sink_radius= self.star.radius)
       
        self.channel_from_ismcode_to_framework = self.ism_code.gas_particles.new_channel_to(self.all_particles)
    
        time = 0. | units.yr
    
        while time <= (self.tend+self.dt/2.):
 
 
            print("Adding new slice of ISM...")
            newslice=self.make_slice()
            self.ism_code.gas_particles.add_particles(newslice)
            self.all_particles.add_particles(newslice)

                
            start = timing.time()
            print("=======================================================")
            print("Evolving to time = ", time.value_in(units.yr), " of ", self.tend.value_in(units.yr)," years...")    
            self.ism_code.evolve_model(time)
            print("This took ", (timing.time() - start), " s")
            
            out_of_bounds = self.ism_code.gas_particles.select_array(lambda x,y,z:(x > self.cylinder_radius)|((z**2+y**2).sqrt() >= self.cylinder_radius), ["x","y","z"]) 
            if len(out_of_bounds)>0:
                print("Removing ", len(out_of_bounds), " particles from the code because they were out of bounds")
                
                self.ism_code.gas_particles.remove_particles(out_of_bounds)
            
            
            self.ism_code.gas_particles.synchronize_to(self.all_particles)  
            sink.accrete(self.ism_code.gas_particles)

            write_set_to_file(self.star, self.filename, "hdf5")
            write_set_to_file(self.all_particles, self.filename, "hdf5")
            
            time += self.dt
            
        print("=======================================================")
        self.ism_code.stop()
예제 #12
0
파일: test_sink.py 프로젝트: Ingwar/amuse
    def test3(self):
        print "Demonstrate new_sink_particles usage (using Gadget2)"
        UnitLength = 1.0 | units.kpc
        UnitMass = 1.0e10 | units.MSun
        UnitVelocity = 1.0 | units.km / units.s
        convert_nbody = nbody_system.nbody_to_si(UnitLength, UnitMass)
        converter = ConvertBetweenGenericAndSiUnits(UnitLength, UnitMass, UnitVelocity)
        number_gas_particles = 1000
        gas = new_evrard_gas_sphere(number_gas_particles, convert_nbody, do_scale=True, seed=12345)

        sph_code = Gadget2(converter)
        sph_code.initialize_code()
        sph_code.parameters.stopping_condition_maximum_density = 10 * UnitMass / UnitLength**3
        sph_code.gas_particles.add_particles(gas)
        self.assertIsOfOrder(max(sph_code.gas_particles.density), UnitMass / UnitLength**3)

        density_limit_detection = sph_code.stopping_conditions.density_limit_detection
        density_limit_detection.enable()

        sph_code.evolve_model(10.0 | units.Myr)
        self.assertTrue(density_limit_detection.is_set())
        self.assertTrue(sph_code.model_time < 10.0 | units.Myr)
        print "density_limit exceeded at t =", sph_code.model_time.as_quantity_in(units.Myr)
        self.assertEquals(len(density_limit_detection.particles()), 1)
        self.assertTrue(density_limit_detection.particles().density >
                10 * UnitMass / UnitLength**3)

        clumps = density_limit_detection.particles().copy()
        sph_code.gas_particles.remove_particles(clumps)
        clumps_in_code = sph_code.dm_particles.add_particles(clumps)

        sinks = new_sink_particles(clumps_in_code,looping_over=self.looping_over)
        self.assertEqual(sinks.sink_radius, clumps.radius)
        self.assertAlmostRelativeEqual(sinks.mass, UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sinks.position, clumps.position, 10)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 1)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)
        self.assertEqual(set(sinks.get_attribute_names_defined_in_store()) - set(["sink_radius","lx","ly","lz"]),
            set(sph_code.particles.get_attribute_names_defined_in_store()))

        sinks.accrete(sph_code.gas_particles)
        self.assertAlmostRelativeEqual(sinks.mass, 3 * UnitMass / number_gas_particles, 10)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 3)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)

        sinks.accrete(sph_code.particles) # Nothing happens: gas already gone, and cannot accrete itself
        self.assertAlmostRelativeEqual(sinks.mass, 3 * UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)

        steps = 0
        while True:
            sph_code.evolve_model(sph_code.model_time + (0.1 | units.Myr))
            sinks.sink_radius = 4 * clumps_in_code.radius
            sinks.accrete(sph_code.gas_particles)
            steps += 1
            if density_limit_detection.is_set():
                break

        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 7)
        self.assertAlmostRelativeEqual(sinks.mass, 7 * UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)

        self.assertTrue(density_limit_detection.is_set())
        self.assertEqual(steps, 5)
        self.assertTrue(sph_code.model_time < 10.0 | units.Myr)
        print "density_limit exceeded at t =", sph_code.model_time.as_quantity_in(units.Myr)
        self.assertEquals(len(density_limit_detection.particles()), 5)
        self.assertTrue((density_limit_detection.particles().density >
                10 * UnitMass / UnitLength**3).all())

        clumps = density_limit_detection.particles().copy()
        sph_code.gas_particles.remove_particles(clumps)
        clumps_in_code = sph_code.dm_particles.add_particles(clumps)

        sinks.add_sinks(clumps_in_code, sink_radius=0.1|units.kpc)
        self.assertEqual(sinks[1:].sink_radius, 0.1 | units.kpc)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 12)
        self.assertAlmostRelativeEqual(sinks.mass[1:], UnitMass / number_gas_particles, 10)
        self.assertAlmostRelativeEqual(sinks.position[1:], clumps.position, 10)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10)
        self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10)

        sinks.accrete(sph_code.gas_particles)
        self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 66)
        self.assertAlmostRelativeEqual(sph_code.particles.total_mass().as_quantity_in(units.MSun), UnitMass, 10)
        self.assertAlmostRelativeEqual(sinks.mass, [7.0, 13.0, 15.0, 9.0, 11.0, 11.0] * UnitMass / number_gas_particles, 10)
예제 #13
0
    def evolve_model(self):
        self.initialize_data()

        self.ism_code = Gadget2(self.converter, number_of_workers=self.n_core)#, debugger='gdb')
        self.ism_code.parameters.time_max = 1024*self.dt       
        self.ism_code.parameters.n_smooth = 64 
        self.ism_code.parameters.n_smooth_tol = 2./64.   
        self.ism_code.parameters.artificial_viscosity_alpha = 0.1 
        self.ism_code.parameters.epsilon_squared = (1. | units.AU)**2.

        self.all_particles = Particles()
        write_set_to_file(self.star, self.filename, "hdf5", append_to_file=False)
        write_set_to_file(self.all_particles, self.filename, "hdf5", append_to_file=False)
        
        self.initial_disc_particles = self.create_disc()
        self.all_particles.add_particles(self.initial_disc_particles)
        self.ism_code.gas_particles.add_particles(self.initial_disc_particles)
        
        #You can only add a sink after adding gas particles
        #starinsph refers to the corresponding particle set/id in the community code
        starinsph = self.ism_code.dm_particles.add_particles(self.star)
        #Use the build-in sink particle routine from amuse.ext.sink. Sink_radius needs to be defined manually otherwise the particle radius in gadget is taken,
        #which does not corresponding to the particle radius in the framework (since 'particles' in gadget do not have a radius, it is set to 0.01 | generic_unit_system.length
        #and corresponds to the gas gravitational smoothing epsilon.           
        sink = new_sink_particles(starinsph, sink_radius= self.star.radius)
       
        self.channel_from_ismcode_to_framework = self.ism_code.gas_particles.new_channel_to(self.all_particles)
    
        time = 0. | units.yr
    
        while time <= (self.tend+self.dt/2.):
 
 
            print "Adding new slice of ISM..."
            newslice=self.make_slice()
            self.ism_code.gas_particles.add_particles(newslice)
            self.all_particles.add_particles(newslice)

                
            start = timing.time()
            print "======================================================="
            print "Evolving to time = ", time.value_in(units.yr), " of ", self.tend.value_in(units.yr)," years..."    
            self.ism_code.evolve_model(time)
            print "This took ", (timing.time() - start), " s"
            
            out_of_bounds = self.ism_code.gas_particles.select_array(lambda x,y,z:(x > self.cylinder_radius)|((z**2+y**2).sqrt() >= self.cylinder_radius), ["x","y","z"]) 
            if len(out_of_bounds)>0:
                print "Removing ", len(out_of_bounds), " particles from the code because they were out of bounds"
                
                self.ism_code.gas_particles.remove_particles(out_of_bounds)
            
            
            self.ism_code.gas_particles.synchronize_to(self.all_particles)  
            sink.accrete(self.ism_code.gas_particles)

            write_set_to_file(self.star, self.filename, "hdf5")
            write_set_to_file(self.all_particles, self.filename, "hdf5")
            
            time += self.dt
            
        print "======================================================="
        self.ism_code.stop()