wsssss introduction

This notebook will show some of the possibilities of wsssss. The documentation is available here.

First we create a grid of MESA inlists, then run that grid with MESA and gyre. We first ensure that either the MESA_DIR environment variable is set or that we pass mesa_dir to MesaGrid, as it needs to know which version of MESA to create a grid for. We also tell MesaGrid to copy the basic files and folders needed for MESA (rn, re, mk, etc.). Next we set some inputs for the grid. We create a grid with 2 initial masses and 2 different overshooting, resulting in 4 sets of inlists.

[1]:
import os

wsssss_dir = "/home/walter/Github/wsssss"
if 'MESA_DIR' not in os.environ.keys():
    os.environ['MESA_DIR'] = '/home/walter/Software/MESA/mesa-24.08.1'
mesa_dir = os.environ['MESA_DIR']

[2]:
from wsssss.inlists import create_grid as cg

# If mesa_dir is not set it will use the MESA_DIR environment variable
grid = cg.MesaGrid(mesa_dir=mesa_dir, add_base_workdir=True)

grid.star_job['history_columns_file'] = 'history_test.list'
# Tell MesaGrid where the file is located:
grid.add_file(os.path.join(f'{wsssss_dir}/tests/make_data', grid.star_job['history_columns_file']))

grid.star_job['pgstar_flag'] = False
grid.star_job['create_pre_main_sequence_model'] = False

grid.kap['use_Type2_opacities'] = True
grid.kap['Zbase'] = 0.02

grid.controls['initial_mass'] = [1, 2]
grid.controls['initial_z'] = 0.02
grid.controls['max_model_number'] = 10
grid.controls['mesh_delta_coeff'] = 5

grid.controls['history_interval'] = 1
grid.controls['photo_interval'] = 8

grid.controls['write_profiles_flag'] = True
grid.controls['profile_interval'] = 9
grid.controls['write_pulse_data_with_profile'] = True
grid.controls['pulse_data_format'] = 'GYRE'

grid.controls[f'{cg.non_mesa_key_start}group_unpack'].append([{'overshoot_scheme(1)': 'exponential',
                                                               'overshoot_zone_type(1)': 'nonburn',
                                                               'overshoot_zone_loc(1)': 'shell',
                                                               'overshoot_bdy_loc(1)': 'bottom',
                                                               'overshoot_f(1)': 0.02,
                                                               'overshoot_f0(1)': 0.001},
                                                              {'overshoot_scheme(1)': 'exponential',
                                                               'overshoot_zone_type(1)': 'nonburn',
                                                               'overshoot_zone_loc(1)': 'shell',
                                                               'overshoot_bdy_loc(1)': 'bottom',
                                                               'overshoot_f(1)': 0.03,
                                                               'overshoot_f0(1)': 0.01}])


def name_function(unpacked):
    return f'm{unpacked["controls"]["initial_mass"]:.3f}_fOV{unpacked["controls"]["overshoot_f(1)"]:.3f}'


grid.set_name_function(name_function)

# If we want, we can apply an arbritraty function on each unpacked inlist with grid.set_inlist_finalize_function

def finalize_function(unpacked):
    if unpacked["controls"]['overshoot_f(1)'] == 0.03:
        unpacked["controls"]["overshoot_D_min"] = 1e-2
    # We could also set the history file output name to something other than the default:
    # unpacked["controls"]["star_history_name"] = f'm{unpacked["controls"]["initial_mass"]:.3f}_fOV{unpacked["controls"]["overshoot_f(1)"]:.3f}.data'
    return unpacked

grid.set_inlist_finalize_function(finalize_function)
[3]:
grid.unpack_inlists()

for i, inlist in enumerate(grid.unpacked):
    print(f'{i:04}')
    for namelist in inlist.keys():
        if isinstance(namelist, str):
            print(f'    {namelist}')
        for key, value in inlist[namelist].items():
            if not isinstance(value, dict):
                if not key.startswith(cg.non_mesa_key_start):
                    print(f'        {key}: {value}')
            else:
                print(f'        {key}:')
                for kkey, vvalue in value.items():
                    if not key.startswith(cg.non_mesa_key_start):
                        print(f'            {kkey}: {vvalue}')
    print()

