(git:31876b5)
Loading...
Searching...
No Matches
gce_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7! **************************************************************************************************
8!> \author Ziwei Chai
9!> \date 09.04.2026
10!> \version 1.0
11! **************************************************************************************************
13
16 USE kinds, ONLY: dp
18 USE pw_methods, ONLY: pw_axpy,&
20 pw_scale,&
24 USE pw_types, ONLY: pw_c1d_gs_type,&
26#include "./base/base_uses.f90"
27
28 IMPLICIT NONE
29
30 PRIVATE
31
32 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gce_methods'
33
35
36CONTAINS
37
38! **************************************************************************************************
39!> \brief map the surface normal to the two in-plane axes and one normal axis
40!> \param surf_normal ...
41!> \param a ...
42!> \param b ...
43!> \param c ...
44!> \author Ziwei Chai
45! **************************************************************************************************
46 SUBROUTINE get_planar_axes(surf_normal, a, b, c)
47
48 INTEGER, INTENT(IN) :: surf_normal
49 INTEGER, INTENT(OUT) :: a, b, c
50
51 SELECT CASE (surf_normal)
52 CASE (3)
53 a = 1
54 b = 2
55 c = 3
56 CASE (1)
57 a = 2
58 b = 3
59 c = 1
60 CASE (2)
61 a = 3
62 b = 1
63 c = 2
64 CASE DEFAULT
65 cpabort("Invalid planar surface normal.")
66 END SELECT
67
68 END SUBROUTINE get_planar_axes
69
70! **************************************************************************************************
71!> \brief calculate the planar averaged real space potential (e.g. Hartree potential) along the
72!> surface normal of a slab model and the corresponding reference (electrostatic) energy
73!> near the simulation cell edge.
74!> \param v_rspace ...
75!> \param dft_control ...
76!> \param do_gce ...
77!> \param ref_esp ...
78!> \param para_env ...
79!> \author Ziwei Chai
80! **************************************************************************************************
81 SUBROUTINE planar_averaged_v_hartree_3d(v_rspace, dft_control, do_gce, ref_esp, para_env)
82
83 TYPE(pw_r3d_rs_type), INTENT(IN) :: v_rspace
84 TYPE(dft_control_type), POINTER :: dft_control
85 LOGICAL, INTENT(IN) :: do_gce
86 REAL(kind=dp), INTENT(INOUT) :: ref_esp
87 TYPE(mp_para_env_type), POINTER :: para_env
88
89 CHARACTER(LEN=*), PARAMETER :: routinen = 'planar_averaged_v_hartree_3d'
90
91 INTEGER :: a, b, c, handle, x, y, z
92 REAL(kind=dp) :: my_ref_esp, ngrids_in_plane
93 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: profile, profile_local
94
95 CALL timeset(routinen, handle)
96
97 IF (do_gce) THEN
98
99 ! a and b cell vectors are parallel to the surface, c vector is not.
100 CALL get_planar_axes(dft_control%pcc_control%surf_normal, a, b, c)
101
102 my_ref_esp = 0.0_dp
103 z = v_rspace%pw_grid%npts(a)*v_rspace%pw_grid%npts(b)
104 ngrids_in_plane = real(z, dp)
105
106!$OMP PARALLEL DO DEFAULT(NONE) &
107!$OMP PRIVATE(x,y,z) &
108!$OMP SHARED(v_rspace,A,b,c)&
109!$OMP REDUCTION(+:my_ref_esp)
110 DO y = v_rspace%pw_grid%bounds_local(1, b), v_rspace%pw_grid%bounds_local(2, b)
111 DO x = v_rspace%pw_grid%bounds_local(1, a), v_rspace%pw_grid%bounds_local(2, a)
112 DO z = v_rspace%pw_grid%bounds_local(1, c), v_rspace%pw_grid%bounds_local(2, c)
113 IF (z == v_rspace%pw_grid%bounds(2, c)) THEN
114 IF (c == 3) THEN
115 my_ref_esp = v_rspace%array(x, y, z) + my_ref_esp
116 ELSE IF (c == 2) THEN
117 my_ref_esp = v_rspace%array(y, z, x) + my_ref_esp
118 ELSE
119 my_ref_esp = v_rspace%array(z, x, y) + my_ref_esp
120 END IF
121 END IF
122 END DO
123 END DO
124 END DO
125!$OMP END PARALLEL DO
126
127 CALL para_env%sum(my_ref_esp)
128 my_ref_esp = my_ref_esp/ngrids_in_plane
129 ref_esp = my_ref_esp
130
131 END IF
132
133 IF (dft_control%do_paep) THEN
134
135 CALL get_planar_axes(dft_control%paep_control%surf_normal, a, b, c)
136
137 z = v_rspace%pw_grid%npts(a)*v_rspace%pw_grid%npts(b)
138 ngrids_in_plane = real(z, dp)
139
140 ALLOCATE (profile(v_rspace%pw_grid%bounds(1, c):v_rspace%pw_grid%bounds(2, c)))
141 profile(:) = 0.0_dp
142
143!$OMP PARALLEL DEFAULT(NONE) &
144!$OMP PRIVATE(x,y,z,profile_local) &
145!$OMP SHARED(v_rspace,A,b,c) &
146!$OMP SHARED(profile)
147
148 ALLOCATE (profile_local(v_rspace%pw_grid%bounds(1, c):v_rspace%pw_grid%bounds(2, c)))
149 profile_local(:) = 0.0_dp
150
151!$OMP DO
152 DO z = v_rspace%pw_grid%bounds_local(1, c), v_rspace%pw_grid%bounds_local(2, c)
153 DO y = v_rspace%pw_grid%bounds_local(1, b), v_rspace%pw_grid%bounds_local(2, b)
154 DO x = v_rspace%pw_grid%bounds_local(1, a), v_rspace%pw_grid%bounds_local(2, a)
155 IF (c == 3) profile_local(z) = profile_local(z) + v_rspace%array(x, y, z)
156 IF (c == 2) profile_local(z) = profile_local(z) + v_rspace%array(y, z, x)
157 IF (c == 1) profile_local(z) = profile_local(z) + v_rspace%array(z, x, y)
158 END DO
159 END DO
160 END DO
161!$OMP END DO
162
163!$OMP CRITICAL
164 profile(:) = profile(:) + profile_local(:)
165!$OMP END CRITICAL
166
167 DEALLOCATE (profile_local)
168
169!$OMP END PARALLEL
170
171 CALL para_env%sum(profile(:))
172 profile(:) = profile(:)/ngrids_in_plane
173
174 DEALLOCATE (profile)
175
176 END IF
177
178 CALL timestop(handle)
179
180 END SUBROUTINE planar_averaged_v_hartree_3d
181
182! **************************************************************************************************
183!> \brief add the planar counter charge density to the total charge density
184!> \param rho_tot_gspace ...
185!> \param pcc_env ...
186!> \param auxbas_pw_pool ...
187!> \author Ziwei Chai
188! **************************************************************************************************
189 SUBROUTINE planar_counter_charge(rho_tot_gspace, pcc_env, auxbas_pw_pool)
190
191 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_tot_gspace
192 TYPE(pcc_control_type), POINTER :: pcc_env
193 TYPE(pw_pool_type), INTENT(IN), POINTER :: auxbas_pw_pool
194
195 CHARACTER(LEN=*), PARAMETER :: routinen = 'planar_counter_charge'
196
197 INTEGER :: a, b, c, handle, lcenter, ucenter, x, y, &
198 z
199 REAL(kind=dp) :: dz, gau_a, tot_charge, val
200 TYPE(pw_c1d_gs_type) :: pcc_density_g
201 TYPE(pw_r3d_rs_type) :: pcc_density_r
202
203 CALL timeset(routinen, handle)
204
205 ! a and b cell vectors are parallel to the surface, c vector is not.
206 CALL get_planar_axes(pcc_env%surf_normal, a, b, c)
207
208 CALL auxbas_pw_pool%create_pw(pcc_density_r)
209 CALL auxbas_pw_pool%create_pw(pcc_density_g)
210 CALL pw_zero(pcc_density_r)
211 CALL pw_zero(pcc_density_g)
212
213 tot_charge = pw_integrate_function(rho_tot_gspace, isign=-1)
214
215 dz = pcc_density_r%pw_grid%dr(c)
216
217 ucenter = pcc_density_r%pw_grid%bounds(2, c) - int(pcc_env%dist_edge/dz)
218 lcenter = pcc_density_r%pw_grid%bounds(1, c) + int(pcc_env%dist_edge/dz)
219 gau_a = 1.0_dp
220!$OMP PARALLEL DO DEFAULT(NONE) &
221!$OMP PRIVATE(x,y,z,val) &
222!$OMP SHARED(pcc_density_r,gau_a,ucenter,lcenter,A,b,c,dz,pcc_env)
223 DO z = pcc_density_r%pw_grid%bounds_local(1, c), pcc_density_r%pw_grid%bounds_local(2, c)
224 val = gau_a*exp(-(dz*real(z - ucenter, dp))**2.0_dp/(2.0_dp*pcc_env%gau_c**2.0_dp))
225 val = val + gau_a*exp(-(dz*real(z - lcenter, dp))**2.0_dp/(2.0_dp*pcc_env%gau_c**2.0_dp))
226 IF (val < 1.0e-15_dp) val = 0.0_dp
227 DO y = pcc_density_r%pw_grid%bounds_local(1, b), pcc_density_r%pw_grid%bounds_local(2, b)
228 DO x = pcc_density_r%pw_grid%bounds_local(1, a), pcc_density_r%pw_grid%bounds_local(2, a)
229 IF (c == 3) pcc_density_r%array(x, y, z) = val
230 IF (c == 2) pcc_density_r%array(y, z, x) = val
231 IF (c == 1) pcc_density_r%array(z, x, y) = val
232 END DO
233 END DO
234 END DO
235!$OMP END PARALLEL DO
236
237 tot_charge = tot_charge/pw_integrate_function(pcc_density_r, isign=1)
238 CALL pw_scale(pcc_density_r, tot_charge)
239 CALL pw_transfer(pcc_density_r, pcc_density_g)
240 CALL pw_axpy(pcc_density_g, rho_tot_gspace)
241 CALL pw_transfer(rho_tot_gspace, pcc_density_r)
242
243 tot_charge = pw_integrate_function(rho_tot_gspace, isign=-1)
244
245 CALL auxbas_pw_pool%give_back_pw(pcc_density_r)
246 CALL auxbas_pw_pool%give_back_pw(pcc_density_g)
247
248 CALL timestop(handle)
249
250 END SUBROUTINE planar_counter_charge
251
252END MODULE gce_methods
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public planar_averaged_v_hartree_3d(v_rspace, dft_control, do_gce, ref_esp, para_env)
calculate the planar averaged real space potential (e.g. Hartree potential) along the surface normal ...
Definition gce_methods.F:82
subroutine, public planar_counter_charge(rho_tot_gspace, pcc_env, auxbas_pw_pool)
add the planar counter charge density to the total charge density
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
stores all the informations relevant to an mpi environment
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...