Skip to content

Commit

Permalink
Adding MESA v15140 to AMUSE (#731)
Browse files Browse the repository at this point in the history
Major thanks to @rjfarmer for this.
  • Loading branch information
rjfarmer committed Mar 10, 2022
1 parent ffe1b47 commit 00db063
Show file tree
Hide file tree
Showing 71 changed files with 10,363 additions and 1,546 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 5 additions & 1 deletion examples/textbook/helium_star.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ def main():

star = Particle()
star.mass = 12.0 | units.MSun
stop_radius = 100 | units.RSun
stop_radius = 90 | units.RSun # Avoid the model going through a blue loop

stellar_evolution = MESA()
se_star = stellar_evolution.particles.add_particle(star)

# This method is only really useful if you need a helium star from an exisiting model
# With the new interface you can do: stellar_evolution.pure_he_stars.add_particles(star)
# Which is much faster

print("Evolving a", star.mass, "star with",
stellar_evolution.__class__.__name__, end=' ')
print("until its radius exceeds", stop_radius)
Expand Down
14 changes: 14 additions & 0 deletions examples/textbook/stellar_massloss_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def main(Mstar, z, dmdt):
stellar.parameters.metallicity = z
bodies = Particles(mass=Mstar)
stellar.particles.add_particles(bodies)
stellar = turnon_massloss(stellar)
channel_to_framework = stellar.particles.new_channel_to(bodies)
copy_argument = ["age", "mass", "radius", "stellar_type"]
while stellar.particles[0].stellar_type < Second_Asymptotic_Giant_Branch:
Expand All @@ -49,6 +50,19 @@ def main(Mstar, z, dmdt):
bodies[0].radius, dmdt, bodies[0].stellar_type)
stellar.stop()
###BOOKLISTSTOP2###

def turnon_massloss(stellar):
if stellar.mesa_version == '2208':
return stellar # Mass loss defaults to on in this version
else:
for particle in stellar.particles:
particle.set_control('cool_wind_RGB_scheme','Reimers')
particle.set_control('Reimers_scaling_factor',0.1)
particle.set_control('cool_wind_AGB_scheme','Blocker')
particle.set_control('Blocker_scaling_factor',0.5)
particle.set_control('RGB_to_AGB_wind_switch',10**-4)
return stellar


def new_option_parser():
from amuse.units.optparse import OptionParser
Expand Down
2 changes: 1 addition & 1 deletion src/amuse/codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ def _import_modules():
pass

_import_modules()


1,571 changes: 29 additions & 1,542 deletions src/amuse/community/mesa/interface.py

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/amuse/community/mesa_r15140/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
src/

*.mod
*.o
*.smod
187 changes: 187 additions & 0 deletions src/amuse/community/mesa_r15140/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# standard amuse configuration include
# config.mk will be made after ./configure has run
ifeq ($(origin AMUSE_DIR), undefined)
AMUSE_DIR := $(shell amusifier --get-amuse-dir)
endif
-include ${AMUSE_DIR}/config.mk


GFORTRAN_VERSION?=$(shell $(FC) -v 2>&1 | grep gcc\ version | cut -d\ -f3)
GFORTRAN_MAJOR_MINOR=$(shell echo $(GFORTRAN_VERSION) | cut -s -d'.' -f1,2)
#IFORT_VERSION?=$(shell $(FC) -v 2>&1 | cut -d\ -f2)
#IFORT_MAJOR_MINOR=$(shell echo $(IFORT_VERSION) | cut -s -d'.' -f1,2)
MPIF90 ?= mpif90
MPICC ?= mpicc
FORTRAN ?= gfortran
PYTHON ?= python
FC ?= $(FORTRAN)
export CC ?= gcc
MPIFC+= $(FCFLAGS)
MPICC+= $(CFLAGS)

LAPACK_LIBS ?= -llapack
BLAS_LIBS ?= -lblas

export FC MPIFC MPICC LAPACK_LIBS BLAS_LIBS


SRC_DIR := $(realpath ./src)

MESA_MAKE_DIR=./mesa_reqs
INCLUDE_DIR=./src/mesa/star/make
export MESA_DIR = $(realpath ./src/mesa-r15140)
MESA_LIB=$(MESA_DIR)/lib/libstar.a
WORK_SRC_DIR=./

export OPENMP_FCFLAGS=$(OPENMP_FCFLAG)

CODE_GENERATOR ?= $(AMUSE_DIR)/build.py
DOWNLOAD_FROM_WEB = $(PYTHON) ./download.py
BUILD_DEP = $(PYTHON) ./build-dep.py
PATCHES_DIR=./patches

include $(PATCHES_DIR)/makefile_header_non_mesasdk

all: mesa_worker

