Private helper shared by every batch VSH routine (GRAD_SSH_ALL, L_SSH_ALL, PVSH_RAD_ALL, PVSH_POL_ALL, PVSH_TOR_ALL, VSH_TOR_ALL, VSH_POL_UP_ALL, VSH_POL_DN_ALL): computes and its two angular gradient components (GRAD_SSH's parts) for every in one pass, so each caller only has to apply its own linear combination/normalization on top.
Warning
Inherits ASSOC_LEGENDRE_NORM_ALL's -dependent
stability limit (safe for unconditionally) --
see STABILITY_FINDINGS.md at the repo root.
YLM_INDEX(l,m). Y_\ell^m ), same size/indexing. Y_\ell^m ), same size/indexing.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| complex(kind=dp), | intent(out) | :: | YLM_OUT((LMAX+1)**2) | |||
| complex(kind=dp), | intent(out) | :: | GSSH_TH((LMAX+1)**2) | |||
| complex(kind=dp), | intent(out) | :: | GSSH_PH((LMAX+1)**2) | |||
| integer(kind=i4), | intent(in) | :: | LMAX |
Maximum degree, . |
||
| real(kind=dp), | intent(in) | :: | THETA |
Colatitude in radians, . |
||
| real(kind=dp), | intent(in) | :: | PHI |
Longitude in radians, . |
SUBROUTINE VSH_CORE_DP(YLM_OUT, GSSH_TH, GSSH_PH, & LMAX, THETA, PHI) IMPLICIT NONE INTEGER(KIND=i4), INTENT(IN) :: LMAX REAL(KIND=dp), INTENT(IN) :: THETA REAL(KIND=dp), INTENT(IN) :: PHI COMPLEX(KIND=dp), INTENT(OUT) :: YLM_OUT((LMAX+1)**2) COMPLEX(KIND=dp), INTENT(OUT) :: GSSH_TH((LMAX+1)**2) COMPLEX(KIND=dp), INTENT(OUT) :: GSSH_PH((LMAX+1)**2) INTEGER(KIND=i4) :: L, M, PSIZE REAL(KIND=dp), ALLOCATABLE :: PNORM(:), DPNORM(:) REAL(KIND=dp) :: SINTH, SIGN_M COMPLEX(KIND=dp) :: EPHIM, YP, GTH_P, GPH_P PSIZE = (LMAX+1)*(LMAX+2)/2 ALLOCATE(PNORM(PSIZE), DPNORM(PSIZE)) CALL ASSOC_LEGENDRE_NORM_ALL(PNORM, LMAX, DCOS(THETA)) CALL DDX_ASSOC_LEGENDRE_NORM_ALL(DPNORM, PNORM, LMAX, & DCOS(THETA)) SINTH = DSIN(THETA) DO L = 0, LMAX DO M = 0, L EPHIM = EXP(j*M*PHI) YP = PNORM(PLM_INDEX(L,M)) * EPHIM GTH_P = -SINTH * DPNORM(PLM_INDEX(L,M)) * EPHIM IF (SINTH .NE. 0.d0) THEN GPH_P = j*M*YP/SINTH ELSE GPH_P = DCMPLX(0.d0, 0.d0) END IF YLM_OUT(YLM_INDEX(L, M)) = YP GSSH_TH(YLM_INDEX(L, M)) = GTH_P GSSH_PH(YLM_INDEX(L, M)) = GPH_P IF (M .GT. 0) THEN SIGN_M = 1.0_dp - 2.0_dp * MOD(M, 2) YLM_OUT(YLM_INDEX(L,-M)) = SIGN_M * CONJG(YP) GSSH_TH(YLM_INDEX(L,-M)) = SIGN_M * CONJG(GTH_P) GSSH_PH(YLM_INDEX(L,-M)) = SIGN_M * CONJG(GPH_P) END IF END DO END DO DEALLOCATE(PNORM, DPNORM) END SUBROUTINE VSH_CORE_DP