bianchi2_lut_mod.f90
Go to the documentation of this file.
1 !------------------------------------------------------------------------------
2 ! bianchi2_lut_mod
3 !
13 !------------------------------------------------------------------------------
14 
16 
17  use s2_types_mod
19 
20  implicit none
21 
22  private
23 
24 
25  !---------------------------------------
26  ! Subroutine and function scope
27  !---------------------------------------
28 
29  public :: bianchi2_lut_init, &
35 
36 
37  !---------------------------------------
38  ! Data types
39  !---------------------------------------
40 
42  type, public :: bianchi2_lut
43  private
45  integer :: lmax_LUT = 0
46 
47  integer :: Ntheta_LUT = 0
48 
50  real(s2_dp), dimension(:,:), allocatable :: table_LUT
51  end type bianchi2_lut
52 
53 
54  !---------------------------------------------------------------------------
55 
56  contains
57 
58 
59  !-------------------------------------------------------------------------
60  ! bianchi2_lut_init
61  !
69  !-------------------------------------------------------------------------
70 
71  function bianchi2_lut_init(lmax,Ntheta) result(lut)
72 
73  integer, intent(in) :: lmax, ntheta
74  type(bianchi2_lut) :: lut
75 
76  integer :: l, itheta
77  real(s2_dp) :: theta,dtheta
78 
79  lut%lmax_LUT = lmax
80  lut%Ntheta_LUT = ntheta
81 
82  allocate(lut%table_LUT(1:lmax,0:ntheta-1))
83 
84  dtheta = (pi - 0d0) / Real(ntheta, s2_dp)
85  do l=1, lmax
86  do itheta=0, ntheta-1
87  theta = itheta*dtheta
88  ! Compute the data with plgndr.
89  lut%table_LUT(l,itheta) = bianchi2_lut_plgndr(l,1,cos(theta))
90  theta = theta + dtheta
91  end do
92  end do
93 
94  end function bianchi2_lut_init
95 
96 
97  !-------------------------------------------------------------------------
98  ! bianchi2_lut_write
99  !
106  !-------------------------------------------------------------------------
107 
108  subroutine bianchi2_lut_write(lut,filename_LUT)
109 
110  type(bianchi2_lut), intent(in) :: lut
111  character(len=S2_STRING_LEN), intent(in) :: filename_lut
112 
113  integer :: l,itheta
114 
115  open(10,file=trim(filename_lut),form='unformatted',&
116  status='replace',action='write')
117 
118  ! Write the sizes of the table.
119  write(10) lut%lmax_LUT
120  write(10) lut%Ntheta_LUT
121 
122  ! Write the table
123  do l=1, lut%lmax_LUT
124  do itheta=0, (lut%Ntheta_LUT - 1)
125  write(10) lut%table_LUT(l,itheta)
126  end do
127  end do
128 
129  close(10)
130 
131  end subroutine bianchi2_lut_write
132 
133 
134  !-------------------------------------------------------------------------
135  ! bianchi2_lut_read
136  !
145  !-------------------------------------------------------------------------
146 
147  function bianchi2_lut_read(lmax,Ntheta,filename_LUT) result(lut)
148 
149  integer, intent(in) :: lmax,ntheta
150  character(len=S2_STRING_LEN) :: filename_lut
151  type(bianchi2_lut) :: lut
152 
153  integer :: l,itheta
154 
155  open(10,file=trim(filename_lut),form='unformatted',&
156  status='old',action='read')
157 
158  read(10) lut%lmax_LUT
159  read(10) lut%Ntheta_LUT
160  allocate(lut%table_LUT(1:lmax,0:ntheta-1))
161 
162  if(lmax .ne. lut%lmax_LUT) then
163  call bianchi2_error(bianchi2_error_plm1table_l_invalid, &
164  'bianchi2_plm1table_getval')
165 
166  elseif(ntheta .ne. lut%Ntheta_LUT) then
167  call bianchi2_error(bianchi2_error_plm1table_theta_invalid, &
168  'bianchi2_plm1table_getval')
169 
170  else
171  do l=1, lmax
172  do itheta=0, ntheta-1
173  read(10) lut%table_LUT(l,itheta)
174  end do
175  end do
176  end if
177 
178  close(10)
179 
180  end function bianchi2_lut_read
181 
182 
183  !--------------------------------------------------------------------------
184  ! bianchi2_lut_access
185  !
194  !--------------------------------------------------------------------------
195 
196  function bianchi2_lut_access(lut,l,itheta) result(plm1)
197 
198  type(bianchi2_lut), intent(in) :: lut
199  integer, intent(in) :: l, itheta
200  real(s2_dp) :: plm1
201 
202  plm1 = lut%table_LUT(l,itheta)
203 
204  end function bianchi2_lut_access
205 
206  !--------------------------------------------------------------------------
207  ! bianchi2_lut_free
208  !
214  !--------------------------------------------------------------------------
215 
216  subroutine bianchi2_lut_free(lut)
217 
218  type(bianchi2_lut), intent(inout) :: lut
219 
220  if(allocated(lut%table_LUT)) deallocate(lut%table_LUT)
221  lut%lmax_LUT = 0
222  lut%Ntheta_LUT = 0
223 
224  end subroutine bianchi2_lut_free
225 
226 
227  !--------------------------------------------------------------------------
228  ! bianchi2_lut_plgndr
229  !
241  !--------------------------------------------------------------------------
242 
243  function bianchi2_lut_plgndr(l,m,x) result(plgndr)
244 
245  integer :: l, m
246  real(s2_dp) :: plgndr, x
247 
248  integer :: i, ll
249  real(s2_dp) :: fact, pll, pmm, pmmp1, somx2
250 
251  if(m<0 .or. m>l .or. abs(x)>1d0) stop 'bad arguments in plgndr'
252 
253  pmm=1. ! Compute Pmm.
254  if(m.gt.0) then
255  somx2=sqrt((1.-x)*(1.+x))
256  fact=1.
257  do i=1,m
258  pmm=-pmm*fact*somx2
259  fact=fact+2.
260  enddo
261  endif
262  if(l.eq.m) then
263  plgndr=pmm
264  else
265  pmmp1=x*(2*m+1)*pmm ! Compute Pm m+1.
266  if(l.eq.m+1) then
267  plgndr=pmmp1
268  else ! Compute Pm l , l > m+ 1.
269  do ll=m+2,l
270  pll=(x*(2*ll-1)*pmmp1-(ll+m-1)*pmm)/(ll-m)
271  pmm=pmmp1
272  pmmp1=pll
273  enddo
274  plgndr=pll
275  endif
276  endif
277  return
278 
279  end function bianchi2_lut_plgndr
280 
281 
282 end module bianchi2_lut_mod