tauintnew.f
289 lines · 1 definitions · on GitHub (7be4133)
Python version: tauintnew.py, 246 lines, on the right (switch to Python above the code).
Purpose
TAUINTNEW computes the convective overturn time scale $\tau_\mathrm{cz}$ (TAUCZ) and the radius of the base of the convection zone (RBCZ), by the method G. Somers introduced in 3/17. Its comment: search from the centre up for the base of the surface convection zone, and from the surface down; if both agree the zone is unique and the "old top-down sinkline method" is used; if not, several convective cells exist, and the crossing time of the lowest cell in the envelope is taken.
How it fits
- Inputs: the full profile from GETTAU (interior and envelope;
Mpoints, of whichMINTare interior shells):HS1,LCZ,HR,HP,HD,HG,SVEL, andDEL1,DEL2: for interior shells GETTAU passesSDEL(1,·)andSDEL(3,·), the radiative and adiabatic gradients, but for the stitched envelope pointsEDELS(1,·)andEDELS(2,·), the radiative and actual gradients. - Who calls it: only GETTAU, when
LNEWTCZis set; otherwiseGETTAUcalls TAUINT. - What it calls: KSPLINE and KSPLINT, a natural cubic spline through four points.
- Outputs:
TAUCZinOVRTRN_MOD(read by the mass-loss and rotation routines, by their names), and the argumentRBCZin solar radii. - Modules:
OVRTRN_MOD(TAUCZ),CONSTANTS_MOD(CLN,CMSUN,CRSUN),JSONfromDIMENSIONS_MOD.
The method
-
Find the zone. From shell
IBEG(first 1) upward: pass the convective core, if any (its topJCORE, 0 at the start of each call), then the first convective shell above a radiative region isIMAX. From the surface downward, the base of the outermost zone isJMAX: the first pointJbelow a convective pointJ+1that is radiative, plus one, so that radiative points at the surface are passed over (JvS 02/2026; if no such point exists,JMAX= 1). A star with no such zone is radiative ($\tau_\mathrm{cz} = 0$); one convective throughout is fully convective. -
Reject false zones and search again from above: a zone less than one decade in pressure above the core, $\log P(\mathrm{JCORE}) - \log P(\mathrm{IMAX}) < 1$ (unless the profile is the interior only); a zone fewer than 3 shells thick; in the interior-only case with two zones (
IJMAX≠ 0,M = MINT),IMAXis set toJMAX; and, at the end, a result $\tau_\mathrm{cz} > 10^{20}$. For a zone,HSTOP>HSBOT, soLCZSURis always true (lines 137–150↗);HSTOPandHSBOTserve only that test.Nothing bounds the restarts or keeps their tests inside the profile (suspected bug 2).
-
The base: $r_b$ where $\nabla_1 - \nabla_2$ changes sign, by linear interpolation in $\log r$ (for a fully convective star, $\log r_b = 1$: The comment's "very small number" is
RBCZ = 1., thenEXP(CLN*RBCZ), that is 10 cm, harmless next to a star's radius; settled from the code, Nov 9, 2026: lines 157–168↗). -
One zone (
IMAX = JMAX): go up from the base to where $r - r_b = H_p$, with $H_p = P/(\rho g)$. Around that point, four shells give $\delta_k = (r_k - r_b) - H_{p,k}$, and natural cubic splines in $\delta$ evaluated at $\delta = 0$ give $v$ and $H_p$ (the four shellsKK-2toKK+1, withKKkept between 3 andM-1, so that they lie inside the profile); then $$\tau_\mathrm{cz} = \frac{H_p}{v}\bigg|_{\,r - r_b = H_p} .$$ If already atIMAX$r - r_b > H_p$, $\tau_\mathrm{cz} = H_p/v$ there; but the code then goes on to step 5, which replaces it (bug 1). A third spline gives the radius at that point,ENVRCL, which nothing reads (unused?, lines 218–223↗). - Several cells, or $r_b + H_p$ outside the star: the lowest zone's top $r_t$ (again where $\nabla_1 - \nabla_2$ changes sign), its width $\Delta r = r_t - r_b$, and $v$ at its middle, $r_b + \Delta r/2$, from a four-point spline in $r$ (the same limits on
KK): $$\tau_\mathrm{cz} = \frac{\Delta r}{v(r_b + \Delta r/2)} .$$
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 overturn time at IMAX is overwritten.
(lines 176–181↗; lines 229–231↗; lines 235–272↗) When the first convective shell is already more than $H_p$ above the base (VALTEST > 0 at IMAX), the code sets TAUCZ = PSCA/CVEL, but the ENDIF moved on 2025-05-31 to avoid a block mismatch (lines 229–230↗) now closes the IF before label 110, so this branch falls through to the averaging method, which sets TAUCZ = DELR/CVEL instead. Before the move, label 110 was inside the ELSE block and the branch went on past it. On the default path (LNEWTCZ true), for one zone (IJMAX = 0) whose first shell lies more than one scale height above the base, as on a coarse grid.
A possible fix:
tauintnew.f
@@ lines 179–184 @@
CVEL = SVEL(IMAX)
PSCA = PSCA2
TAUCZ = PSCA/CVEL
+C 11/09/26 KC via Claude
+C code changed to skip the averaging method, as the branch did before
+C the ENDIF was moved (2025-05-31).
+ GOTO 140
ELSE
DO K = IMAX+1,M-1,1
PSCA1 = PSCA2
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 the 33 runs no model took the branch at lines 176–181↗, that is, none had its first convective shell more than one pressure scale height above the base of a single zone. The fix was not run. What would reach it: a single surface zone with few shells near its base. Intent: The move is marked "KC 2025-05-31 MOVED ENDIF HERE TO AVOID BLOCK MISMATCH" (lines 229–230↗); it made the jump to label 110 legal, and the fall-through looks like a side effect of the move, not a design.
2. (never occurred) The restarts can read past the profile, and can loop forever.
(line 75↗; lines 115–131↗; lines 284–287↗; lines 92–98↗) The searches restart with GOTO 50 for a zone near the core (lines 115–118↗), a zone thinner than 3 shells (lines 124–131↗), and $\tau_\mathrm{cz} > 10^{20}$ (lines 284–287↗). Each restart raises IBEG, but nothing stops it from passing M, after which LCZ(IBEG) is read beyond the profile (line 75↗), and the 3-shell test reads LCZ(IMAX+2) beyond M when IMAX ≥ M-1, and LCZ(IMAX+1) too when IMAX = M (line 124↗). Past its MM points, GETTAU's array LCF holds values from earlier calls (gettau.f, line 59↗; gettau.f, line 158↗; gettau.f, line 180↗). If such a value is true, the fully convective branch sets I = 1 and JCORE = 1 (lines 92–98↗) and the tests that follow send the search back to IBEG = 2, where it can come round again; and a profile convective at every point, the envelope's surface included, with the envelope stitched (M ≠ MINT) restarts at IBEG = 2 without end, since the near-core test then holds at once, $\log P_1 - \log P_1 = 0 < 1$ (lines 115–118↗). Only on the default path (LNEWTCZ on), for a profile whose only convective shells above the core lie within two points of the surface, or a stitched profile convective at every point, the envelope's surface included.
A possible fix:
tauintnew.f
@@ lines 20–26 @@
REAL*8 CVEL,DD1,DD2,DEL1,DEL2,DELR,ENVRCL,FX,HD,HG,HP,HR,HS1,
* HSBOT,HSTOP,PSCA,PSCA1,PSCA2,RBCZ,RTCZ,RTEST,RTEST1,RTEST2,
* SVEL,VALTEST,XDEL,XRAD,YPSC,YRAD,YSPL,YVEL
- INTEGER I,IBEG,IJMAX,IMAX,ITOP,J,JCORE,JMAX,K,KK,M,MINT
+ INTEGER I,IBEG,IJMAX,IMAX,ITOP,J,JCORE,JMAX,K,KK,M,MINT,NREST
LOGICAL*4 LALLCZ,LCZ,LCZSUR,LRADZONE
C 10/13/26 MHP via Claude: removed the unused COMMON/COMP/ declaration
C (no member referenced here; residue of the obsolete-option removals).
@@ lines 71–78 @@
C is radiative never set JCORE, so the test below read the value left
C from an earlier call (SAVE).
JCORE = 0
+C 11/10/26 KC via Claude
+C code changed to bound the restarts: once IBEG passes M, or after M
+C restarts (a search that comes round again), the search ends as for
+C a radiative envelope (TAUCZ = 0), and LCZ is not read past M.
+ NREST = 0
50 LRADZONE = .TRUE.
- IF (LCZ(IBEG)) LRADZONE = .FALSE.
+ NREST = NREST + 1
+ IF(IBEG.GT.M .OR. NREST.GT.M) IBEG = M+1
+ IF(IBEG.LE.M) THEN
+ IF(LCZ(IBEG)) LRADZONE = .FALSE.
+ ENDIF
DO 60 I = IBEG,M,1
IF (.NOT.LRADZONE.AND..NOT.LCZ(I)) THEN
JCORE = I-1
@@ lines 112–118 @@
C ENSURE THIS CZ IS SUFFICIENTLY FAR FROM THE CONVECTIVE CORE. IN SOME CASES
C THERE ARE A FEW SHELLS RIGHT ABOVE THE CORE THAT ARE CONVECTIVE. SKIP THESE.
C KC 2025-05-30 ADDED IF CHECK TO AVOID RUNTIME ERROR.
- IF (IMAX .GT. 0 .AND. JCORE .GT. 0) THEN
+C 11/10/26 KC via Claude
+C code changed to skip this test for a fully convective model, which
+C has no core: there HP(JCORE)-HP(IMAX) is 0, and with the envelope
+C stitched (M.NE.MINT) the search went back to IBEG = 2 without end.
+ IF (IMAX .GT. 0 .AND. JCORE .GT. 0 .AND. .NOT.LALLCZ) THEN
IF(M.NE.MINT .AND. HP(JCORE)-HP(IMAX).LT.1)THEN
IBEG = IMAX+1
GOTO 50
@@ lines 121–126 @@
C ENSURE THIS CZ IS AT LEAST 3 SHELLS THICK. IF NOT, WE ARE LIKELY SNAGGED
C ON A SINGLE SHELL CONV ZONE DEEP IN THE INTERIOR. RECOMMENSE SEARCH FROM
C ABOVE THIS SHELL.
+C 11/10/26 KC via Claude
+C code changed to treat a zone with fewer than 3 shells below M as thin
+C without reading LCZ past M.
+ IF(IMAX+2.GT.M) THEN
+ IBEG = M+1
+ GOTO 50
+ ENDIF
IF(.NOT.(LCZ(IMAX).AND.LCZ(IMAX+1).AND.LCZ(IMAX+2)))THEN
IF(.NOT.LCZ(IMAX+1))THEN
IBEG = IMAX+1
Checked by running YREC (Nov 10, 2026; a line added at each suspected path counted how often it was taken, the outputs otherwise unchanged): In testsuite/Test_m1p4feh+0p0GS98_dif_TAMS the search restarted 120 times, at IBEG = 298 to 352 in profiles of 407 to 427 points, never more than 20 times in a call; in the other four cases run (testsuite/Test_m1p0feh+0p0GS98_base_TAMS, testsuite/Test_m0p3feh+0p0GS98_base_ZAMS, testsuite/Test_m0p8feh+0p0GS98_rotp8p0d0p1mag1e4std_TAMS, and examples/run_standard_solar_model/Test_solarcal_noGS_norot) it never restarted. IBEG never passed M, and the 3-shell test never had IMAX + 2 > M, so nothing was read past the profile and every search ended. The fix was not run: Its guards never act in these runs, so it changes nothing there. The fully convective testsuite/Test_m0p3feh+0p0GS98_base_ZAMS (LNEWTCZ and LCALCENV on by default) never restarted, presumably because its profile's outermost points are radiative, so that it is not convective at every point; this was not checked. What would reach it: a profile whose only convective shells above the core lie within two points of the surface, or a stitched profile convective at every point, the envelope's surface included. Intent: none found.
Definitions
subroutineTAUINTNEW
The newer overturn time (G. Somers 3/17): finds the base of the main surface convection zone from both directions, then $H_p/v$ one pressure scale height above the base (by four-point splines), or the lowest cell's width over its central velocity; also returns the base's radius in solar units.
Uses modules CONSTANTS_MOD, DIMENSIONS_MOD, OVRTRN_MOD
Called by GETTAU
Flowchart of its calls, in order (8)
Change log
The changes since rp_1
Changed since rp_1. COMMON blocks to modules, IMPLICIT NONE (the unused blocks dropped); the downward search for the base of the outermost zone now requires a convective point above the radiative one (JvS 02/2026), so a radiative layer at the surface no longer makes JMAX = M. No question is settled: question 6 (now the question on a fully convective star) concerns the upward search.
Changed since a8a5950. JCORE starts at 0 in each call, so a model with a radiative centre no longer reads a value left from an earlier call (narrows question 1); the four-point stencils keep KK between 3 and M-1, so they no longer read point M+1 (settles former question 3).