0000
    inlist
        star_job:
            read_extra_star_job_inlist(5): True
            extra_star_job_inlist_name(5): inlist_project
        eos:
            read_extra_eos_inlist(5): True
            extra_eos_inlist_name(5): inlist_project
        kap:
            read_extra_kap_inlist(5): True
            extra_kap_inlist_name(5): inlist_project
        controls:
            read_extra_controls_inlist(5): True
            extra_controls_inlist_name(5): inlist_project
        pgstar:
            read_extra_pgstar_inlist(5): True
            extra_pgstar_inlist_name(5): inlist_project
    star_job
        history_columns_file: history_test.list
        pgstar_flag: False
        create_pre_main_sequence_model: False
    eos
    kap
        use_Type2_opacities: True
        Zbase: 0.02
    controls
        initial_mass: 1
        initial_z: 0.02
        max_model_number: 10
        mesh_delta_coeff: 5
        history_interval: 1
        photo_interval: 8
        write_profiles_flag: True
        profile_interval: 9
        write_pulse_data_with_profile: True
        pulse_data_format: GYRE
        overshoot_scheme(1): exponential
        overshoot_zone_type(1): nonburn
        overshoot_zone_loc(1): shell
        overshoot_bdy_loc(1): bottom
        overshoot_f(1): 0.02
        overshoot_f0(1): 0.001
    pgstar

0001
    inlist
        star_job:
            read_extra_star_job_inlist(5): True
            extra_star_job_inlist_name(5): inlist_project
        eos:
            read_extra_eos_inlist(5): True
            extra_eos_inlist_name(5): inlist_project
        kap:
            read_extra_kap_inlist(5): True
            extra_kap_inlist_name(5): inlist_project
        controls:
            read_extra_controls_inlist(5): True
            extra_controls_inlist_name(5): inlist_project
        pgstar:
            read_extra_pgstar_inlist(5): True
            extra_pgstar_inlist_name(5): inlist_project
    star_job
        history_columns_file: history_test.list
        pgstar_flag: False
        create_pre_main_sequence_model: False
    eos
    kap
        use_Type2_opacities: True
        Zbase: 0.02
    controls
        initial_mass: 2
        initial_z: 0.02
        max_model_number: 10
        mesh_delta_coeff: 5
        history_interval: 1
        photo_interval: 8
        write_profiles_flag: True
        profile_interval: 9
        write_pulse_data_with_profile: True
        pulse_data_format: GYRE
        overshoot_scheme(1): exponential
        overshoot_zone_type(1): nonburn
        overshoot_zone_loc(1): shell
        overshoot_bdy_loc(1): bottom
        overshoot_f(1): 0.02
        overshoot_f0(1): 0.001
    pgstar

0002
    inlist
        star_job:
            read_extra_star_job_inlist(5): True
            extra_star_job_inlist_name(5): inlist_project
        eos:
            read_extra_eos_inlist(5): True
            extra_eos_inlist_name(5): inlist_project
        kap:
            read_extra_kap_inlist(5): True
            extra_kap_inlist_name(5): inlist_project
        controls:
            read_extra_controls_inlist(5): True
            extra_controls_inlist_name(5): inlist_project
        pgstar:
            read_extra_pgstar_inlist(5): True
            extra_pgstar_inlist_name(5): inlist_project
    star_job
        history_columns_file: history_test.list
        pgstar_flag: False
        create_pre_main_sequence_model: False
    eos
    kap
        use_Type2_opacities: True
        Zbase: 0.02
    controls
        initial_mass: 1
        initial_z: 0.02
        max_model_number: 10
        mesh_delta_coeff: 5
        history_interval: 1
        photo_interval: 8
        write_profiles_flag: True
        profile_interval: 9
        write_pulse_data_with_profile: True
        pulse_data_format: GYRE
        overshoot_scheme(1): exponential
        overshoot_zone_type(1): nonburn
        overshoot_zone_loc(1): shell
        overshoot_bdy_loc(1): bottom
        overshoot_f(1): 0.03
        overshoot_f0(1): 0.01
        overshoot_D_min: 0.01
    pgstar

