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