1C $$$$$$
2C SUBROUTINE MODEL_TO_EQUAL(COD1,COD2,HCOMP,HQPR,HRU,HS1,HTU, ! KC 2025-05-31
3 SUBROUTINE MODEL_TO_EQUAL(COD1,COD2,HCOMP,HRU,HS1,
4 * * IBEGIN,IEND,M,QCOD1X,QCOD2X,DR,
5 * * ECOD1,ECOD1_H,ECOD2_H,EM,EM_H,
6 * * EQCOD1X_H,EQCOD2X_H,ER,EX,EX_H,NPT,COD1Z,COD2Z,QCOD1Z,QCOD2Z)
7C 10/15/26 MHP via Claude
8C code changed to take JSON from DIMENSIONS_MOD instead of declaring
9C PARAMETER(JSON=5000) here.
10 USE DIMENSIONS_MOD
11C 10/14/26 MHP via Claude
12C code changed to convert COMMON/GRAVEZ/ into GRAVEZ_MOD.
13 USE GRAVEZ_MOD
14C 10/14/26 MHP via Claude
15C code changed to convert COMMON/NMLPAR/ into NMLPAR_MOD.
16 USE NMLPAR_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 COD1,COD1Z,COD2,COD2Z,DELR,DR,DR1,DR2,DRMIN,DRTOT,ECOD1,
22 * * ECOD1_H,ECOD2_H,EM,EM_H,EQCOD1X_H,EQCOD2X_H,ER,EX,EX_H,
23 * * FAC1,FAC2,FACDERIV,FACINTERP,FX,GRIDRAD,HCOMP,HRU,HS1,
24 * * QCOD1X,QCOD1Z,QCOD2X,QCOD2Z,TABLER
25 INTEGER I,IBEGIN,IEND,IU,J,JMIN,K,K0,M,NPT
26C 10/13/26 MHP via Claude
27C formerly COMMON/GRAVSZ/, now dummy arguments.
28 DIMENSION COD1Z(JSON),COD2Z(JSON),QCOD1Z(JSON),QCOD2Z(JSON)
29C 10/12/26 MHP via Claude
30C code changed to extend COMMON/NMLPAR/ to 234 members, adding the
31C namelist variables that the physics routines read from 27 COMMON
32C blocks which also held derived or working members. Those blocks keep
33C only their non-namelist members; five of them -- NEWMX, VMULT,
34C PMMWIND, CCOUT1 and ENVGEN -- had nothing left and are gone.
35C Derivation-only namelist variables from the same blocks went to
36C COMMON/NMLBYPASS/ instead, not here.
37C
38C Declared identically in all 121 files that hold any of these members.
39C Generated from one member list, so every copy is byte-identical; the
40C linker's 'size of symbol changed' warning is the check that they are.
41C 10/13/26 MHP via Claude
42C code changed to replace COMMON/GRAVSZ/ with explicit arguments:
43C setup_grsett.f fills these four and model_to_equal.f reads them, and
44C grsett.f calls both, so grsett.f now owns the storage.
45C DIMENSION COD1(JSON),COD2(JSON),HCOMP(15,JSON),HQPR(JSON),
46C * HRU(JSON),HS1(JSON),HTU(JSON),QCOD1X(JSON),QCOD2X(JSON), ! KC 2025-05-31
47 DIMENSION COD1(JSON),COD2(JSON),HCOMP(15,JSON),
48 * * HRU(JSON),HS1(JSON),QCOD1X(JSON),QCOD2X(JSON),
49 * * ECOD1(JSON),ECOD1_H(JSON),ECOD2_H(JSON),EM(JSON),
50 * * EM_H(JSON),EQCOD1X_H(JSON),EQCOD2X_H(JSON),ER(JSON),EX(JSON),
51 * * EX_H(JSON),FACINTERP(4),FACDERIV(4),TABLER(4)
52 SAVE
53C FIND MINIMUM MODEL POINT SPACING IN RADIUS.
54
55 DRTOT = HRU(IEND)-HRU(IBEGIN)
56 DRMIN = DRTOT
57 DO 7 I = IBEGIN+1,IEND
58 DRMIN=MIN(DRMIN,HRU(I)-HRU(I-1))
59 7 7 CONTINUE
60C ASSIGN THE MINIMUM NUMBER OF EQUALLY SPACED GRID POINTS SUCH THAT
61C DR <= DRMIN.
62 NPT=INT(DRTOT/DRMIN)
63 IF(MOD(DRTOT,DRMIN).NE.0.0D0)NPT=NPT+1
64C JVS add additional trap to deal with models with NPT=1
65C 10/30/26 MHP via Claude
66C code changed to require at least 4 points, not 2. The 4-point
67C Lagrangian stencils here and on the way back read ER(K0..K0+3), so a
68C 2- or 3-point grid read points never set, or ER(-1) and ER(0).
69 NPT = MAX(NPT,4)
70C ENSURE THAT NUMBER OF POINTS DOES NOT EXCEED JSON.
71
72 NPT=MIN(NPT,JSON)
73 DR = DRTOT/DFLOAT(NPT-1)
74
75C SET UP VECTOR OF EQUALLY SPACED RADII AT ZONE MIDPOINTS.
76 ER(1)=HRU(IBEGIN)+0.5D0*DR
77C JVS added logic trap (IF statement)
78 IF (NPT .EQ. 2) THEN
79 ER(2)=ER(1)+DR
80 ELSE
81 DO 10 I = 2,NPT-1 ! old piece
82 IF(I-1 .EQ. 0) PRINT*, 'mte line 47'
83 ER(I)=ER(I-1)+DR ! old piece
84 10 10 CONTINUE ! old piece
85 ENDIF
86
87C NOW USE 4-POINT LAGRANGIAN INTERPOLATION TO FIND RUN OF VARIABLES
88C AT EQUALLY SPACED ZONE MIDPOINTS.
89C
90C FIRST POINT : LINEAR INTERPOLATION BETWEEN STARTING POINT AND 2ND PT.
91 DO 15 IU=2,NPT
92 IF(HRU(IU).GE.ER(1))GOTO 17
93 15 15 CONTINUE
94 IU=NPT
95 17 17 CONTINUE
96 FX=(ER(1)-HRU(IU-1))/(HRU(IU)-HRU(IU-1))
97 EM_H(1) = HS1(IU-1)+FX*(HS1(IU)-HS1(IU-1))
98 ECOD1_H(1)=COD1(IU-1)+FX*(COD1(IU)-COD1(IU-1))
99 ECOD2_H(1)=COD2(IU-1)+FX*(COD2(IU)-COD2(IU-1))
100 EQCOD1X_H(1)=QCOD1X(IU-1)+FX*(QCOD1X(IU)-QCOD1X(IU-1))
101 EQCOD2X_H(1)=QCOD2X(IU-1)+FX*(QCOD2X(IU)-QCOD2X(IU-1))
102 EX_H(1) = HCOMP(1,IU-1)+FX*(HCOMP(1,IU)-HCOMP(1,IU-1))
103 IF(LDIFZ)THEN
104 ECOD1Z_H(1)=COD1Z(IU-1)+FX*(COD1Z(IU)-COD1Z(IU-1))
105 ECOD2Z_H(1)=COD2Z(IU-1)+FX*(COD2Z(IU)-COD2Z(IU-1))
106 EQCOD1Z_H(1)=QCOD1Z(IU-1)+FX*(QCOD1Z(IU)-QCOD1Z(IU-1))
107 EQCOD2Z_H(1)=QCOD2Z(IU-1)+FX*(QCOD2Z(IU)-QCOD2Z(IU-1))
108 EZ_H(1) = HCOMP(8,IU-1)+FX*(HCOMP(8,IU)-HCOMP(8,IU-1))
109 ENDIF
110C CENTER DERIVATIVE.
111 DR1=ER(1)-HRU(IU-1)
112 DR2=HRU(IU)-ER(1)
113 IF(DR2.GT.DR1)THEN
114 FAC1=1.0D0
115 FAC2=DR1/DR2
116 DELR=2.0D0*DR1
117 ELSE IF(DR1.GT.DR2)THEN
118 FAC1=DR2/DR1
119 FAC2=1.0D0
120 DELR=2.0D0*DR2
121 ELSE
122 FAC1=1.0D0
123 FAC2=1.0D0
124 DELR=DR1+DR2
125 ENDIF
126C FOR OTHER POINTS: FIRST FIND 4 NEAREST (IN RADIUS) MODEL POINTS
127C AND THEN FIND LAGRANGIAN INTERPOLATION FACTORS. APPLY THEM TO FIND
128C MODEL QUANTITIES AT THE EQUALLY SPACED GRID POINTS.
129C JMIN IS THE UPPERMOST MODEL POINT ABOVE THE PREVIOUS EQUALLY SPACED
130C GRID POINT (IN RADIUS).
131 JMIN=IBEGIN+1
132 DO 50 I=2,NPT-1
133 DO 20 J = JMIN,IEND
134C FIND 4 MODEL POINTS CLOSEST TO THE EQUALLY SPACED GRID POINT.
135 IF(HRU(J).GE.ER(I))THEN
136C ENSURE THAT FIRST INTERPOLATION POINT NO LESS THAN FIRST MODEL POINT.
137 K0 = MAX(J-2,1)
138C ENSURE THAT LAST INTERPOLATION POINT NO GREATER THAN LAST MODEL POINT.
139 K0 = MIN(K0,M-3)
140 JMIN=J
141 GOTO 30
142 ENDIF
143 20 20 CONTINUE
144 K0 = M-3
145 JMIN=M
146 30 30 CONTINUE
147 DO 40 K=1,4
148 TABLER(K)=HRU(K0+K-1)
149 40 40 CONTINUE
150 GRIDRAD=ER(I)
151C FIND 4 POINT LAGRANGIAN INTERPOLATION FACTORS.
152C FACINTERP=INTERPOLATION FACTORS FOR POINT GRIDRAD GIVEN THE 4 TABLE
153C RADII IN TABLER; FACDERIV=SAME FOR DERIVATIVES AT POINT GRIDRAD.
154 CALL INTERP(TABLER,FACINTERP,FACDERIV,GRIDRAD)
155C PERFORM 4 POINT LAGRANGIAN INTERPOLATION FOR DESIRED QUANTITIES:
156C MASS WITHIN THE RADIUS ER
157 EM_H(I) = FACINTERP(1)*HS1(K0)+FACINTERP(2)*HS1(K0+1)+
158 * * FACINTERP(3)*HS1(K0+2)+FACINTERP(4)*HS1(K0+3)
159C D1
160 ECOD1_H(I) = FACINTERP(1)*COD1(K0)+FACINTERP(2)*COD1(K0+1)+
161 * * FACINTERP(3)*COD1(K0+2)+FACINTERP(4)*COD1(K0+3)
162C D2
163 ECOD2_H(I) = FACINTERP(1)*COD2(K0)+FACINTERP(2)*COD2(K0+1)+
164 * * FACINTERP(3)*COD2(K0+2)+FACINTERP(4)*COD2(K0+3)
165C DERIVATIVE OF D1 WRT X
166 EQCOD1X_H(I)=FACINTERP(1)*QCOD1X(K0)+FACINTERP(2)*QCOD1X(K0+1)
167 * * +FACINTERP(3)*QCOD1X(K0+2)+FACINTERP(4)*QCOD1X(K0+3)
168C DERIVATIVE OF D2 WRT X
169 EQCOD2X_H(I)=FACINTERP(1)*QCOD2X(K0)+FACINTERP(2)*QCOD2X(K0+1)
170 * * +FACINTERP(3)*QCOD2X(K0+2)+FACINTERP(4)*QCOD2X(K0+3)
171C MASS FRACTION OF HYDROGEN
172 EX_H(I)=FACINTERP(1)*HCOMP(1,K0)+FACINTERP(2)*HCOMP(1,K0+1)+
173 * * FACINTERP(3)*HCOMP(1,K0+2)+FACINTERP(4)*HCOMP(1,K0+3)
174 IF(LDIFZ)THEN
175C METAL DIFFUSION-TREATED AS FULLY IONIZED IRON.
176C D1
177 ECOD1Z_H(I)=FACINTERP(1)*COD1Z(K0)+FACINTERP(2)*COD1Z(K0+1)+
178 * * FACINTERP(3)*COD1Z(K0+2)+FACINTERP(4)*COD1Z(K0+3)
179C D2
180 ECOD2Z_H(I)=FACINTERP(1)*COD2Z(K0)+FACINTERP(2)*COD2Z(K0+1)+
181 * * FACINTERP(3)*COD2Z(K0+2)+FACINTERP(4)*COD2Z(K0+3)
182C DERIVATIVE OF D1 WRT Z
183 EQCOD1Z_H(I)=FACINTERP(1)*QCOD1Z(K0)+FACINTERP(2)*QCOD1Z(K0+1)
184 * * +FACINTERP(3)*QCOD1Z(K0+2)+FACINTERP(4)*QCOD1Z(K0+3)
185C DERIVATIVE OF D2 WRT Z
186 EQCOD2Z_H(I)=FACINTERP(1)*QCOD2Z(K0)+FACINTERP(2)*QCOD2Z(K0+1)
187 * * +FACINTERP(3)*QCOD2Z(K0+2)+FACINTERP(4)*QCOD2Z(K0+3)
188C MASS FRACTION OF METALS
189 EZ_H(I)=FACINTERP(1)*HCOMP(8,K0)+FACINTERP(2)*HCOMP(8,K0+1)+
190 * * FACINTERP(3)*HCOMP(8,K0+2)+FACINTERP(4)*HCOMP(8,K0+3)
191 ENDIF
192 50 50 CONTINUE
193C SET UP VECTOR OF EQUALLY SPACED RADII AT ZONE CENTERS.
194
195 ER(1)=HRU(IBEGIN)
196 DO 60 I = 2,NPT
197 ER(I)=ER(I-1)+DR
198 60 60 CONTINUE
199
200
201C NOW USE 4-POINT LAGRANGIAN INTERPOLATION TO FIND RUN OF VARIABLES
202C AT EQUALLY SPACED ZONE CENTERS.
203C
204C FIRST POINT : BY DEFINITION, AT STARTING POINT.
205 EM(1) = HS1(IBEGIN)
206 EX(1) = HCOMP(1,IBEGIN)
207 ECOD1(1)=COD1(IBEGIN)
208 IF(LDIFZ)THEN
209 EZ(1) = HCOMP(8,IBEGIN)
210 ECOD1Z(1) = COD1Z(IBEGIN)
211 ENDIF
212C FOR OTHER POINTS: FIRST FIND 4 NEAREST (IN RADIUS) MODEL POINTS
213C AND THEN FIND LAGRANGIAN INTERPOLATION FACTORS. APPLY THEM TO FIND
214C MODEL QUANTITIES AT THE EQUALLY SPACED GRID POINTS.
215C JMIN IS THE UPPERMOST MODEL POINT ABOVE THE PREVIOUS EQUALLY SPACED
216C GRID POINT (IN RADIUS).
217 JMIN=IBEGIN+1
218 DO 70 I=2,NPT-1
219 DO 80 J = JMIN,IEND
220C FIND 4 MODEL POINTS CLOSEST TO THE EQUALLY SPACED GRID POINT.
221 IF(HRU(J).GE.ER(I))THEN
222C ENSURE THAT FIRST INTERPOLATION POINT NO LESS THAN FIRST MODEL POINT.
223 K0 = MAX(J-2,1)
224C ENSURE THAT LAST INTERPOLATION POINT NO GREATER THAN LAST MODEL POINT.
225 K0 = MIN(K0,M-3)
226 JMIN=J
227 GOTO 90
228 ENDIF
229 80 80 CONTINUE
230 K0 = M-3
231 JMIN=M
232 90 90 CONTINUE
233 DO 100 K=1,4
234 TABLER(K)=HRU(K0+K-1)
235 100 100 CONTINUE
236
237 GRIDRAD=ER(I)
238
239C FIND 4 POINT LAGRANGIAN INTERPOLATION FACTORS.
240C FACINTERP=INTERPOLATION FACTORS FOR POINT GRIDRAD GIVEN THE 4 TABLE
241C RADII IN TABLER; FACDERIV=SAME FOR DERIVATIVES AT POINT GRIDRAD.
242 CALL INTERP(TABLER,FACINTERP,FACDERIV,GRIDRAD)
243C PERFORM 4 POINT LAGRANGIAN INTERPOLATION FOR DESIRED QUANTITIES:
244C MASS WITHIN THE RADIUS ER
245 EM(I) = FACINTERP(1)*HS1(K0)+FACINTERP(2)*HS1(K0+1)+
246 * * FACINTERP(3)*HS1(K0+2)+FACINTERP(4)*HS1(K0+3)
247C D1
248 ECOD1(I) = FACINTERP(1)*COD1(K0)+FACINTERP(2)*COD1(K0+1)+
249 * * FACINTERP(3)*COD1(K0+2)+FACINTERP(4)*COD1(K0+3)
250C MASS FRACTION OF HYDROGEN
251
252 EX(I)=FACINTERP(1)*HCOMP(1,K0)+FACINTERP(2)*HCOMP(1,K0+1)+
253 * * FACINTERP(3)*HCOMP(1,K0+2)+FACINTERP(4)*HCOMP(1,K0+3)
254C METAL DIFFUSION
255 IF(LDIFZ)THEN
256C D1
257 ECOD1Z(I)=FACINTERP(1)*COD1Z(K0)+FACINTERP(2)*COD1Z(K0+1)+
258 * * FACINTERP(3)*COD1Z(K0+2)+FACINTERP(4)*COD1Z(K0+3)
259C MASS FRACTION OF METALS
260 EZ(I)=FACINTERP(1)*HCOMP(8,K0)+FACINTERP(2)*HCOMP(8,K0+1)+
261 * * FACINTERP(3)*HCOMP(8,K0+2)+FACINTERP(4)*HCOMP(8,K0+3)
262 ENDIF
263 70 70 CONTINUE
264C LAST POINT : BY DEFINITION, AT ENDING POINT.
265
266 EM(NPT) = HS1(IEND)
267 EX(NPT) = HCOMP(1,IEND)
268 ECOD1(NPT)=COD1(IEND)
269
270 IF(LDIFZ)THEN
271 EZ(NPT) = HCOMP(8,IEND)
272 ECOD1Z(NPT)=COD1Z(IEND)
273 ENDIF
274 RETURN
275 END
1"""Python version of model_to_equal.f (YREC 7be4133): the diffusion
2coefficients and abundances of the older settling routine (GRSETT) on an
3equally spaced grid in radius."""
4
5import math
6
7import numpy as np
8
9from pyrec import dimensions_mod
10from pyrec import gravez_mod
11from pyrec import nmlpar_mod
12from pyrec.interp import interp
13
14JSON = dimensions_mod.json
15
16# The Fortran's local arrays (SAVE).
17facinterp = np.zeros(5)
18facderiv = np.zeros(5)
19tabler = np.zeros(5)
20
21
22def _lagrange(f: np.ndarray, k0: int) -> float:
23 """FACINTERP(1)*F(K0) + ... + FACINTERP(4)*F(K0+3), in the Fortran's
24 order.
25
26 """
27
28 return (facinterp[1] * f[k0] + facinterp[2] * f[k0 + 1]
29 + facinterp[3] * f[k0 + 2] + facinterp[4] * f[k0 + 3])
30
31
32def _find_k0(r: float, jmin: int, iend: int, m: int, hru: np.ndarray) -> tuple[int, int]:
33 """Labels 20/30 (and 80/90): the first model point J >= JMIN at or
34 above radius r gives the four interpolation points K0..K0+3, kept
35 inside 1..M; returns (k0, jmin) (Fortran lines 133–146, 219–232).
36
37 """
38
39 for j in range(jmin, iend + 1):
40 if hru[j] >= r:
41 k0 = max(j - 2, 1)
42 k0 = min(k0, m - 3)
43 return k0, j
44 return m - 3, m
45
46
47def model_to_equal(cod1: np.ndarray, cod2: np.ndarray, hcomp: np.ndarray, hru: np.ndarray, hs1: np.ndarray, ibegin: int,
48 iend: int, m: int, qcod1x: np.ndarray, qcod2x: np.ndarray, dr: float, ecod1: np.ndarray,
49 ecod1_h: np.ndarray, ecod2_h: np.ndarray, em: np.ndarray, em_h: np.ndarray, eqcod1x_h: np.ndarray,
50 eqcod2x_h: np.ndarray, er: np.ndarray, ex: np.ndarray, ex_h: np.ndarray, npt: int, cod1z: np.ndarray,
51 cod2z: np.ndarray, qcod1z: np.ndarray, qcod2z: np.ndarray) -> tuple[float, int]:
52 """Interpolate the settling coefficients and abundances of GRSETT from
53 the model points (ibegin..iend) to an equally spaced grid in radius, at
54 the grid points and the midpoints (_h).
55
56 Translates: model_to_equal.f#MODEL_TO_EQUAL (7be4133)
57
58 Arguments: the coefficients cod1, cod2, their derivatives in X qcod1x,
59 qcod2x, and the metal ones cod1z, cod2z, qcod1z, qcod2z (from
60 SETUP_GRSETT); hcomp[k, j], the radii hru and masses hs1 (Bahcall-Loeb
61 units); m shells. dr and npt are passed in with any value. Arrays have
62 index 0 unused.
63
64 Sets in place: em, ex, ecod1 on the grid points; em_h, ecod1_h, ecod2_h,
65 eqcod1x_h, eqcod2x_h, ex_h on the midpoints; er (the grid radii, after
66 holding the midpoints' radii); with LDIFZ, the metal arrays of
67 gravez_mod.
68
69 Returns (dr, npt): the grid spacing and the number of grid points.
70
71 """
72
73 gz = gravez_mod
74 ldifz = nmlpar_mod.ldifz
75
76 # The minimum model point spacing in radius, over the whole region
77 # (Fortran lines 55–59).
78 drtot = hru[iend] - hru[ibegin]
79 drmin = drtot
80 for i in range(ibegin + 1, iend + 1):
81 drmin = min(drmin, hru[i] - hru[i - 1])
82
83 # The minimum number of equally spaced points such that DR <= DRMIN, at
84 # least 4 for the 4-point Lagrange stencils (Fortran lines 62–73).
85 npt = int(drtot / drmin)
86 if math.fmod(drtot, drmin) != 0.0:
87 npt = npt + 1
88 npt = max(npt, 4)
89 npt = min(npt, JSON)
90 dr = drtot / float(npt - 1)
91
92 # Equally spaced radii at the zone midpoints, held in ER for now
93 # (Fortran lines 76–85). The NPT == 2 branch cannot be taken.
94 er[1] = hru[ibegin] + 0.5 * dr
95 if npt == 2:
96 er[2] = er[1] + dr
97 else:
98 for i in range(2, npt): # DO 10 (its debug PRINT can never fire)
99 er[i] = er[i - 1] + dr
100
101 # First midpoint: linear interpolation (Fortran lines 91–109).
102 # Suspected bug (see the page): the search runs over model indices
103 # 2..NPT.
104 iu = npt
105 for k in range(2, npt + 1): # DO 15
106 if hru[k] >= er[1]:
107 iu = k
108 break
109 fx = (er[1] - hru[iu - 1]) / (hru[iu] - hru[iu - 1])
110
111 def lin(f):
112 return f[iu - 1] + fx * (f[iu] - f[iu - 1])
113
114 em_h[1] = lin(hs1)
115 ecod1_h[1] = lin(cod1)
116 ecod2_h[1] = lin(cod2)
117 eqcod1x_h[1] = lin(qcod1x)
118 eqcod2x_h[1] = lin(qcod2x)
119 ex_h[1] = hcomp[1, iu - 1] + fx * (hcomp[1, iu] - hcomp[1, iu - 1])
120 if ldifz:
121 gz.ecod1z_h[1] = lin(cod1z)
122 gz.ecod2z_h[1] = lin(cod2z)
123 gz.eqcod1z_h[1] = lin(qcod1z)
124 gz.eqcod2z_h[1] = lin(qcod2z)
125 # Row 8, not row 3 (Z); its values cancel in GRSETT's change.
126 gz.ez_h[1] = hcomp[8, iu - 1] + fx * (hcomp[8, iu] - hcomp[8, iu - 1])
127
128 # "Center derivative": FAC1, FAC2, DELR are never used (Fortran lines
129 # 111–125).
130 dr1 = er[1] - hru[iu - 1]
131 dr2 = hru[iu] - er[1]
132 if dr2 > dr1:
133 fac1, fac2, delr = 1.0, dr1 / dr2, 2.0 * dr1 # noqa: F841 (unused in the Fortran too)
134 elif dr1 > dr2:
135 fac1, fac2, delr = dr2 / dr1, 1.0, 2.0 * dr2 # noqa: F841 (unused in the Fortran too)
136 else:
137 fac1, fac2, delr = 1.0, 1.0, dr1 + dr2 # noqa: F841 (unused in the Fortran too)
138
139 # Other midpoints: 4-point Lagrange interpolation (Fortran lines
140 # 131–192).
141 jmin = ibegin + 1
142 for i in range(2, npt): # DO 50
143 k0, jmin = _find_k0(er[i], jmin, iend, m, hru)
144 for k in range(1, 5):
145 tabler[k] = hru[k0 + k - 1]
146 interp(tabler, facinterp, facderiv, er[i])
147 em_h[i] = _lagrange(hs1, k0)
148 ecod1_h[i] = _lagrange(cod1, k0)
149 ecod2_h[i] = _lagrange(cod2, k0)
150 eqcod1x_h[i] = _lagrange(qcod1x, k0)
151 eqcod2x_h[i] = _lagrange(qcod2x, k0)
152 ex_h[i] = _lagrange(hcomp[1, :], k0)
153 if ldifz:
154 # Metal diffusion, treated as fully ionized iron.
155 gz.ecod1z_h[i] = _lagrange(cod1z, k0)
156 gz.ecod2z_h[i] = _lagrange(cod2z, k0)
157 gz.eqcod1z_h[i] = _lagrange(qcod1z, k0)
158 gz.eqcod2z_h[i] = _lagrange(qcod2z, k0)
159 gz.ez_h[i] = _lagrange(hcomp[8, :], k0)
160
161 # Equally spaced radii at the zone centers (Fortran lines 195–198).
162 er[1] = hru[ibegin]
163 for i in range(2, npt + 1):
164 er[i] = er[i - 1] + dr
165
166 # First point: by definition, at the starting point (Fortran lines
167 # 205–211).
168 em[1] = hs1[ibegin]
169 ex[1] = hcomp[1, ibegin]
170 ecod1[1] = cod1[ibegin]
171 if ldifz:
172 gz.ez[1] = hcomp[8, ibegin]
173 gz.ecod1z[1] = cod1z[ibegin]
174
175 # Other points: 4-point Lagrange interpolation (Fortran lines 217–263).
176 jmin = ibegin + 1
177 for i in range(2, npt): # DO 70
178 k0, jmin = _find_k0(er[i], jmin, iend, m, hru)
179 for k in range(1, 5):
180 tabler[k] = hru[k0 + k - 1]
181 interp(tabler, facinterp, facderiv, er[i])
182 em[i] = _lagrange(hs1, k0)
183 ecod1[i] = _lagrange(cod1, k0)
184 ex[i] = _lagrange(hcomp[1, :], k0)
185 if ldifz:
186 gz.ecod1z[i] = _lagrange(cod1z, k0)
187 gz.ez[i] = _lagrange(hcomp[8, :], k0)
188
189 # Last point: by definition, at the ending point (Fortran lines
190 # 266–273).
191 em[npt] = hs1[iend]
192 ex[npt] = hcomp[1, iend]
193 ecod1[npt] = cod1[iend]
194 if ldifz:
195 gz.ez[npt] = hcomp[8, iend]
196 gz.ecod1z[npt] = cod1z[iend]
197
198 return dr, npt