(git:ed6f26b)
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-2025 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 cp_dbcsr_api, ONLY: dbcsr_add,&
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_reserve_blocks(hmat, rows=[row], cols=[col])
236 CALL dbcsr_get_block_p(hmat, row, col, h_block, found)
237 END IF
238 IF (lrii%lrisr) THEN
239 fw = lrii%wsr
240 IF (trans) THEN
241 h_block(1:nbb, 1:nba) = h_block(1:nbb, 1:nba) + fw*transpose(hs_work(1:nba, 1:nbb))
242 ELSE
243 h_block(1:nba, 1:nbb) = h_block(1:nba, 1:nbb) + fw*hs_work(1:nba, 1:nbb)
244 END IF
245 END IF
246 IF (lrii%lriff) THEN
247 fw = lrii%wff
248 IF (trans) THEN
249 h_block(1:nbb, 1:nba) = h_block(1:nbb, 1:nba) + fw*transpose(hf_work(1:nba, 1:nbb))
250 ELSE
251 h_block(1:nba, 1:nbb) = h_block(1:nba, 1:nbb) + fw*hf_work(1:nba, 1:nbb)
252 END IF
253 END IF
254!$OMP END CRITICAL(addhamiltonian)
255
256 IF (lrii%lrisr) DEALLOCATE (hs_work)
257 IF (lrii%lriff) DEALLOCATE (hf_work)
258 END DO
259!$OMP END PARALLEL
260
261 DO ic = 1, SIZE(h_matrix, 1)
262 CALL dbcsr_finalize(h_matrix(ic)%matrix)
263 END DO
264
265 CALL neighbor_list_iterator_release(nl_iterator)
266
267 END IF
268
269 CALL timestop(handle)
270
271 END SUBROUTINE calculate_lri_ks_matrix
272
273!*****************************************************************************
274!> \brief update of RIGPW KS matrix
275!> \param lri_env ...
276!> \param lri_v_int integrals of potential * ri basis set
277!> \param h_matrix KS matrix, on entry containing the core hamiltonian
278!> \param s_matrix overlap matrix
279!> \param atomic_kind_set ...
280!> \param ispin ...
281!> \note including this in lri_environment_methods?
282! **************************************************************************************************
283 SUBROUTINE calculate_ri_ks_matrix(lri_env, lri_v_int, h_matrix, s_matrix, &
284 atomic_kind_set, ispin)
285
286 TYPE(lri_environment_type), POINTER :: lri_env
287 TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_v_int
288 TYPE(dbcsr_type), POINTER :: h_matrix, s_matrix
289 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
290 INTEGER, INTENT(IN) :: ispin
291
292 CHARACTER(*), PARAMETER :: routinen = 'calculate_ri_ks_matrix'
293
294 INTEGER :: atom_a, handle, i1, i2, iatom, ikind, n, &
295 natom, nbas
296 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of, nsize
297 INTEGER, DIMENSION(:, :), POINTER :: bas_ptr
298 REAL(kind=dp) :: fscal, ftrm1n
299 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: fout, fvec
300 REAL(kind=dp), DIMENSION(:), POINTER :: v
301 TYPE(o3c_vec_type), DIMENSION(:), POINTER :: o3c_vec
302
303 CALL timeset(routinen, handle)
304
305 bas_ptr => lri_env%ri_fit%bas_ptr
306 natom = SIZE(bas_ptr, 2)
307 nbas = bas_ptr(2, natom)
308 ALLOCATE (fvec(nbas), fout(nbas))
309 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
310 DO iatom = 1, natom
311 ikind = kind_of(iatom)
312 atom_a = atom_of_kind(iatom)
313 i1 = bas_ptr(1, iatom)
314 i2 = bas_ptr(2, iatom)
315 n = i2 - i1 + 1
316 fvec(i1:i2) = lri_v_int(ikind)%v_int(atom_a, 1:n)
317 END DO
318 ! f(T) * R^(-1)*n
319 ftrm1n = sum(fvec(:)*lri_env%ri_fit%rm1n(:))
320 lri_env%ri_fit%ftrm1n(ispin) = ftrm1n
321 fscal = ftrm1n/lri_env%ri_fit%ntrm1n
322 ! renormalize fvec -> fvec - fscal * n
323 fvec(:) = fvec(:) - fscal*lri_env%ri_fit%nvec(:)
324 ! solve Rx=f'
325 CALL ri_metric_solver(mat=lri_env%ri_smat(1)%matrix, &
326 vecr=fvec(:), &
327 vecx=fout(:), &
328 matp=lri_env%ri_sinv(1)%matrix, &
329 solver=lri_env%ri_sinv_app, &
330 ptr=bas_ptr)
331 lri_env%ri_fit%fout(:, ispin) = fout(:)
332
333 ! add overlap matrix contribution
334 CALL dbcsr_add(h_matrix, s_matrix, 1.0_dp, fscal)
335
336 ! create a o3c_vec from fout
337 ALLOCATE (nsize(natom), o3c_vec(natom))
338 DO iatom = 1, natom
339 i1 = bas_ptr(1, iatom)
340 i2 = bas_ptr(2, iatom)
341 n = i2 - i1 + 1
342 nsize(iatom) = n
343 END DO
344 CALL o3c_vec_create(o3c_vec, nsize)
345 DEALLOCATE (nsize)
346 DO iatom = 1, natom
347 i1 = bas_ptr(1, iatom)
348 i2 = bas_ptr(2, iatom)
349 n = i2 - i1 + 1
350 CALL get_o3c_vec(o3c_vec, iatom, v)
351 v(1:n) = fout(i1:i2)
352 END DO
353 ! add <T.f'>
354 CALL contract3_o3c(lri_env%o3c, o3c_vec, h_matrix)
355 !
356 CALL o3c_vec_release(o3c_vec)
357 DEALLOCATE (o3c_vec, fvec, fout)
358
359 CALL timestop(handle)
360
361 END SUBROUTINE calculate_ri_ks_matrix
362
363END 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.
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_reserve_blocks(matrix, rows, cols)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
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.