(git:374b731)
Loading...
Searching...
No Matches
lri_ks_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 routines that build the Kohn-Sham matrix for the LRIGPW
10!> and xc parts
11!> \par History
12!> 09.2013 created [Dorothea Golze]
13!> \author Dorothea Golze
14! **************************************************************************************************
18 USE dbcsr_api, ONLY: dbcsr_add,&
19 dbcsr_add_block_node,&
20 dbcsr_finalize,&
21 dbcsr_get_block_p,&
22 dbcsr_p_type,&
23 dbcsr_type
24 USE kinds, ONLY: dp
36 USE qs_o3c_types, ONLY: get_o3c_vec,&
41
42!$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num
43#include "./base/base_uses.f90"
44
45 IMPLICIT NONE
46
47 PRIVATE
48
49 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'lri_ks_methods'
50
52
53CONTAINS
54
55!*****************************************************************************
56!> \brief update of LRIGPW KS matrix
57!> \param lri_env ...
58!> \param lri_v_int integrals of potential * ri basis set
59!> \param h_matrix KS matrix, on entry containing the core hamiltonian
60!> \param atomic_kind_set ...
61!> \param cell_to_index ...
62!> \note including this in lri_environment_methods?
63! **************************************************************************************************
64 SUBROUTINE calculate_lri_ks_matrix(lri_env, lri_v_int, h_matrix, atomic_kind_set, cell_to_index)
65
66 TYPE(lri_environment_type), POINTER :: lri_env
67 TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_v_int
68 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: h_matrix
69 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
70 INTEGER, DIMENSION(:, :, :), OPTIONAL, POINTER :: cell_to_index
71
72 CHARACTER(*), PARAMETER :: routinen = 'calculate_lri_ks_matrix'
73
74 INTEGER :: atom_a, atom_b, col, handle, i, iac, iatom, ic, ikind, ilist, jatom, jkind, &
75 jneighbor, mepos, nba, nbb, nfa, nfb, nkind, nlist, nm, nn, nthread, row
76 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
77 INTEGER, DIMENSION(3) :: cell
78 LOGICAL :: found, trans, use_cell_mapping
79 REAL(kind=dp) :: dab, fw, isn, isna, isnb, rab(3), &
80 threshold
81 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: vi, via, vib
82 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: hf_work, hs_work, int3, wab, wbb
83 REAL(kind=dp), DIMENSION(:, :), POINTER :: h_block
84 TYPE(dbcsr_type), POINTER :: hmat
85 TYPE(lri_int_type), POINTER :: lrii
87 DIMENSION(:), POINTER :: nl_iterator
88 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
89 POINTER :: soo_list
90
91 CALL timeset(routinen, handle)
92 NULLIFY (h_block, lrii, nl_iterator, soo_list)
93
94 threshold = lri_env%eps_o3_int
95
96 use_cell_mapping = (SIZE(h_matrix, 1) > 1)
97 IF (use_cell_mapping) THEN
98 cpassert(PRESENT(cell_to_index))
99 END IF
100
101 IF (ASSOCIATED(lri_env%soo_list)) THEN
102 soo_list => lri_env%soo_list
103
104 nkind = lri_env%lri_ints%nkind
105 nthread = 1
106!$ nthread = omp_get_max_threads()
107
108 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
109 CALL neighbor_list_iterator_create(nl_iterator, soo_list, nthread=nthread)
110!$OMP PARALLEL DEFAULT(NONE)&
111!$OMP SHARED (nthread,nl_iterator,nkind,atom_of_kind,threshold,lri_env,lri_v_int,&
112!$OMP h_matrix,use_cell_mapping,cell_to_index)&
113!$OMP PRIVATE (mepos,ikind,jkind,iatom,jatom,nlist,ilist,jneighbor,rab,iac,dab,lrii,&
114!$OMP nfa,nfb,nba,nbb,nn,hs_work,hf_work,h_block,row,col,trans,found,wab,wbb,&
115!$OMP atom_a,atom_b,isn,nm,vi,isna,isnb,via,vib,fw,int3,cell,ic,hmat)
116
117 mepos = 0
118!$ mepos = omp_get_thread_num()
119
120 DO WHILE (neighbor_list_iterate(nl_iterator, mepos) == 0)
121 CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, iatom=iatom, &
122 jatom=jatom, nlist=nlist, ilist=ilist, inode=jneighbor, &
123 r=rab, cell=cell)
124
125 iac = ikind + nkind*(jkind - 1)
126 dab = sqrt(sum(rab*rab))
127
128 IF (.NOT. ASSOCIATED(lri_env%lri_ints%lri_atom(iac)%lri_node)) cycle
129 IF (lri_env%exact_1c_terms) THEN
130 IF (iatom == jatom .AND. dab < lri_env%delta) cycle
131 END IF
132
133 lrii => lri_env%lri_ints%lri_atom(iac)%lri_node(ilist)%lri_int(jneighbor)
134
135 nfa = lrii%nfa
136 nfb = lrii%nfb
137 nba = lrii%nba
138 nbb = lrii%nbb
139 nn = nfa + nfb
140
141 atom_a = atom_of_kind(iatom)
142 atom_b = atom_of_kind(jatom)
143
144 IF (use_cell_mapping) THEN
145 ic = cell_to_index(cell(1), cell(2), cell(3))
146 cpassert(ic > 0)
147 ELSE
148 ic = 1
149 END IF
150 hmat => h_matrix(ic)%matrix
151
152 ALLOCATE (int3(nba, nbb))
153 IF (lrii%lrisr) THEN
154 ALLOCATE (hs_work(nba, nbb))
155 IF (iatom == jatom .AND. dab < lri_env%delta) THEN
156 nm = nfa
157 ALLOCATE (vi(nfa))
158 vi(1:nfa) = lri_v_int(ikind)%v_int(atom_a, 1:nfa)
159 ELSE
160 nm = nn
161 ALLOCATE (vi(nn))
162 vi(1:nfa) = lri_v_int(ikind)%v_int(atom_a, 1:nfa)
163 vi(nfa + 1:nn) = lri_v_int(jkind)%v_int(atom_b, 1:nfb)
164 END IF
165 isn = sum(lrii%sn(1:nm)*vi(1:nm))/lrii%nsn
166 vi(1:nm) = matmul(lrii%sinv(1:nm, 1:nm), vi(1:nm)) - isn*lrii%sn(1:nm)
167 hs_work(1:nba, 1:nbb) = isn*lrii%soo(1:nba, 1:nbb)
168 IF (iatom == jatom .AND. dab < lri_env%delta) THEN
169 DO i = 1, nfa
170 CALL lri_decomp_i(int3, lrii%cabai, i)
171 hs_work(1:nba, 1:nbb) = hs_work(1:nba, 1:nbb) + vi(i)*int3(1:nba, 1:nbb)
172 END DO
173 ELSE
174 DO i = 1, nfa
175 CALL lri_decomp_i(int3, lrii%cabai, i)
176 hs_work(1:nba, 1:nbb) = hs_work(1:nba, 1:nbb) + vi(i)*int3(1:nba, 1:nbb)
177 END DO
178 DO i = 1, nfb
179 CALL lri_decomp_i(int3, lrii%cabbi, i)
180 hs_work(1:nba, 1:nbb) = hs_work(1:nba, 1:nbb) + vi(nfa + i)*int3(1:nba, 1:nbb)
181 END DO
182 END IF
183 DEALLOCATE (vi)
184 END IF
185
186 IF (lrii%lriff) THEN
187 ALLOCATE (hf_work(nba, nbb), wab(nba, nbb), wbb(nba, nbb))
188 wab(1:nba, 1:nbb) = lri_env%wmat(ikind, jkind)%mat(1:nba, 1:nbb)
189 wbb(1:nba, 1:nbb) = 1.0_dp - lri_env%wmat(ikind, jkind)%mat(1:nba, 1:nbb)
190 !
191 ALLOCATE (via(nfa), vib(nfb))
192 via(1:nfa) = lri_v_int(ikind)%v_int(atom_a, 1:nfa)
193 vib(1:nfb) = lri_v_int(jkind)%v_int(atom_b, 1:nfb)
194 !
195 isna = sum(lrii%sna(1:nfa)*via(1:nfa))/lrii%nsna
196 isnb = sum(lrii%snb(1:nfb)*vib(1:nfb))/lrii%nsnb
197 via(1:nfa) = matmul(lrii%asinv(1:nfa, 1:nfa), via(1:nfa)) - isna*lrii%sna(1:nfa)
198 vib(1:nfb) = matmul(lrii%bsinv(1:nfb, 1:nfb), vib(1:nfb)) - isnb*lrii%snb(1:nfb)
199 !
200 hf_work(1:nba, 1:nbb) = (isna*wab(1:nba, 1:nbb) + isnb*wbb(1:nba, 1:nbb))*lrii%soo(1:nba, 1:nbb)
201 !
202 DO i = 1, nfa
203 IF (lrii%abascr(i) > threshold) THEN
204 CALL lri_decomp_i(int3, lrii%cabai, i)
205 hf_work(1:nba, 1:nbb) = hf_work(1:nba, 1:nbb) + &
206 via(i)*int3(1:nba, 1:nbb)*wab(1:nba, 1:nbb)
207 END IF
208 END DO
209 DO i = 1, nfb
210 IF (lrii%abbscr(i) > threshold) THEN
211 CALL lri_decomp_i(int3, lrii%cabbi, i)
212 hf_work(1:nba, 1:nbb) = hf_work(1:nba, 1:nbb) + &
213 vib(i)*int3(1:nba, 1:nbb)*wbb(1:nba, 1:nbb)
214 END IF
215 END DO
216 !
217 DEALLOCATE (via, vib, wab, wbb)
218 END IF
219 DEALLOCATE (int3)
220
221 ! add h_work to core hamiltonian
222 IF (iatom <= jatom) THEN
223 row = iatom
224 col = jatom
225 trans = .false.
226 ELSE
227 row = jatom
228 col = iatom
229 trans = .true.
230 END IF
231!$OMP CRITICAL(addhamiltonian)
232 NULLIFY (h_block)
233 CALL dbcsr_get_block_p(hmat, row, col, h_block, found)
234 IF (.NOT. ASSOCIATED(h_block)) THEN
235 CALL dbcsr_add_block_node(hmat, row, col, h_block)
236 END IF
237 IF (lrii%lrisr) THEN
238 fw = lrii%wsr
239 IF (trans) THEN
240 h_block(1:nbb, 1:nba) = h_block(1:nbb, 1:nba) + fw*transpose(hs_work(1:nba, 1:nbb))
241 ELSE
242 h_block(1:nba, 1:nbb) = h_block(1:nba, 1:nbb) + fw*hs_work(1:nba, 1:nbb)
243 END IF
244 END IF
245 IF (lrii%lriff) THEN
246 fw = lrii%wff
247 IF (trans) THEN
248 h_block(1:nbb, 1:nba) = h_block(1:nbb, 1:nba) + fw*transpose(hf_work(1:nba, 1:nbb))
249 ELSE
250 h_block(1:nba, 1:nbb) = h_block(1:nba, 1:nbb) + fw*hf_work(1:nba, 1:nbb)
251 END IF
252 END IF
253!$OMP END CRITICAL(addhamiltonian)
254
255 IF (lrii%lrisr) DEALLOCATE (hs_work)
256 IF (lrii%lriff) DEALLOCATE (hf_work)
257 END DO
258!$OMP END PARALLEL
259
260 DO ic = 1, SIZE(h_matrix, 1)
261 CALL dbcsr_finalize(h_matrix(ic)%matrix)
262 END DO
263
264 CALL neighbor_list_iterator_release(nl_iterator)
265
266 END IF
267
268 CALL timestop(handle)
269
270 END SUBROUTINE calculate_lri_ks_matrix
271
272!*****************************************************************************
273!> \brief update of RIGPW KS matrix
274!> \param lri_env ...
275!> \param lri_v_int integrals of potential * ri basis set
276!> \param h_matrix KS matrix, on entry containing the core hamiltonian
277!> \param s_matrix overlap matrix
278!> \param atomic_kind_set ...
279!> \param ispin ...
280!> \note including this in lri_environment_methods?
281! **************************************************************************************************
282 SUBROUTINE calculate_ri_ks_matrix(lri_env, lri_v_int, h_matrix, s_matrix, &
283 atomic_kind_set, ispin)
284
285 TYPE(lri_environment_type), POINTER :: lri_env
286 TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_v_int
287 TYPE(dbcsr_type), POINTER :: h_matrix, s_matrix
288 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
289 INTEGER, INTENT(IN) :: ispin
290
291 CHARACTER(*), PARAMETER :: routinen = 'calculate_ri_ks_matrix'
292
293 INTEGER :: atom_a, handle, i1, i2, iatom, ikind, n, &
294 natom, nbas
295 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of, nsize
296 INTEGER, DIMENSION(:, :), POINTER :: bas_ptr
297 REAL(kind=dp) :: fscal, ftrm1n
298 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: fout, fvec
299 REAL(kind=dp), DIMENSION(:), POINTER :: v
300 TYPE(o3c_vec_type), DIMENSION(:), POINTER :: o3c_vec
301
302 CALL timeset(routinen, handle)
303
304 bas_ptr => lri_env%ri_fit%bas_ptr
305 natom = SIZE(bas_ptr, 2)
306 nbas = bas_ptr(2, natom)
307 ALLOCATE (fvec(nbas), fout(nbas))
308 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
309 DO iatom = 1, natom
310 ikind = kind_of(iatom)
311 atom_a = atom_of_kind(iatom)
312 i1 = bas_ptr(1, iatom)
313 i2 = bas_ptr(2, iatom)
314 n = i2 - i1 + 1
315 fvec(i1:i2) = lri_v_int(ikind)%v_int(atom_a, 1:n)
316 END DO
317 ! f(T) * R^(-1)*n
318 ftrm1n = sum(fvec(:)*lri_env%ri_fit%rm1n(:))
319 lri_env%ri_fit%ftrm1n(ispin) = ftrm1n
320 fscal = ftrm1n/lri_env%ri_fit%ntrm1n
321 ! renormalize fvec -> fvec - fscal * n
322 fvec(:) = fvec(:) - fscal*lri_env%ri_fit%nvec(:)
323 ! solve Rx=f'
324 CALL ri_metric_solver(mat=lri_env%ri_smat(1)%matrix, &
325 vecr=fvec(:), &
326 vecx=fout(:), &
327 matp=lri_env%ri_sinv(1)%matrix, &
328 solver=lri_env%ri_sinv_app, &
329 ptr=bas_ptr)
330 lri_env%ri_fit%fout(:, ispin) = fout(:)
331
332 ! add overlap matrix contribution
333 CALL dbcsr_add(h_matrix, s_matrix, 1.0_dp, fscal)
334
335 ! create a o3c_vec from fout
336 ALLOCATE (nsize(natom), o3c_vec(natom))
337 DO iatom = 1, natom
338 i1 = bas_ptr(1, iatom)
339 i2 = bas_ptr(2, iatom)
340 n = i2 - i1 + 1
341 nsize(iatom) = n
342 END DO
343 CALL o3c_vec_create(o3c_vec, nsize)
344 DEALLOCATE (nsize)
345 DO iatom = 1, natom
346 i1 = bas_ptr(1, iatom)
347 i2 = bas_ptr(2, iatom)
348 n = i2 - i1 + 1
349 CALL get_o3c_vec(o3c_vec, iatom, v)
350 v(1:n) = fout(i1:i2)
351 END DO
352 ! add <T.f'>
353 CALL contract3_o3c(lri_env%o3c, o3c_vec, h_matrix)
354 !
355 CALL o3c_vec_release(o3c_vec)
356 DEALLOCATE (o3c_vec, fvec, fout)
357
358 CALL timestop(handle)
359
360 END SUBROUTINE calculate_ri_ks_matrix
361
362END MODULE lri_ks_methods
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integral compression (fix point accuracy)
subroutine, public lri_decomp_i(aval, cont, ival)
...
contains the types and subroutines for dealing with the lri_env lri : local resolution of the identit...
routines that build the Kohn-Sham matrix for the LRIGPW and xc parts
subroutine, public calculate_lri_ks_matrix(lri_env, lri_v_int, h_matrix, atomic_kind_set, cell_to_index)
update of LRIGPW KS matrix
subroutine, public calculate_ri_ks_matrix(lri_env, lri_v_int, h_matrix, s_matrix, atomic_kind_set, ispin)
update of RIGPW KS matrix
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
Methods used with 3-center overlap type integrals containers.
subroutine, public contract3_o3c(o3c, vec, matrix)
Contraction of 3-tensor over index 3 h(ij) = h(ij) + sum_k (ijk)*v(k)
3-center overlap type integrals containers
subroutine, public o3c_vec_create(o3c_vec, nsize)
...
subroutine, public get_o3c_vec(o3c_vec, i, vec, n)
...
subroutine, public o3c_vec_release(o3c_vec)
...
Calculates integral matrices for RIGPW method.
subroutine, public ri_metric_solver(mat, vecr, vecx, matp, solver, ptr)
solver for RI systems (R*x=n)
Provides all information about an atomic kind.