Exemplo n.º 1
0
    def __init__(self, name, Mtot=(1e15 | units.MSun), Rvir=(500 | units.kpc)):
        self.name = name
        self.converter = nbody_system.nbody_to_si(Mtot, Rvir)
        self.number_of_dm_particles = 1e2
        self.number_of_gas_particles = 1e3

        # Set up numerical smoothing fractions
        self.dm_smoothing_fraction = 0.001
        self.gas_smoothing_fraction = 0.05
        self.dm_epsilon = self.dm_smoothing_fraction * Rvir
        self.gas_epsilon = self.gas_smoothing_fraction * Rvir

        # Setup up gas and dark matter fractions and gas/dm mass
        self.gas_fraction = 0.1
        self.dm_fraction = 1.0 - self.gas_fraction
        self.dm_mass = self.dm_fraction * Mtot
        self.gas_mass = self.gas_fraction * Mtot

        # Set up dark matter particles
        # TODO: probably not use Plummer sphere
        self.dm = new_plummer_model(self.number_of_dm_particles,
                                    convert_nbody=self.converter)
        self.dm.radius = self.dm_epsilon
        self.dm.mass = (1.0 / self.number_of_dm_particles) * self.dm_mass
        self.dm.move_to_center()

        # Set up virialized gas sphere of N gas particles, Plummer sphere
        # TODO: probably not use Plummer sphere
        self.gas = new_plummer_gas_model(self.number_of_gas_particles,
                                         convert_nbody=self.converter)
        self.gas.h_smooth = self.gas_epsilon
        self.gas.move_to_center()
        self.gas.mass = (1.0 / self.number_of_gas_particles) * self.gas_mass

        print "Created ", str(self)
Exemplo n.º 2
0
def main(N, Lstar, boxsize, rho, t_end):

    source = Particle()
    source.position = (0, 0, 0) | units.parsec
    source.flux = Lstar / (20. | units.eV)
    source.rho = rho
    source.xion = 0.0
    source.u = (9. | units.kms)**2

    converter = nbody_system.nbody_to_si(1 | units.MSun, 3 | units.parsec)
    ism = new_plummer_gas_model(N, converter)
    ism.rho = rho
    ism.flux = 0. | units.s**-1
    ism.xion = source.xion
    ism = ism.select(lambda r: r.length() < 0.5 * boxsize, ["position"])

    radiative = SimpleX()
    radiative.parameters.box_size = boxsize
    radiative.parameters.timestep = 100 | units.yr

    radiative.particles.add_particle(source)
    radiative.particles.add_particles(ism)

    radiative.evolve_model(t_end)
    print "min ionization:", radiative.particles.xion.min()
    print "average ionization:", radiative.particles.xion.mean()
    print "max ionization:", radiative.particles.xion.max()

    plot_ionization_fraction(radiative.particles.position,
                             radiative.particles.xion)
    radiative.stop()
def cloud_init(Ngas, Mgas, Rgas):
    '''Initialises the cloud'''
    converter = nbody_system.nbody_to_si(Mgas, Rgas)
    #cloud = molecular_cloud(targetN=Ngas, convert_nbody=converter,\
    #                        base_grid=body_centered_grid_unit_cube).result
    cloud = new_plummer_gas_model(Ngas, convert_nbody=converter)
    return cloud, converter
Exemplo n.º 4
0
def test_gas_init():
    "Test if the gas class works"
    numpy.random.seed(123)
    number_of_gas = 1000
    gas = new_plummer_gas_model(number_of_gas)
    masses = gas.mass
    cloud = GasCode(gas)
    assert len(cloud.particles) == number_of_gas
    assert cloud.particles.mass.sum() == masses.sum()
    cloud.stop()
Exemplo n.º 5
0
def plummer_model_B(nbody, N, Mcloud, Rcloud, parameters=[]):
    np.random.seed(424)

    converter = nbody_system.nbody_to_si(Mcloud, Rcloud)
    bodies = new_plummer_gas_model(N, convert_nbody=converter)

    code = nbody(converter)
    for name, value in parameters:
        setattr(code.parameters, name, value)
    code.particles.add_particles(bodies)
    return code
Exemplo n.º 6
0
 def test5(self):
     print("Test 5: test new_plummer_gas_model with do_scale")
     gas = new_plummer_gas_model(100, do_scale = True)
     
     self.assertEqual(len(gas), 100)
     self.assertAlmostEqual(gas.kinetic_energy(), 0.00 | nbody_system.energy)
     self.assertAlmostEqual(gas.thermal_energy(), 0.25 | nbody_system.energy)
     self.assertAlmostEqual(gas.potential_energy(G=nbody_system.G), -0.50 | nbody_system.energy)
     self.assertAlmostEqual(gas.center_of_mass(),          [0,0,0] | nbody_system.length)
     self.assertAlmostEqual(gas.center_of_mass_velocity(), [0,0,0] | nbody_system.speed)
     self.assertAlmostEqual(gas.total_mass(),                 1.00 | nbody_system.mass)
     self.assertAlmostEqual(gas.virial_radius(),              1.00 | nbody_system.length)
Exemplo n.º 7
0
 def test5(self):
     print "Test 5: test new_plummer_gas_model with do_scale"
     gas = new_plummer_gas_model(100, do_scale = True)
     
     self.assertEqual(len(gas), 100)
     self.assertAlmostEqual(gas.kinetic_energy(), 0.00 | nbody_system.energy)
     self.assertAlmostEqual(gas.thermal_energy(), 0.25 | nbody_system.energy)
     self.assertAlmostEqual(gas.potential_energy(G=nbody_system.G), -0.50 | nbody_system.energy)
     self.assertAlmostEqual(gas.center_of_mass(),          [0,0,0] | nbody_system.length)
     self.assertAlmostEqual(gas.center_of_mass_velocity(), [0,0,0] | nbody_system.speed)
     self.assertAlmostEqual(gas.total_mass(),                 1.00 | nbody_system.mass)
     self.assertAlmostEqual(gas.virial_radius(),              1.00 | nbody_system.length)
