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