00001 subroutine poisson_solver(sou, pot)
00002 use phys_constant, only : long, pi
00003 use grid_parameter, only : nrg, npg, ntg, nlg
00004 use radial_green_fn_grav, only : hgfn
00005 use legendre_fn_grav, only : plmg, hplmg, facnmg, epsig
00006 use trigonometry_grav_theta
00007 use trigonometry_grav_phi, only : sinmpg, cosmpg
00008 use weight_midpoint_grav, only : hwrtpg
00009 use make_array_3d
00010 implicit none
00011 integer :: im, il
00012 integer :: ir, irr, it, itt, ip, ipp
00013 real(long), pointer :: sou(:,:,:),pot(:,:,:)
00014 real(long) :: pef, wok, pi4inv
00015 real(long), pointer :: work1c(:,:,:)
00016 real(long), pointer :: work2c(:,:,:)
00017 real(long), pointer :: work3c(:,:,:)
00018 real(long), pointer :: work4c(:,:,:)
00019 real(long), pointer :: work1s(:,:,:)
00020 real(long), pointer :: work2s(:,:,:)
00021 real(long), pointer :: work3s(:,:,:)
00022 real(long), pointer :: work4s(:,:,:)
00023
00024 call alloc_array3d(work1c, 1, nrg, 1, ntg, 0, nlg)
00025 call alloc_array3d(work1s, 1, nrg, 1, ntg, 0, nlg)
00026 call alloc_array3d(work2c, 1, nrg, 0, nlg, 0, nlg)
00027 call alloc_array3d(work2s, 1, nrg, 0, nlg, 0, nlg)
00028 call alloc_array3d(work3c, 0, nrg, 0, nlg, 0, nlg)
00029 call alloc_array3d(work3s, 0, nrg, 0, nlg, 0, nlg)
00030 call alloc_array3d(work4c, 0, nrg, 0, ntg, 0, nlg)
00031 call alloc_array3d(work4s, 0, nrg, 0, ntg, 0, nlg)
00032
00033 work1c = 0.0
00034 work1s = 0.0
00035 do im = 0, nlg
00036 do ipp = 1, npg
00037 work1c(1:nrg,1:ntg,im) = work1c(1:nrg,1:ntg,im) &
00038 & + 0.5*hwrtpg(1:nrg,1:ntg,ipp)*sou(1:nrg,1:ntg,ipp) &
00039 & *(cosmpg(im,ipp)+cosmpg(im,ipp-1))
00040 work1s(1:nrg,1:ntg,im) = work1s(1:nrg,1:ntg,im) &
00041 & + 0.5*hwrtpg(1:nrg,1:ntg,ipp)*sou(1:nrg,1:ntg,ipp) &
00042 & *(sinmpg(im,ipp)+sinmpg(im,ipp-1))
00043 end do
00044 end do
00045
00046 work2c = 0.0d0
00047 work2s = 0.0d0
00048 do il = 0, nlg
00049 do im = 0, nlg
00050 pef = epsig(im)*facnmg(il,im)
00051 do itt = 1, ntg
00052 wok = pef*hplmg(il,im,itt)
00053 work2c(1:nrg,il,im) = work2c(1:nrg,il,im) + wok*work1c(1:nrg,itt,im)
00054 work2s(1:nrg,il,im) = work2s(1:nrg,il,im) + wok*work1s(1:nrg,itt,im)
00055 end do
00056 end do
00057 end do
00058
00059 work3c = 0.0d0
00060 work3s = 0.0d0
00061 do ir = 0, nrg
00062 do il = 0, nlg
00063 do irr = 1, nrg
00064 work3c(ir,il,0:nlg) = work3c(ir,il,0:nlg) &
00065 & + work2c(irr,il,0:nlg)*hgfn(irr,il,ir)
00066 work3s(ir,il,0:nlg) = work3s(ir,il,0:nlg) &
00067 & + work2s(irr,il,0:nlg)*hgfn(irr,il,ir)
00068 end do
00069 end do
00070 end do
00071
00072 work4c = 0.0d0
00073 work4s = 0.0d0
00074 do it = 0, ntg
00075 do im = 0, nlg
00076 do il = 0, nlg
00077 work4c(0:nrg,it,im) = work4c(0:nrg,it,im) &
00078 & + work3c(0:nrg,il,im)*plmg(il,im,it)
00079 work4s(0:nrg,it,im) = work4s(0:nrg,it,im) &
00080 & + work3s(0:nrg,il,im)*plmg(il,im,it)
00081 end do
00082 end do
00083 end do
00084
00085 pot = 0.0d0
00086 do ip = 0, npg
00087 do im = 0, nlg
00088 pot(0:nrg,0:ntg,ip) = pot(0:nrg,0:ntg,ip) &
00089 & + work4c(0:nrg,0:ntg,im)*cosmpg(im,ip) &
00090 & + work4s(0:nrg,0:ntg,im)*sinmpg(im,ip)
00091 end do
00092 end do
00093
00094 pi4inv = 1.0d0/4.0d0/pi
00095 pot = - pi4inv*pot
00096
00097 deallocate(work1c)
00098 deallocate(work1s)
00099 deallocate(work2c)
00100 deallocate(work2s)
00101 deallocate(work3c)
00102 deallocate(work3s)
00103 deallocate(work4c)
00104 deallocate(work4s)
00105
00106 end subroutine poisson_solver
00107