ifdef DOWNLOAD_CODES
$(MESA_DIR)/install:
make -C . download
else
$(MESA_DIR)/install:
@echo ""
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo ""
@echo "DOWNLOAD_CODES is not set. MESA will not be downloaded and built."
@echo "If you do want MESA, set DOWNLOAD_CODES to 1."
@echo "bash> export DOWNLOAD_CODES=1"
@echo "csh> setenv DOWNLOAD_CODES 1"
@echo "Note: MESA is quite large (2.5 GB downloaded, 19 GB built) and"
@echo "requires gfortran (version >= 9.0.0)."
@echo ""
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo ""
@make -s --no-print-directory -C . raise_error
endif

download:
$(RM) -Rf src
-mkdir src
$(DOWNLOAD_FROM_WEB)
make -C . patch
make -C . skip_tests
make -C . build_hdf5
make -C . build_ndiff
make -C . build_makedepf90
make -C . build_crmath
make -C . build_crlibm
make -C . build_fpx3_deps
make -C . build_fpx3
make -C . build_lapack95
make -C . install_deps

build_ndiff:
cd $(MESA_DIR)/utils;\
rm -rf ndiff-2.00;\
tar xvf ndiff-2.00.tar.gz;\
cd ndiff-2.00;\
./configure;\
make;\

build_makedepf90:
cd $(MESA_DIR)/utils;\
rm -rf makedepf90-2.8.8;\
tar xvf makedepf90-2.8.8.tar.gz;\
cd makedepf90-2.8.8;\
./configure;\
make;\

build_crmath:
cd $(SRC_DIR)/crmath-1.2;\
make;\

