LCOV - code coverage report
Current view: top level - src - cp_subsys_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 96.9 % 129 125
Test Date: 2026-07-25 06:35:44 Functions: 100.0 % 3 3

            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 Initialize a small environment for a particular calculation
      10              : !> \par History
      11              : !>      5.2004 created [fawzi]
      12              : !>      9.2007 cleaned [tlaino] - University of Zurich
      13              : !> \author Teodoro Laino
      14              : ! **************************************************************************************************
      15              : MODULE cp_subsys_methods
      16              :    USE atomic_kind_list_types,          ONLY: atomic_kind_list_create,&
      17              :                                               atomic_kind_list_release,&
      18              :                                               atomic_kind_list_type
      19              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      20              :    USE atprop_types,                    ONLY: atprop_create
      21              :    USE cell_methods,                    ONLY: write_cell
      22              :    USE cell_types,                      ONLY: cell_retain,&
      23              :                                               cell_type
      24              :    USE colvar_methods,                  ONLY: colvar_read
      25              :    USE cp_result_types,                 ONLY: cp_result_create
      26              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      27              :                                               cp_subsys_set,&
      28              :                                               cp_subsys_type
      29              :    USE exclusion_types,                 ONLY: exclusion_type
      30              :    USE input_constants,                 ONLY: do_conn_off,&
      31              :                                               do_stress_analytical,&
      32              :                                               do_stress_diagonal_anal,&
      33              :                                               do_stress_diagonal_numer,&
      34              :                                               do_stress_none,&
      35              :                                               do_stress_numerical
      36              :    USE input_section_types,             ONLY: section_vals_get,&
      37              :                                               section_vals_get_subs_vals,&
      38              :                                               section_vals_type,&
      39              :                                               section_vals_val_get
      40              :    USE kinds,                           ONLY: default_string_length,&
      41              :                                               dp
      42              :    USE message_passing,                 ONLY: mp_para_env_type
      43              :    USE molecule_kind_list_types,        ONLY: molecule_kind_list_create,&
      44              :                                               molecule_kind_list_release,&
      45              :                                               molecule_kind_list_type
      46              :    USE molecule_kind_types,             ONLY: molecule_kind_type
      47              :    USE molecule_list_types,             ONLY: molecule_list_create,&
      48              :                                               molecule_list_release,&
      49              :                                               molecule_list_type
      50              :    USE molecule_types,                  ONLY: molecule_type
      51              :    USE particle_list_types,             ONLY: particle_list_create,&
      52              :                                               particle_list_release,&
      53              :                                               particle_list_type
      54              :    USE particle_types,                  ONLY: particle_type
      55              :    USE qmmm_types_low,                  ONLY: qmmm_env_mm_type
      56              :    USE string_table,                    ONLY: id2str,&
      57              :                                               s2s,&
      58              :                                               str2id
      59              :    USE topology,                        ONLY: connectivity_control,&
      60              :                                               topology_control
      61              :    USE topology_connectivity_util,      ONLY: topology_connectivity_pack
      62              :    USE topology_coordinate_util,        ONLY: topology_coordinate_pack
      63              :    USE topology_types,                  ONLY: deallocate_topology,&
      64              :                                               init_topology,&
      65              :                                               topology_parameters_type
      66              :    USE topology_util,                   ONLY: check_subsys_element
      67              :    USE virial_types,                    ONLY: virial_set
      68              : #include "./base/base_uses.f90"
      69              : 
      70              :    IMPLICIT NONE
      71              :    PRIVATE
      72              : 
      73              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
      74              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_subsys_methods'
      75              : 
      76              :    PUBLIC :: create_small_subsys, cp_subsys_create
      77              : 
      78              : CONTAINS
      79              : 
      80              : ! **************************************************************************************************
      81              : !> \brief Creates allocates and fills subsys from given input.
      82              : !> \param subsys ...
      83              : !> \param para_env ...
      84              : !> \param root_section ...
      85              : !> \param force_env_section ...
      86              : !> \param subsys_section ...
      87              : !> \param use_motion_section ...
      88              : !> \param qmmm ...
      89              : !> \param qmmm_env ...
      90              : !> \param exclusions ...
      91              : !> \param elkind ...
      92              : !> \author Ole Schuett
      93              : ! **************************************************************************************************
      94        32841 :    SUBROUTINE cp_subsys_create(subsys, para_env, &
      95              :                                root_section, force_env_section, subsys_section, &
      96              :                                use_motion_section, qmmm, qmmm_env, exclusions, elkind)
      97              :       TYPE(cp_subsys_type), POINTER                      :: subsys
      98              :       TYPE(mp_para_env_type), POINTER                    :: para_env
      99              :       TYPE(section_vals_type), POINTER                   :: root_section
     100              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: force_env_section, subsys_section
     101              :       LOGICAL, INTENT(IN), OPTIONAL                      :: use_motion_section
     102              :       LOGICAL, OPTIONAL                                  :: qmmm
     103              :       TYPE(qmmm_env_mm_type), OPTIONAL, POINTER          :: qmmm_env
     104              :       TYPE(exclusion_type), DIMENSION(:), OPTIONAL, &
     105              :          POINTER                                         :: exclusions
     106              :       LOGICAL, INTENT(IN), OPTIONAL                      :: elkind
     107              : 
     108              :       INTEGER                                            :: stress_tensor
     109        10947 :       INTEGER, DIMENSION(:), POINTER                     :: seed_vals
     110              :       LOGICAL                                            :: atomic_energy, my_use_motion_section, &
     111              :                                                             pv_availability, pv_diagonal, &
     112              :                                                             pv_numerical
     113              :       TYPE(atomic_kind_list_type), POINTER               :: atomic_kinds
     114        10947 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     115              :       TYPE(molecule_kind_list_type), POINTER             :: mol_kinds
     116        10947 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     117              :       TYPE(molecule_list_type), POINTER                  :: mols
     118        10947 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     119              :       TYPE(particle_list_type), POINTER                  :: particles
     120        10947 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     121              :       TYPE(section_vals_type), POINTER                   :: colvar_section, my_force_env_section, &
     122              :                                                             my_subsys_section
     123              : 
     124            0 :       CPASSERT(.NOT. ASSOCIATED(subsys))
     125       109470 :       ALLOCATE (subsys)
     126              : 
     127        10947 :       CALL para_env%retain()
     128        10947 :       subsys%para_env => para_env
     129              : 
     130        10947 :       my_use_motion_section = .FALSE.
     131        10947 :       IF (PRESENT(use_motion_section)) THEN
     132        10939 :          my_use_motion_section = use_motion_section
     133              :       END IF
     134              : 
     135        10947 :       my_force_env_section => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
     136        10947 :       IF (PRESENT(force_env_section)) THEN
     137        10939 :          my_force_env_section => force_env_section
     138              :       END IF
     139              : 
     140        10947 :       my_subsys_section => section_vals_get_subs_vals(my_force_env_section, "SUBSYS")
     141        10947 :       IF (PRESENT(subsys_section)) THEN
     142        10779 :          my_subsys_section => subsys_section
     143              :       END IF
     144              : 
     145        10947 :       CALL section_vals_val_get(my_subsys_section, "SEED", i_vals=seed_vals)
     146        10947 :       IF (SIZE(seed_vals) == 1) THEN
     147        98487 :          subsys%seed(:, :) = REAL(seed_vals(1), KIND=dp)
     148            4 :       ELSE IF (SIZE(seed_vals) == 6) THEN
     149           60 :          subsys%seed(1:3, 1:2) = RESHAPE(REAL(seed_vals(:), KIND=dp), [3, 2])
     150              :       ELSE
     151            0 :          CPABORT("Supply exactly 1 or 6 arguments for SEED in &SUBSYS only!")
     152              :       END IF
     153              : 
     154        10947 :       colvar_section => section_vals_get_subs_vals(my_subsys_section, "COLVAR")
     155              : 
     156        10947 :       CALL cp_subsys_read_colvar(subsys, colvar_section)
     157              : 
     158              :       !   *** Read the particle coordinates and allocate the atomic kind, ***
     159              :       !   *** the molecule kind, and the molecule data structures         ***
     160              :       CALL topology_control(atomic_kind_set, particle_set, molecule_kind_set, molecule_set, &
     161              :                             subsys%colvar_p, subsys%gci, root_section, para_env, &
     162              :                             force_env_section=my_force_env_section, &
     163              :                             subsys_section=my_subsys_section, use_motion_section=my_use_motion_section, &
     164              :                             qmmm=qmmm, qmmm_env=qmmm_env, exclusions=exclusions, elkind=elkind, &
     165        10947 :                             subsys=subsys)
     166              : 
     167        10947 :       CALL particle_list_create(particles, els_ptr=particle_set)
     168        10947 :       CALL atomic_kind_list_create(atomic_kinds, els_ptr=atomic_kind_set)
     169        10947 :       CALL molecule_list_create(mols, els_ptr=molecule_set)
     170        10947 :       CALL molecule_kind_list_create(mol_kinds, els_ptr=molecule_kind_set)
     171              : 
     172              :       CALL cp_subsys_set(subsys, particles=particles, atomic_kinds=atomic_kinds, &
     173        10947 :                          molecules=mols, molecule_kinds=mol_kinds)
     174              : 
     175        10947 :       CALL particle_list_release(particles)
     176        10947 :       CALL atomic_kind_list_release(atomic_kinds)
     177        10947 :       CALL molecule_list_release(mols)
     178        10947 :       CALL molecule_kind_list_release(mol_kinds)
     179              : 
     180              :       ! Should we compute the virial?
     181        10947 :       CALL section_vals_val_get(my_force_env_section, "STRESS_TENSOR", i_val=stress_tensor)
     182         9881 :       SELECT CASE (stress_tensor)
     183              :       CASE (do_stress_none)
     184         9881 :          pv_availability = .FALSE.
     185         9881 :          pv_numerical = .FALSE.
     186         9881 :          pv_diagonal = .FALSE.
     187              :       CASE (do_stress_analytical)
     188         1012 :          pv_availability = .TRUE.
     189         1012 :          pv_numerical = .FALSE.
     190         1012 :          pv_diagonal = .FALSE.
     191              :       CASE (do_stress_numerical)
     192            2 :          pv_availability = .TRUE.
     193            2 :          pv_numerical = .TRUE.
     194            2 :          pv_diagonal = .FALSE.
     195              :       CASE (do_stress_diagonal_anal)
     196           42 :          pv_availability = .TRUE.
     197           42 :          pv_numerical = .FALSE.
     198           42 :          pv_diagonal = .TRUE.
     199              :       CASE (do_stress_diagonal_numer)
     200           10 :          pv_availability = .TRUE.
     201           10 :          pv_numerical = .TRUE.
     202        10947 :          pv_diagonal = .TRUE.
     203              :       END SELECT
     204              : 
     205      2714856 :       ALLOCATE (subsys%virial)
     206              :       CALL virial_set(virial=subsys%virial, &
     207              :                       pv_availability=pv_availability, &
     208              :                       pv_numer=pv_numerical, &
     209        10947 :                       pv_diagonal=pv_diagonal)
     210              : 
     211              :       ! Should we compute atomic properties?
     212        10947 :       CALL atprop_create(subsys%atprop)
     213        10947 :       CALL section_vals_val_get(my_force_env_section, "PROPERTIES%ATOMIC%ENERGY", l_val=atomic_energy)
     214        10947 :       subsys%atprop%energy = atomic_energy
     215              : 
     216        10947 :       CALL cp_result_create(subsys%results)
     217        10947 :    END SUBROUTINE cp_subsys_create
     218              : 
     219              : ! **************************************************************************************************
     220              : !> \brief reads the colvar section of the colvar
     221              : !> \param subsys ...
     222              : !> \param colvar_section ...
     223              : !> \par History
     224              : !>      2006.01 Joost VandeVondele
     225              : ! **************************************************************************************************
     226        10947 :    SUBROUTINE cp_subsys_read_colvar(subsys, colvar_section)
     227              :       TYPE(cp_subsys_type), POINTER                      :: subsys
     228              :       TYPE(section_vals_type), POINTER                   :: colvar_section
     229              : 
     230              :       INTEGER                                            :: ig, ncol
     231              : 
     232        10947 :       CALL section_vals_get(colvar_section, n_repetition=ncol)
     233        22636 :       ALLOCATE (subsys%colvar_p(ncol))
     234        11413 :       DO ig = 1, ncol
     235          466 :          NULLIFY (subsys%colvar_p(ig)%colvar)
     236        11413 :          CALL colvar_read(subsys%colvar_p(ig)%colvar, ig, colvar_section, subsys%para_env, subsys%cell)
     237              :       END DO
     238        10947 :    END SUBROUTINE cp_subsys_read_colvar
     239              : 
     240              : ! **************************************************************************************************
     241              : !> \brief updates the molecule information of the given subsys
     242              : !> \param small_subsys the subsys to create
     243              : !> \param big_subsys the superset of small_subsys
     244              : !> \param small_cell the cell of small_subsys
     245              : !> \param small_para_env the parallel environment for the new (small)
     246              : !>        subsys
     247              : !> \param sub_atom_index indexes of the atoms that should be in small_subsys
     248              : !> \param sub_atom_kind_name ...
     249              : !> \param para_env ...
     250              : !> \param force_env_section ...
     251              : !> \param subsys_section ...
     252              : !> \param ignore_outside_box ...
     253              : !> \par History
     254              : !>      05.2004 created [fawzi]
     255              : !> \author Fawzi Mohamed, Teodoro Laino
     256              : !> \note
     257              : !>      not really ready to be used with different para_envs for the small
     258              : !>      and big part
     259              : !>      qmmm_env_create() should be the only instance where this subroutine is called
     260              : !>      with small_cell distinct from big_subsys%cell; otherwise it could be possible
     261              : !>      to drop the small_cell as input parameter entirely.
     262              : ! **************************************************************************************************
     263          550 :    SUBROUTINE create_small_subsys(small_subsys, big_subsys, small_cell, &
     264          550 :                                   small_para_env, sub_atom_index, sub_atom_kind_name, &
     265              :                                   para_env, force_env_section, subsys_section, ignore_outside_box)
     266              : 
     267              :       TYPE(cp_subsys_type), POINTER                      :: small_subsys, big_subsys
     268              :       TYPE(cell_type), POINTER                           :: small_cell
     269              :       TYPE(mp_para_env_type), POINTER                    :: small_para_env
     270              :       INTEGER, DIMENSION(:), INTENT(in)                  :: sub_atom_index
     271              :       CHARACTER(len=default_string_length), &
     272              :          DIMENSION(:), INTENT(in)                        :: sub_atom_kind_name
     273              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     274              :       TYPE(section_vals_type), POINTER                   :: force_env_section, subsys_section
     275              :       LOGICAL, INTENT(in), OPTIONAL                      :: ignore_outside_box
     276              : 
     277              :       CHARACTER(len=default_string_length)               :: my_element, strtmp1
     278              :       INTEGER                                            :: iat, id_, nat
     279              :       TYPE(atomic_kind_list_type), POINTER               :: atomic_kinds
     280          550 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     281              :       TYPE(molecule_kind_list_type), POINTER             :: mol_kinds
     282          550 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     283              :       TYPE(molecule_list_type), POINTER                  :: mols
     284          550 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     285              :       TYPE(particle_list_type), POINTER                  :: particles
     286          550 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     287              :       TYPE(topology_parameters_type)                     :: topology
     288              : 
     289          550 :       NULLIFY (mol_kinds, mols, particles, atomic_kinds, atomic_kind_set, particle_set, &
     290          550 :                molecule_kind_set, molecule_set, particles, atomic_kinds)
     291              : 
     292            0 :       CPASSERT(.NOT. ASSOCIATED(small_subsys))
     293          550 :       CPASSERT(ASSOCIATED(big_subsys))
     294          550 :       IF (big_subsys%para_env /= small_para_env) THEN
     295            0 :          CPABORT("big_subsys%para_env==small_para_env")
     296              :       END IF
     297              : 
     298              :       !-----------------------------------------------------------------------------
     299              :       !-----------------------------------------------------------------------------
     300              :       ! 1. Initialize the topology structure type
     301              :       !-----------------------------------------------------------------------------
     302          550 :       CALL init_topology(topology)
     303              : 
     304              :       !-----------------------------------------------------------------------------
     305              :       !-----------------------------------------------------------------------------
     306              :       ! 2. Get the cell info
     307              :       !-----------------------------------------------------------------------------
     308          550 :       topology%cell => small_cell
     309          550 :       CALL cell_retain(small_cell)
     310          550 :       CALL write_cell(small_cell, subsys_section, tag="CELL")
     311          550 :       CALL write_cell(small_cell, subsys_section, tag="CELL_REF")
     312              : 
     313              :       !-----------------------------------------------------------------------------
     314              :       !-----------------------------------------------------------------------------
     315              :       ! 3. Initialize atom coords from the bigger system
     316              :       !-----------------------------------------------------------------------------
     317          550 :       nat = SIZE(sub_atom_index)
     318          550 :       topology%natoms = nat
     319          550 :       CPASSERT(.NOT. ASSOCIATED(topology%atom_info%r))
     320          550 :       CPASSERT(.NOT. ASSOCIATED(topology%atom_info%id_atmname))
     321          550 :       CPASSERT(.NOT. ASSOCIATED(topology%atom_info%id_molname))
     322          550 :       CPASSERT(.NOT. ASSOCIATED(topology%atom_info%id_resname))
     323          550 :       CPASSERT(.NOT. ASSOCIATED(topology%atom_info%atm_mass))
     324          550 :       CPASSERT(.NOT. ASSOCIATED(topology%atom_info%atm_charge))
     325              :       ALLOCATE (topology%atom_info%r(3, nat), topology%atom_info%id_atmname(nat), &
     326              :                 topology%atom_info%id_molname(nat), topology%atom_info%id_resname(nat), &
     327              :                 topology%atom_info%id_element(nat), topology%atom_info%atm_mass(nat), &
     328         6050 :                 topology%atom_info%atm_charge(nat))
     329              : 
     330          550 :       CALL cp_subsys_get(big_subsys, particles=particles)
     331         4290 :       DO iat = 1, nat
     332        14960 :          topology%atom_info%r(:, iat) = particles%els(sub_atom_index(iat))%r
     333         3740 :          topology%atom_info%id_atmname(iat) = str2id(s2s(sub_atom_kind_name(iat)))
     334         3740 :          topology%atom_info%id_molname(iat) = topology%atom_info%id_atmname(iat)
     335         3740 :          topology%atom_info%id_resname(iat) = topology%atom_info%id_atmname(iat)
     336              :          !
     337              :          ! Defining element
     338              :          !
     339         3740 :          id_ = INDEX(id2str(topology%atom_info%id_atmname(iat)), "_") - 1
     340         3740 :          IF (id_ == -1) id_ = LEN_TRIM(id2str(topology%atom_info%id_atmname(iat)))
     341         3740 :          strtmp1 = id2str(topology%atom_info%id_atmname(iat))
     342         3740 :          strtmp1 = strtmp1(1:id_)
     343              :          CALL check_subsys_element(strtmp1, strtmp1, my_element, &
     344         3740 :                                    subsys_section, use_mm_map_first=.FALSE.)
     345         3740 :          topology%atom_info%id_element(iat) = str2id(s2s(my_element))
     346         3740 :          topology%atom_info%atm_mass(iat) = 0._dp
     347         4290 :          topology%atom_info%atm_charge(iat) = 0._dp
     348              :       END DO
     349          550 :       topology%conn_type = do_conn_off
     350              : 
     351              :       !-----------------------------------------------------------------------------
     352              :       !-----------------------------------------------------------------------------
     353              :       ! 4. Read in or generate the molecular connectivity
     354              :       !-----------------------------------------------------------------------------
     355              :       CALL connectivity_control(topology, para_env, subsys_section=subsys_section, &
     356          550 :                                 force_env_section=force_env_section)
     357              : 
     358              :       !-----------------------------------------------------------------------------
     359              :       !-----------------------------------------------------------------------------
     360              :       ! 5. Pack everything into the molecular types
     361              :       !-----------------------------------------------------------------------------
     362              :       CALL topology_connectivity_pack(molecule_kind_set, molecule_set, &
     363          550 :                                       topology, subsys_section=subsys_section)
     364              : 
     365              :       !-----------------------------------------------------------------------------
     366              :       !-----------------------------------------------------------------------------
     367              :       ! 6. Pack everything into the atomic types
     368              :       !-----------------------------------------------------------------------------
     369              :       CALL topology_coordinate_pack(particle_set, atomic_kind_set, &
     370              :                                     molecule_kind_set, molecule_set, topology, subsys_section=subsys_section, &
     371          550 :                                     force_env_section=force_env_section, ignore_outside_box=ignore_outside_box)
     372              : 
     373              :       !-----------------------------------------------------------------------------
     374              :       !-----------------------------------------------------------------------------
     375              :       ! 7. Cleanup the topology structure type
     376              :       !-----------------------------------------------------------------------------
     377          550 :       CALL deallocate_topology(topology)
     378              : 
     379              :       !-----------------------------------------------------------------------------
     380              :       !-----------------------------------------------------------------------------
     381              :       ! 8. Allocate new subsys
     382              :       !-----------------------------------------------------------------------------
     383         4950 :       ALLOCATE (small_subsys)
     384          550 :       CALL para_env%retain()
     385          550 :       small_subsys%para_env => para_env
     386          550 :       CALL particle_list_create(particles, els_ptr=particle_set)
     387          550 :       CALL atomic_kind_list_create(atomic_kinds, els_ptr=atomic_kind_set)
     388          550 :       CALL molecule_list_create(mols, els_ptr=molecule_set)
     389          550 :       CALL molecule_kind_list_create(mol_kinds, els_ptr=molecule_kind_set)
     390              :       CALL cp_subsys_set(small_subsys, particles=particles, atomic_kinds=atomic_kinds, &
     391              :                          molecules=mols, molecule_kinds=mol_kinds, cell=small_cell, &
     392          550 :                          cell_ref=small_cell, use_ref_cell=.FALSE.)
     393          550 :       CALL particle_list_release(particles)
     394          550 :       CALL atomic_kind_list_release(atomic_kinds)
     395          550 :       CALL molecule_list_release(mols)
     396          550 :       CALL molecule_kind_list_release(mol_kinds)
     397              : 
     398       125950 :       ALLOCATE (small_subsys%virial)
     399          550 :       CALL atprop_create(small_subsys%atprop)
     400          550 :       CALL cp_result_create(small_subsys%results)
     401          550 :    END SUBROUTINE create_small_subsys
     402              : 
     403              : END MODULE cp_subsys_methods
        

Generated by: LCOV version 2.0-1