Beispiel #1
0
    def setup_sph_code(self, sph_code, number_of_particles, L, rho, u):
        converter = ConvertBetweenGenericAndSiUnits(L, rho, constants.G)
        sph_code = sph_code(converter,
                            mode='periodic')  #, redirection = 'none')
        sph_code.parameters.periodic_box_size = 10.0 | units.parsec
        gas = Particles(number_of_particles)
        gas.mass = (rho * L**3) / number_of_particles
        numpy.random.seed(12345)
        gas.x = L * numpy.random.uniform(0.0, 1.0, number_of_particles)
        gas.y = L * numpy.random.uniform(0.0, 1.0, number_of_particles)
        gas.z = L * numpy.random.uniform(0.0, 1.0, number_of_particles)
        gas.vx = numpy.zeros(number_of_particles) | units.cm / units.s
        gas.vy = numpy.zeros(number_of_particles) | units.cm / units.s
        gas.vz = numpy.zeros(number_of_particles) | units.cm / units.s
        gas.u = u
        if isinstance(sph_code, Fi):
            sph_code.parameters.self_gravity_flag = False
            sph_code.parameters.timestep = 0.1 | generic_unit_system.time
            gas.h_smooth = L / number_of_particles**(1 / 3.0)
            gas.position -= 0.5 * L

        sph_code.gas_particles.add_particles(gas)
        sph_code.commit_particles()
        #~        sph_code.evolve_model(0.01 | units.Myr)
        return sph_code
def setup_sph_code(sph_code, N, L, rho, u):
    converter = ConvertBetweenGenericAndSiUnits(L, rho, constants.G)
    sph_code = sph_code(converter, mode='periodic')  #, redirection = 'none')
    sph_code.parameters.periodic_box_size = 10.0 | units.parsec
    plummer = new_plummer_gas_model(N, convert_nbody=converter)
    plummer = plummer.select(lambda r: r.length() < 0.5 * L, ["position"])
    N = len(plummer)
    print "N=", len(plummer)
    plummer.mass = (rho * L**3) / N
    gas = Particles(N)
    gas.mass = 0.01 * (rho * L**3) / N
    numpy.random.seed(12345)
    gas.x = L * numpy.random.uniform(0.0, 1.0, N)
    gas.y = L * numpy.random.uniform(0.0, 1.0, N)
    gas.z = L * numpy.random.uniform(0.0, 1.0, N)
    gas.vx = numpy.zeros(N) | units.cm / units.s
    gas.vy = numpy.zeros(N) | units.cm / units.s
    gas.vz = numpy.zeros(N) | units.cm / units.s
    gas.u = u
    if isinstance(sph_code, Fi):
        sph_code.parameters.self_gravity_flag = False
        sph_code.parameters.timestep = 0.1 | generic_unit_system.time
        gas.h_smooth = L / N**(1 / 3.0)
        gas.position -= 0.5 * L

    sph_code.gas_particles.add_particles(gas)
    sph_code.gas_particles.add_particles(plummer)
    sph_code.commit_particles()
    return sph_code
Beispiel #3
0
def run_supernova():
    use_hydro_code = Gadget2
    hydro_code_options = dict(number_of_workers=3)
    number_of_sph_particles = 3000
    t_end = 1.0e4 | units.s

    pickle_file = setup_stellar_evolution_model()
    model = convert_stellar_model_to_SPH(None,
                                         number_of_sph_particles,
                                         seed=12345,
                                         pickle_file=pickle_file,
                                         with_core_particle=True,
                                         target_core_mass=1.4 | units.MSun)
    print("model=", model.core_particle)
    core, gas_without_core, core_radius \
        = model.core_particle, model.gas_particles, model.core_radius

    inject_supernova_energy(gas_without_core)

    print("\nEvolving (SPH) to:", t_end)
    n_steps = 100

    unit_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun,
                                                     constants.G, t_end)
    hydro_code = use_hydro_code(unit_converter, **hydro_code_options)

    try:
        hydro_code.parameters.timestep = t_end / n_steps
    except Exception as exc:
        if not "parameter is read-only" in str(exc): raise

    hydro_code.parameters.epsilon_squared = core_radius**2
    hydro_code.parameters.n_smooth_tol = 0.01
    hydro_code.gas_particles.add_particles(gas_without_core)
    hydro_code.dm_particles.add_particle(core)

    times = [] | units.s
    potential_energies = [] | units.J
    kinetic_energies = [] | units.J
    thermal_energies = [] | units.J
    for time, i_step in [(i * t_end / n_steps, i)
                         for i in range(0, n_steps + 1)]:
        hydro_code.evolve_model(time)
        times.append(time)
        potential_energies.append(hydro_code.potential_energy)
        kinetic_energies.append(hydro_code.kinetic_energy)
        thermal_energies.append(hydro_code.thermal_energy)
        hydro_plot([-1.0, 1.0, -1.0, 1.0] * (350 | units.RSun), hydro_code,
                   (100, 100), time,
                   os.path.join(
                       get_path_to_results(),
                       "supernova_hydro_image{0:=03}.png".format(i_step)))

    energy_plot(times, kinetic_energies, potential_energies, thermal_energies,
                "supernova_energy_evolution.pdf")

    hydro_code.stop()
