22use omp_lib,
only : omp_get_wtime
30 real(dp),
allocatable :: u_ni(:,:)
33 real(dp),
allocatable :: u_i_cav(:)
35 real(dp),
allocatable :: d_ni(:,:)
37 real(dp),
allocatable :: f_ni(:,:)
40 real(dp),
allocatable :: grad_u_ni(:,:,:)
41 real(dp),
allocatable :: dr_u_ni(:,:)
62 real(dp),
allocatable :: vscales(:)
65 real(dp),
allocatable :: v4pi2lp1(:)
70 real(dp),
allocatable :: vscales_rel(:)
76 real(dp),
allocatable :: vfact(:)
80 real(dp),
allocatable :: vcnk(:)
84 real(dp),
allocatable :: m2l_ztranslate_coef(:, :, :)
88 real(dp),
allocatable :: m2l_ztranslate_adj_coef(:, :, :)
90 real(dp),
allocatable :: cgrid(:, :)
92 real(dp),
allocatable :: wgrid(:)
100 integer :: vgrid_nbasis
103 real(dp),
allocatable :: vgrid(:, :)
107 real(dp),
allocatable :: vwgrid(:, :)
109 real(dp),
allocatable :: vgrid2(:, :)
116 real(dp),
allocatable :: pchi(:, :, :)
119 real(dp),
allocatable :: c_ik(:, :)
121 real(dp),
allocatable :: si_ri(:, :)
124 real(dp),
allocatable :: di_ri(:, :)
126 real(dp),
allocatable :: sk_ri(:, :)
129 real(dp),
allocatable :: dk_ri(:, :)
131 real(dp),
allocatable :: termimat(:, :)
133 real(dp),
allocatable :: b(:,:,:)
135 real(dp),
allocatable :: l(:,:,:)
140 integer,
allocatable :: inl(:)
143 integer,
allocatable :: nl(:)
145 integer,
allocatable :: itrnl(:)
148 real(dp),
allocatable :: fi(:, :)
151 real(dp),
allocatable :: ui(:, :)
154 real(dp),
allocatable :: ui_cav(:)
157 real(dp),
allocatable :: zi(:, :, :)
160 real(dp),
allocatable :: zi_dr(:, :)
164 integer,
allocatable :: ncav_sph(:)
166 real(dp),
allocatable :: ccav(:, :)
168 integer,
allocatable :: icav_ia(:)
170 integer,
allocatable :: icav_ja(:)
173 real(dp),
allocatable :: rx_prc(:, :, :)
177 integer,
allocatable :: order(:)
182 integer,
allocatable :: cluster(:, :)
185 integer,
allocatable :: children(:, :)
188 integer,
allocatable :: parent(:)
191 real(dp),
allocatable :: cnode(:, :)
194 real(dp),
allocatable :: rnode(:)
197 integer,
allocatable :: snode(:)
200 real(dp),
allocatable :: sk_rnode(:, :)
203 real(dp),
allocatable :: si_rnode(:, :)
210 integer,
allocatable :: nfar(:)
213 integer,
allocatable :: nnear(:)
216 integer,
allocatable :: far(:)
219 integer,
allocatable :: near(:)
223 integer,
allocatable :: sfar(:)
227 integer,
allocatable :: snear(:)
236 integer :: m2p_nbasis
240 integer :: grad_nbasis
242 real(dp) :: inner_tol
265 type(ddx_error_type),
intent(inout) :: ddx_error
267 integer :: i, alloc_size, l, indl, igrid, isph, l0, &
268 & NZ, ierr, info, tmp_pmax
269 real(dp) :: rho, ctheta, stheta, cphi, sphi, termi, termk, &
271 real(dp),
allocatable :: vplm(:), vcos(:), vsin(:), vylm(:), SK_rijn(:), &
273 complex(dp),
allocatable :: bessel_work(:)
277 if (ddx_error % flag .ne. 0)
then
278 call update_error(ddx_error,
"constants_init received input in error " // &
284 constants % dodiag = .false.
286 constants % nbasis = (params % lmax+1) ** 2
288 constants % n = params % nsph * constants % nbasis
290 if (params % fmm .eq. 0)
then
291 if (params % force .eq. 1)
then
292 constants % dmax = params % lmax + 1
293 constants % vgrid_dmax = params % lmax + 1
295 constants % dmax = params % lmax
296 constants % vgrid_dmax = params % lmax
299 constants % m2p_lmax = -1
300 constants % m2p_nbasis = -1
301 constants % grad_nbasis = -1
305 if (params % force .eq. 1)
then
306 constants % dmax = max(params % pm+params % pl+1, &
308 constants % m2p_lmax = params % lmax + 1
309 constants % grad_nbasis = (params % lmax+2) ** 2
310 constants % vgrid_dmax = max(params % pl, params % lmax) + 1
312 constants % dmax = max(params % pm+params % pl, &
314 constants % m2p_lmax = params % lmax
315 constants % grad_nbasis = -1
316 constants % vgrid_dmax = max(params % pl, params % lmax)
318 constants % m2p_nbasis = (constants % m2p_lmax+1) ** 2
321 constants % vgrid_nbasis = (constants % vgrid_dmax+1) ** 2
322 constants % nfact = 2*constants % dmax+1
323 constants % nscales = (constants % dmax+1) ** 2
325 allocate(constants % vscales(constants % nscales), stat=info)
326 if (info .ne. 0)
then
327 call update_error(ddx_error,
"constants_init: `vscales` allocation " &
331 allocate(constants % v4pi2lp1(constants % dmax+1), stat=info)
332 if (info .ne. 0)
then
333 call update_error(ddx_error,
"constants_init: `v4pi2lp1` allocation " &
337 allocate(constants % vscales_rel(constants % nscales), stat=info)
338 if (info .ne. 0)
then
339 call update_error(ddx_error,
"constants_init: `vscales_rel` " // &
340 &
"allocation failed")
344 call ylmscale(constants % dmax, constants % vscales, &
345 & constants % v4pi2lp1, constants % vscales_rel)
347 allocate(constants % vfact(constants % nfact), stat=info)
348 if (info .ne. 0)
then
349 call update_error(ddx_error,
"constants_init: `vfact` allocation failed")
353 constants % vfact(1) = 1
354 do i = 2, constants % nfact
355 constants % vfact(i) = constants % vfact(i-1) * sqrt(dble(i-1))
359 if (params % fmm .eq. 1 .or. &
360 & (params % model .eq. 3 .and. params % force .eq. 1))
then
361 alloc_size = 2*constants % dmax + 1
362 alloc_size = alloc_size * (constants % dmax+1)
364 allocate(constants % vcnk(alloc_size), stat=info)
365 if (info .ne. 0)
then
366 call update_error(ddx_error,
"constants_init: `vcnk` allocation " &
371 allocate(constants % m2l_ztranslate_coef(&
372 & (params % pm+1), (params % pl+1), (params % pl+1)), &
374 if (info .ne. 0)
then
375 call update_error(ddx_error,
"constants_init: " // &
376 &
"`m2l_ztranslate_coef` allocation failed")
380 allocate(constants % m2l_ztranslate_adj_coef(&
381 & (params % pl+1), (params % pl+1), (params % pm+1)), &
383 if (info .ne. 0)
then
384 call update_error(ddx_error,
"constants_init: " // &
385 &
"`m2l_ztranslate_adj_coef` allocation failed")
390 & params % pl, constants % vcnk, &
391 & constants % m2l_ztranslate_coef, &
392 & constants % m2l_ztranslate_adj_coef)
395 allocate(constants % cgrid(3, params % ngrid), &
396 & constants % wgrid(params % ngrid), stat=info)
397 if (info .ne. 0)
then
398 call update_error(ddx_error,
"constants_init: `cgrid` and `wgrid` " // &
399 &
"allocations failed")
403 call llgrid(params % ngrid, constants % wgrid, constants % cgrid)
406 allocate(constants % vgrid(constants % vgrid_nbasis, params % ngrid), &
407 & constants % vwgrid(constants % vgrid_nbasis, params % ngrid), &
409 if (info .ne. 0)
then
410 call update_error(ddx_error,
"constants_init: `vgrid`, `wgrid` and" // &
411 &
" allocations failed")
414 allocate(vplm(constants % vgrid_nbasis), vcos(constants % vgrid_dmax+1), &
415 & vsin(constants % vgrid_dmax+1), stat=info)
416 if (info .ne. 0)
then
417 call update_error(ddx_error,
"constants_init: `vplm`, `vcos` and " // &
418 &
"`vsin` allocations failed")
423 do igrid = 1, params % ngrid
424 call ylmbas(constants % cgrid(:, igrid), rho, ctheta, stheta, cphi, &
425 & sphi, constants % vgrid_dmax, constants % vscales, &
426 & constants % vgrid(:, igrid), vplm, vcos, vsin)
427 constants % vwgrid(:, igrid) = constants % wgrid(igrid) * &
428 & constants % vgrid(:, igrid)
430 if (params % fmm .eq. 1)
then
431 allocate(constants % vgrid2( &
432 & constants % vgrid_nbasis, params % ngrid), &
434 if (info .ne. 0)
then
435 call update_error(ddx_error,
"constants_init: `vgrid2` " // &
436 &
"allocation failed")
439 do igrid = 1, params % ngrid
440 do l = 0, constants % vgrid_dmax
442 constants % vgrid2(indl-l:indl+l, igrid) = &
443 & constants % vgrid(indl-l:indl+l, igrid) / &
444 & constants % vscales(indl)**2
451 if (ddx_error % flag .ne. 0)
then
452 call update_error(ddx_error,
"constants_geometry_init returned an " // &
458 if (params % model .eq. 3)
then
459 constants % lmax0 = params % lmax
460 constants % nbasis0 = constants % nbasis
461 allocate(vylm(constants % vgrid_nbasis), &
462 & sk_rijn(0:constants % lmax0), dk_rijn(0:constants % lmax0), &
463 & bessel_work(constants % dmax+2), stat=info)
464 if (info .ne. 0)
then
465 call update_error(ddx_error,
"constants_init: `vylm`, `SK_rijn` " // &
466 &
"and `DK_rijn` allocations failed")
469 allocate(constants % SI_ri(0:constants % dmax+1, params % nsph), &
470 & constants % DI_ri(0:constants % dmax+1, params % nsph), &
471 & constants % SK_ri(0:params % lmax+1, params % nsph), &
472 & constants % DK_ri(0:params % lmax+1, params % nsph), &
473 & constants % Pchi(constants % nbasis, constants % nbasis0, params % nsph), &
474 & constants % C_ik(0:params % lmax, params % nsph), &
475 & constants % termimat(0:params % lmax, params % nsph), &
477 if (info .ne. 0)
then
478 call update_error(ddx_error,
"constants_init: allocation failed")
483 do isph = 1, params % nsph
486 call modified_spherical_bessel_first_kind(constants % dmax+1, &
487 & params % rsph(isph)*params % kappa,&
488 & constants % SI_ri(:, isph), constants % DI_ri(:, isph), &
490 call modified_spherical_bessel_second_kind(params % lmax+1, &
491 & params % rsph(isph)*params % kappa, &
492 & constants % SK_ri(:, isph), constants % DK_ri(:, isph), &
497 call mkpmat(params, constants, isph, constants % Pchi(:, :, isph))
499 do l = 0, params % lmax
500 constants % termimat(l, isph) = constants % DI_ri(l, isph) / &
501 & constants % SI_ri(l, isph) * params % kappa
504 do l0 = 0, constants % lmax0
505 termi = constants % DI_ri(l0, isph) / &
506 & constants % SI_ri(l0, isph) * params % kappa
507 termk = constants % DK_ri(l0, isph)/ &
508 & constants % SK_ri(l0, isph) * params % kappa
509 constants % C_ik(l0, isph) = one / (termi-termk)
512 if (params % fmm .eq. 1)
then
513 tmp_pmax = max(params % pm, params % pl)
514 allocate(constants % SI_rnode(tmp_pmax+1, constants % nclusters), &
515 & constants % SK_rnode(tmp_pmax+1, constants % nclusters), &
518 call update_error(ddx_error,
"constants_init: `si_rnode, " // &
519 &
"sk_rnode allocation failed")
522 do i = 1, constants % nclusters
523 z = constants % rnode(i) * params % kappa
524 s1 = sqrt(two/(pi*real(z)))
525 s2 = sqrt(pi/(two*real(z)))
526 call cbesk(z, pt5, 1, 1, bessel_work(1), nz, ierr)
527 constants % SK_rnode(1, i) = s1 * real(bessel_work(1))
528 call cbesi(z, pt5, 1, 1, bessel_work(1), nz, ierr)
529 constants % SI_rnode(1, i) = s2 * real(bessel_work(1))
530 if (tmp_pmax .gt. 0)
then
531 call cbesk(z, 1.5d0, 1, tmp_pmax, bessel_work(2:), nz, ierr)
532 constants % SK_rnode(2:, i) = s1 * real(bessel_work(2:tmp_pmax+1))
533 call cbesi(z, 1.5d0, 1, tmp_pmax, bessel_work(2:), nz, ierr)
534 constants % SI_rnode(2:, i) = s2 * real(bessel_work(2:tmp_pmax+1))
538 deallocate(vylm, sk_rijn, dk_rijn, bessel_work, stat=info)
539 if (info .ne. 0)
then
540 call update_error(ddx_error,
"constants_init: `vylm`, `SK_rijn` " // &
541 &
"and `DK_rijn` deallocations failed")
545 if (params % matvecmem .eq. 1)
then
546 call build_b(constants, params, ddx_error)
547 if (ddx_error % flag .ne. 0)
then
548 call update_error(ddx_error,
"build_b returned an " // &
554 deallocate(vplm, vcos, vsin, stat=info)
555 if (info .ne. 0)
then
556 call update_error(ddx_error,
"constants_init: `vplm`, `vcos` and " // &
557 &
"`vsin` deallocations failed")
561 if (params % matvecmem .eq. 1)
then
563 if (ddx_error % flag .ne. 0)
then
564 call update_error(ddx_error,
"build_itrnl returned an " // &
568 call build_l(constants, params, ddx_error)
569 if (ddx_error % flag .ne. 0)
then
570 call update_error(ddx_error,
"build_l returned an " // &
583 type(ddx_error_type),
intent(inout) :: ddx_error
584 integer :: isph, ij, jsph, ji, istat
586 allocate(constants % itrnl(constants % inl(params % nsph + 1)), stat=istat)
588 call update_error(ddx_error,
'Allocation failed in build_itrnl')
592 do isph = 1, params % nsph
593 do ij = constants % inl(isph), constants % inl(isph + 1) - 1
594 jsph = constants % nl(ij)
595 do ji = constants % inl(jsph), constants % inl(jsph + 1) - 1
596 if (constants % nl(ji) .eq. isph)
exit
598 constants % itrnl(ij) = ji
604subroutine build_l(constants, params, ddx_error)
608 type(ddx_error_type),
intent(inout) :: ddx_error
609 integer :: isph, ij, jsph, igrid, l, m, ind, info
610 real(dp),
dimension(3) :: vij, sij
611 real(dp) :: vvij, tij, xij, oij, rho, ctheta, stheta, cphi, sphi, &
612 & fac, tt, thigh, d_i, f_i
613 real(dp),
dimension(constants % nbasis) :: vylm, vplm
614 real(dp),
dimension(params % lmax + 1) :: vcos, vsin
615 real(dp),
dimension(constants % nbasis, params % ngrid) :: scratch
617 allocate(constants % l(constants % nbasis, constants % nbasis, &
618 & constants % inl(params % nsph + 1)), stat=info)
619 if (info .ne. 0)
then
620 call update_error(ddx_error,
'Allocation failed in build_l')
624 thigh = one + pt5*(params % se + one)*params % eta
626 if (params%switching.eq.0)
then
630 do isph = 1, params % nsph
631 do ij = constants % inl(isph), constants % inl(isph + 1) - 1
632 jsph = constants % nl(ij)
634 do igrid = 1, params % ngrid
635 if (constants % ui(igrid, isph).eq.one) cycle
636 vij = params % csph(:, isph) &
637 & + params % rsph(isph)*constants % cgrid(:,igrid) &
638 & - params % csph(:, jsph)
639 vvij = sqrt(dot_product(vij, vij))
640 tij = vvij/params % rsph(jsph)
641 if (tij.lt.thigh)
then
642 if (tij.ne.zero)
then
647 xij =
fsw(tij, params % se, params % eta)
648 if (constants % fi(igrid, isph).gt.one)
then
649 oij = xij/constants % fi(igrid, isph)
653 call ylmbas(sij, rho, ctheta, stheta, cphi, sphi, &
654 & params % lmax, constants % vscales, vylm, vplm, &
657 do l = 0, params % lmax
659 fac = - tt/(constants % vscales(ind)**2)
661 scratch(ind + m, igrid) = fac*vylm(ind + m)
667 call dgemm(
'n',
't', constants % nbasis, constants % nbasis, params % ngrid, &
668 & one, constants % vwgrid, constants % vgrid_nbasis, scratch, &
669 & constants % nbasis, zero, constants % l(:,:,ij), constants % nbasis)
677 do isph = 1, params % nsph
678 do ij = constants % inl(isph), constants % inl(isph + 1) - 1
679 jsph = constants % nl(ij)
681 do igrid = 1, params % ngrid
682 d_i = constants%switching%d_ni(igrid,isph)
683 f_i = constants%switching%f_ni(igrid,isph)
684 if (constants % ui(igrid, isph).eq.one) cycle
685 vij = params % csph(:, isph) &
686 & + params % rsph(isph)*constants % cgrid(:,igrid) &
687 & - params % csph(:, jsph)
688 vvij = sqrt(dot_product(vij, vij))
689 tij = vvij/params % rsph(jsph)
690 if (tij.lt.thigh)
then
691 if (tij.ne.zero)
then
696 xij =
fsw(tij, params % se, params % eta)
697 oij = xij/(d_i + f_i)
698 call ylmbas(sij, rho, ctheta, stheta, cphi, sphi, &
699 & params % lmax, constants % vscales, vylm, vplm, &
702 do l = 0, params % lmax
704 fac = - tt/(constants % vscales(ind)**2)
706 scratch(ind + m, igrid) = fac*vylm(ind + m)
712 call dgemm(
'n',
't', constants % nbasis, constants % nbasis, params % ngrid, &
713 & one, constants % vwgrid, constants % vgrid_nbasis, scratch, &
714 & constants % nbasis, zero, constants % l(:,:,ij), constants % nbasis)
721subroutine build_b(constants, params, ddx_error)
725 type(ddx_error_type),
intent(inout) :: ddx_error
726 integer :: isph, ij, jsph, igrid, l, m, ind
727 real(dp),
dimension(3) :: vij, sij
728 real(dp) :: vvij, tij, xij, oij, rho, ctheta, stheta, cphi, sphi, &
730 real(dp),
dimension(constants % nbasis) :: vylm, vplm
731 real(dp),
dimension(params % lmax + 1) :: vcos, vsin
732 complex(dp),
dimension(max(2, params % lmax + 1)) :: bessel_work
733 real(dp),
dimension(0:params % lmax) :: SI_rijn, DI_rijn
734 real(dp),
dimension(constants % nbasis, params % ngrid) :: scratch
738 allocate(constants % b(constants % nbasis, constants % nbasis, &
739 & constants % inl(params % nsph + 1)), stat=info)
741 call update_error(ddx_error,
"Allocation failed in build_b")
745 thigh = one + pt5*(params % se + one)*params % eta
747 if (params%switching.eq.0)
then
752 do isph = 1, params % nsph
753 do ij = constants % inl(isph), constants % inl(isph + 1) - 1
754 jsph = constants % nl(ij)
756 do igrid = 1, params % ngrid
757 if (constants % ui(igrid, isph).eq.one) cycle
758 vij = params % csph(:, isph) &
759 & + params % rsph(isph)*constants % cgrid(:,igrid) &
760 & - params % csph(:, jsph)
761 vvij = sqrt(dot_product(vij, vij))
762 tij = vvij/params % rsph(jsph)
763 if (tij.lt.thigh)
then
764 if (tij.ne.zero)
then
769 xij =
fsw(tij, params % se, params % eta)
770 if (constants % fi(igrid, isph).gt.one)
then
771 oij = xij/constants % fi(igrid, isph)
775 call ylmbas(sij, rho, ctheta, stheta, cphi, sphi, &
776 & params % lmax, constants % vscales, vylm, vplm, &
780 vvtij = vvij*params % kappa
781 call modified_spherical_bessel_first_kind(params % lmax, &
782 & vvtij, si_rijn, di_rijn, bessel_work)
783 do l = 0, params % lmax
784 fac = - oij*si_rijn(l)/constants % SI_ri(l, jsph)
787 scratch(ind + m, igrid) = fac*vylm(ind + m)
792 call dgemm(
'n',
't', constants % nbasis, constants % nbasis, params % ngrid, &
793 & one, constants % vwgrid, constants % vgrid_nbasis, scratch, &
794 & constants % nbasis, zero, constants % b(:,:,ij), constants % nbasis)
802 do isph = 1, params % nsph
803 do ij = constants % inl(isph), constants % inl(isph + 1) - 1
804 jsph = constants % nl(ij)
806 do igrid = 1, params % ngrid
807 d_i = constants%switching%d_ni(igrid,isph)
808 f_i = constants%switching%f_ni(igrid,isph)
809 if (constants % ui(igrid, isph).eq.one) cycle
810 vij = params % csph(:, isph) &
811 & + params % rsph(isph)*constants % cgrid(:,igrid) &
812 & - params % csph(:, jsph)
813 vvij = sqrt(dot_product(vij, vij))
814 tij = vvij/params % rsph(jsph)
815 if (tij.lt.thigh)
then
816 if (tij.ne.zero)
then
821 xij =
fsw(tij, params % se, params % eta)
822 oij = xij/(d_i + f_i)
823 call ylmbas(sij, rho, ctheta, stheta, cphi, sphi, &
824 & params % lmax, constants % vscales, vylm, vplm, &
828 vvtij = vvij*params % kappa
829 call modified_spherical_bessel_first_kind(params % lmax, &
830 & vvtij, si_rijn, di_rijn, bessel_work)
831 do l = 0, params % lmax
832 fac = - oij*si_rijn(l)/constants % SI_ri(l, jsph)
835 scratch(ind + m, igrid) = fac*vylm(ind + m)
840 call dgemm(
'n',
't', constants % nbasis, constants % nbasis, params % ngrid, &
841 & one, constants % vwgrid, constants % vgrid_nbasis, scratch, &
842 & constants % nbasis, zero, constants % b(:,:,ij), constants % nbasis)
849subroutine mkpmat(params, constants, isph, pmat)
852 integer,
intent(in) :: isph
853 real(dp),
dimension(constants % nbasis, constants % nbasis0),
intent(inout) :: pmat
854 integer :: l, m, ind, l0, m0, ind0, its
857 do its = 1, params % ngrid
858 if (constants % ui(its,isph).ne.0)
then
859 do l = 0, params % lmax
862 f = constants % wgrid(its) * constants % vgrid(ind+m,its) * constants % ui(its,isph)
863 do l0 = 0, constants % lmax0
864 ind0 = l0*l0 + l0 + 1
866 f0 = constants % vgrid(ind0+m0,its)
867 pmat(ind+m,ind0+m0) = pmat(ind+m,ind0+m0) + f * f0
890 type(ddx_error_type),
intent(inout) :: ddx_error
892 real(dp) :: swthr, v(3), maxv, ssqv, vv, t
893 integer :: i, isph, jsph, inear, igrid, iwork, jwork, lwork, &
894 & old_lwork, icav, info
895 integer,
allocatable :: work(:, :), tmp_work(:, :)
896 real(dp) :: start_time
899 start_time = omp_get_wtime()
900 if (params % fmm .eq. 1)
then
902 allocate(constants % order(params % nsph), stat=info)
903 if (info .ne. 0)
then
904 call update_error(ddx_error,
"constants_geometry_init: `order` " &
905 & //
"allocation failed")
908 constants % nclusters = 2*params % nsph - 1
909 allocate(constants % cluster(2, constants % nclusters), stat=info)
910 if (info .ne. 0)
then
911 call update_error(ddx_error,
"constants_geometry_init: `cluster` " &
912 & //
"allocation failed")
915 allocate(constants % children(2, constants % nclusters), stat=info)
916 if (info .ne. 0)
then
917 call update_error(ddx_error,
"constants_geometry_init: " // &
918 &
"`children` allocation failed")
921 allocate(constants % parent(constants % nclusters), stat=info)
922 if (info .ne. 0)
then
923 call update_error(ddx_error,
"constants_geometry_init: `parent` " &
924 & //
"allocation failed")
927 allocate(constants % cnode(3, constants % nclusters), stat=info)
928 if (info .ne. 0)
then
929 call update_error(ddx_error,
"constants_geometry_init: `cnode` " &
930 & //
"allocation failed")
933 allocate(constants % rnode(constants % nclusters), stat=info)
934 if (info .ne. 0)
then
935 call update_error(ddx_error,
"constants_geometry_init: `rnode` " &
936 & //
"allocation failed")
939 allocate(constants % snode(params % nsph), stat=info)
940 if (info .ne. 0)
then
941 call update_error(ddx_error,
"constants_geometry_init: `snode` " &
942 & //
"allocation failed")
945 allocate(constants % nfar(constants % nclusters), stat=info)
946 if (info .ne. 0)
then
947 call update_error(ddx_error,
"constants_geometry_init: `nfar` " &
948 & //
"allocation failed")
951 allocate(constants % nnear(constants % nclusters), stat=info)
952 if (info .ne. 0)
then
953 call update_error(ddx_error,
"constants_geometry_init: `nnear` " &
954 & //
"allocation failed")
958 call tree_rib_build(params % nsph, params % csph, params % rsph, &
959 & constants % order, constants % cluster, constants % children, &
960 & constants % parent, constants % cnode, constants % rnode, &
961 & constants % snode, ddx_error)
962 if (ddx_error % flag .ne. 0)
then
963 call update_error(ddx_error,
"tree_rib_build returned an " // &
964 &
"ddx_error, exiting")
971 allocate(work(3, lwork), stat=info)
972 if (info .ne. 0)
then
973 call update_error(ddx_error,
"constants_geometry_init: `work` " &
974 & //
"allocation failed")
977 do while (iwork .le. jwork)
978 allocate(tmp_work(3, lwork), stat=info)
979 if (info .ne. 0)
then
980 call update_error(ddx_error,
"constants_geometry_init: " // &
981 &
"`tmp_work` allocation failed")
985 deallocate(work, stat=info)
986 if (info .ne. 0)
then
987 call update_error(ddx_error,
"constants_geometry_init: " // &
988 &
"`work` deallocation failed")
992 lwork = old_lwork + 1000*params % nsph
993 allocate(work(3, lwork), stat=info)
994 if (info .ne. 0)
then
995 call update_error(ddx_error,
"constants_geometry_init: " // &
996 &
"`work` allocation failed")
999 work(:, 1:old_lwork) = tmp_work
1000 deallocate(tmp_work, stat=info)
1001 if (info .ne. 0)
then
1002 call update_error(ddx_error,
"constants_geometry_init: " // &
1003 &
"`tmp_work` deallocation failed")
1007 & constants % children, constants % cnode, &
1008 & constants % rnode, lwork, iwork, jwork, work, &
1009 & constants % nnfar, constants % nfar, constants % nnnear, &
1010 & constants % nnear)
1012 allocate(constants % sfar(constants % nclusters+1), &
1013 & constants % snear(constants % nclusters+1), stat=info)
1014 if (info .ne. 0)
then
1015 call update_error(ddx_error,
"constants_geometry_init: `sfar` " // &
1016 &
"and `snear` allocations failed")
1019 allocate(constants % far(constants % nnfar), stat=info)
1020 if (info .ne. 0)
then
1021 call update_error(ddx_error,
"constants_geometry_init: `far` " // &
1022 &
"allocation failed")
1025 allocate(constants % near(constants % nnnear), stat=info)
1026 if (info .ne. 0)
then
1027 call update_error(ddx_error,
"constants_geometry_init: `near` " // &
1028 &
"allocation failed")
1032 & constants % nnfar, constants % nfar, constants % sfar, &
1033 & constants % far, constants % nnnear, constants % nnear, &
1034 & constants % snear, constants % near)
1035 deallocate(work, stat=info)
1036 if (info .ne. 0)
then
1037 call update_error(ddx_error,
"constants_geometry_init: `work` " // &
1038 &
"deallocation failed")
1043 swthr = one + (params % se+one)*params % eta/two
1045 if (params % fmm .eq. 1)
then
1050 if (ddx_error % flag .ne. 0)
then
1051 call update_error(ddx_error,
"Neighbor list construction failed")
1055 allocate(constants % fi(params % ngrid, params % nsph), &
1056 & constants % ui(params % ngrid, params % nsph), stat=info)
1057 if (info .ne. 0)
then
1058 call update_error(ddx_error,
"`fi` and `ui` allocations failed")
1061 constants % fi = zero
1062 constants % ui = zero
1064 if (params % force .eq. 1)
then
1065 allocate(constants % zi(3, params % ngrid, params % nsph), stat=info)
1066 if (info .ne. 0)
then
1067 call update_error(ddx_error,
"`zi` allocation failed")
1070 constants % zi = zero
1072 allocate(constants % zi_dr(params % ngrid, params % nsph), stat=info)
1073 if (info .ne. 0)
then
1074 call update_error(ddx_error,
"`zi_dr` allocation failed")
1077 constants % zi_dr = zero
1083 do isph = 1, params % nsph
1084 do igrid = 1, params % ngrid
1086 do inear = constants % inl(isph), constants % inl(isph+1)-1
1088 jsph = constants % nl(inear)
1090 v = params % csph(:, isph) - params % csph(:, jsph) + &
1091 & params % rsph(isph)*constants % cgrid(:, igrid)
1092 maxv = max(abs(v(1)), abs(v(2)), abs(v(3)))
1093 if (maxv .gt. zero)
then
1094 ssqv = (v(1)/maxv)**2 + (v(2)/maxv)**2 + (v(3)/maxv)**2
1098 vv = maxv * sqrt(ssqv)
1099 t = vv / params % rsph(jsph)
1101 constants % fi(igrid, isph) = constants % fi(igrid, isph) + &
1102 &
fsw(t, params % se, params % eta)
1104 if (params % force .eq. 1)
then
1106 if ((t .lt. swthr) .and. (t .gt. swthr-params % eta))
then
1108 vv =
dfsw(t, params % se, params % eta) / &
1109 & params % rsph(jsph) / vv
1110 constants % zi(:, igrid, isph) = &
1111 & constants % zi(:, igrid, isph) + vv*v
1112 constants % zi_dr(igrid, isph) = &
1113 & constants % zi_dr(igrid, isph) &
1114 & + vv*dot_product(v, constants % cgrid(:, igrid))
1119 if (constants % fi(igrid, isph) .le. one)
then
1120 constants % ui(igrid, isph) = one - constants % fi(igrid, isph)
1125 if (params%switching.eq.1)
then
1126 call switching_init(params, constants, constants%switching, ddx_error)
1127 constants % ui = constants%switching%u_ni
1128 if (params%force.eq.1)
then
1129 constants % zi = constants%switching%grad_u_ni
1130 constants % zi_dr = constants%switching%dr_u_ni
1133 if (ddx_error % flag .ne. 0)
then
1134 call update_error(ddx_error,
"switching_init returned an " // &
1140 allocate(constants % ncav_sph(params % nsph), stat=info)
1141 if (info .ne. 0)
then
1142 call update_error(ddx_error,
"`ncav_sph` allocation failed")
1147 do isph = 1, params % nsph
1148 constants % ncav_sph(isph) = 0
1150 do i = 1, params % ngrid
1152 if (constants % ui(i, isph) .gt. zero)
then
1153 constants % ncav_sph(isph) = constants % ncav_sph(isph) + 1
1157 constants % ncav = sum(constants % ncav_sph)
1159 allocate(constants % ccav(3, constants % ncav), &
1160 & constants % icav_ia(params % nsph+1), &
1161 & constants % icav_ja(constants % ncav), stat=info)
1162 if (info .ne. 0)
then
1163 call update_error(ddx_error,
"`ccav`, `icav_ia` and " // &
1164 &
"`icav_ja` allocations failed")
1168 allocate(constants % ui_cav(constants % ncav), stat=info)
1169 if (info .ne. 0)
then
1170 call update_error(ddx_error,
"`ui_cav` allocations failed")
1175 constants % icav_ia(1) = 1
1177 do isph = 1, params % nsph
1178 constants % icav_ia(isph+1) = constants % icav_ia(isph) + &
1179 & constants % ncav_sph(isph)
1181 do igrid = 1, params % ngrid
1183 if (constants % ui(igrid, isph) .eq. zero) cycle
1185 constants % ccav(:, icav) = params % csph(:, isph) + &
1186 & params % rsph(isph)* &
1187 & constants % cgrid(:, igrid)
1189 constants % icav_ja(icav) = igrid
1191 constants % ui_cav(icav) = constants % ui(igrid, isph)
1197 if (params % model .eq. 2)
then
1198 allocate(constants % rx_prc( &
1199 & constants % nbasis, constants % nbasis, params % nsph), &
1201 if (info .ne. 0)
then
1202 call update_error(ddx_error,
"constants_geometry_init: `rx_prc` " &
1203 & //
"allocation failed")
1206 call mkprec(params % lmax, constants % nbasis, params % nsph, &
1207 & params % ngrid, params % eps, constants % ui, &
1208 & constants % wgrid, constants % vgrid, constants % vgrid_nbasis, &
1209 & constants % rx_prc, ddx_error)
1210 if (info .ne. 0)
then
1211 call update_error(ddx_error,
"mkprec returned an ddx_error, exiting")
1221 type(ddx_error_type),
intent(inout) :: ddx_error
1222 real(dp) :: swthr, v(3), maxv, ssqv, vv, r
1223 integer :: nngmax, i, lnl, isph, jsph, info
1224 integer,
allocatable :: tmp_nl(:)
1226 swthr = (params % se+one)*params % eta/two
1229 allocate(constants % inl(params % nsph+1), &
1230 & constants % nl(params % nsph*nngmax), stat=info)
1231 if (info .ne. 0)
then
1232 call update_error(ddx_error,
"`inl` and `nl` allocations failed")
1237 do isph = 1, params % nsph
1238 constants % inl(isph) = lnl + 1
1239 do jsph = 1, params % nsph
1240 if (isph .ne. jsph)
then
1241 v = params % csph(:, isph)-params % csph(:, jsph)
1242 maxv = max(abs(v(1)), abs(v(2)), abs(v(3)))
1243 if (maxv .gt. zero)
then
1244 ssqv = (v(1)/maxv)**2 + (v(2)/maxv)**2 + (v(3)/maxv)**2
1248 vv = maxv * sqrt(ssqv)
1254 r = params % rsph(isph) + params % rsph(jsph) &
1255 & + swthr * max(params % rsph(isph), params % rsph(jsph))
1257 constants % nl(i) = jsph
1261 if (i .gt. params % nsph*nngmax)
then
1262 allocate(tmp_nl(params % nsph*nngmax), stat=info)
1263 if (info .ne. 0)
then
1264 call update_error(ddx_error,
"`tmp_nl` " // &
1265 &
"allocation failed")
1268 tmp_nl(1:params % nsph*nngmax) = &
1269 & constants % nl(1:params % nsph*nngmax)
1270 deallocate(constants % nl, stat=info)
1271 if (info .ne. 0)
then
1272 call update_error(ddx_error,
"`nl` " // &
1273 &
"deallocation failed")
1276 nngmax = nngmax + 10
1277 allocate(constants % nl(params % nsph*nngmax), &
1279 if (info .ne. 0)
then
1280 call update_error(ddx_error,
"`nl` " // &
1281 &
"allocation failed")
1284 constants % nl(1:params % nsph*(nngmax-10)) = &
1285 & tmp_nl(1:params % nsph*(nngmax-10))
1286 deallocate(tmp_nl, stat=info)
1287 if (info .ne. 0)
then
1288 call update_error(ddx_error,
"`tmp_nl` " // &
1289 &
"deallocation failed")
1297 constants % inl(params % nsph+1) = lnl+1
1298 constants % nngmax = nngmax
1306 type(ddx_error_type),
intent(inout) :: ddx_error
1307 real(dp) :: swthr, v(3), maxv, ssqv, vv, r
1308 integer :: nngmax, i, lnl, isph, jsph, inode, jnode, j, k, info
1309 integer,
allocatable :: tmp_nl(:)
1311 swthr = (params % se+one)*params % eta/two
1314 allocate(constants % inl(params % nsph+1), &
1315 & constants % nl(params % nsph*nngmax), stat=info)
1316 if (info .ne. 0)
then
1317 call update_error(ddx_error,
"`inl` and `nl` allocations failed")
1323 do isph = 1, params % nsph
1324 constants % inl(isph) = lnl + 1
1325 inode = constants % snode(isph)
1327 do j = constants % snear(inode), constants % snear(inode+1) - 1
1328 jnode = constants % near(j)
1329 do k = constants % cluster(1, jnode), constants % cluster(2, jnode)
1330 jsph = constants % order(k)
1331 if (isph .ne. jsph)
then
1332 v = params % csph(:, isph)-params % csph(:, jsph)
1333 maxv = max(abs(v(1)), abs(v(2)), abs(v(3)))
1334 if (maxv .gt. zero)
then
1335 ssqv = (v(1)/maxv)**2 + (v(2)/maxv)**2 + (v(3)/maxv)**2
1339 vv = maxv * sqrt(ssqv)
1345 r = params % rsph(isph) + params % rsph(jsph) &
1346 & + swthr * max(params % rsph(isph), params % rsph(jsph))
1348 constants % nl(i) = jsph
1352 if (i .gt. params % nsph*nngmax)
then
1353 allocate(tmp_nl(params % nsph*nngmax), stat=info)
1354 if (info .ne. 0)
then
1355 call update_error(ddx_error,
"`tmp_nl` " // &
1356 &
"allocation failed")
1359 tmp_nl(1:params % nsph*nngmax) = &
1360 & constants % nl(1:params % nsph*nngmax)
1361 deallocate(constants % nl, stat=info)
1362 if (info .ne. 0)
then
1363 call update_error(ddx_error,
"`nl` " // &
1364 &
"deallocation failed")
1367 nngmax = nngmax + 10
1368 allocate(constants % nl(params % nsph*nngmax), &
1370 if (info .ne. 0)
then
1371 call update_error(ddx_error,
"`nl` " // &
1372 &
"allocation failed")
1375 constants % nl(1:params % nsph*(nngmax-10)) = &
1376 & tmp_nl(1:params % nsph*(nngmax-10))
1377 deallocate(tmp_nl, stat=info)
1378 if (info .ne. 0)
then
1379 call update_error(ddx_error,
"`tmp_nl` " // &
1380 &
"deallocation failed")
1389 constants % inl(params % nsph+1) = lnl+1
1390 constants % nngmax = nngmax
1420real(dp) function fsw(t, se, eta)
1422 real(dp),
intent(in) :: t, se, eta
1424 real(dp) :: a, b, c, x
1429 x = t - (se*pt5 + pt5)*eta
1434 if (a .le. zero)
then
1437 else if (a .ge. eta)
then
1477 real(dp),
intent(in) :: t, se, eta
1480 real(dp),
parameter :: f30=30.0d0
1485 x = t - (se + 1.d0)*eta / 2.d0
1489 if (x .ge. one)
then
1491 else if (x .le. flow)
then
1494 dfsw = -f30 * (( (one-x)*(x-one+eta) )**2) / (eta**5)
1501subroutine mkprec(lmax, nbasis, nsph, ngrid, eps, ui, wgrid, vgrid, &
1502 & vgrid_nbasis, rx_prc, ddx_error)
1504 integer,
intent(in) :: lmax, nbasis, nsph, ngrid, vgrid_nbasis
1505 real(dp),
intent(in) :: eps, ui(ngrid, nsph), wgrid(ngrid), &
1506 & vgrid(vgrid_nbasis, ngrid)
1508 real(dp),
intent(out) :: rx_prc(nbasis, nbasis, nsph)
1509 type(ddx_error_type),
intent(inout) :: ddx_error
1511 integer :: info, isph, lm, l1, m1, ind1, igrid
1513 integer,
allocatable :: ipiv(:)
1514 real(dp),
allocatable :: work(:)
1515 external :: dgetrf, dgetri
1517 allocate(ipiv(nbasis), work(nbasis**2), stat=info)
1518 if (info .ne. 0)
then
1519 call update_error(ddx_error,
"mkprec: `ipiv` and `work` allocation failed")
1527 f = twopi * ui(igrid, isph) * wgrid(igrid)
1529 ind1 = l1*l1 + l1 + 1
1531 f1 = f * vgrid(ind1+m1, igrid) / (two*dble(l1) + one)
1533 rx_prc(lm, ind1+m1, isph) = &
1534 & rx_prc(lm, ind1+m1, isph) + f1*vgrid(lm, igrid)
1541 f = twopi * (eps+one) / (eps-one)
1544 rx_prc(lm, lm, isph) = rx_prc(lm, lm, isph) + f
1549 call dgetrf(nbasis, nbasis, rx_prc(:, :, isph), nbasis, ipiv, info)
1550 if (info .ne. 0)
then
1551 call update_error(ddx_error,
"mkprec: dgetrf failed")
1554 call dgetri(nbasis, rx_prc(:, :, isph), nbasis, ipiv, work, &
1556 if (info .ne. 0)
then
1557 call update_error(ddx_error,
"mkprec: dgetri failed")
1562 deallocate(work, ipiv, stat=info)
1563 if (info .ne. 0)
then
1564 call update_error(ddx_error,
"mkprec: `ipiv` and `work` " // &
1565 &
"deallocation failed")
1593 & cnode, rnode, snode, ddx_error)
1595 integer,
intent(in) :: nsph
1596 real(dp),
intent(in) :: csph(3, nsph), rsph(nsph)
1598 integer,
intent(out) :: order(nsph), cluster(2, 2*nsph-1), &
1599 & children(2, 2*nsph-1), parent(2*nsph-1), snode(nsph)
1600 real(dp),
intent(out) :: cnode(3, 2*nsph-1), rnode(2*nsph-1)
1601 type(ddx_error_type),
intent(inout) :: ddx_error
1603 integer :: nclusters, i, j, n, s, e, div
1604 real(dp) :: r, r1, r2, c(3), c1(3), c2(3), d, maxc
1606 nclusters = 2*nsph - 1
1609 cluster(2, 1) = nsph
1630 if (ddx_error % flag .ne. 0)
then
1631 call update_error(ddx_error,
"tree_rib_node_bisect returned " // &
1632 &
"an ddx_error, exiting")
1637 cluster(2, j) = s + div - 1
1639 cluster(1, j+1) = s + div
1643 children(2, i) = j + 1
1659 do i = nclusters, 1, -1
1662 if (children(1, i) .eq. 0)
then
1664 j = order(cluster(1, i))
1666 cnode(:, i) = csph(:, j)
1682 maxc = max(abs(c(1)), abs(c(2)), abs(c(3)))
1683 if (maxc .eq. zero)
then
1686 d = (c(1)/maxc)**2 + (c(2)/maxc)**2 + (c(3)/maxc)**2
1690 if (r1 .ge. (r2+d))
then
1694 else if(r2 .ge. (r1+d))
then
1721 integer,
intent(in) :: nsph, n
1722 real(dp),
intent(in) :: csph(3, nsph)
1724 integer,
intent(inout) :: order(n)
1725 integer,
intent(out) :: div
1726 type(ddx_error_type),
intent(inout) :: ddx_error
1728 real(dp) :: c(3), s(3)
1729 real(dp),
allocatable :: tmp_csph(:, :), work(:)
1731 integer :: i, l, r, lwork, info, istat
1732 integer,
allocatable :: tmp_order(:)
1734 allocate(tmp_csph(3, n), tmp_order(n), stat=istat)
1735 if (istat.ne.0)
then
1736 call update_error(ddx_error,
'Allocation failed in tree_node_bisect')
1743 c = c + csph(:, order(i))
1748 tmp_csph(:, i) = csph(:, order(i)) - c
1753 call dgesvd(
'N',
'O', 3, n, tmp_csph, 3, s, tmp_csph, 3, tmp_csph, 3, &
1756 allocate(work(lwork), stat=istat)
1757 if (istat.ne.0)
then
1758 call update_error(ddx_error,
'Allocation failed in tree_node_bisect')
1762 call dgesvd(
'N',
'O', 3, n, tmp_csph, 3, s, tmp_csph, 3, tmp_csph, 3, &
1763 & work, lwork, info)
1765 call update_error(ddx_error,
'DGESVD failed in tree_node_bisect')
1768 deallocate(work, stat=istat)
1769 if (istat.ne.0)
then
1770 call update_error(ddx_error,
'Deallocation failed in tree_node_bisect')
1784 if (tmp_csph(1, i) .ge. zero)
then
1785 tmp_order(l) = order(i)
1789 tmp_order(r) = order(i)
1796 deallocate(tmp_csph, tmp_order, stat=istat)
1797 if (istat.ne.0)
then
1798 call update_error(ddx_error,
'Deallocation failed in tree_node_bisect')
1828 & jwork, work, nnfar, nfar, nnnear, nnear)
1830 integer,
intent(in) :: n, children(2, n), lwork
1831 real(dp),
intent(in) :: cnode(3, n), rnode(n)
1833 integer,
intent(inout) :: iwork, jwork, work(3, lwork)
1834 integer,
intent(out) :: nnfar, nfar(n), nnnear, nnear(n)
1836 integer :: j(2), npairs, k1, k2
1837 real(dp) :: c(3), r, d, dmax, dssq
1839 if (iwork .eq. 0)
then
1846 do while (iwork .le. jwork)
1847 j = work(1:2, iwork)
1848 c = cnode(:, j(1)) - cnode(:, j(2))
1849 r = rnode(j(1)) + rnode(j(2)) + max(rnode(j(1)), rnode(j(2)))
1851 dmax = max(abs(c(1)), abs(c(2)), abs(c(3)))
1852 if (dmax .gt. zero)
then
1853 dssq = (c(1)/dmax)**2 + (c(2)/dmax)**2 + (c(3)/dmax)**2
1857 d = dmax * sqrt(dssq)
1862 npairs = max(1, children(2, j(1))-children(1, j(1))+1) * &
1863 & max(1, children(2, j(2))-children(1, j(2))+1)
1867 else if (npairs .eq. 1)
then
1870 else if (jwork+npairs .gt. lwork)
then
1878 if (children(1, j(1)) .eq. 0)
then
1880 do k2 = children(1, j(2)), children(2, j(2))
1885 else if(children(1, j(2)) .eq. 0)
then
1887 do k1 = children(1, j(1)), children(2, j(1))
1893 do k1 = children(1, j(1)), children(2, j(1))
1894 do k2 = children(1, j(2)), children(2, j(2))
1907 if (work(3, iwork) .eq. 1)
then
1908 nfar(work(1, iwork)) = nfar(work(1, iwork)) + 1
1909 else if (work(3, iwork) .eq. 2)
then
1910 nnear(work(1, iwork)) = nnear(work(1, iwork)) + 1
1921 & nnnear, nnear, snear, near)
1935 integer,
intent(in) :: jwork, lwork, work(3, lwork), n, nnfar, nnnear
1936 integer,
intent(in) :: nfar(n), nnear(n)
1937 integer,
intent(out) :: sfar(n+1), far(nnfar), snear(n+1), near(nnnear)
1939 integer,
allocatable :: cfar(:), cnear(:)
1941 allocate(cfar(n+1), cnear(n+1))
1945 sfar(i) = sfar(i-1) + nfar(i-1)
1946 snear(i) = snear(i-1) + nnear(i-1)
1951 if (work(3, i) .eq. 1)
then
1954 if ((j .gt. n) .or. (j .le. 0))
then
1955 write(*,*)
"ALARM", j
1957 far(cfar(j)) = work(2, i)
1958 cfar(j) = cfar(j) + 1
1959 else if (work(3, i) .eq. 2)
then
1962 if ((j .gt. n) .or. (j .le. 0))
then
1963 write(*,*)
"ALARM", j
1965 near(cnear(j)) = work(2, i)
1966 cnear(j) = cnear(j) + 1
1970 deallocate(cfar, cnear)
1982 type(ddx_error_type),
intent(inout) :: ddx_error
1987 if (
allocated(constants % vscales))
then
1988 deallocate(constants % vscales, stat=istat)
1989 if (istat .ne. 0)
then
1990 call update_error(ddx_error,
"`vscales` deallocation failed!")
1993 if (
allocated(constants % v4pi2lp1))
then
1994 deallocate(constants % v4pi2lp1, stat=istat)
1995 if (istat .ne. 0)
then
1996 call update_error(ddx_error,
"`v4pi2lp1` deallocation failed!")
1999 if (
allocated(constants % vscales_rel))
then
2000 deallocate(constants % vscales_rel, stat=istat)
2001 if (istat .ne. 0)
then
2002 call update_error(ddx_error,
"`vscales_rel` deallocation failed!")
2005 if (
allocated(constants % vfact))
then
2006 deallocate(constants % vfact, stat=istat)
2007 if (istat .ne. 0)
then
2008 call update_error(ddx_error,
"`vfact` deallocation failed!")
2011 if (
allocated(constants % vcnk))
then
2012 deallocate(constants % vcnk, stat=istat)
2013 if (istat .ne. 0)
then
2014 call update_error(ddx_error,
"`vcnk` deallocation failed!")
2017 if (
allocated(constants % m2l_ztranslate_coef))
then
2018 deallocate(constants % m2l_ztranslate_coef, stat=istat)
2019 if (istat .ne. 0)
then
2020 call update_error(ddx_error, &
2021 &
"`m2l_ztranslate_coef` deallocation failed!")
2024 if (
allocated(constants % m2l_ztranslate_adj_coef))
then
2025 deallocate(constants % m2l_ztranslate_adj_coef, stat=istat)
2026 if (istat .ne. 0)
then
2027 call update_error(ddx_error, &
2028 &
"`m2l_ztranslate_adj_coef` deallocation failed!")
2031 if (
allocated(constants % cgrid))
then
2032 deallocate(constants % cgrid, stat=istat)
2033 if (istat .ne. 0)
then
2034 call update_error(ddx_error,
"`cgrid` deallocation failed!")
2037 if (
allocated(constants % wgrid))
then
2038 deallocate(constants % wgrid, stat=istat)
2039 if (istat .ne. 0)
then
2040 call update_error(ddx_error,
"`wgrid` deallocation failed!")
2043 if (
allocated(constants % vgrid))
then
2044 deallocate(constants % vgrid, stat=istat)
2045 if (istat .ne. 0)
then
2046 call update_error(ddx_error,
"`vgrid` deallocation failed!")
2049 if (
allocated(constants % vwgrid))
then
2050 deallocate(constants % vwgrid, stat=istat)
2051 if (istat .ne. 0)
then
2052 call update_error(ddx_error,
"`vwgrid` deallocation failed!")
2055 if (
allocated(constants % vgrid2))
then
2056 deallocate(constants % vgrid2, stat=istat)
2057 if (istat .ne. 0)
then
2058 call update_error(ddx_error,
"`vgrid2` deallocation failed!")
2061 if (
allocated(constants % pchi))
then
2062 deallocate(constants % pchi, stat=istat)
2063 if (istat .ne. 0)
then
2064 call update_error(ddx_error,
"`pchi` deallocation failed!")
2067 if (
allocated(constants % c_ik))
then
2068 deallocate(constants % c_ik, stat=istat)
2069 if (istat .ne. 0)
then
2070 call update_error(ddx_error,
"`c_ik` deallocation failed!")
2073 if (
allocated(constants % si_ri))
then
2074 deallocate(constants % si_ri, stat=istat)
2075 if (istat .ne. 0)
then
2076 call update_error(ddx_error,
"`si_ri` deallocation failed!")
2079 if (
allocated(constants % di_ri))
then
2080 deallocate(constants % di_ri, stat=istat)
2081 if (istat .ne. 0)
then
2082 call update_error(ddx_error,
"`di_ri` deallocation failed!")
2085 if (
allocated(constants % sk_ri))
then
2086 deallocate(constants % sk_ri, stat=istat)
2087 if (istat .ne. 0)
then
2088 call update_error(ddx_error,
"`sk_ri` deallocation failed!")
2091 if (
allocated(constants % dk_ri))
then
2092 deallocate(constants % dk_ri, stat=istat)
2093 if (istat .ne. 0)
then
2094 call update_error(ddx_error,
"`dk_ri` deallocation failed!")
2097 if (
allocated(constants % termimat))
then
2098 deallocate(constants % termimat, stat=istat)
2099 if (istat .ne. 0)
then
2100 call update_error(ddx_error,
"`termimat` deallocation failed!")
2103 if (
allocated(constants % b))
then
2104 deallocate(constants % b, stat=istat)
2105 if (istat .ne. 0)
then
2106 call update_error(ddx_error,
"`b` deallocation failed!")
2109 if (
allocated(constants % l))
then
2110 deallocate(constants % l, stat=istat)
2111 if (istat .ne. 0)
then
2112 call update_error(ddx_error,
"`l` deallocation failed!")
2115 if (
allocated(constants % inl))
then
2116 deallocate(constants % inl, stat=istat)
2117 if (istat .ne. 0)
then
2118 call update_error(ddx_error,
"`inl` deallocation failed!")
2121 if (
allocated(constants % nl))
then
2122 deallocate(constants % nl, stat=istat)
2123 if (istat .ne. 0)
then
2124 call update_error(ddx_error,
"`nl` deallocation failed!")
2127 if (
allocated(constants % itrnl))
then
2128 deallocate(constants % itrnl, stat=istat)
2129 if (istat .ne. 0)
then
2130 call update_error(ddx_error,
"`itrnl` deallocation failed!")
2133 if (
allocated(constants % fi))
then
2134 deallocate(constants % fi, stat=istat)
2135 if (istat .ne. 0)
then
2136 call update_error(ddx_error,
"`fi` deallocation failed!")
2139 if (
allocated(constants % ui))
then
2140 deallocate(constants % ui, stat=istat)
2141 if (istat .ne. 0)
then
2142 call update_error(ddx_error,
"`ui` deallocation failed!")
2145 if (
allocated(constants % ui_cav))
then
2146 deallocate(constants % ui_cav, stat=istat)
2147 if (istat .ne. 0)
then
2148 call update_error(ddx_error,
"`ui_cav` deallocation failed!")
2151 if (
allocated(constants % zi))
then
2152 deallocate(constants % zi, stat=istat)
2153 if (istat .ne. 0)
then
2154 call update_error(ddx_error,
"`zi` deallocation failed!")
2157 if (
allocated(constants % zi_dr))
then
2158 deallocate(constants % zi_dr, stat=istat)
2159 if (istat .ne. 0)
then
2160 call update_error(ddx_error,
"`zi_dr` deallocation failed!")
2163 if (
allocated(constants % ncav_sph))
then
2164 deallocate(constants % ncav_sph, stat=istat)
2165 if (istat .ne. 0)
then
2166 call update_error(ddx_error,
"`ncav_sph` deallocation failed!")
2169 if (
allocated(constants % ccav))
then
2170 deallocate(constants % ccav, stat=istat)
2171 if (istat .ne. 0)
then
2172 call update_error(ddx_error,
"`ccav` deallocation failed!")
2175 if (
allocated(constants % icav_ia))
then
2176 deallocate(constants % icav_ia, stat=istat)
2177 if (istat .ne. 0)
then
2178 call update_error(ddx_error,
"`icav_ia` deallocation failed!")
2181 if (
allocated(constants % icav_ja))
then
2182 deallocate(constants % icav_ja, stat=istat)
2183 if (istat .ne. 0)
then
2184 call update_error(ddx_error,
"`icav_ja` deallocation failed!")
2187 if (
allocated(constants % rx_prc))
then
2188 deallocate(constants % rx_prc, stat=istat)
2189 if (istat .ne. 0)
then
2190 call update_error(ddx_error,
"`rx_prc` deallocation failed!")
2193 if (
allocated(constants % order))
then
2194 deallocate(constants % order, stat=istat)
2195 if (istat .ne. 0)
then
2196 call update_error(ddx_error,
"`order` deallocation failed!")
2199 if (
allocated(constants % cluster))
then
2200 deallocate(constants % cluster, stat=istat)
2201 if (istat .ne. 0)
then
2202 call update_error(ddx_error,
"`cluster` deallocation failed!")
2205 if (
allocated(constants % children))
then
2206 deallocate(constants % children, stat=istat)
2207 if (istat .ne. 0)
then
2208 call update_error(ddx_error,
"`children` deallocation failed!")
2211 if (
allocated(constants % parent))
then
2212 deallocate(constants % parent, stat=istat)
2213 if (istat .ne. 0)
then
2214 call update_error(ddx_error,
"`parent` deallocation failed!")
2217 if (
allocated(constants % cnode))
then
2218 deallocate(constants % cnode, stat=istat)
2219 if (istat .ne. 0)
then
2220 call update_error(ddx_error,
"`cnode` deallocation failed!")
2223 if (
allocated(constants % rnode))
then
2224 deallocate(constants % rnode, stat=istat)
2225 if (istat .ne. 0)
then
2226 call update_error(ddx_error,
"`rnode` deallocation failed!")
2229 if (
allocated(constants % snode))
then
2230 deallocate(constants % snode, stat=istat)
2231 if (istat .ne. 0)
then
2232 call update_error(ddx_error,
"`snode` deallocation failed!")
2235 if (
allocated(constants % sk_rnode))
then
2236 deallocate(constants % sk_rnode, stat=istat)
2237 if (istat .ne. 0)
then
2238 call update_error(ddx_error,
"`sk_rnode` deallocation failed!")
2241 if (
allocated(constants % si_rnode))
then
2242 deallocate(constants % si_rnode, stat=istat)
2243 if (istat .ne. 0)
then
2244 call update_error(ddx_error,
"`si_rnode` deallocation failed!")
2247 if (
allocated(constants % nfar))
then
2248 deallocate(constants % nfar, stat=istat)
2249 if (istat .ne. 0)
then
2250 call update_error(ddx_error,
"`nfar` deallocation failed!")
2253 if (
allocated(constants % nnear))
then
2254 deallocate(constants % nnear, stat=istat)
2255 if (istat .ne. 0)
then
2256 call update_error(ddx_error,
"`nnear` deallocation failed!")
2259 if (
allocated(constants % far))
then
2260 deallocate(constants % far, stat=istat)
2261 if (istat .ne. 0)
then
2262 call update_error(ddx_error,
"`far` deallocation failed!")
2265 if (
allocated(constants % near))
then
2266 deallocate(constants % near, stat=istat)
2267 if (istat .ne. 0)
then
2268 call update_error(ddx_error,
"`near` deallocation failed!")
2271 if (
allocated(constants % sfar))
then
2272 deallocate(constants % sfar, stat=istat)
2273 if (istat .ne. 0)
then
2274 call update_error(ddx_error,
"`sfar` deallocation failed!")
2277 if (
allocated(constants % snear))
then
2278 deallocate(constants % snear, stat=istat)
2279 if (istat .ne. 0)
then
2280 call update_error(ddx_error,
"`snear` deallocation failed!")
2283 if (
allocated(constants % m2l_ztranslate_coef))
then
2284 deallocate(constants % m2l_ztranslate_coef, stat=istat)
2285 if (istat .ne. 0)
then
2286 call update_error(ddx_error,
"`m2l_ztranslate_coef` " // &
2287 &
"deallocation failed!")
2290 if (
allocated(constants % m2l_ztranslate_adj_coef))
then
2291 deallocate(constants % m2l_ztranslate_adj_coef, stat=istat)
2292 if (istat .ne. 0)
then
2293 call update_error(ddx_error,
"`m2l_ztranslate_adj_coef` " // &
2294 &
"deallocation failed!")
2298 call switching_free(constants%switching, ddx_error)
2302subroutine switching_init(params, constants, switching, ddx_error)
2306 type(ddx_error_type),
intent(inout) :: ddx_error
2307 integer :: info, isph, n, icav, ncav
2308 real(dp) :: d_ni, f_ni, u_ni
2310 allocate(switching%u_ni(params%ngrid, params%nsph), &
2311 & switching%d_ni(params%ngrid, params%nsph), &
2312 & switching%f_ni(params%ngrid, params%nsph), &
2315 call update_error(ddx_error, &
2316 &
"Allocation failed in switching_init")
2320 do isph = 1, params%nsph
2321 do n = 1, params%ngrid
2322 call compute_d_and_f(params, constants, isph, n, d_ni, f_ni)
2323 switching%d_ni(n, isph) = d_ni
2324 switching%f_ni(n, isph) = f_ni
2329 do isph = 1, params%nsph
2330 do n = 1, params%ngrid
2331 u_ni = compute_u(params, constants, isph, n)
2332 if (u_ni.ne.zero) ncav = ncav + 1
2335 switching%ncav = ncav
2337 allocate(switching%u_i_cav(switching%ncav), stat=info)
2339 call update_error(ddx_error, &
2340 &
"Allocation failed in switching_init")
2345 do isph = 1, params%nsph
2346 do n = 1, params%ngrid
2347 u_ni = compute_u(params, constants, isph, n)
2348 switching%u_ni(n, isph) = u_ni
2349 if (u_ni.ne.zero)
then
2351 switching%u_i_cav(icav) = u_ni
2356 if (params%force.eq.1)
then
2357 allocate(switching%grad_u_ni(3, params%ngrid, params%nsph), &
2358 & switching%dr_u_ni(params%ngrid, params%nsph), &
2361 call update_error(ddx_error, &
2362 &
"Allocation failed in switching_init")
2366 do isph = 1, params%nsph
2367 do n = 1, params%ngrid
2368 call compute_grad_i_u_i(params, constants, isph, n, &
2369 & switching%grad_u_ni(:, n, isph), &
2370 & switching%dr_u_ni(n, isph))
2375end subroutine switching_init
2377subroutine switching_free(switching, ddx_error)
2379 type(ddx_error_type),
intent(inout) :: ddx_error
2381 if (
allocated(switching%u_ni))
then
2382 deallocate(switching%u_ni, stat=info)
2384 call update_error(ddx_error, &
2385 &
"Deallocation failed in switching_free")
2389 if (
allocated(switching%u_i_cav))
then
2390 deallocate(switching%u_i_cav, stat=info)
2392 call update_error(ddx_error, &
2393 &
"Deallocation failed in switching_free")
2397 if (
allocated(switching%d_ni))
then
2398 deallocate(switching%d_ni, stat=info)
2400 call update_error(ddx_error, &
2401 &
"Deallocation failed in switching_free")
2405 if (
allocated(switching%f_ni))
then
2406 deallocate(switching%f_ni, stat=info)
2408 call update_error(ddx_error, &
2409 &
"Deallocation failed in switching_free")
2413 if (
allocated(switching%grad_u_ni))
then
2414 deallocate(switching%grad_u_ni, stat=info)
2416 call update_error(ddx_error, &
2417 &
"Deallocation failed in switching_free")
2421 if (
allocated(switching%dr_u_ni))
then
2422 deallocate(switching%dr_u_ni, stat=info)
2424 call update_error(ddx_error, &
2425 &
"Deallocation failed in switching_free")
2429end subroutine switching_free
2431real(dp) function compute_t(params, constants, isph, jsph, n)
2434 integer,
intent(in) :: isph, jsph, n
2435 associate(cgrid => constants%cgrid, rsph => params%rsph, &
2436 & csph => params%csph)
2437 compute_t = sqrt((cgrid(1,n)*rsph(isph) + csph(1,isph) &
2438 & - csph(1,jsph))**2 + (cgrid(2,n)*rsph(isph) &
2439 & + csph(2,isph) - csph(2,jsph))**2 &
2440 & + (cgrid(3,n)*rsph(isph) + csph(3,isph) &
2441 & - csph(3,jsph))**2)/rsph(jsph)
2443end function compute_t
2445real(dp) function compute_chi(params, constants, isph, jsph, n)
2446 type(ddx_params_type),
intent(in) :: params
2448 integer,
intent(in) :: isph, jsph, n
2450 t_ijn = compute_t(params, constants, isph, jsph, n)
2451 compute_chi =
fsw(t_ijn, params%se, params%eta)
2452end function compute_chi
2454subroutine compute_d_and_f(params, constants, isph, n, d, f)
2455 type(ddx_params_type),
intent(in) :: params
2457 integer,
intent(in) :: isph, n
2458 real(dp),
intent(out) :: d, f
2463 do ij = constants%inl(isph), constants%inl(isph + 1) - 1
2464 jsph = constants%nl(ij)
2465 chi_ijn = compute_chi(params, constants, isph, jsph, n)
2466 d = d*(one - chi_ijn)
2469end subroutine compute_d_and_f
2471real(dp) function compute_d(params, constants, isph, n)
2472 type(ddx_params_type),
intent(in) :: params
2474 integer,
intent(in) :: isph, n
2478 do ij = constants%inl(isph), constants%inl(isph + 1) - 1
2479 jsph = constants%nl(ij)
2480 chi_ijn = compute_chi(params, constants, isph, jsph, n)
2481 compute_d = compute_d*(one - chi_ijn)
2485real(dp) function compute_f(params, constants, isph, n)
2486 type(ddx_params_type),
intent(in) :: params
2488 integer,
intent(in) :: isph, n
2492 do ij = constants%inl(isph), constants%inl(isph + 1) - 1
2493 jsph = constants%nl(ij)
2494 compute_f = compute_f + compute_chi(params, constants, isph, jsph, n)
2496end function compute_f
2498real(dp) function compute_omega(params, constants, isph, jsph, n)
2499 type(ddx_params_type),
intent(in) :: params
2501 integer,
intent(in) :: isph, jsph, n
2502 real(dp) :: chi_nij, d_ni, f_ni
2504 chi_nij = compute_chi(params, constants, isph, jsph, n)
2505 d_ni = constants%switching%d_ni(n, isph)
2506 f_ni = constants%switching%f_ni(n, isph)
2507 compute_omega = chi_nij/(d_ni + f_ni)
2508end function compute_omega
2510real(dp) function compute_u(params, constants, isph, n)
2511 type(ddx_params_type),
intent(in) :: params
2513 integer,
intent(in) :: isph, n
2516 do ij = constants%inl(isph), constants%inl(isph + 1) - 1
2517 jsph = constants%nl(ij)
2518 compute_u = compute_u - compute_omega(params, constants, isph, jsph, n)
2523 if (abs(compute_u) .le. 1d-15) compute_u = zero
2524end function compute_u
2526subroutine compute_grad_i_u_i(params, constants, isph, n, grad, dr)
2527 type(ddx_params_type),
intent(in) :: params
2529 real(dp),
intent(out) :: grad(3), dr
2530 integer,
intent(in) :: isph, n
2532 real(dp) :: vij(3), vvij, tij, sij(3), grad_tij(3), dr_tij, &
2533 & d_i, f_i, chi_ij, a, b, c, grad_p
2537 d_i = constants%switching%d_ni(n, isph)
2538 f_i = constants%switching%f_ni(n, isph)
2539 a = one/(d_i + f_i)**2
2541 do ij = constants%inl(isph), constants%inl(isph + 1) - 1
2542 jsph = constants%nl(ij)
2543 vij = params % csph(:,isph) + &
2544 & params % rsph(isph)*constants % cgrid(:,n) - &
2545 & params % csph(:,jsph)
2546 vvij = sqrt(vij(1)*vij(1) + vij(2)*vij(2) + vij(3)*vij(3))
2547 tij = vvij/params % rsph(jsph)
2550 grad_tij(:) = sij(:)/params%rsph(jsph)
2551 dr_tij = dot_product(vij, constants%cgrid(:,n)) &
2552 & /(vvij*params%rsph(jsph))
2554 grad_p =
dfsw(tij, params % se, params % eta)
2555 chi_ij =
fsw(tij, params % se, params % eta)
2557 c = a*(d_i + b/(one - chi_ij))*grad_p
2559 grad(:) = grad(:) + c*grad_tij(:)
2563end subroutine compute_grad_i_u_i
subroutine build_itrnl(constants, params, ddx_error)
Build the transposed neighbor list.
subroutine build_b(constants, params, ddx_error)
Allocate and build the HSP sparse matrix, only if incore is set.
subroutine tree_get_farnear_work(n, children, cnode, rnode, lwork, iwork, jwork, work, nnfar, nfar, nnnear, nnear)
Find near and far admissible pairs of tree nodes and store it in work array.
subroutine neighbor_list_init(params, constants, ddx_error)
Build the neighbor list using a N^2 code.
subroutine mkprec(lmax, nbasis, nsph, ngrid, eps, ui, wgrid, vgrid, vgrid_nbasis, rx_prc, ddx_error)
Compute preconditioner assemble the diagonal blocks of the reps matrix then invert them to build the ...
subroutine build_l(constants, params, ddx_error)
Allocate and build the ddCOSMO sparse matrix, only if incore is set.
real(dp) function dfsw(t, se, eta)
Derivative of a switching function.
subroutine constants_init(params, constants, ddx_error)
Compute all necessary constants.
subroutine neighbor_list_init_fmm(params, constants, ddx_error)
Build the neighbor list using a linear scaling code (only if FMMs are enabled)
subroutine constants_geometry_init(params, constants, ddx_error)
Initialize geometry-related constants like list of neighbouring spheres.
subroutine constants_free(constants, ddx_error)
Deallocate the constants.
subroutine tree_rib_build(nsph, csph, rsph, order, cluster, children, parent, cnode, rnode, snode, ddx_error)
Build a recursive inertial binary tree.
real(dp) function fsw(t, se, eta)
Switching function.
subroutine tree_rib_node_bisect(nsph, csph, n, order, div, ddx_error)
Divide given cluster of spheres into two subclusters by inertial bisection.
subroutine mkpmat(params, constants, isph, pmat)
Computation of P_chi.
subroutine tree_get_farnear(jwork, lwork, work, n, nnfar, nfar, sfar, far, nnnear, nnear, snear, near)
Get near and far admissible pairs from work array of tree_get_farnear_work Works only for binary tree...
Harmonics-related core routines.
subroutine ylmscale(p, vscales, v4pi2lp1, vscales_rel)
Compute scaling factors of real normalized spherical harmonics.
subroutine ylmbas(x, rho, ctheta, stheta, cphi, sphi, p, vscales, vylm, vplm, vcos, vsin)
Compute all spherical harmonics up to a given degree at a given point.
subroutine fmm_constants(dmax, pm, pl, vcnk, m2l_ztranslate_coef, m2l_ztranslate_adj_coef)
Compute FMM-related constants.
Module to treat properly user input parameters.
Container for precomputed constants.
Type to check and store user input parameters.