(git:6ba6522)
Loading...
Searching...
No Matches
qs_external_potential.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! **************************************************************************************************
9!> \brief Routines to handle an external electrostatic field
10!> The external field can be generic and is provided by user input
11! **************************************************************************************************
15 USE cell_types, ONLY: cell_type,&
16 pbc
21 USE fparser, ONLY: evalf,&
22 evalfd,&
23 finalizef,&
24 initf,&
25 parsef
29 USE kinds, ONLY: default_path_length,&
31 dp,&
32 int_8
37 USE pw_methods, ONLY: pw_zero
38 USE pw_types, ONLY: pw_r3d_rs_type
43 USE qs_kind_types, ONLY: get_qs_kind,&
45 USE string_utilities, ONLY: compress
46#include "./base/base_uses.f90"
47
48 IMPLICIT NONE
49
50 PRIVATE
51
52 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_external_potential'
53
54! *** Public subroutines ***
55 PUBLIC :: external_e_potential, &
58
59CONTAINS
60
61! **************************************************************************************************
62!> \brief Computes the external potential on the grid
63!> \param qs_env ...
64!> \date 12.2009
65!> \author Teodoro Laino [tlaino]
66! **************************************************************************************************
67 SUBROUTINE external_e_potential(qs_env)
68
69 TYPE(qs_environment_type), POINTER :: qs_env
70
71 CHARACTER(len=*), PARAMETER :: routinen = 'external_e_potential'
72
73 INTEGER :: handle, i, j, k
74 INTEGER(kind=int_8) :: npoints
75 INTEGER, DIMENSION(2, 3) :: bo_global, bo_local
76 REAL(kind=dp) :: dvol, scaling_factor
77 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: efunc, grid_p_i, grid_p_j, grid_p_k
78 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: grid_p
79 REAL(kind=dp), DIMENSION(3) :: dr
80 TYPE(dft_control_type), POINTER :: dft_control
81 TYPE(pw_r3d_rs_type), POINTER :: v_ee
82 TYPE(section_vals_type), POINTER :: ext_pot_section, input
83
84 CALL timeset(routinen, handle)
85 CALL get_qs_env(qs_env, dft_control=dft_control)
86 IF (dft_control%apply_external_potential) THEN
87 IF (dft_control%eval_external_potential) THEN
88 CALL get_qs_env(qs_env, vee=v_ee)
89 IF (dft_control%expot_control%maxwell_solver) THEN
90 scaling_factor = dft_control%expot_control%scaling_factor
91 CALL maxwell_solver(dft_control%maxwell_control, v_ee, &
92 qs_env%sim_step, qs_env%sim_time, &
93 scaling_factor)
94 dft_control%eval_external_potential = .false.
95 ELSE IF (dft_control%expot_control%read_from_cube) THEN
96 scaling_factor = dft_control%expot_control%scaling_factor
97 CALL cp_cube_to_pw(v_ee, 'pot.cube', scaling_factor)
98 dft_control%eval_external_potential = .false.
99 ELSE
100 CALL get_qs_env(qs_env, input=input)
101 ext_pot_section => section_vals_get_subs_vals(input, "DFT%EXTERNAL_POTENTIAL")
102
103 dr = v_ee%pw_grid%dr
104 dvol = v_ee%pw_grid%dvol
105 CALL pw_zero(v_ee)
106
107 bo_local = v_ee%pw_grid%bounds_local
108 bo_global = v_ee%pw_grid%bounds
109
110 npoints = int(bo_local(2, 1) - bo_local(1, 1) + 1, kind=int_8)* &
111 int(bo_local(2, 2) - bo_local(1, 2) + 1, kind=int_8)* &
112 int(bo_local(2, 3) - bo_local(1, 3) + 1, kind=int_8)
113 ALLOCATE (efunc(npoints))
114 ALLOCATE (grid_p(3, npoints))
115 ALLOCATE (grid_p_i(bo_local(1, 1):bo_local(2, 1)))
116 ALLOCATE (grid_p_j(bo_local(1, 2):bo_local(2, 2)))
117 ALLOCATE (grid_p_k(bo_local(1, 3):bo_local(2, 3)))
118
119 DO i = bo_local(1, 1), bo_local(2, 1)
120 grid_p_i(i) = (i - bo_global(1, 1))*dr(1)
121 END DO
122 DO j = bo_local(1, 2), bo_local(2, 2)
123 grid_p_j(j) = (j - bo_global(1, 2))*dr(2)
124 END DO
125 DO k = bo_local(1, 3), bo_local(2, 3)
126 grid_p_k(k) = (k - bo_global(1, 3))*dr(3)
127 END DO
128
129 npoints = 0
130 DO k = bo_local(1, 3), bo_local(2, 3)
131 DO j = bo_local(1, 2), bo_local(2, 2)
132 DO i = bo_local(1, 1), bo_local(2, 1)
133 npoints = npoints + 1
134 grid_p(1, npoints) = grid_p_i(i)
135 grid_p(2, npoints) = grid_p_j(j)
136 grid_p(3, npoints) = grid_p_k(k)
137 END DO
138 END DO
139 END DO
140
141 DEALLOCATE (grid_p_i, grid_p_j, grid_p_k)
142
143 CALL get_external_potential(grid_p, ext_pot_section, func=efunc)
144
145 npoints = 0
146 DO k = bo_local(1, 3), bo_local(2, 3)
147 DO j = bo_local(1, 2), bo_local(2, 2)
148 DO i = bo_local(1, 1), bo_local(2, 1)
149 npoints = npoints + 1
150 v_ee%array(i, j, k) = v_ee%array(i, j, k) + efunc(npoints)
151 END DO
152 END DO
153 END DO
154
155 DEALLOCATE (grid_p, efunc)
156
157 dft_control%eval_external_potential = .false.
158 END IF
159 END IF
160 END IF
161 CALL timestop(handle)
162 END SUBROUTINE external_e_potential
163
164! **************************************************************************************************
165!> \brief Computes the force and the energy due to the external potential on the cores
166!> \param qs_env ...
167!> \param calculate_forces ...
168!> \date 12.2009
169!> \author Teodoro Laino [tlaino]
170! **************************************************************************************************
171 SUBROUTINE external_c_potential(qs_env, calculate_forces)
172
173 TYPE(qs_environment_type), POINTER :: qs_env
174 LOGICAL, OPTIONAL :: calculate_forces
175
176 CHARACTER(len=*), PARAMETER :: routinen = 'external_c_potential'
177
178 INTEGER :: atom_a, handle, iatom, ikind, natom, &
179 nkind, nparticles
180 INTEGER, DIMENSION(:), POINTER :: list
181 LOGICAL :: my_force, pot_on_grid
182 REAL(kind=dp) :: ee_core_ener, zeff
183 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: efunc
184 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: dfunc, r
185 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
186 TYPE(cell_type), POINTER :: cell
187 TYPE(dft_control_type), POINTER :: dft_control
188 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
189 TYPE(pw_r3d_rs_type), POINTER :: v_ee
190 TYPE(qs_energy_type), POINTER :: energy
191 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
192 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
193 TYPE(section_vals_type), POINTER :: ext_pot_section, input
194
195 CALL timeset(routinen, handle)
196 NULLIFY (dft_control)
197
198 CALL get_qs_env(qs_env=qs_env, &
199 atomic_kind_set=atomic_kind_set, &
200 qs_kind_set=qs_kind_set, &
201 energy=energy, &
202 particle_set=particle_set, &
203 input=input, &
204 cell=cell, &
205 dft_control=dft_control)
206
207 IF (dft_control%apply_external_potential .AND. .NOT. qs_env%mimic) THEN
208 !ensure that external potential is loaded to grid
209 IF (dft_control%eval_external_potential) THEN
210 CALL external_e_potential(qs_env)
211 END IF
212 my_force = .false.
213 IF (PRESENT(calculate_forces)) my_force = calculate_forces
214 ee_core_ener = 0.0_dp
215 nkind = SIZE(atomic_kind_set)
216
217 !check if external potential on grid has been loaded from a file instead of giving a function
218 IF (dft_control%expot_control%read_from_cube .OR. &
219 dft_control%expot_control%maxwell_solver) THEN
220 CALL get_qs_env(qs_env, vee=v_ee)
221 pot_on_grid = .true.
222 ELSE
223 pot_on_grid = .false.
224 ext_pot_section => section_vals_get_subs_vals(input, "DFT%EXTERNAL_POTENTIAL")
225 END IF
226
227 nparticles = 0
228 DO ikind = 1, SIZE(atomic_kind_set)
229 CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
230 nparticles = nparticles + max(natom, 0)
231 END DO
232
233 ALLOCATE (efunc(nparticles))
234 ALLOCATE (dfunc(3, nparticles), r(3, nparticles))
235
236 nparticles = 0
237 DO ikind = 1, SIZE(atomic_kind_set)
238 CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=list, natom=natom)
239
240 DO iatom = 1, natom
241 atom_a = list(iatom)
242 nparticles = nparticles + 1
243 !pbc returns r(i) in range [-cell%hmat(i,i)/2, cell%hmat(i,i)/2]
244 !for periodic dimensions (assuming the cell is orthorombic).
245 !This is not consistent with the potential on grid, where r(i) is
246 !in range [0, cell%hmat(i,i)]
247 !Use new pbc function with switch positive_range=.TRUE.
248 r(:, nparticles) = pbc(particle_set(atom_a)%r(:), cell, positive_range=.true.)
249 END DO
250 END DO
251
252 !if potential is on grid, interpolate the value at r,
253 !otherwise evaluate the given function
254 IF (pot_on_grid) THEN
255 DO iatom = 1, nparticles
256 CALL interpolate_external_potential(r(:, iatom), v_ee, func=efunc(iatom), &
257 dfunc=dfunc(:, iatom), calc_derivatives=my_force)
258 END DO
259 ELSE
260 CALL get_external_potential(r, ext_pot_section, func=efunc, dfunc=dfunc, calc_derivatives=my_force)
261 END IF
262
263 IF (my_force) THEN
264 CALL get_qs_env(qs_env=qs_env, force=force)
265 END IF
266
267 nparticles = 0
268 DO ikind = 1, SIZE(atomic_kind_set)
269 CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
270 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
271
272 DO iatom = 1, natom
273 nparticles = nparticles + 1
274
275 ee_core_ener = ee_core_ener + zeff*efunc(nparticles)
276 IF (my_force) THEN
277 force(ikind)%eev(1:3, iatom) = dfunc(1:3, nparticles)*zeff
278 END IF
279 END DO
280 END DO
281 energy%ee_core = ee_core_ener
282
283 DEALLOCATE (dfunc, r)
284 DEALLOCATE (efunc)
285 END IF
286 CALL timestop(handle)
287 END SUBROUTINE external_c_potential
288
289! **************************************************************************************************
290!> \brief Low level function for computing the potential and the derivatives
291!> \param r position in realspace for each grid-point
292!> \param ext_pot_section ...
293!> \param func external potential at r
294!> \param dfunc derivative of the external potential at r
295!> \param calc_derivatives Whether to calculate dfunc
296!> \date 12.2009
297!> \par History
298!> 12.2009 created [tlaino]
299!> 11.2014 reading external cube file added [Juha Ritala & Matt Watkins]
300!> \author Teodoro Laino [tlaino]
301! **************************************************************************************************
302 SUBROUTINE get_external_potential(r, ext_pot_section, func, dfunc, calc_derivatives)
303 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: r
304 TYPE(section_vals_type), POINTER :: ext_pot_section
305 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: func
306 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT), &
307 OPTIONAL :: dfunc
308 LOGICAL, INTENT(IN), OPTIONAL :: calc_derivatives
309
310 CHARACTER(len=*), PARAMETER :: routinen = 'get_external_potential'
311
312 CHARACTER(LEN=default_path_length) :: coupling_function
313 CHARACTER(LEN=default_string_length) :: def_error, this_error
314 CHARACTER(LEN=default_string_length), &
315 DIMENSION(:), POINTER :: my_par
316 INTEGER :: handle, j
317 INTEGER(kind=int_8) :: ipoint, npoints
318 LOGICAL :: check, my_force
319 REAL(kind=dp) :: dedf, dx, err, lerr
320 REAL(kind=dp), DIMENSION(:), POINTER :: my_val
321
322 CALL timeset(routinen, handle)
323 NULLIFY (my_par, my_val)
324 my_force = .false.
325 IF (PRESENT(calc_derivatives)) my_force = calc_derivatives
326 check = PRESENT(dfunc) .EQV. PRESENT(calc_derivatives)
327 cpassert(check)
328 CALL section_vals_val_get(ext_pot_section, "DX", r_val=dx)
329 CALL section_vals_val_get(ext_pot_section, "ERROR_LIMIT", r_val=lerr)
330 CALL get_generic_info(ext_pot_section, "FUNCTION", coupling_function, my_par, my_val, &
331 input_variables=["X", "Y", "Z"], i_rep_sec=1)
332 CALL initf(1)
333 CALL parsef(1, trim(coupling_function), my_par)
334
335 npoints = SIZE(r, 2, kind=int_8)
336
337 DO ipoint = 1, npoints
338 my_val(1) = r(1, ipoint)
339 my_val(2) = r(2, ipoint)
340 my_val(3) = r(3, ipoint)
341
342 IF (PRESENT(func)) func(ipoint) = evalf(1, my_val)
343 IF (my_force) THEN
344 DO j = 1, 3
345 dedf = evalfd(1, j, my_val, dx, err)
346 IF (abs(err) > lerr) THEN
347 WRITE (this_error, "(A,G12.6,A)") "(", err, ")"
348 WRITE (def_error, "(A,G12.6,A)") "(", lerr, ")"
349 CALL compress(this_error, .true.)
350 CALL compress(def_error, .true.)
351 CALL cp_warn(__location__, &
352 'ASSERTION (cond) failed at line '//cp_to_string(__line__)// &
353 ' Error '//trim(this_error)//' in computing numerical derivatives larger then'// &
354 trim(def_error)//' .')
355 END IF
356 dfunc(j, ipoint) = dedf
357 END DO
358 END IF
359 END DO
360 DEALLOCATE (my_par)
361 DEALLOCATE (my_val)
362 CALL finalizef()
363 CALL timestop(handle)
364 END SUBROUTINE get_external_potential
365
366! **************************************************************************************************
367!> \brief subroutine that interpolates the value of the external
368!> potential at position r based on the values on the realspace grid
369!> \param r ...
370!> \param grid external potential pw grid, vee
371!> \param func value of vee at r
372!> \param dfunc derivatives of vee at r
373!> \param calc_derivatives calc dfunc
374! **************************************************************************************************
375 SUBROUTINE interpolate_external_potential(r, grid, func, dfunc, calc_derivatives)
376 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: r
377 TYPE(pw_r3d_rs_type), POINTER :: grid
378 REAL(kind=dp), INTENT(OUT), OPTIONAL :: func, dfunc(3)
379 LOGICAL, INTENT(IN), OPTIONAL :: calc_derivatives
380
381 CHARACTER(len=*), PARAMETER :: routinen = 'interpolate_external_potential'
382
383 INTEGER :: buffer_i, buffer_j, buffer_k, &
384 data_source, fd_extra_point, handle, &
385 i, i_pbc, ip, j, j_pbc, k, k_pbc, &
386 my_rank, num_pe, tag
387 INTEGER, DIMENSION(3) :: lbounds, lbounds_local, lower_inds, &
388 ubounds, ubounds_local, upper_inds
389 LOGICAL :: check, my_force
390 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: bcast_buffer
391 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: grid_buffer
392 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: dgrid
393 REAL(kind=dp), DIMENSION(3) :: dr, subgrid_origin
394 TYPE(mp_comm_type) :: gid
395
396 CALL timeset(routinen, handle)
397 my_force = .false.
398 IF (PRESENT(calc_derivatives)) my_force = calc_derivatives
399 check = PRESENT(dfunc) .EQV. PRESENT(calc_derivatives)
400 cpassert(check)
401
402 IF (my_force) THEN
403 ALLOCATE (grid_buffer(0:3, 0:3, 0:3))
404 ALLOCATE (bcast_buffer(0:3))
405 ALLOCATE (dgrid(1:2, 1:2, 1:2, 3))
406 fd_extra_point = 1
407 ELSE
408 ALLOCATE (grid_buffer(1:2, 1:2, 1:2))
409 ALLOCATE (bcast_buffer(1:2))
410 fd_extra_point = 0
411 END IF
412
413 ! The values of external potential on grid are distributed among the
414 ! processes, so first we have to gather them up
415 gid = grid%pw_grid%para%group
416 my_rank = grid%pw_grid%para%group%mepos
417 num_pe = grid%pw_grid%para%group%num_pe
418 tag = 1
419
420 dr = grid%pw_grid%dr
421 lbounds = grid%pw_grid%bounds(1, :)
422 ubounds = grid%pw_grid%bounds(2, :)
423 lbounds_local = grid%pw_grid%bounds_local(1, :)
424 ubounds_local = grid%pw_grid%bounds_local(2, :)
425
426 ! Determine the indices of grid points that are needed
427 lower_inds = lbounds + floor(r/dr) - fd_extra_point
428 upper_inds = lower_inds + 1 + 2*fd_extra_point
429
430 DO i = lower_inds(1), upper_inds(1)
431 ! If index is out of global bounds, assume periodic boundary conditions
432 i_pbc = pbc_index(i, lbounds(1), ubounds(1))
433 buffer_i = i - lower_inds(1) + 1 - fd_extra_point
434 DO j = lower_inds(2), upper_inds(2)
435 j_pbc = pbc_index(j, lbounds(2), ubounds(2))
436 buffer_j = j - lower_inds(2) + 1 - fd_extra_point
437
438 ! Find the process that has the data for indices i_pbc and j_pbc
439 ! and store the data to bcast_buffer. Assuming that each process has full z data
440 IF (grid%pw_grid%para%mode /= pw_mode_local) THEN
441 DO ip = 0, num_pe - 1
442 IF (grid%pw_grid%para%bo(1, 1, ip, 1) <= i_pbc - lbounds(1) + 1 .AND. &
443 grid%pw_grid%para%bo(2, 1, ip, 1) >= i_pbc - lbounds(1) + 1 .AND. &
444 grid%pw_grid%para%bo(1, 2, ip, 1) <= j_pbc - lbounds(2) + 1 .AND. &
445 grid%pw_grid%para%bo(2, 2, ip, 1) >= j_pbc - lbounds(2) + 1) THEN
446 data_source = ip
447 EXIT
448 END IF
449 END DO
450 IF (my_rank == data_source) THEN
451 IF (lower_inds(3) >= lbounds(3) .AND. upper_inds(3) <= ubounds(3)) THEN
452 bcast_buffer(:) = &
453 grid%array(i_pbc, j_pbc, lower_inds(3):upper_inds(3))
454 ELSE
455 DO k = lower_inds(3), upper_inds(3)
456 k_pbc = pbc_index(k, lbounds(3), ubounds(3))
457 buffer_k = k - lower_inds(3) + 1 - fd_extra_point
458 bcast_buffer(buffer_k) = &
459 grid%array(i_pbc, j_pbc, k_pbc)
460 END DO
461 END IF
462 END IF
463 ! data_source sends data to everyone
464 CALL gid%bcast(bcast_buffer, data_source)
465 grid_buffer(buffer_i, buffer_j, :) = bcast_buffer
466 ELSE
467 grid_buffer(buffer_i, buffer_j, :) = grid%array(i_pbc, j_pbc, lower_inds(3):upper_inds(3))
468 END IF
469 END DO
470 END DO
471
472 ! Now that all the processes have local external potential data around r,
473 ! interpolate the value at r
474 subgrid_origin = (lower_inds - lbounds + fd_extra_point)*dr
475 func = trilinear_interpolation(r, grid_buffer(1:2, 1:2, 1:2), subgrid_origin, dr)
476
477 ! If the derivative of the potential is needed, approximate the derivative at grid
478 ! points using finite differences, and then interpolate the value at r
479 IF (my_force) THEN
480 CALL d_finite_difference(grid_buffer, dr, dgrid)
481 DO i = 1, 3
482 dfunc(i) = trilinear_interpolation(r, dgrid(:, :, :, i), subgrid_origin, dr)
483 END DO
484 DEALLOCATE (dgrid)
485 END IF
486
487 DEALLOCATE (grid_buffer)
488 CALL timestop(handle)
489 END SUBROUTINE interpolate_external_potential
490
491! **************************************************************************************************
492!> \brief subroutine that uses finite differences to approximate the partial
493!> derivatives of the potential based on the given values on grid
494!> \param grid tiny bit of external potential vee
495!> \param dr step size for finite difference
496!> \param dgrid derivatives of grid
497! **************************************************************************************************
498 PURE SUBROUTINE d_finite_difference(grid, dr, dgrid)
499 REAL(kind=dp), DIMENSION(0:, 0:, 0:), INTENT(IN) :: grid
500 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: dr
501 REAL(kind=dp), DIMENSION(1:, 1:, 1:, :), &
502 INTENT(OUT) :: dgrid
503
504 INTEGER :: i, j, k
505
506 DO i = 1, SIZE(dgrid, 1)
507 DO j = 1, SIZE(dgrid, 2)
508 DO k = 1, SIZE(dgrid, 3)
509 dgrid(i, j, k, 1) = 0.5_dp*(grid(i + 1, j, k) - grid(i - 1, j, k))/dr(1)
510 dgrid(i, j, k, 2) = 0.5_dp*(grid(i, j + 1, k) - grid(i, j - 1, k))/dr(2)
511 dgrid(i, j, k, 3) = 0.5_dp*(grid(i, j, k + 1) - grid(i, j, k - 1))/dr(3)
512 END DO
513 END DO
514 END DO
515 END SUBROUTINE d_finite_difference
516
517! **************************************************************************************************
518!> \brief trilinear interpolation function that interpolates value at r based
519!> on 2x2x2 grid points around r in subgrid
520!> \param r where to interpolate to
521!> \param subgrid part of external potential on a grid
522!> \param origin center of grid
523!> \param dr step size
524!> \return interpolated value of external potential
525! **************************************************************************************************
526 PURE FUNCTION trilinear_interpolation(r, subgrid, origin, dr) RESULT(value_at_r)
527 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: r
528 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: subgrid
529 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: origin, dr
530 REAL(kind=dp) :: value_at_r
531
532 REAL(kind=dp), DIMENSION(3) :: norm_r, norm_r_rev
533
534 norm_r = (r - origin)/dr
535 norm_r_rev = 1 - norm_r
536 value_at_r = subgrid(1, 1, 1)*product(norm_r_rev) + &
537 subgrid(2, 1, 1)*norm_r(1)*norm_r_rev(2)*norm_r_rev(3) + &
538 subgrid(1, 2, 1)*norm_r_rev(1)*norm_r(2)*norm_r_rev(3) + &
539 subgrid(1, 1, 2)*norm_r_rev(1)*norm_r_rev(2)*norm_r(3) + &
540 subgrid(1, 2, 2)*norm_r_rev(1)*norm_r(2)*norm_r(3) + &
541 subgrid(2, 1, 2)*norm_r(1)*norm_r_rev(2)*norm_r(3) + &
542 subgrid(2, 2, 1)*norm_r(1)*norm_r(2)*norm_r_rev(3) + &
543 subgrid(2, 2, 2)*product(norm_r)
544 END FUNCTION trilinear_interpolation
545
546! **************************************************************************************************
547!> \brief get a correct value for possible out of bounds index using periodic
548!> boundary conditions
549!> \param i ...
550!> \param lowbound ...
551!> \param upbound ...
552!> \return ...
553! **************************************************************************************************
554 ELEMENTAL FUNCTION pbc_index(i, lowbound, upbound)
555 INTEGER, INTENT(IN) :: i, lowbound, upbound
556 INTEGER :: pbc_index
557
558 IF (i < lowbound) THEN
559 pbc_index = upbound + i - lowbound + 1
560 ELSE IF (i > upbound) THEN
561 pbc_index = lowbound + i - upbound - 1
562 ELSE
563 pbc_index = i
564 END IF
565 END FUNCTION pbc_index
566
567END MODULE qs_external_potential
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
various routines to log and control the output. The idea is that decisions about where to log should ...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_cube_to_pw(grid, filename, scaling, silent)
Thin wrapper around routine cube_to_pw.
subroutine, public get_generic_info(gen_section, func_name, xfunction, parameters, values, var_values, size_variables, i_rep_sec, input_variables)
Reads from the input structure all information for generic functions.
This public domain function parser module is intended for applications where a set of mathematical ex...
Definition fparser.F:17
subroutine, public parsef(i, funcstr, var)
Parse ith function string FuncStr and compile it into bytecode.
Definition fparser.F:174
real(rn) function, public evalf(i, val)
...
Definition fparser.F:206
real(kind=rn) function, public evalfd(id_fun, ipar, vals, h, err)
Evaluates derivatives.
Definition fparser.F:1097
subroutine, public finalizef()
...
Definition fparser.F:127
subroutine, public initf(n)
...
Definition fparser.F:156
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Interface to Maxwell equation solver.
subroutine, public maxwell_solver(maxwell_control, v_ee, sim_step, sim_time, scaling_factor)
Computes the external potential on the grid.
Interface to the message passing library MPI.
Define the data structure for the particle information.
integer, parameter, public pw_mode_local
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Routines to handle an external electrostatic field The external field can be generic and is provided ...
subroutine, public interpolate_external_potential(r, grid, func, dfunc, calc_derivatives)
subroutine that interpolates the value of the external potential at position r based on the values on...
subroutine, public external_c_potential(qs_env, calculate_forces)
Computes the force and the energy due to the external potential on the cores.
subroutine, public external_e_potential(qs_env)
Computes the external potential on the grid.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
Provides all information about a quickstep kind.