def cloud_init(Ngas, Mgas, Rgas, use_plummer=True, seed=1):
    '''Initialises the cloud'''

    np.random.seed(seed)

    converter = nbody_system.nbody_to_si(Mgas, Rgas)
    if use_plummer == True:
        cloud = new_plummer_gas_model(Ngas, convert_nbody=converter)
    else:
        cloud = molecular_cloud(targetN=Ngas, convert_nbody=converter,\
                                base_grid=body_centered_grid_unit_cube).result

    return cloud, converter
Exemplo n.º 9
0
def generate_ism_initial_conditions(N, boxsize):
    converter = nbody_system.nbody_to_si(10|units.MSun, 3|units.parsec)
    ism = new_plummer_gas_model(N, converter)
    ism.flux = 0. | units.s**-1
    ism.xion = 0.0

    hydro = Fi(converter)
    hydro.gas_particles.add_particles(ism)
    hydro.evolve_model(1|units.hour)
    hydro.gas_particles.new_channel_to(ism).copy()
    hydro.stop()
    ism = ism.select(lambda r: r.length() < 0.5*boxsize,["position"])
    print "Max density:", ism.rho.max().in_(units.MSun/units.parsec**3), \
          ism.rho.max().in_(units.amu/units.cm**3)
    return ism
Exemplo n.º 10
0
 def test4(self):
     print "Test 4: test new_plummer_gas_model, model properties"
     numpy.random.seed(345672)
     gas = new_plummer_gas_model(100)
     
     self.assertEqual(len(gas), 100)
     self.assertAlmostEqual(gas.kinetic_energy(), 0.00 | nbody_system.energy)
     self.assertIsOfOrder(  gas.thermal_energy(), 0.25 | nbody_system.energy)
     self.assertAlmostEqual(gas.thermal_energy(), 0.238075609078 | nbody_system.energy)
     self.assertIsOfOrder(  gas.potential_energy(G=nbody_system.G), -0.50 | nbody_system.energy)
     self.assertAlmostEqual(gas.potential_energy(G=nbody_system.G), -0.447052244411 | nbody_system.energy)
     
     self.assertAlmostEqual(gas.center_of_mass(),          [0,0,0] | nbody_system.length)
     self.assertAlmostEqual(gas.center_of_mass_velocity(), [0,0,0] | nbody_system.speed)
     self.assertAlmostEqual(gas.total_mass(),                 1.00 | nbody_system.mass)
     self.assertIsOfOrder(gas.virial_radius(),                1.00 | nbody_system.length)
     self.assertAlmostEqual(gas.virial_radius(),     1.11843751206 | nbody_system.length)
Exemplo n.º 11
0
 def test4(self):
     print("Test 4: test new_plummer_gas_model, model properties")
     numpy.random.seed(345672)
     gas = new_plummer_gas_model(100)
     
     self.assertEqual(len(gas), 100)
     self.assertAlmostEqual(gas.kinetic_energy(), 0.00 | nbody_system.energy)
     self.assertIsOfOrder(  gas.thermal_energy(), 0.25 | nbody_system.energy)
     self.assertAlmostEqual(gas.thermal_energy(), 0.238075609078 | nbody_system.energy)
     self.assertIsOfOrder(  gas.potential_energy(G=nbody_system.G), -0.50 | nbody_system.energy)
     self.assertAlmostEqual(gas.potential_energy(G=nbody_system.G), -0.447052244411 | nbody_system.energy)
     
     self.assertAlmostEqual(gas.center_of_mass(),          [0,0,0] | nbody_system.length)
     self.assertAlmostEqual(gas.center_of_mass_velocity(), [0,0,0] | nbody_system.speed)
     self.assertAlmostEqual(gas.total_mass(),                 1.00 | nbody_system.mass)
     self.assertIsOfOrder(gas.virial_radius(),                1.00 | nbody_system.length)
     self.assertAlmostEqual(gas.virial_radius(),     1.11843751206 | nbody_system.length)
Exemplo n.º 12
0
 def test2(self):
     print "Test 2: testing user interface, with convert_nbody -> SI units"
     convert_nbody = nbody_system.nbody_to_si(6 | units.kg, 7 | units.m)
     gas = new_plummer_gas_model(2, convert_nbody)
     self.assertEquals(gas[0].mass.value_in(units.kg), 3.0)
     self.assertEquals(gas[1].mass.value_in(units.kg), 3.0)
