1C$$$$$$
2 SUBROUTINE MCOWIND(BL,DT,HICZ,IT,OMEGAS,SMASS,
3 * * TEFFL,WOLD,WIND1,WIND2)
4C 10/14/26 MHP via Claude
5C code changed to convert COMMON/OVRTRN/ into OVRTRN_MOD.
6 USE OVRTRN_MOD
7C 10/14/26 MHP via Claude
8C code changed to convert COMMON/NMLPAR/ into NMLPAR_MOD.
9 USE NMLPAR_MOD
10C 10/14/26 MHP via Claude
11C code changed to convert COMMON/CONSTANTS/ into CONSTANTS_MOD.
12 USE CONSTANTS_MOD
13C 10/20/26 MHP via Claude
14C code changed to replace implicit typing with IMPLICIT NONE and
15C explicit declarations.
16 IMPLICIT NONE
17 REAL*8 BL,C,DT,FCEN1,FCEN2,FCORR1,FCORR2,FSUN,HICZ,OMEGAS,RL,
18 * * SMASS,STRUCTFACTOR,TCZ,TEFFL,TEMP,WFIRST,WIND1,WIND2,WN,
19 * * WNOW,WOLD,WP,WSAT
20 INTEGER IT
21
22C 9/25/26 MHP via Claude
23C code changed to merge COMMON/CONST/, COMMON/CONST1/, COMMON/CONST2/,
24C and COMMON/CONST3/ into a single COMMON/CONSTANTS/
25C MHP 8/17 ADDED EXCEN, C_2 TO COMMON BLOCK FOR MATT ET AL. 2012 CENT. TERM
26C 10/12/26 MHP via Claude
27C code changed to extend COMMON/NMLPAR/ to 234 members, adding the
28C namelist variables that the physics routines read from 27 COMMON
29C blocks which also held derived or working members. Those blocks keep
30C only their non-namelist members; five of them -- NEWMX, VMULT,
31C PMMWIND, CCOUT1 and ENVGEN -- had nothing left and are gone.
32C Derivation-only namelist variables from the same blocks went to
33C COMMON/NMLBYPASS/ instead, not here.
34C
35C Declared identically in all 121 files that hold any of these members.
36C Generated from one member list, so every copy is byte-identical; the
37C linker's 'size of symbol changed' warning is the check that they are.
38C 10/13/26 MHP via Claude
39C code changed to retire COMMON/CWIND/. Its namelist members moved to the
40C consolidated block earlier, leaving two. C_2 is a constant, set once in
41C parmin.f, so it is now the last member of COMMON/CONSTANTS/ -- appended
42C there rather than inserted, and added to every declaration so the block
43C keeps one size; parmin.f DATA-initializes CLSUN and CRSUN, so a short
44C declaration anywhere would be the OP95INTERP hazard again. It may
45C eventually become a namelist variable. STRUCTFACTOR, the loss-law
46C prefactor, is computed by AMCALC and read by its own two callers,
47C mwind.f and mcowind.f, so it is now an AMCALC output argument.
48C COMMON/CWIND/WMAX,EXMD,EXW,EXTAU,EXR,EXM,CONSTFACTOR,STRUCTFACTOR,LJDOT0
49C MHP 3/09 ADDED OPTION TO SCALE THE SATURATION RATE BY THE OVERTURN TIMESCALE
50C 10/13/26 MHP via Claude: removed the unused COMMON/DEUTER/ declaration
51C (no member referenced here; residue of the obsolete-option removals).
52C G Somers 3/17, ADDING NEW TAUCZ COMMON BLOCK
53C KC 2025-05-30 reordered common block elements
54C COMMON/PMMWIND/AWIND,LMWIND,LROSSBY,LBSCALE,PMMA,PMMB,PMMC,PMMD,PMMM,
55C * PMMJD,PMMMD,PMMSOLP,PMMSOLW,PMMSOLTAU
56C 10/12/26 MHP via Claude
57C code changed to remove the trailing CHARACTER member AWIND from
58C COMMON/PMMWIND/. Character data does not belong in a COMMON block, and
59C this file never referenced AWIND. It is now a local of parmin.f, the
60C only routine that reads it. Being last, its removal moves no other
61C member, and the block shrinks identically in all five files.
62 SAVE
63C COWIND RETURNS THE CHANGE IN THE ANGULAR VELOCITY OF THE SURFACE
64C CONVECTION ZONE OF A STAR WHICH IS EXPERIENCING ANGULAR MOMENTUM LOSS.
65C
66C INPUT VARIABLES:
67C
68C DECLARED
69C BL : TOTAL LUMINOSITY
70C DT : DIFFUSION TIMESTEP.
71C HICZ : TOTAL MOMENT OF INERTIA OF THE SURFACE C.Z.
72C IT : ITERATION NUMBER (IN THE DIFFUSION ROUTINES).
73C OMEGAS : SURFACE ANGULAR VELOCITY AT THE END OF THE PREVIOUS ITERATION.
74C SMASS : STELLAR MASS (SOLAR UNITS)
75C TEFFL : STELLAR EFFECTIVE TEMPERATURE.
76C WOLD : SURFACE ANGULAR VELOCITY AT THE BEGINNING OF THE TIMESTEP.
77C IN COMMON BLOCKS
78C
79C EXMD,EXW,EXTAU,EXR,EXM,FACTOR : USER PARAMETERS WHICH VARY THE STRENGTH
80C OF ANGULAR MOMENTUM LOSS AND ITS DEPENDENCE ON SURFACE ROTATION RATE
81C AND OTHER STELLAR PARAMETERS.
82C
83C OUTPUT VARIABLES
84C
85C WIND1,WIND2:CHANGE IN ANGULAR VELOCITY OF THE SURFACE C.Z. FOR THE TIMESTEP
86C BASED ON THE ANGULAR VELOCITY AT THE BEGINNING AND END OF THE TIMESTEP
87C RESPECTIVELY.
88C
89C WIND1 AND WIND2 ARE INCORPORATED INTO THE DIFFUSION EQUATIONS;
90C THEY ARE AVERAGED TO FIND THE TOTAL ANGULAR MOMENTUM LOSS FOR THE
91C TIMESTEP.
92C
93C RUN OLD WINDLAW IF LMWIND = FALSE
94 IF(.NOT.LMWIND)THEN
95 CALL COWIND(BL,DT,HICZ,IT,OMEGAS,SMASS,
96 * * TEFFL,WOLD,WIND1,WIND2)
97 GOTO 9999
98 ENDIF
99C
100C G Somers 8/17 CREATE ROTATION DUMMY VARIABLES.
101 WFIRST = WOLD
102 WNOW = OMEGAS
103C
104C ADD ROSSBY SCALING TO WMAX = CRITICAL W FOR THE SUN.
105 IF(LROSSBY)THEN
106C MHP 8/17 CORRECTED TAUCZ CALCULATION TO INTERPOLATE PROPERLY IN TIMESTEP
107 TCZ = TAUCZ0+FRACSTEP*(TAUCZ-TAUCZ0)
108 WSAT = WMAX*PMMSOLTAU/TCZ
109C G Somers 08/17 IF ADDING ADDITIONAL B SCALING, ADD ADDITIONAL TAUCZ TERM.
110 IF(LBSCALE)THEN
111 WFIRST = WFIRST*TCZ/PMMSOLTAU
112 WNOW = WNOW*TCZ/PMMSOLTAU
113 WSAT = WSAT*TCZ/PMMSOLTAU
114 ENDIF
115 ELSE
116 WSAT = WMAX
117 ENDIF
118C
119C G Somers 3/17, COMMENTING OUT OLD WIND LAW COEFFICIENT
120C CALCULATION. ADDING NEW PMM-STYLE VERSION
121C
122CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
123C
124C RL=0.5D0*(BL+CLSUNL-C4PIL-CSIGL-4.D0*TEFFL)
125C RTOT = EXP(CLN*RL)
126C DMDOT IS THE MASS LOSS RATE IN SOLAR MASSES PER YEAR.
127C DMDOT = 2.0D-14
128C DJ/DT = DT*FACTOR*(DMDOT/1.0D-14)**EXMD*OMEGA**EXW*(M/MSUN)**EXM
129C *(R/RSUN)**EXR
130C THE CONSTANT AND EXPONENTS ARE SET IN PARMIN BASED ON THE INPUT
131C INDEX ALFA;SEE PARMIN FOR DETAILS ON THE DEPENDENCE OF EACH ON ALFA.
132C C = DT/HICZ*FACTOR*(DMDOT/1.0D-14)**EXMD
133C * *(RTOT/CRSUN)**EXR*SMASS**EXM
134C
135CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
136C
137C NEW CALCULATION. CALL AMCALC TO SET "STRUCTFACTOR"
138C
139 CALL AMCALC(SMASS,BL,TEFFL,STRUCTFACTOR)
140C
141C CALCULATE THE NEW WIND COEFFICIENT.
142C
143 C = (DT/HICZ)*CONSTFACTOR*STRUCTFACTOR
144C MHP 8/17 ADDED CENTRIFUGAL REDUCTION TERM FROM MATT+2012 ApJ 754, L26
145C NOTE THAT THIS IS IMPLEMENTED HERE RELATIVE TO THE SUN
146C C_2 = 0.0506
147C 10/30/26 MHP via Claude
148C code changed to divide by G (CGL). GL was an unset local, so FSUN
149C lacked its 1/G and the solar reference term was ~1.5e7 too small.
150 FSUN = 0.5*PMMSOLW**2*CRSUN**3/EXP(CLN*CGL)/CMSUN
151C RADIUS
152 RL = 0.5D0*(BL+CLSUNL-C4PIL-CSIGL-4.D0*TEFFL)
153 FCORR1 = 0.5*WOLD**2*EXP(CLN*(3.0*RL-CGL))/SMASS/CMSUN
154 FCORR2 = 0.5*OMEGAS**2*EXP(CLN*(3.0*RL-CGL))/SMASS/CMSUN
155 FCEN1 = ((C_2**2+FSUN)/(C_2**2+FCORR1))**EXCEN
156 FCEN2 = ((C_2**2+FSUN)/(C_2**2+FCORR2))**EXCEN
157C
158C G Somers, END
159 WP = MIN(WFIRST,WSAT)
160 WN = MIN(WNOW,WSAT)
161 WIND1 = C*WP**(EXW-1.0D0)*WOLD*FCEN1
162 TEMP = C*WN**(EXW-1.0D0)*OMEGAS*FCEN2
163C WIND1 = C*WP**(EXW-1.0D0)*WOLD
164C TEMP = C*WN**(EXW-1.0D0)*OMEGAS
165 IF(IT.EQ.1) THEN
166 WIND2 = TEMP
167 ELSE
168 WIND2 = 0.5D0*(WIND2+TEMP)
169 ENDIF
170 9999 9999 CONTINUE
171 RETURN
172 END
1"""Python version of mcowind.f (YREC 7be4133): the change in the surface
2convection zone's angular velocity from the newer magnetized-wind law."""
3
4import math
5
6from pyrec import constants_mod
7from pyrec import nmlpar_mod
8from pyrec import ovrtrn_mod
9from pyrec.amcalc import amcalc
10from pyrec.cowind import cowind
11
12
13def mcowind(bl: float, dt: float, hicz: float, it: int, omegas: float, smass: float, teffl: float, wold: float,
14 wind1: float, wind2: float) -> tuple[float, float]:
15 """Return the change in the surface convection zone's angular velocity
16 over a diffusion step from magnetized-wind loss: a saturated power law
17 in Omega, with optional Rossby scaling of the saturation and the
18 centrifugal correction of Matt et al. (2012). With LMWIND false it
19 hands over to the older law, COWIND.
20
21 Translates: mcowind.f#MCOWIND (7be4133)
22
23 Arguments: bl (log L/Lsun), dt (the diffusion step, s), hicz (moment of
24 inertia of the convection zone), it (the iteration), omegas (surface
25 Omega now), smass (M/Msun), teffl (log Teff), wold (surface Omega at
26 the start of the step); wind1 is output only; wind2 is the running
27 mean from the previous iteration (used for it > 1).
28
29 Returns (wind1, wind2): the changes in Omega computed with Omega at the
30 start and at the end of the step.
31
32 """
33
34 c = constants_mod
35 n = nmlpar_mod
36
37 # The old law, if LMWIND is off (Fortran lines 94–98).
38 if not n.lmwind:
39 wind1, wind2 = cowind(bl, dt, hicz, it, omegas, smass,
40 teffl, wold, wind1, wind2)
41 return wind1, wind2 # label 9999
42
43 # The saturation, with Rossby scaling if desired (Fortran lines
44 # 101–117).
45 wfirst = wold
46 wnow = omegas
47 if n.lrossby:
48 # Turnover time interpolated within the step; saturation scaled.
49 tcz = (ovrtrn_mod.taucz0
50 + ovrtrn_mod.fracstep * (ovrtrn_mod.taucz - ovrtrn_mod.taucz0))
51 wsat = n.wmax * n.pmmsoltau / tcz
52 if n.lbscale:
53 # Question (see the page): only the rates in the min() are
54 # scaled.
55 wfirst = wfirst * tcz / n.pmmsoltau
56 wnow = wnow * tcz / n.pmmsoltau
57 wsat = wsat * tcz / n.pmmsoltau
58 else:
59 wsat = n.wmax
60
61 # New calculation: AMCALC sets the structure factor (Fortran line 139).
62 structfactor = amcalc(smass, bl, teffl, 0.0)
63
64 # The new wind coefficient (Fortran line 143).
65 cc = (dt / hicz) * n.constfactor * structfactor
66
67 # Centrifugal correction (Matt et al. 2012) (Fortran lines 150–156).
68 fsun = 0.5 * n.pmmsolw**2 * c.crsun**3 / math.exp(c.cln * c.cgl) / c.cmsun
69 rl = 0.5 * (bl + c.clsunl - c.c4pil - c.csigl - 4.0 * teffl)
70 fcorr1 = 0.5 * wold**2 * math.exp(c.cln * (3.0 * rl - c.cgl)) / smass / c.cmsun
71 fcorr2 = 0.5 * omegas**2 * math.exp(c.cln * (3.0 * rl - c.cgl)) / smass / c.cmsun
72 fcen1 = ((c.c_2**2 + fsun) / (c.c_2**2 + fcorr1))**n.excen
73 fcen2 = ((c.c_2**2 + fsun) / (c.c_2**2 + fcorr2))**n.excen
74
75 # The changes at the start and end of the step; WIND2 averaged with
76 # its previous value (Fortran lines 159–169).
77 wp = min(wfirst, wsat)
78 wn = min(wnow, wsat)
79 wind1 = cc * wp**(n.exw - 1.0) * wold * fcen1
80 temp = cc * wn**(n.exw - 1.0) * omegas * fcen2
81 if it == 1:
82 wind2 = temp
83 else:
84 # Question (see the page): a running half-and-half mean.
85 wind2 = 0.5 * (wind2 + temp)
86 return wind1, wind2