Beispiel #4
0
def relax_in_isolation(giant_in_sph, sph_code, output_base_name):
    total_mass = giant_in_sph.gas_particles.total_mass() + giant_in_sph.core_particle.mass
    total_radius = max(giant_in_sph.gas_particles.position.lengths_squared()).sqrt()
    dynamical_timescale = (total_radius**3 / (2 * constants.G * total_mass)).sqrt().as_quantity_in(units.day)
    t_end = (10.0 * dynamical_timescale).as_quantity_in(units.day)
    n_steps = 100
    hydro_code_options = dict(number_of_workers=2, redirection='file', redirect_file='hydrodynamics_code_relax_out.log')
    
    unit_converter = ConvertBetweenGenericAndSiUnits(total_radius, total_mass, t_end)
    hydrodynamics = sph_code(unit_converter, **hydro_code_options)
    hydrodynamics.parameters.epsilon_squared = giant_in_sph.core_radius**2
    hydrodynamics.parameters.max_size_timestep = t_end
    hydrodynamics.parameters.time_max = 1.1 * t_end
    hydrodynamics.parameters.time_limit_cpu = 7.0 | units.day
    hydrodynamics.gas_particles.add_particles(giant_in_sph.gas_particles)
    hydrodynamics.dm_particles.add_particle(giant_in_sph.core_particle)
    
    potential_energies = hydrodynamics.potential_energy.as_vector_with_length(1).as_quantity_in(units.erg)
    kinetic_energies = hydrodynamics.kinetic_energy.as_vector_with_length(1).as_quantity_in(units.erg)
    thermal_energies = hydrodynamics.thermal_energy.as_vector_with_length(1).as_quantity_in(units.erg)
    
    print("   Relaxing for", t_end, "(10 * dynamical timescale)")
    times = (t_end * list(range(1, n_steps+1)) / n_steps).as_quantity_in(units.day)
    for i_step, time in enumerate(times):
        hydrodynamics.evolve_model(time)
        print("   Relaxed for:", time)
        potential_energies.append(hydrodynamics.potential_energy)
        kinetic_energies.append(hydrodynamics.kinetic_energy)
        thermal_energies.append(hydrodynamics.thermal_energy)
    
    hydrodynamics.gas_particles.copy_values_of_attributes_to(
        ['mass', 'x','y','z', 'vx','vy','vz', 'u', 'h_smooth'], 
        giant_in_sph.gas_particles)
    giant_in_sph.core_particle.position = hydrodynamics.dm_particles[0].position
    giant_in_sph.core_particle.velocity = hydrodynamics.dm_particles[0].velocity
    hydrodynamics.stop()
    
    snapshotfile = output_base_name + "_gas.amuse"
    write_set_to_file(giant_in_sph.gas_particles, snapshotfile, format='amuse')
    shutil.copy(snapshotfile, os.path.join("..", "giant_models"))
    
    snapshotfile = output_base_name + "_core.amuse"
    # temporarily store core_radius on the core particle
    giant_in_sph.core_particle.radius = giant_in_sph.core_radius
    write_set_to_file(giant_in_sph.core_particle.as_set(), snapshotfile, format='amuse')
    giant_in_sph.core_particle.radius = 0.0 | units.m
    shutil.copy(snapshotfile, os.path.join("..", "giant_models"))
    
    energy_evolution_plot(times, kinetic_energies, potential_energies, thermal_energies, 
        figname = output_base_name + "_energy_evolution.png")
Beispiel #5
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)
    def slowtest1(self):
        stellar_evolution = self.new_instance(MESA)
        stellar_evolution.particles.add_particles(
            Particles(2, mass=[1.0, 5.0] | units.MSun))
        stellar_evolution.evolve_model(10.0 | units.Myr)
        initial_separation = stellar_evolution.particles.radius.sum()

        sph_particles_1 = convert_stellar_model_to_SPH(
            stellar_evolution.particles[0], 200, seed=12345).gas_particles
        sph_particles_2 = convert_stellar_model_to_SPH(
            stellar_evolution.particles[1], 1000, seed=12345).gas_particles
        stellar_evolution.stop()

        initial_speed = 10.0 | units.km / units.s
        sph_particles_2.x += initial_separation
        sph_particles_1.vx += initial_speed
        all_sph_particles = ParticlesSuperset(
            [sph_particles_1, sph_particles_2])
        all_sph_particles.move_to_center()

        t_end = 4.0e3 | units.s
        print "Evolving to:", t_end
        n_steps = 4

        unit_system_converter = ConvertBetweenGenericAndSiUnits(
            1.0 | units.RSun, 1.0 | units.MSun, t_end)
        hydro_code = Gadget2(unit_system_converter)
        hydro_code.gas_particles.add_particles(all_sph_particles)

        pyplot.ion()
        for time in [i * t_end / n_steps for i in range(1, n_steps + 1)]:
            hydro_code.evolve_model(time)
            pyplot.close('all')
            pyplot.figure()
            pynbody_column_density_plot(hydro_code.gas_particles,
                                        width=10 | units.RSun)
            pyplot.draw()
            pyplot.figure()
            loglog(hydro_code.gas_particles.position.lengths_squared(),
                   hydro_code.gas_particles.pressure, 'bo')
            pyplot.draw()

        hydro_code.stop()
        sleep(3)
        pyplot.ioff()