Exemplo n.º 13
0
def res_increase(
    gas=None,
    recalculate_h_density=False,
    seed=123,
    make_cutout=False,
    make_circular_cutout=False,
    circular_rmax=3000 | units.pc,
    x_center=None,
    y_center=None,
    width=None,
    res_increase_factor=85,
):
    numpy.random.seed(seed)
    if gas is None:
        if len(sys.argv) > 2:
            from amuse.io import read_set_from_file
            filename = sys.argv[1]
            res_increase_factor = int(sys.argv[2])
            gas = read_set_from_file(filename, 'amuse')
            if hasattr(gas, "itype"):
                gas = gas[gas.itype == 1]
                del gas.itype
        else:
            from amuse.ic.gasplummer import new_plummer_gas_model
            converter = nbody_system.nbody_to_si(10000 | units.MSun,
                                                 10 | units.pc)
            filename = "test"
            gas = new_plummer_gas_model(10000, converter)
            res_increase_factor = 85
            sph = Fi(converter, mode="openmp")
            gas_in_code = sph.gas_particles.add_particles(gas)
            gas.h_smooth = gas_in_code.h_smooth
            gas.density = gas_in_code.density
            sph.stop()
            write_set_to_file(gas, "old-%s" % filename, "amuse")
            print("old gas created")

    if make_circular_cutout:
        r2 = gas.x**2 + gas.y**2
        cutout = gas[r2 <= circular_rmax**2]
        gas = cutout
        converter = nbody_system.nbody_to_si(gas.total_mass(), width)
        sph = Fi(converter, mode="openmp")
        gas_in_code = sph.gas_particles.add_particles(gas)
        gas.h_smooth = gas_in_code.h_smooth
        gas.density = gas_in_code.density
        sph.stop()

    if make_cutout:
        if (x_center is None or y_center is None or width is None):
            raise Exception("Need to set x_center, y_center and width!")
        cutout = gas.sorted_by_attribute("x")
        cutout = cutout[cutout.x - x_center < width / 2]
        cutout = cutout[cutout.x - x_center > -width / 2]
        cutout = cutout.sorted_by_attribute("y")
        cutout = cutout[cutout.y - y_center < width / 2]
        cutout = cutout[cutout.y - y_center > -width / 2]
        gas = cutout
        converter = nbody_system.nbody_to_si(gas.total_mass(), width)
        sph = Fi(converter, mode="openmp")
        gas_in_code = sph.gas_particles.add_particles(gas)
        gas.h_smooth = gas_in_code.h_smooth
        gas.density = gas_in_code.density
        sph.stop()
        # boundary = test_cutout.h_smooth.max()

    if res_increase_factor == 1:
        return gas

    original_number_of_particles = len(gas)
    new_number_of_particles = (res_increase_factor *
                               original_number_of_particles)

    converter = nbody_system.nbody_to_si(
        gas.total_mass(),
        1 | units.kpc,
    )

    new_gas = Particles(new_number_of_particles)
    # new_gas.h_smooth = gas.h_smooth

    shells, particles_per_shell, shell_radii = find_shell_struct(
        res_increase_factor)

    relative_positions = pos_shift(
        shell_radii,
        particles_per_shell,
        res_increase_factor=res_increase_factor,
    )
    relative_velocities = numpy.zeros(
        res_increase_factor * 3, dtype=float).reshape(res_increase_factor,
                                                      3) | gas.velocity.unit

    random_samples = 50
    number_of_particles = len(gas)
    starting_index = 0
    for r in range(random_samples):
        print("%i / %i random sample done" % (r, random_samples))
        number_of_particles_remaining = len(gas)
        number_of_particles_in_sample = min(
            number_of_particles_remaining,
            int(1 + number_of_particles / random_samples))

        gas_sample = gas.random_sample(number_of_particles_in_sample).copy()
        gas.remove_particles(gas_sample)
        end_index = (starting_index +
                     number_of_particles_in_sample * res_increase_factor)
        new_gas_sample = new_gas[starting_index:end_index]
        psi = 2 * numpy.pi * numpy.random.random()
        theta = 2 * numpy.pi * numpy.random.random()
        phi = 2 * numpy.pi * numpy.random.random()
        relative_positions = rotated(relative_positions, phi, theta, psi)
        # print(len(gas_sample), len(new_gas_sample))
        for i in range(res_increase_factor):
            new_gas_sample[i::res_increase_factor].mass = (gas_sample.mass /
                                                           res_increase_factor)
            new_gas_sample[i::res_increase_factor].x = (
                gas_sample.x + relative_positions[i, 0] * gas_sample.h_smooth)
            new_gas_sample[i::res_increase_factor].y = (
                gas_sample.y + relative_positions[i, 1] * gas_sample.h_smooth)
            new_gas_sample[i::res_increase_factor].z = (
                gas_sample.z + relative_positions[i, 2] * gas_sample.h_smooth)
            new_gas_sample[i::res_increase_factor].vx = (
                gas_sample.vx + relative_velocities[i, 0])
            new_gas_sample[i::res_increase_factor].vy = (
                gas_sample.vy + relative_velocities[i, 1])
            new_gas_sample[i::res_increase_factor].vz = (
                gas_sample.vz + relative_velocities[i, 2])
            new_gas_sample[i::res_increase_factor].density = gas_sample.density
            new_gas_sample[i::res_increase_factor].u = gas_sample.u
        starting_index += number_of_particles_in_sample * res_increase_factor
    new_gas.h_smooth = ((3 * new_gas.mass / (4 * pi * new_gas.density))**(1 /
                                                                          3))

    # sph = Fi(converter, mode="openmp", redirection="none")
    # new_gas_in_code = sph.gas_particles.add_particles(new_gas)
    # new_gas.h_smooth = new_gas_in_code.h_smooth
    # new_gas.density = new_gas_in_code.density
    # sph.stop()

    print("particles now have a mass of %s" %
          (new_gas[0].mass.in_(units.MSun)))
    return new_gas
