Verifies the orthogonal-rotation identity linking the standard and polar VSH bases can be inverted exactly: i.e. rotating VSH_POL_UP/VSH_POL_DN back by the same angle used to build them from PVSH_POL/PVSH_RAD recovers the originals exactly.
theta phi max_absdiff_pol max_absdiff_rad`, each the max over the 3 vector components). ).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=i4), | intent(in) | :: | LMAX |
Maximum degree tested, . |
||
| integer(kind=i4), | intent(in) | :: | NTH |
Number of colatitude points swept over . |
||
| integer(kind=i4), | intent(in) | :: | OUTUNIT |
Fortran unit number to write results to (columns: `L M |
||
| integer(kind=i4), | intent(out) | :: | STATUS |
Output: 0 = pass, 1 = fail (either max difference |
SUBROUTINE VSH_POL_INVERSION(LMAX, NTH, OUTUNIT, STATUS) IMPLICIT NONE INTEGER(KIND=i4), INTENT(IN) :: LMAX INTEGER(KIND=i4), INTENT(IN) :: NTH INTEGER(KIND=i4), INTENT(IN) :: OUTUNIT INTEGER(KIND=i4), INTENT(OUT) :: STATUS INTEGER(KIND=i4) :: L, M, C, ITH, NYLM, IDX REAL(KIND=dp) :: THETA, PHI, DTH, SC_POL, SC_RAD REAL(KIND=dp) :: DIFF_POL, DIFF_RAD COMPLEX(KIND=dp), ALLOCATABLE :: UP(:,:), DN(:,:) COMPLEX(KIND=dp), ALLOCATABLE :: POL(:,:), RAD(:,:) NYLM = (LMAX+1)**2 ALLOCATE(UP(3,NYLM), DN(3,NYLM), POL(3,NYLM), RAD(3,NYLM)) STATUS = 0 DTH = pi / (NTH + 1) PHI = pi / 4.d0 WRITE(OUTUNIT,'(A)') & '# L M theta phi max_absdiff_pol max_absdiff_rad' DO ITH = 1, NTH THETA = ITH * DTH CALL VSH_POL_UP_ALL(UP, LMAX, THETA, PHI) CALL VSH_POL_DN_ALL(DN, LMAX, THETA, PHI) CALL PVSH_POL_ALL(POL, LMAX, THETA, PHI) CALL PVSH_RAD_ALL(RAD, LMAX, THETA, PHI) DO L = 0, LMAX SC_POL = DSQRT(DBLE(L)/(2*L+1.d0)) SC_RAD = DSQRT((L+1.d0)/(2*L+1.d0)) DO M = -L, L IDX = YLM_INDEX(L, M) DIFF_POL = 0.d0 DIFF_RAD = 0.d0 DO C = 1, 3 DIFF_POL = MAX(DIFF_POL, ABS( & SC_POL*UP(C,IDX) + SC_RAD*DN(C,IDX) - POL(C,IDX))) DIFF_RAD = MAX(DIFF_RAD, ABS( & -SC_RAD*UP(C,IDX) + SC_POL*DN(C,IDX) - RAD(C,IDX))) END DO WRITE(OUTUNIT, *) L, M, THETA, PHI, DIFF_POL, DIFF_RAD IF (DIFF_POL > 1.0E-12_dp .OR. DIFF_RAD > 1.0E-12_dp) STATUS = 1 END DO END DO END DO DEALLOCATE(UP, DN, POL, RAD) END SUBROUTINE VSH_POL_INVERSION