def main():
    "Test class with an IMF"
    import sys
    import numpy
    from amuse.units import units

    numpy.random.seed(11)

    try:
        from amuse_masc import make_a_star_cluster
        use_masc = True
    except ImportError:
        use_masc = False

    if len(sys.argv) > 1:
        from amuse.io import read_set_from_file
        stars = read_set_from_file(sys.argv[1], "amuse")
    elif use_masc:
        stars = make_a_star_cluster.new_cluster(number_of_stars=10001)
    else:
        from amuse.ic.salpeter import new_salpeter_mass_distribution
        stars = Particles(10000)
        stars.mass = new_salpeter_mass_distribution(len(stars))
    print("Number of stars: %i" % (len(stars)))

    code = StellarEvolutionCode(evo_code=SeBa)
    code.particles.add_particles(stars)
    print(code.parameters)
    timestep = 0.2 | units.Myr
    for step in range(10):
        time = step * timestep
        code.evolve_model(time)
        print("Evolved to %s" % code.model_time.in_(units.Myr))
        print("Most massive star: %s" % code.particles.mass.max())
Exemple #2
0
    def test16(self):
        print "test evolution of 1000 star sampled over flattish IMF"
        
        number_of_stars=1000
        
        class notsorandom(object):
            def random(self,N):
                return numpy.array(range(N))/(N-1.)
            def random_sample(self,N):
                return numpy.array(range(N))/(N-1.)

        masses = new_salpeter_mass_distribution(
            number_of_stars, 
            mass_min = 0.1 | units.MSun,
            mass_max = 100.0 | units.MSun, 
            alpha = -1.01,random=notsorandom()
        )
 
        stars=Particles(mass=masses)

        instance=SSE()
        instance.particles.add_particles(stars)
        
        i=0
        for p in instance.particles:
          print i,p.mass,
          p.evolve_for(13.2 | units.Gyr)
          print p.mass
          i+=1
        instance.stop()
Exemple #3
0
    def test16(self):
        print("test evolution of 1000 star sampled over flattish IMF")

        number_of_stars = 1000

        class notsorandom(object):
            def random(self, N):
                return numpy.array(range(N)) / (N - 1.)

            def random_sample(self, N):
                return numpy.array(range(N)) / (N - 1.)

        masses = new_salpeter_mass_distribution(number_of_stars,
                                                mass_min=0.1 | units.MSun,
                                                mass_max=100.0 | units.MSun,
                                                alpha=-1.01,
                                                random=notsorandom())

        stars = Particles(mass=masses)

        instance = SSE()
        instance.particles.add_particles(stars)

        i = 0
        for p in instance.particles:
            p.evolve_for(13.2 | units.Gyr)
            i += 1
        instance.stop()
Exemple #4
0
    def __init__(self,
                 num_stars,
                 xoffset,
                 yoffset,
                 zoffset,
                 repopulate_every_run=True):
        self.num_stars = num_stars
        self.xoffset = xoffset
        self.yoffset = yoffset
        self.zoffset = zoffset

        self.repopulate_every_run = repopulate_every_run
        if repopulate_every_run is False:
            # create nbody_converter thing?
            convert_nbody = nbody_system.nbody_to_si(100.0 | units.MSun,
                                                     1 | units.parsec)

            # instantiate plummer sphere
            self.initial_plummer = new_plummer_sphere(self.num_stars,
                                                      convert_nbody)
            self.initial_plummer.x += self.xoffset | units.lightyear
            self.initial_plummer.y += self.yoffset | units.lightyear
            self.initial_plummer.z += self.zoffset | units.lightyear

            # provide mass distribution for stars
            self.initial_plummer.mass = new_salpeter_mass_distribution(
                self.num_stars)

        self.plummer = None
def stellar_population(number_of_stars = 1000,min_mass=0.1, max_mass=125, alpha=-2.35):

    """
    Generates a stellar population that follows the Salpeter mass function
    """
    masses = new_salpeter_mass_distribution(number_of_stars, min_mass | units.MSun, max_mass | units.MSun, alpha = alpha)
    return masses
Exemple #6
0
    def xslowtest16(self):
        print "test full evolution of 1000 star sampled over flattish IMF"

        number_of_stars=1000

        from amuse.ic.salpeter import new_salpeter_mass_distribution
        import numpy

        class notsorandom(object):
            def random(self,N):
                return numpy.array(range(N))/(N-1.)

        masses = new_salpeter_mass_distribution(
            number_of_stars,
            mass_min = 0.1 | units.MSun,
            mass_max = 100.0 | units.MSun,
            alpha = -1.01,random=notsorandom()
        )

        stars = Particles(mass=masses)

        instance=EVtwin()
        instance.parameters.maximum_number_of_stars=number_of_stars
        instance.particles.add_particles(stars)

        for p in instance.particles:
          p.evolve_for(13.2 | units.Gyr)
Exemple #7
0
def demo3(N):

    salpeter_masses = new_salpeter_mass_distribution(N)
    total_mass = salpeter_masses.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec)

    print convert_nbody.to_nbody(100 | units.Myr)

    parts = new_plummer_model(N, convert_nbody)
    parts.radius = 0. | units.RSun
    parts.mass = salpeter_masses
    parts.move_to_center()

    gravity = PhiGRAPE(convert_nbody, use_gl=True)

    eps = 0.001 | units.parsec
    gravity.parameters.epsilon_squared = eps**2

    gravity.particles.add_particles(parts)

    stellar_evolution = SSE()
    stellar_evolution.initialize_module_with_default_parameters()

    stellar_evolution.particles.add_particles(parts)

    return gravity, stellar_evolution
Exemple #8
0
def create_stars(number_of_stars, size):
    masses = new_salpeter_mass_distribution(number_of_stars, mass_min = 2|units.MSun)
    converter = nbody_system.nbody_to_si(masses.sum(), size)
    stars = new_plummer_model(number_of_stars, convert_nbody=converter)
    stars.mass = masses
    stars.zams_mass = masses

    return stars, converter
Exemple #9
0
def create_stars(number_of_stars, size):
    masses = new_salpeter_mass_distribution(number_of_stars,
                                            mass_min=2 | units.MSun)
    converter = nbody_system.nbody_to_si(masses.sum(), size)
    stars = new_plummer_model(number_of_stars, convert_nbody=converter)
    stars.mass = masses
    stars.zams_mass = masses

    return stars, converter
Exemple #10
0
 def test5(self):
     print("Test 5: testing user interface (SI units)")
     numpy.random.seed(345672)
     masses = new_salpeter_mass_distribution(1000)
     
     self.assertEqual(len(masses), 1000)
     self.assertAlmostEqual(masses.mean(), 0.334475937397 | units.MSun)
     self.assertAlmostRelativeEqual(masses.mean(), SalpeterIMF().mass_mean(), 1)
     self.assertAlmostEqual(masses.amin(), 0.10017909529 | units.MSun)
     self.assertAlmostEqual(masses.amax(), 19.7132849297 | units.MSun)
Exemple #11
0
    def test5(self):
        print "Test 5: testing user interface (SI units)"
        numpy.random.seed(345672)
        masses = new_salpeter_mass_distribution(1000)

        self.assertEqual(len(masses), 1000)
        self.assertAlmostEqual(masses.mean(), 0.334475937397 | units.MSun)
        self.assertAlmostRelativeEqual(masses.mean(), SalpeterIMF().mass_mean(), 1)
        self.assertAlmostEqual(masses.amin(), 0.10017909529 | units.MSun)
        self.assertAlmostEqual(masses.amax(), 19.7132849297 | units.MSun)
