1C $$$$$$
2C SUBROUTINE SECULR(DELTS,DT,HD,HG,HI,HL,HP,HR,HS,HS1,HS2,HT,
3C * HJMSAV,LCZ,LC,M,MODEL,OMEGA,
4C * HJM,ETA2,QIW,R0,HCOMP,LFIRST,IMIN,IMAX,
5C * BL,HSTOT,SJTOT,SMASS,TEFFL,LREDO,IREDO, ! KC 2025-05-31
6 SUBROUTINE SECULR(DT,HD,HG,HI,HL,HP,HR,HS,HS1,HS2,HT,
7 * * HJMSAV,LCZ,M,OMEGA,
8 * * HJM,ETA2,QIW,R0,HCOMP,IMIN,IMAX,
9 * * BL,HSTOT,SMASS,TEFFL,LREDO,IREDO,
10 * * HICZ,HSBOT,HSTOP,OMEGAS,LCZSUR,
11C * MRZONE,MXZONE,NRZONE,NZONE, ! KC 2025-05-31
12 * * COD2,HV,LOK,HCOMPS)
13C 10/15/26 MHP via Claude
14C code changed to take JSON from DIMENSIONS_MOD instead of declaring
15C PARAMETER(JSON=5000) here.
16 USE DIMENSIONS_MOD
17C 10/14/26 MHP via Claude
18C code changed to convert COMMON/OLDROT2/ into OLDROT2_MOD.
19 USE OLDROT2_MOD
20C 10/14/26 MHP via Claude
21C code changed to convert COMMON/INTVAR/ into INTVAR_MOD.
22 USE INTVAR_MOD
23C 10/14/26 MHP via Claude
24C code changed to convert COMMON/EGRID/ into EGRID_MOD.
25 USE EGRID_MOD
26C 10/14/26 MHP via Claude
27C code changed to convert COMMON/DISK/ into DISK_MOD.
28 USE DISK_MOD
29C 10/14/26 MHP via Claude
30C code changed to convert COMMON/NMLPAR/ into NMLPAR_MOD.
31 USE NMLPAR_MOD
32C 10/14/26 MHP via Claude
33C code changed to convert COMMON/CONSTANTS/ into CONSTANTS_MOD.
34 USE CONSTANTS_MOD
35C 10/14/26 MHP via Claude
36C code changed to convert COMMON/IOUNITS/ into IOUNITS_MOD.
37 USE IOUNITS_MOD
38C 10/20/26 MHP via Claude
39C code changed to replace implicit typing with IMPLICIT NONE and
40C explicit declarations.
41 IMPLICIT NONE
42 REAL*8 BL,CLTOT,COD,COD2,DBE9,DC12,DC13,DHE3,DJ,DLI7,DN14,DR,DR1,
43 * * DT,DX,ECOD,ECOD2,EI,EJ,EM,ETA2,EW,FACI,HCOMP,HCOMPS,HD,HG,
44 * * HI,HICZ,HJM,HJMP,HJMSAV,HL,HP,HR,HRU,HS,HS1,HS2,HSBOT,
45 * * HSBOTJ,HSTOP,HSTOPJ,HSTOT,HT,HV,OMEGA,OMEGAS,QIW,QWLNR,
46 * * QWRMAX,R0,RLNC,RMID,SMASS,SUMDJ,TEFFL,VFC,WBEG,WIND1,WIND2,
47 * * WSAV
48 INTEGER I,IBEG,ID,IDM,IEND,IMAX,IMAXJ,IMIN,IREDO,ISTART,IT,J,JBEG,
49 * * JEND,JSTART,M
50 LOGICAL*4 LCZ,LCZ1,LCZM,LCZSUR,LDO,LDUM,LDUM2,LFIX,LIMIX,LJDOT,
51 * * LOCK,LOK,LOKAD,LPRT,LREDO,LTEST
52C MHP 6/00 ADDED MRZONE,MXZONE,NRZONE,NZONE FOR BS MIX PLUS BURN
53C 10/13/26 MHP via Claude
54C FACI was COMMON/INTFAC/; seculr.f now owns it and passes it to SETUPV
55C and VCIRC, its only users.
56 DIMENSION FACI(4,JSON)
57C 10/13/26 MHP via Claude
58C VFC was COMMON/VARFC/; seculr.f now owns it and passes it to GETFC and
59C CODIFF.
60 DIMENSION VFC(JSON)
61C 10/13/26 MHP via Claude
62C HCOMPS is now a dummy argument, formerly COMMON/OLDAB/.
63 DIMENSION HCOMPS(15,JSON)
64
65C 10/11/26 MHP via Claude
66C code changed to remove LSCRIB from COMMON/CCOUT/: it was declared
67C positionally in all 17 files sharing this block but never read or
68C written in executable code anywhere, and no namelist file sets it.
69C 10/12/26 MHP via Claude
70C code changed to extend COMMON/NMLPAR/ to 234 members, adding the
71C namelist variables that the physics routines read from 27 COMMON
72C blocks which also held derived or working members. Those blocks keep
73C only their non-namelist members; five of them -- NEWMX, VMULT,
74C PMMWIND, CCOUT1 and ENVGEN -- had nothing left and are gone.
75C Derivation-only namelist variables from the same blocks went to
76C COMMON/NMLBYPASS/ instead, not here.
77C
78C Declared identically in all 121 files that hold any of these members.
79C Generated from one member list, so every copy is byte-identical; the
80C linker's 'size of symbol changed' warning is the check that they are.
81C 10/13/26 MHP via Claude: removed the unused COMMON/CCOUT/ declaration
82C (no member referenced here; residue of the obsolete-option removals).
83C 9/25/26 MHP via Claude
84C code changed to merge COMMON/CONST/, COMMON/CONST1/, COMMON/CONST2/,
85C and COMMON/CONST3/ into a single COMMON/CONSTANTS/
86C MHP 8/17 ADDED EXCEN, C_2 TO COMMON BLOCK FOR MATT ET AL. 2012 CENT. TERM
87C 10/13/26 MHP via Claude: removed the unused COMMON/CWIND/ declaration
88C (no member referenced here; residue of the obsolete-option removals).
89C MHP 6/00 ADDED FLAG FOR CALL TO NDIFCOM
90C 3/92 COMMON BLOCK ADDED FOR CENTERED DW/DLNR.
91C 10/13/26 MHP via Claude: removed the unused COMMON/OLDMOD/ declaration
92C (no member referenced here; residue of the obsolete-option removals).
93C 10/13/26 MHP via Claude: removed the unused COMMON/TEMP2/ declaration
94C (no member referenced here; residue of the obsolete-option removals).
95C 10/13/26 MHP via Claude
96C code changed to replace COMMON/OLDAB/ with an explicit argument: midmod.f
97C fills HCOMPS and seculr.f reads it, both called only from getw.f, which
98C now owns the storage.
99C ADD OPTION FOR VARIABLE FC.
100C 10/13/26 MHP via Claude
101C code changed to replace COMMON/VARFC/ with an explicit argument: seculr.f
102C clears VFC, GETFC fills it and CODIFF reads it, all inside seculr.f's
103C call tree, so seculr.f now owns the storage.
104C 9/25/26 MHP via Claude
105C code changed to consolidate all I/O logical unit numbers, previously
106C scattered across COMMON/LUOUT/, COMMON/LUNUM/, COMMON/ALEX06/,
107C COMMON/ACDPTH/, COMMON/NEWOPAC/, COMMON/LOPAL95/, COMMON/ATMOS2/,
108C COMMON/ALATM03/, COMMON/OPALEOS/, and COMMON/SCV2/, into a single
109C COMMON/IOUNITS/
110C 10/13/26 MHP via Claude
111C code changed to drop COMMON/ROTPRT/, declared here but never used.
112C MHP 9/94 ADDED DISK LOCKING OPTION - FLAG, TIME OVER WHICH LOCKING
113C IS ENFORCED, AND PERIOD AT WHICH LOCKING IS SET ARE OPTIONS.
114C 10/11/26 MHP via Claude
115C BUG FIX: this file reads LCODM and CODM below (the constant
116C diffusion coefficient option) but never declared COMMON/MAG/, so
117C both were uninitialized locals -- LCODM was always .FALSE. and the
118C branch never executed, even though ~101 test/example namelists set
119C LCODM = .TRUE. explicitly. Declaring the block (same layout as
120C codiff.f) makes the namelist values actually arrive here.
121C Time change of theta
122C MHP 3/99 ADDED FLAG TO TREAT THE ENTIRE STAR AS 'CONVECTIVE'
123C FOR ANGULAR MOMENTUM PURPOSES.
124C JNT 09/25 FOR 05/15 ADD IMPJMOD
125 DIMENSION HD(JSON),HI(JSON),HG(JSON),HP(JSON),HS(JSON),
126C * HR(JSON),LC(JSON),OMEGA(JSON),HL(JSON),ETA2(JSON),QIW(JSON), ! KC 2025-05-31
127 * * HR(JSON),OMEGA(JSON),HL(JSON),ETA2(JSON),QIW(JSON),
128 * * HS1(JSON),HS2(JSON),HT(JSON),QWRMAX(JSON),R0(JSON),EM(JSON),
129 * * HJMSAV(JSON),LCZ(JSON),COD(JSON),ECOD2(JSON),
130 * * EI(JSON),EJ(JSON),ECOD(JSON),HRU(JSON),RMID(JSON),
131 * * HV(JSON),QWLNR(JSON),HCOMP(15,JSON),
132 * * HJM(JSON),DJ(JSON),HJMP(JSON),COD2(JSON),WSAV(JSON),EW(JSON),
133 * * ID(JSON)
134C * MRZONE(13,2),MXZONE(12,2)
135 SAVE
136C MHP 6/00 ADDED MRZONE,MXZONE FOR BS MIXING PLUS BURNING
137C SECULR CALCULATES THE TRANSFER OF ANGULAR MOMENTUM(AND THE ASSOCIATED
138C TRANSPORT OF COMPOSITION) DUE TO SECULAR ROTATIONAL INSTABILITIES.
139
140C PRINT OUT DETAILS OF THE DIFFUSION EVERY TIME SHORT OR LONG
141C OUTPUT OF THE MODEL IS GENERATED.
142C
143C G Somers 11/14, EXCLUDE THE IO TO THE FULL FILE. THE CODE
144C WILL NO LONGER REPORT THE CHANGES TO J AT EACH POINT, BECAUSE
145C THIS CAN BE EASILY INFERRED FROM THE EXTENDED SHORT FILE. IF
146C DESIRED, THIS OUTPUT CAN BE RETURNED.
147C IF(.NOT.LPRT0)THEN
148C LPRT = MOD(MODEL+1,NPRTMOD).EQ.0
149C ELSE
150C LPRT = .TRUE.
151C ENDIF
152C IF(.NOT.LSCRIB.OR..NOT.LPRTIN) LPRT = .FALSE.
153 LPRT = .FALSE.
154C 10/29/26 MHP via Claude
155C code changed to clear LREDO on entry. The stable-model exit below
156C (IF(.NOT.LDO) GOTO 9999) returns before CHECKJ or CHECKC can set it,
157C so after a redo the retried sub-step returned the previous attempt's
158C .TRUE., and GETW rewound the clock again although nothing had failed.
159 LREDO = .FALSE.
160C MHP 9/94
161C DISK LOCKING CHECKED
162 LOCK = .FALSE.
163 IF(LDISK .AND. SAGE.LE.TDISK)LOCK = .TRUE.
164C FIRST AND LAST SHELL BOUNDARY CONDITIONS REQUIRE THAT THESE SHELLS BE
165C TREATED AS 'CONVECTIVE' FOR DIFFUSION PURPOSES. FIX THIS.
166 LCZ1 = LCZ(1)
167 LCZM = LCZ(M)
168C SET UP FACTORS USED TO COMPUTE DIFFUSION VELOCITIES.
169C CALL SETUPV(HD,HG,HL,HP,HR,HS1,HT,IMIN,IMAX,LCZ,M,HRU,QWRMAX) ! KC 2025-05-31
170 CALL SETUPV(HD,HG,HL,HP,HR,HS1,HT,IMIN,IMAX,M,HRU,QWRMAX,FACI)
171 CLTOT = CLSUN*HL(M)
172C COMPUTE ANGULAR VELOCITY GRADIENTS
173 DO 10 I = IMIN,IMAX
174C CENTER LOGARITHMIC DERIVATIVE.
175 RLNC = LOG10(RM(I))
176 DR1 = 1.0D0/CLN/(HR(I)-RLNC)+1.0D0/CLN/(RLNC-HR(I-1))
177 QWLNR(I) = 0.25D0*(OMEGA(I)-OMEGA(I-1))*DR1
178C QWLNR(I) = (OMEGA(I)-OMEGA(I-1))/CLN/(HR(I)-HR(I-1))
179 10 10 CONTINUE
180 CALL GETQUA(HD,HG,HRU,OMEGA,M)
181 DO I = 1,M
182 VFC(I) = 0.0D0
183 END DO
184C CHECK STABILITY OF THE MODEL AND COMPUTE CIRCULATION VELOCITIES.
185C MECHANISMS CONSIDERED:SECULAR AND DYNAMICAL SHEAR,EDDINGTON CIRCULATION,
186C AND THE GSF INSTABILITY.
187 IT = 1
188C MHP 06/02 added timestep to call
189C CALL VCIRC(HJM,HR,HRU,IMIN,IMAX,IT,LCZ,M,OMEGA,LDO,QWLNR, ! KC 2025-05-31
190 CALL VCIRC(HR,HRU,IMIN,IMAX,IT,LCZ,M,OMEGA,LDO,QWLNR,
191 * * QWRMAX,HV,CLTOT,DT,HP,FACI)
192 IF(LVFC) CALL GETFC(HD,HRU,HV,IMIN,IMAX,OMEGA,VFC)
193C STORE INITIAL ANGULAR MOMENTUM DISTRIBUTION.
194 DO 20 I =1,M
195 HJMP(I) = HJMSAV(I)
196 WSAV(I) = OMEGA(I)
197 20 20 CONTINUE
198C STORE INITIAL SURFACE ANGULAR VELOCITY FOR USE IN ANGULAR MOMENTUM
199C LOSS CALCULATIONS.
200C WBEG = OMEGA(M)
201 WBEG = WMST(M)
202 LOK = .FALSE.
203C ON THE FIRST LEVEL OF ITERATION, THE UNPERTURBED MODEL IS USED TO
204C CALCULATE THE DIFFUSION VELOCITIES. ON THE SECOND AND SUBSEQUENT
205C ITERATIONS, THE ANGULAR MOMENTUM DISTRIBUTION FROM THE PREVIOUS
206C ITERATION IS USED TO GET THE VELOCITIES. THIS 'NEW' VELOCITY IS THEN
207C AVERAGED WITH THE VELOCITY FOUND IN THE PREVIOUS ITERATION TO GET A
208C CORRECTED V AND THUS A MORE ACCURATE RUN OF DIFFUSION COEFFICIENTS.
209 DO 100 IT = 1,ITDIF2
210 OMEGAS = OMEGA(M)
211 IF(IT.GT.1)THEN
212C COMPUTE NEW RUN OF ANGULAR VELOCITIES (AVERAGE OF INITIAL AND
213C LATEST VALUES).
214 DO I = 1,M
215 OMEGA(I) = 0.5D0*(OMEGA(I)+WSAV(I))
216 END DO
217C COMPUTE NEW RUN OF ANGULAR VELOCITY GRADIENTS.
218 DO 30 I = IMIN,IMAX
219C CENTER LOGARITHMIC DERIVATIVE.
220 RLNC = LOG10(RM(I))
221 DR1 = 1.0D0/CLN/(HR(I)-RLNC)+1.0D0/CLN/(RLNC-HR(I-1))
222 QWLNR(I) = 0.25D0*(OMEGA(I)-OMEGA(I-1))*DR1
223C QWLNR(I) = (OMEGA(I)-OMEGA(I-1))/CLN/(HR(I)-HR(I-1))
224 30 30 CONTINUE
225C ON 2ND AND SUBSEQUENT ITERATIONS,COMPUTE CHARACTERISTIC VELOCITIES
226C FOR THE NEW RUN OF OMEGA AND COMPOSITION FOUND IN THE PREVIOUS
227C ITERATION.
228C MHP 06/02 added pressure and timestep to call
229C CALL VCIRC(HJM,HR,HRU,IMIN,IMAX,IT,LCZ,M,OMEGA,LDO,QWLNR, ! KC 2025-05-31
230 CALL VCIRC(HR,HRU,IMIN,IMAX,IT,LCZ,M,OMEGA,LDO,QWLNR,
231 * * QWRMAX,HV,CLTOT,DT,HP,FACI)
232 IF(LVFC) CALL GETFC(HD,HRU,HV,IMIN,IMAX,OMEGA,VFC)
233C NOW THAT THE NEW DIFFUSION VELOCITIES HAVE BEEN COMPUTED, RESET THE
234C ANGULAR MOMENTUM AND COMPOSITION ARRAYS TO THEIR ORIGINAL VALUES.
235 DO 50 I = 1,M
236 HJM(I) = HJMSAV(I)
237 DO 40 J = 1,4
238 HCOMP(J,I) = HCOMPS(J,I)
239 40 40 CONTINUE
240 50 50 CONTINUE
241C MHP 10/91 CHANGED TO REMIX CZ'S TO THEIR PROPER DEPTH!
242C OTHERWISE, DRASTIC ERRORS OCCUR IN THE PRESENCE OF A DEEPENING CZ
243C (THE LOCAL ABUNDANCE AT THE CZ BASE PRIOR TO THE DEEPENING OF THE
244C CZ IS ASSIGNED TO THE WHOLE CZ - X AND HE3 ONLY, AND ONLY FOR A
245C CZ WHICH IS BECOMING DEEPER.)
246C ENSURE THAT CONVECTIVE REGIONS ARE FULLY MIXED.
247C JVS 0212 CALL MIXCZ(HCOMP,HS2,LCZ,M)
248C KC 2025-05-30 addressed warning messages from Makefile.legacy
249C C G Somers 6/14, SET IMIX = .FALSE. SO THE CORRECT GRADS ARE USED.
250C IMIX = .FALSE.
251C CALL MIXCZ(HCOMP,HS2,HS1,LCZ,HR,HP,HD,HG,M,IMIX)
252C G Somers 6/14, SET LIMIX = .FALSE. SO THE CORRECT GRADS ARE USED.
253 LIMIX = .FALSE.
254C CALL MIXCZ(HCOMP,HS2,HS1,LCZ,HR,HP,HD,HG,M,LIMIX) ! KC 2025-05-31
255 CALL MIXCZ(HCOMP,HS2,LCZ,M)
256C G Somers END
257 ENDIF
258C CALCULATE LOSS OF ANGULAR MOMENTUM DUE TO WIND FOR AN
259C ISOLATED SURFACE C.Z.(NO COUPLING WITH INTERIOR VIA DIFFUSION).
260 IF(LCZSUR.AND.HV(IMAX).EQ.0.0D0 .AND. .NOT.LOCK)THEN
261C FIND MOMENT OF INERTIA OF THE SURFACE C.Z.
262 HICZ = 0.0D0
263 DO 55 I = IMAX,M
264 HICZ = HICZ + HI(I)
265 55 55 CONTINUE
266 LJDOT = LJDOT0
267C MHP 10/02 UNUSED LFIRST REMOVED FROM CALL
268 CALL MWIND(BL,DT,HSBOT,HSTOP,IMAX,M,LJDOT,OMEGAS,
269C * SJTOT,SMASS,TEFFL,HICZ,HJM,LFIRST) ! KC 2025-05-31
270 * * SMASS,TEFFL,HICZ,HJM)
271C REMOVE TORQUE FROM ENTIRE STAR
272C JNT 09/25 FOR 05/15 IMPJMOD=1 SAME AS LSOLID
273 ELSE IF(LCZSUR .AND. (LSOLID .OR. (IMPJMOD.EQ.1)))THEN
274 LJDOT = LJDOT0
275 HSBOTJ = 0.0D0
276 HSTOPJ = EXP(CLN*HSTOT)
277 IMAXJ = 1
278 CALL MWIND(BL,DT,HSBOTJ,HSTOPJ,IMAXJ,M,LJDOT,OMEGAS,
279C * SJTOT,SMASS,TEFFL,HICZ,HJM) ! KC 2025-05-31
280 * * SMASS,TEFFL,HICZ,HJM)
281C WRITE(*,*)HJM(1),HJM(M)
282 JSTART = 1
283 JEND = M
284 CALL SOLID(HD,HJM,HR,HS,HS2,JSTART,JEND,ETA2,HI,OMEGA,
285 * * QIW,R0,M)
286C WRITE(*,*)OMEGA(1),OMEGA(M)
287 ENDIF
288C IF LDO=F,NO INSTABILITIES OCCUR (STABLE AGAINST ALL MECHANISMS).
289 IF(.NOT.LDO) GOTO 9999
290C TREAT CENTRAL AND SURFACE ZONES AS ALWAYS CONVECTIVE
291C (SHOULD BE FIXED TO GIVE BETTER CENTRAL/SURFACE B.C.)
292 LCZ(1) = .TRUE.
293 LCZ(M) = .TRUE.
294C UNSTABLE REGION EXISTS.
295C FIND DIFFUSION COEFFICIENTS(COD) FOR ALL UNSTABLE REGIONS.
296C CALL CODIFF(DELTS,HRU,HV,IMIN,IMAX,LC,LCZ,M,RMID,COD,COD2) ! KC 2025-05-31
297 CALL CODIFF(HRU,M,RMID,COD,COD2,VFC)
298C EACH UNSTABLE REGION IS SOLVED SEPARATELY STARTING HERE.
299C LTEST IS SET T IF A NON-ZERO VELOCITY IS ENCOUNTERED.
300C IBEG IS THE ZONE BELOW THE FIRST NON-ZERO V;IEND IS THE ZONE ABOVE
301C THE LAST NON-ZERO V.
302 LDUM = .FALSE.
303 ISTART = IMIN
304 60 60 CONTINUE
305 LTEST = .FALSE.
306C MHP 8/13 TREAT ENTIRE DOMAIN AS UNSTABLE IF A CONSTANT DIFFUSION
307C COEFFICIENT IS BEING ADDED
308 IF(LCODM.AND.CODM.GT.0.0D0)THEN
309 LTEST = .TRUE.
310 IBEG = IMIN - 1
311 IEND = IMAX
312 ISTART = IMAX + 1
313 GOTO 80
314 ENDIF
315 DO 70 J = ISTART,IMAX
316 IF(HV(J).GT.0.0D0) THEN
317 LTEST = .TRUE.
318 IF(.NOT.LDUM) THEN
319C START OF UNSTABLE REGION
320 LDUM = .TRUE.
321 IBEG = J - 1
322 ENDIF
323 ELSE IF(LDUM) THEN
324C END OF UNSTABLE REGION
325 IEND = J - 1
326 LDUM = .FALSE.
327 ISTART = J + 1
328 GOTO 80
329 ENDIF
330 70 70 CONTINUE
331C IF THE LAST INTERFACE IS UNSTABLE (NON-ZERO V) ENSURE THAT IEND IS SET
332C PROPERLY.
333 IF(LDUM) IEND = IMAX
334 ISTART = IMAX + 1
335 80 80 CONTINUE
336C IF NO NON-ZERO V'S ENCOUNTERED, EXIT.
337 IF(.NOT.LTEST) GOTO 90
338C MHP 08/03 REMOVED OBSOLETE EQUAL ROUTINE
339C IF(M.GT.1)THEN
340C TRANSFORM TO EQUAL GRID SPACING IN CHI FOR THE REGION.
341C CHI IS A NORMALIZED SUM OF THE VARIABLES USED TO PLACE POINTS
342C IN THE HENYEY SCHEME, CHOSEN SUCH THAT THE GRID USED IN THE
343C ANGULAR MOMENTUM EVOLUTION IS CLOSE TO THE GRID STORED FOR
344C THE STRUCTURAL EVOLUTION.
345 CALL ROTGRID(COD,COD2,HD,HI,HJMSAV,HL,HP,HR,HRU,HS,HS1,HS2,
346 * * HSTOT,IBEG,IEND,LCZ,M,WSAV,DR,ECOD,
347 * * ECOD2,EI,EJ,EM,EW,LDUM2)
348C ELSE
349C CALL EQUAL(BL,COD,COD2,HD,HI,HJMSAV,HRU,HS,HS1,HS2,HSTOT,
350C * IBEG,IEND,LCZ,M,TEFFL,DR,ECOD,ECOD2,EI,EJ,
351C * EM,ES1,EW,WSAV,LDUM2,NTOT)
352C ENDIF
353C LDUM2=T IF TWO C.Z.'S ARE SEPARATED BY ONE RADIATIVE ZONE;
354C SKIP IF THIS OCCURS.
355 IF(LDUM2) THEN
356 IF(ISTART.LE.IMAX) THEN
357 GOTO 60
358 ELSE
359 GOTO 90
360 ENDIF
361 ENDIF
362C MHP 3/09 SKIP ANGULAR MOMENTUM EVOLUTION FOR SOLID BODY MODELS
363C JNT 09/25 FOR 05/15 IMPJMOD=1 IS THE SAME AS LSOLID
364 IF(.NOT.LSOLID .AND. (IMPJMOD.NE.1))THEN
365C CHECK IF SURFACE C.Z. IS PART OF THE UNSTABLE REGION.
366C IF SO,CALCULATE TERMS FOR DIFFUSION.
367 IF(LCZSUR.AND.IEND.EQ.IMAX)THEN
368 IF(LOCK)THEN
369 WIND1 = 0.0D0
370 WIND2 = 0.0D0
371 LFIX = .TRUE.
372 ELSE
373 LFIX = .FALSE.
374 IF(LJDOT0)THEN
375 HICZ = EI(NTOT)
376 OMEGAS = OMEGA(M)
377 CALL MCOWIND(BL,DT,HICZ,IT,OMEGAS,SMASS,
378 * * TEFFL,WBEG,WIND1,WIND2)
379 ELSE
380 WIND1 = 0.0D0
381 WIND2 = 0.0D0
382 ENDIF
383 ENDIF
384 ELSE
385 LFIX = .FALSE.
386 WIND1 = 0.0D0
387 WIND2 = 0.0D0
388 ENDIF
389 LOKAD = .FALSE.
390 IF(.NOT.LDIFAD)THEN
391C SET UP DIFFUSION EQUATION ARRAYS TO SOLVE FOR OMEGA AT END OF TSTEP
392 CALL DCOEFT(ECOD,DR,DT,EI,EJ,EW,NTOT,WIND1,WIND2,LFIX)
393C SOLVE MATRIX FOR THE RUN OF OMEGA AT THE END OF THE TIMESTEP AT THE
394C EQUALLY SPACED GRID POINTS.
395C CALL TRIDIA(NTOT,EI,EJ,DJ,SUMDJ) ! KC 2025-05-31
396 CALL TRIDIA(NTOT,EI,DJ,SUMDJ)
397C TRANSFORM THE NEW ANGULAR MOMENTUM DISTRIBUTION BACK TO THE ORIGINAL GRID
398C POINTS IN THE UNSTABLE REGION.
399 ELSE
400C SOLVE FOR OMEGA AND ITS DERIVATIVES IN A BAND MATRIX
401C CALL DADCOEFT(DR,DT,EI,EJ,EW,NTOT,WIND1,WIND2,DJ, ! KC 2025-05-31
402 CALL DADCOEFT(DR,DT,EI,EW,NTOT,WIND1,WIND2,DJ,
403 * * ECOD2,SUMDJ,LFIX,LOKAD)
404 ENDIF
405C MHP 08/03 REMOVED OBSOLETE EQUAL2 ROUTINE
406C IF(M.GT.1)THEN
407C TRANSFORM BACK TO THE ORIGINAL GRID
408 CALL EQ2MOD(DJ,EJ,HS2,IBEG,IEND,LCZ,M,SUMDJ,HJM)
409C ELSE
410C CALL EQUAL2(DJ,EJ,EM,ES1,HS1,IBEG,IEND,LCZ,M,NTOT,HJM)
411C ENDIF
412C PERFORM COMPOSITION DIFFUSION.
413C UNTIL THE FINAL ITERATION, ONLY COMPOSITION DIFFUSION OF SPECIES WHICH
414C AFFECT GRADIENTS IN MEAN MOLECULAR WEIGHT IS COMPUTED (H,HE3,HE4).
415C ON THE FINAL ITERATION, DIFFUSION OF ALL SPECIES IS PERFORMED.
416C MHP 08/03 REMOVED OBSOLETE DIFCOM ROUTINE
417C IF(M.GT.1)THEN
418 ENDIF
419 JBEG = 1
420 JEND = 4
421 CALL NDIFCOM(DT,COD2,ECOD2,EM,HD,HL,HP,HR,HS,HS1,HS2,
422C * HSTOT,HV,IBEG,IEND,IMAX,IMIN,LCZ,LOK,M,NTOT, ! KC 2025-05-31
423 * * HSTOT,HV,IBEG,IEND,IMAX,IMIN,LCZ,LOK,M,
424 * * HCOMP,JBEG,JEND)
425C ELSE
426C CALL DIFCOM(DR,DT,COD2,ECOD2,EM,ES1,HRU,HS,HS1,HS2,HV,
427C * IBEG,IEND,IMIN,LCZ,LOK,M,NTOT,HCOMP)
428C ENDIF
429C RETURN FOR NEXT REGION IF APPLICABLE
430 IF(ISTART.LE.IMAX) GOTO 60
431 90 90 CONTINUE
432C CHECK SOLUTION,UPDATE OMEGA,AND SEE IF ANOTHER ITERATION IS NEEDED.
433 LCZ(1) = LCZ1
434 LCZ(M) = LCZM
435C mhp 10/02 unused ecod, ecod2 no longer passed
436C WRITE(*,*)LSOLID,OMEGA(1),OMEGA(M)
437 CALL CHECKJ(HD,HJMP,HJMSAV,HR,HS,HS2,HV,IMIN,IMAX,IT,LCZ,
438C * LPRT,M,DT,ETA2,HI,HJM,IREDO,LOK,LREDO,OMEGA,QIW,R0, ! KC 2025-05-31
439 * * M,DT,ETA2,HI,HJM,IREDO,LOK,LREDO,OMEGA,QIW,R0,
440 * * WSAV,ID,IDM,LOKAD)
441C * WSAV,ID,IDM,ECOD,ECOD2,LOKAD)
442C WRITE(*,*)OMEGA(1),OMEGA(M)
443C CHECK COMPOSITION DIFFUSION AND RECOMPUTE MEAN MOLECULAR WEIGHT.
444 IF(.NOT.LREDO)CALL CHECKC(HCOMP,IT,LPRT,M,DT,IREDO,LOK,LREDO)
445C MHP 9/93
446 IF(LNOJ)LOK = .TRUE.
447C IF LOK=T,CONVERGED.
448 IF(LOK)GOTO 200
449C IF LREDO=T, A PROBLEM REQUIRES TIMESTEP CUTTING.
450 IF(LREDO)GOTO 9999
451 100 100 CONTINUE
452 LOK = .TRUE.
453 200 200 CONTINUE
454C PERFORM COMPOSITION DIFFUSION OF REMAINING SPECIES.
455 LCZ(1) = .TRUE.
456 LCZ(M) = .TRUE.
457C MHP 6/00 ADDED OPTION OF BS EXTRAPOLATION FOR HE3, CNO
458C LBSMIX=.TRUE.
459C IF(LBSMIX)THEN
460C CALL BSCOMP(DR,DT,COD2,ECOD2,EM,ES1,HRU,HS,HS1,HS2,
461C * IBEG,IEND,IMIN,LCZ,LOK,M,NTOT,HCOMP,HV,
462C * HD,HP,HR,HT,MRZONE,MXZONE,NRZONE,NZONE,HSTOT)
463C ELSE
464C MHP 08/03 REMOVED OBSOLETE DIFCOM ROUTINE
465C IF(M.GT.1)THEN
466 JBEG = 5
467 IF(LEXCOM)THEN
468 JEND = 15
469 ELSE
470 JEND = 11
471 ENDIF
472 CALL NDIFCOM(DT,COD2,ECOD2,EM,HD,HL,HP,HR,HS,HS1,HS2,
473C * HSTOT,HV,IBEG,IEND,IMAX,IMIN,LCZ,LOK,M,NTOT, ! KC 2025-05-31
474 * * HSTOT,HV,IBEG,IEND,IMAX,IMIN,LCZ,LOK,M,
475 * * HCOMP,JBEG,JEND)
476C ELSE
477C CALL DIFCOM(DR,DT,COD2,ECOD2,EM,ES1,HRU,HS,HS1,HS2,HV,
478C * IBEG,IEND,IMIN,LCZ,LOK,M,NTOT,HCOMP)
479C ENDIF
480C MHP 6/00
481 LCZ(1) = LCZ1
482 LCZ(M) = LCZM
483C ADD I/O FOR MIXING.
484 IF(LPRT)THEN
485C MHP 8/03 ADDED HEADER LINE.
486 WRITE(IMODPT,198)
487 198 198 FORMAT('COMPOSITION CHANGE FROM ROTATIONAL MIXING'/
488 * * 5X,'H',8X,'HE3',7X,'C12',7X,'C13',7X,'N14',
489 * * 7X,'LI7',7X,'BE9')
490 DO I = 1,IDM
491 DX = HCOMP(1,ID(I))-HCOMPS(1,ID(I))
492 DHE3 = HCOMP(4,ID(I))-HCOMPS(4,ID(I))
493 DC12 = HCOMP(5,ID(I))-HCOMPS(5,ID(I))
494 DC13 = HCOMP(6,ID(I))-HCOMPS(6,ID(I))
495 DN14 = HCOMP(7,ID(I))-HCOMPS(7,ID(I))
496 DLI7 = HCOMP(14,ID(I))-HCOMPS(14,ID(I))
497 DBE9 = HCOMP(15,ID(I))-HCOMPS(15,ID(I))
498 WRITE(IMODPT,199)ID(I),DX,DHE3,DC12,DC13,DN14,DLI7,DBE9
499 199 199 FORMAT(I5,1P7E10.3)
500 END DO
501 ENDIF
502 9999 9999 CONTINUE
503C MHP 8/03 - OMITTED I/O, COULD REINTRODUCE IN ANOTHER FILE
504C DETERMINE COUPLING FACTOR (I.E. THE FRACTION OF THE TOTAL ANGULAR
505C MOMENTUM LOST FROM THE CORE RELATIVE TO ITS FRACTION OF THE TOTAL
506C MOMENT OF INERTIA).
507C DJCORE = 0.0D0
508C HICORE = 0.0D0
509C HJTOT = 0.0D0
510C DO I = 1,IMAX-1
511C DJCORE = DJCORE + (HJM(I)-HJMSAV(I))*HS2(I)
512C HICORE = HICORE + HI(I)
513C HJTOT = HJTOT + HJM(I)*HS2(I)
514C END DO
515C HIENV = 0.0D0
516C DJENV = 0.0D0
517C DO I = IMAX,M
518C DJENV = DJENV + (HJM(I)-HJMSAV(I))*HS2(I)
519C HIENV = HIENV + HI(I)
520C HJTOT = HJTOT + HJM(I)*HS2(I)
521C END DO
522C FI = HICORE/(HICORE+HIENV)
523C IF(ABS(DJCORE+DJENV).GT.1.0D-32)THEN
524C FJ = DJCORE/(DJCORE+DJENV)
525C ELSE
526C FJ = 1.0D0
527C ENDIF
528C WRITE(88,709)SAGE,HJTOT,OMEGA(M),FJ,FJ/FI,
529C * HCOMP(14,M),HCOMP(15,M)
530C 709 FORMAT(1P7E11.3)
531 RETURN
532 END1"""Python version of seculr.f (YREC development, 7be4133)."""
2
3import math
4from types import SimpleNamespace
5
6import numpy as np
7
8from pyrec import constants_mod
9from pyrec import dimensions_mod
10from pyrec import disk_mod
11from pyrec import egrid_mod
12from pyrec import intvar_mod
13from pyrec import nmlpar_mod
14from pyrec import oldrot2_mod
15from pyrec.checkc import checkc
16from pyrec.checkj import checkj
17from pyrec.codiff import codiff
18from pyrec.dadcoeft import dadcoeft
19from pyrec.dcoeft import dcoeft
20from pyrec.eq2mod import eq2mod
21from pyrec.getfc import getfc
22from pyrec.getqua import getqua
23from pyrec.mcowind import mcowind
24from pyrec.mixcz import mixcz
25from pyrec.mwind import mwind
26from pyrec.ndifcom import ndifcom
27from pyrec.rotgrid import rotgrid
28from pyrec.setupv import setupv
29from pyrec.solid import solid
30from pyrec.tridia import tridia
31from pyrec.vcirc import vcirc
32
33# Fortran SAVEs every local of SECULR: the work arrays below, and the
34# scalars IBEG, IEND, DR, SUMDJ, IDM, ... keep their values between
35# calls. Some of them are read before they are set in a call (question 1
36# on the page), so they live here rather than inside the function.
37_JSON = dimensions_mod.json
38_s = SimpleNamespace(
39 qwrmax=np.zeros(_JSON + 1), em=np.zeros(_JSON + 1),
40 cod=np.zeros(_JSON + 1), ecod2=np.zeros(_JSON + 1),
41 ei=np.zeros(_JSON + 1), ej=np.zeros(_JSON + 1),
42 ecod=np.zeros(_JSON + 1), hru=np.zeros(_JSON + 1),
43 rmid=np.zeros(_JSON + 1), qwlnr=np.zeros(_JSON + 1),
44 dj=np.zeros(_JSON + 1), hjmp=np.zeros(_JSON + 1),
45 wsav=np.zeros(_JSON + 1), ew=np.zeros(_JSON + 1),
46 id=np.zeros(_JSON + 1, dtype=int),
47 faci=np.zeros((4 + 1, _JSON + 1)), # formerly COMMON/INTFAC/
48 vfc=np.zeros(_JSON + 1), # formerly COMMON/VARFC/
49 ibeg=0, iend=0, istart=0, dr=0.0, sumdj=0.0, idm=0,
50 ldum=False, ldum2=False, lokad=False,
51 wind1=0.0, wind2=0.0, lfix=False,
52)
53
54
55def seculr(dt: float, hd: np.ndarray, hg: np.ndarray, hi: np.ndarray, hl: np.ndarray, hp: np.ndarray, hr: np.ndarray,
56 hs: np.ndarray, hs1: np.ndarray, hs2: np.ndarray, ht: np.ndarray, hjmsav: np.ndarray, lcz: np.ndarray,
57 m: int, omega: np.ndarray, hjm: np.ndarray, eta2: np.ndarray, qiw: np.ndarray, r0: np.ndarray,
58 hcomp: np.ndarray, imin: int, imax: int, bl: float, hstot: float, smass: float, teffl: float, lredo: bool,
59 iredo: int, hicz: float, hsbot: float, hstop: float, omegas: float, lczsur: bool, cod2: np.ndarray,
60 hv: np.ndarray, lok: bool, hcomps: np.ndarray) -> tuple[float, bool, int, float, float, bool]:
61 """Secular transport of angular momentum and composition, one step.
62
63 Transfers angular momentum (and the associated transport of
64 composition) by secular rotational instabilities: secular and
65 dynamical shear, Eddington circulation and the GSF instability. Sets
66 up, iterates and checks the diffusion of Omega and of the abundances,
67 with the wind applied to the surface convection zone.
68
69 Translates: seculr.f#SECULR (7be4133)
70
71 Parameters
72 ----------
73 dt : float
74 Time step.
75 hd, hg, hi, hl, hp, hr, hs, hs1, hs2, ht : ndarray, shape (JSON + 1,)
76 The model, by shell.
77 hjmsav : ndarray, shape (JSON + 1,)
78 Specific angular momentum at the start of the step.
79 lcz : ndarray of bool, shape (JSON + 1,)
80 Convection flags; ``lcz[1]`` and ``lcz[m]`` are changed during the
81 call and restored.
82 m : int
83 Number of shells.
84 omega, hjm : ndarray, shape (JSON + 1,)
85 Angular velocity and specific angular momentum, updated in place.
86 eta2, qiw, r0 : ndarray, shape (JSON + 1,)
87 Rotation quantities passed to SOLID and CHECKJ.
88 hcomp : ndarray, shape (16, JSON + 1)
89 Abundances ``hcomp[k, j]``, updated in place.
90 imin, imax : int
91 Range of radiative interfaces.
92 bl, hstot, smass, teffl : float
93 log L/Lsun, log total mass, mass in solar units, log Teff (wind).
94 lredo, iredo, hicz, omegas, lok : bool, int, float, float, bool
95 Input values are kept where the routine does not set them (lredo
96 is cleared on entry).
97 hsbot, hstop : float
98 Masses at the bottom and top of the surface convection zone.
99 lczsur : bool
100 The star has a surface convection zone.
101 cod2, hv : ndarray, shape (JSON + 1,)
102 Composition diffusion coefficients and circulation velocities,
103 set in place.
104 hcomps : ndarray, shape (16, JSON + 1)
105 Abundances at the start of the step (formerly COMMON/OLDAB/).
106
107 Returns
108 -------
109 dt : float
110 The step, halved by CHECKC (or CHECKJ) when it asks for a cut.
111 lredo : bool
112 The step must be cut.
113 iredo : int
114 Why, as set by CHECKJ or CHECKC.
115 hicz : float
116 Moment of inertia of the surface convection zone.
117 omegas : float
118 Surface angular velocity.
119 lok : bool
120 Converged.
121
122 """
123
124 c = constants_mod
125 nml = nmlpar_mod
126 s = _s
127 qwlnr, hru, faci, vfc = s.qwlnr, s.hru, s.faci, s.vfc
128 wsav, hjmp = s.wsav, s.hjmp
129
130 # Printing of the composition changes is switched off (G Somers 11/14)
131 # (Fortran line 153).
132 lprt = False
133
134 # LREDO describes this call only (the stable-model exit returns before
135 # CHECKJ or CHECKC can set it) (Fortran line 159).
136 lredo = False
137
138 # Disk locking (MHP 9/94) (Fortran lines 162–163).
139 lock = False
140 if nml.ldisk and disk_mod.sage <= nml.tdisk:
141 lock = True
142
143 # The first and last shells are treated as convective for diffusion
144 # (Fortran lines 166–167).
145 lcz1 = lcz[1]
146 lczm = lcz[m]
147
148 # Set up factors used to compute diffusion velocities (Fortran lines
149 # 170–171).
150 setupv(hd, hg, hl, hp, hr, hs1, ht, imin, imax, m, hru, s.qwrmax, faci)
151 cltot = c.clsun * hl[m]
152
153 # Angular velocity gradients, centered logarithmic derivative (label 10)
154 # (Fortran lines 173–183).
155 # Question (see the page): RM is the arithmetic mean of the radii.
156 for i in range(imin, imax + 1):
157 rlnc = math.log10(intvar_mod.rm[i])
158 dr1 = 1.0 / c.cln / (hr[i] - rlnc) + 1.0 / c.cln / (rlnc - hr[i - 1])
159 qwlnr[i] = 0.25 * (omega[i] - omega[i - 1]) * dr1
160 getqua(hd, hg, hru, omega, m)
161 vfc[1:m + 1] = 0.0
162
163 # Stability of the model and circulation velocities (Fortran lines
164 # 187–192).
165 it = 1
166 ldo = vcirc(hr, hru, imin, imax, it, lcz, m, omega, False, qwlnr,
167 s.qwrmax, hv, cltot, dt, hp, faci)
168 if nml.lvfc:
169 getfc(hd, hru, hv, imin, imax, omega, vfc)
170
171 # Store the initial angular momentum distribution (label 20) (Fortran
172 # lines 194–197).
173 hjmp[1:m + 1] = hjmsav[1:m + 1]
174 wsav[1:m + 1] = omega[1:m + 1]
175
176 # Initial surface angular velocity, for the angular momentum loss
177 # (Fortran lines 201–202).
178 wbeg = oldrot2_mod.wmst[m]
179 lok = False
180
181 # The iterations (Fortran lines 209–452).
182 converged = False
183 for it in range(1, nml.itdif2 + 1): # label 100
184 omegas = omega[m]
185
186 # From the second iteration: new velocities, j and species 1-4
187 # reset, convection zones remixed (Fortran lines 211–257).
188 if it > 1:
189 # New Omega: average of the initial and the latest values.
190 # Question (see the page): the aim of the averaging.
191 for i in range(1, m + 1):
192 omega[i] = 0.5 * (omega[i] + wsav[i])
193 # New angular velocity gradients (label 30).
194 for i in range(imin, imax + 1):
195 rlnc = math.log10(intvar_mod.rm[i])
196 dr1 = (1.0 / c.cln / (hr[i] - rlnc)
197 + 1.0 / c.cln / (rlnc - hr[i - 1]))
198 qwlnr[i] = 0.25 * (omega[i] - omega[i - 1]) * dr1
199 ldo = vcirc(hr, hru, imin, imax, it, lcz, m, omega, ldo, qwlnr,
200 s.qwrmax, hv, cltot, dt, hp, faci)
201 if nml.lvfc:
202 getfc(hd, hru, hv, imin, imax, omega, vfc)
203 # Reset angular momentum and species 1-4 to their start values
204 # (labels 40, 50).
205 for i in range(1, m + 1):
206 hjm[i] = hjmsav[i]
207 for j in range(1, 5):
208 hcomp[j, i] = hcomps[j, i]
209 # Remix convection zones to their proper depth (MHP 10/91).
210 limix = False # noqa: F841 (unused in the Fortran too)
211 mixcz(hcomp, hs2, lcz, m)
212
213 # Wind loss for an isolated surface convection zone, or from the
214 # whole star (Fortran lines 260–287).
215 if lczsur and hv[imax] == 0.0 and not lock:
216 hicz = 0.0
217 for i in range(imax, m + 1): # label 55
218 hicz = hicz + hi[i]
219 ljdot = nml.ljdot0
220 mwind(bl, dt, hsbot, hstop, imax, m, ljdot, omegas,
221 smass, teffl, hicz, hjm)
222 # Remove the torque from the entire star (IMPJMOD = 1 as LSOLID).
223 elif lczsur and (nml.lsolid or nml.impjmod == 1):
224 ljdot = nml.ljdot0
225 hsbotj = 0.0
226 hstopj = math.exp(c.cln * hstot)
227 imaxj = 1
228 mwind(bl, dt, hsbotj, hstopj, imaxj, m, ljdot, omegas,
229 smass, teffl, hicz, hjm)
230 jstart = 1
231 jend = m
232 solid(hd, hjm, hr, hs, hs2, jstart, jend, eta2, hi, omega,
233 qiw, r0, m)
234
235 # No instability: done (label 9999) (Fortran line 289).
236 if not ldo:
237 return dt, lredo, iredo, hicz, omegas, lok
238
239 # Treat the central and surface zones as convective, and find the
240 # diffusion coefficients for all unstable regions (Fortran lines
241 # 292–297).
242 lcz[1] = True
243 lcz[m] = True
244 codiff(hru, m, s.rmid, s.cod, cod2, vfc)
245
246 # Each unstable region is solved separately. IBEG is the zone
247 # below the first non-zero v, IEND the zone above the last (Fortran
248 # lines 302–337).
249 s.ldum = False
250 s.istart = imin
251 while True: # label 60
252 ltest = False
253 if nml.lcodm and nml.codm > 0.0:
254 # Treat the entire domain as unstable (MHP 8/13); not gated
255 # on solid-body models (KNOWN_ISSUES.md, issue 1).
256 ltest = True
257 s.ibeg = imin - 1
258 s.iend = imax
259 s.istart = imax + 1
260 else:
261 found_end = False
262 for j in range(s.istart, imax + 1): # label 70
263 if hv[j] > 0.0:
264 ltest = True
265 if not s.ldum:
266 # Start of an unstable region.
267 s.ldum = True
268 s.ibeg = j - 1
269 elif s.ldum:
270 # End of an unstable region.
271 s.iend = j - 1
272 s.ldum = False
273 s.istart = j + 1
274 found_end = True
275 break
276 if not found_end:
277 # The last interface is unstable: set IEND properly.
278 if s.ldum:
279 s.iend = imax
280 s.istart = imax + 1
281 # label 80: no non-zero v encountered, exit.
282 if not ltest:
283 break # to label 90
284
285 # Equal spacing in CHI for the region (Fortran lines 345–347).
286 # Question (see the page): the equation's coordinate.
287 s.dr, s.ldum2 = rotgrid(
288 s.cod, cod2, hd, hi, hjmsav, hl, hp, hr, hru, hs, hs1, hs2,
289 hstot, s.ibeg, s.iend, lcz, m, wsav, s.dr, s.ecod,
290 s.ecod2, s.ei, s.ej, s.em, s.ew, s.ldum2)
291 # Two convection zones separated by one radiative zone: skip
292 # (Fortran lines 355–361).
293 if s.ldum2:
294 if s.istart <= imax:
295 continue # to label 60
296 break # to label 90
297
298 # Skip the angular momentum evolution for solid-body models
299 # (IMPJMOD = 1 as LSOLID) (MHP 3/09) (Fortran lines 364–418).
300 if not nml.lsolid and nml.impjmod != 1:
301 # Surface convection zone in the region: wind terms (Fortran
302 # lines 367–388).
303 if lczsur and s.iend == imax:
304 if lock:
305 s.wind1 = 0.0
306 s.wind2 = 0.0
307 s.lfix = True
308 else:
309 s.lfix = False
310 if nml.ljdot0:
311 hicz = s.ei[egrid_mod.ntot]
312 omegas = omega[m]
313 s.wind1, s.wind2 = mcowind(
314 bl, dt, hicz, it, omegas, smass,
315 teffl, wbeg, s.wind1, s.wind2)
316 else:
317 s.wind1 = 0.0
318 s.wind2 = 0.0
319 else:
320 s.lfix = False
321 s.wind1 = 0.0
322 s.wind2 = 0.0
323
324 # Solve for Omega (Fortran lines 389–404).
325 s.lokad = False
326 if not nml.ldifad:
327 # Diffusion equation for Omega at the end of the step,
328 # solved on the equally spaced grid.
329 dcoeft(s.ecod, s.dr, dt, s.ei, s.ej, s.ew,
330 egrid_mod.ntot, s.wind1, s.wind2, s.lfix)
331 s.sumdj = tridia(egrid_mod.ntot, s.ei, s.dj, s.sumdj)
332 else:
333 # Omega and its derivatives in a band matrix.
334 dt, s.wind2, s.sumdj, s.lokad = dadcoeft(
335 s.dr, dt, s.ei, s.ew, egrid_mod.ntot, s.wind1,
336 s.wind2, s.dj, s.ecod2, s.sumdj, s.lfix, s.lokad)
337
338 # Back to the original grid (Fortran line 408).
339 eq2mod(s.dj, s.ej, hs2, s.ibeg, s.iend, lcz, m, s.sumdj, hjm)
340
341 # Composition diffusion of species 1-4 until the final
342 # iteration (the Fortran comment names only H, He3 and He4)
343 # (Fortran lines 419–424).
344 jbeg = 1
345 jend = 4
346 s.ibeg, s.iend = ndifcom(
347 dt, cod2, s.ecod2, s.em, hd, hl, hp, hr, hs, hs1, hs2,
348 hstot, hv, s.ibeg, s.iend, imax, imin, lcz, lok, m,
349 hcomp, jbeg, jend)
350
351 # Next region, if any (Fortran line 430).
352 if s.istart <= imax:
353 continue # to label 60
354 break
355
356 # label 90: check the solution, update Omega, decide whether
357 # another iteration is needed (Fortran lines 433–440).
358 lcz[1] = lcz1
359 lcz[m] = lczm
360 dt, iredo, lok, lredo, s.idm = checkj(
361 hd, hjmp, hjmsav, hr, hs, hs2, hv, imin, imax, it, lcz,
362 m, dt, eta2, hi, hjm, iredo, lok, lredo, omega, qiw, r0,
363 wsav, s.id, s.idm, s.lokad)
364
365 # Check composition diffusion; recompute mean molecular weight; the
366 # exits (Fortran lines 444–450).
367 if not lredo:
368 dt, iredo, lok, lredo = checkc(hcomp, it, lprt, m, dt,
369 iredo, lok, lredo)
370 if nml.lnoj:
371 lok = True
372 if lok:
373 converged = True
374 break # to label 200
375 if lredo:
376 return dt, lredo, iredo, hicz, omegas, lok # label 9999
377
378 # Fortran line 452.
379 if not converged:
380 # Question (see the page): non-convergence counts as success.
381 lok = True
382
383 # label 200: composition diffusion of the remaining species; NDIFCOM
384 # finds every unstable region itself, since lok is True (Fortran lines
385 # 455–482).
386 lcz[1] = True
387 lcz[m] = True
388 jbeg = 5
389 if nml.lexcom:
390 jend = 15
391 else:
392 jend = 11
393 s.ibeg, s.iend = ndifcom(
394 dt, cod2, s.ecod2, s.em, hd, hl, hp, hr, hs, hs1, hs2,
395 hstot, hv, s.ibeg, s.iend, imax, imin, lcz, lok, m,
396 hcomp, jbeg, jend)
397 lcz[1] = lcz1
398 lcz[m] = lczm
399
400 # Output of the composition changes to unit IMODPT (iounits_mod.imodpt;
401 # standard output stands in for it). Never runs: lprt is False (Fortran
402 # lines 484–501).
403 if lprt:
404 print('COMPOSITION CHANGE FROM ROTATIONAL MIXING')
405 print(' H HE3 C12 C13 N14 LI7'
406 ' BE9')
407 for i in range(1, s.idm + 1):
408 k = s.id[i]
409 print(f'{k:5d}' + ''.join(
410 f'{hcomp[j, k] - hcomps[j, k]:10.3E}'
411 for j in (1, 4, 5, 6, 7, 14, 15)))
412
413 # label 9999
414 return dt, lredo, iredo, hicz, omegas, lok