0003
    inlist
        star_job:
            read_extra_star_job_inlist(5): True
            extra_star_job_inlist_name(5): inlist_project
        eos:
            read_extra_eos_inlist(5): True
            extra_eos_inlist_name(5): inlist_project
        kap:
            read_extra_kap_inlist(5): True
            extra_kap_inlist_name(5): inlist_project
        controls:
            read_extra_controls_inlist(5): True
            extra_controls_inlist_name(5): inlist_project
        pgstar:
            read_extra_pgstar_inlist(5): True
            extra_pgstar_inlist_name(5): inlist_project
    star_job
        history_columns_file: history_test.list
        pgstar_flag: False
        create_pre_main_sequence_model: False
    eos
    kap
        use_Type2_opacities: True
        Zbase: 0.02
    controls
        initial_mass: 2
        initial_z: 0.02
        max_model_number: 10
        mesh_delta_coeff: 5
        history_interval: 1
        photo_interval: 8
        write_profiles_flag: True
        profile_interval: 9
        write_pulse_data_with_profile: True
        pulse_data_format: GYRE
        overshoot_scheme(1): exponential
        overshoot_zone_type(1): nonburn
        overshoot_zone_loc(1): shell
        overshoot_bdy_loc(1): bottom
        overshoot_f(1): 0.03
        overshoot_f0(1): 0.01
        overshoot_D_min: 0.01
    pgstar
[4]:
grid_dir = os.path.abspath('example_wsssss')
grid.create_grid(grid_dir, rm_dir=False)
Cannot copy calling file /tmp/ipykernel_409779/2927543967.py to grid directory /home/walter/Github/wsssss/examples/example_wsssss.
[5]:
os.listdir(grid_dir)
[5]:
['m2.000_fOV0.020',
 'star',
 'm1.000_fOV0.020',
 'out_m2.000_fOV0.030',
 'm1.000_fOV0.030',
 'out_m1.000_fOV0.030',
 'out_m1.000_fOV0.020',
 'out_m2.000_fOV0.020',
 'm2.000_fOV0.030']

Run mesa-go

First we compile star and copy it to the grid directory as we will copy it instead of compile it for each run of MESA. Next, run mesa-go (docs), the MESA grid runner. We tell it that each run has a non-default name with --sub-dirs m*, and that before starting MESA to run cp ../star ./ to copy the star executable we created earlier, and after running MESA to run the gyre-driver (docs) on all the profiles in LOGS and to be lenient with which version of gyre is used.

cd /path/to/example_wsssss
cd m1.000_fOV0.020; ./mk; cp star ../; cd ..
mesa-go --sub-dirs m* --cmd-pre-each 'cp ../star ./' --cmd-post-each 'gyre-driver 01 MESA LOGS/*.GYRE --lenient'
check-grid --no-slurm --list-all

Once mesa-go is finished running we check if the grid ran successfully with check-grid (docs). This should show the following:

  termination_code                   count
--------------------------------------------
max_model_number                           4
--------------------------------------------
m1.000_fOV0.021    pre-CHeX       9 max_model_number
m1.000_fOV0.030    pre-CHeX       9 max_model_number
m2.000_fOV0.021    pre-CHeX       9 max_model_number
m2.000_fOV0.030    pre-CHeX       9 max_model_number
--------------------------------------------

Inlists

We can also evaluate an inlist and see which options it sets as well as compare different inlists. We also see that overshoot_d_min is not set in m1.000_fOV0.020/inlist but is set to 0.01 in m1.000_fOV0.030/inlist as expected from grid.set_inlist_finalize_function.

