18subroutine contract_grad_l(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr)
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
28 real(dp),
optional,
intent(inout) :: dr
41 call contract_gradi_lik(params, constants, isph, sigma, xi(:, isph), basloc, dbsloc, vplm, vcos, vsin, fx, dr_local)
42 call contract_gradi_lji(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr_local)
44 if (do_dr) dr = dr_local
46end subroutine contract_grad_l
49subroutine contract_gradi_lik(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr)
50 type(ddx_params_type),
intent(in) :: params
51 type(ddx_constants_type),
intent(in) :: constants
52 integer,
intent(in) :: isph
53 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
54 real(dp),
dimension(params % ngrid),
intent(in) :: xi
55 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
56 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
57 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
58 real(dp),
dimension(3),
intent(inout) :: fx
59 integer :: ig, ij, jsph, l, ind, m
60 real(dp) :: vvij, tij, xij, oij, t, fac, fl, f1, fr1, f2, fr2, f3, fr3, beta, tlow, thigh
61 real(dp) :: vij(3), sij(3), alp(3), va(3)
62 real(dp) :: dsij, dtij(3), alp1(3), alp2(3), alp_rad, dsij_rad(3), dtij_rad, alp1_rad, alp2_rad, va_rad
63 real(dp),
external :: dnrm2
64 real(dp),
intent(inout) :: dr
65 real(dp) :: sjac(3,3), qij
66 tlow = one - pt5*(one - params % se)*params % eta
67 thigh = one + pt5*(one + params % se)*params % eta
69 do ig = 1, params % ngrid
72 do ij = constants % inl(isph), constants % inl(isph+1) - 1
73 jsph = constants % nl(ij)
74 vij = params % csph(:,isph) + &
75 & params % rsph(isph)*constants % cgrid(:,ig) - &
76 & params % csph(:,jsph)
77 vvij = dnrm2(3, vij, 1)
78 tij = vvij/params % rsph(jsph)
79 if (tij.ge.thigh) cycle
86 dsij = 1.0_dp / (tij*params%rsph(jsph))
87 dtij(:) = sij(:)/params%rsph(jsph)
97 sjac(icomp,jcomp) = qij*(sjac(icomp,jcomp) &
98 & - sij(icomp)*sij(jcomp))
102 dsij_rad = constants%cgrid(:,ig)/vvij &
103 & - vij * dot_product(vij, constants%cgrid(:,ig)) / (vvij**3)
104 dtij_rad = dot_product(vij, constants%cgrid(:,ig)) &
105 & / (vvij*params%rsph(jsph))
107 call dbasis(params, constants, sij, basloc, dbsloc, vplm, vcos, vsin)
117 do l = 1, params % lmax
120 fac = t/(constants % vscales(ind)**2)
122 f2 = fac*sigma(ind+m,jsph)
123 f1 = f2*fl*basloc(ind+m)
126 alp1_rad = f1*dtij_rad
128 alp2(1) = sjac(1,1)*dbsloc(1,ind+m) + &
129 & sjac(1,2)*dbsloc(2,ind+m)+sjac(1,3)*dbsloc(3,ind+m)
130 alp2(2) = sjac(2,1)*dbsloc(1,ind+m) + &
131 & sjac(2,2)*dbsloc(2,ind+m)+sjac(2,3)*dbsloc(3,ind+m)
132 alp2(3) = sjac(3,1)*dbsloc(1,ind+m) + &
133 & sjac(3,2)*dbsloc(2,ind+m)+sjac(3,3)*dbsloc(3,ind+m)
134 alp2(:) = alp2(:)*tij*f2
136 alp2_rad = f2*tij*dot_product(dsij_rad, dbsloc(:,ind+m))
138 alp(:) = alp(:) + alp1(:) + alp2(:)
139 alp_rad = alp_rad + alp1_rad + alp2_rad
144 beta =
intmlp(params, constants, tij,sigma(:,jsph),basloc)
145 xij = fsw(tij, params % se, params % eta)
146 if (constants % fi(ig,isph).gt.one)
then
147 oij = xij/constants % fi(ig,isph)
148 f2 = -oij/constants % fi(ig,isph)
154 va(:) = va(:) + f1*alp(:) + beta*f2*constants % zi(:,ig,isph)
155 va_rad = va_rad + f1*alp_rad + beta*f2*constants % zi_dr(ig,isph)
156 if (tij .gt. tlow)
then
157 f3 = beta*dfsw(tij,params % se,params % eta)
158 if (constants % fi(ig,isph).gt.one) f3 = f3/constants % fi(ig,isph)
159 va(:) = va(:) + f3*dtij
160 va_rad = va_rad + f3*dtij_rad
163 fx = fx - constants % wgrid(ig)*xi(ig)*va(:)
164 dr = dr - constants % wgrid(ig)*xi(ig)*va_rad
166end subroutine contract_gradi_lik
169subroutine contract_gradi_lji(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr)
170 type(ddx_params_type),
intent(in) :: params
171 type(ddx_constants_type),
intent(in) :: constants
172 integer,
intent(in) :: isph
173 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
174 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
175 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
176 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
177 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
178 real(dp),
dimension(3),
intent(inout) :: fx
180 integer :: ig, ji, jsph, l, ind, m, jk, ksph
182 real(dp) :: vvji, tji, xji, oji, t, fac, fl, f1, f2, beta, di, tlow, thigh
183 real(dp) :: b, g1, g2, vvjk, tjk, xjk
184 real(dp) :: vji(3), sji(3), alp(3), vb(3), vjk(3), sjk(3), vc(3)
185 real(dp) :: dsji, dtji(3), alp1(3), alp2(3), alp_rad, dsji_rad(3), dtji_rad, alp1_rad, alp2_rad, vb_rad, vc_rad
186 real(dp) :: rho, ctheta, stheta, cphi, sphi
187 real(dp),
external :: dnrm2
188 real(dp),
intent(inout) :: dr
189 real(dp) :: sjac(3,3), qji
191 tlow = one - pt5*(one - params % se)*params % eta
192 thigh = one + pt5*(one + params % se)*params % eta
194 do ig = 1, params % ngrid
201 do ji = constants % inl(isph), constants % inl(isph+1) - 1
202 jsph = constants % nl(ji)
203 vji = params % csph(:,jsph) + &
204 & params % rsph(jsph)*constants % cgrid(:,ig) - &
205 & params % csph(:,isph)
206 vvji = dnrm2(3, vji, 1)
207 tji = vvji/params % rsph(isph)
208 if (tji.gt.thigh) cycle
209 if (tji.ne.zero)
then
223 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
224 & + sji(icomp)*sji(jcomp))
228 dsji = 1.0_dp/(tji*params % rsph(isph))
229 dtji(:) = -sji/params % rsph(isph)
232 dtji_rad = -tji/params%rsph(isph)
234 call dbasis(params, constants, sji, basloc, dbsloc, vplm, vcos, vsin)
244 do l = 1, params % lmax
247 fac = t/(constants % vscales(ind)**2)
249 f2 = fac*sigma(ind+m,isph)
250 f1 = f2*fl*basloc(ind+m)
253 alp1_rad = f1*dtji_rad
255 alp2(1) = sjac(1,1)*dbsloc(1,ind+m) + &
256 & sjac(1,2)*dbsloc(2,ind+m)+sjac(1,3)*dbsloc(3,ind+m)
257 alp2(2) = sjac(2,1)*dbsloc(1,ind+m) + &
258 & sjac(2,2)*dbsloc(2,ind+m)+sjac(2,3)*dbsloc(3,ind+m)
259 alp2(3) = sjac(3,1)*dbsloc(1,ind+m) + &
260 & sjac(3,2)*dbsloc(2,ind+m)+sjac(3,3)*dbsloc(3,ind+m)
261 alp2(:) = alp2(:)*tji*f2
263 alp2_rad = f2*tji*dot_product(dsji_rad,dbsloc(:,ind+m))
265 alp(:) = alp(:) + alp1(:) + alp2(:)
266 alp_rad = alp_rad + alp1_rad + alp2_rad
272 xji = fsw(tji, params % se, params % eta)
273 if (constants % fi(ig,jsph).gt.one)
then
274 oji = xji/constants % fi(ig,jsph)
278 vb = vb + oji*alp*xi(ig,jsph)
279 vb_rad = vb_rad + oji*alp_rad*xi(ig,jsph)
280 if (tji .gt. tlow)
then
281 beta =
intmlp(params, constants, tji, sigma(:,isph), basloc)
282 if (constants % fi(ig,jsph) .gt. one)
then
283 di = one/constants % fi(ig,jsph)
287 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
288 ksph = constants % nl(jk)
289 vjk = params % csph(:,jsph) + &
290 & params % rsph(jsph)*constants % cgrid(:,ig) - &
291 & params % csph(:,ksph)
293 vvjk = dnrm2(3, vjk, 1)
294 tjk = vvjk/params % rsph(ksph)
295 if (ksph.ne.isph)
then
296 if (tjk .le. thigh)
then
300 call ylmbas(sjk, rho, ctheta, stheta, cphi, sphi, &
301 & params % lmax, constants % vscales, basloc, vplm, &
303 g1 =
intmlp(params, constants, tjk, sigma(:,ksph), basloc)
304 xjk = fsw(tjk, params % se, params % eta)
310 g1 = di*di*dfsw(tji, params % se, params % eta)
311 g2 = g1*xi(ig,jsph)*b
313 vc_rad = vc_rad - g2*dtji_rad
319 f2 = (one-fac)*di*dfsw(tji, params % se, params % eta)
320 vb = vb + f2*xi(ig,jsph)*beta*dtji
321 vb_rad = vb_rad + f2*xi(ig,jsph)*beta*dtji_rad
324 fx = fx - constants % wgrid(ig)*(vb + vc)
325 dr = dr - constants % wgrid(ig)*(vb_rad + vc_rad)
327end subroutine contract_gradi_lji
332subroutine contract_grad_u(params, constants, isph, xi, phi, fx, dr)
333 type(ddx_params_type),
intent(in) :: params
334 type(ddx_constants_type),
intent(in) :: constants
335 integer,
intent(in) :: isph
336 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi, phi
337 real(dp),
dimension(3),
intent(inout) :: fx
338 real(dp),
optional,
intent(inout) :: dr
339 integer :: ig, ji, jsph
340 real(dp) :: vvji, tji, fac, swthr
341 real(dp) :: alp(3), vji(3), sji(3), dtji(3)
342 real(dp) :: dtji_rad, alp_rad
343 real(dp),
external :: dnrm2
347 if (
present(dr))
then
353 do ig = 1, params % ngrid
356 if (constants % ui(ig,isph) .gt. zero .and. constants % ui(ig,isph).lt.one)
then
357 alp = alp + phi(ig,isph)*xi(ig,isph)*constants % zi(:,ig,isph)
358 alp_rad = alp_rad + phi(ig,isph)*xi(ig,isph)*constants % zi_dr(ig,isph)
360 do ji = constants % inl(isph), constants % inl(isph+1) - 1
361 jsph = constants % nl(ji)
362 vji = params % csph(:,jsph) + &
363 & params % rsph(jsph)*constants % cgrid(:,ig) - &
364 & params % csph(:,isph)
366 vvji = dnrm2(3, vji, 1)
367 tji = vvji/params % rsph(isph)
368 swthr = one + (params % se + 1.d0)*params % eta / 2.d0
369 if (tji.lt.swthr .and. tji.gt.swthr-params % eta .and. constants % ui(ig,jsph).gt.zero)
then
371 dtji = - sji / params % rsph(isph)
372 dtji_rad = - vvji/(params%rsph(isph)**2)
374 fac = dfsw(tji, params % se, params % eta)
375 alp = alp + fac*phi(ig,jsph)*xi(ig,jsph) * dtji
376 alp_rad = alp_rad + fac*phi(ig,jsph)*xi(ig,jsph) * dtji_rad
380 if (
present(dr))
then
381 dr = dr - constants % wgrid(ig)*alp_rad
383 fx = fx - constants % wgrid(ig)*alp
387end subroutine contract_grad_u
398subroutine contract_grad_b(params, constants, isph, Xe, Xadj_e, force)
400 type(ddx_params_type),
intent(in) :: params
401 type(ddx_constants_type),
intent(in) :: constants
402 integer,
intent(in) :: isph
403 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
404 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
405 real(dp),
dimension(3),
intent(inout) :: force
407 call contract_gradi_bik(params, constants, isph, xe(:,:), &
408 & xadj_e(:, isph), force)
409 call contract_gradi_bji(params, constants, isph, xe(:,:), xadj_e, force)
411end subroutine contract_grad_b
429subroutine contract_grad_c(params, constants, workspace, Xr, Xe, Xadj_r_sgrid, &
430 & Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
432 type(ddx_params_type),
intent(in) :: params
433 type(ddx_constants_type),
intent(in) :: constants
434 type(ddx_workspace_type),
intent(inout) :: workspace
435 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
436 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_r_sgrid, Xadj_e_sgrid
437 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xadj_r, Xadj_e
438 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
439 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: diff_re
440 type(ddx_error_type),
intent(inout) :: ddx_error
442 call contract_grad_c_worker2(params, constants, workspace, xr, xe, xadj_r_sgrid, &
443 & xadj_e_sgrid, xadj_r, xadj_e, force, diff_re, ddx_error)
444 if (ddx_error % flag .ne. 0)
then
445 call update_error(ddx_error, &
446 &
"contract_grad_C_worker2 returned an error, exiting")
449 call contract_grad_c_worker1(params, constants, workspace, xadj_r_sgrid, &
450 & xadj_e_sgrid, diff_re, force, ddx_error)
451 if (ddx_error % flag .ne. 0)
then
452 call update_error(ddx_error, &
453 &
"contract_grad_C_worker1 returned an error, exiting")
457end subroutine contract_grad_c
470subroutine contract_grad_f(params, constants, workspace, sol_adj, sol_sgrid, &
471 & gradpsi, normal_hessian_cav, force, state, ddx_error)
472 type(ddx_params_type),
intent(in) :: params
473 type(ddx_constants_type),
intent(in) :: constants
474 type(ddx_workspace_type),
intent(inout) :: workspace
476 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sol_adj
477 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
478 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
479 real(dp),
dimension(3, constants % ncav),
intent(in) :: normal_hessian_cav
480 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
481 type(ddx_error_type),
intent(inout) :: ddx_error
483 call contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
484 & gradpsi, force, ddx_error)
485 if (ddx_error % flag .ne. 0)
then
486 call update_error(ddx_error, &
487 &
"contract_grad_f_worker1 returned an error, exiting")
491 call contract_grad_f_worker2(params, constants, gradpsi, &
492 & normal_hessian_cav, force, state, ddx_error)
493 if (ddx_error % flag .ne. 0)
then
494 call update_error(ddx_error, &
495 &
"contract_grad_f_worker2 returned an error, exiting")
499end subroutine contract_grad_f
509subroutine contract_gradi_bik(params, constants, isph, Xe, Xadj_e, force)
511 type(ddx_params_type),
intent(in) :: params
512 type(ddx_constants_type),
intent(in) :: constants
513 integer,
intent(in) :: isph
514 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
515 real(dp),
dimension(params % ngrid),
intent(in) :: Xadj_e
516 real(dp),
dimension(3),
intent(inout) :: force
519 integer :: igrid, ineigh, jsph
520 real(dp),
dimension(0:params % lmax) :: SI_rijn
521 real(dp),
dimension(0:params % lmax) :: DI_rijn
527 real(dp) :: rijn, tij, beta, tlow, thigh, xij, oij, f1, f2, f3
530 real(dp) :: vij(3), sij(3), alpha(3), va(3), rj, vtij(3)
531 real(dp),
external :: dnrm2
532 real(dp) :: work(params % lmax+1)
533 complex(dp) :: work_complex(params % lmax+1)
538 tlow = one - pt5*(one - params % se)*params % eta
539 thigh = one + pt5*(one + params % se)*params % eta
542 do igrid = 1, params % ngrid
544 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
545 jsph = constants % nl(ineigh)
546 vij = params % csph(:,isph) + &
547 & params % rsph(isph)*constants % cgrid(:,igrid) - &
548 & params % csph(:,jsph)
549 rijn = dnrm2(3, vij, 1)
550 tij = rijn/params % rsph(jsph)
551 rj = params % rsph(jsph)
552 if (tij.ge.thigh) cycle
554 if (tij.ne.zero)
then
559 vtij = vij*params % kappa
560 call fmm_l2p_bessel_grad(vtij, params % rsph(jsph)*params % kappa, &
561 & params % lmax, constants % vscales, params % kappa, &
562 & xe(:, jsph), zero, alpha)
563 call fmm_l2p_bessel_work(vtij, params % lmax, constants % vscales, &
564 & constants % SI_ri(:, jsph), one, xe(:, jsph), zero, beta, &
565 & work_complex, work)
566 xij = fsw(tij, params % se, params % eta)
567 if (constants % fi(igrid,isph).gt.one)
then
568 oij = xij/constants % fi(igrid,isph)
569 f2 = -oij/constants % fi(igrid,isph)
575 va(:) = va(:) + f1*alpha(:) + beta*f2*constants % zi(:,igrid,isph)
576 if (tij .gt. tlow)
then
577 f3 = beta*dfsw(tij,params % se,params % eta)/params % rsph(jsph)
578 if (constants % fi(igrid,isph).gt.one) &
579 & f3 = f3/constants % fi(igrid,isph)
580 va(:) = va(:) + f3*sij(:)
583 force = force - constants % wgrid(igrid)*xadj_e(igrid)*va(:)
585end subroutine contract_gradi_bik
597subroutine contract_gradi_bji(params, constants, isph, Xe, Xadj_e, force)
599 type(ddx_params_type),
intent(in) :: params
600 type(ddx_constants_type),
intent(in) :: constants
601 integer,
intent(in) :: isph
602 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
603 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
604 real(dp),
dimension(3),
intent(inout) :: force
608 integer :: igrid, jsph, ksph, ineigh, jk
609 real(dp),
dimension(0:params % lmax) :: SI_rjin, SI_rjkn
610 real(dp),
dimension(0:params % lmax) :: DI_rjin, DI_rjkn
618 real(dp) :: rjin, tji, xji, oji, fac, f1, f2, beta_ji, dj, tlow, thigh
619 real(dp) :: b, beta_jk, g1, g2, rjkn, tjk, xjk
623 real(dp) :: vji(3), sji(3), vjk(3), alpha(3), vb(3), vc(3), &
632 real(dp),
external :: dnrm2
633 real(dp) :: work(params % lmax+1)
634 complex(dp) :: work_complex(params % lmax+1)
641 tlow = one - pt5*(one - params % se)*params % eta
642 thigh = one + pt5*(one + params % se)*params % eta
644 do igrid = 1, params % ngrid
647 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
648 jsph = constants % nl(ineigh)
649 vji = params % csph(:,jsph) + &
650 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
651 & params % csph(:,isph)
652 rjin = dnrm2(3, vji, 1)
653 ri = params % rsph(isph)
655 if (tji.gt.thigh) cycle
656 if (tji.ne.zero)
then
661 vtji = vji*params % kappa
662 call fmm_l2p_bessel_grad(vtji, params % rsph(isph)*params % kappa, &
663 & params % lmax, constants % vscales, params % kappa, &
664 & xe(:, isph), zero, alpha)
665 xji = fsw(tji,params % se,params % eta)
666 if (constants % fi(igrid,jsph).gt.one)
then
667 oji = xji/constants % fi(igrid,jsph)
672 vb = vb + f1*alpha*xadj_e(igrid,jsph)
673 if (tji .gt. tlow)
then
674 call fmm_l2p_bessel_work(vtji, params % lmax, &
675 & constants % vscales, constants % SI_ri(:, isph), one, &
676 & xe(:, isph), zero, beta_ji, work_complex, work)
677 if (constants % fi(igrid,jsph) .gt. one)
then
678 dj = one/constants % fi(igrid,jsph)
682 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
683 ksph = constants % nl(jk)
684 vjk = params % csph(:,jsph) + &
685 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
686 & params % csph(:,ksph)
687 rjkn = dnrm2(3, vjk, 1)
688 tjk = rjkn/params % rsph(ksph)
689 if (ksph.ne.isph)
then
690 if (tjk .le. thigh)
then
692 vtjk = vjk*params % kappa
693 call fmm_l2p_bessel_work(vtjk, params % lmax, &
694 & constants % vscales, &
695 & constants % SI_ri(:, ksph), one, xe(:, ksph), &
696 & zero, beta_jk, work_complex, work)
697 xjk = fsw(tjk, params % se, params % eta)
703 g1 = dj*dj*dfsw(tji,params % se,params % eta) &
704 & /params % rsph(isph)
705 g2 = g1*xadj_e(igrid,jsph)*b
712 f2 = (one-fac)*dj*dfsw(tji,params % se,params % eta) &
713 & /params % rsph(isph)
714 vb = vb + f2*xadj_e(igrid,jsph)*beta_ji*sji
717 force = force + constants % wgrid(igrid)*(vb - vc)
719end subroutine contract_gradi_bji
733subroutine contract_grad_c_worker1(params, constants, workspace, Xadj_r_sgrid, &
734 & Xadj_e_sgrid, diff_re, force, ddx_error)
736 type(ddx_params_type),
intent(in) :: params
737 type(ddx_constants_type),
intent(in) :: constants
738 type(ddx_workspace_type),
intent(inout) :: workspace
739 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
741 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
742 & Xadj_r_sgrid, Xadj_e_sgrid
743 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
744 type(ddx_error_type),
intent(inout) :: ddx_error
747 integer :: isph, jsph, igrid, l0, m0, ind0, igrid0, icav, &
755 real(dp) :: sum_int, sum_r, sum_e
757 real(dp) :: vij(3), sij(3), vtij(3)
764 real(dp),
allocatable :: phi_n_r(:,:), phi_n_e(:,:), coefY_d(:,:,:), &
769 real(dp),
dimension(constants % nbasis):: basloc, vplm
771 real(dp),
dimension(3, constants % nbasis):: dbasloc
774 real(dp),
dimension(params % lmax+1):: vcos, vsin
777 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
778 real(dp) :: coef(constants % nbasis0), work(constants % lmax0+1)
779 complex(dp) :: work_complex(constants % lmax0+1)
781 allocate(phi_n_r(params % ngrid, params % nsph), &
782 & phi_n_e(params % ngrid, params % nsph), &
783 & diff_re_sgrid(params % ngrid, params % nsph), stat=istat)
785 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker1")
803 if (params % fmm .eq. 0)
then
804 allocate(coefy_d(constants % ncav, params % ngrid, params % nsph), &
807 call update_error(ddx_error,
"allocation ddx_error in fmm ddx_contract_grad_C_worker1")
813 do jsph = 1, params % nsph
815 do igrid0 = 1, params % ngrid
818 do isph = 1, params % nsph
820 do igrid = 1, params % ngrid
822 if(constants % ui(igrid, isph) .gt. zero)
then
824 vij = params % csph(:,isph) + &
825 & params % rsph(isph)*constants % cgrid(:,igrid) - &
826 & params % csph(:,jsph)
827 rijn = sqrt(dot_product(vij,vij))
830 do l0 = 0, constants % lmax0
832 ind0 = l0**2 + l0 + m0 + 1
833 coef(ind0) = constants % vgrid(ind0, igrid0) * &
834 & constants % C_ik(l0, jsph)
837 vtij = vij*params % kappa
838 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
839 & constants % vscales, constants % SK_ri(:, jsph), one, &
840 & coef, zero, coefy_d(icav, igrid0, jsph), work_complex, work)
849 do jsph = 1, params % nsph
851 do igrid0 = 1, params % ngrid
856 do isph = 1, params % nsph
858 do igrid = 1, params % ngrid
859 if(constants % ui(igrid, isph) .gt. zero)
then
861 sum_r = sum_r + coefy_d(icav, igrid0, jsph)*xadj_r_sgrid(igrid, isph) &
862 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
863 sum_e = sum_e + coefy_d(icav, igrid0, jsph)*xadj_e_sgrid(igrid, isph) &
864 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
868 phi_n_r(igrid0, jsph) = sum_r
869 phi_n_e(igrid0, jsph) = sum_e
877 do isph = 1, params % nsph
878 workspace % tmp_grid(:, isph) = xadj_r_sgrid(:, isph) * &
879 & constants % wgrid(:) * constants % ui(:, isph)
883 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
885 & zero, workspace % tmp_node_l)
887 & workspace % tmp_node_l)
889 & workspace % tmp_node_l, workspace % tmp_node_m)
891 & workspace % tmp_node_m)
893 if(constants % lmax0 .lt. params % pm)
then
894 do isph = 1, params % nsph
895 inode = constants % snode(isph)
896 workspace % tmp_sph(1:constants % nbasis0, isph) = &
897 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
898 & workspace % tmp_node_m(1:constants % nbasis0, inode)
901 indl = (params % pm+1)**2
902 do isph = 1, params % nsph
903 inode = constants % snode(isph)
904 workspace % tmp_sph(1:indl, isph) = &
905 & workspace % tmp_sph(1:indl, isph) + &
906 & workspace % tmp_node_m(:, inode)
910 do isph = 1, params % nsph
911 do l0 = 0, constants % lmax0
912 ind0 = l0*l0 + l0 + 1
913 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
914 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
915 & constants % C_ik(l0, isph)
919 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
920 & one, constants % vgrid, constants % vgrid_nbasis, &
921 & workspace % tmp_sph, constants % nbasis, zero, phi_n_r, params % ngrid)
926 do isph = 1, params % nsph
927 workspace % tmp_grid(:, isph) = xadj_e_sgrid(:, isph) * &
928 & constants % wgrid(:) * constants % ui(:, isph)
932 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
934 & zero, workspace % tmp_node_l)
936 & workspace % tmp_node_l)
938 & workspace % tmp_node_l, workspace % tmp_node_m)
940 & workspace % tmp_node_m)
942 if(constants % lmax0 .lt. params % pm)
then
943 do isph = 1, params % nsph
944 inode = constants % snode(isph)
945 workspace % tmp_sph(1:constants % nbasis0, isph) = &
946 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
947 & workspace % tmp_node_m(1:constants % nbasis0, inode)
950 indl = (params % pm+1)**2
951 do isph = 1, params % nsph
952 inode = constants % snode(isph)
953 workspace % tmp_sph(1:indl, isph) = &
954 & workspace % tmp_sph(1:indl, isph) + &
955 & workspace % tmp_node_m(:, inode)
959 do isph = 1, params % nsph
960 do l0 = 0, constants % lmax0
961 ind0 = l0*l0 + l0 + 1
962 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
963 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
964 & constants % C_ik(l0, isph)
968 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
969 & one, constants % vgrid, constants % vgrid_nbasis, &
970 & workspace % tmp_sph, constants % nbasis, zero, phi_n_e, params % ngrid)
972 call dgemm(
'T',
'N', params % ngrid, params % nsph, &
973 & constants % nbasis, one, constants % vgrid, constants % vgrid_nbasis, &
974 & diff_re , constants % nbasis, zero, diff_re_sgrid, &
976 do isph = 1, params % nsph
977 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_r, force(:, isph))
978 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_e, force(:, isph))
981 deallocate(phi_n_r, phi_n_e, diff_re_sgrid, stat=istat)
983 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
986 if (
allocated(coefy_d))
then
987 deallocate(coefy_d, stat=istat)
989 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
993end subroutine contract_grad_c_worker1
1014subroutine contract_grad_c_worker2(params, constants, workspace, Xr, Xe, &
1015 & Xadj_r_sgrid, Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
1017 type(ddx_params_type),
intent(in) :: params
1018 type(ddx_constants_type),
intent(in) :: constants
1019 type(ddx_workspace_type),
intent(inout) :: workspace
1020 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
1021 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
1022 & Xadj_r_sgrid, Xadj_e_sgrid
1023 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1025 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1026 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: &
1028 type(ddx_error_type),
intent(inout) :: ddx_error
1029 real(dp),
external :: dnrm2
1031 integer :: isph, jsph, igrid, l, m, ind, l0, ind0, icav, indl, inode, &
1032 & ksph, knode, jnode, knear, jsph_node, istat
1034 real(dp),
dimension(3) :: vij, vtij
1043 real(dp),
allocatable :: diff_ep_dim3(:,:), phi_in(:,:), sum_dim3(:,:,:), &
1044 & diff0(:,:), diff1(:,:), diff1_grad(:,:,:), l2l_grad(:,:,:)
1045 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1046 complex(dp) :: work_complex(constants % lmax0+2)
1047 real(dp) :: work(constants % lmax0+2)
1049 allocate(diff_ep_dim3(3, constants % ncav), &
1050 & phi_in(params % ngrid, params % nsph), &
1051 & sum_dim3(3, constants % nbasis, params % nsph), &
1052 & diff0(constants % nbasis0, params % nsph), &
1053 & diff1(constants % nbasis0, params % nsph), &
1054 & diff1_grad((constants % lmax0+2)**2, 3, params % nsph), &
1055 & l2l_grad((params % pl+2)**2, 3, params % nsph), stat=istat)
1056 if (istat.ne.0)
then
1057 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker2")
1069 do jsph = 1, params % nsph
1070 do l = 0, params % lmax
1072 ind = l**2 + l + m + 1
1073 diff_re(ind,jsph) = (params % epsp/params % eps)*(l/params % rsph(jsph)) * &
1074 & xr(ind,jsph) - constants % termimat(l,jsph)*xe(ind,jsph)
1083 do jsph = 1, params % nsph
1084 do l0 = 0, constants % lmax0
1085 do ind0 = l0*l0+1, l0*l0+2*l0+1
1086 diff0(ind0, jsph) = dot_product(diff_re(:,jsph), &
1087 & constants % Pchi(:,ind0, jsph))
1088 diff1(ind0, jsph) = diff0(ind0, jsph) * constants % C_ik(l0, jsph)
1092 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, jsph), &
1093 & constants % vscales, diff1(:, jsph), diff1_grad(:, :, jsph))
1096 if (params % fmm .eq. 0)
then
1101 do isph = 1, params % nsph
1102 do igrid = 1, params % ngrid
1103 if(constants % ui(igrid, isph) .gt. zero)
then
1107 do jsph = 1, params % nsph
1112 vij = params % csph(:, isph) + &
1113 & params % rsph(isph)*constants % cgrid(:, igrid) - &
1114 & params % csph(:, jsph)
1115 vtij = vij * params % kappa
1116 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1117 & constants % vscales, constants % SK_ri(:, jsph), one, &
1118 & diff1(:, jsph), one, val, work_complex, work)
1120 phi_in(igrid, isph) = val
1127 workspace % tmp_sph = zero
1128 workspace % tmp_sph(1:constants % nbasis0, :) = diff1(:, :)
1129 if(constants % lmax0 .lt. params % pm)
then
1130 do isph = 1, params % nsph
1131 inode = constants % snode(isph)
1132 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
1133 & workspace % tmp_sph(1:constants % nbasis0, isph)
1134 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
1137 indl = (params % pm+1)**2
1138 do isph = 1, params % nsph
1139 inode = constants % snode(isph)
1140 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1146 & workspace % tmp_node_l)
1148 call tree_l2p_bessel(params, constants, one, workspace % tmp_node_l, zero, &
1151 & params % lmax, workspace % tmp_sph, one, &
1156 do isph = 1, params % nsph
1157 do igrid = 1, params % ngrid
1158 if (constants % ui(igrid, isph) .eq. zero)
then
1159 phi_in(igrid, isph) = zero
1166 do isph = 1, params % nsph
1167 inode = constants % snode(isph)
1168 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1169 call fmm_l2l_bessel_grad(params % pl, &
1170 & constants % SI_ri(:, isph), constants % vscales, &
1171 & workspace % tmp_node_l(:, inode), &
1172 & l2l_grad(:, :, isph))
1174 workspace % tmp_sph = xadj_r + xadj_e
1175 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1176 & one, constants % vwgrid, constants % vgrid_nbasis, &
1177 & workspace % tmp_sph, constants % nbasis, zero, &
1178 & workspace % tmp_grid, params % ngrid)
1179 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1183 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1185 & workspace % tmp_node_l)
1188 & workspace % tmp_node_m)
1192 if(constants % lmax0+1 .lt. params % pm)
then
1195 do isph = 1, params % nsph
1196 inode = constants % snode(isph)
1197 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1198 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1199 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1202 indl = (params % pm+1)**2
1205 do isph = 1, params % nsph
1206 inode = constants % snode(isph)
1207 workspace % tmp_sph2(1:indl, isph) = &
1208 & workspace % tmp_sph2(1:indl, isph) + &
1209 & workspace % tmp_node_m(:, inode)
1214 do ksph = 1, params % nsph
1216 call contract_grad_u(params, constants, ksph, xadj_r_sgrid, phi_in, force(:, ksph))
1217 call contract_grad_u(params, constants, ksph, xadj_e_sgrid, phi_in, force(:, ksph))
1222 icav = constants % icav_ia(ksph) - 1
1223 if (params % fmm .eq. 0)
then
1224 do igrid = 1, params % ngrid
1225 if (constants % ui(igrid, ksph) .eq. zero) cycle
1227 do jsph = 1, params % nsph
1228 if (jsph .eq. ksph) cycle
1229 vij = params % csph(:,ksph) + &
1230 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1231 & params % csph(:,jsph)
1232 vtij = vij * params % kappa
1238 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1239 & constants % vscales, constants % SK_ri(:, jsph), &
1240 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1241 & diff_ep_dim3(1, icav), work_complex, work)
1242 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1243 & constants % vscales, constants % SK_ri(:, jsph), &
1244 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1245 & diff_ep_dim3(2, icav), work_complex, work)
1246 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1247 & constants % vscales, constants % SK_ri(:, jsph), &
1248 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1249 & diff_ep_dim3(3, icav), work_complex, work)
1253 knode = constants % snode(ksph)
1254 do igrid = 1, params % ngrid
1255 if (constants % ui(igrid, ksph) .eq. zero) cycle
1258 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1259 & l2l_grad(1, 1, ksph), &
1260 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1261 & one, diff_ep_dim3(1, icav), 1)
1263 do knear = constants % snear(knode), constants % snear(knode+1)-1
1264 jnode = constants % near(knear)
1265 do jsph_node = constants % cluster(1, jnode), &
1266 & constants % cluster(2, jnode)
1267 jsph = constants % order(jsph_node)
1268 if (jsph .eq. ksph) cycle
1269 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1270 & params % rsph(ksph)*constants % cgrid(:, igrid)
1271 vtij = vij * params % kappa
1272 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1273 & constants % vscales, constants % SK_ri(:, jsph), &
1274 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1275 & diff_ep_dim3(1, icav), work_complex, work)
1276 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1277 & constants % vscales, constants % SK_ri(:, jsph), &
1278 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1279 & diff_ep_dim3(2, icav), work_complex, work)
1280 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1281 & constants % vscales, constants % SK_ri(:, jsph), &
1282 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1283 & diff_ep_dim3(3, icav), work_complex, work)
1289 icav = constants % icav_ia(ksph) - 1
1290 do igrid =1, params % ngrid
1291 if(constants % ui(igrid, ksph) .gt. zero)
then
1293 do ind = 1, constants % nbasis
1294 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1295 & + diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1296 & *constants % vwgrid(ind, igrid)
1300 do ind = 1, constants % nbasis
1301 force(:, ksph) = force(:, ksph) + &
1302 & sum_dim3(:, ind, ksph)*(xadj_r(ind, ksph) + &
1303 & xadj_e(ind, ksph))
1307 if (params % fmm .eq. 0)
then
1310 do isph = 1, params % nsph
1311 if (isph .eq. ksph) cycle
1312 icav = constants % icav_ia(isph) - 1
1313 do igrid = 1, params % ngrid
1314 if (constants % ui(igrid, isph) .eq. zero) cycle
1316 vij = params % csph(:,isph) + &
1317 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1318 & params % csph(:,ksph)
1319 vtij = vij * params % kappa
1325 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1326 & constants % vscales, constants % SK_ri(:, ksph), &
1327 & params % kappa, diff1_grad(:, 1, ksph), one, &
1328 & diff_ep_dim3(1, icav), work_complex, work)
1329 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1330 & constants % vscales, constants % SK_ri(:, ksph), &
1331 & params % kappa, diff1_grad(:, 2, ksph), one, &
1332 & diff_ep_dim3(2, icav), work_complex, work)
1333 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1334 & constants % vscales, constants % SK_ri(:, ksph), &
1335 & params % kappa, diff1_grad(:, 3, ksph), one, &
1336 & diff_ep_dim3(3, icav), work_complex, work)
1340 do isph = 1, params % nsph
1341 do igrid =1, params % ngrid
1342 if(constants % ui(igrid, isph) .gt. zero)
then
1344 do ind = 1, constants % nbasis
1345 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1346 & + diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1347 & *constants % vwgrid(ind, igrid)
1353 do isph = 1, params % nsph
1354 do ind = 1, constants % nbasis
1355 force(:, ksph) = force(:, ksph) &
1356 & + sum_dim3(:, ind, isph)*(xadj_r(ind, isph) &
1357 & + xadj_e(ind, isph))
1361 call dgemv(
'T', (constants % lmax0+2)**2, 3, params % kappa, &
1362 & diff1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
1363 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
1366 deallocate(diff_ep_dim3, phi_in, sum_dim3, diff1_grad, l2l_grad, &
1367 & diff0, diff1, stat=istat)
1368 if (istat.ne.0)
then
1369 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker2")
1372end subroutine contract_grad_c_worker2
1387subroutine contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
1388 & gradpsi, force, ddx_error)
1390 type(ddx_params_type),
intent(in) :: params
1391 type(ddx_constants_type),
intent(in) :: constants
1392 type(ddx_workspace_type),
intent(inout) :: workspace
1393 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1395 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
1396 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
1397 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1398 type(ddx_error_type),
intent(inout) :: ddx_error
1401 real(dp),
external :: dnrm2
1402 integer :: isph, jsph, igrid, ind, l0, ind0, icav, ksph, &
1403 & knode, jnode, knear, jsph_node, indl, inode, istat
1405 real(dp),
dimension(3) :: vij, vtij
1408 real(dp) :: nderpsi, sum_int
1420 real(dp),
allocatable :: phi_in(:,:), diff_ep_dim3(:,:), &
1421 & sum_dim3(:,:,:), diff0(:,:), sum_sjin(:,:), &
1422 & c0_d(:,:), c0_d1(:,:), c0_d1_grad(:,:,:), l2l_grad(:,:,:)
1423 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1424 complex(dp) :: work_complex(constants % lmax0 + 2)
1425 real(dp) :: work(constants % lmax0 + 2)
1427 allocate(phi_in(params % ngrid, params % nsph), &
1428 & diff_ep_dim3(3, constants % ncav), &
1429 & sum_dim3(3, constants % nbasis, params % nsph), &
1430 & c0_d(constants % nbasis0, params % nsph), &
1431 & c0_d1(constants % nbasis0, params % nsph), &
1432 & c0_d1_grad((constants % lmax0+2)**2, 3, params % nsph), &
1433 & sum_sjin(params % ngrid, params % nsph), &
1434 & l2l_grad((params % pl+2)**2, 3, params % nsph), &
1435 & diff0(constants % nbasis0, params % nsph), stat=istat)
1436 if (istat.ne.0)
then
1437 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker1")
1450 do isph = 1, params % nsph
1451 do igrid= 1, params % ngrid
1452 if ( constants % ui(igrid,isph) .gt. zero )
then
1454 nderpsi = dot_product( gradpsi(:,icav),constants % cgrid(:,igrid) )
1455 c0_d(:, isph) = c0_d(:,isph) + &
1456 & constants % wgrid(igrid)* &
1457 & constants % ui(igrid,isph)*&
1459 & constants % vgrid(1:constants % nbasis0,igrid)
1460 do l0 = 0, constants % lmax0
1461 ind0 = l0*l0 + l0 + 1
1462 c0_d1(ind0-l0:ind0+l0, isph) = c0_d(ind0-l0:ind0+l0, isph) * &
1463 & constants % C_ik(l0, isph)
1466 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, isph), &
1467 & constants % vscales, c0_d1(:, isph), c0_d1_grad(:, :, isph))
1472 if (params % fmm .eq. 0)
then
1475 do isph = 1, params % nsph
1476 do igrid = 1, params % ngrid
1477 if (constants % ui(igrid,isph).gt.zero)
then
1481 do jsph = 1, params % nsph
1482 vij = params % csph(:, isph) + &
1483 & params % rsph(isph)*constants % cgrid(:, igrid) - &
1484 & params % csph(:, jsph)
1485 vtij = vij * params % kappa
1486 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1487 & constants % vscales, constants % SK_ri(:, jsph), one, &
1488 & c0_d1(:, jsph), one, sum_int, work_complex, work)
1490 sum_sjin(igrid,isph) = -(params % epsp/params % eps)*sum_int
1496 workspace % tmp_sph = zero
1497 workspace % tmp_sph(1:constants % nbasis0, :) = c0_d1(:, :)
1498 if(constants % lmax0 .lt. params % pm)
then
1499 do isph = 1, params % nsph
1500 inode = constants % snode(isph)
1501 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
1502 & workspace % tmp_sph(1:constants % nbasis0, isph)
1503 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
1506 indl = (params % pm+1)**2
1507 do isph = 1, params % nsph
1508 inode = constants % snode(isph)
1509 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1515 & workspace % tmp_node_l)
1517 call tree_l2p_bessel(params, constants, -params % epsp/params % eps, workspace % tmp_node_l, zero, &
1519 call tree_m2p_bessel(params, constants, constants % lmax0, -params % epsp/params % eps, &
1520 & params % lmax, workspace % tmp_sph, one, &
1523 do isph = 1, params % nsph
1524 do igrid = 1, params % ngrid
1525 if (constants % ui(igrid, isph) .eq. zero)
then
1526 sum_sjin(igrid, isph) = zero
1531 do isph = 1, params % nsph
1532 inode = constants % snode(isph)
1533 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1534 call fmm_l2l_bessel_grad(params % pl, &
1535 & constants % SI_ri(:, isph), constants % vscales, &
1536 & workspace % tmp_node_l(:, inode), &
1537 & l2l_grad(:, :, isph))
1539 workspace % tmp_sph = sol_adj
1540 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1541 & one, constants % vwgrid, constants % vgrid_nbasis, &
1542 & workspace % tmp_sph, constants % nbasis, zero, &
1543 & workspace % tmp_grid, params % ngrid)
1544 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1548 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1550 & workspace % tmp_node_l)
1553 & workspace % tmp_node_m)
1557 if(constants % lmax0+1 .lt. params % pm)
then
1558 do isph = 1, params % nsph
1559 inode = constants % snode(isph)
1560 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1561 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1562 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1565 indl = (params % pm+1)**2
1566 do isph = 1, params % nsph
1567 inode = constants % snode(isph)
1568 workspace % tmp_sph2(1:indl, isph) = &
1569 & workspace % tmp_sph2(1:indl, isph) + &
1570 & workspace % tmp_node_m(:, inode)
1574 do ksph = 1, params % nsph
1576 call contract_grad_u(params, constants, ksph, sol_sgrid, sum_sjin, force(:, ksph))
1580 icav = constants % icav_ia(ksph) - 1
1581 if (params % fmm .eq. 0)
then
1582 do igrid = 1, params % ngrid
1583 if (constants % ui(igrid, ksph) .eq. zero) cycle
1585 do jsph = 1, params % nsph
1586 if (jsph .eq. ksph) cycle
1587 vij = params % csph(:,ksph) + &
1588 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1589 & params % csph(:,jsph)
1590 vtij = vij * params % kappa
1591 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1592 & constants % vscales, constants % SK_ri(:, jsph), &
1593 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
1594 & diff_ep_dim3(1, icav), work_complex, work)
1595 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1596 & constants % vscales, constants % SK_ri(:, jsph), &
1597 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
1598 & diff_ep_dim3(2, icav), work_complex, work)
1599 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1600 & constants % vscales, constants % SK_ri(:, jsph), &
1601 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
1602 & diff_ep_dim3(3, icav), work_complex, work)
1606 knode = constants % snode(ksph)
1607 do igrid = 1, params % ngrid
1608 if (constants % ui(igrid, ksph) .eq. zero) cycle
1611 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1612 & l2l_grad(1, 1, ksph), &
1613 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1614 & one, diff_ep_dim3(1, icav), 1)
1616 do knear = constants % snear(knode), constants % snear(knode+1)-1
1617 jnode = constants % near(knear)
1618 do jsph_node = constants % cluster(1, jnode), &
1619 & constants % cluster(2, jnode)
1620 jsph = constants % order(jsph_node)
1621 if (jsph .eq. ksph) cycle
1622 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1623 & params % rsph(ksph)*constants % cgrid(:, igrid)
1624 vtij = vij * params % kappa
1625 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1626 & constants % vscales, constants % SK_ri(:, jsph), &
1627 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
1628 & diff_ep_dim3(1, icav), work_complex, work)
1629 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1630 & constants % vscales, constants % SK_ri(:, jsph), &
1631 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
1632 & diff_ep_dim3(2, icav), work_complex, work)
1633 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1634 & constants % vscales, constants % SK_ri(:, jsph), &
1635 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
1636 & diff_ep_dim3(3, icav), work_complex, work)
1642 icav = constants % icav_ia(ksph) - 1
1643 do igrid =1, params % ngrid
1644 if(constants % ui(igrid, ksph) .gt. zero)
then
1646 do ind = 1, constants % nbasis
1647 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1648 & - (params % epsp/params % eps) &
1649 & *diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1650 & *constants % vwgrid(ind, igrid)
1654 do ind = 1, constants % nbasis
1655 force(:, ksph) = force(:, ksph) + &
1656 & sum_dim3(:, ind, ksph)*sol_adj(ind, ksph)
1660 if (params % fmm .eq. 0)
then
1663 do isph = 1, params % nsph
1664 if (isph .eq. ksph) cycle
1665 icav = constants % icav_ia(isph) - 1
1666 do igrid = 1, params % ngrid
1667 if (constants % ui(igrid, isph) .eq. zero) cycle
1669 vij = params % csph(:,isph) + &
1670 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1671 & params % csph(:,ksph)
1672 vtij = vij * params % kappa
1673 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1674 & constants % vscales, constants % SK_ri(:, ksph), &
1675 & params % kappa, c0_d1_grad(:, 1, ksph), one, &
1676 & diff_ep_dim3(1, icav), work_complex, work)
1677 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1678 & constants % vscales, constants % SK_ri(:, ksph), &
1679 & params % kappa, c0_d1_grad(:, 2, ksph), one, &
1680 & diff_ep_dim3(2, icav), work_complex, work)
1681 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1682 & constants % vscales, constants % SK_ri(:, ksph), &
1683 & params % kappa, c0_d1_grad(:, 3, ksph), one, &
1684 & diff_ep_dim3(3, icav), work_complex, work)
1689 do isph = 1, params % nsph
1690 do igrid =1, params % ngrid
1691 if(constants % ui(igrid, isph) .gt. zero)
then
1693 do ind = 1, constants % nbasis
1694 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1695 & - (params % epsp/params % eps) &
1696 & *diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1697 & *constants % vwgrid(ind, igrid)
1704 do isph = 1, params % nsph
1705 do ind = 1, constants % nbasis
1706 force(:, ksph) = force(:, ksph) + sum_dim3(:, ind, isph)*sol_adj(ind, isph)
1710 call dgemv(
'T', (constants % lmax0+2)**2, 3, -params % epsp/params % eps*params % kappa, &
1711 & c0_d1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
1712 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
1716 deallocate(phi_in, diff_ep_dim3, sum_dim3, c0_d, c0_d1, &
1717 & c0_d1_grad, sum_sjin, l2l_grad, diff0, stat=istat)
1718 if (istat.ne.0)
then
1719 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker1")
1723end subroutine contract_grad_f_worker1
1726subroutine contract_grad_f_worker2(params, constants, &
1727 & gradpsi, normal_hessian_cav, force, state, ddx_error)
1728 type(ddx_params_type),
intent(in) :: params
1729 type(ddx_constants_type),
intent(in) :: constants
1730 real(dp),
intent(in) :: gradpsi(3, constants % ncav), &
1731 & normal_hessian_cav(3, constants % ncav)
1732 real(dp),
intent(inout) :: force(3, params % nsph)
1734 type(ddx_error_type),
intent(inout) :: ddx_error
1736 integer :: icav, isph, igrid, istat
1738 real(dp),
allocatable :: gradpsi_grid(:, :)
1740 allocate(gradpsi_grid(params % ngrid, params % nsph), stat=istat)
1741 if (istat.ne.0)
then
1742 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker2")
1747 do isph = 1, params % nsph
1748 do igrid = 1, params % ngrid
1749 if(constants % ui(igrid, isph) .gt. zero)
then
1751 nderpsi = dot_product(gradpsi(:, icav), &
1752 & constants % cgrid(:, igrid))
1753 gradpsi_grid(igrid, isph) = nderpsi
1759 do isph = 1, params % nsph
1760 call contract_grad_u(params, constants, isph, gradpsi_grid, &
1761 & state % phi_n, force(:, isph))
1762 do igrid = 1, params % ngrid
1763 if(constants % ui(igrid, isph) .gt. zero)
then
1765 force(:, isph) = force(:, isph) &
1766 & + constants % wgrid(igrid)*constants % ui(igrid, isph) &
1767 & *state % phi_n(igrid, isph)*normal_hessian_cav(:, icav)
1772 deallocate(gradpsi_grid, stat=istat)
1773 if (istat.ne.0)
then
1774 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker2")
1778end subroutine contract_grad_f_worker2
1781subroutine gradr_sph(params, constants, isph, vplm, vcos, vsin, basloc, &
1782 & dbsloc, g, ygrid, fx)
1785 type(ddx_params_type),
intent(in) :: params
1786 type(ddx_constants_type),
intent(in) :: constants
1787 integer,
intent(in) :: isph
1788 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
1789 & ygrid(params % ngrid, params % nsph)
1790 real(dp),
intent(inout) :: vplm(constants % nbasis), vcos(params % lmax+1), &
1791 & vsin(params % lmax+1), basloc(constants % nbasis), &
1792 & dbsloc(3, constants % nbasis), fx(3)
1794 real(dp) vik(3), sik(3), vki(3), ski(3), vkj(3), skj(3), vji(3), &
1795 & sji(3), va(3), vb(3), a(3)
1799 integer its, ik, ksph, l, m, ind, jsph, icomp, jcomp
1801 real(dp) cx, cy, cz, vvki, tki, gg, fl, fac, vvkj, tkj
1802 real(dp) tt, fcl, fjj, gi, fii, vvji, tji, qji
1803 real(dp) b, vvik, tik, qik, tlow, thigh, duj
1804 real(dp) :: rho, ctheta, stheta, cphi, sphi
1805 real(dp),
external :: dnrm2
1807 tlow = one - pt5*(one - params % se)*params % eta
1808 thigh = one + pt5*(one + params % se)*params % eta
1814 do its = 1, params % ngrid
1816 do ik = constants % inl(isph), constants % inl(isph+1) - 1
1817 ksph = constants % nl(ik)
1819 cx = params % csph(1,ksph) + params % rsph(ksph)*constants % cgrid(1,its)
1820 cy = params % csph(2,ksph) + params % rsph(ksph)*constants % cgrid(2,its)
1821 cz = params % csph(3,ksph) + params % rsph(ksph)*constants % cgrid(3,its)
1822 vki(1) = cx - params % csph(1,isph)
1823 vki(2) = cy - params % csph(2,isph)
1824 vki(3) = cz - params % csph(3,isph)
1827 vvki = dnrm2(3, vki, 1)
1828 tki = vvki/params % rsph(isph)
1835 if ((tki.gt.tlow).and.(tki.lt.thigh) .and. &
1836 & constants % ui(its,ksph).gt.zero)
then
1842 do l = 0, params % lmax
1845 fac = twopi/(two*fl + one)
1848 gg = gg + fac*constants % vgrid(ind+m,its)*g(ind+m,ksph)
1853 do jsph = 1, params % nsph
1854 if (jsph.ne.ksph .and. jsph.ne.isph)
then
1855 vkj(1) = cx - params % csph(1,jsph)
1856 vkj(2) = cy - params % csph(2,jsph)
1857 vkj(3) = cz - params % csph(3,jsph)
1858 vvkj = sqrt(vkj(1)*vkj(1) + vkj(2)*vkj(2) + &
1860 vvkj = dnrm2(3, vkj, 1)
1861 tkj = vvkj/params % rsph(jsph)
1863 call ylmbas(skj, rho, ctheta, stheta, cphi, sphi, &
1864 & params % lmax, constants % vscales, basloc, &
1867 do l = 0, params % lmax
1869 fcl = - fourpi*dble(l)/(two*dble(l)+one)*tt
1872 gg = gg + fcl*g(ind+m,jsph)*basloc(ind+m)
1883 call ylmbas(ski, rho, ctheta, stheta, cphi, sphi, &
1884 & params % lmax, constants % vscales, basloc, &
1887 do l = 0, params % lmax
1889 fcl = - four*pi*dble(l)/(two*dble(l)+one)*tt
1892 gg = gg + fcl*g(ind+m,isph)*basloc(ind+m)
1901 duj = dfsw(tki,params % se, params % eta)/params % rsph(isph)
1902 fjj = duj*constants % wgrid(its)*gg*ygrid(its,ksph)
1903 fx(1) = fx(1) - fjj*ski(1)
1904 fx(2) = fx(2) - fjj*ski(2)
1905 fx(3) = fx(3) - fjj*ski(3)
1910 if (constants % ui(its,isph).gt.zero.and.constants % ui(its,isph).lt.one)
then
1912 do l = 0, params % lmax
1915 fac = twopi/(two*fl + one)
1918 gi = gi + fac*constants % vgrid(ind+m,its)*g(ind+m,isph)
1926 fii = constants % wgrid(its)*gi*ygrid(its,isph)
1927 fx(1) = fx(1) + fii*constants % zi(1,its,isph)
1928 fx(2) = fx(2) + fii*constants % zi(2,its,isph)
1929 fx(3) = fx(3) + fii*constants % zi(3,its,isph)
1935 do its = 1, params % ngrid
1938 do jsph = 1, params % nsph
1939 if (constants % ui(its,jsph).gt.zero .and. jsph.ne.isph)
then
1941 cx = params % csph(1,jsph) + params % rsph(jsph)*constants % cgrid(1,its)
1942 cy = params % csph(2,jsph) + params % rsph(jsph)*constants % cgrid(2,its)
1943 cz = params % csph(3,jsph) + params % rsph(jsph)*constants % cgrid(3,its)
1944 vji(1) = cx - params % csph(1,isph)
1945 vji(2) = cy - params % csph(2,isph)
1946 vji(3) = cz - params % csph(3,isph)
1949 vvji = dnrm2(3, vji, 1)
1950 tji = vvji/params % rsph(isph)
1961 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
1962 & + sji(icomp)*sji(jcomp))
1968 call dbasis(params, constants, sji,basloc,dbsloc,vplm,vcos,vsin)
1973 do l = 0, params % lmax
1976 fcl = - tt*fourpi*fl/(two*fl + one)
1978 fac = fcl*g(ind+m,isph)
1979 b = (fl + one)*basloc(ind+m)/(params % rsph(isph)*tji)
1982 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
1983 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
1984 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
1985 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
1986 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
1987 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
1988 a(1) = a(1) + fac*(sji(1)*b + va(1))
1989 a(2) = a(2) + fac*(sji(2)*b + va(2))
1990 a(3) = a(3) + fac*(sji(3)*b + va(3))
1994 fac = constants % ui(its,jsph)*constants % wgrid(its)*ygrid(its,jsph)
1995 fx(1) = fx(1) - fac*a(1)
1996 fx(2) = fx(2) - fac*a(2)
1997 fx(3) = fx(3) - fac*a(3)
2003 do its = 1, params % ngrid
2004 cx = params % csph(1,isph) + params % rsph(isph)*constants % cgrid(1,its)
2005 cy = params % csph(2,isph) + params % rsph(isph)*constants % cgrid(2,its)
2006 cz = params % csph(3,isph) + params % rsph(isph)*constants % cgrid(3,its)
2010 do ksph = 1, params % nsph
2011 if (constants % ui(its,isph).gt.zero .and. ksph.ne.isph)
then
2013 vik(1) = cx - params % csph(1,ksph)
2014 vik(2) = cy - params % csph(2,ksph)
2015 vik(3) = cz - params % csph(3,ksph)
2018 vvik = dnrm2(3, vik, 1)
2019 tik = vvik/params % rsph(ksph)
2030 sjac(icomp,jcomp) = qik*(sjac(icomp,jcomp) &
2031 & - sik(icomp)*sik(jcomp))
2037 if (constants % ui(its,isph).lt.one)
then
2038 vb(1) = constants % zi(1,its,isph)
2039 vb(2) = constants % zi(2,its,isph)
2040 vb(3) = constants % zi(3,its,isph)
2045 call dbasis(params, constants, sik,basloc,dbsloc,vplm,vcos,vsin)
2049 do l = 0, params % lmax
2052 fcl = - tt*fourpi*fl/(two*fl + one)
2054 fac = fcl*g(ind+m,ksph)
2055 fac = - fac*basloc(ind+m)
2056 a(1) = a(1) + fac*vb(1)
2057 a(2) = a(2) + fac*vb(2)
2058 a(3) = a(3) + fac*vb(3)
2060 fac = constants % ui(its,isph)*fcl*g(ind+m,ksph)
2061 b = - (fl + one)*basloc(ind+m)/(params % rsph(ksph)*tik)
2064 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
2065 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
2066 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
2067 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
2068 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
2069 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
2070 a(1) = a(1) + fac*(sik(1)*b + va(1))
2071 a(2) = a(2) + fac*(sik(2)*b + va(2))
2072 a(3) = a(3) + fac*(sik(3)*b + va(3))
2078 fac = constants % wgrid(its)*ygrid(its,isph)
2079 fx(1) = fx(1) - fac*a(1)
2080 fx(2) = fx(2) - fac*a(2)
2081 fx(3) = fx(3) - fac*a(3)
2083end subroutine gradr_sph
2086subroutine gradr_fmm(params, constants, workspace, g, ygrid, fx)
2089 type(ddx_params_type),
intent(in) :: params
2090 type(ddx_constants_type),
intent(in) :: constants
2091 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2092 & ygrid(params % ngrid, params % nsph)
2094 type(ddx_workspace_type),
intent(inout) :: workspace
2096 real(dp),
intent(out) :: fx(3, params % nsph)
2098 integer :: indl, indl1, l, isph, igrid, ik, ksph, &
2100 integer :: inear, inode, jnode
2101 real(dp) :: gg, c(3), vki(3), vvki, tki, gg3(3), tmp_gg, tmp_c(3)
2102 real(dp) :: tlow, thigh
2103 real(dp),
dimension(3, 3) :: zx_coord_transform, zy_coord_transform
2104 real(dp),
external :: ddot, dnrm2
2105 real(dp) :: work(params % lmax+2)
2107 zx_coord_transform = 0
2108 zx_coord_transform(3, 2) = 1
2109 zx_coord_transform(2, 3) = 1
2110 zx_coord_transform(1, 1) = 1
2111 zy_coord_transform = 0
2112 zy_coord_transform(1, 2) = 1
2113 zy_coord_transform(2, 1) = 1
2114 zy_coord_transform(3, 3) = 1
2115 tlow = one - pt5*(one - params % se)*params % eta
2116 thigh = one + pt5*(one + params % se)*params % eta
2119 workspace % tmp_sph(1, :) = zero
2121 do l = 1, params % lmax
2123 workspace % tmp_sph(indl:indl1, :) = l * g(indl:indl1, :)
2130 call tree_grad_m2m(params, constants, workspace % tmp_sph, &
2131 & workspace % tmp_sph_grad, workspace % tmp_sph2)
2138 do isph = 1, params % nsph
2139 workspace % tmp_grid(:, isph) = ygrid(:, isph) * &
2140 & constants % wgrid(:) * constants % ui(:, isph)
2144 call tree_m2p_adj(params, constants, params % lmax+1, one, &
2145 & workspace % tmp_grid, zero, workspace % tmp_sph2)
2146 call tree_l2p_adj(params, constants, one, workspace % tmp_grid, zero, &
2147 & workspace % tmp_node_l, workspace % tmp_sph_l)
2150 & workspace % tmp_node_m)
2154 if(params % lmax+1 .lt. params % pm)
then
2155 do isph = 1, params % nsph
2156 inode = constants % snode(isph)
2157 workspace % tmp_sph2(:, isph) = workspace % tmp_sph2(:, isph) + &
2158 & workspace % tmp_node_m(1:constants % grad_nbasis, inode)
2161 indl = (params % pm+1)**2
2162 do isph = 1, params % nsph
2163 inode = constants % snode(isph)
2164 workspace % tmp_sph2(1:indl, isph) = &
2165 & workspace % tmp_sph2(1:indl, isph) + &
2166 & workspace % tmp_node_m(:, inode)
2170 do isph = 1, params % nsph
2171 call dgemv(
'T', constants % grad_nbasis, 3, one, &
2172 & workspace % tmp_sph_grad(1, 1, isph), constants % grad_nbasis, &
2173 & workspace % tmp_sph2(1, isph), 1, zero, fx(1, isph), 1)
2180 if(params % lmax .lt. params % pm)
then
2181 do isph = 1, params % nsph
2182 inode = constants % snode(isph)
2183 workspace % tmp_node_m(:constants % nbasis, inode) = &
2184 & workspace % tmp_sph(:, isph)
2185 workspace % tmp_node_m(constants % nbasis+1:, inode) = zero
2188 indl = (params % pm+1)**2
2189 do isph = 1, params % nsph
2190 inode = constants % snode(isph)
2191 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
2197 & workspace % tmp_node_l)
2199 call tree_l2p(params, constants, one, workspace % tmp_node_l, zero, &
2200 & workspace % tmp_grid, workspace % tmp_sph_l)
2201 call tree_m2p(params, constants, params % lmax, one, &
2202 & workspace % tmp_sph, one, workspace % tmp_grid)
2204 if (params % pl .gt. 0)
then
2205 call tree_grad_l2l(params, constants, workspace % tmp_node_l, &
2206 & workspace % tmp_sph_l_grad, workspace % tmp_sph_l)
2210 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
2211 & pt5, constants % vgrid2, constants % vgrid_nbasis, g, &
2212 & constants % nbasis, -one, workspace % tmp_grid, params % ngrid)
2214 do igrid = 1, params % ngrid
2215 do isph = 1, params % nsph
2216 workspace % tmp_grid(igrid, isph) = &
2217 & workspace % tmp_grid(igrid, isph) * constants % wgrid(igrid) * &
2218 & ygrid(igrid, isph)
2223 do isph = 1, params % nsph
2224 do igrid = 1, params % ngrid
2226 do ik = constants % inl(isph), constants % inl(isph+1) - 1
2227 ksph = constants % nl(ik)
2229 if(constants % ui(igrid, ksph) .eq. zero) cycle
2231 c = params % csph(:, ksph) + &
2232 & params % rsph(ksph)*constants % cgrid(:, igrid)
2233 vki = c - params % csph(:, isph)
2236 vvki = dnrm2(3, vki, 1)
2237 tki = vvki / params % rsph(isph)
2239 if((tki.le.tlow) .or. (tki.ge.thigh)) cycle
2243 gg = workspace % tmp_grid(igrid, ksph)
2250 fx(:, isph) = fx(:, isph) - &
2251 & dfsw(tki, params % se, params % eta)/ &
2252 & params % rsph(isph)*gg*(vki/vvki)
2255 if((constants % ui(igrid,isph).gt.zero) .and. &
2256 & (constants % ui(igrid,isph).lt.one))
then
2260 gg = workspace % tmp_grid(igrid, isph)
2265 fx(:, isph) = fx(:, isph) + gg*constants % zi(:, igrid, isph)
2267 if (constants % ui(igrid, isph) .gt. zero)
then
2274 call dgemv(
'T', params % pl**2, 3, one, &
2275 & workspace % tmp_sph_l_grad(1, 1, isph), &
2276 & (params % pl+1)**2, constants % vgrid2(1, igrid), 1, &
2280 inode = constants % snode(isph)
2281 do inear = constants % snear(inode), constants % snear(inode+1)-1
2282 jnode = constants % near(inear)
2283 do jsph_node = constants % cluster(1, jnode), &
2284 & constants % cluster(2, jnode)
2285 jsph = constants % order(jsph_node)
2286 if (isph .eq. jsph) cycle
2287 c = params % csph(:, isph) + &
2288 & params % rsph(isph)*constants % cgrid(:, igrid)
2289 tmp_c = c - params % csph(:, jsph)
2290 call fmm_m2p_work(tmp_c, &
2291 & params % rsph(jsph), params % lmax+1, &
2292 & constants % vscales_rel, one, &
2293 & workspace % tmp_sph_grad(:, 1, jsph), zero, &
2295 gg3(1) = gg3(1) + tmp_gg
2296 call fmm_m2p_work(tmp_c, &
2297 & params % rsph(jsph), params % lmax+1, &
2298 & constants % vscales_rel, one, &
2299 & workspace % tmp_sph_grad(:, 2, jsph), zero, &
2301 gg3(2) = gg3(2) + tmp_gg
2302 call fmm_m2p_work(tmp_c, &
2303 & params % rsph(jsph), params % lmax+1, &
2304 & constants % vscales_rel, one, &
2305 & workspace % tmp_sph_grad(:, 3, jsph), zero, &
2307 gg3(3) = gg3(3) + tmp_gg
2311 fx(:, isph) = fx(:, isph) - constants % wgrid(igrid)*gg3* &
2312 & ygrid(igrid, isph)*constants % ui(igrid, isph)
2316end subroutine gradr_fmm
2319subroutine gradr(params, constants, workspace, g, ygrid, fx)
2322 type(ddx_params_type),
intent(in) :: params
2323 type(ddx_constants_type),
intent(in) :: constants
2324 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2325 & ygrid(params % ngrid, params % nsph)
2327 type(ddx_workspace_type),
intent(inout) :: workspace
2329 real(dp),
intent(out) :: fx(3, params % nsph)
2331 if (params % fmm .eq. 1)
then
2332 call gradr_fmm(params, constants, workspace, g, ygrid, fx)
2334 call gradr_dense(params, constants, workspace, g, ygrid, fx)
2339subroutine gradr_dense(params, constants, workspace, g, ygrid, fx)
2342 type(ddx_params_type),
intent(in) :: params
2343 type(ddx_constants_type),
intent(in) :: constants
2344 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2345 & ygrid(params % ngrid, params % nsph)
2347 type(ddx_workspace_type),
intent(inout) :: workspace
2349 real(dp),
intent(out) :: fx(3, params % nsph)
2353 do isph = 1, params % nsph
2354 call gradr_sph(params, constants, isph, workspace % tmp_vplm, &
2355 & workspace % tmp_vcos, workspace % tmp_vsin, &
2356 & workspace % tmp_vylm, workspace % tmp_vdylm, &
2357 & g, ygrid, fx(:, isph))
2359end subroutine gradr_dense
2364subroutine zeta_grad(params, constants, state, e_cav, forces)
2366 type(ddx_params_type),
intent(in) :: params
2367 type(ddx_constants_type),
intent(in) :: constants
2369 real(dp),
intent(inout) :: forces(3, params % nsph)
2370 real(dp),
intent(in) :: e_cav(3, constants % ncav)
2372 integer :: icav, isph, igrid
2375 do isph = 1, params % nsph
2376 do igrid = 1, params % ngrid
2377 if (constants % ui(igrid, isph) .eq. zero) cycle
2379 forces(:, isph) = forces(:, isph) + pt5 &
2380 & *state % zeta(icav)*e_cav(:, icav)
2383end subroutine zeta_grad
2388subroutine zeta_grad_dr(params, constants, state, e_cav, dr)
2390 type(ddx_params_type),
intent(in) :: params
2391 type(ddx_constants_type),
intent(in) :: constants
2393 real(dp),
intent(inout) :: dr(params % nsph)
2394 real(dp),
intent(in) :: e_cav(3, constants % ncav)
2396 integer :: icav, isph, igrid
2399 do isph = 1, params % nsph
2400 do igrid = 1, params % ngrid
2401 if (constants % ui(igrid, isph) .eq. zero) cycle
2403 dr(isph) = dr(isph) + pt5 &
2404 & * dot_product(constants % cgrid(:,igrid), e_cav(:, icav))*state % zeta(icav)
2407end subroutine zeta_grad_dr
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...