Example #1
0
def setup_stellar_evolution_model():
    out_pickle_file = os.path.join(get_path_to_results(),
                                   "super_giant_stellar_structure.pkl")
    if os.path.exists(out_pickle_file):
        return out_pickle_file

    stellar_evolution = MESA(redirection="none")
    stars = Particles(1)
    stars.mass = 10.0 | units.MSun
    stellar_evolution.initialize_module_with_default_parameters()
    stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()

    print "Evolving a MESA star with mass:", stellar_evolution.particles[
        0].mass
    try:
        while True:
            stellar_evolution.evolve_model()
    except AmuseException as ex:
        print "Evolved star to", stellar_evolution.particles[0].age
        print "Radius:", stellar_evolution.particles[0].radius

    pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file)
    stellar_evolution.stop()
    return out_pickle_file
Example #2
0
def setup_stellar_evolution_model():
    out_pickle_file = os.path.join(get_path_to_results(), "super_giant_stellar_structure.pkl")
    if os.path.exists(out_pickle_file):
        return out_pickle_file

    stellar_evolution = MESA(redirection="none")
    stars = Particles(1)
    stars.mass = 10.0 | units.MSun
    stellar_evolution.particles.add_particles(stars)

    """
    print "Evolving a MESA star with mass:", stellar_evolution.particles[0].mass
    try:
        while True:
            stellar_evolution.evolve_model()
    except AmuseException as ex:
        print "Evolved star to t=", stellar_evolution.particles[0].age,
        print "Mass:", stellar_evolution.particles[0].mass
        print "Radius:", stellar_evolution.particles[0].radius
        print "core-mass:", stellar_evolution.particles[0].core_mass
    """
    while stellar_evolution.particles[0].stellar_type <= 12 | units.stellar_type:
        stellar_evolution.evolve_model()

    pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file)
    stellar_evolution.stop()
    return out_pickle_file
Example #3
0
def brunt_vaisala_frequency_squared_profile(mass, age):
    stellar_evolution = MESA()
    star = stellar_evolution.particles.add_particle(Particle(mass=mass))
    star.evolve_for(age)
    radius_profile = star.get_radius_profile()
    brunt_profile = star.get_brunt_vaisala_frequency_squared_profile()
    stellar_evolution.stop()
    return radius_profile.as_quantity_in(units.RSun), brunt_profile
Example #4
0
def brunt_vaisala_frequency_squared_profile(mass, age):
    stellar_evolution = MESA()
    star = stellar_evolution.particles.add_particle(Particle(mass=mass))
    star.evolve_for(age)
    radius_profile = star.get_radius_profile()
    brunt_profile = star.get_brunt_vaisala_frequency_squared_profile()
    stellar_evolution.stop()
    return radius_profile.as_quantity_in(units.RSun), brunt_profile
 def mesa(self, number_of_stars):
     result = MESA()
     result.initialize_code()
     if number_of_stars > (10):
         warnings.warn("You're simulating a large number of stars with MESA. This may not be such a good idea...")
     if number_of_stars > (1000):
         raise Exception("You want to simulate with more than 1000 stars using MESA, this is not supported")
     return result
Example #6
0
def main():
    temperatures_original = [] | units.K
    luminosities_original = [] | units.LSun
    temperatures_helium = [] | units.K
    luminosities_helium = [] | units.LSun
    
    star =  Particle()
    star.mass = 12.0 | units.MSun
    stop_radius = 100 | units.RSun
    
    stellar_evolution = MESA()
    se_star = stellar_evolution.particles.add_particle(star)
    
    print("Evolving a", star.mass, "star with",
          stellar_evolution.__class__.__name__, end=' ') 
    print("until its radius exceeds", stop_radius)
    while (se_star.radius < stop_radius):
        se_star.evolve_one_step()
        temperatures_original.append(se_star.temperature)
        luminosities_original.append(se_star.luminosity)

###BOOKLISTSTART1###
    number_of_zones = se_star.get_number_of_zones()
    composition     = se_star.get_chemical_abundance_profiles()
    index = (composition[0] > 1.0e-9).nonzero()[0][0] # first zone with X > 1.0e-9
    
    print("Creating helium star, from the inner", index,
          "(out of", str(number_of_zones)+") shells.")
    helium_star = stellar_evolution.new_particle_from_model(dict(
        mass = (se_star.get_cumulative_mass_profile() * se_star.mass)[:index],
        radius = se_star.get_radius_profile()[:index],
        rho    = se_star.get_density_profile()[:index],
        temperature = se_star.get_temperature_profile()[:index],
        luminosity  = se_star.get_luminosity_profile()[:index],
        X_H  = composition[0][:index],
        X_He = composition[1][:index] + composition[2][:index],
        X_C  = composition[3][:index],
        X_N  = composition[4][:index],
        X_O  = composition[5][:index],
        X_Ne = composition[6][:index],
        X_Mg = composition[7][:index],
        X_Si = composition[7][:index]*0.0,
        X_Fe = composition[7][:index]*0.0), 0.0 | units.Myr)