[6]:
from wsssss.inlists import inlists as inl
inl.evaluate_inlist(f'{grid_dir}/m1.000_fOV0.020/inlist')
[6]:
{'star_job': {'history_columns_file': 'history_test.list',
  'pgstar_flag': False,
  'create_pre_main_sequence_model': False},
 'eos': {},
 'kap': {'use_type2_opacities': True, 'zbase': 0.02},
 'controls': {'initial_mass': 1,
  'initial_z': 0.02,
  'max_model_number': 10,
  'mesh_delta_coeff': 5,
  'history_interval': 1,
  'photo_interval': 8,
  'write_profiles_flag': True,
  'profile_interval': 9,
  'write_pulse_data_with_profile': True,
  'pulse_data_format': 'GYRE',
  'overshoot_scheme(1)': 'exponential',
  'overshoot_zone_type(1)': 'nonburn',
  'overshoot_zone_loc(1)': 'shell',
  'overshoot_bdy_loc(1)': 'bottom',
  'overshoot_f(1)': 0.02,
  'overshoot_f0(1)': 0.001},
 'pgstar': {}}
[7]:
inl.compare_inlist(f'{grid_dir}/m1.000_fOV0.020/inlist', f'{grid_dir}/m1.000_fOV0.030/inlist')
left : /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/inlist
right: /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.030/inlist

####### star_job differences #######

####### controls differences #######
overshoot_f(1): (0.02, 0.03)
overshoot_f0(1): (0.001, 0.01)
overshoot_d_min: (None, 0.01)

However, comparing MESA version strings should be done carefully:

[8]:
print(inl.compare_version('11701', 'r24.03.1', '<'), '11701' < 'r24.03.1')
print(inl.compare_version('11701', '8118', '<'), '11701' < '8118')
True True
False True
[9]:
inl.get_mesa_version(mesa_dir)
[9]:
'r24.08.1'

MESA histories and profiles

wsssss can also read MESA histories and profiles, as well as gyre summaries and mode files.

[10]:
from wsssss import load_data as ld
import numpy as np

hist = ld.History(f'{grid_dir}/m1.000_fOV0.020/LOGS/history.data')
print(hist.columns)
['model_number', 'elapsed_time', 'star_age', 'star_mass', 'effective_T', 'photosphere_L', 'photosphere_r', 'luminosity', 'radius', 'gravity', 'center_T', 'center_Rho', 'center_P', 'center_degeneracy', 'center_mu', 'center_ye', 'center_h1', 'center_he3', 'center_he4', 'center_c12', 'center_n14', 'center_o16', 'center_ne20', 'center_mg24', 'surface_h1', 'surface_he3', 'surface_he4', 'surface_c12', 'surface_n14', 'surface_o16', 'surface_ne20', 'surface_mg24', 'mass_conv_core', 'he_core_mass', 'he_core_radius', 'co_core_mass', 'co_core_radius', 'log_LH', 'log_LHe', 'log_LZ', 'log_extra_L', 'log_Lneu', 'log_abs_Lgrav', 'pp', 'cno', 'tri_alpha', 'c_alpha', 'n_alpha', 'o_alpha', 'delta_nu', 'delta_Pg', 'nu_max', 'log_L', 'mix_type_1', 'mix_qtop_1', 'mix_type_2', 'mix_qtop_2', 'mix_type_3', 'mix_qtop_3', 'mix_type_4', 'mix_qtop_4', 'mix_type_5', 'mix_qtop_5', 'mix_type_6', 'mix_qtop_6', 'mix_type_7', 'mix_qtop_7', 'mix_type_8', 'mix_qtop_8', 'mix_type_9', 'mix_qtop_9', 'mix_type_10', 'mix_qtop_10', 'mix_type_11', 'mix_qtop_11', 'mix_type_12', 'mix_qtop_12', 'mix_type_13', 'mix_qtop_13', 'mix_type_14', 'mix_qtop_14', 'mix_type_15', 'mix_qtop_15', 'mix_type_16', 'mix_qtop_16', 'mix_type_17', 'mix_qtop_17', 'mix_type_18', 'mix_qtop_18', 'mix_type_19', 'mix_qtop_19', 'mix_type_20', 'mix_qtop_20', 'burn_type_1', 'burn_qtop_1', 'burn_type_2', 'burn_qtop_2', 'burn_type_3', 'burn_qtop_3', 'burn_type_4', 'burn_qtop_4', 'burn_type_5', 'burn_qtop_5', 'burn_type_6', 'burn_qtop_6', 'burn_type_7', 'burn_qtop_7', 'burn_type_8', 'burn_qtop_8', 'burn_type_9', 'burn_qtop_9', 'burn_type_10', 'burn_qtop_10', 'burn_type_11', 'burn_qtop_11', 'burn_type_12', 'burn_qtop_12', 'burn_type_13', 'burn_qtop_13', 'burn_type_14', 'burn_qtop_14', 'burn_type_15', 'burn_qtop_15', 'burn_type_16', 'burn_qtop_16', 'burn_type_17', 'burn_qtop_17', 'burn_type_18', 'burn_qtop_18', 'burn_type_19', 'burn_qtop_19', 'burn_type_20', 'burn_qtop_20', 'burn_type_21', 'burn_qtop_21', 'burn_type_22', 'burn_qtop_22', 'burn_type_23', 'burn_qtop_23', 'burn_type_24', 'burn_qtop_24', 'burn_type_25', 'burn_qtop_25', 'burn_type_26', 'burn_qtop_26', 'burn_type_27', 'burn_qtop_27', 'burn_type_28', 'burn_qtop_28', 'burn_type_29', 'burn_qtop_29', 'burn_type_30', 'burn_qtop_30']

