00001 
00002 
00003 module legendre_fn_grav
00004   use phys_constant, only : long
00005   implicit none
00006   real(long), pointer  ::  plmg(:,:,:), hplmg(:,:,:)
00007   real(long), pointer  ::  facnmg(:,:), epsig(:) 
00008 contains
00009 subroutine allocate_legendre
00010   use phys_constant,  only : long
00011   use grid_parameter, only : ntg, nlg     
00012   use make_array_3d
00013   use make_array_2d
00014   use make_array_1d
00015   implicit none
00016 
00017 
00018 
00019   call alloc_array3d(plmg, 0, nlg, 0, nlg, 0, ntg)
00020   call alloc_array3d(hplmg, 0, nlg, 0, nlg, 1, ntg)
00021   call alloc_array2d(facnmg, 0, nlg, 0, nlg)
00022   call alloc_array1d(epsig, 0, nlg)
00023 
00024 end subroutine allocate_legendre
00025 SUBROUTINE legendre
00026   use phys_constant,  only : nnlg, long
00027   use grid_parameter, only : ntg, nlg     
00028   use coordinate_grav_theta, only : thg, hthg
00029   use make_array_3d
00030   use make_array_2d
00031   use make_array_1d
00032   implicit none
00033   integer              ::  it, mm, nn
00034   real(long)           ::  fmm, fnn, fnmfm
00035   real(long)           ::  pnag(0:nnlg,0:nnlg), theta
00036 
00037 
00038 
00039   do it = 0, ntg
00040     theta = thg(it)
00041     call legendre_theta(pnag,theta)
00042     plmg(0:nlg,0:nlg,it) = pnag(0:nlg,0:nlg)
00043   end do
00044   do it = 1, ntg
00045     theta = hthg(it)
00046     call legendre_theta(pnag,theta)
00047     hplmg(0:nlg,0:nlg,it) = pnag(0:nlg,0:nlg)
00048   end do
00049 
00050 
00051 
00052   do nn = 0, nlg
00053     do mm = 0, nlg
00054       facnmg(nn,mm) = 0.0d+0
00055     end do
00056   end do
00057 
00058   facnmg(0,0) = 1.0d0
00059   do nn = 1, nlg
00060     fnn  = real(nn)
00061     facnmg(nn,0) = 1.0d0
00062     do mm = 1, nn
00063       fmm  = real(mm)
00064       fnmfm= fnn-fmm + 1.0d0 
00065       facnmg(nn,mm) = facnmg(nn,mm-1)/(fnn+fmm)/fnmfm
00066     end do
00067   end do
00068 
00069   do mm = 0, nlg 
00070     epsig(mm) = 2.0d+0 
00071     if (mm == 0) epsig(mm) = 1.0d+0 
00072   end do
00073 
00074 end subroutine legendre
00075 SUBROUTINE legendre_theta(pnag,theta)
00076   use phys_constant,  only : nnlg, long
00077   use grid_parameter, only : nlg
00078   implicit none
00079   integer     ::  it, mm, nn, kk
00080   real(long)  ::  fmm, fkk, cc, ss, q1, q2
00081   real(long)  ::  pnag(0:nnlg,0:nnlg), theta, fac(0:nnlg)
00082 
00083   cc = cos(theta)
00084   ss = sin(theta)
00085 
00086   pnag(0:nlg,0:nlg)  = 0.0d0
00087 
00088   fac(0) = 1.0d0
00089   do mm = 1, nlg
00090     fmm = real(mm)
00091     fac(mm) = (2.0d0*fmm-1.0d0) * fac(mm-1)
00092   end do
00093 
00094   pnag(0,0) = 1.d0
00095   do mm = 1, nlg
00096     pnag(mm,mm) = fac(mm) * (-ss)**mm 
00097   end do
00098 
00099   do mm = 0, nlg-1
00100     fmm = real(mm)
00101     pnag(mm+1,mm) = (2.0d0*fmm + 1.0d0)* cc*  pnag(mm,mm)
00102   end do
00103 
00104   do mm = 0, nlg-2
00105     fmm = real(mm)
00106     do kk = 2, nlg-mm
00107       fkk = real(kk)
00108       q1 = ( 2.0d0 * fmm + 2.0d0 * fkk - 1.0d0 ) / fkk
00109       q2 = ( 2.0d0 * fmm + fkk - 1.0d0 ) / fkk
00110       pnag(mm+kk,mm) = q1 * cc * pnag(mm+kk-1,mm)- q2 * pnag(mm+kk-2,mm)
00111     end do
00112   end do
00113 end subroutine legendre_theta
00114 end module legendre_fn_grav