A Tour of MESA/star
This document gives a mid-level overview of the structure and control flow of MESA/star.
The star program
The star
executable is generated in the context of a work
directory, the template of which lives at star/work
. This
executable is linked against the various MESA modules, including star
itself.
The source file src/run.f90
contains the program
statement.
This file invokes routines that read the star_job
namelist and
then start a run.
The invoked routines live in star/job
in the files
run_star.f90
and run_star_support.f90
. (This directory also
contains the code associated with the standard run_star_extras
hooks and the special test_suite_extras
routines used to produce
output for the TestHub.)
The routines in run_star_support.f90
contain key parts of the
control flow. The routine run1_star
knows how to initialize the
various things needed for a star run and contains the evolve_loop
.
This is a simple do loop, each iteration of which is a stellar
evolution step.
1 evolve_loop: do while(continue_evolve_loop) ! evolve one step per loop
2
3 continue_evolve_loop = do_evolve_one_step(s, dbg, ierr)
4 if (failed('do_evolve_one_step',ierr)) return
5
6 end do evolve_loop
Within that loop are calls the routine do_evolve_one_step
, which
contains the step_loop
. This loop consists of attempting a
stellar evolution step, and then either accepting the step or
rejecting it and repeating the attempt (via a redo or retry).
1 step_loop: do ! may need to repeat this loop
2
3 if (stop_is_requested(s)) then
4 continue_evolve_loop = .false.
5 result = terminate
6 exit
7 end if
8
9 result = star_evolve_step(id, first_try)
10 if (result == keep_going) result = star_check_model(id)
11 if (result == keep_going) result = s% extras_check_model(id)
12 if (result == keep_going) result = star_pick_next_timestep(id)
13 if (result == keep_going) exit step_loop
14
15 model_number = get_model_number(id, ierr)
16 if (failed('get_model_number',ierr)) return
17
18 if (result == retry .and. s% job% report_retries) then
19 write(*,'(i6,3x,a,/)') model_number, &
20 'retry reason ' // trim(result_reason_str(s% result_reason))
21 end if
22
23 if (result == redo) then
24 result = star_prepare_to_redo(id)
25 end if
26 if (result == retry) then
27 result = star_prepare_to_retry(id)
28 end if
29 if (result == terminate) then
30 continue_evolve_loop = .false.
31 exit step_loop
32 end if
33 first_try = .false.
34
35 end do step_loop
The stellar evolution step itself is triggered via a call to
star_evolve_step
, which is a function defined in the
public star_lib
interface.
In star/public
, in the file star_lib.f90
, this function is
1 integer function star_evolve_step(id, first_try)
2 ! returns either keep_going, redo, retry, or terminate
3 use star_def, only: terminate, keep_going
4 use star_utils, only: start_time, update_time
5 integer, intent(in) :: id
6 logical, intent(in) :: first_try
7 ! true on the first try to take this step
8 ! false if this is a repeat for a retry
9 type (star_info), pointer :: s
10 integer :: ierr
11 integer(8) :: time0, clock_rate
12 real(dp) :: total
13 star_evolve_step = terminate
14 ierr = 0
15 call star_ptr(id, s, ierr)
16 if (ierr /= 0) return
17 if (s% doing_timing) call start_time(s, time0, total)
18 star_evolve_step = star_evolve_step_part1(id, first_try)
19 if (star_evolve_step == keep_going) &
20 star_evolve_step = star_evolve_step_part2(id, first_try)
21 if (s% doing_timing) call update_time(s, time0, total, s% time_evolve_step)
22 end function star_evolve_step
You can see that this splits the step into two parts (part1 and
part2). Those are implemented in star/private
.
Before we go deeper, we should become familiar with the star_info
type, which is conventionally assigned the variable name s
.
The star_info structure
The star_info
type is defined in the star_data
module. (It is
split off in order to allow for star to depend on other modules that
need to know the definition of the star_info
type, without
introducing circular dependencies.)
The definition of this derived type occurs in
public/star_data_def.f90
, but most of the details are deferred to
various include files (*.inc
).
First, is star_data.inc
, which has information about the structure
of the star itself.
! star_data.inc
include "star_data_step_input.inc"
! input for taking a step.
! modified during the step so that at end holds the new model.
! can be saved in models and photos.
include "star_data_step_work.inc"
! working storage for data derived from inputs while taking a step.
! can be undefined when start to take a step (e.g. by calling fill_arrays_with_NaNs).
! not saved in models or in photos.
include "star_data_procedures.inc"
! procedure pointers for hooks and such
This defers to another set of files that divide things up based on whether they are inputs for a step or things that are calculated from these inputs during the process of taking a step.
Some of the most important variables defined in
star_data_step_input.inc
are the arrays xh(:,:)
and
xa(:,:)
, which hold the structure variables and abundance
variables for the model. These are the “truth” about the stellar
structure. Other quantities are derived from these through simple
transformations (e.g., Rho
) or by the interaction with other
modules (e.g., Cp
via the eos
).
The various namelist options for star_job
, controls
, and
pgstar
are also part of the star_info
structure. They are
also added through *.inc
files, but these live in
star_data/private
.
Note
If you are adding a new inlist option, your best bet is to
pick an existing option that it is similar to and grep in star
and star_data
. That will generally show you all the places you
will need to add code.
There is far too much contained in star_info
to go through it
piece by piece, but you should spend some time perusing theses files
to get a feel for what sorts of things go where.
star/private
The guts of MESA live in star/private
.
evolve.f90
There are many files, but the starting point is evolve.f90
. This
file contains the definitions of the part1
and part2
functions
we saw previously.
Part 1 is mainly preparing for the step (see the functions
do_evolve_step_part1
and do_step_part1
). It ends with making
an initial estimate for the mass transfer rate. (The necessity of the
part1/part2 split is primarily driven by binary, where the two stars
interact in a way that means their mass change rates are related.)
Part 2 contains the bulk of the work associate with a step (see the
functions do_evolve_step_part2
and do_step_part2
).
It contains a loop (implicit_mdot_loop
) that allows this part to
be repeated multiple times in cases where the mass change rate may
depend on the calculated stellar structure.
Within this loop is what one generally thinks of as taking a stellar
evolution step. First, some of the operator-split actions are taken
(i.e., CPM, diffusion). Then, the fully-coupled parts are solved in
the call to do_struct_burn_mix
.
do_struct_burn_mix
The function do_struct_burn_mix
lives in struct_burn_mix.f90
.
Warning
Forthcoming