1C
2C
3C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
4C MAIN
5C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
6
7C*******
8C initialize all variables, set up common blocks
9C*******
10
11C the array size, i.e. max # of shells is specified in the
12C parameter statement. it defines JSON. to change the array
13C size do a global change on "JSON=2000" or whatever.
14C 10/14/26 MHP via Claude
15C code changed to convert COMMON/RUNLOOP/ into RUNLOOP_MOD. A blanket
16C USE imports exactly the names the COMMON declaration made global here,
17C so it cannot change meaning. See runloop_mod.f for the block history
18C and for why the module declares the types the implicit rules supplied.
19C 10/14/26 MHP via Claude
20C code changed to convert COMMON/IOUNITS/ into IOUNITS_MOD.
21C 10/14/26 MHP via Claude
22C code changed to convert COMMON/CONSTANTS/ into CONSTANTS_MOD.
23C 10/14/26 MHP via Claude
24C code changed to convert COMMON/NMLPAR/ into NMLPAR_MOD.
25C 10/14/26 MHP via Claude
26C code changed to convert COMMON/CENT/ into CENT_MOD.
27C 10/14/26 MHP via Claude
28C code changed to convert COMMON/CENV/ into CENV_MOD.
29C 10/14/26 MHP via Claude
30C code changed to convert COMMON/CTOL/ into CTOL_MOD.
31C 10/14/26 MHP via Claude
32C code changed to convert COMMON/DEUTER/ into DEUTER_MOD.
33C 10/14/26 MHP via Claude
34C code changed to convert COMMON/DISK/ into DISK_MOD.
35C 10/14/26 MHP via Claude
36C code changed to convert COMMON/ENTROP/ into ENTROP_MOD.
37C 10/14/26 MHP via Claude
38C code changed to convert COMMON/FLUXES/ into FLUXES_MOD.
39C 10/14/26 MHP via Claude
40C code changed to convert COMMON/LIOV/ into LIOV_MOD.
41C 10/14/26 MHP via Claude
42C code changed to convert COMMON/OLDMOD/ into OLDMOD_MOD.
43C 10/14/26 MHP via Claude
44C code changed to convert COMMON/OVRTRN/ into OVRTRN_MOD.
45C 10/14/26 MHP via Claude
46C code changed to convert COMMON/PREVCZ/ into PREVCZ_MOD.
47C 10/14/26 MHP via Claude
48C code changed to convert COMMON/SOUND/ into SOUND_MOD.
49C 10/14/26 MHP via Claude
50C code changed to convert COMMON/LABEL/ into LABEL_MOD.
51C 10/14/26 MHP via Claude
52C code changed to convert COMMON/OP95INTERP/ into OP95INTERP_MOD.
53C 10/15/26 MHP via Claude
54C code changed to take JSON from DIMENSIONS_MOD instead of declaring
55C PARAMETER(JSON=5000) here.
56 USE DIMENSIONS_MOD
57 USE OP95INTERP_MOD
58 USE LABEL_MOD
59C 10/14/26 MHP via Claude
60C code changed to convert COMMON/ACDPTH/ into ACDPTH_MOD.
61 USE ACDPTH_MOD
62 USE SOUND_MOD
63 USE PREVCZ_MOD
64 USE OVRTRN_MOD
65 USE OLDMOD_MOD
66 USE LIOV_MOD
67 USE FLUXES_MOD
68 USE ENTROP_MOD
69 USE DISK_MOD
70 USE DEUTER_MOD
71 USE CTOL_MOD
72 USE CENV_MOD
73 USE CENT_MOD
74 USE NMLPAR_MOD
75 USE CONSTANTS_MOD
76 USE IOUNITS_MOD
77 USE RUNLOOP_MOD
78C 10/20/26 MHP via Claude
79C code changed to replace implicit typing with IMPLICIT NONE and
80C explicit declarations.
81 IMPLICIT NONE
82 REAL*8 AGUESS,ALRI,BE7M,BE7MASSFRACTION,BL,CFENV,CMIXL,DAGE,DCEN,
83 * * DDAGE,DELTS,DELTS0,DELTSH,DL,DLDA,DLDX,DP,DR,DRDA,DRDX,DS1,
84 * * DS2,DS3,DT,DWMAX,E3AL,EALPCA,ECN,ENU,EPP1,EPP2,EPP3,ESTORE,
85 * * ETA2,FACAGE,FLUXI0,FM,FP,FR,FT,FTRI,GL,HCOMP,HCOMPP0,HD,
86 * * HF1,HF2,HG,HHA,HHB,HHC,HI,HJM,HJM0,HKEROT,HKEROTO,HL,HMAX,
87 * * HP,HPP,HR,HR1,HR10,HR11,HR12,HR13,HR2,HR3,HR4,HR5,HR6,HR7,
88 * * HR8,HR9,HS,HS1,HS2,HSRF,HSTOT,HT,HTT,OMEGA,PCEN,PDP,PDT,
89 * * PEP,PET,POA1,POL1,POLEN,POT1,PS,QIW,R0,RHOE,RLL,RS,
90 * * SENVOLD,SJTOT,SKEROT,SMASS,SOLZX,SUM1,T6,TCEN,TEFFI,TEFFL,
91 * * TL,TLUMX,TRIL,TRIT,TS,V,VEL,X,XC12,XC13,XGUESS,XH2,XHE3,
92 * * XMSOL,XN14,XN15,XO16,XO17,XO18,Y,YINI,Z,ZINI,ZTOX
93C 11/02/26 MHP via Claude
94C code changed to drop QDT and QDP, which MAIN only passed from STARIN
95C to CRRECT; COEFFT sets them from EQSTAT before every use.
96 INTEGER I,ICONV,II,IKUT,ISTORE,ITDONE,ITLVL,ITROT,IU,IWRITE,J,
97 * * JCORE,JENV,JENV0,JENV1,JXBEG,JXEND,JXMID,K,KTTAUSV,M,MODEL,
98 * * MODELN,MRZONE,MXZON0,MXZONE,NHMAX,NITER,NK,NRZONE,NSPEC,
99 * * NZONE,NZONE0
100 LOGICAL*4 LAGE,LARGE,LATMO,LC,LDERIV,LFINI,LIMIX,LJDOT,LMIX,
101 * * LNEW,LNEWFIT,LNUTAB,LOCOND,LPASSR,LPRT0,LPTIMESV,LPUNCH,
102 * * LRESET,LSAVPU,LSBC,LSHELL,LSOL,LSTAR
103C 10/13/26 MHP via Claude
104C code changed to replace COMMON/CALSTAR/ with explicit arguments.
105C setscal.f initializes ALRI, LSTAR and LPASSR, chkscal.f reads and
106C updates ALRI and sets the two flags, and main.f reads the flags; main.f
107C calls both routines, so it now owns all three. ALRI is read as well as
108C written inside chkscal.f and is carried across calls there, which
109C main.f's blanket SAVE preserves exactly as the block did.
110C 10/13/26 MHP via Claude
111C COMPMIX was COMMON/I2O/ and XMSOL was COMMON/PULSE/; main.f now owns
112C both and threads them to the output routines.
113 CHARACTER*4 COMPMIX
114C 10/13/26 MHP via Claude
115C YRECVER and GITHASH were COMMON/VERSION/; main.f now owns them and
116C passes them to SETVERSION, which sets them, and to PARMIN, which
117C prints the banner.
118 CHARACTER*10 YRECVER
119 CHARACTER*20 GITHASH
120C DBGLAOL - to save space make tables single precision
121C MHP 8/25 Removed unused variables and added pass-through variables
122C 9/22/26 MHP via Claude
123C code changed to remove the MHD equation of state
124C 9/23/26 MHP via Claude
125C code changed to remove the OPAL92 opacity tables
126C 9/23/26 MHP via Claude
127C code changed to remove the Kurucz 1990 opacity tables
128C 9/23/26 MHP via Claude
129C code changed to remove the LAOL89 opacity tables
130C 9/24/26 MHP via Claude
131C code changed to remove the Alexander 1995 opacity tables
132 CHARACTER*256 FALEX06,FALLARD,FATM,FFERMI,
133 * * FLIV95,FPATM,FPENV,FPMOD,FPUREZ,FSCVH,
134 * * FSCVHE,FSCVZ
135C 9/25/26 MHP via Claude
136C code changed to consolidate all I/O logical unit numbers, previously
137C scattered across COMMON/LUOUT/, COMMON/LUNUM/, COMMON/ALEX06/,
138C COMMON/ACDPTH/, COMMON/NEWOPAC/, COMMON/LOPAL95/, COMMON/ATMOS2/,
139C COMMON/ALATM03/, COMMON/OPALEOS/, and COMMON/SCV2/, into a single
140C COMMON/IOUNITS/
141C 9/24/26 MHP via Claude
142C code changed to remove dead ILLDAT, IKUR from COMMON/LUNUM/
143C 9/24/26 MHP via Claude
144C code changed to remove dead IDYN from COMMON/LUNUM/
145C 9/25/26 MHP via Claude
146C code changed to remove dead COMMON/LUNUM/ISCOMP (declared,
147C assigned a unit number, but never opened or read anywhere)
148C COMMON/LUFNM/ FLAST, FFIRST, FRUN, FSTAND, FFERMI,
149C 1 FDEBUG, FTRACK, FSHORT, FMILNE, FMODPT,
150C 2 FSTOR, FPMOD, FPENV, FPATM, FDYN,
151C 3 FLLDAT, FSNU, FSCOMP, FKUR,
152C 4 FMHD1, FMHD2, FMHD3, FMHD4, FMHD5, FMHD6, FMHD7, FMHD8
153C DBGLAOL
154C MHP 8/25 Removed character file names from common block
155C 9/24/26 MHP via Claude
156C code changed to merge COMMON /MISCOPAC/ and COMMON/NWLAOL/ into
157C COMMON /NEWOPAC/
158C 10/12/26 MHP via Claude
159C code changed to extend COMMON/NMLPAR/ to 234 members, adding the
160C namelist variables that the physics routines read from 27 COMMON
161C blocks which also held derived or working members. Those blocks keep
162C only their non-namelist members; five of them -- NEWMX, VMULT,
163C PMMWIND, CCOUT1 and ENVGEN -- had nothing left and are gone.
164C Derivation-only namelist variables from the same blocks went to
165C COMMON/NMLBYPASS/ instead, not here.
166C
167C Declared identically in all 121 files that hold any of these members.
168C Generated from one member list, so every copy is byte-identical; the
169C linker's 'size of symbol changed' warning is the check that they are.
170C 10/13/26 MHP via Claude: removed the unused COMMON/NEWOPAC/ declaration
171C (no member referenced here; residue of the obsolete-option removals).
172C 10/13/26 MHP via Claude: removed the unused COMMON/CCOUT/ declaration
173C (no member referenced here; residue of the obsolete-option removals).
174C 11/91 COMMON BLOCKS ADDED FOR PRESSURE SCALE HEIGHT CALC. FOR LIBURN
175C 9/25/26 MHP via Claude
176C code changed to merge COMMON/CONST/, COMMON/CONST1/, COMMON/CONST2/,
177C and COMMON/CONST3/ into a single COMMON/CONSTANTS/
178C MHP 05/02 ADDED OPTION TO ITERATE BETWEEN ROTATION AND
179C STRUCTURE CALCULATIONS - SET ITDIF1 GREATER THAN 1
180C 10/13/26 MHP via Claude: removed the unused COMMON/DPMIX/ declaration
181C (no member referenced here; residue of the obsolete-option removals).
182C 9/24/26 MHP via Claude
183C code changed to make CMIXL a plain local variable set from the
184C user-input CMIXLA(NK) vector and passed as an explicit argument to
185C every routine that needs it, instead of broadcasting it via common
186C block, to reduce implicit global state ahead of the F90 module
187C conversion
188C MHP 8/17 ADDED EXCEN, C_2 TO COMMON BLOCK FOR MATT ET AL. 2012 CENT. TERM
189C 10/13/26 MHP via Claude: removed the unused COMMON/CWIND/ declaration
190C (no member referenced here; residue of the obsolete-option removals).
191C COMMON/CWIND/WMAX,EXMD,EXW,EXTAU,EXR,EXM,CONSTFACTOR,STRUCTFACTOR,LJDOT0
192C MHP 10/24 ADDED STOP CRITERIA FOR CENTRAL H,D,AND HE4
193C COMMON/SETT/ENDAGE(50),SETDT(50),LENDAG(50),LSETDT(50)
194C 7/91 ENTROPY TERM COMMON BLOCK ADDED.
195C 7/91 FLAG TO TOGGLE BETWEEN NEW/OLD RATES ADDED.
196C MHP 9/94
197C 10/13/26 MHP via Claude
198C code changed to replace COMMON/ROTPRT/ with an explicit argument: main.f
199C sets LPRT0 and getw.f is its only reader.
200C MHP 9/94 ADDED DISK LOCKING OPTION - FLAG, TIME OVER WHICH LOCKING
201C IS ENFORCED, AND PERIOD AT WHICH LOCKING IS SET ARE OPTIONS.
202C 10/13/26 MHP via Claude
203C code changed to replace COMMON/PULSE/ with an explicit argument. main.f
204C snapshots XMSOL=SMASS and wrtmod.f is the only reader; it is a snapshot,
205C not the running SMASS, so it cannot be replaced by the mass already in
206C scope there.
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 MHP 8/25 Removed character file names from common block
210C 9/25/26 MHP via Claude
211C code changed to remove the LISO isochrone-output option
212C DBG 1/92 let XENV0, ZENV0, and CMIXL be arrays so can change during
213C a set of runs.
214C MHP 8/25 Removed character file names from common block
215C 10/9/26 MHP via Claude
216C code changed to remove COMMON/ZRAMP/ entirely from this file: NK was
217C its only member ever referenced here (as this file's own run-index
218C loop variable, DO 200 NK = 1, NUMRUN below), and is now passed
219C explicitly to PDIST and WRTHEAD instead of relying on them reading
220C it back out of the common block. RSCLZC/RSCLZM1/RSCLZM2/IOLAOL2/
221C LZRAMP (ZRAMP's other members) were never used in this file.
222C DBG 4/26/94 Tired of not have access to current age of model so...
223C 10/13/26 MHP via Claude
224C code changed to drop COMMON/THEAGE/. DAGE, the stellar age, is a local
225C here and was already passed explicitly to every other routine using it
226C (STARIN, HTIMER, WRTOUT, PUTSTORE, CHKSCAL, MASSLOSS, CALCAD and the
227C model readers and writers); PDIST was the last reader taking it via
228C COMMON.
229 DIMENSION TLUMX(8),TRIL(3),TRIT(3),PS(3),TS(3),RS(3),CFENV(9),
230 * *HS(JSON),HL(JSON),HR(JSON),HP(JSON),HT(JSON),HD(JSON),LC(JSON),
231 * *HCOMP(15,JSON),HS1(JSON),HS2(JSON),HHC(JSON),
232 * *HHA(4,2,JSON),HHB(4,JSON),HPP(JSON),HTT(JSON),ESTORE(4),
233 * *HMAX(4),NHMAX(4),HSRF(6),FP(JSON),FT(JSON),
234 * *OMEGA(JSON),HI(JSON),HJM(JSON),HKEROT(JSON),R0(JSON),ETA2(JSON),
235 * *QIW(JSON),HG(JSON),V(12),HKEROTO(JSON)
236C MHP 10/24 FLAG FOR END OF RUN
237 LOGICAL*4 LEND_KIND
238C JVS 02/12
239C 9/25/26 MHP via Claude
240C code changed to remove dead COMMON/STCH/ (declared but never
241C referenced anywhere in this file)
242
243C DBG PULSE OUT 7/92
244C variables used to contral output of pulsation models. model
245C output after has traveled pomax in HR diagram
246C LPOUT and POMAX added to control common block, rest in physics
247C MHP 1/93 add common blocks for automatic calibration of solar models.
248C 10/13/26 MHP via Claude
249C code changed to replace COMMON/CALSUN/ with explicit arguments to
250C CHKCAL and SETCAL. Only these five of the nine members are read here;
251C BLP, RLP, DX and DA stay inside chkcal.f. They are given explicit
252C initial values because CALL SETCAL sits inside IF(LCALS) and so may
253C never run, while the test at IF(LCALS .AND. LSNU .AND. LSOL) below can
254C still evaluate LSOL -- Fortran does not promise .AND. short-circuits.
255C COMMON storage supplied that zero implicitly; a local would not.
256 DATA DLDX,DRDX,DLDA,DRDA,LSOL/4*0.0D0,.FALSE./
257C MHP 6/13 ADD OPTION TO CALIBRATE SOLAR Z/X, SOLAR Z/X, SOLAR AGE
258C COMMON/CALS2/TOLL,TOLR,LCALS
259C DBG 12/94 added calibrate stellar model
260C 10/12/26 MHP via Claude
261C code changed to drop BLI, AGER, BLR, BLRP and AGEI from
262C COMMON/CALSTAR/; they are written and read only in chkscal.f and are
263C now locals there. This file never referenced them.
264C MHP 7/96 common block added for sound speed
265C 10/13/26 MHP via Claude: removed the unused COMMON/CROSS/ declaration
266C (no member referenced here; residue of the obsolete-option removals).
267C 9/24/26 MHP via Claude
268C code changed to remove the Monte Carlo option
269C MHP 3/96 central T,P,RHO added
270C 10/13/26 MHP via Claude: removed the unused COMMON/LLOT95A/ declaration
271C (no member referenced here; residue of the obsolete-option removals).
272C as above for the model Z.
273C 10/13/26 MHP via Claude: removed the unused COMMON/LLOT95/ declaration
274C (no member referenced here; residue of the obsolete-option removals).
275C as above for desired surface value of X.
276C 10/13/26 MHP via Claude: removed the unused COMMON/LLOT95E/ declaration
277C (no member referenced here; residue of the obsolete-option removals).
278C indices for interpolation in Z,X,T, and R; interpolation factors
279C for Z,X,T, and R (and derivative factors for T and RHO).
280C 10/9/26 MHP via Claude
281C code changed to merge COMMON/OP95INDX/ and COMMON/OP95FACT/ into
282C COMMON/OP95INTERP/ (see getopal95.f for the full rationale). This
283C file declares only the JZ..BDD prefix, not the full block (which
284C also has COMMON/OP95EXT/'s RL,RLL,RLH,LEXTL,LEXTH,LEXH appended) --
285C this file already has its own, unrelated RLL (log-luminosity
286C calibration variable, used with CHKCAL/ISNU below) that would
287C collide with OP95EXT's RLL if the full block were declared here.
288C Declaring a prefix is legal Fortran and matches exactly what this
289C file already had (no new members gained).
290C 10/13/26 MHP via Claude
291C code changed to rename COMMON/OP95INTERP/'s RL and RLL to RHO_T63L and
292C RHO_T63LL. RL is log(rho/T6**3), set here as RL = DL - 3*(TL-6); the
293C old names clash with RL and RLL as used for radius throughout the rest
294C of the code, which is why main.f declared only a 10-member prefix of
295C this block to avoid importing them. With the clash gone main.f can
296C declare the full block, which a USE statement will require once this
297C becomes a module.
298C MHP 05/02 ADDED FOR ITERATION BETWEEN ROTATION AND STRUCTURE CALCULATION
299C 10/9/26 MHP via Claude
300C code changed to convert COMMON/ORIGSTART/ to a plain local array:
301C declared only in this file (confirmed via a codebase-wide scan), so
302C there's nothing to share via COMMON. The existing blanket SAVE
303C statement already preserves its values across calls, same as
304C COMMON did.
305 DIMENSION HJM0(JSON),HCOMPP0(15,JSON)
306C MHP 05/02 DEUTERIUM BURNING RATE ADDED
307C***MHP 1/04 inserted for test
308C COMMON/OPTAB/OPTOL,ZSI,IDT,IDD(4)
309C*** end test
310C LLP 8/07 Make LPTIME available for calibration
311C MHP 2/04 ADDED FOR NEUTRINO FLUX TABLE
312C 10/13/26 MHP via Claude
313C code changed to drop COMMON/BE7/; BE7MASSFRACTION now comes back from
314C ENGEB as an argument and is stored into BE7M(I) just below.
315C JVS 02/11
316C KC 2025-05-30 reordered common block elements
317C COMMON/ACDPTH/TAUCZN,DELADJ(JSON),TAUHE, TNORM, TCZ, WHE, ICLCD,
318C 9/25/26 MHP via Claude
319C code changed to remove dead IACAT, IJVS, IJENT, IJDEL unit
320C reservations from COMMON/ACDPTH/ (declared but never opened anywhere)
321C *LCLCD, AGEOUT(5), IACAT, IJLAST, LJLAST, LJWRT, LADON,LAOLY, IJVS,
322 INTEGER NAO
323 DATA NAO/1/
324C 10/11 He3+He3 luminosity info
325C 10/13/26 MHP via Claude: removed the unused COMMON/GRAB/ declaration
326C (no member referenced here; residue of the obsolete-option removals).
327C JVS 08/13 IF THE CZ IS BEYOND THE FITTING POINT, STORE ITS LOCATION
328C 10/13/26 MHP via Claude
329C code changed to remove COMMON/ENVCZ/: ENVRCZ was written once in
330C envint.f and read nowhere, and RINT was never referenced at all. Its
331C only reader was the commented-out JVS block deleted from wrtout.f
332C earlier in this work, so the block died with it.
333C JVS 04/14 Common block for additional timestep governors
334C G Somers 3/17, ADDING NEW TAUCZ COMMON BLOCK
335C MHP 10/24 NEW VARIABLES FOR STOP CONDITIONS ON CENTRAL ABUNDANCE
336C REAL*8 XCEN(2,15),DTPREV
337C LOGICAL*4 L_LASTSTEP
338C
339 DIMENSION BE7M(JSON),FLUXI0(10,JSON)
340 DIMENSION HR1(JSON),HR2(JSON),HR3(JSON),HR4(JSON),HR5(JSON),
341 1 1 HR6(JSON),HR7(JSON),HR8(JSON),HR9(JSON),HR10(JSON),HR11(JSON),
342 2 2 HR12(JSON),HR13(JSON),HF1(JSON),HF2(JSON)
343 DIMENSION MXZONE(12,2),MXZON0(12,2),MRZONE(13,2)
344C 9/24/26 MHP via Claude
345C code changed to remove the Monte Carlo option
346 SAVE
347
348C*******
349C START
350C*******
351 CALL SETVERSION(YRECVER,GITHASH)
352
353 IOWR = 9
354C LPUNCH is TRUE once first model is calculated
355 LPUNCH=.FALSE.
356C read in user parameters
357 CALL PARMIN(FALEX06,FALLARD,FATM,FFERMI,
358 * * FLIV95,FPATM,FPENV,FPMOD,FPUREZ,FSCVH,
359 * * FSCVHE,FSCVZ,YRECVER,GITHASH)
360C set up constants and read in tabular data
361C MHP 8/25 directly pass file names instead of using common blocks
362 CALL SETUPS(FALEX06,FALLARD,FATM,FFERMI,
363 * * FLIV95,FPUREZ,FSCVH,FSCVHE,FSCVZ)
364C 9/24/26 MHP via Claude
365C code changed to remove the Monte Carlo option; this collapses what
366C was the outer Monte Carlo run loop (DO 500 NN = I0,I1, which only
367C ever ran once since LMONTE was always .FALSE.) into straight-line
368C code
369 FACAGE = 1.0D0
370C DBG PULSE: save LPULSE flag, set LPULSE to F except on last model of
371C last run, then set LPULSE to saved value of LPULSE.
372 LSAVPU = LPULSE
373C 02/11 JVS uncommented LPULSE=.FALSE.
374C LPULSE = .FALSE.
375C MHP 1/93 add option to automatically calibrate solar model.
376C MHP 3/96 added counter for # of iterations per converged model and
377C starting estimate of ALPHA and X
378 IF(LCALS)THEN
379 CALL SETCAL(FACAGE,LSOL)
380 ICONV = 1
381 XGUESS = RESCAL(2,1)
382 AGUESS = CMIXLA(1)
383 lptimesv = lptime ! save LPTIME for reuse during calibration
384 kttausv = kttau ! save KTTAU for reuse during calibration
385 ELSE
386 ICONV = 0
387 ENDIF
388C DBG 12/94 add option to automatically calculate a stellar model
389C of specified Teff and L
390 IF (LCALST) THEN
391 CALL SETSCAL(ALRI,LSTAR,LPASSR)
392 ENDIF
393
394C**********
395C RUN THROUGH THE KIND CARDS IN ORDER
396C**********
397 DO 200 NK = 1, NUMRUN
398 LSOUND = .FALSE.
399C LPULSE=.FALSE.
400 XENV0 = XENV0A(NK)
401 ZENV0 = ZENV0A(NK)
402 CMIXL = CMIXLA(NK)
403 LSENV0 = LSENV0A(NK)
404 SENV0 = SENV0A(NK)
405 LRESET = .FALSE.
406 LARGE = .FALSE.
407C MHP 10/02 ZERO OUT INITIAL ANGULAR MOMENTUM
408 SJTOT = 0.0D0
409 SKEROT = 0.0D0
410C read in the initial model here
411C STARIN also calls RSCALE to perform rescaling if requested
412C CALL STARIN(BL,CFENV,DAGE,DDAGE,DELTS,DELTSH,DELTS0,ETA2, ! KC 2025-05-31
413 CALL STARIN(BL,CFENV,DAGE,DDAGE,DELTS,DELTSH,ETA2,
414 * * FP,FT,FTRI,HCOMP,HD,HI,HJM,HKEROT,HL,HP,HR,HS,HS1,HS2,
415C * HSTOT,HT,IKUT,ISTORE,JCORE,JENV,LARGE,LC,LNEW,M,MODEL, ! KC 2025-05-31
416 * * HSTOT,HT,IKUT,ISTORE,JENV,LARGE,LC,LNEW,M,MODEL,
417 * * NK,OMEGA,PS,QIW,R0,RS,SJTOT,SKEROT,SMASS,TEFFL,
418 * * TLUMX,TRIL,TRIT,TS,VEL,HG,V,CMIXL,COMPMIX)
419
420 IF((OMEGA(1) .EQ. 0) .AND. (LROT)) THEN
421
4221611 1611 FORMAT('LROT set to TRUE, but OMEGA(1) = 0. Stopping.',
423 * * ' Initialize rotation rates or set LROT to',
424 * * ' FALSE.')
425 PRINT 1611
426C 10/30/26 MHP via Claude: bare STOP -> STOP 3, the input-error code (issue 38).
427 STOP 3
428 ENDIF
429c MHP 10/24 CHECK STOP CONDITIONS AND DISABLE THEM IF THE STARTING VALUES ARE BELOW THE TARGET THRESHOLD
430 IF(LENDAG(NK))THEN
431 IF(END_DCEN(NK).GT.0.0D0 .AND.
432 * * HCOMP(12,1).LT.END_DCEN(NK))THEN
433 END_DCEN(NK)=-END_DCEN(NK)
434 WRITE(*,101)HCOMP(12,1),END_DCEN(NK)
435 WRITE(ISHORT,101)HCOMP(12,1),END_DCEN(NK)
436 101 101 FORMAT('STARTING D ',E12.4,' BELOW STOP VALUE ',
437 * * E12.4,' STOP DISABLED.')
438 ENDIF
439C 10/29/26 MHP via Claude
440C The X and Y blocks disabled and reported the wrong stop: the X block
441C set END_DCEN = -END_XCEN, leaving the X stop armed and overwriting a
442C D stop, and both printed central D and END_DCEN. Each now disables
443C and reports its own condition.
444 IF(END_XCEN(NK).GT.0.0D0 .AND.
445 * * HCOMP(1,1).LT.END_XCEN(NK))THEN
446 END_XCEN(NK)=-END_XCEN(NK)
447 WRITE(*,102)HCOMP(1,1),END_XCEN(NK)
448 WRITE(ISHORT,102)HCOMP(1,1),END_XCEN(NK)
449 102 102 FORMAT('STARTING X ',E12.4,' BELOW STOP VALUE ',
450 * * E12.4,' STOP DISABLED.')
451 ENDIF
452 IF(END_YCEN(NK).GT.0.0D0 .AND.
453 * * HCOMP(2,1).LT.END_YCEN(NK))THEN
454 END_YCEN(NK)=-END_YCEN(NK)
455 WRITE(*,103)HCOMP(2,1),END_YCEN(NK)
456 WRITE(ISHORT,103)HCOMP(2,1),END_YCEN(NK)
457 103 103 FORMAT('STARTING Y ',E12.4,' BELOW STOP VALUE ',
458 * * E12.4,' STOP DISABLED.')
459 ENDIF
460 ENDIF
461C MHP 2/04 NEUTRINO TABLE
462C LNUTAB = .TRUE.
463 LNUTAB = .FALSE.
464 IF(LNUTAB)THEN
465C SET UP WEIGHTS AND MASSES.
466C HS1 = LOCATION IN GM (UNLOGGED) OF SHELL CENTERS.
467C HS2 = MASS IN GM OF EACH SHELL.
468 DS3 = EXP(CLN*HS(1))
469 DS2 = - DS3
470 DO I = 2,M
471 DS1 = DS2
472 DS2 = DS3
473 DS3 = EXP(CLN*HS(I))
474 HS1(I-1) = DS2
475 HS2(I-1) = 0.5D0*(DS3-DS1)
476 END DO
477 HS1(M) = DS3
478 HS2(M) = EXP(CLN*HSTOT) - 0.5D0*(DS2+DS3)
479 PDT = -1.0D0
480 PDP = 1.0D0
481 DO J = 1,10
482 FLUXTOT(J) = 0.0D0
483 DO K = 1,M
484 FLUXI0(J,K) = 0.0D0
485 END DO
486 END DO
487C ASSIGN LOCAL VARIABLES FOR SR CALL FROM GLOBAL VECTORS.
488 DO I = 1,M
489 DL = HD(I)
490 TL = HT(I)
491C SKIP CALCULATIONS FOR LOW TEMPERATURES.
492 IF(TL.LT.6.0D0)GOTO 666
493 X = HCOMP(1,I)
494 Y = HCOMP(2,I)
495 Z = HCOMP(3,I)
496 XHE3 = HCOMP(4,I)
497 XC12 = HCOMP(5,I)
498 XC13 = HCOMP(6,I)
499 XN14 = HCOMP(7,I)
500 XN15 = HCOMP(8,I)
501 XO16 = HCOMP(9,I)
502 XO17 = HCOMP(10,I)
503 XO18 = HCOMP(11,I)
504 CALL ENGEB(EPP1,EPP2,EPP3,ECN,E3AL,PEP,PET,SUM1,DL,
505C *TL,PDT,PDP,X,Y,Z,XHE3,XC12,XC13,XN14,XN15,XO16,XO17,
506C *XO18,XH2,XLI6,XLI7,XBE9,I,HR1,HR2,HR3,HR4,HR5,HR6,HR7, ! KC 2025-05-31
507 * *TL,X,Y,XHE3,XC12,XC13,XN14,XO16,
508 * *XO18,XH2,IU,HR1,HR2,HR3,HR4,HR5,HR6,HR7,
509 * *HR8,HR9,HR10,HR11,HR12,HR13,HF1,HF2,BE7MASSFRACTION,EALPCA,ENU)
510C BE7 MASS FRACTION.
511 BE7M(I) = BE7MASSFRACTION
512C CONVERT FROM ERG/GM/S TO ERG/S FOR EACH SHELL BY MULTIPLYING
513C BY THE MASS OF EACH SHELL IN GM (HS2).
514 DO J = 1,10
515 FLUXI0(J,I) = FLUX(J)*HS2(I)
516 FLUXTOT(J) = FLUXTOT(J) + FLUXI0(J,I)
517 END DO
518 WRITE(*,911)I,HS2(I),(FLUXI0(J,I),J=1,10)
519 911 911 FORMAT(I5,1P11E10.3)
520 END DO
521 666 666 CONTINUE
522C WRITE OUT TOTAL NEUTRINO FLUXES.
523C ***NOTE THAT THESE ARE IN UNITS OF 10**10. ***
524 WRITE(76,222)(FLUXTOT(I),I=1,10)
525C NORMALIZE FLUXES.
526 DO J = 1,10
527 DO I = 1,M
528 FLUXI0(J,I) = FLUXI0(J,I)/FLUXTOT(J)
529 END DO
530 END DO
531 DO I = 1,M
532C TEMPERATURE IN UNITS OF 10**6 K.
533 T6 = EXP(CLN*(HT(I)-6.0D0))
534 IF(T6.LT.5.0D0)GOTO 141
535C ELECTRON DENSITY.
536 RHOE = HD(I)+LOG10((1.0D0+HCOMP(1,I))/2.0D0)
537C MASS FRACTION.
538 FM = HS2(I)/1.9891D33
539C RADIUS FRACTION.
540 FR = EXP(CLN*HR(I))/CRSUN
541C FLUXES ARE PRINTED IN THE SAME ORDER AS BAHCALL AND PINSONNEAULT.
542 WRITE(76,145)FR,T6,RHOE,FM,BE7M(I),FLUXI0(1,I),FLUXI0(5,I),
543 * * FLUXI0(6,I),
544 * * FLUXI0(7,I),FLUXI0(8,I),FLUXI0(4,I),FLUXI0(2,I),FLUXI0(3,I)
545 145 145 FORMAT(F9.5,F7.3,F6.3,1P10E10.3)
546 END DO
547 141 141 CONTINUE
548 222 222 FORMAT(1P10E10.3)
549C IF(M.GT.1)STOP999
550 ENDIF
551C save mass in solar units
552 XMSOL=SMASS
553C MHP 08/02 STORE STARTING CZ PROPERTIES
554 JCZ = JENV
555 TAUCZ = 0.0D0
556C write out headers of the appropriate output files
557 CALL WRTHEAD(SMASS,CMIXL,NK)
558C DBG PULSE OUT 7/92
559C initialize variables for calculating when to dump pulse output
560 POL1 = BL
561 POT1 = TEFFL
562 POA1 = DAGE
563 POLEN = 0.0D0
564
565 IF(LKUTHE) THEN
566C timestep cutting requires a model stored in logical unit ILAST
567C or it will crash - so copy initial model to unit ILAST
568 IF(LPUNCH) THEN
569 IWRITE = ILAST
570 CALL WRTLST(IWRITE,HCOMP,HD,HL,HP,HR,HS,HT,LC,TRIT,TRIL,
571 * * PS,TS,RS,CFENV,FTRI,TLUMX,JCORE,JENV,MODEL,M,
572 * * SMASS,TEFFL,BL,HSTOT,DAGE,DDAGE,OMEGA,CMIXL,COMPMIX)
573 ENDIF
574 ENDIF
575
576C locate the hydrogen-burning shell and the boundaries of the central
577C and surface convection zones (if applicable).
578 CALL FINDSH(HCOMP,HL,LC,M,JCORE,JENV,JXBEG,JXEND,JXMID,
579 * * LSHELL)
580C determine timestep for model
581C JVS 04/14 Added Teffl to passed variables
582C CALL HTIMER(DELTS,DELTSH,M,HD,HL,HS1,HS2,HT,LC,HCOMP,JCORE,
583C * JXMID,TLUMX,DAGE,DDAGE,QDT,QDP,NK,HP,HR,OMEGA, ! KC 2025-05-31
584 CALL HTIMER(DELTS,DELTSH,M,HD,HL,HS1,HS2,HT,HCOMP,JCORE,
585 * * JXMID,TLUMX,DAGE,DDAGE,NK,HP,HR,OMEGA,
586 * * DWMAX,JXBEG,TEFFL)
587
588 DELTS0 = DELTS
589C zero out entropy terms.
590 DO 99 I = 1,M
591 HTT0(I) = 0.0D0
592 HPP0(I) = 0.0D0
593 HLL0(I) = 0.0D0
594 HRR0(I) = 0.0D0
595 99 99 CONTINUE
596
597C zero out light element burning rates in the surface CZ.
598C 11/02/26 MHP via Claude
599C code changed to clear LBLIOLD instead of zeroing BLI6OLD, BLI7OLD and
600C BBE9OLD, which LIBURN now reuses only when LBLIOLD is set.
601 IF(LEXCOM)THEN
602 LBLIOLD = .FALSE.
603 ENDIF
604
605C for a given kind card, evolve NMODLS(NK) times
606C if rescaling is being performed, NMODLS(NK) is the number of times
607C the new model is being relaxed
608 DO 100 MODELN = 1,NMODLS(NK)
609C rewind ISHORT if LRWSH is true (keeps ISHORT small)
610 IF (LRWSH) THEN
611 REWIND(ISHORT)
612 ENDIF
613C DBG PULSE: if last model of last run then set LPULSE to LSAVPU
614 IF (MODELN.EQ.NMODLS(NK) .AND. NK .EQ. NUMRUN) THEN
615 LPULSE = LSAVPU
616 END IF
617
618C JVS 02/11: Also allow pulse output at particular ages along the way
619C
620C If the step is bracketing an age of interest, turn on output. This will
621C for the step before and step after the age in AGEOUT. Once the info has
622C been printed out, AGEOUT is set to the next age.
623C
624C Turn on calcad:
625 IF (LACOUT) THEN
626 LADON=.TRUE.
627 ELSE
628 LADON = .FALSE.
629 ENDIF
630C If output has been turned on for a previous step, keep it on for the next
631C step, but then turn it off.
632 IF (LACOUT) THEN
633 IF (LJWRT) THEN
634 PRINT*, 'LJWRT on'
635 LPULSE = LSAVPU
636 NAO=NAO+1
637 LCLCD =.TRUE.
638 LJLAST =.FALSE.
639 LJWRT=.FALSE.
640 ELSE IF (.NOT.LJWRT) THEN
641 LCLCD=.FALSE.
642 ENDIF
643C If this is the step before one of the ages of interest, print everything out.
644C Also, save model structure.
645 IF(NAO.LT.6) THEN
646 IF(DAGE+DDAGE/1.0D9-AGEOUT(NAO) .LE. 0.0D0 .AND.
647 * * DAGE+2.0D0*DDAGE/1.0D9-AGEOUT(NAO) .GE. 0.0D0 .AND. .NOT. LJWRT) THEN
648 PRINT*, 'AGEOUT reached'
649 LPULSE = LSAVPU
650 LCLCD = .TRUE.
651 LJLAST = .TRUE.
652 LJWRT=.TRUE.
653 ENDIF
654 ENDIF
655 ENDIF
656
657
658C JVS end
659C
660C DBG PULSE: if endage reached then set LPULSE to LSAVPU
661C MHP 10/24 GENERALIZE CHECK
662 IF(LENDAG(NK).AND.ENDAGE(NK).GT.0.0D0. AND.
663 * * (ABS(ENDAGE(NK)-DAGE*1.0D9-DDAGE) .LE. 1.0D0)) THEN
664 LPULSE = LSAVPU
665C MHP 7/96 compute sound speed for solar model
666 LSOUND = .TRUE.
667 END IF
668
669
670CFD echo LSOUND
671C print*,'MAIN LSOUND = ',LSOUND
672CFD end
673 IF (LPOUT) THEN
674C MHP 8/25 changed to add file names as declared variables
675 CALL PDIST(POL1,POT1,POA1,POLEN,BL,TEFFL,MODELN,NK,FPATM,
676 * * FPENV,FPMOD,DAGE)
677 ENDIF
678
679C STARIN called here for timestep cutting
680 15 15 IF(LARGE) THEN
681C CALL STARIN(BL,CFENV,DAGE,DDAGE,DELTS,DELTSH,DELTS0,ETA2, ! KC 2025-05-31
682 CALL STARIN(BL,CFENV,DAGE,DDAGE,DELTS,DELTSH,ETA2,
683 * * FP,FT,FTRI,HCOMP,HD,HI,HJM,HKEROT,HL,HP,HR,HS,HS1,HS2,
684C * HSTOT,HT,IKUT,ISTORE,JCORE,JENV,LARGE,LC,LNEW,M,MODEL, ! KC 2025-05-31
685 * * HSTOT,HT,IKUT,ISTORE,JENV,LARGE,LC,LNEW,M,MODEL,
686 * * NK,OMEGA,PS,QIW,R0,RS,SJTOT,SKEROT,SMASS,TEFFL,
687 * * TLUMX,TRIL,TRIT,TS,VEL,HG,V,CMIXL,COMPMIX)
688 IF((OMEGA(1) .EQ. 0) .AND. (LROT)) THEN
68918 18 FORMAT('LROT set to TRUE, but OMEGA(1) = 0. Stopping.',
690 * * ' Initialize rotation rates or set LROT to',
691 * * ' FALSE.')
692 PRINT 18
693C 10/30/26 MHP via Claude: bare STOP -> STOP 3, the input-error code (issue 38).
694 STOP 3
695 ENDIF
696 ENDIF
697 LPUNCH = .TRUE.
698
699C skip this section if model not to be aged
700C MHP 7/98
701C need to add logic to permit resacling + time evolution for
702C pre-main sequence models
703C 10/27/26 MHP via Claude
704C code changed to let L_ZERODT_PREMS (CONTROL namelist, default F)
705C disable the pre-MS failsafe below, which ages a KINDRN=2 rescale
706C whenever log Tc < 6.6. With it set, KINDRN=2 is a true zero-timestep
707C rescale for a pre-MS model too. A static solution then exists only
708C if nuclear burning can carry the luminosity, as deuterium burning
709C does in a model at the deuterium birthline. The first evolved run
710C after one should fix its timestep with SETDT: HTIMER otherwise takes
711C the stored timestep, which can be far too long (KNOWN_ISSUES.md 39).
712 IF(IRESCA(NK).NE.2 .AND. MODEL.GE.0) THEN
713 LAGE = .TRUE.
714 ELSE IF(.NOT.L_ZERODT_PREMS .AND. MODEL.GE.0 .AND.
715 * * HT(1).LT.6.6D0)THEN
716 LAGE = .TRUE.
717 ELSE
718 LAGE = .FALSE.
719 ENDIF
720 LNEWFIT = .FALSE.
721 IF(LAGE) THEN
722C ADD MASS LOSS CALCULATION
723 CALL MASSLOSS(BL,DAGE,DELTS,HCOMP,HD,HJM,HP,HR,
724 * * HS,HS1,HS2,HSTOT,HT,JENV,LNEW,
725 * * M,OMEGA,SMASS,TEFFL,SENVOLD,LNEWFIT)
726C STORE COMPOSITION MATRIX AT THE BEGINNING OF THE TIMESTEP.
727 NSPEC = 11
728 IF(LEXCOM)NSPEC=15
729 DO 33 I = 1,M
730 DO 32 J = 1,NSPEC
731 HCOMPP(J,I) = HCOMP(J,I)
732 32 32 CONTINUE
733 33 33 CONTINUE
734 ITLVL=1
735 CALL MIX(DELTS,HCOMP,HD,HL,HP,HR,HS,HS1,HS2,HSTOT,
736C * HT,ITLVL,LC,M,QDT,QDP,DDAGE,JCORE,JENV, ! KC 2025-05-31
737 * * HT,ITLVL,LC,M,DDAGE,JCORE,JENV,
738 * * MXZONE,MXZON0,TEFFL,CMIXL)
739 DDAGE = DELTS/CSECYR
740 DAGE = DAGE + 1.0D-9*DDAGE
741 ENDIF
742C***MHP 1/04 OPACITY TEST
743C IDT = 15
744C DO JJJ = 1,4
745C IDD(JJJ) = 5
746C END DO
747C XXX = 0.7D0
748C ZZZ = 0.02D0
749C Do JJJ = 1,2000
750c READ(75,*)TL,DL,XX,ZZ,OO
751C IF(TT.GT.1.0D9)STOP911
752C TL = LOG10(TT)
753C DL = LOG10(DD)
754C DBG 12/95 GET OPACITY
755C CALL GETOPAC(DL, TL,XXX,ZZZ, O, OL, QOD, QOT)
756c DIFF = (O-OO)/O
757C RL = DL - 3*TL +18.0D0
758C WRITE(76,1554)TL,RL,XXX,ZZZ,O,OO,DIFF
759C 1554 format(4f11.6,3e20.10)
760C END DO
761C*** END TEST
762C rezone new model, except rezoning not performed for He flash calculations
763 IF(.NOT.LKUTHE) THEN
764 CALL HPOINT(M,HSTOT,HS,HS1,HS2,HT,HP,HR,LC,HL,HD,
765 * * HCOMP,PS,RS,ESTORE,ISTORE,LRESET,JXBEG,
766 * * MODEL,LSHELL,JCORE,JENV,OMEGA,ETA2,R0,HI,
767C * HJM,HKEROT,SJTOT,SKEROT,BL,DELTS,FP,FT,
768C * HG,QIW,SMASS,TEFFL) ! KC 2025-05-31
769 * * HJM,HKEROT,SJTOT,SKEROT,FP,FT,HG,QIW,TEFFL,CMIXL)
770C STORE NEW CZ BASE
771 JCZ = JENV
772 ELSE
773C save old model for PTIME
774 DO I=1, M
775 HPO(I) = HP(I)
776 HTO(I) = HT(I)
777 HRO(I) = HR(I)
778 HLO(I) = HL(I)
779 HDO(I) = HD(I)
780 END DO
781C JVS 04/14 Save Teff as well
782 TEFFLO = TEFFL
783C 10/29/26 MHP via Claude
784C code changed to save the surface luminosity, HLSURO, in place of the
785C point count MO. HPOINT re-splines HLO onto the new mesh, so ENTIME's
786C HLO(MO) read an interior point or a stale entry whenever the count
787C changed.
788 HLSURO = HL(M)
789
790 ENDIF
791C store starting distribution of rotational kinetic energy.
792 IF(LROT)THEN
793 DO I = 1,M
794 HKEROTO(I) = HKEROT(I)
795 END DO
796 ENDIF
797C changed for lithium burning with overshoot.
798C store starting depth of C.Z. for light element burning.
799 IF(LEXCOM)THEN
800 RBASE0 = 0.0D0
801 JENV0 = JENV
802 IF(LOVSTE)THEN
803 PSCAL0 = ALPHAE*EXP(CLNDP*(HP(JENV)+2.0D0*HR(JENV)
804 * * -HD(JENV)-CGL-HS(JENV)))
805 ELSE
806 PSCAL0 = 0.0D0
807 ENDIF
808C find burning rates at the beginning of the time step.
809C 10/29/26 MHP via Claude
810C LIRATE88's flag was swapped at all three calls. J=1 evaluates the
811C model passed in and fills the end-of-step rates (RLI6, RLI7, RBE9);
812C J=2 evaluates the saved start-of-step model (HDO, HCOMPP) and fills
813C RLI60, RLI70, RBE90. With the old flags both sets held start-of-step
814C rates, so LIBURN never saw the end-of-step model.
815 CALL LIRATE88(HCOMP,HD,HT,M,2)
816 ENDIF
817C begin correction routines
818C set flags for CRRECT
819C CRRECT checks surface boundary conditions in every iteration
820C if LNEW0 = T, new envelope triangle calculated the 1st iteration
821C (i.e. old triangle ignored)
822C LFINI = T if model has converged
823C LARGE = T if model has diverged
824 IF(LNEW0) LNEW = .TRUE.
825 IF(.NOT.LAGE) DELTS = -DABS(DELTS)
826 FCORR = DABS(FCORR0) - FCORRI
827 ITDONE = 0
828 LARGE = .FALSE.
829 LFINI = .FALSE.
830 IF(.NOT.LNEWS .OR. DELTS.LE.0.0D0)THEN
831 DO 20 I = 1,M
832C zero entropy terms
833 HTT(I) = 0.0D0
834 HPP(I) = 0.0D0
835 HTT0(I) = 0.0D0
836 HPP0(I) = 0.0D0
837 HLL0(I) = 0.0D0
838 HRR0(I) = 0.0D0
839C zero gravitational energy terms.
840 HHC(I) = 0.0D0
841 20 20 CONTINUE
842 ELSE
843C use the rate of change in the previous model to estimate the new
844C run of structure variables.
845 DO 30 I = 1,M
846 DT = HTT0(I)*DELTS
847 DP = HPP0(I)*DELTS
848 DL = HL(I)*HLL0(I)*DELTS
849 DR = HRR0(I)*DELTS
850 HTT(I) = DT
851 HPP(I) = DP
852 HT(I) = HT(I) + DT
853 HP(I) = HP(I) + DP
854 HL(I) = HL(I) + DL
855 HR(I) = HR(I) + DR
856C zero gravitational energy terms.
857 HHC(I) = 0.0D0
858 30 30 CONTINUE
859 ENDIF
860
861C FIRST LEVEL OF ITERATIONS
862C USE ENVELOPE TRIANGLE OF THE PREVIOUS MODEL;
863C FOR THE FIRST MODEL OF A RUN,THE TRIANGLE IS GENERATED HERE.
864 NITER = NITER1
865 LSBC = .FALSE.
866C CALL TO CRRECT - ADDED ITERATION LEVEL
867 ITLVL = 1
868 CALL CRRECT(DELTS,M,NITER,LFINI,LARGE,LNEW,LRESET,LSBC,
869 * * TRIT,TRIL,CFENV,PS,TS,RS,FTRI,ISTORE,ESTORE,HSTOT,
870 * * BL,TEFFL,HD,HHA,HHB,HHC,HL,HMAX,HP,HPP,HR,HS,HS1,
871 * * HS2,HSRF,HT,HTT,HCOMP,LC,NHMAX,TLUMX,LATMO,LDERIV,
872C * LMIX,LOCOND,QDT,QDP,MODEL,FP,FT,ETA2,OMEGA,R0,ITDONE,
873C * HG,HI,HJM, ITLVL,LCZ,MRZONE,MXZONE,NRZONE,NZONE, ! KC 2025-05-31
874 * * LMIX,LOCOND,FP,FT,ETA2,OMEGA,R0,ITDONE,
875 * * HG,HI,HJM, ITLVL,MXZONE,QIW,HKEROT,HKEROTO,CMIXL)
876C SECOND LEVEL OF ITERATIONS
877C CHECK ENVELOPE TRIANGLE BEFORE ITERATING FOR SOLUTION
878 IF(LARGE) GOTO 15
879 LSBC = .TRUE.
880 NITER = NITER2
881 ITLVL = 2
882 CALL CRRECT(DELTS,M,NITER,LFINI,LARGE,LNEW,LRESET,LSBC,
883 * * TRIT,TRIL,CFENV,PS,TS,RS,FTRI,ISTORE,ESTORE,HSTOT,
884 * * BL,TEFFL,HD,HHA,HHB,HHC,HL,HMAX,HP,HPP,HR,HS,HS1,
885 * * HS2,HSRF,HT,HTT,HCOMP,LC,NHMAX,TLUMX,LATMO,LDERIV,
886C * LMIX,LOCOND,QDT,QDP,MODEL,FP,FT,ETA2,OMEGA,R0,ITDONE,
887C * HG,HI,HJM, ITLVL,LCZ,MRZONE,MXZONE,NRZONE,NZONE, ! KC 2025-05-31
888 * * LMIX,LOCOND,FP,FT,ETA2,OMEGA,R0,ITDONE,
889 * * HG,HI,HJM, ITLVL,MXZONE,QIW,HKEROT,HKEROTO,CMIXL)
890 IF(LARGE)GOTO 15
891C 7/91 STORE CHANGES IN THE STRUCTURE. THESE CHANGES ARE USED TO GET AN
892C IMPROVED FIRST GUESS AT THE STRUCTURE FOR THE NEXT MODEL IF LNEWS=T.
893 IF(DELTS.GT.0.0D0)THEN
894 DO 27 II = 1,M
895 HTT0(II)=HTT(II)/DELTS
896 HPP0(II)=HPP(II)/DELTS
897 HLL0(II)=2.0D0*(HL(II)-HLO(II))/(HL(II)+HLO(II))/DELTS
898 HRR0(II)=(HR(II)-HRO(II))/DELTS
899 27 27 CONTINUE
900 ENDIF
901C THIRD LEVEL OF ITERATIONS
902 LSBC = .FALSE.
903 NITER = NITER3
904 ITLVL = 3
905 CALL CRRECT(DELTS,M,NITER,LFINI,LARGE,LNEW,LRESET,LSBC,
906 * * TRIT,TRIL,CFENV,PS,TS,RS,FTRI,ISTORE,ESTORE,HSTOT,
907 * * BL,TEFFL,HD,HHA,HHB,HHC,HL,HMAX,HP,HPP,HR,HS,HS1,
908 * * HS2,HSRF,HT,HTT,HCOMP,LC,NHMAX,TLUMX,LATMO,LDERIV,
909C * LMIX,LOCOND,QDT,QDP,MODEL,FP,FT,ETA2,OMEGA,R0,ITDONE,
910C * HG,HI,HJM, ITLVL,LCZ,MRZONE,MXZONE,NRZONE,NZONE, ! KC 2025-05-31
911 * * LMIX,LOCOND,FP,FT,ETA2,OMEGA,R0,ITDONE,
912 * * HG,HI,HJM, ITLVL,MXZONE,QIW,HKEROT,HKEROTO,CMIXL)
913 IF(LARGE)GOTO 15
914 IF(.NOT.LROT)THEN
915 ITDIF1 = 1
916 ENDIF
917C MHP 05/02
918C IF THE CODE IS ITERATING BETWEEN THE STRUCTURE AND ROTATION
919C SOLUTIONS, ENSURE THAT THE START-OF-TIMESTEP QUANTITIES
920C HCOMPP (COMPOSITION) AND HJMSAV (ANGULAR MOMENTUM) ARE ONLY
921C OVERWRITTEN ON THE LAST RUN THROUGH.
922 IF(ITDIF1.GT.1)THEN
923 DO I = 1,M
924 HJM0(I) = HJM(I)
925 DO J = 1,15
926 HCOMPP0(J,I) = HCOMPP(J,I)
927 END DO
928 END DO
929 ENDIF
930 DO ITROT = 1, ITDIF1
931C MHP 05/02 RESTORE ORIGINAL "START OF TIMESTEP"
932C VALUES FOR THE COMPOSITION MATRIX
933 IF(ITROT.GT.1)THEN
934 DO I = 1,M
935 DO J = 1,15
936 HCOMPP(J,I) = HCOMPP0(J,I)
937 END DO
938 END DO
939 ENDIF
940C 7/91 THE FOURTH LEVEL OF ITERATION REPEATS THE ITERATION BETWEEN THE
941C MIXING AND THE STRUCTURE VARIABLES. IT SHOULD NOT BE USED FOR MODELS
942C WHERE SEMI-CONVECTION IS IMPORTANT (ITERATING BETWEEN THE BURNING AND
943C STRUCTURE GENERATES OSCILLATIONS). IT SHOULD BE USED FOR HIGH-PRECISION
944C WORK (E.G. SOLAR MODELS).
945C Surface boundary conditions checked again since we've changed the
946C composition (and hence the structure) of the model in ITLVL=3
947C (to be implemented when I know the rest of it works!)
948 NITER = NITER4
949 LSBC=.FALSE.
950 ITLVL = 4
951 CALL CRRECT(DELTS,M,NITER,LFINI,LARGE,LNEW,LRESET,LSBC,
952 * * TRIT,TRIL,CFENV,PS,TS,RS,FTRI,ISTORE,ESTORE,HSTOT,
953 * * BL,TEFFL,HD,HHA,HHB,HHC,HL,HMAX,HP,HPP,HR,HS,HS1,
954 * * HS2,HSRF,HT,HTT,HCOMP,LC,NHMAX,TLUMX,LATMO,LDERIV,
955C * LMIX,LOCOND,QDT,QDP,MODEL,FP,FT,ETA2,OMEGA,R0,ITDONE,
956C * HG,HI,HJM,ITLVL,LCZ,MRZONE,MXZONE,NRZONE,NZONE, ! KC 2025-05-31
957 * * LMIX,LOCOND,FP,FT,ETA2,OMEGA,R0,ITDONE,
958 * * HG,HI,HJM,ITLVL,MXZONE,QIW,HKEROT,HKEROTO,CMIXL)
959C 25 CONTINUE
960 IF(.NOT.LFINI) THEN
961C MODEL FAILED TO CONVERGE WITHIN(NITER1+NITER2+NITER3+NITER4)ITERATIONS
962 LARGE = .TRUE.
963 GOTO 15
964 ENDIF
965
966C MODEL HAS CONVERGED
967C ENSURE CONVECTION ZONES ARE FULLY MIXED.
968C MHP 02/12 INFER CONVECTIVE OVERTURN TIMESCALE (USED IN MDOT)
969C JVS 02/12 CALL MIXCZ(HCOMP,HS2,LC,M)
970C KC 2025-05-30 addressed warning messages from Makefile.legacy
971C C G Somers 6/14, SET IMIX = .TRUE. SO THE CORRECT GRADS ARE USED.
972C IMIX = .TRUE.
973C CALL MIXCZ(HCOMP,HS2,HS1,LC,HR,HP,HD,HG,M,IMIX)
974C G Somers 6/14, SET LIMIX = .TRUE. SO THE CORRECT GRADS ARE USED.
975 LIMIX = .TRUE.
976C CALL MIXCZ(HCOMP,HS2,HS1,LC,HR,HP,HD,HG,M,LIMIX) ! KC 2025-05-31
977 CALL MIXCZ(HCOMP,HS2,LC,M)
978C G Somers END
979
980C MHP 9/94 STORE TOTAL AGE IN SAGE
981 SAGE = DAGE
982 IF(LROT) THEN
983C RESTORE ORIGINAL START OF TIMESTEP VALUES
984C TO THE ANGULAR MOMENTUM DISTRIBUTION
985 IF(ITROT.GT.1)THEN
986 DO I = 1,M
987 HJM(I) = HJM0(I)
988 END DO
989 ENDIF
990C MHP 9/94 ADDED FLAG TO TURN ON ROTATION OUTPUT WHEN END OF KIND
991C CARD REACHED.
992C MHP 10/24 GENERALIZE CHECK
993 IF(LENDAG(NK).AND.ENDAGE(NK).GT.0.0D0. AND.
994 * * (ABS(ENDAGE(NK)-DAGE*1.0D9-DDAGE) .LE. 1.0D0)) THEN
995C IF(LENDAG(NK).AND.ENDAGE(NK)-DAGE*1.0D9.LE.1.0D0)THEN
996 LPRT0 = .TRUE.
997 ELSE
998 LPRT0 = .FALSE.
999 ENDIF
1000C FIND THE NEW RUN OF OMEGA
1001C JENV0 ADDED TO SR CALL.
1002 LJDOT = LJDOT0
1003 CALL GETW(BL,DELTS,DWMAX,FP,FT,HCOMP,HD,HJM,HL,HP,HR,
1004C * HS,HS1,HS2,HSTOT,HT,LC,LJDOT,M,MODEL,SJTOT,SMASS, ! KC 2025-05-31
1005 * * HS,HS1,HS2,HSTOT,HT,LC,LJDOT,M,SMASS,
1006 * * TEFFL,ETA2,HG,HI,OMEGA,QIW,R0,JENV0,CMIXL,LPRT0)
1007C CALCULATE FP AND FT GIVEN OMEGA FOR THE NEW POINT DISTRIBUTION
1008 CALL FPFT(HD,HR,HS,M,OMEGA,ETA2,FP,FT,HG,R0)
1009 ENDIF
1010 END DO
1011C LOCATE THE HYDROGEN-BURNING SHELL AND THE BOUNDARIES OF THE CENTRAL
1012C AND SURFACE CONVECTION ZONES (IF APPLICABLE).
1013 CALL FINDSH(HCOMP,HL,LC,M,JCORE,JENV,JXBEG,JXEND,JXMID,
1014 * * LSHELL)
1015C PERFORM LIGHT ELEMENT BURNING
1016 IF(LEXCOM .AND. MODEL.GE.0 .AND. DELTS.GT.0.0D0)THEN
1017C ONLY FOR MODELS WITHOUT ROTATION, OR WITHOUT ROTATIONAL MIXING.
1018 IF(.NOT.LROT .OR. .NOT.LINSTB)THEN
1019C FIND CONVECTION ZONE DEPTH AT THE END OF THE TIME STEP.
1020 CALL CONVEC(HCOMP,HD,HP,HR,HS,HT,LC,M,MRZONE,MXZONE,
1021 * * MXZON0,JCORE,JENV,NRZONE,NZONE,NZONE0)
1022C CHANGED FOR LITHIUM BURNING WITH OVERSHOOT.
1023 JENV1 = JENV
1024 IF(LOVSTE)THEN
1025 PSCAL1 = ALPHAE*EXP(CLNDP*(HP(JENV)+2.0D0*HR(JENV)
1026 * * -HD(JENV)-CGL-HS(JENV)))
1027 ELSE
1028 PSCAL1 = 0.0D0
1029 ENDIF
1030C FIND BURNING RATES AT THE END OF THE TIME STEP.
1031C 10/29/26 MHP via Claude: flag 2 -> 1 (see the start-of-step call).
1032 CALL LIRATE88(HCOMP,HD,HT,M,1)
1033C CALL LIBURN(DELTS,HCOMP,HD,HR,HS1,HS2,HT,JENV1,JENV0,M) ! KC 2025-05-31
1034 CALL LIBURN(DELTS,HCOMP,HR,HS1,HS2,HT,JENV1,JENV0,M)
1035 ENDIF
1036 ENDIF
1037C MHP 07/02 RESTORE PRIOR FITTING POINT IF MASS ACCRETION IS BEING
1038C INCLUDED
1039 IF(LNEWFIT)THEN
1040 CALL GETNEWENV(SENVOLD,HCOMP,HD,HL,HP,HR,HS,HS1,HS2,
1041C * HSTOT,HT,LC,ETA2,HG,HI,HJM,QIW,R0, ! KC 2025-05-31
1042 * * HSTOT,HT,LC,ETA2,HI,HJM,QIW,R0,
1043 * * HKEROT,BL,SJTOT,SKEROT,TEFFL,M,LNEW,CMIXL)
1044C CALCULATE FP AND FT GIVEN OMEGA FOR THE NEW POINT DISTRIBUTION
1045 CALL FPFT(HD,HR,HS,M,OMEGA,ETA2,FP,FT,HG,R0)
1046 LNEWFIT = .FALSE.
1047 ENDIF
1048C DETERMINE TIMESTEP FOR NEXT MODEL
1049C HTIMER ALSO LOCATES THE H-BURNING SHELL
1050C JVS 04/14 added teffl to passed htimer variables
1051 DELTS = DABS(DELTS)
1052 DELTS0 = DELTS
1053C CALL HTIMER(DELTS,DELTSH,M,HD,HL,HS1,HS2,HT,LC,HCOMP,JCORE,
1054C * JXMID,TLUMX,DAGE,DDAGE,QDT,QDP,NK,HP,HR,OMEGA, ! KC 2025-05-31
1055 CALL HTIMER(DELTS,DELTSH,M,HD,HL,HS1,HS2,HT,HCOMP,JCORE,
1056 * * JXMID,TLUMX,DAGE,DDAGE,NK,HP,HR,OMEGA,
1057 * * DWMAX,JXBEG,TEFFL)
1058C IF EVOLVING TO A GIVEN AGE AND KIND CARD IS DONE, AVOID ZEROING OUT
1059C TIMESTEP WRITTEN TO MODEL (AS THIS MAKES CONTINUING A SEQUENCE AWKWARD.)
1060C INSTEAD WRITE THE PREVIOUS MODEL TIMESTEP TO MODEL.
1061C ONLY IF A FIXED END AGE IS USED, NOT FOR OTHER STOPS
1062 IF(LENDAG(NK) .AND. ENDAGE(NK).GT.0.0D0)THEN
1063 IF(ENDAGE(NK)-DAGE*1.0D9.LE.1.0D0)THEN
1064C 10/29/26 MHP via Claude
1065C The floor is 1D-3 of the age. DAGE is in Gyr, so it needs 1D9 to
1066C become years; without it the floor was 1D-12 of the age (0.005 yr at
1067C 4.57 Gyr) and never acted.
1068 DELTS = MAX(DELTS0,1.0D-3*DAGE*1.0D9*CSECYR)
1069 DDAGE = DELTS/CSECYR
1070 ELSE
1071 DELTS0 = DELTS
1072 ENDIF
1073 ELSE
1074 DELTS0 = DELTS
1075 ENDIF
1076 IF(IRESCA(NK).NE.2) MODEL = MODEL+1
1077C WRTOUT IS THE OUTPUT DRIVER ROUTINE
1078 CALL WRTOUT(HCOMP,HD,HL,HP,HR,HS,HS1,HT,LC,M,MODEL,DAGE,
1079 * * DDAGE,SMASS,TEFFL,BL,GL,LSHELL,JXBEG,JXMID,JXEND,JCORE,
1080 * * JENV,TLUMX,TRIT,TRIL,PS,TS,RS,CFENV,FTRI,HSTOT,OMEGA,
1081C * LPUNCH,FP,FT,ETA2,R0,HJM,HI,SJTOT,SKEROT,HS2,NK) ! KC 2025-05-31
1082 * * LPUNCH,FP,FT,ETA2,R0,HJM,HI,SJTOT,SKEROT,HS2,CMIXL,XMSOL,COMPMIX)
1083
1084C MHP 10/24 GENERALIZED STOP CONDITIONS
1085C IF EVOLVING TO A GIVEN AGE AND AGE IS REACHED, KIND CARD IS DONE
1086C IF(LENDAG(NK).AND.ENDAGE(NK)-DAGE*1.0D9.LE.1.0D0)GOTO 110
1087 IF(LENDAG(NK).AND.ENDAGE(NK).GT.0.0D0 .AND.
1088 * * (ENDAGE(NK)-DAGE*1.0D9).LE.1.0D0)GOTO 110
1089C MHP 10/24 CHECK ALL STOP CONDITIONS, EXIT IF ANY SATISFIED
1090 LEND_KIND = .FALSE.
1091 IF(LENDAG(NK).AND.END_DCEN(NK).GT.0.0D0 .AND.
1092 * * HCOMP(12,1).LT.END_DCEN(NK))THEN
1093 WRITE(*,104)HCOMP(12,1),END_DCEN(NK)
1094 104 104 FORMAT('CENTRAL D ',E12.4,' BELOW STOP VALUE ',E12.4)
1095 LEND_KIND =.TRUE.
1096 ENDIF
1097 IF(LENDAG(NK).AND.END_XCEN(NK).GT.0.0D0 .AND.
1098 * * HCOMP(1,1).LT.END_XCEN(NK))THEN
1099 WRITE(*,105)HCOMP(1,1),END_XCEN(NK)
1100 105 105 FORMAT('CENTRAL X ',E12.4,' BELOW STOP VALUE ',E12.4)
1101 LEND_KIND =.TRUE.
1102 ENDIF
1103 IF(LENDAG(NK).AND.END_YCEN(NK).GT.0.0D0 .AND.
1104 * * HCOMP(2,1).LT.END_YCEN(NK))THEN
1105 WRITE(*,106)HCOMP(2,1),END_YCEN(NK)
1106 106 106 FORMAT('CENTRAL Y ',E12.4,' BELOW STOP VALUE ',E12.4)
1107 LEND_KIND =.TRUE.
1108 ENDIF
1109C IF EXITING, SET I/O FLAGS PROPERLY AND EXIT LOOP
1110 IF(LEND_KIND)THEN
1111 LPULSE = LSAVPU
1112 LSOUND = .TRUE.
1113 LPRT0 = .TRUE.
1114 GOTO 110
1115 ENDIF
1116C TEST IF MODEL IS NEAR DESIRED Teff AND L. IF NOT RESCALE AND TRY AGAIN.
1117 IF (LCALST .AND. .NOT. LSTAR) THEN
1118 IF(MOD(NK,2).EQ.0)THEN
1119 IF(MODELN.EQ.1) THEN
1120 TEFFI = 10.0D0**TEFFL
1121 ELSE
1122 CALL CHKSCAL(BL, TEFFL, DAGE, NK,ALRI,LSTAR,LPASSR)
1123 IF(LPASSR) GOTO 200
1124 END IF
1125 ENDIF
1126 ENDIF
1127
1128C END OF RUN
1129 100 100 CONTINUE
1130
1131C G Somers 11/14, CHANGE CALL TO PUTSTORE INSTEAD OF WRTLST.
1132C STORE LAST MODEL IN ISTOR IF LSTORE, LSTPCH, AND LPUNCH ARE .TRUE.
1133 110 110 IF(LSTORE.AND.LSTPCH.AND.LPUNCH) THEN
1134 CALL PUTSTORE(HCOMP,HD,HL,HP,HR,HS,HT,LC,TRIT,TRIL,PS,TS,RS,
1135 * * CFENV,FTRI,TLUMX,JCORE,JENV,MODEL,M,SMASS,TEFFL,BL,HSTOT,
1136 * * DAGE,DDAGE,OMEGA,HS1,ETA2,R0,FP,FT,HJM,HI,CMIXL,XMSOL,COMPMIX)
1137 LPUNCH = .FALSE.
1138 ENDIF
1139C 110 CONTINUE
1140C G Somers END
1141
1142C MHP 1/93 CHECK AUTOMATIC CALIBRATATION OF SOLAR MODEL.
1143c MHP 5/96 changed solar calibration to perform solar models in 3 kind cards
1144 IF(LCALS)THEN
1145C JVS Turn off calcad - speeds things up
1146 LADON=.FALSE.
1147 IF(MOD(NK,3).EQ.0)THEN
1148 RLL = 0.5D0*(BL+CLSUNL-C4PIL-CSIGL-4.0D0*TEFFL)-CRSUNL
1149C MHP 06/13 Add solar Z/X to observables
1150 SOLZX = HCOMP(3,M)/HCOMP(1,M)
1151 CALL CHKCAL(BL,RLL,NK,SOLZX,DLDX,DRDX,DLDA,DRDA,
1152 * * LSOL)
1153C CALL CHKCAL(BL,RLL,NK)
1154 lptime = lptimesv ! Restore LPTIME to original value for next cycle
1155 kttau = kttausv ! Restore KTTAU to original value for next cycle
1156 IF(LSOL) THEN
1157 GO TO 250
1158 ELSE
1159c MHP 8/96 added counter for # of runs needed for calibration
1160 ICONV = ICONV + 1
1161C MHP 6/97 STOP AFTER 10 ATTEMPTS AT CALIBRATION
1162c IF(ICONV.GE.11) GOTO 250
1163 IF(ICONV.GE.15) GOTO 250
1164 IF (LPULSE) THEN
1165C DBG 6/93 Need to delete pulse output because have not got ultimate
1166C model yet.
1167C MHP 8/25 Replaced delete file with rewind file. This is functionally the same and avoids the need to pass the character string for the file name from parmin.
1168 REWIND(IOPMOD)
1169 REWIND(IOPENV)
1170 REWIND(IOPATM)
1171C CLOSE(IOPMOD, STATUS='DELETE')
1172C CLOSE(IOPENV, STATUS='DELETE')
1173C CLOSE(IOPATM, STATUS='DELETE')
1174C OPEN(IOPMOD, FILE=FPMOD,STATUS='UNKNOWN',
1175C * FORM='FORMATTED')
1176C OPEN(IOPENV, FILE=FPENV,STATUS='UNKNOWN',
1177C * FORM='FORMATTED')
1178C OPEN(IOPATM, FILE=FPATM,STATUS='UNKNOWN',
1179C * FORM='FORMATTED')
1180 END IF
1181 END IF
1182 ENDIF
1183 ENDIF
1184
1185C DBG 12/94 NO MORE RUNS NEEDED. HAVE CALIBRATED STELLAR MODEL
1186 IF(LCALST .AND. LSTAR.AND.(MOD(NK,2).EQ.0)) GOTO 250
1187
1188C END RUN LOOP
1189 200 200 CONTINUE
1190C EXIT RUN LOOP
1191 250 250 CONTINUE
1192
1193C 9/24/26 MHP via Claude
1194C code changed to remove the Monte Carlo option
1195 IF(LCALS .AND. LSNU .AND. LSOL)THEN
1196 REWIND(ILAST)
1197 REWIND(IFIRST)
1198 REWIND(IDEBUG)
1199 REWIND(ITRACK)
1200 REWIND(ISHORT)
1201 REWIND(IMODPT)
1202 REWIND(ISTOR)
1203
1204 ZTOX = HCOMP(3,M)/HCOMP(1,M)
1205C 9/24/26 MHP via Claude
1206C code changed to remove the Monte Carlo option
1207C NUMERICAL DATA : #OF RUNS NEEDED FOR A CONVERGED MODEL, INITIAL X
1208C AND ALPHA, FINAL DL/DX,DR/DX,DL/D ALPHA, DR/D ALPHA
1209 WRITE(ISNU,1518)ICONV,XGUESS,AGUESS,DLDX,DRDX,DLDA,DRDA
1210 1518 1518 FORMAT(1X,I2,2F10.6,1P4E11.4)
1211C NEUTRINO FLUXES (SEE ENGEB FOR DETAILS)
1212 WRITE(ISNU, 1516) CLSNU,GASNU,(FLUXTOT(I),I=1,10)
1213 1516 1516 FORMAT(1X,2F8.3,1P10E10.3)
1214C SUMMARY OF STRUCTURE : TC, RHOC, PC, XC, ZC (ADD MU C)
1215 TCEN = 10.0D0**(TCENTER-6.0D0)
1216 PCEN = 10.0D0**(PCENTER-17.0D0)
1217 DCEN = 10.0D0**DCENTER
1218 WRITE(ISNU, 1517)TCEN,DCEN,PCEN,HCOMP(1,1),HCOMP(3,1)
1219 1517 1517 FORMAT(1X,F7.3,F7.2,F6.3,2F8.5)
1220C INITIAL ALPHA,Y,Z,ALPHA; FINAL R, L
1221 YINI = 1.0D0 - RESCAL(2,NK-2) - RESCAL(3,NK-2)
1222 ZINI = RESCAL(3,NK-2)
1223 WRITE(ISNU,1521)CMIXLA(NK),YINI,ZINI,BL,RLL
1224 1521 1521 FORMAT(F7.4,2F8.5,1P2E10.3)
1225C CZ DEPTH (R,M), SURFACE Y, Z, Z/X (ADD T CZ BASE, RHO CZ BASE)
1226 WRITE(ISNU,1522)CZsurf_R,CZsurf_M,HCOMP(2,M),HCOMP(3,M),ZTOX
1227 1522 1522 FORMAT(F8.5,F9.6,2F8.5,F9.6)
1228C ENERGY GENERATION FRACTIONS PP I,II,III,CNO,EGRAV
1229 WRITE(ISNU,1523)(TLUMX(J),J=1,4),TLUMX(7)
1230 1523 1523 FORMAT(1P5E10.3)
1231C 9/24/26 MHP via Claude
1232C code changed to remove the Monte Carlo option
1233 ENDIF
1234
1235 STOP
1236 END1"""Python version of main.f (YREC 7be4133): YREC's main program, which reads
2the run's settings, sets up the tables, and evolves the starting model of
3each kind card model by model."""
4
5import math
6
7import numpy as np
8
9from pyrec import acdpth_mod
10from pyrec import cent_mod
11from pyrec import cenv_mod
12from pyrec import constants_mod
13from pyrec import ctol_mod
14from pyrec import deuter_mod
15from pyrec import dimensions_mod
16from pyrec import disk_mod
17from pyrec import entrop_mod
18from pyrec import fluxes_mod
19from pyrec import iounits_mod
20from pyrec import label_mod
21from pyrec import liov_mod
22from pyrec import nmlpar_mod
23from pyrec import oldmod_mod
24from pyrec import ovrtrn_mod
25from pyrec import prevcz_mod
26from pyrec import runloop_mod
27from pyrec import sound_mod
28from pyrec.chkcal import chkcal
29from pyrec.chkscal import chkscal
30from pyrec.convec import convec
31from pyrec.crrect import crrect
32from pyrec.engeb import engeb
33from pyrec.findsh import findsh
34from pyrec.fpft import fpft
35from pyrec.getnewenv import getnewenv
36from pyrec.getw import getw
37from pyrec.hpoint import hpoint
38from pyrec.htimer import htimer
39from pyrec.liburn import liburn
40from pyrec.lirate88 import lirate88
41from pyrec.massloss import massloss
42from pyrec.mix import mix
43from pyrec.mixcz import mixcz
44from pyrec.parmin import parmin
45from pyrec.pdist import pdist
46from pyrec.putstore import putstore
47from pyrec.setcal import setcal
48from pyrec.setscal import setscal
49from pyrec.setups import setups
50from pyrec.starin import starin
51from pyrec.version import setversion
52from pyrec.wrthead import wrthead
53from pyrec.wrtlst import wrtlst
54from pyrec.wrtout import wrtout
55
56JSON = dimensions_mod.json
57
58
59def main() -> None:
60 """YREC's main program: settings and tables, then for each kind card
61 the starting model and the evolution loop (mass loss, mixing and
62 burning, rezoning, four levels of CRRECT, rotation, light elements,
63 time step, output), with the solar and stellar calibrations around it.
64
65 Translates: main.f#(file level) (7be4133)
66
67 No arguments; it ends with STOP (SystemExit).
68
69 """
70
71 c = constants_mod
72 nml = nmlpar_mod
73 io = iounits_mod
74 rl_ = runloop_mod
75 ent = entrop_mod
76 old = oldmod_mod
77
78 # The model and its work arrays (index 0 unused).
79 hs, hl, hr, hp, ht, hd = (np.zeros(JSON + 1) for _ in range(6))
80 lc = np.zeros(JSON + 1, dtype=bool)
81 hcomp = np.zeros((16, JSON + 1))
82 hs1, hs2, hhc = (np.zeros(JSON + 1) for _ in range(3))
83 hha = np.zeros((5, 3, JSON + 1))
84 hhb = np.zeros((5, JSON + 1))
85 hpp, htt = np.zeros(JSON + 1), np.zeros(JSON + 1)
86 fp, ft, omega, hi, hjm = (np.zeros(JSON + 1) for _ in range(5))
87 hkerot, r0, eta2, qiw, hg = (np.zeros(JSON + 1) for _ in range(5))
88 hkeroto = np.zeros(JSON + 1)
89 tlumx, tril, trit = np.zeros(9), np.zeros(4), np.zeros(4)
90 ps, ts, rs, cfenv = np.zeros(4), np.zeros(4), np.zeros(4), np.zeros(10)
91 estore, hmax = np.zeros(5), np.zeros(5)
92 nhmax = np.zeros(5, dtype=int)
93 hsrf, v = np.zeros(7), np.zeros(13)
94 # Start-of-step j and composition when iterating structure and rotation
95 # (formerly COMMON/ORIGSTART/, now local arrays).
96 hjm0 = np.zeros(JSON + 1)
97 hcompp0 = np.zeros((16, JSON + 1))
98 # The neutrino table (off).
99 be7m = np.zeros(JSON + 1)
100 fluxi0 = np.zeros((11, JSON + 1))
101 hr1, hr2, hr3, hr4, hr5, hr6, hr7, hr8, hr9, hr10, hr11, hr12, hr13 = (
102 np.zeros(JSON + 1) for _ in range(13))
103 hf1, hf2 = np.zeros(JSON + 1), np.zeros(JSON + 1)
104 mxzone = np.zeros((13, 3), dtype=int)
105 mxzon0 = np.zeros((13, 3), dtype=int)
106 mrzone = np.zeros((14, 3), dtype=int)
107
108 # Scalars passed before any routine sets them, or set by the callees
109 # (GL by WRTOUT; LATMO, LDERIV, LMIX, LOCOND by CRRECT). Fortran
110 # leaves them undefined; 0 or False here.
111 bl = dage = ddage = delts = deltsh = ftri = hstot = smass = teffl = 0.0
112 dwmax = gl = sjtot = skerot = senvold = vel = 0.0
113 ikut = istore = jcore = jenv = jxbeg = jxend = jxmid = m = model = 0
114 nrzone = nzone = nzone0 = itdone = jenv0 = 0
115 latmo = lderiv = lmix = locond = lnew = lshell = lnewfit = False
116 lprt0 = False
117 compmix = ''
118 # IU is never set in the Fortran, but passed to ENGEB (unused block).
119 iu = 0
120 # DATA DLDX,DRDX,DLDA,DRDA,LSOL/4*0.0D0,.FALSE./ (explicit, since
121 # SETCAL may never run while LSOL is still tested at the end).
122 dldx = drdx = dlda = drda = 0.0
123 lsol = False
124 # COMMON/CALSTAR/ is now these three locals, set by SETSCAL, CHKSCAL.
125 alri = 0.0
126 lstar = lpassr = False
127 # DATA NAO/1/: the next of the ages AGEOUT.
128 nao = 1
129
130 def _crrect(niter, lsbc, itlvl):
131 """The four calls to CRRECT (below) differ only in NITER,
132 LSBC and ITLVL; the other arguments are main's current values."""
133 return crrect(
134 delts, m, niter, lfini, large, lnew, lreset, lsbc,
135 trit, tril, cfenv, ps, ts, rs, ftri, istore, estore,
136 hstot, bl, teffl, hd, hha, hhb, hhc, hl, hmax, hp,
137 hpp, hr, hs, hs1, hs2, hsrf, ht, htt, hcomp, lc,
138 nhmax, tlumx, latmo, lderiv, lmix, locond,
139 fp, ft, eta2, omega, r0, itdone, hg, hi, hjm, itlvl,
140 mxzone, qiw, hkerot, hkeroto, cmixl)
141
142 # Start: the version; IOWR (PARMIN sets it again) (Fortran lines 351–355).
143 yrecver, githash = setversion('', '')
144 io.iowr = 9
145 # LPUNCH is true once the first model is calculated.
146 lpunch = False
147
148 # Read the run's parameters; it returns the table files' names (Fortran lines 357–359).
149 (falex06, fallard, fatm, ffermi, fliv95, fpatm, fpenv, fpmod, fpurez,
150 fscvh, fscvhe, fscvz) = parmin('', '', '', '', '', '', '', '', '', '',
151 '', '', yrecver, githash)
152
153 # Constants and tables (Fortran lines 362–363).
154 setups(falex06, fallard, fatm, ffermi, fliv95, fpurez, fscvh, fscvhe,
155 fscvz)
156
157 # The Monte Carlo option is removed: one pass, the age factor 1 (Fortran lines 369–372).
158 facage = 1.0
159 lsavpu = nml.lpulse
160
161 # Automatic solar calibration: starting estimates of alpha and X (Fortran lines 378–387).
162 if nml.lcals:
163 lsol = setcal(facage, lsol)
164 iconv = 1
165 xguess = rl_.rescal[2, 1]
166 aguess = nml.cmixla[1]
167 lptimesv = nml.lptime # LPTIME, KTTAU restored at each cycle
168 kttausv = nml.kttau
169 else:
170 iconv = 0
171
172 # Calibration of a star of given Teff and L (Fortran lines 390–392).
173 if nml.lcalst:
174 alri, lstar, lpassr = setscal(alri, lstar, lpassr)
175
176 # The kind-card loop (DO 200): the run's settings (Fortran lines 397–409).
177 for nk in range(1, nml.numrun + 1):
178 sound_mod.lsound = False
179 label_mod.xenv0 = nml.xenv0a[nk]
180 label_mod.zenv0 = nml.zenv0a[nk]
181 cmixl = nml.cmixla[nk]
182 cenv_mod.lsenv0 = nml.lsenv0a[nk]
183 cenv_mod.senv0 = nml.senv0a[nk]
184 lreset = False
185 large = False
186 sjtot = 0.0
187 skerot = 0.0
188
189 # Read in (or keep) the starting model (Fortran lines 413–428).
190 (bl, dage, ddage, delts, deltsh, ftri, hstot, ikut, istore, lnew,
191 m, model, sjtot, skerot, smass, teffl, vel,
192 compmix) = starin(
193 bl, cfenv, dage, ddage, delts, deltsh, eta2, fp, ft, ftri,
194 hcomp, hd, hi, hjm, hkerot, hl, hp, hr, hs, hs1, hs2, hstot, ht,
195 ikut, istore, jenv, large, lc, lnew, m, model, nk, omega, ps,
196 qiw, r0, rs, sjtot, skerot, smass, teffl, tlumx, tril,
197 trit, ts, vel, hg, v, cmixl, compmix)
198 if omega[1] == 0 and nml.lrot:
199 print('LROT set to TRUE, but OMEGA(1) = 0. Stopping.'
200 ' Initialize rotation rates or set LROT to FALSE.')
201 raise SystemExit(3)
202
203 # Disable stop conditions the starting model already meets (Fortran lines 430–460).
204 if rl_.lendag[nk]:
205 if nml.end_dcen[nk] > 0.0 and hcomp[12, 1] < nml.end_dcen[nk]:
206 nml.end_dcen[nk] = -nml.end_dcen[nk]
207 msg = (f"STARTING D {hcomp[12, 1]:12.4E} BELOW STOP VALUE "
208 f"{nml.end_dcen[nk]:12.4E} STOP DISABLED.") # 101
209 print(msg)
210 io.write(io.ishort, msg)
211 if nml.end_xcen[nk] > 0.0 and hcomp[1, 1] < nml.end_xcen[nk]:
212 nml.end_xcen[nk] = -nml.end_xcen[nk]
213 msg = (f"STARTING X {hcomp[1, 1]:12.4E} BELOW STOP VALUE "
214 f"{nml.end_xcen[nk]:12.4E} STOP DISABLED.") # 102
215 print(msg)
216 io.write(io.ishort, msg)
217 if nml.end_ycen[nk] > 0.0 and hcomp[2, 1] < nml.end_ycen[nk]:
218 nml.end_ycen[nk] = -nml.end_ycen[nk]
219 msg = (f"STARTING Y {hcomp[2, 1]:12.4E} BELOW STOP VALUE "
220 f"{nml.end_ycen[nk]:12.4E} STOP DISABLED.") # 103
221 print(msg)
222 io.write(io.ishort, msg)
223
224 # The neutrino table, switched off (MHP 2/04); unused (Fortran lines 461–550).
225 lnutab = False
226 if lnutab:
227 # Weights and masses: HS1, the shell centres (g, unlogged);
228 # HS2, the shells' masses (g).
229 ds3 = math.exp(c.cln * hs[1])
230 ds2 = -ds3
231 for i in range(2, m + 1):
232 ds1 = ds2
233 ds2 = ds3
234 ds3 = math.exp(c.cln * hs[i])
235 hs1[i - 1] = ds2
236 hs2[i - 1] = 0.5 * (ds3 - ds1)
237 hs1[m] = ds3
238 hs2[m] = math.exp(c.cln * hstot) - 0.5 * (ds2 + ds3)
239 pdt = -1.0 # noqa: F841 (unused in the Fortran too)
240 pdp = 1.0 # noqa: F841 (unused in the Fortran too)
241 for j in range(1, 11):
242 fluxes_mod.fluxtot[j] = 0.0
243 for k in range(1, m + 1):
244 fluxi0[j, k] = 0.0
245 for i in range(1, m + 1):
246 dl = hd[i]
247 tl = ht[i]
248 if tl < 6.0:
249 break # go to 666
250 x = hcomp[1, i]
251 y = hcomp[2, i]
252 z = hcomp[3, i] # noqa: F841 (unused in the Fortran too)
253 xhe3 = hcomp[4, i]
254 xc12 = hcomp[5, i]
255 xc13 = hcomp[6, i]
256 xn14 = hcomp[7, i]
257 xn15 = hcomp[8, i] # noqa: F841 (unused in the Fortran too)
258 xo16 = hcomp[9, i]
259 xo17 = hcomp[10, i] # noqa: F841 (unused in the Fortran too)
260 xo18 = hcomp[11, i]
261 xh2 = 0.0 # Fortran: undefined here
262 (epp1, epp2, epp3, ecn, e3al, pep, pet, sum1,
263 be7massfraction, ealpca, enu) = engeb(
264 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, dl, tl, x, y,
265 xhe3, xc12, xc13, xn14, xo16, xo18, xh2, iu, hr1, hr2,
266 hr3, hr4, hr5, hr6, hr7, hr8, hr9, hr10, hr11, hr12,
267 hr13, hf1, hf2, 0.0, 0.0, 0.0)
268 be7m[i] = be7massfraction
269 # From erg/g/s to erg/s for each shell.
270 for j in range(1, 11):
271 fluxi0[j, i] = fluxes_mod.flux[j] * hs2[i]
272 fluxes_mod.fluxtot[j] = (fluxes_mod.fluxtot[j]
273 + fluxi0[j, i])
274 print(f"{i:5d}" + f"{hs2[i]:10.3E}"
275 + "".join(f"{fluxi0[j, i]:10.3E}"
276 for j in range(1, 11))) # format 911
277 # label 666
278 io.write(76, "".join(f"{fluxes_mod.fluxtot[i]:10.3E}"
279 for i in range(1, 11))) # format 222
280 for j in range(1, 11):
281 for i in range(1, m + 1):
282 fluxi0[j, i] = fluxi0[j, i] / fluxes_mod.fluxtot[j]
283 for i in range(1, m + 1):
284 t6 = math.exp(c.cln * (ht[i] - 6.0))
285 if t6 < 5.0:
286 break # go to 141
287 rhoe = hd[i] + math.log10((1.0 + hcomp[1, i]) / 2.0)
288 fm = hs2[i] / 1.9891e33
289 fr = math.exp(c.cln * hr[i]) / c.crsun
290 io.write(76, f"{fr:9.5f}{t6:7.3f}{rhoe:6.3f}"
291 + "".join(f"{q:10.3E}" for q in (
292 fm, be7m[i], fluxi0[1, i], fluxi0[5, i],
293 fluxi0[6, i], fluxi0[7, i], fluxi0[8, i],
294 fluxi0[4, i], fluxi0[2, i],
295 fluxi0[3, i]))) # format 145
296 # label 141
297
298 # Mass in solar units, kept for the output (formerly COMMON/PULSE/) (Fortran lines 552–555).
299 xmsol = smass
300 # Store the starting convection-zone properties (MHP 08/02).
301 deuter_mod.jcz = jenv
302 ovrtrn_mod.taucz = 0.0
303
304 # Headers of the output files (Fortran line 557).
305 wrthead(smass, cmixl, nk)
306
307 # For deciding when to dump pulsation output (Fortran lines 560–563).
308 pol1 = bl
309 pot1 = teffl
310 poa1 = dage
311 polen = 0.0
312
313 # Time-step cutting needs a model in unit ILAST, or it will crash:
314 # copy the initial model there (Fortran lines 565–574).
315 if nml.lkuthe:
316 # Question (see the page): still needed? Only if LPUNCH, and before FINDSH.
317 if lpunch:
318 iwrite = io.ilast
319 wrtlst(iwrite, hcomp, hd, hl, hp, hr, hs, ht, lc, trit, tril,
320 ps, ts, rs, cfenv, ftri, tlumx, jcore, jenv, model, m,
321 smass, teffl, bl, hstot, dage, ddage, omega, cmixl,
322 compmix)
323
324 # The H-burning shell and the convection-zone edges (Fortran lines 578–579).
325 jcore, jenv, jxbeg, jxend, jxmid, lshell = findsh(
326 hcomp, hl, lc, m, jcore, jenv, jxbeg, jxend, jxmid, lshell)
327
328 # The first time step (Fortran lines 584–588).
329 delts, deltsh, ddage, dwmax = htimer(
330 delts, deltsh, m, hd, hl, hs1, hs2, ht, hcomp, jcore, jxmid,
331 tlumx, dage, ddage, nk, hp, hr, omega, dwmax, jxbeg, teffl)
332 delts0 = delts
333
334 # Zero the rates of change for the first guess (Fortran lines 590–595).
335 for i in range(1, m + 1):
336 ent.htt0[i] = 0.0
337 ent.hpp0[i] = 0.0
338 ent.hll0[i] = 0.0
339 ent.hrr0[i] = 0.0
340
341 # Light-element rates of the surface zone: LIBURN recomputes the
342 # start rates until it has stored end rates (LBLIOLD) (Fortran lines 601–603).
343 if nml.lexcom:
344 prevcz_mod.lbliold = False
345
346 # The model loop (DO 100): one evolutionary step each (Fortran lines 608–612).
347 goto200 = False
348 for modeln in range(1, nml.nmodls[nk] + 1):
349 if nml.lrwsh:
350 io.rewind(io.ishort)
351
352 # Pulsation output on the last model of the run (Fortran lines 614–616).
353 if modeln == nml.nmodls[nk] and nk == nml.numrun:
354 nml.lpulse = lsavpu
355
356 # Pulsation output at chosen ages (AGEOUT), for the steps before
357 # and after each (JVS 02/11) (Fortran lines 625–655).
358 a = acdpth_mod
359 if a.lacout:
360 a.ladon = True
361 else:
362 a.ladon = False
363 if a.lacout:
364 if a.ljwrt:
365 print('LJWRT on')
366 nml.lpulse = lsavpu
367 nao = nao + 1
368 a.lclcd = True
369 a.ljlast = False
370 a.ljwrt = False
371 elif not a.ljwrt:
372 a.lclcd = False
373 if nao < 6:
374 if (dage + ddage / 1.0e9 - a.ageout[nao] <= 0.0
375 and dage + 2.0 * ddage / 1.0e9
376 - a.ageout[nao] >= 0.0
377 and not a.ljwrt):
378 print('AGEOUT reached')
379 nml.lpulse = lsavpu
380 a.lclcd = True
381 a.ljlast = True
382 a.ljwrt = True
383
384 # At the final age, pulsation output and sound speed (MHP 10/24) (Fortran lines 662–667).
385 if (rl_.lendag[nk] and nml.endage[nk] > 0.0
386 and abs(nml.endage[nk] - dage * 1.0e9 - ddage) <= 1.0):
387 nml.lpulse = lsavpu
388 sound_mod.lsound = True
389
390 # Fortran lines 673–677.
391 if nml.lpout:
392 pol1, pot1, poa1, polen = pdist(
393 pol1, pot1, poa1, polen, bl, teffl, modeln, nk, fpatm,
394 fpenv, fpmod, dage)
395
396 # Label 15: the step, from STARIN (after a failure) to the end
397 # of the rotation iterations. GOTO 15 is `continue` below.
398 while True:
399 # "STARIN called here for timestep cutting": with LARGE
400 # set, STARIN prints RUN STOPPED and stops (Fortran lines 680–697).
401 if large:
402 (bl, dage, ddage, delts, deltsh, ftri, hstot, ikut,
403 istore, lnew, m, model, sjtot, skerot,
404 smass, teffl, vel, compmix) = starin(
405 bl, cfenv, dage, ddage, delts, deltsh, eta2, fp, ft,
406 ftri, hcomp, hd, hi, hjm, hkerot, hl, hp, hr, hs,
407 hs1, hs2, hstot, ht, ikut, istore, jenv, large, lc,
408 lnew, m, model, nk, omega, ps, qiw, r0,
409 rs, sjtot, skerot, smass, teffl, tlumx, tril, trit,
410 ts, vel, hg, v, cmixl, compmix)
411 if omega[1] == 0 and nml.lrot:
412 print('LROT set to TRUE, but OMEGA(1) = 0. Stopping.'
413 ' Initialize rotation rates or set LROT to'
414 ' FALSE.') # format 18
415 raise SystemExit(3)
416 lpunch = True
417
418 # Age the model, unless the kind card only relaxes a
419 # rescaled model (pre-main-sequence models, log Tc < 6.6,
420 # still age as a failsafe, unless L_ZERODT_PREMS is set)
421 # (Fortran lines 712–720).
422 # Question (see the page): the 6.6.
423 if rl_.iresca[nk] != 2 and model >= 0:
424 lage = True
425 elif (not nml.l_zerodt_prems and model >= 0
426 and ht[1] < 6.6):
427 lage = True
428 else:
429 lage = False
430 lnewfit = False
431
432 # Mass loss, mixing and the age (Fortran lines 721–741).
433 if lage:
434 # Mass loss.
435 delts, hstot, lnew, smass, senvold, lnewfit = massloss(
436 bl, dage, delts, hcomp, hd, hjm, hp, hr, hs, hs1,
437 hs2, hstot, ht, jenv, lnew, m, omega, smass, teffl,
438 senvold, lnewfit)
439 # The composition at the start of the step.
440 nspec = 11
441 if nml.lexcom:
442 nspec = 15
443 for i in range(1, m + 1):
444 for j in range(1, nspec + 1):
445 old.hcompp[j, i] = hcomp[j, i]
446 # Mixing, burning and settling.
447 itlvl = 1
448 ddage, jcore, jenv = mix(
449 delts, hcomp, hd, hl, hp, hr, hs, hs1, hs2, hstot, ht,
450 itlvl, lc, m, ddage, jcore, jenv, mxzone, mxzon0,
451 teffl, cmixl)
452 ddage = delts / c.csecyr
453 dage = dage + 1.0e-9 * ddage
454
455 # Rezone, except for He-flash runs, which only keep the old
456 # model for PTIME (Fortran lines 763–790).
457 if not nml.lkuthe:
458 m, lreset, jcore, jenv, sjtot, skerot = hpoint(
459 m, hstot, hs, hs1, hs2, ht, hp, hr, lc, hl, hd,
460 hcomp, ps, rs, estore, istore, lreset, jxbeg, model,
461 lshell, jcore, jenv, omega, eta2, r0, hi, hjm,
462 hkerot, sjtot, skerot, fp, ft, hg, qiw, teffl, cmixl)
463 deuter_mod.jcz = jenv
464 else:
465 for i in range(1, m + 1):
466 old.hpo[i] = hp[i]
467 old.hto[i] = ht[i]
468 old.hro[i] = hr[i]
469 old.hlo[i] = hl[i]
470 old.hdo[i] = hd[i]
471 old.tefflo = teffl
472 old.hlsuro = hl[m]
473
474 # Fortran lines 792–796.
475 if nml.lrot:
476 for i in range(1, m + 1):
477 hkeroto[i] = hkerot[i]
478
479 # Light elements at the start of the step (Fortran lines 799–816).
480 if nml.lexcom:
481 prevcz_mod.rbase0 = 0.0
482 jenv0 = jenv
483 if nml.lovste:
484 liov_mod.pscal0 = nml.alphae * math.exp(
485 c.clndp * (hp[jenv] + 2.0 * hr[jenv] - hd[jenv]
486 - c.cgl - hs[jenv]))
487 else:
488 liov_mod.pscal0 = 0.0
489 # J = 2: the start-of-step rates, from the saved model.
490 lirate88(hcomp, hd, ht, m, 2)
491
492 # Flags for CRRECT: LNEW0, a new envelope triangle on the
493 # first iteration; LFINI, converged; LARGE, diverged (Fortran lines 824–829).
494 if nml.lnew0:
495 lnew = True
496 if not lage:
497 delts = -abs(delts)
498 ctol_mod.fcorr = abs(nml.fcorr0) - nml.fcorri
499 itdone = 0
500 large = False
501 lfini = False
502
503 # First guess of the structure (Fortran lines 830–859).
504 if not nml.lnews or delts <= 0.0:
505 for i in range(1, m + 1):
506 htt[i] = 0.0
507 hpp[i] = 0.0
508 ent.htt0[i] = 0.0
509 ent.hpp0[i] = 0.0
510 ent.hll0[i] = 0.0
511 ent.hrr0[i] = 0.0
512 hhc[i] = 0.0
513 else:
514 # Extrapolate from the previous model's rates.
515 for i in range(1, m + 1):
516 dt = ent.htt0[i] * delts
517 dp = ent.hpp0[i] * delts
518 dl = hl[i] * ent.hll0[i] * delts
519 dr = ent.hrr0[i] * delts
520 htt[i] = dt
521 hpp[i] = dp
522 ht[i] = ht[i] + dt
523 hp[i] = hp[i] + dp
524 hl[i] = hl[i] + dl
525 hr[i] = hr[i] + dr
526 hhc[i] = 0.0
527
528 # Level 1: the previous envelope triangle (Fortran lines 864–878).
529 niter = nml.niter1
530 lsbc = False
531 itlvl = 1
532 (lfini, large, lnew, lreset, lsbc, ftri, istore, bl, teffl,
533 latmo, lderiv, lmix, locond, itdone) = _crrect(
534 niter, lsbc, itlvl)
535 if large:
536 continue # go to 15
537
538 # Level 2: check the surface boundary condition (Fortran lines 879–890).
539 lsbc = True
540 niter = nml.niter2
541 itlvl = 2
542 (lfini, large, lnew, lreset, lsbc, ftri, istore, bl, teffl,
543 latmo, lderiv, lmix, locond, itdone) = _crrect(
544 niter, lsbc, itlvl)
545 if large:
546 continue # go to 15
547
548 # Store the rates of change for the next step's guess (Fortran lines 893–900).
549 if delts > 0.0:
550 for ii in range(1, m + 1):
551 ent.htt0[ii] = htt[ii] / delts
552 ent.hpp0[ii] = hpp[ii] / delts
553 ent.hll0[ii] = (2.0 * (hl[ii] - old.hlo[ii])
554 / (hl[ii] + old.hlo[ii]) / delts)
555 ent.hrr0[ii] = (hr[ii] - old.hro[ii]) / delts
556
557 # Level 3 (Fortran lines 902–916).
558 lsbc = False
559 niter = nml.niter3
560 itlvl = 3
561 (lfini, large, lnew, lreset, lsbc, ftri, istore, bl, teffl,
562 latmo, lderiv, lmix, locond, itdone) = _crrect(
563 niter, lsbc, itlvl)
564 if large:
565 continue # go to 15
566 if not nml.lrot:
567 nml.itdif1 = 1
568
569 # With rotation, iterate between structure and rotation
570 # ITDIF1 times from the start-of-step j and composition (Fortran lines 922–939).
571 if nml.itdif1 > 1:
572 for i in range(1, m + 1):
573 hjm0[i] = hjm[i]
574 for j in range(1, 16):
575 hcompp0[j, i] = old.hcompp[j, i]
576 goto15 = False
577 for itrot in range(1, nml.itdif1 + 1):
578 if itrot > 1:
579 for i in range(1, m + 1):
580 for j in range(1, 16):
581 old.hcompp[j, i] = hcompp0[j, i]
582
583 # Level 4: repeats the iteration between mixing and
584 # structure (not for models where semiconvection matters,
585 # where it oscillates; for high-precision work such as
586 # solar models) (7/91) (Fortran lines 940–964).
587 # Question (see the page): what level 4 is for; operator splitting.
588 niter = nml.niter4
589 lsbc = False
590 itlvl = 4
591 (lfini, large, lnew, lreset, lsbc, ftri, istore, bl,
592 teffl, latmo, lderiv, lmix, locond,
593 itdone) = _crrect(niter, lsbc, itlvl)
594 if not lfini:
595 # Not converged: treat as diverged.
596 large = True
597 goto15 = True
598 break
599
600 # Converged: fully mix the convection zones (LIMIX, so that
601 # the correct gradients are used) (G. Somers 6/14) (Fortran lines 975–977).
602 limix = True # noqa: F841 (unused in the Fortran too)
603 mixcz(hcomp, hs2, lc, m)
604
605 # The total age, for disk locking (MHP 9/94); rotation (Fortran lines 981–1010).
606 disk_mod.sage = dage
607 if nml.lrot:
608 if itrot > 1:
609 for i in range(1, m + 1):
610 hjm[i] = hjm0[i]
611 # Print the rotation summary at the final age.
612 if (rl_.lendag[nk] and nml.endage[nk] > 0.0
613 and abs(nml.endage[nk] - dage * 1.0e9
614 - ddage) <= 1.0):
615 lprt0 = True
616 else:
617 lprt0 = False
618 # The new Omega: transport and wind loss.
619 ljdot = nml.ljdot0
620 bl, dwmax, ljdot, jenv0 = getw(
621 bl, delts, dwmax, fp, ft, hcomp, hd, hjm, hl, hp,
622 hr, hs, hs1, hs2, hstot, ht, lc, ljdot, m, smass,
623 teffl, eta2, hg, hi, omega, qiw, r0, jenv0,
624 cmixl, lprt0)
625 # The distortion terms.
626 fpft(hd, hr, hs, m, omega, eta2, fp, ft, hg, r0)
627
628 if goto15:
629 continue # go to 15
630 break
631
632 # The H-burning shell and convection-zone edges again (Fortran lines 1013–1014).
633 jcore, jenv, jxbeg, jxend, jxmid, lshell = findsh(
634 hcomp, hl, lc, m, jcore, jenv, jxbeg, jxend, jxmid, lshell)
635
636 # Light-element burning (with rotational mixing, GETW does it) (Fortran lines 1016–1036).
637 if nml.lexcom and model >= 0 and delts > 0.0:
638 if not nml.lrot or not nml.linstb:
639 jcore, jenv, nrzone, nzone, nzone0 = convec(
640 hcomp, hd, hp, hr, hs, ht, lc, m, mrzone, mxzone,
641 mxzon0, jcore, jenv, nrzone, nzone, nzone0)
642 jenv1 = jenv
643 if nml.lovste:
644 liov_mod.pscal1 = nml.alphae * math.exp(
645 c.clndp * (hp[jenv] + 2.0 * hr[jenv] - hd[jenv]
646 - c.cgl - hs[jenv]))
647 else:
648 liov_mod.pscal1 = 0.0
649 # J = 1: the end-of-step rates, from the new model.
650 lirate88(hcomp, hd, ht, m, 1)
651 liburn(delts, hcomp, hr, hs1, hs2, ht, jenv1, jenv0, m)
652
653 # Restore the earlier fitting point after accretion (MHP 07/02) (Fortran lines 1039–1047).
654 if lnewfit:
655 senvold, sjtot, skerot, m, lnew = getnewenv(
656 senvold, hcomp, hd, hl, hp, hr, hs, hs1, hs2, hstot, ht,
657 lc, eta2, hi, hjm, qiw, r0, hkerot, bl, sjtot, skerot,
658 teffl, m, lnew, cmixl)
659 fpft(hd, hr, hs, m, omega, eta2, fp, ft, hg, r0)
660 lnewfit = False
661
662 # The time step for the next model (HTIMER also locates the
663 # H-burning shell) (Fortran lines 1051–1057).
664 delts = abs(delts)
665 delts0 = delts
666 delts, deltsh, ddage, dwmax = htimer(
667 delts, deltsh, m, hd, hl, hs1, hs2, ht, hcomp, jcore, jxmid,
668 tlumx, dage, ddage, nk, hp, hr, omega, dwmax, jxbeg, teffl)
669
670 # At a fixed final age, write the previous step, floored at 1D-3
671 # of the age (DAGE in Gyr), rather than the clipped last one, so
672 # that the sequence can be continued (Fortran lines 1062–1075).
673 if rl_.lendag[nk] and nml.endage[nk] > 0.0:
674 if nml.endage[nk] - dage * 1.0e9 <= 1.0:
675 delts = max(delts0, 1.0e-3 * dage * 1.0e9 * c.csecyr)
676 ddage = delts / c.csecyr
677 else:
678 delts0 = delts
679 else:
680 delts0 = delts
681
682 # The model number, and the output driver (Fortran lines 1076–1082).
683 if rl_.iresca[nk] != 2:
684 model = model + 1
685 gl, lpunch = wrtout(
686 hcomp, hd, hl, hp, hr, hs, hs1, ht, lc, m, model, dage,
687 ddage, smass, teffl, bl, gl, lshell, jxbeg, jxmid, jxend,
688 jcore, jenv, tlumx, trit, tril, ps, ts, rs, cfenv, ftri,
689 hstot, omega, lpunch, fp, ft, eta2, r0, hjm, hi, sjtot,
690 skerot, hs2, cmixl, xmsol, compmix)
691
692 # Stop conditions (MHP 10/24) (Fortran lines 1087–1115).
693 # Suspected bug (see the page): LENDAG is set only for KINDRN = 1.
694 if (rl_.lendag[nk] and nml.endage[nk] > 0.0
695 and (nml.endage[nk] - dage * 1.0e9) <= 1.0):
696 break # go to 110
697 lend_kind = False
698 if (rl_.lendag[nk] and nml.end_dcen[nk] > 0.0
699 and hcomp[12, 1] < nml.end_dcen[nk]):
700 print(f"CENTRAL D {hcomp[12, 1]:12.4E} BELOW STOP VALUE "
701 f"{nml.end_dcen[nk]:12.4E}") # format 104
702 lend_kind = True
703 if (rl_.lendag[nk] and nml.end_xcen[nk] > 0.0
704 and hcomp[1, 1] < nml.end_xcen[nk]):
705 print(f"CENTRAL X {hcomp[1, 1]:12.4E} BELOW STOP VALUE "
706 f"{nml.end_xcen[nk]:12.4E}") # format 105
707 lend_kind = True
708 if (rl_.lendag[nk] and nml.end_ycen[nk] > 0.0
709 and hcomp[2, 1] < nml.end_ycen[nk]):
710 print(f"CENTRAL Y {hcomp[2, 1]:12.4E} BELOW STOP VALUE "
711 f"{nml.end_ycen[nk]:12.4E}") # format 106
712 lend_kind = True
713 if lend_kind:
714 nml.lpulse = lsavpu
715 sound_mod.lsound = True
716 lprt0 = True
717 break # go to 110
718
719 # Is the model near the desired Teff and L? If not, rescale and
720 # try again (Fortran lines 1117–1126).
721 if nml.lcalst and not lstar:
722 if nk % 2 == 0:
723 if modeln == 1:
724 teffi = 10.0**teffl # noqa: F841 (unused in the Fortran too)
725 else:
726 alri, lstar, lpassr = chkscal(bl, teffl, dage, nk,
727 alri, lstar, lpassr)
728 if lpassr:
729 goto200 = True
730 break # go to 200
731 # label 100 (end of the model loop)
732 if goto200:
733 continue # go to 200
734
735 # Label 110: store the last model in ISTOR if asked (Fortran lines 1133–1138).
736 if nml.lstore and nml.lstpch and lpunch:
737 putstore(hcomp, hd, hl, hp, hr, hs, ht, lc, trit, tril, ps, ts,
738 rs, cfenv, ftri, tlumx, jcore, jenv, model, m, smass,
739 teffl, bl, hstot, dage, ddage, omega, hs1, eta2, r0, fp,
740 ft, hjm, hi, cmixl, xmsol, compmix)
741 lpunch = False
742
743 # The solar calibration, in three kind cards (MHP 1/93, 5/96) (Fortran lines 1144–1183).
744 if nml.lcals:
745 acdpth_mod.ladon = False # calcad off, for speed (JVS)
746 if nk % 3 == 0:
747 rll = (0.5 * (bl + c.clsunl - c.c4pil - c.csigl
748 - 4.0 * teffl) - c.crsunl)
749 # The solar Z/X as an observable (MHP 06/13).
750 solzx = hcomp[3, m] / hcomp[1, m]
751 dldx, drdx, dlda, drda, lsol = chkcal(
752 bl, rll, nk, solzx, dldx, drdx, dlda, drda, lsol)
753 nml.lptime = lptimesv
754 nml.kttau = kttausv
755 if lsol:
756 break # go to 250
757 else:
758 iconv = iconv + 1
759 # Stop after 15 attempts (the Fortran comment still says
760 # 10) (MHP 6/97).
761 if iconv >= 15:
762 break # go to 250
763 if nml.lpulse:
764 # The pulsation output is not final yet: rewind.
765 io.rewind(io.iopmod)
766 io.rewind(io.iopenv)
767 io.rewind(io.iopatm)
768
769 # The star of given Teff and L is matched (Fortran line 1186).
770 if nml.lcalst and lstar and nk % 2 == 0:
771 break # go to 250
772 # label 200
773
774 # Label 250: the solar calibration's summary (Fortran lines 1195–1233).
775 if nml.lcals and nml.lsnu and lsol:
776 for unit in (io.ilast, io.ifirst, io.idebug, io.itrack, io.ishort,
777 io.imodpt, io.istor):
778 io.rewind(unit)
779 ztox = hcomp[3, m] / hcomp[1, m]
780 # Runs needed, initial X and alpha, final dL/dX, dR/dX, dL/dalpha,
781 # dR/dalpha.
782 io.write(io.isnu, f" {iconv:2d}{xguess:10.6f}{aguess:10.6f}"
783 f"{dldx:11.4E}{drdx:11.4E}{dlda:11.4E}"
784 f"{drda:11.4E}") # format 1518
785 # Neutrino fluxes (see ENGEB).
786 io.write(io.isnu, f" {fluxes_mod.clsnu:8.3f}{fluxes_mod.gasnu:8.3f}"
787 + "".join(f"{fluxes_mod.fluxtot[i]:10.3E}"
788 for i in range(1, 11))) # format 1516
789 # Structure: Tc, rho_c, Pc, Xc, Zc.
790 tcen = 10.0**(cent_mod.tcenter - 6.0)
791 pcen = 10.0**(cent_mod.pcenter - 17.0)
792 dcen = 10.0**cent_mod.dcenter
793 io.write(io.isnu, f" {tcen:7.3f}{dcen:7.2f}{pcen:6.3f}"
794 f"{hcomp[1, 1]:8.5f}{hcomp[3, 1]:8.5f}") # format 1517
795 # Initial alpha, Y, Z; final L, R.
796 yini = 1.0 - rl_.rescal[2, nk - 2] - rl_.rescal[3, nk - 2]
797 zini = rl_.rescal[3, nk - 2]
798 io.write(io.isnu, f"{nml.cmixla[nk]:7.4f}{yini:8.5f}{zini:8.5f}"
799 f"{bl:10.3E}{rll:10.3E}") # format 1521
800 # The convection zone's base (R, M), surface Y, Z and Z/X.
801 io.write(io.isnu, f"{cent_mod.czsurf_r:8.5f}{cent_mod.czsurf_m:9.6f}"
802 f"{hcomp[2, m]:8.5f}{hcomp[3, m]:8.5f}"
803 f"{ztox:9.6f}") # format 1522
804 # Energy generation fractions: pp I, II, III, CNO, gravitational.
805 io.write(io.isnu, "".join(f"{tlumx[j]:10.3E}"
806 for j in (1, 2, 3, 4, 7))) # format 1523
807
808 # Fortran line 1235.
809 raise SystemExit # STOP
810
811
812if __name__ == "__main__":
813 main()