LCOV - code coverage report
Current view: top level - src - lri_ks_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 25 69 36.2 %
Date: 2024-12-21 06:28:57 Functions: 1 2 50.0 %

          Line data    Source code
       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             : ! **************************************************************************************************
      15             : MODULE lri_ks_methods
      16             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      17             :                                               get_atomic_kind_set
      18             :    USE cp_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
      29             :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      30             :                                               neighbor_list_iterate,&
      31             :                                               neighbor_list_iterator_create,&
      32             :                                               neighbor_list_iterator_p_type,&
      33             :                                               neighbor_list_iterator_release,&
      34             :                                               neighbor_list_set_p_type
      35             :    USE qs_o3c_methods,                  ONLY: contract3_o3c
      36             :    USE qs_o3c_types,                    ONLY: get_o3c_vec,&
      37             :                                               o3c_vec_create,&
      38             :                                               o3c_vec_release,&
      39             :                                               o3c_vec_type
      40             :    USE ri_environment_methods,          ONLY: ri_metric_solver
      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             : 
      51             :    PUBLIC :: calculate_lri_ks_matrix, calculate_ri_ks_matrix
      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         718 :    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         718 :       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         718 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: vi, via, vib
      82         718 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: hf_work, hs_work, int3, wab, wbb
      83         718 :       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         718 :          DIMENSION(:), POINTER                           :: nl_iterator
      88             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
      89         718 :          POINTER                                         :: soo_list
      90             : 
      91         718 :       CALL timeset(routineN, handle)
      92         718 :       NULLIFY (h_block, lrii, nl_iterator, soo_list)
      93             : 
      94         718 :       threshold = lri_env%eps_o3_int
      95             : 
      96         718 :       use_cell_mapping = (SIZE(h_matrix, 1) > 1)
      97         718 :       IF (use_cell_mapping) THEN
      98           6 :          CPASSERT(PRESENT(cell_to_index))
      99             :       END IF
     100             : 
     101         718 :       IF (ASSOCIATED(lri_env%soo_list)) THEN
     102         718 :          soo_list => lri_env%soo_list
     103             : 
     104         718 :          nkind = lri_env%lri_ints%nkind
     105             :          nthread = 1
     106         718 : !$       nthread = omp_get_max_threads()
     107             : 
     108         718 :          CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
     109         718 :          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         718 : !$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        3578 :          DO ic = 1, SIZE(h_matrix, 1)
     261        3578 :             CALL dbcsr_finalize(h_matrix(ic)%matrix)
     262             :          END DO
     263             : 
     264         718 :          CALL neighbor_list_iterator_release(nl_iterator)
     265             : 
     266             :       END IF
     267             : 
     268         718 :       CALL timestop(handle)
     269             : 
     270        1436 :    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           0 :    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           0 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of, nsize
     296             :       INTEGER, DIMENSION(:, :), POINTER                  :: bas_ptr
     297             :       REAL(KIND=dp)                                      :: fscal, ftrm1n
     298           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: fout, fvec
     299           0 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: v
     300           0 :       TYPE(o3c_vec_type), DIMENSION(:), POINTER          :: o3c_vec
     301             : 
     302           0 :       CALL timeset(routineN, handle)
     303             : 
     304           0 :       bas_ptr => lri_env%ri_fit%bas_ptr
     305           0 :       natom = SIZE(bas_ptr, 2)
     306           0 :       nbas = bas_ptr(2, natom)
     307           0 :       ALLOCATE (fvec(nbas), fout(nbas))
     308           0 :       CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
     309           0 :       DO iatom = 1, natom
     310           0 :          ikind = kind_of(iatom)
     311           0 :          atom_a = atom_of_kind(iatom)
     312           0 :          i1 = bas_ptr(1, iatom)
     313           0 :          i2 = bas_ptr(2, iatom)
     314           0 :          n = i2 - i1 + 1
     315           0 :          fvec(i1:i2) = lri_v_int(ikind)%v_int(atom_a, 1:n)
     316             :       END DO
     317             :       ! f(T) * R^(-1)*n
     318           0 :       ftrm1n = SUM(fvec(:)*lri_env%ri_fit%rm1n(:))
     319           0 :       lri_env%ri_fit%ftrm1n(ispin) = ftrm1n
     320           0 :       fscal = ftrm1n/lri_env%ri_fit%ntrm1n
     321             :       ! renormalize fvec -> fvec - fscal * n
     322           0 :       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           0 :                             ptr=bas_ptr)
     330           0 :       lri_env%ri_fit%fout(:, ispin) = fout(:)
     331             : 
     332             :       ! add overlap matrix contribution
     333           0 :       CALL dbcsr_add(h_matrix, s_matrix, 1.0_dp, fscal)
     334             : 
     335             :       ! create a o3c_vec from fout
     336           0 :       ALLOCATE (nsize(natom), o3c_vec(natom))
     337           0 :       DO iatom = 1, natom
     338           0 :          i1 = bas_ptr(1, iatom)
     339           0 :          i2 = bas_ptr(2, iatom)
     340           0 :          n = i2 - i1 + 1
     341           0 :          nsize(iatom) = n
     342             :       END DO
     343           0 :       CALL o3c_vec_create(o3c_vec, nsize)
     344           0 :       DEALLOCATE (nsize)
     345           0 :       DO iatom = 1, natom
     346           0 :          i1 = bas_ptr(1, iatom)
     347           0 :          i2 = bas_ptr(2, iatom)
     348           0 :          n = i2 - i1 + 1
     349           0 :          CALL get_o3c_vec(o3c_vec, iatom, v)
     350           0 :          v(1:n) = fout(i1:i2)
     351             :       END DO
     352             :       ! add <T.f'>
     353           0 :       CALL contract3_o3c(lri_env%o3c, o3c_vec, h_matrix)
     354             :       !
     355           0 :       CALL o3c_vec_release(o3c_vec)
     356           0 :       DEALLOCATE (o3c_vec, fvec, fout)
     357             : 
     358           0 :       CALL timestop(handle)
     359             : 
     360           0 :    END SUBROUTINE calculate_ri_ks_matrix
     361             : 
     362             : END MODULE lri_ks_methods

Generated by: LCOV version 1.15