Exemplo n.º 14
0
def generate_ism_initial_conditions(N, M=10|units.MSun, R=3|units.parsec,
                                    boxsize=10|units.parsec, which=1):
    
    converter = nbody_system.nbody_to_si(M, R)

    # Option 0: Plummer model with mass M and virial radius R.
    # Option 1: Homogeneous sphere with radius R and same central
    #		density as the Plummer model.

    a = R/1.7				# Plummer parameter
    rho0 = 3*M/(4*numpy.pi*a**3)	# Plummer model central density
    rhp = 1.3*a				# Plummer model half-mass radius

    print 'a =', a.in_(units.parsec)
    print 'rhp =', rhp.in_(units.parsec)
    print 'rho0 =', rho0.in_(units.MSun/units.parsec**3)

    if which == 0:
        rmax = boxsize
        ism = new_plummer_gas_model(N, converter)
    else:
        Ru = R
        rmax = Ru
        ism = new_uniform_spherical_particle_distribution(N, Ru,
                                                      4*numpy.pi*rho0*Ru**3/3,
                                                          type="random")
        rhu = Ru/3**0.5
        print 'rhu =', rhu.in_(units.parsec)
        ism.vx = 0.|units.kms
        ism.vy = 0.|units.kms
        ism.vz = 0.|units.kms
        ism.u = (0.075|units.kms)**2
        
        print 'M =', ism.mass.sum().in_(units.MSun)

    #print 'mean u =', ism.u.sum().in_(units.kms**2)/N
    #print 'max u =', ism.u.max().in_(units.kms**2)

    rr = ((ism.position)**2).sum(axis=1).sqrt().value_in(units.parsec)
    ii = numpy.argsort(rr)
    print 'rh =', rr[ii[N/2]], 'parsec'

    ism.flux = 0. | units.s**-1
    ism.xion = 0.0

    hydro = Fi(converter)
    hydro.gas_particles.add_particles(ism)
    hydro.evolve_model(1|units.yr)
    hydro.gas_particles.new_channel_to(ism).copy()
    hydro.stop()

    '''
    plot_density(rr, ism.rho.value_in(units.MSun/units.parsec**3),
                 rho0.value_in(units.MSun/units.parsec**3),
                 a.value_in(units.parsec))
    '''

    #print 'max density =', ism.rho.max().in_(units.MSun/units.parsec**3)
    rc = a/3.
    cent = ism.select(lambda r: r.length() < rc, ["position"])
    print 'approximate central density =', \
        (3*cent.mass.sum()/(4*numpy.pi*rc**3)).in_(units.MSun/units.parsec**3)

    ism = ism.select(lambda r: r.length() < 0.5*boxsize, ["position"])
    #print "max density in box =", \
    #      ism.rho.max().in_(units.MSun/units.parsec**3), \
    #      ism.rho.max().in_(units.amu/units.cm**3)
    if rmax > boxsize/2: rmax = boxsize/2
    
    return ism,rho0,a,M,rmax
Exemplo n.º 15
0
 def new_gas_cluster(self):
     particles = gasplummer.new_plummer_gas_model(
         self.ngas, convert_nbody=self.converter)
     particles.h_smooth = self.gas_epsilon
     particles.mass = (1.0 / self.ngas) * self.gas_mass
     return particles
Exemplo n.º 16
0
class TestSinkAccretion(TestWithMPI):
    converter = nbody_system.nbody_to_si(2 | units.pc, 10000 | units.MSun)
    gas = new_plummer_gas_model(100000, converter)
    gas.h_smooth = 0.1 | units.pc
    gas.u = temperature_to_u(10 | units.K)
    origin_gas = Particle()
    origin_gas.x = 0 | units.pc
    origin_gas.y = 0 | units.pc
    origin_gas.z = 0 | units.pc
    origin_gas.vx = 0 | units.kms
    origin_gas.vy = 0 | units.kms
    origin_gas.vz = 0 | units.kms
    origin_gas.mass = gas[0].mass
    origin_gas.h_smooth = 0.03 | units.pc
    origin_gas.u = 100 | units.kms**2

    def test_forming(self):
        """
        Tests if this cloud indeed forms a sink from origin particle
        """
        result, message = should_a_sink_form(
            self.origin_gas,
            self.gas,
            check_thermal=True,
            accretion_radius=0.1 | units.pc,
        )
        self.assertEqual([True], result)

    def test_divergence(self):
        self.skip("Not yet implemented")

    def test_smoothing_length_too_large(self):
        """
        Tests if this cloud fails to form a sink from origin particle because
        its smoothing length is too large
        """
        h_smooth = 0.05 | units.pc
        origin_gas = self.origin_gas.copy()
        origin_gas.h_smooth = h_smooth
        result, message = should_a_sink_form(
            origin_gas,
            self.gas,
            check_thermal=True,
            accretion_radius=1.99 * h_smooth,
        )
        self.assertEqual([False], result)
        self.assertEqual(["smoothing length too large"], message)

    def test_too_hot(self):
        """
        Tests if this cloud fails to form a sink from origin particle because
        its thermal energy is too high
        """
        gas = self.gas.copy()
        gas.u = temperature_to_u(20 | units.K)
        result, message = should_a_sink_form(
            self.origin_gas,
            gas,
            check_thermal=True,
            accretion_radius=0.1 | units.pc,
        )
        self.assertEqual([False], result)
        self.assertEqual(["e_th/e_pot > 0.5"], message)

    def test_expanding(self):
        """
        Tests if this cloud fails to form a sink from origin particle because
        its kinetic energy is too high
        """
        gas = self.gas.copy()
        gas.vx = gas.x / (10 | units.kyr)
        gas.vy = gas.y / (10 | units.kyr)
        gas.vz = gas.z / (10 | units.kyr)
        result, message = should_a_sink_form(
            self.origin_gas,
            gas,
            check_thermal=True,
            accretion_radius=0.1 | units.pc,
        )
        self.assertEqual([False], result)
        self.assertEqual(["e_tot < 0"], message)

    def test_rotating(self):
        """
        Tests if this cloud fails to form a sink from origin particle because
        it is rotating
        """
        gas = self.gas.copy()
        gas.vx = gas.y / (10 | units.kyr)
        gas.vy = -gas.x / (10 | units.kyr)
        result, message = should_a_sink_form(
            self.origin_gas,
            gas,
            check_thermal=True,
            accretion_radius=0.1 | units.pc,
        )
        self.assertEqual(["e_rot too big"], message)
        self.assertEqual([False], result)
Exemplo n.º 17
0
 def new_gas_cluster(self):
     particles=gasplummer.new_plummer_gas_model(self.ngas,convert_nbody=self.converter)
     particles.h_smooth= self.gas_epsilon
     particles.mass = (1.0/self.ngas) * self.gas_mass
     return particles
Exemplo n.º 18
0
 def test2(self):
     print "Test 2: testing user interface, with convert_nbody -> SI units"
     convert_nbody = nbody_system.nbody_to_si(6|units.kg, 7 | units.m) 
     gas =  new_plummer_gas_model(2, convert_nbody)
     self.assertEquals(gas[0].mass.value_in(units.kg), 3.0)
     self.assertEquals(gas[1].mass.value_in(units.kg), 3.0)
