37 #include "../base/base_uses.f90"
43 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dgs'
45 PUBLIC :: dg_get_patch
47 dg_sum_patch, dg_sum_patch_force_3d, dg_sum_patch_force_1d, &
50 INTERFACE dg_sum_patch
51 MODULE PROCEDURE dg_sum_patch_coef, dg_sum_patch_arr
54 INTERFACE dg_sum_patch_force_3d
55 MODULE PROCEDURE dg_sum_patch_force_coef_3d, dg_sum_patch_force_arr_3d
58 INTERFACE dg_sum_patch_force_1d
59 MODULE PROCEDURE dg_sum_patch_force_coef_1d, dg_sum_patch_force_arr_1d
62 INTERFACE dg_get_patch
63 MODULE PROCEDURE dg_get_patch_1, dg_get_patch_2
66 INTERFACE dg_add_patch
67 MODULE PROCEDURE dg_add_patch_simple, dg_add_patch_folded
70 INTERFACE dg_int_patch_3d
71 MODULE PROCEDURE dg_int_patch_simple_3d, dg_int_patch_folded_3d
74 INTERFACE dg_int_patch_1d
75 MODULE PROCEDURE dg_int_patch_simple_1d, dg_int_patch_folded_1d
93 grid_ref, rs_dims, iounit, fft_usage)
95 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: b_cell_hmat
96 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s
97 REAL(kind=
dp),
INTENT(IN) :: cutoff_radius
98 TYPE(pw_grid_type),
POINTER :: grid_s, grid_b
99 TYPE(pw_grid_type),
INTENT(IN),
OPTIONAL :: grid_ref
100 INTEGER,
DIMENSION(2),
INTENT(in),
OPTIONAL :: rs_dims
101 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
102 LOGICAL,
INTENT(IN),
OPTIONAL :: fft_usage
104 INTEGER,
DIMENSION(2, 3) :: bo
105 REAL(kind=
dp) :: cutoff, ecut
106 REAL(kind=
dp),
DIMENSION(3, 3) :: s_cell_hmat, unit_cell_hmat
108 CALL dg_find_cutoff(b_cell_hmat, npts_s, cutoff_radius, grid_s, grid_b, cutoff)
110 ecut = 0.5_dp*cutoff*cutoff
112 IF (
PRESENT(grid_ref))
THEN
113 CALL pw_grid_setup(b_cell_hmat, grid_b, bounds=bo, cutoff=ecut, spherical=.true., &
114 ref_grid=grid_ref, rs_dims=rs_dims, iounit=iounit, fft_usage=fft_usage)
116 CALL pw_grid_setup(b_cell_hmat, grid_b, bounds=bo, cutoff=ecut, spherical=.true., &
117 rs_dims=rs_dims, iounit=iounit, fft_usage=fft_usage)
120 CALL dg_find_basis(grid_b%npts, b_cell_hmat, unit_cell_hmat)
122 CALL dg_set_cell(grid_s%npts, unit_cell_hmat, s_cell_hmat)
125 CALL pw_grid_setup(s_cell_hmat, grid_s, bounds=bo, cutoff=ecut, iounit=iounit, fft_usage=fft_usage)
136 PURE FUNCTION get_cell_lengths(cell_hmat)
RESULT(abc)
137 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
138 REAL(kind=
dp),
DIMENSION(3) :: abc
140 abc(1) = sqrt(cell_hmat(1, 1)*cell_hmat(1, 1) + &
141 cell_hmat(2, 1)*cell_hmat(2, 1) + &
142 cell_hmat(3, 1)*cell_hmat(3, 1))
143 abc(2) = sqrt(cell_hmat(1, 2)*cell_hmat(1, 2) + &
144 cell_hmat(2, 2)*cell_hmat(2, 2) + &
145 cell_hmat(3, 2)*cell_hmat(3, 2))
146 abc(3) = sqrt(cell_hmat(1, 3)*cell_hmat(1, 3) + &
147 cell_hmat(2, 3)*cell_hmat(2, 3) + &
148 cell_hmat(3, 3)*cell_hmat(3, 3))
149 END FUNCTION get_cell_lengths
160 SUBROUTINE dg_find_cutoff(b_cell_hmat, npts_s, cutoff_radius, grid_s, &
163 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: b_cell_hmat
164 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s
165 REAL(kind=
dp),
INTENT(IN) :: cutoff_radius
166 TYPE(pw_grid_type),
POINTER :: grid_s, grid_b
167 REAL(kind=
dp),
INTENT(OUT) :: cutoff
170 REAL(kind=
dp) :: b_cell_deth, cell_lengths(3), dr(3)
171 REAL(kind=
dp),
DIMENSION(3, 3) :: b_cell_h_inv
173 b_cell_deth = abs(
det_3x3(b_cell_hmat))
174 IF (b_cell_deth < 1.0e-10_dp)
THEN
175 CALL cp_abort(__location__, &
176 "An invalid set of cell vectors was specified. "// &
177 "The determinant det(h) is too small")
179 b_cell_h_inv =
inv_3x3(b_cell_hmat)
188 cell_lengths = get_cell_lengths(b_cell_hmat)
190 CALL dg_get_spacing(nout, cutoff_radius, dr)
191 CALL dg_find_radix(dr, cell_lengths, grid_b%npts)
194 IF (nout(1) > grid_b%npts(1))
THEN
195 grid_b%npts(1) = nout(1)
196 dr(1) = cell_lengths(1)/real(nout(1), kind=
dp)
198 IF (nout(2) > grid_b%npts(2))
THEN
199 grid_b%npts(2) = nout(2)
200 dr(2) = cell_lengths(2)/real(nout(2), kind=
dp)
202 IF (nout(3) > grid_b%npts(3))
THEN
203 grid_b%npts(3) = nout(3)
204 dr(3) = cell_lengths(3)/real(nout(3), kind=
dp)
208 grid_b%bounds(1, :) = -grid_b%npts/2
209 grid_b%bounds(2, :) = +(grid_b%npts - 1)/2
212 grid_s%bounds(1, :) = -nout(:)/2
213 grid_s%bounds(2, :) = (+nout(:) - 1)/2
219 END SUBROUTINE dg_find_cutoff
227 SUBROUTINE dg_get_spacing(npts, cutoff_radius, dr)
229 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
230 REAL(kind=
dp),
INTENT(IN) :: cutoff_radius
231 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: dr
233 dr(:) = cutoff_radius/(real(npts(:), kind=
dp)/2.0_dp)
235 END SUBROUTINE dg_get_spacing
244 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: b_cell_hmat
245 TYPE(pw_grid_type),
POINTER :: grid_b, grid_s
247 REAL(kind=
dp),
DIMENSION(3, 3) :: s_cell_hmat, unit_cell_hmat
249 CALL dg_find_basis(grid_b%npts, b_cell_hmat, unit_cell_hmat)
250 CALL dg_set_cell(grid_s%npts, unit_cell_hmat, s_cell_hmat)
260 SUBROUTINE dg_find_radix(dr, cell_lengths, npts)
262 REAL(kind=
dp),
INTENT(INOUT) :: dr(3)
263 REAL(kind=
dp),
INTENT(IN) :: cell_lengths(3)
264 INTEGER,
DIMENSION(:),
INTENT(OUT) :: npts
266 INTEGER,
DIMENSION(3) :: nin
268 nin(:) = nint(cell_lengths(:)/dr(:))
275 dr(:) = cell_lengths(:)/real(npts(:), kind=
dp)
277 END SUBROUTINE dg_find_radix
285 PURE SUBROUTINE dg_find_basis(npts, cell_hmat, unit_cell_hmat)
286 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
287 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
288 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: unit_cell_hmat
293 unit_cell_hmat(:, i) = cell_hmat(:, i)/real(npts(:), kind=
dp)
296 END SUBROUTINE dg_find_basis
306 PURE SUBROUTINE dg_set_cell(npts, unit_cell_hmat, cell_hmat)
307 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts
308 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: unit_cell_hmat
309 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: cell_hmat
313 cell_hmat(:, 1) = unit_cell_hmat(:, 1)*npts(1)
314 cell_hmat(:, 2) = unit_cell_hmat(:, 2)*npts(2)
315 cell_hmat(:, 3) = unit_cell_hmat(:, 3)*npts(3)
317 END SUBROUTINE dg_set_cell
332 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
333 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: r
334 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s, npts_b
335 INTEGER,
INTENT(OUT) :: centre(3)
336 INTEGER,
INTENT(IN) :: lb(3)
337 COMPLEX(KIND=dp),
DIMENSION(lb(1):),
INTENT(OUT) :: ex
338 COMPLEX(KIND=dp),
DIMENSION(lb(2):),
INTENT(OUT) :: ey
339 COMPLEX(KIND=dp),
DIMENSION(lb(3):),
INTENT(OUT) :: ez
341 REAL(kind=
dp) :: delta(3)
343 CALL dg_get_delta(cell_hmat, r, npts_s, npts_b, centre, delta)
358 SUBROUTINE dg_get_delta(cell_hmat, r, npts_s, npts_b, centre, delta)
359 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: cell_hmat
360 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: r
361 INTEGER,
DIMENSION(:),
INTENT(IN) :: npts_s, npts_b
362 INTEGER,
DIMENSION(:),
INTENT(OUT) :: centre
363 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: delta
365 REAL(kind=
dp) :: cell_deth
366 REAL(kind=
dp),
DIMENSION(3) :: grid_i, s
367 REAL(kind=
dp),
DIMENSION(3, 3) :: cell_h_inv
369 cell_deth = abs(
det_3x3(cell_hmat))
370 IF (cell_deth < 1.0e-10_dp)
THEN
371 CALL cp_abort(__location__, &
372 "An invalid set of cell vectors was specified. "// &
373 "The determinant det(h) is too small")
376 cell_h_inv =
inv_3x3(cell_hmat)
379 s = matmul(cell_h_inv, r)
383 grid_i(1:3) = real(npts_b(1:3), kind=
dp)*s(1:3)
386 centre(:) = nint(grid_i(:))
389 delta(:) = (grid_i(:) - centre(:))/real(npts_s(:), kind=
dp)
391 centre(:) = centre(:) + npts_b(:)/2
392 centre(:) =
modulo(centre(:), npts_b(:))
393 centre(:) = centre(:) - npts_b(:)/2
395 END SUBROUTINE dg_get_delta
403 PURE SUBROUTINE dg_sum_patch_coef(rs, rhos, center)
405 TYPE(realspace_grid_type),
INTENT(INOUT) :: rs
406 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rhos
407 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
410 INTEGER,
DIMENSION(3) :: nc
415 DO i = rhos%pw_grid%bounds(1, 1), rhos%pw_grid%bounds(2, 1)
416 ia = i - rhos%pw_grid%bounds(1, 1) + 1
417 ii = center(1) + i - rs%lb_local(1)
419 rs%px(ia) = ii + rs%npts_local(1) + 1
421 ELSEIF (ii >= rs%npts_local(1))
THEN
422 rs%px(ia) = ii - rs%npts_local(1) + 1
428 DO i = rhos%pw_grid%bounds(1, 2), rhos%pw_grid%bounds(2, 2)
429 ia = i - rhos%pw_grid%bounds(1, 2) + 1
430 ii = center(2) + i - rs%lb_local(2)
432 rs%py(ia) = ii + rs%npts_local(2) + 1
434 ELSEIF (ii >= rs%npts_local(2))
THEN
435 rs%py(ia) = ii - rs%npts_local(2) + 1
441 DO i = rhos%pw_grid%bounds(1, 3), rhos%pw_grid%bounds(2, 3)
442 ia = i - rhos%pw_grid%bounds(1, 3) + 1
443 ii = center(3) + i - rs%lb_local(3)
445 rs%pz(ia) = ii + rs%npts_local(3) + 1
447 ELSEIF (ii >= rs%npts_local(3))
THEN
448 rs%pz(ia) = ii - rs%npts_local(3) + 1
456 CALL dg_add_patch(rs%r, rhos%array, rhos%pw_grid%npts, &
462 CALL dg_add_patch(rs%r, rhos%array, rhos%pw_grid%npts, nc)
465 END SUBROUTINE dg_sum_patch_coef
473 PURE SUBROUTINE dg_sum_patch_arr(rs, rhos, center)
475 TYPE(realspace_grid_type),
INTENT(INOUT) :: rs
476 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rhos
477 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
480 INTEGER,
DIMENSION(3) :: lb, nc, ns, ub
483 ns(1) =
SIZE(rhos, 1)
484 ns(2) =
SIZE(rhos, 2)
485 ns(3) =
SIZE(rhos, 3)
492 ii = center(1) + i - rs%lb_local(1)
494 rs%px(ia) = ii + rs%npts_local(1) + 1
496 ELSEIF (ii >= rs%npts_local(1))
THEN
497 rs%px(ia) = ii - rs%npts_local(1) + 1
505 ii = center(2) + i - rs%lb_local(2)
507 rs%py(ia) = ii + rs%npts_local(2) + 1
509 ELSEIF (ii >= rs%npts_local(2))
THEN
510 rs%py(ia) = ii - rs%npts_local(2) + 1
518 ii = center(3) + i - rs%lb_local(3)
520 rs%pz(ia) = ii + rs%npts_local(3) + 1
522 ELSEIF (ii >= rs%npts_local(3))
THEN
523 rs%pz(ia) = ii - rs%npts_local(3) + 1
531 CALL dg_add_patch(rs%r, rhos, ns, rs%px, rs%py, rs%pz)
536 CALL dg_add_patch(rs%r, rhos, ns, nc)
539 END SUBROUTINE dg_sum_patch_arr
548 PURE SUBROUTINE dg_sum_patch_force_arr_3d(drpot, rhos, center, force)
550 TYPE(realspace_grid_type),
DIMENSION(:), &
551 INTENT(INOUT) :: drpot
552 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rhos
553 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
554 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: force
557 INTEGER,
DIMENSION(3) :: lb, nc, ns, ub
560 ns(1) =
SIZE(rhos, 1)
561 ns(2) =
SIZE(rhos, 2)
562 ns(3) =
SIZE(rhos, 3)
569 ii = center(1) + i - drpot(1)%lb_local(1)
571 drpot(1)%px(ia) = ii + drpot(1)%npts_local(1) + 1
573 ELSEIF (ii >= drpot(1)%npts_local(1))
THEN
574 drpot(1)%px(ia) = ii - drpot(1)%npts_local(1) + 1
577 drpot(1)%px(ia) = ii + 1
582 ii = center(2) + i - drpot(1)%lb_local(2)
584 drpot(1)%py(ia) = ii + drpot(1)%npts_local(2) + 1
586 ELSEIF (ii >= drpot(1)%npts_local(2))
THEN
587 drpot(1)%py(ia) = ii - drpot(1)%npts_local(2) + 1
590 drpot(1)%py(ia) = ii + 1
595 ii = center(3) + i - drpot(1)%lb_local(3)
597 drpot(1)%pz(ia) = ii + drpot(1)%npts_local(3) + 1
599 ELSEIF (ii >= drpot(1)%npts_local(3))
THEN
600 drpot(1)%pz(ia) = ii - drpot(1)%npts_local(3) + 1
603 drpot(1)%pz(ia) = ii + 1
608 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
609 drpot(3)%r, rhos, force, ns, &
610 drpot(1)%px, drpot(1)%py, drpot(1)%pz)
612 nc(1) = drpot(1)%px(1) - 1
613 nc(2) = drpot(1)%py(1) - 1
614 nc(3) = drpot(1)%pz(1) - 1
615 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
616 drpot(3)%r, rhos, force, ns, nc)
619 END SUBROUTINE dg_sum_patch_force_arr_3d
628 PURE SUBROUTINE dg_sum_patch_force_arr_1d(drpot, rhos, center, force)
630 TYPE(realspace_grid_type),
INTENT(INOUT) :: drpot
631 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rhos
632 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
633 REAL(kind=
dp),
INTENT(OUT) :: force
636 INTEGER,
DIMENSION(3) :: lb, nc, ns, ub
639 ns(1) =
SIZE(rhos, 1)
640 ns(2) =
SIZE(rhos, 2)
641 ns(3) =
SIZE(rhos, 3)
648 ii = center(1) + i - drpot%lb_local(1)
650 drpot%px(ia) = ii + drpot%npts_local(1) + 1
652 ELSEIF (ii >= drpot%desc%npts(1))
THEN
653 drpot%px(ia) = ii - drpot%npts_local(1) + 1
656 drpot%px(ia) = ii + 1
661 ii = center(2) + i - drpot%lb_local(2)
663 drpot%py(ia) = ii + drpot%npts_local(2) + 1
665 ELSEIF (ii >= drpot%desc%npts(2))
THEN
666 drpot%py(ia) = ii - drpot%npts_local(2) + 1
669 drpot%py(ia) = ii + 1
674 ii = center(3) + i - drpot%lb_local(3)
676 drpot%pz(ia) = ii + drpot%npts_local(3) + 1
678 ELSEIF (ii >= drpot%desc%npts(3))
THEN
679 drpot%pz(ia) = ii - drpot%npts_local(3) + 1
682 drpot%pz(ia) = ii + 1
687 CALL dg_int_patch_1d(drpot%r, rhos, force, ns, &
688 drpot%px, drpot%py, drpot%pz)
690 nc(1) = drpot%px(1) - 1
691 nc(2) = drpot%py(1) - 1
692 nc(3) = drpot%pz(1) - 1
693 CALL dg_int_patch_1d(drpot%r, rhos, force, ns, nc)
696 END SUBROUTINE dg_sum_patch_force_arr_1d
705 PURE SUBROUTINE dg_sum_patch_force_coef_3d(drpot, rhos, center, force)
707 TYPE(realspace_grid_type),
DIMENSION(:), &
708 INTENT(INOUT) :: drpot
709 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rhos
710 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
711 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: force
714 INTEGER,
DIMENSION(3) :: nc
719 DO i = rhos%pw_grid%bounds(1, 1), rhos%pw_grid%bounds(2, 1)
720 ia = i - rhos%pw_grid%bounds(1, 1) + 1
721 ii = center(1) + i - drpot(1)%lb_local(1)
723 drpot(1)%px(ia) = ii + drpot(1)%desc%npts(1) + 1
725 ELSEIF (ii >= drpot(1)%desc%npts(1))
THEN
726 drpot(1)%px(ia) = ii - drpot(1)%desc%npts(1) + 1
729 drpot(1)%px(ia) = ii + 1
732 DO i = rhos%pw_grid%bounds(1, 2), rhos%pw_grid%bounds(2, 2)
733 ia = i - rhos%pw_grid%bounds(1, 2) + 1
734 ii = center(2) + i - drpot(1)%lb_local(2)
736 drpot(1)%py(ia) = ii + drpot(1)%desc%npts(2) + 1
738 ELSEIF (ii >= drpot(1)%desc%npts(2))
THEN
739 drpot(1)%py(ia) = ii - drpot(1)%desc%npts(2) + 1
742 drpot(1)%py(ia) = ii + 1
745 DO i = rhos%pw_grid%bounds(1, 3), rhos%pw_grid%bounds(2, 3)
746 ia = i - rhos%pw_grid%bounds(1, 3) + 1
747 ii = center(3) + i - drpot(1)%lb_local(3)
749 drpot(1)%pz(ia) = ii + drpot(1)%desc%npts(3) + 1
751 ELSEIF (ii >= drpot(1)%desc%npts(3))
THEN
752 drpot(1)%pz(ia) = ii - drpot(1)%desc%npts(3) + 1
755 drpot(1)%pz(ia) = ii + 1
760 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
761 drpot(3)%r, rhos%array, force, rhos%pw_grid%npts, &
762 drpot(1)%px, drpot(1)%py, drpot(1)%pz)
764 nc(1) = drpot(1)%px(1) - 1
765 nc(2) = drpot(1)%py(1) - 1
766 nc(3) = drpot(1)%pz(1) - 1
767 CALL dg_int_patch_3d(drpot(1)%r, drpot(2)%r, &
768 drpot(3)%r, rhos%array, force, rhos%pw_grid%npts, nc)
771 END SUBROUTINE dg_sum_patch_force_coef_3d
780 PURE SUBROUTINE dg_sum_patch_force_coef_1d(drpot, rhos, center, force)
782 TYPE(realspace_grid_type),
INTENT(INOUT) :: drpot
783 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rhos
784 INTEGER,
DIMENSION(3),
INTENT(IN) :: center
785 REAL(kind=
dp),
INTENT(OUT) :: force
788 INTEGER,
DIMENSION(3) :: nc
793 DO i = rhos%pw_grid%bounds(1, 1), rhos%pw_grid%bounds(2, 1)
794 ia = i - rhos%pw_grid%bounds(1, 1) + 1
795 ii = center(1) + i - drpot%lb_local(1)
797 drpot%px(ia) = ii + drpot%desc%npts(1) + 1
799 ELSEIF (ii >= drpot%desc%npts(1))
THEN
800 drpot%px(ia) = ii - drpot%desc%npts(1) + 1
803 drpot%px(ia) = ii + 1
806 DO i = rhos%pw_grid%bounds(1, 2), rhos%pw_grid%bounds(2, 2)
807 ia = i - rhos%pw_grid%bounds(1, 2) + 1
808 ii = center(2) + i - drpot%lb_local(2)
810 drpot%py(ia) = ii + drpot%desc%npts(2) + 1
812 ELSEIF (ii >= drpot%desc%npts(2))
THEN
813 drpot%py(ia) = ii - drpot%desc%npts(2) + 1
816 drpot%py(ia) = ii + 1
819 DO i = rhos%pw_grid%bounds(1, 3), rhos%pw_grid%bounds(2, 3)
820 ia = i - rhos%pw_grid%bounds(1, 3) + 1
821 ii = center(3) + i - drpot%lb_local(3)
823 drpot%pz(ia) = ii + drpot%desc%npts(3) + 1
825 ELSEIF (ii >= drpot%desc%npts(3))
THEN
826 drpot%pz(ia) = ii - drpot%desc%npts(3) + 1
829 drpot%pz(ia) = ii + 1
834 CALL dg_int_patch_1d(drpot%r, rhos%array, force, &
835 rhos%pw_grid%npts, drpot%px, drpot%py, drpot%pz)
837 nc(1) = drpot%px(1) - 1
838 nc(2) = drpot%py(1) - 1
839 nc(3) = drpot%pz(1) - 1
840 CALL dg_int_patch_1d(drpot%r, rhos%array, force, rhos%pw_grid%npts, nc)
843 END SUBROUTINE dg_sum_patch_force_coef_1d
854 SUBROUTINE dg_get_patch_1(rho0, rhos1, charge1, ex1, ey1, ez1)
856 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho0
857 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: rhos1
858 REAL(kind=
dp),
INTENT(IN) :: charge1
859 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(IN) :: ex1, ey1, ez1
861 COMPLEX(KIND=dp) :: za, zb
862 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: zs
864 TYPE(pw_c3d_rs_type) :: cd
866 nd = rhos1%pw_grid%npts
868 ALLOCATE (zs(nd(1)*nd(2)))
870 CALL cd%create(rho0%pw_grid)
873 za = cmplx(0.0_dp, 0.0_dp, kind=
dp)
874 zb = cmplx(charge1, 0.0_dp, kind=
dp)
875 CALL rankup(nd, za, cd%array, zb, ex1, ey1, ez1, zs)
876 CALL pw_multiply_with(cd, rho0)
877 CALL fft3d(
bwfft, nd, cd%array)
878 CALL pw_copy(cd, rhos1)
883 END SUBROUTINE dg_get_patch_1
899 SUBROUTINE dg_get_patch_2(rho0, rhos1, rhos2, charge1, charge2, &
900 ex1, ey1, ez1, ex2, ey2, ez2)
902 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho0
903 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: rhos1, rhos2
904 REAL(kind=
dp),
INTENT(IN) :: charge1, charge2
905 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(IN) :: ex1, ey1, ez1, ex2, ey2, ez2
907 COMPLEX(KIND=dp) :: za, zb
908 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: zs
910 TYPE(pw_c3d_rs_type) :: cd
912 nd = rhos1%pw_grid%npts
914 ALLOCATE (zs(nd(1)*nd(2)))
916 CALL cd%create(rhos1%pw_grid)
919 za = cmplx(0.0_dp, 0.0_dp, kind=
dp)
920 zb = cmplx(charge2, 0.0_dp, kind=
dp)
921 CALL rankup(nd, za, cd%array, zb, ex2, ey2, ez2, zs)
922 za = cmplx(0.0_dp, 1.0_dp, kind=
dp)
923 zb = cmplx(charge1, 0.0_dp, kind=
dp)
924 CALL rankup(nd, za, cd%array, zb, ex1, ey1, ez1, zs)
925 CALL pw_multiply_with(cd, rho0)
926 CALL fft3d(
bwfft, nd, cd%array)
927 CALL copy_cri(cd%array, rhos1%array, rhos2%array)
932 END SUBROUTINE dg_get_patch_2
941 PURE SUBROUTINE dg_add_patch_simple(rb, rs, ns, nc)
943 REAL(kind=
dp),
INTENT(INOUT) :: rb(:, :, :)
944 REAL(kind=
dp),
INTENT(IN) :: rs(:, :, :)
945 INTEGER,
INTENT(IN) :: ns(3), nc(3)
947 INTEGER :: i, ii, j, jj, k, kk
955 rb(ii, jj, kk) = rb(ii, jj, kk) + rs(i, j, k)
960 END SUBROUTINE dg_add_patch_simple
971 PURE SUBROUTINE dg_add_patch_folded(rb, rs, ns, px, py, pz)
973 REAL(kind=
dp),
INTENT(INOUT) :: rb(:, :, :)
974 REAL(kind=
dp),
INTENT(IN) :: rs(:, :, :)
975 INTEGER,
INTENT(IN) :: ns(:)
976 INTEGER,
DIMENSION(:),
INTENT(IN) :: px, py, pz
978 INTEGER :: i, ii, j, jj, k, kk
986 rb(ii, jj, kk) = rb(ii, jj, kk) + rs(i, j, k)
991 END SUBROUTINE dg_add_patch_folded
1003 PURE SUBROUTINE dg_int_patch_simple_3d(rbx, rby, rbz, rs, f, ns, nc)
1005 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rbx, rby, rbz, rs
1006 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: f
1007 INTEGER,
INTENT(IN) :: ns(3), nc(3)
1009 INTEGER :: i, ii, j, jj, k, kk
1020 f(1) = f(1) + s*rbx(ii, jj, kk)
1021 f(2) = f(2) + s*rby(ii, jj, kk)
1022 f(3) = f(3) + s*rbz(ii, jj, kk)
1027 END SUBROUTINE dg_int_patch_simple_3d
1037 PURE SUBROUTINE dg_int_patch_simple_1d(rb, rs, f, ns, nc)
1039 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rb, rs
1040 REAL(kind=
dp),
INTENT(OUT) :: f
1041 INTEGER,
INTENT(IN) :: ns(3), nc(3)
1043 INTEGER :: i, ii, j, jj, k, kk
1054 f = f + s*rb(ii, jj, kk)
1059 END SUBROUTINE dg_int_patch_simple_1d
1073 PURE SUBROUTINE dg_int_patch_folded_3d(rbx, rby, rbz, rs, f, ns, px, py, pz)
1075 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rbx, rby, rbz, rs
1076 REAL(kind=
dp),
DIMENSION(3),
INTENT(INOUT) :: f
1077 INTEGER,
INTENT(IN) :: ns(3)
1078 INTEGER,
DIMENSION(:),
INTENT(IN) :: px, py, pz
1080 INTEGER :: i, ii, j, jj, k, kk
1091 f(1) = f(1) + s*rbx(ii, jj, kk)
1092 f(2) = f(2) + s*rby(ii, jj, kk)
1093 f(3) = f(3) + s*rbz(ii, jj, kk)
1098 END SUBROUTINE dg_int_patch_folded_3d
1110 PURE SUBROUTINE dg_int_patch_folded_1d(rb, rs, f, ns, px, py, pz)
1112 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: rb, rs
1113 REAL(kind=
dp),
INTENT(INOUT) :: f
1114 INTEGER,
INTENT(IN) :: ns(3)
1115 INTEGER,
DIMENSION(:),
INTENT(IN) :: px, py, pz
1117 INTEGER :: i, ii, j, jj, k, kk
1128 f = f + s*rb(ii, jj, kk)
1133 END SUBROUTINE dg_int_patch_folded_1d
1146 SUBROUTINE rankup(n, za, cmat, zb, ex, ey, ez, scr)
1151 INTEGER,
DIMENSION(3),
INTENT(IN) :: n
1152 COMPLEX(KIND=dp),
INTENT(IN) :: za
1153 COMPLEX(KIND=dp),
DIMENSION(:, :, :), &
1154 INTENT(INOUT) :: cmat
1155 COMPLEX(KIND=dp),
INTENT(IN) :: zb
1156 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(IN) :: ex, ey, ez
1157 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(INOUT) :: scr
1164 CALL zgeru(n(1), n(2), zb, ex, 1, ey, 1, scr, n(1))
1165 CALL zscal(n3, za, cmat, 1)
1166 CALL zgeru(n2, n(3),
z_one, scr, 1, ez, 1, cmat, n2)
1168 END SUBROUTINE rankup
1176 SUBROUTINE copy_cri(z, r1, r2)
1182 COMPLEX(KIND=dp),
INTENT(IN) :: z(:, :, :)
1183 REAL(kind=
dp),
INTENT(INOUT) :: r1(:, :, :), r2(:, :, :)
1186 r1(:, :, :) = real(z(:, :, :), kind=
dp)
1187 r2(:, :, :) = aimag(z(:, :, :))
1190 END SUBROUTINE copy_cri
real(kind=dp) function det_3x3(a)
...
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_grid_change(b_cell_hmat, grid_b, grid_s)
...
subroutine, public dg_pme_grid_setup(b_cell_hmat, npts_s, cutoff_radius, grid_s, grid_b, grid_ref, rs_dims, iounit, fft_usage)
...
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 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.
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_setup(cell_hmat, pw_grid, grid_span, cutoff, bounds, bounds_local, npts, spherical, odd, fft_usage, ncommensurate, icommensurate, blocked, ref_grid, rs_dims, iounit)
sets up a pw_grid
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)
...