Beispiel #7
0
def prepare_giant_system(sph_code, giant_model, view_on_giant, time_unit, n_steps):
    hydro_code_options = dict(number_of_workers=2, 
        redirection='file', redirect_file='hydrodynamics_code_out.log')
    unit_converter = ConvertBetweenGenericAndSiUnits(
        1.0 | units.RSun, 
        giant_model.gas_particles.total_mass() + giant_model.core_particle.mass, 
        time_unit)
    system = sph_code(unit_converter, **hydro_code_options)
    system.parameters.epsilon_squared = giant_model.core_radius**2
    system.parameters.max_size_timestep = time_unit / n_steps
    system.parameters.time_max = 1.1 * time_unit
    system.parameters.time_limit_cpu = 7.0 | units.day

    giant_model.gas_particles.position += view_on_giant.position
    giant_model.gas_particles.velocity += view_on_giant.velocity
    
    giant_model.core_particle.position += view_on_giant.position
    giant_model.core_particle.velocity += view_on_giant.velocity
    
    system.gas_particles.add_particles(giant_model.gas_particles)
    system.dm_particles.add_particle(giant_model.core_particle)
    return system
    def new_particles(self):
        input_file = os.path.join(get_path_to_results(),
                                  "test_sph_to_star_input.hdf5")
        if os.path.exists(input_file):
            return read_set_from_file(input_file, "hdf5")

        stellar_evolution = EVtwin()
        stellar_evolution.particles.add_particle(
            Particle(mass=1.0 | units.MSun))
        stellar_evolution.evolve_model(100.0 | units.Myr)
        particles = convert_stellar_model_to_SPH(
            stellar_evolution.particles[0], 500, seed=12345).gas_particles
        stellar_evolution.stop()

        hydrodynamics = Gadget2(
            ConvertBetweenGenericAndSiUnits(1.0 | units.MSun, 1.0 | units.RSun,
                                            1.0e3 | units.s))
        hydrodynamics.gas_particles.add_particles(particles)
        hydrodynamics.evolve_model(1.0 | units.s)
        hydrodynamics.gas_particles.copy_values_of_attributes_to(
            ["density", "u", "pressure"], particles)
        hydrodynamics.stop()
        write_set_to_file(particles, input_file, "hdf5")
        return particles