If we don’t need all these columns we can choose which columns to keep in History (or and data class in load_data) :

[11]:
hist = ld.History(f'{grid_dir}/m1.000_fOV0.020/LOGS/history.data', keep_columns=['model_number', 'star_age', 'effective_T', 'luminosity', 'nu_max', 'delta_nu', 'delta_Pg'])
print(hist.columns)
['model_number', 'star_age', 'effective_T', 'luminosity', 'nu_max', 'delta_nu', 'delta_Pg']

We can access the data in two ways, through attributes of hist.data or through the hist.get method:

[12]:
hist.data.star_age
hist.get('star_age')
np.all(hist.get('star_age') == hist.data.star_age)
[12]:
True

We can also index directly on hist, this will return a new History with a correctly set profile index, containing only profiles in the new History file.

[13]:
print(len(hist))
print(hist.data)
print(hist.index)
10
[( 1,  100000.    , 5616.90892797, 0.70925563, 168.08043363, 0., 3945.14980227)
 ( 2,  220000.    , 5614.14501653, 0.70804627, 168.05210824, 0., 3945.08631765)
 ( 3,  364000.    , 5604.89019466, 0.70420514, 167.92708726, 0., 3943.76604529)
 ( 4,  536800.    , 5580.62037896, 0.69460378, 167.59231705, 0., 3938.01161344)
 ( 5,  744160.    , 5575.69560644, 0.6946222 , 167.152432  , 0., 3925.75774334)
 ( 6,  992992.    , 5577.13854459, 0.69672805, 166.90750047, 0., 3917.43838629)
 ( 7, 1291590.4   , 5578.83351588, 0.69861458, 166.72173235, 0., 3911.01712141)
 ( 8, 1649908.48  , 5579.89506039, 0.70000223, 166.57075811, 0., 3905.86420042)
 ( 9, 2079890.176 , 5580.69086712, 0.7011625 , 166.43786954, 0., 3901.34770013)
 (10, 2595868.2112, 5581.41662209, 0.7022522 , 166.31199997, 0., 3897.06714391)]
[[ 1  2  1]
 [ 9  1  2]
 [10  3  3]]
[14]:
new_hist = hist[:5]
print(len(new_hist))
print(new_hist.data)
print(new_hist.index)
5
[(1, 100000., 5616.90892797, 0.70925563, 168.08043363, 0., 3945.14980227)
 (2, 220000., 5614.14501653, 0.70804627, 168.05210824, 0., 3945.08631765)
 (3, 364000., 5604.89019466, 0.70420514, 167.92708726, 0., 3943.76604529)
 (4, 536800., 5580.62037896, 0.69460378, 167.59231705, 0., 3938.01161344)
 (5, 744160., 5575.69560644, 0.6946222 , 167.152432  , 0., 3925.75774334)]
[[1 2 1]]

The same is true for gyre summaries:

[15]:
gs = ld.GyreSummary(f'{hist.LOGS}/../gyre_out/profile1.data.GYRE.sgyre_l')
print(gs.data)
print()
print(gs[gs.data.l == 0].data)
[(1., 1.82764478e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3309.71129536, 0., 0, 0, 19, 19)
 (1., 1.57116548e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3471.5380448 , 0., 0, 0, 20, 20)
 (1., 1.38862698e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3634.47656824, 0., 0, 0, 21, 21)
 (1., 1.24263570e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3797.7041817 , 0., 0, 0, 22, 22)
 (1., 1.12116935e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3961.31386135, 0., 0, 0, 23, 23)
 (1., 1.03091459e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4124.99185735, 0., 0, 0, 24, 24)
 (1., 9.63169050e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4288.82138142, 0., 0, 0, 25, 25)
 (1., 9.15110781e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4453.22548755, 0., 0, 0, 26, 26)
 (1., 8.77471803e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4617.86112542, 0., 0, 0, 27, 27)
 (1., 8.44784618e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4782.93365092, 0., 0, 0, 28, 28)
 (1., 2.01195016e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3223.42320367, 0., 1, 0, 17, 18)
 (1., 1.69127179e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3385.16288116, 0., 1, 0, 18, 19)
 (1., 1.48022252e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3547.55896439, 0., 1, 0, 19, 20)
 (1., 1.31330986e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3710.78091331, 0., 1, 0, 20, 21)
 (1., 1.18119987e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3874.44966317, 0., 1, 0, 21, 22)
 (1., 1.07390212e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4038.06751587, 0., 1, 0, 22, 23)
 (1., 9.93904450e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4202.03953297, 0., 1, 0, 23, 24)
 (1., 9.38204390e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4366.1774459 , 0., 1, 0, 24, 25)
 (1., 8.94148813e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4530.80566806, 0., 1, 0, 25, 26)
 (1., 8.60259786e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4695.84074713, 0., 1, 0, 26, 27)]

[(1., 1.82764478e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3309.71129536, 0., 0, 0, 19, 19)
 (1., 1.57116548e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3471.5380448 , 0., 0, 0, 20, 20)
 (1., 1.38862698e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3634.47656824, 0., 0, 0, 21, 21)
 (1., 1.24263570e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3797.7041817 , 0., 0, 0, 22, 22)
 (1., 1.12116935e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 3961.31386135, 0., 0, 0, 23, 23)
 (1., 1.03091459e-08, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4124.99185735, 0., 0, 0, 24, 24)
 (1., 9.63169050e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4288.82138142, 0., 0, 0, 25, 25)
 (1., 9.15110781e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4453.22548755, 0., 0, 0, 26, 26)
 (1., 8.77471803e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4617.86112542, 0., 0, 0, 27, 27)
 (1., 8.44784618e-09, 2.71503057e+33, 1.98840987e+33, 6.18702395e+10, 4782.93365092, 0., 0, 0, 28, 28)]

Convenience function to load all MESA profiles or gyre summaries are also available:

[16]:
profs = ld.load_profs(hist)
print(profs)
ld.load_gss(hist)
[MESA profile data file at /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/LOGS/profile1.data
{'model_number': 1, 'num_zones': 3828, 'star_mass': 1.0, 'star_age': 100000.0, 'Teff': 5616.908927965037, 'photosphere_L': 0.7092556343734885, 'center_h1': 0.6969903923887202, 'center_he4': 0.2825119329953253, 'date': '20260320'}, MESA profile data file at /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/LOGS/profile2.data
{'model_number': 9, 'num_zones': 217, 'star_mass': 1.0, 'star_age': 2079890.176, 'Teff': 5580.690867117586, 'photosphere_L': 0.7011624968709207, 'center_h1': 0.6968676556622809, 'center_he4': 0.2826257295568369, 'date': '20260320'}, MESA profile data file at /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/LOGS/profile3.data
{'model_number': 10, 'num_zones': 217, 'star_mass': 1.0, 'star_age': 2595868.2112000003, 'Teff': 5581.416622090657, 'photosphere_L': 0.70225220496579, 'center_h1': 0.696835018765734, 'center_he4': 0.28265520404943156, 'date': '20260320'}]
[16]:
[GyreSummary at /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/gyre_out/profile1.data.GYRE.sgyre_l,
 GyreSummary at /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/gyre_out/profile2.data.GYRE.sgyre_l,
 GyreSummary at /home/walter/Github/wsssss/examples/example_wsssss/m1.000_fOV0.020/gyre_out/profile3.data.GYRE.sgyre_l]