Exemple #12
0
def new_cluster(number_of_stars=1000):
    masses = new_salpeter_mass_distribution(number_of_stars,
                                            mass_min=0.1 | units.MSun,
                                            mass_max=125.0 | units.MSun,
                                            alpha=-2.35)
    nbody_converter = nbody_system.nbody_to_si(masses.sum(), 1 | units.parsec)
    particles = new_plummer_model(number_of_stars, nbody_converter)
    particles.mass = masses
    particles.move_to_center()
    return particles
Exemple #13
0
def new_cluster(number_of_stars = 1000):
    masses = new_salpeter_mass_distribution(
        number_of_stars, 
        mass_min = 0.1 | units.MSun,
        mass_max = 125.0 | units.MSun, 
        alpha = -2.35
    )
    nbody_converter = nbody_system.nbody_to_si(masses.sum(), 1 | units.parsec)
    particles = new_plummer_model(number_of_stars, nbody_converter)
    particles.mass = masses
    particles.move_to_center()
    return particles
Exemple #14
0
def new_cluster(number_of_stars=1000):
    masses = new_salpeter_mass_distribution(number_of_stars,
                                            mass_min=0.1 | units.MSun,
                                            mass_max=125.0 | units.MSun,
                                            alpha=-2.35)

    particles = Particles(number_of_stars)
    particles.mass = masses
    particles.x = units.parsec(random.gamma(2.0, 1.0, number_of_stars))
    particles.y = units.parsec(random.gamma(1.0, 1.0, number_of_stars))
    particles.z = units.parsec(random.random(number_of_stars))

    return particles
Exemple #15
0
def new_cluster(number_of_stars = 1000):
    masses = new_salpeter_mass_distribution(
        number_of_stars, 
        mass_min = 0.1 | units.MSun,
        mass_max = 125.0 | units.MSun, 
        alpha = -2.35
    )
    
    particles = Particles(number_of_stars)
    particles.mass = masses
    particles.x = units.parsec(random.gamma(2.0, 1.0, number_of_stars))
    particles.y = units.parsec(random.gamma(1.0, 1.0, number_of_stars))
    particles.z = units.parsec(random.random(number_of_stars))
    
    return particles
Exemple #16
0
def create_cluster(Ncl, Mstar, Rcl, Mcut):
    """
    Create a cluster with Salpeter IMF from 0.1 - Mstar | units.MSun,
    distributed in a virialzed Plummer sphere. Split stars into
    two particle sets: below_cut and above_cut for m < Mcut; m >= Mcut.
    """

    print "Deriving a set of", str(Ncl), "random masses",\
        "following a Salpeter IMF between 0.1 and",\
        str(Mstar), "MSun (alpha = -2.35)."
    salpeter_masses = new_salpeter_mass_distribution(Ncl, mass_max=Mstar)
    total_mass = salpeter_masses.sum()

    print "Distributing particles in a virialized Plummer sphere."
    nbody_converter = nbody_system.nbody_to_si(total_mass, Rcl)
    particles = new_plummer_model(Ncl, nbody_converter)
    particles.move_to_center()

    print "Setting masses of the stars in Plummer sphere."
    particles.mass = salpeter_masses

    print "Cluster virial radius", particles.virial_radius()

    # NB ParticlesSubset does not have the savepoint attribute?!
    # Without ,copy(), we have amuse.datamodel.particles.ParticlesSubset
    # With .copy(), we have amuse.datamodel.particles.Particles; save works (:
    stars_below_cut = particles.select(lambda m: m < Mcut, ["mass"])
    stars_above_cut = particles.select(lambda m: m >= Mcut, ["mass"])

    print "Number of stars below", str(Mcut), "=", len(stars_below_cut)
    print "Number of stars above", str(Mcut), "=", len(stars_above_cut)

    try:
        import Gnuplot
        print "Plotting distribution of stars below and above cut-off."
        plotter = Gnuplot.Gnuplot()
        plotter('set terminal post enhance color')
        plotter('set output "CA_Exam_TLRH_PlummerSphere_SalpeterIMF_splitup.ps"')
        plotter.splot(stars_below_cut.position.value_in(units.parsec),
                      stars_above_cut.position.value_in(units.parsec),)
    except ImportError:
        print "Unable to produce plot: couldn't find Gnuplot."
    except AssertionError:
        print "Fails because on of the sets is empty"

    # I return the particles superset because the particles superset is saved
    # when the subset is changed. This superset can be written to file. (:
    return particles, stars_below_cut, stars_above_cut, nbody_converter
def simulate_stellar_evolution(
    stellar_evolution=SSE(),
    number_of_stars=1000,
    end_time=1000.0 | units.Myr,
    name_of_the_figure="cluster_HR_diagram.png",
):
    """
    A cluster of stars will be created, with masses following a Salpeter IMF.
    The stellar evolution will be simulated using any of the legacy codes (SSE,
    EVtwin, or MESA).
    Finally, a Hertzsprung-Russell diagram will be produced for the final state
    of the simulation.
    """
    print("The evolution of", str(number_of_stars), "stars will be ",
          "simulated until t =", str(end_time), "...")

    stellar_evolution.commit_parameters()

    print(
        "Deriving a set of", str(number_of_stars), "random masses",
        "following a Salpeter IMF between 0.1 and 125 MSun (alpha = -2.35).")

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)

    print("Initializing the particles")
    stars = datamodel.Particles(number_of_stars)
    stars.mass = salpeter_masses
    print("Stars to evolve:")
    print(stars)
    stars = stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()

    # print stars.temperature

    print("Start evolving...")
    stellar_evolution.evolve_model(end_time)

    print("Evolved model successfully.")
    temperatures = stars.temperature
    luminosities = stars.luminosity

    stellar_evolution.stop()

    plot_HR_diagram(temperatures, luminosities, name_of_the_figure, end_time)

    print("All done!")
def simulate_stellar_evolution(
        stellar_evolution=SSE(),
        number_of_stars=1000,
        end_time=1000.0 | units.Myr,
        name_of_the_figure="cluster_HR_diagram.png",
):
    """
    A cluster of stars will be created, with masses following a Salpeter IMF.
    The stellar evolution will be simulated using any of the legacy codes (SSE,
    EVtwin, or MESA).
    Finally, a Hertzsprung-Russell diagram will be produced for the final state
    of the simulation.
    """
    print "The evolution of", str(number_of_stars), "stars will be ",  \
        "simulated until t =", str(end_time), "..."

    stellar_evolution.commit_parameters()

    print (
            "Deriving a set of", str(number_of_stars), "random masses",
            "following a Salpeter IMF between 0.1 and 125 MSun (alpha = -2.35).")

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)

    print "Initializing the particles"
    stars = datamodel.Particles(number_of_stars)
    stars.mass = salpeter_masses
    print "Stars to evolve:"
    print stars
    stars = stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()

    # print stars.temperature

    print "Start evolving..."
    stellar_evolution.evolve_model(end_time)

    print "Evolved model successfully."
    temperatures = stars.temperature
    luminosities = stars.luminosity

    stellar_evolution.stop()

    plot_HR_diagram(temperatures, luminosities, name_of_the_figure, end_time)

    print "All done!"