###BOOKLISTSTOP1###

    print("\nStar properties before helium star evolution:\n",
          stellar_evolution.particles)
    for i in range(1000):
        helium_star.evolve_one_step()
        temperatures_helium.append(helium_star.temperature)
        luminosities_helium.append(helium_star.luminosity)
    print("\nStar properties after helium star evolution:\n",
          stellar_evolution.particles)
    
    stellar_evolution.stop()
    return temperatures_original, luminosities_original, \
           temperatures_helium, luminosities_helium
Example #7
0
def main():
    temperatures_original = [] | units.K
    luminosities_original = [] | units.LSun
    temperatures_helium = [] | units.K
    luminosities_helium = [] | units.LSun
    
    star =  Particle()
    star.mass = 12.0 | units.MSun
    stop_radius = 100 | units.RSun
    
    stellar_evolution = MESA()
    se_star = stellar_evolution.particles.add_particle(star)
    
    print("Evolving a", star.mass, "star with",
          stellar_evolution.__class__.__name__, end=' ') 
    print("until its radius exceeds", stop_radius)
    while (se_star.radius < stop_radius):
        se_star.evolve_one_step()
        temperatures_original.append(se_star.temperature)
        luminosities_original.append(se_star.luminosity)

###BOOKLISTSTART1###
    number_of_zones = se_star.get_number_of_zones()
    composition     = se_star.get_chemical_abundance_profiles()
    index = (composition[0] > 1.0e-9).nonzero()[0][0] # first zone with X > 1.0e-9
    
    print("Creating helium star, from the inner", index,
          "(out of", str(number_of_zones)+") shells.")
    helium_star = stellar_evolution.new_particle_from_model(dict(
        mass = (se_star.get_cumulative_mass_profile() * se_star.mass)[:index],
        radius = se_star.get_radius_profile()[:index],
        rho    = se_star.get_density_profile()[:index],
        temperature = se_star.get_temperature_profile()[:index],
        luminosity  = se_star.get_luminosity_profile()[:index],
        X_H  = composition[0][:index],
        X_He = composition[1][:index] + composition[2][:index],
        X_C  = composition[3][:index],
        X_N  = composition[4][:index],
        X_O  = composition[5][:index],
        X_Ne = composition[6][:index],
        X_Mg = composition[7][:index],
        X_Si = composition[7][:index]*0.0,
        X_Fe = composition[7][:index]*0.0), 0.0 | units.Myr)
###BOOKLISTSTOP1###

    print("\nStar properties before helium star evolution:\n",
          stellar_evolution.particles)
    for i in range(1000):
        helium_star.evolve_one_step()
        temperatures_helium.append(helium_star.temperature)
        luminosities_helium.append(helium_star.luminosity)
    print("\nStar properties after helium star evolution:\n",
          stellar_evolution.particles)
    
    stellar_evolution.stop()
    return temperatures_original, luminosities_original, \
           temperatures_helium, luminosities_helium
 def mesa(self, number_of_stars):
     result = MESA()
     result.initialize_code()
     if number_of_stars > (10):
         warnings.warn(
             "You're simulating a large number of stars with MESA. This may not be such a good idea...")
     if number_of_stars > (1000):
         raise Exception(
             "You want to simulate with more than 1000 stars using MESA, this is not supported")
     return result
Example #9
0
def setup_stellar_evolution_model():
    out_pickle_file = os.path.join(
        get_path_to_results(), "super_giant_stellar_structure.pkl")
    if os.path.exists(out_pickle_file):
        return out_pickle_file

    stellar_evolution = MESA(redirection="none")
    stars = Particles(1)
    stars.mass = 10.0 | units.MSun
    stellar_evolution.initialize_module_with_default_parameters()
    stellar_evolution.particles.add_particles(stars)
    stellar_evolution.commit_particles()

    print(
            "Evolving a MESA star with mass:",
            stellar_evolution.particles[0].mass
            )
    try:
        while True:
            stellar_evolution.evolve_model()
    except AmuseException as ex:
        print "Evolved star to", stellar_evolution.particles[0].age
        print "Radius:", stellar_evolution.particles[0].radius

    pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file)
    stellar_evolution.stop()
    return out_pickle_file