We can also load a gyre summary from a MESA profile:

[17]:
gs = ld.load_gs_from_profile(profs[0])

Various convenience functions are available in functions, for example calculating \(\Delta\nu\) from a gyre summary. The full list is available in the documentation.

[18]:
from wsssss import functions as uf
print(hist.data.delta_nu[hist.get_profile_index(1)[0]], uf.calc_deltanu(gs, hist))
168.08043363435422 163.70286603873035

Constants

Over the course of MESA’s development the physical constant definitions have changed. wsssss knows about this and can get the constants used by the version of MESA used by a History. The constants in wsssss are generated from $MESA_DIR/const/public/const_def.f90 for pre- and post-15140 as the definitions changed in 15140.

[19]:
c = uf.get_constants(hist)
print(c.standard_cgrav)
6.6743e-08
[20]:
from wsssss.constants import pre15140
print(c.standard_cgrav, pre15140.standard_cgrav)
print(c.standard_cgrav == pre15140.standard_cgrav)
6.6743e-08 6.67428e-08
False
[21]:
print(list(c.__dict__.keys())[8:])
['version', 'max_extra_inlists', 'pi', 'pi2', 'pi4', 'eulercon', 'eulernum', 'ln2', 'ln3', 'lnpi', 'ln10', 'iln10', 'a2rad', 'rad2a', 'one_third', 'two_thirds', 'four_thirds', 'five_thirds', 'one_sixth', 'four_thirds_pi', 'ln4pi3', 'two_13', 'four_13', 'sqrt2', 'sqrt_2_div_3', 'avo', 'amu', 'clight', 'qe', 'kerg', 'boltzm', 'planck_h', 'hbar', 'cgas', 'ev2erg', 'mev_to_ergs', 'mev_amu', 'mev2gr', 'qconv', 'kev', 'boltz_sigma', 'crad', 'au', 'pc', 'dayyer', 'secday', 'secyer', 'ly', 'mn', 'mp', 'me', 'rbohr', 'fine', 'hion', 'sige', 'weinberg_theta', 'num_neu_fam', 'standard_cgrav', 'mu_sun', 'mu_earth', 'mu_jupiter', 'agesun', 'msun', 'rsun', 'lsun', 'teffsun', 'loggsun', 'mbolsun', 'm_earth', 'r_earth', 'r_earth_polar', 'm_jupiter', 'r_jupiter', 'r_jupiter_polar', 'semimajor_axis_jupiter', 'arg_not_provided', 'missing_value', 'crystallized', 'no_mixing', 'convective_mixing', 'overshoot_mixing', 'semiconvective_mixing', 'thermohaline_mixing', 'rotation_mixing', 'rayleigh_taylor_mixing', 'minimum_mixing', 'anonymous_mixing', 'leftover_convective_mixing', 'phase_separation_mixing', 'number_of_mixing_types']

Plotting

There are many plotting functions avialable in wsssss.plotting.plotting (docs), some of them are exhibited here:

[22]:
from wsssss.plotting import plotting as pl

hist = ld.History(f'{grid_dir}/m1.000_fOV0.020/LOGS/history.data')
profs = ld.load_profs(hist)
gss = ld.load_gss(hist)

pl.make_kipp(hist)
pl.make_structural(profs[-1])
pl.make_echelle(gss[-1], hist)
[22]:
(<Figure size 640x480 with 1 Axes>,
 <Axes: xlabel='Frequency + 52.48 mod 176.03 $\\mu$Hz', ylabel='Frequency ($\\mu$Hz)'>)
../_images/examples_examples_35_1.png
../_images/examples_examples_35_2.png
../_images/examples_examples_35_3.png