Exemplo n.º 19
0
 def test3(self):
     print "Test 3: testing user interface, without convert_nbody -> nbody units"
     gas =  new_plummer_gas_model(2, None)
     self.assertEquals(gas[0].mass.value_in(nbody_system.mass), 0.5)
     self.assertEquals(gas[1].mass.value_in(nbody_system.mass), 0.5)
Exemplo n.º 20
0
def run_hydrodynamics(N=100, Mtot=1|units.MSun, Rvir=1|units.RSun,
                      t_end=0.5|units.day, n_steps=10,\
                      vx = 0 |(units.RSun/units.day),\
                      vy = 0 |(units.RSun/units.day),\
                      vz = 0 |(units.RSun/units.day),\
                      plummer1=None, plummer2=None,\
                      bodyname = None):

    """ Runs the hydrodynamics simulation and returns a HydroResults
    instance. 


    FUNCTION WALKTHROUGH:

    In the following explanation 'plummer1' and 'plummer2' are assumed
    to be hdf5 files written by the function write_set_to_file().

    Case 1: 
    If 'plummer1' and 'plummer2' are filenames of hdf5 files, then these 
    two plummer spheres will be smashed together. 

    Case 2:
    If only plummer1 is supplied, then it will evolve plummer1 with 
    t_end timerange and n_steps steps.

    Case 3:
    If no plummers spheres are supplied, then it will generate a new
    plummer sphere using the default/supplied initial conditions. 

   
    OUTPUT FILES:

    If 'results_out' is specified, the HydroResult instance is written
    to file in HDF5 format. This however does not use 
    write_set_to_file() which writes the entire Particles class and
    its attributes to file at each dt, but uses write_to_hdf5() 
    from the 'support' module which is tailored to writing
    HydroResults instances to file. This HDF5 contains all necessary
    data to plot the required plots of the assignment.
    
    In addition, the last snapshot of the Particles instance is written
    to file using write_set_to_file(), the latter file is written to 
    the 'bodies' directory. Only the last snapshot is written to file
    because the history of a Particle set is not of interest when 
    reloading them to smash plummer spheres.   """

    converter = nbody_system.nbody_to_si(Mtot, Rvir)

    fi = Fi(converter)

    if plummer1 and plummer2: 
        eta_smash = 0.3 |units.day
        if plummer1 == plummer2:
            bodies1 = read_set_from_file(plummer1, format='hdf5')
            bodies2 = bodies1.copy()
            bodies2.key += 1
        else:
            bodies1 = read_set_from_file(plummer1, format='hdf5')
            bodies2 = read_set_from_file(plummer2, format='hdf5')

        bodies1.move_to_center()
        bodies2.move_to_center()

        if vx.value_in(vx.unit) == 0  and vy.value_in(vy.unit) == 0 \
            and vz.value_in(vz.unit) == 0:
            bodies1.x += -1 |units.RSun
            bodies2.x += 1 |units.RSun

        else:
            bodies1.x += (-1)*vx*eta_smash
            bodies2.x += 1*vx*eta_smash
            bodies1.vx += vx
            bodies2.vx += (-1)*vx 
            bodies1.vy += vy
            bodies2.vy += (-1)*vy
            bodies1.vz += vz
            bodies2.vz += (-1)*vz

        bodies1.add_particles(bodies2)
        bodies = bodies1

    elif plummer1 or plummer2: 
        if plummer1:
            bodies = read_set_from_file(plummer1)
        else:
            bodies = read_set_from_file(plummer2)
        bodies.move_to_center()

    else: 
        bodies = new_plummer_gas_model(N, convert_nbody=converter)

    fi.gas_particles.add_particles(bodies)
    fi_to_framework = fi.gas_particles.new_channel_to(bodies)

    fi.parameters.self_gravity_flag = True

    data = {'lagrangianradii':AdaptingVectorQuantity(),\
            'angular_momentum':AdaptingVectorQuantity(),\
            'time':AdaptingVectorQuantity(),\
            'positions':AdaptingVectorQuantity(),\
            'kinetic_energy':AdaptingVectorQuantity(),\
            'potential_energy':AdaptingVectorQuantity(),\
            'total_energy':AdaptingVectorQuantity() } 

    mass_fractions = [0.10, 0.25, 0.50, 0.75]
    setattr(data['lagrangianradii'], 'mf', mass_fractions)

    data['radius_initial'], data['densities_initial'] = radial_density(\
         fi.particles.x, fi.particles.mass, N=10, dim=1)

    timerange = numpy.linspace(0, t_end.value_in(t_end.unit),\
                                  n_steps) | t_end.unit
    data['time'].extend(timerange)
 
    fi.parameters.timestep = t_end/(n_steps+1)

    widget = drawwidget("Evolving")
    pbar = pb.ProgressBar(widgets=widget, maxval=len(timerange)).start()

    for i, t in enumerate(timerange):
        fi.evolve_model(t)
        data['kinetic_energy'].append(fi.kinetic_energy)
        data['potential_energy'].append(fi.potential_energy)
        data['total_energy'].append(fi.total_energy)
        data['positions'].append(fi.particles.position)
        data['angular_momentum'].append(fi.gas_particles.\
                                        total_angular_momentum())
        data['lagrangianradii'].append(fi.particles.LagrangianRadii(\
                                       unit_converter=converter,\
                                       mf=mass_fractions)[0])
        if t == timerange[-1] and bodyname:
            if os.path.dirname(bodyname) == '':
                filename = "bodies/"+bodyname 
            fi_to_framework.copy()
            write_set_to_file(bodies.savepoint(t), filename, "hdf5")

        pbar.update(i)
    pbar.finish()

    data['radius_final'], data['densities_final'] = radial_density(\
         fi.particles.x, fi.particles.mass, N=10, dim=1)

    fi.stop()

    results = HydroResults(data)
    return results 
