altabinit.f
153 lines · 1 definitions · on GitHub (7be4133)
Python version: altabinit.py, 112 lines, on the right (switch to Python above the code).
Variables on this page (16)
al_tefflmax, al_tefflmin, glmax, glmin, gls, glxmax, glxmin, iglmax, iglmin, ishort, ngl, nteff, pls, tefflmax, tefflmin, teffls
Purpose
This file checks the Allard atmosphere table that ALFILEIN has just read and derives the limits that the lookup ALSURFP needs: the range of $\log T_\mathrm{eff}$, and for each $T_\mathrm{eff}$ row the valid columns in $\log g$ and the allowed range of $\log g$, extrapolation included.
How it fits
- Who calls it: ALFILEIN, at the end of reading.
- What it calls: ALPRINT, to print the table when it is bad.
- Inputs:
ALATM01_MOD(the table). - Outputs:
ALATM02_MOD(GLmin,GLmax,IGLmin,IGLmax,TEFFLmin,TEFFLmax,GLXmin,GLXmax), read by ALSURFP and ALPRINT;ALATM05_MOD(AL_TEFFLmin,AL_TEFFLmax, the table's own first and last $\log T_\mathrm{eff}$), read by SURFBC to decide when to switch away from Allard atmospheres.
The method
With $t_i$ the table's $\log T_\mathrm{eff}$ and $g_j$ its $\log g$ values:
- $t_\mathrm{min} = t_1 - (t_2 - t_1)$ and $t_\mathrm{max} = t_n + (t_n - t_{n-1})$: one row's width beyond each end.
- For each row $i$, the first and last valid columns $j_1(i)$, $j_2(i)$ (entries above $-998$).
-
The allowed range of $\log g$ in each row: $$g_\mathrm{min}(i) = g_{j_1} - 4\,(g_{j_1+1} - g_{j_1}), \qquad g_\mathrm{max}(i) = g_{j_2} + (g_{j_2} - g_{j_2-1}),$$ and the extremes over all rows,
GLXminandGLXmax. -
Validate: no invalid entry between $j_1$ and $j_2$ in any row, at least 4 rows, and at least 4 valid entries per row (4-point Lagrange interpolation needs them). Otherwise print the table and stop. Only
PLsis checked, which is enough: ALFILEIN fillsP100LsandT100Lsfrom the same record asPLs(alfilein.f, lines 334–337↗), and refuses an old-format file, which has no $\tau = 100$ values, whenLALTPTau100asks for them (alfilein.f, lines 156–164↗) (settled from the code, Nov 9, 2026).
Suspected bugs, checked by running the code
Each bug is marked by what running the code showed: (changes results, large) or (small), the fix moving a run clearly beyond a null change; (stops the run); (wrong output), the fix changing only what is written; (harmless in the runs), within the noise; (never occurred), the code ran but the fault did not; (not reached); (cannot be reached), a guard prevents it; (withdrawn), the suspicion was wrong.
1. (never occurred) A format mismatch stops the run with a run-time error.
(lines 119–124↗) The "less than 4 rows" message writes two strings and an integer with format 910, (A,I3), which has only one A: the second string meets I3. With gfortran this is a run-time error ("Expected INTEGER for item 2"), so a table with fewer than 4 rows stops the run there, without the message, ALPRINT's table, and the exit status 3 meant for input errors. Only for a bad table.
A possible fix:
altabinit.f
@@ lines 120–126 @@
LBadTable = .true.
write(ISHORT,910) 'ALTABINIT: Bad input Allard Table: ',
x 'Less than 4 rows: nTeff = ',nTeff
- 910 format(A,I3)
+C 11/09/26 KC via Claude
+C code changed to give format 910 the two strings it is written with.
+ 910 format(2A,I3)
endif
do i = 1, nTeff
j1 = iGLmin(i)
Checked by running YREC (Nov 9, 2026; a line added at each suspected path counted how often it was taken, the outputs otherwise unchanged): The test ran once, in testsuite/Test_solarGS98_allard, the only one of 34 runs (26 of YREC's cases, from a 0.04 $M_\odot$ brown dwarf and the solar models to 9 $M_\odot$, rotation, and helium burning, and 8 made-up ones; one of these, with FCORE = 1.0, stopped in its first second) with the Allard table, with 62 rows and 6 columns; the message was never written. Reading the code, a requested ALATM_FeH that is not in the table (for example $-0.25$ with Nextgen2.all, whose values run from 0 to $-4$) leaves no row and reaches it, after step 1 has read TEFFLs(0) and TEFFLs(-1) (lines 63–64↗); not run. No fix was run. Intent: none found.
2. (never occurred) A row with no valid entry is read out of bounds.
(lines 68–84↗; lines 92–98↗) A row whose PLs are all at $-999$ never sets iGLmin(i), iGLmax(i), which keep 0 (or an earlier table's values); step 3 then reads GLs(j1+1) and GLs(j2-1), GLs(-1) for an unset row, and step 4 (a) reads PLs(i,0), before step 4 (b) rejects the row. A row with one valid entry, in the first column, reads GLs(0). The table is rejected either way; the reads come first. Only for a bad table.
A possible fix:
altabinit.f
@@ lines 66–71 @@
C 2. For each row in GL, find the index of the smallest element (iGLmin) and the index of the
C largest element (iGLmax). There is one pair of these for each TEFFL.
do i = 1, nTeff
+C 11/09/26 KC via Claude
+C code changed to give a row with no valid entry an empty range
+C (iGLmin = 1, iGLmax = 0), which steps 3 and 4 (a) skip and step
+C 4 (b) rejects.
+ iGLmin(i) = 1
+ iGLmax(i) = 0
do j = 1, nGL
if(PLs(i,j) .gt. -998D0) then
iGLmin(i) = j
@@ lines 92–97 @@
do i = 1, nTeff
j1 = iGLmin(i)
j2 = iGLmax(i)
+C 11/09/26 KC via Claude
+C code changed to skip a row with fewer than two valid entries, whose
+C range in GL cannot be set; step 4 (b) rejects it.
+ if(j2 .le. j1) cycle
GLmin(i) = GLs(j1) - 4D0*(GLs(j1+1) - GLs(j1))
if(GLmin(i) .lt. GLXmin) GLXmin = GLmin(i)
GLmax(i) = GLs(j2) + (GLs(j2) - GLs(j2-1))
Checked by running YREC (Nov 9, 2026; a line added at each suspected path counted how often it was taken, the outputs otherwise unchanged): Step 3 ran for each of the 62 rows of the table in testsuite/Test_solarGS98_allard, and no row had fewer than two valid entries. Every row of the three tables in input/atmos/allard/ (Nextgen2.all, AMES-Cond2.all, and AMES-Dusty2.all, every [Fe/H]) holds at least four, read from the files; only a bad table, or the request of alfilein.f, suspected bug 1, would reach it, and neither was run. No fix was run. Intent: none found.
3. (not reached) An empty table is read out of bounds.
(lines 61–64↗; lines 119–124↗; alfilein.f, lines 209–213↗) When no record of the file has the requested ALATM_FeH and ALATM_Alpha, ALFILEIN leaves nTeff at 0 (alfilein.f, line 197↗) and calls ALTABINIT, whose step 1 reads TEFFLs(0) and TEFFLs(-1), outside TEFFLs(NTA), and TEFFLs(1) and TEFFLs(2), never set for this table; with one matching row, it reads TEFFLs(0) and an unset TEFFLs(2). Step 4 (b) rejects the table only later (line 119↗), and the run stops either way (under gfortran, through the format error of suspected bug 1, which writes two strings with a format for one); nothing computed from the reads is used. Only with KTTAU = 4 and an [Fe/H] or $\alpha$ the file does not hold (no case sets ALATM_FeH or ALATM_Alpha; both default to 0, which every table holds).
A possible fix:
altabinit.f
@@ lines 54–59 @@
C it also retires the hazard behind the earlier alfilein.f fix, where a
C mis-indented EXTERNAL was absorbed into this declaration and renamed
C DUMMY4.
+C 11/10/26 KC via Claude
+C code changed to stop, before the range is set from TEFFLs, when the
+C file holds fewer than 4 rows for the requested [Fe/H] and alpha.
+ if(nTeff .lt. 4) then
+ write(ISHORT,'(2A,I3)') 'ALTABINIT: Bad input Allard Table: ',
+ x 'Less than 4 rows: nTeff = ',nTeff
+ goto 9999
+ endif
C 1. Find the minimum (TEFFLmin) and maximum (TEFFLmax) permissable values of TEFFL. These are
C one row's width below the bottom and above the top of the table. Because the first level
Checked by running YREC (Nov 10, 2026; a line added at each suspected path counted how often it was taken, the outputs otherwise unchanged): ALTABINIT ran once in testsuite/Test_solarGS98_allard, with 62 rows and 6 columns, so the reads stayed inside the table: not reached. What would reach it: with KTTAU = 4, an ALATM_FeH absent from the file (with Nextgen2.all, for example $-0.3$ or $+0.3$; with AMES-Dusty2.all, anything but 0) or an ALATM_Alpha other than 0 (not run). The fix was not run, since the condition did not hold. Intent: none found.
Definitions
subroutineALTABINIT
Derives each row's valid range in $\log g$ and the table's range in $\log T_\mathrm{eff}$ (ALATM02_MOD, ALATM05_MOD), checks the table, and stops the run (after ALPRINT) if it is bad.
Uses modules ALATM01_MOD, ALATM02_MOD, ALATM05_MOD, IOUNITS_MOD
Called by ALFILEIN
Compiler warnings (1)
gfortran -Wall -Wextra, compiling only; nothing was run.
- line 41: Unused variable ‘laltptau100’ declared [-Wunused-variable]
Change log
The changes since rp_1
Changed since rp_1. Declarations only: COMMON blocks to modules (/ALATM01/, /ALATM02/, /ALATM05/, /LUOUT/ to IOUNITS_MOD; the unused /ALATM03/ and /ALATM04/ dropped, though a stray declaration of LALTPTau100 remains, unused? (line 41↗)), IMPLICIT NONE.
Changed since a8a5950. The stop on a bad table now exits with status 3, the code for input errors, instead of a bare STOP (KNOWN_ISSUES.md, issue 38).