Example #10
0
 def code_factory(self):
     try:
         MESA()
     except Exception as message:
         self.skip(
             "Tried to instantiate a new object of the optional code with type '{0}', but this code is not available"
             .format(MESA))
     return MESA
Example #11
0
def setup_stellar_evolution_model():
    out_pickle_file = os.path.join(get_path_to_results(),
                                   "super_giant_stellar_structure.pkl")
    if os.path.exists(out_pickle_file):
        return out_pickle_file

    print "Creating initial conditions from a MESA stellar evolution model..."

    stellar_evolution = MESA(redirection = "none")
    stars =  Particles(1)
    stars.mass = 10.0 | units.MSun
    stellar_evolution.particles.add_particles(stars)

    while stellar_evolution.particles[0].stellar_type <= 12|units.stellar_type:
        stellar_evolution.evolve_model()
    
    pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file)
    stellar_evolution.stop()
    return out_pickle_file
Example #12
0
def setup_stellar_evolution_model():
    out_pickle_file = os.path.join(get_path_to_results(), "super_giant_stellar_structure.pkl")
    if os.path.exists(out_pickle_file):
        return out_pickle_file
    
    stellar_evolution = MESA(redirection = "none")
    stars =  Particles(1)
    stars.mass = 10.0 | units.MSun
    stellar_evolution.particles.add_particles(stars)

    """
    print "Evolving a MESA star with mass:", stellar_evolution.particles[0].mass
    try:
        while True:
            stellar_evolution.evolve_model()
    except AmuseException as ex:
        print "Evolved star to t=", stellar_evolution.particles[0].age,
        print "Mass:", stellar_evolution.particles[0].mass
        print "Radius:", stellar_evolution.particles[0].radius
        print "core-mass:", stellar_evolution.particles[0].core_mass
    """
    while stellar_evolution.particles[0].stellar_type <= 12|units.stellar_type:
        stellar_evolution.evolve_model()
#    while stellar_evolution.particles[0].stellar_type <= 3|units.stellar_type:
#        stellar_evolution.evolve_model()
    
    pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file)
    stellar_evolution.stop()
    return out_pickle_file
    def slowtest3(self):
        print "Testing ParallelStellarEvolution evolve_model"
        particles = Particles(4)
        particles.mass = range(1, 1 + len(particles)) | units.MSun

        serial = MESA()
        inserial = serial.particles.add_particles(particles)
        self.assertAlmostEqual(inserial.mass,
                               range(1, 1 + len(particles)) | units.MSun)
        serial.evolve_model(0.2 | units.Myr)

        parallel = ParallelStellarEvolution(MESA,
                                            number_of_workers=3,
                                            **default_options)
        inparallel = parallel.particles.add_particles(particles)
        self.assertAlmostEqual(inparallel.mass,
                               range(1, 1 + len(particles)) | units.MSun)
        parallel.evolve_model(0.2 | units.Myr)
        self.assertEqual(parallel.model_time, 0.2 | units.Myr)
        self.assertTrue(numpy.all(inparallel.age >= (0.2 | units.Myr)))
        self.assertTrue(
            numpy.all(
                inparallel.age - inparallel.time_step <= (0.2 | units.Myr)))

        self.assertEqual(inserial.luminosity, inparallel.luminosity)
        self.assertEqual(inserial.time_step, inparallel.time_step)
        self.assertEqual(inserial.temperature, inparallel.temperature)
        serial.stop()
        parallel.stop()
 def slowtest3(self):
     print "Testing ParallelStellarEvolution evolve_model"
     particles = Particles(4)
     particles.mass = range(1, 1+len(particles)) | units.MSun
     
     serial = MESA()
     inserial = serial.particles.add_particles(particles)
     self.assertAlmostEqual(inserial.mass, range(1, 1+len(particles)) | units.MSun)
     serial.evolve_model(0.2 | units.Myr)
     
     parallel = ParallelStellarEvolution(MESA, number_of_workers=3, **default_options)
     inparallel = parallel.particles.add_particles(particles)
     self.assertAlmostEqual(inparallel.mass, range(1, 1+len(particles)) | units.MSun)
     parallel.evolve_model(0.2 | units.Myr)
     self.assertEqual(parallel.model_time, 0.2 | units.Myr)
     self.assertTrue(numpy.all(inparallel.age >= (0.2 | units.Myr)))
     self.assertTrue(numpy.all(inparallel.age - inparallel.time_step <= (0.2 | units.Myr)))
     
     self.assertEqual(inserial.luminosity, inparallel.luminosity)
     self.assertEqual(inserial.time_step, inparallel.time_step)
     self.assertEqual(inserial.temperature, inparallel.temperature)
     serial.stop()
     parallel.stop()