Exemplo n.º 21
0
def clustergas(sfeff=0.05,
               Nstar=1000,
               Ngas=1000,
               t_end=30. | units.Myr,
               dt_plot=0.05 | units.Myr,
               Rscale=0.5 | units.parsec,
               runid="runtest",
               feedback_efficiency=0.03,
               subvirialfac=1.,
               grav_code=PhiGRAPE,
               gas_code=Gadget2,
               se_code=SSEplus,
               grav_couple_code=Octgrav,
               grav_code_extra=dict(mode='gpu', redirection='none'),
               gas_code_extra=dict(number_of_workers=3,
                                   use_gl=False,
                                   redirection='none'),
               se_code_extra=dict(redirection='none'),
               grav_couple_code_extra=dict()):

    try:
        os.mkdir(runid)
    except:
        pass
    print "Nstar, Ngas:", Nstar, Ngas
    eps = 0.05 * Rscale
    eps_star = 0.001 * Rscale

    star_masses = new_salpeter_mass_distribution(Nstar,
                                                 mass_max=100. | units.MSun)
    total_star_mass = star_masses.sum()
    total_mass = total_star_mass / sfeff
    print "maxmass:", max(star_masses)
    print "Tcross", (2.8 *
                     (Rscale**3 / constants.G / total_star_mass)**0.5).in_(
                         units.Myr)

    print sorted(star_masses)[-10:]
    #  raise Exception

    conv = nbody_system.nbody_to_si(total_mass, Rscale)

    star_parts = new_plummer_model(Nstar, convert_nbody=conv)
    star_parts.mass = star_masses
    star_parts.radius = eps_star

    # sub-virialized
    star_parts.vx = star_parts.vx * subvirialfac
    star_parts.vy = star_parts.vy * subvirialfac
    star_parts.vz = star_parts.vz * subvirialfac

    print "total cluster mass:", total_mass.in_(units.MSun)
    print "star mass:", total_star_mass.in_(units.MSun)
    print "gas mass:", (total_mass - total_star_mass).in_(units.MSun)

    print "t_end:", conv.to_nbody(t_end)

    gas_parts = new_plummer_gas_model(Ngas,
                                      convert_nbody=conv,
                                      base_grid=body_centered_grid_unit_cube)
    gas_parts.h_smooth = 0. | units.parsec
    gas_parts.mass = gas_parts.mass * (1 - sfeff)

    print "gas particle mass:", ((total_mass - total_star_mass) /
                                 len(gas_parts)).in_(units.MSun)

    mu = 1.4 | units.amu
    gamma1 = 1.6667 - 1
    #  print 'min Temp:', (gamma1*min(gas_parts.u)*(1.4*units.amu)/constants.kB).in_(units.K)
    print 'min Temp:', (gamma1 * min(gas_parts.u) * mu / constants.kB).in_(
        units.K)

    mgas = (total_mass - total_star_mass) / len(gas_parts)
    print max(gas_parts.u)**0.5

    dt = smaller_nbody_power_of_two(dt_plot, conv)
    dt_star = smaller_nbody_power_of_two(0.001 | units.Myr, conv)  #0.001

    #original settings
    #  dt_sph=dt_star
    #  dt_fast=dt_star*8  # 8
    #  dt_feedback=dt_fast*2 # 1

    #new, improved, more snapshots (thanks inti)
    dt_fast = dt / 2  # 8
    dt_feedback = dt  # 1

    feedback_dt = (10. | units.yr, dt_fast)

    if not dt_star <= dt_fast <= dt_feedback:
        raise Exception

    print 'dt_plot:', conv.to_nbody(dt_plot), dt_plot.in_(units.Myr)
    print 'dt:', conv.to_nbody(dt), dt.in_(units.Myr)
    print 'dt_feedback:', conv.to_nbody(dt_feedback), dt_feedback.in_(
        units.Myr)
    print 'dt_fast:', conv.to_nbody(dt_fast), dt_fast.in_(units.Myr)
    print 'dt_star:', conv.to_nbody(dt_star), dt_star.in_(units.Myr)

    star_parts.move_to_center()
    gas_parts.move_to_center()

    sys = grav_gas_sse(
        grav_code,
        gas_code,
        se_code,
        grav_couple_code,
        conv,
        mgas,
        star_parts,
        gas_parts,
        dt_feedback,
        dt_fast,
        grav_parameters=(["epsilon_squared",
                          eps_star**2], ["timestep_parameter", 0.1]),
        #                                ["timestep", dt_star]),
        gas_parameters=(
            ["time_max", 32. | units.Myr],
            #                               ["courant", 0.15 | units.none],
            ["n_smooth", 64 | units.none],
            #                               ["artificial_viscosity_alpha",1.| units.none],
            ["n_smooth_tol", 0.005 | units.none],
            ## NB
            ["max_size_timestep", dt_fast],
            ## NB
            ["time_limit_cpu", 3600000 | units.s]),
        couple_parameters=(["epsilon_squared", eps**2], ["opening_angle",
                                                         0.5]),
        feedback_efficiency=feedback_efficiency,
        feedback_radius=0.025 * Rscale,
        feedback_dt=feedback_dt,
        grav_code_extra=grav_code_extra,
        gas_code_extra=gas_code_extra,
        se_code_extra=se_code_extra,
        grav_couple_code_extra=grav_couple_code_extra)

    nsnap = 0
    sys.synchronize_model()
    t = sys.model_time
    tout = t.value_in(units.Myr)
    ek = sys.kinetic_energy.value_in(1.e51 * units.erg)
    ep = sys.potential_energy.value_in(1.e51 * units.erg)
    eth = sys.thermal_energy.value_in(1.e51 * units.erg)
    ef = sys.feedback_energy.value_in(1.e51 * units.erg)
    print 't Ek Ep Eth Ef:', tout, ek, ep, eth, ef, ek + ep + eth - ef
    sys.dump_system_state(runid + "/dump-%6.6i" % nsnap)

    print 'max smooth:', max(sys.sph.gas_particles.radius).in_(units.parsec)
    print 'mean smooth:', sys.sph.gas_particles.radius.mean().in_(units.parsec)
    print 'min smooth:', min(sys.sph.gas_particles.radius).in_(units.parsec)
    print 'eps:', eps.in_(units.parsec)
    print 'feedback radius:', (0.01 * Rscale).in_(units.parsec)

    while (t < t_end - dt / 2):
        beginning = time.time()
        sys.evolve_model(t + dt)
        sys.synchronize_model()
        t = sys.model_time
        tout = t.value_in(units.Myr)
        ek = sys.kinetic_energy.value_in(1.e51 * units.erg)
        ep = sys.potential_energy.value_in(1.e51 * units.erg)
        eth = sys.thermal_energy.value_in(1.e51 * units.erg)
        ef = sys.feedback_energy.value_in(1.e51 * units.erg)
        print 't Ek Ep Eth Ef:', tout, ek, ep, eth, ef, ek + ep + eth - ef
        nsnap += 1
        sys.dump_system_state(runid + "/dump-%6.6i" % nsnap)

        end = time.time()

        print 'iteration', nsnap, 'took:', (end - beginning), 'seconds'