build_crlibm:
cd $(SRC_DIR)/crlibm-1.0beta4;\
./configure --enable-static=yes;\
make;\
make install;\
ar cru libcrlibm.a *.o scs_lib/*.o

build_fpx3:
mv $(SRC_DIR)/fpx3 $(SRC_DIR)/fpx3_folder;\
cp $(SRC_DIR)/fpx3_folder/fpx3 $(SRC_DIR)/fpx3

build_lapack95:
cd $(SRC_DIR)/LAPACK95/SRC;\
mkdir ../lapack95_modules;\
make clean;\
make single_double_complex_dcomplex

build_fpx3_deps:
chmod u+x $(SRC_DIR)/fpx3_deps

build_hdf5:
cd $(SRC_DIR)/hdf5-1.12.0;\
./configure --enable-fortran --enable-fortran2003 --enable-parallel --prefix=$(MESA_DIR) --enable-shared=no;\
make;\
make install

clean:
$(RM) -f *~ *.pyc *.mod *.smod *.o worker_code worker_code.f90 $(MESA_LIB)
$(RM) -f mesa_worker mesa_worker_sockets worker_code-sockets.f90
make -C $(MESA_MAKE_DIR) clean

veryclean: clean
cd $(MESA_DIR); ./clean

distclean: clean
$(RM) -Rf src
$(RM) -Rf src.*
$(RM) -Rf .pc

mesa_worker: worker_code.f90 mesa_interface.o interface.o run_star_extras.o
$(MPIF90) $(FCFLAGS) $(FFLAGS) $(LDFLAGS) $(FCopenmp) $(FS_FLAGS) $^ -o $@ \
$(LOAD_EXTRAS1) $(OTHER_INCLUDES) $(LOAD_MESA_STAR) $(LOAD_EXTRAS) $(FS_LIBS) $(LIBS)

mesa_interface.o: mesa_interface.f90 $(MESA_LIB) run_star_extras.o
$(WORK_COMPILE) -I$(MESA_DIR)/star/make -I./ $<


run_star_extras.o: run_star_extras.f90 $(MESA_LIB)
$(WORK_COMPILE) $<


worker_code.f90: interface.py
$(CODE_GENERATOR) --type=f90 interface.py MESAInterface -o $@


$(MESA_LIB): $(MESA_DIR)/install
mkdir -p $(MESA_DIR)/lib $(MESA_DIR)/include
cd $(MESA_DIR);\
env PATH=$(MESA_DIR)/../:$(PATH) ./install


patch:
mkdir -p $(MESA_DIR)/lib $(MESA_DIR)/include
$(PYTHON) ./patch_files.py
cp $(PATCHES_DIR)/makefile_header_non_mesasdk $(MESA_DIR)/utils/makefile_header

install_deps:
cp ./src/crmath-1.2/libcrmath.a $(MESA_DIR)/lib/.
cp ./src/crmath-1.2/*.mod $(MESA_DIR)/include/.
cp ./src/crmath-1.2/*.smod $(MESA_DIR)/include/.
cp ./src/crlibm-1.0beta4/libcrlibm.a $(MESA_DIR)/lib/.
cp ./src/LAPACK95/lapack95_modules/*.mod $(MESA_DIR)/include/.
cp ./src/LAPACK95/lapack95.a $(MESA_DIR)/lib/liblapack95.a
cp $(MESA_DIR)/utils/makedepf90-2.8.8/makedepf90 $(SRC_DIR)/.
cp $(MESA_DIR)/utils/ndiff-2.00/ndiff $(SRC_DIR)/.

interface.o: interface.f90 $(MESA_LIB)
$(WORK_COMPILE) $<

skip_tests:
#This one should always be skipped
touch $(MESA_DIR)/adipls/skip_test
# We cant guarentee bit-for-bit as we dont control the compiler used
# So everyone has to skip the build tests
touch $(MESA_DIR)/skip_test
134 changes: 134 additions & 0 deletions src/amuse/community/mesa_r15140/download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env python

import subprocess
import os
import sys
import time
import urllib.request
import urllib.parse
import urllib.error
from optparse import OptionParser
import glob
import shutil
import stat

class GetCodeFromHttp(object):
url_template = ''
filename_template = "mesa-r{version}.zip"
version = ""
zip=True
unpack=True

def directory(self):
return os.path.abspath(os.path.dirname(__file__))

def src_directory(self):
return os.path.join(self.directory(), 'src')

def unpack_downloaded_file(self, filename):
print("unpacking", filename)
if self.unpack:
if self.zip:
arguments = ['unzip']
else:
arguments = ['tar','xvf']
arguments.append(filename)
subprocess.call(
arguments,
cwd=os.path.join(self.src_directory())
)
print("done")

def start(self):
try:
os.mkdir('src')
except FileExistsError:
pass

url = self.url_template.format(version=self.version)
filename = self.filename_template.format(version=self.version)
filepath = os.path.join(self.src_directory(), filename)
print("downloading version", self.version, "from", url, "to", filename)
urllib.request.urlretrieve(url, filepath)
print("downloading finished")
self.unpack_downloaded_file(filename)


def make_exectuable(filename):
st = os.stat(filename)
os.chmod(filename, st.st_mode | stat.S_IEXEC)

def get_crmath():
instance = GetCodeFromHttp()
instance.url_template = 'https://github.com/rhdtownsend/crmath/archive/{version}.zip'
instance.filename_template='{version}.zip'
instance.version = 'v1.2'
instance.start()


def get_crlibm():
instance = GetCodeFromHttp()
instance.url_template = 'http://www.astro.wisc.edu/~townsend/resource/download/sdk2/src/crlibm-{version}.tar.gz'
instance.filename_template='crlibm-{version}.tar.gz'
instance.version = '1.0beta4'
instance.zip=False
instance.start()

def get_fpx3deps():
instance = GetCodeFromHttp()
instance.url_template = 'https://raw.githubusercontent.com/rhdtownsend/sdk2/master/profile/common/fpx3/fpx3_deps'
instance.filename_template='fpx3_deps'
instance.version = ''
instance.zip=False
instance.unpack=False
instance.start()

def get_fpx3():
instance = GetCodeFromHttp()
instance.url_template = 'http://www.astro.wisc.edu/~townsend/resource/download/sdk2/src/fpx3.tar.gz'
instance.filename_template='fpx3.tar.gz'
instance.version = ''
instance.zip=False
instance.start()

def get_lapack95():
instance = GetCodeFromHttp()
instance.url_template = 'http://www.astro.wisc.edu/~townsend/resource/download/sdk2/src/lapack95.tgz'
instance.filename_template='lapack95.tar.gz'
instance.version = ''
instance.zip=False
instance.start()

def get_mesa():
instance = GetCodeFromHttp()

if 'AMUSE_LOCAL_COPY_MESA' in os.environ:
instance.url_template = os.environ['AMUSE_LOCAL_COPY_MESA']
else:
instance.url_template = "https://zenodo.org/record/4311514/files/mesa-r{version}.zip"

instance.version='15140'
instance.start()

def get_hdf5():
instance = GetCodeFromHttp()
instance.url_template = "https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.12/hdf5-{version}/src/hdf5-{version}.tar.bz2"
instance.filename_template='hdf-{version}.tar.bz2'
instance.version = '1.12.0'
instance.zip=False
instance.start()


def main():
get_lapack95()
get_crmath()
get_crlibm()
get_fpx3()
get_fpx3deps()
get_hdf5()
get_mesa()



if __name__ == "__main__":
main()
8 changes: 8 additions & 0 deletions src/amuse/community/mesa_r15140/examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
The Astrophysical Multipurpose Software Environment
AMUSE contains a lot of functionality to execute astrophysical experiments.
Look into the interface packages for the interfacing to physical model simulation software.
You can also use AMUSE to convert common data formats.
"""

0 comments on commit 00db063

Please sign in to comment.