class CalculateSolutionIn3D(object):
    number_of_workers = 1
    number_of_grid_points = 10
    gamma = 5.0 / 3.0
    name_of_the_code = "gadget2"
    hydro_code_options = dict(redirection="none")
    convert_generic_units = ConvertBetweenGenericAndSiUnits(
        1.0 | units.kpc, 1.0e10 | units.MSun, constants.G)
    convert_nbody_units = nbody_to_si(1.0 | units.kpc, 1.0e10 | units.MSun)

    def __init__(self, **keyword_arguments):
        for x in keyword_arguments:
            # print x, keyword_arguments[x]
            setattr(self, x, keyword_arguments[x])

        self.dimensions_of_mesh = (self.number_of_grid_points * 3,
                                   self.number_of_grid_points,
                                   self.number_of_grid_points)

    def new_instance_of_code(self):
        attribute = "new_instance_of_{0}_code".format(
            self.name_of_the_code.lower())
        return getattr(self, attribute)()

    def new_instance_of_athena_code(self):
        result = Athena(number_of_workers=self.number_of_workers,
                        **self.hydro_code_options)
        result.initialize_code()
        result.parameters.gamma = self.gamma
        result.parameters.courant_number = 0.3
        return result

    def new_instance_of_mpiamrvac_code(self):
        result = MpiAmrVac(number_of_workers=self.number_of_workers,
                           **self.hydro_code_options)
        result.set_parameters_filename(result.default_parameters_filename)
        result.initialize_code()
        return result

    def new_instance_of_capreole_code(self):
        result = Capreole(number_of_workers=self.number_of_workers,
                          **self.hydro_code_options)
        result.initialize_code()
        return result

    grid_hydro_codes = ("athena", "mpiamrvac", "capreole")

    def new_instance_of_gadget2_code(self):
        result = Gadget2(self.convert_generic_units,
                         number_of_workers=self.number_of_workers,
                         mode="periodic",
                         **self.hydro_code_options)
        result.initialize_code()
        return result

    def new_instance_of_fi_code(self):
        result = Fi(self.convert_nbody_units,
                    number_of_workers=self.number_of_workers,
                    mode="periodic",
                    **self.hydro_code_options)
        result.initialize_code()
        result.parameters.self_gravity_flag = False
        result.parameters.timestep = 0.01 | time
        return result

    sph_hydro_codes = ("gadget2", "fi")

    def set_parameters(self, instance):
        if self.name_of_the_code in self.sph_hydro_codes:
            instance.parameters.periodic_box_size = 1.0 | length
        else:
            instance.parameters.mesh_size = self.dimensions_of_mesh

            instance.parameters.length_x = 1 | length
            instance.parameters.length_y = 1 | length
            instance.parameters.length_z = 1 | length

            instance.parameters.x_boundary_conditions = ("periodic",
                                                         "periodic")
            instance.parameters.y_boundary_conditions = ("periodic",
                                                         "periodic")
            instance.parameters.z_boundary_conditions = ("periodic",
                                                         "periodic")

        result = instance.commit_parameters()

    def new_grid(self):
        grid = Grid.create(self.dimensions_of_mesh, [1, 1, 1] | length)
        self.clear_grid(grid)
        return grid

    def clear_grid(self, grid):
        density = mass / length**3
        momentum = speed * density
        energy = mass / (time**2 * length)

        grid.rho = 0.0 | density
        grid.rhovx = 0.0 | momentum
        grid.rhovy = 0.0 | momentum
        grid.rhovz = 0.0 | momentum
        grid.energy = 0.0 | energy

        return grid

    def initialize_grid_with_shock(self, grid):
        energy = mass / (time**2 * length)

        halfway = self.dimensions_of_mesh[0] / 2 - 1

        firsthalf = grid.x <= 0.5 | length
        secondhalf = grid.x > 0.5 | length
        grid[firsthalf].rho = 4.0 | density
        grid[firsthalf].energy = (1.0 | energy) / (self.gamma - 1)
        grid[secondhalf].rho = 1.0 | density
        grid[secondhalf].energy = (0.1795 | energy) / (self.gamma - 1)

    def set_initial_conditions(self, instance):
        if self.name_of_the_code in self.sph_hydro_codes:
            initial_grid = self.new_grid()
            self.initialize_grid_with_shock(initial_grid)
            if self.name_of_the_code == "fi":
                initial_grid.position -= 0.5 | length
            sph_particles = convert_grid_to_SPH(initial_grid,
                                                self.number_of_particles)
            instance.gas_particles.add_particles(sph_particles)
        else:
            for x in instance.itergrids():
                inmem = x.copy()
                self.clear_grid(inmem)
                self.initialize_grid_with_shock(inmem)
                from_model_to_code = inmem.new_channel_to(x)
                from_model_to_code.copy()

            instance.initialize_grid()

    def copy_results(self, instance):
        if self.name_of_the_code in self.sph_hydro_codes:
            n_samples = self.number_of_grid_points * 3
            result = Particles(n_samples)
            result.position = [(x, 0.5, 0.5) | length
                               for x in numpy.linspace(0.0, 1.0, n_samples)]
            x, y, z = result.x, result.y, result.z
            if self.name_of_the_code == "fi":
                x -= (0.5 | length)
                y -= (0.5 | length)
                z -= (0.5 | length)
            no_speed = [0.0] * n_samples | speed
            result.rho, result.rhovx, result.rhovy, result.rhovz, result.energy = [
                self.convert_generic_units.to_generic(quantity)
                for quantity in instance.get_hydro_state_at_point(
                    x, y, z, no_speed, no_speed, no_speed)
            ]
        else:
            result = []
            for x in instance.itergrids():
                result.append(x.copy())
        return result

    def get_solution_at_time(self, time):
        instance = self.new_instance_of_code()
        self.set_parameters(instance)
        self.set_initial_conditions(instance)

        print "start evolve"
        instance.evolve_model(time)

        print "copying results"
        result = self.copy_results(instance)

        print "terminating code"
        instance.stop()

        return result
Beispiel #10
0
    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)