Exemplo n.º 22
0
 def test3(self):
     print "Test 3: testing user interface, without convert_nbody -> nbody units"
     gas = new_plummer_gas_model(2, None)
     self.assertEquals(gas[0].mass.value_in(nbody_system.mass), 0.5)
     self.assertEquals(gas[1].mass.value_in(nbody_system.mass), 0.5)
Exemplo n.º 23
0
      escapers=self.particles.select_array(
        lambda x,y,z: (x**2+y**2+z**2 > outofbox**2), ["x","y","z"])
      print "***", len(escapers)
      if len(escapers)>0:
        self.escapers.add_particles(escapers)
        self.particles.remove_particles(escapers)
#      Fi.evolve_model(self,*args, **kargs)
      self.overridden().evolve_model(*args,**kargs)
      

if __name__=="__main__":
  Ngas=1000
  conv = nbody_system.nbody_to_si(100 | units.MSun, 1 | units.parsec)
  dt=conv.to_si(1|nbody_system.time)/100
  print dt.in_(units.Myr)
  parts=new_plummer_gas_model(Ngas,convert_nbody=conv)
  parts.h_smooth=0 | units.parsec
  outofbox=0.9*10. | units.parsec
  escapers=parts.select_array(
        lambda x,y,z: (x**2+y**2+z**2 > outofbox**2), ["x","y","z"])
  print "**",len(escapers),outofbox.in_(units.parsec)

  parts.remove_particles(escapers)
  print len(parts)

  sph=BoxedFi(convert_nbody=conv,use_gl=True)
  sph.parameters.pboxsize=20. | units.parsec
  sph.parameters.timestep=dt
  sph.parameters.self_gravity_flag=False

  sph.gas_particles.add_particles(parts)
Exemplo n.º 24
0
def generate_ism_initial_conditions(N,
                                    M=10 | units.MSun,
                                    R=3 | units.parsec,
                                    boxsize=10 | units.parsec,
                                    which=1):

    converter = nbody_system.nbody_to_si(M, R)

    # Option 0: Plummer model with mass M and virial radius R.
    # Option 1: Homogeneous sphere with radius R and same central
    #		density as the Plummer model.

    a = R / 1.7  # Plummer parameter
    rho0 = 3 * M / (4 * numpy.pi * a**3)  # Plummer model central density
    rhp = 1.3 * a  # Plummer model half-mass radius

    print('a =', a.in_(units.parsec))
    print('rhp =', rhp.in_(units.parsec))
    print('rho0 =', rho0.in_(units.MSun / units.parsec**3))

    if which == 0:
        rmax = boxsize
        ism = new_plummer_gas_model(N, converter)
    else:
        Ru = R
        rmax = Ru
        ism = new_uniform_spherical_particle_distribution(N,
                                                          Ru,
                                                          4 * numpy.pi * rho0 *
                                                          Ru**3 / 3,
                                                          type="random")
        rhu = Ru / 3**0.5
        print('rhu =', rhu.in_(units.parsec))
        ism.vx = 0. | units.kms
        ism.vy = 0. | units.kms
        ism.vz = 0. | units.kms
        ism.u = (0.075 | units.kms)**2

        print('M =', ism.mass.sum().in_(units.MSun))

    #print 'mean u =', ism.u.sum().in_(units.kms**2)/N
    #print 'max u =', ism.u.max().in_(units.kms**2)

    rr = ((ism.position)**2).sum(axis=1).sqrt().value_in(units.parsec)
    ii = numpy.argsort(rr)
    print('rh =', rr[ii[N / 2]], 'parsec')

    ism.flux = 0. | units.s**-1
    ism.xion = 0.0

    hydro = Fi(converter)
    hydro.gas_particles.add_particles(ism)
    hydro.evolve_model(1 | units.yr)
    hydro.gas_particles.new_channel_to(ism).copy()
    hydro.stop()
    '''
    plot_density(rr, ism.rho.value_in(units.MSun/units.parsec**3),
                 rho0.value_in(units.MSun/units.parsec**3),
                 a.value_in(units.parsec))
    '''

    #print 'max density =', ism.rho.max().in_(units.MSun/units.parsec**3)
    rc = a / 3.
    cent = ism.select(lambda r: r.length() < rc, ["position"])
    print('approximate central density =', \
        (3*cent.mass.sum()/(4*numpy.pi*rc**3)).in_(units.MSun/units.parsec**3))

    ism = ism.select(lambda r: r.length() < 0.5 * boxsize, ["position"])
    #print "max density in box =", \
    #      ism.rho.max().in_(units.MSun/units.parsec**3), \
    #      ism.rho.max().in_(units.amu/units.cm**3)
    if rmax > boxsize / 2: rmax = boxsize / 2

    return ism, rho0, a, M, rmax
