1 subroutine da_setlegpol(nj, max_wavenumber, alp_size, sinlat, coslat, alp)
3 !-----------------------------------------------------------------------
5 !-----------------------------------------------------------------------
10 ! Uses ECMWF recursion relation as opposed to Num Rec. one which can only go
11 ! to m about 12 with single precision). However, still use NumRec one for
12 ! m = 0 and 1 as ECMWF one requires m-2 for asslegpol of order m.
13 ! Reference: Jarraud and Simmons (1990) and Belousov (1962).
15 integer, intent(in) :: nj ! Latitude dimension.
16 integer, intent(in) :: max_wavenumber ! Maximum zonal wavenumber.
17 integer, intent(in) :: alp_size ! Ass. Leg. Pol. array size.
18 real, intent(in) :: sinlat(1:nj) ! sine(latitude).
19 real, intent(in) :: coslat(1:nj) ! cosine(latitude).
20 real, intent(out) :: alp(1:alp_size) ! Associated Legendre Polynomial.
22 integer :: j, l, m, mm ! Loop counters.
23 integer :: l1, l2, m2 ! Markers.
24 integer :: index_j, index_m, index ! Indexing counters for ALP array.
25 integer :: index_m2, index_l2m2 ! Indexing counters for ALP array.
26 integer :: index_l1m2, index_l1m ! Indexing counters for ALP array.
28 real :: c(2:max_wavenumber,2:max_wavenumber) ! Recursion coefficient.
29 real :: d(2:max_wavenumber,2:max_wavenumber) ! Recursion coefficient.
30 real :: e(2:max_wavenumber,2:max_wavenumber) ! Recursion coefficient.
32 if (trace_use) call da_trace_entry("da_setlegpol")
36 ! Compute Associated Legendre polynomials for latitude range:
38 do j = 1, (nj + 1) / 2
39 index_j = (j - 1) * (max_wavenumber + 1) * (max_wavenumber + 2) / 2
41 ! use Num. Rec. recursion relation for m = 0, 1:
44 index_m = m * (max_wavenumber + 1 - m) + m * (m + 1) / 2 + 1 - m
45 do l = m, max_wavenumber
46 index = index_m + index_j + l
47 call da_asslegpol(l, m, sinlat(j), coslat(j), alp(index))
49 ! Multiply by normalization constant
50 ! (to ensure 1/2 integral^1_-1 Pml Pml1 = 1 if l = l1):
56 alp(index) = sqrt(real(2*l+1) / s) * alp(index)
61 ! Jarraud recursion relation coefficients:
63 do m = 2, max_wavenumber
64 do l = m, max_wavenumber
65 c(l,m) = sqrt ((real(2*l+1)/real(2*l-3)) * (real(l+m-1)/real(l+m)) * &
66 (real(l+m-3)/real(l+m-2)))
67 d(l,m) = sqrt ((real(2*l+1)/real(2*l-1)) * (real(l+m-1)/real(l+m)) * &
68 (real(l-m+1)/real(l+m-2)))
69 e(l,m) = sqrt ((real(2*l+1)/real(2*l-1)) * (real(l-m) /real(l+m)))
73 ! use Jarraud recursion relation for m>=2:
75 do j = 1, (nj + 1) / 2
76 index_j = (j - 1) * (max_wavenumber + 1) * (max_wavenumber + 2) / 2
78 do m = 2, max_wavenumber
79 index_m = m * (max_wavenumber + 1 - m) + m * (m + 1) / 2 + 1 - m
81 index_m2 = m2 * (max_wavenumber + 1 - m2) + m2 * (m2+1) / 2 + 1 - m2
83 do l = m, max_wavenumber
86 index = index_j + index_m + l
87 index_l2m2 = index_j + index_m2 + l2
88 index_l1m2 = index_j + index_m2 + l1
89 index_l1m = index_j + index_m + l1
91 alp(index) = c(l,m) * alp(index_l2m2) - d(l,m) * sinlat(j) * &
92 alp(index_l1m2) + e(l,m) * sinlat(j) * alp(index_l1m)
97 if (trace_use) call da_trace_exit("da_setlegpol")
99 end subroutine da_setlegpol