Beispiel #11
0
class CalculateSolutionIn3D(object):
    size = 10.0 | length

    number_of_workers = 1
    number_of_grid_points = 25
    gamma = 5.0 / 3.0
    rho_medium = 0 | density
    rho_sphere = 0.5 | density
    center = [1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0] * size
    radius = 1.0 | length
    total_mass = 1.0 | mass
    name_of_the_code = "athena_selfgravity"
    convert_generic_units = ConvertBetweenGenericAndSiUnits(
        1.0 | units.kpc, 1.0e10 | units.MSun, constants.G)

    def __init__(self, **keyword_arguments):
        for x in keyword_arguments:
            print(x, keyword_arguments[x])
            setattr(self, x, keyword_arguments[x])

        self.dimensions_of_mesh = (self.number_of_grid_points,
                                   self.number_of_grid_points,
                                   self.number_of_grid_points)

        self.instance = None

    def new_instance_of_code(self):
        attribute = "new_instance_of_{0}_code".format(
            self.name_of_the_code.lower())
        return getattr(self, attribute)()

    def new_instance_of_athena_selfgravity_code(self):
        result = Athena(mode=AthenaInterface.MODE_SELF_GRAVITY,
                        redirection="none",
                        number_of_workers=1)
        result.initialize_code()
        result.parameters.gamma = self.gamma
        result.parameters.courant_number = 0.3
        result.set_grav_mean_rho(self.rho_mean)
        return result

    def new_instance_of_athena_code(self):
        result = Athena(redirection="none", number_of_workers=1)
        result.initialize_code()
        result.parameters.gamma = self.gamma
        result.parameters.courant_number = 0.3
        return result

    def new_instance_of_athena_and_nbody_code(self):
        gridcode = Athena(redirection="none", number_of_workers=1)
        gridcode.initialize_code()
        gridcode.parameters.gamma = self.gamma
        gridcode.parameters.courant_number = 0.3

        gridcode.set_has_external_gravitational_potential(1)

        nbodycode = PhiGRAPE(mode="gpu")
        # nbodycode = Octgrav(mode="gpu")
        nbodycode.initialize_code()
        nbodycode.parameters.epsilon_squared = (
            self.size / (10000.0 * self.number_of_grid_points))**2
        nbodycode.commit_parameters()

        result = HydroGridAndNbody(gridcode, nbodycode)
        return result

    def new_instance_of_capreole_and_nbody_code(self):
        gridcode = Capreole(number_of_workers=self.number_of_workers)
        gridcode.initialize_code()
        nbodycode = PhiGRAPE(mode="gpu")
        # nbodycode = Octgrav(mode="gpu")
        nbodycode.initialize_code()
        nbodycode.parameters.epsilon_squared = (
            self.size / (10000.0 * self.number_of_grid_points))**2
        nbodycode.commit_parameters()

        result = HydroGridAndNbodyWithAccelerationTransfer(gridcode, nbodycode)
        return result

    def set_parameters(self, instance):

        instance.parameters.mesh_size = self.dimensions_of_mesh

        instance.parameters.length_x = self.size
        instance.parameters.length_y = self.size
        instance.parameters.length_z = self.size

        instance.parameters.x_boundary_conditions = ("periodic", "periodic")
        instance.parameters.y_boundary_conditions = ("periodic", "periodic")
        instance.parameters.z_boundary_conditions = ("periodic", "periodic")

        result = instance.commit_parameters()

    def new_grid(self):

        density = mass / length**3

        density = density
        momentum = speed * density
        energy = mass / (time**2 * length)

        grid = Grid.create(self.dimensions_of_mesh,
                           (10.0, 10.0, 10.0) | length)

        grid.rho = self.rho_medium
        grid.rhovx = 0.0 | momentum
        grid.rhovy = 0.0 | momentum
        grid.rhovz = 0.0 | momentum
        grid.energy = 0.0 | energy

        return grid

    def initialize_grid_with_plummer_sphere(self, grid):
        scaled_radius = self.radius  # / 1.695

        radii = (grid.position - self.center).lengths()
        selected_radii = radii[radii < self.radius]
        print("number of cells in cloud (number of cells in grid)",
              len(selected_radii), grid.shape, grid.size)

        self.rho_sphere = ((0.75 * self.total_mass / (pi *
                                                      (scaled_radius**3))))
        grid.rho = (self.rho_medium + (self.rho_sphere *
                                       ((1 + (radii**2) /
                                         (scaled_radius**2))**(-5.0 / 2.0))))

        internal_energy = ((0.25 | potential) * (1.0 | length / mass) *
                           self.total_mass / scaled_radius)
        # 1.0 * grid.rho *
        grid.energy = grid.rho * \
            (internal_energy/((1.0+(radii/scaled_radius)**2)**(1.0/2.0)))

    def setup_code(self):
        print("setup code")

        self.grid = self.new_grid()
        self.initialize_grid_with_plummer_sphere(self.grid)
        print("Mean density", self.grid.rho.flatten().mean())
        self.rho_mean = self.grid.rho.flatten().mean()

        self.instance = self.new_instance_of_code()
        self.set_parameters(self.instance)

        self.from_model_to_code = self.grid.new_channel_to(self.instance.grid)
        self.from_code_to_model = self.instance.grid.new_channel_to(self.grid)

        self.from_code_to_model.copy_attributes((
            "x",
            "y",
            "z",
        ))
        self.from_model_to_code.copy()
        self.instance.initialize_grid()

    def get_solution_at_time(self, time):
        if self.instance is None:
            self.setup_code()

        print("start evolve")
        self.instance.evolve_model(time)

        print("copying results")
        self.from_code_to_model.copy()

        # print "max,min", max(self.grid.rhovx.flatten()), min(self.grid.rhovx.flatten())
        # print "max,min", max(self.grid.rhovy.flatten()), min(self.grid.rhovy.flatten())
        # print "max,min", max(self.grid.rhovz.flatten()), min(self.grid.rhovz.flatten())
        # print "max,min", max(self.grid.energy.flatten()), min(self.grid.energy.flatten())
        # print "max,min", max(self.grid.rho.flatten()), min(self.grid.rho.flatten())

        return self.grid
