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 integer :: its, ij, jsph
163 real(dp) :: vij(3), vtij(3)
164 real(dp) :: vvij, tij, xij, oij, thigh
165 thigh = one + (params % se+one)/two*params % eta
167 if (params%switching.eq.0)
then
168 do its = 1, params % ngrid
169 if (constants % ui(its,isph).lt.one)
then
170 do ij = constants % inl(isph), constants % inl(isph+1)-1
171 jsph = constants % nl(ij)
174 vij = params % csph(:,isph) + params % rsph(isph) &
175 & *constants % cgrid(:,its) - params % csph(:,jsph)
176 vvij = sqrt(dot_product(vij,vij))
177 tij = vvij/params % rsph(jsph)
179 if (tij.lt.thigh)
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)
197 do its = 1, params % ngrid
199 if (constants%ui(its,isph).lt.one)
then
200 d_i = constants%switching%d_ni(its,isph)
201 f_i = constants%switching%f_ni(its,isph)
203 do ij = constants % inl(isph), constants % inl(isph+1)-1
204 jsph = constants % nl(ij)
206 vij = params % csph(:,isph) + params % rsph(isph)* &
207 & constants % cgrid(:,its) - params % csph(:,jsph)
208 vvij = sqrt(vij(1)*vij(1) + vij(2)*vij(2) + vij(3)*vij(3))
209 tij = vvij / params % rsph(jsph)
211 if (tij.lt.thigh)
then
212 xij = fsw(tij, params % se, params % eta)
213 oij = xij/(d_i + f_i)
214 vtij = vij*params % kappa
215 call fmm_l2p_bessel_work(vtij, &
216 & params % lmax, constants % vscales, &
217 & constants % SI_ri(:, jsph), oij, x(:, jsph), one, &
218 & pot(its), work_complex, work)
224end subroutine calcv2_lpb
233subroutine convert_ddcosmo(params, constants, direction, vector)
235 type(ddx_params_type),
intent(in) :: params
236 type(ddx_constants_type),
intent(in) :: constants
237 integer,
intent(in) :: direction
239 real(dp),
intent(inout) :: vector(constants % nbasis, params % nsph)
241 integer :: isph, l, m, ind
244 do isph = 1, params % nsph
245 do l = 0, params % lmax
247 fac = fourpi / (two*dble(l) + one)
248 if (direction .eq. -1) fac = one / fac
250 vector(ind+m, isph) = fac*vector(ind+m, isph)
254end subroutine convert_ddcosmo
268subroutine inthsp(params, constants, rijn, isph, basloc, fac_hsp, work)
270 type(ddx_params_type),
intent(in) :: params
271 type(ddx_constants_type),
intent(in) :: constants
272 integer,
intent(in) :: isph
273 real(dp),
intent(in) :: rijn
274 real(dp),
dimension(constants % nbasis),
intent(in) :: basloc
275 real(dp),
dimension(constants % nbasis),
intent(inout) :: fac_hsp
276 complex(dp),
intent(out) :: work(max(2, params % lmax+1))
277 real(dp),
dimension(0:params % lmax) :: SI_rijn, DI_rijn
283 call modified_spherical_bessel_first_kind(params % lmax, &
284 & rijn*params % kappa, si_rijn, di_rijn, work)
285 do l = 0, params % lmax
287 ind = l*l + l + 1 + m
288 fac_hsp(ind) = si_rijn(l)/constants % SI_ri(l,isph)*basloc(ind)
305subroutine adjrhs_lpb(params, constants, isph, xi, vlm, basloc, &
306 & vplm, vcos, vsin, tmp_bessel)
309 type(ddx_params_type),
intent(in) :: params
310 type(ddx_constants_type),
intent(in) :: constants
311 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
312 real(dp),
dimension((params % lmax+1)**2),
intent(out) :: vlm
313 real(dp),
dimension((params % lmax+1)**2),
intent(out) :: basloc, vplm
314 real(dp),
dimension(params % lmax+1),
intent(out) :: vcos, vsin
315 complex(dp),
dimension(max(2, params % lmax+1)),
intent(out) :: tmp_bessel
316 integer,
intent(in) :: isph
318 integer :: ij, jsph, ig, l, ind, m
319 real(dp) :: vji(3), vvji, tji, sji(3), xji, oji, fac
320 real(dp) :: rho, ctheta, stheta, cphi, sphi
321 real(dp),
dimension(constants % nbasis) :: fac_hsp
322 real(dp) :: thigh, d_j, f_j
323 thigh = one + (params % se+one)/two*params % eta
325 if (params%switching.eq.0)
then
327 do ij = constants % inl(isph), constants % inl(isph+1)-1
329 jsph = constants % nl(ij)
331 do ig = 1, params % ngrid
333 vji = params % csph(:,jsph) + params % rsph(jsph)* &
334 & constants % cgrid(:,ig) - params % csph(:,isph)
335 vvji = sqrt(dot_product(vji,vji))
336 tji = vvji/params % rsph(isph)
338 if (tji.lt.thigh)
then
340 if (tji.ne.zero)
then
345 call ylmbas(sji, rho, ctheta, stheta, cphi, &
346 & sphi, params % lmax, &
347 & constants % vscales, basloc, &
349 call inthsp_adj(params, constants, vvji, isph, basloc, fac_hsp, &
352 xji = fsw(tji, params % se, params % eta)
354 if ( constants % fi(ig,jsph).gt.one )
then
355 oji = xji/ constants % fi(ig,jsph)
360 fac = constants % wgrid(ig) * xi(ig,jsph) * oji
362 do l = 0, params % lmax
366 vlm(ind+m) = vlm(ind+m) + fac*fac_hsp(ind+m)
373 do ij = constants % inl(isph), constants % inl(isph+1)-1
374 jsph = constants % nl(ij)
375 do ig = 1, params % ngrid
376 vji = params % csph(:,jsph) + params % rsph(jsph)* &
377 & constants % cgrid(:,ig) - params % csph(:,isph)
378 vvji = sqrt(dot_product(vji,vji))
379 tji = vvji/params % rsph(isph)
380 if (tji.lt.thigh)
then
381 if (tji.ne.zero)
then
387 call ylmbas(sji, rho, ctheta, stheta, cphi, &
388 & sphi, params % lmax, &
389 & constants % vscales, basloc, &
391 call inthsp_adj(params, constants, vvji, isph, &
392 & basloc, fac_hsp, tmp_bessel)
394 d_j = constants%switching%d_ni(ig,jsph)
395 f_j = constants%switching%f_ni(ig,jsph)
396 xji = fsw(tji, params % se, params % eta)
399 fac = constants % wgrid(ig) * xi(ig,jsph) * oji
400 do l = 0, params % lmax
403 vlm(ind+m) = vlm(ind+m) + fac*fac_hsp(ind+m)
410end subroutine adjrhs_lpb
422subroutine inthsp_adj(params, constants, rjin, jsph, basloc, &
426 type(ddx_params_type),
intent(in) :: params
427 type(ddx_constants_type),
intent(in) :: constants
428 integer,
intent(in) :: jsph
429 real(dp),
intent(in) :: rjin
430 real(dp),
dimension(constants % nbasis),
intent(in) :: basloc
431 real(dp),
dimension(constants % nbasis),
intent(inout) :: fac_hsp
432 complex(dp),
intent(out) :: work(max(2, params % lmax+1))
433 real(dp),
dimension(0:params % lmax) :: SI_rjin, DI_rjin
441 call modified_spherical_bessel_first_kind(params % lmax, &
442 & rjin*params % kappa, si_rjin, di_rjin, work)
444 do l = 0, params % lmax
446 ind = l*l + l + 1 + m
447 fac_hsp(ind) = si_rjin(l)/constants % SI_ri(l,jsph)*basloc(ind)
450endsubroutine 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.