├── .gitignore ├── CODEOWNERS ├── CODE_OF_CONDUCT.rst ├── CONTRIBUTING.md ├── README.md ├── check_examples.sh └── hooks ├── Fuller_AM ├── Fuller_AM_example │ ├── .gitignore │ ├── clean │ ├── inlist │ ├── inlist_FullerAM │ ├── inlist_pgstar │ ├── make │ │ └── makefile │ ├── mk │ ├── re │ ├── rn │ └── src │ │ ├── run.f90 │ │ └── run_star_extras.f90 ├── Fuller_AM_transport.inc └── README.md ├── README.md ├── atm_T_tau_gradr_factor.f90 ├── cmd_line_args.py ├── czb_mesh_function ├── README.md ├── czb_mesh_function.inc ├── czb_mesh_function_def.inc ├── czb_mesh_function_extras_controls.inc └── star_example │ ├── inlist │ ├── inlist_czb_mesh_function │ ├── inlist_example │ ├── inlist_pgstar │ └── src │ └── run_star_extras.f90 ├── dbconvpen ├── .gitignore ├── README.md ├── dbconvpen.inc └── star_example │ ├── history_columns.list │ ├── inlist │ ├── inlist_dbcp │ ├── profile_columns.list │ └── src │ └── run_star_extras.f90 ├── detach_binary ├── README.md ├── binary_example │ ├── .gitignore │ ├── clean │ ├── inlist │ ├── inlist1 │ ├── inlist2 │ ├── inlist_project │ ├── make │ │ └── makefile │ ├── mk │ ├── re │ ├── rn │ └── src │ │ ├── binary_run.f90 │ │ ├── run_binary_extras.f90 │ │ └── run_star_extras.f90 └── detach_binary.inc ├── enhanced_Tayler_Spruit ├── README.md ├── enhanced_Tayler_Spruit.inc └── star_example │ ├── inlist_project │ └── src │ └── run_star_extras.f90 ├── hydro_Ttau ├── 624.dek ├── README.md ├── TtauFeH0.dat ├── astero_example │ ├── inlist │ ├── inlist_astero_search_controls │ ├── inlist_hydro_Ttau │ └── src │ │ └── run_star_extras.f90 ├── hydro_Ttau_def.inc ├── hydro_Ttau_proc.inc └── star_example │ ├── inlist │ ├── inlist_hydro_Ttau │ └── src │ └── run_star_extras.f90 ├── low_mass_torques ├── README.md ├── low_mass_torques.inc ├── low_mass_torques_extras_startup.inc └── star_example │ ├── inlist_project │ └── src │ └── run_star_extras.f90 ├── remove_surface_by_temperature ├── README.md ├── main.inc └── star_example │ ├── clean │ ├── inlist │ ├── inlist_pgstar │ ├── inlist_project │ ├── make │ └── makefile │ ├── mk │ ├── re │ ├── rn │ └── src │ ├── run.f90 │ └── run_star_extras.f90 ├── try_mesa_contrib.f90 └── wd_builder ├── README.md ├── star_example ├── basic_HeCO_composition.dat ├── inlist_wd_builder └── src │ └── run_star_extras.f90 ├── wd_builder.inc └── wd_builder_def.inc /.gitignore: -------------------------------------------------------------------------------- 1 | ## Misc 2 | *~ 3 | ._* 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # Every hook should have an owner 5 | 6 | hooks/czb_mesh_function @jschwab 7 | hooks/enhanced_Tayler_Spruit @adamjermyn 8 | hooks/hydro_Ttau @warrickball 9 | hooks/low_mass_torques @adamjermyn 10 | hooks/remove_surface_by_temperature @adamjermyn 11 | hooks/wd_builder @fxt44 12 | hooks/atm_T_tau_gradr_factor.f90 @warrickball 13 | hooks/cmd_line_args.py @warrickball 14 | hooks/detach_binary @mathren -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.rst: -------------------------------------------------------------------------------- 1 | MESA Code of Conduct 2 | ==================== 3 | 4 | Code 5 | ---- 6 | 7 | In the interest of fostering a productive and welcoming collaborative 8 | environment, we ask that participants in the MESA project (whether 9 | developers, contributors, or users) commit to the following standards of 10 | behavior: 11 | 12 | - Participants will conduct themselves in a professional manner that is 13 | welcoming, inclusive, and free from any form of disrespect, 14 | intimidation, bullying, discrimination, harassment, and retaliation. 15 | 16 | - Participants will treat each other with civility and respect to 17 | create a collegial and professional environment where all voices and 18 | perspectives can be heard irrespective of biases, known and unknown. 19 | Creating an ethical and supportive environment is the responsibility 20 | of all participants. 21 | 22 | - Participants will avoid taking inappropriate actions or making 23 | statements based on characteristics such as age, race, ethnicity, 24 | sexual orientation, gender identity, gender expression, marital 25 | status, nationality, political affiliation, ability status, 26 | educational background, occupation, seniority or any other 27 | characteristic protected by law. 28 | 29 | Scope 30 | ----- 31 | 32 | This Code of Conduct applies within spaces, both physical and virtual, 33 | that are established and/or supported as part of the MESA project. 34 | Examples include the MESA mailing lists, the MESA Github repository, 35 | MESA instrument papers, and MESA-branded events such as the annual 36 | Summer School. 37 | 38 | Enforcement 39 | ----------- 40 | 41 | Instances of Code-of-Conduct violations should be reported by contacting 42 | one or more of the following MESA Responsible Persons (MRPs): 43 | 44 | - Lars Bildsten (bildsten@kitp.ucsb.edu) 45 | - Josiah Schwab (jwschwab@ucsc.edu) 46 | - Frank Timmes (fxt44@mac.com) 47 | - Anne Thoul (anne.thoul@uliege.be) 48 | - Rich Townsend (rhtownsend@wisc.edu) 49 | 50 | All reports will be reviewed and investigated and will result in a 51 | response that is deemed necessary and appropriate to the circumstances. 52 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Reporting issues 2 | 3 | If you run into a problem with one of the hooks in ``mesa-contrib``, 4 | you should open an issue and include any error messages and how to 5 | reproduce the problem. This usually includes 6 | 7 | * your MESA version, 8 | * your ``inlist``s, 9 | * your ``run_star_extras.f90`` and 10 | * anything else you've changed. 11 | 12 | Please reduce your input files to the minimum needed to reproduce the 13 | problem. 14 | 15 | # Contributing 16 | 17 | The whole point of ``mesa-contrib`` is to encourage and promote users' 18 | implementations of useful tools and physical models, so we welcome 19 | contributions! A contribution might be an implementation of a new 20 | formula for a stellar wind or a routine that writes out data in a 21 | format that can be passed to another stellar physics program. We 22 | particularly encourage you to add code that you've used in 23 | publications, so that others can easily reproduce your work and cite 24 | it if they use or develop it. 25 | 26 | ## What to include 27 | 28 | The code for your new hook should usually go in a folder like 29 | ``hooks/my_new_hook`` unless it's a single file, in which case it can 30 | go straight in ``hooks`` (but must be well documented in the 31 | file). Your Fortran source should follow the 32 | [MESA style](https://docs.mesastar.org/en/latest/developing/code_style.html). 33 | 34 | You should add a ``README.md`` file that 35 | 36 | * describes what the code does 37 | * gives your GitHub username and 38 | * describes how to use the hook. 39 | 40 | If appropriate, you should point to any publication (or other citable 41 | object, e.g. a Zenodo entry) that users should cite. You should also 42 | add your name to the top-level ``CODEOWNERS`` file so that you will be 43 | notified of changes to your contribution. 44 | 45 | It's helpful (and users are more likely to use your hook) if you 46 | include an example or examples. You should design these so that they 47 | will work with something like 48 | 49 | ``` 50 | cp -r "${MESA_DIR}"/star/work test_contrib 51 | cd test_contrib 52 | cp "${MESA_CONTRIB_DIR}"/my-new-hook/star_example/src/* src/ 53 | ./mk 54 | ./rn 55 | ``` 56 | 57 | All example folders matching ``hooks/*/{star,binary,astero}_example/`` 58 | will be run by the `check_examples.sh` script. It helps to keep the 59 | example runtimes short (e.g., a few minutes long) so that 60 | `check_examples.sh` finishes in a reasonable time. 61 | 62 | ## How to add your code to ``mesa-contrib`` 63 | 64 | New contributions must be proposed through GitHub's *pull request* 65 | (PR) system. The process is roughly: 66 | 67 | 1. fork the ``mesa-contrib`` repo (click *Fork* in the top-right of the GitHub interface), 68 | 2. clone your fork to you computer, 69 | 3. create a new branch for your additions (e.g. ``git checkout -b my-new-hook``), 70 | 4. make, commit and push your changes and 71 | 5. open a PR. 72 | 73 | You'll usually develop your new hook with the latest release version 74 | of MESA and should therefore make your PR against the ``release`` 75 | branch 76 | 77 | Once the PR is opened, the repo maintainers will review your code 78 | and decide whether to merge it into the repo, perhaps 79 | after some changes are made. 80 | 81 | ## Your responsibilities 82 | 83 | After your contribution has been merged, you are committing 84 | to 85 | 86 | * responding to users who come across issues and 87 | * keeping your hook working as MESA develops. 88 | 89 | Both might sound daunting but the maintainers and other users or 90 | contributors will help where possible. e.g. with simple compilation 91 | errors. Many changes to keep up with MESA will be minor updates to 92 | the hook interfaces. If the ``mesa-contrib`` maintainers can simply 93 | update your contribution to be consistent with changes in the MESA 94 | hooks interface, in a way that makes no change to the mathematics 95 | behind your hook, we will. 96 | 97 | If, however, it isn't clear how your code needs to be correctly 98 | updated (e.g. some quantity you use is removed from the star pointer), 99 | we'll expect you to commit to fixing or removing it, though we'll try 100 | our best to help figure out what to do. 101 | 102 | Code that remains broken will confuse and frustrate users and 103 | eventually be removed from ``mesa-contrib``. 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MESA Contributed Procedures 2 | 3 | This repo contains contributed procedures that can be used with the 4 | stellar evolution code [Modules for Experiments in Stellar Astrophysics 5 | (MESA)](http://mesastar.org/). 6 | 7 | Although this repo is administered by the MESA team and many of the 8 | contributions are from team members, it is *not* part of the main 9 | trunk and the MESA team takes no responsibility for the correctness of 10 | the procedures. If you are having trouble with a particular 11 | procedure, you should contact the person(s) who contributed that 12 | procedure to see if they can help. 13 | 14 | Many of the procedures will have been developed for a particular 15 | scientific purpose and have an associated publication in which the 16 | contributor used that procedure. If so, please cite the relevant 17 | publication(s) when using that procedure. 18 | 19 | ## Usage 20 | 21 | To use `contrib`, you must already be familiar with 22 | [extending MESA using `run_star_extras.f90`](https://docs.mesastar.org/en/latest/using_mesa/extending_mesa.html). 23 | 24 | The `contrib` repo can be used with any version of MESA after r12479 25 | by checking out this repo to some 26 | directory (e.g. `$HOME/mesa-contrib`) and pointing the environment 27 | variable `MESA_CONTRIB_DIR` there. e.g. 28 | 29 | export MESA_CONTRIB_DIR=$HOME/mesa-contrib 30 | 31 | Then, `$MESA_CONTRIB_DIR/hooks` will be added to the include path when 32 | compiling a MESA `work` folder. Use your chosen routine by adding an 33 | `include` statements after `contains` in your `run_star_extras.f90`. e.g. 34 | to use `hooks/try_mesa_contrib.f90`, you would add something like 35 | 36 | ````f90 37 | ... 38 | contains 39 | 40 | include 'try_mesa_contrib.f90' ! add this line 41 | 42 | subroutine extras_controls(id, ierr) 43 | integer, intent(in) :: id 44 | ... 45 | ```` 46 | 47 | to get access to the (trivial) subroutine `try_mesa_contrib`. If you 48 | call this at the end of `extras_controls`, 49 | 50 | ````f90 51 | ... 52 | 53 | call try_mesa_contrib 54 | 55 | end subroutine 56 | ```` 57 | 58 | you should see the message 59 | 60 | ````console 61 | you're ready to call routines from mesa-contrib 62 | ```` 63 | 64 | shortly after the start of your MESA run. 65 | -------------------------------------------------------------------------------- /check_examples.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # export environment variables that MESA needs 4 | export MESA_CONTRIB_DIR=$(pwd) 5 | export MESA_FORCE_PGSTAR_FLAG=false 6 | 7 | # make tmpdir for testing 8 | # local to script; MESA doesn't need it so no need to export 9 | MESA_WORK_DIR_BASE=$(mktemp -d) 10 | 11 | # arguments are 12 | # 1. folder name of hook 13 | # 2. module name (star/binary/astero) 14 | do_one(){ 15 | 16 | ( 17 | echo checking "$1" "$2" 18 | 19 | EXAMPLE_DIR="${MESA_CONTRIB_DIR}"/"$1""$2"_example 20 | 21 | # if this kind of example doesn't exist, exit 22 | if [ ! -d "${EXAMPLE_DIR}" ]; then 23 | exit 24 | fi 25 | 26 | # set MESA_WORK_DIR 27 | MESA_WORK_DIR="${MESA_WORK_DIR_BASE}"/"$1""$2" 28 | mkdir -p "${MESA_WORK_DIR}" 29 | 30 | # go there 31 | cd "${MESA_WORK_DIR}" || exit 32 | 33 | # copy in files from stock workdir 34 | cp -r "${MESA_DIR}"/"$2"/work/* . 35 | 36 | # copy in example test files 37 | # cp -vr "${EXAMPLE_DIR}"/src/* src/ 38 | cp -vr "${EXAMPLE_DIR}"/* ./ 39 | 40 | # try and make it 41 | if ./mk > mk.out 2> mk.err; then 42 | if [ -s 'mk.err' ]; then 43 | echo "[COMPILE WARN]" 44 | echo "see $MESA_WORK_DIR for details" 45 | exit 46 | else 47 | echo "[COMPILE OK]" 48 | # cleanup 49 | # rm -rf "${MESA_WORK_DIR}" 50 | fi 51 | else 52 | echo "[COMPILE FAIL]" 53 | echo "see $MESA_WORK_DIR for details" 54 | exit 55 | fi 56 | 57 | # try to run it 58 | if ./rn > rn.out 2> rn.err; then 59 | if [ -s 'rn.err' ]; then 60 | echo "[RUN WARN]" 61 | echo "see $MESA_WORK_DIR for details" 62 | exit 63 | else 64 | echo "[RUN OK]" 65 | # cleanup 66 | rm -rf "${MESA_WORK_DIR}" 67 | fi 68 | else 69 | echo "[RUN FAIL]" 70 | echo "see $MESA_WORK_DIR for details" 71 | exit 72 | fi 73 | ) 74 | 75 | } 76 | 77 | echo 78 | for d in hooks/*/ ; do 79 | do_one "$d" star 80 | do_one "$d" binary 81 | do_one "$d" astero 82 | echo 83 | done 84 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/.gitignore: -------------------------------------------------------------------------------- 1 | LOGS/* 2 | png/* 3 | photos/* 4 | *.data 5 | *.o 6 | *.smod 7 | *.mod 8 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/clean: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd make 4 | make clean 5 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/inlist: -------------------------------------------------------------------------------- 1 | &star_job 2 | read_extra_star_job_inlist(1) = .true. 3 | extra_star_job_inlist_name(1) = 'inlist_FullerAM' 4 | / 5 | 6 | 7 | &eos 8 | read_extra_eos_inlist(1) = .true. 9 | extra_eos_inlist_name(1) = 'inlist_FullerAM' 10 | / 11 | 12 | 13 | &kap 14 | read_extra_kap_inlist(1) = .true. 15 | extra_kap_inlist_name(1) = 'inlist_FullerAM' 16 | / 17 | 18 | 19 | &controls 20 | read_extra_controls_inlist(1) = .true. 21 | extra_controls_inlist_name(1) = 'inlist_FullerAM' 22 | / 23 | 24 | 25 | &pgstar 26 | read_extra_pgstar_inlist(1) = .true. 27 | extra_pgstar_inlist_name(1) = 'inlist_pgstar' 28 | / 29 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/inlist_FullerAM: -------------------------------------------------------------------------------- 1 | ! very loosely inspired by `inlist1` in the `cleanworkdir` 2 | ! subdirectory of the reproducibility package for Fuller & Lu 2022 3 | ! available at https://zenodo.org/records/5778001 it is only meant to 4 | ! illustrate the use of the Fuller AM transport. 5 | 6 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 | ! *not meant for science-quality results* ! 8 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 9 | 10 | &star_job 11 | pgstar_flag =.true. 12 | change_rotation_flag = .false. ! rotation off until near zams 13 | new_omega_div_omega_crit = 0.5d0! 14 | near_zams_relax_omega_div_omega_crit = .true. 15 | num_steps_to_relax_rotation = 10 ! use this many steps to change value 16 | relax_omega_max_yrs_dt = 1d3 ! << MS lifetime 17 | / ! end of star_job namelist 18 | 19 | 20 | &eos 21 | / ! end of eos namelist 22 | 23 | 24 | &kap 25 | ! kap options 26 | ! see kap/defaults/kap.defaults 27 | use_Type2_opacities = .true. 28 | Zbase = 0.02d0 29 | / ! end of kap namelist 30 | 31 | 32 | &controls 33 | 34 | use_other_am_mixing = .true. 35 | 36 | initial_mass = 15d0 37 | initial_z = 0.02d0 38 | 39 | am_nu_ST_factor = 0 ! turn off "classic" TS dynamo from Spruit 2002 40 | smooth_nu_ST = 5 41 | smooth_D_ST = 5 42 | use_other_am_mixing = .true. 43 | premix_omega = .true. 44 | recalc_mixing_info_each_substep = .true. 45 | am_nu_factor = 1d0 46 | am_nu_non_rotation_factor = 1d0 47 | am_nu_visc_factor = 0.333d0 48 | 49 | ! overshooting 50 | ! ~Brott+11 51 | overshoot_scheme(1) = 'step' 52 | overshoot_zone_type(1) = 'any' 53 | overshoot_zone_loc(1) = 'core' 54 | overshoot_bdy_loc(1) = 'any' 55 | overshoot_f(1) = 0.345d0 56 | overshoot_f0(1) = 0.01d0 57 | 58 | 59 | ! wind 60 | hot_wind_scheme = 'Dutch' 61 | cool_wind_RGB_scheme = 'Dutch' 62 | cool_wind_AGB_scheme = 'Dutch' 63 | RGB_to_AGB_wind_switch = 1.0d-4 64 | Dutch_scaling_factor = 1.0d0 65 | 66 | ! artificial mixing to smooth spikes 67 | set_min_D_mix = .true. 68 | min_D_mix = 1d2 69 | 70 | !extra spatial resolution 71 | max_dq = 0.02d0 72 | 73 | ! stopping condition 74 | max_model_number = 1000 75 | / ! end of controls namelist 76 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/inlist_pgstar: -------------------------------------------------------------------------------- 1 | &pgstar 2 | pgstar_interval = 10 3 | Profile_Panels1_win_flag = .true. 4 | Profile_Panels1_win_width = 6 5 | Profile_Panels1_win_aspect_ratio = 1.5 6 | Profile_Panels1_title = 'Abundance-Rotation-Mixing' 7 | Profile_Panels1_num_panels = 4 8 | Profile_Panels1_yaxis_name(1) = 'Abundance' 9 | Profile_Panels1_yaxis_name(2) = 'Dynamo' 10 | Profile_Panels1_yaxis_name(3) = 'Mixing' 11 | Profile_Panels1_yaxis_name(4) = 'Power' 12 | / 13 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/make/makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(MESA_DIR),) 2 | ifeq ($($MESA_DIR_INTENTIONALLY_EMPTY),) 3 | $(error MESA_DIR environment variable is not set) 4 | endif 5 | endif 6 | 7 | STAR = star 8 | 9 | include $(MESA_DIR)/star/work_standard_makefile 10 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/mk: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function check_okay { 4 | if [ $? -ne 0 ] 5 | then 6 | echo 7 | echo "FAILED" 8 | echo 9 | exit 1 10 | fi 11 | } 12 | 13 | cd make; make; check_okay 14 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/re: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | shopt -u expand_aliases 4 | 5 | photo_directory=photos 6 | 7 | function most_recent_photo { 8 | ls -tp "$photo_directory" | grep -v / | head -1 9 | } 10 | 11 | if [ $# -eq 0 ] 12 | then 13 | photo=$(most_recent_photo) 14 | else 15 | photo=$1 16 | fi 17 | 18 | if [ -z "$photo" ] || ! [ -f "$photo_directory/$photo" ] 19 | then 20 | echo "specified photo ($photo) does not exist" 21 | exit 1 22 | fi 23 | 24 | echo "restart from $photo" 25 | if ! cp "$photo_directory/$photo" restart_photo 26 | then 27 | echo "failed to copy photo ($photo)" 28 | exit 1 29 | fi 30 | 31 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 32 | ./star 33 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 34 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/rn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -f restart_photo 4 | 5 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 6 | ./star 7 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 8 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/src/run.f90: -------------------------------------------------------------------------------- 1 | program run 2 | use run_star_support, only: do_read_star_job 3 | use run_star, only: do_run_star 4 | 5 | implicit none 6 | 7 | integer :: ierr 8 | character (len=32) :: inlist_fname 9 | 10 | ierr = 0 11 | inlist_fname = 'inlist' 12 | 13 | call do_read_star_job(inlist_fname, ierr) 14 | if (ierr /= 0) stop 1 15 | 16 | call do_run_star(inlist_fname) 17 | 18 | end program run 19 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/Fuller_AM_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010-2019 Bill Paxton & The MESA Team 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | 30 | implicit none 31 | 32 | ! these routines are called by the standard run_star check_model 33 | contains 34 | 35 | include 'Fuller_AM/Fuller_AM_transport.inc' 36 | 37 | subroutine extras_controls(id, ierr) 38 | integer, intent(in) :: id 39 | integer, intent(out) :: ierr 40 | type (star_info), pointer :: s 41 | ierr = 0 42 | call star_ptr(id, s, ierr) 43 | if (ierr /= 0) return 44 | 45 | ! this is the place to set any procedure pointers you want to change 46 | ! e.g., other_wind, other_mixing, other_energy (see star_data.inc) 47 | 48 | 49 | ! the extras functions in this file will not be called 50 | ! unless you set their function pointers as done below. 51 | ! otherwise we use a null_ version which does nothing (except warn). 52 | 53 | s% extras_startup => extras_startup 54 | s% extras_start_step => extras_start_step 55 | s% extras_check_model => extras_check_model 56 | s% extras_finish_step => extras_finish_step 57 | s% extras_after_evolve => extras_after_evolve 58 | s% how_many_extra_history_columns => how_many_extra_history_columns 59 | s% data_for_extra_history_columns => data_for_extra_history_columns 60 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 61 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 62 | 63 | s% how_many_extra_history_header_items => how_many_extra_history_header_items 64 | s% data_for_extra_history_header_items => data_for_extra_history_header_items 65 | s% how_many_extra_profile_header_items => how_many_extra_profile_header_items 66 | s% data_for_extra_profile_header_items => data_for_extra_profile_header_items 67 | 68 | !! for Fuller & Lu 2022 AM transport 69 | s% other_am_mixing => TSF_Fuller_Lu22 70 | print *, "Using Fuller & Lu 2022 AM transport" 71 | 72 | !! for Fuller et al. 2019 AM transport 73 | !! comment above and uncomment below 74 | ! s% other_am_mixing => TSF_Fuller19 75 | ! print *, "Using Fuller et al. 2019 AM transport" 76 | end subroutine extras_controls 77 | 78 | 79 | subroutine extras_startup(id, restart, ierr) 80 | integer, intent(in) :: id 81 | logical, intent(in) :: restart 82 | integer, intent(out) :: ierr 83 | type (star_info), pointer :: s 84 | ierr = 0 85 | call star_ptr(id, s, ierr) 86 | if (ierr /= 0) return 87 | end subroutine extras_startup 88 | 89 | 90 | integer function extras_start_step(id) 91 | integer, intent(in) :: id 92 | integer :: ierr 93 | type (star_info), pointer :: s 94 | ierr = 0 95 | call star_ptr(id, s, ierr) 96 | if (ierr /= 0) return 97 | extras_start_step = 0 98 | end function extras_start_step 99 | 100 | 101 | ! returns either keep_going, retry, or terminate. 102 | integer function extras_check_model(id) 103 | integer, intent(in) :: id 104 | integer :: ierr 105 | type (star_info), pointer :: s 106 | ierr = 0 107 | call star_ptr(id, s, ierr) 108 | if (ierr /= 0) return 109 | extras_check_model = keep_going 110 | if (.false. .and. s% star_mass_h1 < 0.35d0) then 111 | ! stop when star hydrogen mass drops to specified level 112 | extras_check_model = terminate 113 | write(*, *) 'have reached desired hydrogen mass' 114 | return 115 | end if 116 | 117 | 118 | ! if you want to check multiple conditions, it can be useful 119 | ! to set a different termination code depending on which 120 | ! condition was triggered. MESA provides 9 customizable 121 | ! termination codes, named t_xtra1 .. t_xtra9. You can 122 | ! customize the messages that will be printed upon exit by 123 | ! setting the corresponding termination_code_str value. 124 | ! termination_code_str(t_xtra1) = 'my termination condition' 125 | 126 | ! by default, indicate where (in the code) MESA terminated 127 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 128 | end function extras_check_model 129 | 130 | 131 | integer function how_many_extra_history_columns(id) 132 | integer, intent(in) :: id 133 | integer :: ierr 134 | type (star_info), pointer :: s 135 | ierr = 0 136 | call star_ptr(id, s, ierr) 137 | if (ierr /= 0) return 138 | how_many_extra_history_columns = 0 139 | end function how_many_extra_history_columns 140 | 141 | 142 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 143 | integer, intent(in) :: id, n 144 | character (len=maxlen_history_column_name) :: names(n) 145 | real(dp) :: vals(n) 146 | integer, intent(out) :: ierr 147 | type (star_info), pointer :: s 148 | ierr = 0 149 | call star_ptr(id, s, ierr) 150 | if (ierr /= 0) return 151 | 152 | ! note: do NOT add the extras names to history_columns.list 153 | ! the history_columns.list is only for the built-in history column options. 154 | ! it must not include the new column names you are adding here. 155 | 156 | 157 | end subroutine data_for_extra_history_columns 158 | 159 | 160 | integer function how_many_extra_profile_columns(id) 161 | integer, intent(in) :: id 162 | integer :: ierr 163 | type (star_info), pointer :: s 164 | ierr = 0 165 | call star_ptr(id, s, ierr) 166 | if (ierr /= 0) return 167 | how_many_extra_profile_columns = 0 168 | end function how_many_extra_profile_columns 169 | 170 | 171 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 172 | integer, intent(in) :: id, n, nz 173 | character (len=maxlen_profile_column_name) :: names(n) 174 | real(dp) :: vals(nz,n) 175 | integer, intent(out) :: ierr 176 | type (star_info), pointer :: s 177 | integer :: k 178 | ierr = 0 179 | call star_ptr(id, s, ierr) 180 | if (ierr /= 0) return 181 | 182 | ! note: do NOT add the extra names to profile_columns.list 183 | ! the profile_columns.list is only for the built-in profile column options. 184 | ! it must not include the new column names you are adding here. 185 | 186 | ! here is an example for adding a profile column 187 | !if (n /= 1) stop 'data_for_extra_profile_columns' 188 | !names(1) = 'beta' 189 | !do k = 1, nz 190 | ! vals(k,1) = s% Pgas(k)/s% P(k) 191 | !end do 192 | 193 | end subroutine data_for_extra_profile_columns 194 | 195 | 196 | integer function how_many_extra_history_header_items(id) 197 | integer, intent(in) :: id 198 | integer :: ierr 199 | type (star_info), pointer :: s 200 | ierr = 0 201 | call star_ptr(id, s, ierr) 202 | if (ierr /= 0) return 203 | how_many_extra_history_header_items = 0 204 | end function how_many_extra_history_header_items 205 | 206 | 207 | subroutine data_for_extra_history_header_items(id, n, names, vals, ierr) 208 | integer, intent(in) :: id, n 209 | character (len=maxlen_history_column_name) :: names(n) 210 | real(dp) :: vals(n) 211 | type(star_info), pointer :: s 212 | integer, intent(out) :: ierr 213 | ierr = 0 214 | call star_ptr(id,s,ierr) 215 | if(ierr/=0) return 216 | 217 | ! here is an example for adding an extra history header item 218 | ! also set how_many_extra_history_header_items 219 | ! names(1) = 'mixing_length_alpha' 220 | ! vals(1) = s% mixing_length_alpha 221 | 222 | end subroutine data_for_extra_history_header_items 223 | 224 | 225 | integer function how_many_extra_profile_header_items(id) 226 | integer, intent(in) :: id 227 | integer :: ierr 228 | type (star_info), pointer :: s 229 | ierr = 0 230 | call star_ptr(id, s, ierr) 231 | if (ierr /= 0) return 232 | how_many_extra_profile_header_items = 0 233 | end function how_many_extra_profile_header_items 234 | 235 | 236 | subroutine data_for_extra_profile_header_items(id, n, names, vals, ierr) 237 | integer, intent(in) :: id, n 238 | character (len=maxlen_profile_column_name) :: names(n) 239 | real(dp) :: vals(n) 240 | type(star_info), pointer :: s 241 | integer, intent(out) :: ierr 242 | ierr = 0 243 | call star_ptr(id,s,ierr) 244 | if(ierr/=0) return 245 | 246 | ! here is an example for adding an extra profile header item 247 | ! also set how_many_extra_profile_header_items 248 | ! names(1) = 'mixing_length_alpha' 249 | ! vals(1) = s% mixing_length_alpha 250 | 251 | end subroutine data_for_extra_profile_header_items 252 | 253 | 254 | ! returns either keep_going or terminate. 255 | ! note: cannot request retry; extras_check_model can do that. 256 | integer function extras_finish_step(id) 257 | integer, intent(in) :: id 258 | integer :: ierr 259 | type (star_info), pointer :: s 260 | ierr = 0 261 | call star_ptr(id, s, ierr) 262 | if (ierr /= 0) return 263 | extras_finish_step = keep_going 264 | 265 | ! to save a profile, 266 | ! s% need_to_save_profiles_now = .true. 267 | ! to update the star log, 268 | ! s% need_to_update_history_now = .true. 269 | 270 | ! see extras_check_model for information about custom termination codes 271 | ! by default, indicate where (in the code) MESA terminated 272 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 273 | end function extras_finish_step 274 | 275 | 276 | subroutine extras_after_evolve(id, ierr) 277 | integer, intent(in) :: id 278 | integer, intent(out) :: ierr 279 | type (star_info), pointer :: s 280 | ierr = 0 281 | call star_ptr(id, s, ierr) 282 | if (ierr /= 0) return 283 | end subroutine extras_after_evolve 284 | 285 | 286 | end module run_star_extras 287 | -------------------------------------------------------------------------------- /hooks/Fuller_AM/README.md: -------------------------------------------------------------------------------- 1 | # Fuller et al. angular momentum transport 2 | 3 | ## Overview 4 | 5 | The functions in `Fuller_AM_transport.inc` implement the modified 6 | Tayler-Spruit dynamo by Fuller and collaborators. 7 | 8 | Specifically `TSF_Fuller19` implements the algorithm described in 9 | [Fuller et al. 10 | 2019](https://ui.adsabs.harvard.edu/abs/2019MNRAS.485.3661F/abstract) 11 | and available in the original form at 12 | https://zenodo.org/records/3228403, and `TSF_Fuller_Lu22` implements 13 | the algorithm described in [Fuller & Lu 14 | 2022](https://ui.adsabs.harvard.edu/abs/2022MNRAS.511.3951F/abstract) 15 | and available in the original form at 16 | https://zenodo.org/records/5778001. Here, they are only adapted for 17 | compatibility with the current MESA version (r24.03.1). All credits go 18 | to the original authors of the papers above, which you should cite if you 19 | use this. 20 | 21 | The two functions are overall similar, but the latter does not have a 22 | minimum shear threshold to activate and has a different efficiency 23 | value. Refer to the above papers and references therein for more 24 | details. 25 | 26 | ## Usage 27 | 28 | The two routines are mutually exclusive, you can only use one _or_ the 29 | other. 30 | 31 | Make sure `$MESA_CONTRIB_DIR` is set to the appropriate location and 32 | your `run_star_extras.f90` includes this file, e.g.: 33 | 34 | ```Fortran 35 | 36 | contains 37 | 38 | include 'Fuller_AM/Fuller_AM_transport.inc' 39 | ``` 40 | 41 | Then, these can be used as any `other` hook in MESA, that is: 42 | 43 | * set `use_other_am_mixing=.true.` in your inlist 44 | * inside `run_star_extras.f90`, in the routine `extras_controls`, 45 | point `other_am_mixing` to one of the two functions, e.g.: 46 | `s% other_am_mixing => TSF_Fuller19` or `s% other_am_mixing => TSF_Fuller_lu22` 47 | 48 | ### Example 49 | 50 | Example inlists and `run_star_extras.f90` (based on the 51 | `$MESA_DIR/star/work` template) are provided in `Fuller_AM_example` 52 | and by default will call the Fuller & Lu 2022 version. 53 | 54 | It has been tested with MESA version r24.03.1. 55 | 56 | ## Maintainer 57 | 58 | This contribution is maintained by Mathieu Renzo (`mathren`) 59 | -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | # Style suggestions 2 | 3 | ## Overview 4 | 5 | Routines and data can go anywhere in a contribution directory, including in subfolders. 6 | You just need to be sure to point to the correct locations in your `run_star_extras.f90`. 7 | 8 | Please include 9 | `` 10 | This contribution is maintained by Your Name/GitHub ID 11 | `` 12 | 13 | in your `README.md` so that your contribution has a contact and known maintainer. 14 | You should also add your name to the top-level `CODEOWNERS` file. 15 | 16 | ## Usage 17 | 18 | It helps to include example directories showing how your contribution is used. 19 | Depending on which parts of MESA your contribution touches you may want to include examples for the star, rsp, and/or astero modules. 20 | 21 | Typically an example directory contains whatever inlists are needed as well as a `src` directory containing the sample `run_star_extras.f90`. 22 | In your `run_star_extras.f90`, around the `contains` statement you'll need 23 | 24 | ````f90 25 | include 'contribution_directory/any_data_to_include.inc' 26 | 27 | contains 28 | 29 | include 'contribution_directory/routines.dek' 30 | include 'contribution_directory/more_routines/inc' 31 | ```` 32 | 33 | If you have chosen to put your routines and data in subfolders, just amend the paths above accordingly. 34 | 35 | Also, if your contribution makes use of any MESA hooks you'll need to point those hooks in extras_controls: 36 | 37 | ````f90 38 | subroutine extras_controls(id, ierr) 39 | ... 40 | call hydro_Ttau_setup(id, ierr) 41 | ... 42 | s% other_gradr_factor => hydro_Ttau_gradr_factor 43 | s% other_surface_PT => hydro_Ttau_surface_PT 44 | ... 45 | end subroutine extras_controls 46 | ```` 47 | 48 | Please document all such changes users need to make in order to use your contribution. 49 | 50 | ## Extra history and profile columns 51 | 52 | Sometimes users will want to use multiple contributions in their work. 53 | Each contribution might have routines for adding history and/or profile columns. 54 | To make it easier for users to combine these routines, we recommend that these routines have a hook-specific name. 55 | That avoids namespace conflicts. 56 | Otherwise we recommend that these routines follow the call signature of the current methods for extra profile and history columns. 57 | If your routines follow this signature, then a user can incorporate your routines alongside other contributions as follows: 58 | 59 | ````f90 60 | integer function how_many_extra_history_columns(id) 61 | integer, intent(in) :: id 62 | integer :: ierr 63 | type (star_info), pointer :: s 64 | ierr = 0 65 | call star_ptr(id, s, ierr) 66 | if (ierr /= 0) return 67 | how_many_extra_history_columns = 0 68 | how_many_extra_history_columns = how_many_extra_history_columns + contribution1_how_many_extra_history_columns(id) 69 | how_many_extra_history_columns = how_many_extra_history_columns + contribution2_how_many_extra_history_columns(id) 70 | how_many_extra_history_columns = how_many_extra_history_columns + contribution3_how_many_extra_history_columns(id) 71 | ... 72 | 73 | end function how_many_extra_history_columns 74 | 75 | 76 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 77 | integer, intent(in) :: id, n 78 | character (len=maxlen_history_column_name) :: names(n) 79 | real(dp) :: vals(n) 80 | integer, intent(out) :: ierr 81 | integer :: j 82 | type (star_info), pointer :: s 83 | ierr = 0 84 | call star_ptr(id, s, ierr) 85 | if (ierr /= 0) return 86 | 87 | ! note: do NOT add the extras names to history_columns.list 88 | ! the history_columns.list is only for the built-in history column options. 89 | ! it must not include the new column names you are adding here. 90 | 91 | j = 1 92 | nc = contribution1_how_many_extra_history_columns(id) 93 | call contribution1_data_for_extra_history_columns(id, nc, names(j:j+nc), vals(j:j+nc), ierr) 94 | 95 | j = j + nc 96 | nc = contribution2_how_many_extra_history_columns(id) 97 | call contribution2_data_for_extra_history_columns(id, nc, names(j:j+nc), vals(j:j+nc), ierr) 98 | 99 | j = j + nc 100 | nc = contribution3_how_many_extra_history_columns(id) 101 | call contribution3_data_for_extra_history_columns(id, nc, names(j:j+nc), vals(j:j+nc), ierr) 102 | ... 103 | 104 | end subroutine data_for_extra_history_columns 105 | ```` 106 | 107 | and similarly for profile columns. Note that for profile columns you need to explicitly slice the first index of the ``vals`` array, as in ``vals(1:s%nz,j:j+nc)``. 108 | -------------------------------------------------------------------------------- /hooks/atm_T_tau_gradr_factor.f90: -------------------------------------------------------------------------------- 1 | ! Modifies the radiative gradient so that the "interior" model 2 | ! correctly reproduces the T(τ) relation selected by the 3 | ! `atm_T_tau_relation` control. 4 | ! 5 | ! If the T(τ) relation is expressed as 6 | ! 7 | ! T⁴(τ) = 3Teff⁴/4 (τ + q(τ)) 8 | ! 9 | ! then the radiative gradient factor is 1+q'(τ). For an Eddington 10 | ! atmosphere, q(τ)=2/3 so q'(τ)=0 and the factor isn't necessary. 11 | ! 12 | ! Added by @warrickball (2019-12-16). 13 | 14 | 15 | subroutine atm_T_tau_gradr_factor(id, ierr) 16 | integer, intent(in) :: id 17 | integer, intent(out) :: ierr 18 | type (star_info), pointer :: s 19 | integer :: k 20 | ierr = 0 21 | call star_ptr(id, s, ierr) 22 | if (ierr /= 0) return 23 | 24 | do k = 1, s% nz 25 | s% gradr_factor(k) = 1d0 + dq_dtau(s% atm_T_tau_relation, s% tau(k)) 26 | end do 27 | 28 | end subroutine atm_T_tau_gradr_factor 29 | 30 | 31 | real(dp) function dq_dtau(atm_T_tau_relation, tau) 32 | character (len=strlen), intent(in) :: atm_T_tau_relation 33 | real(dp), intent(in) :: tau 34 | real(dp) :: e1, e2, de1_dtau, de2_dtau, h1 35 | real(dp), parameter :: & 36 | q1 = 1.0361d0, & 37 | q2 = -0.3134d0, & 38 | q3 = 2.44799995d0, & 39 | q4 = -0.29589999d0, & 40 | q5 = 30.0d0 41 | 42 | select case (atm_T_tau_relation) 43 | case ('Eddington') 44 | dq_dtau = 0d0 45 | case ('Krishna_Swamy') 46 | if (tau == 0) then 47 | e1 = 1; de1_dtau = -2.54d0 48 | e2 = 1; de2_dtau = -30d0 49 | else 50 | e1 = exp(-2.54d0*tau); de1_dtau = -2.54d0*e1 51 | e2 = exp(-30d0*tau); de2_dtau = -30d0*e2 52 | end if 53 | dq_dtau = - 0.815d0*de1_dtau - 0.025d0*de2_dtau 54 | case ('solar_Hopf') 55 | if (tau == 0) then 56 | e1 = 1; de1_dtau = -q3 57 | e2 = 1; de2_dtau = -q5 58 | else 59 | e1 = exp(-q3*tau); de1_dtau = -q3*e1 60 | e2 = exp(-q5*tau); de2_dtau = -q5*e2 61 | end if 62 | dq_dtau = q2*de1_dtau + q4*de2_dtau 63 | case default 64 | dq_dtau = -1 65 | end select 66 | 67 | end function dq_dtau 68 | -------------------------------------------------------------------------------- /hooks/cmd_line_args.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Generates the command-line argument hook for MESA, which is saved to 4 | # `$MESA_CONTRIB_DIR/hooks/cmd_line_args.inc`. 5 | # 6 | # You can add or remove the parameters you'd like to control from the 7 | # list `args`, below. 8 | # 9 | # To use the command line arguments in MESA, add the variable 10 | # declarations 11 | # 12 | # integer :: i_arg 13 | # character(len=32) :: arg 14 | # 15 | # to the preamble of the `extras_controls` function and 16 | # 17 | # include `cmd_line_args.inc` 18 | # 19 | # after the call to `star_ptr` in your `run_star_extras.f90`. In your 20 | # work folder, run `./clean` and `./mk` and then run MESA with, e.g. 21 | # 22 | # $ ./star inlist --initial-mass 2.0 23 | # 24 | # Added by @warrickball following the simple example by @jschwab on 25 | # the mailing list. 26 | # 27 | # https://lists.mesastar.org/pipermail/mesa-users/2020-January/011068.html 28 | 29 | import os 30 | 31 | # Change this list to include the controls you'd like to vary from the 32 | # command line. 33 | args = ['initial_mass', 'initial_z', 'initial_y', 'mixing_length_alpha'] 34 | 35 | with open(os.environ['MESA_CONTRIB_DIR'] + '/hooks/cmd_line_args.inc', 'wt') as f: 36 | f.write('\n'.join([ 37 | " ! Add these two variables to extras_controls preamble", 38 | " ! integer :: i_arg", 39 | " ! character(len=32) :: arg", 40 | " ! then include this after the star pointer is set.", 41 | "", 42 | " i_arg = 2 ! first argument is filename of inlist", 43 | " call GET_COMMAND_ARGUMENT(i_arg, arg)", 44 | " do while (arg /= ' ')", 45 | " select case (arg)", 46 | ""])) 47 | 48 | for arg in args: 49 | f.write('\n'.join([ 50 | " case ('--%s')" % arg.replace('_', '-'), 51 | " i_arg = i_arg + 1", 52 | " call GET_COMMAND_ARGUMENT(i_arg, arg)", 53 | " read(arg, *) s%% %s" % arg, 54 | ""])) 55 | 56 | f.write('\n'.join([ 57 | " case default", 58 | " stop 'invalid command-line argument: '//trim(arg)", 59 | " end select", 60 | "", 61 | " i_arg = i_arg + 1", 62 | " call GET_COMMAND_ARGUMENT(i_arg, arg)", 63 | " end do", 64 | ""])) 65 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/README.md: -------------------------------------------------------------------------------- 1 | # ``czb_mesh_function`` 2 | 3 | ## Overview 4 | 5 | This provides a mesh function that can be used to increase resolution 6 | in the vicinity of convection zone boundaries (czb). 7 | 8 | This contribution is maintained by Josiah Schwab (@jschwab). 9 | 10 | ## Usage 11 | 12 | An example inlist and `run_star_extras.f90` are provided in the 13 | `star_example` subfolder. That setup illustrates putting additional 14 | zones around the top boundary of the core convection zone in a 2.5 15 | Msun star. 16 | 17 | The czb_mesh inlist options follow the same pattern-matching approach 18 | as the MESA overshooting controls. 19 | 20 | ````Fortran 21 | ! set defaults 22 | czb_mesh_zone_type(:) = '' ! Possible values: burn_H, burn_He, burn_Z, nonburn, any 23 | czb_mesh_zone_loc(:) = '' ! Possible values: core, shell, any 24 | czb_mesh_bdy_loc(:) = '' ! Possible values: bottom, top, any 25 | 26 | czb_mesh_f(:) = 0d0 ! target zone spacing in delta_lnP (i.e. ~= 1/f zones per scale height) 27 | czb_mesh_l(:) = 0d0 ! extent of enhanced resolution region (in pressure scale heights) 28 | 29 | ```` 30 | 31 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/czb_mesh_function.inc: -------------------------------------------------------------------------------- 1 | subroutine read_inlist_czb_mesh_function(ierr) 2 | integer, intent(out) :: ierr 3 | character (len=256) :: filename, message 4 | integer :: unit 5 | filename = 'inlist_czb_mesh_function' 6 | 7 | write(*,*) 'read_inlist_czb_mesh_function' 8 | 9 | ! set defaults 10 | czb_mesh_zone_type(:) = '' ! Possible values: burn_H, burn_He, burn_Z, nonburn, any 11 | czb_mesh_zone_loc(:) = '' ! Possible values: core, shell, any 12 | czb_mesh_bdy_loc(:) = '' ! Possible values: bottom, top, any` 13 | 14 | czb_mesh_f(:) = 0d0 15 | czb_mesh_l(:) = 0d0 16 | 17 | open(newunit=unit, file=trim(filename), action='read', delim='quote', iostat=ierr) 18 | if (ierr /= 0) then 19 | write(*, *) 'Failed to open control namelist file ', trim(filename) 20 | else 21 | read(unit, nml=czb_mesh_function, iostat=ierr) 22 | close(unit) 23 | if (ierr /= 0) then 24 | write(*, *) 'Failed while trying to read control namelist file ', trim(filename) 25 | write(*, '(a)') & 26 | 'The following runtime error message might help you find the problem' 27 | write(*, *) 28 | open(newunit=unit, file=trim(filename), action='read', delim='quote', status='old', iostat=ierr) 29 | read(unit, nml=czb_mesh_function) 30 | close(unit) 31 | end if 32 | end if 33 | 34 | end subroutine read_inlist_czb_mesh_function 35 | 36 | 37 | subroutine czb_mesh_fcn (s, fcn, ierr) 38 | 39 | type(star_info), pointer :: s 40 | real(dp), intent(inout) :: fcn(:) 41 | integer, intent(out) :: ierr 42 | 43 | logical, parameter :: DEBUG = .FALSE. 44 | 45 | integer :: i 46 | integer :: j 47 | integer :: k 48 | logical :: is_core 49 | logical :: match_zone_type 50 | logical :: match_zone_loc 51 | logical :: match_bdy_loc 52 | 53 | include 'formats' 54 | 55 | ! Initialize 56 | 57 | ierr = 0 58 | fcn = 1d0 59 | 60 | if (DEBUG) then 61 | write(*, 3) 'conv_bdy_mesh_function; model, n_conv_bdy=', s%model_number, s%num_conv_boundaries 62 | end if 63 | 64 | ! Loop over convective boundaries, from center to surface 65 | 66 | conv_bdy_loop : do i = 1, s%num_conv_boundaries 67 | 68 | if (DEBUG) then 69 | write(*,*) 'zone ', i 70 | write(*,*) 'burn_H', s%burn_h_conv_region(i) 71 | write(*,*) 'burn_He', s%burn_he_conv_region(i) 72 | write(*,*) 'burn_Z', s%burn_Z_conv_region(i) 73 | write(*,*) 'is_core', (i == 1 .AND. s%R_center == 0d0 .AND. s%top_conv_bdy(i)) 74 | write(*,*) 'top', s%top_conv_bdy(i) 75 | end if 76 | 77 | ! Loop over criteria 78 | 79 | criteria_loop : do j = 1, NUM_CZB_MESH_PARAM_SETS 80 | 81 | ! Skip if the zone type is blank 82 | 83 | if (czb_mesh_zone_type(j) == '') cycle criteria_loop 84 | 85 | ! Check if the criteria match the current boundary 86 | 87 | select case (czb_mesh_zone_type(j)) 88 | case ('burn_H') 89 | match_zone_type = s%burn_h_conv_region(i) 90 | case ('burn_He') 91 | match_zone_type = s%burn_he_conv_region(i) 92 | case ('burn_Z') 93 | match_zone_type = s%burn_z_conv_region(i) 94 | case ('nonburn') 95 | match_zone_type = .NOT. ( & 96 | s%burn_h_conv_region(i) .OR. & 97 | s%burn_he_conv_region(i) .OR. & 98 | s%burn_z_conv_region(i) ) 99 | case ('any') 100 | match_zone_type = .TRUE. 101 | case default 102 | write(*,*) 'Invalid czb_mesh_zone_type: j, czb_mesh_zone_type(j)=', j, czb_mesh_zone_type(j) 103 | ierr = -1 104 | return 105 | end select 106 | 107 | is_core = (i == 1 .AND. s%R_center == 0d0 .AND. s%top_conv_bdy(i)) 108 | 109 | select case (czb_mesh_zone_loc(j)) 110 | case ('core') 111 | match_zone_loc = is_core 112 | case ('shell') 113 | match_zone_loc = .NOT. is_core 114 | case ('any') 115 | match_zone_loc = .TRUE. 116 | case default 117 | write(*,*) 'Invalid czb_mesh_zone_loc: j, czb_mesh_zone_loc(j)=', j, czb_mesh_zone_loc(j) 118 | ierr = -1 119 | return 120 | end select 121 | 122 | select case (czb_mesh_bdy_loc(j)) 123 | case ('bottom') 124 | match_bdy_loc = .NOT. s%top_conv_bdy(i) 125 | case ('top') 126 | match_bdy_loc = s%top_conv_bdy(i) 127 | case ('any') 128 | match_bdy_loc = .TRUE. 129 | case default 130 | write(*,*) 'Invalid czb_mesh_bdy_loc: j, czb_mesh_bdy_loc(j)=', j, czb_mesh_bdy_loc(j) 131 | ierr = -1 132 | return 133 | end select 134 | 135 | if (.NOT. (match_zone_type .AND. match_zone_loc .AND. match_bdy_loc)) cycle criteria_loop 136 | 137 | if (DEBUG) then 138 | write(*,*) 'czb_mesh at convective boundary: i, j=', i, j 139 | write(*,*) ' czb_mesh_zone_type=', TRIM(czb_mesh_zone_type(j)) 140 | write(*,*) ' czb_mesh_zone_loc=', TRIM(czb_mesh_zone_loc(j)) 141 | write(*,*) ' czb_mesh_bdy_loc=', TRIM(czb_mesh_bdy_loc(j)) 142 | endif 143 | 144 | ! Evaluate the mesh function 145 | call eval_czb_mesh_fcn(s, i, j, fcn, ierr) 146 | 147 | if (ierr /= 0) return 148 | 149 | end do criteria_loop 150 | 151 | end do conv_bdy_loop 152 | 153 | ! Finish 154 | fcn(1) = s% lnPeos(1) 155 | do k = 2, s% nz 156 | fcn(k) = fcn(k-1) + (s% lnPeos(k) - s% lnPeos(k-1)) * fcn(k) 157 | end do 158 | 159 | return 160 | 161 | end subroutine czb_mesh_fcn 162 | 163 | subroutine eval_czb_mesh_fcn (s, i, j, fcn, ierr) 164 | 165 | type(star_info), pointer :: s 166 | integer, intent(in) :: i 167 | integer, intent(in) :: j 168 | real(dp), intent(inout) :: fcn(:) 169 | integer, intent(out) :: ierr 170 | 171 | logical, parameter :: DEBUG = .FALSE. 172 | 173 | real(dp) :: f 174 | real(dp) :: l 175 | integer :: k_cb 176 | real(dp) :: r_cb 177 | real(dp) :: Hp_cb 178 | integer :: k 179 | real(dp) :: r 180 | real(dp) :: dr 181 | 182 | 183 | ierr = 0 184 | 185 | ! Extract parameters 186 | 187 | f = czb_mesh_f(j) 188 | l = czb_mesh_l(j) 189 | 190 | ! Evaluate convective boundary (_cb) parameters 191 | 192 | call eval_conv_bdy_k(s, i, k_cb, ierr) 193 | if (ierr /= 0) return 194 | 195 | call eval_conv_bdy_r(s, i, r_cb, ierr) 196 | if (ierr /= 0) return 197 | 198 | call eval_conv_bdy_Hp(s, i, Hp_cb, ierr) 199 | if (ierr /= 0) return 200 | 201 | ! Loop over cells; first outward, then inward 202 | 203 | outward_cell_loop : do k = k_cb, 1, -1 204 | 205 | r = s%r(k) 206 | dr = r - r_cb 207 | 208 | fcn(k) = max(fcn(k), 1d0/f) 209 | 210 | if (dr > Hp_cb * l) then 211 | exit outward_cell_loop 212 | endif 213 | 214 | end do outward_cell_loop 215 | 216 | inward_cell_loop : do k = k_cb+1, s% nz, 1 217 | 218 | r = s%r(k) 219 | dr = r_cb - r 220 | 221 | fcn(k) = max(fcn(k), 1d0/f) 222 | 223 | if (dr > Hp_cb * l) then 224 | exit inward_cell_loop 225 | endif 226 | 227 | end do inward_cell_loop 228 | 229 | 230 | if (DEBUG) then 231 | write(*,*) 'conv_bdy_mesh:' 232 | write(*,*) ' f =', f 233 | write(*,*) ' l =', l 234 | write(*,*) ' Hp_cb =', Hp_cb 235 | end if 236 | 237 | ! Finish 238 | 239 | return 240 | 241 | end subroutine eval_czb_mesh_fcn 242 | 243 | 244 | !**** 245 | ! copy of routines from star/private/overshoot_utils.f90 246 | !**** 247 | 248 | subroutine eval_conv_bdy_k (s, i, k, ierr) 249 | 250 | type(star_info), pointer :: s 251 | integer, intent(in) :: i 252 | integer, intent(out) :: k 253 | integer, intent(out) :: ierr 254 | 255 | ! Evaluate the index k of the cell containing the i'th convective 256 | ! boundary 257 | 258 | ierr = 0 259 | 260 | if (s%top_conv_bdy(i)) then 261 | k = s%conv_bdy_loc(i) 262 | else 263 | k = s%conv_bdy_loc(i) - 1 264 | endif 265 | 266 | if (k >= s%nz .OR. k < 1) then 267 | write(*,*) 'Invalid cell for convective boundary: i, k, nz=', i, k, s%nz 268 | ierr = -1 269 | return 270 | endif 271 | 272 | ! Finish 273 | 274 | return 275 | 276 | end subroutine eval_conv_bdy_k 277 | 278 | !**** 279 | 280 | subroutine eval_conv_bdy_r (s, i, r, ierr) 281 | 282 | type(star_info), pointer :: s 283 | integer, intent(in) :: i 284 | real(dp), intent(out) :: r 285 | integer, intent(out) :: ierr 286 | 287 | integer :: k 288 | real(dp) :: w 289 | 290 | ! Evaluate the radius r at the i'th convective boundary 291 | 292 | ! Find the convective boundary cell 293 | 294 | ierr = 0 295 | 296 | call eval_conv_bdy_k(s, i, k, ierr) 297 | if (ierr /= 0) return 298 | 299 | ! Interpolate r based on the fact that r^3 varies linearly with q 300 | ! across the (constant-density) cell 301 | 302 | w = s%cz_bdy_dq(k)/s%dq(k) 303 | 304 | if (w < 0._dp .OR. w > 1._dp) then 305 | write(*,*) 'Invalid weight for convective boundary: i, w=', i, w 306 | ierr = -1 307 | return 308 | end if 309 | 310 | associate (k_o => k, & 311 | k_i => k+1) 312 | 313 | r = pow(( w)*s%r(k_i)*s%r(k_i)*s%r(k_i) + & 314 | (1._dp-w)*s%r(k_o)*s%r(k_o)*s%r(k_o), 1._dp/3._dp) 315 | 316 | end associate 317 | 318 | ! Finish 319 | 320 | return 321 | 322 | end subroutine eval_conv_bdy_r 323 | 324 | !**** 325 | 326 | subroutine eval_conv_bdy_Hp (s, i, Hp, ierr) 327 | 328 | use num_lib 329 | 330 | type(star_info), pointer :: s 331 | integer, intent(in) :: i 332 | real(dp), intent(out) :: Hp 333 | integer, intent(out) :: ierr 334 | 335 | integer :: k 336 | real(dp) :: r 337 | real(dp) :: w 338 | real(dp) :: x0 339 | real(dp) :: x1 340 | real(dp) :: x2 341 | real(dp) :: x 342 | real(dp) :: a0 343 | real(dp) :: a1 344 | real(dp) :: a2 345 | real(dp) :: P 346 | real(dp) :: rho 347 | real(dp) :: r_top 348 | real(dp) :: r_bot 349 | real(dp) :: dr 350 | 351 | ! Evaluate the pressure scale height Hp at the i'th convective boundary 352 | 353 | ! Find the convective boundary cell 354 | 355 | ierr = 0 356 | 357 | call eval_conv_bdy_k(s, i, k, ierr) 358 | if (ierr /= 0) return 359 | 360 | ! Evaluate the radius at the convective boundary 361 | 362 | call eval_conv_bdy_r(s, i, r, ierr) 363 | if (ierr /= 0) return 364 | 365 | ! Interpoalte the pressure and density at the boundary, using a 366 | ! quadratic fit across the boundary cell and its neighbors (the 367 | ! x's are fractional mass distances from the outer edge of cell 368 | ! k-1); then, evaluate the pressure scale height 369 | 370 | associate (k_o => k-1, & 371 | k_m => k, & 372 | k_i => k+1) 373 | 374 | x0 = s%dq(k_o)/2._dp 375 | x1 = s%dq(k_o) + s%dq(k_m)/2._dp 376 | x2 = s%dq(k_o) + s%dq(k_m) + s%dq(k_i)/2._dp 377 | 378 | x = s%dq(k_o) + s%cz_bdy_dq(k) 379 | 380 | call two_piece_linear_coeffs(x, x0, x1, x2, a0, a1, a2, ierr) 381 | if (ierr /= 0) return 382 | 383 | P = exp(a0*s%lnPeos(k_o) + a1*s%lnPeos(k_m) + a2*s%lnPeos(k_i)) 384 | rho = exp(a0*s%lnd(k_o) + a1*s%lnd(k_m) + a2*s%lnd(k_i)) 385 | 386 | ! Evaluate the pressure scale height 387 | 388 | Hp = P/(rho*s%cgrav(k_m)* & 389 | (s%M_center + s%xmstar*s%conv_bdy_q(i))/(r*r)) 390 | 391 | end associate 392 | 393 | ! (Possibly) limit the scale height using the size of the 394 | ! convection zone 395 | 396 | if (s%limit_overshoot_Hp_using_size_of_convection_zone) then 397 | 398 | ! Determine the radial extent of the convection zone (note that 399 | ! r_top/r_bot don't coincide exactly with the r calculated 400 | ! above) 401 | 402 | if (s%top_conv_bdy(i)) then 403 | 404 | if (i == 1) then 405 | r_bot = s%R_center 406 | else 407 | if (s%top_conv_bdy(i-1)) then 408 | write(*,*) 'Double top boundary in overshoot; i=', i 409 | ierr = -1 410 | return 411 | end if 412 | r_bot = s%r(s%conv_bdy_loc(i-1)) 413 | endif 414 | 415 | r_top = s%r(k) 416 | 417 | else 418 | 419 | r_bot = s%r(k+1) 420 | 421 | if (i == s%num_conv_boundaries) then 422 | r_top = s%r(1) 423 | else 424 | if (.NOT. s%top_conv_bdy(i+1)) then 425 | write(*,*) 'Double bottom boundary in overshoot; i=', i 426 | ierr = -1 427 | return 428 | endif 429 | r_top = s%r(s%conv_bdy_loc(i+1)) 430 | endif 431 | 432 | endif 433 | 434 | dr = r_top - r_bot 435 | 436 | ! Apply the limit 437 | 438 | if (s%overshoot_alpha > 0d0) then 439 | if (s%overshoot_alpha*Hp > dr) Hp = dr/s%overshoot_alpha 440 | else 441 | if (s%alpha_mlt(k)*Hp > dr) Hp = dr/s%mixing_length_alpha 442 | end if 443 | 444 | end if 445 | 446 | ! Finish 447 | 448 | return 449 | 450 | end subroutine eval_conv_bdy_Hp 451 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/czb_mesh_function_def.inc: -------------------------------------------------------------------------------- 1 | integer, parameter :: NUM_CZB_MESH_PARAM_SETS = 16 2 | 3 | real(dp) :: czb_mesh_f(NUM_CZB_MESH_PARAM_SETS) 4 | real(dp) :: czb_mesh_l(NUM_CZB_MESH_PARAM_SETS) 5 | character(256) :: czb_mesh_zone_type(NUM_CZB_MESH_PARAM_SETS) 6 | character(256) :: czb_mesh_zone_loc(NUM_CZB_MESH_PARAM_SETS) 7 | character(256) :: czb_mesh_bdy_loc(NUM_CZB_MESH_PARAM_SETS) 8 | 9 | namelist /czb_mesh_function/ & 10 | czb_mesh_zone_type, & 11 | czb_mesh_zone_loc, & 12 | czb_mesh_bdy_loc, & 13 | czb_mesh_f, & 14 | czb_mesh_l 15 | 16 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/czb_mesh_function_extras_controls.inc: -------------------------------------------------------------------------------- 1 | ! setup 2 | call read_inlist_czb_mesh_function(ierr) 3 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/star_example/inlist: -------------------------------------------------------------------------------- 1 | ! This is the first inlist file that MESA reads when it starts. 2 | 3 | ! This file tells MESA to go look elsewhere for its configuration 4 | ! info. This makes changing between different inlists easier, by 5 | ! allowing you to easily change the name of the file that gets read. 6 | 7 | &star_job 8 | 9 | read_extra_star_job_inlist1 = .true. 10 | extra_star_job_inlist1_name = 'inlist_example' 11 | 12 | / ! end of star_job namelist 13 | 14 | 15 | &eos 16 | 17 | read_extra_eos_inlist1 = .true. 18 | extra_eos_inlist1_name = 'inlist_example' 19 | 20 | / ! end of eos namelist 21 | 22 | 23 | &kap 24 | 25 | read_extra_kap_inlist1 = .true. 26 | extra_kap_inlist1_name = 'inlist_example' 27 | 28 | / ! end of kap namelist 29 | 30 | 31 | &controls 32 | 33 | read_extra_controls_inlist1 = .true. 34 | extra_controls_inlist1_name = 'inlist_example' 35 | 36 | / ! end of controls namelist 37 | 38 | 39 | &pgstar 40 | 41 | read_extra_pgstar_inlist1 = .true. 42 | extra_pgstar_inlist1_name = 'inlist_pgstar' 43 | 44 | / ! end of pgstar namelist 45 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/star_example/inlist_czb_mesh_function: -------------------------------------------------------------------------------- 1 | &czb_mesh_function 2 | 3 | czb_mesh_zone_type(1) = 'any' ! Possible values: burn_H, burn_He, burn_Z, nonburn, any 4 | czb_mesh_zone_loc(1) = 'core' ! Possible values: core, shell, any 5 | czb_mesh_bdy_loc(1) = 'any' ! Possible values: bottom, top, any 6 | czb_mesh_f(1) = 0.005 7 | czb_mesh_l(1) = 0.05 8 | 9 | / ! end of czb_mesh_function 10 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/star_example/inlist_example: -------------------------------------------------------------------------------- 1 | &star_job 2 | ! see star/defaults/star_job.defaults 3 | 4 | ! begin with a ZAMS 5 | create_pre_main_sequence_model = .false. 6 | 7 | ! save a model at the end of the run 8 | save_model_when_terminate = .false. 9 | save_model_filename = '15M_at_TAMS.mod' 10 | 11 | ! display on-screen plots 12 | pgstar_flag = .true. 13 | 14 | / ! end of star_job namelist 15 | 16 | 17 | &eos 18 | ! eos options 19 | ! see eos/defaults/eos.defaults 20 | 21 | / ! end of eos namelist 22 | 23 | 24 | &kap 25 | ! kap options 26 | ! see kap/defaults/kap.defaults 27 | use_Type2_opacities = .true. 28 | Zbase = 0.02 29 | 30 | / ! end of kap namelist 31 | 32 | 33 | &controls 34 | ! see star/defaults/controls.defaults 35 | 36 | ! starting specifications 37 | initial_mass = 2.5 ! in Msun units 38 | initial_z = 0.02 39 | 40 | ! when to stop 41 | 42 | ! stop when the center mass fraction of h1 drops below this limit 43 | xa_central_lower_limit_species(1) = 'h1' 44 | xa_central_lower_limit(1) = 1d-3 45 | 46 | ! wind 47 | 48 | ! atmosphere 49 | 50 | ! rotation 51 | 52 | ! element diffusion 53 | 54 | ! mlt 55 | 56 | ! mixing 57 | 58 | overshoot_scheme(1) = 'exponential' 59 | overshoot_zone_type(1) = 'any' 60 | overshoot_zone_loc(1) = 'core' 61 | overshoot_bdy_loc(1) = 'top' 62 | overshoot_f(1) = 0.005 63 | overshoot_f0(1) = 0.025 64 | 65 | ! use mesh function to resolve overshoot region 66 | use_other_mesh_functions = .true. 67 | 68 | ! timesteps 69 | 70 | ! mesh 71 | 72 | ! solver 73 | 74 | ! output 75 | 76 | / ! end of controls namelist 77 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/star_example/inlist_pgstar: -------------------------------------------------------------------------------- 1 | &pgstar 2 | ! see star/defaults/pgstar.defaults 3 | 4 | ! show temperature/density profile 5 | ! this plots the internal structure at single timestep 6 | TRho_Profile_win_flag = .true. 7 | 8 | ! add legend explaining colors 9 | show_TRho_Profile_legend = .true. 10 | 11 | ! display numerical info about the star 12 | show_TRho_Profile_text_info = .true. 13 | 14 | ! set window size (aspect_ratio = height/width) 15 | TRho_Profile_win_width = 8 16 | TRho_Profile_win_aspect_ratio = 0.75 17 | 18 | 19 | Profile_Panels1_win_flag = .true. 20 | 21 | Profile_Panels1_win_width = 6 22 | Profile_Panels1_win_aspect_ratio = 0.75 23 | 24 | Profile_Panels1_xaxis_name = 'logP' 25 | Profile_Panels1_xaxis_reversed = .false. 26 | Profile_Panels1_xmin = 16.5 27 | Profile_Panels1_xmax = -101d0 28 | Profile_Panels1_xmargin = 0d0 29 | Profile_Panels1_show_mix_regions_on_xaxis = .false. 30 | 31 | Profile_Panels1_show_grid = .true. 32 | 33 | Profile_Panels1_num_panels = 2 34 | Profile_Panels1_yaxis_name(1) = 'log_D_mix' 35 | Profile_Panels1_ymin(1) = 0 36 | Profile_Panels1_other_yaxis_name(1) = 'log_D_ovr' 37 | Profile_Panels1_other_ymin(1) = 0 38 | Profile_Panels1_yaxis_name(2) = 'zone' 39 | Profile_Panels1_other_yaxis_name(2) = 'mixing_type' 40 | 41 | 42 | / ! end of pgstar namelist 43 | -------------------------------------------------------------------------------- /hooks/czb_mesh_function/star_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010-2019 Bill Paxton & The MESA Team 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | 30 | implicit none 31 | 32 | include 'czb_mesh_function/czb_mesh_function_def.inc' 33 | 34 | contains 35 | 36 | include 'czb_mesh_function/czb_mesh_function.inc' 37 | 38 | subroutine how_many_other_mesh_fcns(id, n) 39 | integer, intent(in) :: id 40 | integer, intent(out) :: n 41 | n = 1 42 | end subroutine how_many_other_mesh_fcns 43 | 44 | 45 | subroutine other_mesh_fcn_data( & 46 | id, nfcns, names, gval_is_xa_function, vals1, ierr) 47 | integer, intent(in) :: id 48 | integer, intent(in) :: nfcns 49 | character (len=*) :: names(:) 50 | logical, intent(out) :: gval_is_xa_function(:) ! (nfcns) 51 | real(dp), pointer :: vals1(:) ! =(nz, nfcns) 52 | integer, intent(out) :: ierr 53 | integer :: nz, k 54 | real(dp), pointer :: vals(:,:) 55 | type (star_info), pointer :: s 56 | ierr = 0 57 | call star_ptr(id, s, ierr) 58 | if (ierr /= 0) return 59 | gval_is_xa_function(1:nfcns) = .false. 60 | nz = s% nz 61 | vals(1:nz,1:nfcns) => vals1(1:nz*nfcns) 62 | names(1) = 'czb_mesh_function' 63 | call czb_mesh_fcn(s, vals(1:nz,1), ierr) 64 | end subroutine other_mesh_fcn_data 65 | 66 | 67 | subroutine extras_controls(id, ierr) 68 | integer, intent(in) :: id 69 | integer, intent(out) :: ierr 70 | type (star_info), pointer :: s 71 | ierr = 0 72 | call star_ptr(id, s, ierr) 73 | if (ierr /= 0) return 74 | 75 | include 'czb_mesh_function/czb_mesh_function_extras_controls.inc' 76 | 77 | s% how_many_other_mesh_fcns => how_many_other_mesh_fcns 78 | s% other_mesh_fcn_data => other_mesh_fcn_data 79 | 80 | ! the extras functions in this file will not be called 81 | ! unless you set their function pointers as done below. 82 | ! otherwise we use a null_ version which does nothing (except warn). 83 | 84 | s% extras_startup => extras_startup 85 | s% extras_start_step => extras_start_step 86 | s% extras_check_model => extras_check_model 87 | s% extras_finish_step => extras_finish_step 88 | s% extras_after_evolve => extras_after_evolve 89 | s% how_many_extra_history_columns => how_many_extra_history_columns 90 | s% data_for_extra_history_columns => data_for_extra_history_columns 91 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 92 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 93 | 94 | s% how_many_extra_history_header_items => how_many_extra_history_header_items 95 | s% data_for_extra_history_header_items => data_for_extra_history_header_items 96 | s% how_many_extra_profile_header_items => how_many_extra_profile_header_items 97 | s% data_for_extra_profile_header_items => data_for_extra_profile_header_items 98 | 99 | end subroutine extras_controls 100 | 101 | 102 | subroutine extras_startup(id, restart, ierr) 103 | integer, intent(in) :: id 104 | logical, intent(in) :: restart 105 | integer, intent(out) :: ierr 106 | type (star_info), pointer :: s 107 | ierr = 0 108 | call star_ptr(id, s, ierr) 109 | if (ierr /= 0) return 110 | end subroutine extras_startup 111 | 112 | 113 | integer function extras_start_step(id) 114 | integer, intent(in) :: id 115 | integer :: ierr 116 | type (star_info), pointer :: s 117 | ierr = 0 118 | call star_ptr(id, s, ierr) 119 | if (ierr /= 0) return 120 | extras_start_step = 0 121 | end function extras_start_step 122 | 123 | 124 | ! returns either keep_going, retry, backup, or terminate. 125 | integer function extras_check_model(id) 126 | integer, intent(in) :: id 127 | integer :: ierr 128 | type (star_info), pointer :: s 129 | ierr = 0 130 | call star_ptr(id, s, ierr) 131 | if (ierr /= 0) return 132 | extras_check_model = keep_going 133 | 134 | ! by default, indicate where (in the code) MESA terminated 135 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 136 | end function extras_check_model 137 | 138 | 139 | integer function how_many_extra_history_columns(id) 140 | integer, intent(in) :: id 141 | integer :: ierr 142 | type (star_info), pointer :: s 143 | ierr = 0 144 | call star_ptr(id, s, ierr) 145 | if (ierr /= 0) return 146 | how_many_extra_history_columns = 0 147 | end function how_many_extra_history_columns 148 | 149 | 150 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 151 | integer, intent(in) :: id, n 152 | character (len=maxlen_history_column_name) :: names(n) 153 | real(dp) :: vals(n) 154 | integer, intent(out) :: ierr 155 | type (star_info), pointer :: s 156 | ierr = 0 157 | call star_ptr(id, s, ierr) 158 | if (ierr /= 0) return 159 | 160 | ! note: do NOT add the extras names to history_columns.list 161 | ! the history_columns.list is only for the built-in history column options. 162 | ! it must not include the new column names you are adding here. 163 | 164 | 165 | end subroutine data_for_extra_history_columns 166 | 167 | 168 | integer function how_many_extra_profile_columns(id) 169 | integer, intent(in) :: id 170 | integer :: ierr 171 | type (star_info), pointer :: s 172 | ierr = 0 173 | call star_ptr(id, s, ierr) 174 | if (ierr /= 0) return 175 | how_many_extra_profile_columns = 0 176 | end function how_many_extra_profile_columns 177 | 178 | 179 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 180 | integer, intent(in) :: id, n, nz 181 | character (len=maxlen_profile_column_name) :: names(n) 182 | real(dp) :: vals(nz,n) 183 | integer, intent(out) :: ierr 184 | type (star_info), pointer :: s 185 | integer :: k 186 | ierr = 0 187 | call star_ptr(id, s, ierr) 188 | if (ierr /= 0) return 189 | 190 | ! note: do NOT add the extra names to profile_columns.list 191 | ! the profile_columns.list is only for the built-in profile column options. 192 | ! it must not include the new column names you are adding here. 193 | 194 | ! here is an example for adding a profile column 195 | !if (n /= 1) stop 'data_for_extra_profile_columns' 196 | !names(1) = 'beta' 197 | !do k = 1, nz 198 | ! vals(k,1) = s% Pgas(k)/s% P(k) 199 | !end do 200 | 201 | end subroutine data_for_extra_profile_columns 202 | 203 | 204 | integer function how_many_extra_history_header_items(id) 205 | integer, intent(in) :: id 206 | integer :: ierr 207 | type (star_info), pointer :: s 208 | ierr = 0 209 | call star_ptr(id, s, ierr) 210 | if (ierr /= 0) return 211 | how_many_extra_history_header_items = 0 212 | end function how_many_extra_history_header_items 213 | 214 | 215 | subroutine data_for_extra_history_header_items(id, n, names, vals, ierr) 216 | integer, intent(in) :: id, n 217 | character (len=maxlen_history_column_name) :: names(n) 218 | real(dp) :: vals(n) 219 | type(star_info), pointer :: s 220 | integer, intent(out) :: ierr 221 | ierr = 0 222 | call star_ptr(id,s,ierr) 223 | if(ierr/=0) return 224 | 225 | ! here is an example for adding an extra history header item 226 | ! also set how_many_extra_history_header_items 227 | ! names(1) = 'mixing_length_alpha' 228 | ! vals(1) = s% mixing_length_alpha 229 | 230 | end subroutine data_for_extra_history_header_items 231 | 232 | 233 | integer function how_many_extra_profile_header_items(id) 234 | integer, intent(in) :: id 235 | integer :: ierr 236 | type (star_info), pointer :: s 237 | ierr = 0 238 | call star_ptr(id, s, ierr) 239 | if (ierr /= 0) return 240 | how_many_extra_profile_header_items = 0 241 | end function how_many_extra_profile_header_items 242 | 243 | 244 | subroutine data_for_extra_profile_header_items(id, n, names, vals, ierr) 245 | integer, intent(in) :: id, n 246 | character (len=maxlen_profile_column_name) :: names(n) 247 | real(dp) :: vals(n) 248 | type(star_info), pointer :: s 249 | integer, intent(out) :: ierr 250 | ierr = 0 251 | call star_ptr(id,s,ierr) 252 | if(ierr/=0) return 253 | 254 | ! here is an example for adding an extra profile header item 255 | ! also set how_many_extra_profile_header_items 256 | ! names(1) = 'mixing_length_alpha' 257 | ! vals(1) = s% mixing_length_alpha 258 | 259 | end subroutine data_for_extra_profile_header_items 260 | 261 | 262 | ! returns either keep_going or terminate. 263 | ! note: cannot request retry or backup; extras_check_model can do that. 264 | integer function extras_finish_step(id) 265 | integer, intent(in) :: id 266 | integer :: ierr 267 | type (star_info), pointer :: s 268 | ierr = 0 269 | call star_ptr(id, s, ierr) 270 | if (ierr /= 0) return 271 | extras_finish_step = keep_going 272 | 273 | ! to save a profile, 274 | ! s% need_to_save_profiles_now = .true. 275 | ! to update the star log, 276 | ! s% need_to_update_history_now = .true. 277 | 278 | ! see extras_check_model for information about custom termination codes 279 | ! by default, indicate where (in the code) MESA terminated 280 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 281 | end function extras_finish_step 282 | 283 | 284 | subroutine extras_after_evolve(id, ierr) 285 | integer, intent(in) :: id 286 | integer, intent(out) :: ierr 287 | type (star_info), pointer :: s 288 | ierr = 0 289 | call star_ptr(id, s, ierr) 290 | if (ierr /= 0) return 291 | end subroutine extras_after_evolve 292 | 293 | 294 | end module run_star_extras 295 | 296 | -------------------------------------------------------------------------------- /hooks/dbconvpen/.gitignore: -------------------------------------------------------------------------------- 1 | baseline_test/* 2 | *.org 3 | *.o 4 | *.a 5 | *.data 6 | *.dat 7 | *.mod 8 | *.smod 9 | *.index 10 | *LOGS/* 11 | *photos/* 12 | scripts/* 13 | star 14 | rn 15 | re 16 | mk 17 | clean 18 | make/* 19 | src/run.f90 -------------------------------------------------------------------------------- /hooks/dbconvpen/README.md: -------------------------------------------------------------------------------- 1 | # Dissipation Balanced Convective Penetration 2 | 3 | ## Overview 4 | 5 | The functions in `dbconvpen.inc` implement the dissipation balanced 6 | convective penetration scheme for convective boundary mixing described 7 | in [Johnston et al. 2024](https://ui.adsabs.harvard.edu/abs/2024ApJ...964..170J/abstract) based on the 3D simulations of [Anders et al. 8 | 2022](https://ui.adsabs.harvard.edu/abs/2022ApJ...926..169A/abstract). 9 | 10 | This is appropriate for convective boundary mixing due to convective 11 | penetration in stars with convective cores with masses <40Mo. 12 | 13 | ## Usage 14 | 15 | Make sure `$MESA_CONTRIB_DIR` is set to the appropriate location and 16 | your `run_star_extras.f90` includes this file, e.g.: 17 | 18 | ``` Fortran90 19 | contains 20 | include 'dbconvpen/dbconvpen.inc' 21 | ``` 22 | Then make sure to set the following in your inlist: 23 | 24 | ``` Fortran90 25 | overshoot_scheme(1) = 'other' 26 | overshoot_zone_type(1) = 'any' 27 | overshoot_zone_loc(1) = 'core' 28 | overshoot_bdy_loc(1) = 'top' 29 | ``` 30 | You can/should add some exponential overshooting on top of this to 31 | include processes other than convective penetration. 32 | 33 | N.B.: while the original implementation of [Johnston et al. 34 | 2024](https://ui.adsabs.harvard.edu/abs/2024ApJ...964..170J/abstract) 35 | (available on [zenodo](https://doi.org/10.5281/zenodo.10286503)) used 36 | global variables in the `run_star_extras.f90` to make some values 37 | accessible to multiple routines, these have been replaced using 38 | `s%xtra(1:6)`, `s%lxtra(1)`, and `s%ixtra(1:2)` in this 39 | implementation. Therefore if using this implementation, one should not 40 | use these extra variables elsewhere in your `run_star_extras.f90`. 41 | 42 | 43 | ## Maintainer 44 | 45 | This contribution is maintained by Mathieu Renzo (`mathren`). 46 | 47 | -------------------------------------------------------------------------------- /hooks/dbconvpen/dbconvpen.inc: -------------------------------------------------------------------------------- 1 | ! Renamed variable w.r.t. original run_star_extras.f90 2 | ! lxtra(1) is doing_DBP 3 | ! xtra(1) is m_core 4 | ! xtra(2) is mass_PZ 5 | ! xtra(3) is delta_r_PZ 6 | ! xtra(4) is alpha_PZ 7 | ! xtra(5) is r_core 8 | ! xtra(6) is rho_core_top 9 | ! ixtra(1) is k_PZ_top 10 | ! ixtra(2) is k_PZ_bottom 11 | 12 | 13 | subroutine other_adjust_mlt_gradT_fraction_Peclet(id, ierr) 14 | integer, intent(in) :: id 15 | integer, intent(out) :: ierr 16 | type(star_info), pointer :: s 17 | real(dp) :: fraction, Peclet_number, diffusivity ! f is fraction to compose grad_T = f*grad_ad + (1-f)*grad_rad 18 | integer :: k 19 | logical, parameter :: DEBUG = .false. 20 | 21 | ierr = 0 22 | call star_ptr(id, s, ierr) 23 | if (ierr /= 0) return 24 | 25 | if (s%D_mix(1) /= s%D_mix(1)) return ! To ignore iterations where Dmix and gradT are NaNs 26 | 27 | if (s%num_conv_boundaries <= 1) then ! Is zero at initialisation of the run 28 | if (DEBUG) then 29 | write(*,*) 'runstarex_gradT: skip since there are no convective boundaries' 30 | end if 31 | return 32 | endif 33 | 34 | do k= s%nz, 1, -1 35 | if (s%D_mix(k) <= s% min_D_mix) exit 36 | 37 | diffusivity = 16.0_dp * boltz_sigma * pow3(s% T(k)) / ( 3.0_dp * s% opacity(k) * pow2(s% rho(k)) * s% cp(k) ) 38 | Peclet_number = s% conv_vel(k) * s% scale_height(k) * s% mixing_length_alpha / diffusivity 39 | 40 | if (Peclet_number >= 100.0_dp) then 41 | fraction = 1.0_dp 42 | else if (Peclet_number <= 0.01_dp) then 43 | fraction = 0.0_dp 44 | else 45 | fraction = (safe_log10(Peclet_number)+2.0_dp)/4.0_dp 46 | end if 47 | 48 | s% adjust_mlt_gradT_fraction(k) = fraction 49 | end do 50 | 51 | end subroutine other_adjust_mlt_gradT_fraction_Peclet 52 | 53 | 54 | subroutine extended_convective_penetration(id, i, j, k_a, k_b, D, vc, ierr) 55 | integer, intent(in) :: id, i, j 56 | integer, intent(out) :: k_a, k_b 57 | real(dp), intent(out), dimension(:) :: D, vc 58 | integer, intent(out) :: ierr 59 | type (star_info), pointer :: s 60 | 61 | logical, parameter :: DEBUG = .false. 62 | real(dp) :: f, f2, f0 63 | real(dp) :: D0, Delta0 64 | real(dp) :: w 65 | real(dp) :: factor 66 | real(dp) :: r_cb, Hp_cb 67 | real(dp) :: r_ob, D_ob, vc_ob 68 | logical :: outward 69 | integer :: dk, k, k_ob 70 | real(dp) :: r, dr, r_step 71 | 72 | ! Evaluate the overshoot diffusion coefficient D(k_a:k_b) and 73 | ! mixing velocity vc(k_a:k_b) at the i'th convective boundary, 74 | ! using the j'th set of overshoot parameters. The overshoot 75 | ! follows the extended convective penetration scheme description by Mathias 76 | ! Michielsen, "Probing the shape of the mixing profile and of the thermal 77 | ! structure at the convective core boundary through asteroseismology", 78 | ! A&A, 628, 76 (2019) 79 | 80 | ierr = 0 81 | call star_ptr(id, s, ierr) 82 | if (ierr /= 0) return 83 | 84 | if ((i /= 1) .or. (s%mixing_type(s%nz) /= convective_mixing)) then 85 | write(*,'(A,i2,A,i2)') 'ERROR: dissipation_balanced_penetration can only be used for core convection, & 86 | &so the first convective boundary. The routine got called for convective boundary number ',i, & 87 | &', and the mixing type in the core was', s%mixing_type(s%nz) 88 | ierr = -1 89 | return 90 | end if 91 | 92 | call dissipation_balanced_penetration(s, id) !, s%xtra(1), s% xtra(2), s% xtra(3), s% xtra(4), s% xtra(5), s% xtra(6)) 93 | ! s% xtra(4) is distance from core boundary outward, so add f0 to it to make PZ zone reach that region 94 | s% xtra(4) = s% xtra(4) + s%overshoot_f0(j) 95 | ! Extract parameters 96 | f = s% xtra(4) ! extend of step function (a_ov) 97 | f0 = s%overshoot_f0(j) 98 | f2 = s%overshoot_f(j) ! exponential decay (f_ov) 99 | 100 | D0 = s%overshoot_D0(j) 101 | Delta0 = s%overshoot_Delta0(j) 102 | 103 | if (f < 0.0_dp .or. f0 <= 0.0_dp .or. f2 < 0.0_dp) then 104 | write(*,*) 'ERROR: for extended convective penetration, must set f0 > 0, and f and f2 >= 0' 105 | write(*,*) 'see description of overshooting in star/defaults/control.defaults' 106 | ierr = -1 107 | return 108 | end if 109 | 110 | ! Evaluate convective boundary (_cb) parameters 111 | call star_eval_conv_bdy_r(s, i, r_cb, ierr) 112 | if (ierr /= 0) return 113 | 114 | call star_eval_conv_bdy_Hp(s, i, Hp_cb, ierr) 115 | if (ierr /= 0) return 116 | 117 | ! Evaluate overshoot boundary (_ob) parameters 118 | call star_eval_over_bdy_params(s, i, f0, k_ob, r_ob, D_ob, vc_ob, ierr) 119 | if (ierr /= 0) return 120 | 121 | ! Loop over cell faces, adding overshoot until D <= overshoot_D_min 122 | outward = s%top_conv_bdy(i) 123 | 124 | if (outward) then 125 | k_a = k_ob 126 | k_b = 1 127 | dk = -1 128 | else 129 | k_a = k_ob+1 130 | k_b = s%nz 131 | dk = 1 132 | endif 133 | 134 | if (f > 0.0_dp) then 135 | r_step = f*Hp_cb 136 | else 137 | r_step = 0.0_dp 138 | endif 139 | 140 | face_loop : do k = k_a, k_b, dk 141 | ! Evaluate the extended convective penetration factor 142 | r = s%r(k) 143 | if (outward) then 144 | dr = r - r_ob 145 | else 146 | dr = r_ob - r 147 | endif 148 | 149 | if (dr < r_step .AND. f > 0.0_dp) then ! step factor 150 | factor = 1.0_dp 151 | else 152 | if ( f2 > 0.0_dp) then ! exponential factor 153 | factor = exp(-2.0_dp*(dr-r_step)/(f2*Hp_cb)) 154 | else 155 | factor = 0.0_dp 156 | endif 157 | endif 158 | 159 | ! Store the diffusion coefficient and velocity 160 | D(k) = (D0 + Delta0*D_ob)*factor 161 | vc(k) = (D0/D_ob + Delta0)*vc_ob*factor 162 | 163 | ! Check for early overshoot completion 164 | if (D(k) < s%overshoot_D_min) then 165 | k_b = k 166 | exit face_loop 167 | endif 168 | 169 | end do face_loop 170 | 171 | if (DEBUG) then 172 | write(*,*) 'step exponential overshoot:' 173 | write(*,*) ' k_a, k_b =', k_a, k_b 174 | write(*,*) ' r_a, r_b =', s%r(k_a), s%r(k_b) 175 | write(*,*) ' r_ob, r_cb =', r_ob, r_cb 176 | write(*,*) ' Hp_cb =', Hp_cb 177 | end if 178 | 179 | end subroutine extended_convective_penetration 180 | 181 | 182 | 183 | subroutine dissipation_balanced_penetration(s, id) 184 | use eos_def 185 | use star_lib 186 | use kap_def 187 | type (star_info), pointer :: s 188 | integer, intent(in) :: id 189 | real(dp), parameter :: f = 0.86d0 190 | real(dp), parameter :: xi = 0.6d0 191 | integer :: k, j, ierr 192 | real(dp) :: Lint, V_CZ, Favg, RHS, dr, h, dLint 193 | real(dp) :: r_cb 194 | 195 | s% lxtra(1) = .true. 196 | V_CZ = 0d0 197 | Lint = 0d0 198 | 199 | call star_eval_conv_bdy_k(s, 1, k, ierr) 200 | call star_eval_conv_bdy_r(s, 1, r_cb, ierr) 201 | s% ixtra(2) = k 202 | s% xtra(5) = r_cb 203 | s% xtra(1) = s%m(k) 204 | s% xtra(6) = s%rho(k) 205 | h = s%scale_height(k) 206 | 207 | ! prescription based on Jermyn A. et al (2022) https://arxiv.org/pdf/2203.09525.pdf 208 | ! Equation A1 is used here. 209 | ! RHS refers to right-hand side of equation A1, and Lint the integrated 210 | ! luminosity on either left or right side of that equation 211 | 212 | ! Integrate over cells that are fully in CZ 213 | ! r and L_conv are face values, assume they change linear within cell 214 | do j=s%nz,k+1,-1 215 | if (j .eq. s%nz) then 216 | dr = s%r(j) 217 | Lint = Lint + s%L_conv(j)*0.5 * dr 218 | else 219 | dr = s%r(j) - s%r(j+1) 220 | Lint = Lint + (s%L_conv(j+1) + s%L_conv(j))*0.5 * dr 221 | endif 222 | end do 223 | 224 | ! Take cell that is partially convective 225 | ! convective part of cell k 226 | ! L_conv goes to 0 at edge of conv zone 227 | dr = r_cb - s%r(k+1) 228 | Lint = Lint + s%L_conv(k+1)*0.5 * dr 229 | 230 | ! Calculate target RHS 231 | V_CZ = 4d0/3d0 * pi * r_cb*r_cb*r_cb 232 | Favg = Lint / V_CZ 233 | RHS = (1d0 - f) * Lint 234 | Lint = 0d0 235 | 236 | ! Integrate over RZ until we find the edge of the PZ 237 | ! remainder of cell k (non-convective part) 238 | ! Do integration explicitly, f*xi*4*pi*r^2 is moved outside of integral 239 | dr = s%r(k) - r_cb 240 | dLint = xi * f * 4d0 * pi * (pow3(s%r(k))-pow3(r_cb))/3 * Favg + (s%L(k)*0.5 * (s%grada_face(k) / s%gradr(k) - 1d0)) * dr 241 | Lint = dLint 242 | 243 | ! If remainder of cell k would already satisfy Lint > RHS 244 | if (Lint > RHS) then 245 | dr = dr*(Lint - RHS)/dLint 246 | s% xtra(2) = s%rho(k) * 4d0/3d0 * pi * (pow3(r_cb+dr) - pow3(r_cb)) !s%m(k) - s%xtra(1) !only used for history output 247 | s% xtra(3) = dr 248 | s% xtra(4) = s% xtra(3) / h 249 | s% ixtra(1) = k 250 | return 251 | end if 252 | ! Else calculate dL_int for each cell, until the total integrated L > RHS 253 | do j=k-1,1,-1 254 | dr = s%r(j) - s%r(j+1) 255 | dLint = xi * f * 4d0 * pi * (pow3(s%r(j))-pow3(s%r(j+1)))/3 * Favg & 256 | + ( (s%L(j+1)*(s%grada_face(j+1) / s%gradr(j+1) - 1d0) +(s%L(j)*(s%grada_face(j) / s%gradr(j) - 1d0)) )*0.5 * dr) 257 | 258 | if (Lint + dLint > RHS) then 259 | dr = dr*(RHS - Lint)/dLint 260 | s% xtra(2) = s%m(j) - s%xtra(1) !only used for history output 261 | s% xtra(3) = s%r(j+1)+dr - r_cb 262 | s% xtra(4) = s% xtra(3) / h 263 | s% ixtra(1) = j 264 | return 265 | end if 266 | Lint = Lint + dLint 267 | end do 268 | 269 | end subroutine dissipation_balanced_penetration 270 | 271 | subroutine mesh_delta_coeff_core_boundary(id, ierr) 272 | integer, intent(in) :: id 273 | ! real(dp), intent(in), dimension(:) :: eps_h, eps_he, eps_z 274 | integer, intent(out) :: ierr 275 | type (star_info), pointer :: s 276 | logical, parameter :: dbg = .false. 277 | integer :: k, k_max_N2comp 278 | real(dp) :: Hp, r_lower, r_upper_ov, r_upper_BV 279 | real(dp) :: xtra_dist_below, xtra_dist_above_ov, xtra_dist_above_bv, xtra_coeff_mesh 280 | ierr = 0 281 | call star_ptr(id, s, ierr) 282 | if (ierr /= 0) return 283 | 284 | ! set defaults 285 | xtra_dist_below = s% x_ctrl(1) 286 | xtra_dist_above_ov = s% x_ctrl(2) 287 | xtra_dist_above_bv = s% x_ctrl(3) 288 | xtra_coeff_mesh = s% x_ctrl(4) 289 | 290 | if (xtra_coeff_mesh == 1d0 .or. xtra_coeff_mesh < 0) return 291 | if (s% mixing_type(s% nz) /= convective_mixing) return ! only enable for convective cores 292 | 293 | r_upper_ov=-1 294 | r_upper_BV=-1 295 | k_max_N2comp = maxloc(s% brunt_n2_composition_term(:), 1) 296 | ! Find boundary of convective core, and go inwards by the specified distance (in Hp) 297 | do k = s% nz, 1, -1 298 | if (s% mixing_type(k) == convective_mixing) then 299 | continue 300 | else 301 | Hp = s% scale_height(k) !s% P(k)/(s% rho(k)*s% grav(k)) 302 | r_lower = max (s% r(s%nz), s% r(k) - xtra_dist_below*Hp) 303 | exit 304 | endif 305 | end do 306 | 307 | do k = s% nz, 1, -1 308 | ! Start increasing the mesh once closer than the given distance (in Hp) to the core boundary 309 | if (s%r(k) > r_lower) then 310 | if (xtra_coeff_mesh < s% mesh_delta_coeff_factor(k)) then 311 | s% mesh_delta_coeff_factor(k) = xtra_coeff_mesh 312 | end if 313 | else 314 | cycle 315 | endif 316 | 317 | ! Go up to the given distance past the overshoot boundary 318 | if (r_upper_ov<0 .and. s% mixing_type(k) /= overshoot_mixing .and. s% mixing_type(k) /= convective_mixing) then 319 | if (xtra_dist_above_ov > 0) then 320 | Hp = s% scale_height(k) !s% P(k)/(s% rho(k)*s% grav(k)) 321 | r_upper_ov = min(s% r(1), s% r(k) + xtra_dist_above_ov*Hp) 322 | else 323 | r_upper_ov = 0 324 | end if 325 | end if 326 | 327 | ! Go up to the given distance past the order in magnitude decrease in BV composition term, outwards of its maximum 328 | if (r_upper_BV<0 .and. k < k_max_N2comp .and. (s% brunt_n2_composition_term(k)*10 < maxval(s% brunt_n2_composition_term(:))) ) then 329 | if (xtra_dist_above_bv > 0) then 330 | Hp = s% scale_height(k) !s% P(k)/(s% rho(k)*s% grav(k)) 331 | r_upper_BV = min(s% r(1), s% r(k) + xtra_dist_above_bv*Hp) 332 | else 333 | r_upper_BV = 0 334 | end if 335 | end if 336 | 337 | ! Stop increasing mesh when further than the specified distance from both the overshoot boundary and BV composition peak 338 | if (s% r(k) > r_upper_ov .and. s% r(k) > r_upper_BV .and. r_upper_ov >=0 .and. r_upper_BV >=0) exit 339 | end do 340 | 341 | end subroutine mesh_delta_coeff_core_boundary 342 | -------------------------------------------------------------------------------- /hooks/dbconvpen/star_example/inlist: -------------------------------------------------------------------------------- 1 | ! This is the first inlist file that MESA reads when it starts. 2 | 3 | ! This file tells MESA to go look elsewhere for its configuration 4 | ! info. This makes changing between different inlists easier, by 5 | ! allowing you to easily change the name of the file that gets read. 6 | 7 | &star_job 8 | 9 | read_extra_star_job_inlist(1) = .true. 10 | extra_star_job_inlist_name(1) = 'inlist_dbcp' 11 | 12 | / ! end of star_job namelist 13 | 14 | 15 | &eos 16 | 17 | read_extra_eos_inlist(1) = .true. 18 | extra_eos_inlist_name(1) = 'inlist_dbcp' 19 | 20 | / ! end of eos namelist 21 | 22 | 23 | &kap 24 | 25 | read_extra_kap_inlist(1) = .true. 26 | extra_kap_inlist_name(1) = 'inlist_dbcp' 27 | 28 | / ! end of kap namelist 29 | 30 | 31 | &controls 32 | 33 | read_extra_controls_inlist(1) = .true. 34 | extra_controls_inlist_name(1) = 'inlist_dbcp' 35 | 36 | / ! end of controls namelist 37 | 38 | 39 | &pgstar 40 | 41 | / ! end of pgstar namelist 42 | -------------------------------------------------------------------------------- /hooks/dbconvpen/star_example/inlist_dbcp: -------------------------------------------------------------------------------- 1 | &star_job 2 | 3 | pgstar_flag = .true. 4 | 5 | initial_zfracs = 8 6 | 7 | / ! end of star_job namelist 8 | 9 | 10 | &eos 11 | / ! end of eos namelist 12 | 13 | 14 | &kap 15 | use_Type2_opacities = .true. 16 | Zbase = 0.02 17 | kap_file_prefix = 'OP_a09_nans_removed_by_hand' 18 | 19 | ! ------------------------------------------------------ 20 | ! Recommended settings for publication quality 21 | ! commented out to speed-up tests 22 | 23 | ! cubic_interpolation_in_X = .true. 24 | ! cubic_interpolation_in_Z = .true. 25 | ! ------------------------------------------------------ 26 | 27 | / ! end of kap namelist 28 | 29 | 30 | &controls 31 | 32 | ! when to stop 33 | max_model_number = 200 34 | 35 | initial_mass = 8.0 ! in Msun units 36 | initial_z = 0.02 37 | !initial_y = 0.276 38 | 39 | ! Mixing 40 | min_D_mix = 100 41 | set_min_D_mix = .true. 42 | 43 | use_Ledoux_criterion = .false. 44 | MLT_option = 'Cox' 45 | mixing_length_alpha = 1.8d0 46 | 47 | do_conv_premix = .true. 48 | predictive_mix(1) = .false. 49 | predictive_zone_type(1) = 'any' 50 | predictive_zone_loc(1) = 'core' 51 | predictive_bdy_loc(1) = 'top' 52 | 53 | ! Overshooting 54 | overshoot_scheme(1) = 'other' ! use dissipation balanced convective penetration 55 | overshoot_zone_type(1) = 'any' 56 | overshoot_zone_loc(1) = 'core' 57 | overshoot_bdy_loc(1) = 'top' 58 | 59 | ! add some exponential overshooting on top 60 | overshoot_f0(1) = 0.005 61 | overshoot_f(1) = 0.01 62 | ! overshoot_D0(1) = 0.005 63 | 64 | 65 | ! Solver 66 | 67 | energy_eqn_option = 'dedt' 68 | 69 | ! ------------------------------------------------------ 70 | ! Recommended settings for publication quality 71 | ! commented out to speed-up tests 72 | 73 | ! ! Atmosphere 74 | 75 | ! atm_option = 'T_tau' 76 | ! atm_T_tau_relation = 'Krishna_Swamy' 77 | ! atm_T_tau_opacity = 'iterated' 78 | 79 | ! ! Wind 80 | 81 | ! hot_wind_scheme = 'Dutch' 82 | ! cool_wind_RGB_scheme = 'Dutch' 83 | ! cool_wind_AGB_scheme = 'Dutch' 84 | ! Dutch_scaling_factor = 0.8d0 85 | 86 | ! ! Solver 87 | ! use_gold_tolerances = .false. 88 | 89 | ! Resolution 90 | 91 | ! max_allowed_nz = 100000 92 | ! mesh_delta_coeff = 0.4 93 | ! time_delta_coeff = 0.5 94 | 95 | ! varcontrol_target = 1d-4 96 | ! min_allowed_varcontrol_target = 1d-5 97 | 98 | ! num_cells_for_smooth_gradL_composition_term = 10 99 | ! threshold_for_smooth_gradL_composition_term = 0.02 100 | 101 | ! num_cells_for_smooth_brunt_B = 10 102 | ! threshold_for_smooth_brunt_B = 0.1 103 | 104 | ! ! extra mesh controls 105 | ! x_ctrl(1) = 0.1 ! xtra_dist_below 106 | ! x_ctrl(2) = 0.1 ! xtra_dist_above_ov 107 | ! x_ctrl(3) = 0.1 ! xtra_dist_above_bv 108 | ! x_ctrl(4) = 0.15 ! xtra_coeff_mesh 109 | ! ------------------------------------------------------ 110 | 111 | / ! end of controls namelist 112 | 113 | 114 | &pgstar 115 | / ! end of pgstar namelist 116 | -------------------------------------------------------------------------------- /hooks/dbconvpen/star_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010-2019 Bill Paxton & The MESA Team 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | use chem_def 30 | 31 | implicit none 32 | 33 | contains 34 | 35 | include 'dbconvpen/dbconvpen.inc' 36 | 37 | subroutine extras_controls(id, ierr) 38 | integer, intent(in) :: id 39 | integer, intent(out) :: ierr 40 | type (star_info), pointer :: s 41 | 42 | ierr = 0 43 | call star_ptr(id, s, ierr) 44 | if (ierr /= 0) return 45 | 46 | s% extras_startup => extras_startup 47 | s% extras_start_step => extras_start_step 48 | s% extras_check_model => extras_check_model 49 | s% extras_finish_step => extras_finish_step 50 | s% extras_after_evolve => extras_after_evolve 51 | s% how_many_extra_history_columns => how_many_extra_history_columns 52 | s% data_for_extra_history_columns => data_for_extra_history_columns 53 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 54 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 55 | 56 | s% how_many_extra_history_header_items => how_many_extra_history_header_items 57 | s% data_for_extra_history_header_items => data_for_extra_history_header_items 58 | s% how_many_extra_profile_header_items => how_many_extra_profile_header_items 59 | s% data_for_extra_profile_header_items => data_for_extra_profile_header_items 60 | 61 | ! s% other_adjust_mlt_gradT_fraction => other_adjust_mlt_gradT_fraction_Peclet 62 | s% lxtra(1) = .true. ! turns it on! 63 | s% other_overshooting_scheme => extended_convective_penetration 64 | end subroutine extras_controls 65 | 66 | 67 | subroutine extras_startup(id, restart, ierr) 68 | integer, intent(in) :: id 69 | logical, intent(in) :: restart 70 | integer, intent(out) :: ierr 71 | type (star_info), pointer :: s 72 | ierr = 0 73 | call star_ptr(id, s, ierr) 74 | if (ierr /= 0) return 75 | end subroutine extras_startup 76 | 77 | 78 | integer function extras_start_step(id) 79 | integer, intent(in) :: id 80 | integer :: ierr 81 | type (star_info), pointer :: s 82 | ierr = 0 83 | call star_ptr(id, s, ierr) 84 | if (ierr /= 0) return 85 | extras_start_step = 0 86 | end function extras_start_step 87 | 88 | 89 | ! returns either keep_going, retry, backup, or terminate. 90 | integer function extras_check_model(id) 91 | integer, intent(in) :: id 92 | integer :: ierr 93 | type (star_info), pointer :: s 94 | logical :: do_retry 95 | integer :: k 96 | ierr = 0 97 | call star_ptr(id, s, ierr) 98 | if (ierr /= 0) return 99 | extras_check_model = keep_going 100 | 101 | ! Flag PZ as anonymous_mixing 102 | if (s% lxtra(1)) then 103 | do k=s% ixtra(2), s% ixtra(1), -1 104 | s%mixing_type(k) = anonymous_mixing 105 | end do 106 | endif 107 | 108 | do_retry = .false. 109 | 110 | ! by default, indicate where (in the code) MESA terminated 111 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 112 | end function extras_check_model 113 | 114 | 115 | integer function how_many_extra_history_columns(id) 116 | integer, intent(in) :: id 117 | integer :: ierr 118 | type (star_info), pointer :: s 119 | ierr = 0 120 | call star_ptr(id, s, ierr) 121 | if (ierr /= 0) return 122 | how_many_extra_history_columns = 7 123 | end function how_many_extra_history_columns 124 | 125 | 126 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 127 | integer, intent(in) :: id, n 128 | character (len=maxlen_history_column_name) :: names(n) 129 | real(dp) :: vals(n) 130 | real(dp) :: r_cb 131 | integer :: k 132 | integer, intent(out) :: ierr 133 | type (star_info), pointer :: s 134 | ierr = 0 135 | call star_ptr(id, s, ierr) 136 | if (ierr /= 0) return 137 | 138 | call star_eval_conv_bdy_r(s, 1, r_cb, ierr) 139 | 140 | ! s% xtra(2)=0 141 | ! s% xtra(3)=0 142 | ! s% xtra(4)=0 143 | 144 | ! if (s% mixing_type(s% nz) /= convective_mixing) then 145 | ! s% xtra(5) = 0 146 | ! s% xtra(1) = 0 147 | ! s% xtra(6) = 0 148 | ! else 149 | ! call star_eval_conv_bdy_k(s, 1, k, ierr) 150 | ! s% xtra(5) = r_cb 151 | ! s% xtra(1) = s%m(k) 152 | ! s% xtra(6) = s%rho(k) 153 | ! endif 154 | 155 | names(1) = 'm_core' 156 | names(2) = 'mass_pen_zone' 157 | names(3) = 'delta_r_pen_zone' 158 | names(4) = 'alpha_pen_zone' 159 | names(5) = 's% xtra(5)' 160 | names(6) = 's% xtra(6)_pen' 161 | names(7) = 'r_cb' 162 | 163 | vals(1) = s% xtra(1)/Msun 164 | vals(2) = s% xtra(2)/Msun 165 | vals(3) = s% xtra(3)/Rsun 166 | vals(4) = s% xtra(4) 167 | vals(5) = s% xtra(5)/Rsun 168 | vals(6) = s% xtra(6) 169 | vals(7) = r_cb/Rsun 170 | 171 | end subroutine data_for_extra_history_columns 172 | 173 | 174 | integer function how_many_extra_profile_columns(id) 175 | integer, intent(in) :: id 176 | integer :: ierr 177 | type (star_info), pointer :: s 178 | ierr = 0 179 | call star_ptr(id, s, ierr) 180 | if (ierr /= 0) return 181 | how_many_extra_profile_columns = 0 182 | end function how_many_extra_profile_columns 183 | 184 | 185 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 186 | integer, intent(in) :: id, n, nz 187 | character (len=maxlen_profile_column_name) :: names(n) 188 | real(dp) :: vals(nz,n) 189 | integer, intent(out) :: ierr 190 | ! integer :: vals_nr 191 | type (star_info), pointer :: s 192 | integer :: k 193 | ierr = 0 194 | call star_ptr(id, s, ierr) 195 | if (ierr /= 0) return 196 | 197 | end subroutine data_for_extra_profile_columns 198 | 199 | 200 | integer function how_many_extra_history_header_items(id) 201 | integer, intent(in) :: id 202 | integer :: ierr 203 | type (star_info), pointer :: s 204 | ierr = 0 205 | call star_ptr(id, s, ierr) 206 | if (ierr /= 0) return 207 | how_many_extra_history_header_items = 0 208 | end function how_many_extra_history_header_items 209 | 210 | 211 | subroutine data_for_extra_history_header_items(id, n, names, vals, ierr) 212 | integer, intent(in) :: id, n 213 | character (len=maxlen_history_column_name) :: names(n) 214 | real(dp) :: vals(n) 215 | type(star_info), pointer :: s 216 | integer, intent(out) :: ierr 217 | ierr = 0 218 | call star_ptr(id,s,ierr) 219 | if(ierr/=0) return 220 | 221 | ! here is an example for adding an extra history header item 222 | ! also set how_many_extra_history_header_items 223 | ! names(1) = 'mixing_length_alpha' 224 | ! vals(1) = s% mixing_length_alpha 225 | end subroutine data_for_extra_history_header_items 226 | 227 | 228 | integer function how_many_extra_profile_header_items(id) 229 | integer, intent(in) :: id 230 | integer :: ierr 231 | type (star_info), pointer :: s 232 | ierr = 0 233 | call star_ptr(id, s, ierr) 234 | if (ierr /= 0) return 235 | how_many_extra_profile_header_items = 0 236 | end function how_many_extra_profile_header_items 237 | 238 | 239 | subroutine data_for_extra_profile_header_items(id, n, names, vals, ierr) 240 | integer, intent(in) :: id, n 241 | character (len=maxlen_profile_column_name) :: names(n) 242 | real(dp) :: vals(n) 243 | type(star_info), pointer :: s 244 | integer, intent(out) :: ierr 245 | ierr = 0 246 | call star_ptr(id,s,ierr) 247 | if(ierr/=0) return 248 | 249 | ! here is an example for adding an extra profile header item 250 | ! also set how_many_extra_profile_header_items 251 | ! names(1) = 'mixing_length_alpha' 252 | ! vals(1) = s% mixing_length_alpha 253 | 254 | end subroutine data_for_extra_profile_header_items 255 | 256 | 257 | ! returns either keep_going or terminate. 258 | ! note: cannot request retry or backup; extras_check_model can do that. 259 | integer function extras_finish_step(id) 260 | integer, intent(in) :: id 261 | integer :: ierr 262 | type (star_info), pointer :: s 263 | character (len=200) :: fname 264 | ierr = 0 265 | call star_ptr(id, s, ierr) 266 | if (ierr /= 0) return 267 | extras_finish_step = keep_going 268 | 269 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 270 | 271 | end function extras_finish_step 272 | 273 | 274 | subroutine extras_after_evolve(id, ierr) 275 | integer, intent(in) :: id 276 | integer, intent(out) :: ierr 277 | type (star_info), pointer :: s 278 | ierr = 0 279 | call star_ptr(id, s, ierr) 280 | if (ierr /= 0) return 281 | end subroutine extras_after_evolve 282 | 283 | end module run_star_extras 284 | -------------------------------------------------------------------------------- /hooks/detach_binary/README.md: -------------------------------------------------------------------------------- 1 | # ``detach binary`` 2 | 3 | ## Overview 4 | 5 | This routine can be used to continue the evolution of the initially 6 | less massive star (typically `star 2`) as an "effectively single" 7 | star. This can be used, for example, to simulate the disruption of a 8 | binary because of the core-collapse of the initially more massive star 9 | ([Blaauw 1961](https://ui.adsabs.harvard.edu/abs/1961BAN....15..265B/abstract), 10 | [Renzo et al. 2019](https://ui.adsabs.harvard.edu/abs/2019A%26A...624A..66R/abstract)). 11 | 12 | When calling this routine: 13 | 14 | * `star 1` will be turned into a point mass, the donor pointer `b% d_i%` is 15 | set to `star 2` 16 | * the binary separation is set to something enormous (`1d99` solar 17 | radii) 18 | * tides, Roche lobe overflow, magnetic braking, and angular momentum accretion will 19 | be ignored in the remaining evolution 20 | 21 | It assumes that you are running a binary with `evolve_both_stars = 22 | .true.`, and otherwise will set `ierr=1` and hit a Fortran `STOP`. You 23 | can comment out the `STOP` statement, exit the subroutine, and check 24 | the returned `ierr` from where you called it 25 | 26 | ## Usage 27 | 28 | Typically, this will be used from `extras_binary_finish_step` in 29 | `run_binary_extras.f90`. 30 | 31 | To use this routine you need to include it in your `run_binary_extras.f90`, 32 | after the `contains` statement you'll need 33 | 34 | ```Fortran 35 | 36 | contains 37 | 38 | include 'detach_binary/detach_binary.inc' 39 | ``` 40 | 41 | ### Example 42 | 43 | Example inlists and `run_binary_extras.f90` (based on the 44 | `$MESA_DIR/binary/work` template) are provided in `test_detach_binary`. 45 | 46 | In this example, at `model_number = 3` the binary 47 | is detached and the evolution of the initially 48 | less massive star is continued until `model_number=5`. 49 | 50 | It has been tested with MESA version 15140 and `29bd15f`. 51 | 52 | ## Maintainer 53 | 54 | This contribution is maintained by Mathieu Renzo (`mathren`) 55 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/.gitignore: -------------------------------------------------------------------------------- 1 | LOGS/* 2 | LOGS1/* 3 | LOGS2/* 4 | photos/* 5 | photos1/* 6 | photos2/* 7 | *.data 8 | *.o 9 | *.mod 10 | *.smod 11 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/clean: -------------------------------------------------------------------------------- 1 | cd make 2 | make clean 3 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/inlist: -------------------------------------------------------------------------------- 1 | 2 | &binary_job 3 | 4 | read_extra_binary_job_inlist1 = .true. 5 | extra_binary_job_inlist1_name = 'inlist_project' 6 | 7 | / ! end of star_job namelist 8 | 9 | 10 | 11 | &binary_controls 12 | 13 | read_extra_binary_controls_inlist1 = .true. 14 | extra_binary_controls_inlist1_name = 'inlist_project' 15 | 16 | / ! end of controls namelist 17 | 18 | 19 | 20 | &binary_pgstar 21 | 22 | read_extra_binary_pgstar_inlist1 = .true. 23 | extra_binary_pgstar_inlist1_name = 'inlist_project' 24 | 25 | / ! end of pgstar namelist 26 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/inlist1: -------------------------------------------------------------------------------- 1 | &star_job 2 | 3 | 4 | show_log_description_at_start = .true. 5 | 6 | pgstar_flag = .true. 7 | 8 | / ! end of star_job namelist 9 | 10 | &eos 11 | ! eos options 12 | ! see eos/defaults/eos.defaults 13 | 14 | / ! end of eos namelist 15 | 16 | 17 | &kap 18 | ! kap options 19 | ! see kap/defaults/kap.defaults 20 | use_Type2_opacities = .true. 21 | Zbase = 0.02 22 | 23 | / ! end of kap namelist 24 | 25 | 26 | &controls 27 | 28 | log_directory = 'LOGS1' 29 | 30 | profile_interval = -1 31 | history_interval = -1 32 | terminal_interval = 1 33 | write_header_frequency = 10 34 | 35 | / ! end of controls namelist 36 | 37 | 38 | &pgstar 39 | 40 | / ! end of pgstar namelist 41 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/inlist2: -------------------------------------------------------------------------------- 1 | &star_job 2 | 3 | show_log_description_at_start = .false. 4 | 5 | 6 | / ! end of star_job namelist 7 | 8 | &eos 9 | ! eos options 10 | ! see eos/defaults/eos.defaults 11 | 12 | / ! end of eos namelist 13 | 14 | 15 | &kap 16 | ! kap options 17 | ! see kap/defaults/kap.defaults 18 | use_Type2_opacities = .true. 19 | Zbase = 0.02 20 | 21 | / ! end of kap namelist 22 | 23 | &controls 24 | 25 | log_directory = 'LOGS2' 26 | 27 | profile_interval = -1 28 | history_interval = -1 29 | terminal_interval = 1 30 | write_header_frequency = 10 31 | 32 | max_model_number = 5 33 | 34 | / ! end of controls namelist 35 | 36 | 37 | &pgstar 38 | 39 | 40 | 41 | / ! end of pgstar namelist 42 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/inlist_project: -------------------------------------------------------------------------------- 1 | &binary_job 2 | 3 | inlist_names(1) = 'inlist1' 4 | inlist_names(2) = 'inlist2' 5 | 6 | evolve_both_stars = .true. 7 | 8 | / ! end of binary_job namelist 9 | 10 | &binary_controls 11 | 12 | m1 = 1.0d0 ! donor mass in Msun 13 | m2 = 1.4d0 ! companion mass in Msun 14 | initial_period_in_days = 2d0 15 | 16 | max_tries_to_achieve = 20 17 | 18 | / ! end of binary_controls namelist 19 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/make/makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(MESA_DIR),) 2 | ifeq ($($MESA_DIR_INTENTIONALLY_EMPTY),) 3 | $(error MESA_DIR environment variable is not set) 4 | endif 5 | endif 6 | 7 | include $(MESA_DIR)/binary/work_standard_makefile_binary 8 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/mk: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function check_okay { 4 | if [ $? -ne 0 ] 5 | then 6 | echo 7 | echo "FAILED" 8 | echo 9 | exit 1 10 | fi 11 | } 12 | 13 | cd make; make; check_okay 14 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/re: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | shopt -u expand_aliases 4 | 5 | photo_directory=photos 6 | 7 | function most_recent_photo { 8 | bp=$(ls -tp "$photo_directory/"b_* | head -1) 9 | echo ${bp#"$photo_directory/"b_} 10 | } 11 | 12 | if [ $# -eq 0 ] 13 | then 14 | photo=$(most_recent_photo) 15 | else 16 | photo=$1 17 | fi 18 | 19 | if [ -z "$photo" ] || ! [ -f "$photo_directory/b_$photo" ] || ! [ -f "$photo_directory/1_$photo" ] 20 | then 21 | echo "Not all specified photos exist: $photo" 22 | exit 1 23 | fi 24 | 25 | echo "restart from $photo" 26 | echo "$photo" > .restart 27 | 28 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 29 | ./binary 30 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 31 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/rn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -f .restart 4 | 5 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 6 | ./binary 7 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 8 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/src/binary_run.f90: -------------------------------------------------------------------------------- 1 | program binary_run 2 | use run_binary, only: do_run_binary 3 | 4 | call do_run_binary(.true.) 5 | 6 | end program binary_run 7 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/src/run_binary_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2012-2019 Bill Paxton & The MESA Team 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | module run_binary_extras 23 | 24 | use star_lib 25 | use star_def 26 | use const_def 27 | use chem_def 28 | use num_lib 29 | use binary_def 30 | use math_lib 31 | 32 | implicit none 33 | 34 | contains 35 | 36 | ! to be able to detach the binary 37 | include 'detach_binary/detach_binary.inc' 38 | 39 | 40 | subroutine extras_binary_controls(binary_id, ierr) 41 | integer :: binary_id 42 | integer, intent(out) :: ierr 43 | type (binary_info), pointer :: b 44 | ierr = 0 45 | 46 | call binary_ptr(binary_id, b, ierr) 47 | if (ierr /= 0) then 48 | write(*,*) 'failed in binary_ptr' 49 | return 50 | end if 51 | 52 | ! Set these function pointers to point to the functions you wish to use in 53 | ! your run_binary_extras. Any which are not set, default to a null_ version 54 | ! which does nothing. 55 | b% how_many_extra_binary_history_header_items => how_many_extra_binary_history_header_items 56 | b% data_for_extra_binary_history_header_items => data_for_extra_binary_history_header_items 57 | b% how_many_extra_binary_history_columns => how_many_extra_binary_history_columns 58 | b% data_for_extra_binary_history_columns => data_for_extra_binary_history_columns 59 | 60 | b% extras_binary_startup=> extras_binary_startup 61 | b% extras_binary_start_step=> extras_binary_start_step 62 | b% extras_binary_check_model=> extras_binary_check_model 63 | b% extras_binary_finish_step => extras_binary_finish_step 64 | b% extras_binary_after_evolve=> extras_binary_after_evolve 65 | 66 | ! Once you have set the function pointers you want, then uncomment this (or set it in your star_job inlist) 67 | ! to disable the printed warning message, 68 | b% warn_binary_extra =.false. 69 | 70 | end subroutine extras_binary_controls 71 | 72 | 73 | integer function how_many_extra_binary_history_header_items(binary_id) 74 | use binary_def, only: binary_info 75 | integer, intent(in) :: binary_id 76 | how_many_extra_binary_history_header_items = 0 77 | end function how_many_extra_binary_history_header_items 78 | 79 | 80 | subroutine data_for_extra_binary_history_header_items( & 81 | binary_id, n, names, vals, ierr) 82 | type (binary_info), pointer :: b 83 | integer, intent(in) :: binary_id, n 84 | character (len=maxlen_binary_history_column_name) :: names(n) 85 | real(dp) :: vals(n) 86 | integer, intent(out) :: ierr 87 | ierr = 0 88 | call binary_ptr(binary_id, b, ierr) 89 | if (ierr /= 0) then 90 | write(*,*) 'failed in binary_ptr' 91 | return 92 | end if 93 | end subroutine data_for_extra_binary_history_header_items 94 | 95 | 96 | integer function how_many_extra_binary_history_columns(binary_id) 97 | use binary_def, only: binary_info 98 | integer, intent(in) :: binary_id 99 | how_many_extra_binary_history_columns = 0 100 | end function how_many_extra_binary_history_columns 101 | 102 | 103 | subroutine data_for_extra_binary_history_columns(binary_id, n, names, vals, ierr) 104 | type (binary_info), pointer :: b 105 | integer, intent(in) :: binary_id 106 | integer, intent(in) :: n 107 | character (len=maxlen_binary_history_column_name) :: names(n) 108 | real(dp) :: vals(n) 109 | integer, intent(out) :: ierr 110 | ierr = 0 111 | call binary_ptr(binary_id, b, ierr) 112 | if (ierr /= 0) then 113 | write(*,*) 'failed in binary_ptr' 114 | return 115 | end if 116 | 117 | end subroutine data_for_extra_binary_history_columns 118 | 119 | 120 | integer function extras_binary_startup(binary_id,restart,ierr) 121 | type (binary_info), pointer :: b 122 | integer, intent(in) :: binary_id 123 | integer, intent(out) :: ierr 124 | logical, intent(in) :: restart 125 | call binary_ptr(binary_id, b, ierr) 126 | if (ierr /= 0) then ! failure in binary_ptr 127 | return 128 | end if 129 | 130 | ! b% s1% job% warn_run_star_extras = .false. 131 | extras_binary_startup = keep_going 132 | end function extras_binary_startup 133 | 134 | integer function extras_binary_start_step(binary_id,ierr) 135 | type (binary_info), pointer :: b 136 | integer, intent(in) :: binary_id 137 | integer, intent(out) :: ierr 138 | 139 | extras_binary_start_step = keep_going 140 | call binary_ptr(binary_id, b, ierr) 141 | if (ierr /= 0) then ! failure in binary_ptr 142 | return 143 | end if 144 | 145 | end function extras_binary_start_step 146 | 147 | !Return either keep_going, retry or terminate 148 | integer function extras_binary_check_model(binary_id) 149 | type (binary_info), pointer :: b 150 | integer, intent(in) :: binary_id 151 | integer :: ierr 152 | call binary_ptr(binary_id, b, ierr) 153 | if (ierr /= 0) then ! failure in binary_ptr 154 | return 155 | end if 156 | extras_binary_check_model = keep_going 157 | 158 | end function extras_binary_check_model 159 | 160 | 161 | ! returns either keep_going or terminate. 162 | ! note: cannot request retry; extras_check_model can do that. 163 | integer function extras_binary_finish_step(binary_id) 164 | type (binary_info), pointer :: b 165 | integer, intent(in) :: binary_id 166 | integer :: ierr 167 | call binary_ptr(binary_id, b, ierr) 168 | if (ierr /= 0) then ! failure in binary_ptr 169 | return 170 | end if 171 | extras_binary_finish_step = keep_going 172 | 173 | ! example on how to detach the binary 174 | if (b% model_number == 3) then 175 | call detach_binary(binary_id, ierr) 176 | end if 177 | 178 | 179 | end function extras_binary_finish_step 180 | 181 | subroutine extras_binary_after_evolve(binary_id, ierr) 182 | type (binary_info), pointer :: b 183 | integer, intent(in) :: binary_id 184 | integer, intent(out) :: ierr 185 | call binary_ptr(binary_id, b, ierr) 186 | if (ierr /= 0) then ! failure in binary_ptr 187 | return 188 | end if 189 | 190 | 191 | end subroutine extras_binary_after_evolve 192 | 193 | end module run_binary_extras 194 | -------------------------------------------------------------------------------- /hooks/detach_binary/binary_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2012 Bill Paxton 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | use chem_def 30 | use num_lib 31 | use binary_def 32 | 33 | implicit none 34 | 35 | ! these routines are called by the standard run_star check_model 36 | contains 37 | 38 | include 'standard_run_star_extras.inc' 39 | 40 | end module run_star_extras 41 | 42 | -------------------------------------------------------------------------------- /hooks/detach_binary/detach_binary.inc: -------------------------------------------------------------------------------- 1 | subroutine detach_binary(binary_id, ierr) 2 | ! This routine can be called in binary_extra_finish_step to 3 | ! continue the evolution of the secondary as a single star, e.g. 4 | ! because of the explosion of the companion and the disruption of 5 | ! the binary. 6 | use binary_lib, only: binary_set_separation_eccentricity 7 | type (binary_info), pointer :: b 8 | integer, intent(in) :: binary_id 9 | integer, intent(out) :: ierr ! ierr = 0 means success 10 | call binary_ptr(binary_id, b, ierr) 11 | if (ierr /= 0) return 12 | 13 | print *, '****************************************' 14 | print *, '* Switching from binary to single star *' 15 | print *, '****************************************' 16 | 17 | if (b% job% evolve_both_stars .eqv. .false.) then 18 | ! detaching a binary with a point mass would imply 19 | ! evolving two detached point masses 20 | ! probably not what you want to do 21 | ierr = 1 22 | STOP 'Cannot detach a binary with point mass companion' 23 | ! you can remove this STOP statement, add a return, and check 24 | ! for the value of ierr where you call this routine from instead 25 | end if 26 | 27 | b% job% evolve_both_stars = .false. 28 | b% ignore_hard_limits_this_step = .true. 29 | print *, 'current mtransfer_rate', b% mtransfer_rate, 'will be set to zero' 30 | b% mtransfer_rate = 0d0 31 | b% change_factor = b% max_change_factor 32 | print *, 'shutting down tides, accretion of J, magnetic braking, and missing wind' 33 | b% do_tidal_sync = .false. 34 | b% do_j_accretion = .false. 35 | b% do_jdot_mb = .false. 36 | b% do_jdot_missing_wind = .false. 37 | print *, 'ignore RLOF from now on' 38 | b% ignore_rlof_flag = .true. 39 | ! fix Eddington mdot stuff 40 | b% eq_initial_bh_mass = b% s_donor% m(1) 41 | b% mdot_edd = 1d99 42 | b% mdot_edd_eta = 0d0 43 | ! switch donor and accretor 44 | b% d_i = 2 45 | b% a_i = 1 46 | ! switch pointers 47 | b% s_donor => b% s2 48 | b% s_accretor => b% s1 49 | ! set point mass index 50 | b% point_mass_i = 1 51 | ! update separation and eccentricity to be very large and zero respectively 52 | call binary_set_separation_eccentricity(binary_id, 1d99, 0d0, ierr) 53 | if (ierr /= 0) return 54 | ! for sanity checks 55 | ! print *, '****************************************' 56 | ! print *, 'new period:' 57 | ! print *, b% period 58 | ! print *, 'new separation:' 59 | ! print *, b% separation 60 | ! print *, 'new Jorb:' 61 | ! print *, b% angular_momentum_j 62 | ! print *, 'new eccentricity:' 63 | ! print *, b% eccentricity 64 | ! print *, '****************************************' 65 | end subroutine detach_binary 66 | -------------------------------------------------------------------------------- /hooks/enhanced_Tayler_Spruit/README.md: -------------------------------------------------------------------------------- 1 | # ``enhanced_Tayler_Spruit`` 2 | 3 | ## Overview 4 | 5 | These routines implement the enhanced Tayler-Spruit dynamo prescription of [Fuller et al. (2019)](https://ui.adsabs.harvard.edu/abs/2019MNRAS.485.3661F/abstract). 6 | This prescription sets `am_nu_omega`, which is the diffusivity of angular velocity. 7 | In principle the dynamo also results in chemical mixing, but these routines do not implement that effect. 8 | If you use these routines please cite this publication. 9 | 10 | This contribution is maintained by @adamjermyn. 11 | 12 | ## Usage 13 | 14 | Example inlists and `run_star_extras.f90` are provided for a normal 15 | MESA `star` run in the `star_example` subfolder. These are the same 16 | as those appearing in the [Zenodo](https://zenodo.org/record/3228403#.XinEzi3MzUI) entry for [Fuller et al. (2019)](https://ui.adsabs.harvard.edu/abs/2019MNRAS.485.3661F/abstract), 17 | but with the relevant subroutines split into `enhanced_Tayler_Spruit.inc`. 18 | 19 | To use these routines you need to include them in your `run_star_extras.f90`, after 20 | the `contains` statement you'll need 21 | 22 | ````Fortran 23 | 24 | contains 25 | 26 | include 'enhanced_Tayler_Spruit/enhanced_Tayler_Spruit.inc' 27 | ```` 28 | 29 | In `extras_controls` point you also need 30 | 31 | ````Fortran 32 | subroutine extras_controls(id, ierr) 33 | ... 34 | s% other_am_mixing => TSF 35 | ... 36 | end subroutine extras_controls 37 | ```` 38 | 39 | Note that `star_example/run_star_extras.f90` includes routines for adding extra history and profile columns which may be of interest. 40 | -------------------------------------------------------------------------------- /hooks/enhanced_Tayler_Spruit/star_example/inlist_project: -------------------------------------------------------------------------------- 1 | 2 | &star_job 3 | pgstar_flag = .true. 4 | new_rotation_flag = .true. 5 | change_rotation_flag = .true. 6 | change_initial_rotation_flag = .true. 7 | new_omega = 3.64e-5 8 | set_initial_omega = .true. 9 | / ! end of star_job namelist 10 | 11 | 12 | &eos 13 | ! eos options 14 | ! see eos/defaults/eos.defaults 15 | 16 | / ! end of eos namelist 17 | 18 | 19 | &kap 20 | ! kap options 21 | ! see kap/defaults/kap.defaults 22 | use_Type2_opacities = .true. 23 | Zbase = 0.02 24 | 25 | / ! end of kap namelist 26 | 27 | &controls 28 | ! ----------------------- short run for testing 29 | xa_central_lower_limit_species(1) = 'h1' 30 | xa_central_lower_limit(1) = 1d-3 31 | !------------------------ MAIN 32 | initial_mass = 1.6 33 | initial_z = 0.02 34 | set_min_D_mix = .true. 35 | min_D_mix = 1d1 36 | mesh_delta_coeff = 0.7 37 | varcontrol_target = 0.7d-3 38 | predictive_mix(1) = .true. 39 | predictive_superad_thresh(1) = 0.005 40 | predictive_avoid_reversal(1) = 'he4' 41 | predictive_zone_type(1) = 'any' 42 | predictive_zone_loc(1) = 'core' 43 | predictive_bdy_loc(1) = 'top' 44 | dX_div_X_limit_min_X = 1d-4 45 | dX_div_X_limit = 5d-1 46 | dX_nuc_drop_min_X_limit = 1d-4 47 | dX_nuc_drop_limit = 1d-2 48 | !--------------------- Rotation 49 | am_nu_ST_factor = 0 50 | use_other_am_mixing = .true. 51 | premix_omega = .true. 52 | recalc_mixing_info_each_substep = .true. 53 | am_nu_factor = 1 54 | am_nu_non_rotation_factor = 1d0 55 | am_nu_visc_factor = 0.333 56 | !------------------------- WIND 57 | cool_wind_RGB_scheme = 'Reimers' 58 | cool_wind_AGB_scheme = 'Blocker' 59 | RGB_to_AGB_wind_switch = 1d-4 60 | Reimers_scaling_factor = 0.2 61 | Blocker_scaling_factor = 0.5 62 | use_accreted_material_j = .true. 63 | accreted_material_j = 0 64 | !------------------- OVERSHOOTING 65 | overshoot_scheme(1) = 'exponential' 66 | overshoot_zone_type(1) = 'any' 67 | overshoot_zone_loc(1) = 'any' 68 | overshoot_bdy_loc(1) = 'any' 69 | overshoot_f(1) = 0.015 70 | overshoot_f0(1) = 0.005 71 | 72 | / ! end of controls namelist 73 | -------------------------------------------------------------------------------- /hooks/enhanced_Tayler_Spruit/star_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010 Bill Paxton 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | 30 | implicit none 31 | 32 | 33 | ! these routines are called by the standard run_star check_model 34 | contains 35 | 36 | include 'enhanced_Tayler_Spruit/enhanced_Tayler_Spruit.inc' 37 | !include 'standard_run_star_extras.inc' 38 | 39 | subroutine extras_controls(id, ierr) 40 | integer, intent(in) :: id 41 | integer, intent(out) :: ierr 42 | type (star_info), pointer :: s 43 | ierr = 0 44 | call star_ptr(id, s, ierr) 45 | if (ierr /= 0) return 46 | 47 | s% extras_startup => extras_startup 48 | s% extras_check_model => extras_check_model 49 | s% extras_finish_step => extras_finish_step 50 | s% extras_after_evolve => extras_after_evolve 51 | s% how_many_extra_history_columns => how_many_extra_history_columns 52 | s% data_for_extra_history_columns => data_for_extra_history_columns 53 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 54 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 55 | s% job% warn_run_star_extras = .false. 56 | 57 | s% other_am_mixing => TSF 58 | 59 | end subroutine extras_controls 60 | 61 | integer function how_many_extra_profile_columns(id) 62 | use star_def, only: star_info 63 | integer, intent(in) :: id 64 | integer :: ierr 65 | type (star_info), pointer :: s 66 | ierr = 0 67 | call star_ptr(id, s, ierr) 68 | if (ierr /= 0) return 69 | how_many_extra_profile_columns = 6 70 | end function how_many_extra_profile_columns 71 | 72 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 73 | use star_def, only: star_info, maxlen_profile_column_name 74 | use const_def, only: dp 75 | integer, intent(in) :: id, n, nz 76 | 77 | character (len=maxlen_profile_column_name) :: names(n), names_TS(6) 78 | real(dp) :: vals(nz,n), vals_TS(nz,6) 79 | 80 | integer, intent(out) :: ierr 81 | integer :: j, k 82 | ierr = 0 83 | 84 | call TS_data_for_extra_profile_columns(id, 6, nz, names_TS, vals_TS, ierr) 85 | 86 | do k=1,n 87 | do j=1,nz 88 | vals(j,k) = vals_TS(j,k) 89 | end do 90 | names(k) = names_TS(k) 91 | end do 92 | 93 | end subroutine data_for_extra_profile_columns 94 | 95 | integer function how_many_extra_history_columns(id) 96 | integer, intent(in) :: id 97 | integer :: ierr 98 | type (star_info), pointer :: s 99 | ierr = 0 100 | call star_ptr(id, s, ierr) 101 | if (ierr /= 0) return 102 | how_many_extra_history_columns = 6 103 | end function how_many_extra_history_columns 104 | 105 | 106 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 107 | use const_def, only: pi 108 | integer, intent(in) :: id, n 109 | character (len=maxlen_history_column_name) :: names(n), names_TS(6) 110 | real(dp) :: vals(n), vals_TS(6) 111 | integer :: k 112 | integer, intent(out) :: ierr 113 | ierr = 0 114 | 115 | call TS_data_for_extra_history_columns(id, n, names_TS, vals_TS, ierr) 116 | 117 | do k=1,6 118 | names(k) = names_TS(k) 119 | vals(k) = vals_TS(k) 120 | end do 121 | 122 | end subroutine data_for_extra_history_columns 123 | 124 | 125 | 126 | ! None of the following functions are called unless you set their 127 | ! function point in extras_control. 128 | 129 | 130 | subroutine extras_startup(id, restart, ierr) 131 | integer, intent(in) :: id 132 | logical, intent(in) :: restart 133 | integer, intent(out) :: ierr 134 | type (star_info), pointer :: s 135 | ierr = 0 136 | call star_ptr(id, s, ierr) 137 | if (ierr /= 0) return 138 | end subroutine extras_startup 139 | 140 | 141 | ! returns either keep_going, retry, backup, or terminate. 142 | integer function extras_check_model(id) 143 | integer, intent(in) :: id 144 | integer :: ierr 145 | type (star_info), pointer :: s 146 | ierr = 0 147 | call star_ptr(id, s, ierr) 148 | if (ierr /= 0) return 149 | extras_check_model = keep_going 150 | if (.false. .and. s% star_mass_h1 < 0.35d0) then 151 | ! stop when star hydrogen mass drops to specified level 152 | extras_check_model = terminate 153 | write(*, *) 'have reached desired hydrogen mass' 154 | return 155 | end if 156 | 157 | 158 | ! if you want to check multiple conditions, it can be useful 159 | ! to set a different termination code depending on which 160 | ! condition was triggered. MESA provides 9 customizable 161 | ! termination codes, named t_xtra1 .. t_xtra9. You can 162 | ! customize the messages that will be printed upon exit by 163 | ! setting the corresponding termination_code_str value. 164 | ! termination_code_str(t_xtra1) = 'my termination condition' 165 | 166 | ! by default, indicate where (in the code) MESA terminated 167 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 168 | end function extras_check_model 169 | 170 | 171 | 172 | 173 | ! returns either keep_going or terminate. 174 | ! note: cannot request retry or backup; extras_check_model can do that. 175 | integer function extras_finish_step(id) 176 | integer, intent(in) :: id 177 | integer :: ierr 178 | type (star_info), pointer :: s 179 | ierr = 0 180 | call star_ptr(id, s, ierr) 181 | if (ierr /= 0) return 182 | extras_finish_step = keep_going 183 | 184 | ! to save a profile, 185 | ! s% need_to_save_profiles_now = .true. 186 | ! to update the star log, 187 | ! s% need_to_update_history_now = .true. 188 | 189 | ! see extras_check_model for information about custom termination codes 190 | ! by default, indicate where (in the code) MESA terminated 191 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 192 | end function extras_finish_step 193 | 194 | 195 | subroutine extras_after_evolve(id, ierr) 196 | integer, intent(in) :: id 197 | integer, intent(out) :: ierr 198 | type (star_info), pointer :: s 199 | ierr = 0 200 | call star_ptr(id, s, ierr) 201 | if (ierr /= 0) return 202 | end subroutine extras_after_evolve 203 | 204 | end module run_star_extras 205 | 206 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/README.md: -------------------------------------------------------------------------------- 1 | # ``hydro_Ttau`` 2 | 3 | ## Overview 4 | 5 | These routines implement atmospheric T(τ) relations and mixing-length 6 | parameters derived from and calibrated to 3D radiation hydrodynamics 7 | simulations of the near-surface layers of cool stars. The T(τ) 8 | relations are described by [Trampedach et 9 | al. (2014a)](https://ui.adsabs.harvard.edu/abs/2014MNRAS.442..805T/abstract) 10 | and the calibrated MLT parameters by [Trampedach et 11 | al. (2014b)](https://ui.adsabs.harvard.edu/abs/2014MNRAS.445.4366T/abstract). 12 | Their implementation in MESA is detailed by [Mosumgaard et 13 | al. (2018)](https://ui.adsabs.harvard.edu/abs/2018MNRAS.478.5650M/abstract). 14 | Two examples using the T(τ) relations were provided through the test 15 | suite from SVN r10460 and subsequently moved into the `mesa-contrib` 16 | repo. If you use the `hydro_Ttau` routines, please cite these 17 | publications. 18 | 19 | This contribution is maintained by [@warrickball](https://github.com/warrickball). 20 | 21 | ## Usage 22 | 23 | Example inlists and `run_star_extras.f90` are provided for both a normal 24 | MESA `star` run and run with the `astero` submodule in the 25 | corresponding subfolders. These are in essence the same inlists that 26 | were used the old test cases `hydro_Ttau_evolve` and 27 | `hydro_Ttau_solar`, which are in turn what was used for the results in 28 | [Mosumgaard et 29 | al. (2018)](https://ui.adsabs.harvard.edu/abs/2018MNRAS.478.5650M/abstract). 30 | Those results were computed using MESA r9575 so some controls and 31 | parameters will have changed as MESA developed. 32 | 33 | To use the `hydro_Ttau` relations, you need to include the definitions 34 | in `hydro_Ttau_def.inc` and procedures in `hydro_Ttau_procs.inc` and 35 | `624.dek` in the usual way. i.e. in your `run_star_extras.f90`, around 36 | the `contains` statement you'll need 37 | 38 | ````Fortran 39 | include 'hydro_Ttau/hydro_Ttau_def.inc' 40 | 41 | contains 42 | 43 | include 'hydro_Ttau/624.dek' 44 | include 'hydro_Ttau/hydro_Ttau_proc.inc' 45 | ```` 46 | 47 | In `extras_controls`, call the subroutine `hydro_Ttau_setup`, which 48 | will load the table of T(τ) relations and mixing-length parameters and 49 | make a first call to the interpolator to put initial data in the 50 | relevant arrays. 51 | 52 | You'll also need to point `s% other_gradr_factor` and `s% 53 | other_surface_PT` to the matching `hydro_Ttau` procedures, named 54 | `hydro_Ttau_gradr_factor` and `hydro_Ttau_surface_PT`, 55 | respectively. i.e. your `extras_controls` subroutines should look like 56 | 57 | ````Fortran 58 | subroutine extras_controls(id, ierr) 59 | ... 60 | call hydro_Ttau_setup(id, ierr) 61 | ... 62 | s% other_gradr_factor => hydro_Ttau_gradr_factor 63 | s% other_surface_PT => hydro_Ttau_surface_PT 64 | ... 65 | end subroutine extras_controls 66 | ```` 67 | 68 | Finally, you need to call `hydro_Ttau_update` to interpolate in `logg` 69 | and `Teff` for each stellar model, which means you need to add a call like 70 | ````Fortran 71 | call hydro_Ttau_update(id, ierr) 72 | ```` 73 | to `extras_start_step` and `extras_check_model`. 74 | 75 | Two quantities that `hydro_Ttau` manipulates that are worth following 76 | in your histories are `s% mixing_length_alpha` and `s% tau_base`. The 77 | examples add these using the `extra_history_columns` procedures. 78 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/astero_example/inlist: -------------------------------------------------------------------------------- 1 | ! This is the first inlist file that MESA reads when it starts. 2 | 3 | ! This file tells MESA to go look elsewhere for its configuration 4 | ! info. This makes changing between different inlists easier, by 5 | ! allowing you to easily change the name of the file that gets read. 6 | 7 | &star_job 8 | 9 | read_extra_star_job_inlist1 = .true. 10 | extra_star_job_inlist1_name = 'inlist_hydro_Ttau' 11 | 12 | / ! end of star_job namelist 13 | 14 | 15 | &eos 16 | 17 | read_extra_eos_inlist1 = .true. 18 | extra_eos_inlist1_name = 'inlist_hydro_Ttau' 19 | 20 | / ! end of eos namelist 21 | 22 | 23 | &kap 24 | 25 | read_extra_kap_inlist1 = .true. 26 | extra_kap_inlist1_name = 'inlist_hydro_Ttau' 27 | 28 | / ! end of kap namelist 29 | 30 | 31 | &controls 32 | 33 | read_extra_controls_inlist1 = .true. 34 | extra_controls_inlist1_name = 'inlist_hydro_Ttau' 35 | 36 | / ! end of controls namelist 37 | 38 | 39 | &pgstar 40 | 41 | read_extra_pgstar_inlist1 = .true. 42 | extra_pgstar_inlist1_name = 'inlist_pgstar' 43 | 44 | / ! end of pgstar namelist 45 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/astero_example/inlist_hydro_Ttau: -------------------------------------------------------------------------------- 1 | &star_job 2 | ! begin with a pre-main sequence model 3 | create_pre_main_sequence_model = .true. 4 | pre_ms_relax_to_start_radiative_core = .false. 5 | pre_ms_T_c = 9d5 6 | pre_ms_relax_num_steps = 100 7 | 8 | ! include atmospheric structure in model 9 | relax_to_this_tau_factor = 3.2d-4 10 | dlogtau_factor = 0.05d0 ! 0.1d0 11 | relax_tau_factor = .true. 12 | 13 | initial_zfracs = 2 14 | 15 | save_model_when_terminate = .true. 16 | save_model_filename = 'final.mod' 17 | 18 | set_initial_cumulative_energy_error = .true. 19 | new_cumulative_energy_error = 0d0 20 | 21 | pgstar_flag = .false. ! .true. 22 | / !end of star_job namelist 23 | 24 | 25 | &eos 26 | ! eos options 27 | ! see eos/defaults/eos.defaults 28 | 29 | / ! end of eos namelist 30 | 31 | 32 | &kap 33 | ! kap options 34 | ! see kap/defaults/kap.defaults 35 | use_Type2_opacities = .true. 36 | Zbase = 0.02 37 | 38 | ! use matching opacity tables 39 | kap_file_prefix = 'gn93' 40 | kap_lowT_prefix = 'lowT_rt14_ag89' 41 | 42 | cubic_interpolation_in_X = .true. ! .false. 43 | cubic_interpolation_in_Z = .true. ! .false. 44 | 45 | / ! end of kap namelist 46 | 47 | 48 | &controls 49 | energy_eqn_option = 'dedt' 50 | use_gold_tolerances = .true. 51 | 52 | num_trace_history_values = 2 53 | trace_history_value_name(1) = 'rel_E_err' 54 | trace_history_value_name(2) = 'log_rel_run_E_err' 55 | 56 | atm_option = 'T_tau' 57 | atm_T_tau_relation = 'Eddington' 58 | atm_T_tau_opacity = 'fixed' 59 | 60 | ! x_ctrl(1) = 1.0355772536d0 61 | MLT_option = 'ML1' ! 'Cox' 62 | calculate_Brunt_N2 = .true. 63 | num_cells_for_smooth_brunt_B = 0 64 | 65 | use_other_surface_PT = .true. ! fix for T4_tau at top of model 66 | use_other_gradr_factor = .true. 67 | 68 | T_mix_limit = 1d4 ! otherwise little bit of settling in atmosphere 69 | 70 | max_years_for_timestep = 1d7 71 | mesh_delta_coeff = 0.5 72 | 73 | ! atomic diffusion 74 | do_element_diffusion = .true. ! determines whether or not we do diffusion 75 | diffusion_dt_limit = 7d11 ! no element diffusion if dt < this limit (in seconds) 76 | diffusion_T_full_on = 1d3 77 | diffusion_T_full_off = 1d3 78 | 79 | diffusion_calculates_ionization = .true. 80 | 81 | diffusion_num_classes = 4 ! number of classes of species for diffusion calculations 82 | diffusion_class_representative(1) = 'h1' 83 | diffusion_class_representative(2) = 'he4' 84 | diffusion_class_representative(3) = 'o16' 85 | diffusion_class_representative(4) = 'fe56' 86 | 87 | ! in ascending order. species goes into 1st class with A_max >= species A 88 | diffusion_class_A_max(1) = 2 89 | diffusion_class_A_max(2) = 4 90 | diffusion_class_A_max(3) = 16 91 | diffusion_class_A_max(4) = 10000 92 | 93 | diffusion_class_typical_charge(1) = 1 94 | diffusion_class_typical_charge(2) = 2 95 | diffusion_class_typical_charge(3) = 8 96 | diffusion_class_typical_charge(4) = 21 97 | / ! end of controls namelist 98 | 99 | &pgstar 100 | / ! end of pgstar namelist 101 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/astero_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010 Bill Paxton 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | use utils_lib, only: mesa_error 30 | 31 | implicit none 32 | 33 | include 'hydro_Ttau/hydro_Ttau_def.inc' 34 | 35 | contains 36 | 37 | include 'hydro_Ttau/624.dek' 38 | include 'hydro_Ttau/hydro_Ttau_proc.inc' 39 | 40 | subroutine extras_controls(id, ierr) 41 | use astero_def, only: star_astero_procs 42 | integer, intent(in) :: id 43 | integer, intent(out) :: ierr 44 | type (star_info), pointer :: s 45 | 46 | ierr = 0 47 | call star_ptr(id, s, ierr) 48 | if (ierr /= 0) return 49 | 50 | ! this is the place to set any procedure pointers you want to change 51 | ! e.g., other_wind, other_mixing, other_energy (see star_data.inc) 52 | 53 | call hydro_Ttau_setup(id, ierr) 54 | if (ierr /= 0) stop 'failed to setup hydro_Ttau in extras_controls' 55 | 56 | s% extras_startup => extras_startup 57 | s% extras_check_model => extras_check_model 58 | s% extras_finish_step => extras_finish_step 59 | s% extras_after_evolve => extras_after_evolve 60 | s% how_many_extra_history_columns => how_many_extra_history_columns 61 | s% data_for_extra_history_columns => data_for_extra_history_columns 62 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 63 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 64 | 65 | s% how_many_extra_history_header_items => how_many_extra_history_header_items 66 | s% data_for_extra_history_header_items => data_for_extra_history_header_items 67 | s% how_many_extra_profile_header_items => how_many_extra_profile_header_items 68 | s% data_for_extra_profile_header_items => data_for_extra_profile_header_items 69 | 70 | s% other_gradr_factor => hydro_Ttau_gradr_factor 71 | s% other_surface_PT => hydro_Ttau_surface_PT 72 | 73 | s% job% warn_run_star_extras =.false. 74 | 75 | include 'set_star_astero_procs.inc' 76 | end subroutine extras_controls 77 | 78 | 79 | subroutine extras_startup(id, restart, ierr) 80 | integer, intent(in) :: id 81 | logical, intent(in) :: restart 82 | integer, intent(out) :: ierr 83 | type (star_info), pointer :: s 84 | ierr = 0 85 | call star_ptr(id, s, ierr) 86 | if (ierr /= 0) return 87 | 88 | call hydro_Ttau_update(id, ierr) 89 | if (ierr /= 0) call mesa_error(__FILE__, __LINE__) 90 | 91 | end subroutine extras_startup 92 | 93 | 94 | ! returns either keep_going, retry, backup, or terminate. 95 | integer function extras_check_model(id) 96 | use astero_def, only: my_var1, my_var2, my_var3 97 | integer, intent(in) :: id 98 | integer :: ierr 99 | type (star_info), pointer :: s 100 | 101 | include 'formats' 102 | 103 | ierr = 0 104 | call star_ptr(id, s, ierr) 105 | if (ierr /= 0) return 106 | 107 | call hydro_Ttau_update(id, ierr) 108 | if (ierr /= 0) call mesa_error(__FILE__, __LINE__) 109 | 110 | extras_check_model = keep_going 111 | 112 | my_var1 = s% delta_Pg 113 | !write(*,2) 'delta_Pg', s% model_number, my_var1 114 | 115 | 116 | ! if you want to check multiple conditions, it can be useful 117 | ! to set a different termination code depending on which 118 | ! condition was triggered. MESA provides 9 customizable 119 | ! termination codes, named t_xtra1 .. t_xtra9. You can 120 | ! customize the messages that will be printed upon exit by 121 | ! setting the corresponding termination_code_str value. 122 | ! termination_code_str(t_xtra1) = 'my termination conditon' 123 | 124 | ! by default, indicate where (in the code) MESA terminated 125 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 126 | end function extras_check_model 127 | 128 | 129 | subroutine set_my_vars(id, ierr) ! called from star_astero code 130 | !use astero_search_data, only: include_my_var1_in_chi2, my_var1 131 | integer, intent(in) :: id 132 | integer, intent(out) :: ierr 133 | type (star_info), pointer :: s 134 | ! my_var's are predefined in the simplex_search_data. 135 | ! this routine's job is to assign those variables to current value in the model. 136 | ! it is called whenever a new value of chi2 is calculated. 137 | ! only necessary to set the my_var's you are actually using. 138 | ierr = 0 139 | !if (include_my_var1_in_chi2) then 140 | call star_ptr(id, s, ierr) 141 | if (ierr /= 0) return 142 | !my_var1 = s% Teff 143 | !end if 144 | end subroutine set_my_vars 145 | 146 | 147 | subroutine will_set_my_param(id, i, new_value, ierr) ! called from star_astero code 148 | !use astero_search_data, only: vary_my_param1 149 | integer, intent(in) :: id 150 | integer, intent(in) :: i ! which of my_param's will be set 151 | real(dp), intent(in) :: new_value 152 | integer, intent(out) :: ierr 153 | type (star_info), pointer :: s 154 | ierr = 0 155 | 156 | if (i == 1) then 157 | call star_ptr(id, s, ierr) 158 | if (ierr /= 0) return 159 | s% x_ctrl(1) = new_value 160 | end if 161 | 162 | end subroutine will_set_my_param 163 | 164 | 165 | integer function how_many_extra_history_columns(id) 166 | integer, intent(in) :: id 167 | how_many_extra_history_columns = 2 ! 0 168 | end function how_many_extra_history_columns 169 | 170 | 171 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 172 | integer, intent(in) :: id, n 173 | character (len=maxlen_history_column_name) :: names(n) 174 | real(dp) :: vals(n) 175 | integer, intent(out) :: ierr 176 | type (star_info), pointer :: s 177 | ierr = 0 178 | call star_ptr(id, s, ierr) 179 | if (ierr /= 0) return 180 | 181 | !note: do NOT add these names to history_columns.list 182 | ! the history_columns.list is only for the built-in log column options. 183 | ! it must not include the new column names you are adding here. 184 | 185 | 186 | names(1) = 'alpha' 187 | vals(1) = s% mixing_length_alpha 188 | 189 | names(2) = 'tau_base' 190 | vals(2) = s% tau_base 191 | 192 | end subroutine data_for_extra_history_columns 193 | 194 | 195 | integer function how_many_extra_profile_columns(id) 196 | integer, intent(in) :: id 197 | how_many_extra_profile_columns = 0 198 | end function how_many_extra_profile_columns 199 | 200 | 201 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 202 | integer, intent(in) :: id, n, nz 203 | character (len=maxlen_profile_column_name) :: names(n) 204 | real(dp) :: vals(nz,n) 205 | integer, intent(out) :: ierr 206 | integer :: k 207 | ierr = 0 208 | 209 | !note: do NOT add these names to profile_columns.list 210 | ! the profile_columns.list is only for the built-in profile column options. 211 | ! it must not include the new column names you are adding here. 212 | 213 | ! here is an example for adding a profile column 214 | !if (n /= 1) stop 'data_for_extra_profile_columns' 215 | !names(1) = 'beta' 216 | !do k = 1, nz 217 | ! vals(k,1) = s% Pgas(k)/s% P(k) 218 | !end do 219 | 220 | end subroutine data_for_extra_profile_columns 221 | 222 | 223 | integer function how_many_extra_history_header_items(id) 224 | integer, intent(in) :: id 225 | integer :: ierr 226 | type (star_info), pointer :: s 227 | ierr = 0 228 | call star_ptr(id, s, ierr) 229 | if (ierr /= 0) return 230 | how_many_extra_history_header_items = 0 231 | end function how_many_extra_history_header_items 232 | 233 | 234 | subroutine data_for_extra_history_header_items(id, n, names, vals, ierr) 235 | integer, intent(in) :: id, n 236 | character (len=maxlen_history_column_name) :: names(n) 237 | real(dp) :: vals(n) 238 | type(star_info), pointer :: s 239 | integer, intent(out) :: ierr 240 | ierr = 0 241 | call star_ptr(id,s,ierr) 242 | if(ierr/=0) return 243 | 244 | ! here is an example for adding an extra history header item 245 | ! also set how_many_extra_history_header_items 246 | ! names(1) = 'mixing_length_alpha' 247 | ! vals(1) = s% mixing_length_alpha 248 | 249 | end subroutine data_for_extra_history_header_items 250 | 251 | 252 | integer function how_many_extra_profile_header_items(id) 253 | integer, intent(in) :: id 254 | integer :: ierr 255 | type (star_info), pointer :: s 256 | ierr = 0 257 | call star_ptr(id, s, ierr) 258 | if (ierr /= 0) return 259 | how_many_extra_profile_header_items = 2 260 | end function how_many_extra_profile_header_items 261 | 262 | 263 | subroutine data_for_extra_profile_header_items(id, n, names, vals, ierr) 264 | integer, intent(in) :: id, n 265 | character (len=maxlen_profile_column_name) :: names(n) 266 | real(dp) :: vals(n) 267 | type(star_info), pointer :: s 268 | integer, intent(out) :: ierr 269 | ierr = 0 270 | call star_ptr(id,s,ierr) 271 | if(ierr/=0) return 272 | 273 | names(1) = 'alpha' 274 | vals(1) = s% mixing_length_alpha 275 | 276 | names(2) = 'tau_base' 277 | vals(2) = s% tau_base 278 | 279 | end subroutine data_for_extra_profile_header_items 280 | 281 | 282 | ! returns either keep_going or terminate. 283 | ! note: cannot request retry or backup; extras_check_model can do that. 284 | integer function extras_finish_step(id) 285 | integer, intent(in) :: id 286 | integer :: ierr 287 | type (star_info), pointer :: s 288 | ierr = 0 289 | call star_ptr(id, s, ierr) 290 | if (ierr /= 0) return 291 | extras_finish_step = keep_going 292 | 293 | ! to save a profile, 294 | ! s% need_to_save_profiles_now = .true. 295 | ! to update the star log, 296 | ! s% need_to_update_history_now = .true. 297 | 298 | ! see extras_check_model for information about custom termination codes 299 | ! by default, indicate where (in the code) MESA terminated 300 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 301 | end function extras_finish_step 302 | 303 | 304 | subroutine extras_after_evolve(id, ierr) 305 | use astero_def 306 | use utils_lib, only: mv 307 | integer, intent(in) :: id 308 | integer, intent(out) :: ierr 309 | character (len=256) :: format_string, num_string, basename 310 | ierr = 0 311 | 312 | write(format_string,'( "(i",i2.2,".",i2.2,")" )') num_digits, num_digits 313 | write(num_string,format_string) sample_number+1 ! sample number hasn't been incremented yet 314 | basename = trim(sample_results_prefix) // trim(num_string) 315 | call mv(best_model_fgong_filename, trim(basename) // trim('.fgong'), skip_errors=.true.) 316 | call mv(best_model_profile_filename, trim(basename) // trim('.profile'), skip_errors=.true.) 317 | 318 | end subroutine extras_after_evolve 319 | 320 | end module run_star_extras 321 | 322 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/hydro_Ttau_def.inc: -------------------------------------------------------------------------------- 1 | ! variables for hydro Ttau relations and MLT parameters 2 | integer, parameter :: Nsims = 37 3 | integer, parameter :: Nqtau = 82 4 | 5 | character(len=2), parameter :: sNsims = '37' 6 | character(len=2), parameter :: sNsims1 = '38' 7 | 8 | real(dp), dimension(Nqtau) :: qltau, qhpf, dqhpf 9 | real(dp), dimension(Nsims) :: Teffsl, gravsl, FeH, alph 10 | real(dp), dimension(Nsims) :: sigalph, LTeff3, Logg3 11 | real(dp) :: aa(Nsims,Nqtau), aa1(Nsims+1,Nqtau) 12 | integer :: iadj(6*Nsims), iend(Nsims), isrt(Nsims) 13 | integer :: ist 14 | 15 | ! data for interpolant 16 | integer, parameter :: nwork=6 ! 2*pm_work_size in interp_1d_def 17 | ! real(dp), dimension(4*Nqtau) :: f1 18 | ! real(dp), dimension(Nqtau*nwork) :: work1 19 | real(dp), pointer :: f1(:), work1(:) 20 | character(len=256) :: interp_dbg_str 21 | 22 | real(dp) :: tau_base_hydro_Ttau, lntau_base_hydro_Ttau, logtau_base_hydro_Ttau 23 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/star_example/inlist: -------------------------------------------------------------------------------- 1 | ! This is the first inlist file that MESA reads when it starts. 2 | 3 | ! This file tells MESA to go look elsewhere for its configuration 4 | ! info. This makes changing between different inlists easier, by 5 | ! allowing you to easily change the name of the file that gets read. 6 | 7 | &star_job 8 | 9 | read_extra_star_job_inlist1 = .true. 10 | extra_star_job_inlist1_name = 'inlist_hydro_Ttau' 11 | 12 | / ! end of star_job namelist 13 | 14 | 15 | &eos 16 | 17 | read_extra_eos_inlist1 = .true. 18 | extra_eos_inlist1_name = 'inlist_hydro_Ttau' 19 | 20 | / ! end of eos namelist 21 | 22 | 23 | &kap 24 | 25 | read_extra_kap_inlist1 = .true. 26 | extra_kap_inlist1_name = 'inlist_hydro_Ttau' 27 | 28 | / ! end of kap namelist 29 | 30 | 31 | &controls 32 | 33 | read_extra_controls_inlist1 = .true. 34 | extra_controls_inlist1_name = 'inlist_hydro_Ttau' 35 | 36 | / ! end of controls namelist 37 | 38 | 39 | &pgstar 40 | 41 | read_extra_pgstar_inlist1 = .true. 42 | extra_pgstar_inlist1_name = 'inlist_pgstar' 43 | 44 | / ! end of pgstar namelist 45 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/star_example/inlist_hydro_Ttau: -------------------------------------------------------------------------------- 1 | &star_job 2 | 3 | show_log_description_at_start = .false. 4 | 5 | ! begin with a pre-main sequence model 6 | create_pre_main_sequence_model = .true. 7 | pre_ms_relax_to_start_radiative_core = .false. 8 | pre_ms_T_c = 9d5 9 | pre_ms_relax_num_steps = 100 10 | 11 | ! include atmospheric structure in model 12 | relax_to_this_tau_factor = 3.2d-4 13 | dlogtau_factor = 0.05d0 ! 0.1d0 14 | relax_tau_factor = .true. 15 | 16 | initial_zfracs = 2 17 | 18 | write_profile_when_terminate = .true. 19 | filename_for_profile_when_terminate = 'final.profile' 20 | 21 | save_model_when_terminate = .true. 22 | save_model_filename = 'final.mod' 23 | 24 | set_initial_cumulative_energy_error = .true. 25 | new_cumulative_energy_error = 0d0 26 | 27 | ! display on-screen plots 28 | pgstar_flag = .false. ! .true. 29 | / !end of star_job namelist 30 | 31 | 32 | &eos 33 | ! eos options 34 | ! see eos/defaults/eos.defaults 35 | 36 | / ! end of eos namelist 37 | 38 | 39 | &kap 40 | ! kap options 41 | ! see kap/defaults/kap.defaults 42 | use_Type2_opacities = .true. 43 | Zbase = 0.02 44 | 45 | ! use matching opacity tables 46 | kap_file_prefix = 'gn93' 47 | kap_lowT_prefix = 'lowT_rt14_ag89' 48 | 49 | cubic_interpolation_in_X = .true. ! .false. 50 | cubic_interpolation_in_Z = .true. ! .false. 51 | 52 | / ! end of kap namelist 53 | 54 | 55 | &controls 56 | energy_eqn_option = 'dedt' 57 | use_gold_tolerances = .true. 58 | 59 | initial_mass = 1 60 | initial_z = 0.0197532968d0 61 | initial_y = 0.2715560186d0 62 | 63 | num_trace_history_values = 2 64 | trace_history_value_name(1) = 'rel_E_err' 65 | trace_history_value_name(2) = 'log_rel_run_E_err' 66 | 67 | photosphere_r_upper_limit = 15d0 68 | 69 | atm_option = 'T_tau' 70 | atm_T_tau_relation = 'Eddington' 71 | atm_T_tau_opacity = 'fixed' 72 | 73 | x_ctrl(1) = 1.0355772536d0 74 | MLT_option = 'ML1' ! 'Cox' 75 | calculate_Brunt_N2 = .true. 76 | 77 | use_other_surface_PT = .true. ! fix for T4_tau at top of model 78 | use_other_gradr_factor = .true. 79 | 80 | T_mix_limit = 1d4 ! otherwise little bit of settling in atmosphere 81 | 82 | max_years_for_timestep = 1d8 83 | mesh_delta_coeff = 0.5 84 | 85 | ! stop when the center mass fraction of h1 drops below this limit 86 | xa_central_lower_limit_species(1) = 'h1' 87 | xa_central_lower_limit(1) = 1d-3 88 | 89 | ! atomic diffusion 90 | do_element_diffusion = .true. ! determines whether or not we do diffusion 91 | diffusion_dt_limit = 7d11 ! no element diffusion if dt < this limit (in seconds) 92 | diffusion_T_full_on = 1d3 93 | diffusion_T_full_off = 1d3 94 | 95 | diffusion_calculates_ionization = .true. 96 | 97 | diffusion_num_classes = 4 ! number of classes of species for diffusion calculations 98 | diffusion_class_representative(1) = 'h1' 99 | diffusion_class_representative(2) = 'he4' 100 | diffusion_class_representative(3) = 'o16' 101 | diffusion_class_representative(4) = 'fe56' 102 | 103 | ! in ascending order. species goes into 1st class with A_max >= species A 104 | diffusion_class_A_max(1) = 2 105 | diffusion_class_A_max(2) = 4 106 | diffusion_class_A_max(3) = 16 107 | diffusion_class_A_max(4) = 10000 108 | 109 | diffusion_class_typical_charge(1) = 1 110 | diffusion_class_typical_charge(2) = 2 111 | diffusion_class_typical_charge(3) = 8 112 | diffusion_class_typical_charge(4) = 21 113 | 114 | / ! end of controls namelist 115 | 116 | &pgstar 117 | / ! end of pgstar namelist 118 | -------------------------------------------------------------------------------- /hooks/hydro_Ttau/star_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010-2019 Bill Paxton & The MESA Team 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | 30 | implicit none 31 | 32 | include 'hydro_Ttau/hydro_Ttau_def.inc' 33 | 34 | ! these routines are called by the standard run_star check_model 35 | contains 36 | 37 | include 'hydro_Ttau/624.dek' 38 | include 'hydro_Ttau/hydro_Ttau_proc.inc' 39 | 40 | subroutine extras_controls(id, ierr) 41 | integer, intent(in) :: id 42 | integer, intent(out) :: ierr 43 | type (star_info), pointer :: s 44 | 45 | ierr = 0 46 | call star_ptr(id, s, ierr) 47 | if (ierr /= 0) return 48 | 49 | call hydro_Ttau_setup(id, ierr) 50 | if (ierr /= 0) stop 'failed to setup hydro_Ttau in extras_controls' 51 | ! write(*,*) 'initialized hydro_Ttau in extras_controls' 52 | 53 | ! this is the place to set any procedure pointers you want to change 54 | ! e.g., other_wind, other_mixing, other_energy (see star_data.inc) 55 | 56 | ! the extras functions in this file will not be called 57 | ! unless you set their function pointers as done below. 58 | ! otherwise we use a null_ version which does nothing (except warn). 59 | 60 | s% extras_startup => extras_startup 61 | s% extras_start_step => extras_start_step 62 | s% extras_check_model => extras_check_model 63 | s% extras_finish_step => extras_finish_step 64 | s% extras_after_evolve => extras_after_evolve 65 | s% how_many_extra_history_columns => how_many_extra_history_columns 66 | s% data_for_extra_history_columns => data_for_extra_history_columns 67 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 68 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 69 | 70 | s% how_many_extra_history_header_items => how_many_extra_history_header_items 71 | s% data_for_extra_history_header_items => data_for_extra_history_header_items 72 | s% how_many_extra_profile_header_items => how_many_extra_profile_header_items 73 | s% data_for_extra_profile_header_items => data_for_extra_profile_header_items 74 | 75 | s% other_gradr_factor => hydro_Ttau_gradr_factor 76 | s% other_surface_PT => hydro_Ttau_surface_PT 77 | 78 | end subroutine extras_controls 79 | 80 | 81 | subroutine extras_startup(id, restart, ierr) 82 | integer, intent(in) :: id 83 | logical, intent(in) :: restart 84 | integer, intent(out) :: ierr 85 | type (star_info), pointer :: s 86 | ierr = 0 87 | call star_ptr(id, s, ierr) 88 | if (ierr /= 0) return 89 | 90 | ! write(*,*) 'called hydro_Ttau_update in extras_startup' 91 | call hydro_Ttau_update(id, ierr) 92 | 93 | end subroutine extras_startup 94 | 95 | 96 | integer function extras_start_step(id) 97 | integer, intent(in) :: id 98 | integer :: ierr 99 | type (star_info), pointer :: s 100 | ierr = 0 101 | call star_ptr(id, s, ierr) 102 | if (ierr /= 0) return 103 | extras_start_step = 0 104 | end function extras_start_step 105 | 106 | 107 | ! returns either keep_going, retry, backup, or terminate. 108 | integer function extras_check_model(id) 109 | integer, intent(in) :: id 110 | integer :: ierr 111 | type (star_info), pointer :: s 112 | ierr = 0 113 | call star_ptr(id, s, ierr) 114 | if (ierr /= 0) return 115 | extras_check_model = keep_going 116 | 117 | ! write(*,*) 'called hydro_Ttau_update in extras_check_model' 118 | call hydro_Ttau_update(id, ierr) 119 | 120 | ! if you want to check multiple conditions, it can be useful 121 | ! to set a different termination code depending on which 122 | ! condition was triggered. MESA provides 9 customizable 123 | ! termination codes, named t_xtra1 .. t_xtra9. You can 124 | ! customize the messages that will be printed upon exit by 125 | ! setting the corresponding termination_code_str value. 126 | ! termination_code_str(t_xtra1) = 'my termination condition' 127 | 128 | ! by default, indicate where (in the code) MESA terminated 129 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 130 | end function extras_check_model 131 | 132 | 133 | integer function how_many_extra_history_columns(id) 134 | integer, intent(in) :: id 135 | integer :: ierr 136 | type (star_info), pointer :: s 137 | ierr = 0 138 | call star_ptr(id, s, ierr) 139 | if (ierr /= 0) return 140 | how_many_extra_history_columns = 2 141 | end function how_many_extra_history_columns 142 | 143 | 144 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 145 | integer, intent(in) :: id, n 146 | character (len=maxlen_history_column_name) :: names(n) 147 | real(dp) :: vals(n) 148 | integer, intent(out) :: ierr 149 | type (star_info), pointer :: s 150 | ierr = 0 151 | call star_ptr(id, s, ierr) 152 | if (ierr /= 0) return 153 | 154 | ! note: do NOT add the extras names to history_columns.list 155 | ! the history_columns.list is only for the built-in history column options. 156 | ! it must not include the new column names you are adding here. 157 | 158 | 159 | names(1) = 'alpha' 160 | vals(1) = s% mixing_length_alpha 161 | 162 | names(2) = 'tau_base' 163 | vals(2) = s% tau_base 164 | 165 | end subroutine data_for_extra_history_columns 166 | 167 | 168 | integer function how_many_extra_profile_columns(id) 169 | use star_def, only: star_info 170 | integer, intent(in) :: id 171 | integer :: ierr 172 | type (star_info), pointer :: s 173 | ierr = 0 174 | call star_ptr(id, s, ierr) 175 | if (ierr /= 0) return 176 | how_many_extra_profile_columns = 0 177 | end function how_many_extra_profile_columns 178 | 179 | 180 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 181 | use star_def, only: star_info, maxlen_profile_column_name 182 | use const_def, only: dp 183 | integer, intent(in) :: id, n, nz 184 | character (len=maxlen_profile_column_name) :: names(n) 185 | real(dp) :: vals(nz,n) 186 | integer, intent(out) :: ierr 187 | type (star_info), pointer :: s 188 | integer :: k 189 | ierr = 0 190 | call star_ptr(id, s, ierr) 191 | if (ierr /= 0) return 192 | 193 | ! note: do NOT add the extra names to profile_columns.list 194 | ! the profile_columns.list is only for the built-in profile column options. 195 | ! it must not include the new column names you are adding here. 196 | 197 | ! here is an example for adding a profile column 198 | !if (n /= 1) stop 'data_for_extra_profile_columns' 199 | !names(1) = 'beta' 200 | !do k = 1, nz 201 | ! vals(k,1) = s% Pgas(k)/s% P(k) 202 | !end do 203 | 204 | end subroutine data_for_extra_profile_columns 205 | 206 | 207 | integer function how_many_extra_history_header_items(id) 208 | integer, intent(in) :: id 209 | integer :: ierr 210 | type (star_info), pointer :: s 211 | ierr = 0 212 | call star_ptr(id, s, ierr) 213 | if (ierr /= 0) return 214 | how_many_extra_history_header_items = 0 215 | end function how_many_extra_history_header_items 216 | 217 | 218 | subroutine data_for_extra_history_header_items(id, n, names, vals, ierr) 219 | integer, intent(in) :: id, n 220 | character (len=maxlen_history_column_name) :: names(n) 221 | real(dp) :: vals(n) 222 | type(star_info), pointer :: s 223 | integer, intent(out) :: ierr 224 | ierr = 0 225 | call star_ptr(id,s,ierr) 226 | if(ierr/=0) return 227 | 228 | ! here is an example for adding an extra history header item 229 | ! also set how_many_extra_history_header_items 230 | ! names(1) = 'mixing_length_alpha' 231 | ! vals(1) = s% mixing_length_alpha 232 | 233 | end subroutine data_for_extra_history_header_items 234 | 235 | 236 | integer function how_many_extra_profile_header_items(id) 237 | integer, intent(in) :: id 238 | integer :: ierr 239 | type (star_info), pointer :: s 240 | ierr = 0 241 | call star_ptr(id, s, ierr) 242 | if (ierr /= 0) return 243 | how_many_extra_profile_header_items = 2 244 | end function how_many_extra_profile_header_items 245 | 246 | 247 | subroutine data_for_extra_profile_header_items(id, n, names, vals, ierr) 248 | integer, intent(in) :: id, n 249 | character (len=maxlen_profile_column_name) :: names(n) 250 | real(dp) :: vals(n) 251 | type(star_info), pointer :: s 252 | integer, intent(out) :: ierr 253 | ierr = 0 254 | call star_ptr(id,s,ierr) 255 | if(ierr/=0) return 256 | 257 | names(1) = 'alpha' 258 | vals(1) = s% mixing_length_alpha 259 | 260 | names(2) = 'tau_base' 261 | vals(2) = s% tau_base 262 | 263 | end subroutine data_for_extra_profile_header_items 264 | 265 | 266 | ! returns either keep_going or terminate. 267 | ! note: cannot request retry or backup; extras_check_model can do that. 268 | integer function extras_finish_step(id) 269 | integer, intent(in) :: id 270 | integer :: ierr 271 | type (star_info), pointer :: s 272 | ierr = 0 273 | call star_ptr(id, s, ierr) 274 | if (ierr /= 0) return 275 | extras_finish_step = keep_going 276 | 277 | ! to save a profile, 278 | ! s% need_to_save_profiles_now = .true. 279 | ! to update the star log, 280 | ! s% need_to_update_history_now = .true. 281 | 282 | ! see extras_check_model for information about custom termination codes 283 | ! by default, indicate where (in the code) MESA terminated 284 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 285 | end function extras_finish_step 286 | 287 | 288 | subroutine extras_after_evolve(id, ierr) 289 | integer, intent(in) :: id 290 | integer, intent(out) :: ierr 291 | type (star_info), pointer :: s 292 | ierr = 0 293 | call star_ptr(id, s, ierr) 294 | if (ierr /= 0) return 295 | end subroutine extras_after_evolve 296 | 297 | end module run_star_extras 298 | 299 | -------------------------------------------------------------------------------- /hooks/low_mass_torques/README.md: -------------------------------------------------------------------------------- 1 | # ``low_mass_torques`` 2 | 3 | ## Overview 4 | 5 | These routines implement the wind angular momentum loss schemes of [Kawaler 1988](https://ui.adsabs.harvard.edu/abs/1988ApJ...333..236K/abstract) and 6 | [van Sanders & Pinsonneault](https://ui.adsabs.harvard.edu/abs/2013ApJ...776...67V/abstract) using the ``other_torque`` hook. 7 | The implementation is based on the MESA 2019 summer school lab by [Marc Pinsonneault](https://zenodo.org/record/3374959#.XjmqPC2ZPUI). 8 | These are most relevant to low-mass stars, and notably assume that the star has a surface convection zone. 9 | If you use these routines please cite the relevant publications, as well as the summer school lab with ``doi:10.5281/zenodo.3374959``. 10 | 11 | This contribution is maintained by @adamjermyn. 12 | 13 | ## Usage 14 | 15 | Example inlists and `run_star_extras.f90` are provided for a normal 16 | MESA `star` run in the `star_example` subfolder. 17 | 18 | To use these routines you need to include them in your `run_star_extras.f90`, after 19 | the `contains` statement you'll need 20 | 21 | ````Fortran 22 | 23 | contains 24 | 25 | include 'low_mass_torques/low_mass_torques.inc' 26 | ```` 27 | 28 | In `extras_controls` point you also need 29 | 30 | ````Fortran 31 | subroutine extras_controls(id, ierr) 32 | ... 33 | s% other_torque => low_mass_torques 34 | ... 35 | end subroutine extras_controls 36 | 37 | subroutine extras_startup 38 | ... 39 | include 'low_mass_torques/low_mass_torques_extras_startup.inc' 40 | end subroutine extras_startup 41 | ```` 42 | 43 | Note that `star_example/run_star_extras.f90` includes routines for adding extra history and profile columns which may be of interest. 44 | -------------------------------------------------------------------------------- /hooks/low_mass_torques/low_mass_torques.inc: -------------------------------------------------------------------------------- 1 | subroutine low_mass_torques(id, ierr) 2 | use math_lib 3 | integer, intent(in) :: id 4 | integer, intent(out) :: ierr 5 | type (star_info), pointer :: s 6 | integer :: j, k, k_end, wind_distribution_option, Jdot_option 7 | real(dp) :: jdot, net_I, solar_photosphere_p, solar_tcz 8 | ierr = 0 9 | call star_ptr(id, s, ierr) 10 | if (ierr /= 0) return 11 | 12 | Jdot_option = s% x_integer_ctrl(2) 13 | 14 | 15 | ! If there's a disk, lock to it 16 | if (s% star_age < s% x_ctrl(1)) then 17 | do j=1,s% nz 18 | s% omega(j) = s% x_ctrl(2) 19 | end do 20 | ! Otherwise, find the net torque 21 | else if (Jdot_option == 1) then 22 | jdot = s% x_ctrl(3) * 1.1265d47 * s%omega(1) * s%omega(1) * s%omega(1) ! Constant from Kawaler 1988 23 | else if (Jdot_option == 2) then 24 | jdot = s% x_ctrl(3) * 1.1265d47 * s%omega(1) * pow2(min(s% omega(1), s% x_ctrl(4))) 25 | else if (Jdot_option == 3) then 26 | solar_photosphere_p = 1.12612d5 27 | solar_tcz = 1.09d6 28 | jdot = s% x_ctrl(3) * 5.557d46 * pow(s%r(1) / Rsun, 3d0) * pow(s%m(1) / Msun, -0.22d0) ! True solar torque of 1.3e30 divided by omega_sun^3 29 | jdot = jdot * pow(s%L(1) / Lsun, 0.56d0) 30 | jdot = jdot * pow(photosphere_pressure(id) / solar_photosphere_p, 0.44d0) 31 | jdot = jdot * s%omega(1) * pow2(min(s%omega(1) * s% x_ctrl(5) / solar_tcz, s% x_ctrl(4))) 32 | end if 33 | 34 | ! Distribute the torque 35 | if (s% star_age > s% x_ctrl(1)) then 36 | 37 | wind_distribution_option = s% x_integer_ctrl(1) 38 | 39 | if (wind_distribution_option == 1) then 40 | ! Distribute jdot proportional to i_rot in the top convection zone 41 | 42 | k_end = s% x_integer_ctrl(5) 43 | 44 | ! Catches if the CZ disappeared 45 | if (k_end < 10) then 46 | k_end = 10 47 | else if (k_end > s% nz) then 48 | k_end = s% nz 49 | end if 50 | 51 | ! Figure out how massive the top convection zone is 52 | net_I = 0d0 53 | do k=1,k_end 54 | net_I = net_I + s% i_rot(k)%val * s% dm(k) 55 | end do 56 | 57 | ! Distribute Jdot 58 | do k=1,k_end 59 | s% extra_jdot(k) = -jdot * s% i_rot(k)%val * s% dm(k) / net_I 60 | end do 61 | else if (wind_distribution_option == 2) then 62 | ! Distribute jdot proportional to i_rot in the whole star 63 | net_I = 0d0 64 | do k=1,s% nz 65 | net_I = net_I + s% i_rot(k)%val * s% dm(k) 66 | end do 67 | 68 | do k=1,s% nz 69 | s% extra_jdot(k) = -jdot * s% i_rot(k)%val * s% dm(k) / net_I 70 | end do 71 | end if 72 | 73 | do k=1,s% nz 74 | s% extra_jdot(k) = s% extra_jdot(k) / s% dm(k) 75 | end do 76 | 77 | end if 78 | 79 | 80 | 81 | ! Shoulduse one or the other but not both 82 | s% extra_omegadot(:) = 0 83 | end subroutine low_mass_torques 84 | 85 | ! None of the following functions are called unless you set their 86 | ! function point in extras_control. 87 | 88 | real(dp) function convective_tau(id) 89 | integer, intent(in) :: id 90 | type (star_info), pointer :: s 91 | real(dp) :: conv_tau 92 | integer j, j_cz 93 | integer ierr 94 | 95 | ierr = 0 96 | call star_ptr(id, s, ierr) 97 | if (ierr /= 0) return 98 | 99 | j_cz = 1 100 | do j=2,s%nz 101 | if (s%brunt_N2(j-1) < 1d-8 .and. s% brunt_N2(j) > 1d-8) then 102 | ! Found a lower CZ boundary 103 | j_cz = j 104 | exit ! Leave the loop 105 | end if 106 | if (j == s% nz) then 107 | j_cz = s%nz 108 | end if 109 | end do 110 | 111 | s%x_integer_ctrl(5) = j_cz 112 | 113 | do j=1,s%nz 114 | if (s%r(j)-s%scale_height(j) < s%r(j_cz)) then 115 | conv_tau = s%scale_height(j) / s%conv_vel(j) 116 | exit ! Leave the loop 117 | end if 118 | end do 119 | 120 | convective_tau = conv_tau 121 | end function convective_tau 122 | 123 | real(dp) function photosphere_pressure(id) 124 | integer, intent(in) :: id 125 | type (star_info), pointer :: s 126 | real(dp) :: p_tau, tau23 127 | integer j 128 | integer :: ierr 129 | 130 | ierr = 0 131 | call star_ptr(id, s, ierr) 132 | if (ierr /= 0) return 133 | 134 | tau23 = 2d0 / 3d0 135 | do j=1,s%nz 136 | if (s% tau(j) > tau23) then 137 | if (j == 1) then 138 | ! Extrapolate 139 | p_tau = s% peos(1) * tau23 / s%tau(1) 140 | else 141 | ! Interpolate 142 | p_tau = (s% peos(j) * (s% tau(j) - tau23) + s% peos(j-1) *(tau23 - s% tau(j-1))) & 143 | / (s%tau(j) - s% tau(j-1)) 144 | end if 145 | exit ! Leave the loop 146 | end if 147 | end do 148 | 149 | photosphere_pressure = p_tau 150 | end function photosphere_pressure 151 | -------------------------------------------------------------------------------- /hooks/low_mass_torques/low_mass_torques_extras_startup.inc: -------------------------------------------------------------------------------- 1 | s% x_ctrl(5) = convective_tau(id) 2 | -------------------------------------------------------------------------------- /hooks/low_mass_torques/star_example/inlist_project: -------------------------------------------------------------------------------- 1 | ! inlist to generate a standard 1 solar mass model at the deuterium burning birthline 2 | 3 | ! For the sake of future readers of this file (yourself included), 4 | ! ONLY include the controls you are actually using. DO NOT include 5 | ! all of the other controls that simply have their default values. 6 | 7 | &star_job 8 | 9 | ! begin with a pre-main sequence model 10 | create_pre_main_sequence_model = .true. 11 | 12 | ! save a model at the end of the run 13 | save_model_when_terminate = .true. 14 | save_model_filename = 'simplesolar.model' 15 | 16 | change_initial_net = .true. ! switch nuclear reaction network 17 | new_net_name = 'pp_and_cno_extras.net' 18 | 19 | num_special_rate_factors = 1 20 | reaction_for_special_factor(1) = 'r_c12_ag_o16' 21 | special_rate_factor(1) = 1 22 | filename_of_special_rate(1) = 'r_c12_ag_o16_kunz.txt' 23 | 24 | num_special_rate_factors = 1 25 | reaction_for_special_factor(1) = 'r_n14_pg_o15' 26 | special_rate_factor(1) = 1 27 | filename_of_special_rate(1) = 'r_n14_pg_o15_nacreII.dat' 28 | 29 | set_uniform_initial_composition = .true. 30 | initial_h1 = 0.711552 31 | initial_h2 = 0.0 32 | initial_he3 = 0.000031 33 | initial_he4 = 0.269829 34 | initial_zfracs = 3 35 | 36 | set_initial_model_number = .true. 37 | initial_model_number = 0 38 | 39 | ! save a model at the end of the run 40 | save_model_when_terminate = .true. 41 | save_model_filename = 'final.model' 42 | 43 | ! Rotation 44 | new_rotation_flag = .true. 45 | change_rotation_flag = .true. 46 | set_initial_omega = .true. 47 | new_omega = 9.09025d-6 48 | 49 | ! display on-screen plots 50 | pgstar_flag = .true. 51 | 52 | / !end of star_job namelist 53 | 54 | 55 | &kap 56 | 57 | Zbase = 0.018588 58 | kap_file_prefix = 'OP_gs98' 59 | kap_lowT_prefix = 'lowT_fa05_gs98' ! for lower temperatures. 60 | 61 | / 62 | 63 | &controls 64 | 65 | varcontrol_target = 1.0d-3 ! timestep for structural change, 10x MESA default 66 | 67 | ! starting specifications 68 | initial_mass = 1.4 ! in Msun units 69 | initial_z = 0.018588 70 | 71 | mixing_length_alpha = 1.816711 72 | ! options for energy conservation (see MESA V, Section 3) 73 | energy_eqn_option = 'dedt' 74 | use_gold_tolerances = .true. 75 | 76 | max_age = 2d9 77 | 78 | ! Control disk wind 79 | use_other_torque = .true. 80 | x_ctrl(1) = 3.0e6 ! disk lifetime in years 81 | x_ctrl(2) = 9.090256e-6 ! disk omega in rad/s 82 | x_ctrl(3) = 2.56d0 ! calibration constant for jdot 83 | x_ctrl(4) = 2.86e-5 ! saturation threshold for wind in rad/s 84 | x_integer_ctrl(1) = 1 ! distribute torque 1=scz 2 = whole star 85 | x_integer_ctrl(2) = 3 ! 1 = kawaler 2 = sat kawaler 3 = vsp13 86 | 87 | ! Force uniform rotation 88 | set_uniform_am_nu_non_rot = .true. 89 | uniform_am_nu_non_rot = 1d20 90 | 91 | ! atmosphere 92 | atm_option = 'table' 93 | atm_table = 'photosphere' 94 | 95 | ! atomic diffusion 96 | do_element_diffusion = .false. ! determines whether or not we do diffusion 97 | diffusion_dt_limit = 7d11 ! no element diffusion if dt < this limit (in seconds) 98 | diffusion_T_full_on = 1d3 99 | diffusion_T_full_off = 1d3 100 | T_mix_limit = 3d4 101 | 102 | diffusion_calculates_ionization = .true. 103 | 104 | diffusion_num_classes = 4 ! number of classes of species for diffusion calculations 105 | diffusion_class_representative(1) = 'h1' 106 | diffusion_class_representative(2) = 'he4' 107 | diffusion_class_representative(3) = 'o16' 108 | diffusion_class_representative(4) = 'fe56' 109 | 110 | ! in ascending order. species goes into 1st class with A_max >= species A 111 | diffusion_class_A_max(1) = 2 112 | diffusion_class_A_max(2) = 4 113 | diffusion_class_A_max(3) = 16 114 | diffusion_class_A_max(4) = 10000 115 | 116 | diffusion_use_isolve = .true. 117 | diffusion_rtol_for_isolve = 1d-4 118 | diffusion_atol_for_isolve = 1d-5 119 | diffusion_maxsteps_for_isolve = 1000 120 | diffusion_isolve_solver = 'ros2_solver' 121 | 122 | ! Convective tau initialization 123 | x_ctrl(5) = 0d0 124 | x_integer_ctrl(5) = 0 125 | 126 | / ! end of controls namelist 127 | -------------------------------------------------------------------------------- /hooks/low_mass_torques/star_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010 Bill Paxton 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | 30 | implicit none 31 | 32 | 33 | ! these routines are called by the standard run_star check_model 34 | contains 35 | 36 | include 'low_mass_torques/low_mass_torques.inc' 37 | !include 'standard_run_star_extras.inc' 38 | 39 | subroutine extras_controls(id, ierr) 40 | integer, intent(in) :: id 41 | integer, intent(out) :: ierr 42 | type (star_info), pointer :: s 43 | ierr = 0 44 | call star_ptr(id, s, ierr) 45 | if (ierr /= 0) return 46 | 47 | s% extras_startup => extras_startup 48 | s% extras_check_model => extras_check_model 49 | s% extras_finish_step => extras_finish_step 50 | s% extras_after_evolve => extras_after_evolve 51 | s% how_many_extra_history_columns => how_many_extra_history_columns 52 | s% data_for_extra_history_columns => data_for_extra_history_columns 53 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 54 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 55 | s% job% warn_run_star_extras = .false. 56 | 57 | s% other_torque => low_mass_torques 58 | 59 | end subroutine extras_controls 60 | 61 | integer function how_many_extra_profile_columns(id) 62 | use star_def, only: star_info 63 | integer, intent(in) :: id 64 | integer :: ierr 65 | type (star_info), pointer :: s 66 | ierr = 0 67 | call star_ptr(id, s, ierr) 68 | if (ierr /= 0) return 69 | how_many_extra_profile_columns = 6 70 | end function how_many_extra_profile_columns 71 | 72 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 73 | use star_def, only: star_info, maxlen_profile_column_name 74 | use const_def, only: dp 75 | integer, intent(in) :: id, n, nz 76 | 77 | character (len=maxlen_profile_column_name) :: names(n) 78 | real(dp) :: vals(nz,n) 79 | 80 | integer, intent(out) :: ierr 81 | integer :: k 82 | ierr = 0 83 | 84 | end subroutine data_for_extra_profile_columns 85 | 86 | 87 | integer function how_many_extra_history_columns(id) 88 | integer, intent(in) :: id 89 | integer :: ierr 90 | type (star_info), pointer :: s 91 | ierr = 0 92 | call star_ptr(id, s, ierr) 93 | if (ierr /= 0) return 94 | how_many_extra_history_columns = 0 95 | end function how_many_extra_history_columns 96 | 97 | 98 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 99 | use const_def, only: pi 100 | integer, intent(in) :: id, n 101 | character (len=maxlen_history_column_name) :: names(n) 102 | real(dp) :: vals(n) 103 | integer :: k 104 | integer, intent(out) :: ierr 105 | ierr = 0 106 | end subroutine data_for_extra_history_columns 107 | 108 | 109 | 110 | ! None of the following functions are called unless you set their 111 | ! function point in extras_control. 112 | 113 | 114 | subroutine extras_startup(id, restart, ierr) 115 | integer, intent(in) :: id 116 | logical, intent(in) :: restart 117 | integer, intent(out) :: ierr 118 | type (star_info), pointer :: s 119 | ierr = 0 120 | call star_ptr(id, s, ierr) 121 | if (ierr /= 0) return 122 | include 'low_mass_torques/low_mass_torques_extras_startup.inc' 123 | end subroutine extras_startup 124 | 125 | 126 | ! returns either keep_going, retry, backup, or terminate. 127 | integer function extras_check_model(id) 128 | integer, intent(in) :: id 129 | integer :: ierr 130 | type (star_info), pointer :: s 131 | ierr = 0 132 | call star_ptr(id, s, ierr) 133 | if (ierr /= 0) return 134 | extras_check_model = keep_going 135 | if (.false. .and. s% star_mass_h1 < 0.35d0) then 136 | ! stop when star hydrogen mass drops to specified level 137 | extras_check_model = terminate 138 | write(*, *) 'have reached desired hydrogen mass' 139 | return 140 | end if 141 | 142 | 143 | ! if you want to check multiple conditions, it can be useful 144 | ! to set a different termination code depending on which 145 | ! condition was triggered. MESA provides 9 customizable 146 | ! termination codes, named t_xtra1 .. t_xtra9. You can 147 | ! customize the messages that will be printed upon exit by 148 | ! setting the corresponding termination_code_str value. 149 | ! termination_code_str(t_xtra1) = 'my termination condition' 150 | 151 | ! by default, indicate where (in the code) MESA terminated 152 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 153 | end function extras_check_model 154 | 155 | 156 | 157 | 158 | ! returns either keep_going or terminate. 159 | ! note: cannot request retry or backup; extras_check_model can do that. 160 | integer function extras_finish_step(id) 161 | integer, intent(in) :: id 162 | integer :: ierr 163 | type (star_info), pointer :: s 164 | ierr = 0 165 | call star_ptr(id, s, ierr) 166 | if (ierr /= 0) return 167 | extras_finish_step = keep_going 168 | 169 | ! to save a profile, 170 | ! s% need_to_save_profiles_now = .true. 171 | ! to update the star log, 172 | ! s% need_to_update_history_now = .true. 173 | 174 | ! see extras_check_model for information about custom termination codes 175 | ! by default, indicate where (in the code) MESA terminated 176 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 177 | end function extras_finish_step 178 | 179 | 180 | subroutine extras_after_evolve(id, ierr) 181 | integer, intent(in) :: id 182 | integer, intent(out) :: ierr 183 | type (star_info), pointer :: s 184 | ierr = 0 185 | call star_ptr(id, s, ierr) 186 | if (ierr /= 0) return 187 | end subroutine extras_after_evolve 188 | 189 | end module run_star_extras 190 | 191 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/README.md: -------------------------------------------------------------------------------- 1 | 2 | # ``remove_surface_by_temperature`` 3 | 4 | ## Overview 5 | 6 | These routines enable MESA to remove surface material below a fixed temperature. 7 | This was previously implemented as part of MESA/star/private/remove_shells.f90 in the routine do_remove_surface_by_temperature. 8 | 9 | This contribution is maintained by @adamjermyn. 10 | 11 | ## Usage 12 | 13 | Example inlists and `run_star_extras.f90` are provided for a normal 14 | MESA `star` run in the `star_example` subfolder. 15 | 16 | To use these routines you need to include them in your `run_star_extras.f90`, after 17 | the `contains` statement you'll need 18 | 19 | ````Fortran 20 | 21 | real(dp), parameter :: remove_surface_temperature = (desired temperature) 22 | 23 | contains 24 | 25 | include 'remove_surface_by_temperature/main.inc' 26 | ```` 27 | 28 | In `extras_controls` point you also need 29 | 30 | ````Fortran 31 | subroutine extras_controls(id, ierr) 32 | ... 33 | s% other_remove_surface => remove_surface_by_temperature 34 | ... 35 | end subroutine extras_controls 36 | ```` 37 | 38 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/main.inc: -------------------------------------------------------------------------------- 1 | subroutine remove_surface_by_temperature(id, ierr, k) 2 | integer, intent(in) :: id 3 | integer, intent(out) :: ierr 4 | type (star_info), pointer :: s 5 | integer, intent(out) :: k 6 | call get_star_ptr(id, s, ierr) 7 | if (ierr /= 0) then 8 | write(*,*) 'remove_surface_by_temperature: get_star_ptr ierr', ierr 9 | return 10 | end if 11 | if (remove_surface_temperature <= s% T(1)) return 12 | do k=1,s% nz 13 | if (s% T(k) >= remove_surface_temperature) then 14 | return 15 | end if 16 | end do 17 | ierr = -1 18 | end subroutine remove_surface_by_temperature 19 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/clean: -------------------------------------------------------------------------------- 1 | cd make 2 | make clean 3 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/inlist: -------------------------------------------------------------------------------- 1 | ! this is the master inlist that MESA reads when it starts. 2 | 3 | ! This file tells MESA to go look elsewhere for its configuration 4 | ! info. This makes changing between different inlists easier, by 5 | ! allowing you to easily change the name of the file that gets read. 6 | 7 | &star_job 8 | 9 | read_extra_star_job_inlist1 = .true. 10 | extra_star_job_inlist1_name = 'inlist_project' 11 | 12 | / ! end of star_job namelist 13 | 14 | 15 | &eos 16 | 17 | read_extra_eos_inlist1 = .true. 18 | extra_eos_inlist1_name = 'inlist_project' 19 | 20 | / ! end of eos namelist 21 | 22 | 23 | &kap 24 | 25 | read_extra_kap_inlist1 = .true. 26 | extra_kap_inlist1_name = 'inlist_project' 27 | 28 | / ! end of kap namelist 29 | 30 | 31 | &controls 32 | 33 | read_extra_controls_inlist1 = .true. 34 | extra_controls_inlist1_name = 'inlist_project' 35 | 36 | / ! end of controls namelist 37 | 38 | 39 | &pgstar 40 | 41 | read_extra_pgstar_inlist1 = .true. 42 | extra_pgstar_inlist1_name = 'inlist_pgstar' 43 | 44 | / ! end of pgstar namelist 45 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/inlist_pgstar: -------------------------------------------------------------------------------- 1 | &pgstar 2 | ! see star/defaults/pgstar.defaults 3 | 4 | grid6_win_flag = .true. 5 | 6 | / ! end of pgstar namelist 7 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/inlist_project: -------------------------------------------------------------------------------- 1 | ! inlist to evolve a 15 solar mass star 2 | 3 | ! For the sake of future readers of this file (yourself included), 4 | ! ONLY include the controls you are actually using. DO NOT include 5 | ! all of the other controls that simply have their default values. 6 | 7 | &star_job 8 | ! see star/defaults/star_job.defaults 9 | 10 | ! begin with a pre-main sequence model 11 | create_pre_main_sequence_model = .true. 12 | 13 | ! save a model at the end of the run 14 | save_model_when_terminate = .false. 15 | save_model_filename = '15M_at_TAMS.mod' 16 | 17 | ! display on-screen plots 18 | pgstar_flag = .true. 19 | 20 | / ! end of star_job namelist 21 | 22 | 23 | &eos 24 | ! eos options 25 | ! see eos/defaults/eos.defaults 26 | 27 | / ! end of eos namelist 28 | 29 | 30 | &kap 31 | ! kap options 32 | ! see kap/defaults/kap.defaults 33 | use_Type2_opacities = .true. 34 | Zbase = 0.02 35 | 36 | / ! end of kap namelist 37 | 38 | 39 | &controls 40 | ! see star/defaults/controls.defaults 41 | 42 | ! starting specifications 43 | initial_mass = 15 ! in Msun units 44 | initial_z = 0.02 45 | 46 | ! when to stop 47 | 48 | ! stop when the star nears ZAMS (Lnuc/L > 0.99) 49 | Lnuc_div_L_zams_limit = 0.99d0 50 | stop_near_zams = .true. 51 | 52 | ! stop when the center mass fraction of h1 drops below this limit 53 | xa_central_lower_limit_species(1) = 'h1' 54 | xa_central_lower_limit(1) = 1d-3 55 | 56 | ! wind 57 | 58 | ! atmosphere 59 | 60 | ! rotation 61 | 62 | ! element diffusion 63 | 64 | ! mlt 65 | 66 | ! mixing 67 | 68 | ! timesteps 69 | 70 | ! mesh 71 | 72 | ! solver 73 | ! options for energy conservation (see MESA V, Section 3) 74 | energy_eqn_option = 'dedt' 75 | use_gold_tolerances = .true. 76 | 77 | ! output 78 | 79 | / ! end of controls namelist 80 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/make/makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(MESA_DIR),) 2 | ifeq ($($MESA_DIR_INTENTIONALLY_EMPTY),) 3 | $(error MESA_DIR environment variable is not set) 4 | endif 5 | endif 6 | 7 | STAR = star 8 | 9 | include $(MESA_DIR)/star/work_standard_makefile 10 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/mk: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function check_okay { 4 | if [ $? -ne 0 ] 5 | then 6 | echo 7 | echo "FAILED" 8 | echo 9 | exit 1 10 | fi 11 | } 12 | 13 | cd make; make; check_okay 14 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/re: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | photo_directory=photos 4 | 5 | function most_recent_photo { 6 | ls -t "$photo_directory" | head -1 7 | } 8 | 9 | if [ $# -eq 0 ] 10 | then 11 | photo=$(most_recent_photo) 12 | else 13 | photo=$1 14 | fi 15 | 16 | if [ -z "$photo" ] || ! [ -f "$photo_directory/$photo" ] 17 | then 18 | echo "specified photo does not exist" 19 | exit 1 20 | fi 21 | 22 | echo "restart from $photo" 23 | if ! cp "$photo_directory/$photo" restart_photo 24 | then 25 | echo "failed to copy photo" 26 | exit 1 27 | fi 28 | 29 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 30 | ./star 31 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 32 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/rn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -f restart_photo 4 | 5 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 6 | ./star 7 | date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S" 8 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/src/run.f90: -------------------------------------------------------------------------------- 1 | program run 2 | use run_star_support, only: do_read_star_job 3 | use run_star, only: do_run_star 4 | 5 | implicit none 6 | 7 | integer :: ierr 8 | character (len=32) :: inlist_fname 9 | 10 | ierr = 0 11 | inlist_fname = 'inlist' 12 | 13 | call do_read_star_job(inlist_fname, ierr) 14 | if (ierr /= 0) stop 1 15 | 16 | call do_run_star(inlist_fname) 17 | 18 | end program run 19 | -------------------------------------------------------------------------------- /hooks/remove_surface_by_temperature/star_example/src/run_star_extras.f90: -------------------------------------------------------------------------------- 1 | ! *********************************************************************** 2 | ! 3 | ! Copyright (C) 2010-2019 Bill Paxton & The MESA Team 4 | ! 5 | ! this file is part of mesa. 6 | ! 7 | ! mesa is free software; you can redistribute it and/or modify 8 | ! it under the terms of the gnu general library public license as published 9 | ! by the free software foundation; either version 2 of the license, or 10 | ! (at your option) any later version. 11 | ! 12 | ! mesa is distributed in the hope that it will be useful, 13 | ! but without any warranty; without even the implied warranty of 14 | ! merchantability or fitness for a particular purpose. see the 15 | ! gnu library general public license for more details. 16 | ! 17 | ! you should have received a copy of the gnu library general public license 18 | ! along with this software; if not, write to the free software 19 | ! foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 | ! 21 | ! *********************************************************************** 22 | 23 | module run_star_extras 24 | 25 | use star_lib 26 | use star_def 27 | use const_def 28 | use math_lib 29 | 30 | implicit none 31 | 32 | real(dp), parameter :: remove_surface_temperature = 0.77d4 33 | 34 | ! these routines are called by the standard run_star check_model 35 | contains 36 | 37 | include 'remove_surface_by_temperature/main.inc' 38 | 39 | subroutine extras_controls(id, ierr) 40 | integer, intent(in) :: id 41 | integer, intent(out) :: ierr 42 | type (star_info), pointer :: s 43 | ierr = 0 44 | call star_ptr(id, s, ierr) 45 | if (ierr /= 0) return 46 | 47 | ! this is the place to set any procedure pointers you want to change 48 | ! e.g., other_wind, other_mixing, other_energy (see star_data.inc) 49 | 50 | 51 | ! the extras functions in this file will not be called 52 | ! unless you set their function pointers as done below. 53 | ! otherwise we use a null_ version which does nothing (except warn). 54 | 55 | s% extras_startup => extras_startup 56 | s% extras_start_step => extras_start_step 57 | s% extras_check_model => extras_check_model 58 | s% extras_finish_step => extras_finish_step 59 | s% extras_after_evolve => extras_after_evolve 60 | s% how_many_extra_history_columns => how_many_extra_history_columns 61 | s% data_for_extra_history_columns => data_for_extra_history_columns 62 | s% how_many_extra_profile_columns => how_many_extra_profile_columns 63 | s% data_for_extra_profile_columns => data_for_extra_profile_columns 64 | 65 | s% how_many_extra_history_header_items => how_many_extra_history_header_items 66 | s% data_for_extra_history_header_items => data_for_extra_history_header_items 67 | s% how_many_extra_profile_header_items => how_many_extra_profile_header_items 68 | s% data_for_extra_profile_header_items => data_for_extra_profile_header_items 69 | 70 | s% other_remove_surface => remove_surface_by_temperature 71 | 72 | end subroutine extras_controls 73 | 74 | 75 | subroutine extras_startup(id, restart, ierr) 76 | integer, intent(in) :: id 77 | logical, intent(in) :: restart 78 | integer, intent(out) :: ierr 79 | type (star_info), pointer :: s 80 | ierr = 0 81 | call star_ptr(id, s, ierr) 82 | if (ierr /= 0) return 83 | end subroutine extras_startup 84 | 85 | 86 | integer function extras_start_step(id) 87 | integer, intent(in) :: id 88 | integer :: ierr 89 | type (star_info), pointer :: s 90 | ierr = 0 91 | call star_ptr(id, s, ierr) 92 | if (ierr /= 0) return 93 | extras_start_step = 0 94 | end function extras_start_step 95 | 96 | 97 | ! returns either keep_going, retry, or terminate. 98 | integer function extras_check_model(id) 99 | integer, intent(in) :: id 100 | integer :: ierr 101 | type (star_info), pointer :: s 102 | ierr = 0 103 | call star_ptr(id, s, ierr) 104 | if (ierr /= 0) return 105 | extras_check_model = keep_going 106 | if (.false. .and. s% star_mass_h1 < 0.35d0) then 107 | ! stop when star hydrogen mass drops to specified level 108 | extras_check_model = terminate 109 | write(*, *) 'have reached desired hydrogen mass' 110 | return 111 | end if 112 | 113 | 114 | ! if you want to check multiple conditions, it can be useful 115 | ! to set a different termination code depending on which 116 | ! condition was triggered. MESA provides 9 customizable 117 | ! termination codes, named t_xtra1 .. t_xtra9. You can 118 | ! customize the messages that will be printed upon exit by 119 | ! setting the corresponding termination_code_str value. 120 | ! termination_code_str(t_xtra1) = 'my termination condition' 121 | 122 | ! by default, indicate where (in the code) MESA terminated 123 | if (extras_check_model == terminate) s% termination_code = t_extras_check_model 124 | end function extras_check_model 125 | 126 | 127 | integer function how_many_extra_history_columns(id) 128 | integer, intent(in) :: id 129 | integer :: ierr 130 | type (star_info), pointer :: s 131 | ierr = 0 132 | call star_ptr(id, s, ierr) 133 | if (ierr /= 0) return 134 | how_many_extra_history_columns = 0 135 | end function how_many_extra_history_columns 136 | 137 | 138 | subroutine data_for_extra_history_columns(id, n, names, vals, ierr) 139 | integer, intent(in) :: id, n 140 | character (len=maxlen_history_column_name) :: names(n) 141 | real(dp) :: vals(n) 142 | integer, intent(out) :: ierr 143 | type (star_info), pointer :: s 144 | ierr = 0 145 | call star_ptr(id, s, ierr) 146 | if (ierr /= 0) return 147 | 148 | ! note: do NOT add the extras names to history_columns.list 149 | ! the history_columns.list is only for the built-in history column options. 150 | ! it must not include the new column names you are adding here. 151 | 152 | 153 | end subroutine data_for_extra_history_columns 154 | 155 | 156 | integer function how_many_extra_profile_columns(id) 157 | integer, intent(in) :: id 158 | integer :: ierr 159 | type (star_info), pointer :: s 160 | ierr = 0 161 | call star_ptr(id, s, ierr) 162 | if (ierr /= 0) return 163 | how_many_extra_profile_columns = 0 164 | end function how_many_extra_profile_columns 165 | 166 | 167 | subroutine data_for_extra_profile_columns(id, n, nz, names, vals, ierr) 168 | integer, intent(in) :: id, n, nz 169 | character (len=maxlen_profile_column_name) :: names(n) 170 | real(dp) :: vals(nz,n) 171 | integer, intent(out) :: ierr 172 | type (star_info), pointer :: s 173 | integer :: k 174 | ierr = 0 175 | call star_ptr(id, s, ierr) 176 | if (ierr /= 0) return 177 | 178 | ! note: do NOT add the extra names to profile_columns.list 179 | ! the profile_columns.list is only for the built-in profile column options. 180 | ! it must not include the new column names you are adding here. 181 | 182 | ! here is an example for adding a profile column 183 | !if (n /= 1) stop 'data_for_extra_profile_columns' 184 | !names(1) = 'beta' 185 | !do k = 1, nz 186 | ! vals(k,1) = s% Pgas(k)/s% P(k) 187 | !end do 188 | 189 | end subroutine data_for_extra_profile_columns 190 | 191 | 192 | integer function how_many_extra_history_header_items(id) 193 | integer, intent(in) :: id 194 | integer :: ierr 195 | type (star_info), pointer :: s 196 | ierr = 0 197 | call star_ptr(id, s, ierr) 198 | if (ierr /= 0) return 199 | how_many_extra_history_header_items = 0 200 | end function how_many_extra_history_header_items 201 | 202 | 203 | subroutine data_for_extra_history_header_items(id, n, names, vals, ierr) 204 | integer, intent(in) :: id, n 205 | character (len=maxlen_history_column_name) :: names(n) 206 | real(dp) :: vals(n) 207 | type(star_info), pointer :: s 208 | integer, intent(out) :: ierr 209 | ierr = 0 210 | call star_ptr(id,s,ierr) 211 | if(ierr/=0) return 212 | 213 | ! here is an example for adding an extra history header item 214 | ! also set how_many_extra_history_header_items 215 | ! names(1) = 'mixing_length_alpha' 216 | ! vals(1) = s% mixing_length_alpha 217 | 218 | end subroutine data_for_extra_history_header_items 219 | 220 | 221 | integer function how_many_extra_profile_header_items(id) 222 | integer, intent(in) :: id 223 | integer :: ierr 224 | type (star_info), pointer :: s 225 | ierr = 0 226 | call star_ptr(id, s, ierr) 227 | if (ierr /= 0) return 228 | how_many_extra_profile_header_items = 0 229 | end function how_many_extra_profile_header_items 230 | 231 | 232 | subroutine data_for_extra_profile_header_items(id, n, names, vals, ierr) 233 | integer, intent(in) :: id, n 234 | character (len=maxlen_profile_column_name) :: names(n) 235 | real(dp) :: vals(n) 236 | type(star_info), pointer :: s 237 | integer, intent(out) :: ierr 238 | ierr = 0 239 | call star_ptr(id,s,ierr) 240 | if(ierr/=0) return 241 | 242 | ! here is an example for adding an extra profile header item 243 | ! also set how_many_extra_profile_header_items 244 | ! names(1) = 'mixing_length_alpha' 245 | ! vals(1) = s% mixing_length_alpha 246 | 247 | end subroutine data_for_extra_profile_header_items 248 | 249 | 250 | ! returns either keep_going or terminate. 251 | ! note: cannot request retry; extras_check_model can do that. 252 | integer function extras_finish_step(id) 253 | integer, intent(in) :: id 254 | integer :: ierr 255 | type (star_info), pointer :: s 256 | ierr = 0 257 | call star_ptr(id, s, ierr) 258 | if (ierr /= 0) return 259 | extras_finish_step = keep_going 260 | 261 | ! to save a profile, 262 | ! s% need_to_save_profiles_now = .true. 263 | ! to update the star log, 264 | ! s% need_to_update_history_now = .true. 265 | 266 | ! see extras_check_model for information about custom termination codes 267 | ! by default, indicate where (in the code) MESA terminated 268 | if (extras_finish_step == terminate) s% termination_code = t_extras_finish_step 269 | end function extras_finish_step 270 | 271 | 272 | subroutine extras_after_evolve(id, ierr) 273 | integer, intent(in) :: id 274 | integer, intent(out) :: ierr 275 | type (star_info), pointer :: s 276 | ierr = 0 277 | call star_ptr(id, s, ierr) 278 | if (ierr /= 0) return 279 | end subroutine extras_after_evolve 280 | 281 | end module run_star_extras 282 | 283 | -------------------------------------------------------------------------------- /hooks/try_mesa_contrib.f90: -------------------------------------------------------------------------------- 1 | subroutine try_mesa_contrib 2 | write(*,*) "you're ready to call routines from mesa-contrib" 3 | end subroutine try_mesa_contrib 4 | -------------------------------------------------------------------------------- /hooks/wd_builder/README.md: -------------------------------------------------------------------------------- 1 | # ``wd_builder`` 2 | 3 | ## Overview 4 | 5 | This provides an alternate initial model builder that creates a white 6 | dwarf of a given mass and chemical composition. The initial thermal 7 | structure is roughly approximated as a degenerate isothermal core and 8 | a radiative envelope. The initial model is not in thermal equilibrium 9 | and so there is an initial transient phase lasting a few thermal times 10 | that should be disregarded. 11 | 12 | This contribution was developed by Josiah Schwab (@jschwab). 13 | 14 | ## Usage 15 | 16 | Example inlists and `run_star_extras.f90` are provided for a normal 17 | MESA `star` run in the `star_example` subfolder. 18 | 19 | To use these routines you need to include them in your 20 | `run_star_extras.f90`, after the `contains` statement you'll need 21 | 22 | ````Fortran 23 | include 'wd_builder/wd_builder_def.inc' 24 | 25 | contains 26 | 27 | include 'wd_builder/wd_builder.inc' 28 | ```` 29 | 30 | In `extras_controls` you also need 31 | 32 | ````Fortran 33 | subroutine extras_controls(id, ierr) 34 | ... 35 | s% other_build_initial_model => wd_builder 36 | ... 37 | end subroutine extras_controls 38 | 39 | ```` 40 | 41 | and to set `use_other_build_initial_model = .true.` in your inlist. 42 | 43 | The user is also responsible for providing an implementation for the 44 | subroutine `wd_builder_get_xa` that returns the chemical composition 45 | as a function of mass coordinate. Two example implementations are 46 | provided: one that reads from a file and one that uses a simple 47 | parameterization. 48 | -------------------------------------------------------------------------------- /hooks/wd_builder/star_example/basic_HeCO_composition.dat: -------------------------------------------------------------------------------- 1 | 4 10 2 | 0.000 0.00 0.00 0.98 0.00 0.02 0.00 0.00 0.00 0.00 0.00 3 | 0.001 0.00 0.00 0.98 0.00 0.02 0.00 0.00 0.00 0.00 0.00 4 | 0.002 0.00 0.00 0.00 0.30 0.00 0.68 0.00 0.00 0.02 0.00 5 | 1.000 0.00 0.00 0.00 0.30 0.00 0.68 0.00 0.00 0.02 0.00 6 | -------------------------------------------------------------------------------- /hooks/wd_builder/star_example/inlist_wd_builder: -------------------------------------------------------------------------------- 1 | &star_job 2 | 3 | ! build our own model 4 | create_initial_model = .true. 5 | initial_model_relax_num_steps = 100 6 | 7 | ! this file can be used to specify the composition 8 | relax_composition_filename = 'basic_HeCO_composition.dat' 9 | 10 | ! net choice picks which isos are included 11 | change_net = .true. 12 | new_net_name = 'o18_and_ne22.net' 13 | 14 | ! display on-screen plots 15 | pgstar_flag = .true. 16 | 17 | / ! end of star_job namelist 18 | 19 | &eos 20 | 21 | / ! end of eos namelist 22 | 23 | &kap 24 | 25 | ! opacities 26 | use_type2_opacities = .true. 27 | Zbase = 0.02 28 | 29 | / ! end of kap namelist 30 | 31 | &controls 32 | 33 | ! starting specifications 34 | use_other_build_initial_model = .true. 35 | initial_mass = 0.6 ! in Msun 36 | x_ctrl(1) = 2e8 ! central temperature (K) 37 | x_ctrl(2) = 0.1 ! initial Lcore (Lsun) 38 | 39 | ! turn off burning 40 | eps_nuc_factor = 0 41 | dxdt_nuc_factor = 0 42 | 43 | ! WD atm choice 44 | atm_option = 'table' 45 | atm_table = 'DB_WD_tau_25' 46 | 47 | ! options for energy conservation (see MESA V, Section 3) 48 | energy_eqn_option = 'eps_grav' 49 | use_gold_tolerances = .false. 50 | 51 | / ! end of controls namelist 52 | -------------------------------------------------------------------------------- /hooks/wd_builder/wd_builder_def.inc: -------------------------------------------------------------------------------- 1 | integer, parameter :: i_Tc = 1 2 | integer, parameter :: i_Lc = 2 3 | logical, parameter :: dbg = .true. 4 | 5 | abstract interface 6 | subroutine get_xa_interface(s, q, xa) 7 | use const_def, only: dp 8 | use star_def, only: star_info 9 | type (star_info), pointer :: s 10 | real(dp), intent(in) :: q 11 | real(dp) :: xa(:) 12 | end subroutine get_xa_interface 13 | end interface 14 | 15 | procedure (get_xa_interface), pointer :: wd_builder_get_xa 16 | --------------------------------------------------------------------------------