Exemple #19
0
    def populate(self):

        if self.repopulate_every_run:
            # create nbody_converter thing?
            convert_nbody = nbody_system.nbody_to_si(100.0 | units.MSun,
                                                     1 | units.parsec)

            # instantiate plummer sphere
            self.plummer = new_plummer_sphere(self.num_stars, convert_nbody)
            self.plummer.x += self.xoffset | units.lightyear
            self.plummer.y += self.yoffset | units.lightyear
            self.plummer.z += self.zoffset | units.lightyear

            # provide mass distribution for stars
            self.plummer.mass = new_salpeter_mass_distribution(self.num_stars)
        else:
            self.plummer = self.initial_plummer
Exemple #20
0
def new_field_stars(
    N,
    width=10 | units.parsec,
    height=10 | units.parsec,
    depth=100 | units.parsec,
    massdistribution="salpeter",
    agespread=3 | units.Gyr,
    seed=1701,
):
    np.random.seed(seed)
    stars = Particles(N)
    stars.x = (np.random.random(N) - 0.5) * width
    stars.y = (np.random.random(N) - 0.5) * height
    stars.z = (np.random.random(N) - 0.02) * depth
    if massdistribution == "salpeter":
        stars.mass = new_salpeter_mass_distribution(N)

    return stars
Exemple #21
0
def demo2(N):

    salpeter_masses = new_salpeter_mass_distribution(N)
    total_mass = salpeter_masses.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec)

    parts = new_plummer_model(N, convert_nbody)
    parts.radius = 0. | nbody_system.length
    parts.mass = salpeter_masses
    parts.move_to_center()

    interface = PhiGRAPE(convert_nbody, use_gl=True)

    eps = 0.001 | units.parsec
    interface.parameters.epsilon_squared = eps**2

    interface.particles.add_particles(parts)

    return interface
Exemple #22
0
def main():
    assert is_mpd_running()
    seed = None

    nstars = 128
    if len(sys.argv) > 1:
        stars = int(sys.argv[1])
    with_units = len(sys.argv) > 2

    if not with_units:
        mass_unit = nbody_system.mass
        length_unit = nbody_system.length
    else:
        mass_unit = units.MSun
        length_unit = units.parsec

    m_min = 0.1 | mass_unit
    m_max = 100 | mass_unit
    alpha = -2.35

    r_vir = 1 | length_unit
    masses = new_salpeter_mass_distribution(nstars, m_min, m_max, alpha)
    m_tot = masses.sum()

    if not with_units:
        convert_nbody = None
        masses /= m_tot.value_in(nbody_system.mass)  # scale to unit mass
        m_tot = 1 | nbody_system.mass
    else:
        convert_nbody = nbody_system.nbody_to_si(m_tot, r_vir)
        convert_nbody.set_as_default()
        print m_tot

    stars = new_plummer_model(nstars, convert_nbody, random_state=seed)
    stars.mass = masses

    LagrangianRadii(stars, verbose=True)
Exemple #23
0
def generate_cluster(number_of_stars, mass_of_cluster, radius_of_cluster):
    # numpy.random.seed(1)

    if (mass_of_cluster > 0 | units.MSun):
        number_of_stars = int(mass_of_cluster.value_in(units.MSun)) * 5

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)
    imf = salpeter_masses

    if (mass_of_cluster > 0 | units.MSun):
        print("sorted sampling salpeter IMF, total mass:", mass_of_cluster)
        imf_cumsum = imf.cumsum()
        pick_up_number = (imf_cumsum <= mass_of_cluster).sum()
        if (pick_up_number < number_of_stars):
            imf_pick_up = imf[:pick_up_number + 1]
            sorted_imf_pick_up = np.sort(imf_pick_up)
            if (sorted_imf_pick_up[pick_up_number] - mass_of_cluster <
                    mass_of_cluster - sorted_imf_pick_up[pick_up_number - 1]):
                pick_up_number += 1
            imf = sorted_imf_pick_up[:pick_up_number]
            number_of_stars = pick_up_number
    total_mass = imf.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass,
                                             radius_of_cluster | units.parsec)

    print("generate plummer model, N=", number_of_stars)
    particles = new_plummer_model(number_of_stars, convert_nbody)

    print("setting masses of the stars")
    particles.radius = 0.0 | units.RSun
    particles.mass = imf

    #particles.mass[0] = 40.0 |units.MSun
    #particles.mass[1] = 50.0 |units.MSun

    return particles, convert_nbody
Exemple #24
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'
Exemple #25
0
    t_end = o.t_end | units.Myr
    dt = o.dt | units.Myr

    stellar_evolution = SSE()
    stellar_evolution.commit_parameters()

    stars = Particles(o.N)
    Mmin = o.Mmin | units.MSun
    Mmax = o.Mmax | units.MSun
    if o.verbose:
        print("#Selected parameters: ")
        print("#\tN=", o.N)
        print("#\tIMF=", o.Mmin, "MSun", o.Mmax, "MSun", o.x_imf)
        print("#\t t [Myr] \t <m> [MSun] \t\t d<m>/dt [MSun/Myr]")

    stars.mass = new_salpeter_mass_distribution(
        o.N, mass_min=Mmin, mass_max=Mmax, alpha=o.x_imf)

    stars = stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()
    t = 0 | units.Myr
    mm = stars.mass.sum()/len(stars)
    while t < t_end:
        mm_last = mm
        t += dt
        stellar_evolution.evolve_model(t)
        mm = stars.mass.sum()/len(stars)
        dmm_dt = (mm_last-mm)/dt
        if o.verbose:
            print("t = ", t, "<m>=", mm.as_quantity_in(units.MSun),
                  " d<m>/dt = ", dmm_dt.as_quantity_in(units.MSun/units.Myr))
        else:
