40#include "../base/base_uses.f90"
46 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dgs'
54 MODULE PROCEDURE dg_sum_patch_coef, dg_sum_patch_arr
58 MODULE PROCEDURE dg_sum_patch_force_coef_3d, dg_sum_patch_force_arr_3d
62 MODULE PROCEDURE dg_sum_patch_force_coef_1d, dg_sum_patch_force_arr_1d
66 MODULE PROCEDURE dg_get_patch_1, dg_get_patch_2
69 INTERFACE dg_add_patch
70 MODULE PROCEDURE dg_add_patch_simple, dg_add_patch_folded
73 INTERFACE dg_int_patch_3d
74 MODULE PROCEDURE dg_int_patch_simple_3d, dg_int_patch_folded_3d
77 INTERFACE dg_int_patch_1d
78 MODULE PROCEDURE dg_int_patch_simple_1d, dg_int_patch_folded_1d
97 mp_comm, grid_ref, rs_dims, iounit, fft_usage)
99 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: b_cell_hmat
100 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s
101 REAL(kind=
dp),
INTENT(IN) :: cutoff_radius
106 INTEGER,
DIMENSION(2),
INTENT(in),
OPTIONAL :: rs_dims
107 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
108 LOGICAL,
INTENT(IN),
OPTIONAL :: fft_usage
110 INTEGER,
DIMENSION(2, 3) :: bounds_b, bounds_s
111 REAL(kind=
dp) :: cutoff, ecut
112 REAL(kind=
dp),
DIMENSION(3, 3) :: s_cell_hmat, unit_cell_hmat
114 CALL dg_find_cutoff(b_cell_hmat, npts_s, cutoff_radius, bounds_s, bounds_b, cutoff)
116 ecut = 0.5_dp*cutoff*cutoff
117 IF (
PRESENT(grid_ref))
THEN
118 CALL pw_grid_create(grid_b, mp_comm, b_cell_hmat, bounds=bounds_b, grid_span=
halfspace, cutoff=ecut, spherical=.true., &
119 ref_grid=grid_ref, rs_dims=rs_dims, iounit=iounit, fft_usage=fft_usage)
121 CALL pw_grid_create(grid_b, mp_comm, b_cell_hmat, bounds=bounds_b, grid_span=
halfspace, cutoff=ecut, spherical=.true., &
122 rs_dims=rs_dims, iounit=iounit, fft_usage=fft_usage)
125 CALL dg_find_basis(grid_b%npts, b_cell_hmat, unit_cell_hmat)
127 CALL dg_set_cell(bounds_s(2, :) - bounds_s(1, :) + 1, unit_cell_hmat, s_cell_hmat)
130 cutoff=ecut, iounit=iounit, fft_usage=fft_usage)
141 PURE FUNCTION get_cell_lengths(cell_hmat)
RESULT(abc)
142 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
143 REAL(kind=
dp),
DIMENSION(3) :: abc
145 abc(1) = sqrt(cell_hmat(1, 1)*cell_hmat(1, 1) + &
146 cell_hmat(2, 1)*cell_hmat(2, 1) + &
147 cell_hmat(3, 1)*cell_hmat(3, 1))
148 abc(2) = sqrt(cell_hmat(1, 2)*cell_hmat(1, 2) + &
149 cell_hmat(2, 2)*cell_hmat(2, 2) + &
150 cell_hmat(3, 2)*cell_hmat(3, 2))
151 abc(3) = sqrt(cell_hmat(1, 3)*cell_hmat(1, 3) + &
152 cell_hmat(2, 3)*cell_hmat(2, 3) + &
153 cell_hmat(3, 3)*cell_hmat(3, 3))
154 END FUNCTION get_cell_lengths
165 SUBROUTINE dg_find_cutoff(b_cell_hmat, npts_s, cutoff_radius, &
166 bounds_s, bounds_b, cutoff)
168 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: b_cell_hmat
169 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s
170 REAL(kind=
dp),
INTENT(IN) :: cutoff_radius
171 INTEGER,
DIMENSION(2, 3),
INTENT(OUT) :: bounds_s, bounds_b
172 REAL(kind=
dp),
INTENT(OUT) :: cutoff
174 INTEGER,
DIMENSION(3) :: nout, npts_b
175 REAL(kind=
dp) :: b_cell_deth, cell_lengths(3), dr(3)
176 REAL(kind=
dp),
DIMENSION(3, 3) :: b_cell_h_inv
178 b_cell_deth = abs(
det_3x3(b_cell_hmat))
179 IF (b_cell_deth < 1.0e-10_dp)
THEN
180 CALL cp_abort(__location__, &
181 "An invalid set of cell vectors was specified. "// &
182 "The determinant det(h) is too small")
184 b_cell_h_inv =
inv_3x3(b_cell_hmat)
193 cell_lengths = get_cell_lengths(b_cell_hmat)
195 CALL dg_get_spacing(nout, cutoff_radius, dr)
196 CALL dg_find_radix(dr, cell_lengths, npts_b)
199 IF (nout(1) > npts_b(1))
THEN
201 dr(1) = cell_lengths(1)/real(nout(1), kind=
dp)
203 IF (nout(2) > npts_b(2))
THEN
205 dr(2) = cell_lengths(2)/real(nout(2), kind=
dp)
207 IF (nout(3) > npts_b(3))
THEN
209 dr(3) = cell_lengths(3)/real(nout(3), kind=
dp)
213 bounds_b(1, :) = -npts_b/2
214 bounds_b(2, :) = +(npts_b - 1)/2
216 bounds_s(1, :) = -nout(:)/2
217 bounds_s(2, :) = (+nout(:) - 1)/2
221 END SUBROUTINE dg_find_cutoff
229 SUBROUTINE dg_get_spacing(npts, cutoff_radius, dr)
231 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
232 REAL(kind=
dp),
INTENT(IN) :: cutoff_radius
233 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: dr
235 dr(:) = cutoff_radius/(real(npts(:), kind=
dp)/2.0_dp)
237 END SUBROUTINE dg_get_spacing
246 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: b_cell_hmat
249 REAL(kind=
dp),
DIMENSION(3, 3) :: s_cell_hmat, unit_cell_hmat
251 CALL dg_find_basis(grid_b%npts, b_cell_hmat, unit_cell_hmat)
252 CALL dg_set_cell(grid_s%npts, unit_cell_hmat, s_cell_hmat)
262 SUBROUTINE dg_find_radix(dr, cell_lengths, npts)
264 REAL(kind=
dp),
INTENT(INOUT) :: dr(3)
265 REAL(kind=
dp),
INTENT(IN) :: cell_lengths(3)
266 INTEGER,
DIMENSION(:),
INTENT(OUT) :: npts
268 INTEGER,
DIMENSION(3) :: nin
270 nin(:) = nint(cell_lengths(:)/dr(:))
277 dr(:) = cell_lengths(:)/real(npts(:), kind=
dp)
279 END SUBROUTINE dg_find_radix
287 PURE SUBROUTINE dg_find_basis(npts, cell_hmat, unit_cell_hmat)
288 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
289 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
290 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: unit_cell_hmat
295 unit_cell_hmat(:, i) = cell_hmat(:, i)/real(npts(:), kind=
dp)
298 END SUBROUTINE dg_find_basis
308 PURE SUBROUTINE dg_set_cell(npts, unit_cell_hmat, cell_hmat)
309 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
310 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: unit_cell_hmat
311 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: cell_hmat
315 cell_hmat(:, 1) = unit_cell_hmat(:, 1)*npts(1)
316 cell_hmat(:, 2) = unit_cell_hmat(:, 2)*npts(2)
317 cell_hmat(:, 3) = unit_cell_hmat(:, 3)*npts(3)
319 END SUBROUTINE dg_set_cell
334 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
335 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: r
336 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s, npts_b
337 INTEGER,
INTENT(OUT) :: centre(3)
338 INTEGER,
INTENT(IN) :: lb(3)
339 COMPLEX(KIND=dp),
DIMENSION(lb(1):),
INTENT(OUT) :: ex
340 COMPLEX(KIND=dp),
DIMENSION(lb(2):),
INTENT(OUT) :: ey
341 COMPLEX(KIND=dp),
DIMENSION(lb(3):),
INTENT(OUT) :: ez
343 REAL(kind=
dp) :: delta(3)
345 CALL dg_get_delta(cell_hmat, r, npts_s, npts_b, centre, delta)
360 SUBROUTINE dg_get_delta(cell_hmat, r, npts_s, npts_b, centre, delta)
361 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
362 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: r
363 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s, npts_b
364 INTEGER,
DIMENSION(:),
INTENT(OUT) :: centre
365 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: delta
367 REAL(kind=
dp) :: cell_deth
368 REAL(kind=
dp),
DIMENSION(3) :: grid_i, s
369 REAL(kind=
dp),
DIMENSION(3, 3) :: cell_h_inv
371 cell_deth = abs(
det_3x3(cell_hmat))
372 IF (cell_deth < 1.0e-10_dp)
THEN
373 CALL cp_abort(__location__, &
374 "An invalid set of cell vectors was specified. "// &
375 "The determinant det(h) is too small")
378 cell_h_inv =
inv_3x3(cell_hmat)
381 s = matmul(cell_h_inv, r)
385 grid_i(1:3) = real(npts_b(1:3), kind=
dp)*s(1:3)
388 centre(:) = nint(grid_i(:))
391 delta(:) = (grid_i(:) - centre(:))/real(npts_s(:), kind=
dp)
393 centre(:) = centre(:) + npts_b(:)/2
394 centre(:) =
modulo(centre(:), npts_b(:))
395 centre(:) = centre(:) - npts_b(:)/2
397 END SUBROUTINE dg_get_delta
405 PURE SUBROUTINE dg_sum_patch_coef(rs, rhos, center)
409 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
412 INTEGER,
DIMENSION(3) :: nc
417 DO i = rhos%pw_grid%bounds(1, 1), rhos%pw_grid%bounds(2, 1)
418 ia = i - rhos%pw_grid%bounds(1, 1) + 1
419 ii = center(1) + i - rs%lb_local(1)
421 rs%px(ia) = ii + rs%npts_local(1) + 1
423 ELSEIF (ii >= rs%npts_local(1))
THEN
424 rs%px(ia) = ii - rs%npts_local(1) + 1
430 DO i = rhos%pw_grid%bounds(1, 2), rhos%pw_grid%bounds(2, 2)
431 ia = i - rhos%pw_grid%bounds(1, 2) + 1
432 ii = center(2) + i - rs%lb_local(2)
434 rs%py(ia) = ii + rs%npts_local(2) + 1
436 ELSEIF (ii >= rs%npts_local(2))
THEN
437 rs%py(ia) = ii - rs%npts_local(2) + 1
443 DO i = rhos%pw_grid%bounds(1, 3), rhos%pw_grid%bounds(2, 3)
444 ia = i - rhos%pw_grid%bounds(1, 3) + 1
445 ii = center(3) + i - rs%lb_local(3)
447 rs%pz(ia) = ii + rs%npts_local(3) + 1
449 ELSEIF (ii >= rs%npts_local(3))
THEN
450 rs%pz(ia) = ii - rs%npts_local(3) + 1
458 CALL dg_add_patch(rs%r, rhos%array, rhos%pw_grid%npts, &
464 CALL dg_add_patch(rs%r, rhos%array, rhos%pw_grid%npts, nc)
467 END SUBROUTINE dg_sum_patch_coef
475 PURE SUBROUTINE dg_sum_patch_arr(rs, rhos, center)
478 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rhos
479 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
482 INTEGER,
DIMENSION(3) :: lb, nc, ns, ub
485 ns(1) =
SIZE(rhos, 1)
486 ns(2) =
SIZE(rhos, 2)
487 ns(3) =
SIZE(rhos, 3)
494 ii = center(1) + i - rs%lb_local(1)
496 rs%px(ia) = ii + rs%npts_local(1) + 1
498 ELSEIF (ii >= rs%npts_local(1))
THEN
499 rs%px(ia) = ii - rs%npts_local(1) + 1
507 ii = center(2) + i - rs%lb_local(2)
509 rs%py(ia) = ii + rs%npts_local(2) + 1
511 ELSEIF (ii >= rs%npts_local(2))
THEN
512 rs%py(ia) = ii - rs%npts_local(2) + 1
520 ii = center(3) + i - rs%lb_local(3)
522 rs%pz(ia) = ii + rs%npts_local(3) + 1
524 ELSEIF (ii >= rs%npts_local(3))
THEN
525 rs%pz(ia) = ii - rs%npts_local(3) + 1
533 CALL dg_add_patch(rs%r, rhos, ns, rs%px, rs%py, rs%pz)
538 CALL dg_add_patch(rs%r, rhos, ns, nc)
541 END SUBROUTINE dg_sum_patch_arr
550 PURE SUBROUTINE dg_sum_patch_force_arr_3d(drpot, rhos, center, force)
553 INTENT(INOUT) :: drpot
554 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rhos
555 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
556 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: force
559 INTEGER,
DIMENSION(3) :: lb, nc, ns, ub
562 ns(1) =
SIZE(rhos, 1)
563 ns(2) =
SIZE(rhos, 2)
564 ns(3) =
SIZE(rhos, 3)
571 ii = center(1) + i - drpot(1)%lb_local(1)
573 drpot(1)%px(ia) = ii + drpot(1)%npts_local(1) + 1
575 ELSEIF (ii >= drpot(1)%npts_local(1))
THEN
576 drpot(1)%px(ia) = ii - drpot(1)%npts_local(1) + 1
579 drpot(1)%px(ia) = ii + 1
584 ii = center(2) + i - drpot(1)%lb_local(2)
586 drpot(1)%py(ia) = ii + drpot(1)%npts_local(2) + 1
588 ELSEIF (ii >= drpot(1)%npts_local(2))
THEN
589 drpot(1)%py(ia) = ii - drpot(1)%npts_local(2) + 1
592 drpot(1)%py(ia) = ii + 1
597 ii = center(3) + i - drpot(1)%lb_local(3)
599 drpot(1)%pz(ia) = ii + drpot(1)%npts_local(3) + 1
601 ELSEIF (ii >= drpot(1)%npts_local(3))
THEN
602 drpot(1)%pz(ia) = ii - drpot(1)%npts_local(3) + 1
605 drpot(1)%pz(ia) = ii + 1
610 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
611 drpot(3)%r, rhos, force, ns, &
612 drpot(1)%px, drpot(1)%py, drpot(1)%pz)
614 nc(1) = drpot(1)%px(1) - 1
615 nc(2) = drpot(1)%py(1) - 1
616 nc(3) = drpot(1)%pz(1) - 1
617 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
618 drpot(3)%r, rhos, force, ns, nc)
621 END SUBROUTINE dg_sum_patch_force_arr_3d
630 PURE SUBROUTINE dg_sum_patch_force_arr_1d(drpot, rhos, center, force)
633 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rhos
634 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
635 REAL(kind=
dp),
INTENT(OUT) :: force
638 INTEGER,
DIMENSION(3) :: lb, nc, ns, ub
641 ns(1) =
SIZE(rhos, 1)
642 ns(2) =
SIZE(rhos, 2)
643 ns(3) =
SIZE(rhos, 3)
650 ii = center(1) + i - drpot%lb_local(1)
652 drpot%px(ia) = ii + drpot%npts_local(1) + 1
654 ELSEIF (ii >= drpot%desc%npts(1))
THEN
655 drpot%px(ia) = ii - drpot%npts_local(1) + 1
658 drpot%px(ia) = ii + 1
663 ii = center(2) + i - drpot%lb_local(2)
665 drpot%py(ia) = ii + drpot%npts_local(2) + 1
667 ELSEIF (ii >= drpot%desc%npts(2))
THEN
668 drpot%py(ia) = ii - drpot%npts_local(2) + 1
671 drpot%py(ia) = ii + 1
676 ii = center(3) + i - drpot%lb_local(3)
678 drpot%pz(ia) = ii + drpot%npts_local(3) + 1
680 ELSEIF (ii >= drpot%desc%npts(3))
THEN
681 drpot%pz(ia) = ii - drpot%npts_local(3) + 1
684 drpot%pz(ia) = ii + 1
689 CALL dg_int_patch_1d(drpot%r, rhos, force, ns, &
690 drpot%px, drpot%py, drpot%pz)
692 nc(1) = drpot%px(1) - 1
693 nc(2) = drpot%py(1) - 1
694 nc(3) = drpot%pz(1) - 1
695 CALL dg_int_patch_1d(drpot%r, rhos, force, ns, nc)
698 END SUBROUTINE dg_sum_patch_force_arr_1d
707 PURE SUBROUTINE dg_sum_patch_force_coef_3d(drpot, rhos, center, force)
710 INTENT(INOUT) :: drpot
712 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
713 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: force
716 INTEGER,
DIMENSION(3) :: nc
721 DO i = rhos%pw_grid%bounds(1, 1), rhos%pw_grid%bounds(2, 1)
722 ia = i - rhos%pw_grid%bounds(1, 1) + 1
723 ii = center(1) + i - drpot(1)%lb_local(1)
725 drpot(1)%px(ia) = ii + drpot(1)%desc%npts(1) + 1
727 ELSEIF (ii >= drpot(1)%desc%npts(1))
THEN
728 drpot(1)%px(ia) = ii - drpot(1)%desc%npts(1) + 1
731 drpot(1)%px(ia) = ii + 1
734 DO i = rhos%pw_grid%bounds(1, 2), rhos%pw_grid%bounds(2, 2)
735 ia = i - rhos%pw_grid%bounds(1, 2) + 1
736 ii = center(2) + i - drpot(1)%lb_local(2)
738 drpot(1)%py(ia) = ii + drpot(1)%desc%npts(2) + 1
740 ELSEIF (ii >= drpot(1)%desc%npts(2))
THEN
741 drpot(1)%py(ia) = ii - drpot(1)%desc%npts(2) + 1
744 drpot(1)%py(ia) = ii + 1
747 DO i = rhos%pw_grid%bounds(1, 3), rhos%pw_grid%bounds(2, 3)
748 ia = i - rhos%pw_grid%bounds(1, 3) + 1
749 ii = center(3) + i - drpot(1)%lb_local(3)
751 drpot(1)%pz(ia) = ii + drpot(1)%desc%npts(3) + 1
753 ELSEIF (ii >= drpot(1)%desc%npts(3))
THEN
754 drpot(1)%pz(ia) = ii - drpot(1)%desc%npts(3) + 1
757 drpot(1)%pz(ia) = ii + 1
762 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
763 drpot(3)%r, rhos%array, force, rhos%pw_grid%npts, &
764 drpot(1)%px, drpot(1)%py, drpot(1)%pz)
766 nc(1) = drpot(1)%px(1) - 1
767 nc(2) = drpot(1)%py(1) - 1
768 nc(3) = drpot(1)%pz(1) - 1
769 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
770 drpot(3)%r, rhos%array, force, rhos%pw_grid%npts, nc)
773 END SUBROUTINE dg_sum_patch_force_coef_3d
782 PURE SUBROUTINE dg_sum_patch_force_coef_1d(drpot, rhos, center, force)
786 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
787 REAL(kind=
dp),
INTENT(OUT) :: force
790 INTEGER,
DIMENSION(3) :: nc
795 DO i = rhos%pw_grid%bounds(1, 1), rhos%pw_grid%bounds(2, 1)
796 ia = i - rhos%pw_grid%bounds(1, 1) + 1
797 ii = center(1) + i - drpot%lb_local(1)
799 drpot%px(ia) = ii + drpot%desc%npts(1) + 1
801 ELSEIF (ii >= drpot%desc%npts(1))
THEN
802 drpot%px(ia) = ii - drpot%desc%npts(1) + 1
805 drpot%px(ia) = ii + 1
808 DO i = rhos%pw_grid%bounds(1, 2), rhos%pw_grid%bounds(2, 2)
809 ia = i - rhos%pw_grid%bounds(1, 2) + 1
810 ii = center(2) + i - drpot%lb_local(2)
812 drpot%py(ia) = ii + drpot%desc%npts(2) + 1
814 ELSEIF (ii >= drpot%desc%npts(2))
THEN
815 drpot%py(ia) = ii - drpot%desc%npts(2) + 1
818 drpot%py(ia) = ii + 1
821 DO i = rhos%pw_grid%bounds(1, 3), rhos%pw_grid%bounds(2, 3)
822 ia = i - rhos%pw_grid%bounds(1, 3) + 1
823 ii = center(3) + i - drpot%lb_local(3)
825 drpot%pz(ia) = ii + drpot%desc%npts(3) + 1
827 ELSEIF (ii >= drpot%desc%npts(3))
THEN
828 drpot%pz(ia) = ii - drpot%desc%npts(3) + 1
831 drpot%pz(ia) = ii + 1
836 CALL dg_int_patch_1d(drpot%r, rhos%array, force, &
837 rhos%pw_grid%npts, drpot%px, drpot%py, drpot%pz)
839 nc(1) = drpot%px(1) - 1
840 nc(2) = drpot%py(1) - 1
841 nc(3) = drpot%pz(1) - 1
842 CALL dg_int_patch_1d(drpot%r, rhos%array, force, rhos%pw_grid%npts, nc)
845 END SUBROUTINE dg_sum_patch_force_coef_1d
856 SUBROUTINE dg_get_patch_1(rho0, rhos1, charge1, ex1, ey1, ez1)
860 REAL(KIND=
dp),
INTENT(IN) :: charge1
861 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(IN) :: ex1, ey1, ez1
863 COMPLEX(KIND=dp) :: za, zb
864 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: zs
868 nd = rhos1%pw_grid%npts
870 ALLOCATE (zs(nd(1)*nd(2)))
872 CALL cd%create(rho0%pw_grid)
876 zb = cmplx(charge1, 0.0_dp, kind=
dp)
877 CALL rankup(nd, za, cd%array, zb, ex1, ey1, ez1, zs)
885 END SUBROUTINE dg_get_patch_1
901 SUBROUTINE dg_get_patch_2(rho0, rhos1, rhos2, charge1, charge2, &
902 ex1, ey1, ez1, ex2, ey2, ez2)
906 REAL(KIND=
dp),
INTENT(IN) :: charge1, charge2
907 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(IN) :: ex1, ey1, ez1, ex2, ey2, ez2
909 COMPLEX(KIND=dp) :: za, zb
910 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: zs
914 nd = rhos1%pw_grid%npts
916 ALLOCATE (zs(nd(1)*nd(2)))
918 CALL cd%create(rhos1%pw_grid)
922 zb = cmplx(charge2, 0.0_dp, kind=
dp)
923 CALL rankup(nd, za, cd%array, zb, ex2, ey2, ez2, zs)
925 zb = cmplx(charge1, 0.0_dp, kind=
dp)
926 CALL rankup(nd, za, cd%array, zb, ex1, ey1, ez1, zs)
929 CALL copy_cri(cd%array, rhos1%array, rhos2%array)
934 END SUBROUTINE dg_get_patch_2
943 PURE SUBROUTINE dg_add_patch_simple(rb, rs, ns, nc)
945 REAL(KIND=
dp),
INTENT(INOUT) :: rb(:, :, :)
946 REAL(KIND=
dp),
INTENT(IN) :: rs(:, :, :)
947 INTEGER,
INTENT(IN) :: ns(3), nc(3)
949 INTEGER :: i, ii, j, jj, k, kk
957 rb(ii, jj, kk) = rb(ii, jj, kk) + rs(i, j, k)
962 END SUBROUTINE dg_add_patch_simple
973 PURE SUBROUTINE dg_add_patch_folded(rb, rs, ns, px, py, pz)
975 REAL(KIND=
dp),
INTENT(INOUT) :: rb(:, :, :)
976 REAL(KIND=
dp),
INTENT(IN) :: rs(:, :, :)
977 INTEGER,
INTENT(IN) :: ns(:)
978 INTEGER,
DIMENSION(:),
INTENT(IN) :: px, py, pz
980 INTEGER :: i, ii, j, jj, k, kk
988 rb(ii, jj, kk) = rb(ii, jj, kk) + rs(i, j, k)
993 END SUBROUTINE dg_add_patch_folded
1005 PURE SUBROUTINE dg_int_patch_simple_3d(rbx, rby, rbz, rs, f, ns, nc)
1007 REAL(KIND=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rbx, rby, rbz, rs
1008 REAL(KIND=
dp),
DIMENSION(3),
INTENT(OUT) :: f
1009 INTEGER,
INTENT(IN) :: ns(3), nc(3)
1011 INTEGER :: i, ii, j, jj, k, kk
1022 f(1) = f(1) + s*rbx(ii, jj, kk)
1023 f(2) = f(2) + s*rby(ii, jj, kk)
1024 f(3) = f(3) + s*rbz(ii, jj, kk)
1029 END SUBROUTINE dg_int_patch_simple_3d
1039 PURE SUBROUTINE dg_int_patch_simple_1d(rb, rs, f, ns, nc)
1041 REAL(KIND=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rb, rs
1042 REAL(KIND=
dp),
INTENT(OUT) :: f
1043 INTEGER,
INTENT(IN) :: ns(3), nc(3)
1045 INTEGER :: i, ii, j, jj, k, kk
1056 f = f + s*rb(ii, jj, kk)
1061 END SUBROUTINE dg_int_patch_simple_1d
1075 PURE SUBROUTINE dg_int_patch_folded_3d(rbx, rby, rbz, rs, f, ns, px, py, pz)
1077 REAL(KIND=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rbx, rby, rbz, rs
1078 REAL(KIND=
dp),
DIMENSION(3),
INTENT(INOUT) :: f
1079 INTEGER,
INTENT(IN) :: ns(3)
1080 INTEGER,
DIMENSION(:),
INTENT(IN) :: px, py, pz
1082 INTEGER :: i, ii, j, jj, k, kk
1093 f(1) = f(1) + s*rbx(ii, jj, kk)
1094 f(2) = f(2) + s*rby(ii, jj, kk)
1095 f(3) = f(3) + s*rbz(ii, jj, kk)
1100 END SUBROUTINE dg_int_patch_folded_3d
1112 PURE SUBROUTINE dg_int_patch_folded_1d(rb, rs, f, ns, px, py, pz)
1114 REAL(KIND=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rb, rs
1115 REAL(KIND=
dp),
INTENT(INOUT) :: f
1116 INTEGER,
INTENT(IN) :: ns(3)
1117 INTEGER,
DIMENSION(:),
INTENT(IN) :: px, py, pz
1119 INTEGER :: i, ii, j, jj, k, kk
1130 f = f + s*rb(ii, jj, kk)
1135 END SUBROUTINE dg_int_patch_folded_1d
1148 SUBROUTINE rankup(n, za, cmat, zb, ex, ey, ez, scr)
1153 INTEGER,
DIMENSION(3),
INTENT(IN) :: n
1154 COMPLEX(KIND=dp),
INTENT(IN) :: za
1155 COMPLEX(KIND=dp),
DIMENSION(:, :, :), &
1156 INTENT(INOUT) :: cmat
1157 COMPLEX(KIND=dp),
INTENT(IN) :: zb
1158 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(IN) :: ex, ey, ez
1159 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(INOUT) :: scr
1166 CALL zgeru(n(1), n(2), zb, ex, 1, ey, 1, scr, n(1))
1167 CALL zscal(n3, za, cmat, 1)
1168 CALL zgeru(n2, n(3),
z_one, scr, 1, ez, 1, cmat, n2)
1170 END SUBROUTINE rankup
1178 SUBROUTINE copy_cri(z, r1, r2)
1184 COMPLEX(KIND=dp),
INTENT(IN) :: z(:, :, :)
1185 REAL(KIND=
dp),
INTENT(INOUT) :: r1(:, :, :), r2(:, :, :)
1188 r1(:, :, :) = real(z(:, :, :), kind=
dp)
1189 r2(:, :, :) = aimag(z(:, :, :))
1192 END SUBROUTINE copy_cri
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
subroutine, public dg_pme_grid_setup(b_cell_hmat, npts_s, cutoff_radius, grid_s, grid_b, mp_comm, grid_ref, rs_dims, iounit, fft_usage)
...
subroutine, public dg_grid_change(b_cell_hmat, grid_b, grid_s)
...
subroutine, public dg_get_strucfac(cell_hmat, r, npts_s, npts_b, centre, lb, ex, ey, ez)
...
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
complex(kind=dp), parameter, public z_zero
Collection of simple mathematical functions and subroutines.
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
Interface to the message passing library MPI.
type(mp_comm_type), parameter, public mp_comm_self
This module returns additional info on PW grids.
real(kind=dp) function, public pw_find_cutoff(npts, h_inv)
Given a grid and a box, calculate the corresponding cutoff *** This routine calculates the cutoff in ...
integer, parameter, public halfspace
This module defines the grid data type and some basic operations on it.
subroutine, public pw_grid_change(cell_hmat, pw_grid)
Recalculate the g-vectors after a change of the box.
subroutine, public structure_factor_evaluate(delta, lb, ex, ey, ez)
...