runNewpoly.py Script Documentation
This Python script serves as a wrapper around a Fortran program named 'newpoly.py', which is used to generate polytropic models of stars. The script includes functionalities to handle command line arguments, format input for the Fortran program, and manage the file environment for the program's execution. It provides features such as estimating effective temperature and luminosity based on input parameters like metal mass fractions and solar mass units, setting up the environment for the Fortran program to run by creating symlinks to specified input and output files, and invoking the Fortran program as a subprocess. The script is designed to facilitate the interaction with the 'newpoly' program by abstracting parameter file formatting and environmental setup tasks, making it easier for users to generate polytropic star models by providing simple command line arguments.
# runNewpoly.py # Thomas M. Boudreaux # Last Modified: May 10th 2021 # python wrapper around newpoly.py fortran file # newpoly generates a polytropic model of a star # this program takes in command line arguments and formates # the namelist file for that program so that it is easier to call import generateNML as gNML import numpy as np import argparse import os def setup_env(inputFile, outputFile): """setup_env desc: setup the enviroment for the fortran program newpoly to run Inputs: - inputFile: (str) path to the input namelist file - outputFile: (str) path to file to save the polytropic model to PreState: N/A PostState: - If fort.11 and fort.12 exist in the local directory remove them - Symlink the inputfile to fort.11 - Symlink the outputfile to fort.12 Returns: bool - True if both symlinks were created sucsessfully - False otherwise """ if os.path.islink("fort.11"): os.remove("fort.11") if os.path.islink("fort.12"): os.remove("fort.12") os.symlink(inputFile, "fort.11") os.symlink(outputFile, "fort.12") if os.path.islink("fort.11") and os.path.islink("fort.12"): return True else: return False def estimate_teff_lum(zz, zsolar, mixlen, sumass): """estimate_teff_lum desc: empirically calibrated relations between metal mass fraction, mixing length, mass and Temperature + Luminosity Inputs: - zz: (float) Metal Mass Fraction - zsolar: (float) Metal mass fraction of the sun - mixlen: (float) Mixing length - sumass: (float) Mass in solar mass units PreState: N/A PostState: N/A Returns (teff: float, lum: float): - (float) teff - estimate log effective temperature in solar units - (float) lum - estimated log luminosity in solar units """ # log(zz/zsolar) ~> [Fe/H] Tadjust = -0.010*np.log(zz/zsolar)/np.log(10) + 0.1*(mixlen-1.9) Ladjust = -0.015*np.log(zz/zsolar)/np.log(10) # Handel stars of mass less than 0.39 solar masses differently # this is about the fully convective boundary if (sumass <= .390): teff = 0.430 * sumass + 3.410 lum = 6.20 * sumass - 1.02 else: teff = 3.64 + (4.0 - sumass) * 0.01 lum = 2.0 + 0.4 * (sumass - 2.0) teff = teff + Tadjust lum = lum + Ladjust return teff, lum def run_program(prog): """run_program desc: call a subprocess of some program Inputs: - prog: (str) some path to some program to instantiate as a subprocess PreState: N/A PostState: - Prog has been run Returns: N/A """ os.popen(prog) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Generate name list files for " "the newpoly program incoperating correct " "isotropic abundances") parser.add_argument("prog", help="path to new poly program", type=str) parser.add_argument("X", help="Hydrogen Mass Fraction", type=float) parser.add_argument("Z", help="Metal Mass Fraction", type=float) parser.add_argument("C", help="Carbon Metal Mass Fraction", type=float) parser.add_argument("N", help="Nitrogen Metal Mass Fraction", type=float) parser.add_argument("O", help="Oxygen Metal Mass Fraction", type=float) parser.add_argument("-Li", help="Lithium Metal Mass Fraction", type=float) parser.add_argument("-Be", help="Berylium Metal Mass Fraction", type=float) parser.add_argument("--sumass", help="mass in solar mass units", type=float, default=1.0) parser.add_argument("--CMIXL", help="Mixing length", type=float, default=1.9126) parser.add_argument("--BETA", help="Beta", type=float, default=1.0) parser.add_argument("--FMASS1", help="FMASS1", type=float, default=9.9e-6) parser.add_argument("--FMASS2", help="FMASS2", type=float, default=0.9999) parser.add_argument("--DDAGE", help="Age?", type=float, default=10000) parser.add_argument("--PN", help="PN", type=float, default=1.5) parser.add_argument("--NLEXCOM", help="! LEXCOM", action="store_false") parser.add_argument("--polyOutput", help="path to save nml file too", default='poly.nml') parser.add_argument("--compName", help="Composition Name to add to output file", default="comp", type=str) args = parser.parse_args() teff, lum = estimate_teff_lum(args.Z, 0.0134, args.CMIXL, args.sumass) eS, eES = gNML.format_elem(args) polynml = gNML.generate_nml(args, eS, eES, args.polyOutput, teff, lum) outputFile = f"m{int(args.sumass*100)}{args.compName}.prems" envOK = setup_env(args.polyOutput, outputFile) if envOK: run_program(args.prog) else: raise OSError("Enviroment not setup correctly! Unit files cannot be found!")