Beispiel #12
0
def head_on_stellar_merger(
    masses=[0.3, 3.0] | units.MSun,
    star_age=310.0 | units.Myr,
    maximally_evolved_stars=False,
    initial_separation=4.0 | units.RSun,
    angle=numpy.pi / 3,
    initial_speed=3000.0 | units.km / units.s,
    initial_speed_perpendicular=30.0 | units.km / units.s,
    number_of_sph_particles=1000,
    t_end=1.0e4 | units.s,
    sph_code=Fi,
    steps_per_snapshot=4,
    snapshot_size=100,
    use_stored_stellar_models=True
):
    """
    masses: Mass of the two stars
    star_age: Initial age of the stars (if maximally_evolved_stars is False)
    maximally_evolved_stars: Evolve stars as far as the Stellar Evolution code
    can get
    number_of_sph_particles: Total number of particles of both stars, divided
    according to their masses
    t_end: (Physical, not computational) duration of the hydrodynamics
    simulation
    sph_code: Code to use for the hydrodynamics simulation
    steps_per_snapshot: A hydroplot snapshot is generated each time after this
    many steps (0 or None means no snapshots)
    snapshot_size: Size of the snapshot in pixels along one dimension
    use_stored_stellar_models: Flag to use previously stored stellar model
    files (for speed-up).
    """

    # Convert some of the input parameters to string, for use in output file
    # names:
    n_string = "n" + ("%1.0e" % (number_of_sph_particles)
                      ).replace("+0", "").replace("+", "")
    t_end_string = "t" + ("%1.0e" % (t_end.value_in(units.s))
                          ).replace("+0", "").replace("+", "")
    masses_string = (
            "m1_"
            + (
                "%0.3e" % (masses[0].value_in(units.MSun))
                ).replace("+0", "").replace("+", "")
            + "_m2_"
            + (
                "%0.3e" % (masses[1].value_in(units.MSun))
                ).replace("+0", "").replace("+", "")
            )
    if maximally_evolved_stars:
        star_age_string = "a_max"
    else:
        star_age_string = "a" + \
            ("%0.3e" % (star_age.value_in(units.Myr))).replace(
                "+0", "").replace("+", "")

    base_output_file_name = os.path.join(
        get_path_to_results(), "stellar_merger_"+n_string+"_"+t_end_string)
    pickle_file_1 = os.path.join(get_path_to_results(
    ), "stellar_merger_"+masses_string+"_"+star_age_string+"_1.pkl")
    pickle_file_2 = os.path.join(get_path_to_results(
    ), "stellar_merger_"+masses_string+"_"+star_age_string+"_2.pkl")

    if not use_stored_stellar_models or not (os.path.exists(pickle_file_1) and os.path.exists(pickle_file_2)):
        stars = Particles(2)
        stars.mass = masses
        try:
            stellar_evolution = MESA()
            stellar_evolution.initialize_code()
        except:
            print("MESA was not built. Returning.")
            return
        stellar_evolution.commit_parameters()
        stellar_evolution.particles.add_particles(stars)
        stellar_evolution.commit_particles()

        if maximally_evolved_stars:
            try:
                while True:
                    stellar_evolution.evolve_model()
            except AmuseException as exception:
                print(exception)
        else:
            stellar_evolution.evolve_model(star_age)

        if os.path.exists(pickle_file_1):
            print("Could not save stellar model 1: file already exists.")
        else:
            pickle_stellar_model(stellar_evolution.particles[0], pickle_file_1)
            print("Stellar model 1 saved at:", pickle_file_1)
        if os.path.exists(pickle_file_2):
            print("Could not save stellar model 2: file already exists.")
        else:
            pickle_stellar_model(stellar_evolution.particles[1], pickle_file_2)
            print("Stellar model 2 saved at:", pickle_file_2)
        
        stellar_evolution.stop()

    model_1 = StellarModel2SPH(None, None, pickle_file=pickle_file_1)
    model_2 = StellarModel2SPH(None, None, pickle_file=pickle_file_2)
    model_1.unpickle_stellar_structure()
    model_2.unpickle_stellar_structure()
    composition = model_2.composition_profile
    midpoints = model_2.midpoints_profile[1:-1]
    specific_internal_energy = model_2.specific_internal_energy_profile
    
    number_of_sph_particles_1 = int(
        round(
            number_of_sph_particles
            * (model_1.mass / (model_1.mass + model_2.mass))
        )
    )
    number_of_sph_particles_2 = (
        number_of_sph_particles
        - number_of_sph_particles_1
    )
    print("Creating initial conditions from a MESA stellar evolution model:")
    print(
        model_1.mass,
        "star consisting of",
        number_of_sph_particles_1,
        "particles."
    )
    sph_particles_1 = convert_stellar_model_to_SPH(
        None, 
        number_of_sph_particles_1, 
        seed=12345,
        pickle_file = pickle_file_1
    ).gas_particles
    print(
        model_2.mass,
        "star consisting of",
        number_of_sph_particles_2,
        "particles."
    )
    sph_particles_2 = convert_stellar_model_to_SPH(
            None,
            number_of_sph_particles_2,
            pickle_file=pickle_file_2
            ).gas_particles
    initial_separation += model_1.radius + model_2.radius
    sph_particles_2.x += numpy.cos(angle) * initial_separation
    sph_particles_2.y += numpy.sin(angle) * initial_separation
    sph_particles_1.vx += (
            numpy.cos(angle) * initial_speed
            - numpy.sin(angle) * initial_speed_perpendicular
            )
    sph_particles_1.vy += (
            numpy.cos(angle) * initial_speed_perpendicular
            + numpy.sin(angle) * initial_speed
            )
    view = (
            [-0.5, 0.5, -0.5, 0.5]
            * (initial_separation + model_1.radius + model_2.radius)
            )

    all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2])
    all_sph_particles.move_to_center()

    unit_converter = ConvertBetweenGenericAndSiUnits(
        1.0 | units.RSun, constants.G, t_end)
    hydro_legacy_code = sph_code(unit_converter)
    n_steps = 100
    hydro_legacy_code.parameters.n_smooth = 96
    try:
        hydro_legacy_code.parameters.timestep = t_end / n_steps
    except Exception as exc:
        if "parameter is read-only" not in str(exc):
            raise
    hydro_legacy_code.gas_particles.add_particles(all_sph_particles)

    times = [] | units.Myr
    kinetic_energies = [] | units.J
    potential_energies = [] | units.J
    thermal_energies = [] | units.J

    print("Evolving to:", t_end)
    for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]:
        hydro_legacy_code.evolve_model(time)
        times.append(time)
        kinetic_energies.append(hydro_legacy_code.kinetic_energy)
        potential_energies.append(hydro_legacy_code.potential_energy)
        thermal_energies.append(hydro_legacy_code.thermal_energy)
        if steps_per_snapshot and (not i_step % steps_per_snapshot):
            hydro_plot(
                view,
                hydro_legacy_code,
                (snapshot_size, snapshot_size),
                base_output_file_name +
                "_hydro_image{0:=03}.png".format(i_step)
            )

    hydro_legacy_code.gas_particles.new_channel_to(
            all_sph_particles
            ).copy_attributes(
                    ['mass', 'x', 'y', 'z', 'vx', 'vy', 'vz', 'u']
                    )
    center_of_mass = all_sph_particles.center_of_mass(
            ).as_quantity_in(units.RSun)
    center_of_mass_velocity = all_sph_particles.center_of_mass_velocity(
            ).as_quantity_in(units.km / units.s)
    print()
    print("center_of_mass:", center_of_mass)
    print("center_of_mass_velocity:", center_of_mass_velocity)
    all_sph_particles.position -= center_of_mass
    sph_midpoints = all_sph_particles.position.lengths()

    energy_plot(
        times,
        kinetic_energies, potential_energies, thermal_energies,
        base_output_file_name+"_energy_evolution.png"
    )
    thermal_energy_plot(
        times,
        thermal_energies,
        base_output_file_name+"_thermal_energy_evolution.png"
    )
    composition_comparison_plot(
        midpoints, composition[0],
        sph_midpoints, all_sph_particles.h1,
        base_output_file_name+"_composition_h1.png"
    )
    internal_energy_comparison_plot(
        midpoints, specific_internal_energy,
        sph_midpoints, all_sph_particles.u,
        base_output_file_name+"_new_u.png"
    )
    hydro_plot(
        [-2.0, 2.0, -2.0, 2.0] | units.RSun,
        hydro_legacy_code,
        (100, 100),
        base_output_file_name + "_hydro_image.png"
    )
    hydro_legacy_code.stop()
    print("All done!\n")