def randomparticles_w_ss(N=20, L=1000. | units.AU, dv=2.5 | units.kms):
    from amuse.ic.salpeter import new_salpeter_mass_distribution

    conv = nbody_system.nbody_to_si(N * 1. | units.MSun, 1000. | units.AU)
    conv_sub = nbody_system.nbody_to_si(1. | units.MSun, 50. | units.AU)

    dt = smaller_nbody_power_of_two(1000. | units.day, conv)
    print(dt.in_(units.day))

    dt_param = 0.02
    LL = L.value_in(units.AU)

    def radius(sys, eta=dt_param, _G=constants.G):
        radius = ((_G * sys.total_mass() * dt**2 / eta**2)**(1. / 3.))

        #    xcm,ycm,zcm=sys.center_of_mass()
        #    r2max=((sys.x-xcm)**2+(sys.y-ycm)**2+(sys.z-zcm)**2).max()

        #    if radius < 10 | units.AU:
        #      radius=20. | units.AU
        #    return max(radius,r2max**0.5)
        return radius * ((len(sys) + 1) / 2.)**0.75

    def timestep(ipart, jpart, eta=dt_param / 2, _G=constants.G):
        dx = ipart.x - jpart.x
        dy = ipart.y - jpart.y
        dz = ipart.z - jpart.z
        dr2 = dx**2 + dy**2 + dz**2
        #    if dr2>0:
        dr = dr2**0.5
        dr3 = dr * dr2
        mu = _G * (ipart.mass + jpart.mass)
        tau = eta / 2. / 2.**0.5 * (dr3 / mu)**0.5
        return tau

    numpy.random.seed(7654304)

    masses = new_salpeter_mass_distribution(N,
                                            mass_min=0.3 | units.MSun,
                                            mass_max=10. | units.MSun)

    #masses=([1.]*10) | units.MSun

    stars = Particles(N, mass=masses)

    stars.x = L * numpy.random.uniform(-1., 1., N)
    stars.y = L * numpy.random.uniform(-1., 1., N)
    stars.z = L * 0.
    stars.vx = dv * numpy.random.uniform(-1., 1., N)
    stars.vy = dv * numpy.random.uniform(-1., 1., N)
    stars.vz = dv * 0.

    stars.radius = (1. | units.RSun) * (stars.mass /
                                        (1. | units.MSun))**(1. / 3.)

    stars.move_to_center()

    parts = HierarchicalParticles(stars)

    #  ss=new_solar_system()[[0,5,6,7,8]]
    #  parts.assign_subsystem(ss,parts[0])

    def parent_worker():
        code = Hermite(conv)
        code.parameters.epsilon_squared = 0. | units.AU**2
        code.parameters.end_time_accuracy_factor = 0.
        code.parameters.dt_param = 0.001
        print(code.parameters.dt_dia.in_(units.yr))
        return code

    def sub_worker(parts):
        mode = system_type(parts)
        if mode == "twobody":
            code = TwoBody(conv_sub)
        elif mode == "solarsystem":
            code = Mercury(conv_sub)
        elif mode == "nbody":
            code = Huayno(conv_sub)
            code.parameters.inttype_parameter = code.inttypes.SHARED4
        return code

    def py_worker():
        code = CalculateFieldForParticles(gravity_constant=constants.G)
        return code

    nemesis = Nemesis(parent_worker, sub_worker, py_worker)
    nemesis.timestep = dt
    nemesis.distfunc = timestep
    nemesis.threshold = dt
    nemesis.radius = radius
    nemesis.commit_parameters()
    nemesis.particles.add_particles(parts)
    nemesis.commit_particles()

    tend = 3200. | units.yr
    t = 0 | units.yr
    dtdiag = dt * 2

    time = [0.]

    allparts = nemesis.particles.all()
    E = allparts.potential_energy() + allparts.kinetic_energy()
    E1 = nemesis.potential_energy + nemesis.kinetic_energy

    com = allparts.center_of_mass()
    mom = allparts.total_momentum()
    ang = allparts.total_angular_momentum()

    E0 = E
    A0 = (ang[0]**2 + ang[1]**2 + ang[2]**2)**0.5
    P0 = mom[0].value_in(units.MSun * units.kms)
    totalE = [0.]
    totalA = [0.]
    totalP = [0.]

    ss = nemesis.particles.all()
    x = (ss.x).value_in(units.AU)
    xx = [x]
    y = (ss.y).value_in(units.AU)
    yy = [y]

    nstep = 0
    while t < tend - dtdiag / 2:
        t += dtdiag
        nemesis.evolve_model(t)
        print(t.in_(units.yr))
        print(len(nemesis.particles))

        time.append(t.value_in(units.yr))

        allparts = nemesis.particles.all()
        E = allparts.potential_energy() + allparts.kinetic_energy()
        E1 = nemesis.potential_energy + nemesis.kinetic_energy

        ang = allparts.total_angular_momentum()
        mom = allparts.total_momentum()
        A = (ang[0]**2 + ang[1]**2 + ang[2]**2)**0.5
        P = mom[0].value_in(units.MSun * units.kms)
        totalE.append(abs((E0 - E) / E0))
        totalA.append(abs((A0 - A) / A0))
        totalP.append(abs(P0 - P))
        print(totalE[-1], (E - E1) / E)
        #    print allparts.potential_energy(),nemesis.potential_energy

        ss = nemesis.particles.all()
        x = (ss.x).value_in(units.AU)
        y = (ss.y).value_in(units.AU)
        lowm = numpy.where(ss.mass.value_in(units.MSun) < 0.1)[0]
        highm = numpy.where(ss.mass.value_in(units.MSun) >= 0.1)[0]

        xcm = nemesis.particles.x.value_in(units.AU)
        ycm = nemesis.particles.y.value_in(units.AU)
        r = (nemesis.particles.radius).value_in(units.AU)

        xx.append(x)
        yy.append(y)
        key = ss.key

        f = pyplot.figure(figsize=(8, 8))
        ax = f.gca()
        circles = []
        #    for i in range(len(xx[0])):
        #      pyplot.plot(xx[-1][i],yy[-1][i],colors[key[i]%numpy.uint64(len(colors))]+
        #                                markerstyles[key[i]%numpy.uint64(len(markerstyles))],markersize=8,mew=2)
        pyplot.plot(xx[-1][highm], yy[-1][highm], 'go', markersize=8, mew=2)
        pyplot.plot(xx[-1][lowm], yy[-1][lowm], 'b+', markersize=6, mew=1.5)

        for p in nemesis.particles:
            #      if nemesis.particles.collection_attributes.subsystems.has_key(p):
            c = 'k'
            ls = 'solid'
            code_colors = dict(TwoBody='b',
                               Mercury='r',
                               Huayno='g',
                               Hermite='y')
            code_ls = dict(TwoBody='dotted',
                           Mercury='dashed',
                           Huayno='dashdot',
                           Hermite='solid')
            if nemesis.subcodes.has_key(p):
                c = code_colors[nemesis.subcodes[p].__class__.__name__]
                ls = code_ls[nemesis.subcodes[p].__class__.__name__]
            x = p.x.value_in(units.AU)
            y = p.y.value_in(units.AU)
            r = p.radius.value_in(units.AU)
            circles.append(
                pyplot.Circle((x, y), r, color=c, lw=0.8, ls=ls, fill=False))
        for c in circles:
            ax.add_artist(c)


#    pyplot.plot(xcm,ycm,'k+', markersize=4,mew=1)
        pyplot.xlim(-1.2 * LL, 1.2 * LL)
        pyplot.ylim(-1.2 * LL, 1.2 * LL)
        pyplot.xlabel("AU")
        pyplot.text(-580, -580, '%8.2f' % t.value_in(units.yr), fontsize=18)
        #    pyplot.text(-400,-400,len(nemesis.particles),fontsize=18)
        pyplot.savefig('xy%6.6i.png' % nstep, bbox_inches='tight')
        f.clear()
        pyplot.close(f)

        nstep += 1

    time = numpy.array(time)
    totalE = numpy.array(totalE)
    totalA = numpy.array(totalA)
    totalP = numpy.array(totalP)
    xx = numpy.array(xx)
    yy = numpy.array(yy)

    f = pyplot.figure(figsize=(8, 8))
    pyplot.semilogy(time, totalE, 'r')
    pyplot.semilogy(time, totalA, 'g')
    pyplot.semilogy(time, totalP, 'b')
    pyplot.savefig('dEdA.png')

    f = pyplot.figure(figsize=(8, 8))
    for i in range(len(xx[0])):
        pyplot.plot(xx[:, i], yy[:, i],
                    colors[i % len(colors)] + linestyles[i % len(linestyles)])
    pyplot.xlim(-LL, LL)
    pyplot.ylim(-LL, LL)
    pyplot.savefig('all-xy.png')
