(git:3f0d10b)
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
20 USE fparser, ONLY: evalf,&
21 evalfd,&
22 finalizef,&
23 initf,&
24 parsef
28 USE kinds, ONLY: default_path_length,&
30 dp,&
31 int_8
36 USE pw_methods, ONLY: pw_zero
37 USE pw_types, ONLY: pw_r3d_rs_type
42 USE qs_kind_types, ONLY: get_qs_kind,&
44 USE string_utilities, ONLY: compress
45#include "./base/base_uses.f90"
46
47 IMPLICIT NONE
48
49 PRIVATE
50
51 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_external_potential'
52
53! *** Public subroutines ***
54 PUBLIC :: external_e_potential, &
57
58CONTAINS
59
60! **************************************************************************************************
61!> \brief Computes the external potential on the grid
62!> \param qs_env ...
63!> \date 12.2009
64!> \author Teodoro Laino [tlaino]
65! **************************************************************************************************
66 SUBROUTINE external_e_potential(qs_env)
67
68 TYPE(qs_environment_type), POINTER :: qs_env
69
70 CHARACTER(len=*), PARAMETER :: routinen = 'external_e_potential'
71
72 INTEGER :: handle, i, j, k
73 INTEGER(kind=int_8) :: npoints
74 INTEGER, DIMENSION(2, 3) :: bo_global, bo_local
75 REAL(kind=dp) :: dvol, scaling_factor
76 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: efunc, grid_p_i, grid_p_j, grid_p_k
77 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: grid_p
78 REAL(kind=dp), DIMENSION(3) :: dr
79 TYPE(dft_control_type), POINTER :: dft_control
80 TYPE(pw_r3d_rs_type), POINTER :: v_ee
81 TYPE(section_vals_type), POINTER :: ext_pot_section, input
82
83 CALL timeset(routinen, handle)
84 CALL get_qs_env(qs_env, dft_control=dft_control)
85 IF (dft_control%apply_external_potential) THEN
86 IF (dft_control%eval_external_potential) THEN
87 CALL get_qs_env(qs_env, vee=v_ee)
88 IF (dft_control%expot_control%maxwell_solver) THEN
89 scaling_factor = dft_control%expot_control%scaling_factor
90 CALL maxwell_solver(dft_control%maxwell_control, v_ee, &
91 qs_env%sim_step, qs_env%sim_time, &
92 scaling_factor)
93 dft_control%eval_external_potential = .false.
94 ELSE IF (dft_control%expot_control%read_from_cube) THEN
95 scaling_factor = dft_control%expot_control%scaling_factor
96 CALL cp_cube_to_pw(v_ee, 'pot.cube', scaling_factor)
97 dft_control%eval_external_potential = .false.
98 ELSE
99 CALL get_qs_env(qs_env, input=input)
100 ext_pot_section => section_vals_get_subs_vals(input, "DFT%EXTERNAL_POTENTIAL")
101
102 dr = v_ee%pw_grid%dr
103 dvol = v_ee%pw_grid%dvol
104 CALL pw_zero(v_ee)
105
106 bo_local = v_ee%pw_grid%bounds_local
107 bo_global = v_ee%pw_grid%bounds
108
109 npoints = int(bo_local(2, 1) - bo_local(1, 1) + 1, kind=int_8)* &
110 int(bo_local(2, 2) - bo_local(1, 2) + 1, kind=int_8)* &
111 int(bo_local(2, 3) - bo_local(1, 3) + 1, kind=int_8)
112 ALLOCATE (efunc(npoints))
113 ALLOCATE (grid_p(3, npoints))
114 ALLOCATE (grid_p_i(bo_local(1, 1):bo_local(2, 1)))
115 ALLOCATE (grid_p_j(bo_local(1, 2):bo_local(2, 2)))
116 ALLOCATE (grid_p_k(bo_local(1, 3):bo_local(2, 3)))
117
118 DO i = bo_local(1, 1), bo_local(2, 1)
119 grid_p_i(i) = (i - bo_global(1, 1))*dr(1)
120 END DO
121 DO j = bo_local(1, 2), bo_local(2, 2)
122 grid_p_j(j) = (j - bo_global(1, 2))*dr(2)
123 END DO
124 DO k = bo_local(1, 3), bo_local(2, 3)
125 grid_p_k(k) = (k - bo_global(1, 3))*dr(3)
126 END DO
127
128 npoints = 0
129 DO k = bo_local(1, 3), bo_local(2, 3)
130 DO j = bo_local(1, 2), bo_local(2, 2)
131 DO i = bo_local(1, 1), bo_local(2, 1)
132 npoints = npoints + 1
133 grid_p(1, npoints) = grid_p_i(i)
134 grid_p(2, npoints) = grid_p_j(j)
135 grid_p(3, npoints) = grid_p_k(k)
136 END DO
137 END DO
138 END DO
139
140 DEALLOCATE (grid_p_i, grid_p_j, grid_p_k)
141
142 CALL get_external_potential(grid_p, ext_pot_section, func=efunc)
143
144 npoints = 0
145 DO k = bo_local(1, 3), bo_local(2, 3)
146 DO j = bo_local(1, 2), bo_local(2, 2)
147 DO i = bo_local(1, 1), bo_local(2, 1)
148 npoints = npoints + 1
149 v_ee%array(i, j, k) = v_ee%array(i, j, k) + efunc(npoints)
150 END DO
151 END DO
152 END DO
153
154 DEALLOCATE (grid_p, efunc)
155
156 dft_control%eval_external_potential = .false.
157 END IF
158 END IF
159 END IF
160 CALL timestop(handle)
161 END SUBROUTINE external_e_potential
162
163! **************************************************************************************************
164!> \brief Computes the force and the energy due to the external potential on the cores
165!> \param qs_env ...
166!> \param calculate_forces ...
167!> \date 12.2009
168!> \author Teodoro Laino [tlaino]
169! **************************************************************************************************
170 SUBROUTINE external_c_potential(qs_env, calculate_forces)
171
172 TYPE(qs_environment_type), POINTER :: qs_env
173 LOGICAL, OPTIONAL :: calculate_forces
174
175 CHARACTER(len=*), PARAMETER :: routinen = 'external_c_potential'
176
177 INTEGER :: atom_a, handle, iatom, ikind, natom, &
178 nkind, nparticles
179 INTEGER, DIMENSION(:), POINTER :: list
180 LOGICAL :: my_force, pot_on_grid
181 REAL(kind=dp) :: ee_core_ener, zeff
182 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: efunc
183 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: dfunc, r
184 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
185 TYPE(cell_type), POINTER :: cell
186 TYPE(dft_control_type), POINTER :: dft_control
187 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
188 TYPE(pw_r3d_rs_type), POINTER :: v_ee
189 TYPE(qs_energy_type), POINTER :: energy
190 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
191 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
192 TYPE(section_vals_type), POINTER :: ext_pot_section, input
193
194 CALL timeset(routinen, handle)
195 NULLIFY (dft_control)
196
197 CALL get_qs_env(qs_env=qs_env, &
198 atomic_kind_set=atomic_kind_set, &
199 qs_kind_set=qs_kind_set, &
200 energy=energy, &
201 particle_set=particle_set, &
202 input=input, &
203 cell=cell, &
204 dft_control=dft_control)
205
206 IF (dft_control%apply_external_potential .AND. .NOT. qs_env%mimic) THEN
207 !ensure that external potential is loaded to grid
208 IF (dft_control%eval_external_potential) THEN
209 CALL external_e_potential(qs_env)
210 END IF
211 my_force = .false.
212 IF (PRESENT(calculate_forces)) my_force = calculate_forces
213 ee_core_ener = 0.0_dp
214 nkind = SIZE(atomic_kind_set)
215
216 !check if external potential on grid has been loaded from a file instead of giving a function
217 IF (dft_control%expot_control%read_from_cube .OR. &
218 dft_control%expot_control%maxwell_solver) THEN
219 CALL get_qs_env(qs_env, vee=v_ee)
220 pot_on_grid = .true.
221 ELSE
222 pot_on_grid = .false.
223 ext_pot_section => section_vals_get_subs_vals(input, "DFT%EXTERNAL_POTENTIAL")
224 END IF
225
226 nparticles = 0
227 DO ikind = 1, SIZE(atomic_kind_set)
228 CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
229 nparticles = nparticles + max(natom, 0)
230 END DO
231
232 ALLOCATE (efunc(nparticles))
233 ALLOCATE (dfunc(3, nparticles), r(3, nparticles))
234
235 nparticles = 0
236 DO ikind = 1, SIZE(atomic_kind_set)
237 CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=list, natom=natom)
238
239 DO iatom = 1, natom
240 atom_a = list(iatom)
241 nparticles = nparticles + 1
242 !pbc returns r(i) in range [-cell%hmat(i,i)/2, cell%hmat(i,i)/2]
243 !for periodic dimensions (assuming the cell is orthorombic).
244 !This is not consistent with the potential on grid, where r(i) is
245 !in range [0, cell%hmat(i,i)]
246 !Use new pbc function with switch positive_range=.TRUE.
247 r(:, nparticles) = pbc(particle_set(atom_a)%r(:), cell, positive_range=.true.)
248 END DO
249 END DO
250
251 !if potential is on grid, interpolate the value at r,
252 !otherwise evaluate the given function
253 IF (pot_on_grid) THEN
254 DO iatom = 1, nparticles
255 CALL interpolate_external_potential(r(:, iatom), v_ee, func=efunc(iatom), &
256 dfunc=dfunc(:, iatom), calc_derivatives=my_force)
257 END DO
258 ELSE
259 CALL get_external_potential(r, ext_pot_section, func=efunc, dfunc=dfunc, calc_derivatives=my_force)
260 END IF
261
262 IF (my_force) THEN
263 CALL get_qs_env(qs_env=qs_env, force=force)
264 END IF
265
266 nparticles = 0
267 DO ikind = 1, SIZE(atomic_kind_set)
268 CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
269 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
270
271 DO iatom = 1, natom
272 nparticles = nparticles + 1
273
274 ee_core_ener = ee_core_ener + zeff*efunc(nparticles)
275 IF (my_force) THEN
276 force(ikind)%eev(1:3, iatom) = dfunc(1:3, nparticles)*zeff
277 END IF
278 END DO
279 END DO
280 energy%ee_core = ee_core_ener
281
282 DEALLOCATE (dfunc, r)
283 DEALLOCATE (efunc)
284 END IF
285 CALL timestop(handle)
286 END SUBROUTINE external_c_potential
287
288! **************************************************************************************************
289!> \brief Low level function for computing the potential and the derivatives
290!> \param r position in realspace for each grid-point
291!> \param ext_pot_section ...
292!> \param func external potential at r
293!> \param dfunc derivative of the external potential at r
294!> \param calc_derivatives Whether to calculate dfunc
295!> \date 12.2009
296!> \par History
297!> 12.2009 created [tlaino]
298!> 11.2014 reading external cube file added [Juha Ritala & Matt Watkins]
299!> \author Teodoro Laino [tlaino]
300! **************************************************************************************************
301 SUBROUTINE get_external_potential(r, ext_pot_section, func, dfunc, calc_derivatives)
302 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: r
303 TYPE(section_vals_type), POINTER :: ext_pot_section
304 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: func
305 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT), &
306 OPTIONAL :: dfunc
307 LOGICAL, INTENT(IN), OPTIONAL :: calc_derivatives
308
309 CHARACTER(len=*), PARAMETER :: routinen = 'get_external_potential'
310
311 CHARACTER(LEN=default_path_length) :: coupling_function
312 CHARACTER(LEN=default_string_length) :: def_error, this_error
313 CHARACTER(LEN=default_string_length), &
314 ALLOCATABLE, DIMENSION(:) :: my_par
315 INTEGER :: handle, j
316 INTEGER(kind=int_8) :: ipoint, npoints
317 LOGICAL :: check, my_force
318 REAL(kind=dp) :: dedf, dx, err, lerr
319 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: my_val
320
321 CALL timeset(routinen, handle)
322 my_force = .false.
323 IF (PRESENT(calc_derivatives)) my_force = calc_derivatives
324 check = PRESENT(dfunc) .EQV. PRESENT(calc_derivatives)
325 cpassert(check)
326 CALL parse_function_section(ext_pot_section, "FUNCTION", coupling_function, &
327 my_par, my_val, i_rep_sec=1, &
328 input_variables=["X", "Y", "Z"], dx=dx, error_limit=lerr)
329 CALL initf(1)
330 CALL parsef(1, trim(coupling_function), my_par)
331
332 npoints = SIZE(r, 2, kind=int_8)
333
334 DO ipoint = 1, npoints
335 my_val(1) = r(1, ipoint)
336 my_val(2) = r(2, ipoint)
337 my_val(3) = r(3, ipoint)
338
339 IF (PRESENT(func)) func(ipoint) = evalf(1, my_val)
340 IF (my_force) THEN
341 DO j = 1, 3
342 dedf = evalfd(1, j, my_val, dx, err)
343 IF (abs(err) > lerr) THEN
344 WRITE (this_error, "(A,G12.6,A)") "(", err, ")"
345 WRITE (def_error, "(A,G12.6,A)") "(", lerr, ")"
346 CALL compress(this_error, .true.)
347 CALL compress(def_error, .true.)
348 CALL cp_warn(__location__, &
349 'ASSERTION (cond) failed at line '//cp_to_string(__line__)// &
350 ' Error '//trim(this_error)//' in computing numerical derivatives larger than'// &
351 trim(def_error)//' .')
352 END IF
353 dfunc(j, ipoint) = dedf
354 END DO
355 END IF
356 END DO
357 DEALLOCATE (my_par)
358 DEALLOCATE (my_val)
359 CALL finalizef()
360 CALL timestop(handle)
361 END SUBROUTINE get_external_potential
362
363! **************************************************************************************************
364!> \brief subroutine that interpolates the value of the external
365!> potential at position r based on the values on the realspace grid
366!> \param r ...
367!> \param grid external potential pw grid, vee
368!> \param func value of vee at r
369!> \param dfunc derivatives of vee at r
370!> \param calc_derivatives calc dfunc
371! **************************************************************************************************
372 SUBROUTINE interpolate_external_potential(r, grid, func, dfunc, calc_derivatives)
373 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: r
374 TYPE(pw_r3d_rs_type), POINTER :: grid
375 REAL(kind=dp), INTENT(OUT), OPTIONAL :: func, dfunc(3)
376 LOGICAL, INTENT(IN), OPTIONAL :: calc_derivatives
377
378 CHARACTER(len=*), PARAMETER :: routinen = 'interpolate_external_potential'
379
380 INTEGER :: buffer_i, buffer_j, buffer_k, &
381 data_source, fd_extra_point, handle, &
382 i, i_pbc, ip, j, j_pbc, k, k_pbc, &
383 my_rank, num_pe, tag
384 INTEGER, DIMENSION(3) :: lbounds, lbounds_local, lower_inds, &
385 ubounds, ubounds_local, upper_inds
386 LOGICAL :: check, my_force
387 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: bcast_buffer
388 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: grid_buffer
389 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: dgrid
390 REAL(kind=dp), DIMENSION(3) :: dr, subgrid_origin
391 TYPE(mp_comm_type) :: gid
392
393 CALL timeset(routinen, handle)
394 my_force = .false.
395 IF (PRESENT(calc_derivatives)) my_force = calc_derivatives
396 check = PRESENT(dfunc) .EQV. PRESENT(calc_derivatives)
397 cpassert(check)
398
399 IF (my_force) THEN
400 ALLOCATE (grid_buffer(0:3, 0:3, 0:3))
401 ALLOCATE (bcast_buffer(0:3))
402 ALLOCATE (dgrid(1:2, 1:2, 1:2, 3))
403 fd_extra_point = 1
404 ELSE
405 ALLOCATE (grid_buffer(1:2, 1:2, 1:2))
406 ALLOCATE (bcast_buffer(1:2))
407 fd_extra_point = 0
408 END IF
409
410 ! The values of external potential on grid are distributed among the
411 ! processes, so first we have to gather them up
412 gid = grid%pw_grid%para%group
413 my_rank = grid%pw_grid%para%group%mepos
414 num_pe = grid%pw_grid%para%group%num_pe
415 tag = 1
416
417 dr = grid%pw_grid%dr
418 lbounds = grid%pw_grid%bounds(1, :)
419 ubounds = grid%pw_grid%bounds(2, :)
420 lbounds_local = grid%pw_grid%bounds_local(1, :)
421 ubounds_local = grid%pw_grid%bounds_local(2, :)
422
423 ! Determine the indices of grid points that are needed
424 lower_inds = lbounds + floor(r/dr) - fd_extra_point
425 upper_inds = lower_inds + 1 + 2*fd_extra_point
426
427 DO i = lower_inds(1), upper_inds(1)
428 ! If index is out of global bounds, assume periodic boundary conditions
429 i_pbc = pbc_index(i, lbounds(1), ubounds(1))
430 buffer_i = i - lower_inds(1) + 1 - fd_extra_point
431 DO j = lower_inds(2), upper_inds(2)
432 j_pbc = pbc_index(j, lbounds(2), ubounds(2))
433 buffer_j = j - lower_inds(2) + 1 - fd_extra_point
434
435 ! Find the process that has the data for indices i_pbc and j_pbc
436 ! and store the data to bcast_buffer. Assuming that each process has full z data
437 IF (grid%pw_grid%para%mode /= pw_mode_local) THEN
438 DO ip = 0, num_pe - 1
439 IF (grid%pw_grid%para%bo(1, 1, ip, 1) <= i_pbc - lbounds(1) + 1 .AND. &
440 grid%pw_grid%para%bo(2, 1, ip, 1) >= i_pbc - lbounds(1) + 1 .AND. &
441 grid%pw_grid%para%bo(1, 2, ip, 1) <= j_pbc - lbounds(2) + 1 .AND. &
442 grid%pw_grid%para%bo(2, 2, ip, 1) >= j_pbc - lbounds(2) + 1) THEN
443 data_source = ip
444 EXIT
445 END IF
446 END DO
447 IF (my_rank == data_source) THEN
448 IF (lower_inds(3) >= lbounds(3) .AND. upper_inds(3) <= ubounds(3)) THEN
449 bcast_buffer(:) = &
450 grid%array(i_pbc, j_pbc, lower_inds(3):upper_inds(3))
451 ELSE
452 DO k = lower_inds(3), upper_inds(3)
453 k_pbc = pbc_index(k, lbounds(3), ubounds(3))
454 buffer_k = k - lower_inds(3) + 1 - fd_extra_point
455 bcast_buffer(buffer_k) = &
456 grid%array(i_pbc, j_pbc, k_pbc)
457 END DO
458 END IF
459 END IF
460 ! data_source sends data to everyone
461 CALL gid%bcast(bcast_buffer, data_source)
462 grid_buffer(buffer_i, buffer_j, :) = bcast_buffer
463 ELSE
464 grid_buffer(buffer_i, buffer_j, :) = grid%array(i_pbc, j_pbc, lower_inds(3):upper_inds(3))
465 END IF
466 END DO
467 END DO
468
469 ! Now that all the processes have local external potential data around r,
470 ! interpolate the value at r
471 subgrid_origin = (lower_inds - lbounds + fd_extra_point)*dr
472 func = trilinear_interpolation(r, grid_buffer(1:2, 1:2, 1:2), subgrid_origin, dr)
473
474 ! If the derivative of the potential is needed, approximate the derivative at grid
475 ! points using finite differences, and then interpolate the value at r
476 IF (my_force) THEN
477 CALL d_finite_difference(grid_buffer, dr, dgrid)
478 DO i = 1, 3
479 dfunc(i) = trilinear_interpolation(r, dgrid(:, :, :, i), subgrid_origin, dr)
480 END DO
481 DEALLOCATE (dgrid)
482 END IF
483
484 DEALLOCATE (grid_buffer)
485 CALL timestop(handle)
486 END SUBROUTINE interpolate_external_potential
487
488! **************************************************************************************************
489!> \brief subroutine that uses finite differences to approximate the partial
490!> derivatives of the potential based on the given values on grid
491!> \param grid tiny bit of external potential vee
492!> \param dr step size for finite difference
493!> \param dgrid derivatives of grid
494! **************************************************************************************************
495 PURE SUBROUTINE d_finite_difference(grid, dr, dgrid)
496 REAL(kind=dp), DIMENSION(0:, 0:, 0:), INTENT(IN) :: grid
497 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: dr
498 REAL(kind=dp), DIMENSION(1:, 1:, 1:, :), &
499 INTENT(OUT) :: dgrid
500
501 INTEGER :: i, j, k
502
503 DO i = 1, SIZE(dgrid, 1)
504 DO j = 1, SIZE(dgrid, 2)
505 DO k = 1, SIZE(dgrid, 3)
506 dgrid(i, j, k, 1) = 0.5_dp*(grid(i + 1, j, k) - grid(i - 1, j, k))/dr(1)
507 dgrid(i, j, k, 2) = 0.5_dp*(grid(i, j + 1, k) - grid(i, j - 1, k))/dr(2)
508 dgrid(i, j, k, 3) = 0.5_dp*(grid(i, j, k + 1) - grid(i, j, k - 1))/dr(3)
509 END DO
510 END DO
511 END DO
512 END SUBROUTINE d_finite_difference
513
514! **************************************************************************************************
515!> \brief trilinear interpolation function that interpolates value at r based
516!> on 2x2x2 grid points around r in subgrid
517!> \param r where to interpolate to
518!> \param subgrid part of external potential on a grid
519!> \param origin center of grid
520!> \param dr step size
521!> \return interpolated value of external potential
522! **************************************************************************************************
523 PURE FUNCTION trilinear_interpolation(r, subgrid, origin, dr) RESULT(value_at_r)
524 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: r
525 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: subgrid
526 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: origin, dr
527 REAL(kind=dp) :: value_at_r
528
529 REAL(kind=dp), DIMENSION(3) :: norm_r, norm_r_rev
530
531 norm_r = (r - origin)/dr
532 norm_r_rev = 1 - norm_r
533 value_at_r = subgrid(1, 1, 1)*product(norm_r_rev) + &
534 subgrid(2, 1, 1)*norm_r(1)*norm_r_rev(2)*norm_r_rev(3) + &
535 subgrid(1, 2, 1)*norm_r_rev(1)*norm_r(2)*norm_r_rev(3) + &
536 subgrid(1, 1, 2)*norm_r_rev(1)*norm_r_rev(2)*norm_r(3) + &
537 subgrid(1, 2, 2)*norm_r_rev(1)*norm_r(2)*norm_r(3) + &
538 subgrid(2, 1, 2)*norm_r(1)*norm_r_rev(2)*norm_r(3) + &
539 subgrid(2, 2, 1)*norm_r(1)*norm_r(2)*norm_r_rev(3) + &
540 subgrid(2, 2, 2)*product(norm_r)
541 END FUNCTION trilinear_interpolation
542
543! **************************************************************************************************
544!> \brief get a correct value for possible out of bounds index using periodic
545!> boundary conditions
546!> \param i ...
547!> \param lowbound ...
548!> \param upbound ...
549!> \return ...
550! **************************************************************************************************
551 ELEMENTAL FUNCTION pbc_index(i, lowbound, upbound)
552 INTEGER, INTENT(IN) :: i, lowbound, upbound
553 INTEGER :: pbc_index
554
555 IF (i < lowbound) THEN
556 pbc_index = upbound + i - lowbound + 1
557 ELSE IF (i > upbound) THEN
558 pbc_index = lowbound + i - upbound - 1
559 ELSE
560 pbc_index = i
561 END IF
562 END FUNCTION pbc_index
563
564END 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.
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
Creates and parses an input section to define a generic function.
subroutine, public parse_function_section(gen_section, func_name, xfunction, parameters, values, var_values, i_rep_sec, input_variables, dx, error_limit)
Reads from the input structure all information for generic functions.
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
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.