Beispiel #13
0
from amuse.community.fi.interface import Fi

from amuse.rfi.core import is_mpd_running
usage = """\
usage: amuse.sh %prog [options]

This example script will simulate the spherical collapse of 
an initially-cold adiabatic gas cloud, with a radial density 
profile proportional to 1/r.
"""

labels = [['K', 'V', 'U', 'E'], ['K', 'V', 'U', 'E']]
fi_gadget_labels = [['K_fi', 'V_fi', 'U_fi', 'E_fi'],
                    ['K_gadget', 'V_gadget', 'U_gadget', 'E_gadget']]

convert_generic_units = ConvertBetweenGenericAndSiUnits(
    1.0 | units.kpc, 1.0e10 | units.MSun, constants.G)
convert_nbody_units = nbody_system.nbody_to_si(1.0 | units.kpc,
                                               1.0e10 | units.MSun)


def run_evrard(hydro_legacy_codes,
               number_of_particles,
               random_seed=None,
               name_of_the_figure="evrard_collapse_test.png"):

    print "\nThe spherical collapse of an initially-cold adiabatic gas cloud,\n", \
        "consisting of ", str(number_of_particles), "particles will be simulated...\n"

    t_end = 3.0 * convert_nbody_units.to_si(
        1.0 | nbody_system.time)  # (3 natural timescales)
    print "Evolving to (3 natural timescales): ", t_end.as_quantity_in(
Beispiel #14
0
def run_supernova():
    # options:
    use_hydro_code = Gadget2  # Fi -or- Gadget2
    hydro_code_options = dict(
        number_of_workers=3
    )  # e.g. dict(use_gl = True) or dict(redirection = "none")
    number_of_sph_particles = 30000
    t_end = 1.0e5 | units.s

    pickle_file = setup_stellar_evolution_model()

    print "Creating initial conditions from a MESA stellar evolution model..."
    model = convert_stellar_model_to_SPH(
        None,
        number_of_sph_particles,
        seed=12345,
        pickle_file=pickle_file,
        #        base_grid_options = dict(type = "glass", target_rms = 0.01),
        with_core_particle=True)
    core, gas_without_core, core_radius = model.core_particle, model.gas_particles, model.core_radius
    if len(core):
        print "Created", len(
            gas_without_core), "SPH particles and one 'core-particle':\n", core
        print "Setting gravitational smoothing to:", core_radius
    else:
        print "Warning: Only SPH particles created."

    inject_supernova_energy(gas_without_core)

    print "\nEvolving (SPH) to:", t_end
    n_steps = 100

    unit_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun,
                                                     constants.G, t_end)
    hydro_code = use_hydro_code(unit_converter, **hydro_code_options)

    try:
        hydro_code.parameters.timestep = t_end / n_steps
    except Exception as exc:
        if not "parameter is read-only" in str(exc): raise

    hydro_code.parameters.epsilon_squared = core_radius**2
    hydro_code.parameters.n_smooth_tol = 0.01
    hydro_code.gas_particles.add_particles(gas_without_core)
    hydro_code.dm_particles.add_particles(core)

    times = [] | units.s
    potential_energies = [] | units.J
    kinetic_energies = [] | units.J
    thermal_energies = [] | units.J
    for time, i_step in [(i * t_end / n_steps, i)
                         for i in range(0, n_steps + 1)]:
        hydro_code.evolve_model(time)
        times.append(time)
        potential_energies.append(hydro_code.potential_energy)
        kinetic_energies.append(hydro_code.kinetic_energy)
        thermal_energies.append(hydro_code.thermal_energy)
        hydro_plot([-1.0, 1.0, -1.0, 1.0] * (350 | units.RSun), hydro_code,
                   (100, 100),
                   os.path.join(
                       get_path_to_results(),
                       "supernova_hydro_image{0:=03}.png".format(i_step)))

    energy_plot(
        times, kinetic_energies, potential_energies, thermal_energies,
        os.path.join(get_path_to_results(), "supernova_energy_evolution.png"))

    hydro_code.stop()
    print "All done!\n"