Example #15
0
def simulate_evolution_tracks(
        masses=[0.5, 1.0, 1.25, 1.5, 2.25, 3.0, 5.0, 9.0, 15.0] | units.MSun):
    stellar_evolution = MESA()
    stellar_evolution.parameters.AGB_wind_scheme = 0
    stellar_evolution.parameters.RGB_wind_scheme = 0

    stars = datamodel.Particles(len(masses), mass=masses)
    stars = stellar_evolution.pre_ms_stars.add_particles(stars)

    data = {}

    for star in stars:
        luminosity = [] | units.LSun
        temperature = [] | units.K
        time = [] | units.yr

        print('Evolving pre main sequence star with')
        print('    mass:', star.mass)
        print('    luminosity:', star.luminosity)
        print('    radius:', star.radius)

        while star.stellar_type == 17 | units.stellar_type:
            luminosity.append(star.luminosity)
            temperature.append(star.temperature)
            time.append(star.age)
            star.evolve_one_step()

        print('Evolved pre main sequence star to:', star.stellar_type)
        print('    age:', star.age)
        print('    mass:', star.mass)
        print('    luminosity:', star.luminosity)
        print('    radius:', star.radius)
        print()

        stardata = {}
        stardata['luminosity'] = luminosity
        stardata['temperature'] = temperature
        stardata['time'] = time
        data[star.mass] = stardata

    return data
def evolve_star_and_apply_mass_loss(radius, mdot):
    print("Evolve to radius = ", radius, "and then apply mdot =", mdot)

    stev = MESA(redirection='none')

    # We have to switch off all wind mass loss for manual mass loss to work
    stev.parameters.AGB_wind_scheme = 0
    stev.parameters.RGB_wind_scheme = 0

    star = stev.particles.add_particle(Particle(mass=2 | units.MSun))

    while star.radius < radius:
        star.evolve_one_step()
        print("evolved to:", star.age, "->", star.radius)

    star1 = star.copy()

    # High mass loss rates can only be calculated for small time steps
    star.time_step = 1. | units.yr
    star.mass_change = mdot
    print(star.mass_change)
    star.evolve_one_step()

    print_report(star1, star, mdot)
Example #17
0
def setup_stellar_evolution_model():
    out_pickle_file = os.path.join(get_path_to_results(),
                                   "super_giant_stellar_structure.pkl")
    if os.path.exists(out_pickle_file):
        return out_pickle_file
    print("Creating initial conditions from a MESA stellar evolution model...")

    stellar_evolution = MESA(redirection="none")
    stars = Particles(1)
    stars.mass = 10.0 | units.MSun
    stellar_evolution.particles.add_particles(stars)

    while stellar_evolution.particles[
            0].stellar_type <= 12 | units.stellar_type:
        stellar_evolution.evolve_model()

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

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

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

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

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

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

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

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

    print "Evolving to t =", t_end, " (using", sph_code.__name__, "SPH code)."
    for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]:
        hydro_legacy_code.evolve_model(time)
        if not i_step % 4:
            hydro_plot(
                view,
                hydro_legacy_code,
                (300, 300),
                base_output_file_name +
                "_hydro_image{0:=03}.png".format(i_step)
            )
    hydro_legacy_code.stop()
    print "All done!\n"