Exemple #27
0
def simulate_small_cluster(number_of_stars,
                           end_time=40 | units.Myr,
                           name_of_the_figure="test-2.svg"):
    random.seed()

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)
    total_mass = salpeter_masses.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec)
    convert_nbody.set_as_default()

    particles = new_plummer_model(number_of_stars, convert_nbody)

    gravity = PhiGRAPE(convert_nbody, mode="gpu")
    gravity.initialize_code()
    gravity.parameters.timestep_parameter = 0.01
    gravity.parameters.initial_timestep_parameter = 0.01
    gravity.parameters.epsilon_squared = 0.000001 | units.parsec**2

    stellar_evolution = SSE()
    stellar_evolution.initialize_module_with_default_parameters()

    #print "setting masses of the stars"
    particles.radius = 0.0 | units.RSun

    #comment out to get plummer masses
    particles.mass = salpeter_masses

    gravity.particles.add_particles(particles)
    gravity.initialize_particles(0.0)

    from_model_to_gravity = particles.new_channel_to(gravity.particles)
    from_gravity_to_model = gravity.particles.new_channel_to(particles)

    time = 0.0 | units.Myr
    particles.savepoint(time)

    move_particles_to_center_of_mass(particles)

    kineticEnergy = gravity.kinetic_energy.value_in(units.J)
    potentialEnergy = gravity.potential_energy.value_in(units.J)
    ToverV = kineticEnergy / potentialEnergy

    file.write(str(time.value_in(units.Myr)))
    file.write(' ')
    file.write(str(ToverV))
    file.write('\n')

    while time < end_time:
        time += 0.25 | units.Myr
        gravity.evolve_model(time)
        from_gravity_to_model.copy()
        print "Evolved model to t    =", str(time)
        print "Evolved model to t    =", str(
            convert_nbody.to_nbody(time.value_in(units.Myr) | units.Myr))

        kineticEnergy = gravity.kinetic_energy.value_in(units.J)
        potentialEnergy = gravity.potential_energy.value_in(units.J)
        ToverV = kineticEnergy / potentialEnergy

        print "Kin / Pot             =", ToverV
        #print "Particle Mass         =", particles[1].mass

        file.write(str(time.value_in(units.Myr)))
        file.write(' ')
        file.write(str(ToverV))
        file.write('\n')

    file.close()

    if os.path.exists('small.hdf5'):
        os.remove('small.hdf5')
    storage = store.StoreHDF("small.hdf5")
    storage.store(particles)

    del gravity
    del stellar_evolution
cluster_populations = []

j = 0  #counter

while j <= Nclusters:

    Mcluster = masses[j] | units.MSun

    Nstars, Mmin_star, Mmax_star = 100, 0.1, 100.
    mZams_flag = 0

    while mZams_flag == 0:

        mZams = new_salpeter_mass_distribution(Nstars,
                                               Mmin_star | units.MSun,
                                               Mmax_star | units.MSun,
                                               random=np.random)
        mass_difference_ratio = (Mcluster - mZams.sum()) / Mcluster

        if mass_difference_ratio > 0.01:
            Nstars += 1

        if mass_difference_ratio < -0.01:
            Nstars -= 1

        if np.abs(mass_difference_ratio) <= 0.01:
            mZams_flag = 1

    star_masses = mZams.value_in(units.MSun)
    np.savetxt('star_masses_index=%i.txt' % j, star_masses)
        stars = int(sys.argv[1])
    with_units = len(sys.argv) > 2

    if not with_units:
        mass_unit = nbody_system.mass
        length_unit = nbody_system.length
    else:
        mass_unit = units.MSun
        length_unit = units.parsec

    m_min = 0.1 | mass_unit
    m_max = 100 | mass_unit
    alpha = -2.35

    r_vir = 1 | length_unit
    masses = new_salpeter_mass_distribution(nstars, m_min, m_max, alpha)
    m_tot = masses.sum()

    if not with_units:
        convert_nbody = None
        masses /= m_tot.value_in(nbody_system.mass)  # scale to unit mass
        m_tot = 1 | nbody_system.mass
    else:
        convert_nbody = nbody_system.nbody_to_si(m_tot, r_vir)
        convert_nbody.set_as_default()
        print m_tot

    stars = new_plummer_model(nstars, convert_nbody, random_state=seed)
    stars.mass = masses

    LagrangianRadii(stars, verbose=1)
Exemple #30
0
def simulate_small_cluster(number_of_stars,
                           end_time=40 | units.Myr,
                           name_of_the_figure="test-2.svg"):
    random.seed()

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)
    total_mass = salpeter_masses.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec)
    convert_nbody.set_as_default()

    print 'end_time:', convert_nbody.to_nbody(end_time)
    print convert_nbody.to_nbody(total_mass)

    particles = new_plummer_model(number_of_stars, convert_nbody)

    gravity = PhiGRAPE(convert_nbody, mode="gpu", use_gl="true")
    gravity.parameters.timestep_parameter = 0.01
    gravity.parameters.initial_timestep_parameter = 0.01
    gravity.parameters.epsilon_squared = 0.0015 | units.parsec**2

    particles.radius = 0.0 | units.RSun
    #    particles.mass = salpeter_masses

    move_particles_to_center_of_mass(particles)

    gravity.particles.add_particles(particles)

    gravity.initialize_particles(0.0)

    gravity.start_viewer()

    from_model_to_gravity = particles.new_channel_to(gravity.particles)
    from_gravity_to_model = gravity.particles.new_channel_to(particles)

    time = 0.0 | units.Myr
    #    particles.savepoint(time)

    kineticEnergy = gravity.kinetic_energy.value_in(units.J)
    potentialEnergy = gravity.potential_energy.value_in(units.J)
    ToverV = kineticEnergy / potentialEnergy
    E0 = convert_nbody.to_nbody(gravity.kinetic_energy +
                                gravity.potential_energy)

    file.write(str(time.value_in(units.Myr)))
    file.write(' ')
    file.write(str(ToverV))
    file.write('\n')

    gravity.parameters.timestep_parameter = 0.01
    gravity.parameters.initial_timestep_parameter = 0.01

    while time < end_time:
        time += 0.5 * convert_nbody.to_si(1 | nbody_system.time)
        gravity.evolve_model(time)
        gravity.synchronize_model()
        from_gravity_to_model.copy()
        print "Evolved model to t    =", str(time)

        kineticEnergy = gravity.kinetic_energy.value_in(units.J)
        potentialEnergy = gravity.potential_energy.value_in(units.J)
        ToverV = kineticEnergy / potentialEnergy
        Et = convert_nbody.to_nbody(gravity.kinetic_energy +
                                    gravity.potential_energy)

        print "Kin / Pot             =", ToverV, (Et - E0) / E0

        file.write(str(time.value_in(units.Myr)))
        file.write(' ')
        file.write(str(ToverV))
        file.write('\n')

    file.close()

    if os.path.exists('small.hdf5'):
        os.remove('small.hdf5')
    storage = store.StoreHDF("small.hdf5")
    storage.store(particles)

    del gravity
    del stellar_evolution