Beispiel #15
0
def head_on_stellar_merger(
        masses=[0.3, 3.0] | units.MSun,
        star_age=310.0 | units.Myr,
        initial_separation=4.0 | units.RSun,
        angle=numpy.pi / 3,
        initial_speed=3000.0 | units.km / units.s,
        initial_speed_perpendicular=30.0 | units.km / units.s,
        number_of_sph_particles=50000,
        t_end=1.0e4 | units.s,
        sph_code=Fi,
    ):
    """
    masses: Mass of the two stars
    star_age: Initial age of the stars
    number_of_sph_particles: Total number of particles of both stars, divided
    according to their masses
    t_end: (Physical, not computational) duration of the hydrodynamics
    simulation
    sph_code: Code to use for the hydrodynamics simulation
    """

    # Convert some of the input parameters to string, for use in output file
    # names:
    n_string = "n" + ("%1.0e" % (number_of_sph_particles)
                      ).replace("+0", "").replace("+", "")
    t_end_string = "t" + ("%1.0e" % (t_end.value_in(units.s))
                          ).replace("+0", "").replace("+", "")

    base_output_file_name = os.path.join(
        get_path_to_results(), "stellar_merger_"+n_string+"_"+t_end_string)

    stars = Particles(2)
    stars.mass = masses
    try:
        stellar_evolution = MESA()
        stellar_evolution.initialize_code()
    except:
        print "MESA was not built. Returning."
        return
    stellar_evolution.commit_parameters()
    stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()
    print "Evolving stars with MESA..."
    stellar_evolution.evolve_model(star_age)

    number_of_sph_particles_1 = int(
            round(
                number_of_sph_particles
                * (
                    stellar_evolution.particles[0].mass
                    / stellar_evolution.particles.mass.sum()
                    )
                )
            )
    number_of_sph_particles_2 = (
            number_of_sph_particles - number_of_sph_particles_1
            )
    print "Creating initial conditions from a MESA stellar evolution model:"
    print(
            stellar_evolution.particles[0].mass,
            "star consisting of", number_of_sph_particles_1, "particles."
            )
    sph_particles_1 = convert_stellar_model_to_SPH(
        stellar_evolution.particles[0],
        number_of_sph_particles_1,
        seed=12345
    ).gas_particles
    print(
            stellar_evolution.particles[1].mass,
            "star consisting of", number_of_sph_particles_2, "particles."
            )
    sph_particles_2 = convert_stellar_model_to_SPH(
        stellar_evolution.particles[1],
        number_of_sph_particles_2
    ).gas_particles

    initial_separation += stellar_evolution.particles.radius.sum()
    sph_particles_2.x += numpy.cos(angle) * initial_separation
    sph_particles_2.y += numpy.sin(angle) * initial_separation
    sph_particles_1.vx += numpy.cos(angle) * initial_speed - \
        numpy.sin(angle) * initial_speed_perpendicular
    sph_particles_1.vy += numpy.cos(angle) * initial_speed_perpendicular + \
        numpy.sin(angle) * initial_speed
    view = [-0.5, 0.5, -0.5, 0.5] * \
        (initial_separation + stellar_evolution.particles.radius.sum())
    stellar_evolution.stop()

    all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2])
    all_sph_particles.move_to_center()

    unit_converter = ConvertBetweenGenericAndSiUnits(
        1.0 | units.RSun, constants.G, t_end)
    hydro_legacy_code = sph_code(unit_converter)
    n_steps = 100
    hydro_legacy_code.parameters.n_smooth = 96
    try:
        hydro_legacy_code.parameters.timestep = t_end / n_steps
    except Exception as exc:
        if "parameter is read-only" not in str(exc):
            raise
    hydro_legacy_code.gas_particles.add_particles(all_sph_particles)

    print "Evolving to t =", t_end, " (using", sph_code.__name__, "SPH code)."
    for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]:
        hydro_legacy_code.evolve_model(time)
        if not i_step % 4:
            hydro_plot(
                view,
                hydro_legacy_code,
                (300, 300),
                base_output_file_name +
                "_hydro_image{0:=03}.png".format(i_step)
            )
    hydro_legacy_code.stop()
    print "All done!\n"