MODULE SUPOL_MOD CONTAINS SUBROUTINE SUPOL(KNSMAX,DDMU,DDPOL,DDA,DDB,DDC,DDD,DDE,DDF,DDG,DDH,DDI) !**** *SUPOL * - Routine to compute the Legendre polynomials ! Purpose. ! -------- ! For a given value of mu, computes the Legendre ! polynomials. !** Interface. ! ---------- ! *CALL* *SUPOL(KNSMAX,DDMU,DDPOL,DDA,DDB,DDC,DDD,DDE ! ,DDF,DDG,DDH,DDI) ! Explicit arguments : ! -------------------- ! KNSMAX : Truncation (triangular) ! DDMU : Abscissa at which the polynomials are computed (mu) ! DDPOL : Polynomials (the first index is m and the second n) ! Implicit arguments : None ! -------------------- ! Method. ! ------- ! See documentation ! Externals. ! ---------- ! Reference. ! ---------- ! ECMWF Research Department documentation of the IFS ! Author. ! ------- ! Mats Hamrud and Philippe Courtier *ECMWF* ! Modifications. ! -------------- ! Original : 87-10-15 ! K. YESSAD (MAY 1998): modification to avoid underflow. ! ------------------------------------------------------------------ USE PARKIND1 ,ONLY : JPIM ,JPRB USE PARKIND2 ,ONLY : JPRH IMPLICIT NONE INTEGER(KIND=JPIM),INTENT(IN) :: KNSMAX REAL(KIND=JPRH) ,INTENT(IN) :: DDMU REAL(KIND=JPRH) ,INTENT(IN) :: DDC(0:KNSMAX,0:KNSMAX) REAL(KIND=JPRH) ,INTENT(IN) :: DDD(0:KNSMAX,0:KNSMAX) REAL(KIND=JPRH) ,INTENT(IN) :: DDE(0:KNSMAX,0:KNSMAX) REAL(KIND=JPRH) ,INTENT(IN) :: DDA(0:KNSMAX),DDB(0:KNSMAX),DDF(0:KNSMAX) REAL(KIND=JPRH) ,INTENT(IN) :: DDG(0:KNSMAX),DDH(0:KNSMAX),DDI(0:KNSMAX) REAL(KIND=JPRH) ,INTENT(OUT) :: DDPOL(0:KNSMAX,0:KNSMAX) REAL(KIND=JPRH) :: DLX,DLSITA,DL1SITA,DLKM2,DLKM1,DLK,DL1,DLS INTEGER(KIND=JPIM) :: JM, JN REAL(KIND=JPRB) :: Z ! ------------------------------------------------------------------ !* 1. First two columns. ! ------------------ DLX=DDMU DLSITA=SQRT(1.0_JPRB-DLX*DLX) ! IF WE ARE LESS THAN 1Meter FROM THE POLE, IF(ABS(REAL(DLSITA,KIND(Z))) <= SQRT(EPSILON(Z)))THEN DLX=1._JPRB DLSITA=0._JPRB DL1SITA=0._JPRB ELSE DL1SITA=1.0_JPRB/DLSITA ENDIF DLKM2=1._JPRB DLKM1=DLX DDPOL(0,0)=DLKM2 DDPOL(0,1)=DLKM1*DDA(1) DDPOL(1,1)=DLSITA*DDB(1) DO JN=2,KNSMAX DLK=DDF(JN)*DLX*DLKM1-DDG(JN)*DLKM2 DL1=DDI(JN)*(DLKM1-DLX*DLK)*DL1SITA DDPOL(0,JN)=DLK*DDA(JN) DDPOL(1,JN)=DL1*DDB(JN) DLKM2=DLKM1 DLKM1=DLK ENDDO ! ------------------------------------------------------------------ !* 2. Diagonal (the terms 0,0 and 1,1 have already been computed) ! ----------------------------------------------------------- DLS=DL1SITA*TINY(DLS) !OCL SCALAR DO JN=2,KNSMAX DDPOL(JN,JN)=DDPOL(JN-1,JN-1)*DLSITA*DDH(JN) IF ( ABS(DDPOL(JN,JN)) < DLS ) DDPOL(JN,JN)=0.0_JPRB ENDDO ! ------------------------------------------------------------------ !* 3. General recurrence. ! ------------------- DO JN=3,KNSMAX !DIR$ IVDEP !OCL NOVREC DO JM=2,JN-1 DDPOL(JM,JN)=DDC(JM,JN)*DDPOL(JM-2,JN-2)& &-DDD(JM,JN)*DDPOL(JM-2,JN-1)*DLX & &+DDE(JM,JN)*DDPOL(JM ,JN-1)*DLX ENDDO ENDDO ! ------------------------------------------------------------------ END SUBROUTINE SUPOL END MODULE SUPOL_MOD