LCOV - code coverage report
Current view: top level - src - qs_dftb3_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 100.0 % 184 184
Test Date: 2025-07-25 12:55:17 Functions: 100.0 % 1 1

            Line data    Source code
       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 Calculation of DFTB3 Terms
      10              : !> \author JGH
      11              : ! **************************************************************************************************
      12              : MODULE qs_dftb3_methods
      13              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14              :                                               get_atomic_kind_set
      15              :    USE atprop_types,                    ONLY: atprop_type
      16              :    USE cell_types,                      ONLY: cell_type
      17              :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      18              :                                               dbcsr_get_block_p,&
      19              :                                               dbcsr_iterator_blocks_left,&
      20              :                                               dbcsr_iterator_next_block,&
      21              :                                               dbcsr_iterator_start,&
      22              :                                               dbcsr_iterator_stop,&
      23              :                                               dbcsr_iterator_type,&
      24              :                                               dbcsr_p_type
      25              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      26              :    USE kinds,                           ONLY: dp
      27              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      28              :                                               kpoint_type
      29              :    USE message_passing,                 ONLY: mp_para_env_type
      30              :    USE particle_types,                  ONLY: particle_type
      31              :    USE qs_energy_types,                 ONLY: qs_energy_type
      32              :    USE qs_environment_types,            ONLY: get_qs_env,&
      33              :                                               qs_environment_type
      34              :    USE qs_force_types,                  ONLY: qs_force_type
      35              :    USE qs_kind_types,                   ONLY: qs_kind_type
      36              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      37              :                                               neighbor_list_iterate,&
      38              :                                               neighbor_list_iterator_create,&
      39              :                                               neighbor_list_iterator_p_type,&
      40              :                                               neighbor_list_iterator_release,&
      41              :                                               neighbor_list_set_p_type
      42              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      43              :                                               qs_rho_type
      44              :    USE sap_kind_types,                  ONLY: sap_int_type
      45              :    USE virial_methods,                  ONLY: virial_pair_force
      46              :    USE virial_types,                    ONLY: virial_type
      47              : #include "./base/base_uses.f90"
      48              : 
      49              :    IMPLICIT NONE
      50              : 
      51              :    PRIVATE
      52              : 
      53              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_dftb3_methods'
      54              : 
      55              :    PUBLIC :: build_dftb3_diagonal
      56              : 
      57              : CONTAINS
      58              : 
      59              : ! **************************************************************************************************
      60              : !> \brief ...
      61              : !> \param qs_env ...
      62              : !> \param ks_matrix ...
      63              : !> \param rho ...
      64              : !> \param mcharge ...
      65              : !> \param energy ...
      66              : !> \param xgamma ...
      67              : !> \param zeff ...
      68              : !> \param sap_int ...
      69              : !> \param calculate_forces ...
      70              : !> \param just_energy ...
      71              : ! **************************************************************************************************
      72        26782 :    SUBROUTINE build_dftb3_diagonal(qs_env, ks_matrix, rho, mcharge, energy, xgamma, zeff, &
      73              :                                    sap_int, calculate_forces, just_energy)
      74              : 
      75              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      76              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
      77              :       TYPE(qs_rho_type), POINTER                         :: rho
      78              :       REAL(dp), DIMENSION(:), INTENT(in)                 :: mcharge
      79              :       TYPE(qs_energy_type), POINTER                      :: energy
      80              :       REAL(dp), DIMENSION(:), INTENT(in)                 :: xgamma, zeff
      81              :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
      82              :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
      83              : 
      84              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_dftb3_diagonal'
      85              : 
      86              :       INTEGER                                            :: atom_i, atom_j, handle, i, ia, iac, &
      87              :                                                             iatom, ic, icol, ikind, irow, is, &
      88              :                                                             jatom, jkind, natom, nimg, nkind
      89        26782 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
      90              :       INTEGER, DIMENSION(3)                              :: cellind
      91        26782 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
      92              :       LOGICAL                                            :: found, use_virial
      93              :       REAL(KIND=dp)                                      :: dr, eb3, eloc, fi, gmij, ua, ui, uj
      94              :       REAL(KIND=dp), DIMENSION(3)                        :: fij, rij
      95        26782 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: dsblock, ksblock, pblock, sblock
      96        26782 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: dsint
      97        26782 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
      98              :       TYPE(atprop_type), POINTER                         :: atprop
      99              :       TYPE(cell_type), POINTER                           :: cell
     100              :       TYPE(dbcsr_iterator_type)                          :: iter
     101        26782 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
     102              :       TYPE(distribution_1d_type), POINTER                :: local_particles
     103              :       TYPE(kpoint_type), POINTER                         :: kpoints
     104              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     105              :       TYPE(neighbor_list_iterator_p_type), &
     106        26782 :          DIMENSION(:), POINTER                           :: nl_iterator
     107              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     108        26782 :          POINTER                                         :: n_list
     109        26782 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     110        26782 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     111        26782 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     112              :       TYPE(virial_type), POINTER                         :: virial
     113              : 
     114        26782 :       CALL timeset(routineN, handle)
     115        26782 :       NULLIFY (atprop)
     116              : 
     117              :       ! Energy
     118              :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, &
     119        26782 :                       qs_kind_set=qs_kind_set, atprop=atprop)
     120              :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
     121        26782 :                                kind_of=kind_of, atom_of_kind=atom_of_kind)
     122              : 
     123        26782 :       eb3 = 0.0_dp
     124        26782 :       CALL get_qs_env(qs_env=qs_env, local_particles=local_particles)
     125        95368 :       DO ikind = 1, SIZE(local_particles%n_el)
     126        68586 :          ua = xgamma(ikind)
     127       234611 :          DO ia = 1, local_particles%n_el(ikind)
     128       139243 :             iatom = local_particles%list(ikind)%array(ia)
     129       139243 :             eloc = -1.0_dp/6.0_dp*ua*mcharge(iatom)**3
     130       139243 :             eb3 = eb3 + eloc
     131       207829 :             IF (atprop%energy) THEN
     132              :                ! we have to add the part not covered by 0.5*Tr(FP)
     133         9756 :                eloc = -0.5_dp*eloc - 0.25_dp*ua*zeff(ikind)*mcharge(iatom)**2
     134         9756 :                atprop%atecoul(iatom) = atprop%atecoul(iatom) + eloc
     135              :             END IF
     136              :          END DO
     137              :       END DO
     138        26782 :       CALL get_qs_env(qs_env=qs_env, para_env=para_env)
     139        26782 :       CALL para_env%sum(eb3)
     140        26782 :       energy%dftb3 = eb3
     141              : 
     142              :       ! Forces and Virial
     143        26782 :       IF (calculate_forces) THEN
     144              :          CALL get_qs_env(qs_env=qs_env, matrix_s_kp=matrix_s, natom=natom, force=force, &
     145          542 :                          cell=cell, virial=virial, particle_set=particle_set)
     146              :          ! virial
     147          542 :          use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     148          542 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     149          542 :          IF (SIZE(matrix_p, 1) == 2) THEN
     150          432 :             DO ic = 1, SIZE(matrix_p, 2)
     151              :                CALL dbcsr_add(matrix_p(1, ic)%matrix, matrix_p(2, ic)%matrix, &
     152          432 :                               alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     153              :             END DO
     154              :          END IF
     155              :          !
     156          542 :          nimg = SIZE(matrix_p, 2)
     157          542 :          NULLIFY (cell_to_index)
     158          542 :          IF (nimg > 1) THEN
     159           58 :             NULLIFY (kpoints)
     160           58 :             CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
     161           58 :             CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
     162              :          END IF
     163          542 :          IF (nimg == 1) THEN
     164              :             ! no k-points; all matrices have been transformed to periodic bsf
     165          484 :             CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
     166       104816 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
     167       104332 :                CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
     168       104332 :                ikind = kind_of(irow)
     169       104332 :                atom_i = atom_of_kind(irow)
     170       104332 :                ui = xgamma(ikind)
     171       104332 :                jkind = kind_of(icol)
     172       104332 :                atom_j = atom_of_kind(icol)
     173       104332 :                uj = xgamma(jkind)
     174              :                !
     175       104332 :                gmij = -0.5_dp*(ui*mcharge(irow)**2 + uj*mcharge(icol)**2)
     176              :                !
     177       104332 :                NULLIFY (pblock)
     178              :                CALL dbcsr_get_block_p(matrix=matrix_p(1, 1)%matrix, &
     179       104332 :                                       row=irow, col=icol, block=pblock, found=found)
     180       104332 :                CPASSERT(found)
     181       417812 :                DO i = 1, 3
     182       312996 :                   NULLIFY (dsblock)
     183              :                   CALL dbcsr_get_block_p(matrix=matrix_s(1 + i, 1)%matrix, &
     184       312996 :                                          row=irow, col=icol, block=dsblock, found=found)
     185       312996 :                   CPASSERT(found)
     186      2883402 :                   fi = -gmij*SUM(pblock*dsblock)
     187       312996 :                   force(ikind)%rho_elec(i, atom_i) = force(ikind)%rho_elec(i, atom_i) + fi
     188       312996 :                   force(jkind)%rho_elec(i, atom_j) = force(jkind)%rho_elec(i, atom_j) - fi
     189       730324 :                   fij(i) = fi
     190              :                END DO
     191              :             END DO
     192          484 :             CALL dbcsr_iterator_stop(iter)
     193              :             ! use dsint list
     194          484 :             IF (use_virial) THEN
     195          130 :                CPASSERT(ASSOCIATED(sap_int))
     196          130 :                CALL get_qs_env(qs_env, nkind=nkind)
     197          394 :                DO ikind = 1, nkind
     198          990 :                   DO jkind = 1, nkind
     199          596 :                      iac = ikind + nkind*(jkind - 1)
     200          596 :                      IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
     201          468 :                      ui = xgamma(ikind)
     202          468 :                      uj = xgamma(jkind)
     203         5200 :                      DO ia = 1, sap_int(iac)%nalist
     204         4468 :                         IF (.NOT. ASSOCIATED(sap_int(iac)%alist(ia)%clist)) CYCLE
     205         4448 :                         iatom = sap_int(iac)%alist(ia)%aatom
     206       187768 :                         DO ic = 1, sap_int(iac)%alist(ia)%nclist
     207       182724 :                            jatom = sap_int(iac)%alist(ia)%clist(ic)%catom
     208       730896 :                            rij = sap_int(iac)%alist(ia)%clist(ic)%rac
     209       730896 :                            dr = SQRT(SUM(rij(:)**2))
     210       187192 :                            IF (dr > 1.e-6_dp) THEN
     211       180490 :                               dsint => sap_int(iac)%alist(ia)%clist(ic)%acint
     212       180490 :                               gmij = -0.5_dp*(ui*mcharge(iatom)**2 + uj*mcharge(jatom)**2)
     213       180490 :                               icol = MAX(iatom, jatom)
     214       180490 :                               irow = MIN(iatom, jatom)
     215       180490 :                               NULLIFY (pblock)
     216              :                               CALL dbcsr_get_block_p(matrix=matrix_p(1, 1)%matrix, &
     217       180490 :                                                      row=irow, col=icol, block=pblock, found=found)
     218       180490 :                               CPASSERT(found)
     219       721960 :                               DO i = 1, 3
     220       721960 :                                  IF (irow == iatom) THEN
     221      8589414 :                                     fij(i) = -gmij*SUM(pblock*dsint(:, :, i))
     222              :                                  ELSE
     223      6196560 :                                     fij(i) = -gmij*SUM(TRANSPOSE(pblock)*dsint(:, :, i))
     224              :                                  END IF
     225              :                               END DO
     226       180490 :                               fi = 1.0_dp
     227       180490 :                               IF (iatom == jatom) fi = 0.5_dp
     228       180490 :                               CALL virial_pair_force(virial%pv_virial, fi, fij, rij)
     229              :                            END IF
     230              :                         END DO
     231              :                      END DO
     232              :                   END DO
     233              :                END DO
     234              :             END IF
     235              :          ELSE
     236           58 :             NULLIFY (n_list)
     237           58 :             CALL get_qs_env(qs_env=qs_env, sab_orb=n_list)
     238           58 :             CALL neighbor_list_iterator_create(nl_iterator, n_list)
     239        33640 :             DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     240              :                CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     241        33582 :                                       iatom=iatom, jatom=jatom, r=rij, cell=cellind)
     242              : 
     243       134328 :                dr = SQRT(SUM(rij**2))
     244        33582 :                IF (iatom == jatom .AND. dr < 1.0e-6_dp) CYCLE
     245              : 
     246        33410 :                icol = MAX(iatom, jatom)
     247        33410 :                irow = MIN(iatom, jatom)
     248              : 
     249        33410 :                ic = cell_to_index(cellind(1), cellind(2), cellind(3))
     250        33410 :                CPASSERT(ic > 0)
     251              : 
     252        33410 :                ikind = kind_of(iatom)
     253        33410 :                atom_i = atom_of_kind(iatom)
     254        33410 :                ui = xgamma(ikind)
     255        33410 :                jkind = kind_of(jatom)
     256        33410 :                atom_j = atom_of_kind(jatom)
     257        33410 :                uj = xgamma(jkind)
     258              :                !
     259        33410 :                gmij = -0.5_dp*(ui*mcharge(iatom)**2 + uj*mcharge(jatom)**2)
     260              :                !
     261        33410 :                NULLIFY (pblock)
     262              :                CALL dbcsr_get_block_p(matrix=matrix_p(1, ic)%matrix, &
     263        33410 :                                       row=irow, col=icol, block=pblock, found=found)
     264        33410 :                CPASSERT(found)
     265       133640 :                DO i = 1, 3
     266       100230 :                   NULLIFY (dsblock)
     267              :                   CALL dbcsr_get_block_p(matrix=matrix_s(1 + i, ic)%matrix, &
     268       100230 :                                          row=irow, col=icol, block=dsblock, found=found)
     269       100230 :                   CPASSERT(found)
     270       100230 :                   IF (irow == iatom) THEN
     271      3677568 :                      fi = -gmij*SUM(pblock*dsblock)
     272              :                   ELSE
     273      2379069 :                      fi = gmij*SUM(pblock*dsblock)
     274              :                   END IF
     275       100230 :                   force(ikind)%rho_elec(i, atom_i) = force(ikind)%rho_elec(i, atom_i) + fi
     276       100230 :                   force(jkind)%rho_elec(i, atom_j) = force(jkind)%rho_elec(i, atom_j) - fi
     277       233870 :                   fij(i) = fi
     278              :                END DO
     279        33468 :                IF (use_virial) THEN
     280        22502 :                   fi = 1.0_dp
     281        22502 :                   IF (iatom == jatom) fi = 0.5_dp
     282        22502 :                   CALL virial_pair_force(virial%pv_virial, fi, fij, rij)
     283              :                END IF
     284              : 
     285              :             END DO
     286           58 :             CALL neighbor_list_iterator_release(nl_iterator)
     287              :             !
     288              :          END IF
     289              : 
     290          542 :          IF (SIZE(matrix_p, 1) == 2) THEN
     291          432 :             DO ic = 1, SIZE(matrix_p, 2)
     292              :                CALL dbcsr_add(matrix_p(1, ic)%matrix, matrix_p(2, ic)%matrix, &
     293          432 :                               alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
     294              :             END DO
     295              :          END IF
     296              :       END IF
     297              : 
     298              :       ! KS matrix
     299        26782 :       IF (.NOT. just_energy) THEN
     300        26172 :          CALL get_qs_env(qs_env=qs_env, matrix_s_kp=matrix_s, natom=natom)
     301              :          !
     302        26172 :          nimg = SIZE(ks_matrix, 2)
     303        26172 :          NULLIFY (cell_to_index)
     304        26172 :          IF (nimg > 1) THEN
     305         4626 :             NULLIFY (kpoints)
     306         4626 :             CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
     307         4626 :             CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
     308              :          END IF
     309              : 
     310        26172 :          IF (nimg == 1) THEN
     311              :             ! no k-points; all matrices have been transformed to periodic bsf
     312        21546 :             CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
     313      1932564 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
     314      1911018 :                CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
     315      1911018 :                ikind = kind_of(irow)
     316      1911018 :                ui = xgamma(ikind)
     317      1911018 :                jkind = kind_of(icol)
     318      1911018 :                uj = xgamma(jkind)
     319      1911018 :                gmij = -0.5_dp*(ui*mcharge(irow)**2 + uj*mcharge(icol)**2)
     320      3851978 :                DO is = 1, SIZE(ks_matrix, 1)
     321      1919414 :                   NULLIFY (ksblock)
     322              :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
     323      1919414 :                                          row=irow, col=icol, block=ksblock, found=found)
     324      1919414 :                   CPASSERT(found)
     325     47703686 :                   ksblock = ksblock - 0.5_dp*gmij*sblock
     326              :                END DO
     327              :             END DO
     328        21546 :             CALL dbcsr_iterator_stop(iter)
     329              :          ELSE
     330         4626 :             NULLIFY (n_list)
     331         4626 :             CALL get_qs_env(qs_env=qs_env, sab_orb=n_list)
     332         4626 :             CALL neighbor_list_iterator_create(nl_iterator, n_list)
     333      2203364 :             DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     334              :                CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     335      2198738 :                                       iatom=iatom, jatom=jatom, r=rij, cell=cellind)
     336              : 
     337      2198738 :                icol = MAX(iatom, jatom)
     338      2198738 :                irow = MIN(iatom, jatom)
     339              : 
     340      2198738 :                ic = cell_to_index(cellind(1), cellind(2), cellind(3))
     341      2198738 :                CPASSERT(ic > 0)
     342              : 
     343      2198738 :                ikind = kind_of(iatom)
     344      2198738 :                ui = xgamma(ikind)
     345      2198738 :                jkind = kind_of(jatom)
     346      2198738 :                uj = xgamma(jkind)
     347      2198738 :                gmij = -0.5_dp*(ui*mcharge(iatom)**2 + uj*mcharge(jatom)**2)
     348              :                !
     349      2198738 :                NULLIFY (sblock)
     350              :                CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
     351      2198738 :                                       row=irow, col=icol, block=sblock, found=found)
     352      2198738 :                CPASSERT(found)
     353      4589702 :                DO is = 1, SIZE(ks_matrix, 1)
     354      2386338 :                   NULLIFY (ksblock)
     355              :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
     356      2386338 :                                          row=irow, col=icol, block=ksblock, found=found)
     357      2386338 :                   CPASSERT(found)
     358    155819908 :                   ksblock = ksblock - 0.5_dp*gmij*sblock
     359              :                END DO
     360              : 
     361              :             END DO
     362         4626 :             CALL neighbor_list_iterator_release(nl_iterator)
     363              :             !
     364              :          END IF
     365              :       END IF
     366              : 
     367        26782 :       CALL timestop(handle)
     368              : 
     369        53564 :    END SUBROUTINE build_dftb3_diagonal
     370              : 
     371              : END MODULE qs_dftb3_methods
     372              : 
        

Generated by: LCOV version 2.0-1