34#include "./base/base_uses.f90"
38 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .false.
39 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_ddapc_methods'
62 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gfunc
63 REAL(kind=
dp),
DIMENSION(:),
POINTER :: w
64 REAL(kind=
dp),
INTENT(IN) :: gcut
66 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
68 CHARACTER(len=*),
PARAMETER :: routinen =
'ddapc_eval_gfunc'
70 INTEGER :: e_dim, handle, ig, igauss, s_dim
71 REAL(kind=
dp) :: g2, gcut2, rc, rc2
73 CALL timeset(routinen, handle)
76 s_dim = rho_tot_g%pw_grid%first_gne0
77 e_dim = rho_tot_g%pw_grid%ngpts_cut_local
78 ALLOCATE (gfunc(s_dim:e_dim,
SIZE(radii)))
79 ALLOCATE (w(s_dim:e_dim))
82 DO igauss = 1,
SIZE(radii)
86 g2 = rho_tot_g%pw_grid%gsq(ig)
88 gfunc(ig, igauss) = exp(-g2*rc2/4.0_dp)
92 g2 = rho_tot_g%pw_grid%gsq(ig)
94 w(ig) =
fourpi*(g2 - gcut2)**2/(g2*gcut2)
113 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: bv
114 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gfunc
115 REAL(kind=
dp),
DIMENSION(:),
POINTER :: w
117 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
119 REAL(kind=
dp),
INTENT(IN) :: gcut
121 CHARACTER(len=*),
PARAMETER :: routinen =
'build_b_vector'
123 COMPLEX(KIND=dp) :: phase
124 INTEGER :: e_dim, handle, idim, ig, igauss, igmax, &
126 REAL(kind=
dp) :: arg, g2, gcut2, gvec(3), rvec(3)
127 REAL(kind=
dp),
DIMENSION(:),
POINTER :: my_bv, my_bvw
129 CALL timeset(routinen, handle)
130 NULLIFY (my_bv, my_bvw)
132 s_dim = rho_tot_g%pw_grid%first_gne0
133 e_dim = rho_tot_g%pw_grid%ngpts_cut_local
136 g2 = rho_tot_g%pw_grid%gsq(ig)
140 IF (igmax >= s_dim)
THEN
141 ALLOCATE (my_bv(s_dim:igmax))
142 ALLOCATE (my_bvw(s_dim:igmax))
144 DO iparticle = 1,
SIZE(particle_set)
145 rvec = particle_set(iparticle)%r
148 gvec = rho_tot_g%pw_grid%g(:, ig)
149 arg = dot_product(gvec, rvec)
150 phase = cmplx(cos(arg), -sin(arg), kind=
dp)
151 my_bv(ig) = w(ig)*real(conjg(rho_tot_g%array(ig))*phase, kind=
dp)
153 DO igauss = 1,
SIZE(radii)
154 idim = (iparticle - 1)*
SIZE(radii) + igauss
156 my_bvw(ig) = my_bv(ig)*gfunc(ig, igauss)
164 DO iparticle = 1,
SIZE(particle_set)
165 DO igauss = 1,
SIZE(radii)
166 idim = (iparticle - 1)*
SIZE(radii) + igauss
171 CALL timestop(handle)
190 SUBROUTINE build_a_matrix(Am, gfunc, w, particle_set, radii, rho_tot_g, gcut, g_dot_rvec_sin, g_dot_rvec_cos)
191 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: am
192 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gfunc
193 REAL(kind=
dp),
DIMENSION(:),
POINTER :: w
195 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
197 REAL(kind=
dp),
INTENT(IN) :: gcut
198 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: g_dot_rvec_sin, g_dot_rvec_cos
200 CHARACTER(len=*),
PARAMETER :: routinen =
'build_A_matrix'
202 INTEGER :: e_dim, handle, idim1, idim2, ig, &
203 igauss1, igauss2, igmax, iparticle1, &
204 iparticle2, istart_g, s_dim
205 REAL(kind=
dp) :: g2, gcut2, tmp
206 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: my_am, my_amw
207 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: gfunc_sq(:, :, :)
211 CALL timeset(routinen, handle)
213 s_dim = rho_tot_g%pw_grid%first_gne0
214 e_dim = rho_tot_g%pw_grid%ngpts_cut_local
217 g2 = rho_tot_g%pw_grid%gsq(ig)
221 IF (igmax >= s_dim)
THEN
222 ALLOCATE (my_am(s_dim:igmax))
223 ALLOCATE (my_amw(s_dim:igmax))
224 ALLOCATE (gfunc_sq(s_dim:igmax,
SIZE(radii),
SIZE(radii)))
226 DO igauss1 = 1,
SIZE(radii)
227 DO igauss2 = 1,
SIZE(radii)
228 gfunc_sq(s_dim:igmax, igauss1, igauss2) = w(s_dim:igmax)*gfunc(s_dim:igmax, igauss1)*gfunc(s_dim:igmax, igauss2)
232 DO iparticle1 = 1,
SIZE(particle_set)
233 DO iparticle2 = iparticle1,
SIZE(particle_set)
236 my_am(ig) = (g_dot_rvec_cos(ig - s_dim + 1, iparticle1)*g_dot_rvec_cos(ig - s_dim + 1, iparticle2) + &
237 g_dot_rvec_sin(ig - s_dim + 1, iparticle1)*g_dot_rvec_sin(ig - s_dim + 1, iparticle2))
239 DO igauss1 = 1,
SIZE(radii)
240 idim1 = (iparticle1 - 1)*
SIZE(radii) + igauss1
242 IF (iparticle2 == iparticle1) istart_g = igauss1
243 DO igauss2 = istart_g,
SIZE(radii)
244 idim2 = (iparticle2 - 1)*
SIZE(radii) + igauss2
245 my_amw(s_dim:igmax) = my_am(s_dim:igmax)*gfunc_sq(s_dim:igmax, igauss1, igauss2)
249 am(idim2, idim1) = tmp
250 am(idim1, idim2) = tmp
255 DEALLOCATE (gfunc_sq)
259 CALL timestop(handle)
277 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: dbv
278 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gfunc
279 REAL(kind=
dp),
DIMENSION(:),
POINTER :: w
281 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: radii
283 REAL(kind=
dp),
INTENT(IN) :: gcut
284 INTEGER,
INTENT(IN) :: iparticle0
286 CHARACTER(len=*),
PARAMETER :: routinen =
'build_der_b_vector'
288 COMPLEX(KIND=dp) :: dphase
289 INTEGER :: e_dim, handle, idim, ig, igauss, igmax, &
291 REAL(kind=
dp) :: arg, g2, gcut2
292 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: my_dbvw
293 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: my_dbv
294 REAL(kind=
dp),
DIMENSION(3) :: gvec, rvec
296 CALL timeset(routinen, handle)
298 s_dim = rho_tot_g%pw_grid%first_gne0
299 e_dim = rho_tot_g%pw_grid%ngpts_cut_local
302 g2 = rho_tot_g%pw_grid%gsq(ig)
306 IF (igmax >= s_dim)
THEN
307 ALLOCATE (my_dbv(3, s_dim:igmax))
308 ALLOCATE (my_dbvw(s_dim:igmax))
309 DO iparticle = 1,
SIZE(particle_set)
310 IF (iparticle /= iparticle0) cycle
311 rvec = particle_set(iparticle)%r
313 gvec = rho_tot_g%pw_grid%g(:, ig)
314 arg = dot_product(gvec, rvec)
315 dphase = -cmplx(sin(arg), cos(arg), kind=
dp)
316 my_dbv(:, ig) = w(ig)*real(conjg(rho_tot_g%array(ig))*dphase, kind=
dp)*gvec(:)
318 DO igauss = 1,
SIZE(radii)
319 idim = (iparticle - 1)*
SIZE(radii) + igauss
321 my_dbvw(ig) = my_dbv(1, ig)*gfunc(ig, igauss)
325 my_dbvw(ig) = my_dbv(2, ig)*gfunc(ig, igauss)
329 my_dbvw(ig) = my_dbv(3, ig)*gfunc(ig, igauss)
337 DO iparticle = 1,
SIZE(particle_set)
338 IF (iparticle /= iparticle0) cycle
339 DO igauss = 1,
SIZE(radii)
340 idim = (iparticle - 1)*
SIZE(radii) + igauss
341 dbv(idim, 1:3) = 0.0_dp
345 CALL timestop(handle)
368 rho_tot_g, gcut, iparticle0, nparticles, g_dot_rvec_sin, g_dot_rvec_cos)
369 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT) :: dam
370 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gfunc
371 REAL(kind=
dp),
DIMENSION(:),
POINTER :: w
373 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
375 REAL(kind=
dp),
INTENT(IN) :: gcut
376 INTEGER,
INTENT(IN) :: iparticle0, nparticles
377 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: g_dot_rvec_sin, g_dot_rvec_cos
379 CHARACTER(len=*),
PARAMETER :: routinen =
'build_der_A_matrix_rows'
381 INTEGER :: e_dim, handle, ig, igauss2, igmax, &
382 iparticle1, iparticle2, s_dim
383 REAL(kind=
dp) :: g2, gcut2
389 REAL(kind=
dp),
ALLOCATABLE :: lhs(:, :), rhs(:, :)
390 INTEGER :: nr, np, ng, icomp, ipp
392 CALL timeset(routinen, handle)
394 s_dim = rho_tot_g%pw_grid%first_gne0
395 e_dim = rho_tot_g%pw_grid%ngpts_cut_local
398 g2 = rho_tot_g%pw_grid%gsq(ig)
404 np =
SIZE(particle_set)
405 ng = igmax - s_dim + 1
406 IF (igmax >= s_dim)
THEN
407 ALLOCATE (lhs(nparticles*nr, ng))
408 ALLOCATE (rhs(ng, np*nr))
412 DO iparticle2 = 1, np
414 rhs(1:ng, (iparticle2 - 1)*nr + igauss2) = g_dot_rvec_sin(1:ng, iparticle2)*gfunc(s_dim:igmax, igauss2)
419 DO ipp = 1, nparticles
420 iparticle1 = iparticle0 + ipp - 1
422 lhs((ipp - 1)*nr + 1:(ipp - 1)*nr + nr, ig - s_dim + 1) = w(ig)*rho_tot_g%pw_grid%g(icomp, ig)* &
423 gfunc(ig, 1:nr)*g_dot_rvec_cos(ig - s_dim + 1, iparticle1)
427 CALL dgemm(
'N',
'N', nparticles*nr, np*nr, ng, 1.0d0, lhs(1, 1), nparticles*nr, rhs(1, 1), &
428 ng, 0.0d0, dam((iparticle0 - 1)*nr + 1, 1, icomp), np*nr)
430 DO ipp = 1, nparticles
431 iparticle1 = iparticle0 + ipp - 1
432 CALL dgemm(
'N',
'N', nr, nr, ng, 1.0d0, lhs((ipp - 1)*nr + 1, 1), nparticles*nr, rhs(1, (iparticle1 - 1)*nr + 1), &
433 ng, 1.0d0, dam((iparticle1 - 1)*nr + 1, (iparticle1 - 1)*nr + 1, icomp), np*nr)
440 DO iparticle2 = 1, np
442 rhs(1:ng, (iparticle2 - 1)*nr + igauss2) = -g_dot_rvec_cos(1:ng, iparticle2)*gfunc(s_dim:igmax, igauss2)
447 DO ipp = 1, nparticles
448 iparticle1 = iparticle0 + ipp - 1
450 lhs((ipp - 1)*nr + 1:(ipp - 1)*nr + nr, ig - s_dim + 1) = w(ig)*rho_tot_g%pw_grid%g(icomp, ig)*gfunc(ig, 1:nr)* &
451 g_dot_rvec_sin(ig - s_dim + 1, iparticle1)
455 CALL dgemm(
'N',
'N', nparticles*nr, np*nr, ng, 1.0d0, lhs(1, 1), nparticles*nr, rhs(1, 1), &
456 ng, 1.0d0, dam((iparticle0 - 1)*nr + 1, 1, icomp), np*nr)
458 DO ipp = 1, nparticles
459 iparticle1 = iparticle0 + ipp - 1
460 CALL dgemm(
'N',
'N', nr, nr, ng, 1.0d0, lhs((ipp - 1)*nr + 1, 1), nparticles*nr, rhs(1, (iparticle1 - 1)*nr + 1), &
461 ng, 1.0d0, dam((iparticle1 - 1)*nr + 1, (iparticle1 - 1)*nr + 1, icomp), np*nr)
468 CALL timestop(handle)
477 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: g_dot_rvec_sin, g_dot_rvec_cos
479 IF (
ALLOCATED(g_dot_rvec_sin))
DEALLOCATE (g_dot_rvec_sin)
480 IF (
ALLOCATED(g_dot_rvec_cos))
DEALLOCATE (g_dot_rvec_cos)
494 REAL(kind=
dp),
INTENT(IN) :: gcut
495 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: g_dot_rvec_sin, g_dot_rvec_cos
497 INTEGER :: e_dim, ig, igmax, iparticle, s_dim
498 REAL(kind=
dp) :: g2, g_dot_rvec, gcut2, rvec(3)
501 s_dim = rho_tot_g%pw_grid%first_gne0
502 e_dim = rho_tot_g%pw_grid%ngpts_cut_local
505 g2 = rho_tot_g%pw_grid%gsq(ig)
510 IF (igmax >= s_dim)
THEN
511 ALLOCATE (g_dot_rvec_sin(1:igmax - s_dim + 1,
SIZE(particle_set)))
512 ALLOCATE (g_dot_rvec_cos(1:igmax - s_dim + 1,
SIZE(particle_set)))
514 DO iparticle = 1,
SIZE(particle_set)
515 rvec = particle_set(iparticle)%r
517 g_dot_rvec = dot_product(rho_tot_g%pw_grid%g(:, ig), rvec)
518 g_dot_rvec_sin(ig - s_dim + 1, iparticle) = sin(g_dot_rvec)
519 g_dot_rvec_cos(ig - s_dim + 1, iparticle) = cos(g_dot_rvec)
543 rho_tot_g, radii, iw, Vol)
544 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gami
545 REAL(kind=
dp),
INTENT(OUT) :: c0
546 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gfunc
547 REAL(kind=
dp),
DIMENSION(:),
POINTER :: w
549 REAL(kind=
dp),
INTENT(IN) :: gcut
551 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
552 INTEGER,
INTENT(IN) :: iw
553 REAL(kind=
dp),
INTENT(IN) :: vol
555 CHARACTER(len=*),
PARAMETER :: routinen =
'ddapc_eval_AmI'
557 INTEGER :: handle, ndim
558 REAL(kind=
dp) :: condition_number, inv_error
559 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ame, cv
560 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: am, ami, amw, g_dot_rvec_cos, &
565 CALL timeset(routinen, handle)
566 ndim =
SIZE(particle_set)*
SIZE(radii)
567 ALLOCATE (am(ndim, ndim))
568 ALLOCATE (ami(ndim, ndim))
569 ALLOCATE (gami(ndim, ndim))
576 CALL build_a_matrix(am, gfunc, w, particle_set, radii, rho_tot_g, gcut, g_dot_rvec_sin, g_dot_rvec_cos)
578 am(:, :) = am(:, :)/(vol*vol)
579 CALL rho_tot_g%pw_grid%para%group%sum(am)
582 ALLOCATE (amw(ndim, ndim))
586 condition_number = maxval(abs(ame))/minval(abs(ame))
587 WRITE (iw,
'(T3,A)')
" Eigenvalues of Matrix A:"
588 WRITE (iw,
'(T3,4E15.8)') ame
589 WRITE (iw,
'(T3,A,1E15.9)')
" Condition number:", condition_number
590 IF (condition_number > 1.0e12_dp)
THEN
591 WRITE (iw, fmt=
"(/,T2,A)") &
592 "WARNING: high condition number => possibly ill-conditioned matrix"
599 WRITE (iw,
'(T3,A,F15.9)')
" Error inverting the A matrix: ", inv_error
601 c0 = dot_product(cv, matmul(ami, cv))
606 CALL timestop(handle)
625 RECURSIVE SUBROUTINE ewald_ddapc_pot(cp_para_env, coeff, factor, cell, multipole_section, &
626 particle_set, M, radii)
629 REAL(kind=
dp),
INTENT(IN) :: factor
633 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: m
634 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
636 CHARACTER(len=*),
PARAMETER :: routinen =
'ewald_ddapc_pot'
638 INTEGER :: ewmdim, handle, iaxis, idim, idim1, idim2, idimo, igauss1, igauss2, ip1, ip2, &
639 iparticle1, iparticle2, istart_g, k1, k2, k3, n_rep, ndim, r1, r2, r3
640 INTEGER,
DIMENSION(3) :: gmax, image_cell, rmax, rmin
642 REAL(kind=
dp) :: alpha, eps, ew_neut,
fac, fac3, frac_radius, fs, g_ewald, galpha, gsq, &
643 gsqi, ij_fac, my_val, r, r2tmp, r_ewald, rc1, rc12, rc2, rc22, rcut, rcut2, t1, tol, tol1
644 REAL(kind=
dp),
DIMENSION(3) :: g_index, gvec, ra, rvec, svec
645 REAL(kind=
dp),
DIMENSION(:),
POINTER :: ewm
648 CALL timeset(routinen, handle)
649 cpassert(.NOT.
ASSOCIATED(m))
650 cpassert(
ASSOCIATED(radii))
651 rcut = min(norm2(cell%hmat(:, 1)), norm2(cell%hmat(:, 2)), norm2(cell%hmat(:, 3)))/2.0_dp
657 analyt = analyt .OR. .NOT. cell%orthorhombic .OR. .NOT.
ASSOCIATED(coeff)
662 eps = min(abs(eps), 0.5_dp)
663 tol = sqrt(abs(log(eps*rcut)))
664 alpha = sqrt(abs(log(eps*rcut*tol)))/rcut
665 galpha = 1.0_dp/(4.0_dp*alpha*alpha)
666 tol1 = sqrt(-log(eps*rcut*(2.0_dp*tol*alpha)**2))
667 IF (cell%orthorhombic)
THEN
669 gmax(iaxis) = nint(0.25_dp + cell%hmat(iaxis, iaxis)*alpha*tol1/
pi)
673 gmax(iaxis) = ceiling(alpha*tol1*norm2(cell%hmat(:, iaxis))/
pi)
676 fac = 1.e0_dp/cell%deth
678 ew_neut = -
fac*
pi/alpha**2
680 ewmdim =
SIZE(particle_set)*(
SIZE(particle_set) + 1)/2
681 ndim =
SIZE(particle_set)*
SIZE(radii)
682 ALLOCATE (ewm(ewmdim))
683 ALLOCATE (m(ndim, ndim))
688 DO iparticle1 = 1,
SIZE(particle_set)
689 ip1 = (iparticle1 - 1)*
SIZE(radii)
690 DO iparticle2 = 1, iparticle1
692 IF (iparticle1 == iparticle2) ij_fac = 0.5_dp
694 ip2 = (iparticle2 - 1)*
SIZE(radii)
697 IF (mod(iparticle1, cp_para_env%num_pe) /= cp_para_env%mepos) cycle
702 rvec = particle_set(iparticle1)%r - particle_set(iparticle2)%r
704 IF (iparticle1 /= iparticle2)
THEN
706 r2tmp = dot_product(ra, ra)
707 IF (r2tmp <= rcut2)
THEN
713 svec = matmul(cell%h_inv, rvec)
715 frac_radius = rcut*norm2(cell%h_inv(iaxis, :))
716 rmin(iaxis) = floor(-svec(iaxis) - frac_radius)
717 rmax(iaxis) = ceiling(-svec(iaxis) + frac_radius)
719 DO r1 = rmin(1), rmax(1)
720 DO r2 = rmin(2), rmax(2)
721 DO r3 = rmin(3), rmax(3)
722 IF ((r1 == 0) .AND. (r2 == 0) .AND. (r3 == 0)) cycle
723 image_cell = [r1, r2, r3]
724 ra = rvec + matmul(cell%hmat, real(image_cell, kind=
dp))
725 r2tmp = dot_product(ra, ra)
726 IF (r2tmp <= rcut2)
THEN
729 r_ewald = r_ewald + t1*ij_fac
740 DO k2 = -gmax(2), gmax(2)
741 DO k3 = -gmax(3), gmax(3)
742 IF (k1 == 0 .AND. k2 == 0 .AND. k3 == 0) cycle
743 fs = 2.0_dp;
IF (k1 == 0) fs = 1.0_dp
744 g_index = [real(k1, kind=
dp), real(k2, kind=
dp), real(k3, kind=
dp)]
745 gvec =
twopi*matmul(transpose(cell%h_inv), g_index)
746 gsq = dot_product(gvec, gvec)
748 t1 =
fac*gsqi*exp(-galpha*gsq)
749 g_ewald = g_ewald + t1*cos(dot_product(gvec, rvec))
759 g_ewald = r_ewald +
fourpi*g_ewald
763 IF (iparticle1 == iparticle2)
THEN
764 g_ewald = g_ewald - 2.0_dp*alpha*
oorootpi
767 IF (iparticle1 /= iparticle2)
THEN
769 r = sqrt(dot_product(ra, ra))
772 ewm(idim) = my_val - factor*g_ewald
776 CALL cp_para_env%sum(ewm)
778 DO iparticle2 = 1,
SIZE(particle_set)
779 ip2 = (iparticle2 - 1)*
SIZE(radii)
780 idimo = (iparticle2 - 1)
781 idimo = idimo*(idimo + 1)/2
782 DO igauss2 = 1,
SIZE(radii)
783 idim2 = ip2 + igauss2
786 DO iparticle1 = 1, iparticle2
787 ip1 = (iparticle1 - 1)*
SIZE(radii)
788 idim = idimo + iparticle1
790 IF (iparticle1 == iparticle2) istart_g = igauss2
791 DO igauss1 = istart_g,
SIZE(radii)
792 idim1 = ip1 + igauss1
795 m(idim1, idim2) = ewm(idim) - factor*ew_neut - factor*fac3*(rc12 + rc22)
796 m(idim2, idim1) = m(idim1, idim2)
802 CALL timestop(handle)
819 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: m
820 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii
822 INTEGER :: i, idim, idim1, idim2, igauss1, igauss2, ip1, ip2, iparticle1, iparticle2, &
823 istart_g, j, l, lmax, n_rep1, n_rep2, ndim, output_unit, weight
824 INTEGER,
DIMENSION(:),
POINTER ::
list
825 LOGICAL :: fixed_center
826 REAL(kind=
dp) :: center(3), eps_in, eps_out, factor, &
827 mass, mycos, r1, r2, rs, rvec(3)
828 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pos, r0
829 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: cost, locp
831 fixed_center = .false.
833 ndim =
SIZE(particle_set)*
SIZE(radii)
834 ALLOCATE (m(ndim, ndim))
841 IF (n_rep1 /= 0)
THEN
847 IF (n_rep2 /= 0)
THEN
855 r0 = r0 + particle_set(
list(i))%r
857 r0 = r0/real(
SIZE(
list), kind=
dp)
862 r0 = r0 + particle_set(
list(i))%r*particle_set(
list(i))%atomic_kind%mass
863 mass = mass + particle_set(
list(i))%atomic_kind%mass
869 IF (fixed_center)
THEN
877 cpassert(n_rep1 /= 0 .OR. n_rep2 /= 0)
879 ALLOCATE (locp(0:lmax,
SIZE(particle_set)))
880 ALLOCATE (pos(
SIZE(particle_set)))
881 ALLOCATE (cost(
SIZE(particle_set),
SIZE(particle_set)))
883 DO i = 1,
SIZE(particle_set)
884 rvec = particle_set(i)%r - center
885 r2 = dot_product(rvec, rvec)
888 IF (output_unit > 0)
THEN
889 WRITE (output_unit,
'(A,I6,A)')
"Atom number :: ", i,
" is out of the solvation sphere"
890 WRITE (output_unit,
'(2(A,F12.6))')
"Distance from the center::", r1,
" Radius of the sphere::", rs
895 IF (r1 /= 0.0_dp)
THEN
897 locp(l, i) = (r1**l*real(l + 1, kind=
dp)*(eps_in - eps_out))/ &
898 (rs**(2*l + 1)*eps_in*(real(l, kind=
dp)*eps_in + real(l + 1, kind=
dp)*eps_out))
902 locp(0, i) = (eps_in - eps_out)/(rs*eps_in*eps_out)
908 DO i = 1,
SIZE(particle_set)
911 IF (pos(i)*pos(j) /= 0.0_dp)
THEN
912 mycos = dot_product(particle_set(i)%r - center, particle_set(j)%r - center)/(pos(i)*pos(j))
913 IF (abs(mycos) > 1.0_dp) mycos = sign(1.0_dp, mycos)
915 factor = factor + locp(l, i)*pos(j)**l*
legendre(mycos, l, 0)
926 DO iparticle2 = 1,
SIZE(particle_set)
927 ip2 = (iparticle2 - 1)*
SIZE(radii)
928 DO igauss2 = 1,
SIZE(radii)
929 idim2 = ip2 + igauss2
930 DO iparticle1 = 1, iparticle2
931 ip1 = (iparticle1 - 1)*
SIZE(radii)
933 IF (iparticle1 == iparticle2) istart_g = igauss2
934 DO igauss1 = istart_g,
SIZE(radii)
935 idim1 = ip1 + igauss1
936 m(idim1, idim2) = cost(iparticle1, iparticle2)
937 m(idim2, idim1) = m(idim1, idim2)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Handles all functions related to the CELL.
contains information regarding the decoupling/recoupling method of Bloechl
subroutine, public cleanup_g_dot_rvec_sin_cos(g_dot_rvec_sin, g_dot_rvec_cos)
deallocate g_dot_rvec_* arrays
subroutine, public build_der_b_vector(dbv, gfunc, w, particle_set, radii, rho_tot_g, gcut, iparticle0)
Computes the derivative of B vector for the evaluation of the Pulay forces.
subroutine, public build_b_vector(bv, gfunc, w, particle_set, radii, rho_tot_g, gcut)
Computes the B vector for the solution of the linear system.
subroutine, public build_a_matrix(am, gfunc, w, particle_set, radii, rho_tot_g, gcut, g_dot_rvec_sin, g_dot_rvec_cos)
Computes the A matrix for the solution of the linear system.
subroutine, public solvation_ddapc_pot(solvation_section, particle_set, m, radii)
Evaluates the electrostatic potential due to a simple solvation model Spherical cavity in a dieletric...
subroutine, public prep_g_dot_rvec_sin_cos(rho_tot_g, particle_set, gcut, g_dot_rvec_sin, g_dot_rvec_cos)
precompute sin(g.r) and cos(g.r) for quicker evaluations of sin(g.(r1-r2)) and cos(g....
recursive subroutine, public ewald_ddapc_pot(cp_para_env, coeff, factor, cell, multipole_section, particle_set, m, radii)
Evaluates the Ewald term E2 and E3 energy term for the decoupling/coupling of periodic images.
subroutine, public ddapc_eval_ami(gami, c0, gfunc, w, particle_set, gcut, rho_tot_g, radii, iw, vol)
Computes the inverse AmI of the Am matrix.
subroutine, public build_der_a_matrix_rows(dam, gfunc, w, particle_set, radii, rho_tot_g, gcut, iparticle0, nparticles, g_dot_rvec_sin, g_dot_rvec_cos)
Computes the derivative of the A matrix for the evaluation of the Pulay forces.
subroutine, public ddapc_eval_gfunc(gfunc, w, gcut, rho_tot_g, radii)
...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Defines the basic variable types.
integer, parameter, public dp
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition of mathematical constants and functions.
real(kind=dp), parameter, public oorootpi
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public fourpi
real(kind=dp), parameter, public twopi
real(kind=dp), dimension(0:maxfac), parameter, public fac
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Interface to the message passing library MPI.
Define the data structure for the particle information.
different utils that are useful to manipulate splines on the regular grid of a pw
real(kind=dp) function, public eval_interp_spl3_pbc(vec, pw)
Evaluates the PBC interpolated Spline (pw) function on the generic input vector (vec)
Calculate spherical harmonics.
real(kind=dp) function, public legendre(x, l, m)
...
Type defining parameters related to the simulation cell.
stores all the informations relevant to an mpi environment