27subroutine wghpot_f(params, constants, workspace, gradphi, f, ddx_error)
29 type(ddx_params_type),
intent(in) :: params
30 type(ddx_constants_type),
intent(in) :: constants
31 real(dp),
intent(in) :: gradphi(3, constants % ncav)
33 type(ddx_workspace_type),
intent(inout) :: workspace
34 type(ddx_error_type),
intent(inout) :: ddx_error
36 real(dp),
intent(out) :: f(params % ngrid, params % nsph)
38 integer :: isph, ig, ic, ind, ind0, jsph
39 real(dp) :: nderphi, sumSijn, sumSijn_pre
40 real(dp),
dimension(3) :: vij, vtij
41 real(dp),
allocatable :: SK_rijn(:), DK_rijn(:), c0(:,:), c1(:,:)
42 integer :: l0, icav, istatus, indl, inode
43 complex(dp) :: work_complex(constants % lmax0 + 1)
44 real(dp) :: work(constants % lmax0 + 1)
47 allocate(sk_rijn(0:constants % lmax0), dk_rijn(0:constants % lmax0), &
48 & c0(constants % nbasis0, params % nsph), &
49 & c1(constants % nbasis0, params % nsph), stat=istatus)
50 if (istatus.ne.0)
then
51 call update_error(ddx_error,
'Allocation in wghpot_f failed')
60 do isph = 1, params % nsph
61 do ig = 1, params % ngrid
62 if (constants % ui(ig, isph) .ne. zero)
then
64 nderphi = dot_product(gradphi(:, ic), constants % cgrid(:,ig))
65 c0(:, isph) = c0(:, isph) + &
66 & constants % wgrid(ig)*constants % ui(ig,isph)*&
67 & nderphi*constants % vgrid(1:constants % nbasis0,ig)
68 do l0 = 0, constants % lmax0
71 c1(ind0:ind, isph) = constants % C_ik(l0, isph) * &
80 if (params % fmm .eq. 0)
then
82 do isph = 1, params % nsph
83 do ig = 1, params % ngrid
84 if (constants % ui(ig,isph).gt.zero)
then
88 do jsph = 1, params % nsph
90 vij = params % csph(:,isph) + &
91 & params % rsph(isph)*constants % cgrid(:,ig) - &
92 & params % csph(:,jsph)
93 vtij = vij*params % kappa
94 call fmm_m2p_bessel_work(vtij, &
95 & constants % lmax0, constants % vscales, &
96 & constants % SK_ri(:, jsph), one, &
97 & c1(:, jsph), one, sumsijn, work_complex, work)
102 f(ig,isph) = -(params % epsp/params % eps)*constants % ui(ig,isph) * sumsijn
108 workspace % tmp_node_m = zero
109 workspace % tmp_node_l = zero
110 workspace % tmp_sph = zero
111 workspace % tmp_sph(1:constants % nbasis0, :) = c1(:, :)
112 if(constants % lmax0 .lt. params % pm)
then
113 do isph = 1, params % nsph
114 inode = constants % snode(isph)
115 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
116 & workspace % tmp_sph(1:constants % nbasis0, isph)
117 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
120 indl = (params % pm+1)**2
121 do isph = 1, params % nsph
122 inode = constants % snode(isph)
123 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
129 & workspace % tmp_node_l)
131 call tree_l2p_bessel(params, constants, one, workspace % tmp_node_l, zero, &
132 & workspace % tmp_grid)
134 & params % lmax, workspace % tmp_sph, one, &
135 & workspace % tmp_grid)
136 f = -(params % epsp/params % eps) * constants % ui * workspace % tmp_grid
139 deallocate(sk_rijn, dk_rijn, c0, c1, stat=istatus)
140 if (istatus.ne.0)
then
141 call update_error(ddx_error,
'Deallocation in wghpot_f failed')
144end subroutine wghpot_f
154subroutine calcv2_lpb (params, constants, isph, pot, x)
155 type(ddx_params_type),
intent(in) :: params
156 type(ddx_constants_type),
intent(in) :: constants
157 integer,
intent(in) :: isph
158 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: x
159 real(dp),
dimension(params % ngrid),
intent(inout) :: pot
160 complex(dp) :: work_complex(params % lmax+1)
161 real(dp) :: work(params % lmax+1)
162 real(dp),
dimension(params % ngrid) :: pot2
163 integer :: its, ij, jsph
164 real(dp) :: vij(3), vtij(3)
165 real(dp) :: vvij, tij, xij, oij
169 do its = 1, params % ngrid
170 if (constants % ui(its,isph).lt.one)
then
171 do ij = constants % inl(isph), constants % inl(isph+1)-1
172 jsph = constants % nl(ij)
175 vij = params % csph(:,isph) + params % rsph(isph)*constants % cgrid(:,its) - params % csph(:,jsph)
176 vvij = sqrt(dot_product(vij,vij))
177 tij = vvij/params % rsph(jsph)
179 if ( tij.lt.( one + (params % se+one)/two*params % eta ) )
then
180 xij = fsw(tij, params % se, params % eta)
181 if (constants % fi(its,isph).gt.one)
then
182 oij = xij/constants % fi(its, isph)
186 vtij = vij*params % kappa
187 call fmm_l2p_bessel_work(vtij, &
188 & params % lmax, constants % vscales, &
189 & constants % SI_ri(:, jsph), oij, x(:, jsph), one, &
190 & pot(its), work_complex, work)
195endsubroutine calcv2_lpb
204subroutine convert_ddcosmo(params, constants, direction, vector)
206 type(ddx_params_type),
intent(in) :: params
207 type(ddx_constants_type),
intent(in) :: constants
208 integer,
intent(in) :: direction
210 real(dp),
intent(inout) :: vector(constants % nbasis, params % nsph)
212 integer :: isph, l, m, ind
215 do isph = 1, params % nsph
216 do l = 0, params % lmax
218 fac = fourpi / (two*dble(l) + one)
219 if (direction .eq. -1) fac = one / fac
221 vector(ind+m, isph) = fac*vector(ind+m, isph)
225end subroutine convert_ddcosmo
239subroutine inthsp(params, constants, rijn, isph, basloc, fac_hsp, work)
241 type(ddx_params_type),
intent(in) :: params
242 type(ddx_constants_type),
intent(in) :: constants
243 integer,
intent(in) :: isph
244 real(dp),
intent(in) :: rijn
245 real(dp),
dimension(constants % nbasis),
intent(in) :: basloc
246 real(dp),
dimension(constants % nbasis),
intent(inout) :: fac_hsp
247 complex(dp),
intent(out) :: work(max(2, params % lmax+1))
248 real(dp),
dimension(0:params % lmax) :: SI_rijn, DI_rijn
254 call modified_spherical_bessel_first_kind(params % lmax, &
255 & rijn*params % kappa, si_rijn, di_rijn, work)
256 do l = 0, params % lmax
258 ind = l*l + l + 1 + m
259 fac_hsp(ind) = si_rijn(l)/constants % SI_ri(l,isph)*basloc(ind)
276subroutine adjrhs_lpb(params, constants, isph, xi, vlm, basloc, &
277 & vplm, vcos, vsin, tmp_bessel)
280 type(ddx_params_type),
intent(in) :: params
281 type(ddx_constants_type),
intent(in) :: constants
282 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
283 real(dp),
dimension((params % lmax+1)**2),
intent(out) :: vlm
284 real(dp),
dimension((params % lmax+1)**2),
intent(out) :: basloc, vplm
285 real(dp),
dimension(params % lmax+1),
intent(out) :: vcos, vsin
286 complex(dp),
dimension(max(2, params % lmax+1)),
intent(out) :: tmp_bessel
287 integer,
intent(in) :: isph
289 integer :: ij, jsph, ig, l, ind, m
290 real(dp) :: vji(3), vvji, tji, sji(3), xji, oji, fac
291 real(dp) :: rho, ctheta, stheta, cphi, sphi
292 real(dp),
dimension(constants % nbasis) :: fac_hsp
295 do ij = constants % inl(isph), constants % inl(isph+1)-1
297 jsph = constants % nl(ij)
299 do ig = 1, params % ngrid
301 vji = params % csph(:,jsph) + params % rsph(jsph)* &
302 & constants % cgrid(:,ig) - params % csph(:,isph)
303 vvji = sqrt(dot_product(vji,vji))
304 tji = vvji/params % rsph(isph)
306 if ( tji.lt.( one + (params % se+one)/two*params % eta ) )
then
308 if (tji.ne.zero)
then
313 call ylmbas(sji, rho, ctheta, stheta, cphi, &
314 & sphi, params % lmax, &
315 & constants % vscales, basloc, &
317 call inthsp_adj(params, constants, vvji, isph, basloc, fac_hsp, &
320 xji = fsw( tji, params % se, params % eta )
322 if ( constants % fi(ig,jsph).gt.one )
then
323 oji = xji/ constants % fi(ig,jsph)
328 fac = constants % wgrid(ig) * xi(ig,jsph) * oji
330 do l = 0, params % lmax
334 vlm(ind+m) = vlm(ind+m) + fac*fac_hsp(ind+m)
340end subroutine adjrhs_lpb
352subroutine inthsp_adj(params, constants, rjin, jsph, basloc, &
356 type(ddx_params_type),
intent(in) :: params
357 type(ddx_constants_type),
intent(in) :: constants
358 integer,
intent(in) :: jsph
359 real(dp),
intent(in) :: rjin
360 real(dp),
dimension(constants % nbasis),
intent(in) :: basloc
361 real(dp),
dimension(constants % nbasis),
intent(inout) :: fac_hsp
362 complex(dp),
intent(out) :: work(max(2, params % lmax+1))
363 real(dp),
dimension(0:params % lmax) :: SI_rjin, DI_rjin
371 call modified_spherical_bessel_first_kind(params % lmax, &
372 & rjin*params % kappa, si_rjin, di_rjin, work)
374 do l = 0, params % lmax
376 ind = l*l + l + 1 + m
377 fac_hsp(ind) = si_rjin(l)/constants % SI_ri(l,jsph)*basloc(ind)
380endsubroutine inthsp_adj
Core routines and parameters of the ddX software.
subroutine tree_l2p_bessel(params, constants, alpha, node_l, beta, grid_v)
TODO.
subroutine tree_m2l_bessel_rotation(params, constants, node_m, node_l)
Transfer multipole local coefficients into local over a tree.
subroutine tree_m2p_bessel(params, constants, p, alpha, sph_p, sph_m, beta, grid_v)
TODO.
subroutine tree_l2l_bessel_rotation(params, constants, node_l)
Transfer local coefficients over a tree.
subroutine tree_m2m_bessel_rotation(params, constants, node_m)
Transfer multipole coefficients over a tree.
Core routines and parameters specific to ddLPB.