(git:374b731)
Loading...
Searching...
No Matches
qmmm_elpot.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \par History
10!> 09.2004 created [tlaino]
11!> \author Teodoro Laino
12! **************************************************************************************************
14 USE cell_types, ONLY: cell_type
18 USE cp_output_handling, ONLY: cp_p_file,&
27 USE kinds, ONLY: default_path_length,&
29 dp
30 USE mathconstants, ONLY: rootpi
34 USE qmmm_types_low, ONLY: qmmm_pot_type,&
36#include "./base/base_uses.f90"
37
38 IMPLICIT NONE
39 PRIVATE
40
41 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
42 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qmmm_elpot'
43 PUBLIC :: qmmm_potential_init
44
45CONTAINS
46
47! **************************************************************************************************
48!> \brief Initialize the QMMM potential stored on vector,
49!> according the qmmm_coupl_type
50!> \param qmmm_coupl_type ...
51!> \param mm_el_pot_radius ...
52!> \param potentials ...
53!> \param pgfs ...
54!> \param mm_cell ...
55!> \param compatibility ...
56!> \param print_section ...
57!> \par History
58!> 09.2004 created [tlaino]
59!> \author Teodoro Laino
60! **************************************************************************************************
61 SUBROUTINE qmmm_potential_init(qmmm_coupl_type, mm_el_pot_radius, potentials, &
62 pgfs, mm_cell, compatibility, print_section)
63 INTEGER, INTENT(IN) :: qmmm_coupl_type
64 REAL(kind=dp), DIMENSION(:), POINTER :: mm_el_pot_radius
65 TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER :: potentials
66 TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER :: pgfs
67 TYPE(cell_type), POINTER :: mm_cell
68 LOGICAL, INTENT(IN) :: compatibility
69 TYPE(section_vals_type), POINTER :: print_section
70
71 REAL(kind=dp), PARAMETER :: dx = 0.05_dp
72
73 CHARACTER(LEN=default_path_length) :: myformat
74 CHARACTER(LEN=default_string_length) :: rc_s
75 INTEGER :: i, ig, ig_start, j, k, myind, ndim, np, &
76 output_unit, unit_nr
77 INTEGER, DIMENSION(:), POINTER :: mm_atom_index
78 LOGICAL :: found
79 REAL(kind=dp) :: a, g, rc, rmax, rmin, t, t1, t2, x
80 REAL(kind=dp), DIMENSION(:), POINTER :: radius
81 REAL(kind=dp), DIMENSION(:, :), POINTER :: pot0_2
82 TYPE(cp_logger_type), POINTER :: logger
83 TYPE(qmmm_gaussian_type), POINTER :: pgf
84
85 logger => cp_get_default_logger()
86 output_unit = cp_logger_get_default_io_unit(logger)
87 rmin = 0.0_dp
88 rmax = sqrt(mm_cell%hmat(1, 1)**2 + &
89 mm_cell%hmat(2, 2)**2 + &
90 mm_cell%hmat(3, 3)**2)
91 np = ceiling(rmax/dx) + 1
92 !
93 ! Preprocessing
94 !
95 IF (SIZE(mm_el_pot_radius) /= 0) THEN
96 ALLOCATE (radius(1))
97 radius(1) = mm_el_pot_radius(1)
98 ELSE
99 ALLOCATE (radius(0))
100 END IF
101 loop_on_all_values: DO i = 2, SIZE(mm_el_pot_radius)
102 found = .false.
103 loop_on_found_values: DO j = 1, SIZE(radius)
104 IF (mm_el_pot_radius(i) .EQ. radius(j)) THEN
105 found = .true.
106 EXIT loop_on_found_values
107 END IF
108 END DO loop_on_found_values
109 IF (.NOT. found) THEN
110 ndim = SIZE(radius)
111 ndim = ndim + 1
112 CALL reallocate(radius, 1, ndim)
113 radius(ndim) = mm_el_pot_radius(i)
114 END IF
115 END DO loop_on_all_values
116 !
117 cpassert(.NOT. ASSOCIATED(potentials))
118 ALLOCATE (potentials(SIZE(radius)))
119
120 potential_type: DO k = 1, SIZE(radius)
121
122 rc = radius(k)
123 ALLOCATE (potentials(k)%Pot)
124 SELECT CASE (qmmm_coupl_type)
125 CASE (do_qmmm_coulomb)
126 NULLIFY (pot0_2)
127 CASE (do_qmmm_pcharge)
128 NULLIFY (pot0_2)
130 ALLOCATE (pot0_2(2, np))
131 END SELECT
132
133 SELECT CASE (qmmm_coupl_type)
135 ! Do Nothing
137 IF (qmmm_coupl_type == do_qmmm_gauss) THEN
138 ! Smooth Coulomb Potential :: Erf(x/rc)/x
139 pot0_2(1, 1) = 2.0_dp/(rootpi*rc)
140 pot0_2(2, 1) = 0.0_dp
141 x = 0.0_dp
142 DO i = 2, np
143 x = x + dx
144 pot0_2(1, i) = erf(x/rc)/x
145 t = 2._dp/(rootpi*x*rc)*exp(-(x/rc)**2)
146 pot0_2(2, i) = (t - pot0_2(1, i)/x)*dx
147 END DO
148 ELSEIF (qmmm_coupl_type == do_qmmm_swave) THEN
149 ! S-wave expansion :: 1/x - exp(-2*x/rc) * ( 1/x - 1/rc )
150 pot0_2(1, 1) = 1.0_dp/rc
151 pot0_2(2, 1) = 0.0_dp
152 x = 0.0_dp
153 DO i = 2, np
154 x = x + dx
155 t = exp(-2.0_dp*x/rc)/rc
156 pot0_2(1, i) = (1.0_dp - t*(rc + x))/x
157 pot0_2(2, i) = ((t*(rc**2 + 2.0_dp*rc*x + 2.0_dp*x**2)/rc - 1.0_dp)/x**2)*dx
158 END DO
159 END IF
160 pgf => pgfs(k)%pgf
161 cpassert(pgf%Elp_Radius == rc)
162 ig_start = 1
163 IF (compatibility .AND. (qmmm_coupl_type == do_qmmm_gauss)) ig_start = 2
164 DO ig = ig_start, pgf%number_of_gaussians
165 a = pgf%Ak(ig)
166 g = pgf%Gk(ig)
167 pot0_2(1, 1) = pot0_2(1, 1) - a
168 x = 0.0_dp
169 DO i = 2, np
170 x = x + dx
171 t = exp(-(x/g)**2)*a
172 t1 = 1/g**2
173 t2 = t1*t
174 pot0_2(1, i) = pot0_2(1, i) - t
175 pot0_2(2, i) = pot0_2(2, i) + 2.0_dp*x*t2*dx
176 END DO
177 END DO
178
179 ! Print info on the unidimensional MM electrostatic potential
180 IF (btest(cp_print_key_should_output(logger%iter_info, print_section, "MM_POTENTIAL") &
181 , cp_p_file)) THEN
182 WRITE (rc_s, '(F6.3)') rc
183 unit_nr = cp_print_key_unit_nr(logger, print_section, "MM_POTENTIAL", &
184 extension="_rc="//trim(adjustl(rc_s))//".data")
185 IF (unit_nr > 0) THEN
186 WRITE (unit_nr, '(A)') "# MM ELECTROSTATIC POTENTIAL - UNIDIMENSIONAL - ATOMIC UNITS"
187 WRITE (unit_nr, '(A,I5)') "# MM ELECTROSTATIC POTENTIAL - Nr. of Gaussians:", pgf%number_of_gaussians
188 WRITE (unit_nr, '(A,T10,A,T30,A,T300,A)') "#", "Xval", "Gaussians", "LongRange"
189 myformat = "T10,F15.9,T30,"
190 DO ig = 1, pgf%number_of_gaussians
191 myind = index(myformat, " ")
192 WRITE (myformat(myind:), '(A6)') "F12.9,"
193 END DO
194 myind = index(myformat, " ") - 1
195 myformat = myformat(1:myind)//"T300,F15.9"
196 myind = index(myformat, " ") - 1
197 x = 0.0_dp
198 DO i = 1, np
199 WRITE (unit_nr, '('//myformat(1:myind)//')') &
200 x, (exp(-(x/pgf%Gk(ig))**2)*pgf%Ak(ig), ig=1, pgf%number_of_gaussians), pot0_2(1, i)
201 x = x + dx
202 END DO
203 END IF
204 CALL cp_print_key_finished_output(unit_nr, logger, print_section, &
205 "MM_POTENTIAL")
206 END IF
207 CASE DEFAULT
208 DEALLOCATE (potentials(k)%Pot)
209 IF (output_unit > 0) WRITE (output_unit, '(A)') " QMMM Potential - Spline Interpolation - not Initialized!"
210 cycle potential_type
211 END SELECT
212 NULLIFY (mm_atom_index)
213 ALLOCATE (mm_atom_index(1))
214 ! Build mm_atom_index List
215 DO j = 1, SIZE(mm_el_pot_radius)
216 IF (rc .EQ. mm_el_pot_radius(j)) THEN
217 ndim = SIZE(mm_atom_index)
218 mm_atom_index(ndim) = j
219 CALL reallocate(mm_atom_index, 1, ndim + 1)
220 END IF
221 END DO
222 CALL reallocate(mm_atom_index, 1, ndim)
223
224 NULLIFY (potentials(k)%Pot%pot0_2)
225 CALL qmmm_pot_type_create(potentials(k)%Pot, pot0_2=pot0_2, &
226 rmax=rmax, rmin=rmin, dx=dx, rc=rc, npts=np, &
227 mm_atom_index=mm_atom_index)
228
229 END DO potential_type
230 DEALLOCATE (radius)
231 END SUBROUTINE qmmm_potential_init
232
233! **************************************************************************************************
234!> \brief Creates the qmmm_pot_type structure
235!> \param Pot ...
236!> \param pot0_2 ...
237!> \param Rmax ...
238!> \param Rmin ...
239!> \param dx ...
240!> \param npts ...
241!> \param rc ...
242!> \param mm_atom_index ...
243!> \par History
244!> 09.2004 created [tlaino]
245!> \author Teodoro Laino
246! **************************************************************************************************
247 SUBROUTINE qmmm_pot_type_create(Pot, pot0_2, Rmax, Rmin, dx, npts, rc, &
248 mm_atom_index)
249 TYPE(qmmm_pot_type), POINTER :: pot
250 REAL(kind=dp), DIMENSION(:, :), POINTER :: pot0_2
251 REAL(kind=dp), INTENT(IN) :: rmax, rmin, dx
252 INTEGER, INTENT(IN) :: npts
253 REAL(kind=dp), INTENT(IN) :: rc
254 INTEGER, DIMENSION(:), POINTER :: mm_atom_index
255
256 pot%pot0_2 => pot0_2
257 pot%mm_atom_index => mm_atom_index
258 pot%Rmax = rmax
259 pot%Rmin = rmin
260 pot%Rc = rc
261 pot%dx = dx
262 pot%npts = npts
263
264 END SUBROUTINE qmmm_pot_type_create
265
266END MODULE qmmm_elpot
Handles all functions related to the CELL.
Definition cell_types.F:15
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_qmmm_pcharge
integer, parameter, public do_qmmm_coulomb
integer, parameter, public do_qmmm_swave
integer, parameter, public do_qmmm_gauss
objects that represent the structure of input sections and the data contained in an input section
Defines the basic variable types.
Definition kinds.F:23
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
Definition of mathematical constants and functions.
real(kind=dp), parameter, public rootpi
Utility routines for the memory handling.
subroutine, public qmmm_potential_init(qmmm_coupl_type, mm_el_pot_radius, potentials, pgfs, mm_cell, compatibility, print_section)
Initialize the QMMM potential stored on vector, according the qmmm_coupl_type.
Definition qmmm_elpot.F:63
Sets the typo for the gaussian treatment of the qm/mm interaction.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represent a pointer to a qmmm_gaussian_type, to be able to create arrays of pointers
Real Space Potential.