From ./rn to do_evolve_step
The "Nuts and Bolts" section of the Appendix of the second MESA Instrument paper (starting on page 34) describes how MESA evolves a star for a single step using the top level routine 'do_evolve_step'. This is an excellent high-level overview of how MESA works that came out of last year's summer school.
But how does the code get from you typing ./rn on the command line to actually executing do_evolve_step? The presentation on Tuesday night was a little too impromptu and I made a real hash of it. (Apologies for wasting your time.) Hopefully this will be a bit clearer and fill in some of the gaps.
Let's make a new copy of a MESA working directory and poke around a bit.
cp -r $MESA_DIR/star/work my_work cd my_work
The executable file that actually gets run when we run MESA is called 'star'. We'll see how it is generated in just a bit. It is important to know that the scripts ./rn and ./re are just convenient wrappers for invoking 'star'.
So let's take a look at ./rn, with some added commentary
#!/bin/bash # print the SVN revision of the version of MESA that is being used if [ ! -z "${MESA_DIR}" ]; then svn info $MESA_DIR > .svninfo grep "Revision" .svninfo fi # get rid of any file lingering from a previous restart. the presence # or absence of a file with this name is how MESA determines whether # it is supposed to be doing a restart. how this works will make more # sense once you look at ./re rm -f restart_photo # print the date & time; run MESA; print the date & time date;./star;date
And now let's do the same for ./re, which is the command that one uses to resume MESA runs from a saved binary ("photos") file.
#!/bin/bash # this function checks that the exit code of the previous command. if # it did not indicate that it sucessfully completed, the script exits function check_okay { if [ $? -ne 0 ] then exit 1 fi } # print the first argument given to the bash script # you invoke ./re as # $ ./re <filename> # where <filename> is one of the files in the photos directory # so this displays the filename passed to the script. echo $1 # try to copy the given file from photos/ to a file named # restart_photo. if this fails, exit. cp photos/$1 restart_photo check_okay # we see that star is invoked in exactly the same way as in ./rn so # MESA determines whether a restart is occuring based on the presence # of a file named restart_photo. that's why the ./rn script made sure # to remove such a file before invoking star! date;./star;date
So how do we get this all-important 'star' executable file in the first place? It is generated by running ./mk which then uses a standard MESA makefile to compile the code. This makefile compiles three files
src/run.f <MESA_DIR>/star/job/run_star.f src/run_star_extras.f
and then links with lot of other things to make the 'star' executable.
We looked at run_star_extras.f on Monday night, so now lets look at run.f which is what contains the fortran program declaration for 'star'.
program run use run_star_support, only: do_read_star_job use run_star, only: do_run_star implicit none integer :: ierr character (len=32) :: inlist_fname ierr = 0 ! your main inlist file must be called 'inlist' inlist_fname = 'inlist' ! read the star_job namelist from the inlist call do_read_star_job(inlist_fname, ierr) if (ierr /= 0) stop 1 ! actually run the star calculations call do_run_star(inlist_fname) end program
So this program sends us off to 'do_run_star' in the star/job/run_star.f file and down the rabbit hole we go!
subroutine do_run_star(inlist_fname_arg) use run_star_support, only: run1_star use run_star_extras use star_lib, only: star_shutdown character (len=*) :: inlist_fname_arg optional inlist_fname_arg logical, parameter :: do_pre_load = .true., do_free_star = .true., & restart_okay = .true. integer :: id, ierr logical :: restart character (len=256) :: inlist_fname ! call your main inlist file 'inlist' unless you choose otherwise if (present(inlist_fname_arg)) then inlist_fname = inlist_fname_arg else inlist_fname = 'inlist' end if ! run the evolution for a single star call run1_star( & do_pre_load, do_free_star, restart_okay, & id, restart, & extras_controls, & extras_startup, & extras_check_model, & how_many_extra_history_columns, & data_for_extra_history_columns, & how_many_extra_profile_columns, & data_for_extra_profile_columns, & extras_finish_step, & extras_after_evolve, & ierr, & inlist_fname) ! clean up after we are done call star_shutdown end subroutine do_run_star
So now the next step is to go look at 'run1_star', which comes from star/job/run_star_support.f. But that's where things really start to happen: the subroutine is over 500 lines long. I provided a pseudocode outline of that function in Monday's run_star_extras.f tutorial, so I urge you to go take a look at that.
Smack dab in the middle of the step_loop in 'run1_star' is a call to 'star_evolve_step', which comes from star/public/star_lib.f. Now we've made it deep enough to star seeing our star program interact with the star module.
In general, each of the modules in MESA (which are the many sub-directories that you see in the main mesa/ directory) are structured in the same way. They provide public constants and subroutines for other programs or modules to interact with: these live in <modulename>/public. Then these public methods will call private methods (which live in <modulename>/private) and it i these private methods where all the work happens.
We can see this clearly by looking at 'star_evolve_step'
! this routine takes one step in the evolution. ! when it returns successfully (i.e, with value = keep_going), the data ! describing the new model can be found in the variables defined in star_def. integer function star_evolve_step(id, first_try, just_did_backup) ! returns either keep_going, redo, retry, backup, or terminate use star_def, only: terminate use star_def, only: star_info use evolve, only: do_evolve_step integer, intent(in) :: id logical, intent(in) :: first_try ! true on the first try to take this step ! false if this is a repeat for a retry or a backup logical, intent(in) :: just_did_backup type (star_info), pointer :: s integer :: ierr star_evolve_step = terminate ierr = 0 call star_ptr(id, s, ierr) if (ierr /= 0) return star_evolve_step = do_evolve_step(id, first_try, just_did_backup) end function star_evolve_step
which doesn't do too much more than hand us off to 'do_evolve_step', the function that is quite nicely described in the MESA instrument paper. So to keep digging into MESA take a look at that.