PyREC scaffolding (from YREC development, 7be4133)/ op95ztab.fGlossary

op95ztab.f

126 lines · 1 definitions · on GitHub (7be4133)

Python version: op95ztab.py, 102 lines, on the right (switch to Python above the code).

Variables on this page (8)

cappa, cappa2, numd, numt, numz, nz, ztab, zzg

Purpose

Builds the OPAL95 opacity tables at the model's fixed $Z$ (one table for each of the ten $X$ values) from the full set of tables (MHP 7/98). The result is what OP953D interpolates, and what OP95XTAB reduces further to the surface $X$.

How it fits

  • Inputs: the desired $Z$; the full set in LLOT95A_MOD (ZZG, NZ, CAPPA2).
  • Who calls it: LL95TBL, after reading the tables.
  • What it calls: INTRP2.
  • Output: CAPPA(10,70,19) and ZTAB in LLOT95_MOD, read by OP953D, OP95XTAB, GETOPAL95 and CALCAD.

The method

It finds the four $Z$ values around the desired $Z$ and interpolates each $(T, R)$ entry with Lagrange weights $b_k$, $\log\kappa(X_j, T, R) = \sum_k b_k\,\log\kappa(Z_k, X_j, T, R)$:

  • tables 1–8 (present at every $Z$): directly;
  • table 9 ($X = 0.95$): only if $Z < 0.04$, from four $Z$ values no larger than 0.04 (shifted to 0.01–0.04 if needed); for $Z \ge 0.04$, CAPPA(9,…) keeps old values (zeros at first), which OP95XTAB reads at exactly $Z = 0.04$ (a bug on that page);
  • table 10 ($X = 1 - Z$): only if $Z < 0.1$, from four $Z$ values below 0.1 (shifted to 0.03–0.08 if needed).

The search for the four $Z$ values only accepts a fourth value up to the twelfth, $Z = 0.08$ (the loop runs to NUMZ-1), so any $Z > 0.08$ stops the run ("DESIRED Z … OUTSIDE OP95 TABLE RANGE"), although the comment says "Z > 0.1." The top table, $Z = 0.1$, still enters as the fourth of the four values (bug 1 below).

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. (not reached) The run stops for $0.08 < Z \le 0.1$.

(lines 34–46↗) The search for the four $Z$ values runs only to NUMZ-1, so a fourth value is accepted up to the twelfth, $Z = 0.08$, and any $Z$ between 0.08 and 0.1 stops the run ("DESIRED Z … OUTSIDE OP95 TABLE RANGE"), though the tables reach 0.1 and the comment says only "DESIRED Z > 0.1D0" stops. Taken only when ZOPAL951 is above 0.08 (the routine's only caller, ll95tbl.f, lines 204–206↗).

A possible fix, a choice for the developers: either correct the comment to $Z > 0.08$, or run the loop to NUMZ (with IDZ at most NUMZ-3) and move label 30 after the loop that fills table 10, so that $Z \ge 0.1$ skips that table (suspected bug 2).

Checked by running YREC (Nov 9, 2026; a line added at each suspected path counted how often it was taken, the outputs otherwise unchanged): not reached in any 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 (each one of YREC's cases with a few settings changed), of which one stopped in its first second: No case sets ZOPAL951 above 0.08. What would reach it: ZOPAL951 between 0.08 and 0.1. The fix was not run. Intent: The comment at line 41 ("DESIRED Z > 0.1D0; STOP") gives 0.1 as the limit.

2. (cannot be reached) Label 30 in the wrong place.

(lines 97–124↗) For $Z \ge 0.1$, GOTO 30 is meant to skip table 10 ("OMIT TABLE 10 (X = 1-Z) IF DESIRED Z >= 0.1"), but label 30 stands before the loop that fills table 10, so it would be filled anyway, with IDZ2 and BB left from an earlier call (or never set). Since $Z > 0.08$ stops the run first (the search for the four $Z$ values runs only to NUMZ-1, suspected bug 1), this path is never reached now; it matters only if the limit is raised.

A possible fix:

op95ztab.f

@@ lines 95–100 @@
       END DO
  20   CONTINUE
 C  OMIT TABLE 10 (X = 1-Z) IF DESIRED Z >= 0.1
+C 11/09/26 KC via Claude
+C code changed to put label 30 after the loop that fills table 10, so
+C that table 10 is skipped for Z >= 0.1 as the comment says.
       IF(Z.GE.0.1D0)GOTO 30
 C  CHECK TO ENSURE THAT Z=0.1 TABLE IS NOT ONE OF THE 4 TABLES; ADJUST
 C  INTERPOLATION FACTORS IF NEEDED.
@@ lines 110–116 @@
             BB(I) = B(I)
          END DO
       ENDIF
- 30   CONTINUE
       I1 = NZ(IDZ2)+10
       I2 = NZ(IDZ2+1)+10
       I3 = NZ(IDZ2+2)+10
@@ lines 122–126 @@
      *      BB(4)*CAPPA2(I4,J,K)
          END DO
       END DO
+ 30   CONTINUE
       RETURN
       END

Checked by running YREC (Nov 9, 2026; a line added at each suspected path counted how often it was taken, the outputs otherwise unchanged): not reached in any of the 34 runs, and it cannot be reached at 7be4133: Any $Z$ above 0.08, and so $Z \ge 0.1$, stops the run at lines 41–46↗ before label 30, since the search for the four $Z$ values runs only to NUMZ-1 (suspected bug 1). Intent: The comment at line 97 ("OMIT TABLE 10 (X = 1-Z) IF DESIRED Z >= 0.1") says table 10 is to be skipped.

Definitions

subroutineOP95ZTAB

lines 6–126 · GitHub

Uses modules LLOT95A_MOD, LLOT95_MOD

Called by LL95TBL

Flowchart of its calls, in order (3)
if (ZZG(IDZ+3).GT.0.04D0), lines 73–78
if (ZZG(IDZ+3).GE.0.1D0), lines 101–106

Change log

The changes since rp_1

Changed since rp_1. Declarations only: COMMON blocks to modules (/LLOT95/ to LLOT95_MOD, /LLOT95A/ to LLOT95A_MOD), IMPLICIT NONE (the unused parameters NUMX and NUMXZ dropped).

Changed since a8a5950. The stop for a $Z$ outside the table now exits with status 3, the code for input errors, instead of a bare STOP (KNOWN_ISSUES.md, issue 38). The limit at $Z = 0.08$ stands (bug 1).