(git:b279b6b)
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 ! **************************************************************************************************
16  USE atomic_kind_types, ONLY: atomic_kind_type,&
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
25  USE lri_compression, ONLY: lri_decomp_i
26  USE lri_environment_types, ONLY: lri_environment_type,&
27  lri_int_type,&
28  lri_kind_type
32  neighbor_list_iterator_p_type,&
34  neighbor_list_set_p_type
35  USE qs_o3c_methods, ONLY: contract3_o3c
36  USE qs_o3c_types, ONLY: get_o3c_vec,&
39  o3c_vec_type
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 
53 CONTAINS
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
86  TYPE(neighbor_list_iterator_p_type), &
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 
362 END 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
Definition: qs_o3c_types.F:12
subroutine, public o3c_vec_create(o3c_vec, nsize)
...
Definition: qs_o3c_types.F:592
subroutine, public get_o3c_vec(o3c_vec, i, vec, n)
...
Definition: qs_o3c_types.F:634
subroutine, public o3c_vec_release(o3c_vec)
...
Definition: qs_o3c_types.F:614
Calculates integral matrices for RIGPW method.
subroutine, public ri_metric_solver(mat, vecr, vecx, matp, solver, ptr)
solver for RI systems (R*x=n)