LCOV - code coverage report
Current view: top level - src/subsys - molecule_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 77.5 % 160 124
Test Date: 2026-07-25 06:35:44 Functions: 50.0 % 16 8

            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 Define the data structure for the molecule information.
      10              : !> \par History
      11              : !>      JGH (22.05.2004) add last_atom information
      12              : !>      Teodoro Laino [tlaino] 12.2008 - Preparing for VIRTUAL SITE constraints
      13              : !>                                       (patch by Marcel Baer)
      14              : !> \author Matthias Krack (29.08.2003)
      15              : ! **************************************************************************************************
      16              : MODULE molecule_types
      17              : 
      18              :    USE colvar_types,                    ONLY: colvar_counters,&
      19              :                                               colvar_release,&
      20              :                                               colvar_type
      21              :    USE kinds,                           ONLY: dp
      22              :    USE molecule_kind_types,             ONLY: colvar_constraint_type,&
      23              :                                               fixd_constraint_type,&
      24              :                                               g3x3_constraint_type,&
      25              :                                               g4x6_constraint_type,&
      26              :                                               get_molecule_kind,&
      27              :                                               molecule_kind_type,&
      28              :                                               vsite_constraint_type
      29              : #include "../base/base_uses.f90"
      30              : 
      31              :    IMPLICIT NONE
      32              : 
      33              :    PRIVATE
      34              : 
      35              :    ! Global parameters (in this module)
      36              : 
      37              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'molecule_types'
      38              : 
      39              :    ! Molecular constraint types
      40              :    TYPE local_colvar_constraint_type
      41              :       TYPE(colvar_type), POINTER                         :: colvar => NULL(), &
      42              :                                                             colvar_old => NULL()
      43              :       REAL(KIND=dp)                                      :: lambda = 0.0_dp, &
      44              :                                                             sigma = 0.0_dp
      45              :       LOGICAL                                            :: init = .FALSE.
      46              :    END TYPE local_colvar_constraint_type
      47              : 
      48              :    TYPE local_g3x3_constraint_type
      49              :       LOGICAL                                            :: init = .FALSE.
      50              :       REAL(KIND=dp)                                      :: scale = 0.0_dp, &
      51              :                                                             imass1 = 0.0_dp, &
      52              :                                                             imass2 = 0.0_dp, &
      53              :                                                             imass3 = 0.0_dp, &
      54              :                                                             scale_old = 0.0_dp
      55              :       REAL(KIND=dp), DIMENSION(3)                        :: fa = 0.0_dp, &
      56              :                                                             fb = 0.0_dp, &
      57              :                                                             fc = 0.0_dp, &
      58              :                                                             f_roll1 = 0.0_dp, &
      59              :                                                             f_roll2 = 0.0_dp, &
      60              :                                                             f_roll3 = 0.0_dp, &
      61              :                                                             ra_old = 0.0_dp, &
      62              :                                                             rb_old = 0.0_dp, &
      63              :                                                             rc_old = 0.0_dp, &
      64              :                                                             r0_12 = 0.0_dp, &
      65              :                                                             r0_13 = 0.0_dp, &
      66              :                                                             r0_23 = 0.0_dp, &
      67              :                                                             va = 0.0_dp, &
      68              :                                                             vb = 0.0_dp, &
      69              :                                                             vc = 0.0_dp, &
      70              :                                                             del_lambda = 0.0_dp, &
      71              :                                                             lambda = 0.0_dp, &
      72              :                                                             lambda_old = 0.0_dp
      73              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: amat = 0.0_dp
      74              :    END TYPE local_g3x3_constraint_type
      75              : 
      76              :    TYPE local_g4x6_constraint_type
      77              :       LOGICAL                                            :: init = .FALSE.
      78              :       REAL(KIND=dp)                                      :: scale = 0.0_dp, &
      79              :                                                             scale_old = 0.0_dp, &
      80              :                                                             imass1 = 0.0_dp, &
      81              :                                                             imass2 = 0.0_dp, &
      82              :                                                             imass3 = 0.0_dp, &
      83              :                                                             imass4 = 0.0_dp
      84              :       REAL(KIND=dp), DIMENSION(3)                        :: fa = 0.0_dp, &
      85              :                                                             fb = 0.0_dp, &
      86              :                                                             fc = 0.0_dp, &
      87              :                                                             fd = 0.0_dp, &
      88              :                                                             fe = 0.0_dp, &
      89              :                                                             ff = 0.0_dp, &
      90              :                                                             f_roll1 = 0.0_dp, &
      91              :                                                             f_roll2 = 0.0_dp, &
      92              :                                                             f_roll3 = 0.0_dp, &
      93              :                                                             f_roll4 = 0.0_dp, &
      94              :                                                             f_roll5 = 0.0_dp, &
      95              :                                                             f_roll6 = 0.0_dp, &
      96              :                                                             ra_old = 0.0_dp, &
      97              :                                                             rb_old = 0.0_dp, &
      98              :                                                             rc_old = 0.0_dp, &
      99              :                                                             rd_old = 0.0_dp, &
     100              :                                                             re_old = 0.0_dp, &
     101              :                                                             rf_old = 0.0_dp, &
     102              :                                                             va = 0.0_dp, &
     103              :                                                             vb = 0.0_dp, &
     104              :                                                             vc = 0.0_dp, &
     105              :                                                             vd = 0.0_dp, &
     106              :                                                             ve = 0.0_dp, &
     107              :                                                             vf = 0.0_dp, &
     108              :                                                             r0_12 = 0.0_dp, &
     109              :                                                             r0_13 = 0.0_dp, &
     110              :                                                             r0_14 = 0.0_dp, &
     111              :                                                             r0_23 = 0.0_dp, &
     112              :                                                             r0_24 = 0.0_dp, &
     113              :                                                             r0_34 = 0.0_dp
     114              :       REAL(KIND=dp), DIMENSION(6)                        :: del_lambda = 0.0_dp, &
     115              :                                                             lambda = 0.0_dp, &
     116              :                                                             lambda_old = 0.0_dp
     117              :       REAL(KIND=dp), DIMENSION(6, 6)                     :: amat = 0.0_dp
     118              :    END TYPE local_g4x6_constraint_type
     119              : 
     120              :    TYPE local_states_type
     121              :       INTEGER                                            :: nstates = 0 ! Kohn-Sham states for molecule
     122              :       INTEGER, DIMENSION(:), POINTER                     :: states => NULL() ! indices of Kohn-Sham states for molecule
     123              :    END TYPE local_states_type
     124              : 
     125              :    TYPE local_constraint_type
     126              :       TYPE(local_colvar_constraint_type), &
     127              :          DIMENSION(:), POINTER                           :: lcolv => NULL()
     128              :       TYPE(local_g3x3_constraint_type), DIMENSION(:), &
     129              :          POINTER                                         :: lg3x3 => NULL()
     130              :       TYPE(local_g4x6_constraint_type), DIMENSION(:), &
     131              :          POINTER                                         :: lg4x6 => NULL()
     132              :    END TYPE local_constraint_type
     133              : 
     134              :    TYPE global_constraint_type
     135              :       TYPE(colvar_counters)                              :: ncolv = colvar_counters()
     136              :       INTEGER                                            :: ntot = 0, &
     137              :                                                             nrestraint = 0, &
     138              :                                                             ng3x3 = 0, &
     139              :                                                             ng3x3_restraint = 0, &
     140              :                                                             ng4x6 = 0, &
     141              :                                                             ng4x6_restraint = 0, &
     142              :                                                             nvsite = 0, &
     143              :                                                             nvsite_restraint = 0
     144              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list => NULL()
     145              :       TYPE(colvar_constraint_type), DIMENSION(:), &
     146              :          POINTER                                         :: colv_list => NULL()
     147              :       TYPE(g3x3_constraint_type), DIMENSION(:), POINTER  :: g3x3_list => NULL()
     148              :       TYPE(g4x6_constraint_type), DIMENSION(:), POINTER  :: g4x6_list => NULL()
     149              :       TYPE(vsite_constraint_type), DIMENSION(:), POINTER :: vsite_list => NULL()
     150              :       TYPE(local_colvar_constraint_type), &
     151              :          DIMENSION(:), POINTER                           :: lcolv => NULL()
     152              :       TYPE(local_g3x3_constraint_type), DIMENSION(:), &
     153              :          POINTER                                         :: lg3x3 => NULL()
     154              :       TYPE(local_g4x6_constraint_type), DIMENSION(:), &
     155              :          POINTER                                         :: lg4x6 => NULL()
     156              :    END TYPE global_constraint_type
     157              : 
     158              :    ! Molecule type
     159              :    TYPE molecule_type
     160              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind => NULL() ! pointer to molecule kind information
     161              :       TYPE(local_states_type), DIMENSION(:), POINTER     :: lmi => NULL() ! local (spin)-states information
     162              :       TYPE(local_constraint_type), POINTER               :: lci => NULL() ! local molecule constraint info
     163              :       INTEGER                                            :: first_atom = 0 ! global index of first atom in molecule
     164              :       INTEGER                                            :: last_atom = 0 ! global index of last atom in molecule
     165              :       INTEGER                                            :: first_shell = 0 ! global index of first shell atom in molecule
     166              :       INTEGER                                            :: last_shell = 0 ! global index of last shell atom in molecule
     167              :    END TYPE molecule_type
     168              : 
     169              :    ! Public data types
     170              : 
     171              :    PUBLIC :: local_colvar_constraint_type, &
     172              :              local_g3x3_constraint_type, &
     173              :              local_g4x6_constraint_type, &
     174              :              local_constraint_type, &
     175              :              local_states_type, &
     176              :              global_constraint_type, &
     177              :              molecule_type
     178              : 
     179              :    ! Public subroutines
     180              : 
     181              :    PUBLIC :: deallocate_global_constraint, &
     182              :              allocate_molecule_set, &
     183              :              deallocate_molecule_set, &
     184              :              get_molecule, &
     185              :              set_molecule, &
     186              :              set_molecule_set, &
     187              :              molecule_of_atom, &
     188              :              get_molecule_set_info, &
     189              :              get_domain_set_info
     190              : 
     191              : CONTAINS
     192              : 
     193              : ! **************************************************************************************************
     194              : !> \brief   Deallocate a global constraint.
     195              : !> \param gci ...
     196              : !> \par History
     197              : !>      07.2003 created [fawzi]
     198              : !>      01.2014 moved from cp_subsys_release() into separate routine.
     199              : !> \author  Ole Schuett
     200              : ! **************************************************************************************************
     201        11500 :    SUBROUTINE deallocate_global_constraint(gci)
     202              :       TYPE(global_constraint_type), POINTER              :: gci
     203              : 
     204              :       INTEGER                                            :: i
     205              : 
     206        11500 :       IF (ASSOCIATED(gci)) THEN
     207              :          ! List of constraints
     208        10950 :          IF (ASSOCIATED(gci%colv_list)) THEN
     209          110 :             DO i = 1, SIZE(gci%colv_list)
     210          110 :                DEALLOCATE (gci%colv_list(i)%i_atoms)
     211              :             END DO
     212           44 :             DEALLOCATE (gci%colv_list)
     213              :          END IF
     214              : 
     215        10950 :          IF (ASSOCIATED(gci%g3x3_list)) THEN
     216            4 :             DEALLOCATE (gci%g3x3_list)
     217              :          END IF
     218              : 
     219        10950 :          IF (ASSOCIATED(gci%g4x6_list)) THEN
     220            4 :             DEALLOCATE (gci%g4x6_list)
     221              :          END IF
     222              : 
     223              :          ! Local information
     224        10950 :          IF (ASSOCIATED(gci%lcolv)) THEN
     225          110 :             DO i = 1, SIZE(gci%lcolv)
     226           66 :                CALL colvar_release(gci%lcolv(i)%colvar)
     227          110 :                CALL colvar_release(gci%lcolv(i)%colvar_old)
     228              :             END DO
     229           44 :             DEALLOCATE (gci%lcolv)
     230              :          END IF
     231              : 
     232        10950 :          IF (ASSOCIATED(gci%lg3x3)) THEN
     233            4 :             DEALLOCATE (gci%lg3x3)
     234              :          END IF
     235              : 
     236        10950 :          IF (ASSOCIATED(gci%lg4x6)) THEN
     237            4 :             DEALLOCATE (gci%lg4x6)
     238              :          END IF
     239              : 
     240        10950 :          IF (ASSOCIATED(gci%fixd_list)) THEN
     241            2 :             DEALLOCATE (gci%fixd_list)
     242              :          END IF
     243              : 
     244        10950 :          DEALLOCATE (gci)
     245              :       END IF
     246        11500 :    END SUBROUTINE deallocate_global_constraint
     247              : 
     248              : ! **************************************************************************************************
     249              : !> \brief   Allocate a molecule set.
     250              : !> \param molecule_set ...
     251              : !> \param nmolecule ...
     252              : !> \date    29.08.2003
     253              : !> \author  Matthias Krack
     254              : !> \version 1.0
     255              : ! **************************************************************************************************
     256        11500 :    SUBROUTINE allocate_molecule_set(molecule_set, nmolecule)
     257              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     258              :       INTEGER, INTENT(IN)                                :: nmolecule
     259              : 
     260        11500 :       IF (ASSOCIATED(molecule_set)) CALL deallocate_molecule_set(molecule_set)
     261              : 
     262       350302 :       ALLOCATE (molecule_set(nmolecule))
     263              : 
     264        11500 :    END SUBROUTINE allocate_molecule_set
     265              : 
     266              : ! **************************************************************************************************
     267              : !> \brief   Deallocate a molecule set.
     268              : !> \param molecule_set ...
     269              : !> \date    29.08.2003
     270              : !> \author  Matthias Krack
     271              : !> \version 1.0
     272              : ! **************************************************************************************************
     273        11500 :    SUBROUTINE deallocate_molecule_set(molecule_set)
     274              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     275              : 
     276              :       INTEGER                                            :: imolecule, j
     277              : 
     278        11500 :       IF (ASSOCIATED(molecule_set)) THEN
     279              : 
     280       327302 :          DO imolecule = 1, SIZE(molecule_set)
     281       315802 :             IF (ASSOCIATED(molecule_set(imolecule)%lmi)) THEN
     282           70 :                DO j = 1, SIZE(molecule_set(imolecule)%lmi)
     283           70 :                   IF (ASSOCIATED(molecule_set(imolecule)%lmi(j)%states)) THEN
     284           40 :                      DEALLOCATE (molecule_set(imolecule)%lmi(j)%states)
     285              :                   END IF
     286              :                END DO
     287           30 :                DEALLOCATE (molecule_set(imolecule)%lmi)
     288              :             END IF
     289       327302 :             IF (ASSOCIATED(molecule_set(imolecule)%lci)) THEN
     290        43692 :                IF (ASSOCIATED(molecule_set(imolecule)%lci%lcolv)) THEN
     291         4336 :                   DO j = 1, SIZE(molecule_set(imolecule)%lci%lcolv)
     292         2228 :                      CALL colvar_release(molecule_set(imolecule)%lci%lcolv(j)%colvar)
     293         4336 :                      CALL colvar_release(molecule_set(imolecule)%lci%lcolv(j)%colvar_old)
     294              :                   END DO
     295         2108 :                   DEALLOCATE (molecule_set(imolecule)%lci%lcolv)
     296              :                END IF
     297        43692 :                IF (ASSOCIATED(molecule_set(imolecule)%lci%lg3x3)) THEN
     298        36354 :                   DEALLOCATE (molecule_set(imolecule)%lci%lg3x3)
     299              :                END IF
     300        43692 :                IF (ASSOCIATED(molecule_set(imolecule)%lci%lg4x6)) THEN
     301          650 :                   DEALLOCATE (molecule_set(imolecule)%lci%lg4x6)
     302              :                END IF
     303        43692 :                DEALLOCATE (molecule_set(imolecule)%lci)
     304              :             END IF
     305              :          END DO
     306        11500 :          DEALLOCATE (molecule_set)
     307              : 
     308              :       END IF
     309        11500 :       NULLIFY (molecule_set)
     310              : 
     311        11500 :    END SUBROUTINE deallocate_molecule_set
     312              : 
     313              : ! **************************************************************************************************
     314              : !> \brief   Get components from a molecule data set.
     315              : !> \param molecule ...
     316              : !> \param molecule_kind ...
     317              : !> \param lmi ...
     318              : !> \param lci ...
     319              : !> \param lg3x3 ...
     320              : !> \param lg4x6 ...
     321              : !> \param lcolv ...
     322              : !> \param first_atom ...
     323              : !> \param last_atom ...
     324              : !> \param first_shell ...
     325              : !> \param last_shell ...
     326              : !> \date    29.08.2003
     327              : !> \author  Matthias Krack
     328              : !> \version 1.0
     329              : ! **************************************************************************************************
     330      8698341 :    SUBROUTINE get_molecule(molecule, molecule_kind, lmi, lci, lg3x3, lg4x6, lcolv, &
     331              :                            first_atom, last_atom, first_shell, last_shell)
     332              : 
     333              :       TYPE(molecule_type), INTENT(IN)                    :: molecule
     334              :       TYPE(molecule_kind_type), OPTIONAL, POINTER        :: molecule_kind
     335              :       TYPE(local_states_type), DIMENSION(:), OPTIONAL, &
     336              :          POINTER                                         :: lmi
     337              :       TYPE(local_constraint_type), OPTIONAL, POINTER     :: lci
     338              :       TYPE(local_g3x3_constraint_type), OPTIONAL, &
     339              :          POINTER                                         :: lg3x3(:)
     340              :       TYPE(local_g4x6_constraint_type), OPTIONAL, &
     341              :          POINTER                                         :: lg4x6(:)
     342              :       TYPE(local_colvar_constraint_type), DIMENSION(:), &
     343              :          OPTIONAL, POINTER                               :: lcolv
     344              :       INTEGER, OPTIONAL                                  :: first_atom, last_atom, first_shell, &
     345              :                                                             last_shell
     346              : 
     347      8698341 :       IF (PRESENT(first_atom)) first_atom = molecule%first_atom
     348      8698341 :       IF (PRESENT(last_atom)) last_atom = molecule%last_atom
     349      8698341 :       IF (PRESENT(first_shell)) first_shell = molecule%first_shell
     350      8698341 :       IF (PRESENT(last_shell)) last_shell = molecule%last_shell
     351      8698341 :       IF (PRESENT(molecule_kind)) molecule_kind => molecule%molecule_kind
     352      8698341 :       IF (PRESENT(lmi)) lmi => molecule%lmi
     353      8698341 :       IF (PRESENT(lci)) lci => molecule%lci
     354      8698341 :       IF (PRESENT(lcolv)) THEN
     355       928471 :          IF (ASSOCIATED(molecule%lci)) THEN
     356       928471 :             lcolv => molecule%lci%lcolv
     357              :          ELSE
     358            0 :             CPABORT("The pointer lci is not associated")
     359              :          END IF
     360              :       END IF
     361      8698341 :       IF (PRESENT(lg3x3)) THEN
     362      1530904 :          IF (ASSOCIATED(molecule%lci)) THEN
     363      1530904 :             lg3x3 => molecule%lci%lg3x3
     364              :          ELSE
     365            0 :             CPABORT("The pointer lci is not associated")
     366              :          END IF
     367              :       END IF
     368      8698341 :       IF (PRESENT(lg4x6)) THEN
     369       885788 :          IF (ASSOCIATED(molecule%lci)) THEN
     370       885788 :             lg4x6 => molecule%lci%lg4x6
     371              :          ELSE
     372            0 :             CPABORT("The pointer lci is not associated")
     373              :          END IF
     374              :       END IF
     375              : 
     376      8698341 :    END SUBROUTINE get_molecule
     377              : 
     378              : ! **************************************************************************************************
     379              : !> \brief   Set a molecule data set.
     380              : !> \param molecule ...
     381              : !> \param molecule_kind ...
     382              : !> \param lmi ...
     383              : !> \param lci ...
     384              : !> \param lcolv ...
     385              : !> \param lg3x3 ...
     386              : !> \param lg4x6 ...
     387              : !> \date    29.08.2003
     388              : !> \author  Matthias Krack
     389              : !> \version 1.0
     390              : ! **************************************************************************************************
     391       982778 :    SUBROUTINE set_molecule(molecule, molecule_kind, lmi, lci, lcolv, lg3x3, lg4x6)
     392              :       TYPE(molecule_type), INTENT(INOUT)                 :: molecule
     393              :       TYPE(molecule_kind_type), OPTIONAL, POINTER        :: molecule_kind
     394              :       TYPE(local_states_type), DIMENSION(:), OPTIONAL, &
     395              :          POINTER                                         :: lmi
     396              :       TYPE(local_constraint_type), OPTIONAL, POINTER     :: lci
     397              :       TYPE(local_colvar_constraint_type), DIMENSION(:), &
     398              :          OPTIONAL, POINTER                               :: lcolv
     399              :       TYPE(local_g3x3_constraint_type), OPTIONAL, &
     400              :          POINTER                                         :: lg3x3(:)
     401              :       TYPE(local_g4x6_constraint_type), OPTIONAL, &
     402              :          POINTER                                         :: lg4x6(:)
     403              : 
     404       982778 :       IF (PRESENT(molecule_kind)) molecule%molecule_kind => molecule_kind
     405       982778 :       IF (PRESENT(lmi)) molecule%lmi => lmi
     406       982778 :       IF (PRESENT(lci)) molecule%lci => lci
     407       982778 :       IF (PRESENT(lcolv)) THEN
     408         2108 :          IF (ASSOCIATED(molecule%lci)) THEN
     409         2108 :             molecule%lci%lcolv => lcolv
     410              :          ELSE
     411            0 :             CPABORT("The pointer lci is not associated")
     412              :          END IF
     413              :       END IF
     414       982778 :       IF (PRESENT(lg3x3)) THEN
     415        36354 :          IF (ASSOCIATED(molecule%lci)) THEN
     416        36354 :             molecule%lci%lg3x3 => lg3x3
     417              :          ELSE
     418            0 :             CPABORT("The pointer lci is not associated")
     419              :          END IF
     420              :       END IF
     421       982778 :       IF (PRESENT(lg4x6)) THEN
     422          650 :          IF (ASSOCIATED(molecule%lci)) THEN
     423          650 :             molecule%lci%lg4x6 => lg4x6
     424              :          ELSE
     425            0 :             CPABORT("The pointer lci is not associated")
     426              :          END IF
     427              :       END IF
     428              : 
     429       982778 :    END SUBROUTINE set_molecule
     430              : 
     431              : ! **************************************************************************************************
     432              : !> \brief   Set a molecule data set.
     433              : !> \param molecule_set ...
     434              : !> \param first_atom ...
     435              : !> \param last_atom ...
     436              : !> \date    29.08.2003
     437              : !> \author  Matthias Krack
     438              : !> \version 1.0
     439              : ! **************************************************************************************************
     440        11500 :    SUBROUTINE set_molecule_set(molecule_set, first_atom, last_atom)
     441              :       TYPE(molecule_type), DIMENSION(:), INTENT(INOUT)   :: molecule_set
     442              :       INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL        :: first_atom, last_atom
     443              : 
     444              :       INTEGER                                            :: imolecule
     445              : 
     446        11500 :       IF (PRESENT(first_atom)) THEN
     447        11500 :          IF (SIZE(first_atom) /= SIZE(molecule_set)) THEN
     448              :             CALL cp_abort(__LOCATION__, &
     449              :                           "The sizes of first_atom and molecule_set "// &
     450            0 :                           "are different")
     451              :          END IF
     452              : 
     453       327302 :          DO imolecule = 1, SIZE(molecule_set)
     454       327302 :             molecule_set(imolecule)%first_atom = first_atom(imolecule)
     455              :          END DO
     456              :       END IF
     457              : 
     458        11500 :       IF (PRESENT(last_atom)) THEN
     459        11500 :          IF (SIZE(last_atom) /= SIZE(molecule_set)) THEN
     460              :             CALL cp_abort(__LOCATION__, &
     461              :                           "The sizes of last_atom and molecule_set "// &
     462            0 :                           "are different")
     463              :          END IF
     464              : 
     465       327302 :          DO imolecule = 1, SIZE(molecule_set)
     466       327302 :             molecule_set(imolecule)%last_atom = last_atom(imolecule)
     467              :          END DO
     468              :       END IF
     469              : 
     470        11500 :    END SUBROUTINE set_molecule_set
     471              : 
     472              : ! **************************************************************************************************
     473              : !> \brief   finds for each atom the molecule it belongs to
     474              : !> \param molecule_set ...
     475              : !> \param atom_to_mol ...
     476              : ! **************************************************************************************************
     477          536 :    SUBROUTINE molecule_of_atom(molecule_set, atom_to_mol)
     478              :       TYPE(molecule_type), DIMENSION(:), INTENT(IN)      :: molecule_set
     479              :       INTEGER, DIMENSION(:), INTENT(OUT)                 :: atom_to_mol
     480              : 
     481              :       INTEGER                                            :: first_atom, iatom, imol, last_atom
     482              : 
     483         3386 :       DO imol = 1, SIZE(molecule_set)
     484         2850 :          CALL get_molecule(molecule=molecule_set(imol), first_atom=first_atom, last_atom=last_atom)
     485         9728 :          DO iatom = first_atom, last_atom
     486         9192 :             atom_to_mol(iatom) = imol
     487              :          END DO ! iatom
     488              :       END DO ! imol
     489              : 
     490          536 :    END SUBROUTINE molecule_of_atom
     491              : 
     492              : ! **************************************************************************************************
     493              : !> \brief returns information about molecules in the set.
     494              : !> \param molecule_set ...
     495              : !> \param atom_to_mol ...
     496              : !> \param mol_to_first_atom ...
     497              : !> \param mol_to_last_atom ...
     498              : !> \param mol_to_nelectrons ...
     499              : !> \param mol_to_nbasis ...
     500              : !> \param mol_to_charge ...
     501              : !> \param mol_to_multiplicity ...
     502              : !> \par History
     503              : !>       2011.06 created [Rustam Z Khaliullin]
     504              : !> \author Rustam Z Khaliullin
     505              : ! **************************************************************************************************
     506          780 :    SUBROUTINE get_molecule_set_info(molecule_set, atom_to_mol, mol_to_first_atom, &
     507          780 :                                     mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, &
     508          260 :                                     mol_to_multiplicity)
     509              : 
     510              :       TYPE(molecule_type), DIMENSION(:), INTENT(IN)      :: molecule_set
     511              :       INTEGER, DIMENSION(:), INTENT(OUT), OPTIONAL :: atom_to_mol, mol_to_first_atom, &
     512              :          mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, mol_to_multiplicity
     513              : 
     514              :       INTEGER                                            :: first_atom, iatom, imol, last_atom, &
     515              :                                                             nbasis, nelec
     516              :       REAL(KIND=dp)                                      :: charge
     517              :       TYPE(molecule_kind_type), POINTER                  :: imol_kind
     518              : 
     519         1948 :       DO imol = 1, SIZE(molecule_set)
     520              : 
     521              :          CALL get_molecule(molecule=molecule_set(imol), molecule_kind=imol_kind, &
     522         1688 :                            first_atom=first_atom, last_atom=last_atom)
     523              : 
     524         1688 :          IF (PRESENT(mol_to_nelectrons)) THEN
     525          822 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     526          822 :             mol_to_nelectrons(imol) = nelec
     527              :          END IF
     528              : 
     529         1688 :          IF (PRESENT(mol_to_multiplicity)) THEN
     530              :             ! RZK-warning: At the moment we can only get the total number
     531              :             !  of electrons (alpha+beta) and we do not have a way to get the multiplicity of mols.
     532              :             !  Therefore, the best we can do is to assume the singlet state for even number of electrons
     533              :             !  and doublet state for odd number of electrons (assume ne_alpha > ne_beta).
     534              :             !  The best way to implement a correct multiplicity subroutine in the future is to get
     535              :             !  the number of alpha and beta e- for each atom from init_atom_electronic_state. This way (as opposed to
     536              :             !  reading the multiplicities from file) the number of occupied and virtual orbitals
     537              :             !  will be consistent with atomic guess. A guess with broken symmetry will be easy to
     538              :             !  implement as well.
     539          854 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     540          854 :             IF (MOD(nelec, 2) == 0) THEN
     541          844 :                mol_to_multiplicity(imol) = 1
     542              :             ELSE
     543           10 :                mol_to_multiplicity(imol) = 2
     544              :             END IF
     545              :          END IF
     546              : 
     547         1688 :          IF (PRESENT(mol_to_charge)) THEN
     548          854 :             CALL get_molecule_kind(imol_kind, charge=charge)
     549          854 :             mol_to_charge(imol) = NINT(charge)
     550              :          END IF
     551              : 
     552         1688 :          IF (PRESENT(mol_to_nbasis)) THEN
     553          822 :             CALL get_molecule_kind(imol_kind, nsgf=nbasis)
     554          822 :             mol_to_nbasis(imol) = nbasis
     555              :          END IF
     556              : 
     557         1688 :          IF (PRESENT(mol_to_first_atom)) THEN
     558         1688 :             mol_to_first_atom(imol) = first_atom
     559              :          END IF
     560              : 
     561         1688 :          IF (PRESENT(mol_to_last_atom)) THEN
     562         1688 :             mol_to_last_atom(imol) = last_atom
     563              :          END IF
     564              : 
     565         1948 :          IF (PRESENT(atom_to_mol)) THEN
     566         2806 :             DO iatom = first_atom, last_atom
     567         2806 :                atom_to_mol(iatom) = imol
     568              :             END DO ! iatom
     569              :          END IF
     570              : 
     571              :       END DO ! imol
     572              : 
     573          260 :    END SUBROUTINE get_molecule_set_info
     574              : 
     575              : ! **************************************************************************************************
     576              : !> \brief ...
     577              : !> \param molecule_set ...
     578              : !> \param atom_to_mol ...
     579              : !> \param mol_to_first_atom ...
     580              : !> \param mol_to_last_atom ...
     581              : !> \param mol_to_nelectrons ...
     582              : !> \param mol_to_nbasis ...
     583              : !> \param mol_to_charge ...
     584              : !> \param mol_to_multiplicity ...
     585              : ! **************************************************************************************************
     586            0 :    SUBROUTINE get_domain_set_info(molecule_set, atom_to_mol, mol_to_first_atom, &
     587            0 :                                   mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, &
     588            0 :                                   mol_to_multiplicity)
     589              : 
     590              :       TYPE(molecule_type), DIMENSION(:), INTENT(IN)      :: molecule_set
     591              :       INTEGER, DIMENSION(:), INTENT(OUT), OPTIONAL :: atom_to_mol, mol_to_first_atom, &
     592              :          mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, mol_to_multiplicity
     593              : 
     594              :       INTEGER                                            :: first_atom, iatom, imol, last_atom, &
     595              :                                                             nbasis, nelec
     596              :       REAL(KIND=dp)                                      :: charge
     597              :       TYPE(molecule_kind_type), POINTER                  :: imol_kind
     598              : 
     599            0 :       DO imol = 1, SIZE(molecule_set)
     600              : 
     601              :          CALL get_molecule(molecule=molecule_set(imol), molecule_kind=imol_kind, &
     602            0 :                            first_atom=first_atom, last_atom=last_atom)
     603              : 
     604            0 :          IF (PRESENT(mol_to_nelectrons)) THEN
     605            0 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     606            0 :             mol_to_nelectrons(imol) = nelec
     607              :          END IF
     608              : 
     609            0 :          IF (PRESENT(mol_to_multiplicity)) THEN
     610              :             ! RZK-warning: At the moment we can only get the total number
     611              :             !  of electrons (alpha+beta) and we do not have a way to get the multiplicity of mols.
     612              :             !  Therefore, the best we can do is to assume the singlet state for even number of electrons
     613              :             !  and doublet state for odd number of electrons (assume ne_alpha > ne_beta).
     614              :             !  The best way to implement a correct multiplicity subroutine in the future is to get
     615              :             !  the number of alpha and beta e- for each atom from init_atom_electronic_state. This way (as opposed to
     616              :             !  reading the multiplicities from file) the number of occupied and virtual orbitals
     617              :             !  will be consistent with atomic guess. A guess with broken symmetry will be easy to
     618              :             !  implement as well.
     619            0 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     620            0 :             IF (MOD(nelec, 2) == 0) THEN
     621            0 :                mol_to_multiplicity(imol) = 1
     622              :             ELSE
     623            0 :                mol_to_multiplicity(imol) = 2
     624              :             END IF
     625              :          END IF
     626              : 
     627            0 :          IF (PRESENT(mol_to_charge)) THEN
     628            0 :             CALL get_molecule_kind(imol_kind, charge=charge)
     629            0 :             mol_to_charge(imol) = NINT(charge)
     630              :          END IF
     631              : 
     632            0 :          IF (PRESENT(mol_to_nbasis)) THEN
     633            0 :             CALL get_molecule_kind(imol_kind, nsgf=nbasis)
     634            0 :             mol_to_nbasis(imol) = nbasis
     635              :          END IF
     636              : 
     637            0 :          IF (PRESENT(mol_to_first_atom)) THEN
     638            0 :             mol_to_first_atom(imol) = first_atom
     639              :          END IF
     640              : 
     641            0 :          IF (PRESENT(mol_to_last_atom)) THEN
     642            0 :             mol_to_last_atom(imol) = last_atom
     643              :          END IF
     644              : 
     645            0 :          IF (PRESENT(atom_to_mol)) THEN
     646            0 :             DO iatom = first_atom, last_atom
     647            0 :                atom_to_mol(iatom) = imol
     648              :             END DO ! iatom
     649              :          END IF
     650              : 
     651              :       END DO ! imol
     652              : 
     653            0 :    END SUBROUTINE get_domain_set_info
     654              : 
     655            0 : END MODULE molecule_types
        

Generated by: LCOV version 2.0-1