1C $$$$$$
2C SUBROUTINE MOMI(ETA2,HD,HR,HS,HS2,JSTART,JEND,OMEGA,R0,HI,QIW,M) ! KC 2025-05-31
3 SUBROUTINE MOMI(ETA2,HR,HS,HS2,JSTART,JEND,OMEGA,R0,HI,QIW)
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/NMLPAR/ into NMLPAR_MOD.
10 USE NMLPAR_MOD
11C 10/14/26 MHP via Claude
12C code changed to convert COMMON/CONSTANTS/ into CONSTANTS_MOD.
13 USE CONSTANTS_MOD
14C 10/20/26 MHP via Claude
15C code changed to replace implicit typing with IMPLICIT NONE and
16C explicit declarations.
17 IMPLICIT NONE
18 REAL*8 A,CON,ETA2,ETA2X,H0,HI,HIM,HR,HS,HS2,OMEGA,QIW,QIWM,QR0R,
19 * * R0,R03,R0P,R0R,RAD,RPHI3,RPHIP
20 INTEGER I,JEND,JSTART
21
22C 10/11/26 MHP via Claude
23C code changed to remove LSCRIB from COMMON/CCOUT/: it was declared
24C positionally in all 17 files sharing this block but never read or
25C written in executable code anywhere, and no namelist file sets it.
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: removed the unused COMMON/CCOUT/ declaration
39C (no member referenced here; residue of the obsolete-option removals).
40C 9/25/26 MHP via Claude
41C code changed to merge COMMON/CONST/, COMMON/CONST1/, COMMON/CONST2/,
42C and COMMON/CONST3/ into a single COMMON/CONSTANTS/
43C 10/13/26 MHP via Claude: removed the unused COMMON/IOUNITS/ declaration
44C (no member referenced here; residue of the obsolete-option removals).
45C DIMENSION HD(JSON),HR(JSON),HS2(JSON),R0(JSON),ETA2(JSON),HI(JSON) ! KC 2025-05-31
46 DIMENSION HR(JSON),HS2(JSON),R0(JSON),ETA2(JSON),HI(JSON)
47 DIMENSION OMEGA(JSON),HS(JSON),QIW(JSON)
48 SAVE
49
50C FIND THE MOMENT OF INERTIA (HI) AND DI/D(OMEGA) (QIW).
51C MOMI ASSUMES THAT SHAPE HAS ALREADY BEEN CALLED.
52C MOMENT OF INERTIA IS CALCULATED BY THE METHOD USED IN WAI-YUEN LAW'S
53C THESIS(YALE,1980) P.61.
54 IF(JSTART.EQ.1) THEN
55 R0P = 0.0D0
56 RPHIP = 0.0D0
57 ELSE
58 R0P = DLOG(R0(JSTART - 1))
59 RPHIP = CLN*HR(JSTART - 1)
60 ENDIF
61 CON = CC13*5.0D0/DEXP(CLN*CGL)
62 IF(WALPCZ.NE.0.0D0)THEN
63 DO I = JSTART,JEND
64 HI(I) = CC23*HS2(I)*EXP(CLN*2.0D0*HR(I))
65 QIW(I) = 0.0D0
66 END DO
67 IF(JSTART.EQ.1)THEN
68 RAD = 0.5D0*(HR(1)+HR(2))
69 HI(1) = 0.4D0*HS2(1)*EXP(CLN*2.0D0*RAD)
70 ENDIF
71 RETURN
72 ENDIF
73 DO 20 I = JSTART,JEND
74C QR0R = D LN R0/ D LN R
75C
76 QR0R = 1.0D0
77 H0 = CC23*HS2(I)*DEXP(CLN*2.0D0*HR(I))
78 R03 = R0(I)**3
79 RPHI3 = DEXP(CLN*3.0D0*HR(I))
80 R0R = (R03/RPHI3)*R0(I)**2
81 A = CON*OMEGA(I)**2*R03/(DEXP(CLN*HS(I))*(2.0D0+ETA2(I)))
82 ETA2X = ETA2(I)
83C EVALUATE INTEGRAL AT THE ZONE CENTER
84 CALL INTMOM(A,ETA2X,QR0R,R0R,HIM,QIWM)
85 HI(I) = HIM*HS2(I)
86 QIW(I) = QIWM*HS2(I)
87 R0P = DLOG(R0(I))
88 RPHIP = CLN*HR(I)
89 20 20 CONTINUE
90
91 RETURN
92 END
1"""Python version of momi.f (YREC 7be4133): the moment of inertia of each
2shell of a rotating, distorted model, and its derivative in A (called
3dI/dOmega in the comments)."""
4
5import math
6import numpy as np
7
8from pyrec import constants_mod
9from pyrec import nmlpar_mod
10from pyrec.intmom import intmom
11
12
13def momi(eta2: np.ndarray, hr: np.ndarray, hs: np.ndarray, hs2: np.ndarray, jstart: int, jend: int, omega: np.ndarray,
14 r0: np.ndarray, hi: np.ndarray, qiw: np.ndarray) -> None:
15 """Compute the moment of inertia hi and A dI/dA qiw of the shells
16 jstart..jend (Law's thesis, Yale 1980, p. 61), from the shapes found by
17 SHAPE; thin spherical shells when WALPCZ is not 0.
18
19 Translates: momi.f#MOMI (7be4133)
20
21 Arguments: the shape parameters eta2 and r0; log r (hr), log m (hs),
22 the shell masses hs2 and the angular velocities omega; the range
23 jstart..jend. Arrays have index 0 unused.
24
25 Sets in place: hi, qiw. Returns nothing.
26
27 """
28
29 c = constants_mod
30
31 # The previous shell's ln r0 and ln r, and the constant of A
32 # (Fortran lines 54–61). r0p and rphip are unused (in the Fortran too).
33 if jstart == 1:
34 r0p = 0.0 # noqa: F841 (unused in the Fortran too)
35 rphip = 0.0 # noqa: F841 (unused in the Fortran too)
36 else:
37 r0p = math.log(r0[jstart - 1]) # noqa: F841 (unused in the Fortran too)
38 rphip = c.cln * hr[jstart - 1] # noqa: F841 (unused in the Fortran too)
39 con = c.cc13 * 5.0 / math.exp(c.cln * c.cgl)
40
41 # Thin spherical shells when WALPCZ is not 0 (Fortran lines 62–72).
42 # Question (see the page): WALPCZ as a switch for every shell.
43 if nmlpar_mod.walpcz != 0.0:
44 for i in range(jstart, jend + 1):
45 hi[i] = c.cc23 * hs2[i] * math.exp(c.cln * 2.0 * hr[i])
46 qiw[i] = 0.0
47 if jstart == 1:
48 rad = 0.5 * (hr[1] + hr[2])
49 hi[1] = 0.4 * hs2[1] * math.exp(c.cln * 2.0 * rad)
50 return
51
52 # Distorted shells, through INTMOM (Fortran lines 73–89).
53 for i in range(jstart, jend + 1): # loop 20
54 # QR0R = d ln r0 / d ln r.
55 qr0r = 1.0
56 h0 = c.cc23 * hs2[i] * math.exp(c.cln * 2.0 * hr[i]) # noqa: F841 (unused in the Fortran too)
57 r03 = r0[i]**3
58 rphi3 = math.exp(c.cln * 3.0 * hr[i])
59 r0r = (r03 / rphi3) * r0[i]**2
60 a = con * omega[i]**2 * r03 / (math.exp(c.cln * hs[i])
61 * (2.0 + eta2[i]))
62 eta2x = eta2[i]
63 # The integral at the zone centre.
64 him, qiwm = intmom(a, eta2x, qr0r, r0r, 0.0, 0.0)
65 hi[i] = him * hs2[i]
66 qiw[i] = qiwm * hs2[i]
67 r0p = math.log(r0[i]) # noqa: F841 (unused in the Fortran too)
68 rphip = c.cln * hr[i] # noqa: F841 (unused in the Fortran too)