LCOV - code coverage report
Current view: top level - src - qs_subsys_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cb5d5fc) Lines: 98.1 % 54 53
Test Date: 2026-04-24 07:01:27 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Routines that work on qs_subsys_type
      10              : !> \author Ole Schuett
      11              : ! **************************************************************************************************
      12              : MODULE qs_subsys_methods
      13              :    USE atom_types,                      ONLY: lmat
      14              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      15              :                                               get_atomic_kind
      16              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      17              :                                               gto_basis_set_type
      18              :    USE cp_subsys_methods,               ONLY: cp_subsys_create
      19              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      20              :                                               cp_subsys_release,&
      21              :                                               cp_subsys_type
      22              :    USE external_potential_types,        ONLY: all_potential_type,&
      23              :                                               get_potential,&
      24              :                                               gth_potential_type,&
      25              :                                               sgp_potential_type
      26              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      27              :                                               section_vals_type
      28              :    USE kinds,                           ONLY: dp
      29              :    USE message_passing,                 ONLY: mp_para_env_type
      30              :    USE molecule_kind_types,             ONLY: get_molecule_kind,&
      31              :                                               molecule_kind_type,&
      32              :                                               set_molecule_kind
      33              :    USE qs_cneo_types,                   ONLY: cneo_potential_type,&
      34              :                                               get_cneo_potential
      35              :    USE qs_kind_types,                   ONLY: create_qs_kind_set,&
      36              :                                               get_qs_kind,&
      37              :                                               init_atom_electronic_state,&
      38              :                                               qs_kind_type
      39              :    USE qs_subsys_types,                 ONLY: qs_subsys_set,&
      40              :                                               qs_subsys_type
      41              : #include "./base/base_uses.f90"
      42              : 
      43              :    IMPLICIT NONE
      44              :    PRIVATE
      45              : 
      46              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_subsys_methods'
      47              : 
      48              :    PUBLIC :: qs_subsys_create
      49              : 
      50              : CONTAINS
      51              : 
      52              : ! **************************************************************************************************
      53              : !> \brief Creates a qs_subsys. Optionally an existsing cp_subsys is used.
      54              : !> \param subsys ...
      55              : !> \param para_env ...
      56              : !> \param root_section ...
      57              : !> \param force_env_section ...
      58              : !> \param subsys_section ...
      59              : !> \param use_motion_section ...
      60              : !> \param cp_subsys ...
      61              : !> \param elkind ...
      62              : !> \param silent ...
      63              : ! **************************************************************************************************
      64        23286 :    SUBROUTINE qs_subsys_create(subsys, para_env, root_section, force_env_section, subsys_section, &
      65              :                                use_motion_section, cp_subsys, elkind, silent)
      66              :       TYPE(qs_subsys_type), INTENT(OUT)                  :: subsys
      67              :       TYPE(mp_para_env_type), POINTER                    :: para_env
      68              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: root_section
      69              :       TYPE(section_vals_type), POINTER                   :: force_env_section, subsys_section
      70              :       LOGICAL, INTENT(IN)                                :: use_motion_section
      71              :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: cp_subsys
      72              :       LOGICAL, INTENT(IN), OPTIONAL                      :: elkind, silent
      73              : 
      74              :       LOGICAL                                            :: be_silent
      75         7762 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
      76              :       TYPE(cp_subsys_type), POINTER                      :: my_cp_subsys
      77         7762 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
      78              :       TYPE(section_vals_type), POINTER                   :: kind_section
      79              : 
      80         7762 :       NULLIFY (atomic_kind_set, qs_kind_set, kind_section, my_cp_subsys)
      81              : 
      82         7762 :       be_silent = .FALSE.
      83         7762 :       IF (PRESENT(silent)) be_silent = silent
      84              :       ! create cp_subsys
      85         7762 :       IF (PRESENT(cp_subsys)) THEN
      86          544 :          my_cp_subsys => cp_subsys
      87         7218 :       ELSE IF (PRESENT(root_section)) THEN
      88              :          CALL cp_subsys_create(my_cp_subsys, para_env, root_section=root_section, &
      89              :                                force_env_section=force_env_section, &
      90              :                                subsys_section=subsys_section, &
      91              :                                use_motion_section=use_motion_section, &
      92         7218 :                                elkind=elkind)
      93              :       ELSE
      94            0 :          CPABORT("qs_subsys_create: cp_subsys or root_section needed")
      95              :       END IF
      96              : 
      97              :       ! setup qs_kinds
      98         7762 :       CALL cp_subsys_get(my_cp_subsys, atomic_kind_set=atomic_kind_set)
      99         7762 :       kind_section => section_vals_get_subs_vals(subsys_section, "KIND")
     100              :       CALL create_qs_kind_set(qs_kind_set, atomic_kind_set, kind_section, &
     101         7762 :                               para_env, force_env_section, be_silent)
     102              : 
     103              :       CALL num_ao_el_per_molecule(my_cp_subsys%molecule_kinds%els, &
     104         7762 :                                   qs_kind_set)
     105              : 
     106              :       CALL qs_subsys_set(subsys, &
     107              :                          cp_subsys=my_cp_subsys, &
     108              :                          cell_ref=my_cp_subsys%cell_ref, &
     109              :                          use_ref_cell=my_cp_subsys%use_ref_cell, &
     110         7762 :                          qs_kind_set=qs_kind_set)
     111              : 
     112         7762 :       IF (.NOT. PRESENT(cp_subsys)) CALL cp_subsys_release(my_cp_subsys)
     113              : 
     114         7762 :    END SUBROUTINE qs_subsys_create
     115              : 
     116              : ! **************************************************************************************************
     117              : !> \brief   Read a molecule kind data set from the input file.
     118              : !> \param molecule_kind_set ...
     119              : !> \param qs_kind_set ...
     120              : !> \date    22.11.2004
     121              : !> \par History
     122              : !>      Rustam Z. Khaliullin 10.2014 - charges and electrons of molecules
     123              : !>                                     are now in agreement with atomic guess
     124              : !> \author  MI
     125              : !> \version 1.0
     126              : ! **************************************************************************************************
     127         7762 :    SUBROUTINE num_ao_el_per_molecule(molecule_kind_set, qs_kind_set)
     128              : 
     129              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     130              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     131              : 
     132              :       INTEGER                                            :: arbitrary_spin, iatom, ikind, imol, &
     133              :                                                             n_ao, natom, nmol_kind, nsgf, nspins, &
     134              :                                                             z_molecule
     135              :       INTEGER, DIMENSION(0:lmat, 10)                     :: ne_core, ne_elem, ne_explicit
     136              :       INTEGER, DIMENSION(2)                              :: n_occ_alpha_and_beta
     137              :       REAL(KIND=dp)                                      :: charge_molecule, zeff, zeff_correction
     138              :       REAL(KIND=dp), DIMENSION(0:lmat, 10, 2)            :: edelta
     139              :       TYPE(all_potential_type), POINTER                  :: all_potential
     140              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     141              :       TYPE(cneo_potential_type), POINTER                 :: cneo_potential
     142              :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     143              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     144              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     145              :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
     146              : 
     147         7762 :       IF (ASSOCIATED(molecule_kind_set)) THEN
     148              : 
     149         7762 :          nspins = 2
     150         7762 :          nmol_kind = SIZE(molecule_kind_set, 1)
     151              :          natom = 0
     152              : 
     153              :          !   *** Initialize the molecule kind data structure ***
     154         7762 :          ARBITRARY_SPIN = 1
     155        43765 :          DO imol = 1, nmol_kind
     156              : 
     157        36003 :             molecule_kind => molecule_kind_set(imol)
     158              :             CALL get_molecule_kind(molecule_kind=molecule_kind, &
     159        36003 :                                    natom=natom)
     160              :             !nelectron = 0
     161        36003 :             n_ao = 0
     162       108009 :             n_occ_alpha_and_beta(1:nspins) = 0
     163        36003 :             z_molecule = 0
     164              : 
     165        74026 :             DO iatom = 1, natom
     166              : 
     167        38023 :                atomic_kind => molecule_kind%atom_list(iatom)%atomic_kind
     168        38023 :                CALL get_atomic_kind(atomic_kind, kind_number=ikind)
     169              :                CALL get_qs_kind(qs_kind_set(ikind), &
     170              :                                 basis_set=orb_basis_set, &
     171              :                                 all_potential=all_potential, &
     172              :                                 gth_potential=gth_potential, &
     173              :                                 sgp_potential=sgp_potential, &
     174        38023 :                                 cneo_potential=cneo_potential)
     175              : 
     176              :                ! Obtain the electronic state of the atom
     177              :                ! The same state is used to calculate the ATOMIC GUESS
     178              :                ! It is great that we are consistent with ATOMIC_GUESS
     179              :                CALL init_atom_electronic_state(atomic_kind=atomic_kind, &
     180              :                                                qs_kind=qs_kind_set(ikind), &
     181              :                                                ncalc=ne_explicit, &
     182              :                                                ncore=ne_core, &
     183              :                                                nelem=ne_elem, &
     184        38023 :                                                edelta=edelta)
     185              : 
     186              :                ! If &BS section is used ATOMIC_GUESS is calculated twice
     187              :                ! for two separate wfns with their own alpha-beta combinations
     188              :                ! This is done to break the spin symmetry of the initial wfn
     189              :                ! For now, only alpha part of &BS is used to count electrons on
     190              :                ! molecules
     191              :                ! Get the number of explicit electrons (i.e. with orbitals)
     192              :                ! For now, only the total number of electrons can be obtained
     193              :                ! from init_atom_electronic_state
     194              :                n_occ_alpha_and_beta(ARBITRARY_SPIN) = &
     195              :                   n_occ_alpha_and_beta(ARBITRARY_SPIN) + SUM(ne_explicit) + &
     196      5361243 :                   SUM(NINT(2*edelta(:, :, ARBITRARY_SPIN)))
     197              :                ! We need a way to specify the number of alpha and beta electrons
     198              :                ! on each molecule (i.e. multiplicity is not enough)
     199              :                !n_occ(ispin) = n_occ(ispin) + SUM(ne_explicit) + SUM(NINT(2*edelta(:, :, ispin)))
     200              : 
     201        38023 :                IF (ASSOCIATED(all_potential)) THEN
     202              :                   CALL get_potential(potential=all_potential, zeff=zeff, &
     203        19964 :                                      zeff_correction=zeff_correction)
     204        18059 :                ELSE IF (ASSOCIATED(gth_potential)) THEN
     205              :                   CALL get_potential(potential=gth_potential, zeff=zeff, &
     206        17709 :                                      zeff_correction=zeff_correction)
     207          350 :                ELSE IF (ASSOCIATED(sgp_potential)) THEN
     208              :                   CALL get_potential(potential=sgp_potential, zeff=zeff, &
     209           50 :                                      zeff_correction=zeff_correction)
     210          300 :                ELSE IF (ASSOCIATED(cneo_potential)) THEN
     211           14 :                   CALL get_cneo_potential(potential=cneo_potential, zeff=zeff)
     212           14 :                   zeff_correction = 0.0_dp
     213              :                ELSE
     214          286 :                   zeff = 0.0_dp
     215          286 :                   zeff_correction = 0.0_dp
     216              :                END IF
     217        38023 :                z_molecule = z_molecule + NINT(zeff - zeff_correction)
     218              : 
     219              :                ! this one does not work because nelem is not adjusted in the symmetry breaking code
     220              :                !CALL get_atomic_kind(atomic_kind,z=z)
     221              :                !z_molecule=z_molecule+z
     222              : 
     223        38023 :                IF (ASSOCIATED(orb_basis_set)) THEN
     224        32081 :                   CALL get_gto_basis_set(gto_basis_set=orb_basis_set, nsgf=nsgf)
     225              :                ELSE
     226         5942 :                   nsgf = 0
     227              :                END IF
     228       112049 :                n_ao = n_ao + nsgf
     229              : 
     230              :             END DO ! iatom
     231              : 
     232              :             ! At this point we have the number of electrons (alpha+beta) on the molecule
     233              :             !  as they are seen by the ATOMIC GUESS routines
     234        36003 :             charge_molecule = REAL(z_molecule - n_occ_alpha_and_beta(ARBITRARY_SPIN), dp)
     235              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     236              :                                    nelectron=n_occ_alpha_and_beta(ARBITRARY_SPIN), &
     237              :                                    charge=charge_molecule, &
     238        79768 :                                    nsgf=n_ao)
     239              : 
     240              :          END DO ! imol
     241              :       END IF
     242              : 
     243         7762 :    END SUBROUTINE num_ao_el_per_molecule
     244              : 
     245              : END MODULE qs_subsys_methods
        

Generated by: LCOV version 2.0-1