(git:f7b9015)
Loading...
Searching...
No Matches
semi_empirical_mpole_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! **************************************************************************************************
9!> \brief Setup and Methods for semi-empirical multipole types
10!> \author Teodoro Laino [tlaino] - 08.2008 Zurich University
11! **************************************************************************************************
13
15 USE kinds, ONLY: dp
16 USE mathconstants, ONLY: sqrt3
18 indexa,&
19 indexb,&
29#include "./base/base_uses.f90"
30
31 IMPLICIT NONE
32
33 PRIVATE
34
35! *** Global parameters ***
36 LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .false.
37 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'semi_empirical_mpole_methods'
38
42
43CONTAINS
44
45! **************************************************************************************************
46!> \brief Setup semi-empirical mpole type
47!> This function setup for each semi-empirical type a structure containing
48!> the multipolar expansion for all possible combination on-site of atomic
49!> orbitals ( \mu \nu |
50!> \param mpoles ...
51!> \param se_parameter ...
52!> \param method ...
53!> \date 09.2008
54!> \author Teodoro Laino [tlaino] - University of Zurich
55! **************************************************************************************************
56 SUBROUTINE semi_empirical_mpole_p_setup(mpoles, se_parameter, method)
57 TYPE(semi_empirical_mpole_p_type), DIMENSION(:), &
58 POINTER :: mpoles
59 TYPE(semi_empirical_type), POINTER :: se_parameter
60 INTEGER, INTENT(IN) :: method
61
62 CHARACTER(LEN=3), DIMENSION(9), PARAMETER :: &
63 label_print_orb = [" s", " px", " py", " pz", "dx2", "dzx", "dz2", "dzy", "dxy"]
64 INTEGER, DIMENSION(9), PARAMETER :: loc_index = [1, 2, 2, 2, 3, 3, 3, 3, 3]
65
66 INTEGER :: a, b, i, ind1, ind2, j, k, k1, k2, mu, &
67 natorb, ndim, nr
68 REAL(kind=dp) :: dlm, tmp, wp, ws, zb, zp, zs, zt
69 REAL(kind=dp), DIMENSION(3, 3, 45) :: m2
70 REAL(kind=dp), DIMENSION(3, 45) :: m1
71 REAL(kind=dp), DIMENSION(45) :: m0
72 REAL(kind=dp), DIMENSION(6, 0:2) :: amn
73 TYPE(semi_empirical_mpole_type), POINTER :: mpole
74
75 cpassert(.NOT. ASSOCIATED(mpoles))
76 ! If there are atomic orbitals proceed with the expansion in multipoles
77 natorb = se_parameter%natorb
78 IF (natorb /= 0) THEN
79 ndim = natorb*(natorb + 1)/2
80 CALL semi_empirical_mpole_p_create(mpoles, ndim)
81
82 ! Select method for multipolar expansion
83
84 ! Fill in information on multipole expansion due to atomic orbitals charge
85 ! distribution
86 NULLIFY (mpole)
87 CALL amn_l(se_parameter, amn)
88 DO i = 1, natorb
89 DO j = 1, i
90 ind1 = indexa(se_map_alm(i), se_map_alm(j))
91 ind2 = indexb(i, j)
92 ! the order in the mpoles structure is like the standard one for the
93 ! integrals: s px py pz dx2-y2 dzx dz2 dzy dxy (lower triangular)
94 ! which differs from the order of the Hamiltonian in CP2K. But I
95 ! preferred to keep this order for consistency with the integrals
96 mpole => mpoles(ind2)%mpole
97 mpole%indi = i
98 mpole%indj = j
99 a = loc_index(i)
100 b = loc_index(j)
101 mpole%c = huge(0.0_dp)
102 mpole%d = huge(0.0_dp)
103 mpole%qs = huge(0.0_dp)
104 mpole%qc = huge(0.0_dp)
105
106 ! Charge
107 IF (alm(ind1, 0, 0) /= 0.0_dp) THEN
108 dlm = 1.0_dp/sqrt(real((2*0 + 1), kind=dp))
109 tmp = -dlm*amn(indexb(a, b), 0)
110 mpole%c = tmp*alm(ind1, 0, 0)
111 mpole%task(1) = .true.
112 END IF
113
114 ! Dipole
115 IF (any(alm(ind1, 1, -1:1) /= 0.0_dp)) THEN
116 dlm = 1.0_dp/sqrt(real((2*1 + 1), kind=dp))
117 tmp = -dlm*amn(indexb(a, b), 1)
118 mpole%d(1) = tmp*alm(ind1, 1, 1)
119 mpole%d(2) = tmp*alm(ind1, 1, -1)
120 mpole%d(3) = tmp*alm(ind1, 1, 0)
121 mpole%task(2) = .true.
122 END IF
123
124 ! Quadrupole
125 IF (any(alm(ind1, 2, -2:2) /= 0.0_dp)) THEN
126 dlm = 1.0_dp/sqrt(real((2*2 + 1), kind=dp))
127 tmp = -dlm*amn(indexb(a, b), 2)
128
129 ! Spherical components
130 mpole%qs(1) = tmp*alm(ind1, 2, 0) ! d3z2-r2
131 mpole%qs(2) = tmp*alm(ind1, 2, 1) ! dzx
132 mpole%qs(3) = tmp*alm(ind1, 2, -1) ! dzy
133 mpole%qs(4) = tmp*alm(ind1, 2, 2) ! dx2-y2
134 mpole%qs(5) = tmp*alm(ind1, 2, -2) ! dxy
135
136 ! Convert into cartesian components
137 CALL quadrupole_sph_to_cart(mpole%qc, mpole%qs)
138 mpole%task(3) = .true.
139 END IF
140
141 IF (debug_this_module) THEN
142 WRITE (*, '(A,2I6,A)') "Orbitals ", i, j, &
143 " ("//label_print_orb(i)//","//label_print_orb(j)//")"
144 IF (mpole%task(1)) WRITE (*, '(9F12.6)') mpole%c
145 IF (mpole%task(2)) WRITE (*, '(9F12.6)') mpole%d
146 IF (mpole%task(3)) WRITE (*, '(9F12.6)') mpole%qc
147 WRITE (*, *)
148 END IF
149 END DO
150 END DO
151
152 IF (method == do_method_pnnl) THEN
153 ! No d-function for Schenter type integrals
154 cpassert(natorb <= 4)
155
156 m0 = 0.0_dp
157 m1 = 0.0_dp
158 m2 = 0.0_dp
159
160 DO mu = 1, se_parameter%natorb
161 m0(indexb(mu, mu)) = 1.0_dp
162 END DO
163
164 zs = se_parameter%sto_exponents(0)
165 zp = se_parameter%sto_exponents(1)
166 nr = se_parameter%nr
167
168 ws = real((2*nr + 2)*(2*nr + 1), dp)/(24.0_dp*zs**2)
169 DO k = 1, 3
170 m2(k, k, indexb(1, 1)) = ws
171 END DO
172
173 IF (zp > 0._dp) THEN
174 zt = sqrt(zs*zp)
175 zb = 0.5_dp*(zs + zp)
176 DO k = 1, 3
177 m1(k, indexb(1, 1 + k)) = (zt/zb)**(2*nr + 1)*real(2*nr + 1, dp)/(2.0_dp*zb*sqrt3)
178 END DO
179
180 wp = real((2*nr + 2)*(2*nr + 1), dp)/(40.0_dp*zp**2)
181 DO k1 = 1, 3
182 DO k2 = 1, 3
183 IF (k1 == k2) THEN
184 m2(k2, k2, indexb(1 + k1, 1 + k1)) = 3.0_dp*wp
185 ELSE
186 m2(k2, k2, indexb(1 + k1, 1 + k1)) = wp
187 END IF
188 END DO
189 END DO
190 m2(1, 2, indexb(1 + 1, 1 + 2)) = wp
191 m2(2, 1, indexb(1 + 1, 1 + 2)) = wp
192 m2(2, 3, indexb(1 + 2, 1 + 3)) = wp
193 m2(3, 2, indexb(1 + 2, 1 + 3)) = wp
194 m2(3, 1, indexb(1 + 3, 1 + 1)) = wp
195 m2(1, 3, indexb(1 + 3, 1 + 1)) = wp
196 END IF
197
198 DO i = 1, natorb
199 DO j = 1, i
200 ind1 = indexa(se_map_alm(i), se_map_alm(j))
201 ind2 = indexb(i, j)
202 mpole => mpoles(ind2)%mpole
203 mpole%indi = i
204 mpole%indj = j
205 ! Charge
206 mpole%cs = -m0(indexb(i, j))
207 ! Dipole
208 mpole%ds = -m1(1:3, indexb(i, j))
209 ! Quadrupole
210 mpole%qq = -3._dp*m2(1:3, 1:3, indexb(i, j))
211 IF (debug_this_module) THEN
212 WRITE (*, '(A,2I6,A)') "Orbitals ", i, j, &
213 " ("//label_print_orb(i)//","//label_print_orb(j)//")"
214 WRITE (*, '(9F12.6)') mpole%cs
215 WRITE (*, '(9F12.6)') mpole%ds
216 WRITE (*, '(9F12.6)') mpole%qq
217 WRITE (*, *)
218 END IF
219 END DO
220 END DO
221 ELSE
222 mpole%cs = mpole%c
223 mpole%ds = mpole%d
224 mpole%qq = mpole%qc
225 END IF
226 END IF
227
228 END SUBROUTINE semi_empirical_mpole_p_setup
229
230! **************************************************************************************************
231!> \brief Transforms the quadrupole components from sphericals to cartesians
232!> \param qcart ...
233!> \param qsph ...
234!> \date 09.2008
235!> \author Teodoro Laino [tlaino] - University of Zurich
236! **************************************************************************************************
237 SUBROUTINE quadrupole_sph_to_cart(qcart, qsph)
238 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT) :: qcart
239 REAL(kind=dp), DIMENSION(5), INTENT(IN) :: qsph
240
241! Notation
242! qs(1) - d3z2-r2
243! qs(2) - dzx
244! qs(3) - dzy
245! qs(4) - dx2-y2
246! qs(5) - dxy
247! Cartesian components
248
249 qcart(1, 1) = (qsph(4) - qsph(1)/sqrt(3.0_dp))*sqrt(3.0_dp)/2.0_dp
250 qcart(2, 1) = qsph(5)*sqrt(3.0_dp)/2.0_dp
251 qcart(3, 1) = qsph(2)*sqrt(3.0_dp)/2.0_dp
252 qcart(2, 2) = -(qsph(4) + qsph(1)/sqrt(3.0_dp))*sqrt(3.0_dp)/2.0_dp
253 qcart(3, 2) = qsph(3)*sqrt(3.0_dp)/2.0_dp
254 qcart(3, 3) = qsph(1)
255 ! Symmetrize tensor
256 qcart(1, 2) = qcart(2, 1)
257 qcart(1, 3) = qcart(3, 1)
258 qcart(2, 3) = qcart(3, 2)
259
260 END SUBROUTINE quadrupole_sph_to_cart
261
262! **************************************************************************************************
263!> \brief Setup NDDO multipole type
264!> \param nddo_mpole ...
265!> \param natom ...
266!> \date 09.2008
267!> \author Teodoro Laino [tlaino] - University of Zurich
268! **************************************************************************************************
269 SUBROUTINE nddo_mpole_setup(nddo_mpole, natom)
270 TYPE(nddo_mpole_type), POINTER :: nddo_mpole
271 INTEGER, INTENT(IN) :: natom
272
273 CHARACTER(len=*), PARAMETER :: routinen = 'nddo_mpole_setup'
274
275 INTEGER :: handle
276
277 CALL timeset(routinen, handle)
278
279 IF (ASSOCIATED(nddo_mpole)) THEN
280 CALL nddo_mpole_release(nddo_mpole)
281 END IF
282 CALL nddo_mpole_create(nddo_mpole)
283 ! Allocate Global Arrays
284 ALLOCATE (nddo_mpole%charge(natom))
285 ALLOCATE (nddo_mpole%dipole(3, natom))
286 ALLOCATE (nddo_mpole%quadrupole(3, 3, natom))
287
288 ALLOCATE (nddo_mpole%efield0(natom))
289 ALLOCATE (nddo_mpole%efield1(3, natom))
290 ALLOCATE (nddo_mpole%efield2(9, natom))
291
292 CALL timestop(handle)
293
294 END SUBROUTINE nddo_mpole_setup
295
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_method_pnnl
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public sqrt3
Arrays of parameters used in the semi-empirical calculations \References Everywhere in this module TC...
integer, dimension(9), public se_map_alm
integer, dimension(9, 9), public indexb
real(kind=dp), dimension(45, 0:2, -2:2), public alm
integer, dimension(9, 9), public indexa
Setup and Methods for semi-empirical multipole types.
subroutine, public semi_empirical_mpole_p_setup(mpoles, se_parameter, method)
Setup semi-empirical mpole type This function setup for each semi-empirical type a structure containi...
subroutine, public quadrupole_sph_to_cart(qcart, qsph)
Transforms the quadrupole components from sphericals to cartesians.
subroutine, public nddo_mpole_setup(nddo_mpole, natom)
Setup NDDO multipole type.
Definition of the semi empirical multipole integral expansions types.
subroutine, public nddo_mpole_release(nddo_mpole)
Deallocate NDDO multipole type.
subroutine, public semi_empirical_mpole_p_create(mpole, ndim)
Allocate semi-empirical mpole type.
subroutine, public nddo_mpole_create(nddo_mpole)
Allocate NDDO multipole type.
Utilities to post-process semi-empirical parameters.
Definition of the semi empirical parameter types.
Global Multipolar NDDO information type.
Semi-empirical integral multipole expansion type - pointer type.
Semi-empirical integral multipole expansion type.