Exemplo n.º 25
0
def run_hydrodynamics(N=100, Mtot=1|units.MSun, Rvir=1|units.RSun,
                      t_end=0.5|units.day, n_steps=10,\
                      vx = 0 |(units.RSun/units.day),\
                      vy = 0 |(units.RSun/units.day),\
                      vz = 0 |(units.RSun/units.day),\
                      plummer1=None, plummer2=None,\
                      bodyname = None):
    """ Runs the hydrodynamics simulation and returns a HydroResults
    instance. 


    FUNCTION WALKTHROUGH:

    In the following explanation 'plummer1' and 'plummer2' are assumed
    to be hdf5 files written by the function write_set_to_file().

    Case 1: 
    If 'plummer1' and 'plummer2' are filenames of hdf5 files, then these 
    two plummer spheres will be smashed together. 

    Case 2:
    If only plummer1 is supplied, then it will evolve plummer1 with 
    t_end timerange and n_steps steps.

    Case 3:
    If no plummers spheres are supplied, then it will generate a new
    plummer sphere using the default/supplied initial conditions. 

   
    OUTPUT FILES:

    If 'results_out' is specified, the HydroResult instance is written
    to file in HDF5 format. This however does not use 
    write_set_to_file() which writes the entire Particles class and
    its attributes to file at each dt, but uses write_to_hdf5() 
    from the 'support' module which is tailored to writing
    HydroResults instances to file. This HDF5 contains all necessary
    data to plot the required plots of the assignment.
    
    In addition, the last snapshot of the Particles instance is written
    to file using write_set_to_file(), the latter file is written to 
    the 'bodies' directory. Only the last snapshot is written to file
    because the history of a Particle set is not of interest when 
    reloading them to smash plummer spheres.   """

    converter = nbody_system.nbody_to_si(Mtot, Rvir)

    fi = Fi(converter)

    if plummer1 and plummer2:
        eta_smash = 0.3 | units.day
        if plummer1 == plummer2:
            bodies1 = read_set_from_file(plummer1, format='hdf5')
            bodies2 = bodies1.copy()
            bodies2.key += 1
        else:
            bodies1 = read_set_from_file(plummer1, format='hdf5')
            bodies2 = read_set_from_file(plummer2, format='hdf5')

        bodies1.move_to_center()
        bodies2.move_to_center()

        if vx.value_in(vx.unit) == 0  and vy.value_in(vy.unit) == 0 \
            and vz.value_in(vz.unit) == 0:
            bodies1.x += -1 | units.RSun
            bodies2.x += 1 | units.RSun

        else:
            bodies1.x += (-1) * vx * eta_smash
            bodies2.x += 1 * vx * eta_smash
            bodies1.vx += vx
            bodies2.vx += (-1) * vx
            bodies1.vy += vy
            bodies2.vy += (-1) * vy
            bodies1.vz += vz
            bodies2.vz += (-1) * vz

        bodies1.add_particles(bodies2)
        bodies = bodies1

    elif plummer1 or plummer2:
        if plummer1:
            bodies = read_set_from_file(plummer1)
        else:
            bodies = read_set_from_file(plummer2)
        bodies.move_to_center()

    else:
        bodies = new_plummer_gas_model(N, convert_nbody=converter)

    fi.gas_particles.add_particles(bodies)
    fi_to_framework = fi.gas_particles.new_channel_to(bodies)

    fi.parameters.self_gravity_flag = True

    data = {'lagrangianradii':AdaptingVectorQuantity(),\
            'angular_momentum':AdaptingVectorQuantity(),\
            'time':AdaptingVectorQuantity(),\
            'positions':AdaptingVectorQuantity(),\
            'kinetic_energy':AdaptingVectorQuantity(),\
            'potential_energy':AdaptingVectorQuantity(),\
            'total_energy':AdaptingVectorQuantity() }

    mass_fractions = [0.10, 0.25, 0.50, 0.75]
    setattr(data['lagrangianradii'], 'mf', mass_fractions)

    data['radius_initial'], data['densities_initial'] = radial_density(\
         fi.particles.x, fi.particles.mass, N=10, dim=1)

    timerange = numpy.linspace(0, t_end.value_in(t_end.unit),\
                                  n_steps) | t_end.unit
    data['time'].extend(timerange)

    fi.parameters.timestep = t_end / (n_steps + 1)

    widget = drawwidget("Evolving")
    pbar = pb.ProgressBar(widgets=widget, maxval=len(timerange)).start()

    for i, t in enumerate(timerange):
        fi.evolve_model(t)
        data['kinetic_energy'].append(fi.kinetic_energy)
        data['potential_energy'].append(fi.potential_energy)
        data['total_energy'].append(fi.total_energy)
        data['positions'].append(fi.particles.position)
        data['angular_momentum'].append(fi.gas_particles.\
                                        total_angular_momentum())
        data['lagrangianradii'].append(fi.particles.LagrangianRadii(\
                                       unit_converter=converter,\
                                       mf=mass_fractions)[0])
        if t == timerange[-1] and bodyname:
            if os.path.dirname(bodyname) == '':
                filename = "bodies/" + bodyname
            fi_to_framework.copy()
            write_set_to_file(bodies.savepoint(t), filename, "hdf5")

        pbar.update(i)
    pbar.finish()

    data['radius_final'], data['densities_final'] = radial_density(\
         fi.particles.x, fi.particles.mass, N=10, dim=1)

    fi.stop()

    results = HydroResults(data)
    return results