Exemple #31
0
def simulate_small_cluster(number_of_stars,
                           end_time=40 | units.Myr,
                           name_of_the_figure="test-2.svg"):
    # numpy.random.seed(1)

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)
    total_mass = salpeter_masses.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec)

    particles = new_plummer_model(number_of_stars, convert_nbody)

    gravity = BHTree(convert_nbody)
    # print gravity.parameters.timestep.as_quantity_in(units.Myr)
    gravity.parameters.timestep = 0.0001 | units.Myr  # tiny!
    gravity.parameters.epsilon_squared \
        = (float(number_of_stars)**(-0.333333) | units.parsec) ** 2

    stellar_evolution = SSE()

    print "setting masses of the stars"
    particles.radius = 0.0 | units.RSun
    particles.mass = salpeter_masses

    print "initializing the particles"
    stellar_evolution.particles.add_particles(particles)
    from_stellar_evolution_to_model \
        = stellar_evolution.particles.new_channel_to(particles)
    from_stellar_evolution_to_model.copy_attributes(["mass"])

    print "centering the particles"
    particles.move_to_center()
    print "scaling particles to viridial equilibrium"
    particles.scale_to_standard(convert_nbody)

    gravity.particles.add_particles(particles)
    from_model_to_gravity = particles.new_channel_to(gravity.particles)
    from_gravity_to_model = gravity.particles.new_channel_to(particles)

    time = 0.0 | units.Myr
    particles.savepoint(time)

    total_energy_at_t0 = gravity.kinetic_energy + gravity.potential_energy

    print "evolving the model until t = " + str(end_time)
    while time < end_time:
        time += 0.25 | units.Myr

        print "gravity evolve step starting"
        gravity.evolve_model(time)
        print "gravity evolve step done"

        print "stellar evolution step starting"
        stellar_evolution.evolve_model(time)
        print "stellar evolution step done"

        from_gravity_to_model.copy()
        from_stellar_evolution_to_model.copy_attributes(["mass", "radius"])

        particles.savepoint(time)

        from_model_to_gravity.copy_attributes(["mass"])

        total_energy_at_this_time \
            = gravity.kinetic_energy + gravity.potential_energy
        print_log(time, gravity, particles, total_energy_at_t0,
                  total_energy_at_this_time)

    test_results_path = get_path_to_results()
    output_file = os.path.join(test_results_path, "small.hdf5")
    if os.path.exists(output_file):
        os.remove(output_file)
    storage = store.StoreHDF(output_file)
    storage.store(particles)

    gravity.stop()
    stellar_evolution.stop()

    plot_particles(particles, name_of_the_figure)
Exemple #32
0
def kira(tend, N, R, Nbin):
    logging.basicConfig(level=logging.ERROR)

    mass = new_salpeter_mass_distribution(N, mass_min=10 | units.MSun)
    converter = nbody_system.nbody_to_si(mass.sum(), R)
    code = Hermite(converter)
    stars = new_plummer_model(N, convert_nbody=converter)
    stars.mass = mass
    stars.radius = 0.01/len(stars) | R.unit

    single_stars, binary_stars, singles_in_binaries \
        = make_secondaries(stars, Nbin)
    print(binary_stars)

    stellar = SeBa()
    stellar.particles.add_particles(single_stars)
    stellar.particles.add_particles(singles_in_binaries)
    stellar.binaries.add_particles(binary_stars)
    channel_to_stars = stellar.particles.new_channel_to(stars)

    encounter_code = encounters.HandleEncounter(
        kepler_code=new_kepler(converter),
        resolve_collision_code=new_smalln(converter),
        interaction_over_code=None,
        G=constants.G
    )
    multiples_code = encounters.Multiples(
        gravity_code=code,
        handle_encounter_code=encounter_code,
        G=constants.G
    )
    multiples_code.particles.add_particles((stars-binary_stars).copy())
    multiples_code.singles_in_binaries.add_particles(singles_in_binaries)
    multiples_code.binaries.add_particles(binary_stars)
    multiples_code.commit_particles()
    channel_from_stars_to_particles \
        = stellar.particles.new_channel_to(multiples_code.particles)

    stopping_condition \
        = multiples_code.stopping_conditions.binaries_change_detection
    stopping_condition.enable()

    from matplotlib import pyplot
    from distinct_colours import get_distinct
    pyplot.rcParams.update({'font.size': 30})
    figure = pyplot.figure(figsize=(12, 9))
    ax = pyplot.gca()
    ax.get_yaxis().get_major_formatter().set_useOffset(False)
    ax.xaxis._autolabelpos = True
    ax.yaxis._autolabelpos = True

    color = get_distinct(2)
    pyplot.scatter(numpy.log10(stellar.binaries.semi_major_axis.
                               value_in(units.AU)),
                   stellar.binaries.eccentricity, c=color[0], s=200, lw=0)

    t = quantities.linspace(0*tend, tend, 11)
    for ti in t:
        print(("t, Energy=", ti, multiples_code.particles.mass.sum(),
              multiples_code.get_total_energy()))
        multiples_code.evolve_model(ti)
        print(("at t=", multiples_code.model_time,
              "Nmultiples:", len(multiples_code.multiples)))

        if stopping_condition.is_set():
            resolve_changed_binaries(stopping_condition, stellar, converter)

        stellar.evolve_model(ti)
        channel_from_stars_to_particles.copy_attributes(["mass", "radius"])
        update_dynamical_binaries_from_stellar(stellar, multiples_code,
                                               converter)

        print(("Lagrangian radii:",
              multiples_code.all_singles.LagrangianRadii(converter)))
        print(("MC.particles", multiples_code.particles))
        print(("Lagrangian radii:",
              multiples_code.particles.LagrangianRadii(converter)))
        print(("t, Energy=", ti, multiples_code.get_total_energy()))

    pyplot.scatter(numpy.log10(stellar.binaries.semi_major_axis
                               .value_in(units.AU)),
                   stellar.binaries.eccentricity, c=color[1], lw=0, s=50)
    pyplot.xlabel("$\log_{10}(a/R_\odot)$")
    pyplot.ylabel("eccentricity")

    save_file = 'kira_a_vs_e.pdf'
    pyplot.savefig(save_file)
    print('\nSaved figure in file', save_file, '\n')
    pyplot.show()

    stellar.stop()
    dt = o.dt | units.Myr

    stellar_evolution = SSE()
    stellar_evolution.commit_parameters()

    stars = Particles(o.N)
    Mmin = o.Mmin | units.MSun
    Mmax = o.Mmax | units.MSun
    if o.verbose:
        print("#Selected parameters: ")
        print("#\tN=", o.N)
        print("#\tIMF=", o.Mmin, "MSun", o.Mmax, "MSun", o.x_imf)
        print("#\t t [Myr] \t <m> [MSun] \t\t d<m>/dt [MSun/Myr]")

    stars.mass = new_salpeter_mass_distribution(o.N,
                                                mass_min=Mmin,
                                                mass_max=Mmax,
                                                alpha=o.x_imf)

    stars = stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()
    t = 0 | units.Myr
    mm = stars.mass.sum() / len(stars)
    while t < t_end:
        mm_last = mm
        t += dt
        stellar_evolution.evolve_model(t)
        mm = stars.mass.sum() / len(stars)
        dmm_dt = (mm_last - mm) / dt
        if o.verbose:
            print("t = ", t, "<m>=", mm.as_quantity_in(units.MSun),
                  " d<m>/dt = ", dmm_dt.as_quantity_in(units.MSun / units.Myr))
