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
354 do ig = 1, params % ngrid
357 if (constants % ui(ig,isph) .gt. zero .and. constants % ui(ig,isph).lt.one)
then
358 alp = alp + phi(ig,isph)*xi(ig,isph)*constants % zi(:,ig,isph)
359 alp_rad = alp_rad + phi(ig,isph)*xi(ig,isph)*constants % zi_dr(ig,isph)
361 do ji = constants % inl(isph), constants % inl(isph+1) - 1
362 jsph = constants % nl(ji)
363 vji = params % csph(:,jsph) + &
364 & params % rsph(jsph)*constants % cgrid(:,ig) - &
365 & 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)
373 fac = dfsw(tji, params % se, params % eta)
374 alp = alp + fac*phi(ig,jsph)*xi(ig,jsph) * dtji
375 alp_rad = alp_rad + fac*phi(ig,jsph)*xi(ig,jsph) * dtji_rad
378 fx = fx - constants % wgrid(ig)*alp
379 dr_local = dr_local - constants % wgrid(ig)*alp_rad
383 if (do_dr) dr = dr_local
384end subroutine contract_grad_u
395subroutine contract_grad_b(params, constants, isph, Xe, Xadj_e, force)
397 type(ddx_params_type),
intent(in) :: params
398 type(ddx_constants_type),
intent(in) :: constants
399 integer,
intent(in) :: isph
400 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
401 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
402 real(dp),
dimension(3),
intent(inout) :: force
404 call contract_gradi_bik(params, constants, isph, xe(:,:), &
405 & xadj_e(:, isph), force)
406 call contract_gradi_bji(params, constants, isph, xe(:,:), xadj_e, force)
408end subroutine contract_grad_b
426subroutine contract_grad_c(params, constants, workspace, Xr, Xe, Xadj_r_sgrid, &
427 & Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
429 type(ddx_params_type),
intent(in) :: params
430 type(ddx_constants_type),
intent(in) :: constants
431 type(ddx_workspace_type),
intent(inout) :: workspace
432 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
433 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_r_sgrid, Xadj_e_sgrid
434 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xadj_r, Xadj_e
435 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
436 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: diff_re
437 type(ddx_error_type),
intent(inout) :: ddx_error
439 call contract_grad_c_worker2(params, constants, workspace, xr, xe, xadj_r_sgrid, &
440 & xadj_e_sgrid, xadj_r, xadj_e, force, diff_re, ddx_error)
441 if (ddx_error % flag .ne. 0)
then
442 call update_error(ddx_error, &
443 &
"contract_grad_C_worker2 returned an error, exiting")
446 call contract_grad_c_worker1(params, constants, workspace, xadj_r_sgrid, &
447 & xadj_e_sgrid, diff_re, force, ddx_error)
448 if (ddx_error % flag .ne. 0)
then
449 call update_error(ddx_error, &
450 &
"contract_grad_C_worker1 returned an error, exiting")
454end subroutine contract_grad_c
467subroutine contract_grad_f(params, constants, workspace, sol_adj, sol_sgrid, &
468 & gradpsi, normal_hessian_cav, force, state, ddx_error)
469 type(ddx_params_type),
intent(in) :: params
470 type(ddx_constants_type),
intent(in) :: constants
471 type(ddx_workspace_type),
intent(inout) :: workspace
473 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sol_adj
474 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
475 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
476 real(dp),
dimension(3, constants % ncav),
intent(in) :: normal_hessian_cav
477 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
478 type(ddx_error_type),
intent(inout) :: ddx_error
480 call contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
481 & gradpsi, force, ddx_error)
482 if (ddx_error % flag .ne. 0)
then
483 call update_error(ddx_error, &
484 &
"contract_grad_f_worker1 returned an error, exiting")
488 call contract_grad_f_worker2(params, constants, gradpsi, &
489 & normal_hessian_cav, force, state, ddx_error)
490 if (ddx_error % flag .ne. 0)
then
491 call update_error(ddx_error, &
492 &
"contract_grad_f_worker2 returned an error, exiting")
496end subroutine contract_grad_f
506subroutine contract_gradi_bik(params, constants, isph, Xe, Xadj_e, force)
508 type(ddx_params_type),
intent(in) :: params
509 type(ddx_constants_type),
intent(in) :: constants
510 integer,
intent(in) :: isph
511 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
512 real(dp),
dimension(params % ngrid),
intent(in) :: Xadj_e
513 real(dp),
dimension(3),
intent(inout) :: force
516 integer :: igrid, ineigh, jsph
517 real(dp),
dimension(0:params % lmax) :: SI_rijn
518 real(dp),
dimension(0:params % lmax) :: DI_rijn
524 real(dp) :: rijn, tij, beta, tlow, thigh, xij, oij, f1, f2, f3
527 real(dp) :: vij(3), sij(3), alpha(3), va(3), rj, vtij(3)
528 real(dp),
external :: dnrm2
529 real(dp) :: work(params % lmax+1)
530 complex(dp) :: work_complex(params % lmax+1)
535 tlow = one - pt5*(one - params % se)*params % eta
536 thigh = one + pt5*(one + params % se)*params % eta
539 do igrid = 1, params % ngrid
541 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
542 jsph = constants % nl(ineigh)
543 vij = params % csph(:,isph) + &
544 & params % rsph(isph)*constants % cgrid(:,igrid) - &
545 & params % csph(:,jsph)
546 rijn = dnrm2(3, vij, 1)
547 tij = rijn/params % rsph(jsph)
548 rj = params % rsph(jsph)
549 if (tij.ge.thigh) cycle
551 if (tij.ne.zero)
then
556 vtij = vij*params % kappa
557 call fmm_l2p_bessel_grad(vtij, params % rsph(jsph)*params % kappa, &
558 & params % lmax, constants % vscales, params % kappa, &
559 & xe(:, jsph), zero, alpha)
560 call fmm_l2p_bessel_work(vtij, params % lmax, constants % vscales, &
561 & constants % SI_ri(:, jsph), one, xe(:, jsph), zero, beta, &
562 & work_complex, work)
563 xij = fsw(tij, params % se, params % eta)
564 if (constants % fi(igrid,isph).gt.one)
then
565 oij = xij/constants % fi(igrid,isph)
566 f2 = -oij/constants % fi(igrid,isph)
572 va(:) = va(:) + f1*alpha(:) + beta*f2*constants % zi(:,igrid,isph)
573 if (tij .gt. tlow)
then
574 f3 = beta*dfsw(tij,params % se,params % eta)/params % rsph(jsph)
575 if (constants % fi(igrid,isph).gt.one) &
576 & f3 = f3/constants % fi(igrid,isph)
577 va(:) = va(:) + f3*sij(:)
580 force = force - constants % wgrid(igrid)*xadj_e(igrid)*va(:)
582end subroutine contract_gradi_bik
594subroutine contract_gradi_bji(params, constants, isph, Xe, Xadj_e, force)
596 type(ddx_params_type),
intent(in) :: params
597 type(ddx_constants_type),
intent(in) :: constants
598 integer,
intent(in) :: isph
599 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
600 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
601 real(dp),
dimension(3),
intent(inout) :: force
605 integer :: igrid, jsph, ksph, ineigh, jk
606 real(dp),
dimension(0:params % lmax) :: SI_rjin, SI_rjkn
607 real(dp),
dimension(0:params % lmax) :: DI_rjin, DI_rjkn
615 real(dp) :: rjin, tji, xji, oji, fac, f1, f2, beta_ji, dj, tlow, thigh
616 real(dp) :: b, beta_jk, g1, g2, rjkn, tjk, xjk
620 real(dp) :: vji(3), sji(3), vjk(3), alpha(3), vb(3), vc(3), &
629 real(dp),
external :: dnrm2
630 real(dp) :: work(params % lmax+1)
631 complex(dp) :: work_complex(params % lmax+1)
638 tlow = one - pt5*(one - params % se)*params % eta
639 thigh = one + pt5*(one + params % se)*params % eta
641 do igrid = 1, params % ngrid
644 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
645 jsph = constants % nl(ineigh)
646 vji = params % csph(:,jsph) + &
647 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
648 & params % csph(:,isph)
649 rjin = dnrm2(3, vji, 1)
650 ri = params % rsph(isph)
652 if (tji.gt.thigh) cycle
653 if (tji.ne.zero)
then
658 vtji = vji*params % kappa
659 call fmm_l2p_bessel_grad(vtji, params % rsph(isph)*params % kappa, &
660 & params % lmax, constants % vscales, params % kappa, &
661 & xe(:, isph), zero, alpha)
662 xji = fsw(tji,params % se,params % eta)
663 if (constants % fi(igrid,jsph).gt.one)
then
664 oji = xji/constants % fi(igrid,jsph)
669 vb = vb + f1*alpha*xadj_e(igrid,jsph)
670 if (tji .gt. tlow)
then
671 call fmm_l2p_bessel_work(vtji, params % lmax, &
672 & constants % vscales, constants % SI_ri(:, isph), one, &
673 & xe(:, isph), zero, beta_ji, work_complex, work)
674 if (constants % fi(igrid,jsph) .gt. one)
then
675 dj = one/constants % fi(igrid,jsph)
679 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
680 ksph = constants % nl(jk)
681 vjk = params % csph(:,jsph) + &
682 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
683 & params % csph(:,ksph)
684 rjkn = dnrm2(3, vjk, 1)
685 tjk = rjkn/params % rsph(ksph)
686 if (ksph.ne.isph)
then
687 if (tjk .le. thigh)
then
689 vtjk = vjk*params % kappa
690 call fmm_l2p_bessel_work(vtjk, params % lmax, &
691 & constants % vscales, &
692 & constants % SI_ri(:, ksph), one, xe(:, ksph), &
693 & zero, beta_jk, work_complex, work)
694 xjk = fsw(tjk, params % se, params % eta)
700 g1 = dj*dj*dfsw(tji,params % se,params % eta) &
701 & /params % rsph(isph)
702 g2 = g1*xadj_e(igrid,jsph)*b
709 f2 = (one-fac)*dj*dfsw(tji,params % se,params % eta) &
710 & /params % rsph(isph)
711 vb = vb + f2*xadj_e(igrid,jsph)*beta_ji*sji
714 force = force + constants % wgrid(igrid)*(vb - vc)
716end subroutine contract_gradi_bji
730subroutine contract_grad_c_worker1(params, constants, workspace, Xadj_r_sgrid, &
731 & Xadj_e_sgrid, diff_re, force, ddx_error)
733 type(ddx_params_type),
intent(in) :: params
734 type(ddx_constants_type),
intent(in) :: constants
735 type(ddx_workspace_type),
intent(inout) :: workspace
736 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
738 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
739 & Xadj_r_sgrid, Xadj_e_sgrid
740 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
741 type(ddx_error_type),
intent(inout) :: ddx_error
744 integer :: isph, jsph, igrid, l0, m0, ind0, igrid0, icav, &
752 real(dp) :: sum_int, sum_r, sum_e
754 real(dp) :: vij(3), sij(3), vtij(3)
761 real(dp),
allocatable :: phi_n_r(:,:), phi_n_e(:,:), coefY_d(:,:,:), &
766 real(dp),
dimension(constants % nbasis):: basloc, vplm
768 real(dp),
dimension(3, constants % nbasis):: dbasloc
771 real(dp),
dimension(params % lmax+1):: vcos, vsin
774 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
775 real(dp) :: coef(constants % nbasis0), work(constants % lmax0+1)
776 complex(dp) :: work_complex(constants % lmax0+1)
778 allocate(phi_n_r(params % ngrid, params % nsph), &
779 & phi_n_e(params % ngrid, params % nsph), &
780 & diff_re_sgrid(params % ngrid, params % nsph), stat=istat)
782 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker1")
800 if (params % fmm .eq. 0)
then
801 allocate(coefy_d(constants % ncav, params % ngrid, params % nsph), &
804 call update_error(ddx_error,
"allocation ddx_error in fmm ddx_contract_grad_C_worker1")
810 do jsph = 1, params % nsph
812 do igrid0 = 1, params % ngrid
815 do isph = 1, params % nsph
817 do igrid = 1, params % ngrid
819 if(constants % ui(igrid, isph) .gt. zero)
then
821 vij = params % csph(:,isph) + &
822 & params % rsph(isph)*constants % cgrid(:,igrid) - &
823 & params % csph(:,jsph)
824 rijn = sqrt(dot_product(vij,vij))
827 do l0 = 0, constants % lmax0
829 ind0 = l0**2 + l0 + m0 + 1
830 coef(ind0) = constants % vgrid(ind0, igrid0) * &
831 & constants % C_ik(l0, jsph)
834 vtij = vij*params % kappa
835 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
836 & constants % vscales, constants % SK_ri(:, jsph), one, &
837 & coef, zero, coefy_d(icav, igrid0, jsph), work_complex, work)
846 do jsph = 1, params % nsph
848 do igrid0 = 1, params % ngrid
853 do isph = 1, params % nsph
855 do igrid = 1, params % ngrid
856 if(constants % ui(igrid, isph) .gt. zero)
then
858 sum_r = sum_r + coefy_d(icav, igrid0, jsph)*xadj_r_sgrid(igrid, isph) &
859 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
860 sum_e = sum_e + coefy_d(icav, igrid0, jsph)*xadj_e_sgrid(igrid, isph) &
861 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
865 phi_n_r(igrid0, jsph) = sum_r
866 phi_n_e(igrid0, jsph) = sum_e
874 do isph = 1, params % nsph
875 workspace % tmp_grid(:, isph) = xadj_r_sgrid(:, isph) * &
876 & constants % wgrid(:) * constants % ui(:, isph)
880 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
882 & zero, workspace % tmp_node_l)
884 & workspace % tmp_node_l)
886 & workspace % tmp_node_l, workspace % tmp_node_m)
888 & workspace % tmp_node_m)
890 if(constants % lmax0 .lt. params % pm)
then
891 do isph = 1, params % nsph
892 inode = constants % snode(isph)
893 workspace % tmp_sph(1:constants % nbasis0, isph) = &
894 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
895 & workspace % tmp_node_m(1:constants % nbasis0, inode)
898 indl = (params % pm+1)**2
899 do isph = 1, params % nsph
900 inode = constants % snode(isph)
901 workspace % tmp_sph(1:indl, isph) = &
902 & workspace % tmp_sph(1:indl, isph) + &
903 & workspace % tmp_node_m(:, inode)
907 do isph = 1, params % nsph
908 do l0 = 0, constants % lmax0
909 ind0 = l0*l0 + l0 + 1
910 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
911 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
912 & constants % C_ik(l0, isph)
916 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
917 & one, constants % vgrid, constants % vgrid_nbasis, &
918 & workspace % tmp_sph, constants % nbasis, zero, phi_n_r, params % ngrid)
923 do isph = 1, params % nsph
924 workspace % tmp_grid(:, isph) = xadj_e_sgrid(:, isph) * &
925 & constants % wgrid(:) * constants % ui(:, isph)
929 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
931 & zero, workspace % tmp_node_l)
933 & workspace % tmp_node_l)
935 & workspace % tmp_node_l, workspace % tmp_node_m)
937 & workspace % tmp_node_m)
939 if(constants % lmax0 .lt. params % pm)
then
940 do isph = 1, params % nsph
941 inode = constants % snode(isph)
942 workspace % tmp_sph(1:constants % nbasis0, isph) = &
943 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
944 & workspace % tmp_node_m(1:constants % nbasis0, inode)
947 indl = (params % pm+1)**2
948 do isph = 1, params % nsph
949 inode = constants % snode(isph)
950 workspace % tmp_sph(1:indl, isph) = &
951 & workspace % tmp_sph(1:indl, isph) + &
952 & workspace % tmp_node_m(:, inode)
956 do isph = 1, params % nsph
957 do l0 = 0, constants % lmax0
958 ind0 = l0*l0 + l0 + 1
959 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
960 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
961 & constants % C_ik(l0, isph)
965 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
966 & one, constants % vgrid, constants % vgrid_nbasis, &
967 & workspace % tmp_sph, constants % nbasis, zero, phi_n_e, params % ngrid)
969 call dgemm(
'T',
'N', params % ngrid, params % nsph, &
970 & constants % nbasis, one, constants % vgrid, constants % vgrid_nbasis, &
971 & diff_re , constants % nbasis, zero, diff_re_sgrid, &
973 do isph = 1, params % nsph
974 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_r, force(:, isph))
975 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_e, force(:, isph))
978 deallocate(phi_n_r, phi_n_e, diff_re_sgrid, stat=istat)
980 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
983 if (
allocated(coefy_d))
then
984 deallocate(coefy_d, stat=istat)
986 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
990end subroutine contract_grad_c_worker1
1011subroutine contract_grad_c_worker2(params, constants, workspace, Xr, Xe, &
1012 & Xadj_r_sgrid, Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
1014 type(ddx_params_type),
intent(in) :: params
1015 type(ddx_constants_type),
intent(in) :: constants
1016 type(ddx_workspace_type),
intent(inout) :: workspace
1017 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
1018 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
1019 & Xadj_r_sgrid, Xadj_e_sgrid
1020 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1022 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1023 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: &
1025 type(ddx_error_type),
intent(inout) :: ddx_error
1026 real(dp),
external :: dnrm2
1028 integer :: isph, jsph, igrid, l, m, ind, l0, ind0, icav, indl, inode, &
1029 & ksph, knode, jnode, knear, jsph_node, istat
1031 real(dp),
dimension(3) :: vij, vtij
1040 real(dp),
allocatable :: diff_ep_dim3(:,:), phi_in(:,:), sum_dim3(:,:,:), &
1041 & diff0(:,:), diff1(:,:), diff1_grad(:,:,:), l2l_grad(:,:,:)
1042 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1043 complex(dp) :: work_complex(constants % lmax0+2)
1044 real(dp) :: work(constants % lmax0+2)
1046 allocate(diff_ep_dim3(3, constants % ncav), &
1047 & phi_in(params % ngrid, params % nsph), &
1048 & sum_dim3(3, constants % nbasis, params % nsph), &
1049 & diff0(constants % nbasis0, params % nsph), &
1050 & diff1(constants % nbasis0, params % nsph), &
1051 & diff1_grad((constants % lmax0+2)**2, 3, params % nsph), &
1052 & l2l_grad((params % pl+2)**2, 3, params % nsph), stat=istat)
1053 if (istat.ne.0)
then
1054 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker2")
1066 do jsph = 1, params % nsph
1067 do l = 0, params % lmax
1069 ind = l**2 + l + m + 1
1070 diff_re(ind,jsph) = (params % epsp/params % eps)*(l/params % rsph(jsph)) * &
1071 & xr(ind,jsph) - constants % termimat(l,jsph)*xe(ind,jsph)
1080 do jsph = 1, params % nsph
1081 do l0 = 0, constants % lmax0
1082 do ind0 = l0*l0+1, l0*l0+2*l0+1
1083 diff0(ind0, jsph) = dot_product(diff_re(:,jsph), &
1084 & constants % Pchi(:,ind0, jsph))
1085 diff1(ind0, jsph) = diff0(ind0, jsph) * constants % C_ik(l0, jsph)
1089 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, jsph), &
1090 & constants % vscales, diff1(:, jsph), diff1_grad(:, :, jsph))
1093 if (params % fmm .eq. 0)
then
1098 do isph = 1, params % nsph
1099 do igrid = 1, params % ngrid
1100 if(constants % ui(igrid, isph) .gt. zero)
then
1104 do jsph = 1, params % nsph
1109 vij = params % csph(:, isph) + &
1110 & params % rsph(isph)*constants % cgrid(:, igrid) - &
1111 & params % csph(:, jsph)
1112 vtij = vij * params % kappa
1113 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1114 & constants % vscales, constants % SK_ri(:, jsph), one, &
1115 & diff1(:, jsph), one, val, work_complex, work)
1117 phi_in(igrid, isph) = val
1124 workspace % tmp_sph = zero
1125 workspace % tmp_sph(1:constants % nbasis0, :) = diff1(:, :)
1126 if(constants % lmax0 .lt. params % pm)
then
1127 do isph = 1, params % nsph
1128 inode = constants % snode(isph)
1129 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
1130 & workspace % tmp_sph(1:constants % nbasis0, isph)
1131 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
1134 indl = (params % pm+1)**2
1135 do isph = 1, params % nsph
1136 inode = constants % snode(isph)
1137 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1143 & workspace % tmp_node_l)
1145 call tree_l2p_bessel(params, constants, one, workspace % tmp_node_l, zero, &
1148 & params % lmax, workspace % tmp_sph, one, &
1153 do isph = 1, params % nsph
1154 do igrid = 1, params % ngrid
1155 if (constants % ui(igrid, isph) .eq. zero)
then
1156 phi_in(igrid, isph) = zero
1163 do isph = 1, params % nsph
1164 inode = constants % snode(isph)
1165 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1166 call fmm_l2l_bessel_grad(params % pl, &
1167 & constants % SI_ri(:, isph), constants % vscales, &
1168 & workspace % tmp_node_l(:, inode), &
1169 & l2l_grad(:, :, isph))
1171 workspace % tmp_sph = xadj_r + xadj_e
1172 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1173 & one, constants % vwgrid, constants % vgrid_nbasis, &
1174 & workspace % tmp_sph, constants % nbasis, zero, &
1175 & workspace % tmp_grid, params % ngrid)
1176 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1180 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1182 & workspace % tmp_node_l)
1185 & workspace % tmp_node_m)
1189 if(constants % lmax0+1 .lt. params % pm)
then
1192 do isph = 1, params % nsph
1193 inode = constants % snode(isph)
1194 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1195 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1196 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1199 indl = (params % pm+1)**2
1202 do isph = 1, params % nsph
1203 inode = constants % snode(isph)
1204 workspace % tmp_sph2(1:indl, isph) = &
1205 & workspace % tmp_sph2(1:indl, isph) + &
1206 & workspace % tmp_node_m(:, inode)
1211 do ksph = 1, params % nsph
1213 call contract_grad_u(params, constants, ksph, xadj_r_sgrid, phi_in, force(:, ksph))
1214 call contract_grad_u(params, constants, ksph, xadj_e_sgrid, phi_in, force(:, ksph))
1219 icav = constants % icav_ia(ksph) - 1
1220 if (params % fmm .eq. 0)
then
1221 do igrid = 1, params % ngrid
1222 if (constants % ui(igrid, ksph) .eq. zero) cycle
1224 do jsph = 1, params % nsph
1225 if (jsph .eq. ksph) cycle
1226 vij = params % csph(:,ksph) + &
1227 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1228 & params % csph(:,jsph)
1229 vtij = vij * params % kappa
1235 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1236 & constants % vscales, constants % SK_ri(:, jsph), &
1237 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1238 & diff_ep_dim3(1, icav), work_complex, work)
1239 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1240 & constants % vscales, constants % SK_ri(:, jsph), &
1241 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1242 & diff_ep_dim3(2, icav), work_complex, work)
1243 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1244 & constants % vscales, constants % SK_ri(:, jsph), &
1245 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1246 & diff_ep_dim3(3, icav), work_complex, work)
1250 knode = constants % snode(ksph)
1251 do igrid = 1, params % ngrid
1252 if (constants % ui(igrid, ksph) .eq. zero) cycle
1255 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1256 & l2l_grad(1, 1, ksph), &
1257 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1258 & one, diff_ep_dim3(1, icav), 1)
1260 do knear = constants % snear(knode), constants % snear(knode+1)-1
1261 jnode = constants % near(knear)
1262 do jsph_node = constants % cluster(1, jnode), &
1263 & constants % cluster(2, jnode)
1264 jsph = constants % order(jsph_node)
1265 if (jsph .eq. ksph) cycle
1266 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1267 & params % rsph(ksph)*constants % cgrid(:, igrid)
1268 vtij = vij * params % kappa
1269 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1270 & constants % vscales, constants % SK_ri(:, jsph), &
1271 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1272 & diff_ep_dim3(1, icav), work_complex, work)
1273 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1274 & constants % vscales, constants % SK_ri(:, jsph), &
1275 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1276 & diff_ep_dim3(2, icav), work_complex, work)
1277 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1278 & constants % vscales, constants % SK_ri(:, jsph), &
1279 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1280 & diff_ep_dim3(3, icav), work_complex, work)
1286 icav = constants % icav_ia(ksph) - 1
1287 do igrid =1, params % ngrid
1288 if(constants % ui(igrid, ksph) .gt. zero)
then
1290 do ind = 1, constants % nbasis
1291 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1292 & + diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1293 & *constants % vwgrid(ind, igrid)
1297 do ind = 1, constants % nbasis
1298 force(:, ksph) = force(:, ksph) + &
1299 & sum_dim3(:, ind, ksph)*(xadj_r(ind, ksph) + &
1300 & xadj_e(ind, ksph))
1304 if (params % fmm .eq. 0)
then
1307 do isph = 1, params % nsph
1308 if (isph .eq. ksph) cycle
1309 icav = constants % icav_ia(isph) - 1
1310 do igrid = 1, params % ngrid
1311 if (constants % ui(igrid, isph) .eq. zero) cycle
1313 vij = params % csph(:,isph) + &
1314 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1315 & params % csph(:,ksph)
1316 vtij = vij * params % kappa
1322 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1323 & constants % vscales, constants % SK_ri(:, ksph), &
1324 & params % kappa, diff1_grad(:, 1, ksph), one, &
1325 & diff_ep_dim3(1, icav), work_complex, work)
1326 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1327 & constants % vscales, constants % SK_ri(:, ksph), &
1328 & params % kappa, diff1_grad(:, 2, ksph), one, &
1329 & diff_ep_dim3(2, icav), work_complex, work)
1330 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1331 & constants % vscales, constants % SK_ri(:, ksph), &
1332 & params % kappa, diff1_grad(:, 3, ksph), one, &
1333 & diff_ep_dim3(3, icav), work_complex, work)
1337 do isph = 1, params % nsph
1338 do igrid =1, params % ngrid
1339 if(constants % ui(igrid, isph) .gt. zero)
then
1341 do ind = 1, constants % nbasis
1342 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1343 & + diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1344 & *constants % vwgrid(ind, igrid)
1350 do isph = 1, params % nsph
1351 do ind = 1, constants % nbasis
1352 force(:, ksph) = force(:, ksph) &
1353 & + sum_dim3(:, ind, isph)*(xadj_r(ind, isph) &
1354 & + xadj_e(ind, isph))
1358 call dgemv(
'T', (constants % lmax0+2)**2, 3, params % kappa, &
1359 & diff1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
1360 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
1363 deallocate(diff_ep_dim3, phi_in, sum_dim3, diff1_grad, l2l_grad, &
1364 & diff0, diff1, stat=istat)
1365 if (istat.ne.0)
then
1366 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker2")
1369end subroutine contract_grad_c_worker2
1384subroutine contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
1385 & gradpsi, force, ddx_error)
1387 type(ddx_params_type),
intent(in) :: params
1388 type(ddx_constants_type),
intent(in) :: constants
1389 type(ddx_workspace_type),
intent(inout) :: workspace
1390 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1392 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
1393 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
1394 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1395 type(ddx_error_type),
intent(inout) :: ddx_error
1398 real(dp),
external :: dnrm2
1399 integer :: isph, jsph, igrid, ind, l0, ind0, icav, ksph, &
1400 & knode, jnode, knear, jsph_node, indl, inode, istat
1402 real(dp),
dimension(3) :: vij, vtij
1405 real(dp) :: nderpsi, sum_int
1417 real(dp),
allocatable :: phi_in(:,:), diff_ep_dim3(:,:), &
1418 & sum_dim3(:,:,:), diff0(:,:), sum_sjin(:,:), &
1419 & c0_d(:,:), c0_d1(:,:), c0_d1_grad(:,:,:), l2l_grad(:,:,:)
1420 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1421 complex(dp) :: work_complex(constants % lmax0 + 2)
1422 real(dp) :: work(constants % lmax0 + 2)
1424 allocate(phi_in(params % ngrid, params % nsph), &
1425 & diff_ep_dim3(3, constants % ncav), &
1426 & sum_dim3(3, constants % nbasis, params % nsph), &
1427 & c0_d(constants % nbasis0, params % nsph), &
1428 & c0_d1(constants % nbasis0, params % nsph), &
1429 & c0_d1_grad((constants % lmax0+2)**2, 3, params % nsph), &
1430 & sum_sjin(params % ngrid, params % nsph), &
1431 & l2l_grad((params % pl+2)**2, 3, params % nsph), &
1432 & diff0(constants % nbasis0, params % nsph), stat=istat)
1433 if (istat.ne.0)
then
1434 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker1")
1447 do isph = 1, params % nsph
1448 do igrid= 1, params % ngrid
1449 if ( constants % ui(igrid,isph) .gt. zero )
then
1451 nderpsi = dot_product( gradpsi(:,icav),constants % cgrid(:,igrid) )
1452 c0_d(:, isph) = c0_d(:,isph) + &
1453 & constants % wgrid(igrid)* &
1454 & constants % ui(igrid,isph)*&
1456 & constants % vgrid(1:constants % nbasis0,igrid)
1457 do l0 = 0, constants % lmax0
1458 ind0 = l0*l0 + l0 + 1
1459 c0_d1(ind0-l0:ind0+l0, isph) = c0_d(ind0-l0:ind0+l0, isph) * &
1460 & constants % C_ik(l0, isph)
1463 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, isph), &
1464 & constants % vscales, c0_d1(:, isph), c0_d1_grad(:, :, isph))
1469 if (params % fmm .eq. 0)
then
1472 do isph = 1, params % nsph
1473 do igrid = 1, params % ngrid
1474 if (constants % ui(igrid,isph).gt.zero)
then
1478 do jsph = 1, params % nsph
1479 vij = params % csph(:, isph) + &
1480 & params % rsph(isph)*constants % cgrid(:, igrid) - &
1481 & params % csph(:, jsph)
1482 vtij = vij * params % kappa
1483 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1484 & constants % vscales, constants % SK_ri(:, jsph), one, &
1485 & c0_d1(:, jsph), one, sum_int, work_complex, work)
1487 sum_sjin(igrid,isph) = -(params % epsp/params % eps)*sum_int
1493 workspace % tmp_sph = zero
1494 workspace % tmp_sph(1:constants % nbasis0, :) = c0_d1(:, :)
1495 if(constants % lmax0 .lt. params % pm)
then
1496 do isph = 1, params % nsph
1497 inode = constants % snode(isph)
1498 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
1499 & workspace % tmp_sph(1:constants % nbasis0, isph)
1500 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
1503 indl = (params % pm+1)**2
1504 do isph = 1, params % nsph
1505 inode = constants % snode(isph)
1506 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1512 & workspace % tmp_node_l)
1514 call tree_l2p_bessel(params, constants, -params % epsp/params % eps, workspace % tmp_node_l, zero, &
1516 call tree_m2p_bessel(params, constants, constants % lmax0, -params % epsp/params % eps, &
1517 & params % lmax, workspace % tmp_sph, one, &
1520 do isph = 1, params % nsph
1521 do igrid = 1, params % ngrid
1522 if (constants % ui(igrid, isph) .eq. zero)
then
1523 sum_sjin(igrid, isph) = zero
1528 do isph = 1, params % nsph
1529 inode = constants % snode(isph)
1530 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1531 call fmm_l2l_bessel_grad(params % pl, &
1532 & constants % SI_ri(:, isph), constants % vscales, &
1533 & workspace % tmp_node_l(:, inode), &
1534 & l2l_grad(:, :, isph))
1536 workspace % tmp_sph = sol_adj
1537 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1538 & one, constants % vwgrid, constants % vgrid_nbasis, &
1539 & workspace % tmp_sph, constants % nbasis, zero, &
1540 & workspace % tmp_grid, params % ngrid)
1541 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1545 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1547 & workspace % tmp_node_l)
1550 & workspace % tmp_node_m)
1554 if(constants % lmax0+1 .lt. params % pm)
then
1555 do isph = 1, params % nsph
1556 inode = constants % snode(isph)
1557 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1558 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1559 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1562 indl = (params % pm+1)**2
1563 do isph = 1, params % nsph
1564 inode = constants % snode(isph)
1565 workspace % tmp_sph2(1:indl, isph) = &
1566 & workspace % tmp_sph2(1:indl, isph) + &
1567 & workspace % tmp_node_m(:, inode)
1571 do ksph = 1, params % nsph
1573 call contract_grad_u(params, constants, ksph, sol_sgrid, sum_sjin, force(:, ksph))
1577 icav = constants % icav_ia(ksph) - 1
1578 if (params % fmm .eq. 0)
then
1579 do igrid = 1, params % ngrid
1580 if (constants % ui(igrid, ksph) .eq. zero) cycle
1582 do jsph = 1, params % nsph
1583 if (jsph .eq. ksph) cycle
1584 vij = params % csph(:,ksph) + &
1585 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1586 & params % csph(:,jsph)
1587 vtij = vij * params % kappa
1588 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1589 & constants % vscales, constants % SK_ri(:, jsph), &
1590 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
1591 & diff_ep_dim3(1, icav), work_complex, work)
1592 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1593 & constants % vscales, constants % SK_ri(:, jsph), &
1594 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
1595 & diff_ep_dim3(2, icav), work_complex, work)
1596 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1597 & constants % vscales, constants % SK_ri(:, jsph), &
1598 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
1599 & diff_ep_dim3(3, icav), work_complex, work)
1603 knode = constants % snode(ksph)
1604 do igrid = 1, params % ngrid
1605 if (constants % ui(igrid, ksph) .eq. zero) cycle
1608 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1609 & l2l_grad(1, 1, ksph), &
1610 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1611 & one, diff_ep_dim3(1, icav), 1)
1613 do knear = constants % snear(knode), constants % snear(knode+1)-1
1614 jnode = constants % near(knear)
1615 do jsph_node = constants % cluster(1, jnode), &
1616 & constants % cluster(2, jnode)
1617 jsph = constants % order(jsph_node)
1618 if (jsph .eq. ksph) cycle
1619 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1620 & params % rsph(ksph)*constants % cgrid(:, igrid)
1621 vtij = vij * params % kappa
1622 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1623 & constants % vscales, constants % SK_ri(:, jsph), &
1624 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
1625 & diff_ep_dim3(1, icav), work_complex, work)
1626 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1627 & constants % vscales, constants % SK_ri(:, jsph), &
1628 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
1629 & diff_ep_dim3(2, icav), work_complex, work)
1630 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1631 & constants % vscales, constants % SK_ri(:, jsph), &
1632 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
1633 & diff_ep_dim3(3, icav), work_complex, work)
1639 icav = constants % icav_ia(ksph) - 1
1640 do igrid =1, params % ngrid
1641 if(constants % ui(igrid, ksph) .gt. zero)
then
1643 do ind = 1, constants % nbasis
1644 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1645 & - (params % epsp/params % eps) &
1646 & *diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1647 & *constants % vwgrid(ind, igrid)
1651 do ind = 1, constants % nbasis
1652 force(:, ksph) = force(:, ksph) + &
1653 & sum_dim3(:, ind, ksph)*sol_adj(ind, ksph)
1657 if (params % fmm .eq. 0)
then
1660 do isph = 1, params % nsph
1661 if (isph .eq. ksph) cycle
1662 icav = constants % icav_ia(isph) - 1
1663 do igrid = 1, params % ngrid
1664 if (constants % ui(igrid, isph) .eq. zero) cycle
1666 vij = params % csph(:,isph) + &
1667 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1668 & params % csph(:,ksph)
1669 vtij = vij * params % kappa
1670 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1671 & constants % vscales, constants % SK_ri(:, ksph), &
1672 & params % kappa, c0_d1_grad(:, 1, ksph), one, &
1673 & diff_ep_dim3(1, icav), work_complex, work)
1674 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1675 & constants % vscales, constants % SK_ri(:, ksph), &
1676 & params % kappa, c0_d1_grad(:, 2, ksph), one, &
1677 & diff_ep_dim3(2, icav), work_complex, work)
1678 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1679 & constants % vscales, constants % SK_ri(:, ksph), &
1680 & params % kappa, c0_d1_grad(:, 3, ksph), one, &
1681 & diff_ep_dim3(3, icav), work_complex, work)
1686 do isph = 1, params % nsph
1687 do igrid =1, params % ngrid
1688 if(constants % ui(igrid, isph) .gt. zero)
then
1690 do ind = 1, constants % nbasis
1691 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1692 & - (params % epsp/params % eps) &
1693 & *diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1694 & *constants % vwgrid(ind, igrid)
1701 do isph = 1, params % nsph
1702 do ind = 1, constants % nbasis
1703 force(:, ksph) = force(:, ksph) + sum_dim3(:, ind, isph)*sol_adj(ind, isph)
1707 call dgemv(
'T', (constants % lmax0+2)**2, 3, -params % epsp/params % eps*params % kappa, &
1708 & c0_d1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
1709 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
1713 deallocate(phi_in, diff_ep_dim3, sum_dim3, c0_d, c0_d1, &
1714 & c0_d1_grad, sum_sjin, l2l_grad, diff0, stat=istat)
1715 if (istat.ne.0)
then
1716 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker1")
1720end subroutine contract_grad_f_worker1
1723subroutine contract_grad_f_worker2(params, constants, &
1724 & gradpsi, normal_hessian_cav, force, state, ddx_error)
1725 type(ddx_params_type),
intent(in) :: params
1726 type(ddx_constants_type),
intent(in) :: constants
1727 real(dp),
intent(in) :: gradpsi(3, constants % ncav), &
1728 & normal_hessian_cav(3, constants % ncav)
1729 real(dp),
intent(inout) :: force(3, params % nsph)
1731 type(ddx_error_type),
intent(inout) :: ddx_error
1733 integer :: icav, isph, igrid, istat
1735 real(dp),
allocatable :: gradpsi_grid(:, :)
1737 allocate(gradpsi_grid(params % ngrid, params % nsph), stat=istat)
1738 if (istat.ne.0)
then
1739 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker2")
1744 do isph = 1, params % nsph
1745 do igrid = 1, params % ngrid
1746 if(constants % ui(igrid, isph) .gt. zero)
then
1748 nderpsi = dot_product(gradpsi(:, icav), &
1749 & constants % cgrid(:, igrid))
1750 gradpsi_grid(igrid, isph) = nderpsi
1756 do isph = 1, params % nsph
1757 call contract_grad_u(params, constants, isph, gradpsi_grid, &
1758 & state % phi_n, force(:, isph))
1759 do igrid = 1, params % ngrid
1760 if(constants % ui(igrid, isph) .gt. zero)
then
1762 force(:, isph) = force(:, isph) &
1763 & + constants % wgrid(igrid)*constants % ui(igrid, isph) &
1764 & *state % phi_n(igrid, isph)*normal_hessian_cav(:, icav)
1769 deallocate(gradpsi_grid, stat=istat)
1770 if (istat.ne.0)
then
1771 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker2")
1775end subroutine contract_grad_f_worker2
1778subroutine gradr_sph(params, constants, isph, vplm, vcos, vsin, basloc, &
1779 & dbsloc, g, ygrid, fx)
1782 type(ddx_params_type),
intent(in) :: params
1783 type(ddx_constants_type),
intent(in) :: constants
1784 integer,
intent(in) :: isph
1785 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
1786 & ygrid(params % ngrid, params % nsph)
1787 real(dp),
intent(inout) :: vplm(constants % nbasis), vcos(params % lmax+1), &
1788 & vsin(params % lmax+1), basloc(constants % nbasis), &
1789 & dbsloc(3, constants % nbasis), fx(3)
1791 real(dp) vik(3), sik(3), vki(3), ski(3), vkj(3), skj(3), vji(3), &
1792 & sji(3), va(3), vb(3), a(3)
1796 integer its, ik, ksph, l, m, ind, jsph, icomp, jcomp
1798 real(dp) cx, cy, cz, vvki, tki, gg, fl, fac, vvkj, tkj
1799 real(dp) tt, fcl, fjj, gi, fii, vvji, tji, qji
1800 real(dp) b, vvik, tik, qik, tlow, thigh, duj
1801 real(dp) :: rho, ctheta, stheta, cphi, sphi
1802 real(dp),
external :: dnrm2
1804 tlow = one - pt5*(one - params % se)*params % eta
1805 thigh = one + pt5*(one + params % se)*params % eta
1811 do its = 1, params % ngrid
1813 do ik = constants % inl(isph), constants % inl(isph+1) - 1
1814 ksph = constants % nl(ik)
1816 cx = params % csph(1,ksph) + params % rsph(ksph)*constants % cgrid(1,its)
1817 cy = params % csph(2,ksph) + params % rsph(ksph)*constants % cgrid(2,its)
1818 cz = params % csph(3,ksph) + params % rsph(ksph)*constants % cgrid(3,its)
1819 vki(1) = cx - params % csph(1,isph)
1820 vki(2) = cy - params % csph(2,isph)
1821 vki(3) = cz - params % csph(3,isph)
1824 vvki = dnrm2(3, vki, 1)
1825 tki = vvki/params % rsph(isph)
1832 if ((tki.gt.tlow).and.(tki.lt.thigh) .and. &
1833 & constants % ui(its,ksph).gt.zero)
then
1839 do l = 0, params % lmax
1842 fac = twopi/(two*fl + one)
1845 gg = gg + fac*constants % vgrid(ind+m,its)*g(ind+m,ksph)
1850 do jsph = 1, params % nsph
1851 if (jsph.ne.ksph .and. jsph.ne.isph)
then
1852 vkj(1) = cx - params % csph(1,jsph)
1853 vkj(2) = cy - params % csph(2,jsph)
1854 vkj(3) = cz - params % csph(3,jsph)
1855 vvkj = sqrt(vkj(1)*vkj(1) + vkj(2)*vkj(2) + &
1857 vvkj = dnrm2(3, vkj, 1)
1858 tkj = vvkj/params % rsph(jsph)
1860 call ylmbas(skj, rho, ctheta, stheta, cphi, sphi, &
1861 & params % lmax, constants % vscales, basloc, &
1864 do l = 0, params % lmax
1866 fcl = - fourpi*dble(l)/(two*dble(l)+one)*tt
1869 gg = gg + fcl*g(ind+m,jsph)*basloc(ind+m)
1880 call ylmbas(ski, rho, ctheta, stheta, cphi, sphi, &
1881 & params % lmax, constants % vscales, basloc, &
1884 do l = 0, params % lmax
1886 fcl = - four*pi*dble(l)/(two*dble(l)+one)*tt
1889 gg = gg + fcl*g(ind+m,isph)*basloc(ind+m)
1898 duj = dfsw(tki,params % se, params % eta)/params % rsph(isph)
1899 fjj = duj*constants % wgrid(its)*gg*ygrid(its,ksph)
1900 fx(1) = fx(1) - fjj*ski(1)
1901 fx(2) = fx(2) - fjj*ski(2)
1902 fx(3) = fx(3) - fjj*ski(3)
1907 if (constants % ui(its,isph).gt.zero.and.constants % ui(its,isph).lt.one)
then
1909 do l = 0, params % lmax
1912 fac = twopi/(two*fl + one)
1915 gi = gi + fac*constants % vgrid(ind+m,its)*g(ind+m,isph)
1923 fii = constants % wgrid(its)*gi*ygrid(its,isph)
1924 fx(1) = fx(1) + fii*constants % zi(1,its,isph)
1925 fx(2) = fx(2) + fii*constants % zi(2,its,isph)
1926 fx(3) = fx(3) + fii*constants % zi(3,its,isph)
1932 do its = 1, params % ngrid
1935 do jsph = 1, params % nsph
1936 if (constants % ui(its,jsph).gt.zero .and. jsph.ne.isph)
then
1938 cx = params % csph(1,jsph) + params % rsph(jsph)*constants % cgrid(1,its)
1939 cy = params % csph(2,jsph) + params % rsph(jsph)*constants % cgrid(2,its)
1940 cz = params % csph(3,jsph) + params % rsph(jsph)*constants % cgrid(3,its)
1941 vji(1) = cx - params % csph(1,isph)
1942 vji(2) = cy - params % csph(2,isph)
1943 vji(3) = cz - params % csph(3,isph)
1946 vvji = dnrm2(3, vji, 1)
1947 tji = vvji/params % rsph(isph)
1958 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
1959 & + sji(icomp)*sji(jcomp))
1965 call dbasis(params, constants, sji,basloc,dbsloc,vplm,vcos,vsin)
1970 do l = 0, params % lmax
1973 fcl = - tt*fourpi*fl/(two*fl + one)
1975 fac = fcl*g(ind+m,isph)
1976 b = (fl + one)*basloc(ind+m)/(params % rsph(isph)*tji)
1979 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
1980 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
1981 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
1982 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
1983 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
1984 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
1985 a(1) = a(1) + fac*(sji(1)*b + va(1))
1986 a(2) = a(2) + fac*(sji(2)*b + va(2))
1987 a(3) = a(3) + fac*(sji(3)*b + va(3))
1991 fac = constants % ui(its,jsph)*constants % wgrid(its)*ygrid(its,jsph)
1992 fx(1) = fx(1) - fac*a(1)
1993 fx(2) = fx(2) - fac*a(2)
1994 fx(3) = fx(3) - fac*a(3)
2000 do its = 1, params % ngrid
2001 cx = params % csph(1,isph) + params % rsph(isph)*constants % cgrid(1,its)
2002 cy = params % csph(2,isph) + params % rsph(isph)*constants % cgrid(2,its)
2003 cz = params % csph(3,isph) + params % rsph(isph)*constants % cgrid(3,its)
2007 do ksph = 1, params % nsph
2008 if (constants % ui(its,isph).gt.zero .and. ksph.ne.isph)
then
2010 vik(1) = cx - params % csph(1,ksph)
2011 vik(2) = cy - params % csph(2,ksph)
2012 vik(3) = cz - params % csph(3,ksph)
2015 vvik = dnrm2(3, vik, 1)
2016 tik = vvik/params % rsph(ksph)
2027 sjac(icomp,jcomp) = qik*(sjac(icomp,jcomp) &
2028 & - sik(icomp)*sik(jcomp))
2034 if (constants % ui(its,isph).lt.one)
then
2035 vb(1) = constants % zi(1,its,isph)
2036 vb(2) = constants % zi(2,its,isph)
2037 vb(3) = constants % zi(3,its,isph)
2042 call dbasis(params, constants, sik,basloc,dbsloc,vplm,vcos,vsin)
2046 do l = 0, params % lmax
2049 fcl = - tt*fourpi*fl/(two*fl + one)
2051 fac = fcl*g(ind+m,ksph)
2052 fac = - fac*basloc(ind+m)
2053 a(1) = a(1) + fac*vb(1)
2054 a(2) = a(2) + fac*vb(2)
2055 a(3) = a(3) + fac*vb(3)
2057 fac = constants % ui(its,isph)*fcl*g(ind+m,ksph)
2058 b = - (fl + one)*basloc(ind+m)/(params % rsph(ksph)*tik)
2061 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
2062 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
2063 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
2064 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
2065 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
2066 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
2067 a(1) = a(1) + fac*(sik(1)*b + va(1))
2068 a(2) = a(2) + fac*(sik(2)*b + va(2))
2069 a(3) = a(3) + fac*(sik(3)*b + va(3))
2075 fac = constants % wgrid(its)*ygrid(its,isph)
2076 fx(1) = fx(1) - fac*a(1)
2077 fx(2) = fx(2) - fac*a(2)
2078 fx(3) = fx(3) - fac*a(3)
2080end subroutine gradr_sph
2083subroutine gradr_fmm(params, constants, workspace, g, ygrid, fx)
2086 type(ddx_params_type),
intent(in) :: params
2087 type(ddx_constants_type),
intent(in) :: constants
2088 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2089 & ygrid(params % ngrid, params % nsph)
2091 type(ddx_workspace_type),
intent(inout) :: workspace
2093 real(dp),
intent(out) :: fx(3, params % nsph)
2095 integer :: indl, indl1, l, isph, igrid, ik, ksph, &
2097 integer :: inear, inode, jnode
2098 real(dp) :: gg, c(3), vki(3), vvki, tki, gg3(3), tmp_gg, tmp_c(3)
2099 real(dp) :: tlow, thigh
2100 real(dp),
dimension(3, 3) :: zx_coord_transform, zy_coord_transform
2101 real(dp),
external :: ddot, dnrm2
2102 real(dp) :: work(params % lmax+2)
2104 zx_coord_transform = 0
2105 zx_coord_transform(3, 2) = 1
2106 zx_coord_transform(2, 3) = 1
2107 zx_coord_transform(1, 1) = 1
2108 zy_coord_transform = 0
2109 zy_coord_transform(1, 2) = 1
2110 zy_coord_transform(2, 1) = 1
2111 zy_coord_transform(3, 3) = 1
2112 tlow = one - pt5*(one - params % se)*params % eta
2113 thigh = one + pt5*(one + params % se)*params % eta
2116 workspace % tmp_sph(1, :) = zero
2118 do l = 1, params % lmax
2120 workspace % tmp_sph(indl:indl1, :) = l * g(indl:indl1, :)
2127 call tree_grad_m2m(params, constants, workspace % tmp_sph, &
2128 & workspace % tmp_sph_grad, workspace % tmp_sph2)
2135 do isph = 1, params % nsph
2136 workspace % tmp_grid(:, isph) = ygrid(:, isph) * &
2137 & constants % wgrid(:) * constants % ui(:, isph)
2141 call tree_m2p_adj(params, constants, params % lmax+1, one, &
2142 & workspace % tmp_grid, zero, workspace % tmp_sph2)
2143 call tree_l2p_adj(params, constants, one, workspace % tmp_grid, zero, &
2144 & workspace % tmp_node_l, workspace % tmp_sph_l)
2147 & workspace % tmp_node_m)
2151 if(params % lmax+1 .lt. params % pm)
then
2152 do isph = 1, params % nsph
2153 inode = constants % snode(isph)
2154 workspace % tmp_sph2(:, isph) = workspace % tmp_sph2(:, isph) + &
2155 & workspace % tmp_node_m(1:constants % grad_nbasis, inode)
2158 indl = (params % pm+1)**2
2159 do isph = 1, params % nsph
2160 inode = constants % snode(isph)
2161 workspace % tmp_sph2(1:indl, isph) = &
2162 & workspace % tmp_sph2(1:indl, isph) + &
2163 & workspace % tmp_node_m(:, inode)
2167 do isph = 1, params % nsph
2168 call dgemv(
'T', constants % grad_nbasis, 3, one, &
2169 & workspace % tmp_sph_grad(1, 1, isph), constants % grad_nbasis, &
2170 & workspace % tmp_sph2(1, isph), 1, zero, fx(1, isph), 1)
2177 if(params % lmax .lt. params % pm)
then
2178 do isph = 1, params % nsph
2179 inode = constants % snode(isph)
2180 workspace % tmp_node_m(:constants % nbasis, inode) = &
2181 & workspace % tmp_sph(:, isph)
2182 workspace % tmp_node_m(constants % nbasis+1:, inode) = zero
2185 indl = (params % pm+1)**2
2186 do isph = 1, params % nsph
2187 inode = constants % snode(isph)
2188 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
2194 & workspace % tmp_node_l)
2196 call tree_l2p(params, constants, one, workspace % tmp_node_l, zero, &
2197 & workspace % tmp_grid, workspace % tmp_sph_l)
2198 call tree_m2p(params, constants, params % lmax, one, &
2199 & workspace % tmp_sph, one, workspace % tmp_grid)
2201 if (params % pl .gt. 0)
then
2202 call tree_grad_l2l(params, constants, workspace % tmp_node_l, &
2203 & workspace % tmp_sph_l_grad, workspace % tmp_sph_l)
2207 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
2208 & pt5, constants % vgrid2, constants % vgrid_nbasis, g, &
2209 & constants % nbasis, -one, workspace % tmp_grid, params % ngrid)
2211 do igrid = 1, params % ngrid
2212 do isph = 1, params % nsph
2213 workspace % tmp_grid(igrid, isph) = &
2214 & workspace % tmp_grid(igrid, isph) * constants % wgrid(igrid) * &
2215 & ygrid(igrid, isph)
2220 do isph = 1, params % nsph
2221 do igrid = 1, params % ngrid
2223 do ik = constants % inl(isph), constants % inl(isph+1) - 1
2224 ksph = constants % nl(ik)
2226 if(constants % ui(igrid, ksph) .eq. zero) cycle
2228 c = params % csph(:, ksph) + &
2229 & params % rsph(ksph)*constants % cgrid(:, igrid)
2230 vki = c - params % csph(:, isph)
2233 vvki = dnrm2(3, vki, 1)
2234 tki = vvki / params % rsph(isph)
2236 if((tki.le.tlow) .or. (tki.ge.thigh)) cycle
2240 gg = workspace % tmp_grid(igrid, ksph)
2247 fx(:, isph) = fx(:, isph) - &
2248 & dfsw(tki, params % se, params % eta)/ &
2249 & params % rsph(isph)*gg*(vki/vvki)
2252 if((constants % ui(igrid,isph).gt.zero) .and. &
2253 & (constants % ui(igrid,isph).lt.one))
then
2257 gg = workspace % tmp_grid(igrid, isph)
2262 fx(:, isph) = fx(:, isph) + gg*constants % zi(:, igrid, isph)
2264 if (constants % ui(igrid, isph) .gt. zero)
then
2271 call dgemv(
'T', params % pl**2, 3, one, &
2272 & workspace % tmp_sph_l_grad(1, 1, isph), &
2273 & (params % pl+1)**2, constants % vgrid2(1, igrid), 1, &
2277 inode = constants % snode(isph)
2278 do inear = constants % snear(inode), constants % snear(inode+1)-1
2279 jnode = constants % near(inear)
2280 do jsph_node = constants % cluster(1, jnode), &
2281 & constants % cluster(2, jnode)
2282 jsph = constants % order(jsph_node)
2283 if (isph .eq. jsph) cycle
2284 c = params % csph(:, isph) + &
2285 & params % rsph(isph)*constants % cgrid(:, igrid)
2286 tmp_c = c - params % csph(:, jsph)
2287 call fmm_m2p_work(tmp_c, &
2288 & params % rsph(jsph), params % lmax+1, &
2289 & constants % vscales_rel, one, &
2290 & workspace % tmp_sph_grad(:, 1, jsph), zero, &
2292 gg3(1) = gg3(1) + tmp_gg
2293 call fmm_m2p_work(tmp_c, &
2294 & params % rsph(jsph), params % lmax+1, &
2295 & constants % vscales_rel, one, &
2296 & workspace % tmp_sph_grad(:, 2, jsph), zero, &
2298 gg3(2) = gg3(2) + tmp_gg
2299 call fmm_m2p_work(tmp_c, &
2300 & params % rsph(jsph), params % lmax+1, &
2301 & constants % vscales_rel, one, &
2302 & workspace % tmp_sph_grad(:, 3, jsph), zero, &
2304 gg3(3) = gg3(3) + tmp_gg
2308 fx(:, isph) = fx(:, isph) - constants % wgrid(igrid)*gg3* &
2309 & ygrid(igrid, isph)*constants % ui(igrid, isph)
2313end subroutine gradr_fmm
2316subroutine gradr(params, constants, workspace, g, ygrid, fx)
2319 type(ddx_params_type),
intent(in) :: params
2320 type(ddx_constants_type),
intent(in) :: constants
2321 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2322 & ygrid(params % ngrid, params % nsph)
2324 type(ddx_workspace_type),
intent(inout) :: workspace
2326 real(dp),
intent(out) :: fx(3, params % nsph)
2328 if (params % fmm .eq. 1)
then
2329 call gradr_fmm(params, constants, workspace, g, ygrid, fx)
2331 call gradr_dense(params, constants, workspace, g, ygrid, fx)
2336subroutine gradr_dense(params, constants, workspace, g, ygrid, fx)
2339 type(ddx_params_type),
intent(in) :: params
2340 type(ddx_constants_type),
intent(in) :: constants
2341 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2342 & ygrid(params % ngrid, params % nsph)
2344 type(ddx_workspace_type),
intent(inout) :: workspace
2346 real(dp),
intent(out) :: fx(3, params % nsph)
2350 do isph = 1, params % nsph
2351 call gradr_sph(params, constants, isph, workspace % tmp_vplm, &
2352 & workspace % tmp_vcos, workspace % tmp_vsin, &
2353 & workspace % tmp_vylm, workspace % tmp_vdylm, &
2354 & g, ygrid, fx(:, isph))
2356end subroutine gradr_dense
2361subroutine zeta_grad(params, constants, state, e_cav, forces)
2363 type(ddx_params_type),
intent(in) :: params
2364 type(ddx_constants_type),
intent(in) :: constants
2366 real(dp),
intent(inout) :: forces(3, params % nsph)
2367 real(dp),
intent(in) :: e_cav(3, constants % ncav)
2369 integer :: icav, isph, igrid
2372 do isph = 1, params % nsph
2373 do igrid = 1, params % ngrid
2374 if (constants % ui(igrid, isph) .eq. zero) cycle
2376 forces(:, isph) = forces(:, isph) + pt5 &
2377 & *state % zeta(icav)*e_cav(:, icav)
2380end subroutine zeta_grad
2385subroutine zeta_grad_dr(params, constants, state, e_cav, dr)
2387 type(ddx_params_type),
intent(in) :: params
2388 type(ddx_constants_type),
intent(in) :: constants
2390 real(dp),
intent(inout) :: dr(params % nsph)
2391 real(dp),
intent(in) :: e_cav(3, constants % ncav)
2393 integer :: icav, isph, igrid
2396 do isph = 1, params % nsph
2397 do igrid = 1, params % ngrid
2398 if (constants % ui(igrid, isph) .eq. zero) cycle
2400 dr(isph) = dr(isph) + pt5 &
2401 & * dot_product(constants % cgrid(:,igrid), e_cav(:, icav))*state % zeta(icav)
2404end 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...