18subroutine contract_grad_l(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx)
19type(ddx_params_type),
intent(in) :: params
20 type(ddx_constants_type),
intent(in) :: constants
21 integer,
intent(in) :: isph
22 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
23 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
24 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
25 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
26 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
27 real(dp),
dimension(3),
intent(inout) :: fx
29 call contract_gradi_lik(params, constants, isph, sigma, xi(:, isph), basloc, dbsloc, vplm, vcos, vsin, fx )
30 call contract_gradi_lji(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx )
32end subroutine contract_grad_l
35subroutine contract_gradi_lik(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx )
36 type(ddx_params_type),
intent(in) :: params
37 type(ddx_constants_type),
intent(in) :: constants
38 integer,
intent(in) :: isph
39 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
40 real(dp),
dimension(params % ngrid),
intent(in) :: xi
41 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
42 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
43 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
44 real(dp),
dimension(3),
intent(inout) :: fx
45 integer :: ig, ij, jsph, l, ind, m
46 real(dp) :: vvij, tij, xij, oij, t, fac, fl, f1, f2, f3, beta, tlow, thigh
47 real(dp) :: vij(3), sij(3), alp(3), va(3)
48 real(dp),
external :: dnrm2
49 tlow = one - pt5*(one - params % se)*params % eta
50 thigh = one + pt5*(one + params % se)*params % eta
52 do ig = 1, params % ngrid
54 do ij = constants % inl(isph), constants % inl(isph+1) - 1
55 jsph = constants % nl(ij)
56 vij = params % csph(:,isph) + &
57 & params % rsph(isph)*constants % cgrid(:,ig) - &
58 & params % csph(:,jsph)
59 vvij = dnrm2(3, vij, 1)
60 tij = vvij/params % rsph(jsph)
61 if (tij.ge.thigh) cycle
67 call dbasis(params, constants, sij, basloc, dbsloc, vplm, vcos, vsin)
70 do l = 1, params % lmax
73 fac = t/(constants % vscales(ind)**2)
75 f2 = fac*sigma(ind+m,jsph)
76 f1 = f2*fl*basloc(ind+m)
77 alp(:) = alp(:) + f1*sij(:) + f2*dbsloc(:,ind+m)
81 beta =
intmlp(params, constants, tij,sigma(:,jsph),basloc)
82 xij = fsw(tij, params % se, params % eta)
83 if (constants % fi(ig,isph).gt.one)
then
84 oij = xij/constants % fi(ig,isph)
85 f2 = -oij/constants % fi(ig,isph)
90 f1 = oij/params % rsph(jsph)
91 va(:) = va(:) + f1*alp(:) + beta*f2*constants % zi(:,ig,isph)
92 if (tij .gt. tlow)
then
93 f3 = beta*dfsw(tij,params % se,params % eta)/params % rsph(jsph)
94 if (constants % fi(ig,isph).gt.one) f3 = f3/constants % fi(ig,isph)
95 va(:) = va(:) + f3*sij(:)
98 fx = fx - constants % wgrid(ig)*xi(ig)*va(:)
100end subroutine contract_gradi_lik
103subroutine contract_gradi_lji(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx )
104 type(ddx_params_type),
intent(in) :: params
105 type(ddx_constants_type),
intent(in) :: constants
106 integer,
intent(in) :: isph
107 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
108 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
109 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
110 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
111 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
112 real(dp),
dimension(3),
intent(inout) :: fx
114 integer :: ig, ji, jsph, l, ind, m, jk, ksph
116 real(dp) :: vvji, tji, xji, oji, t, fac, fl, f1, f2, beta, di, tlow, thigh
117 real(dp) :: b, g1, g2, vvjk, tjk, xjk
118 real(dp) :: vji(3), sji(3), alp(3), vb(3), vjk(3), sjk(3), vc(3)
119 real(dp) :: rho, ctheta, stheta, cphi, sphi
120 real(dp),
external :: dnrm2
122 tlow = one - pt5*(one - params % se)*params % eta
123 thigh = one + pt5*(one + params % se)*params % eta
125 do ig = 1, params % ngrid
128 do ji = constants % inl(isph), constants % inl(isph+1) - 1
129 jsph = constants % nl(ji)
130 vji = params % csph(:,jsph) + &
131 & params % rsph(jsph)*constants % cgrid(:,ig) - &
132 & params % csph(:,isph)
133 vvji = dnrm2(3, vji, 1)
134 tji = vvji/params % rsph(isph)
135 if (tji.gt.thigh) cycle
136 if (tji.ne.zero)
then
141 call dbasis(params, constants, sji, basloc, dbsloc, vplm, vcos, vsin)
144 do l = 1, params % lmax
147 fac = t/(constants % vscales(ind)**2)
149 f2 = fac*sigma(ind+m,isph)
150 f1 = f2*fl*basloc(ind+m)
151 alp = alp + f1*sji + f2*dbsloc(:,ind+m)
155 xji = fsw(tji, params % se, params % eta)
156 if (constants % fi(ig,jsph).gt.one)
then
157 oji = xji/constants % fi(ig,jsph)
161 f1 = oji/params % rsph(isph)
162 vb = vb + f1*alp*xi(ig,jsph)
163 if (tji .gt. tlow)
then
164 beta =
intmlp(params, constants, tji, sigma(:,isph), basloc)
165 if (constants % fi(ig,jsph) .gt. one)
then
166 di = one/constants % fi(ig,jsph)
170 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
171 ksph = constants % nl(jk)
172 vjk = params % csph(:,jsph) + &
173 & params % rsph(jsph)*constants % cgrid(:,ig) - &
174 & params % csph(:,ksph)
176 vvjk = dnrm2(3, vjk, 1)
177 tjk = vvjk/params % rsph(ksph)
178 if (ksph.ne.isph)
then
179 if (tjk .le. thigh)
then
183 call ylmbas(sjk, rho, ctheta, stheta, cphi, sphi, &
184 & params % lmax, constants % vscales, basloc, vplm, &
186 g1 =
intmlp(params, constants, tjk, sigma(:,ksph), basloc)
187 xjk = fsw(tjk, params % se, params % eta)
193 g1 = di*di*dfsw(tji, params % se, params % eta)/params % rsph(isph)
194 g2 = g1*xi(ig,jsph)*b
201 f2 = (one-fac)*di*dfsw(tji, params % se, params % eta)/params % rsph(isph)
202 vb = vb + f2*xi(ig,jsph)*beta*sji
205 fx = fx + constants % wgrid(ig)*(vb - vc)
207end subroutine contract_gradi_lji
210subroutine contract_grad_u(params, constants, isph, xi, phi, fx )
211 type(ddx_params_type),
intent(in) :: params
212 type(ddx_constants_type),
intent(in) :: constants
213 integer,
intent(in) :: isph
214 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi, phi
215 real(dp),
dimension(3),
intent(inout) :: fx
216 integer :: ig, ji, jsph
217 real(dp) :: vvji, tji, fac, swthr
218 real(dp) :: alp(3), vji(3), sji(3)
219 real(dp),
external :: dnrm2
220 do ig = 1, params % ngrid
222 if (constants % ui(ig,isph) .gt. zero .and. constants % ui(ig,isph).lt.one)
then
223 alp = alp + phi(ig,isph)*xi(ig,isph)*constants % zi(:,ig,isph)
225 do ji = constants % inl(isph), constants % inl(isph+1) - 1
226 jsph = constants % nl(ji)
227 vji = params % csph(:,jsph) + &
228 & params % rsph(jsph)*constants % cgrid(:,ig) - &
229 & params % csph(:,isph)
231 vvji = dnrm2(3, vji, 1)
232 tji = vvji/params % rsph(isph)
233 swthr = one + (params % se + 1.d0)*params % eta / 2.d0
234 if (tji.lt.swthr .and. tji.gt.swthr-params % eta .and. constants % ui(ig,jsph).gt.zero)
then
236 fac = - dfsw(tji, params % se, params % eta)/params % rsph(isph)
237 alp = alp + fac*phi(ig,jsph)*xi(ig,jsph)*sji
240 fx = fx - constants % wgrid(ig)*alp
242end subroutine contract_grad_u
253subroutine contract_grad_b(params, constants, isph, Xe, Xadj_e, force)
255 type(ddx_params_type),
intent(in) :: params
256 type(ddx_constants_type),
intent(in) :: constants
257 integer,
intent(in) :: isph
258 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
259 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
260 real(dp),
dimension(3),
intent(inout) :: force
262 call contract_gradi_bik(params, constants, isph, xe(:,:), &
263 & xadj_e(:, isph), force)
264 call contract_gradi_bji(params, constants, isph, xe(:,:), xadj_e, force)
266end subroutine contract_grad_b
284subroutine contract_grad_c(params, constants, workspace, Xr, Xe, Xadj_r_sgrid, &
285 & Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
287 type(ddx_params_type),
intent(in) :: params
288 type(ddx_constants_type),
intent(in) :: constants
289 type(ddx_workspace_type),
intent(inout) :: workspace
290 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
291 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_r_sgrid, Xadj_e_sgrid
292 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xadj_r, Xadj_e
293 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
294 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: diff_re
295 type(ddx_error_type),
intent(inout) :: ddx_error
297 call contract_grad_c_worker2(params, constants, workspace, xr, xe, xadj_r_sgrid, &
298 & xadj_e_sgrid, xadj_r, xadj_e, force, diff_re, ddx_error)
299 if (ddx_error % flag .ne. 0)
then
300 call update_error(ddx_error, &
301 &
"contract_grad_C_worker2 returned an error, exiting")
304 call contract_grad_c_worker1(params, constants, workspace, xadj_r_sgrid, &
305 & xadj_e_sgrid, diff_re, force, ddx_error)
306 if (ddx_error % flag .ne. 0)
then
307 call update_error(ddx_error, &
308 &
"contract_grad_C_worker1 returned an error, exiting")
312end subroutine contract_grad_c
325subroutine contract_grad_f(params, constants, workspace, sol_adj, sol_sgrid, &
326 & gradpsi, normal_hessian_cav, force, state, ddx_error)
327 type(ddx_params_type),
intent(in) :: params
328 type(ddx_constants_type),
intent(in) :: constants
329 type(ddx_workspace_type),
intent(inout) :: workspace
331 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sol_adj
332 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
333 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
334 real(dp),
dimension(3, constants % ncav),
intent(in) :: normal_hessian_cav
335 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
336 type(ddx_error_type),
intent(inout) :: ddx_error
338 call contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
339 & gradpsi, force, ddx_error)
340 if (ddx_error % flag .ne. 0)
then
341 call update_error(ddx_error, &
342 &
"contract_grad_f_worker1 returned an error, exiting")
346 call contract_grad_f_worker2(params, constants, gradpsi, &
347 & normal_hessian_cav, force, state, ddx_error)
348 if (ddx_error % flag .ne. 0)
then
349 call update_error(ddx_error, &
350 &
"contract_grad_f_worker2 returned an error, exiting")
354end subroutine contract_grad_f
364subroutine contract_gradi_bik(params, constants, isph, Xe, Xadj_e, force)
366 type(ddx_params_type),
intent(in) :: params
367 type(ddx_constants_type),
intent(in) :: constants
368 integer,
intent(in) :: isph
369 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
370 real(dp),
dimension(params % ngrid),
intent(in) :: Xadj_e
371 real(dp),
dimension(3),
intent(inout) :: force
374 integer :: igrid, ineigh, jsph
375 real(dp),
dimension(0:params % lmax) :: SI_rijn
376 real(dp),
dimension(0:params % lmax) :: DI_rijn
382 real(dp) :: rijn, tij, beta, tlow, thigh, xij, oij, f1, f2, f3
385 real(dp) :: vij(3), sij(3), alpha(3), va(3), rj, vtij(3)
386 real(dp),
external :: dnrm2
387 real(dp) :: work(params % lmax+1)
388 complex(dp) :: work_complex(params % lmax+1)
393 tlow = one - pt5*(one - params % se)*params % eta
394 thigh = one + pt5*(one + params % se)*params % eta
397 do igrid = 1, params % ngrid
399 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
400 jsph = constants % nl(ineigh)
401 vij = params % csph(:,isph) + &
402 & params % rsph(isph)*constants % cgrid(:,igrid) - &
403 & params % csph(:,jsph)
404 rijn = dnrm2(3, vij, 1)
405 tij = rijn/params % rsph(jsph)
406 rj = params % rsph(jsph)
407 if (tij.ge.thigh) cycle
409 if (tij.ne.zero)
then
414 vtij = vij*params % kappa
415 call fmm_l2p_bessel_grad(vtij, params % rsph(jsph)*params % kappa, &
416 & params % lmax, constants % vscales, params % kappa, &
417 & xe(:, jsph), zero, alpha)
418 call fmm_l2p_bessel_work(vtij, params % lmax, constants % vscales, &
419 & constants % SI_ri(:, jsph), one, xe(:, jsph), zero, beta, &
420 & work_complex, work)
421 xij = fsw(tij, params % se, params % eta)
422 if (constants % fi(igrid,isph).gt.one)
then
423 oij = xij/constants % fi(igrid,isph)
424 f2 = -oij/constants % fi(igrid,isph)
430 va(:) = va(:) + f1*alpha(:) + beta*f2*constants % zi(:,igrid,isph)
431 if (tij .gt. tlow)
then
432 f3 = beta*dfsw(tij,params % se,params % eta)/params % rsph(jsph)
433 if (constants % fi(igrid,isph).gt.one) &
434 & f3 = f3/constants % fi(igrid,isph)
435 va(:) = va(:) + f3*sij(:)
438 force = force - constants % wgrid(igrid)*xadj_e(igrid)*va(:)
440end subroutine contract_gradi_bik
452subroutine contract_gradi_bji(params, constants, isph, Xe, Xadj_e, force)
454 type(ddx_params_type),
intent(in) :: params
455 type(ddx_constants_type),
intent(in) :: constants
456 integer,
intent(in) :: isph
457 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
458 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
459 real(dp),
dimension(3),
intent(inout) :: force
463 integer :: igrid, jsph, ksph, ineigh, jk
464 real(dp),
dimension(0:params % lmax) :: SI_rjin, SI_rjkn
465 real(dp),
dimension(0:params % lmax) :: DI_rjin, DI_rjkn
473 real(dp) :: rjin, tji, xji, oji, fac, f1, f2, beta_ji, dj, tlow, thigh
474 real(dp) :: b, beta_jk, g1, g2, rjkn, tjk, xjk
478 real(dp) :: vji(3), sji(3), vjk(3), alpha(3), vb(3), vc(3), &
487 real(dp),
external :: dnrm2
488 real(dp) :: work(params % lmax+1)
489 complex(dp) :: work_complex(params % lmax+1)
496 tlow = one - pt5*(one - params % se)*params % eta
497 thigh = one + pt5*(one + params % se)*params % eta
499 do igrid = 1, params % ngrid
502 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
503 jsph = constants % nl(ineigh)
504 vji = params % csph(:,jsph) + &
505 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
506 & params % csph(:,isph)
507 rjin = dnrm2(3, vji, 1)
508 ri = params % rsph(isph)
510 if (tji.gt.thigh) cycle
511 if (tji.ne.zero)
then
516 vtji = vji*params % kappa
517 call fmm_l2p_bessel_grad(vtji, params % rsph(isph)*params % kappa, &
518 & params % lmax, constants % vscales, params % kappa, &
519 & xe(:, isph), zero, alpha)
520 xji = fsw(tji,params % se,params % eta)
521 if (constants % fi(igrid,jsph).gt.one)
then
522 oji = xji/constants % fi(igrid,jsph)
527 vb = vb + f1*alpha*xadj_e(igrid,jsph)
528 if (tji .gt. tlow)
then
529 call fmm_l2p_bessel_work(vtji, params % lmax, &
530 & constants % vscales, constants % SI_ri(:, isph), one, &
531 & xe(:, isph), zero, beta_ji, work_complex, work)
532 if (constants % fi(igrid,jsph) .gt. one)
then
533 dj = one/constants % fi(igrid,jsph)
537 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
538 ksph = constants % nl(jk)
539 vjk = params % csph(:,jsph) + &
540 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
541 & params % csph(:,ksph)
542 rjkn = dnrm2(3, vjk, 1)
543 tjk = rjkn/params % rsph(ksph)
544 if (ksph.ne.isph)
then
545 if (tjk .le. thigh)
then
547 vtjk = vjk*params % kappa
548 call fmm_l2p_bessel_work(vtjk, params % lmax, &
549 & constants % vscales, &
550 & constants % SI_ri(:, ksph), one, xe(:, ksph), &
551 & zero, beta_jk, work_complex, work)
552 xjk = fsw(tjk, params % se, params % eta)
558 g1 = dj*dj*dfsw(tji,params % se,params % eta) &
559 & /params % rsph(isph)
560 g2 = g1*xadj_e(igrid,jsph)*b
567 f2 = (one-fac)*dj*dfsw(tji,params % se,params % eta) &
568 & /params % rsph(isph)
569 vb = vb + f2*xadj_e(igrid,jsph)*beta_ji*sji
572 force = force + constants % wgrid(igrid)*(vb - vc)
574end subroutine contract_gradi_bji
588subroutine contract_grad_c_worker1(params, constants, workspace, Xadj_r_sgrid, &
589 & Xadj_e_sgrid, diff_re, force, ddx_error)
591 type(ddx_params_type),
intent(in) :: params
592 type(ddx_constants_type),
intent(in) :: constants
593 type(ddx_workspace_type),
intent(inout) :: workspace
594 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
596 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
597 & Xadj_r_sgrid, Xadj_e_sgrid
598 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
599 type(ddx_error_type),
intent(inout) :: ddx_error
602 integer :: isph, jsph, igrid, l0, m0, ind0, igrid0, icav, &
610 real(dp) :: sum_int, sum_r, sum_e
612 real(dp) :: vij(3), sij(3), vtij(3)
619 real(dp),
allocatable :: phi_n_r(:,:), phi_n_e(:,:), coefY_d(:,:,:), &
624 real(dp),
dimension(constants % nbasis):: basloc, vplm
626 real(dp),
dimension(3, constants % nbasis):: dbasloc
629 real(dp),
dimension(params % lmax+1):: vcos, vsin
632 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
633 real(dp) :: coef(constants % nbasis0), work(constants % lmax0+1)
634 complex(dp) :: work_complex(constants % lmax0+1)
636 allocate(phi_n_r(params % ngrid, params % nsph), &
637 & phi_n_e(params % ngrid, params % nsph), &
638 & diff_re_sgrid(params % ngrid, params % nsph), stat=istat)
640 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker1")
658 if (params % fmm .eq. 0)
then
659 allocate(coefy_d(constants % ncav, params % ngrid, params % nsph), &
662 call update_error(ddx_error,
"allocation ddx_error in fmm ddx_contract_grad_C_worker1")
668 do jsph = 1, params % nsph
670 do igrid0 = 1, params % ngrid
673 do isph = 1, params % nsph
675 do igrid = 1, params % ngrid
677 if(constants % ui(igrid, isph) .gt. zero)
then
679 vij = params % csph(:,isph) + &
680 & params % rsph(isph)*constants % cgrid(:,igrid) - &
681 & params % csph(:,jsph)
682 rijn = sqrt(dot_product(vij,vij))
685 do l0 = 0, constants % lmax0
687 ind0 = l0**2 + l0 + m0 + 1
688 coef(ind0) = constants % vgrid(ind0, igrid0) * &
689 & constants % C_ik(l0, jsph)
692 vtij = vij*params % kappa
693 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
694 & constants % vscales, constants % SK_ri(:, jsph), one, &
695 & coef, zero, coefy_d(icav, igrid0, jsph), work_complex, work)
704 do jsph = 1, params % nsph
706 do igrid0 = 1, params % ngrid
711 do isph = 1, params % nsph
713 do igrid = 1, params % ngrid
714 if(constants % ui(igrid, isph) .gt. zero)
then
716 sum_r = sum_r + coefy_d(icav, igrid0, jsph)*xadj_r_sgrid(igrid, isph) &
717 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
718 sum_e = sum_e + coefy_d(icav, igrid0, jsph)*xadj_e_sgrid(igrid, isph) &
719 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
723 phi_n_r(igrid0, jsph) = sum_r
724 phi_n_e(igrid0, jsph) = sum_e
732 do isph = 1, params % nsph
733 workspace % tmp_grid(:, isph) = xadj_r_sgrid(:, isph) * &
734 & constants % wgrid(:) * constants % ui(:, isph)
738 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
740 & zero, workspace % tmp_node_l)
742 & workspace % tmp_node_l)
744 & workspace % tmp_node_l, workspace % tmp_node_m)
746 & workspace % tmp_node_m)
748 if(constants % lmax0 .lt. params % pm)
then
749 do isph = 1, params % nsph
750 inode = constants % snode(isph)
751 workspace % tmp_sph(1:constants % nbasis0, isph) = &
752 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
753 & workspace % tmp_node_m(1:constants % nbasis0, inode)
756 indl = (params % pm+1)**2
757 do isph = 1, params % nsph
758 inode = constants % snode(isph)
759 workspace % tmp_sph(1:indl, isph) = &
760 & workspace % tmp_sph(1:indl, isph) + &
761 & workspace % tmp_node_m(:, inode)
765 do isph = 1, params % nsph
766 do l0 = 0, constants % lmax0
767 ind0 = l0*l0 + l0 + 1
768 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
769 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
770 & constants % C_ik(l0, isph)
774 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
775 & one, constants % vgrid, constants % vgrid_nbasis, &
776 & workspace % tmp_sph, constants % nbasis, zero, phi_n_r, params % ngrid)
781 do isph = 1, params % nsph
782 workspace % tmp_grid(:, isph) = xadj_e_sgrid(:, isph) * &
783 & constants % wgrid(:) * constants % ui(:, isph)
787 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
789 & zero, workspace % tmp_node_l)
791 & workspace % tmp_node_l)
793 & workspace % tmp_node_l, workspace % tmp_node_m)
795 & workspace % tmp_node_m)
797 if(constants % lmax0 .lt. params % pm)
then
798 do isph = 1, params % nsph
799 inode = constants % snode(isph)
800 workspace % tmp_sph(1:constants % nbasis0, isph) = &
801 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
802 & workspace % tmp_node_m(1:constants % nbasis0, inode)
805 indl = (params % pm+1)**2
806 do isph = 1, params % nsph
807 inode = constants % snode(isph)
808 workspace % tmp_sph(1:indl, isph) = &
809 & workspace % tmp_sph(1:indl, isph) + &
810 & workspace % tmp_node_m(:, inode)
814 do isph = 1, params % nsph
815 do l0 = 0, constants % lmax0
816 ind0 = l0*l0 + l0 + 1
817 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
818 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
819 & constants % C_ik(l0, isph)
823 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
824 & one, constants % vgrid, constants % vgrid_nbasis, &
825 & workspace % tmp_sph, constants % nbasis, zero, phi_n_e, params % ngrid)
827 call dgemm(
'T',
'N', params % ngrid, params % nsph, &
828 & constants % nbasis, one, constants % vgrid, constants % vgrid_nbasis, &
829 & diff_re , constants % nbasis, zero, diff_re_sgrid, &
831 do isph = 1, params % nsph
832 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_r, force(:, isph))
833 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_e, force(:, isph))
836 deallocate(phi_n_r, phi_n_e, diff_re_sgrid, stat=istat)
838 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
841 if (
allocated(coefy_d))
then
842 deallocate(coefy_d, stat=istat)
844 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
848end subroutine contract_grad_c_worker1
869subroutine contract_grad_c_worker2(params, constants, workspace, Xr, Xe, &
870 & Xadj_r_sgrid, Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
872 type(ddx_params_type),
intent(in) :: params
873 type(ddx_constants_type),
intent(in) :: constants
874 type(ddx_workspace_type),
intent(inout) :: workspace
875 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
876 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
877 & Xadj_r_sgrid, Xadj_e_sgrid
878 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
880 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
881 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: &
883 type(ddx_error_type),
intent(inout) :: ddx_error
884 real(dp),
external :: dnrm2
886 integer :: isph, jsph, igrid, l, m, ind, l0, ind0, icav, indl, inode, &
887 & ksph, knode, jnode, knear, jsph_node, istat
889 real(dp),
dimension(3) :: vij, vtij
898 real(dp),
allocatable :: diff_ep_dim3(:,:), phi_in(:,:), sum_dim3(:,:,:), &
899 & diff0(:,:), diff1(:,:), diff1_grad(:,:,:), l2l_grad(:,:,:)
900 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
901 complex(dp) :: work_complex(constants % lmax0+2)
902 real(dp) :: work(constants % lmax0+2)
904 allocate(diff_ep_dim3(3, constants % ncav), &
905 & phi_in(params % ngrid, params % nsph), &
906 & sum_dim3(3, constants % nbasis, params % nsph), &
907 & diff0(constants % nbasis0, params % nsph), &
908 & diff1(constants % nbasis0, params % nsph), &
909 & diff1_grad((constants % lmax0+2)**2, 3, params % nsph), &
910 & l2l_grad((params % pl+2)**2, 3, params % nsph), stat=istat)
912 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker2")
924 do jsph = 1, params % nsph
925 do l = 0, params % lmax
927 ind = l**2 + l + m + 1
928 diff_re(ind,jsph) = (params % epsp/params % eps)*(l/params % rsph(jsph)) * &
929 & xr(ind,jsph) - constants % termimat(l,jsph)*xe(ind,jsph)
938 do jsph = 1, params % nsph
939 do l0 = 0, constants % lmax0
940 do ind0 = l0*l0+1, l0*l0+2*l0+1
941 diff0(ind0, jsph) = dot_product(diff_re(:,jsph), &
942 & constants % Pchi(:,ind0, jsph))
943 diff1(ind0, jsph) = diff0(ind0, jsph) * constants % C_ik(l0, jsph)
947 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, jsph), &
948 & constants % vscales, diff1(:, jsph), diff1_grad(:, :, jsph))
951 if (params % fmm .eq. 0)
then
956 do isph = 1, params % nsph
957 do igrid = 1, params % ngrid
958 if(constants % ui(igrid, isph) .gt. zero)
then
962 do jsph = 1, params % nsph
967 vij = params % csph(:, isph) + &
968 & params % rsph(isph)*constants % cgrid(:, igrid) - &
969 & params % csph(:, jsph)
970 vtij = vij * params % kappa
971 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
972 & constants % vscales, constants % SK_ri(:, jsph), one, &
973 & diff1(:, jsph), one, val, work_complex, work)
975 phi_in(igrid, isph) = val
982 workspace % tmp_sph = zero
983 workspace % tmp_sph(1:constants % nbasis0, :) = diff1(:, :)
984 if(constants % lmax0 .lt. params % pm)
then
985 do isph = 1, params % nsph
986 inode = constants % snode(isph)
987 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
988 & workspace % tmp_sph(1:constants % nbasis0, isph)
989 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
992 indl = (params % pm+1)**2
993 do isph = 1, params % nsph
994 inode = constants % snode(isph)
995 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1001 & workspace % tmp_node_l)
1003 call tree_l2p_bessel(params, constants, one, workspace % tmp_node_l, zero, &
1006 & params % lmax, workspace % tmp_sph, one, &
1011 do isph = 1, params % nsph
1012 do igrid = 1, params % ngrid
1013 if (constants % ui(igrid, isph) .eq. zero)
then
1014 phi_in(igrid, isph) = zero
1021 do isph = 1, params % nsph
1022 inode = constants % snode(isph)
1023 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1024 call fmm_l2l_bessel_grad(params % pl, &
1025 & constants % SI_ri(:, isph), constants % vscales, &
1026 & workspace % tmp_node_l(:, inode), &
1027 & l2l_grad(:, :, isph))
1029 workspace % tmp_sph = xadj_r + xadj_e
1030 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1031 & one, constants % vwgrid, constants % vgrid_nbasis, &
1032 & workspace % tmp_sph, constants % nbasis, zero, &
1033 & workspace % tmp_grid, params % ngrid)
1034 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1038 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1040 & workspace % tmp_node_l)
1043 & workspace % tmp_node_m)
1047 if(constants % lmax0+1 .lt. params % pm)
then
1050 do isph = 1, params % nsph
1051 inode = constants % snode(isph)
1052 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1053 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1054 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1057 indl = (params % pm+1)**2
1060 do isph = 1, params % nsph
1061 inode = constants % snode(isph)
1062 workspace % tmp_sph2(1:indl, isph) = &
1063 & workspace % tmp_sph2(1:indl, isph) + &
1064 & workspace % tmp_node_m(:, inode)
1069 do ksph = 1, params % nsph
1071 call contract_grad_u(params, constants, ksph, xadj_r_sgrid, phi_in, force(:, ksph))
1072 call contract_grad_u(params, constants, ksph, xadj_e_sgrid, phi_in, force(:, ksph))
1077 icav = constants % icav_ia(ksph) - 1
1078 if (params % fmm .eq. 0)
then
1079 do igrid = 1, params % ngrid
1080 if (constants % ui(igrid, ksph) .eq. zero) cycle
1082 do jsph = 1, params % nsph
1083 if (jsph .eq. ksph) cycle
1084 vij = params % csph(:,ksph) + &
1085 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1086 & params % csph(:,jsph)
1087 vtij = vij * params % kappa
1093 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1094 & constants % vscales, constants % SK_ri(:, jsph), &
1095 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1096 & diff_ep_dim3(1, icav), work_complex, work)
1097 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1098 & constants % vscales, constants % SK_ri(:, jsph), &
1099 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1100 & diff_ep_dim3(2, icav), work_complex, work)
1101 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1102 & constants % vscales, constants % SK_ri(:, jsph), &
1103 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1104 & diff_ep_dim3(3, icav), work_complex, work)
1108 knode = constants % snode(ksph)
1109 do igrid = 1, params % ngrid
1110 if (constants % ui(igrid, ksph) .eq. zero) cycle
1113 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1114 & l2l_grad(1, 1, ksph), &
1115 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1116 & one, diff_ep_dim3(1, icav), 1)
1118 do knear = constants % snear(knode), constants % snear(knode+1)-1
1119 jnode = constants % near(knear)
1120 do jsph_node = constants % cluster(1, jnode), &
1121 & constants % cluster(2, jnode)
1122 jsph = constants % order(jsph_node)
1123 if (jsph .eq. ksph) cycle
1124 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1125 & params % rsph(ksph)*constants % cgrid(:, igrid)
1126 vtij = vij * params % kappa
1127 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1128 & constants % vscales, constants % SK_ri(:, jsph), &
1129 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1130 & diff_ep_dim3(1, icav), work_complex, work)
1131 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1132 & constants % vscales, constants % SK_ri(:, jsph), &
1133 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1134 & diff_ep_dim3(2, icav), work_complex, work)
1135 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1136 & constants % vscales, constants % SK_ri(:, jsph), &
1137 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1138 & diff_ep_dim3(3, icav), work_complex, work)
1144 icav = constants % icav_ia(ksph) - 1
1145 do igrid =1, params % ngrid
1146 if(constants % ui(igrid, ksph) .gt. zero)
then
1148 do ind = 1, constants % nbasis
1149 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1150 & + diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1151 & *constants % vwgrid(ind, igrid)
1155 do ind = 1, constants % nbasis
1156 force(:, ksph) = force(:, ksph) + &
1157 & sum_dim3(:, ind, ksph)*(xadj_r(ind, ksph) + &
1158 & xadj_e(ind, ksph))
1162 if (params % fmm .eq. 0)
then
1165 do isph = 1, params % nsph
1166 if (isph .eq. ksph) cycle
1167 icav = constants % icav_ia(isph) - 1
1168 do igrid = 1, params % ngrid
1169 if (constants % ui(igrid, isph) .eq. zero) cycle
1171 vij = params % csph(:,isph) + &
1172 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1173 & params % csph(:,ksph)
1174 vtij = vij * params % kappa
1180 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1181 & constants % vscales, constants % SK_ri(:, ksph), &
1182 & params % kappa, diff1_grad(:, 1, ksph), one, &
1183 & diff_ep_dim3(1, icav), work_complex, work)
1184 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1185 & constants % vscales, constants % SK_ri(:, ksph), &
1186 & params % kappa, diff1_grad(:, 2, ksph), one, &
1187 & diff_ep_dim3(2, icav), work_complex, work)
1188 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1189 & constants % vscales, constants % SK_ri(:, ksph), &
1190 & params % kappa, diff1_grad(:, 3, ksph), one, &
1191 & diff_ep_dim3(3, icav), work_complex, work)
1195 do isph = 1, params % nsph
1196 do igrid =1, params % ngrid
1197 if(constants % ui(igrid, isph) .gt. zero)
then
1199 do ind = 1, constants % nbasis
1200 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1201 & + diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1202 & *constants % vwgrid(ind, igrid)
1208 do isph = 1, params % nsph
1209 do ind = 1, constants % nbasis
1210 force(:, ksph) = force(:, ksph) &
1211 & + sum_dim3(:, ind, isph)*(xadj_r(ind, isph) &
1212 & + xadj_e(ind, isph))
1216 call dgemv(
'T', (constants % lmax0+2)**2, 3, params % kappa, &
1217 & diff1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
1218 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
1221 deallocate(diff_ep_dim3, phi_in, sum_dim3, diff1_grad, l2l_grad, &
1222 & diff0, diff1, stat=istat)
1223 if (istat.ne.0)
then
1224 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker2")
1227end subroutine contract_grad_c_worker2
1242subroutine contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
1243 & gradpsi, force, ddx_error)
1245 type(ddx_params_type),
intent(in) :: params
1246 type(ddx_constants_type),
intent(in) :: constants
1247 type(ddx_workspace_type),
intent(inout) :: workspace
1248 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1250 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
1251 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
1252 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1253 type(ddx_error_type),
intent(inout) :: ddx_error
1256 real(dp),
external :: dnrm2
1257 integer :: isph, jsph, igrid, ind, l0, ind0, icav, ksph, &
1258 & knode, jnode, knear, jsph_node, indl, inode, istat
1260 real(dp),
dimension(3) :: vij, vtij
1263 real(dp) :: nderpsi, sum_int
1275 real(dp),
allocatable :: phi_in(:,:), diff_ep_dim3(:,:), &
1276 & sum_dim3(:,:,:), diff0(:,:), sum_sjin(:,:), &
1277 & c0_d(:,:), c0_d1(:,:), c0_d1_grad(:,:,:), l2l_grad(:,:,:)
1278 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1279 complex(dp) :: work_complex(constants % lmax0 + 2)
1280 real(dp) :: work(constants % lmax0 + 2)
1282 allocate(phi_in(params % ngrid, params % nsph), &
1283 & diff_ep_dim3(3, constants % ncav), &
1284 & sum_dim3(3, constants % nbasis, params % nsph), &
1285 & c0_d(constants % nbasis0, params % nsph), &
1286 & c0_d1(constants % nbasis0, params % nsph), &
1287 & c0_d1_grad((constants % lmax0+2)**2, 3, params % nsph), &
1288 & sum_sjin(params % ngrid, params % nsph), &
1289 & l2l_grad((params % pl+2)**2, 3, params % nsph), &
1290 & diff0(constants % nbasis0, params % nsph), stat=istat)
1291 if (istat.ne.0)
then
1292 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker1")
1305 do isph = 1, params % nsph
1306 do igrid= 1, params % ngrid
1307 if ( constants % ui(igrid,isph) .gt. zero )
then
1309 nderpsi = dot_product( gradpsi(:,icav),constants % cgrid(:,igrid) )
1310 c0_d(:, isph) = c0_d(:,isph) + &
1311 & constants % wgrid(igrid)* &
1312 & constants % ui(igrid,isph)*&
1314 & constants % vgrid(1:constants % nbasis0,igrid)
1315 do l0 = 0, constants % lmax0
1316 ind0 = l0*l0 + l0 + 1
1317 c0_d1(ind0-l0:ind0+l0, isph) = c0_d(ind0-l0:ind0+l0, isph) * &
1318 & constants % C_ik(l0, isph)
1321 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, isph), &
1322 & constants % vscales, c0_d1(:, isph), c0_d1_grad(:, :, isph))
1327 if (params % fmm .eq. 0)
then
1330 do isph = 1, params % nsph
1331 do igrid = 1, params % ngrid
1332 if (constants % ui(igrid,isph).gt.zero)
then
1336 do jsph = 1, params % nsph
1337 vij = params % csph(:, isph) + &
1338 & params % rsph(isph)*constants % cgrid(:, igrid) - &
1339 & params % csph(:, jsph)
1340 vtij = vij * params % kappa
1341 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1342 & constants % vscales, constants % SK_ri(:, jsph), one, &
1343 & c0_d1(:, jsph), one, sum_int, work_complex, work)
1345 sum_sjin(igrid,isph) = -(params % epsp/params % eps)*sum_int
1351 workspace % tmp_sph = zero
1352 workspace % tmp_sph(1:constants % nbasis0, :) = c0_d1(:, :)
1353 if(constants % lmax0 .lt. params % pm)
then
1354 do isph = 1, params % nsph
1355 inode = constants % snode(isph)
1356 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
1357 & workspace % tmp_sph(1:constants % nbasis0, isph)
1358 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
1361 indl = (params % pm+1)**2
1362 do isph = 1, params % nsph
1363 inode = constants % snode(isph)
1364 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1370 & workspace % tmp_node_l)
1372 call tree_l2p_bessel(params, constants, -params % epsp/params % eps, workspace % tmp_node_l, zero, &
1374 call tree_m2p_bessel(params, constants, constants % lmax0, -params % epsp/params % eps, &
1375 & params % lmax, workspace % tmp_sph, one, &
1378 do isph = 1, params % nsph
1379 do igrid = 1, params % ngrid
1380 if (constants % ui(igrid, isph) .eq. zero)
then
1381 sum_sjin(igrid, isph) = zero
1386 do isph = 1, params % nsph
1387 inode = constants % snode(isph)
1388 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1389 call fmm_l2l_bessel_grad(params % pl, &
1390 & constants % SI_ri(:, isph), constants % vscales, &
1391 & workspace % tmp_node_l(:, inode), &
1392 & l2l_grad(:, :, isph))
1394 workspace % tmp_sph = sol_adj
1395 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1396 & one, constants % vwgrid, constants % vgrid_nbasis, &
1397 & workspace % tmp_sph, constants % nbasis, zero, &
1398 & workspace % tmp_grid, params % ngrid)
1399 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1403 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1405 & workspace % tmp_node_l)
1408 & workspace % tmp_node_m)
1412 if(constants % lmax0+1 .lt. params % pm)
then
1413 do isph = 1, params % nsph
1414 inode = constants % snode(isph)
1415 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1416 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1417 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1420 indl = (params % pm+1)**2
1421 do isph = 1, params % nsph
1422 inode = constants % snode(isph)
1423 workspace % tmp_sph2(1:indl, isph) = &
1424 & workspace % tmp_sph2(1:indl, isph) + &
1425 & workspace % tmp_node_m(:, inode)
1429 do ksph = 1, params % nsph
1431 call contract_grad_u(params, constants, ksph, sol_sgrid, sum_sjin, force(:, ksph))
1435 icav = constants % icav_ia(ksph) - 1
1436 if (params % fmm .eq. 0)
then
1437 do igrid = 1, params % ngrid
1438 if (constants % ui(igrid, ksph) .eq. zero) cycle
1440 do jsph = 1, params % nsph
1441 if (jsph .eq. ksph) cycle
1442 vij = params % csph(:,ksph) + &
1443 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1444 & params % csph(:,jsph)
1445 vtij = vij * params % kappa
1446 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1447 & constants % vscales, constants % SK_ri(:, jsph), &
1448 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
1449 & diff_ep_dim3(1, icav), work_complex, work)
1450 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1451 & constants % vscales, constants % SK_ri(:, jsph), &
1452 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
1453 & diff_ep_dim3(2, icav), work_complex, work)
1454 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1455 & constants % vscales, constants % SK_ri(:, jsph), &
1456 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
1457 & diff_ep_dim3(3, icav), work_complex, work)
1461 knode = constants % snode(ksph)
1462 do igrid = 1, params % ngrid
1463 if (constants % ui(igrid, ksph) .eq. zero) cycle
1466 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1467 & l2l_grad(1, 1, ksph), &
1468 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1469 & one, diff_ep_dim3(1, icav), 1)
1471 do knear = constants % snear(knode), constants % snear(knode+1)-1
1472 jnode = constants % near(knear)
1473 do jsph_node = constants % cluster(1, jnode), &
1474 & constants % cluster(2, jnode)
1475 jsph = constants % order(jsph_node)
1476 if (jsph .eq. ksph) cycle
1477 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1478 & params % rsph(ksph)*constants % cgrid(:, igrid)
1479 vtij = vij * params % kappa
1480 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1481 & constants % vscales, constants % SK_ri(:, jsph), &
1482 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
1483 & diff_ep_dim3(1, icav), work_complex, work)
1484 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1485 & constants % vscales, constants % SK_ri(:, jsph), &
1486 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
1487 & diff_ep_dim3(2, icav), work_complex, work)
1488 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1489 & constants % vscales, constants % SK_ri(:, jsph), &
1490 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
1491 & diff_ep_dim3(3, icav), work_complex, work)
1497 icav = constants % icav_ia(ksph) - 1
1498 do igrid =1, params % ngrid
1499 if(constants % ui(igrid, ksph) .gt. zero)
then
1501 do ind = 1, constants % nbasis
1502 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1503 & - (params % epsp/params % eps) &
1504 & *diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1505 & *constants % vwgrid(ind, igrid)
1509 do ind = 1, constants % nbasis
1510 force(:, ksph) = force(:, ksph) + &
1511 & sum_dim3(:, ind, ksph)*sol_adj(ind, ksph)
1515 if (params % fmm .eq. 0)
then
1518 do isph = 1, params % nsph
1519 if (isph .eq. ksph) cycle
1520 icav = constants % icav_ia(isph) - 1
1521 do igrid = 1, params % ngrid
1522 if (constants % ui(igrid, isph) .eq. zero) cycle
1524 vij = params % csph(:,isph) + &
1525 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1526 & params % csph(:,ksph)
1527 vtij = vij * params % kappa
1528 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1529 & constants % vscales, constants % SK_ri(:, ksph), &
1530 & params % kappa, c0_d1_grad(:, 1, ksph), one, &
1531 & diff_ep_dim3(1, icav), work_complex, work)
1532 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1533 & constants % vscales, constants % SK_ri(:, ksph), &
1534 & params % kappa, c0_d1_grad(:, 2, ksph), one, &
1535 & diff_ep_dim3(2, icav), work_complex, work)
1536 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1537 & constants % vscales, constants % SK_ri(:, ksph), &
1538 & params % kappa, c0_d1_grad(:, 3, ksph), one, &
1539 & diff_ep_dim3(3, icav), work_complex, work)
1544 do isph = 1, params % nsph
1545 do igrid =1, params % ngrid
1546 if(constants % ui(igrid, isph) .gt. zero)
then
1548 do ind = 1, constants % nbasis
1549 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1550 & - (params % epsp/params % eps) &
1551 & *diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1552 & *constants % vwgrid(ind, igrid)
1559 do isph = 1, params % nsph
1560 do ind = 1, constants % nbasis
1561 force(:, ksph) = force(:, ksph) + sum_dim3(:, ind, isph)*sol_adj(ind, isph)
1565 call dgemv(
'T', (constants % lmax0+2)**2, 3, -params % epsp/params % eps*params % kappa, &
1566 & c0_d1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
1567 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
1571 deallocate(phi_in, diff_ep_dim3, sum_dim3, c0_d, c0_d1, &
1572 & c0_d1_grad, sum_sjin, l2l_grad, diff0, stat=istat)
1573 if (istat.ne.0)
then
1574 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker1")
1578end subroutine contract_grad_f_worker1
1581subroutine contract_grad_f_worker2(params, constants, &
1582 & gradpsi, normal_hessian_cav, force, state, ddx_error)
1583 type(ddx_params_type),
intent(in) :: params
1584 type(ddx_constants_type),
intent(in) :: constants
1585 real(dp),
intent(in) :: gradpsi(3, constants % ncav), &
1586 & normal_hessian_cav(3, constants % ncav)
1587 real(dp),
intent(inout) :: force(3, params % nsph)
1589 type(ddx_error_type),
intent(inout) :: ddx_error
1591 integer :: icav, isph, igrid, istat
1593 real(dp),
allocatable :: gradpsi_grid(:, :)
1595 allocate(gradpsi_grid(params % ngrid, params % nsph), stat=istat)
1596 if (istat.ne.0)
then
1597 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker2")
1602 do isph = 1, params % nsph
1603 do igrid = 1, params % ngrid
1604 if(constants % ui(igrid, isph) .gt. zero)
then
1606 nderpsi = dot_product(gradpsi(:, icav), &
1607 & constants % cgrid(:, igrid))
1608 gradpsi_grid(igrid, isph) = nderpsi
1614 do isph = 1, params % nsph
1615 call contract_grad_u(params, constants, isph, gradpsi_grid, &
1616 & state % phi_n, force(:, isph))
1617 do igrid = 1, params % ngrid
1618 if(constants % ui(igrid, isph) .gt. zero)
then
1620 force(:, isph) = force(:, isph) &
1621 & + constants % wgrid(igrid)*constants % ui(igrid, isph) &
1622 & *state % phi_n(igrid, isph)*normal_hessian_cav(:, icav)
1627 deallocate(gradpsi_grid, stat=istat)
1628 if (istat.ne.0)
then
1629 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker2")
1633end subroutine contract_grad_f_worker2
1636subroutine gradr_sph(params, constants, isph, vplm, vcos, vsin, basloc, &
1637 & dbsloc, g, ygrid, fx)
1640 type(ddx_params_type),
intent(in) :: params
1641 type(ddx_constants_type),
intent(in) :: constants
1642 integer,
intent(in) :: isph
1643 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
1644 & ygrid(params % ngrid, params % nsph)
1645 real(dp),
intent(inout) :: vplm(constants % nbasis), vcos(params % lmax+1), &
1646 & vsin(params % lmax+1), basloc(constants % nbasis), &
1647 & dbsloc(3, constants % nbasis), fx(3)
1649 real(dp) vik(3), sik(3), vki(3), ski(3), vkj(3), skj(3), vji(3), &
1650 & sji(3), va(3), vb(3), a(3)
1654 integer its, ik, ksph, l, m, ind, jsph, icomp, jcomp
1656 real(dp) cx, cy, cz, vvki, tki, gg, fl, fac, vvkj, tkj
1657 real(dp) tt, fcl, fjj, gi, fii, vvji, tji, qji
1658 real(dp) b, vvik, tik, qik, tlow, thigh, duj
1659 real(dp) :: rho, ctheta, stheta, cphi, sphi
1660 real(dp),
external :: dnrm2
1662 tlow = one - pt5*(one - params % se)*params % eta
1663 thigh = one + pt5*(one + params % se)*params % eta
1669 do its = 1, params % ngrid
1671 do ik = constants % inl(isph), constants % inl(isph+1) - 1
1672 ksph = constants % nl(ik)
1674 cx = params % csph(1,ksph) + params % rsph(ksph)*constants % cgrid(1,its)
1675 cy = params % csph(2,ksph) + params % rsph(ksph)*constants % cgrid(2,its)
1676 cz = params % csph(3,ksph) + params % rsph(ksph)*constants % cgrid(3,its)
1677 vki(1) = cx - params % csph(1,isph)
1678 vki(2) = cy - params % csph(2,isph)
1679 vki(3) = cz - params % csph(3,isph)
1682 vvki = dnrm2(3, vki, 1)
1683 tki = vvki/params % rsph(isph)
1690 if ((tki.gt.tlow).and.(tki.lt.thigh) .and. &
1691 & constants % ui(its,ksph).gt.zero)
then
1697 do l = 0, params % lmax
1700 fac = twopi/(two*fl + one)
1703 gg = gg + fac*constants % vgrid(ind+m,its)*g(ind+m,ksph)
1708 do jsph = 1, params % nsph
1709 if (jsph.ne.ksph .and. jsph.ne.isph)
then
1710 vkj(1) = cx - params % csph(1,jsph)
1711 vkj(2) = cy - params % csph(2,jsph)
1712 vkj(3) = cz - params % csph(3,jsph)
1713 vvkj = sqrt(vkj(1)*vkj(1) + vkj(2)*vkj(2) + &
1715 vvkj = dnrm2(3, vkj, 1)
1716 tkj = vvkj/params % rsph(jsph)
1718 call ylmbas(skj, rho, ctheta, stheta, cphi, sphi, &
1719 & params % lmax, constants % vscales, basloc, &
1722 do l = 0, params % lmax
1724 fcl = - fourpi*dble(l)/(two*dble(l)+one)*tt
1727 gg = gg + fcl*g(ind+m,jsph)*basloc(ind+m)
1738 call ylmbas(ski, rho, ctheta, stheta, cphi, sphi, &
1739 & params % lmax, constants % vscales, basloc, &
1742 do l = 0, params % lmax
1744 fcl = - four*pi*dble(l)/(two*dble(l)+one)*tt
1747 gg = gg + fcl*g(ind+m,isph)*basloc(ind+m)
1756 duj = dfsw(tki,params % se, params % eta)/params % rsph(isph)
1757 fjj = duj*constants % wgrid(its)*gg*ygrid(its,ksph)
1758 fx(1) = fx(1) - fjj*ski(1)
1759 fx(2) = fx(2) - fjj*ski(2)
1760 fx(3) = fx(3) - fjj*ski(3)
1765 if (constants % ui(its,isph).gt.zero.and.constants % ui(its,isph).lt.one)
then
1767 do l = 0, params % lmax
1770 fac = twopi/(two*fl + one)
1773 gi = gi + fac*constants % vgrid(ind+m,its)*g(ind+m,isph)
1781 fii = constants % wgrid(its)*gi*ygrid(its,isph)
1782 fx(1) = fx(1) + fii*constants % zi(1,its,isph)
1783 fx(2) = fx(2) + fii*constants % zi(2,its,isph)
1784 fx(3) = fx(3) + fii*constants % zi(3,its,isph)
1790 do its = 1, params % ngrid
1793 do jsph = 1, params % nsph
1794 if (constants % ui(its,jsph).gt.zero .and. jsph.ne.isph)
then
1796 cx = params % csph(1,jsph) + params % rsph(jsph)*constants % cgrid(1,its)
1797 cy = params % csph(2,jsph) + params % rsph(jsph)*constants % cgrid(2,its)
1798 cz = params % csph(3,jsph) + params % rsph(jsph)*constants % cgrid(3,its)
1799 vji(1) = cx - params % csph(1,isph)
1800 vji(2) = cy - params % csph(2,isph)
1801 vji(3) = cz - params % csph(3,isph)
1804 vvji = dnrm2(3, vji, 1)
1805 tji = vvji/params % rsph(isph)
1816 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
1817 & + sji(icomp)*sji(jcomp))
1823 call dbasis(params, constants, sji,basloc,dbsloc,vplm,vcos,vsin)
1828 do l = 0, params % lmax
1831 fcl = - tt*fourpi*fl/(two*fl + one)
1833 fac = fcl*g(ind+m,isph)
1834 b = (fl + one)*basloc(ind+m)/(params % rsph(isph)*tji)
1837 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
1838 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
1839 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
1840 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
1841 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
1842 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
1843 a(1) = a(1) + fac*(sji(1)*b + va(1))
1844 a(2) = a(2) + fac*(sji(2)*b + va(2))
1845 a(3) = a(3) + fac*(sji(3)*b + va(3))
1849 fac = constants % ui(its,jsph)*constants % wgrid(its)*ygrid(its,jsph)
1850 fx(1) = fx(1) - fac*a(1)
1851 fx(2) = fx(2) - fac*a(2)
1852 fx(3) = fx(3) - fac*a(3)
1858 do its = 1, params % ngrid
1859 cx = params % csph(1,isph) + params % rsph(isph)*constants % cgrid(1,its)
1860 cy = params % csph(2,isph) + params % rsph(isph)*constants % cgrid(2,its)
1861 cz = params % csph(3,isph) + params % rsph(isph)*constants % cgrid(3,its)
1865 do ksph = 1, params % nsph
1866 if (constants % ui(its,isph).gt.zero .and. ksph.ne.isph)
then
1868 vik(1) = cx - params % csph(1,ksph)
1869 vik(2) = cy - params % csph(2,ksph)
1870 vik(3) = cz - params % csph(3,ksph)
1873 vvik = dnrm2(3, vik, 1)
1874 tik = vvik/params % rsph(ksph)
1885 sjac(icomp,jcomp) = qik*(sjac(icomp,jcomp) &
1886 & - sik(icomp)*sik(jcomp))
1892 if (constants % ui(its,isph).lt.one)
then
1893 vb(1) = constants % zi(1,its,isph)
1894 vb(2) = constants % zi(2,its,isph)
1895 vb(3) = constants % zi(3,its,isph)
1900 call dbasis(params, constants, sik,basloc,dbsloc,vplm,vcos,vsin)
1904 do l = 0, params % lmax
1907 fcl = - tt*fourpi*fl/(two*fl + one)
1909 fac = fcl*g(ind+m,ksph)
1910 fac = - fac*basloc(ind+m)
1911 a(1) = a(1) + fac*vb(1)
1912 a(2) = a(2) + fac*vb(2)
1913 a(3) = a(3) + fac*vb(3)
1915 fac = constants % ui(its,isph)*fcl*g(ind+m,ksph)
1916 b = - (fl + one)*basloc(ind+m)/(params % rsph(ksph)*tik)
1919 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
1920 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
1921 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
1922 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
1923 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
1924 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
1925 a(1) = a(1) + fac*(sik(1)*b + va(1))
1926 a(2) = a(2) + fac*(sik(2)*b + va(2))
1927 a(3) = a(3) + fac*(sik(3)*b + va(3))
1933 fac = constants % wgrid(its)*ygrid(its,isph)
1934 fx(1) = fx(1) - fac*a(1)
1935 fx(2) = fx(2) - fac*a(2)
1936 fx(3) = fx(3) - fac*a(3)
1938end subroutine gradr_sph
1941subroutine gradr_fmm(params, constants, workspace, g, ygrid, fx)
1944 type(ddx_params_type),
intent(in) :: params
1945 type(ddx_constants_type),
intent(in) :: constants
1946 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
1947 & ygrid(params % ngrid, params % nsph)
1949 type(ddx_workspace_type),
intent(inout) :: workspace
1951 real(dp),
intent(out) :: fx(3, params % nsph)
1953 integer :: indl, indl1, l, isph, igrid, ik, ksph, &
1955 integer :: inear, inode, jnode
1956 real(dp) :: gg, c(3), vki(3), vvki, tki, gg3(3), tmp_gg, tmp_c(3)
1957 real(dp) :: tlow, thigh
1958 real(dp),
dimension(3, 3) :: zx_coord_transform, zy_coord_transform
1959 real(dp),
external :: ddot, dnrm2
1960 real(dp) :: work(params % lmax+2)
1962 zx_coord_transform = 0
1963 zx_coord_transform(3, 2) = 1
1964 zx_coord_transform(2, 3) = 1
1965 zx_coord_transform(1, 1) = 1
1966 zy_coord_transform = 0
1967 zy_coord_transform(1, 2) = 1
1968 zy_coord_transform(2, 1) = 1
1969 zy_coord_transform(3, 3) = 1
1970 tlow = one - pt5*(one - params % se)*params % eta
1971 thigh = one + pt5*(one + params % se)*params % eta
1974 workspace % tmp_sph(1, :) = zero
1976 do l = 1, params % lmax
1978 workspace % tmp_sph(indl:indl1, :) = l * g(indl:indl1, :)
1985 call tree_grad_m2m(params, constants, workspace % tmp_sph, &
1986 & workspace % tmp_sph_grad, workspace % tmp_sph2)
1993 do isph = 1, params % nsph
1994 workspace % tmp_grid(:, isph) = ygrid(:, isph) * &
1995 & constants % wgrid(:) * constants % ui(:, isph)
1999 call tree_m2p_adj(params, constants, params % lmax+1, one, &
2000 & workspace % tmp_grid, zero, workspace % tmp_sph2)
2001 call tree_l2p_adj(params, constants, one, workspace % tmp_grid, zero, &
2002 & workspace % tmp_node_l, workspace % tmp_sph_l)
2005 & workspace % tmp_node_m)
2009 if(params % lmax+1 .lt. params % pm)
then
2010 do isph = 1, params % nsph
2011 inode = constants % snode(isph)
2012 workspace % tmp_sph2(:, isph) = workspace % tmp_sph2(:, isph) + &
2013 & workspace % tmp_node_m(1:constants % grad_nbasis, inode)
2016 indl = (params % pm+1)**2
2017 do isph = 1, params % nsph
2018 inode = constants % snode(isph)
2019 workspace % tmp_sph2(1:indl, isph) = &
2020 & workspace % tmp_sph2(1:indl, isph) + &
2021 & workspace % tmp_node_m(:, inode)
2025 do isph = 1, params % nsph
2026 call dgemv(
'T', constants % grad_nbasis, 3, one, &
2027 & workspace % tmp_sph_grad(1, 1, isph), constants % grad_nbasis, &
2028 & workspace % tmp_sph2(1, isph), 1, zero, fx(1, isph), 1)
2035 if(params % lmax .lt. params % pm)
then
2036 do isph = 1, params % nsph
2037 inode = constants % snode(isph)
2038 workspace % tmp_node_m(:constants % nbasis, inode) = &
2039 & workspace % tmp_sph(:, isph)
2040 workspace % tmp_node_m(constants % nbasis+1:, inode) = zero
2043 indl = (params % pm+1)**2
2044 do isph = 1, params % nsph
2045 inode = constants % snode(isph)
2046 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
2052 & workspace % tmp_node_l)
2054 call tree_l2p(params, constants, one, workspace % tmp_node_l, zero, &
2055 & workspace % tmp_grid, workspace % tmp_sph_l)
2056 call tree_m2p(params, constants, params % lmax, one, &
2057 & workspace % tmp_sph, one, workspace % tmp_grid)
2059 if (params % pl .gt. 0)
then
2060 call tree_grad_l2l(params, constants, workspace % tmp_node_l, &
2061 & workspace % tmp_sph_l_grad, workspace % tmp_sph_l)
2065 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
2066 & pt5, constants % vgrid2, constants % vgrid_nbasis, g, &
2067 & constants % nbasis, -one, workspace % tmp_grid, params % ngrid)
2069 do igrid = 1, params % ngrid
2070 do isph = 1, params % nsph
2071 workspace % tmp_grid(igrid, isph) = &
2072 & workspace % tmp_grid(igrid, isph) * constants % wgrid(igrid) * &
2073 & ygrid(igrid, isph)
2078 do isph = 1, params % nsph
2079 do igrid = 1, params % ngrid
2081 do ik = constants % inl(isph), constants % inl(isph+1) - 1
2082 ksph = constants % nl(ik)
2084 if(constants % ui(igrid, ksph) .eq. zero) cycle
2086 c = params % csph(:, ksph) + &
2087 & params % rsph(ksph)*constants % cgrid(:, igrid)
2088 vki = c - params % csph(:, isph)
2091 vvki = dnrm2(3, vki, 1)
2092 tki = vvki / params % rsph(isph)
2094 if((tki.le.tlow) .or. (tki.ge.thigh)) cycle
2098 gg = workspace % tmp_grid(igrid, ksph)
2105 fx(:, isph) = fx(:, isph) - &
2106 & dfsw(tki, params % se, params % eta)/ &
2107 & params % rsph(isph)*gg*(vki/vvki)
2110 if((constants % ui(igrid,isph).gt.zero) .and. &
2111 & (constants % ui(igrid,isph).lt.one))
then
2115 gg = workspace % tmp_grid(igrid, isph)
2120 fx(:, isph) = fx(:, isph) + gg*constants % zi(:, igrid, isph)
2122 if (constants % ui(igrid, isph) .gt. zero)
then
2129 call dgemv(
'T', params % pl**2, 3, one, &
2130 & workspace % tmp_sph_l_grad(1, 1, isph), &
2131 & (params % pl+1)**2, constants % vgrid2(1, igrid), 1, &
2135 inode = constants % snode(isph)
2136 do inear = constants % snear(inode), constants % snear(inode+1)-1
2137 jnode = constants % near(inear)
2138 do jsph_node = constants % cluster(1, jnode), &
2139 & constants % cluster(2, jnode)
2140 jsph = constants % order(jsph_node)
2141 if (isph .eq. jsph) cycle
2142 c = params % csph(:, isph) + &
2143 & params % rsph(isph)*constants % cgrid(:, igrid)
2144 tmp_c = c - params % csph(:, jsph)
2145 call fmm_m2p_work(tmp_c, &
2146 & params % rsph(jsph), params % lmax+1, &
2147 & constants % vscales_rel, one, &
2148 & workspace % tmp_sph_grad(:, 1, jsph), zero, &
2150 gg3(1) = gg3(1) + tmp_gg
2151 call fmm_m2p_work(tmp_c, &
2152 & params % rsph(jsph), params % lmax+1, &
2153 & constants % vscales_rel, one, &
2154 & workspace % tmp_sph_grad(:, 2, jsph), zero, &
2156 gg3(2) = gg3(2) + tmp_gg
2157 call fmm_m2p_work(tmp_c, &
2158 & params % rsph(jsph), params % lmax+1, &
2159 & constants % vscales_rel, one, &
2160 & workspace % tmp_sph_grad(:, 3, jsph), zero, &
2162 gg3(3) = gg3(3) + tmp_gg
2166 fx(:, isph) = fx(:, isph) - constants % wgrid(igrid)*gg3* &
2167 & ygrid(igrid, isph)*constants % ui(igrid, isph)
2171end subroutine gradr_fmm
2174subroutine gradr(params, constants, workspace, g, ygrid, fx)
2177 type(ddx_params_type),
intent(in) :: params
2178 type(ddx_constants_type),
intent(in) :: constants
2179 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2180 & ygrid(params % ngrid, params % nsph)
2182 type(ddx_workspace_type),
intent(inout) :: workspace
2184 real(dp),
intent(out) :: fx(3, params % nsph)
2186 if (params % fmm .eq. 1)
then
2187 call gradr_fmm(params, constants, workspace, g, ygrid, fx)
2189 call gradr_dense(params, constants, workspace, g, ygrid, fx)
2194subroutine gradr_dense(params, constants, workspace, g, ygrid, fx)
2197 type(ddx_params_type),
intent(in) :: params
2198 type(ddx_constants_type),
intent(in) :: constants
2199 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2200 & ygrid(params % ngrid, params % nsph)
2202 type(ddx_workspace_type),
intent(inout) :: workspace
2204 real(dp),
intent(out) :: fx(3, params % nsph)
2208 do isph = 1, params % nsph
2209 call gradr_sph(params, constants, isph, workspace % tmp_vplm, &
2210 & workspace % tmp_vcos, workspace % tmp_vsin, &
2211 & workspace % tmp_vylm, workspace % tmp_vdylm, &
2212 & g, ygrid, fx(:, isph))
2214end subroutine gradr_dense
2219subroutine zeta_grad(params, constants, state, e_cav, forces)
2221 type(ddx_params_type),
intent(in) :: params
2222 type(ddx_constants_type),
intent(in) :: constants
2224 real(dp),
intent(inout) :: forces(3, params % nsph)
2225 real(dp),
intent(in) :: e_cav(3, constants % ncav)
2227 integer :: icav, isph, igrid
2230 do isph = 1, params % nsph
2231 do igrid = 1, params % ngrid
2232 if (constants % ui(igrid, isph) .eq. zero) cycle
2234 forces(:, isph) = forces(:, isph) + pt5 &
2235 & *state % zeta(icav)*e_cav(:, icav)
2238end subroutine zeta_grad
Core routines and parameters of the ddX software.
subroutine tree_grad_l2l(params, constants, node_l, sph_l_grad, work)
TODO.
subroutine tree_l2p_bessel(params, constants, alpha, node_l, beta, grid_v)
TODO.
subroutine tree_l2p_bessel_adj(params, constants, alpha, grid_v, beta, node_l)
TODO.
subroutine tree_l2l_rotation(params, constants, node_l)
Transfer local coefficients over a tree.
subroutine tree_m2m_rotation(params, constants, node_m)
Transfer multipole coefficients over a tree.
subroutine tree_l2p(params, constants, alpha, node_l, beta, grid_v, sph_l)
TODO.
subroutine tree_l2p_adj(params, constants, alpha, grid_v, beta, node_l, sph_l)
TODO.
subroutine tree_m2l_bessel_rotation(params, constants, node_m, node_l)
Transfer multipole local coefficients into local over a tree.
subroutine tree_m2m_bessel_rotation_adj(params, constants, node_m)
Adjoint transfer multipole coefficients over a tree.
subroutine tree_m2l_rotation(params, constants, node_m, node_l)
Transfer multipole local coefficients into local over a tree.
subroutine tree_m2p(params, constants, p, alpha, sph_m, beta, grid_v)
TODO.
subroutine tree_m2p_bessel(params, constants, p, alpha, sph_p, sph_m, beta, grid_v)
TODO.
subroutine tree_l2l_bessel_rotation_adj(params, constants, node_l)
Adjoint transfer local coefficients over a tree.
subroutine tree_l2l_bessel_rotation(params, constants, node_l)
Transfer local coefficients over a tree.
subroutine tree_m2p_bessel_nodiag_adj(params, constants, p, alpha, grid_v, beta, sph_p, sph_m)
TODO.
subroutine tree_m2l_bessel_rotation_adj(params, constants, node_l, node_m)
Adjoint transfer multipole local coefficients into local over a tree.
subroutine tree_grad_m2m(params, constants, sph_m, sph_m_grad, work)
TODO.
subroutine tree_m2p_adj(params, constants, p, alpha, grid_v, beta, sph_m)
TODO.
subroutine tree_m2p_bessel_adj(params, constants, p, alpha, grid_v, beta, sph_p, sph_m)
TODO.
subroutine tree_m2l_rotation_adj(params, constants, node_l, node_m)
Adjoint transfer multipole local coefficients into local over a tree.
subroutine tree_l2l_rotation_adj(params, constants, node_l)
Adjoint transfer local coefficients over a tree.
subroutine tree_m2m_rotation_adj(params, constants, node_m)
Adjoint transfer multipole coefficients over a tree.
subroutine tree_m2m_bessel_rotation(params, constants, node_m)
Transfer multipole coefficients over a tree.
subroutine dbasis(params, constants, x, basloc, dbsloc, vplm, vcos, vsin)
Compute first derivatives of spherical harmonics.
real(dp) function intmlp(params, constants, t, sigma, basloc)
TODO.
Core routines and parameters specific to gradients.
This defined type contains the primal and adjoint RHSs, the solution of the primal and adjoint linear...