1C
2C
3C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
4C PARMIN
5C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
6C 9/22/26 MHP via Claude
7C code changed to remove the MHD equation of state
8C 9/23/26 MHP via Claude
9C code changed to remove the OPAL92 opacity tables
10C 9/23/26 MHP via Claude
11C code changed to remove the Kurucz 1990 opacity tables
12C 9/23/26 MHP via Claude
13C code changed to remove the LAOL89 opacity tables
14C 9/24/26 MHP via Claude
15C code changed to remove the Alexander 1995 opacity tables
16 SUBROUTINE PARMIN(FALEX06,FALLARD,FATM,FFERMI,
17 * * FLIV95,FPATM,FPENV,FPMOD,FPUREZ,FSCVH,
18 * * FSCVHE,FSCVZ,YRECVER,GITHASH)
19C 10/14/26 MHP via Claude
20C code changed to convert COMMON/NEWOPAC/ into NEWOPAC_MOD.
21 USE NEWOPAC_MOD
22C 10/14/26 MHP via Claude
23C code changed to convert COMMON/LABEL/ into LABEL_MOD.
24 USE LABEL_MOD
25C 10/14/26 MHP via Claude
26C code changed to convert COMMON/ACDPTH/ into ACDPTH_MOD.
27 USE ACDPTH_MOD
28C 10/14/26 MHP via Claude
29C code changed to convert COMMON/COMP/ into COMP_MOD.
30 USE COMP_MOD
31C 10/14/26 MHP via Claude
32C code changed to convert COMMON/CCOUT/ into CCOUT_MOD.
33 USE CCOUT_MOD
34C 10/14/26 MHP via Claude
35C code changed to convert COMMON/NMLBYPASS/ into NMLBYPASS_MOD.
36 USE NMLBYPASS_MOD
37C 10/14/26 MHP via Claude
38C code changed to convert COMMON/NMLPAR/ into NMLPAR_MOD.
39 USE NMLPAR_MOD
40C 10/14/26 MHP via Claude
41C code changed to convert COMMON/CONSTANTS/ into CONSTANTS_MOD.
42 USE CONSTANTS_MOD
43C 10/14/26 MHP via Claude
44C code changed to convert COMMON/INTPAR/ into INTPAR_MOD.
45 USE INTPAR_MOD
46C 10/14/26 MHP via Claude
47C code changed to convert COMMON/IOUNITS/ into IOUNITS_MOD.
48 USE IOUNITS_MOD
49C 10/14/26 MHP via Claude
50C code changed to convert COMMON/RUNLOOP/ into RUNLOOP_MOD. A blanket
51C USE imports exactly the names the COMMON declaration made global here,
52C so it cannot change meaning. See runloop_mod.f for the block history
53C and for why the module declares the types the implicit rules supplied.
54 USE RUNLOOP_MOD
55C 10/20/26 MHP via Claude
56C code changed to replace implicit typing with IMPLICIT NONE and
57C explicit declarations.
58 IMPLICIT NONE
59 REAL*8 ALFA,FK,RSCLCM,RSCLM,RSCLX,RSCLZ,SUM_FRAC,WMAX_SUN
60 INTEGER KINDRN,NCMXCK,NKIND
61 LOGICAL*4 LCMXBAD
62
63C PARAMETERS NT AND NG FOR TABULATED SURFACE PRESSURES.
64C JNT 6/2014 ADD NTC AND NGC FOR KURUCZ/CASTELLI SURFACE PRESSURES
65C PARAMETERS NTA AND NGA FOR TABULATED ALLARD MODEL SURFACE PRESSURES.
66
67 CHARACTER*10 YRECVER
68 CHARACTER*20 GITHASH
69 CHARACTER*256 VERFMT
70 CHARACTER*256 FPUREZ
71 CHARACTER*256 DESCRIP(2)
72 CHARACTER*3 ANEWCP,ATMP,AID(12)
73C MHP 10/24 MIXTURE TYPE FOR NEW HEAVY ELEMENT MIXTURE MACHINERY
74 CHARACTER*8 AMIX,AISO,AMIXT(4)
75 REAL*8 ZXMIXT(4),FRAC_CT(4),FRAC_NT(4),FRAC_OT(4)
76 DIMENSION KINDRN(50),RSCLM(50),RSCLX(50),RSCLZ(50),
77 1 1 RSCLCM(50)
78C 9/25/26 MHP via Claude
79C code changed to remove the LISO isochrone-output option
80 CHARACTER*256 FATM
81 CHARACTER*256 FSTCH
82 CHARACTER*256 FALLARD,FSCVH,FSCVHE,FSCVZ
83 CHARACTER*256 FLAST, FFIRST, FFERMI,
84 1 1 FDEBUG, FTRACK, FSHORT, FMILNE, FMODPT,
85 2 2 FSTOR, FPMOD, FPENV, FPATM,
86 3 3 FSNU, FSCOMP
87C 9/25/26 MHP via Claude
88C code changed to add FSOUND, the Csound.dat sound-speed-profile
89C output filename, to the file-name-managed unit system
90 CHARACTER*256 FSOUND
91C 9/24/26 MHP via Claude
92C code changed to remove the Monte Carlo option
93C JVS 02/11 PARAMETERS for command line yrec input file specification
94C and extra acoustic depth (calcad.f) output files
95C CHARACTER*256 FCLCD, YREC1, YREC2, FACAT, FJLAST,FJVS, FJENT, FJDEL
96 CHARACTER*256 FCLCD, YREC1, YREC2
97 !CHARACTER*256 FJLAST
98 CHARACTER*256 CMD ! Shell command composition for system() call
99 INTEGER I, LAST_SLASH_IDX
100C 9/25/26 MHP via Claude
101C code changed to remove dead IACAT, IJVS, IJENT, IJDEL unit
102C reservations
103C 10/14/26 MHP via Claude
104C code changed to drop ICLCD and IJLAST from this declaration. Both are
105C IOUNITS members, and redundantly typing a COMMON member is legal while
106C doing the same to a USE-associated name is rejected:
107C "Symbol 'iclcd' conflicts with symbol from module 'iounits_mod'".
108C IOUNITS_MOD supplies both types. MRK is a genuine local and stays.
109 INTEGER MRK
110C 10/12/26 MHP via Claude
111C code changed to extend COMMON/NMLPAR/ to 234 members, adding the
112C namelist variables that the physics routines read from 27 COMMON
113C blocks which also held derived or working members. Those blocks keep
114C only their non-namelist members; five of them -- NEWMX, VMULT,
115C PMMWIND, CCOUT1 and ENVGEN -- had nothing left and are gone.
116C Derivation-only namelist variables from the same blocks went to
117C COMMON/NMLBYPASS/ instead, not here.
118C
119C Declared identically in all 121 files that hold any of these members.
120C Generated from one member list, so every copy is byte-identical; the
121C linker's 'size of symbol changed' warning is the check that they are.
122C 9/25/26 MHP via Claude
123C code changed to consolidate all I/O logical unit numbers, previously
124C scattered across COMMON/LUOUT/, COMMON/LUNUM/, COMMON/ALEX06/,
125C COMMON/ACDPTH/, COMMON/NEWOPAC/, COMMON/LOPAL95/, COMMON/ATMOS2/,
126C COMMON/ALATM03/, COMMON/OPALEOS/, and COMMON/SCV2/, into a single
127C COMMON/IOUNITS/
128C 9/25/26 MHP via Claude
129C code changed to add ISOUND (Csound.dat unit) to COMMON/IOUNITS/
130C 9/24/26 MHP via Claude
131C code changed to remove dead ILLDAT, IKUR from COMMON/LUNUM/
132C 9/24/26 MHP via Claude
133C code changed to remove dead IDYN from COMMON/LUNUM/
134C 9/25/26 MHP via Claude
135C code changed to remove dead COMMON/LUNUM/ISCOMP (declared,
136C assigned a unit number, but never opened or read anywhere)
137C MHP 8/25 Removed file names from common block
138C COMMON/LUFNM/ FLAST, FFIRST, FRUN, FSTAND, FFERMI,
139C 1 FDEBUG, FTRACK, FSHORT, FMILNE, FMODPT,
140C 2 FSTOR, FPMOD, FPENV, FPATM, FDYN,
141C 3 FLLDAT, FSNU, FSCOMP, FKUR,
142C 4 FMHD1, FMHD2, FMHD3, FMHD4, FMHD5, FMHD6, FMHD7, FMHD8
143C 9/24/26 MHP via Claude
144C code changed to remove the Monte Carlo option
145C 10/12/26 MHP via Claude
146C code changed to drop COMMON/DESC/, which was declared in parmin.f alone.
147C DESCRIP is now simply a local, kept by the blanket SAVE, and remains a
148C CONTROL namelist variable. Character data does not belong in a COMMON
149C block.
150C 10/11/26 MHP via Claude
151C code changed to remove LSCRIB from COMMON/CCOUT/: it was declared
152C positionally in all 17 files sharing this block but never read or
153C written in executable code anywhere, and no namelist file sets it.
154C 10/13/26 MHP via Claude: removed the unused COMMON/CENV/ declaration
155C (no member referenced here; residue of the obsolete-option removals).
156C 9/25/26 MHP via Claude
157C code changed to merge COMMON/CONST/, COMMON/CONST1/, COMMON/CONST2/,
158C and COMMON/CONST3/ into a single COMMON/CONSTANTS/
159C 9/24/26 MHP via Claude
160C code changed to remove dead CMIXL from COMMON/CONST3/; it is now
161C passed as an explicit argument where actually used
162C 10/13/26 MHP via Claude
163C code changed to drop COMMON/CTLIM/; TENV is now derived in envint.f,
164C its only reader, from TENV0 and TENV1.
165C 10/13/26 MHP via Claude: removed the unused COMMON/CTOL/ declaration
166C (no member referenced here; residue of the obsolete-option removals).
167C 7/91 LSEMIC (SEMI-CONVECTION) ADDED TO COMMON BLOCK.
168C 10/13/26 MHP via Claude: removed the unused COMMON/DPMIX/ declaration
169C (no member referenced here; residue of the obsolete-option removals).
170C MHP 10/24 ADDED NEW CONTROLS FOR ALTERING THE CNO MASS FRACTIONS
171C ISOTOPIC RATIOS(C,N,O) AND D/HE3/LI/BE/B ABUNDANCES.
172C THESE CONTROLS ONLY ALTER THE MIXTURE IN THE STARTING MODEL AND ONLY
173C IF THE MODEL IS CHEMICALLY UNEVOLVED. POSTPROCESSING TOOLS SHOULD BE USED FOR THE
174C CORE HE BURNING PHASE.
175c COMMON/NEWCMP/XNEWCP,INEWCP,LNEWCP,LREL,ANEWCP
176C 10/12/26 MHP via Claude
177C code changed to remove COMMON/OPTAB/ entirely. Once OPTOL moved to the
178C consolidated namelist block, every remaining member was write-only:
179C ZSI appeared only in a DATA statement in parmin.f, and IDT and IDD were
180C assigned the constants 15 and 5 in coefft.f, envint.f, physic.f and
181C starin.f and read nowhere in the code. They are leftovers from the
182C removed opacity-table interpolation schemes.
183C MHP 10/24 ADDED STOP CRITERIA FOR CENTRAL H,D,AND HE4
184C DBG 7/92 COMMON BLOCK ADDED TO COMPUTE DEBYE-HUCKEL CORRECTION.
185C 10/13/26 MHP via Claude: removed the unused COMMON/DEBHU/ declaration
186C (no member referenced here; residue of the obsolete-option removals).
187C MHP 10/90 DIFFERENT FC FOR DIFFERENT MECHANISMS INTRODUCED.
188C ALSO OPTION FOR SMOOTHING VELOCITIES FOR LENGTH SCALE CALCULATIONS.
189C MHP 5/90 ADD COMMON BLOCK FOR GRAVITATIONAL SETTLING.
190C MHP 5/90 ADD COMMON BLOCK FOR NEW TREATMENT OF
191C ENTROPY TERM(LNEWS),AND THE CALCULATION
192C OF SOLAR NEUTRINOS(LSNU).ALSO ALLOWS A FOURTH LEVEL OF ITERATION(NITER4).
193C MHP 7/91 ADDED COMMON BLOCK FOR NUMERICAL PARAMETERS IN KEMCOM.
194C YCK >>> OPAL95
195 CHARACTER*256 FLIV95
196C MHP 8/25 Removed character file names from common block
197C <<< YCK
198C MHP 6/90 ADDITIONAL COMMON BLOCK FOR SETTLING.
199C GES 6/15 NEW COMMON BLOCK FOR LIGHT DIFFUSION AND NEW DIFF ROUTINE.
200C DBG PULSE
201C 10/13/26 MHP via Claude
202C code changed to drop COMMON/PULSE/, declared here but never used.
203C DBG PULSE OUT 7/92
204C VARIABLES USED TO CONTROL OUTPUT OF PULSATION MODELS. MODEL
205C OUTPUT AFTER HAS TRAVELED POMAX IN HR DIAGRAM
206C LPOUT AND POMAX ADDED TO CONTROL COMMON BLOCK, REST IN PHYSICS
207C 10/13/26 MHP via Claude: removed the unused COMMON/ATMOS/ declaration
208C (no member referenced here; residue of the obsolete-option removals).
209C 10/13/26 MHP via Claude: removed the unused COMMON/ATMOS2/ declaration
210C (no member referenced here; residue of the obsolete-option removals).
211C JMH
212C JNT 6/14 SAME AS ATMOS2 BUT FOR KURUCZ/CASTELLI2004 ATMOSPHERES
213C 10/13/26 MHP via Claude: removed the unused COMMON/ATMOS2C/ declaration
214C (no member referenced here; residue of the obsolete-option removals).
215C 9/06 GN --- New neutrino loss common block
216C KC 2025-05-30 reordered common block elements
217C COMMON/NULOSS/LNULOS1,DSNUDT,DSNUDD
218C 10/13/26 MHP via Claude
219C code changed to remove COMMON/NULOSS/: engeb.f assigns DSNUDT and
220C DSNUDD and nothing reads them, in engeb.f or anywhere else, so they are
221C now plain locals there. parmin.f declared the block without using it.
222C MHP 1/93 ADD OPTION TO AUTOMATICALLY CALIBRATE SOLAR MODEL.
223C COMMON/CALS2/TOLL,TOLR,LCALS
224C MHP 6/13 ADD OPTION TO CALIBRATE SOLAR Z/X, SOLAR Z/X, SOLAR AGE
225C DBG 7/92 ADDED DEBYE HUCKEL PARAMETERS TO NAMELIST, ETADH0, ETADH1
226
227C 10/13/26 MHP via Claude: removed the unused COMMON/CALSTAR/ declaration
228C (no member referenced here; residue of the obsolete-option removals).
229C OPAL eos
230 CHARACTER*256 FcondOpacP,FOPALE06
231C MHP 8/25 Remove file names from common blocks
232C 9/24/26 MHP via Claude
233C code changed to remove the OPAL 1995/2001 equations of state
234C OPACITY COMMON BLOCKS - modified 3/09
235C 9/23/26 MHP via Claude
236C code changed to remove the OPAL92 opacity tables
237C 9/23/26 MHP via Claude
238C code changed to remove the Kurucz 1990 opacity tables
239C 9/23/26 MHP via Claude
240C code changed to remove the LAOL89 opacity tables
241C 9/24/26 MHP via Claude
242C code changed to remove the Alexander 1995 opacity tables
243C 9/24/26 MHP via Claude
244C code changed to remove dead opacity-table Z-value inputs
245C 9/24/26 MHP via Claude
246C code changed to merge COMMON /MISCOPAC/ and COMMON/NWLAOL/ into
247C COMMON /NEWOPAC/
248 CHARACTER*256 FALEX06
249C 10/13/26 MHP via Claude: removed the unused COMMON/CROSS/ declaration
250C (no member referenced here; residue of the obsolete-option removals).
251C 10/12/26 MHP via Claude
252C code changed to merge COMMON/NEWPARAM/, COMMON/NEWCROSS/ and
253C COMMON/XSECT/ into a single COMMON/NMLBYPASS/, declared here, in
254C remap.f and in starin.f.
255C
256C These are namelist variables that exist only to set other quantities,
257C or that are reserved for future development; none is read by the wider
258C code. Keeping them in their own block keeps them OUT of the single
259C consolidated namelist block being built, so that block holds only
260C variables the physics routines actually consume. starin.f declares it
261C although it uses none of them yet, so the isotope and cross-section
262C machinery there can reach them without reopening this layout.
263C
264C Member order is NEWPARAM, then NEWCROSS, then XSECT, and the three
265C declarations are generated from one list so all files agree.
266C 10/13/26 MHP via Claude: removed the unused COMMON/SCVEOS/ declaration
267C (no member referenced here; residue of the obsolete-option removals).
268C 10/13/26 MHP via Claude: removed the unused COMMON/DISK/ declaration
269C (no member referenced here; residue of the obsolete-option removals).
270C MHP 3/99 ADDED FLAG TO TREAT THE ENTIRE STAR AS 'CONVECTIVE'
271C FOR ANGULAR MOMENTUM PURPOSES.
272C JNT 2025/09/04 ADD IMPJMOD TO SOLID
273C FROM JNT 05/15 add IMPJMOD (impose J model) which controls angular momentum
274C coupling (0=no effect, 1=solid body rotation, 2= solid body core decoupled from surface cz
275C decoupled from surface cz, 3=solid body core coupled to surface cz)
276C MHP 10/01 ADDED COMMON BLOCK FOR MASS LOSS/ACCRETION
277C mhp 8/10 added option to scale mass loss rate by rotation; requires rotating model
278C MHP 2/12 MOVED INTO PMM TORQUE MODEL, RETAINED MDOT SWITCH
279C KC 2025-05-30 reordered common block elements
280C COMMON/MASSCHG3/LSOLWIND,DMSUN,DMWSUN,DMWMAX
281C COMMON/MASSCHG3/DMSUN,DMWSUN,DMWMAX,LSOLWIND
282CFD 10/09 ADDED COMMON BLOCK FOR EXTRA MIXING. IT MIMIC SOME MIXING BY AFFECTING
283C THE SETTLING COEFFICIENT DIRECTLY (in setup_grsett.f)
284C JVS 02/11 Acoustic depth calc common block
285C KC 2025-05-30 reordered common block elements
286C COMMON/ACDPTH/TAUCZN,DELADJ(JSON),TAUHE, TNORM, TCZ, WHE, ICLCD,
287C 9/25/26 MHP via Claude
288C code changed to remove dead IACAT, IJVS, IJENT, IJDEL unit
289C reservations from COMMON/ACDPTH/ (declared but never opened anywhere)
290C *LCLCD, AGEOUT(5), IACAT, IJLAST, LJLAST, LJWRT, LADON,LAOLY, IJVS,
291C JVS END
292C JVS 04/14 Common block for additional timestep governors
293C MHP 02/12 NEW PARAMETERIZATION OF ANGULAR MOMENTUM AND MASS LOSS
294C FROM MAGNETIZED SOLAR-LIKE WINDS
295 CHARACTER*3 AWIND
296C KC 2025-05-30 reordered common block elements
297C COMMON/PMMWIND/AWIND,LMWIND,LROSSBY,LBSCALE,PMMA,PMMB,PMMC,PMMD,PMMM,
298C * PMMJD,PMMMD,PMMSOLP,PMMSOLW,PMMSOLTAU
299C 10/12/26 MHP via Claude
300C code changed to remove the trailing CHARACTER member AWIND from
301C COMMON/PMMWIND/. Character data does not belong in a COMMON block, and
302C AWIND is referenced in executable code only here, where it selects the
303C wind law ('K97'/'V13') below; the other four files declaring this block
304C never used it. AWIND stays a PHYSICS namelist variable and is now a
305C local, kept across calls by the blanket SAVE. Being last, its removal
306C moves no other member.
307C MHP 8/17 ADDED EXCEN, C_2 TO COMMON BLOCK FOR MATT ET AL. 2012 CENT. TERM
308C 10/13/26 MHP via Claude
309C code changed to retire COMMON/CWIND/. Its namelist members moved to the
310C consolidated block earlier, leaving two. C_2 is a constant, set once in
311C parmin.f, so it is now the last member of COMMON/CONSTANTS/ -- appended
312C there rather than inserted, and added to every declaration so the block
313C keeps one size; parmin.f DATA-initializes CLSUN and CRSUN, so a short
314C declaration anywhere would be the OP95INTERP hazard again. It may
315C eventually become a namelist variable. STRUCTFACTOR, the loss-law
316C prefactor, is computed by AMCALC and read by its own two callers,
317C mwind.f and mcowind.f, so it is now an AMCALC output argument.
318C CREATE A NEW COMMON BLOCK FOR OVERTURN TIMESCALE THINGS (PPHOT,TAUCZ,LNEWTCZ)
319C 10/13/26 MHP via Claude: removed the unused COMMON/OVRTRN/ declaration
320C (no member referenced here; residue of the obsolete-option removals).
321C MHP 02/12 PERMIT CONSTANT DIFFUSION COEFFICIENT
322C KC 2025-05-30 reordered common block elements
323C COMMON/MAG/LCODM,CODM
324C
325C G Somers 6/14 ALLOW VARIABLE LI/BE DESTRUCTION CROSS SECTIONS
326C G Somers END
327C 10/13/26 MHP via Claude
328C code changed to replace COMMON/VERSION/ with explicit arguments. These
329C are CHARACTER, which does not belong in a COMMON block; SETVERSION sets
330C them and parmin.f is the only reader, so main.f now holds them and
331C passes them to both.
332 SAVE
333C
334C SPLIT NAMELIST INTO TWO: CONTROL and PHYSICS
335 NAMELIST /CONTROL/
336 * * CMIXLA, CALSOLAGE, CALSOLZX,
337 * * DESCRIP,
338 * * ENDAGE,
339 * * FPUREZ,
340 * * FLAST, FFIRST, FFERMI, FDEBUG, FTRACK, FSHORT, FSTCH,
341 * * FMILNE, FMODPT, FSTOR, FPMOD, FPATM, FPENV,
342 * * FSNU, FSCOMP, FATM, FSOUND,
343 * * FALLARD, FSCVH, FSCVHE, FSCVZ, FLIV95,
344 * * IPVER, ITRVER,
345 * * KINDRN,
346 * * LDEBUG, LCORR, LMILNE, LTRACK, LSTORE, LFIRST,
347 * * LSTPCH, LSTCH,
348C G Somers 11/14
349 * * LSTATM,LSTENV,LSTMOD,LSTPHYS,LSTROT,
350C G Somers END
351 * * LPULSE, LZRAMP, LTEFF, LCALST, LPUREZ,
352C MHP 9/24 add LCALSOLZX to namelist
353C 9/25/26 MHP via Claude
354C code changed to remove the LISO isochrone-output option
355 * * LRWSH, LSENV0A, LPOUT,LCALS,LCALSOLZX,
356 * * LOPAL95,
357 * * NPOINT,
358 * * NPENV, NPRTMOD, NPRTPT, NUMRUN, NMODLS,
359 * * POA, POB, POC, POMAX,
360 * * RSCLM, RSCLX, RSCLZ, RSCLCM, RSCLZC, RSCLZM1, RSCLZM2,
361 * * SETDT, SENV0A,STEFF,SR,
362 * * TOLR, TOLL,TOLZ,
363 * * XENV0A, XLS, XLSTOL,
364 * * ZENV0A,
365C 9/24/26 MHP via Claude
366C code changed to remove dead opacity-table Z-value inputs
367 * * ZOPAL951,
368C 9/24/26 MHP via Claude
369C code changed to remove the OPAL 1995/2001 equations of state
370 * * FcondOpacP,FOPALE06,FALEX06,LALEX06,
371C MHP 10/24 ADDED END_DCEN,END_XCEN,END_YCEN VECTORS TO NML1, USED IN MAIN
372C MHP 10/24 ADDED HEAVY ELEMENT MIXTURE CONTROLS TO NML1,USED IN STARIN
373C 10/27/26 MHP via Claude: added L_ZERODT_PREMS, used in MAIN
374 * * END_DCEN,END_XCEN,END_YCEN,L_ZERODT_PREMS,ISETMIX,ISETISO,
375 * * AMIX,AISO,FRAC_C,FRAC_N,FRAC_O,R12_13,R14_15,R16_17,R16_18,ZXMIX,
376 * * XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,XBE9_INI,XB10_INI,XB11_INI
377C
378 NAMELIST /PHYSICS/
379 * * ATMMIN, ATMBEG, ATMERR, ATMMAX, ATMD0, ANEWCP, ATMP, ACFPFT,
380 * * ATIME, ALPHAC, ALPHAE, ALFA, ALPHAM, ATMSTP, ABSTOL, BETAC,
381 * * CMIN, CLSUN, CRSUN,
382 * * DPENV, DTDIF, DTWIND, DJOK, DT_GS,
383 * * ENVERR, ENVMAX, ENVMIN, ENVBEG, ENVSTP,ETADH0,ETADH1,
384 * * FCORR0, FCORRI, FK, FW, FC, FO, FMU, FES,
385 * * FCORE, FGSF, FSS, FESC, FSSC, FGSFC, FGRY, FGRZ,
386 * * GRTOL,
387 * * HTOLER, HPTTOL,
388 * * ITFP1, ITFP2, IMAX, ITDIF1, ITDIF2, IES, IGSF, IMU, ILAMBDA,
389 * * KTTAU, KEMMAX,
390 * * LVFC, LDIFAD, LNOJ, LNEWDIF, LDIFY, LDIFZ, LDIFLI, LSNU, LDH,
391 * * LNEWCP, LKUTHE, LOVSTC, LOVSTE, LOVSTM, LOVMAX,
392 * * LEXCOM, LROT, LNEW0, LINSTB, LWNEW, LJDOT0, LPTIME,LADOV,LTRIST,
393 * * LENVG, LNULOS1, LTHOUL, LTHOULFIT,
394 * * LCORE, LSEMIC, LNEWS,
395 * * MCORE,
396 * * NITER1, NITER2, NITER3, NITER4, NUSE, NITER_GS,
397 * * OPTOL,
398 * * RCRIT, RELTOL,
399 * * STOLR0,
400 * * TCUT, TSCUT, TENV0, TENV1, TGCUT, TRIDT, TRIDL,
401 * * TOLLAOL,
402 * * VNEW,
403 * * WALPCZ, WNEW, WEAKSCREENING,
404 * * XNEWCP, XMIN,
405 * * YMIN, TMOLMIN,TMOLMAX,
406 * * SSTANDARD,LSCV,
407 * * LDISK,TDISK,PDISK,WMAX,LSOLID,IMPJMOD, !JNT 09/2025 FOR 05/15
408 * * DMDT0,FCZDMDT,FTOTDMDT,COMPACC,CREIM,LREIMER,LMDOT,
409 * * LcondOpacP,LOPALE06,LNumDeriv,
410 * * ALATM_FeH,ALATM_Alpha,LALTPTau100,! For new Allard Atmospheres
411 * * CSTMIXING, CSTDIFFMIX, !CFD oct2009 To mimic mixing(reduce settling)
412C 10/8/26 MHP via Claude
413C code changed to remove LPMM: confirmed unused (not in any COMMON
414C block, no conditional anywhere in the code references it, and its
415C own DATA default was already commented out), so it had zero effect
416C on any run. The PMMA/PMMB/PMMC/PMMD/PMMM/PMMJD/PMMMD
417C parameters below remain live, used under the LMWIND option.
418C 10/11/26 MHP via Claude
419C code changed to remove PMMWMAX: like LPMM, it was in no COMMON
420C block, had no DATA default, and was referenced nowhere in the code,
421C so setting it had no effect. No namelist file sets it.
422 * * LSOLWIND,LMWIND,LROSSBY,LBSCALE,
423 * * AWIND,PMMA,PMMB,PMMC,PMMD,PMMM,PMMJD,PMMMD,
424C MHP 8/17 ADDED WMAX_SUN
425 * * PMMSOLP,PMMSOLW,PMMSOLTAU,LCODM,CODM,WMAX_SUN,
426C G Somers 6/14
427 * * XSLI6,XSLI7,XSBE91,XSBE92,XSBE93,
428 * * LXLI6,LXLI7,LXBE91,LXBE92,LXBE93,
429 * * SLI6,SLI7,SBE91,SBE92,SBE93,LNEWNUC,
430 * * SPOTF, SPOTX, LSDEPTH,
431C G Somers END
432C MHP 09/14 ADDED CROSS SECTIONS
433 * * S0_1_1,S0_3_3,S0_3_4,S0_1_12,S0_1_13,S0_1_14,S0_1_16,
434 * * S0_PEP,S0_1_BE7E,S0_1_BE7P,S0_HEP,S0_1_15_C12ALP,S0_1_15_O16,
435 * * S0P_1_1,S0P_3_3,S0P_3_4,S0P_1_12,S0P_1_13,S0P_1_14,
436 * * S0P_1_16,S0PP_1_12,S0PP_1_13,S0PP_1_16,S0P_1_BE7P,S0PP_1_BE7P,
437 * * FLAG_DX,FLAG_DW,FLAG_DZ,LSTRUCT_TIME,
438 * * TIME_CORE_MIN,TIME_DL,TIME_DP,TIME_DR,TIME_DT,TIME_DW_GLOBAL,
439 * * TIME_DW_MIX,TIME_DX_CORE_FRAC,TIME_DX_CORE_TOT,TIME_DX_SHELL,
440 * * TIME_DX_TOTAL,TIME_DY_CORE_FRAC,TIME_DY_CORE_TOT,TIME_DY_SHELL,
441 * * TIME_DY_TOTAL,TOL_CZBASE_FINE_WIDTH,TOL_DL_MAX,TOL_DM_MAX,
442 * * TOL_DM_MIN,TOL_DP_CORE_MAX,TOL_DP_CZBASE_MAX,TOL_DP_ENV_MAX,
443 * * TOL_DX_MAX,TOL_DZ_MAX,TIME_MAX_DT_FRAC,LNEWVARS,
444C G Somers 3/17 USE NEW OVERTURN TIMESCALE CALC?
445 * * LNEWTCZ, LCALCENV
446C
447C 10/8/26 MHP via Claude
448C code added: an output-only NAMELIST (never READ, only WRITTEN) for
449C variables that are derived/overridden after PHYSICS and CONTROL are
450C read in, so their effective (post-derivation) values can be echoed
451C to .short alongside the raw namelists, without a hand-written
452C FORMAT per variable. Excludes purely incidental I/O bookkeeping
453C (e.g. CMD, FCLCD, ICLCD, MRK, LAST_SLASH_IDX).
454 NAMELIST /DERIVED/
455 * * CLN, CC13, CC23,
456 * * CONSTFACTOR, EXCEN, EXL, EXM, EXMD, EXPR, EXR, EXTAU, EXW, WMAX,
457 * * LDIFY, LDIFZ, LTHOUL, LTHOULFIT, LNEW0, LNEWDIF, ILAMBDA,
458 * * SLI6, SLI7, SBE91, SBE92, SBE93, FRAC_C, FRAC_N, FRAC_O,
459 * * ZXMIX, SUM_FRAC, LISOTOPE, LMIXTURE, INEWCP,
460C 10/13/26 MHP via Claude
461C code changed to drop CMIXL from the output-only DERIVED namelist. The
462C mixing length actually used is the scalar CMIXL that main.f reads out of
463C the per-run vector CMIXLA at CMIXL = CMIXLA(NK), then passes on as an
464C explicit argument. PARMIN is called once, before the run loop, so it
465C has no NK and cannot know that value: its own CMIXL never leaves this
466C routine and keeps its DATA default, so the echo reported 1.4 no matter
467C what the namelist asked for -- 1.4 against an actual 1.797279, for
468C instance. CMIXLA is echoed with the CONTROL namelist, with the real
469C per-run values, so nothing is lost by removing this line.
470 * * LREL, KTTAU0, LTTAU
471C
472C DBG DATA CARDS FOR THE RUN PARAMETERS
473C 9/24/26 MHP via Claude
474C code changed to remove the Monte Carlo option
475c Changed slightly 3He-3He on 9/25/97 to take account of the S'.
476c Previously (6/16/97) used S at Gamow Peak. Agrees with Workshop paper.
477c
478C MHP 7/93 VARIABLE FC OPTION
479C MHP 9/94 COMBINED DIFFUSION/ADVECTION OPTION
480C MHP 9/93
481 DATA KINDRN/50*1/
482C MHP 10/24 ADDED NEW DEFAULTS FOR END CONDITIONS ON CENTRAL D,X,Y
483 DATA RSCLM, RSCLX, RSCLZ, RSCLCM/50*0.0, 50*0.0, 50*0.0, 50*0.0/
484 DATA AID/'HE3','C12','C13','N14','N15','O16','O17','O18','H2 ',
485 * *'LI6','LI7','BE9'/
486C 10/14/26 MHP via Claude
487C code changed to move DATA STOLR0,IMAX,NUSE/1.0D-3,11,7/ into
488C INTPAR_MOD as initializers. DATA on a USE-associated name is rejected,
489C so the defaults had to move with the block. Same effect: all three are
490C PHYSICS namelist variables, and the module initializer is applied once
491C at load time, before PARMIN runs and before the namelist read.
492 DATA ANEWCP/' '/
493C 10/8/26 MHP via Claude
494C code changed to add a blank default for ATMP: it had no DATA
495C statement anywhere, so its storage was zero-initialized to NUL
496C bytes rather than blanks. Harmless as long as nothing echoed it
497C (IF(ATMP.EQ.'ABS') at line ~1173 just evaluates false either way,
498C matching the LREL=.TRUE. default), but the new NML=PHYSICS echo
499C writes it out verbatim, and raw NUL bytes turned .short into a
500C binary-looking file. Blank matches the "not 'ABS'" default.
501 DATA ATMP/' '/
502C MHP 10/24 ADDED NEW MIXTURE CONTROL ISETISO CONTROLS CNO ISOTOPE RATIOS AND
503C LIGHT ELEMENT ABUNDANCES D,HE3,LI6,LI7,BE9,B10,B11 (1=USED)
504C ISETMIX CONTROLS C+N+O MASS FRACTIONS (1=USED)
505C AMIX AND AISO ARE STRINGS IDENTIFYING EITHER A PRESET MIXTURE OR A CUSTOM ONE ('CUS')
506C SUPPORTED AMIX AT PRESENT ARE 'GS98','AAG21',M22M','M22P'. SUPPORTED AISO IS 'L21'.
507C FOR A CUSTOM MIXTURE YOU CAN ENTER INDIVIDUAL VALUES.
508C TO BE ADDED - AMIX FROM ATOMIC OPACITY TABLES (INEWMIX=2) AND OTHER MIXTURES/ISOTOPES
509 DATA AMIX, AISO/'GS98', 'L21'/
510C L21 DEFAULT ISOTOPE DATA LODDERS ET AL. 2021 SSRV 217,44
511C GS98 DEFAULT CNO FRACTIONS OF METALS GREVESSE&sAUVAL 1998 SSRV 85,161
512C MHP 10/24 DATA FOR CNO FRACTIONS AND Z/X OF DIFFERNT SOLAR MIXTURES.
513C AMIXT IS THE LIST OF IDS,EACH OF WHICH HAS A ZX AND CNO FRACS
514C ENTRY 1 =GS98(IN PARMIN),2=ASPLUND ET AL. 2021 A&A 653,141
515C 3,4=MAGG ET AL. 2021 (MET,PHOT) A&A 661,140
516 DATA AMIXT,ZXMIXT,FRAC_CT,FRAC_NT,FRAC_OT/'GS98','AAG21',
517 * * 'M22P','M22M',0.02292D0,0.0187D0,0.0225D0,0.0226D0,
518 * * 0.172148D0,0.184156D0,0.19239D0,0.191425D0,
519 * * 0.050426D0,0.050344D0,0.059012D0,0.058716D0,
520 * * 0.468195D0,0.416592D0,0.415631D0,0.413545D0/
521C ATIME(13) was orginally = 1.5.
522C JVS 04/14
523C 10/15/26 MHP via Claude
524C code changed to remove DATA CMIXL/1.4D0/. PARMIN's own CMIXL is a local
525C that nothing reads -- ifort reports it as unused -- and it has been dead
526C since CMIXL was dropped from the output-only DERIVED namelist on
527C 10/13/26. The mixing length the code actually uses is the scalar
528C main.f:382 takes from the per-run vector as CMIXL = CMIXLA(NK), so a
529C default here could never reach the run; keeping one would only suggest
530C otherwise. An illegal CMIXLA is now trapped below instead.
531C DATA DPENV,LNSTDMX,LOVSTC,ALPHAC,LOVSTE,ALPHAE, LOVSTM, ALPHAM
532C */1.0D0,.FALSE.,.FALSE., 0.0D0, .FALSE.,0.0D0, .FALSE., 0.0/
533C JVS 07/13
534C END JVS
535 DATA ALFA, FK/1.5D0, 1.0D0/
536C MHP 8/17 INITIALIZED WMAX_SUN
537 DATA WMAX_SUN/1000.0/
538C DBG PULSE DATA CARD FOR PULSATION
539C 10/14/26 MHP via Claude
540C code changed to move DATA CLSUN,CRSUN/3.8515D33,6.9598D10/ into
541C CONSTANTS_MOD as initializers, since DATA on a USE-associated name is
542C rejected. Same effect: both are PHYSICS namelist variables, and the
543C module initializer is applied at load time, before this routine runs
544C and before the namelist read. CLSUNL and CRSUNL are derived from them
545C later, in setups.f.
546C DBG If LCORE is TRUE then calculate shells interior to start up
547C model's inner most shell.
548C MHP 5/90 NEW DATA STATEMENTS FOR NEW PARAMETERS
549C DBGLAOL
550C DBG 11/11/91
551C 9/25/26 MHP via Claude
552C code changed to add a default for FSOUND matching the previous
553C hardcoded Csound.dat behavior; overridable via the CONTROL namelist
554 DATA FSOUND/'Csound.dat'/
555C 10/8/26 MHP via Claude
556C code changed to add blank defaults for the remaining CONTROL/PHYSICS
557C CHARACTER namelist variables that had none. Each is always set by
558C every current test's namelist anyway, but with no DATA default their
559C storage zero-initializes to NUL bytes rather than blanks; harmless
560C as long as nothing echoed them, but the new NML=CONTROL/PHYSICS echo
561C (see above) writes every member verbatim, and raw NULs turn .short
562C into a binary-looking file for any run that leaves one of these
563C unset (as FDEBUG and FSTCH, both legacy/unused outputs, always are).
564C A single blank is padded to each variable's full declared length by
565C the compiler, same as ANEWCP's existing default above. FALEX06,
566C FALLARD, FATM, FFERMI, FLIV95, FPATM, FPENV, FPMOD, FPUREZ, FSCVH,
567C FSCVHE, FSCVZ are PARMIN's own dummy arguments (not local variables,
568C can't take a DATA default here) but are always explicitly set by
569C every current test's namelist, so are not at risk in practice.
570 DATA DESCRIP/2*' '/
571 DATA FDEBUG,FFIRST,FLAST/3*' '/
572 DATA FMILNE,FMODPT,FOPALE06,FSCOMP/4*' '/
573 DATA FSHORT,FSNU,FSTCH,FSTOR,FTRACK,FcondOpacP/6*' '/
574C 3/92 DBG
575C DBG PULSE OUT 7/92
576C MHP 06/13 ADDED FLAG TO CALIBRATE TO SOLAR Z/X, SOLAR Z/X, SOLAR AGE
577C DATA TOLL,TOLR,LCALS/1.0D-5,1.0D-4,.FALSE./
578C DBG 4/94 ZRAMP STUFF
579C DBG 12/94 CALIBRATED STELLAR MODEL STUFF
580C LLP >>> OPAL 2006 EOS, Potekhin Conductive Opacities,
581C Use Numerical Derivitives switches
582C 9/24/26 MHP via Claude
583C code changed to remove the OPAL 1995/2001 equations of state
584C MHP 8/25 Removed hard coded defaults
585C Alex low T opacity
586C DATA OPECALEX/'OPACALEXANDER.X00',
587C + 'OPACALEXANDER.X01',
588C + 'OPACALEXANDER.X02',
589C + 'OPACALEXANDER.X035',
590C + 'OPACALEXANDER.X05',
591C + 'OPACALEXANDER.X07',
592C + 'OPACALEXANDER.X08'/
593
594C DBG 1/96 THE ARRAY V, READ IN VIA RDLAOL, CONTAINED THE MASS FRACTIONS
595C OF THE ENVELOPE ELEMENTS. IT WAS USED IN STARIN TO DEFINE FXENV,
596C WHICH ARE THE NUMBER FRACTION OF THE ENVELOPE ELEMENTS. FXENV WAS
597C THEN UPDATED IN EQSTAT AND EQSAHA. HERE WE DEFINE VNEW PASSED
598C IN A COMMON BLOCK VNEWCB. IT IS IDENTICAL TO V EXCEPT THAT THE NUMBERS
599C ARE DEFINED HERE EXPLICITY FOR A G&N93 SOLAR MIXTURE. YOU CAN
600C CHANGE THEM VIA THE PHYSICS NAMELIST. V IS SET EQUAL TO VNEW IN
601C STARIN EXCEPT WHEN LLAOL=T (TO MAINTAIN BACKWARD COMPATIBILITY.
602C Na Al Mg Fe
603C Si C H O
604C N Ar Ne He
605C MHP 5/97 OPTION FOR SAUMON, CHABRIER, AND VAN HORN EOS ADDED
606C MHP 3/99 OPTION FOR SB ROTATION ENFORCED IN THE ENTIRE STAR AT
607C ALL TIMES
608C JNT 09/2025 FOR 05/15 IMPJMOD default set to 0
609C mhp 8/10 added scaled solar wind mass loss option
610C DATA LSOLWIND,DMSUN,DMWSUN,DMWMAX/.FALSE.,-2.0D-14,2.863E-6,9.054E-5/
611C 3/09 Alexander 2006 opacity table options and opacity ramp options
612CFD 10/09 Mimic mixing options - acting on setling and differential settling
613C JVS 02/11 Initialize acoustic depth common block values appropriately
614C JVS end
615C MHP 02/12 NEW PARAMETERIZATION OF ANGULAR MOMENTUM AND MASS LOSS
616C FROM MAGNETIZED SOLAR-LIKE WINDS
617C DATA LPMM,PMMA,PMMB,PMMC,PMMM,PMMJD,PMMMD,PMMWMAX,
618C * PMMSOLP,PMMSOLW,PMMSOLTAU
619C * /.FALSE.,2.0D0,1.0D0,0.0D0,0.22D0,1.32E30,1.27E12,
620C * 2.836E-5,4.9304D0,2.836E-6,1.065E6/
621C G Somers 6/16 NEW PARAMETERIZATION OF ANGULAR MOMENTUM AND MASS LOSS FROM
622C SOLAR WINDS. FOLLOW MATT ET AL (2012) FORMULATION, BUT DEFAULT TO KAWALER
623C TYPE LAW.
624C MHP 8/17 CHANGED DEFAULT FOR PMMA TO 2 FROM 0
625 DATA AWIND/'K97'/
626C MHP 02/12 PERMIT CONSTANT DIFFUSION COEFFICIENT
627C
628C G Somers 06/14 ALLOW NEW LI DESTRUCTION CROSS SECTIONS
629C NEW VALUES SHOULD BE IN UNITS OF keV b.
630C DEFAULT LI6 = 5,500 keV b FROM FOWLER ET AL. 1967
631C DEFAULT LI7 = 52 keV b FROM ROLFS & KAVANAGH 1986
632C DEFAULT BE9(P,G)B10 (BE91) = 1.1 keV b INFERRED FROM FOWLER 1988
633C THEY DON'T SHOW THIS REACTION, SO THIS IS APPROXIMATE.
634C DEFAULT BE9(P,D)2HE4 (BE92) = 15,000 keV b FROM FOWLER ET AL. 1967
635C DEFAULT BE9(P,A)LI6 (BE93) = 15,000 keV b FROM FOWLER ET AL. 1967
636C G Somers END
637C MHP 8/14 DEFAULT CROSS-SECTIONS ARE TAKEN FROM THE SOLAR FUSION II PAPER
638C REFERENCE ADELBERGER ET AL. 2011. UNITS ARE KeV b
639C NOTE: PEP IS THE PROPORTIONALITY CONSTANT RELATIVE TO PP
640C NOTE: BE7+E- IS THE PROPORTIONALITY CONSTANT IN THE LINEAR TERM
641C THE CODE USES T9, NOT T6, SO ANY EXPRESSION IN TERMS OF T/10^6 K
642C NEEDS TO BE DIVIDED BY 1000^0.5 (FOR BOTH PEP AND BE7+E-)
643C REFERENCE FIRST DERRIVATIVES OF CROSS-SECTIONS (ADELBERGER ET AL. 2011)
644C UNITS ARE b
645C REFERENCE SECOND DERIVATIVES OF CROSS SECTIONS (ADELBERGER ET AL. 2011)
646C DEFAULT TO YES FOR NEW TAUCZ CALCULATION
647C
648C THIS SUBROUTINE READS ALL USER DEFINED QUANTITIES FROM THE
649C FILES yrec8.nml1 and yrec8.nml2
650C VALUES FOR LOGICAL UNITS USED IN READS AND WRITES SET IN DATA
651C STATEMENT; THEY CAN BE CHANGED IN THE NAMELIST IF NEEDED.
652C LOGICAL UNIT 5 = READ FROM SCREEN
653C LOGICAL UNIT 6 = WRITE TO SCREEN: FOR BATCH USE STATUS FILE INSTEAD
654C SPECIFY ALL LOGICAL UNIT NUMBERS HERE:
655C OUTPUT: STATUS FILE
656 IOWR = 6
657C OUTPUT: LAST MODEL (TEXT)
658 ILAST = 11
659C INPUT: FIRST MODEL (TEXT)
660 IFIRST = 12
661C INPUT: PHYSICS NAMELIST
662 IRUN = 13
663C INPUT: CONTROL NAMELIST
664 ISTAND = 14
665C INPUT: FERMI TABLES
666 IFERMI = 15
667C OUTPUT: RESERVED for DEBUGGING
668 IDEBUG = 18
669C OUTPUT: TRACK
670 ITRACK = 19
671C OUTPUT: ALL DIAGNOSTIC INFO
672 ISHORT = 20
673C OUTPUT: MILNE INVARIANT VARIABLES
674 IMILNE = 21
675C OUTPUT: SHELL BY SHELL INFO ON MODELS
676 IMODPT = 22
677C OUTPUT: SAVED MODELS, CAN BE USED AS STARTING MODEL
678 ISTOR = 23
679C OUTPUT: FOR PULSATION CODE, INTERIOR
680 IOPMOD = 24
681C OUTPUT: FOR PULSATION CODE, ENVELOPE
682 IOPENV = 25
683C OUTPUT: FOR PULSATION CODE, ATMOSPHERE
684 IOPATM = 26
685C 9/25/26 MHP via Claude
686C code changed to remove dead ILSTBN, ISTOBN, IFSTBN unit reservations
687C (assigned here but never opened, read, or written anywhere; not even
688C shared via a common block)
689C OUTPUT: SOUND SPEED PROFILE (WRITTEN BY WRTMOD WHEN LSOUND IS TRUE)
690 ISOUND = 500
691C 9/24/26 MHP via Claude
692C code changed to remove the Monte Carlo option
693C 9/23/26 MHP via Claude
694C code changed to remove the OPAL92 opacity tables
695C YCK INPUT: OPAL95 OPACITY TABLE
696 ILIV95 = 48
697C OUTPUT: SNU FLUXES
698 ISNU = 33
699C 9/25/26 MHP via Claude
700C code changed to remove dead COMMON/LUNUM/ISCOMP unit reservation
701C 9/23/26 MHP via Claude
702C code changed to remove the Kurucz 1990 opacity tables
703C 9/25/26 MHP via Claude
704C code changed to remove the LISO isochrone-output option
705C INPUT: KURUCZ ATMOSPHER TABLE
706 IOATM = 38
707C 9/24/26 MHP via Claude
708C code changed to remove the Alexander 1995 opacity tables
709C INPUT: OPAL EQUATION OF STATE
710 IOPALE = 49
711C 9/23/26 MHP via Claude
712C code changed to remove the LAOL89 opacity tables
713C INPUT: LAOL OPACITIES FOR PURE CN IN DENSE GRID FORMAT
714 IOPUREZ = 62
715C DBG 4/94
716C INPUT:
717C DBG 8/95 SECOND OPOACITY TABLES FOR ZRAMP AND Z DIFFUSION
718C 9/23/26 MHP via Claude
719C code changed to remove the OPAL92 opacity tables
720C 9/23/26 MHP via Claude
721C code changed to remove the Kurucz 1990 opacity tables
722C MHP 6/97 ADDED OPTION FOR ALLARD MODEL ATMOSPHERES
723 IOATMA = 66
724C 9/24/26 MHP via Claude
725C code changed to remove the Monte Carlo option
726C INPUT FILES FOR THE SCV EOS
727 ISCVH=72
728 ISCVHE=73
729 ISCVZ=74
730C Input files for Potekhin conductive opacities. LLP 7/8/06
731 IcondOpacP = 75
732C FcondOpacP = 'condall.d'
733C Default FeH and Alpha for new Allard Atmospheres
734 ALATM_FeH = 0D0
735 ALATM_Alpha = 0D0
736 LALTPTAU100 = .FALSE.
737C 3/09 Input file for 2006 Alexander opacities
738 IALEX06 = 90
739
740 print *,''
741 print *,'Yale Rotating Evolution Code - YREC, v',YRECVER(1:LEN_TRIM(YRECVER)),' (',GITHASH(1:LEN_TRIM(GITHASH)),')'
742
743C JVS 02/11 Altered the yrec8 input format so that files can be entered
744C on the command line, with the *.nml1 as the first argument, and *.nml2 as
745C the second. Defaults to yrec8.nml1 and yrec8.nml2 if none are provided.
746c OPEN(UNIT=ISTAND, FILE='yrec8.nml1', STATUS='OLD')
747c OPEN(UNIT=IRUN, FILE='yrec8.nml2', STATUS='OLD')
748c READ(UNIT=ISTAND, NML=CONTROL)
749c READ(UNIT=IRUN, NML=PHYSICS)
750c CLOSE(ISTAND)
751c CLOSE(IRUN)
752
753C Dynamically create format string so version info is nicely spaced
754 WRITE(VERFMT, 315) LEN_TRIM(YRECVER), LEN_TRIM(GITHASH)
755 315 315 FORMAT('(''# YREC v'', A', I2.2, ', '' ('', A', I2.2,
756 * * ', '')'')')
757
758 CALL GETARG(1, YREC1)
759 IF (YREC1(1:2) .EQ. ' ') YREC1 = 'yrec8.nml1'
760 print *, ' '
761 write(*,*) 'CONTROL namelist : ',YREC1(1:LEN_TRIM(YREC1))
762
763 CALL GETARG(2, YREC2)
764 IF (YREC2(1:2) .EQ. ' ') YREC2 = 'yrec8.nml2'
765 write(*,*) 'PHYSICS namelist : ',YREC2(1:LEN_TRIM(YREC2))
766
767 OPEN(UNIT=ISTAND, FILE=YREC1, STATUS='OLD')
768 OPEN(UNIT=IRUN, FILE=YREC2, STATUS='OLD')
769 READ(UNIT=ISTAND, NML=CONTROL)
770 READ(UNIT=IRUN, NML=PHYSICS)
771 CLOSE(ISTAND)
772 CLOSE(IRUN)
773C MHP 8/14 SUBROUTINE TO CONVERT MORE USER-FRIENDLY INPUT VARIABLES
774C INTO THE VECTORS USED IN THE CODE (SUPERCEDES OLDER INPUTS)
775 CALL REMAP
776C MHP 06/13 Added memory of whether the choice of atmospheres has
777C been changed during the run, and what the original setting was
778 KTTAU0 = KTTAU
779 LTTAU = .FALSE.
780C 9/25/26 MHP via Claude
781C 10/8/26 MHP via Claude
782C code changed to resolve the fort.20 live issue noted above (now
783C removed): the namelist echo belongs after ISHORT is OPENed, not
784C here. Moved to just past OPEN(ISHORT,...), alongside the rest of
785C the run-parameter echo -- see the NML=PHYSICS/CONTROL/DERIVED
786C writes there.
787
788C Post-process all CONTROL namelist vars that hold path values.
789C Expand any placeholders found in the string with the value taken from a
790C corresponding environment variable, if one is defined.
791 CALL EXPAND_VALUE(FALEX06)
792 CALL EXPAND_VALUE(FALLARD)
793 CALL EXPAND_VALUE(FATM)
794 CALL EXPAND_VALUE(FcondOpacP)
795 CALL EXPAND_VALUE(FFERMI)
796 CALL EXPAND_VALUE(FFIRST)
797 CALL EXPAND_VALUE(FLAST)
798 CALL EXPAND_VALUE(FLIV95)
799 CALL EXPAND_VALUE(FMODPT)
800 CALL EXPAND_VALUE(FOPALE06)
801 CALL EXPAND_VALUE(FPATM)
802 CALL EXPAND_VALUE(FPENV)
803 CALL EXPAND_VALUE(FPMOD)
804 CALL EXPAND_VALUE(FPUREZ)
805 CALL EXPAND_VALUE(FSCOMP)
806 CALL EXPAND_VALUE(FSCVH)
807 CALL EXPAND_VALUE(FSCVHE)
808 CALL EXPAND_VALUE(FSCVZ)
809 CALL EXPAND_VALUE(FSHORT)
810 CALL EXPAND_VALUE(FSNU)
811 CALL EXPAND_VALUE(FSOUND)
812 CALL EXPAND_VALUE(FSTOR)
813 CALL EXPAND_VALUE(FTRACK)
814
815C Create output directory as specified in the FTRACK value of CONTROL
816C namelist if it doesn't already exist.
817 ! find index of last '/' char. Use that to snip out the directory name.
818 DO I = LEN_TRIM(FTRACK), 1, -1
819 IF (FTRACK(I:I) .EQ. '/') THEN
820 LAST_SLASH_IDX = I
821 GOTO 1250
822 ENDIF
823 END DO
8241250 1250 CONTINUE
825 CMD = 'mkdir -p "' // FTRACK(1:LAST_SLASH_IDX) // '"'
826 print *,"OUTPUT placed in : ",FTRACK(1:LAST_SLASH_IDX)
827 print *, ''
828 CALL system(CMD)
829
830
831C JVS 02/11 Acoustic depth/ Asteroseismic glitch output. Puts output
832C in the same directory as all other output, and names it with the
833C same conventions
834 IF (LACOUT) THEN
835 ICLCD = 91
836 MRK=INDEX(FSHORT,'short')
837 FCLCD=FSHORT(1:MRK-1)//'calcad'
838 OPEN(UNIT=ICLCD, FILE=FCLCD, STATUS='UNKNOWN')
839 WRITE(ICLCD,*) 'Acoustic depth calculation output file'
840 WRITE(ICLCD,*) 'age (Gyr),radius(cm),1/sound speed(s/cm),radius (CZ), 1/cs (CZ)
841 * * delad,gamma1,P, T, X'
842
843
844C 9/25/26 MHP via Claude
845C code changed to remove dead IACAT, IJVS, IJENT, IJDEL unit
846C reservations (all were declared but never opened anywhere)
847C IJLAST = 93
848C FJLAST=FSHORT(1:MRK-1)//'jlast'
849C OPEN(UNIT=IJLAST, FILE=FJLAST, STATUS='UNKNOWN')
850 ENDIF
851
852
853C JVS END
854C
855C G Somers 6/14, DEFINE SCALING COEFFICIENT FOR LI/BE CROSS SECTIONS
856C DEFAULT LI6 = 5.5 MeV b FROM FOWLER ET AL. 1967
857C DEFAULT LI7 = 52 keV b FROM ROLFS & KAVANAGH 1986
858C DEFAULT BE9(P,G)B10 (BE91) = 1.1 keV b INFERRED FROM FOWLER 1988
859C DEFAULT BE9(P,D)2HE4 (BE92) = 15,000 keV b FROM FOWLER ET AL. 1967
860C DEFAULT BE9(P,A)LI6 (BE93) = 15,000 keV b FROM FOWLER ET AL. 1967
861 IF (LXLI6) THEN
862 SLI6 = XSLI6/5.5D3
863 ENDIF
864 IF (LXLI7) THEN
865 SLI7 = XSLI7/5.2D1
866 ENDIF
867 IF (LXBE91) THEN
868 SBE91 = XSBE91/1.1D0
869 ENDIF
870 IF (LXBE92) THEN
871 SBE92 = XSBE92/1.5D4
872 ENDIF
873 IF (LXBE93) THEN
874 SBE93 = XSBE93/1.5D4
875 ENDIF
876C G Somers END
877C MHP 8/25 open relevant table as well as ensuring that only one is selected
878C 9/24/26 MHP via Claude
879C code changed to remove the OPAL 1995/2001 equations of state
880 IF (LOPALE06) THEN
881 OPEN(IOPALE, FILE=FOPALE06,STATUS='OLD')
882 ENDIF
883C 9/23/26 MHP via Claude
884C code changed to remove the Kurucz 1990 opacity tables
885C 9/24/26 MHP via Claude
886C code changed to remove the Alexander 1995 opacity tables
887
888 OPEN(ISTOR,FILE=FSTOR,FORM='FORMATTED',STATUS='UNKNOWN')
889 REWIND(ISTOR)
890C G Somers 11/14 write the new header for the .store file, if LSTORE = TRUE.
891 IF(LSTORE)THEN
892C JvS 08/25 Added stitched interior and envelope option
893 IF(LSTCH)THEN
894 LPHHD = .TRUE.
895 ELSE
896 WRITE(ISTOR,VERFMT) YRECVER, GITHASH
897 WRITE(ISTOR,1012)
898 ENDIF
899 ENDIF
900 1012 1012 FORMAT('# Header Key',/,'# ModType ModNum #Shells ',
901 1 1 'M/Msun log(Teff) log(L/Lsun) log(M/gram) Age/Gyr',
902 1 1 ' Timestep/yr log(M_inner/gram) log(M_outer/gram)',/,
903 1 1 '# JCORE JENV CMIXL EOS ATM ALOK HIK LPUREZ COMPMIX',
904 1 1 ' LEXCOM LDIFY LDIFZ LSEMIC LOVSTC LOVSTE LOVSTM',
905 1 1 ' LROT LINSTB LJDOT0 LDISK TDISK PDISK WMAX LSTORE',
906 1 1 ' LSTATM LSTENV LSTMOD LSTPHYS LSTROT',/,'# PPI_lum',
907 1 1 ' PPII_lum PPIII_lum CNO_lum 3He_lum ',
908 1 1 'OldNeu_lum Grav_lum',/,'# ENV1-3 log(Teff)',
909 1 1 ' log(L/Lsun) P_base T_base R_base MatrixElements'
910 1 1 ,/)
911C 1013 FORMAT('# JCORE JENV CMIXL EOS ATM ALOK HIK LPUREZ COMPMIX',
912C 1 ' LEXCOM LDIFY LDIFZ LSEMIC LOVSTC LOVSTE LOVSTM',
913C 1 ' LROT LINSTB LJDOT0 LDISK TDISK PDISK WMAX LSTORE',
914C 1 ' LSTATM LSTENV LSTMOD LSTPHYS LSTROT'
915C 1 ,/)
916C 1014 FORMAT(
917C 1'MODEL SHELL MASS RADIUS LUMINOSITY PRESSURE TEMPERATURE DENSITY OMEGA ',
918C 1'CONVECTIVE INTERIOR_PT H1 He4 METALS He3 C12 C13 N14 N15 O16 O17 O18 H2 Li6 Li7 ',
919C 1'Be9 OPACITY GRAV DELR DEL DELAD V_CONV GAM1 HII HEII HEIII BETA ',
920C 1'ETA PPI PPII PPIII CNO TRIPLE_ALPHA E_NUC E_NEU E_GRAV CP DLNRHODLNT A RP/RE FP ',
921C 1'FT J/M MOMENT DEL_KE V_ES V_GSF V_SS VTOT ')
922C G Somers END
923
924 OPEN(ISHORT,FILE=FSHORT,FORM='FORMATTED',STATUS='UNKNOWN')
925 REWIND(ISHORT)
926C 9/25/26 MHP via Claude
927C code changed to open the sound-speed-profile output (previously
928C hardcoded to unit 500/'Csound.dat' in wrtmod.f) here instead, using
929C the managed ISOUND unit and FSOUND filename. Opened unconditionally
930C since LSOUND is only known at runtime, well after PARMIN returns.
931C Rewound explicitly so every run starts with a clean file even if
932C LSOUND never becomes true this run (STATUS='UNKNOWN' alone does not
933C truncate/reposition an existing file on OPEN, so without this a
934C stale file from an earlier LSOUND-triggering run would otherwise be
935C left in place, opened but unwritten, and could be mistaken for
936C fresh output).
937 OPEN(ISOUND,FILE=FSOUND,FORM='FORMATTED',STATUS='UNKNOWN')
938 REWIND(ISOUND)
939 IF (LTRACK) THEN
940 OPEN(UNIT=ITRACK,FILE=FTRACK, FORM='FORMATTED',
941 * * STATUS='UNKNOWN')
942 REWIND(ITRACK)
943 ENDIF
944
945C SNU OUTPUT
946 IF(LSNU) THEN
947 OPEN(UNIT=ISNU,FILE=FSNU, FORM='FORMATTED',
948 * * STATUS='UNKNOWN')
949 REWIND(ISNU)
950 ENDIF
951 IF(LDEBUG) THEN
952 OPEN(IDEBUG,FILE=FDEBUG,FORM='FORMATTED',
953 * * STATUS='UNKNOWN')
954 END IF
955C MHP Moved opening of FMILNE here, no need to do elsewhere
956 IF(LMILNE)THEN
957 OPEN(UNIT=IMILNE,FILE=FMILNE,FORM='FORMATTED',
958 * * STATUS='UNKNOWN',ACCESS='APPEND')
959 ENDIF
960C MHP 10/02 LBNIN never set, ignore loop
961C IF (.NOT.LBNIN) THEN
962 OPEN(UNIT=IFIRST,FILE=FFIRST,FORM='FORMATTED',STATUS='OLD')
963C END IF
964 OPEN(UNIT=ILAST,FILE=FLAST,FORM='FORMATTED',STATUS='UNKNOWN')
965 OPEN(UNIT=IMODPT,FILE=FMODPT,FORM='FORMATTED',STATUS='UNKNOWN')
966C OPEN ALL PULSE FILES
967 IF(LPULSE) THEN
968 OPEN(IOPMOD, FILE=FPMOD,STATUS='UNKNOWN',FORM='FORMATTED')
969 OPEN(IOPENV, FILE=FPENV,STATUS='UNKNOWN',FORM='FORMATTED')
970 OPEN(IOPATM, FILE=FPATM,STATUS='UNKNOWN',FORM='FORMATTED')
971 END IF
972C 9/24/26 MHP via Claude
973C code changed to remove the Monte Carlo option
974C MHP 8/25 Moved opening of conductive opacity and EoS tables here, to avoid complicated passages of declared variables.
975 IF(LcondOpacP)then
976 open(IcondOpacP,file=FcondOpacP,status='OLD')
977 ENDIF
978C 9/25/26 MHP via Claude
979C code changed to remove the LISO isochrone-output option
980 IF(LSEMIC)THEN
981 IF(LOVSTC.OR.LOVSTE.OR.LOVSTM)THEN
982 WRITE(ISHORT,2)LSEMIC,LOVSTE,LOVSTC,LOVSTM
983 2 2 FORMAT(1X,'ERROR IN SUBROUTINE PARMIN'/'SEMI-CONVECTION',
984 * * ' AND OVERSHOOT FLAGS BOTH TURNED ON'/'FLAGS LSEMIC',L2,
985 * * ' OVERSHOOT - CORE,ENVELOPE,INTERMEDIATE-',3L2/'RUN STOPPED')
986C 10/30/26 MHP via Claude: bare STOP -> STOP 3, the input-error code (issue 38).
987 STOP 3
988 ENDIF
989 ENDIF
990C 10/29/26 MHP via Claude
991C Refuse LDIFAD with rotation. The advection-diffusion transport
992C (DADCOEFT) rebuilds ECOD3 and ECOD4 from equal-grid arrays that no
993C routine assigns (EV0, EV1A, EV1B, EV2A, EV2B, FGEOM, ECOD5, ECOD6,
994C QCHIRE, ...), so it zeroes ROTGRID's coefficients, drops every
995C transport term from the angular-momentum matrix and leaves 0/0 mixing
996C velocities. The mapping of SETUPV's FV* arrays onto the equal grid
997C was never written. LDIFAD acts only in the rotation routines, so a
998C non-rotating deck that sets it is unaffected. Bug-sweep report L13.
999 IF(LROT .AND. LDIFAD)THEN
1000 WRITE(ISHORT,3)
1001 WRITE(*,3)
1002 3 3 FORMAT(1X,'ERROR IN SUBROUTINE PARMIN'/' LDIFAD (ADVECTION-',
1003 * * 'DIFFUSION TRANSPORT OF ANGULAR MOMENTUM) IS NOT IMPLEMENTED:'/
1004 * * ' DADCOEFT READS COEFFICIENTS THAT NO ROUTINE SETS. SET',
1005 * * ' LDIFAD = .FALSE. FOR ROTATING RUNS.'/'RUN STOPPED')
1006 STOP 1
1007 ENDIF
1008 WRITE(ISHORT,1)(HPTTOL(I),I=1,12),ALPHAE,ALPHAC,LINSTB,LJDOT0,
1009 * * ALFA,FK,FW,FC,FO,FMU,RCRIT
1010 1 1 FORMAT(1X,'PT TOL',12F6.3/1X,'O.S.ENV',F6.3,' O.S.CORE',F6.3,
1011 * * ' LINSTB ',L1,' LJDOT ',L1,' WIND IND.',F6.3,' FK',
1012 * * 1PE8.2/1X,' FV',0PF5.2,' FC',F5.2,' COUPLING'
1013 * * ,F6.3, ' F MU',F5.2,' RCRIT',F9.1)
1014C 10/13/26 MHP via Claude
1015C code changed to remove the TENV derivation: it existed only to populate
1016C COMMON/CTLIM/ for envint.f, which now derives it itself.
1017 IF(LROT) THEN
1018 LNEW0 = .TRUE.
1019 IF(WALPCZ.LT.-2.0D0) WALPCZ = -2.0D0
1020 IF(WALPCZ.GT.0.0D0) WALPCZ = 0.0D0
1021C JNT 09/2025 LSOLID OVERWRITES IMPJMOD
1022 IF(LSOLID) IMPJMOD = 1
1023CCCCCC OLD OR NEW WINDLAW.
1024 IF(.NOT.LMWIND)THEN
1025CCCCCC INSTRUCTIONS FOR THE OLD WINDLAW
1026CCCCCC
1027CCCCCC SET UP COEFFICIENTS FOR ANGULAR MOMENTUM LOSS VIA WINDS.
1028CCCCCC GIVEN THE INDEX ALFA, THE FORMULA FOR JDOT IS
1029CCCCCC JDOT = FK*2.036D33*1.452D9**ALFA*(MDOT/1.0D-14)**(1-2ALFA/3)
1030CCCCCC *OMEGA**(1+4ALFA/3)*(R/RSUN)**(2-ALFA)*(M/MSUN)**-ALFA/3
1031CCCCCC EXMD = EXPONENT OF MDOT TERM; EXW SAME FOR OMEGA;EXR FOR R;EXM FOR M.
1032CCCCCC FK IS A FUDGE FACTOR,SET TO 1 TO REPRODUCE THE OBSERVED SOLAR ANGULAR
1033CCCCCC MOMENTUM LOSS.
1034 CC13 = 1.0D0/3.0D0
1035 CC23 = 2.0D0/3.0D0
1036 CONSTFACTOR = FK*2.036D33*1.452D9**ALFA
1037 EXMD = 1.0D0 - CC23*ALFA
1038 EXW = 1.0D0 + 2.0D0*CC23*ALFA
1039 EXR = 2.0D0 - ALFA
1040 EXM = -CC13*ALFA
1041C
1042C INSTRUCTIONS FOR THE NEW WINDLAW
1043C
1044C SET UP INDICES FOR LOSS LAW IN TERMS OF PMM A, B, C, M.
1045C INCLUDE A PMMD AS WELL, FOR TURNING TAUCZ and CENTRIFUG DEPENDENCE ON/OFF.
1046C EXCEN = EXPONENT FOR CENTRIFUGAL TERM, {K2^2/(K2^2+0.5*W^2 R^3/GM)}^PMMM
1047C
1048C AWIND = 'K97' ENFORCES KRISHNAMURTHI (1997) WIND LAW.
1049C AWIND = 'V13' ENFORCES VAN SADERS + PINSONNEAULT (2013) WIND LAW, AS ADAPTED
1050C FROM MATT ET AL. (2008,2012).
1051C AWIND = 'CUS' ADOPTS THE M-D VALUES GIVEN IN THE NAMELIST.
1052C
1053C
1054C THEN CONVERT THE PMM VALUES INTO EXPONENTS FOR THE TORQUE CALCULATION.
1055C BASIC EQUATIONS, WHERE EVERY TERM IS SCALED TO SOLAR, ARE:
1056C
1057C Jdot = w * Bmag^4m * Mdot^1-2m * R^5m+2 * M^-m * Fcen^md
1058C Bmag = Pphot^0.5 * (w * R^c)^b * Tcz^d
1059C GM/R * Mdot = (Lx/Lbol * Lbol)^a -> Mdot = R * M^-1 * Lbol * w^a
1060C ...where Lx/Lbol is assumed to scale with w to the power of a.
1061C
1062C THIS GIVES:
1063C JDOT ~ w ^ 1+a-2ma+4mb
1064C ~ Tcz ^ 4md
1065C ~ R ^ 3+3m+4mbc
1066C ~ M ^ m-1
1067C ~ Lbol ^ 1-2m
1068C ~ Pphot ^ 2m
1069C ~ Fcen ^ md
1070C
1071C For moment, ignore GM/R term in Mdot. This makes:
1072C JDOT ~ R ^ 2+5m+4mbc
1073C JDOT ~ M ^ -m
1074C
1075 ELSE
1076 IF(AWIND.EQ.'K97')THEN
1077 PMMM = ALFA/3.0
1078C MHP 8/17 CORRECT DEFAULT FOR A = 2, NOT 0
1079 PMMA = 2.0
1080 PMMB = 1.0
1081 PMMC = 2.0
1082 PMMD = 0.0
1083 LBSCALE = .FALSE.
1084 ELSEIF(AWIND.EQ.'V13')THEN
1085 PMMM = 0.22D0
1086 PMMA = 2.0
1087 PMMB = 1.0
1088 PMMC = 0.0
1089 PMMD = 1.0
1090 LBSCALE = .TRUE.
1091 ENDIF
1092 EXW = 1.0D0 + PMMA - 2.0D0*PMMA*PMMM + 4.0D0*PMMM*PMMB
1093C G Somers 8/17 ZERO'D OUT EXTAU. TAUCZ TERM NOW COMPUTED IN
1094C MWIND/MCOWIND, NOT IN AMCALC.
1095C EXTAU = 4.0D0*PMMM
1096 EXTAU = 0.0
1097C JvS 09/25 REMOVED TYPO IN EXR = 2.0D0+5.0D0*PMMM-4.0D0*PMMM*PMMB*PMMC
1098 EXR = 2.0D0+5.0D0*PMMM-4.0D0*PMMM*PMMC
1099 EXM = -PMMM
1100 EXL = 1.0D0 - 2.0D0*PMMM
1101C G Somers 11/17, ADDED PMMD TO SWTICH OFF IN K97 FORM.
1102 EXPR = 2.0D0*PMMM*PMMD
1103 EXCEN = PMMM*PMMD
1104C INITIALIZE CONSTANT FACTOR FOR CENTRIFUGAL TERM
1105 C_2 = 0.0506D0
1106C SET THE CONSTANT FACTOR
1107 CONSTFACTOR = FK*PMMJD/PMMSOLW**EXW
1108C IF RELEVANT RESET THE SATURATION THRESHOLD IN
1109C TERMS OF THE SOLAR ROTATION RATE. WMAX_SUN<1000
1110C INDICATES SATURATION (AT THE SUN), SO
1111C WSAT = WMAX_SUN*PMMSOLW
1112 IF(WMAX_SUN.LT.1.0E3)THEN
1113 WMAX = WMAX_SUN*PMMSOLW
1114 ENDIF
1115 ENDIF
1116 ENDIF
1117C WINDLAW END
1118C
1119 CLN = DLOG(10.0D0)
1120 IF(LNEWCP) THEN
1121 LREL = .TRUE.
1122 IF(ATMP.EQ.'ABS') LREL = .FALSE.
1123C DECIDE WHICH ELEMENT IN ARRAY HCOMP TO BE RESCALED
1124C USING CHARACTER ARRAY AID AND INPUT CHARACTER VARIABLE ANEWCP
1125 DO 10 I = 1,12
1126 IF(ANEWCP.EQ.AID(I)) THEN
1127C INEWCP IS THE INDEX OF THE ELEMENT BEING ALTERED
1128 INEWCP = I + 3
1129 GOTO 30
1130 ENDIF
1131 10 10 CONTINUE
1132C ANEWCP NOT A RECOGNIZED ELEMENT
1133 LNEWCP = .FALSE.
1134 WRITE(ISHORT,20) ANEWCP
1135 20 20 FORMAT(1X,'VARIABLE',A4,1X,'NOT A RECOGNIZED ELEMENT'/1X,
1136 * * 'RESCALING NOT PERFORMED')
1137 30 30 CONTINUE
1138 ENDIF
1139 LMIXTURE = .FALSE.
1140 LISOTOPE = .FALSE.
1141 IF(ISETMIX.EQ.1)THEN
1142C IF DEFAULT MIX (GS98) CNOFRACS ARE ALREADY SET.
1143C IF(AMIX.EQ.'GS98')THEN
1144C LMIXTURE = .TRUE.
1145C GOTO 606
1146C ENDIF
1147C FOR A CUSTOM MIX,DISABLE IF THE SUM OF CNO MASS FRACTIONS EXCEEDS ONE
1148C OR IF ANY MASS FRACTION IS NEGATIVE
1149 IF(AMIX.EQ.'CUS')THEN
1150 IF(FRAC_C.LT.0.0D0.OR.FRAC_N.LT.0.0D0.OR.FRAC_O.LT.0.0D0)THEN
1151 WRITE(*,591)FRAC_C,FRAC_N,FRAC_O
1152 WRITE(ISHORT,591)FRAC_C,FRAC_N,FRAC_O
1153 591 591 FORMAT('NEGATIVE INPUT CNO FRACTION ',3E12.4,
1154 * * ' MIX NOT MODIFIED')
1155 GOTO 602
1156 ENDIF
1157 SUM_FRAC=FRAC_C+FRAC_N+FRAC_O
1158 IF(SUM_FRAC.GE.1.0D0)THEN
1159 WRITE(*,598)FRAC_C,FRAC_N,FRAC_O
1160 WRITE(ISHORT,598)FRAC_C,FRAC_N,FRAC_O
1161 598 598 FORMAT('INPUT CNO FRACTION ',3E12.4,
1162 * * ' EXCEEDS 1. MIX NOT MODIFIED')
1163 GOTO 602
1164 ENDIF
1165C VALID MIXTURE, USE CUSTOM ENTRIES FROM .NML1
1166 LMIXTURE = .TRUE.
1167 GOTO 606
1168 ENDIF
1169C SEARCH THROUGH OTHER VALID MIXTURE ENTRIES;IF FOUND,ASSIGN
1170C DO I = 2,4
1171 DO I = 1,4
1172 IF(AMIX.EQ.AMIXT(I))THEN
1173 ZXMIX = ZXMIXT(I)
1174 FRAC_C = FRAC_CT(I)
1175 FRAC_N = FRAC_NT(I)
1176 FRAC_O = FRAC_OT(I)
1177 LMIXTURE = .TRUE.
1178 GOTO 606
1179 ENDIF
1180 END DO
1181C NO VALID MIX SPECIFIED
1182 WRITE(*,589)AMIX
1183 WRITE(ISHORT,589)AMIX
1184 589 589 FORMAT('DESIRED CNO MIXTURE ',A8,' NOT FOUND. MIX NOT ALTERED.')
1185 ENDIF
1186 606 606 IF(LMIXTURE)THEN
1187 WRITE(*,604)AMIX,FRAC_C,FRAC_N,FRAC_O
1188 WRITE(ISHORT,604)AMIX,FRAC_C,FRAC_N,FRAC_O
1189 604 604 FORMAT('CNO MIXTURE ',A8,' C ',E12.4,' N ',E12.4,' O ',
1190 * * E12.4,' APPLIED TO STARTING MODEL.')
1191 ENDIF
1192C CHECK IF ISOTOPE RATIOS NEED TO BE ALTERED
1193 602 602 IF(ISETISO.EQ.1)THEN
1194C FOR A CUSTOM MIX,DISABLE IF THE SUM OF CNO MASS FRACTIONS EXCEEDS ONE
1195C OR IF ANY MASS FRACTION IS NEGATIVE
1196 IF(AISO.EQ.'CUS')THEN
1197 IF(R12_13.LT.0.0D0 .OR. R14_15.LT.0.0D0 .OR. R16_17.LT.0.0D0
1198 * * .OR. R16_18.LT.0.0D0 .OR. XH2_INI.LT.0.0D0 .OR. XHE3_INI.LT.0.0D0
1199 * * .OR. XLI6_INI.LT.0.0D0 .OR. XLI7_INI.LT.0.0D0 .OR.
1200 * * XBE9_INI.LT.0.0D0.OR.XB10_INI.LT.0.0D0 .OR.XB11_INI.LT.0.0D0)THEN
1201 WRITE(*,596)R12_13,R14_15,R16_17,R16_18,
1202 * * XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,XBE9_INI,XB10_INI,XB11_INI
1203 WRITE(ISHORT,596)R12_13,R14_15,R16_17,R16_18,
1204 * * XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,XBE9_INI,XB10_INI,XB11_INI
1205 596 596 FORMAT('NEGATIVE INPUT ISOTOPE RATIO OR LIGHT ELEMENT'
1206 * * ' MASS FRACTION ',11E12.4,
1207 * * ' MIX NOT MODIFIED')
1208 GOTO 603
1209 ENDIF
1210 SUM_FRAC= XH2_INI+XHE3_INI+XLI6_INI+XLI7_INI+XBE9_INI+
1211 * * XB10_INI+XB11_INI
1212 IF(SUM_FRAC.GE.1.0D0)THEN
1213 WRITE(*,595)XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,XBE9_INI,
1214 * * XB10_INI,XB11_INI
1215 WRITE(ISHORT,595)XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,
1216 * * XBE9_INI,XB10_INI,XB11_INI
1217 595 595 FORMAT('SUM OF LIGHT ELEMENT MASS FRACTIONS EXCEEDS 1',
1218 * * 11E12.4,' MIX NOT MODIFIED')
1219 GOTO 603
1220 ENDIF
1221C CURRENTLY THERE ARE ONLY 2 VALID OPTIONS - THE DEFAULT (L21) OR
1222C A CUSTOM MIXTURE (CUS) - IF NEITHER IS TRUE, EXIT
1223 ELSE IF(AISO.NE.'L21')THEN
1224 GOTO 603
1225 ENDIF
1226C PASSED ALL CHECKS - EITHER THE DEFAULT OR THE CUSTOM SETTINGS WILL BE APPLIED
1227 LISOTOPE = .TRUE.
1228 ENDIF
1229 IF(LISOTOPE)THEN
1230 WRITE(*,605)AISO,R12_13,R16_18,
1231 * * XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,XBE9_INI
1232 WRITE(ISHORT,605)AISO,R12_13,R16_18,
1233 * * XH2_INI,XHE3_INI,XLI6_INI,XLI7_INI,XBE9_INI
1234 605 605 FORMAT('ISOTOPE AND LIGHT ELEMENT MIXTURE ',A8,' C12/C13 ',
1235 * * E12.4,' O16/O18 ',E12.4,' H2 ',E12.4,' HE3 ',E12.4,' LI6 ',
1236 * * E12.4,' LI7 ',E12.4,' BE9 ',E12.4,' APPLIED TO STARTING MODEL.')
1237 ENDIF
1238C DBG 12/95 ENSURE CORRECT PARAMETERS FOR Z DIFFUSION
1239 603 603 IF (LDIFZ) THEN
1240 LDIFY=.TRUE.
1241 LTHOUL=.TRUE.
1242 END IF
1243
1244C G SOMERS 04/15; ENSURE CORRECT PARAMETERS FOR LIGHT ELEMENT DIFFUSION.
1245 IF(LDIFLI)THEN
1246 LNEWDIF=.TRUE.
1247 LDIFY=.TRUE.
1248 LDIFZ=.TRUE.
1249 LTHOUL=.TRUE.
1250 LTHOULFIT=.FALSE.
1251 ILAMBDA=4
1252 ENDIF
1253
1254C WRITE OUT RUN PARAMETERS.
1255C 10/8/26 MHP via Claude
1256C code changed to replace the hand-written STANDARD/CURRENT echo
1257C tables (which only covered a subset of namelist variables, had
1258C truncated arrays for ATIME/HPTTOL, and had a broken arg list on the
1259C old TRIDT/TRIDL line -- WRITE(ISHORT,45) TRIDT,TRIDL/TRIDT/TRIDL was
1260C parsed as two items, not four, despite FORMAT 45's four-column
1261C header) with a complete, always-in-sync echo of the actual PHYSICS
1262C and CONTROL namelists, plus a DERIVED namelist (declared above) for
1263C the handful of values that are only meaningful after post-namelist-
1264C read derivation/overrides (e.g. CMIXL, LREL, the LDIFLI-forced
1265C cascade). The NPOINT/NPENV/NPRTMOD/NPRTPT sentinel-default logic
1266C below is functional, not echo, and is preserved unchanged.
1267 IF(NPOINT.LE.0) NPOINT = 9999
1268 IF(NPENV.LE.0) NPENV = 9999
1269 IF(NPRTMOD.LE.0) NPRTMOD = 9999
1270 IF(NPRTPT.LE.0) NPRTPT = 9999
1271 WRITE(ISHORT,NML=PHYSICS)
1272 WRITE(ISHORT,NML=CONTROL)
1273 WRITE(ISHORT,NML=DERIVED)
1274C 10/15/26 MHP via Claude
1275C code changed to trap an illegal convective mixing length before the run
1276C starts. CMIXLA is the per-run vector the mixing length is taken from --
1277C main.f:382 sets CMIXL = CMIXLA(NK) for each kind card -- and nothing
1278C validated it anywhere. It has no default, so an entry the namelist
1279C never sets is zero, and a zero or negative mixing length is unphysical:
1280C the run fails further in, where the cause is no longer apparent.
1281C
1282C Only the entries that will actually be used are checked. Under solar
1283C calibration just CMIXLA(1) comes from the namelist: SETCAL sets
1284C NUMRUN = 48 and fills entries 2..48 from CMIXLA(1), so checking the
1285C whole vector here would report entries the user never supplied. The
1286C bound is MIN(NUMRUN,50) because CMIXLA is dimensioned 50 while NUMRUN
1287C is read from the namelist and is not itself range-checked.
1288C
1289C Placed after the namelist echo, unlike the LSEMIC/overshoot trap above,
1290C so that the .short file carries the inputs that caused the stop as well
1291C as the diagnosis.
1292 IF(LCALS)THEN
1293 NCMXCK = 1
1294 ELSE
1295 NCMXCK = MIN(NUMRUN,50)
1296 ENDIF
1297 LCMXBAD = .FALSE.
1298 DO I = 1,NCMXCK
1299 IF(CMIXLA(I).LE.0.0D0)THEN
1300 LCMXBAD = .TRUE.
1301 WRITE(ISHORT,8801)I,CMIXLA(I)
1302 WRITE(*,8801)I,CMIXLA(I)
1303 ENDIF
1304 END DO
1305 8801 8801 FORMAT(1X,'ERROR IN SUBROUTINE PARMIN'/'ILLEGAL MIXING LENGTH:',
1306 * * ' CMIXLA(',I2,') =',1PE12.4,' - MUST BE POSITIVE')
1307 IF(LCMXBAD)THEN
1308 IF(LCALS)THEN
1309 WRITE(ISHORT,8802)
1310 WRITE(*,8802)
1311 ELSE
1312 WRITE(ISHORT,8803)NCMXCK
1313 WRITE(*,8803)NCMXCK
1314 ENDIF
1315C 10/30/26 MHP via Claude: bare STOP -> STOP 3, the input-error code (issue 38).
1316 STOP 3
1317 ENDIF
1318 8802 8802 FORMAT('SOLAR CALIBRATION IS ON, SO ONLY CMIXLA(1) IS READ FROM',
1319 * * ' THE NAMELIST'/'RUN STOPPED')
1320 8803 8803 FORMAT('CMIXLA MUST BE SET FOR EACH OF THE',I3,' KIND CARDS'/
1321 * * 'RUN STOPPED')
1322C 10/30/26 MHP via Claude
1323C code changed to refuse a non-positive envelope triangle size. A zero
1324C size made SURFBC's reflection walk loop for ever, and a negative TRIDT
1325C started the triangle with the wrong orientation.
1326 IF(TRIDT.LE.0.0D0 .OR. TRIDL.LE.0.0D0)THEN
1327 WRITE(ISHORT,8804)TRIDT,TRIDL
1328 WRITE(*,8804)TRIDT,TRIDL
1329 8804 8804 FORMAT(1X,'ERROR IN SUBROUTINE PARMIN'/'ENVELOPE TRIANGLE SIZE',
1330 * * ' TRIDT',1PE11.3,' TRIDL',E11.3,' MUST BE POSITIVE'/
1331 * * 'RUN STOPPED')
1332 STOP 3
1333 ENDIF
1334 IF(KTTAU .EQ. 0) THEN
1335 WRITE(ISHORT, 197)
1336 ELSE IF (KTTAU .EQ. 1) THEN
1337 WRITE(ISHORT, 198)
1338 ELSE IF (KTTAU .EQ. 2) THEN
1339 WRITE(ISHORT, 1999)
1340 ELSE IF (KTTAU .EQ. 3) THEN
1341 WRITE(ISHORT, 1888)
1342 ELSE IF (KTTAU .EQ. 4) THEN
1343 WRITE(ISHORT, 1889)
1344C JNT 6/14 ADD FOR NEW KURUCZ/CASTELLI ATMOSPHERE TABLES
1345 ELSE IF (KTTAU .EQ. 5) THEN
1346 WRITE(ISHORT, 1887)
1347 END IF
1348 197 197 FORMAT(' USING EDDINGTON T-TAU RELATION.')
1349 198 198 FORMAT(' USING KRISHNA-SWAMY T-TAU RELATION.')
1350 1999 1999 FORMAT(' USING HARVARD-SMITHSONIAN REFERENCE ATMOSPHERE')
1351 1888 1888 FORMAT(' USING KURUCZ ATMOSPHERE TABLE')
1352 1889 1889 FORMAT(' USING ALLARD ATMOSPHERE TABLE')
1353 1887 1887 FORMAT(' USING KURUCZ/CASTELLI ATMOSPHERE TABLE')
1354
1355C DBG PULSE
1356 IF (LPULSE) THEN
1357 WRITE(ISHORT,196)
1358 196 196 FORMAT(/,' CALCULATE PULSATION OUTPUT ON LAST MODEL')
1359 END IF
1360 IF (LPUREZ) THEN
1361 WRITE(ISHORT,*) ' USING PURE C AND N OPACITY TABLES'
1362 END IF
1363
1364 WRITE(IMODPT,310) DESCRIP(1), DESCRIP(2)
1365
1366 WRITE(ISHORT,314)
1367 WRITE(ISHORT,VERFMT) YRECVER, GITHASH
1368 WRITE(ISHORT,310) DESCRIP(1), DESCRIP(2)
1369 310 310 FORMAT('# DESCRIPTION OF RUN:',A80,/, '#',9X,' ',8X,': ',
1370 * * A80,/,'#', 100('='))
1371
1372 IF(LTRACK) THEN
1373
1374 WRITE(ITRACK,314)
1375 314 314 FORMAT('#',/,'#',100('='))
1376 WRITE(ITRACK,VERFMT) YRECVER, GITHASH
1377 WRITE(ITRACK,320) DESCRIP(1), DESCRIP(2)
1378 320 320 FORMAT('# DESCRIPTION OF RUN:',A80,/, '#',9X,' ',8X,': ',
1379 * * A80,/,'#', 100('='))
1380
1381 ENDIF
1382 WRITE(ISHORT,323)
1383 323 323 FORMAT(' USING OSCILATORY SPLINE INTERPOLATION IN HPOINT')
1384
1385C INTERPRET RUN FROM SEQUENCE OF "KIND" CARDS
1386
1387 WRITE(ISHORT,200)
1388 200 200 FORMAT(/35X,'RUN CARDS'/)
1389
1390 LFIRST(1) = .TRUE.
1391
1392C RUN LOOP
1393 DO 1000 NKIND=1, NUMRUN
1394C READ IN NMODLS AND MODEL SOURCE(MEMORY OR FIRST MODEL)-SAME FOR ALL
1395 IRESCA(NKIND) = KINDRN(NKIND)
1396 IF(KINDRN(NKIND).EQ.1) THEN
1397C EVOLVE CARD
1398C MHP 10/24 GENERALIZE STOP CONDITIONS
1399C LENDAG(NKIND) = ENDAGE(NKIND).GT.0D0
1400 IF(ENDAGE(NKIND).GT.0.0D0 .OR. END_DCEN(NKIND).GT.0.0D0
1401 * * .OR. END_XCEN(NKIND).GT.0.0D0 .OR. END_YCEN(NKIND).GT.0.0D0)THEN
1402 LENDAG(NKIND)=.TRUE.
1403 ELSE
1404 LENDAG(NKIND)=.FALSE.
1405 ENDIF
1406 LSETDT(NKIND) = SETDT(NKIND).GT.0D0
1407 IF (NMODLS(NKIND).GT.0) THEN
1408 IF (LFIRST(NKIND)) THEN
1409 WRITE(IOWR,350) NKIND,NMODLS(NKIND)
1410 WRITE(ISHORT,350) NKIND,NMODLS(NKIND)
1411 350 350 FORMAT(/1X,'RUN #',I3,' EVOLVE ',I5,
1412 1 1 ' MODELS, STARTING',
1413 2 2 ' WITH THE INPUT "FIRST MODEL".')
1414 ELSE
1415 WRITE(IOWR,351) NKIND, NMODLS(NKIND)
1416 WRITE(ISHORT,351) NKIND, NMODLS(NKIND)
1417 351 351 FORMAT(/1X,'RUN #',I3,' EVOLVE ',I5,
1418 1 1 ' MODELS, STARTING',
1419 1 1 ' WITH THE PREVIOUS RUN''S LAST MODEL.')
1420 END IF
1421C GENERALIZE STOP CONDITIONS
1422 IF(LENDAG(NKIND).OR.LSETDT(NKIND)) THEN
1423 WRITE(IOWR,370)LENDAG(NKIND),LSETDT(NKIND),
1424 * * ENDAGE(NKIND), SETDT(NKIND),END_DCEN(NKIND),
1425 * * END_XCEN(NKIND),END_YCEN(NKIND)
1426 WRITE(ISHORT,370)LENDAG(NKIND),LSETDT(NKIND),
1427 * * ENDAGE(NKIND), SETDT(NKIND),END_DCEN(NKIND),
1428 * * END_XCEN(NKIND),END_YCEN(NKIND)
1429 370 370 FORMAT(1X,'EVOLVE TO AGE ',L1,' SET DELT ',
1430 * * L1,' FINAL AGE ', E9.2,' FIXED TSTEP ',E9.2,
1431 * * ' CENTRAL D ',E10.4,' CENTRAL X ',E12.4,' CENTRAL Y ',E12.4)
1432 ENDIF
1433 END IF
1434 ELSE IF(KINDRN(NKIND).EQ.2) THEN
1435C RESCALE CARD: RESCALE STARTING MODEL
1436C QUANTITIES TO BE RESCALED STORED IN ARRAY RESCALE(4,50)
1437C WHERE THE ELEMENTS MASS,X,Z,CORE MASS ARE STORED IN ORDER
1438 RESCAL(1,NKIND) = RSCLM(NKIND)
1439 RESCAL(2,NKIND) = RSCLX(NKIND)
1440 RESCAL(3,NKIND) = RSCLZ(NKIND)
1441 RESCAL(4,NKIND) = RSCLCM(NKIND)
1442 IF (NMODLS(NKIND) .GT. 0) THEN
1443 IF (LFIRST(NKIND)) THEN
1444 WRITE(IOWR,450) NKIND
1445 WRITE(ISHORT,450) NKIND
1446 450 450 FORMAT(/1X,'RUN #',I3,
1447 1 1 ' RESCALE THE INPUT MODEL: "FIRST MODEL".')
1448 ELSE
1449 WRITE(IOWR,451) NKIND
1450 WRITE(ISHORT,451) NKIND
1451 451 451 FORMAT(/1X,'RUN #',I3,
1452 1 1 ' RESCALE THE PREVIOUS RUN''S LAST MODEL.')
1453 END IF
1454 WRITE(IOWR,452) NMODLS(NKIND),(RESCAL(I,NKIND),I = 1,4)
1455 WRITE(ISHORT,452) NMODLS(NKIND),
1456 1 1 (RESCAL(I,NKIND),I = 1,4)
1457 452 452 FORMAT(1X,'RELAX RESCALED MODEL',I3,
1458 * * ' TIMES. RESCALE THE FOLLOW',
1459 * * 'ING(0=USE CURRENT VALUE):'/1X,'MASS ',
1460 * * F9.6,3X,'X',F9.6,3X,'Z',
1461 * * F9.6,3X,'CORE MASS',F9.6)
1462 END IF
1463 ELSE IF(KINDRN(NKIND).EQ.3) THEN
1464C RESCALE AND EVOLVE CARD: RESCALE STARTING MODEL
1465C QUANTITIES TO BE RESCALED STORED IN ARRAY RESCALE(4,50)
1466C WHERE THE ELEMENTS MASS,X,Z,CORE MASS ARE STORED IN ORDER
1467 RESCAL(1,NKIND) = RSCLM(NKIND)
1468 RESCAL(2,NKIND) = RSCLX(NKIND)
1469 RESCAL(3,NKIND) = RSCLZ(NKIND)
1470 RESCAL(4,NKIND) = RSCLCM(NKIND)
1471 IF (LFIRST(NKIND)) THEN
1472 WRITE(IOWR,550) NKIND
1473 WRITE(ISHORT,550) NKIND
1474 550 550 FORMAT(/1X,'RUN #',I3,
1475 1 1 ' RESCALE & EVOLVE THE INPUT MODEL: "FIRST MODEL".')
1476 ELSE
1477 WRITE(IOWR,451) NKIND
1478 WRITE(ISHORT,451) NKIND
1479C 551 FORMAT(/1X,'RUN #',I3,
1480C 1 ' RESCALE & EVOLVE THE PREVIOUS RUN''S LAST MODEL.')
1481 END IF
1482 WRITE(IOWR,452) NMODLS(NKIND),(RESCAL(I,NKIND),I = 1,4)
1483 WRITE(ISHORT,452) NMODLS(NKIND),
1484 1 1 (RESCAL(I,NKIND),I = 1,4)
1485 END IF
1486 IF(RESCAL(3,NKIND).GE.0.0D0) ZENV=RESCAL(3,NKIND)
1487 1000 1000 CONTINUE
1488 RETURN
1489 END
1490
1491
1492C Replace any defined "{YREC_XXX}" placeholder string in the passed
1493C variable with the value of the corresponding environment variable.
1494 SUBROUTINE EXPAND_VALUE(NML_VAR)
1495C 10/20/26 MHP via Claude
1496C code changed to replace implicit typing with IMPLICIT NONE and
1497C explicit declarations.
1498 IMPLICIT NONE
1499 INTEGER I,NUM_ENVVARS
1500 PARAMETER (NUM_ENVVARS=3) ! Number of possible env. vars.
1501 CHARACTER*256 NML_VAR
1502 CHARACTER*256 TEMP
1503 CHARACTER*256 PHOLDERS(NUM_ENVVARS)
1504 CHARACTER*256 DEFAULTS(NUM_ENVVARS)
1505 CHARACTER*256 PHOLDER
1506 INTEGER STLEN1, STLEN2, PH_LEN, DEF_LEN
1507C Each placeholder (env var name enclosed in curly braces) to be
1508C supported for expansion in namelists, along with default value in the
1509C case where the var is not defined in the execution environment.
1510C The number of assignment pairs here must match the value of the
1511C parameter NUM_ENVVARS, above.
1512 PHOLDERS(1) = "{YREC_INPUT}"
1513 DEFAULTS(1) = "../../input"
1514
1515 PHOLDERS(2) = "{YREC_START}"
1516 DEFAULTS(2) = "../../startmodels"
1517
1518 PHOLDERS(3) = "{YREC_OUTPUT}"
1519 DEFAULTS(3) = "output"
1520
1521 DO 5000 i=1, NUM_ENVVARS
1522 PH_LEN = LEN_TRIM(PHOLDERS(i))
1523 DEF_LEN = LEN_TRIM(DEFAULTS(i))
1524 PHOLDER = PHOLDERS(i)(1:PH_LEN)
1525
1526 IF (NML_VAR(1:PH_LEN) .EQ. PHOLDER) THEN ! If placeholder
1527 CALL getenv(PHOLDER(2:PH_LEN-1), TEMP)
1528 STLEN1 = LEN_TRIM(TEMP)
1529 STLEN2 = LEN_TRIM(NML_VAR)
1530 IF (STLEN1 .NE. 0) THEN ! If env var set
1531 TEMP(STLEN1+1:STLEN1+STLEN2-PH_LEN) = NML_VAR(PH_LEN+1:STLEN2)
1532 !print *,"Override: ",TEMP(1:LEN_TRIM(TEMP))
1533 ELSE ! No env var. Use default path.
1534 TEMP(1:DEF_LEN) = DEFAULTS(i)(1:LEN_TRIM(DEFAULTS(i)))
1535 TEMP(DEF_LEN+1:DEF_LEN+STLEN2) = NML_VAR(PH_LEN+1:STLEN2)
1536 !print *,"default: ",TEMP(1:LEN_TRIM(TEMP))
1537 END IF
1538 NML_VAR = TEMP
1539 END IF
15405000 5000 CONTINUE
1541 END1"""Python version of parmin.f (YREC development, 7be4133): a run's
2parameters, its input and output files, and its run cards."""
3
4import math
5import os
6import re
7import sys
8from types import SimpleNamespace
9
10import numpy as np
11
12from pyrec import acdpth_mod
13from pyrec import ccout_mod
14from pyrec import comp_mod
15from pyrec import constants_mod
16from pyrec import intpar_mod
17from pyrec import iounits_mod
18from pyrec import nmlbypass_mod
19from pyrec import nmlpar_mod
20from pyrec import runloop_mod
21from pyrec.remap import remap
22
23_this = sys.modules[__name__]
24
25# PARMIN's own locals with DATA defaults, kept between calls (SAVE). Arrays
26# have index 0 unused, as everywhere in pyrec. Character values are kept
27# without Fortran's trailing blanks (Fortran lines 481–625).
28kindrn = np.ones(51, dtype=int) # DATA KINDRN/50*1/
29rsclm = np.zeros(51)
30rsclx = np.zeros(51)
31rsclz = np.zeros(51)
32rsclcm = np.zeros(51)
33aid = ['', 'HE3', 'C12', 'C13', 'N14', 'N15', 'O16', 'O17', 'O18', 'H2',
34 'LI6', 'LI7', 'BE9']
35anewcp = ''
36atmp = ''
37# The CNO mixture and isotope sets (MHP 10/24). AMIXT lists the preset
38# mixtures, each with its Z/X and C, N, O fractions of the metals: GS98,
39# Asplund et al. 2021, and Magg et al. (met, phot).
40# Question (see the page): the year of the Magg et al. mixtures.
41amix = 'GS98'
42aiso = 'L21'
43amixt = ['', 'GS98', 'AAG21', 'M22P', 'M22M']
44zxmixt = np.array([0.0, 0.02292, 0.0187, 0.0225, 0.0226])
45frac_ct = np.array([0.0, 0.172148, 0.184156, 0.19239, 0.191425])
46frac_nt = np.array([0.0, 0.050426, 0.050344, 0.059012, 0.058716])
47frac_ot = np.array([0.0, 0.468195, 0.416592, 0.415631, 0.413545])
48alfa = 1.5 # the old wind law's index
49fk = 1.0 # its fudge factor
50wmax_sun = 1000.0 # saturation threshold in solar units (MHP 8/17)
51awind = 'K97' # the Matt et al. presets: 'K97', 'V13' or 'CUS'
52fsound = 'Csound.dat'
53descrip = ['', '', '']
54fdebug = ffirst = flast = ''
55fmilne = fmodpt = fopale06 = fscomp = ''
56fshort = fsnu = fstch = fstor = ftrack = fcondopacp = ''
57fcalcad = '' # FCLCD
58yrec1 = yrec2 = ''
59cmd = ''
60sum_frac = 0.0
61last_slash_idx = 0 # Suspected bug (see the page): unset without a '/'
62mrk = 0
63ncmxck = 0
64lcmxbad = False
65
66# The three namelists, member by member in the Fortran's order, each with
67# where the variable lives: 'nml' NMLPAR_MOD, 'byp' NMLBYPASS_MOD, 'con'
68# CONSTANTS_MOD, 'ipar' INTPAR_MOD, 'loc' a local of PARMIN (this file),
69# 'arg' one of PARMIN's arguments (Fortran lines 335–460).
70_CONTROL = (
71 ('nml', 'cmixla'), ('nml', 'calsolage'), ('nml', 'calsolzx'),
72 ('loc', 'descrip'), ('nml', 'endage'), ('arg', 'fpurez'),
73 ('loc', 'flast'), ('loc', 'ffirst'), ('arg', 'ffermi'), ('loc', 'fdebug'),
74 ('loc', 'ftrack'), ('loc', 'fshort'), ('loc', 'fstch'), ('loc', 'fmilne'),
75 ('loc', 'fmodpt'), ('loc', 'fstor'), ('arg', 'fpmod'), ('arg', 'fpatm'),
76 ('arg', 'fpenv'), ('loc', 'fsnu'), ('loc', 'fscomp'), ('arg', 'fatm'),
77 ('loc', 'fsound'), ('arg', 'fallard'), ('arg', 'fscvh'),
78 ('arg', 'fscvhe'), ('arg', 'fscvz'), ('arg', 'fliv95'), ('nml', 'ipver'),
79 ('nml', 'itrver'), ('loc', 'kindrn'), ('nml', 'ldebug'), ('nml', 'lcorr'),
80 ('nml', 'lmilne'), ('nml', 'ltrack'), ('nml', 'lstore'),
81 ('nml', 'lfirst'), ('nml', 'lstpch'), ('nml', 'lstch'), ('nml', 'lstatm'),
82 ('nml', 'lstenv'), ('nml', 'lstmod'), ('nml', 'lstphys'),
83 ('nml', 'lstrot'), ('nml', 'lpulse'), ('nml', 'lzramp'), ('nml', 'lteff'),
84 ('nml', 'lcalst'), ('nml', 'lpurez'), ('nml', 'lrwsh'),
85 ('nml', 'lsenv0a'), ('nml', 'lpout'), ('nml', 'lcals'),
86 ('nml', 'lcalsolzx'), ('nml', 'lopal95'), ('nml', 'npoint'),
87 ('byp', 'npenv'), ('nml', 'nprtmod'), ('nml', 'nprtpt'),
88 ('nml', 'numrun'), ('nml', 'nmodls'), ('nml', 'poa'), ('nml', 'pob'),
89 ('nml', 'poc'), ('nml', 'pomax'), ('loc', 'rsclm'), ('loc', 'rsclx'),
90 ('loc', 'rsclz'), ('loc', 'rsclcm'), ('nml', 'rsclzc'),
91 ('nml', 'rsclzm1'), ('nml', 'rsclzm2'), ('nml', 'setdt'),
92 ('nml', 'senv0a'), ('nml', 'steff'), ('nml', 'sr'), ('nml', 'tolr'),
93 ('nml', 'toll'), ('nml', 'tolz'), ('nml', 'xenv0a'), ('nml', 'xls'),
94 ('nml', 'xlstol'), ('nml', 'zenv0a'), ('nml', 'zopal951'),
95 ('loc', 'fcondopacp'), ('loc', 'fopale06'), ('arg', 'falex06'),
96 ('nml', 'lalex06'), ('nml', 'end_dcen'), ('nml', 'end_xcen'),
97 ('nml', 'end_ycen'), ('nml', 'l_zerodt_prems'), ('byp', 'isetmix'),
98 ('byp', 'isetiso'),
99 ('loc', 'amix'), ('loc', 'aiso'), ('nml', 'frac_c'), ('nml', 'frac_n'),
100 ('nml', 'frac_o'), ('nml', 'r12_13'), ('byp', 'r14_15'),
101 ('byp', 'r16_17'), ('nml', 'r16_18'), ('byp', 'zxmix'),
102 ('nml', 'xh2_ini'), ('nml', 'xhe3_ini'), ('nml', 'xli6_ini'),
103 ('nml', 'xli7_ini'), ('nml', 'xbe9_ini'), ('byp', 'xb10_ini'),
104 ('byp', 'xb11_ini'),
105)
106
107_PHYSICS = (
108 ('nml', 'atmmin'), ('nml', 'atmbeg'), ('nml', 'atmerr'),
109 ('nml', 'atmmax'), ('nml', 'atmd0'), ('loc', 'anewcp'), ('loc', 'atmp'),
110 ('nml', 'acfpft'), ('nml', 'atime'), ('nml', 'alphac'), ('nml', 'alphae'),
111 ('loc', 'alfa'), ('nml', 'alpham'), ('nml', 'atmstp'), ('nml', 'abstol'),
112 ('nml', 'betac'), ('nml', 'cmin'), ('con', 'clsun'), ('con', 'crsun'),
113 ('nml', 'dpenv'), ('nml', 'dtdif'), ('nml', 'dtwind'), ('nml', 'djok'),
114 ('nml', 'dt_gs'), ('nml', 'enverr'), ('nml', 'envmax'), ('nml', 'envmin'),
115 ('nml', 'envbeg'), ('nml', 'envstp'), ('nml', 'etadh0'),
116 ('nml', 'etadh1'), ('nml', 'fcorr0'), ('nml', 'fcorri'), ('loc', 'fk'),
117 ('nml', 'fw'), ('nml', 'fc'), ('byp', 'fo'), ('nml', 'fmu'),
118 ('nml', 'fes'), ('nml', 'fcore'), ('nml', 'fgsf'), ('nml', 'fss'),
119 ('nml', 'fesc'), ('nml', 'fssc'), ('nml', 'fgsfc'), ('nml', 'fgry'),
120 ('nml', 'fgrz'), ('nml', 'grtol'), ('nml', 'htoler'), ('nml', 'hpttol'),
121 ('nml', 'itfp1'), ('nml', 'itfp2'), ('ipar', 'imax'), ('nml', 'itdif1'),
122 ('nml', 'itdif2'), ('nml', 'ies'), ('nml', 'igsf'), ('nml', 'imu'),
123 ('nml', 'ilambda'), ('nml', 'kttau'), ('nml', 'kemmax'), ('nml', 'lvfc'),
124 ('nml', 'ldifad'), ('nml', 'lnoj'), ('nml', 'lnewdif'), ('nml', 'ldify'),
125 ('nml', 'ldifz'), ('nml', 'ldifli'), ('nml', 'lsnu'), ('nml', 'ldh'),
126 ('nml', 'lnewcp'), ('nml', 'lkuthe'), ('nml', 'lovstc'),
127 ('nml', 'lovste'), ('nml', 'lovstm'), ('nml', 'lovmax'),
128 ('nml', 'lexcom'), ('nml', 'lrot'), ('nml', 'lnew0'), ('nml', 'linstb'),
129 ('nml', 'lwnew'), ('nml', 'ljdot0'), ('nml', 'lptime'), ('nml', 'ladov'),
130 ('nml', 'ltrist'), ('byp', 'lenvg'), ('nml', 'lnulos1'),
131 ('nml', 'lthoul'), ('nml', 'lthoulfit'), ('nml', 'lcore'),
132 ('nml', 'lsemic'), ('nml', 'lnews'), ('nml', 'mcore'), ('nml', 'niter1'),
133 ('nml', 'niter2'), ('nml', 'niter3'), ('nml', 'niter4'), ('ipar', 'nuse'),
134 ('nml', 'niter_gs'), ('nml', 'optol'), ('nml', 'rcrit'),
135 ('nml', 'reltol'), ('ipar', 'stolr0'), ('nml', 'tcut'), ('nml', 'tscut'),
136 ('nml', 'tenv0'), ('nml', 'tenv1'), ('nml', 'tgcut'), ('nml', 'tridt'),
137 ('nml', 'tridl'), ('nml', 'tollaol'), ('nml', 'vnew'), ('nml', 'walpcz'),
138 ('nml', 'wnew'), ('nml', 'weakscreening'), ('nml', 'xnewcp'),
139 ('nml', 'xmin'), ('nml', 'ymin'), ('nml', 'tmolmin'), ('nml', 'tmolmax'),
140 ('nml', 'sstandard'), ('nml', 'lscv'), ('nml', 'ldisk'), ('nml', 'tdisk'),
141 ('nml', 'pdisk'), ('nml', 'wmax'), ('nml', 'lsolid'), ('nml', 'impjmod'),
142 ('nml', 'dmdt0'), ('nml', 'fczdmdt'), ('nml', 'ftotdmdt'),
143 ('nml', 'compacc'), ('nml', 'creim'), ('nml', 'lreimer'),
144 ('nml', 'lmdot'), ('nml', 'lcondopacp'), ('nml', 'lopale06'),
145 ('nml', 'lnumderiv'), ('nml', 'alatm_feh'), ('nml', 'alatm_alpha'),
146 ('nml', 'laltptau100'), ('nml', 'cstmixing'), ('nml', 'cstdiffmix'),
147 ('nml', 'lsolwind'), ('nml', 'lmwind'), ('nml', 'lrossby'),
148 ('nml', 'lbscale'), ('loc', 'awind'), ('byp', 'pmma'), ('byp', 'pmmb'),
149 ('byp', 'pmmc'), ('byp', 'pmmd'), ('byp', 'pmmm'), ('byp', 'pmmjd'),
150 ('byp', 'pmmmd'), ('nml', 'pmmsolp'), ('nml', 'pmmsolw'),
151 ('nml', 'pmmsoltau'), ('nml', 'lcodm'), ('nml', 'codm'),
152 ('loc', 'wmax_sun'), ('byp', 'xsli6'), ('byp', 'xsli7'),
153 ('byp', 'xsbe91'), ('byp', 'xsbe92'), ('byp', 'xsbe93'), ('byp', 'lxli6'),
154 ('byp', 'lxli7'), ('byp', 'lxbe91'), ('byp', 'lxbe92'), ('byp', 'lxbe93'),
155 ('nml', 'sli6'), ('nml', 'sli7'), ('nml', 'sbe91'), ('nml', 'sbe92'),
156 ('nml', 'sbe93'), ('byp', 'lnewnuc'), ('nml', 'spotf'), ('nml', 'spotx'),
157 ('nml', 'lsdepth'), ('byp', 's0_1_1'), ('byp', 's0_3_3'),
158 ('byp', 's0_3_4'), ('byp', 's0_1_12'), ('byp', 's0_1_13'),
159 ('byp', 's0_1_14'), ('byp', 's0_1_16'), ('byp', 's0_pep'),
160 ('byp', 's0_1_be7e'), ('byp', 's0_1_be7p'), ('byp', 's0_hep'),
161 ('byp', 's0_1_15_c12alp'), ('byp', 's0_1_15_o16'), ('byp', 's0p_1_1'),
162 ('byp', 's0p_3_3'), ('byp', 's0p_3_4'), ('byp', 's0p_1_12'),
163 ('byp', 's0p_1_13'), ('byp', 's0p_1_14'), ('byp', 's0p_1_16'),
164 ('byp', 's0pp_1_12'), ('byp', 's0pp_1_13'), ('byp', 's0pp_1_16'),
165 ('byp', 's0p_1_be7p'), ('byp', 's0pp_1_be7p'), ('byp', 'flag_dx'),
166 ('byp', 'flag_dw'), ('byp', 'flag_dz'), ('byp', 'lstruct_time'),
167 ('byp', 'time_core_min'), ('byp', 'time_dl'), ('byp', 'time_dp'),
168 ('byp', 'time_dr'), ('byp', 'time_dt'), ('byp', 'time_dw_global'),
169 ('byp', 'time_dw_mix'), ('byp', 'time_dx_core_frac'),
170 ('byp', 'time_dx_core_tot'), ('byp', 'time_dx_shell'),
171 ('byp', 'time_dx_total'), ('byp', 'time_dy_core_frac'),
172 ('byp', 'time_dy_core_tot'), ('byp', 'time_dy_shell'),
173 ('byp', 'time_dy_total'), ('byp', 'tol_czbase_fine_width'),
174 ('byp', 'tol_dl_max'), ('byp', 'tol_dm_max'), ('byp', 'tol_dm_min'),
175 ('byp', 'tol_dp_core_max'), ('byp', 'tol_dp_czbase_max'),
176 ('byp', 'tol_dp_env_max'), ('byp', 'tol_dx_max'), ('byp', 'tol_dz_max'),
177 ('byp', 'time_max_dt_frac'), ('byp', 'lnewvars'), ('nml', 'lnewtcz'),
178 ('nml', 'lcalcenv'),
179)
180
181_DERIVED = (
182 ('con', 'cln'), ('con', 'cc13'), ('con', 'cc23'), ('nml', 'constfactor'),
183 ('nml', 'excen'), ('nml', 'exl'), ('nml', 'exm'), ('nml', 'exmd'),
184 ('nml', 'expr'), ('nml', 'exr'), ('nml', 'extau'), ('nml', 'exw'),
185 ('nml', 'wmax'), ('nml', 'ldify'), ('nml', 'ldifz'), ('nml', 'lthoul'),
186 ('nml', 'lthoulfit'), ('nml', 'lnew0'), ('nml', 'lnewdif'),
187 ('nml', 'ilambda'), ('nml', 'sli6'), ('nml', 'sli7'), ('nml', 'sbe91'),
188 ('nml', 'sbe92'), ('nml', 'sbe93'), ('nml', 'frac_c'), ('nml', 'frac_n'),
189 ('nml', 'frac_o'), ('byp', 'zxmix'), ('loc', 'sum_frac'),
190 ('nml', 'lisotope'), ('nml', 'lmixture'), ('nml', 'inewcp'),
191 ('nml', 'lrel'), ('nml', 'kttau0'), ('nml', 'lttau'),
192)
193
194# The .store file's header key (format 1012).
195_STORE_KEY = (
196 "# Header Key\n"
197 "# ModType ModNum #Shells M/Msun log(Teff) log(L/Lsun)"
198 " log(M/gram) Age/Gyr Timestep/yr log(M_inner/gram)"
199 " log(M_outer/gram)\n"
200 "# JCORE JENV CMIXL EOS ATM ALOK HIK LPUREZ COMPMIX LEXCOM"
201 " LDIFY LDIFZ LSEMIC LOVSTC LOVSTE LOVSTM LROT LINSTB LJDOT0"
202 " LDISK TDISK PDISK WMAX LSTORE LSTATM LSTENV LSTMOD LSTPHYS"
203 " LSTROT\n"
204 "# PPI_lum PPII_lum PPIII_lum CNO_lum 3He_lum "
205 "OldNeu_lum Grav_lum\n"
206 "# ENV1-3 log(Teff) log(L/Lsun) P_base T_base R_base"
207 " MatrixElements\n")
208
209# The atmosphere choice by KTTAU (formats 197, 198, 1999, 1888, 1889,
210# 1887).
211_KTTAU_TEXT = {
212 0: " USING EDDINGTON T-TAU RELATION.",
213 1: " USING KRISHNA-SWAMY T-TAU RELATION.",
214 2: " USING HARVARD-SMITHSONIAN REFERENCE ATMOSPHERE",
215 3: " USING KURUCZ ATMOSPHERE TABLE",
216 4: " USING ALLARD ATMOSPHERE TABLE",
217 5: " USING KURUCZ/CASTELLI ATMOSPHERE TABLE",
218}
219
220
221def _l(flag):
222 """A logical in an L format: T or F."""
223
224 return 'T' if flag else 'F'
225
226
227def _owners(args):
228 return {'nml': nmlpar_mod, 'byp': nmlbypass_mod, 'con': constants_mod,
229 'ipar': intpar_mod, 'loc': _this, 'arg': args}
230
231
232def _value(token, like):
233 """Convert one namelist value to the type of the variable it sets."""
234
235 if isinstance(like, (bool, np.bool_)):
236 t = token.upper().lstrip('.')
237 return t.startswith('T')
238 if isinstance(like, str):
239 if token[:1] in "'\"":
240 return token[1:-1].replace(token[0] * 2, token[0])
241 return token
242 number = token.replace('d', 'e').replace('D', 'E')
243 if isinstance(like, (int, np.integer)):
244 return int(float(number))
245 return float(number)
246
247
248def _fortran_order(shape, start):
249 """The indices of an array (index 0 unused) from `start` on, in
250 Fortran's order: the first index varies fastest."""
251
252 idx = list(start)
253 while True:
254 yield tuple(idx)
255 for d in range(len(idx)):
256 idx[d] += 1
257 if idx[d] < shape[d]:
258 break
259 idx[d] = 1
260 else:
261 return
262
263
264def _read_namelist(path, group, members, owners):
265 """READ(UNIT, NML=group): a minimal reader for the namelist files YREC
266 uses (name = values, name(i) = values, repeat counts r*v, quoted
267 strings, logicals, D exponents, '!' comments). Each value is stored
268 where its variable lives."""
269
270 table = {name: (owners[where], name) for where, name in members}
271 with open(path) as f:
272 # Drop '!' comments, outside quoted strings.
273 text = ''.join(re.sub(r"^((?:[^'\"!]|'[^']*'|\"[^\"]*\")*)!.*",
274 r"\1", line) for line in f)
275 start = re.search(r'[&$]' + group + r'\b', text, re.IGNORECASE)
276 if start is None:
277 raise SystemExit(f"namelist /{group}/ not found in {path}")
278 body = text[start.end():]
279 tokens = re.findall(r"'(?:[^']|'')*'|\"(?:[^\"]|\"\")*\"|"
280 r"[A-Za-z_]\w*\s*(?:\([^)]*\))?\s*=|/|"
281 r"[&$]END\b|[^\s,'\"/=]+", body, re.IGNORECASE)
282 target = None
283 for tok in tokens:
284 if tok == '/' or tok.upper().lstrip('&$') == 'END':
285 break
286 if tok.endswith('='):
287 m = re.match(r'(\w+)\s*(?:\(([^)]*)\))?', tok)
288 owner, attr = table[m.group(1).lower()]
289 current = getattr(owner, attr)
290 if m.group(2):
291 first = tuple(int(i) for i in m.group(2).split(','))
292 else:
293 first = None
294 if isinstance(current, np.ndarray):
295 place = _fortran_order(current.shape,
296 first or (1,) * current.ndim)
297 elif isinstance(current, list):
298 place = iter(range(first[0] if first else 1, len(current)))
299 else:
300 place = None
301 target = (owner, attr, current, place)
302 continue
303 owner, attr, current, place = target
304 count, _, item = tok.rpartition('*') if re.match(r'\d+\*', tok) \
305 else ('1', '', tok)
306 for _ in range(int(count)):
307 if place is None:
308 setattr(owner, attr, _value(item, current))
309 else:
310 where = next(place)
311 like = current[where]
312 current[where] = _value(item, like)
313
314
315def _format_value(v):
316 if isinstance(v, (bool, np.bool_)):
317 return _l(v)
318 if isinstance(v, str):
319 return "'" + v + "'"
320 return repr(v.item() if isinstance(v, np.generic) else v)
321
322
323def _write_namelist(unit, group, members, owners):
324 """WRITE(UNIT, NML=group): every member with its value (the layout
325 approximates the compiler's)."""
326
327 lines = [f"&{group}"]
328 for where, name in members:
329 v = getattr(owners[where], name)
330 if isinstance(v, np.ndarray):
331 sub = v[(slice(1, None),) * v.ndim].ravel(order='F')
332 text = ', '.join(_format_value(x) for x in sub)
333 elif isinstance(v, list):
334 text = ', '.join(_format_value(x) for x in v[1:])
335 else:
336 text = _format_value(v)
337 lines.append(f" {name.upper()}={text},")
338 lines.append("/")
339 iounits_mod.write(unit, "\n".join(lines))
340
341
342def _both(text):
343 """WRITE(*, fmt) and WRITE(ISHORT, fmt) of the same record."""
344
345 print(text)
346 iounits_mod.write(iounits_mod.ishort, text)
347
348
349def _screen_and_short(text):
350 """WRITE(IOWR, fmt) and WRITE(ISHORT, fmt) of the same record."""
351
352 iounits_mod.write(iounits_mod.iowr, text)
353 iounits_mod.write(iounits_mod.ishort, text)
354
355
356def parmin(falex06: str, fallard: str, fatm: str, ffermi: str, fliv95: str, fpatm: str, fpenv: str, fpmod: str,
357 fpurez: str, fscvh: str, fscvhe: str, fscvz: str, yrecver: str,
358 githash: str) -> tuple[str, str, str, str, str, str, str, str, str, str, str, str]:
359 """Read the run's parameters from the CONTROL and PHYSICS namelists into
360 the modules, set the unit numbers, expand the file names' placeholders,
361 open the output files and some tables, derive settings (wind law,
362 mixtures, settling switches), write the settings to the .short file,
363 and interpret the run cards.
364
365 Translates: parmin.f#PARMIN (7be4133)
366
367 Arguments: the 12 table file names (set from the CONTROL namelist; any
368 value), and yrecver, githash, the code's version and git hash.
369
370 Returns (falex06, fallard, fatm, ffermi, fliv95, fpatm, fpenv, fpmod,
371 fpurez, fscvh, fscvhe, fscvz): the file names as read and expanded.
372
373 """
374
375 global anewcp, atmp, sum_frac, last_slash_idx, mrk, ncmxck, lcmxbad
376 global yrec1, yrec2, cmd, fcalcad
377 me = _this
378 io = iounits_mod
379 nml = nmlpar_mod
380 byp = nmlbypass_mod
381 c = constants_mod
382 args = SimpleNamespace(falex06=falex06, fallard=fallard, fatm=fatm,
383 ffermi=ffermi, fliv95=fliv95, fpatm=fpatm,
384 fpenv=fpenv, fpmod=fpmod, fpurez=fpurez,
385 fscvh=fscvh, fscvhe=fscvhe, fscvz=fscvz)
386 owners = _owners(args)
387
388 # All logical unit numbers (Fortran lines 654–738).
389 io.iowr = 6 # output: status file (the screen)
390 io.ilast = 11 # output: last model
391 io.ifirst = 12 # input: first model
392 io.irun = 13 # input: PHYSICS namelist
393 io.istand = 14 # input: CONTROL namelist
394 io.ifermi = 15 # input: Fermi tables
395 io.idebug = 18 # output: debugging
396 io.itrack = 19 # output: track
397 io.ishort = 20 # output: all diagnostic information
398 io.imilne = 21 # output: Milne invariant variables
399 io.imodpt = 22 # output: shell by shell information
400 io.istor = 23 # output: saved models
401 io.iopmod = 24 # output: pulsation, interior
402 io.iopenv = 25 # output: pulsation, envelope
403 io.iopatm = 26 # output: pulsation, atmosphere
404 io.isound = 500 # output: sound-speed profile (WRTMOD, LSOUND)
405 io.iliv95 = 48 # input: OPAL95 opacity table
406 io.isnu = 33 # output: neutrino fluxes
407 io.ioatm = 38 # input: Kurucz atmosphere table
408 io.iopale = 49 # input: OPAL equation of state
409 io.iopurez = 62 # input: pure C and N opacities
410 io.ioatma = 66 # input: Allard model atmospheres
411 io.iscvh = 72 # input: SCV EOS tables
412 io.iscvhe = 73
413 io.iscvz = 74
414 io.icondopacp = 75 # input: Potekhin conductive opacities
415 # Default [Fe/H] and alpha for the new Allard atmospheres (Fortran lines
416 # 733–735).
417 nml.alatm_feh = 0.0
418 nml.alatm_alpha = 0.0
419 nml.laltptau100 = False
420 io.ialex06 = 90 # input: Alexander 2006 opacities
421
422
423 # The version line (Fortran lines 740–756).
424 print(' ')
425 print(f" Yale Rotating Evolution Code - YREC, v{yrecver.rstrip()} "
426 f"({githash.rstrip()})")
427 # VERFMT, the version line (format built at run time, 315).
428 verline = f"# YREC v{yrecver.rstrip()} ({githash.rstrip()})"
429
430
431 # The namelist files from the command line, or the defaults (JVS 02/11)
432 # (Fortran lines 758–771).
433 yrec1 = sys.argv[1] if len(sys.argv) > 1 else ''
434 if yrec1[:2].strip() == '':
435 yrec1 = 'yrec8.nml1'
436 print(' ')
437 print(f" CONTROL namelist : {yrec1.rstrip()}")
438 yrec2 = sys.argv[2] if len(sys.argv) > 2 else ''
439 if yrec2[:2].strip() == '':
440 yrec2 = 'yrec8.nml2'
441 print(f" PHYSICS namelist : {yrec2.rstrip()}")
442 # OPEN, READ(NML=...) and CLOSE of ISTAND and IRUN.
443 _read_namelist(yrec1, 'CONTROL', _CONTROL, owners)
444 _read_namelist(yrec2, 'PHYSICS', _PHYSICS, owners)
445
446 # Map the newer inputs onto the vectors the code uses (MHP 8/14)
447 # (Fortran lines 772–775).
448 # Question (see the page): the old entries that REMAP overwrites.
449 remap()
450
451 # Remember the original atmosphere choice (SURFBC may switch it) (MHP
452 # 06/13) (Fortran lines 776–779).
453 nml.kttau0 = nml.kttau
454 nml.lttau = False
455
456 # Expand a leading placeholder in every file name (Fortran lines
457 # 788–813).
458 for where, name in (('arg', 'falex06'), ('arg', 'fallard'),
459 ('arg', 'fatm'), ('loc', 'fcondopacp'),
460 ('arg', 'ffermi'), ('loc', 'ffirst'),
461 ('loc', 'flast'), ('arg', 'fliv95'),
462 ('loc', 'fmodpt'), ('loc', 'fopale06'),
463 ('arg', 'fpatm'), ('arg', 'fpenv'), ('arg', 'fpmod'),
464 ('arg', 'fpurez'), ('loc', 'fscomp'),
465 ('arg', 'fscvh'), ('arg', 'fscvhe'),
466 ('arg', 'fscvz'), ('loc', 'fshort'),
467 ('loc', 'fsnu'), ('loc', 'fsound'), ('loc', 'fstor'),
468 ('loc', 'ftrack')):
469 owner = owners[where]
470 setattr(owner, name, expand_value(getattr(owner, name)))
471
472 # Create the output folder, FTRACK up to its last '/' (Fortran lines
473 # 814–828).
474 for i in range(len(me.ftrack.rstrip()), 0, -1):
475 if me.ftrack[i - 1] == '/':
476 last_slash_idx = i
477 break
478 # label 1250. Suspected bug (see the page): no '/' leaves
479 # LAST_SLASH_IDX unset.
480 cmd = 'mkdir -p "' + me.ftrack[:last_slash_idx] + '"'
481 print(f" OUTPUT placed in : {me.ftrack[:last_slash_idx]}")
482 print(' ')
483 os.system(cmd)
484
485 # The acoustic-depth output, named after the .short file (JVS 02/11)
486 # (Fortran lines 830–850).
487 if acdpth_mod.lacout:
488 io.iclcd = 91
489 mrk = me.fshort.find('short') + 1 # INDEX: 0 if absent
490 # Possible bug (see the page): no 'short' in FSHORT gives
491 # plain 'calcad' in the current folder.
492 fcalcad = me.fshort[:max(mrk - 1, 0)] + 'calcad'
493 io.open(io.iclcd, fcalcad, status='UNKNOWN')
494 io.write(io.iclcd, ' Acoustic depth calculation output file')
495 # The second string continues onto a continuation line in the
496 # Fortran; its blanks are kept as in the source.
497 io.write(io.iclcd, ' age (Gyr),radius(cm),1/sound speed(s/cm),'
498 'radius (CZ), 1/cs (CZ) delad,gamma1,P, T, X')
499
500 # Li/Be cross sections given by the user, as factors on the defaults (Li6
501 # 5.5 MeV b; Li7 52 keV b; Be9 1.1, 15000, 15000 keV b) (G Somers 6/14)
502 # (Fortran lines 855–876).
503 if byp.lxli6:
504 nml.sli6 = byp.xsli6 / 5.5e3
505 if byp.lxli7:
506 nml.sli7 = byp.xsli7 / 5.2e1
507 if byp.lxbe91:
508 nml.sbe91 = byp.xsbe91 / 1.1
509 if byp.lxbe92:
510 nml.sbe92 = byp.xsbe92 / 1.5e4
511 if byp.lxbe93:
512 nml.sbe93 = byp.xsbe93 / 1.5e4
513
514 # The OPAL 2006 EOS table (Fortran lines 877–882).
515 if nml.lopale06:
516 io.open(io.iopale, me.fopale06, status='OLD')
517
518 # The stored models, with their header if LSTORE (Fortran lines
519 # 888–899).
520 io.open(io.istor, me.fstor, status='UNKNOWN')
521 io.rewind(io.istor)
522 if nml.lstore:
523 # The stitched interior and envelope option (JvS 08/25).
524 if nml.lstch:
525 ccout_mod.lphhd = True
526 else:
527 io.write(io.istor, verline)
528 io.write(io.istor, _STORE_KEY) # format 1012
529
530
531 # The .short file and the other files (Fortran lines 924–977).
532 io.open(io.ishort, me.fshort, status='UNKNOWN')
533 io.rewind(io.ishort)
534 # The sound-speed profile, opened always (LSOUND is known only later).
535 io.open(io.isound, me.fsound, status='UNKNOWN')
536 io.rewind(io.isound)
537 if nml.ltrack:
538 io.open(io.itrack, me.ftrack, status='UNKNOWN')
539 io.rewind(io.itrack)
540 if nml.lsnu:
541 io.open(io.isnu, me.fsnu, status='UNKNOWN')
542 io.rewind(io.isnu)
543 if nml.ldebug:
544 io.open(io.idebug, me.fdebug, status='UNKNOWN')
545 if nml.lmilne:
546 io.open(io.imilne, me.fmilne, status='UNKNOWN', access='APPEND')
547 io.open(io.ifirst, me.ffirst, status='OLD')
548 io.open(io.ilast, me.flast, status='UNKNOWN')
549 io.open(io.imodpt, me.fmodpt, status='UNKNOWN')
550 if nml.lpulse:
551 io.open(io.iopmod, args.fpmod, status='UNKNOWN')
552 io.open(io.iopenv, args.fpenv, status='UNKNOWN')
553 io.open(io.iopatm, args.fpatm, status='UNKNOWN')
554 if nml.lcondopacp:
555 io.open(io.icondopacp, me.fcondopacp, status='OLD')
556
557 # Semiconvection with any overshoot stops the run (Fortran lines
558 # 978–989).
559 # Question (see the page): why may the two not be combined?
560 if nml.lsemic:
561 if nml.lovstc or nml.lovste or nml.lovstm:
562 io.write(io.ishort,
563 f" ERROR IN SUBROUTINE PARMIN\nSEMI-CONVECTION AND "
564 f"OVERSHOOT FLAGS BOTH TURNED ON\nFLAGS LSEMIC "
565 f"{_l(nml.lsemic)} OVERSHOOT - CORE,ENVELOPE,"
566 f"INTERMEDIATE- {_l(nml.lovste)} {_l(nml.lovstc)} "
567 f"{_l(nml.lovstm)}\nRUN STOPPED") # format 2
568 raise SystemExit(3)
569 # LDIFAD with rotation stops the run: the advection-diffusion transport
570 # (DADCOEFT) reads coefficients that no routine sets (Fortran lines
571 # 990–1007).
572 if nml.lrot and nml.ldifad:
573 text = (" ERROR IN SUBROUTINE PARMIN\n LDIFAD (ADVECTION-DIFFUSION "
574 "TRANSPORT OF ANGULAR MOMENTUM) IS NOT IMPLEMENTED:\n "
575 "DADCOEFT READS COEFFICIENTS THAT NO ROUTINE SETS. SET "
576 "LDIFAD = .FALSE. FOR ROTATING RUNS.\nRUN STOPPED") # format 3
577 io.write(io.ishort, text)
578 print(text)
579 raise SystemExit(1)
580
581 # The line of tolerances and rotation settings (Fortran lines
582 # 1008–1016).
583 io.write(io.ishort,
584 " PT TOL" + ''.join(f"{nml.hpttol[i]:6.3f}" for i in range(1, 13))
585 + f"\n O.S.ENV{nml.alphae:6.3f} O.S.CORE{nml.alphac:6.3f}"
586 f" LINSTB {_l(nml.linstb)} LJDOT {_l(nml.ljdot0)} WIND IND."
587 f"{me.alfa:6.3f} FK{me.fk:8.2E}\n FV{nml.fw:5.2f} FC"
588 f"{nml.fc:5.2f} COUPLING{byp.fo:6.3f} F MU{nml.fmu:5.2f}"
589 f" RCRIT{nml.rcrit:9.1f}") # format 1
590
591 # Rotation and the wind law (Fortran lines 1017–1117).
592 if nml.lrot:
593 nml.lnew0 = True
594 if nml.walpcz < -2.0:
595 nml.walpcz = -2.0
596 if nml.walpcz > 0.0:
597 nml.walpcz = 0.0
598 # LSOLID overrides IMPJMOD (JNT 09/2025).
599 if nml.lsolid:
600 nml.impjmod = 1
601 if not nml.lmwind:
602 # The old wind law:
603 # JDOT = FK*2.036D33*1.452D9**ALFA*(MDOT/1.0D-14)**(1-2ALFA/3)
604 # *OMEGA**(1+4ALFA/3)*(R/RSUN)**(2-ALFA)*(M/MSUN)**-ALFA/3
605 # Question (see the page): the units of OMEGA and JDOT.
606 c.cc13 = 1.0 / 3.0
607 c.cc23 = 2.0 / 3.0
608 nml.constfactor = me.fk * 2.036e33 * 1.452e9**me.alfa
609 nml.exmd = 1.0 - c.cc23 * me.alfa
610 nml.exw = 1.0 + 2.0 * c.cc23 * me.alfa
611 nml.exr = 2.0 - me.alfa
612 nml.exm = -c.cc13 * me.alfa
613 else:
614 # The Matt et al. law: the indices a, b, c, d, m, preset by
615 # AWIND ('CUS' keeps the namelist's), give the exponents.
616 if me.awind == 'K97':
617 byp.pmmm = me.alfa / 3.0
618 # The default for A is 2, not 0 (MHP 8/17).
619 byp.pmma = 2.0
620 byp.pmmb = 1.0
621 byp.pmmc = 2.0
622 byp.pmmd = 0.0
623 nml.lbscale = False
624 elif me.awind == 'V13':
625 byp.pmmm = 0.22
626 byp.pmma = 2.0
627 byp.pmmb = 1.0
628 byp.pmmc = 0.0
629 byp.pmmd = 1.0
630 nml.lbscale = True
631 nml.exw = (1.0 + byp.pmma - 2.0 * byp.pmma * byp.pmmm
632 + 4.0 * byp.pmmm * byp.pmmb)
633 # The tau_cz term is applied in MWIND/MCOWIND, not here (G Somers
634 # 8/17).
635 nml.extau = 0.0
636 # EXR with the typo removed (JvS 09/25). Question (see the page):
637 # the Fortran comment's derivation gives another exponent.
638 nml.exr = 2.0 + 5.0 * byp.pmmm - 4.0 * byp.pmmm * byp.pmmc
639 nml.exm = -byp.pmmm
640 nml.exl = 1.0 - 2.0 * byp.pmmm
641 nml.expr = 2.0 * byp.pmmm * byp.pmmd
642 nml.excen = byp.pmmm * byp.pmmd
643 # The constant factor of the centrifugal term.
644 c.c_2 = 0.0506
645 nml.constfactor = me.fk * byp.pmmjd / nml.pmmsolw**nml.exw
646 # WMAX_SUN < 1000: saturation, at WMAX_SUN times the solar rate.
647 if me.wmax_sun < 1.0e3:
648 nml.wmax = me.wmax_sun * nml.pmmsolw
649 # Wind law end.
650
651 # Fortran line 1119.
652 c.cln = math.log(10.0)
653
654 # A single species to rescale in the starting model (Fortran lines
655 # 1120–1138).
656 if nml.lnewcp:
657 nml.lrel = True
658 if atmp.rstrip() == 'ABS':
659 nml.lrel = False
660 for i in range(1, 13):
661 if anewcp.rstrip() == aid[i]:
662 # INEWCP, the index of the element in HCOMP.
663 nml.inewcp = i + 3
664 break
665 else:
666 # ANEWCP is not a recognized element (format 20).
667 nml.lnewcp = False
668 io.write(io.ishort, f" VARIABLE{anewcp:>4} NOT A RECOGNIZED "
669 f"ELEMENT\n RESCALING NOT PERFORMED")
670 # label 30
671
672 # The CNO mixture (ISETMIX) and the isotope ratios and light-element
673 # abundances (ISETISO) of the starting model (MHP 10/24) (Fortran lines
674 # 1139–1191).
675 # Suspected bug (see the page): ISETMIX = 2 and ISETISO = 2, the
676 # documentation's custom mixtures, do nothing.
677 nml.lmixture = False
678 nml.lisotope = False
679 to_606 = True # False where the Fortran jumps to label 602
680 if byp.isetmix == 1:
681 if me.amix.rstrip() == 'CUS':
682 # A custom mixture: no negative fraction, sum below one.
683 if nml.frac_c < 0.0 or nml.frac_n < 0.0 or nml.frac_o < 0.0:
684 _both(f"NEGATIVE INPUT CNO FRACTION {nml.frac_c:12.4E}"
685 f"{nml.frac_n:12.4E}{nml.frac_o:12.4E}"
686 " MIX NOT MODIFIED") # 591
687 to_606 = False
688 else:
689 sum_frac = nml.frac_c + nml.frac_n + nml.frac_o
690 if sum_frac >= 1.0:
691 _both(f"INPUT CNO FRACTION {nml.frac_c:12.4E}"
692 f"{nml.frac_n:12.4E}{nml.frac_o:12.4E}"
693 " EXCEEDS 1. MIX NOT MODIFIED") # 598
694 to_606 = False
695 else:
696 nml.lmixture = True
697 else:
698 # A preset mixture, if its name is known.
699 for i in range(1, 5):
700 if me.amix.rstrip() == amixt[i]:
701 byp.zxmix = zxmixt[i]
702 nml.frac_c = frac_ct[i]
703 nml.frac_n = frac_nt[i]
704 nml.frac_o = frac_ot[i]
705 nml.lmixture = True
706 break
707 else:
708 _both(f"DESIRED CNO MIXTURE {me.amix:8} NOT FOUND."
709 " MIX NOT ALTERED.") # 589
710 # label 606
711 if to_606 and nml.lmixture:
712 _both(f"CNO MIXTURE {me.amix:8} C {nml.frac_c:12.4E} N "
713 f"{nml.frac_n:12.4E} O {nml.frac_o:12.4E} APPLIED TO "
714 "STARTING MODEL.") # 604
715
716 # label 602: the isotope ratios (Fortran lines 1192–1237).
717 to_605 = True # False where the Fortran jumps to label 603
718 if byp.isetiso == 1:
719 if me.aiso.rstrip() == 'CUS':
720 ratios = (nml.r12_13, byp.r14_15, byp.r16_17, nml.r16_18)
721 light = (nml.xh2_ini, nml.xhe3_ini, nml.xli6_ini, nml.xli7_ini,
722 nml.xbe9_ini, byp.xb10_ini, byp.xb11_ini)
723 if any(v < 0.0 for v in ratios + light):
724 _both("NEGATIVE INPUT ISOTOPE RATIO OR LIGHT ELEMENT MASS "
725 "FRACTION " + ''.join(f"{v:12.4E}"
726 for v in ratios + light)
727 + " MIX NOT MODIFIED") # 596
728 to_605 = False
729 else:
730 sum_frac = (nml.xh2_ini + nml.xhe3_ini + nml.xli6_ini
731 + nml.xli7_ini + nml.xbe9_ini + byp.xb10_ini
732 + byp.xb11_ini)
733 if sum_frac >= 1.0:
734 _both("SUM OF LIGHT ELEMENT MASS FRACTIONS EXCEEDS 1"
735 + ''.join(f"{v:12.4E}" for v in light)
736 + " MIX NOT MODIFIED") # 595
737 to_605 = False
738 elif me.aiso.rstrip() != 'L21':
739 # Only the default (L21) or a custom set are valid.
740 to_605 = False
741 if to_605:
742 nml.lisotope = True
743 if to_605 and nml.lisotope:
744 _both(f"ISOTOPE AND LIGHT ELEMENT MIXTURE {me.aiso:8} C12/C13 "
745 f"{nml.r12_13:12.4E} O16/O18 {nml.r16_18:12.4E} H2 "
746 f"{nml.xh2_ini:12.4E} HE3 {nml.xhe3_ini:12.4E} LI6 "
747 f"{nml.xli6_ini:12.4E} LI7 {nml.xli7_ini:12.4E} BE9 "
748 f"{nml.xbe9_ini:12.4E} APPLIED TO STARTING MODEL.") # 605
749
750 # label 603: the settling switches. Z diffusion needs Y diffusion and
751 # Thoul's coefficients (DBG 12/95) (Fortran lines 1238–1252).
752 if nml.ldifz:
753 nml.ldify = True
754 nml.lthoul = True
755 # Light-element diffusion (G Somers 04/15).
756 if nml.ldifli:
757 nml.lnewdif = True
758 nml.ldify = True
759 nml.ldifz = True
760 nml.lthoul = True
761 nml.lthoulfit = False
762 nml.ilambda = 4
763
764 # The run's parameters: the namelists as read, and the derived values
765 # (Fortran lines 1254–1273).
766 if nml.npoint <= 0:
767 nml.npoint = 9999
768 if byp.npenv <= 0:
769 byp.npenv = 9999
770 if nml.nprtmod <= 0:
771 nml.nprtmod = 9999
772 if nml.nprtpt <= 0:
773 nml.nprtpt = 9999
774 _write_namelist(io.ishort, 'PHYSICS', _PHYSICS, owners)
775 _write_namelist(io.ishort, 'CONTROL', _CONTROL, owners)
776 _write_namelist(io.ishort, 'DERIVED', _DERIVED, owners)
777
778 # Every mixing length the run uses must be positive (10/15/26). Under
779 # solar calibration only CMIXLA(1) comes from the namelist (Fortran lines
780 # 1274–1321).
781 if nml.lcals:
782 ncmxck = 1
783 else:
784 ncmxck = min(nml.numrun, 50)
785 lcmxbad = False
786 for i in range(1, ncmxck + 1):
787 if nml.cmixla[i] <= 0.0:
788 lcmxbad = True
789 text = (f" ERROR IN SUBROUTINE PARMIN\nILLEGAL MIXING LENGTH: "
790 f"CMIXLA({i:2d}) ={nml.cmixla[i]:12.4E} - MUST BE "
791 "POSITIVE") # 8801
792 io.write(io.ishort, text)
793 print(text)
794 if lcmxbad:
795 if nml.lcals:
796 text = ("SOLAR CALIBRATION IS ON, SO ONLY CMIXLA(1) IS READ FROM"
797 " THE NAMELIST\nRUN STOPPED") # 8802
798 else:
799 text = (f"CMIXLA MUST BE SET FOR EACH OF THE{ncmxck:3d} KIND "
800 "CARDS\nRUN STOPPED") # 8803
801 io.write(io.ishort, text)
802 print(text)
803 raise SystemExit(3)
804
805 # A non-positive envelope triangle size stops the run (Fortran lines
806 # 1322–1333).
807 if nml.tridt <= 0.0 or nml.tridl <= 0.0:
808 text = (f" ERROR IN SUBROUTINE PARMIN\nENVELOPE TRIANGLE SIZE TRIDT"
809 f"{nml.tridt:11.3E} TRIDL{nml.tridl:11.3E} MUST BE POSITIVE"
810 "\nRUN STOPPED") # 8804
811 io.write(io.ishort, text)
812 print(text)
813 raise SystemExit(3)
814
815 # The atmosphere, the pulsation output and the pure C and N tables
816 # (Fortran lines 1334–1362).
817 if nml.kttau in _KTTAU_TEXT:
818 io.write(io.ishort, _KTTAU_TEXT[nml.kttau])
819 if nml.lpulse:
820 io.write(io.ishort, "\n CALCULATE PULSATION OUTPUT ON LAST MODEL")
821 if nml.lpurez:
822 io.write(io.ishort, ' USING PURE C AND N OPACITY TABLES')
823
824 # The run's description (formats 310, 314, 320) (Fortran lines
825 # 1364–1383).
826 rule = '#' + '=' * 100
827 description = (f"# DESCRIPTION OF RUN:{descrip[1]:<80.80}\n#"
828 + ' ' * 9 + ' ' + ' ' * 8
829 + f": {descrip[2]:<80.80}\n{rule}")
830 io.write(io.imodpt, description)
831 io.write(io.ishort, "#\n" + rule)
832 io.write(io.ishort, verline)
833 io.write(io.ishort, description)
834 if nml.ltrack:
835 io.write(io.itrack, "#\n" + rule)
836 io.write(io.itrack, verline)
837 io.write(io.itrack, description)
838 io.write(io.ishort, " USING OSCILATORY SPLINE INTERPOLATION IN HPOINT")
839
840 # Interpret the run from the sequence of "kind" cards (Fortran lines
841 # 1385–1488).
842 io.write(io.ishort, "\n" + ' ' * 35 + "RUN CARDS\n")
843 nml.lfirst[1] = True
844 rl = runloop_mod
845 for nkind in range(1, nml.numrun + 1):
846 rl.iresca[nkind] = kindrn[nkind]
847 if kindrn[nkind] == 1:
848 # Evolve card: stop at an age, or at a central D, X or Y (MHP
849 # 10/24). Only here are LENDAG and LSETDT set (see main.f's
850 # page, bug 1).
851 if (nml.endage[nkind] > 0.0 or nml.end_dcen[nkind] > 0.0
852 or nml.end_xcen[nkind] > 0.0
853 or nml.end_ycen[nkind] > 0.0):
854 rl.lendag[nkind] = True
855 else:
856 rl.lendag[nkind] = False
857 rl.lsetdt[nkind] = nml.setdt[nkind] > 0.0
858 if nml.nmodls[nkind] > 0:
859 if nml.lfirst[nkind]:
860 _screen_and_short(
861 f"\n RUN #{nkind:3d} EVOLVE {nml.nmodls[nkind]:5d}"
862 ' MODELS, STARTING WITH THE INPUT "FIRST MODEL".')
863 else:
864 _screen_and_short(
865 f"\n RUN #{nkind:3d} EVOLVE {nml.nmodls[nkind]:5d}"
866 " MODELS, STARTING WITH THE PREVIOUS RUN'S LAST "
867 "MODEL.")
868 if rl.lendag[nkind] or rl.lsetdt[nkind]:
869 _screen_and_short(
870 f" EVOLVE TO AGE {_l(rl.lendag[nkind])} SET DELT "
871 f"{_l(rl.lsetdt[nkind])} FINAL AGE "
872 f"{nml.endage[nkind]:9.2E} FIXED TSTEP "
873 f"{nml.setdt[nkind]:9.2E} CENTRAL D "
874 f"{nml.end_dcen[nkind]:10.4E} CENTRAL X "
875 f"{nml.end_xcen[nkind]:12.4E} CENTRAL Y "
876 f"{nml.end_ycen[nkind]:12.4E}") # 370
877 elif kindrn[nkind] == 2:
878 # Rescale card: mass, X, Z and core mass, in RESCAL(1..4, card).
879 rl.rescal[1, nkind] = rsclm[nkind]
880 rl.rescal[2, nkind] = rsclx[nkind]
881 rl.rescal[3, nkind] = rsclz[nkind]
882 rl.rescal[4, nkind] = rsclcm[nkind]
883 if nml.nmodls[nkind] > 0:
884 if nml.lfirst[nkind]:
885 _screen_and_short(f"\n RUN #{nkind:3d} RESCALE THE "
886 'INPUT MODEL: "FIRST MODEL".') # 450
887 else:
888 _screen_and_short(f"\n RUN #{nkind:3d} RESCALE THE "
889 "PREVIOUS RUN'S LAST MODEL.") # 451
890 _screen_and_short(_relax_text(nml.nmodls[nkind], nkind))
891 elif kindrn[nkind] == 3:
892 # Rescale-and-evolve card.
893 rl.rescal[1, nkind] = rsclm[nkind]
894 rl.rescal[2, nkind] = rsclx[nkind]
895 rl.rescal[3, nkind] = rsclz[nkind]
896 rl.rescal[4, nkind] = rsclcm[nkind]
897 if nml.lfirst[nkind]:
898 _screen_and_short(f"\n RUN #{nkind:3d} RESCALE & EVOLVE "
899 'THE INPUT MODEL: "FIRST MODEL".') # 550
900 else:
901 # Suspected bug (see the page): format 451, its own 551 is
902 # commented out.
903 _screen_and_short(f"\n RUN #{nkind:3d} RESCALE THE "
904 "PREVIOUS RUN'S LAST MODEL.")
905 _screen_and_short(_relax_text(nml.nmodls[nkind], nkind))
906 # Suspected bug (see the page): runs for every card, evolve cards
907 # too.
908 if rl.rescal[3, nkind] >= 0.0:
909 comp_mod.zenv = rl.rescal[3, nkind]
910 # label 1000
911 a = args
912 return (a.falex06, a.fallard, a.fatm, a.ffermi, a.fliv95, a.fpatm,
913 a.fpenv, a.fpmod, a.fpurez, a.fscvh, a.fscvhe, a.fscvz)
914
915
916def _relax_text(nmodls, nkind):
917 """Format 452: the rescaling of a rescale card."""
918
919 r = runloop_mod.rescal
920 return (f" RELAX RESCALED MODEL{nmodls:3d} TIMES. RESCALE THE FOLLOWING"
921 f"(0=USE CURRENT VALUE):\n MASS {r[1, nkind]:9.6f} X"
922 f"{r[2, nkind]:9.6f} Z{r[3, nkind]:9.6f} CORE MASS"
923 f"{r[4, nkind]:9.6f}")
924
925
926# The placeholders EXPAND_VALUE knows, with the defaults used when the
927# environment variable of that name is not set.
928_PHOLDERS = ('{YREC_INPUT}', '{YREC_START}', '{YREC_OUTPUT}')
929_DEFAULTS = ('../../input', '../../startmodels', 'output')
930
931
932def expand_value(nml_var: str) -> str:
933 """Replace a placeholder at the start of a file name, {YREC_INPUT},
934 {YREC_START} or {YREC_OUTPUT}, by the environment variable of that
935 name, or by its default if it is not set.
936
937 Translates: parmin.f#EXPAND_VALUE (7be4133)
938
939 Arguments: nml_var, the file name.
940
941 Returns nml_var, expanded.
942
943 """
944
945 # Fortran lines 1512–1540.
946 # Suspected bug (see the page): in the Fortran's default branch the
947 # tail of TEMP after the name is left undefined; here it is empty.
948 for i in range(len(_PHOLDERS)):
949 pholder = _PHOLDERS[i]
950 ph_len = len(pholder)
951 if nml_var[:ph_len] == pholder:
952 temp = os.environ.get(pholder[1:ph_len - 1], '').rstrip()
953 if len(temp) != 0:
954 # The environment variable is set.
955 temp = temp + nml_var.rstrip()[ph_len:]
956 else:
957 # Not set: use the default path.
958 temp = _DEFAULTS[i] + nml_var.rstrip()[ph_len:]
959 nml_var = temp
960 # label 5000
961 return nml_var