Example #19
0
def head_on_stellar_merger(
        masses = [0.3, 3.0] | units.MSun, 
        star_age = 310.0 | units.Myr, 
        maximally_evolved_stars = False,
        initial_separation = 4.0 | units.RSun, 
        angle = numpy.pi / 3,
        initial_speed = 3000.0 | units.km / units.s, 
        initial_speed_perpendicular = 30.0 | units.km / units.s, 
        number_of_sph_particles = 1000, 
        t_end = 1.0e4 | units.s,
        sph_code = Fi,
        steps_per_snapshot = 4,
        snapshot_size = 100,
        use_stored_stellar_models = True
    ):
    """
    masses: Mass of the two stars
    star_age: Initial age of the stars (if maximally_evolved_stars is False)
    maximally_evolved_stars: Evolve stars as far as the Stellar Evolution code can get
    number_of_sph_particles: Total number of particles of both stars, divided according to their masses
    t_end: (Physical, not computational) duration of the hydrodynamics simulation
    sph_code: Code to use for the hydrodynamics simulation
    steps_per_snapshot: A hydroplot snapshot is generated each time after this many steps (0 or None means no snapshots)
    snapshot_size: Size of the snapshot in pixels along one dimension
    use_stored_stellar_models: Flag to use previously stored stellar model files (for speed-up).
    """
    
    # Convert some of the input parameters to string, for use in output file names:    
    n_string = "n" + ("%1.0e"%(number_of_sph_particles)).replace("+0","").replace("+","")
    t_end_string = "t" + ("%1.0e"%(t_end.value_in(units.s))).replace("+0","").replace("+","")
    masses_string = ("m1_" + ("%0.3e"%(masses[0].value_in(units.MSun))).replace("+0","").replace("+","") +
        "_m2_" + ("%0.3e"%(masses[1].value_in(units.MSun))).replace("+0","").replace("+",""))
    if maximally_evolved_stars:
        star_age_string = "a_max"
    else:
        star_age_string = "a" + ("%0.3e"%(star_age.value_in(units.Myr))).replace("+0","").replace("+","")
    
    base_output_file_name = os.path.join(get_path_to_results(), "stellar_merger_"+n_string+"_"+t_end_string)
    pickle_file_1 = os.path.join(get_path_to_results(), "stellar_merger_"+masses_string+"_"+star_age_string+"_1.pkl")
    pickle_file_2 = os.path.join(get_path_to_results(), "stellar_merger_"+masses_string+"_"+star_age_string+"_2.pkl")
    
    if not use_stored_stellar_models or not (os.path.exists(pickle_file_1) and os.path.exists(pickle_file_2)):
        stars =  Particles(2)
        stars.mass = masses
        try:
            stellar_evolution = MESA()
            stellar_evolution.initialize_code()
        except:
            print "MESA was not built. Returning."
            return
        stellar_evolution.commit_parameters() 
        stellar_evolution.particles.add_particles(stars)
        stellar_evolution.commit_particles()
        
        if maximally_evolved_stars:
            try:
                while True:
                    stellar_evolution.evolve_model()
            except AmuseException as exception:
                print exception
        else:
            stellar_evolution.evolve_model(star_age)
        
        if os.path.exists(pickle_file_1):
            print "Could not save stellar model 1: file already exists."
        else:
            pickle_stellar_model(stellar_evolution.particles[0], pickle_file_1)
            print "Stellar model 1 saved at:", pickle_file_1
        if os.path.exists(pickle_file_2):
            print "Could not save stellar model 2: file already exists."
        else:
            pickle_stellar_model(stellar_evolution.particles[1], pickle_file_2)
            print "Stellar model 2 saved at:", pickle_file_2
        
        stellar_evolution.stop()
    
    model_1 = StellarModel2SPH(None, None, pickle_file = pickle_file_1)
    model_2 = StellarModel2SPH(None, None, pickle_file = pickle_file_2)
    model_1.unpickle_stellar_structure()
    model_2.unpickle_stellar_structure()
    composition = model_2.composition_profile
    midpoints = model_2.midpoints_profile[1:-1]
    specific_internal_energy = model_2.specific_internal_energy_profile
    
    number_of_sph_particles_1 = int(round(number_of_sph_particles * 
        (model_1.mass / (model_1.mass + model_2.mass))))
    number_of_sph_particles_2 = number_of_sph_particles - number_of_sph_particles_1
    print "Creating initial conditions from a MESA stellar evolution model:"
    print model_1.mass, "star consisting of", number_of_sph_particles_1, "particles."
    sph_particles_1 = convert_stellar_model_to_SPH(
        None, 
        number_of_sph_particles_1, 
        seed=12345,
        pickle_file = pickle_file_1
    ).gas_particles
    print model_2.mass, "star consisting of", number_of_sph_particles_2, "particles."
    sph_particles_2 = convert_stellar_model_to_SPH(
        None, 
        number_of_sph_particles_2, 
        pickle_file = pickle_file_2
    ).gas_particles
    initial_separation += model_1.radius + model_2.radius
    sph_particles_2.x  += numpy.cos(angle) * initial_separation
    sph_particles_2.y  += numpy.sin(angle) * initial_separation
    sph_particles_1.vx += numpy.cos(angle) * initial_speed - numpy.sin(angle) * initial_speed_perpendicular
    sph_particles_1.vy += numpy.cos(angle) * initial_speed_perpendicular + numpy.sin(angle) * initial_speed
    view = [-0.5, 0.5, -0.5, 0.5] * (initial_separation + model_1.radius + model_2.radius)
    
    all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2])
    all_sph_particles.move_to_center()
    
    unit_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun, constants.G, t_end)
    hydro_legacy_code = sph_code(unit_converter)
    n_steps = 100
    hydro_legacy_code.parameters.n_smooth = 96
    try:
        hydro_legacy_code.parameters.timestep = t_end / n_steps
    except Exception as exc:
        if not "parameter is read-only" in str(exc): raise
    hydro_legacy_code.gas_particles.add_particles(all_sph_particles)
    
    times = [] | units.Myr
    kinetic_energies =   [] | units.J
    potential_energies = [] | units.J
    thermal_energies =   [] | units.J
    
    print "Evolving to:", t_end
    for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]:
        hydro_legacy_code.evolve_model(time)
        times.append(time)
        kinetic_energies.append(   hydro_legacy_code.kinetic_energy)
        potential_energies.append( hydro_legacy_code.potential_energy)
        thermal_energies.append(   hydro_legacy_code.thermal_energy)
        if steps_per_snapshot and (not i_step % steps_per_snapshot):
            hydro_plot(
                view,
                hydro_legacy_code,
                (snapshot_size, snapshot_size),
                base_output_file_name + "_hydro_image{0:=03}.png".format(i_step)
            )

    
    hydro_legacy_code.gas_particles.new_channel_to(all_sph_particles).copy_attributes(
        ['mass', 'x','y','z', 'vx','vy','vz', 'u'])
    center_of_mass = all_sph_particles.center_of_mass().as_quantity_in(units.RSun)
    center_of_mass_velocity = all_sph_particles.center_of_mass_velocity().as_quantity_in(units.km / units.s)
    print
    print "center_of_mass:", center_of_mass
    print "center_of_mass_velocity:", center_of_mass_velocity
    all_sph_particles.position -= center_of_mass
    sph_midpoints = all_sph_particles.position.lengths()
    
    energy_plot(
        times, 
        kinetic_energies, potential_energies, thermal_energies, 
        base_output_file_name+"_energy_evolution.png"
    )
    thermal_energy_plot(
        times, 
        thermal_energies, 
        base_output_file_name+"_thermal_energy_evolution.png"
    )
    composition_comparison_plot(
        midpoints, composition[0], 
        sph_midpoints, all_sph_particles.h1, 
        base_output_file_name+"_composition_h1.png"
    )
    internal_energy_comparison_plot(
        midpoints, specific_internal_energy, 
        sph_midpoints, all_sph_particles.u, 
        base_output_file_name+"_new_u.png"
    )
    hydro_plot(
        [-2.0, 2.0, -2.0, 2.0] | units.RSun,
        hydro_legacy_code,
        (100, 100),
        base_output_file_name + "_hydro_image.png"
    )
    hydro_legacy_code.stop()
    print "All done!\n"
