19subroutine contract_grad_l(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr)
20type(ddx_params_type),
intent(in) :: params
21 type(ddx_constants_type),
intent(in) :: constants
22 integer,
intent(in) :: isph
23 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
24 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
25 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
26 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
27 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
28 real(dp),
dimension(3),
intent(inout) :: fx
29 real(dp),
optional,
intent(inout) :: dr
42 if (params%switching.eq.0)
then
43 call contract_gradi_lik(params, constants, isph, sigma, xi(:, isph), basloc, dbsloc, vplm, vcos, vsin, fx, dr_local)
44 call contract_gradi_lji(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr_local)
46 call contract_grad_l_new(params, constants, isph, sigma, xi, &
47 & basloc, dbsloc, vplm, vcos, vsin, fx, dr_local)
50 if (do_dr) dr = dr_local
52end subroutine contract_grad_l
54subroutine contract_grad_l_new(params, constants, isph, x, xi, &
55 & basloc, dbsloc, vplm, vcos, vsin, fx, dr)
57 type(ddx_params_type),
intent(in) :: params
58 type(ddx_constants_type),
intent(in) :: constants
59 integer,
intent(in) :: isph
60 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: x
61 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
62 real(dp),
dimension(3),
intent(inout) :: fx
63 real(dp),
intent(inout) :: dr
65 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
66 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
67 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
69 real(dp) :: tlow, thigh
70 integer :: ig, ij, ji, jsph, icomp, jcomp, l, m, ind, ki, ksph, kj
71 real(dp) :: vij(3), vvij, sij(3), tij, oij, qij, grad_tij(3), &
72 & dr_sij(3), dr_tij, f_i, d_i, xij
73 real(dp) :: vji(3), vvji, sji(3), tji, oji, qji, grad_tji(3), &
74 & dr_sji(3), dr_tji, f_j, d_j, xji
75 real(dp) :: fl, a, b, c, d1, d2, e, tmp_fx(3), sjac_dylm(3), &
76 & sjac(3,3), tmp_dr, dr_s_dylm, grad_p, bj
77 real(dp) :: vik(3), vvik, sik(3), tik, grad_tik(3), dr_tik, xik
78 real(dp) :: vjk(3), vvjk, sjk(3), tjk, xjk
79 real(dp) :: rho, ctheta, stheta, cphi, sphi
81 tlow = one - pt5*(one - params % se)*params % eta
82 thigh = one + pt5*(one + params % se)*params % eta
85 do ig = 1, params % ngrid
86 do ij = constants % inl(isph), constants % inl(isph+1) - 1
87 jsph = constants % nl(ij)
90 oij = compute_omega(params, constants, isph, jsph, ig)
91 if (oij.eq.zero) cycle
92 vij = params % csph(:,isph) + &
93 & params % rsph(isph)*constants % cgrid(:,ig) - &
94 & params % csph(:,jsph)
95 vvij = sqrt(vij(1)*vij(1) + vij(2)*vij(2) + vij(3)*vij(3))
96 tij = vvij/params % rsph(jsph)
101 grad_tij(:) = sij(:)/params%rsph(jsph)
109 sjac(icomp,jcomp) = qij*(sjac(icomp,jcomp) &
110 & - sij(icomp)*sij(jcomp))
116 dr_sij = constants%cgrid(:,ig)/vvij &
117 & - vij*dot_product(vij, constants%cgrid(:,ig))/(vvij**3)
118 dr_tij = dot_product(vij, constants%cgrid(:,ig)) &
119 & /(vvij*params%rsph(jsph))
122 call dbasis(params, constants, sij, basloc, dbsloc, vplm, &
127 a = xi(ig,isph)*constants%wgrid(ig)*oij
130 do l = 0, params % lmax
133 b = a*fourpi/(two*fl + one)*tij**(l-1)
138 sjac_dylm(1) = sjac(1,1)*dbsloc(1,ind+m) + &
139 & sjac(1,2)*dbsloc(2,ind+m)+sjac(1,3) &
141 sjac_dylm(2) = sjac(2,1)*dbsloc(1,ind+m) + &
142 & sjac(2,2)*dbsloc(2,ind+m)+sjac(2,3)* &
144 sjac_dylm(3) = sjac(3,1)*dbsloc(1,ind+m) + &
145 & sjac(3,2)*dbsloc(2,ind+m)+sjac(3,3) &
150 dr_s_dylm = dr_sij(1)*dbsloc(1,ind+m) &
151 & + dr_sij(2)*dbsloc(2,ind+m) &
152 & + dr_sij(3)*dbsloc(3,ind+m)
155 d1 = c*fl*basloc(ind+m)
157 tmp_fx(:) = tmp_fx(:) &
158 & - c*fl*basloc(ind+m)*grad_tij(:) &
159 & - c*tij*sjac_dylm(:)
160 dr = dr - c*fl*basloc(ind+m)*dr_tij &
162 e = e + b*x(ind+m,jsph)*basloc(ind+m)*tij
168 d_i = constants%switching%d_ni(ig,isph)
169 f_i = constants%switching%f_ni(ig,isph)
171 if (tij.ge.tlow .and. tij.le.thigh)
then
172 grad_p = dfsw(tij, params % se, params % eta)
174 tmp_fx(:) = tmp_fx(:) - b*grad_tij(:)
175 tmp_dr = tmp_dr - b*dr_tij
177 xij = fsw(tij, params % se, params % eta)
178 if (xij .ne. zero)
then
179 b = a*xij/(d_i + f_i)
180 do ki = constants % inl(isph), constants % inl(isph+1) - 1
181 ksph = constants % nl(ki)
182 vik = params%csph(:,isph) + &
183 & params%rsph(isph)*constants%cgrid(:,ig) - &
184 & params%csph(:,ksph)
185 vvik = sqrt(vik(1)*vik(1) + vik(2)*vik(2) &
187 tik = vvik/params % rsph(ksph)
188 if (tik.ge.tlow .and. tik.le.thigh)
then
189 xik = fsw(tik, params % se, params % eta)
191 grad_tik(:) = sik(:)/params%rsph(ksph)
192 dr_tik = dot_product(vik, constants%cgrid(:,ig)) &
193 & /(vvik*params%rsph(ksph))
194 grad_p = dfsw(tik, params % se, params % eta)
196 if (grad_p.ne.zero)
then
197 c = b*(one - d_i/(one - xik))*grad_p
202 tmp_fx(:) = tmp_fx(:) + c*grad_tik
203 tmp_dr = tmp_dr + c*dr_tik
209 fx(:) = fx(:) + tmp_fx(:)
214 do ig = 1, params % ngrid
215 do ji = constants % inl(isph), constants % inl(isph+1) - 1
216 jsph = constants % nl(ji)
219 oji = compute_omega(params, constants, jsph, isph, ig)
220 if (oji.eq.zero) cycle
221 vji = params % csph(:,jsph) + &
222 & params % rsph(jsph)*constants % cgrid(:,ig) - &
223 & params % csph(:,isph)
224 vvji = sqrt(vji(1)*vji(1) + vji(2)*vji(2) + vji(3)*vji(3))
225 tji = vvji/params % rsph(isph)
230 grad_tji(:) = -sji/params % rsph(isph)
238 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
239 & + sji(icomp)*sji(jcomp))
246 dr_tji = -tji/params%rsph(isph)
249 call dbasis(params, constants, sji, basloc, dbsloc, vplm, &
254 a = xi(ig,jsph)*constants%wgrid(ig)*oji
257 do l = 0, params % lmax
260 b = a*fourpi/(two*fl + one)*tji**(l-1)
265 sjac_dylm(1) = sjac(1,1)*dbsloc(1,ind+m) + &
266 & sjac(1,2)*dbsloc(2,ind+m)+sjac(1,3)*dbsloc(3,ind+m)
267 sjac_dylm(2) = sjac(2,1)*dbsloc(1,ind+m) + &
268 & sjac(2,2)*dbsloc(2,ind+m)+sjac(2,3)*dbsloc(3,ind+m)
269 sjac_dylm(3) = sjac(3,1)*dbsloc(1,ind+m) + &
270 & sjac(3,2)*dbsloc(2,ind+m)+sjac(3,3)*dbsloc(3,ind+m)
274 dr_s_dylm = dr_sji(1)*dbsloc(1,ind+m) &
275 & + dr_sji(2)*dbsloc(2,ind+m) &
276 & + dr_sji(3)*dbsloc(3,ind+m)
279 d1 = c*fl*basloc(ind+m)
281 tmp_fx(:) = tmp_fx(:) &
282 & - c*fl*basloc(ind+m)*grad_tji(:) &
283 & - c*tji*sjac_dylm(:)
284 tmp_dr = tmp_dr - c*fl*basloc(ind+m)*dr_tji &
286 e = e + b*x(ind+m,isph)*basloc(ind+m)*tji
292 d_j = constants%switching%d_ni(ig,jsph)
293 f_j = constants%switching%f_ni(ig,jsph)
295 if (tji.ge.tlow .and. tji.le.thigh)
then
296 grad_p = dfsw(tji, params % se, params % eta)
298 tmp_fx(:) = tmp_fx(:) - b*grad_tji(:)
299 tmp_dr = tmp_dr - b*dr_tji
302 fx(:) = fx(:) + tmp_fx(:)
310 do ig = 1, params % ngrid
311 do ij = constants % inl(isph), constants % inl(isph+1) - 1
312 jsph = constants % nl(ij)
315 vji = params % csph(:,jsph) + &
316 & params % rsph(jsph)*constants % cgrid(:,ig) - &
317 & params % csph(:,isph)
318 vvji = sqrt(vji(1)*vji(1) + vji(2)*vji(2) + vji(3)*vji(3))
319 tji = vvji/params % rsph(isph)
322 if (.not.(tji.ge.tlow .and. tji.le.thigh)) cycle
326 grad_tji(:) = -sji/params % rsph(isph)
330 dr_tji = -tji/params%rsph(isph)
332 xji = fsw(tji, params % se, params % eta)
334 d_j = constants%switching%d_ni(ig,jsph)
335 f_j = constants%switching%f_ni(ig,jsph)
336 grad_p = dfsw(tji, params % se, params % eta)
338 if (grad_p.eq.zero) cycle
341 do kj = constants % inl(jsph), constants % inl(jsph+1) - 1
342 ksph = constants % nl(kj)
343 if (jsph.eq.ksph) cycle
346 vjk = params % csph(:,jsph) + &
347 & params % rsph(jsph)*constants % cgrid(:,ig) - &
348 & params % csph(:,ksph)
349 vvjk = sqrt(vjk(1)*vjk(1) + vjk(2)*vjk(2) &
351 tjk = vvjk/params % rsph(ksph)
354 xjk = fsw(tjk, params % se, params % eta)
355 if (xjk.eq.zero) cycle
358 call ylmbas(sjk, rho, ctheta, stheta, cphi, sphi, &
359 & params % lmax, constants % vscales, basloc, &
364 a = xi(ig,jsph)*constants%wgrid(ig)
365 do l = 0, params % lmax
368 b = a*fourpi/(two*fl + one)*tjk**l
370 e = e + b*x(ind+m,ksph)*basloc(ind+m)
378 c = bj/(d_j + f_j)**2*(one - d_j/(one - xji))*grad_p
379 tmp_fx(:) = tmp_fx(:) + c*grad_tji
380 tmp_dr = tmp_dr + c*dr_tji
384 fx(:) = fx(:) + tmp_fx(:)
387end subroutine contract_grad_l_new
390subroutine contract_gradi_lik(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr)
391 type(ddx_params_type),
intent(in) :: params
392 type(ddx_constants_type),
intent(in) :: constants
393 integer,
intent(in) :: isph
394 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sigma
395 real(dp),
dimension(params % ngrid),
intent(in) :: xi
396 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
397 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
398 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
399 real(dp),
dimension(3),
intent(inout) :: fx
400 integer :: ig, ij, jsph, l, ind, m
401 real(dp) :: vvij, tij, xij, oij, t, fac, fl, f1, f2, f3, beta, tlow, thigh
402 real(dp) :: vij(3), sij(3), alp(3), va(3)
403 real(dp) :: dsij, dtij(3), alp1(3), alp2(3), alp_rad, dsij_rad(3), dtij_rad, alp1_rad, alp2_rad, va_rad
404 real(dp),
external :: dnrm2
405 real(dp),
intent(inout) :: dr
406 real(dp) :: sjac(3,3), qij
407 tlow = one - pt5*(one - params % se)*params % eta
408 thigh = one + pt5*(one + params % se)*params % eta
410 do ig = 1, params % ngrid
413 do ij = constants % inl(isph), constants % inl(isph+1) - 1
414 jsph = constants % nl(ij)
415 vij = params % csph(:,isph) + &
416 & params % rsph(isph)*constants % cgrid(:,ig) - &
417 & params % csph(:,jsph)
418 vvij = dnrm2(3, vij, 1)
419 tij = vvij/params % rsph(jsph)
420 if (tij.ge.thigh) cycle
421 if (tij.ne.zero)
then
427 dsij = 1.0_dp / (tij*params%rsph(jsph))
428 dtij(:) = sij(:)/params%rsph(jsph)
438 sjac(icomp,jcomp) = qij*(sjac(icomp,jcomp) &
439 & - sij(icomp)*sij(jcomp))
443 dsij_rad = constants%cgrid(:,ig)/vvij &
444 & - vij * dot_product(vij, constants%cgrid(:,ig)) / (vvij**3)
445 dtij_rad = dot_product(vij, constants%cgrid(:,ig)) &
446 & / (vvij*params%rsph(jsph))
448 call dbasis(params, constants, sij, basloc, dbsloc, vplm, vcos, vsin)
458 do l = 1, params % lmax
461 fac = t/(constants % vscales(ind)**2)
463 f2 = fac*sigma(ind+m,jsph)
464 f1 = f2*fl*basloc(ind+m)
467 alp1_rad = f1*dtij_rad
469 alp2(1) = sjac(1,1)*dbsloc(1,ind+m) + &
470 & sjac(1,2)*dbsloc(2,ind+m)+sjac(1,3)*dbsloc(3,ind+m)
471 alp2(2) = sjac(2,1)*dbsloc(1,ind+m) + &
472 & sjac(2,2)*dbsloc(2,ind+m)+sjac(2,3)*dbsloc(3,ind+m)
473 alp2(3) = sjac(3,1)*dbsloc(1,ind+m) + &
474 & sjac(3,2)*dbsloc(2,ind+m)+sjac(3,3)*dbsloc(3,ind+m)
475 alp2(:) = alp2(:)*tij*f2
477 alp2_rad = f2*tij*dot_product(dsij_rad, dbsloc(:,ind+m))
479 alp(:) = alp(:) + alp1(:) + alp2(:)
480 alp_rad = alp_rad + alp1_rad + alp2_rad
485 beta =
intmlp(params, constants, tij,sigma(:,jsph),basloc)
486 xij = fsw(tij, params % se, params % eta)
487 if (constants % fi(ig,isph).gt.one)
then
488 oij = xij/constants % fi(ig,isph)
489 f2 = -oij/constants % fi(ig,isph)
495 va(:) = va(:) + f1*alp(:) + beta*f2*constants % zi(:,ig,isph)
496 va_rad = va_rad + f1*alp_rad + beta*f2*constants % zi_dr(ig,isph)
497 if (tij .gt. tlow)
then
498 f3 = beta*dfsw(tij,params % se,params % eta)
499 if (constants % fi(ig,isph).gt.one) f3 = f3/constants % fi(ig,isph)
500 va(:) = va(:) + f3*dtij
501 va_rad = va_rad + f3*dtij_rad
504 fx = fx - constants % wgrid(ig)*xi(ig)*va(:)
505 dr = dr - constants % wgrid(ig)*xi(ig)*va_rad
507end subroutine contract_gradi_lik
510subroutine contract_gradi_lji(params, constants, isph, sigma, xi, basloc, dbsloc, vplm, vcos, vsin, fx, dr)
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) :: sigma
515 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi
516 real(dp),
dimension(constants % nbasis),
intent(inout) :: basloc, vplm
517 real(dp),
dimension(3, constants % nbasis),
intent(inout) :: dbsloc
518 real(dp),
dimension(params % lmax+1),
intent(inout) :: vcos, vsin
519 real(dp),
dimension(3),
intent(inout) :: fx
521 integer :: ig, ji, jsph, l, ind, m, jk, ksph
523 real(dp) :: vvji, tji, xji, oji, t, fac, fl, f1, f2, beta, di, tlow, thigh
524 real(dp) :: b, g1, g2, vvjk, tjk, xjk
525 real(dp) :: vji(3), sji(3), alp(3), vb(3), vjk(3), sjk(3), vc(3)
526 real(dp) :: dsji, dtji(3), alp1(3), alp2(3), alp_rad, dsji_rad(3), dtji_rad, alp1_rad, alp2_rad, vb_rad, vc_rad
527 real(dp) :: rho, ctheta, stheta, cphi, sphi
528 real(dp),
external :: dnrm2
529 real(dp),
intent(inout) :: dr
530 real(dp) :: sjac(3,3), qji
532 tlow = one - pt5*(one - params % se)*params % eta
533 thigh = one + pt5*(one + params % se)*params % eta
535 do ig = 1, params % ngrid
542 do ji = constants % inl(isph), constants % inl(isph+1) - 1
543 jsph = constants % nl(ji)
544 vji = params % csph(:,jsph) + &
545 & params % rsph(jsph)*constants % cgrid(:,ig) - &
546 & params % csph(:,isph)
547 vvji = dnrm2(3, vji, 1)
548 tji = vvji/params % rsph(isph)
549 if (tji.gt.thigh) cycle
550 if (tji.ne.zero)
then
564 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
565 & + sji(icomp)*sji(jcomp))
569 dsji = 1.0_dp/(tji*params % rsph(isph))
570 dtji(:) = -sji/params % rsph(isph)
573 dtji_rad = -tji/params%rsph(isph)
575 call dbasis(params, constants, sji, basloc, dbsloc, vplm, vcos, vsin)
585 do l = 1, params % lmax
588 fac = t/(constants % vscales(ind)**2)
590 f2 = fac*sigma(ind+m,isph)
591 f1 = f2*fl*basloc(ind+m)
594 alp1_rad = f1*dtji_rad
596 alp2(1) = sjac(1,1)*dbsloc(1,ind+m) + &
597 & sjac(1,2)*dbsloc(2,ind+m)+sjac(1,3)*dbsloc(3,ind+m)
598 alp2(2) = sjac(2,1)*dbsloc(1,ind+m) + &
599 & sjac(2,2)*dbsloc(2,ind+m)+sjac(2,3)*dbsloc(3,ind+m)
600 alp2(3) = sjac(3,1)*dbsloc(1,ind+m) + &
601 & sjac(3,2)*dbsloc(2,ind+m)+sjac(3,3)*dbsloc(3,ind+m)
602 alp2(:) = alp2(:)*tji*f2
604 alp2_rad = f2*tji*dot_product(dsji_rad,dbsloc(:,ind+m))
606 alp(:) = alp(:) + alp1(:) + alp2(:)
607 alp_rad = alp_rad + alp1_rad + alp2_rad
613 xji = fsw(tji, params % se, params % eta)
614 if (constants % fi(ig,jsph).gt.one)
then
615 oji = xji/constants % fi(ig,jsph)
619 vb = vb + oji*alp*xi(ig,jsph)
620 vb_rad = vb_rad + oji*alp_rad*xi(ig,jsph)
621 if (tji .gt. tlow)
then
622 beta =
intmlp(params, constants, tji, sigma(:,isph), basloc)
623 if (constants % fi(ig,jsph) .gt. one)
then
624 di = one/constants % fi(ig,jsph)
628 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
629 ksph = constants % nl(jk)
630 vjk = params % csph(:,jsph) + &
631 & params % rsph(jsph)*constants % cgrid(:,ig) - &
632 & params % csph(:,ksph)
634 vvjk = dnrm2(3, vjk, 1)
635 tjk = vvjk/params % rsph(ksph)
636 if (ksph.ne.isph)
then
637 if (tjk .le. thigh)
then
641 call ylmbas(sjk, rho, ctheta, stheta, cphi, sphi, &
642 & params % lmax, constants % vscales, basloc, vplm, &
644 g1 =
intmlp(params, constants, tjk, sigma(:,ksph), basloc)
645 xjk = fsw(tjk, params % se, params % eta)
651 g1 = di*di*dfsw(tji, params % se, params % eta)
652 g2 = g1*xi(ig,jsph)*b
654 vc_rad = vc_rad - g2*dtji_rad
660 f2 = (one-fac)*di*dfsw(tji, params % se, params % eta)
661 vb = vb + f2*xi(ig,jsph)*beta*dtji
662 vb_rad = vb_rad + f2*xi(ig,jsph)*beta*dtji_rad
665 fx = fx - constants % wgrid(ig)*(vb + vc)
666 dr = dr - constants % wgrid(ig)*(vb_rad + vc_rad)
668end subroutine contract_gradi_lji
673subroutine contract_grad_u(params, constants, isph, xi, phi, fx, dr)
675 type(ddx_params_type),
intent(in) :: params
676 type(ddx_constants_type),
intent(in) :: constants
677 integer,
intent(in) :: isph
678 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: xi, phi
679 real(dp),
dimension(3),
intent(inout) :: fx
680 real(dp),
optional,
intent(inout) :: dr
681 integer :: ig, ji, jsph
682 real(dp) :: vvji, tji, fac, swthr
683 real(dp) :: alp(3), vji(3), sji(3), dtji(3)
684 real(dp) :: dtji_rad, alp_rad
685 real(dp),
external :: dnrm2
687 real(dp) :: xi_w_v_i, d_i, f_i, xi_w_v_j, d_j, f_j, grad_p, &
688 & chi_ij, chi_ji, grad_t(3), a, vij(3), vvij, tij, sij(3), dr_t
690 if (params%switching.eq.0)
then
692 do ig = 1, params % ngrid
695 if (constants % ui(ig,isph) .gt. zero .and. constants % ui(ig,isph).lt.one)
then
696 alp = alp + phi(ig,isph)*xi(ig,isph)*constants % zi(:,ig,isph)
697 alp_rad = alp_rad + phi(ig,isph)*xi(ig,isph)*constants % zi_dr(ig,isph)
699 do ji = constants % inl(isph), constants % inl(isph+1) - 1
700 jsph = constants % nl(ji)
701 vji = params % csph(:,jsph) + &
702 & params % rsph(jsph)*constants % cgrid(:,ig) - &
703 & params % csph(:,isph)
704 vvji = dnrm2(3, vji, 1)
705 tji = vvji/params % rsph(isph)
706 swthr = one + (params % se + 1.d0)*params % eta / 2.d0
707 if (tji.lt.swthr .and. tji.gt.swthr-params % eta .and. constants % ui(ig,jsph).gt.zero)
then
709 dtji = - sji / params % rsph(isph)
710 dtji_rad = - vvji/(params%rsph(isph)**2)
711 fac = dfsw(tji, params % se, params % eta)
712 alp = alp + fac*phi(ig,jsph)*xi(ig,jsph) * dtji
713 alp_rad = alp_rad + fac*phi(ig,jsph)*xi(ig,jsph) * dtji_rad
716 fx = fx - constants % wgrid(ig)*alp
717 dr_local = dr_local - constants % wgrid(ig)*alp_rad
722 do ig = 1, params % ngrid
723 xi_w_v_i = xi(ig,isph)*constants%wgrid(ig)*phi(ig,isph)
724 d_i = constants%switching%d_ni(ig,isph)
725 f_i = constants%switching%f_ni(ig,isph)
726 do ji = constants % inl(isph), constants % inl(isph+1) - 1
727 jsph = constants % nl(ji)
728 vji = params % csph(:,jsph) + &
729 & params % rsph(jsph)*constants % cgrid(:,ig) - &
730 & params % csph(:,isph)
731 vvji = sqrt(vji(1)*vji(1) + vji(2)*vji(2) &
734 tji = vvji/params % rsph(isph)
736 vij = params % csph(:,isph) + &
737 & params % rsph(isph)*constants % cgrid(:,ig) - &
738 & params % csph(:,jsph)
739 vvij = sqrt(vij(1)*vij(1) + vij(2)*vij(2) &
742 tij = vvij/params % rsph(jsph)
744 swthr = one + (params % se + one)*params % eta/two
746 xi_w_v_j = xi(ig,jsph)*constants%wgrid(ig)*phi(ig,jsph)
747 d_j = constants%switching%d_ni(ig,jsph)
748 f_j = constants%switching%f_ni(ig,jsph)
750 if (tij.lt.swthr .and. tij.gt.swthr-params % eta)
then
753 grad_p = dfsw(tij, params % se, params % eta)
754 chi_ij = fsw(tij, params % se, params % eta)
755 grad_t = sij/params%rsph(jsph)
756 dr_t = (constants%cgrid(1,ig)*sij(1) &
757 & + constants%cgrid(2,ig)*sij(2) &
758 & + constants%cgrid(3,ig)*sij(3)) &
760 a = xi_w_v_i/(f_i+d_i)**2 &
761 & *(-d_i - f_i*d_i/(one-chi_ij))*grad_p
763 dr_local = dr_local + a*dr_t
766 if (tji.lt.swthr .and. tji.gt.swthr-params % eta)
then
769 grad_p = dfsw(tji, params % se, params % eta)
770 chi_ji = fsw(tji, params % se, params % eta)
771 grad_t = -sji/params%rsph(isph)
772 dr_t = -tji/params%rsph(isph)
773 a = xi_w_v_j/(f_j+d_j)**2 &
774 & *(-d_j - f_j*d_j/(one-chi_ji))*grad_p
776 dr_local = dr_local + a*dr_t
782 if (
present(dr)) dr = dr_local
783end subroutine contract_grad_u
794subroutine contract_grad_b(params, constants, isph, Xe, Xadj_e, force)
796 type(ddx_params_type),
intent(in) :: params
797 type(ddx_constants_type),
intent(in) :: constants
798 integer,
intent(in) :: isph
799 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
800 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
801 real(dp),
dimension(3),
intent(inout) :: force
804 if (params%switching.eq.0)
then
805 call contract_gradi_bik(params, constants, isph, xe(:,:), &
806 & xadj_e(:, isph), force)
807 call contract_gradi_bji(params, constants, isph, xe(:,:), xadj_e, force)
809 call contract_grad_b_new(params, constants, isph, xe(:,:), xadj_e, force, dr)
812end subroutine contract_grad_b
823subroutine contract_grad_b_new(params, constants, isph, Xe, Xadj_e, force, dr)
825 type(ddx_params_type),
intent(in) :: params
826 type(ddx_constants_type),
intent(in) :: constants
827 integer,
intent(in) :: isph
828 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
829 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
830 real(dp),
dimension(3),
intent(inout) :: force
831 real(dp),
intent(inout) :: dr
833 real(dp) :: tlow, thigh
834 integer :: ig, ij, ji, jsph, l, ind, ki, ksph, kj
835 real(dp) :: vij(3), vvij, sij(3), tij, oij, grad_tij(3), d_i, f_i, xij
836 real(dp) :: vji(3), vvji, sji(3), tji, oji, grad_tji(3), dr_tji, &
838 real(dp) :: vik(3), vvik, sik(3), tik, grad_tik(3), xik
839 real(dp) :: vjk(3), vvjk, tjk, xjk
840 real(dp) :: vtij(3), vtji(3), vtjk(3), alpha(3)
841 real(dp) :: beta, beta_dr, beta_jk, fac
842 real(dp) :: Xe_dr(constants % nbasis)
843 real(dp) :: a, b, c, e, bj, grad_p, tmp_fx(3), tmp_dr
844 real(dp),
external :: dnrm2
845 real(dp) :: work(params % lmax+1)
846 complex(dp) :: work_complex(params % lmax+1)
848 tlow = one - pt5*(one - params % se)*params % eta
849 thigh = one + pt5*(one + params % se)*params % eta
851 do l = 0, params % lmax
853 fac = - params % kappa * constants % DI_ri(l, isph) &
854 & / constants % SI_ri(l, isph)
855 xe_dr(ind-l:ind+l) = fac * xe(ind-l:ind+l, isph)
859 do ig = 1, params % ngrid
860 do ij = constants % inl(isph), constants % inl(isph+1) - 1
861 jsph = constants % nl(ij)
864 oij = compute_omega(params, constants, isph, jsph, ig)
865 if (oij.eq.zero) cycle
866 vij = params % csph(:,isph) + &
867 & params % rsph(isph)*constants % cgrid(:,ig) - &
868 & params % csph(:,jsph)
869 vvij = dnrm2(3, vij, 1)
870 tij = vvij/params % rsph(jsph)
872 vtij = vij*params % kappa
875 grad_tij(:) = sij(:)/params % rsph(jsph)
879 call fmm_l2p_bessel_grad(vtij, params % rsph(jsph)*params % kappa, &
880 & params % lmax, constants % vscales, params % kappa, &
881 & xe(:, jsph), zero, alpha)
884 call fmm_l2p_bessel_work(vtij, params % lmax, constants % vscales, &
885 & constants % SI_ri(:, jsph), one, xe(:, jsph), zero, beta, &
886 & work_complex, work)
888 a = xadj_e(ig,isph)*constants % wgrid(ig)
889 tmp_fx(:) = - a*oij*alpha(:)
893 d_i = constants % switching % d_ni(ig,isph)
894 f_i = constants % switching % f_ni(ig,isph)
896 if (tij.ge.tlow .and. tij.le.thigh)
then
897 grad_p = dfsw(tij, params % se, params % eta)
899 tmp_fx(:) = tmp_fx(:) - b*grad_tij(:)
901 xij = fsw(tij, params % se, params % eta)
902 if (xij .ne. zero)
then
903 b = a*xij/(d_i + f_i)
904 do ki = constants % inl(isph), constants % inl(isph+1) - 1
905 ksph = constants % nl(ki)
906 vik = params % csph(:,isph) + &
907 & params % rsph(isph)*constants % cgrid(:,ig) - &
908 & params % csph(:,ksph)
909 vvik = dnrm2(3, vik, 1)
910 tik = vvik/params % rsph(ksph)
911 if (tik.ge.tlow .and. tik.le.thigh)
then
912 xik = fsw(tik, params % se, params % eta)
914 grad_tik(:) = sik(:)/params % rsph(ksph)
915 grad_p = dfsw(tik, params % se, params % eta)
917 if (grad_p.ne.zero)
then
918 c = b*(one - d_i/(one - xik))*grad_p
923 tmp_fx(:) = tmp_fx(:) + c*grad_tik
928 force(:) = force(:) + tmp_fx(:)
929 dr = dr + dot_product(tmp_fx, constants % cgrid(:,ig))
934 do ig = 1, params % ngrid
935 do ji = constants % inl(isph), constants % inl(isph+1) - 1
936 jsph = constants % nl(ji)
939 oji = compute_omega(params, constants, jsph, isph, ig)
940 if (oji.eq.zero) cycle
941 vji = params % csph(:,jsph) + &
942 & params % rsph(jsph)*constants % cgrid(:,ig) - &
943 & params % csph(:,isph)
944 vvji = dnrm2(3, vji, 1)
945 tji = vvji/params % rsph(isph)
947 vtji = vji*params % kappa
950 grad_tji(:) = -sji/params % rsph(isph)
953 dr_tji = -tji/params % rsph(isph)
956 call fmm_l2p_bessel_grad(vtji, params % rsph(isph)*params % kappa, &
957 & params % lmax, constants % vscales, params % kappa, &
958 & xe(:, isph), zero, alpha)
961 call fmm_l2p_bessel_work(vtji, params % lmax, constants % vscales, &
962 & constants % SI_ri(:, isph), one, xe(:, isph), zero, beta, &
963 & work_complex, work)
966 call fmm_l2p_bessel_work(vtji, params % lmax, constants % vscales, &
967 & constants % SI_ri(:, isph), one, xe_dr, zero, beta_dr, &
968 & work_complex, work)
970 a = xadj_e(ig,jsph)*constants % wgrid(ig)
971 tmp_fx(:) = a*oji*alpha(:)
972 tmp_dr = - a*oji*beta_dr
976 d_j = constants % switching % d_ni(ig,jsph)
977 f_j = constants % switching % f_ni(ig,jsph)
979 if (tji.ge.tlow .and. tji.le.thigh)
then
980 grad_p = dfsw(tji, params % se, params % eta)
982 tmp_fx(:) = tmp_fx(:) - b*grad_tji(:)
983 tmp_dr = tmp_dr - b*dr_tji
986 force(:) = force(:) + tmp_fx(:)
994 do ig = 1, params % ngrid
995 do ij = constants % inl(isph), constants % inl(isph+1) - 1
996 jsph = constants % nl(ij)
999 vji = params % csph(:,jsph) + &
1000 & params % rsph(jsph)*constants % cgrid(:,ig) - &
1001 & params % csph(:,isph)
1002 vvji = dnrm2(3, vji, 1)
1003 tji = vvji/params % rsph(isph)
1006 if (.not.(tji.ge.tlow .and. tji.le.thigh)) cycle
1009 grad_tji(:) = -sji/params % rsph(isph)
1012 dr_tji = -tji/params % rsph(isph)
1014 xji = fsw(tji, params % se, params % eta)
1016 d_j = constants % switching % d_ni(ig,jsph)
1017 f_j = constants % switching % f_ni(ig,jsph)
1018 grad_p = dfsw(tji, params % se, params % eta)
1020 if (grad_p.eq.zero) cycle
1023 do kj = constants % inl(jsph), constants % inl(jsph+1) - 1
1024 ksph = constants % nl(kj)
1025 if (jsph.eq.ksph) cycle
1028 vjk = params % csph(:,jsph) + &
1029 & params % rsph(jsph)*constants % cgrid(:,ig) - &
1030 & params % csph(:,ksph)
1031 vvjk = dnrm2(3, vjk, 1)
1032 tjk = vvjk/params % rsph(ksph)
1034 xjk = fsw(tjk, params % se, params % eta)
1035 if (xjk.eq.zero) cycle
1039 vtjk = vjk*params % kappa
1040 call fmm_l2p_bessel_work(vtjk, params % lmax, &
1041 & constants % vscales, constants % SI_ri(:, ksph), one, &
1042 & xe(:, ksph), zero, beta_jk, work_complex, work)
1044 e = xadj_e(ig,jsph)*constants % wgrid(ig)*beta_jk
1048 c = bj/(d_j + f_j)**2*(one - d_j/(one - xji))*grad_p
1049 tmp_fx(:) = tmp_fx(:) + c*grad_tji
1050 tmp_dr = tmp_dr + c*dr_tji
1054 force(:) = force(:) + tmp_fx(:)
1057end subroutine contract_grad_b_new
1075subroutine contract_grad_c(params, constants, workspace, Xr, Xe, Xadj_r_sgrid, &
1076 & Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
1078 type(ddx_params_type),
intent(in) :: params
1079 type(ddx_constants_type),
intent(in) :: constants
1080 type(ddx_workspace_type),
intent(inout) :: workspace
1081 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
1082 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_r_sgrid, Xadj_e_sgrid
1083 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xadj_r, Xadj_e
1084 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1085 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: diff_re
1086 type(ddx_error_type),
intent(inout) :: ddx_error
1088 call contract_grad_c_worker2(params, constants, workspace, xr, xe, xadj_r_sgrid, &
1089 & xadj_e_sgrid, xadj_r, xadj_e, force, diff_re, ddx_error)
1090 if (ddx_error % flag .ne. 0)
then
1091 call update_error(ddx_error, &
1092 &
"contract_grad_C_worker2 returned an error, exiting")
1095 call contract_grad_c_worker1(params, constants, workspace, xadj_r_sgrid, &
1096 & xadj_e_sgrid, diff_re, force, ddx_error)
1097 if (ddx_error % flag .ne. 0)
then
1098 call update_error(ddx_error, &
1099 &
"contract_grad_C_worker1 returned an error, exiting")
1103end subroutine contract_grad_c
1116subroutine contract_grad_f(params, constants, workspace, sol_adj, sol_sgrid, &
1117 & gradpsi, normal_hessian_cav, force, state, ddx_error)
1118 type(ddx_params_type),
intent(in) :: params
1119 type(ddx_constants_type),
intent(in) :: constants
1120 type(ddx_workspace_type),
intent(inout) :: workspace
1122 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: sol_adj
1123 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
1124 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
1125 real(dp),
dimension(3, constants % ncav),
intent(in) :: normal_hessian_cav
1126 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1127 type(ddx_error_type),
intent(inout) :: ddx_error
1129 call contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
1130 & gradpsi, force, ddx_error)
1131 if (ddx_error % flag .ne. 0)
then
1132 call update_error(ddx_error, &
1133 &
"contract_grad_f_worker1 returned an error, exiting")
1137 call contract_grad_f_worker2(params, constants, gradpsi, &
1138 & normal_hessian_cav, force, state, ddx_error)
1139 if (ddx_error % flag .ne. 0)
then
1140 call update_error(ddx_error, &
1141 &
"contract_grad_f_worker2 returned an error, exiting")
1145end subroutine contract_grad_f
1155subroutine contract_gradi_bik(params, constants, isph, Xe, Xadj_e, force)
1157 type(ddx_params_type),
intent(in) :: params
1158 type(ddx_constants_type),
intent(in) :: constants
1159 integer,
intent(in) :: isph
1160 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
1161 real(dp),
dimension(params % ngrid),
intent(in) :: Xadj_e
1162 real(dp),
dimension(3),
intent(inout) :: force
1165 integer :: igrid, ineigh, jsph
1166 real(dp),
dimension(0:params % lmax) :: SI_rijn
1167 real(dp),
dimension(0:params % lmax) :: DI_rijn
1173 real(dp) :: rijn, tij, beta, tlow, thigh, xij, oij, f1, f2, f3
1176 real(dp) :: vij(3), sij(3), alpha(3), va(3), rj, vtij(3)
1177 real(dp),
external :: dnrm2
1178 real(dp) :: work(params % lmax+1)
1179 complex(dp) :: work_complex(params % lmax+1)
1184 tlow = one - pt5*(one - params % se)*params % eta
1185 thigh = one + pt5*(one + params % se)*params % eta
1188 do igrid = 1, params % ngrid
1190 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
1191 jsph = constants % nl(ineigh)
1192 vij = params % csph(:,isph) + &
1193 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1194 & params % csph(:,jsph)
1195 rijn = dnrm2(3, vij, 1)
1196 tij = rijn/params % rsph(jsph)
1197 rj = params % rsph(jsph)
1198 if (tij.ge.thigh) cycle
1200 if (tij.ne.zero)
then
1205 vtij = vij*params % kappa
1206 call fmm_l2p_bessel_grad(vtij, params % rsph(jsph)*params % kappa, &
1207 & params % lmax, constants % vscales, params % kappa, &
1208 & xe(:, jsph), zero, alpha)
1209 call fmm_l2p_bessel_work(vtij, params % lmax, constants % vscales, &
1210 & constants % SI_ri(:, jsph), one, xe(:, jsph), zero, beta, &
1211 & work_complex, work)
1212 xij = fsw(tij, params % se, params % eta)
1213 if (constants % fi(igrid,isph).gt.one)
then
1214 oij = xij/constants % fi(igrid,isph)
1215 f2 = -oij/constants % fi(igrid,isph)
1221 va(:) = va(:) + f1*alpha(:) + beta*f2*constants % zi(:,igrid,isph)
1222 if (tij .gt. tlow)
then
1223 f3 = beta*dfsw(tij,params % se,params % eta)/params % rsph(jsph)
1224 if (constants % fi(igrid,isph).gt.one) &
1225 & f3 = f3/constants % fi(igrid,isph)
1226 va(:) = va(:) + f3*sij(:)
1229 force = force - constants % wgrid(igrid)*xadj_e(igrid)*va(:)
1231end subroutine contract_gradi_bik
1243subroutine contract_gradi_bji(params, constants, isph, Xe, Xadj_e, force)
1245 type(ddx_params_type),
intent(in) :: params
1246 type(ddx_constants_type),
intent(in) :: constants
1247 integer,
intent(in) :: isph
1248 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xe
1249 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: Xadj_e
1250 real(dp),
dimension(3),
intent(inout) :: force
1254 integer :: igrid, jsph, ksph, ineigh, jk
1255 real(dp),
dimension(0:params % lmax) :: SI_rjin, SI_rjkn
1256 real(dp),
dimension(0:params % lmax) :: DI_rjin, DI_rjkn
1264 real(dp) :: rjin, tji, xji, oji, fac, f1, f2, beta_ji, dj, tlow, thigh
1265 real(dp) :: b, beta_jk, g1, g2, rjkn, tjk, xjk
1269 real(dp) :: vji(3), sji(3), vjk(3), alpha(3), vb(3), vc(3), &
1278 real(dp),
external :: dnrm2
1279 real(dp) :: work(params % lmax+1)
1280 complex(dp) :: work_complex(params % lmax+1)
1287 tlow = one - pt5*(one - params % se)*params % eta
1288 thigh = one + pt5*(one + params % se)*params % eta
1290 do igrid = 1, params % ngrid
1293 do ineigh = constants % inl(isph), constants % inl(isph+1) - 1
1294 jsph = constants % nl(ineigh)
1295 vji = params % csph(:,jsph) + &
1296 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
1297 & params % csph(:,isph)
1298 rjin = dnrm2(3, vji, 1)
1299 ri = params % rsph(isph)
1301 if (tji.gt.thigh) cycle
1302 if (tji.ne.zero)
then
1307 vtji = vji*params % kappa
1308 call fmm_l2p_bessel_grad(vtji, params % rsph(isph)*params % kappa, &
1309 & params % lmax, constants % vscales, params % kappa, &
1310 & xe(:, isph), zero, alpha)
1311 xji = fsw(tji,params % se,params % eta)
1312 if (constants % fi(igrid,jsph).gt.one)
then
1313 oji = xji/constants % fi(igrid,jsph)
1318 vb = vb + f1*alpha*xadj_e(igrid,jsph)
1319 if (tji .gt. tlow)
then
1320 call fmm_l2p_bessel_work(vtji, params % lmax, &
1321 & constants % vscales, constants % SI_ri(:, isph), one, &
1322 & xe(:, isph), zero, beta_ji, work_complex, work)
1323 if (constants % fi(igrid,jsph) .gt. one)
then
1324 dj = one/constants % fi(igrid,jsph)
1328 do jk = constants % inl(jsph), constants % inl(jsph+1) - 1
1329 ksph = constants % nl(jk)
1330 vjk = params % csph(:,jsph) + &
1331 & params % rsph(jsph)*constants % cgrid(:,igrid) - &
1332 & params % csph(:,ksph)
1333 rjkn = dnrm2(3, vjk, 1)
1334 tjk = rjkn/params % rsph(ksph)
1335 if (ksph.ne.isph)
then
1336 if (tjk .le. thigh)
then
1338 vtjk = vjk*params % kappa
1339 call fmm_l2p_bessel_work(vtjk, params % lmax, &
1340 & constants % vscales, &
1341 & constants % SI_ri(:, ksph), one, xe(:, ksph), &
1342 & zero, beta_jk, work_complex, work)
1343 xjk = fsw(tjk, params % se, params % eta)
1349 g1 = dj*dj*dfsw(tji,params % se,params % eta) &
1350 & /params % rsph(isph)
1351 g2 = g1*xadj_e(igrid,jsph)*b
1358 f2 = (one-fac)*dj*dfsw(tji,params % se,params % eta) &
1359 & /params % rsph(isph)
1360 vb = vb + f2*xadj_e(igrid,jsph)*beta_ji*sji
1363 force = force + constants % wgrid(igrid)*(vb - vc)
1365end subroutine contract_gradi_bji
1379subroutine contract_grad_c_worker1(params, constants, workspace, Xadj_r_sgrid, &
1380 & Xadj_e_sgrid, diff_re, force, ddx_error)
1382 type(ddx_params_type),
intent(in) :: params
1383 type(ddx_constants_type),
intent(in) :: constants
1384 type(ddx_workspace_type),
intent(inout) :: workspace
1385 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1387 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
1388 & Xadj_r_sgrid, Xadj_e_sgrid
1389 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1390 type(ddx_error_type),
intent(inout) :: ddx_error
1393 integer :: isph, jsph, igrid, l0, m0, ind0, igrid0, icav, &
1394 & indl, inode, istat
1401 real(dp) :: sum_int, sum_r, sum_e
1403 real(dp) :: vij(3), sij(3), vtij(3)
1410 real(dp),
allocatable :: phi_n_r(:,:), phi_n_e(:,:), coefY_d(:,:,:), &
1411 & diff_re_sgrid(:,:)
1415 real(dp),
dimension(constants % nbasis):: basloc, vplm
1417 real(dp),
dimension(3, constants % nbasis):: dbasloc
1420 real(dp),
dimension(params % lmax+1):: vcos, vsin
1423 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1424 real(dp) :: coef(constants % nbasis0), work(constants % lmax0+1)
1425 complex(dp) :: work_complex(constants % lmax0+1)
1427 allocate(phi_n_r(params % ngrid, params % nsph), &
1428 & phi_n_e(params % ngrid, params % nsph), &
1429 & diff_re_sgrid(params % ngrid, params % nsph), stat=istat)
1430 if (istat.ne.0)
then
1431 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker1")
1440 diff_re_sgrid = zero
1449 if (params % fmm .eq. 0)
then
1450 allocate(coefy_d(constants % ncav, params % ngrid, params % nsph), &
1452 if (istat.ne.0)
then
1453 call update_error(ddx_error,
"allocation ddx_error in fmm ddx_contract_grad_C_worker1")
1459 do jsph = 1, params % nsph
1461 do igrid0 = 1, params % ngrid
1464 do isph = 1, params % nsph
1466 do igrid = 1, params % ngrid
1468 if(constants % ui(igrid, isph) .gt. zero)
then
1470 vij = params % csph(:,isph) + &
1471 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1472 & params % csph(:,jsph)
1473 rijn = sqrt(dot_product(vij,vij))
1476 do l0 = 0, constants % lmax0
1478 ind0 = l0**2 + l0 + m0 + 1
1479 coef(ind0) = constants % vgrid(ind0, igrid0) * &
1480 & constants % C_ik(l0, jsph)
1483 vtij = vij*params % kappa
1484 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1485 & constants % vscales, constants % SK_ri(:, jsph), one, &
1486 & coef, zero, coefy_d(icav, igrid0, jsph), work_complex, work)
1495 do jsph = 1, params % nsph
1497 do igrid0 = 1, params % ngrid
1502 do isph = 1, params % nsph
1504 do igrid = 1, params % ngrid
1505 if(constants % ui(igrid, isph) .gt. zero)
then
1507 sum_r = sum_r + coefy_d(icav, igrid0, jsph)*xadj_r_sgrid(igrid, isph) &
1508 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
1509 sum_e = sum_e + coefy_d(icav, igrid0, jsph)*xadj_e_sgrid(igrid, isph) &
1510 & * constants % wgrid(igrid)*constants % ui(igrid, isph)
1514 phi_n_r(igrid0, jsph) = sum_r
1515 phi_n_e(igrid0, jsph) = sum_e
1523 do isph = 1, params % nsph
1524 workspace % tmp_grid(:, isph) = xadj_r_sgrid(:, isph) * &
1525 & constants % wgrid(:) * constants % ui(:, isph)
1529 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
1531 & zero, workspace % tmp_node_l)
1533 & workspace % tmp_node_l)
1535 & workspace % tmp_node_l, workspace % tmp_node_m)
1537 & workspace % tmp_node_m)
1539 if(constants % lmax0 .lt. params % pm)
then
1540 do isph = 1, params % nsph
1541 inode = constants % snode(isph)
1542 workspace % tmp_sph(1:constants % nbasis0, isph) = &
1543 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
1544 & workspace % tmp_node_m(1:constants % nbasis0, inode)
1547 indl = (params % pm+1)**2
1548 do isph = 1, params % nsph
1549 inode = constants % snode(isph)
1550 workspace % tmp_sph(1:indl, isph) = &
1551 & workspace % tmp_sph(1:indl, isph) + &
1552 & workspace % tmp_node_m(:, inode)
1556 do isph = 1, params % nsph
1557 do l0 = 0, constants % lmax0
1558 ind0 = l0*l0 + l0 + 1
1559 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
1560 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
1561 & constants % C_ik(l0, isph)
1565 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
1566 & one, constants % vgrid, constants % vgrid_nbasis, &
1567 & workspace % tmp_sph, constants % nbasis, zero, phi_n_r, params % ngrid)
1572 do isph = 1, params % nsph
1573 workspace % tmp_grid(:, isph) = xadj_e_sgrid(:, isph) * &
1574 & constants % wgrid(:) * constants % ui(:, isph)
1578 & workspace % tmp_grid, zero, params % lmax, workspace % tmp_sph)
1580 & zero, workspace % tmp_node_l)
1582 & workspace % tmp_node_l)
1584 & workspace % tmp_node_l, workspace % tmp_node_m)
1586 & workspace % tmp_node_m)
1588 if(constants % lmax0 .lt. params % pm)
then
1589 do isph = 1, params % nsph
1590 inode = constants % snode(isph)
1591 workspace % tmp_sph(1:constants % nbasis0, isph) = &
1592 & workspace % tmp_sph(1:constants % nbasis0, isph) + &
1593 & workspace % tmp_node_m(1:constants % nbasis0, inode)
1596 indl = (params % pm+1)**2
1597 do isph = 1, params % nsph
1598 inode = constants % snode(isph)
1599 workspace % tmp_sph(1:indl, isph) = &
1600 & workspace % tmp_sph(1:indl, isph) + &
1601 & workspace % tmp_node_m(:, inode)
1605 do isph = 1, params % nsph
1606 do l0 = 0, constants % lmax0
1607 ind0 = l0*l0 + l0 + 1
1608 workspace % tmp_sph(ind0-l0:ind0+l0, isph) = &
1609 & workspace % tmp_sph(ind0-l0:ind0+l0, isph) * &
1610 & constants % C_ik(l0, isph)
1614 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis0, &
1615 & one, constants % vgrid, constants % vgrid_nbasis, &
1616 & workspace % tmp_sph, constants % nbasis, zero, phi_n_e, params % ngrid)
1618 call dgemm(
'T',
'N', params % ngrid, params % nsph, &
1619 & constants % nbasis, one, constants % vgrid, constants % vgrid_nbasis, &
1620 & diff_re , constants % nbasis, zero, diff_re_sgrid, &
1622 do isph = 1, params % nsph
1623 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_r, force(:, isph))
1624 call contract_grad_u(params, constants, isph, diff_re_sgrid, phi_n_e, force(:, isph))
1627 deallocate(phi_n_r, phi_n_e, diff_re_sgrid, stat=istat)
1628 if (istat.ne.0)
then
1629 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
1632 if (
allocated(coefy_d))
then
1633 deallocate(coefy_d, stat=istat)
1634 if (istat.ne.0)
then
1635 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker1")
1639end subroutine contract_grad_c_worker1
1660subroutine contract_grad_c_worker2(params, constants, workspace, Xr, Xe, &
1661 & Xadj_r_sgrid, Xadj_e_sgrid, Xadj_r, Xadj_e, force, diff_re, ddx_error)
1663 type(ddx_params_type),
intent(in) :: params
1664 type(ddx_constants_type),
intent(in) :: constants
1665 type(ddx_workspace_type),
intent(inout) :: workspace
1666 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: Xr, Xe
1667 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: &
1668 & Xadj_r_sgrid, Xadj_e_sgrid
1669 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
1671 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
1672 real(dp),
dimension(constants % nbasis, params % nsph),
intent(out) :: &
1674 type(ddx_error_type),
intent(inout) :: ddx_error
1675 real(dp),
external :: dnrm2
1677 integer :: isph, jsph, igrid, l, m, ind, l0, ind0, icav, indl, inode, &
1678 & ksph, knode, jnode, knear, jsph_node, istat
1680 real(dp),
dimension(3) :: vij, vtij
1689 real(dp),
allocatable :: diff_ep_dim3(:,:), phi_in(:,:), sum_dim3(:,:,:), &
1690 & diff0(:,:), diff1(:,:), diff1_grad(:,:,:), l2l_grad(:,:,:)
1691 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
1692 complex(dp) :: work_complex(constants % lmax0+2)
1693 real(dp) :: work(constants % lmax0+2)
1695 allocate(diff_ep_dim3(3, constants % ncav), &
1696 & phi_in(params % ngrid, params % nsph), &
1697 & sum_dim3(3, constants % nbasis, params % nsph), &
1698 & diff0(constants % nbasis0, params % nsph), &
1699 & diff1(constants % nbasis0, params % nsph), &
1700 & diff1_grad((constants % lmax0+2)**2, 3, params % nsph), &
1701 & l2l_grad((params % pl+2)**2, 3, params % nsph), stat=istat)
1702 if (istat.ne.0)
then
1703 call update_error(ddx_error,
"allocation ddx_error in ddx_contract_grad_C_worker2")
1715 do jsph = 1, params % nsph
1716 do l = 0, params % lmax
1718 ind = l**2 + l + m + 1
1719 diff_re(ind,jsph) = (params % epsp/params % eps)*(l/params % rsph(jsph)) * &
1720 & xr(ind,jsph) - constants % termimat(l,jsph)*xe(ind,jsph)
1729 do jsph = 1, params % nsph
1730 do l0 = 0, constants % lmax0
1731 do ind0 = l0*l0+1, l0*l0+2*l0+1
1732 diff0(ind0, jsph) = dot_product(diff_re(:,jsph), &
1733 & constants % Pchi(:,ind0, jsph))
1734 diff1(ind0, jsph) = diff0(ind0, jsph) * constants % C_ik(l0, jsph)
1738 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, jsph), &
1739 & constants % vscales, diff1(:, jsph), diff1_grad(:, :, jsph))
1742 if (params % fmm .eq. 0)
then
1747 do isph = 1, params % nsph
1748 do igrid = 1, params % ngrid
1749 if(constants % ui(igrid, isph) .gt. zero)
then
1753 do jsph = 1, params % nsph
1758 vij = params % csph(:, isph) + &
1759 & params % rsph(isph)*constants % cgrid(:, igrid) - &
1760 & params % csph(:, jsph)
1761 vtij = vij * params % kappa
1762 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
1763 & constants % vscales, constants % SK_ri(:, jsph), one, &
1764 & diff1(:, jsph), one, val, work_complex, work)
1766 phi_in(igrid, isph) = val
1773 workspace % tmp_sph = zero
1774 workspace % tmp_sph(1:constants % nbasis0, :) = diff1(:, :)
1775 if(constants % lmax0 .lt. params % pm)
then
1776 do isph = 1, params % nsph
1777 inode = constants % snode(isph)
1778 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
1779 & workspace % tmp_sph(1:constants % nbasis0, isph)
1780 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
1783 indl = (params % pm+1)**2
1784 do isph = 1, params % nsph
1785 inode = constants % snode(isph)
1786 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
1792 & workspace % tmp_node_l)
1794 call tree_l2p_bessel(params, constants, one, workspace % tmp_node_l, zero, &
1797 & params % lmax, workspace % tmp_sph, one, &
1802 do isph = 1, params % nsph
1803 do igrid = 1, params % ngrid
1804 if (constants % ui(igrid, isph) .eq. zero)
then
1805 phi_in(igrid, isph) = zero
1812 do isph = 1, params % nsph
1813 inode = constants % snode(isph)
1814 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
1815 call fmm_l2l_bessel_grad(params % pl, &
1816 & constants % SI_ri(:, isph), constants % vscales, &
1817 & workspace % tmp_node_l(:, inode), &
1818 & l2l_grad(:, :, isph))
1820 workspace % tmp_sph = xadj_r + xadj_e
1821 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
1822 & one, constants % vwgrid, constants % vgrid_nbasis, &
1823 & workspace % tmp_sph, constants % nbasis, zero, &
1824 & workspace % tmp_grid, params % ngrid)
1825 workspace % tmp_grid = workspace % tmp_grid * constants % ui
1829 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
1831 & workspace % tmp_node_l)
1834 & workspace % tmp_node_m)
1838 if(constants % lmax0+1 .lt. params % pm)
then
1841 do isph = 1, params % nsph
1842 inode = constants % snode(isph)
1843 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
1844 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
1845 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
1848 indl = (params % pm+1)**2
1851 do isph = 1, params % nsph
1852 inode = constants % snode(isph)
1853 workspace % tmp_sph2(1:indl, isph) = &
1854 & workspace % tmp_sph2(1:indl, isph) + &
1855 & workspace % tmp_node_m(:, inode)
1860 do ksph = 1, params % nsph
1862 call contract_grad_u(params, constants, ksph, xadj_r_sgrid, phi_in, force(:, ksph))
1863 call contract_grad_u(params, constants, ksph, xadj_e_sgrid, phi_in, force(:, ksph))
1868 icav = constants % icav_ia(ksph) - 1
1869 if (params % fmm .eq. 0)
then
1870 do igrid = 1, params % ngrid
1871 if (constants % ui(igrid, ksph) .eq. zero) cycle
1873 do jsph = 1, params % nsph
1874 if (jsph .eq. ksph) cycle
1875 vij = params % csph(:,ksph) + &
1876 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
1877 & params % csph(:,jsph)
1878 vtij = vij * params % kappa
1884 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1885 & constants % vscales, constants % SK_ri(:, jsph), &
1886 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1887 & diff_ep_dim3(1, icav), work_complex, work)
1888 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1889 & constants % vscales, constants % SK_ri(:, jsph), &
1890 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1891 & diff_ep_dim3(2, icav), work_complex, work)
1892 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1893 & constants % vscales, constants % SK_ri(:, jsph), &
1894 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1895 & diff_ep_dim3(3, icav), work_complex, work)
1899 knode = constants % snode(ksph)
1900 do igrid = 1, params % ngrid
1901 if (constants % ui(igrid, ksph) .eq. zero) cycle
1904 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
1905 & l2l_grad(1, 1, ksph), &
1906 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
1907 & one, diff_ep_dim3(1, icav), 1)
1909 do knear = constants % snear(knode), constants % snear(knode+1)-1
1910 jnode = constants % near(knear)
1911 do jsph_node = constants % cluster(1, jnode), &
1912 & constants % cluster(2, jnode)
1913 jsph = constants % order(jsph_node)
1914 if (jsph .eq. ksph) cycle
1915 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
1916 & params % rsph(ksph)*constants % cgrid(:, igrid)
1917 vtij = vij * params % kappa
1918 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1919 & constants % vscales, constants % SK_ri(:, jsph), &
1920 & -params % kappa, diff1_grad(:, 1, jsph), one, &
1921 & diff_ep_dim3(1, icav), work_complex, work)
1922 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1923 & constants % vscales, constants % SK_ri(:, jsph), &
1924 & -params % kappa, diff1_grad(:, 2, jsph), one, &
1925 & diff_ep_dim3(2, icav), work_complex, work)
1926 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1927 & constants % vscales, constants % SK_ri(:, jsph), &
1928 & -params % kappa, diff1_grad(:, 3, jsph), one, &
1929 & diff_ep_dim3(3, icav), work_complex, work)
1935 icav = constants % icav_ia(ksph) - 1
1936 do igrid =1, params % ngrid
1937 if(constants % ui(igrid, ksph) .gt. zero)
then
1939 do ind = 1, constants % nbasis
1940 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
1941 & + diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
1942 & *constants % vwgrid(ind, igrid)
1946 do ind = 1, constants % nbasis
1947 force(:, ksph) = force(:, ksph) + &
1948 & sum_dim3(:, ind, ksph)*(xadj_r(ind, ksph) + &
1949 & xadj_e(ind, ksph))
1953 if (params % fmm .eq. 0)
then
1956 do isph = 1, params % nsph
1957 if (isph .eq. ksph) cycle
1958 icav = constants % icav_ia(isph) - 1
1959 do igrid = 1, params % ngrid
1960 if (constants % ui(igrid, isph) .eq. zero) cycle
1962 vij = params % csph(:,isph) + &
1963 & params % rsph(isph)*constants % cgrid(:,igrid) - &
1964 & params % csph(:,ksph)
1965 vtij = vij * params % kappa
1971 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1972 & constants % vscales, constants % SK_ri(:, ksph), &
1973 & params % kappa, diff1_grad(:, 1, ksph), one, &
1974 & diff_ep_dim3(1, icav), work_complex, work)
1975 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1976 & constants % vscales, constants % SK_ri(:, ksph), &
1977 & params % kappa, diff1_grad(:, 2, ksph), one, &
1978 & diff_ep_dim3(2, icav), work_complex, work)
1979 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
1980 & constants % vscales, constants % SK_ri(:, ksph), &
1981 & params % kappa, diff1_grad(:, 3, ksph), one, &
1982 & diff_ep_dim3(3, icav), work_complex, work)
1986 do isph = 1, params % nsph
1987 do igrid =1, params % ngrid
1988 if(constants % ui(igrid, isph) .gt. zero)
then
1990 do ind = 1, constants % nbasis
1991 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
1992 & + diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
1993 & *constants % vwgrid(ind, igrid)
1999 do isph = 1, params % nsph
2000 do ind = 1, constants % nbasis
2001 force(:, ksph) = force(:, ksph) &
2002 & + sum_dim3(:, ind, isph)*(xadj_r(ind, isph) &
2003 & + xadj_e(ind, isph))
2007 call dgemv(
'T', (constants % lmax0+2)**2, 3, params % kappa, &
2008 & diff1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
2009 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
2012 deallocate(diff_ep_dim3, phi_in, sum_dim3, diff1_grad, l2l_grad, &
2013 & diff0, diff1, stat=istat)
2014 if (istat.ne.0)
then
2015 call update_error(ddx_error,
"deallocation ddx_error in ddx_contract_grad_C_worker2")
2018end subroutine contract_grad_c_worker2
2033subroutine contract_grad_f_worker1(params, constants, workspace, sol_adj, sol_sgrid, &
2034 & gradpsi, force, ddx_error)
2036 type(ddx_params_type),
intent(in) :: params
2037 type(ddx_constants_type),
intent(in) :: constants
2038 type(ddx_workspace_type),
intent(inout) :: workspace
2039 real(dp),
dimension(constants % nbasis, params % nsph),
intent(in) :: &
2041 real(dp),
dimension(params % ngrid, params % nsph),
intent(in) :: sol_sgrid
2042 real(dp),
dimension(3, constants % ncav),
intent(in) :: gradpsi
2043 real(dp),
dimension(3, params % nsph),
intent(inout) :: force
2044 type(ddx_error_type),
intent(inout) :: ddx_error
2047 real(dp),
external :: dnrm2
2048 integer :: isph, jsph, igrid, ind, l0, ind0, icav, ksph, &
2049 & knode, jnode, knear, jsph_node, indl, inode, istat
2051 real(dp),
dimension(3) :: vij, vtij
2054 real(dp) :: nderpsi, sum_int
2066 real(dp),
allocatable :: phi_in(:,:), diff_ep_dim3(:,:), &
2067 & sum_dim3(:,:,:), diff0(:,:), sum_sjin(:,:), &
2068 & c0_d(:,:), c0_d1(:,:), c0_d1_grad(:,:,:), l2l_grad(:,:,:)
2069 real(dp),
dimension(0:params % lmax) :: SK_rijn, DK_rijn
2070 complex(dp) :: work_complex(constants % lmax0 + 2)
2071 real(dp) :: work(constants % lmax0 + 2)
2073 allocate(phi_in(params % ngrid, params % nsph), &
2074 & diff_ep_dim3(3, constants % ncav), &
2075 & sum_dim3(3, constants % nbasis, params % nsph), &
2076 & c0_d(constants % nbasis0, params % nsph), &
2077 & c0_d1(constants % nbasis0, params % nsph), &
2078 & c0_d1_grad((constants % lmax0+2)**2, 3, params % nsph), &
2079 & sum_sjin(params % ngrid, params % nsph), &
2080 & l2l_grad((params % pl+2)**2, 3, params % nsph), &
2081 & diff0(constants % nbasis0, params % nsph), stat=istat)
2082 if (istat.ne.0)
then
2083 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker1")
2096 do isph = 1, params % nsph
2097 do igrid= 1, params % ngrid
2098 if ( constants % ui(igrid,isph) .gt. zero )
then
2100 nderpsi = dot_product( gradpsi(:,icav),constants % cgrid(:,igrid) )
2101 c0_d(:, isph) = c0_d(:,isph) + &
2102 & constants % wgrid(igrid)* &
2103 & constants % ui(igrid,isph)*&
2105 & constants % vgrid(1:constants % nbasis0,igrid)
2106 do l0 = 0, constants % lmax0
2107 ind0 = l0*l0 + l0 + 1
2108 c0_d1(ind0-l0:ind0+l0, isph) = c0_d(ind0-l0:ind0+l0, isph) * &
2109 & constants % C_ik(l0, isph)
2112 call fmm_m2m_bessel_grad(constants % lmax0, constants % SK_ri(:, isph), &
2113 & constants % vscales, c0_d1(:, isph), c0_d1_grad(:, :, isph))
2118 if (params % fmm .eq. 0)
then
2121 do isph = 1, params % nsph
2122 do igrid = 1, params % ngrid
2123 if (constants % ui(igrid,isph).gt.zero)
then
2127 do jsph = 1, params % nsph
2128 vij = params % csph(:, isph) + &
2129 & params % rsph(isph)*constants % cgrid(:, igrid) - &
2130 & params % csph(:, jsph)
2131 vtij = vij * params % kappa
2132 call fmm_m2p_bessel_work(vtij, constants % lmax0, &
2133 & constants % vscales, constants % SK_ri(:, jsph), one, &
2134 & c0_d1(:, jsph), one, sum_int, work_complex, work)
2136 sum_sjin(igrid,isph) = -(params % epsp/params % eps)*sum_int
2142 workspace % tmp_sph = zero
2143 workspace % tmp_sph(1:constants % nbasis0, :) = c0_d1(:, :)
2144 if(constants % lmax0 .lt. params % pm)
then
2145 do isph = 1, params % nsph
2146 inode = constants % snode(isph)
2147 workspace % tmp_node_m(1:constants % nbasis0, inode) = &
2148 & workspace % tmp_sph(1:constants % nbasis0, isph)
2149 workspace % tmp_node_m(constants % nbasis0+1:, inode) = zero
2152 indl = (params % pm+1)**2
2153 do isph = 1, params % nsph
2154 inode = constants % snode(isph)
2155 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
2161 & workspace % tmp_node_l)
2163 call tree_l2p_bessel(params, constants, -params % epsp/params % eps, workspace % tmp_node_l, zero, &
2165 call tree_m2p_bessel(params, constants, constants % lmax0, -params % epsp/params % eps, &
2166 & params % lmax, workspace % tmp_sph, one, &
2169 do isph = 1, params % nsph
2170 do igrid = 1, params % ngrid
2171 if (constants % ui(igrid, isph) .eq. zero)
then
2172 sum_sjin(igrid, isph) = zero
2177 do isph = 1, params % nsph
2178 inode = constants % snode(isph)
2179 workspace % tmp_sph_l(:, isph) = workspace % tmp_node_l(:, inode)
2180 call fmm_l2l_bessel_grad(params % pl, &
2181 & constants % SI_ri(:, isph), constants % vscales, &
2182 & workspace % tmp_node_l(:, inode), &
2183 & l2l_grad(:, :, isph))
2185 workspace % tmp_sph = sol_adj
2186 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
2187 & one, constants % vwgrid, constants % vgrid_nbasis, &
2188 & workspace % tmp_sph, constants % nbasis, zero, &
2189 & workspace % tmp_grid, params % ngrid)
2190 workspace % tmp_grid = workspace % tmp_grid * constants % ui
2194 & workspace % tmp_grid, zero, params % lmax+1, workspace % tmp_sph2)
2196 & workspace % tmp_node_l)
2199 & workspace % tmp_node_m)
2203 if(constants % lmax0+1 .lt. params % pm)
then
2204 do isph = 1, params % nsph
2205 inode = constants % snode(isph)
2206 workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) = &
2207 & workspace % tmp_sph2(1:(constants % lmax0+2)**2, isph) + &
2208 & workspace % tmp_node_m(1:(constants % lmax0+2)**2, inode)
2211 indl = (params % pm+1)**2
2212 do isph = 1, params % nsph
2213 inode = constants % snode(isph)
2214 workspace % tmp_sph2(1:indl, isph) = &
2215 & workspace % tmp_sph2(1:indl, isph) + &
2216 & workspace % tmp_node_m(:, inode)
2220 do ksph = 1, params % nsph
2222 call contract_grad_u(params, constants, ksph, sol_sgrid, sum_sjin, force(:, ksph))
2226 icav = constants % icav_ia(ksph) - 1
2227 if (params % fmm .eq. 0)
then
2228 do igrid = 1, params % ngrid
2229 if (constants % ui(igrid, ksph) .eq. zero) cycle
2231 do jsph = 1, params % nsph
2232 if (jsph .eq. ksph) cycle
2233 vij = params % csph(:,ksph) + &
2234 & params % rsph(ksph)*constants % cgrid(:,igrid) - &
2235 & params % csph(:,jsph)
2236 vtij = vij * params % kappa
2237 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2238 & constants % vscales, constants % SK_ri(:, jsph), &
2239 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
2240 & diff_ep_dim3(1, icav), work_complex, work)
2241 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2242 & constants % vscales, constants % SK_ri(:, jsph), &
2243 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
2244 & diff_ep_dim3(2, icav), work_complex, work)
2245 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2246 & constants % vscales, constants % SK_ri(:, jsph), &
2247 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
2248 & diff_ep_dim3(3, icav), work_complex, work)
2252 knode = constants % snode(ksph)
2253 do igrid = 1, params % ngrid
2254 if (constants % ui(igrid, ksph) .eq. zero) cycle
2257 call dgemv(
'T', (params % pl+2)**2, 3, -params % kappa, &
2258 & l2l_grad(1, 1, ksph), &
2259 & (params % pl+2)**2, constants % vgrid(1, igrid), 1, &
2260 & one, diff_ep_dim3(1, icav), 1)
2262 do knear = constants % snear(knode), constants % snear(knode+1)-1
2263 jnode = constants % near(knear)
2264 do jsph_node = constants % cluster(1, jnode), &
2265 & constants % cluster(2, jnode)
2266 jsph = constants % order(jsph_node)
2267 if (jsph .eq. ksph) cycle
2268 vij = params % csph(:, ksph) - params % csph(:, jsph) + &
2269 & params % rsph(ksph)*constants % cgrid(:, igrid)
2270 vtij = vij * params % kappa
2271 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2272 & constants % vscales, constants % SK_ri(:, jsph), &
2273 & -params % kappa, c0_d1_grad(:, 1, jsph), one, &
2274 & diff_ep_dim3(1, icav), work_complex, work)
2275 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2276 & constants % vscales, constants % SK_ri(:, jsph), &
2277 & -params % kappa, c0_d1_grad(:, 2, jsph), one, &
2278 & diff_ep_dim3(2, icav), work_complex, work)
2279 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2280 & constants % vscales, constants % SK_ri(:, jsph), &
2281 & -params % kappa, c0_d1_grad(:, 3, jsph), one, &
2282 & diff_ep_dim3(3, icav), work_complex, work)
2288 icav = constants % icav_ia(ksph) - 1
2289 do igrid =1, params % ngrid
2290 if(constants % ui(igrid, ksph) .gt. zero)
then
2292 do ind = 1, constants % nbasis
2293 sum_dim3(:,ind,ksph) = sum_dim3(:,ind,ksph) &
2294 & - (params % epsp/params % eps) &
2295 & *diff_ep_dim3(:,icav)*constants % ui(igrid, ksph) &
2296 & *constants % vwgrid(ind, igrid)
2300 do ind = 1, constants % nbasis
2301 force(:, ksph) = force(:, ksph) + &
2302 & sum_dim3(:, ind, ksph)*sol_adj(ind, ksph)
2306 if (params % fmm .eq. 0)
then
2309 do isph = 1, params % nsph
2310 if (isph .eq. ksph) cycle
2311 icav = constants % icav_ia(isph) - 1
2312 do igrid = 1, params % ngrid
2313 if (constants % ui(igrid, isph) .eq. zero) cycle
2315 vij = params % csph(:,isph) + &
2316 & params % rsph(isph)*constants % cgrid(:,igrid) - &
2317 & params % csph(:,ksph)
2318 vtij = vij * params % kappa
2319 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2320 & constants % vscales, constants % SK_ri(:, ksph), &
2321 & params % kappa, c0_d1_grad(:, 1, ksph), one, &
2322 & diff_ep_dim3(1, icav), work_complex, work)
2323 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2324 & constants % vscales, constants % SK_ri(:, ksph), &
2325 & params % kappa, c0_d1_grad(:, 2, ksph), one, &
2326 & diff_ep_dim3(2, icav), work_complex, work)
2327 call fmm_m2p_bessel_work(vtij, constants % lmax0+1, &
2328 & constants % vscales, constants % SK_ri(:, ksph), &
2329 & params % kappa, c0_d1_grad(:, 3, ksph), one, &
2330 & diff_ep_dim3(3, icav), work_complex, work)
2335 do isph = 1, params % nsph
2336 do igrid =1, params % ngrid
2337 if(constants % ui(igrid, isph) .gt. zero)
then
2339 do ind = 1, constants % nbasis
2340 sum_dim3(:,ind,isph) = sum_dim3(:,ind,isph) &
2341 & - (params % epsp/params % eps) &
2342 & *diff_ep_dim3(:,icav)*constants % ui(igrid, isph) &
2343 & *constants % vwgrid(ind, igrid)
2350 do isph = 1, params % nsph
2351 do ind = 1, constants % nbasis
2352 force(:, ksph) = force(:, ksph) + sum_dim3(:, ind, isph)*sol_adj(ind, isph)
2356 call dgemv(
'T', (constants % lmax0+2)**2, 3, -params % epsp/params % eps*params % kappa, &
2357 & c0_d1_grad(1, 1, ksph), (constants % lmax0+2)**2, &
2358 & workspace % tmp_sph2(1, ksph), 1, one, force(1, ksph), 1)
2362 deallocate(phi_in, diff_ep_dim3, sum_dim3, c0_d, c0_d1, &
2363 & c0_d1_grad, sum_sjin, l2l_grad, diff0, stat=istat)
2364 if (istat.ne.0)
then
2365 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker1")
2369end subroutine contract_grad_f_worker1
2372subroutine contract_grad_f_worker2(params, constants, &
2373 & gradpsi, normal_hessian_cav, force, state, ddx_error)
2374 type(ddx_params_type),
intent(in) :: params
2375 type(ddx_constants_type),
intent(in) :: constants
2376 real(dp),
intent(in) :: gradpsi(3, constants % ncav), &
2377 & normal_hessian_cav(3, constants % ncav)
2378 real(dp),
intent(inout) :: force(3, params % nsph)
2380 type(ddx_error_type),
intent(inout) :: ddx_error
2382 integer :: icav, isph, igrid, istat
2384 real(dp),
allocatable :: gradpsi_grid(:, :)
2386 allocate(gradpsi_grid(params % ngrid, params % nsph), stat=istat)
2387 if (istat.ne.0)
then
2388 call update_error(ddx_error,
"allocation ddx_error in ddx_grad_f_worker2")
2393 do isph = 1, params % nsph
2394 do igrid = 1, params % ngrid
2395 if(constants % ui(igrid, isph) .gt. zero)
then
2397 nderpsi = dot_product(gradpsi(:, icav), &
2398 & constants % cgrid(:, igrid))
2399 gradpsi_grid(igrid, isph) = nderpsi
2405 do isph = 1, params % nsph
2406 call contract_grad_u(params, constants, isph, gradpsi_grid, &
2407 & state % phi_n, force(:, isph))
2408 do igrid = 1, params % ngrid
2409 if(constants % ui(igrid, isph) .gt. zero)
then
2411 force(:, isph) = force(:, isph) &
2412 & + constants % wgrid(igrid)*constants % ui(igrid, isph) &
2413 & *state % phi_n(igrid, isph)*normal_hessian_cav(:, icav)
2418 deallocate(gradpsi_grid, stat=istat)
2419 if (istat.ne.0)
then
2420 call update_error(ddx_error,
"deallocation ddx_error in ddx_grad_f_worker2")
2424end subroutine contract_grad_f_worker2
2427subroutine gradr_sph(params, constants, isph, vplm, vcos, vsin, basloc, &
2428 & dbsloc, g, ygrid, fx)
2431 type(ddx_params_type),
intent(in) :: params
2432 type(ddx_constants_type),
intent(in) :: constants
2433 integer,
intent(in) :: isph
2434 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2435 & ygrid(params % ngrid, params % nsph)
2436 real(dp),
intent(inout) :: vplm(constants % nbasis), vcos(params % lmax+1), &
2437 & vsin(params % lmax+1), basloc(constants % nbasis), &
2438 & dbsloc(3, constants % nbasis), fx(3)
2440 real(dp) vik(3), sik(3), vki(3), ski(3), vkj(3), skj(3), vji(3), &
2441 & sji(3), va(3), vb(3), a(3)
2445 integer its, ik, ksph, l, m, ind, jsph, icomp, jcomp
2447 real(dp) cx, cy, cz, vvki, tki, gg, fl, fac, vvkj, tkj
2448 real(dp) tt, fcl, fjj, gi, fii, vvji, tji, qji
2449 real(dp) b, vvik, tik, qik, tlow, thigh, duj
2450 real(dp) :: rho, ctheta, stheta, cphi, sphi
2451 real(dp),
external :: dnrm2
2452 real(dp) :: d_k, f_k, chi_ki, grad_p
2454 tlow = one - pt5*(one - params % se)*params % eta
2455 thigh = one + pt5*(one + params % se)*params % eta
2461 do its = 1, params % ngrid
2463 do ik = constants % inl(isph), constants % inl(isph+1) - 1
2464 ksph = constants % nl(ik)
2466 cx = params % csph(1,ksph) + params % rsph(ksph)*constants % cgrid(1,its)
2467 cy = params % csph(2,ksph) + params % rsph(ksph)*constants % cgrid(2,its)
2468 cz = params % csph(3,ksph) + params % rsph(ksph)*constants % cgrid(3,its)
2469 vki(1) = cx - params % csph(1,isph)
2470 vki(2) = cy - params % csph(2,isph)
2471 vki(3) = cz - params % csph(3,isph)
2474 vvki = dnrm2(3, vki, 1)
2475 tki = vvki/params % rsph(isph)
2482 if ((tki.gt.tlow).and.(tki.lt.thigh) .and. &
2483 & constants % ui(its,ksph).gt.zero)
then
2489 do l = 0, params % lmax
2492 fac = twopi/(two*fl + one)
2495 gg = gg + fac*constants % vgrid(ind+m,its)*g(ind+m,ksph)
2500 do jsph = 1, params % nsph
2501 if (jsph.ne.ksph .and. jsph.ne.isph)
then
2502 vkj(1) = cx - params % csph(1,jsph)
2503 vkj(2) = cy - params % csph(2,jsph)
2504 vkj(3) = cz - params % csph(3,jsph)
2505 vvkj = sqrt(vkj(1)*vkj(1) + vkj(2)*vkj(2) + &
2507 vvkj = dnrm2(3, vkj, 1)
2508 tkj = vvkj/params % rsph(jsph)
2510 call ylmbas(skj, rho, ctheta, stheta, cphi, sphi, &
2511 & params % lmax, constants % vscales, basloc, &
2514 do l = 0, params % lmax
2516 fcl = - fourpi*dble(l)/(two*dble(l)+one)*tt
2519 gg = gg + fcl*g(ind+m,jsph)*basloc(ind+m)
2530 call ylmbas(ski, rho, ctheta, stheta, cphi, sphi, &
2531 & params % lmax, constants % vscales, basloc, &
2534 do l = 0, params % lmax
2536 fcl = - four*pi*dble(l)/(two*dble(l)+one)*tt
2539 gg = gg + fcl*g(ind+m,isph)*basloc(ind+m)
2548 if (params%switching.eq.0)
then
2549 duj = dfsw(tki,params % se, params % eta)/params % rsph(isph)
2551 d_k = constants%switching%d_ni(its, ksph)
2552 f_k = constants%switching%f_ni(its, ksph)
2553 chi_ki = fsw(tki,params%se,params%eta)
2554 grad_p = dfsw(tki,params%se,params%eta)
2555 duj = one/(d_k + f_k)**2 &
2556 & *(d_k + d_k*f_k/(one - chi_ki)) &
2557 & *grad_p/params%rsph(isph)
2559 fjj = duj*constants % wgrid(its)*gg*ygrid(its,ksph)
2560 fx(1) = fx(1) - fjj*ski(1)
2561 fx(2) = fx(2) - fjj*ski(2)
2562 fx(3) = fx(3) - fjj*ski(3)
2567 if (constants % ui(its,isph).gt.zero.and.constants % ui(its,isph).lt.one)
then
2569 do l = 0, params % lmax
2572 fac = twopi/(two*fl + one)
2575 gi = gi + fac*constants % vgrid(ind+m,its)*g(ind+m,isph)
2583 fii = constants % wgrid(its)*gi*ygrid(its,isph)
2584 fx(1) = fx(1) + fii*constants % zi(1,its,isph)
2585 fx(2) = fx(2) + fii*constants % zi(2,its,isph)
2586 fx(3) = fx(3) + fii*constants % zi(3,its,isph)
2592 do its = 1, params % ngrid
2595 do jsph = 1, params % nsph
2596 if (constants % ui(its,jsph).gt.zero .and. jsph.ne.isph)
then
2598 cx = params % csph(1,jsph) + params % rsph(jsph)*constants % cgrid(1,its)
2599 cy = params % csph(2,jsph) + params % rsph(jsph)*constants % cgrid(2,its)
2600 cz = params % csph(3,jsph) + params % rsph(jsph)*constants % cgrid(3,its)
2601 vji(1) = cx - params % csph(1,isph)
2602 vji(2) = cy - params % csph(2,isph)
2603 vji(3) = cz - params % csph(3,isph)
2606 vvji = dnrm2(3, vji, 1)
2607 tji = vvji/params % rsph(isph)
2618 sjac(icomp,jcomp) = qji*(sjac(icomp,jcomp) &
2619 & + sji(icomp)*sji(jcomp))
2625 call dbasis(params, constants, sji,basloc,dbsloc,vplm,vcos,vsin)
2630 do l = 0, params % lmax
2633 fcl = - tt*fourpi*fl/(two*fl + one)
2635 fac = fcl*g(ind+m,isph)
2636 b = (fl + one)*basloc(ind+m)/(params % rsph(isph)*tji)
2639 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
2640 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
2641 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
2642 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
2643 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
2644 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
2645 a(1) = a(1) + fac*(sji(1)*b + va(1))
2646 a(2) = a(2) + fac*(sji(2)*b + va(2))
2647 a(3) = a(3) + fac*(sji(3)*b + va(3))
2651 fac = constants % ui(its,jsph)*constants % wgrid(its)*ygrid(its,jsph)
2652 fx(1) = fx(1) - fac*a(1)
2653 fx(2) = fx(2) - fac*a(2)
2654 fx(3) = fx(3) - fac*a(3)
2660 do its = 1, params % ngrid
2661 cx = params % csph(1,isph) + params % rsph(isph)*constants % cgrid(1,its)
2662 cy = params % csph(2,isph) + params % rsph(isph)*constants % cgrid(2,its)
2663 cz = params % csph(3,isph) + params % rsph(isph)*constants % cgrid(3,its)
2667 do ksph = 1, params % nsph
2668 if (constants % ui(its,isph).gt.zero .and. ksph.ne.isph)
then
2670 vik(1) = cx - params % csph(1,ksph)
2671 vik(2) = cy - params % csph(2,ksph)
2672 vik(3) = cz - params % csph(3,ksph)
2675 vvik = dnrm2(3, vik, 1)
2676 tik = vvik/params % rsph(ksph)
2687 sjac(icomp,jcomp) = qik*(sjac(icomp,jcomp) &
2688 & - sik(icomp)*sik(jcomp))
2694 if (constants % ui(its,isph).lt.one)
then
2695 vb(1) = constants % zi(1,its,isph)
2696 vb(2) = constants % zi(2,its,isph)
2697 vb(3) = constants % zi(3,its,isph)
2702 call dbasis(params, constants, sik,basloc,dbsloc,vplm,vcos,vsin)
2706 do l = 0, params % lmax
2709 fcl = - tt*fourpi*fl/(two*fl + one)
2711 fac = fcl*g(ind+m,ksph)
2712 fac = - fac*basloc(ind+m)
2713 a(1) = a(1) + fac*vb(1)
2714 a(2) = a(2) + fac*vb(2)
2715 a(3) = a(3) + fac*vb(3)
2717 fac = constants % ui(its,isph)*fcl*g(ind+m,ksph)
2718 b = - (fl + one)*basloc(ind+m)/(params % rsph(ksph)*tik)
2721 va(1) = sjac(1,1)*dbsloc(1,ind+m) + &
2722 & sjac(1,2)*dbsloc(2,ind+m) + sjac(1,3)*dbsloc(3,ind+m)
2723 va(2) = sjac(2,1)*dbsloc(1,ind+m) + &
2724 & sjac(2,2)*dbsloc(2,ind+m) + sjac(2,3)*dbsloc(3,ind+m)
2725 va(3) = sjac(3,1)*dbsloc(1,ind+m) + &
2726 & sjac(3,2)*dbsloc(2,ind+m) + sjac(3,3)*dbsloc(3,ind+m)
2727 a(1) = a(1) + fac*(sik(1)*b + va(1))
2728 a(2) = a(2) + fac*(sik(2)*b + va(2))
2729 a(3) = a(3) + fac*(sik(3)*b + va(3))
2735 fac = constants % wgrid(its)*ygrid(its,isph)
2736 fx(1) = fx(1) - fac*a(1)
2737 fx(2) = fx(2) - fac*a(2)
2738 fx(3) = fx(3) - fac*a(3)
2740end subroutine gradr_sph
2743subroutine gradr_fmm(params, constants, workspace, g, ygrid, fx)
2746 type(ddx_params_type),
intent(in) :: params
2747 type(ddx_constants_type),
intent(in) :: constants
2748 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2749 & ygrid(params % ngrid, params % nsph)
2751 type(ddx_workspace_type),
intent(inout) :: workspace
2753 real(dp),
intent(out) :: fx(3, params % nsph)
2755 integer :: indl, indl1, l, isph, igrid, ik, ksph, &
2757 integer :: inear, inode, jnode
2758 real(dp) :: gg, c(3), vki(3), vvki, tki, gg3(3), tmp_gg, tmp_c(3)
2759 real(dp) :: d_k, f_k, chi_ki, grad_p, duj
2760 real(dp) :: tlow, thigh
2761 real(dp),
dimension(3, 3) :: zx_coord_transform, zy_coord_transform
2762 real(dp),
external :: ddot, dnrm2
2763 real(dp) :: work(params % lmax+2)
2765 zx_coord_transform = 0
2766 zx_coord_transform(3, 2) = 1
2767 zx_coord_transform(2, 3) = 1
2768 zx_coord_transform(1, 1) = 1
2769 zy_coord_transform = 0
2770 zy_coord_transform(1, 2) = 1
2771 zy_coord_transform(2, 1) = 1
2772 zy_coord_transform(3, 3) = 1
2773 tlow = one - pt5*(one - params % se)*params % eta
2774 thigh = one + pt5*(one + params % se)*params % eta
2777 workspace % tmp_sph(1, :) = zero
2779 do l = 1, params % lmax
2781 workspace % tmp_sph(indl:indl1, :) = l * g(indl:indl1, :)
2788 call tree_grad_m2m(params, constants, workspace % tmp_sph, &
2789 & workspace % tmp_sph_grad, workspace % tmp_sph2)
2796 do isph = 1, params % nsph
2797 workspace % tmp_grid(:, isph) = ygrid(:, isph) * &
2798 & constants % wgrid(:) * constants % ui(:, isph)
2802 call tree_m2p_adj(params, constants, params % lmax+1, one, &
2803 & workspace % tmp_grid, zero, workspace % tmp_sph2)
2804 call tree_l2p_adj(params, constants, one, workspace % tmp_grid, zero, &
2805 & workspace % tmp_node_l, workspace % tmp_sph_l)
2808 & workspace % tmp_node_m)
2812 if(params % lmax+1 .lt. params % pm)
then
2813 do isph = 1, params % nsph
2814 inode = constants % snode(isph)
2815 workspace % tmp_sph2(:, isph) = workspace % tmp_sph2(:, isph) + &
2816 & workspace % tmp_node_m(1:constants % grad_nbasis, inode)
2819 indl = (params % pm+1)**2
2820 do isph = 1, params % nsph
2821 inode = constants % snode(isph)
2822 workspace % tmp_sph2(1:indl, isph) = &
2823 & workspace % tmp_sph2(1:indl, isph) + &
2824 & workspace % tmp_node_m(:, inode)
2828 do isph = 1, params % nsph
2829 call dgemv(
'T', constants % grad_nbasis, 3, one, &
2830 & workspace % tmp_sph_grad(1, 1, isph), constants % grad_nbasis, &
2831 & workspace % tmp_sph2(1, isph), 1, zero, fx(1, isph), 1)
2838 if(params % lmax .lt. params % pm)
then
2839 do isph = 1, params % nsph
2840 inode = constants % snode(isph)
2841 workspace % tmp_node_m(:constants % nbasis, inode) = &
2842 & workspace % tmp_sph(:, isph)
2843 workspace % tmp_node_m(constants % nbasis+1:, inode) = zero
2846 indl = (params % pm+1)**2
2847 do isph = 1, params % nsph
2848 inode = constants % snode(isph)
2849 workspace % tmp_node_m(:, inode) = workspace % tmp_sph(1:indl, isph)
2855 & workspace % tmp_node_l)
2857 call tree_l2p(params, constants, one, workspace % tmp_node_l, zero, &
2858 & workspace % tmp_grid, workspace % tmp_sph_l)
2859 call tree_m2p(params, constants, params % lmax, one, &
2860 & workspace % tmp_sph, one, workspace % tmp_grid)
2862 if (params % pl .gt. 0)
then
2863 call tree_grad_l2l(params, constants, workspace % tmp_node_l, &
2864 & workspace % tmp_sph_l_grad, workspace % tmp_sph_l)
2868 call dgemm(
'T',
'N', params % ngrid, params % nsph, constants % nbasis, &
2869 & pt5, constants % vgrid2, constants % vgrid_nbasis, g, &
2870 & constants % nbasis, -one, workspace % tmp_grid, params % ngrid)
2872 do igrid = 1, params % ngrid
2873 do isph = 1, params % nsph
2874 workspace % tmp_grid(igrid, isph) = &
2875 & workspace % tmp_grid(igrid, isph) * constants % wgrid(igrid) * &
2876 & ygrid(igrid, isph)
2881 do isph = 1, params % nsph
2882 do igrid = 1, params % ngrid
2884 do ik = constants % inl(isph), constants % inl(isph+1) - 1
2885 ksph = constants % nl(ik)
2887 if(constants % ui(igrid, ksph) .eq. zero) cycle
2889 c = params % csph(:, ksph) + &
2890 & params % rsph(ksph)*constants % cgrid(:, igrid)
2891 vki = c - params % csph(:, isph)
2894 vvki = dnrm2(3, vki, 1)
2895 tki = vvki / params % rsph(isph)
2897 if((tki.le.tlow) .or. (tki.ge.thigh)) cycle
2901 gg = workspace % tmp_grid(igrid, ksph)
2908 if (params%switching.eq.0)
then
2909 fx(:, isph) = fx(:, isph) - &
2910 & dfsw(tki, params % se, params % eta)/ &
2911 & params % rsph(isph)*gg*(vki/vvki)
2913 d_k = constants%switching%d_ni(igrid, ksph)
2914 f_k = constants%switching%f_ni(igrid, ksph)
2915 chi_ki = fsw(tki,params%se,params%eta)
2916 grad_p = dfsw(tki,params%se,params%eta)
2917 duj = one/(d_k + f_k)**2 &
2918 & *(d_k + d_k*f_k/(one - chi_ki)) &
2919 & *grad_p/params%rsph(isph)
2920 fx(:, isph) = fx(:, isph) - gg*duj*(vki/vvki)
2924 if((constants % ui(igrid,isph).gt.zero) .and. &
2925 & (constants % ui(igrid,isph).lt.one))
then
2929 gg = workspace % tmp_grid(igrid, isph)
2934 fx(:, isph) = fx(:, isph) + gg*constants % zi(:, igrid, isph)
2936 if (constants % ui(igrid, isph) .gt. zero)
then
2943 call dgemv(
'T', params % pl**2, 3, one, &
2944 & workspace % tmp_sph_l_grad(1, 1, isph), &
2945 & (params % pl+1)**2, constants % vgrid2(1, igrid), 1, &
2949 inode = constants % snode(isph)
2950 do inear = constants % snear(inode), constants % snear(inode+1)-1
2951 jnode = constants % near(inear)
2952 do jsph_node = constants % cluster(1, jnode), &
2953 & constants % cluster(2, jnode)
2954 jsph = constants % order(jsph_node)
2955 if (isph .eq. jsph) cycle
2956 c = params % csph(:, isph) + &
2957 & params % rsph(isph)*constants % cgrid(:, igrid)
2958 tmp_c = c - params % csph(:, jsph)
2959 call fmm_m2p_work(tmp_c, &
2960 & params % rsph(jsph), params % lmax+1, &
2961 & constants % vscales_rel, one, &
2962 & workspace % tmp_sph_grad(:, 1, jsph), zero, &
2964 gg3(1) = gg3(1) + tmp_gg
2965 call fmm_m2p_work(tmp_c, &
2966 & params % rsph(jsph), params % lmax+1, &
2967 & constants % vscales_rel, one, &
2968 & workspace % tmp_sph_grad(:, 2, jsph), zero, &
2970 gg3(2) = gg3(2) + tmp_gg
2971 call fmm_m2p_work(tmp_c, &
2972 & params % rsph(jsph), params % lmax+1, &
2973 & constants % vscales_rel, one, &
2974 & workspace % tmp_sph_grad(:, 3, jsph), zero, &
2976 gg3(3) = gg3(3) + tmp_gg
2980 fx(:, isph) = fx(:, isph) - constants % wgrid(igrid)*gg3* &
2981 & ygrid(igrid, isph)*constants % ui(igrid, isph)
2985end subroutine gradr_fmm
2988subroutine gradr(params, constants, workspace, g, ygrid, fx)
2991 type(ddx_params_type),
intent(in) :: params
2992 type(ddx_constants_type),
intent(in) :: constants
2993 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
2994 & ygrid(params % ngrid, params % nsph)
2996 type(ddx_workspace_type),
intent(inout) :: workspace
2998 real(dp),
intent(out) :: fx(3, params % nsph)
3000 if (params % fmm .eq. 1)
then
3001 call gradr_fmm(params, constants, workspace, g, ygrid, fx)
3003 call gradr_dense(params, constants, workspace, g, ygrid, fx)
3008subroutine gradr_dense(params, constants, workspace, g, ygrid, fx)
3011 type(ddx_params_type),
intent(in) :: params
3012 type(ddx_constants_type),
intent(in) :: constants
3013 real(dp),
intent(in) :: g(constants % nbasis, params % nsph), &
3014 & ygrid(params % ngrid, params % nsph)
3016 type(ddx_workspace_type),
intent(inout) :: workspace
3018 real(dp),
intent(out) :: fx(3, params % nsph)
3022 do isph = 1, params % nsph
3023 call gradr_sph(params, constants, isph, workspace % tmp_vplm, &
3024 & workspace % tmp_vcos, workspace % tmp_vsin, &
3025 & workspace % tmp_vylm, workspace % tmp_vdylm, &
3026 & g, ygrid, fx(:, isph))
3028end subroutine gradr_dense
3033subroutine zeta_grad(params, constants, state, e_cav, forces)
3035 type(ddx_params_type),
intent(in) :: params
3036 type(ddx_constants_type),
intent(in) :: constants
3038 real(dp),
intent(inout) :: forces(3, params % nsph)
3039 real(dp),
intent(in) :: e_cav(3, constants % ncav)
3041 integer :: icav, isph, igrid
3044 do isph = 1, params % nsph
3045 do igrid = 1, params % ngrid
3046 if (constants % ui(igrid, isph) .eq. zero) cycle
3048 forces(:, isph) = forces(:, isph) + pt5 &
3049 & *state % zeta(icav)*e_cav(:, icav)
3052end subroutine zeta_grad
3057subroutine zeta_grad_dr(params, constants, state, e_cav, dr)
3059 type(ddx_params_type),
intent(in) :: params
3060 type(ddx_constants_type),
intent(in) :: constants
3062 real(dp),
intent(inout) :: dr(params % nsph)
3063 real(dp),
intent(in) :: e_cav(3, constants % ncav)
3065 integer :: icav, isph, igrid
3068 do isph = 1, params % nsph
3069 do igrid = 1, params % ngrid
3070 if (constants % ui(igrid, isph) .eq. zero) cycle
3072 dr(isph) = dr(isph) + pt5 &
3073 & * dot_product(constants % cgrid(:,igrid), e_cav(:, icav))*state % zeta(icav)
3076end 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...