1C
2C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
3C SETUPS
4C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
5C MHP 8/25 Passed file names directly instead of through common, as character strings in common blocks can cause problems
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 SETUPS(FALEX06,FALLARD,FATM,FFERMI,
17 * * FLIV95,FPUREZ,FSCVH,FSCVHE,FSCVZ)
18C 10/14/26 MHP via Claude
19C code changed to convert COMMON/SCVEOS/ into SCVEOS_MOD.
20 USE SCVEOS_MOD
21C 10/14/26 MHP via Claude
22C code changed to convert COMMON/FAC/ into FAC_MOD.
23 USE FAC_MOD
24C 10/14/26 MHP via Claude
25C code changed to convert COMMON/DEBHU/ into DEBHU_MOD.
26 USE DEBHU_MOD
27C 10/14/26 MHP via Claude
28C code changed to convert COMMON/COMP/ into COMP_MOD.
29 USE COMP_MOD
30C 10/14/26 MHP via Claude
31C code changed to convert COMMON/CCR/ into CCR_MOD.
32 USE CCR_MOD
33C 10/14/26 MHP via Claude
34C code changed to convert COMMON/ATMOS2C/ into ATMOS2C_MOD.
35 USE ATMOS2C_MOD
36C 10/14/26 MHP via Claude
37C code changed to convert COMMON/ATMOS2/ into ATMOS2_MOD.
38 USE ATMOS2_MOD
39C 10/14/26 MHP via Claude
40C code changed to convert COMMON/ATMOS/ into ATMOS_MOD.
41 USE ATMOS_MOD
42C 10/14/26 MHP via Claude
43C code changed to convert COMMON/NMLPAR/ into NMLPAR_MOD.
44 USE NMLPAR_MOD
45C 10/14/26 MHP via Claude
46C code changed to convert COMMON/CONSTANTS/ into CONSTANTS_MOD.
47 USE CONSTANTS_MOD
48C 10/14/26 MHP via Claude
49C code changed to convert COMMON/IOUNITS/ into IOUNITS_MOD.
50 USE IOUNITS_MOD
51C 10/20/26 MHP via Claude
52C code changed to replace implicit typing with IMPLICIT NONE and
53C explicit declarations.
54 IMPLICIT NONE
55 REAL*8 CBOLTZ,CC,CMELEC,CPLNCK,ELEC,HMASS,HRA
56 INTEGER I,J,K,K1,K2,NCARDS,NG,NGC,NT,NTC,NTS
57 LOGICAL*4 LCATCH
58C JNT 06/14 ADD NTC FOR KURUCZ/CASTELLI 2004 ATM
59 PARAMETER (NT=57,NG=11)
60 PARAMETER (NTC=76,NGC=11)
61 PARAMETER (NTS=63)
62C MHP 8/97 ADDED NTA AND NGA FOR ALLARD ATMOSPHERE
63C DBGLAOL
64
65 INTEGER DUM2, DUM4
66 REAL*8 DUM1, DUM3
67C MHP 8/25 Reduced declared variables to ones actually used here or passed to other routine
68 CHARACTER*256 FALEX06,FALLARD,FATM, FFERMI,FLIV95,
69 * * FPUREZ,FSCVH,FSCVHE,FSCVZ
70C 9/24/26 MHP via Claude
71C code changed to remove dead ILLDAT, IKUR from COMMON/LUNUM/
72C 9/24/26 MHP via Claude
73C code changed to remove dead IDYN from COMMON/LUNUM/
74C 9/25/26 MHP via Claude
75C code changed to consolidate all I/O logical unit numbers, previously
76C scattered across COMMON/LUOUT/, COMMON/LUNUM/, COMMON/ALEX06/,
77C COMMON/ACDPTH/, COMMON/NEWOPAC/, COMMON/LOPAL95/, COMMON/ATMOS2/,
78C COMMON/ALATM03/, COMMON/OPALEOS/, and COMMON/SCV2/, into a single
79C COMMON/IOUNITS/
80C 9/25/26 MHP via Claude
81C code changed to remove dead COMMON/LUNUM/ISCOMP (declared,
82C assigned a unit number, but never opened or read anywhere)
83C MHP 8/25 Removed file names from common block
84c COMMON/LUFNM/ FLAST, FFIRST, FRUN, FSTAND, FFERMI,
85c 1 FDEBUG, FTRACK, FSHORT, FMILNE, FMODPT,
86c 2 FSTOR, FPMOD, FPENV, FPATM, FDYN,
87c 3 FLLDAT, FSNU, FSCOMP, FKUR,
88c 4 FMHD1, FMHD2, FMHD3, FMHD4, FMHD5, FMHD6, FMHD7, FMHD8
89C DBGLAOL
90C MHP 8/25 Removed character file names from common block
91C 9/24/26 MHP via Claude
92C code changed to merge COMMON /MISCOPAC/ and COMMON/NWLAOL/ into
93C COMMON /NEWOPAC/
94C 10/12/26 MHP via Claude
95C code changed to extend COMMON/NMLPAR/ to 234 members, adding the
96C namelist variables that the physics routines read from 27 COMMON
97C blocks which also held derived or working members. Those blocks keep
98C only their non-namelist members; five of them -- NEWMX, VMULT,
99C PMMWIND, CCOUT1 and ENVGEN -- had nothing left and are gone.
100C Derivation-only namelist variables from the same blocks went to
101C COMMON/NMLBYPASS/ instead, not here.
102C
103C Declared identically in all 121 files that hold any of these members.
104C Generated from one member list, so every copy is byte-identical; the
105C linker's 'size of symbol changed' warning is the check that they are.
106C 10/13/26 MHP via Claude: removed the unused COMMON/NEWOPAC/ declaration
107C (no member referenced here; residue of the obsolete-option removals).
108C DBG 7/92 COMMON BLOCK ADDED TO COMPUTE DEBYE-HUCKEL CORRECTION.
109C 9/25/26 MHP via Claude
110C code changed to merge COMMON/CONST/, COMMON/CONST1/, COMMON/CONST2/,
111C and COMMON/CONST3/ into a single COMMON/CONSTANTS/
112C 9/24/26 MHP via Claude
113C code changed to remove dead CMIXL from COMMON/CONST3/; it is now
114C passed as an explicit argument where actually used
115C MHP 8/25 Removed file names from common block
116C JMH 8/18/91
117C COMMON/ATMOS2/ATMPL(NT,NG),ATMTL(NT),
118C * ATMGL(NG),ATMZ,IOATM,FATM
119C JNT 06/14
120C MHP 8/92 COMMON BLOCK ADDED FOR LOWER EDGE OF TABLE IN LOG G.
121C MHP 5/97 ADDED COMMON BLOCK FOR SCV EOS TABLES
122C 10/9/26 MHP via Claude
123C code changed to rename this slot IDT -> IDTSCV: parmin.f and
124C starin.f also declare COMMON/OPTAB/'s own, unrelated IDT, so this
125C slot was called IDTT there as a workaround. Renamed to IDTSCV
126C everywhere COMMON/SCVEOS/ is declared for one consistent name.
127C MHP 8/25 Removed file names from common block
128
129 SAVE
130
131CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
132C SETUP CONSTANTS
133CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
134 CLNDP = DLOG(10.0D0)
135 CLN = CLNDP
136 CLNI = 1.0D0/CLN
137c Luminosity of Sun
138 CLSUNL = DLOG10(CLSUN)
139 CLNSUN = CLN/CLSUN
140c Mass of Sun
141 CMSUN = 1.9891D33
142 CMSUNL = DLOG10(CMSUN)
143C Radius of Sun
144 CRSUNL = DLOG10(CRSUN)
145C Bolometric magnitude of the sun
146 CMBOL = 4.79D0
147C No. of seconds per year and other mathematical constants
148 CSECYR = 3.1558D7
149 CC13 = 1.0D0/3.0D0
150 CC23 = CC13 + CC13
151 CPI = 3.1415926535898D0
152 C4PI = 4.0D0*CPI
153 C4PIL = DLOG10(C4PI)
154 C4PI3L = DLOG10(CC13*C4PI)
155C Speed of Light
156 CC = 2.99792458D10
157C Stefan-Boltzmann constant
158 CSIG = 5.67051D-5
159 CSIGL = DLOG10(CSIG)
160C radiation constant/3
161 CA3 = CSIG*4.0D0/(3.0D0*CC)
162 CA3L = DLOG10(CA3)
163C molar gas constant
164 CGAS = 8.314510D7
165C log of Gravitational constant G=6.67259D-8
166 CGL = -7.17571D0
167C mass of the electron
168 CMELEC = 9.1093897D-28
169c Boltzmann constant
170 CBOLTZ = 1.380658D-16
171c Planck's constant
172 CPLNCK = 6.6260755D-27
173 CMKH = 1.50D0*DLOG10(2.0D0*CPI*CMELEC)+2.5D0*DLOG10(CBOLTZ)-
174 * * 3.0D0*DLOG10(CPLNCK)
175 CDELRL = -C4PI3L - CSIGL - DLOG10(16.0D0)
176 CMIXL2 = CC13
177 CMIXL3 = 16.0D0*DSQRT(2.0D0)*CSIG
178C DBG CALCULATE DEBYE-HUCKEL CONSTAND CDH
179C mass hydrogen atom (gm)
180 HMASS = 1.0D0/6.0222137D23
181C charge electron (ESU)
182 ELEC=4.802D-10
183 CDH = -SQRT(CPI/(CBOLTZ*HMASS*HMASS*HMASS))*ELEC*ELEC*ELEC/3.0D0
184C Electric charge of C,N,O,Ne,Na,Mg,Al,Si,P,S,Cl,Ar,Ca,Ti,Cr,Mn,Fe,Ni
185 DHNUE(1) = 6.0D0
186 DHNUE(2) = 7.0D0
187 DHNUE(3) = 8.0D0
188 DHNUE(4) = 10.0D0
189 DHNUE(5) = 11.0D0
190 DHNUE(6) = 12.0D0
191 DHNUE(7) = 13.0D0
192 DHNUE(8) = 14.0D0
193 DHNUE(9) = 15.0D0
194 DHNUE(10) = 16.0D0
195 DHNUE(11) = 17.0D0
196 DHNUE(12) = 18.0D0
197 DHNUE(13) = 20.0D0
198 DHNUE(14) = 22.0D0
199 DHNUE(15) = 24.0D0
200 DHNUE(16) = 25.0D0
201 DHNUE(17) = 26.0D0
202 DHNUE(18) = 28.0D0
203CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
204C EVALUATE TAU = 2/3 TEMPERATURE FOR HRA
205CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
206 HRAS = HRA(CC23)
207CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
208C SET UP OPACITY TABLES
209CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
210 CALL SETUPOPAC(XENV, FALEX06,
211 * *FLIV95,FPUREZ)
212C
213C
214CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
215C INPUT F-TABLES FOR DEGENERATE EQUATION OF STATE
216CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
217C OPEN DATA FILES
218 OPEN(UNIT=IFERMI,FILE=FFERMI,FORM='FORMATTED',STATUS='OLD')
219 READ(IFERMI,150) (DVAL(I), I = 1,43)
220 READ(IFERMI,150) (ETAT8(I), I = 1,43)
221 READ(IFERMI,160) (I,J,(DTABLE(K,I,J),K=1,5),NCARDS=1,860)
222 150 150 FORMAT(8X,9F8.4)
223 160 160 FORMAT(2I5,5F12.7)
224 REWIND IFERMI
225 K1 = 1
226 DO 180 I=1,41
227C MHP 10/02 SHOULD BE INT(DVAL,ETC.)
228 IF (DVAL(I+1).LE.DVAL(I)) THEN
229C IF (INT(DVAL(I+1)).LE.INT(DVAL(I))) THEN
230 WRITE(ISHORT,1000) I
231 1000 1000 FORMAT(1X,39('>'),40('<')/1X,'ERROR IN SUBROUTINE SETUPS'/
232 * * 1X,'GLITCH IN FERMI TABLE ELEMENT',I4/1X,'RUN STOPPED')
233C 10/30/26 MHP via Claude: bare STOP -> STOP 3, the input-error code (issue 38).
234 STOP 3
235 ENDIF
236 K = INT((DVAL(I+1) - DVAL(I))*20.0D0 + 0.10D0)
237 K2 = K1 + K - 1
238 IF (I.EQ.41) K2 = 261
239 DO 170 J=K1,K2
240 IDEN(J) = I
241 170 170 CONTINUE
242 K1 = K2 + 1
243 180 180 CONTINUE
244
245C CLOSE EQUATION OF STATE FILE.
246 CLOSE(IFERMI)
247C JMH 8/18/91
248CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
249C INPUT PRESSURE TABLE FOR SURFACE BOUNDARY CONDITIONS
250CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
251 IF ((KTTAU .EQ. 3) .OR. (KTTAU .EQ. 4)) THEN
252C OPEN SURFACE PRESSURE TABLE
253 OPEN(IOATM,FILE=FATM, STATUS='OLD')
254C GET ABUNDANCE:
255 READ(IOATM,200) ATMZ
256 200 200 FORMAT(1X,10X,1PE16.8,/)
257C GET VALUES OF LOG Teff:
258 READ(IOATM,201) (ATMTL(I),I=1,NT)
259 201 201 FORMAT(1P4E16.8,13(/1P4E16.8),/1PE16.8,/)
260C GET VALUES OF LOG G:
261 READ(IOATM,202) (ATMGL(I),I=1,NG)
262 202 202 FORMAT(1P4E16.8,/1P4E16.8,/1P3E16.8,/)
263C GET GRID OF LOG PRESSURE VALUES:
264 DO 205 J=1,NT
265 READ(IOATM,203) (ATMPL(J,I),I=1,NG)
266 203 203 FORMAT(1P4E16.8,/1P4E16.8,/1P3E16.8)
267 205 205 CONTINUE
268 REWIND IOATM
269 CLOSE(IOATM)
270C G Somers 5/15; added a catch that allows the code to work
271C if the highest gravity P value for a specific
272C temperature is -999. LCATCH is set to true
273C once the first valid P is read, and it can
274C set the minimum P thereafter.
275 DO J = 1,NT
276 LCATCH = .FALSE.
277 DO K = NG,1,-1
278 IF(ATMPL(J,K).LE.0.0D0)THEN
279C check if the first non-999 value has been reached.
280C if so, set IMIN.
281 IF(LCATCH)THEN
282 IMIN(J) = K + 1
283 GOTO 5
284 ENDIF
285 ELSE
286C if we have reached a non-negative pressure value,
287C turn off the catch so IMIN can be set. also record
288C the highest gravity with a pressure for later int.
289 IF(.NOT.LCATCH) IMINMAX(J) = K
290 LCATCH = .TRUE.
291 ENDIF
292 END DO
293 IMIN(J) = 1
294 5 5 CONTINUE
295C if all of the P values at a given T are -999, set IMIN
296C to the number of gravity terms. in responce, the code
297C should break when trying to find surface P.
298 IF(.NOT.LCATCH) IMIN(J) = NG
299 END DO
300C G Somers 5/15 END
301C MHP 6/97 ADDED OPTION FOR ALLARD MODEL ATMOSPHERES; USED INSTEAD OF
302C KURUCZ FOR TEFF < 10,000 K.
303 IF(KTTAU .EQ. 4)THEN
304C ATMZA = 0.02D0
305 CALL ALFileIn(FALLARD) ! Get Allard Atmospheres files and
306 ENDIF ! initialize tables. 9/23/08 LLP
307
308
309C JNT 6/14 ADD OPTION FOR NEW KURUCZ/CASTELLI ATMOSHPERES
310 ELSE IF (KTTAU .EQ. 5) THEN
311C OPEN SURFACE PRESSURE TABLE
312 OPEN(IOATM,FILE=FATM, STATUS='OLD')
313C GET ABUNDANCE:
314 READ(IOATM,200) ATMZ
315C GET VALUES OF LOG Teff:
316 READ(IOATM,206) (ATMTLC(I),I=1,NTC)
317 206 206 FORMAT(1P4E16.8,18(/1P4E16.8),/)
318C GET VALUES OF LOG G:
319 READ(IOATM,208) (ATMGLC(I),I=1,NGC)
320 208 208 FORMAT(1P4E16.8,/1P4E16.8,/1P3E16.8,/)
321C GET GRID OF LOG PRESSURE VALUES:
322 DO 207 J=1,NTC
323 READ(IOATM,203) (ATMPLC(J,I),I=1,NGC)
324 207 207 CONTINUE
325 REWIND IOATM
326 CLOSE(IOATM)
327C G Somers 5/15; added a catch that allows the code to work
328C if the highest gravity P value for a specific
329C temperature is -999. LCATCH is set to true
330C once the first valid P is read, and it can
331C set the minimum P thereafter.
332 DO J = 1,NTC
333 LCATCH = .FALSE.
334 DO K = NGC,1,-1
335 IF(ATMPLC(J,K).LE.0.0D0)THEN
336C check if the first non-999 value has been reached.
337C if so, set IMIN2.
338 IF(LCATCH)THEN
339 IMIN2(J) = K + 1
340 GOTO 6
341 ENDIF
342 ELSE
343C if we have reached a non-negative pressure value,
344C turn off the catch so IMIN2 can be set. also record
345C the highest gravity with a pressure for later int.
346 IF(.NOT.LCATCH) IMINMAX2(J) = K
347 LCATCH = .TRUE.
348 ENDIF
349 END DO
350 IMIN2(J) = 1
351 6 6 CONTINUE
352C if all of the P values at a given T are -999, set IMIN
353C to the number of gravity terms. in responce, the code
354C should break when trying to find surface P.
355 IF(.NOT.LCATCH) IMIN2(J) = NG
356 END DO
357C END JNT 6/14
358 ENDIF
359
360C 10/13/26 MHP via Claude
361C code changed to read the OPAL 2006 EOS table here, with the other table
362C reads, instead of lazily on the first call to ESAC06. The gate matches
363C the OPEN of IOPALE in parmin.f. This and the SCV read below are
364C independent; a run may use both.
365 IF(lopale06)THEN
366 CALL SETEOS06
367 ENDIF
368C MHP 5/97 ADDED OPTION FOR NEW SCV EQUATION OF STATE TABLES.
369 IF(LSCV)THEN
370 OPEN(UNIT=ISCVH,FILE=FSCVH,STATUS='OLD')
371 OPEN(UNIT=ISCVHE,FILE=FSCVHE,STATUS='OLD')
372 OPEN(UNIT=ISCVZ,FILE=FSCVZ,STATUS='OLD')
373C READ IN EQUATION OF STATE TABLES FOR HYDROGEN AND HELIUM
374 DO I = 1, NTS
375 READ(ISCVH,1) TLOGX(I),NPTSX(I)
376 READ(ISCVHE,1) DUM1,DUM2
377 READ(ISCVZ,1) DUM3,DUM4
378 1 1 FORMAT(F5.2,I4)
379C TABLE GRID POINTS IN T, P(T) ARE THE SAME - NPTSY AND TLOGX
380C READ IN TO RETAIN PARALLEL COMMON BLOCK STRUCTURE.
381 DO J = 1, NPTSX(I)
382 READ(ISCVH,2) (TABLEX(I,J,K),K=1,11)
383 READ(ISCVHE,2) (TABLEY(I,J,K),K=1,11)
384 2 2 FORMAT(F6.2,1P2E13.5,0P,8F9.4)
385 END DO
386C READ IN METAL EQUATION OF STATE TABLE; COMPUTED USING THE PRATHER
387C EQUATION OF STATE IN THE OLD YALE CODE.
388 DO J = NPTSX(I),1,-1
389 READ(ISCVZ,3)(TABLEZ(I,J,K),K=1,13)
390 3 3 FORMAT(F6.2,12F9.4)
391 END DO
392 END DO
393 ENDIF
394
395 RETURN
396 END1"""Python version of setups.f (YREC 7be4133): the one-time setup of a run's
2constants and tables."""
3
4import math
5
6from pyrec import atmos2_mod
7from pyrec import atmos2c_mod
8from pyrec import atmos_mod
9from pyrec import ccr_mod
10from pyrec import comp_mod
11from pyrec import constants_mod
12from pyrec import debhu_mod
13from pyrec import fac_mod
14from pyrec import iounits_mod # ISHORT; Python opens the tables by name
15from pyrec import nmlpar_mod
16from pyrec import scveos_mod
17from pyrec.alfilein import alfilein
18from pyrec.esac06 import seteos06
19from pyrec.hra import hra
20from pyrec.setupopac import setupopac
21
22NT, NG = 57, 11 # the atmosphere grid (KTTAU = 3, 4)
23NTC, NGC = 76, 11 # the Kurucz/Castelli grid (KTTAU = 5)
24NTS = 63 # temperatures of the SCV tables
25
26
27def _fields(line, widths):
28 """Split a fixed-format record into floats (a blank field reads as 0,
29 as in Fortran)."""
30
31 out, pos = [], 0
32 for w in widths:
33 text = line[pos:pos + w].strip()
34 out.append(float(text.replace('D', 'E')) if text else 0.0)
35 pos += w
36 return out
37
38
39def _read_e16(f, n, rows):
40 """Read n values in E16.8 fields, as many per record as `rows` says
41 (formats 201, 202, 203, 206, 208)."""
42
43 values = []
44 for count in rows:
45 values += _fields(f.readline(), [16] * count)
46 return values[:n]
47
48
49def setups(falex06: str, fallard: str, fatm: str, ffermi: str, fliv95: str, fpurez: str, fscvh: str, fscvhe: str,
50 fscvz: str) -> None:
51 """Set the physical constants, then read every table the run needs:
52 opacities (through setupopac), the Fermi-Dirac tables, the
53 model-atmosphere pressure tables, the OPAL 2006 EOS tables and the SCV
54 EOS tables. All results go into modules; nothing is returned.
55
56 Translates: setups.f#SETUPS (7be4133)
57
58 Arguments: the file names of the tables (strings).
59
60 """
61
62 c = constants_mod
63
64 # Setup constants (cgs) (Fortran lines 131–177).
65 c.clndp = math.log(10.0)
66 c.cln = c.clndp
67 c.clni = 1.0 / c.cln
68 c.clsunl = math.log10(c.clsun) # clsun as already set
69 c.clnsun = c.cln / c.clsun
70 c.cmsun = 1.9891e33
71 c.cmsunl = math.log10(c.cmsun)
72 c.crsunl = math.log10(c.crsun) # crsun as already set
73 c.cmbol = 4.79
74 c.csecyr = 3.1558e7
75 c.cc13 = 1.0 / 3.0
76 c.cc23 = c.cc13 + c.cc13
77 c.cpi = 3.1415926535898
78 c.c4pi = 4.0 * c.cpi
79 c.c4pil = math.log10(c.c4pi)
80 c.c4pi3l = math.log10(c.cc13 * c.c4pi)
81 cc = 2.99792458e10 # speed of light (local)
82 c.csig = 5.67051e-5
83 c.csigl = math.log10(c.csig)
84 c.ca3 = c.csig * 4.0 / (3.0 * cc) # radiation constant / 3
85 c.ca3l = math.log10(c.ca3)
86 c.cgas = 8.314510e7
87 c.cgl = -7.17571 # log G, G = 6.67259e-8
88 cmelec = 9.1093897e-28
89 cboltz = 1.380658e-16
90 cplnck = 6.6260755e-27
91 c.cmkh = (1.50 * math.log10(2.0 * c.cpi * cmelec)
92 + 2.5 * math.log10(cboltz) - 3.0 * math.log10(cplnck))
93 c.cdelrl = -c.c4pi3l - c.csigl - math.log10(16.0)
94 c.cmixl2 = c.cc13
95 c.cmixl3 = 16.0 * math.sqrt(2.0) * c.csig
96
97 # The Debye-Hueckel constant CDH (DBG) (Fortran lines 178–183).
98 hmass = 1.0 / 6.0222137e23
99 elec = 4.802e-10
100 debhu_mod.cdh = (-math.sqrt(c.cpi / (cboltz * hmass * hmass * hmass))
101 * elec * elec * elec / 3.0)
102
103 # Charges of C, N, O, Ne, Na, Mg, Al, Si, P, S, Cl, Ar, Ca, Ti, Cr, Mn,
104 # Fe, Ni (Fortran lines 184–202).
105 for k, z in enumerate([6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18,
106 20, 22, 24, 25, 26, 28], start=1):
107 debhu_mod.dhnue[k] = float(z)
108
109 # Temperature at tau = 2/3 of the HRA (Fortran lines 203–206).
110 atmos_mod.hras = hra(c.cc23)
111
112 # Opacity tables (Fortran lines 207–211).
113 setupopac(comp_mod.xenv, falex06, fliv95, fpurez)
114
115 # F-tables for the degenerate equation of state (Fortran lines 214–224).
116 with open(ffermi) as f:
117 for arr in (ccr_mod.dval, ccr_mod.etat8):
118 vals = []
119 while len(vals) < 43: # format 150: 8X,9F8.4
120 line = f.readline()
121 vals += _fields(line[8:], [8] * min(9, 43 - len(vals)))
122 arr[1:44] = vals
123 for ncards in range(1, 861): # format 160: 2I5,5F12.7
124 line = f.readline()
125 # Question (see the page): I and J come from the record and are
126 # used as subscripts at once.
127 i, j = int(line[0:5]), int(line[5:10])
128 ccr_mod.dtable[1:6, i, j] = _fields(line[10:], [12] * 5)
129
130 # The index IDEN of the density bins; the table's density grid must
131 # increase (Fortran lines 225–246).
132 k1 = 1
133 for i in range(1, 42):
134 # Question (see the page): "should be INT(DVAL, etc.)" (MHP 10/02).
135 if ccr_mod.dval[i + 1] <= ccr_mod.dval[i]:
136 iounits_mod.write(iounits_mod.ishort, # format 1000
137 ' ' + '>' * 39 + '<' * 40
138 + '\n ERROR IN SUBROUTINE SETUPS'
139 + f'\n GLITCH IN FERMI TABLE ELEMENT{i:4d}'
140 + '\n RUN STOPPED')
141 raise SystemExit(3)
142 k = int((ccr_mod.dval[i + 1] - ccr_mod.dval[i]) * 20.0 + 0.10)
143 k2 = k1 + k - 1
144 if i == 41:
145 k2 = 261
146 for j in range(k1, k2 + 1):
147 ccr_mod.iden[j] = i
148 k1 = k2 + 1
149
150 # Pressure tables for the surface boundary condition (Fortran lines
151 # 248–307).
152 kttau = nmlpar_mod.kttau
153 if kttau == 3 or kttau == 4:
154 a = atmos2_mod
155 with open(fatm) as f:
156 a.atmz = _fields(f.readline(), [11, 16])[1] # format 200
157 f.readline()
158 a.atmtl[1:NT + 1] = _read_e16(f, NT, [4] * 14 + [1]) # 201
159 f.readline()
160 a.atmgl[1:NG + 1] = _read_e16(f, NG, [4, 4, 3]) # 202
161 f.readline()
162 for j in range(1, NT + 1):
163 a.atmpl[j, 1:NG + 1] = _read_e16(f, NG, [4, 4, 3]) # 203
164 _set_imin(a.atmpl, NT, NG, fac_mod.imin, fac_mod.iminmax, NG)
165 # Allard model atmospheres, below 10,000 K (MHP 6/97).
166 if kttau == 4:
167 alfilein(fallard)
168 elif kttau == 5:
169 # Kurucz/Castelli atmospheres (JNT 6/14) (Fortran lines 309–357).
170 a = atmos2c_mod
171 with open(fatm) as f:
172 atmos2_mod.atmz = _fields(f.readline(), [11, 16])[1] # 200
173 f.readline()
174 a.atmtlc[1:NTC + 1] = _read_e16(f, NTC, [4] * 19) # 206
175 f.readline()
176 a.atmglc[1:NGC + 1] = _read_e16(f, NGC, [4, 4, 3]) # 208
177 f.readline()
178 for j in range(1, NTC + 1):
179 a.atmplc[j, 1:NGC + 1] = _read_e16(f, NGC, [4, 4, 3])
180 # Suspected bug (see the page): an empty row sets IMIN2 to NG, not
181 # NGC.
182 _set_imin(a.atmplc, NTC, NGC, fac_mod.imin2, fac_mod.iminmax2, NG)
183
184 # OPAL 2006 EOS table (Fortran lines 360–367).
185 if nmlpar_mod.lopale06:
186 seteos06()
187
188 # SCV equation-of-state tables (MHP 5/97) (Fortran lines 368–393).
189 if nmlpar_mod.lscv:
190 s = scveos_mod
191 with open(fscvh) as fh, open(fscvhe) as fhe, open(fscvz) as fz:
192 for i in range(1, NTS + 1):
193 line = fh.readline() # format 1
194 s.tlogx[i] = _fields(line, [5])[0]
195 s.nptsx[i] = int(line[5:9])
196 fhe.readline() # dum1, dum2
197 fz.readline() # dum3, dum4
198 widths2 = [6, 13, 13] + [9] * 8 # format 2
199 for j in range(1, s.nptsx[i] + 1):
200 s.tablex[i, j, 1:12] = _fields(fh.readline(), widths2)
201 s.tabley[i, j, 1:12] = _fields(fhe.readline(), widths2)
202 # Metal table (Prather EOS, old Yale code), in reverse order.
203 for j in range(s.nptsx[i], 0, -1): # format 3
204 s.tablez[i, j, 1:14] = _fields(fz.readline(),
205 [6] + [9] * 12)
206
207
208def _set_imin(atmpl, nt, ng, imin, iminmax, ng_empty):
209 """G Somers 5/15: for each temperature j, the range of gravities with a
210 valid pressure: iminmax[j], the highest, and imin[j], the lowest of the
211 contiguous valid run below it (or ng_empty if there is none). Written
212 out twice in the Fortran, for each grid (Fortran lines 270–299 and
213 327–356)."""
214
215 for j in range(1, nt + 1):
216 lcatch = False
217 for k in range(ng, 0, -1):
218 if atmpl[j, k] <= 0.0:
219 if lcatch:
220 imin[j] = k + 1
221 break # to label 5 (6)
222 else:
223 if not lcatch:
224 iminmax[j] = k
225 lcatch = True
226 else:
227 imin[j] = 1
228 if not lcatch:
229 imin[j] = ng_empty