Batch-consistency check: DDX_ASSOC_LEGENDRE_ALL vs. looped
DDX_ASSOC_LEGENDRE calls, for , swept over NX points . Same
tolerance/output convention as BATCH_ALM_CONS.
X dP_batch dP_single abs_diff`). ).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=i4), | intent(in) | :: | LMAX |
Maximum degree tested, . |
||
| integer(kind=i4), | intent(in) | :: | NX |
Number of 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 (some relative error |
SUBROUTINE BATCH_DALM_CONS(LMAX, NX, OUTUNIT, STATUS) IMPLICIT NONE INTEGER(KIND=i4), INTENT(IN) :: LMAX INTEGER(KIND=i4), INTENT(IN) :: NX INTEGER(KIND=i4), INTENT(IN) :: OUTUNIT INTEGER(KIND=i4), INTENT(OUT) :: STATUS INTEGER(KIND=i4) :: L, M, IX, PSIZE REAL(KIND=dp) :: X, DX, DP_SINGLE, SCALE, REL_ERR REAL(KIND=dp), ALLOCATABLE :: P_BATCH(:), DP_BATCH(:) PSIZE = (LMAX+1)*(LMAX+2)/2 ALLOCATE(P_BATCH(PSIZE), DP_BATCH(PSIZE)) STATUS = 0 DX = 1.8_dp / (NX - 1) WRITE(OUTUNIT, '(A)') '# L M X dP_batch dP_single abs_diff' DO IX = 0, NX-1 X = -0.9_dp + IX * DX CALL ASSOC_LEGENDRE_ALL(P_BATCH, LMAX, X) CALL DDX_ASSOC_LEGENDRE_ALL(DP_BATCH, P_BATCH, LMAX, X) DO L = 0, LMAX DO M = 0, L DP_SINGLE = DDX_ASSOC_LEGENDRE(L, M, X) WRITE(OUTUNIT, *) L, M, X, & DP_BATCH(PLM_INDEX(L, M)), DP_SINGLE, & ABS(DP_BATCH(PLM_INDEX(L, M)) - DP_SINGLE) SCALE = MAX(ABS(DP_SINGLE), 1.0_dp) REL_ERR = ABS(DP_BATCH(PLM_INDEX(L, M)) - DP_SINGLE) / SCALE IF (REL_ERR > 1.0E-12_dp) STATUS = 1 END DO END DO END DO DEALLOCATE(P_BATCH, DP_BATCH) END SUBROUTINE BATCH_DALM_CONS