1C $$$$$$
2 SUBROUTINE MIXCOM(DT,ECOD2,EM,HS2,IBEG,IEND,LCZ,LOK,M,HCOMP,
3 * * JBEG,JEND)
4C 10/15/26 MHP via Claude
5C code changed to take JSON from DIMENSIONS_MOD instead of declaring
6C PARAMETER(JSON=5000) here.
7 USE DIMENSIONS_MOD
8C 10/14/26 MHP via Claude
9C code changed to convert COMMON/TRIDI/ into TRIDI_MOD.
10 USE TRIDI_MOD
11C 10/14/26 MHP via Claude
12C code changed to convert COMMON/SPLIN/ into SPLIN_MOD.
13 USE SPLIN_MOD
14C 10/14/26 MHP via Claude
15C code changed to convert COMMON/EGRID/ into EGRID_MOD.
16 USE EGRID_MOD
17C 10/20/26 MHP via Claude
18C code changed to replace implicit typing with IMPLICIT NONE and
19C explicit declarations.
20 IMPLICIT NONE
21 REAL*8 DCOMP,DCOMP2,DT,ECOD2,ECOMP,EM,HCOMP,HS2,SUMSPEC,SUMSPEC2,
22 * * TEST
23 INTEGER I,I0,I1,IBEG,ID,IEND,II,J,JBEG,JEND,M,N,NSPEC,NTAB
24 LOGICAL*4 LCZ,LOK
25 DIMENSION ECOD2(JSON),EM(JSON),HCOMP(15,JSON),HS2(JSON),LCZ(JSON)
26 DIMENSION ECOMP(JSON),ID(15)
27 SAVE
28C DIFCOM CALCULATES THE DIFFUSION OF COMPOSITION DUE TO ANGULAR MOMENTUM
29C TRANSPORT. THIS IS DONE BY TRANSFORMING TO AN EQUALLY SPACED GRID
30C WHICH WAS PREVIOUSLY DEFINED AND THEN TRANSFORMING BACK.
31C
32C INPUT VARIABLES:
33C DT : DIFFUSION TIMESTEP(SEC).
34C ECOD2 : DIFFUSION COEFFICIENTS FOR COMPOSITION TRANSPORT AT THE EQUALLY
35C SPACED GRID POINTS.
36C EM : MASSES OF THE EQUALLY SPACED GRID POINTS(GM).
37C NOTE: FOR CONVECTIVE BOUNDARIES THE MASS OF THE LAST GRID POINT IS
38C THE MASS OF THE ENTIRE CONVECTION ZONE.
39C HCOMP : ARRAY OF MASS FRACTION OF ALL OF THE SPECIES AT THE ORIGINAL
40C MODEL POINTS.
41C HS2 : MASSES OF THE ORIGINAL MODEL POINTS(UNLOGGED).
42C IBEG,IEND :THE FIRST/LAST UNSTABLE POINTS IN THE REGION.
43C NOTE: FOR CONVECTIVE BOUNDARIES THESE ARE ONLY THE FIRST CONVECTIVE
44C POINTS ADJACENT TO AN UNSTABLE RADIATIVE REGION.
45C LCZ : FLAG WHICH TELLS WHICH OF THE ORIGINAL MODEL POINTS ARE
46C CONVECTIVE FOR ANGULAR MOMENTUM TRANSPORT PURPOSES(I.E. INCLUDES
47C OVERSHOOT REGIONS). LCZ=T IF CONVECTIVE.
48C M : NUMBER OF MODEL POINTS.
49C
50C OUTPUT VARIABLES:
51C HCOMP IS UPDATED IN DIFCOM TO GIVE THE NEW RUN OF COMPOSITION AFTER
52C ANGULAR MOMENTUM TRANSPORT.
53C
54C BEFORE THE LAST ITERATION(LOK=F),ONLY DIFFUSION OF H,HE4,HE3 CALCULATED
55C TO CALCULATE CHANGE IN MU GRADIENTS CAUSED BY DIFFUSION.
56C THIS ROUTINE WILL THEREFORE BE CALLED EITHER TO MIX THE OTHER SPECIES
57C OR JUST THE FIRST 4 DEPENDING ON LOK.
58C DETERMINE WHICH SPECIES VARY OVER THE UNSTABLE REGION.
59 NSPEC = 0
60 DO J = JBEG, JEND
61 TEST = HCOMP(J,IBEG)
62C ABUNDANCE 2(HE4) IS DEFINED AS 1-X-Z-HE3 SO IT IS NOT SOLVED FOR.
63 IF(J.NE.2)THEN
64 DO I = IBEG+1,IEND
65 IF(DABS(HCOMP(J,I)-TEST).GT.1.0D-14) THEN
66 NSPEC = NSPEC + 1
67 ID(NSPEC) = J
68 GOTO 20
69 ENDIF
70 END DO
71 ENDIF
72 20 20 CONTINUE
73 END DO
74 IF(NSPEC.EQ.0) GOTO 200
75C NOW SOLVE FOR DIFFUSION OF ALL SPECIES THAT VARY OVER THE
76C UNSTABLE REGION USING THE SAME DIFFUSION COEFFICIENTS.
77 NTAB = IEND - IBEG + 1
78C FIND RUN OF COMPOSITION AT THE EQUALLY SPACED GRID POINTS AT THE
79C START OF THE DIFFUSION TIMESTEP. THIS IS DONE USING AN OSCULATORY
80C SPLINE.
81 DO N = 1,NSPEC
82 DO I = 1,NTAB
83 II = I + IBEG - 1
84 XTAB(I) = CHI(I)
85 YTAB(I) = HCOMP(ID(N),II)
86 END DO
87 CALL OSPLIN(ECHI,ECOMP,XTAB,YTAB,NTAB,NTOT)
88C SET UP DIFFUSION EQUATION ARRAYS TO SOLVE FOR COMP AT END OF TSTEP
89 CALL CCOEFT(ECOD2,DCHI,DT,ECOMP,EM,NTOT)
90C SOLVE MATRIX FOR THE RUN OF COMP AT TIME N+1 AT THE NEW GRID.
91 CALL CTRIDI(NTOT)
92C TRANSFORM BACK TO THE ORIGINAL GRID AND UPDATE HCOMP IN THE
93C DIFFUSED REGION. U IS THE NEW RUN OF COMPOSITION IN THE REGION AT THE
94C EQUALLY SPACED GRID POINTS.
95C FOR THE BOUNDARY POINTS IN THE MODEL,EXTRAPOLATING U PAST THE
96C LAST EQUALLY SPACED GRID POINTS CAN LEAD TO SERIOUS ERRORS.
97C THEREFORE ADD THE *CHANGE* IN COMPOSITION AT THE EQUALLY SPACED GRID
98C POINTS TO HCOMP AND DO NOT REPLACE HCOMP WITH U.
99 DCOMP = 0.0D0
100 DO I = 1,NTOT
101 XTAB(I) = ECHI(I)
102 YTAB(I) = U(I)-ECOMP(I)
103 DCOMP = DCOMP + YTAB(I)*EM(I)
104 END DO
105 DO I = 1,NTAB
106 XVAL(I) = CHI(I)
107 END DO
108C USE YVAL AS DUMMY ARRAY FOR THE NEW RUN OF COMP AT THE ORIGINAL
109C POINT GRID.
110 CALL OSPLIN(XVAL,YVAL,XTAB,YTAB,NTOT,NTAB)
111C CHECK FOR LOWER CONVECTION ZONE
112C 10/30/26 MHP via Claude
113C code changed to widen the write-back with the test MIXGRID's sums
114C use: any convection zone adjoining the region, whether or not the end
115C zone is itself convective. The sums took that zone's mass into the
116C end cell, but its change went to the end zone alone when that zone
117C was radiative, so species were not conserved. I1 is now also set
118C when the top zone is radiative; it was left from an earlier call.
119 IF(IBEG.GT.1)THEN
120 DO I = IBEG-1,1,-1
121 IF(.NOT.LCZ(I))THEN
122 I0 = I + 1
123 GOTO 90
124 ENDIF
125 END DO
126 I0 = 1
127 90 90 CONTINUE
128 ELSE
129 I0 = IBEG
130 ENDIF
131C CHECK FOR UPPER CONVECTION ZONE.
132 IF(IEND.LT.M)THEN
133 DO I = IEND+1,M
134 IF(.NOT.LCZ(I))THEN
135 I1 = I - 1
136 GOTO 97
137 ENDIF
138 END DO
139 I1 = M
140 97 97 CONTINUE
141 ELSE
142 I1 = IEND
143 ENDIF
144 DCOMP2 = 0.0D0
145C COMPUTE SUM OF SPECIES MASS
146 SUMSPEC = 0.0D0
147 DO I = I0,I1
148 SUMSPEC = SUMSPEC + HS2(I)*HCOMP(ID(N),I)
149 END DO
150C UPDATE COMPOSITION ARRAY.
151 SUMSPEC2 = 0.0D0
152 DO I = 1,NTAB
153 J = IBEG+I-1
154 HCOMP(ID(N),J) = HCOMP(ID(N),J)+YVAL(I)
155 DCOMP2 = DCOMP2 + YVAL(I)*HS2(J)
156 SUMSPEC2 = SUMSPEC2 + HS2(J)*HCOMP(ID(N),J)
157 END DO
158C UPDATE INNER CZ COMPOSITION IF APPLICABLE.
159C A convective end zone was mixed with its neighbour, so copy its value;
160C a radiative one was not, so add the end cell's change instead.
161 IF(I0.LT.IBEG)THEN
162 DO I = IBEG-1,I0,-1
163 IF(LCZ(IBEG))THEN
164 HCOMP(ID(N),I)=HCOMP(ID(N),IBEG)
165 ELSE
166 HCOMP(ID(N),I)=HCOMP(ID(N),I)+YVAL(1)
167 ENDIF
168 SUMSPEC2 = SUMSPEC2 + HS2(I)*HCOMP(ID(N),I)
169 DCOMP2 = DCOMP2 + YVAL(1)*HS2(I)
170 END DO
171 ENDIF
172C UPDATE OUTER CZ COMPOSITION IF APPLICABLE.
173 IF(IEND.LT.I1)THEN
174 DO I = IEND+1,I1
175 IF(LCZ(IEND))THEN
176 HCOMP(ID(N),I)=HCOMP(ID(N),IEND)
177 ELSE
178 HCOMP(ID(N),I)=HCOMP(ID(N),I)+YVAL(NTAB)
179 ENDIF
180 SUMSPEC2 = SUMSPEC2 + HS2(I)*HCOMP(ID(N),I)
181 DCOMP2 = DCOMP2 + YVAL(NTAB)*HS2(I)
182 END DO
183 ENDIF
184C CHECK FOR CONSERVATION OF SPECIES
185c TEST = ABS(SUMSPEC-SUMSPEC2)
186c WRITE(*,911)ID(N),DCOMP,DCOMP2,SUMSPEC
187c 911 FORMAT(I5,1P3E10.2)
188c IF(TEST.GT.1.0D-10*SUMSPEC)THEN
189c RATIO = SUMSPEC/SUMSPEC2
190c DO I = I0,I1
191c HCOMP(ID(N),I)=RATIO*HCOMP(ID(N),I)
192c END DO
193c ENDIF
194 END DO
195C ADJUST HE4 FOR CHANGES IN X, Z, AND HE3.
196 IF(.NOT.LOK)THEN
197 DO I = I0,I1
198 HCOMP(2,I) = 1.0D0 - HCOMP(1,I) - HCOMP(3,I) - HCOMP(4,I)
199 END DO
200 ENDIF
201 200 200 CONTINUE
202 RETURN
203 END
1"""Python version of mixcom.f (YREC 7be4133): composition diffused across
2one unstable region on the equally spaced grid in chi."""
3
4import numpy as np
5
6from pyrec import dimensions_mod
7from pyrec import egrid_mod
8from pyrec import splin_mod
9from pyrec import tridi_mod
10from pyrec.ccoeft import ccoeft
11from pyrec.ctridi import ctridi
12from pyrec.osplin import osplin
13
14JSON = dimensions_mod.json
15
16# The Fortran's locals (SAVE).
17ecomp = np.zeros(JSON + 1)
18id_ = np.zeros(16, dtype=int)
19i0 = 0
20i1 = 0
21
22
23def mixcom(dt: float, ecod2: np.ndarray, em: np.ndarray, hs2: np.ndarray, ibeg: int, iend: int, lcz: np.ndarray,
24 lok: bool, m: int, hcomp: np.ndarray, jbeg: int, jend: int) -> None:
25 """Diffuse each species in rows jbeg..jend (helium, row 2, by closure)
26 that varies over the region ibeg..iend: interpolate it to the equal
27 grid in chi, solve the implicit diffusion equation there, interpolate
28 the change back and add it; adjoining convection zones take the edge
29 abundance if the edge zone is convective, or the end cell's change if
30 it is radiative. Before the last iteration (lok False),
31 Y = 1 - X - Z - He3.
32
33 Translates: mixcom.f#MIXCOM (7be4133)
34
35 Arguments: the step dt (s); ecod2 and em on the equal grid (from
36 MIXGRID); the shell masses hs2; the region ibeg..iend; the convective
37 flags lcz; lok; m shells; the model hcomp[k, j]; the rows jbeg..jend.
38 The grid is in egrid_mod (chi, echi, dchi, ntot). Arrays have index 0
39 unused.
40
41 Sets in place: hcomp. Returns nothing.
42
43 """
44
45 global i0, i1
46 chi = egrid_mod.chi
47 echi = egrid_mod.echi
48 xval = splin_mod.xval
49 yval = splin_mod.yval
50 xtab = splin_mod.xtab
51 ytab = splin_mod.ytab
52 u = tridi_mod.u
53
54 # Which species vary over the unstable region (Fortran lines 59–74).
55 nspec = 0
56 for j in range(jbeg, jend + 1):
57 test = hcomp[j, ibeg]
58 # Row 2 (He4) is 1 - X - Z - He3, not solved for.
59 if j != 2:
60 for i in range(ibeg + 1, iend + 1):
61 if abs(hcomp[j, i] - test) > 1.0e-14:
62 nspec += 1
63 id_[nspec] = j
64 break # GOTO 20
65 if nspec == 0:
66 return # GOTO 200
67
68 ntab = iend - ibeg + 1
69 ntot = egrid_mod.ntot
70 for n in range(1, nspec + 1):
71 # The composition at the equal grid points at the start of the step (Fortran lines 77–87).
72 for i in range(1, ntab + 1):
73 ii = i + ibeg - 1
74 xtab[i] = chi[i]
75 ytab[i] = hcomp[id_[n], ii]
76 osplin(echi, ecomp, xtab, ytab, ntab, ntot)
77
78 # The implicit diffusion equation, solved for u in tridi_mod (Fortran lines 89–91).
79 ccoeft(ecod2, egrid_mod.dchi, dt, ecomp, em, ntot)
80 ctridi(ntot)
81
82 # The change, not the new abundance, is interpolated back (Fortran lines 99–110).
83 dcomp = 0.0
84 for i in range(1, ntot + 1):
85 xtab[i] = echi[i]
86 ytab[i] = u[i] - ecomp[i]
87 dcomp = dcomp + ytab[i] * em[i]
88 for i in range(1, ntab + 1):
89 xval[i] = chi[i]
90 osplin(xval, yval, xtab, ytab, ntot, ntab)
91
92 # A lower convection zone (Fortran lines 119–130).
93 if ibeg > 1:
94 for i in range(ibeg - 1, 0, -1):
95 if not lcz[i]:
96 i0 = i + 1
97 break # GOTO 90
98 else:
99 i0 = 1
100 else:
101 i0 = ibeg
102
103 # An upper convection zone (Fortran lines 132–143).
104 if iend < m:
105 for i in range(iend + 1, m + 1):
106 if not lcz[i]:
107 i1 = i - 1
108 break # GOTO 97
109 else:
110 i1 = m
111 else:
112 i1 = iend
113
114 # The species' mass before the update; the sums dcomp2, sumspec and
115 # sumspec2 feed only a disabled check (unused?) (Fortran lines 144–149).
116 dcomp2 = 0.0
117 sumspec = 0.0
118 for i in range(i0, i1 + 1):
119 sumspec = sumspec + hs2[i] * hcomp[id_[n], i]
120
121 # Update the composition (Fortran lines 151–157).
122 sumspec2 = 0.0
123 for i in range(1, ntab + 1):
124 j = ibeg + i - 1
125 hcomp[id_[n], j] = hcomp[id_[n], j] + yval[i]
126 dcomp2 = dcomp2 + yval[i] * hs2[j]
127 sumspec2 = sumspec2 + hs2[j] * hcomp[id_[n], j]
128
129 # The inner convection zone, if any (Fortran lines 161–171).
130 if i0 < ibeg:
131 for i in range(ibeg - 1, i0 - 1, -1):
132 if lcz[ibeg]:
133 hcomp[id_[n], i] = hcomp[id_[n], ibeg]
134 else:
135 hcomp[id_[n], i] = hcomp[id_[n], i] + yval[1]
136 sumspec2 = sumspec2 + hs2[i] * hcomp[id_[n], i]
137 dcomp2 = dcomp2 + yval[1] * hs2[i]
138
139 # The outer convection zone, if any (Fortran lines 173–183).
140 if iend < i1:
141 for i in range(iend + 1, i1 + 1):
142 if lcz[iend]:
143 hcomp[id_[n], i] = hcomp[id_[n], iend]
144 else:
145 hcomp[id_[n], i] = hcomp[id_[n], i] + yval[ntab]
146 sumspec2 = sumspec2 + hs2[i] * hcomp[id_[n], i]
147 dcomp2 = dcomp2 + yval[ntab] * hs2[i]
148 # The conservation check (rescaling to sumspec) is commented out (Fortran lines 184–193).
149
150 # He4 adjusted for the changes in X, Z and He3 (Fortran lines 196–200).
151 if not lok:
152 for i in range(i0, i1 + 1):
153 hcomp[2, i] = 1.0 - hcomp[1, i] - hcomp[3, i] - hcomp[4, i]