Example #20
0
def head_on_stellar_merger(
    masses=[0.3, 3.0] | units.MSun,
    star_age=310.0 | units.Myr,
    maximally_evolved_stars=False,
    initial_separation=4.0 | units.RSun,
    angle=numpy.pi / 3,
    initial_speed=3000.0 | units.km / units.s,
    initial_speed_perpendicular=30.0 | units.km / units.s,
    number_of_sph_particles=1000,
    t_end=1.0e4 | units.s,
    sph_code=Fi,
    steps_per_snapshot=4,
    snapshot_size=100,
    use_stored_stellar_models=True
):
    """
    masses: Mass of the two stars
    star_age: Initial age of the stars (if maximally_evolved_stars is False)
    maximally_evolved_stars: Evolve stars as far as the Stellar Evolution code
    can get
    number_of_sph_particles: Total number of particles of both stars, divided
    according to their masses
    t_end: (Physical, not computational) duration of the hydrodynamics
    simulation
    sph_code: Code to use for the hydrodynamics simulation
    steps_per_snapshot: A hydroplot snapshot is generated each time after this
    many steps (0 or None means no snapshots)
    snapshot_size: Size of the snapshot in pixels along one dimension
    use_stored_stellar_models: Flag to use previously stored stellar model
    files (for speed-up).
    """

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

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

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

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

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

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

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

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

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

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

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

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