Exemple #34
0
def assignment_2d():
    current_cluster_mass = 400 | units.MSun
    initial_mass_fraction = 0.84
    desired_initial_mass = current_cluster_mass / initial_mass_fraction

    masses = new_salpeter_mass_distribution(100000)
    mean_salpeter_mass = masses.mean()
    print "mean salpeter mass", mean_salpeter_mass
    N = int(desired_initial_mass / mean_salpeter_mass)
    print "N", N


    Rvir = 10 | units.lightyear
    z = 0.17
    masses = new_salpeter_mass_distribution(N)
    converter = nbody_system.nbody_to_si(masses.sum(), Rvir)
    G_SI = converter.to_si(nbody_system.G)
    bodies = new_plummer_sphere(N, convert_nbody=converter)
    bodies.mass = masses
    bodies.metalicity = z

    # start the gravity solver
    gravity = BHTree(converter)
    gravity.initialize_code()
    gravity.parameters.timestep = 0.1 | units.Myr

    # start the stellar evolution solver
    stellar = SSE()
    stars = stellar.particles.add_particles(bodies)
    from_stellar_evolution_to_model \
        = stellar.particles.new_channel_to(bodies)
    from_stellar_evolution_to_model.copy_attributes(["mass"])

    bodies.scale_to_standard(converter)
    gravity.particles.add_particles(bodies)

    from_model_to_gravity = bodies.new_channel_to(gravity.particles)
    from_gravity_to_model = gravity.particles.new_channel_to(bodies)
    gravity.commit_particles()

    end_time = 1000 | units.Myr
    current_time = 0 | units.Myr
    cluster = "Hyades"
    bound_stars_counts = []
    main_sequence_stars_counts = []
    giant_stars_counts = []
    remnant_stars_counts = []
    max_radii = [] | units.parsec
    virial_radii = [] | units.parsec
    times = [] | units.Myr
    while current_time < end_time:
        name_of_the_figure = "isochrone_with_grav_"+str(int(current_time.value_in(units.Myr)))+".png"

        gravity.evolve_model(current_time)
        stellar.evolve_model(current_time)


        from_gravity_to_model.copy()
        from_stellar_evolution_to_model.copy_attributes(["mass", "radius"])
        from_model_to_gravity.copy_attributes(["mass"])


        remnant_count = 0
        main_sequence_count = 0
        giant_count = 0
        for star in stars:
            if stellar_remnant_state(star):
                remnant_count += 1
            if stellar_giant_state(star):
                giant_count += 1
            if stellar_main_sequence_state(star):
                main_sequence_count += 1
        max_radius = bodies.total_radius()
        virial_radius = bodies.virial_radius()
        bound_star_count = len(bodies.bound_subset(unit_converter=converter, G=G_SI))
        print "bound stars:", bound_star_count
        print "main sequence stars:", main_sequence_count
        print "giant stars:", giant_count
        print "remnant stars:", remnant_count
        print "cluster radius(max from centre):", max_radius
        print "virial radius:", virial_radius
        print current_time

        times.append(current_time)
        remnant_stars_counts.append(remnant_count)
        giant_stars_counts.append(giant_count)
        main_sequence_stars_counts.append(main_sequence_count)
        max_radii.append(max_radius)
        virial_radii.append(virial_radius)
        bound_stars_counts.append(bound_star_count)


        temperatures = stars.temperature
        luminosities = stars.luminosity

        plot_HR_diagram(temperatures, luminosities,
                        cluster+"/",
                        name_of_the_figure, current_time)
        current_time += 10 | units.Myr
    data = {}
    data["bound_stars_at_time"] = bound_stars_counts
    data["remnant_stars_at_time"] = remnant_stars_counts
    data["giant_stars_at_time"] = giant_stars_counts
    data["main_sequence_stars_at_time"] = main_sequence_stars_counts
    data["max_radius_at_time"] = max_radii
    data["virial_radii"] = virial_radii
    data["times"] = times
    pickle.dump(data, open(cluster+"/assignment2d.dat", "wb"))
Exemple #35
0
        stars = int(sys.argv[1])
    with_units = len(sys.argv) > 2

    if not with_units :
        mass_unit = nbody_system.mass
        length_unit = nbody_system.length
    else :
        mass_unit = units.MSun
        length_unit = units.parsec

    m_min = 0.1 | mass_unit
    m_max = 100 | mass_unit
    alpha = -2.35

    r_vir = 1 | length_unit
    masses = new_salpeter_mass_distribution(nstars, m_min, m_max, alpha)
    m_tot = masses.sum()

    if not with_units :
        convert_nbody = None
        masses /= m_tot.value_in(nbody_system.mass)     # scale to unit mass 
        m_tot = 1 | nbody_system.mass
    else :
        convert_nbody = nbody_system.nbody_to_si(m_tot, r_vir)
        convert_nbody.set_as_default()
        print m_tot

    stars = new_plummer_model(nstars, convert_nbody, random_state = seed);
    stars.mass = masses 
    
    LagrangianRadii(stars, verbose=1)
Exemple #36
0
def make_a_star_cluster(
        stellar_mass=False,
        initial_mass_function="salpeter",
        upper_mass_limit=125. | units.MSun,
        number_of_stars=1024,
        effective_radius=3.0 | units.parsec,
        star_distribution="plummer",
        star_distribution_w0=7.0,
        star_distribution_fd=2.0,
        star_metallicity=0.01,
        # initial_binary_fraction=0,
        **kwargs):
    """
    Create stars.
    When using an IMF, either the stellar mass is fixed (within
    stochastic error) or the number of stars is fixed. When using
    equal-mass stars, both are fixed.
    """

    if stellar_mass:
        # Add stars to cluster, until mass limit reached (inclusive!)
        if initial_mass_function == "kroupa":
            from amuse.ic.brokenimf import new_kroupa_mass_distribution
            mass = new_kroupa_mass_distribution(0)
            while mass.sum() < stellar_mass:
                mass.append(
                    new_kroupa_mass_distribution(
                        1,
                        mass_max=upper_mass_limit,
                    )[0])
            total_mass = mass.sum()
            number_of_stars = len(mass)
        elif initial_mass_function == "salpeter":
            from amuse.ic.salpeter import new_salpeter_mass_distribution
            mass = new_salpeter_mass_distribution(0)
            while mass.sum() < stellar_mass:
                mass.append(
                    new_salpeter_mass_distribution(
                        1,
                        mass_max=upper_mass_limit,
                    )[0])
            total_mass = mass.sum()
            number_of_stars = len(mass)
        elif initial_mass_function == "fixed":
            mass_of_individual_star = stellar_mass / number_of_stars
            mass = mass_of_individual_star
            total_mass = stellar_mass
        else:
            return -1, "No mass function"
    else:
        # Give stars their mass
        if initial_mass_function == "kroupa":
            from amuse.ic.brokenimf import new_kroupa_mass_distribution
            mass = new_kroupa_mass_distribution(
                number_of_stars,
                mass_max=upper_mass_limit,
            )
            total_mass = mass.sum()
        elif initial_mass_function == "salpeter":
            from amuse.ic.salpeter import new_salpeter_mass_distribution
            mass = new_salpeter_mass_distribution(
                number_of_stars,
                mass_max=upper_mass_limit,
            )
            total_mass = mass.sum()
        elif initial_mass_function == "fixed":
            mass = mass_of_individual_star
            total_mass = number_of_stars * mass
        else:
            return -1, "No mass function"

    converter = generic_unit_converter.ConvertBetweenGenericAndSiUnits(
        total_mass,
        1. | units.kms,
        effective_radius,
    )
    # Give stars a position and velocity, based on the distribution model.
    if star_distribution == "plummer":
        from amuse.ic.plummer import new_plummer_sphere
        stars = new_plummer_sphere(
            number_of_stars,
            convert_nbody=converter,
        )
    elif star_distribution == "king":
        from amuse.ic.kingmodel import new_king_model
        stars = new_king_model(
            number_of_stars,
            star_distribution_w0,
            convert_nbody=converter,
        )
    elif star_distribution == "fractal":
        from amuse.ic.fractalcluster import new_fractal_cluster_model
        stars = new_fractal_cluster_model(
            number_of_stars,
            fractal_dimension=star_distribution_fd,
            convert_nbody=converter,
        )
    else:
        return -1, "No stellar distribution"

    # set the stellar mass.
    stars.mass = mass

    # set other stellar parameters.
    stars.metallicity = star_metallicity

    # Virialize the star cluster
    stars.move_to_center()
    stars.scale_to_standard(
        convert_nbody=converter,
        # virial_ratio=virial_ratio,
        # smoothing_length_squared= ...,
    )

    # Record the cluster's initial parameters to the particle distribution
    stars.collection_attributes.initial_mass_function = initial_mass_function
    stars.collection_attributes.upper_mass_limit = upper_mass_limit
    stars.collection_attributes.number_of_stars = number_of_stars

    stars.collection_attributes.effective_radius = effective_radius

    stars.collection_attributes.star_distribution = star_distribution
    stars.collection_attributes.star_distribution_w0 = star_distribution_w0
    stars.collection_attributes.star_distribution_fd = star_distribution_fd

    stars.collection_attributes.star_metallicity = star_metallicity

    # Derived/legacy values
    stars.collection_attributes.converter_mass = \
        converter.to_si(1 | nbody_system.mass)
    stars.collection_attributes.converter_length =\
        converter.to_si(1 | nbody_system.length)
    stars.collection_attributes.converter_speed =\
        converter.to_si(1 | nbody_system.speed)

    return stars
def simulate_small_cluster(number_of_stars, end_time=40 | units.Myr,
                           name_of_the_figure="test-2.svg"):
    # numpy.random.seed(1)

    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)
    total_mass = salpeter_masses.sum()

    convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec)

    particles = new_plummer_model(number_of_stars, convert_nbody)

    gravity = BHTree(convert_nbody)
    gravity.initialize_code()
    # gravity.parameters.set_defaults()
    # print gravity.parameters.timestep.as_quantity_in(units.Myr)
    gravity.parameters.timestep = 0.0001 | units.Myr  # tiny!
    gravity.parameters.epsilon_squared \
        = (float(number_of_stars)**(-0.333333) | units.parsec) ** 2

    stellar_evolution = SSE()
    stellar_evolution.initialize_module_with_default_parameters()

    print "setting masses of the stars"
    particles.radius = 0.0 | units.RSun
    particles.mass = salpeter_masses

    print "initializing the particles"
    stellar_evolution.particles.add_particles(particles)
    from_stellar_evolution_to_model \
        = stellar_evolution.particles.new_channel_to(particles)
    from_stellar_evolution_to_model.copy_attributes(["mass"])

    print "centering the particles"
    particles.move_to_center()
    print "scaling particles to viridial equilibrium"
    particles.scale_to_standard(convert_nbody)

    gravity.particles.add_particles(particles)
    from_model_to_gravity = particles.new_channel_to(gravity.particles)
    from_gravity_to_model = gravity.particles.new_channel_to(particles)

    gravity.commit_particles()

    time = 0.0 | units.Myr
    particles.savepoint(time)

    total_energy_at_t0 = gravity.kinetic_energy + gravity.potential_energy

    print "evolving the model until t = " + str(end_time)
    while time < end_time:
        time += 0.25 | units.Myr

        print "Gravity evolve step starting"
        gravity_evolve = gravity.evolve_model.async(time)

        print "Stellar evolution step starting"
        stellar_evolution_evolve = stellar_evolution.evolve_model(time)

        print "Stellar evolution step done."

        gravity_evolve.result()
        print "Gravity evolve step done."

        from_gravity_to_model.copy()
        from_stellar_evolution_to_model.copy_attributes(["mass", "radius"])

        particles.savepoint(time)

        from_model_to_gravity.copy_attributes(["mass"])

        total_energy_at_this_time \
            = gravity.kinetic_energy + gravity.potential_energy
        print_log(time, gravity, particles,
                  total_energy_at_t0, total_energy_at_this_time)

    test_results_path = get_path_to_results()
    output_file = os.path.join(test_results_path, "small.hdf5")
    if os.path.exists(output_file):
        os.remove(output_file)
    storage = store.StoreHDF(output_file)
    storage.store(particles)

    gravity.stop()
    stellar_evolution.stop()

    plot_particles(particles, name_of_the_figure)
Exemple #38
0
def create_cluster_isochrone(cluster, algorithm=SSE,
                             number_of_stars=1339,
                             end_time=1000 | units.Myr,
                             z=0.012
                             ):
    """
    Code for Assignment 2B.
    @param cluster: Name of cluter (used as dir to store data)
    @param stellar: specify the stellar evolution code.
        valid options are:
            MESA, EVtwin (both Henyey)
            SSE, SeBa (both parameterized)
    @param number_of_stars: how many stars to evolve
    @param end_time: how long the cluster is evolved
    @return: dumps the data to file
    """

    data = {}

    stellar = algorithm()
    algorithm_name = str(algorithm).split('.')[-1][:-2]

    print "Deriving a set of {0} random masses ".format(number_of_stars),
    print "following a Salpeter IMF between 0.1 and 125 Msun",
    print "(alpha = -2.35)."
    salpeter_masses = new_salpeter_mass_distribution(number_of_stars)

    print "Initializing the particles"
    stars = datamodel.Particles(number_of_stars)
    stars.mass = salpeter_masses

    total_mass = 0 | units.MSun
    for m in stars.mass: total_mass += m
    print "total mass =", total_mass

    data['initial_total_mass'] = total_mass

    stars.metallicity = z

    print "The evolution of {0} stars will be".format(number_of_stars),
    print "simulated until t = {0}".format(end_time),
    print ", using algorithm {0}".format(algorithm_name)
    stellar.commit_parameters()

    print "Stars to evolve:"
    print stars
    data['stars'] = stars

    stars = stellar.particles.add_particles(stars)
    stellar.commit_particles()

    print "Start evolving..."
    # stellar.evolve_model(end_time)

    times = [] | units.Myr
    luminosity_at_time = [] | units.LSun
    temperatures_at_time = [] | units.K
    mass_at_time = [] | units.MSun

    current_time = 0 | units.Myr
    while current_time < end_time:
        name_of_the_figure = "isochrone_{0}_{1}_{2}.png".\
            format(algorithm_name, number_of_stars,
                   int(current_time.value_in(units.Myr)))

        stellar.evolve_model(current_time)
        temperatures = stars.temperature
        luminosities = stars.luminosity

        times.append(current_time)
        luminosity_at_time.append(luminosities)
        temperatures_at_time.append(temperatures)
        mass_at_time.append(stars.total_mass())


        print current_time
        plot_HR_diagram(temperatures, luminosities,
                        cluster+"/",
                        name_of_the_figure, current_time)

        current_time += 10 | units.Myr

    print "Evolved model successfully."
    stellar.stop()

    print "All done!"

    data['times'] = times
    data['luminosity_at_time'] = luminosity_at_time
    data['temperatures_at_time'] = temperatures_at_time
    data['mass_at_time'] = mass_at_time

    print data
    pickle.dump(data, open(cluster+"/assignment2b.dat", "wb"))