LCOV - code coverage report
Current view: top level - src/subsys - molecule_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:85b8a9b) Lines: 77.5 % 160 124
Test Date: 2026-06-14 06:48:14 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        11338 :    SUBROUTINE deallocate_global_constraint(gci)
     202              :       TYPE(global_constraint_type), POINTER              :: gci
     203              : 
     204              :       INTEGER                                            :: i
     205              : 
     206        11338 :       IF (ASSOCIATED(gci)) THEN
     207              :          ! List of constraints
     208        10788 :          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        10788 :          IF (ASSOCIATED(gci%g3x3_list)) &
     216            4 :             DEALLOCATE (gci%g3x3_list)
     217              : 
     218        10788 :          IF (ASSOCIATED(gci%g4x6_list)) &
     219            4 :             DEALLOCATE (gci%g4x6_list)
     220              : 
     221              :          ! Local information
     222        10788 :          IF (ASSOCIATED(gci%lcolv)) THEN
     223          110 :             DO i = 1, SIZE(gci%lcolv)
     224           66 :                CALL colvar_release(gci%lcolv(i)%colvar)
     225          110 :                CALL colvar_release(gci%lcolv(i)%colvar_old)
     226              :             END DO
     227           44 :             DEALLOCATE (gci%lcolv)
     228              :          END IF
     229              : 
     230        10788 :          IF (ASSOCIATED(gci%lg3x3)) &
     231            4 :             DEALLOCATE (gci%lg3x3)
     232              : 
     233        10788 :          IF (ASSOCIATED(gci%lg4x6)) &
     234            4 :             DEALLOCATE (gci%lg4x6)
     235              : 
     236        10788 :          IF (ASSOCIATED(gci%fixd_list)) &
     237            2 :             DEALLOCATE (gci%fixd_list)
     238              : 
     239        10788 :          DEALLOCATE (gci)
     240              :       END IF
     241        11338 :    END SUBROUTINE deallocate_global_constraint
     242              : 
     243              : ! **************************************************************************************************
     244              : !> \brief   Allocate a molecule set.
     245              : !> \param molecule_set ...
     246              : !> \param nmolecule ...
     247              : !> \date    29.08.2003
     248              : !> \author  Matthias Krack
     249              : !> \version 1.0
     250              : ! **************************************************************************************************
     251        11338 :    SUBROUTINE allocate_molecule_set(molecule_set, nmolecule)
     252              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     253              :       INTEGER, INTENT(IN)                                :: nmolecule
     254              : 
     255        11338 :       IF (ASSOCIATED(molecule_set)) CALL deallocate_molecule_set(molecule_set)
     256              : 
     257       348958 :       ALLOCATE (molecule_set(nmolecule))
     258              : 
     259        11338 :    END SUBROUTINE allocate_molecule_set
     260              : 
     261              : ! **************************************************************************************************
     262              : !> \brief   Deallocate a molecule set.
     263              : !> \param molecule_set ...
     264              : !> \date    29.08.2003
     265              : !> \author  Matthias Krack
     266              : !> \version 1.0
     267              : ! **************************************************************************************************
     268        11338 :    SUBROUTINE deallocate_molecule_set(molecule_set)
     269              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     270              : 
     271              :       INTEGER                                            :: imolecule, j
     272              : 
     273        11338 :       IF (ASSOCIATED(molecule_set)) THEN
     274              : 
     275       326282 :          DO imolecule = 1, SIZE(molecule_set)
     276       314944 :             IF (ASSOCIATED(molecule_set(imolecule)%lmi)) THEN
     277           70 :                DO j = 1, SIZE(molecule_set(imolecule)%lmi)
     278           70 :                   IF (ASSOCIATED(molecule_set(imolecule)%lmi(j)%states)) THEN
     279           40 :                      DEALLOCATE (molecule_set(imolecule)%lmi(j)%states)
     280              :                   END IF
     281              :                END DO
     282           30 :                DEALLOCATE (molecule_set(imolecule)%lmi)
     283              :             END IF
     284       326282 :             IF (ASSOCIATED(molecule_set(imolecule)%lci)) THEN
     285        43692 :                IF (ASSOCIATED(molecule_set(imolecule)%lci%lcolv)) THEN
     286         4336 :                   DO j = 1, SIZE(molecule_set(imolecule)%lci%lcolv)
     287         2228 :                      CALL colvar_release(molecule_set(imolecule)%lci%lcolv(j)%colvar)
     288         4336 :                      CALL colvar_release(molecule_set(imolecule)%lci%lcolv(j)%colvar_old)
     289              :                   END DO
     290         2108 :                   DEALLOCATE (molecule_set(imolecule)%lci%lcolv)
     291              :                END IF
     292        43692 :                IF (ASSOCIATED(molecule_set(imolecule)%lci%lg3x3)) THEN
     293        36354 :                   DEALLOCATE (molecule_set(imolecule)%lci%lg3x3)
     294              :                END IF
     295        43692 :                IF (ASSOCIATED(molecule_set(imolecule)%lci%lg4x6)) THEN
     296          650 :                   DEALLOCATE (molecule_set(imolecule)%lci%lg4x6)
     297              :                END IF
     298        43692 :                DEALLOCATE (molecule_set(imolecule)%lci)
     299              :             END IF
     300              :          END DO
     301        11338 :          DEALLOCATE (molecule_set)
     302              : 
     303              :       END IF
     304        11338 :       NULLIFY (molecule_set)
     305              : 
     306        11338 :    END SUBROUTINE deallocate_molecule_set
     307              : 
     308              : ! **************************************************************************************************
     309              : !> \brief   Get components from a molecule data set.
     310              : !> \param molecule ...
     311              : !> \param molecule_kind ...
     312              : !> \param lmi ...
     313              : !> \param lci ...
     314              : !> \param lg3x3 ...
     315              : !> \param lg4x6 ...
     316              : !> \param lcolv ...
     317              : !> \param first_atom ...
     318              : !> \param last_atom ...
     319              : !> \param first_shell ...
     320              : !> \param last_shell ...
     321              : !> \date    29.08.2003
     322              : !> \author  Matthias Krack
     323              : !> \version 1.0
     324              : ! **************************************************************************************************
     325      8688461 :    SUBROUTINE get_molecule(molecule, molecule_kind, lmi, lci, lg3x3, lg4x6, lcolv, &
     326              :                            first_atom, last_atom, first_shell, last_shell)
     327              : 
     328              :       TYPE(molecule_type), INTENT(IN)                    :: molecule
     329              :       TYPE(molecule_kind_type), OPTIONAL, POINTER        :: molecule_kind
     330              :       TYPE(local_states_type), DIMENSION(:), OPTIONAL, &
     331              :          POINTER                                         :: lmi
     332              :       TYPE(local_constraint_type), OPTIONAL, POINTER     :: lci
     333              :       TYPE(local_g3x3_constraint_type), OPTIONAL, &
     334              :          POINTER                                         :: lg3x3(:)
     335              :       TYPE(local_g4x6_constraint_type), OPTIONAL, &
     336              :          POINTER                                         :: lg4x6(:)
     337              :       TYPE(local_colvar_constraint_type), DIMENSION(:), &
     338              :          OPTIONAL, POINTER                               :: lcolv
     339              :       INTEGER, OPTIONAL                                  :: first_atom, last_atom, first_shell, &
     340              :                                                             last_shell
     341              : 
     342      8688461 :       IF (PRESENT(first_atom)) first_atom = molecule%first_atom
     343      8688461 :       IF (PRESENT(last_atom)) last_atom = molecule%last_atom
     344      8688461 :       IF (PRESENT(first_shell)) first_shell = molecule%first_shell
     345      8688461 :       IF (PRESENT(last_shell)) last_shell = molecule%last_shell
     346      8688461 :       IF (PRESENT(molecule_kind)) molecule_kind => molecule%molecule_kind
     347      8688461 :       IF (PRESENT(lmi)) lmi => molecule%lmi
     348      8688461 :       IF (PRESENT(lci)) lci => molecule%lci
     349      8688461 :       IF (PRESENT(lcolv)) THEN
     350       928471 :          IF (ASSOCIATED(molecule%lci)) THEN
     351       928471 :             lcolv => molecule%lci%lcolv
     352              :          ELSE
     353            0 :             CPABORT("The pointer lci is not associated")
     354              :          END IF
     355              :       END IF
     356      8688461 :       IF (PRESENT(lg3x3)) THEN
     357      1530904 :          IF (ASSOCIATED(molecule%lci)) THEN
     358      1530904 :             lg3x3 => molecule%lci%lg3x3
     359              :          ELSE
     360            0 :             CPABORT("The pointer lci is not associated")
     361              :          END IF
     362              :       END IF
     363      8688461 :       IF (PRESENT(lg4x6)) THEN
     364       885788 :          IF (ASSOCIATED(molecule%lci)) THEN
     365       885788 :             lg4x6 => molecule%lci%lg4x6
     366              :          ELSE
     367            0 :             CPABORT("The pointer lci is not associated")
     368              :          END IF
     369              :       END IF
     370              : 
     371      8688461 :    END SUBROUTINE get_molecule
     372              : 
     373              : ! **************************************************************************************************
     374              : !> \brief   Set a molecule data set.
     375              : !> \param molecule ...
     376              : !> \param molecule_kind ...
     377              : !> \param lmi ...
     378              : !> \param lci ...
     379              : !> \param lcolv ...
     380              : !> \param lg3x3 ...
     381              : !> \param lg4x6 ...
     382              : !> \date    29.08.2003
     383              : !> \author  Matthias Krack
     384              : !> \version 1.0
     385              : ! **************************************************************************************************
     386       980204 :    SUBROUTINE set_molecule(molecule, molecule_kind, lmi, lci, lcolv, lg3x3, lg4x6)
     387              :       TYPE(molecule_type), INTENT(INOUT)                 :: molecule
     388              :       TYPE(molecule_kind_type), OPTIONAL, POINTER        :: molecule_kind
     389              :       TYPE(local_states_type), DIMENSION(:), OPTIONAL, &
     390              :          POINTER                                         :: lmi
     391              :       TYPE(local_constraint_type), OPTIONAL, POINTER     :: lci
     392              :       TYPE(local_colvar_constraint_type), DIMENSION(:), &
     393              :          OPTIONAL, POINTER                               :: lcolv
     394              :       TYPE(local_g3x3_constraint_type), OPTIONAL, &
     395              :          POINTER                                         :: lg3x3(:)
     396              :       TYPE(local_g4x6_constraint_type), OPTIONAL, &
     397              :          POINTER                                         :: lg4x6(:)
     398              : 
     399       980204 :       IF (PRESENT(molecule_kind)) molecule%molecule_kind => molecule_kind
     400       980204 :       IF (PRESENT(lmi)) molecule%lmi => lmi
     401       980204 :       IF (PRESENT(lci)) molecule%lci => lci
     402       980204 :       IF (PRESENT(lcolv)) THEN
     403         2108 :          IF (ASSOCIATED(molecule%lci)) THEN
     404         2108 :             molecule%lci%lcolv => lcolv
     405              :          ELSE
     406            0 :             CPABORT("The pointer lci is not associated")
     407              :          END IF
     408              :       END IF
     409       980204 :       IF (PRESENT(lg3x3)) THEN
     410        36354 :          IF (ASSOCIATED(molecule%lci)) THEN
     411        36354 :             molecule%lci%lg3x3 => lg3x3
     412              :          ELSE
     413            0 :             CPABORT("The pointer lci is not associated")
     414              :          END IF
     415              :       END IF
     416       980204 :       IF (PRESENT(lg4x6)) THEN
     417          650 :          IF (ASSOCIATED(molecule%lci)) THEN
     418          650 :             molecule%lci%lg4x6 => lg4x6
     419              :          ELSE
     420            0 :             CPABORT("The pointer lci is not associated")
     421              :          END IF
     422              :       END IF
     423              : 
     424       980204 :    END SUBROUTINE set_molecule
     425              : 
     426              : ! **************************************************************************************************
     427              : !> \brief   Set a molecule data set.
     428              : !> \param molecule_set ...
     429              : !> \param first_atom ...
     430              : !> \param last_atom ...
     431              : !> \date    29.08.2003
     432              : !> \author  Matthias Krack
     433              : !> \version 1.0
     434              : ! **************************************************************************************************
     435        11338 :    SUBROUTINE set_molecule_set(molecule_set, first_atom, last_atom)
     436              :       TYPE(molecule_type), DIMENSION(:), INTENT(INOUT)   :: molecule_set
     437              :       INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL        :: first_atom, last_atom
     438              : 
     439              :       INTEGER                                            :: imolecule
     440              : 
     441        11338 :       IF (PRESENT(first_atom)) THEN
     442        11338 :          IF (SIZE(first_atom) /= SIZE(molecule_set)) THEN
     443              :             CALL cp_abort(__LOCATION__, &
     444              :                           "The sizes of first_atom and molecule_set "// &
     445            0 :                           "are different")
     446              :          END IF
     447              : 
     448       326282 :          DO imolecule = 1, SIZE(molecule_set)
     449       326282 :             molecule_set(imolecule)%first_atom = first_atom(imolecule)
     450              :          END DO
     451              :       END IF
     452              : 
     453        11338 :       IF (PRESENT(last_atom)) THEN
     454        11338 :          IF (SIZE(last_atom) /= SIZE(molecule_set)) THEN
     455              :             CALL cp_abort(__LOCATION__, &
     456              :                           "The sizes of last_atom and molecule_set "// &
     457            0 :                           "are different")
     458              :          END IF
     459              : 
     460       326282 :          DO imolecule = 1, SIZE(molecule_set)
     461       326282 :             molecule_set(imolecule)%last_atom = last_atom(imolecule)
     462              :          END DO
     463              :       END IF
     464              : 
     465        11338 :    END SUBROUTINE set_molecule_set
     466              : 
     467              : ! **************************************************************************************************
     468              : !> \brief   finds for each atom the molecule it belongs to
     469              : !> \param molecule_set ...
     470              : !> \param atom_to_mol ...
     471              : ! **************************************************************************************************
     472          536 :    SUBROUTINE molecule_of_atom(molecule_set, atom_to_mol)
     473              :       TYPE(molecule_type), DIMENSION(:), INTENT(IN)      :: molecule_set
     474              :       INTEGER, DIMENSION(:), INTENT(OUT)                 :: atom_to_mol
     475              : 
     476              :       INTEGER                                            :: first_atom, iatom, imol, last_atom
     477              : 
     478         3386 :       DO imol = 1, SIZE(molecule_set)
     479         2850 :          CALL get_molecule(molecule=molecule_set(imol), first_atom=first_atom, last_atom=last_atom)
     480         9728 :          DO iatom = first_atom, last_atom
     481         9192 :             atom_to_mol(iatom) = imol
     482              :          END DO ! iatom
     483              :       END DO ! imol
     484              : 
     485          536 :    END SUBROUTINE molecule_of_atom
     486              : 
     487              : ! **************************************************************************************************
     488              : !> \brief returns information about molecules in the set.
     489              : !> \param molecule_set ...
     490              : !> \param atom_to_mol ...
     491              : !> \param mol_to_first_atom ...
     492              : !> \param mol_to_last_atom ...
     493              : !> \param mol_to_nelectrons ...
     494              : !> \param mol_to_nbasis ...
     495              : !> \param mol_to_charge ...
     496              : !> \param mol_to_multiplicity ...
     497              : !> \par History
     498              : !>       2011.06 created [Rustam Z Khaliullin]
     499              : !> \author Rustam Z Khaliullin
     500              : ! **************************************************************************************************
     501          780 :    SUBROUTINE get_molecule_set_info(molecule_set, atom_to_mol, mol_to_first_atom, &
     502          780 :                                     mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, &
     503          260 :                                     mol_to_multiplicity)
     504              : 
     505              :       TYPE(molecule_type), DIMENSION(:), INTENT(IN)      :: molecule_set
     506              :       INTEGER, DIMENSION(:), INTENT(OUT), OPTIONAL :: atom_to_mol, mol_to_first_atom, &
     507              :          mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, mol_to_multiplicity
     508              : 
     509              :       INTEGER                                            :: first_atom, iatom, imol, last_atom, &
     510              :                                                             nbasis, nelec
     511              :       REAL(KIND=dp)                                      :: charge
     512              :       TYPE(molecule_kind_type), POINTER                  :: imol_kind
     513              : 
     514         1948 :       DO imol = 1, SIZE(molecule_set)
     515              : 
     516              :          CALL get_molecule(molecule=molecule_set(imol), molecule_kind=imol_kind, &
     517         1688 :                            first_atom=first_atom, last_atom=last_atom)
     518              : 
     519         1688 :          IF (PRESENT(mol_to_nelectrons)) THEN
     520          822 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     521          822 :             mol_to_nelectrons(imol) = nelec
     522              :          END IF
     523              : 
     524         1688 :          IF (PRESENT(mol_to_multiplicity)) THEN
     525              :             ! RZK-warning: At the moment we can only get the total number
     526              :             !  of electrons (alpha+beta) and we do not have a way to get the multiplicity of mols.
     527              :             !  Therefore, the best we can do is to assume the singlet state for even number of electrons
     528              :             !  and doublet state for odd number of electrons (assume ne_alpha > ne_beta).
     529              :             !  The best way to implement a correct multiplicity subroutine in the future is to get
     530              :             !  the number of alpha and beta e- for each atom from init_atom_electronic_state. This way (as opposed to
     531              :             !  reading the multiplicities from file) the number of occupied and virtual orbitals
     532              :             !  will be consistent with atomic guess. A guess with broken symmetry will be easy to
     533              :             !  implement as well.
     534          854 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     535          854 :             IF (MOD(nelec, 2) == 0) THEN
     536          844 :                mol_to_multiplicity(imol) = 1
     537              :             ELSE
     538           10 :                mol_to_multiplicity(imol) = 2
     539              :             END IF
     540              :          END IF
     541              : 
     542         1688 :          IF (PRESENT(mol_to_charge)) THEN
     543          854 :             CALL get_molecule_kind(imol_kind, charge=charge)
     544          854 :             mol_to_charge(imol) = NINT(charge)
     545              :          END IF
     546              : 
     547         1688 :          IF (PRESENT(mol_to_nbasis)) THEN
     548          822 :             CALL get_molecule_kind(imol_kind, nsgf=nbasis)
     549          822 :             mol_to_nbasis(imol) = nbasis
     550              :          END IF
     551              : 
     552         1688 :          IF (PRESENT(mol_to_first_atom)) THEN
     553         1688 :             mol_to_first_atom(imol) = first_atom
     554              :          END IF
     555              : 
     556         1688 :          IF (PRESENT(mol_to_last_atom)) THEN
     557         1688 :             mol_to_last_atom(imol) = last_atom
     558              :          END IF
     559              : 
     560         1948 :          IF (PRESENT(atom_to_mol)) THEN
     561         2806 :             DO iatom = first_atom, last_atom
     562         2806 :                atom_to_mol(iatom) = imol
     563              :             END DO ! iatom
     564              :          END IF
     565              : 
     566              :       END DO ! imol
     567              : 
     568          260 :    END SUBROUTINE get_molecule_set_info
     569              : 
     570              : ! **************************************************************************************************
     571              : !> \brief ...
     572              : !> \param molecule_set ...
     573              : !> \param atom_to_mol ...
     574              : !> \param mol_to_first_atom ...
     575              : !> \param mol_to_last_atom ...
     576              : !> \param mol_to_nelectrons ...
     577              : !> \param mol_to_nbasis ...
     578              : !> \param mol_to_charge ...
     579              : !> \param mol_to_multiplicity ...
     580              : ! **************************************************************************************************
     581            0 :    SUBROUTINE get_domain_set_info(molecule_set, atom_to_mol, mol_to_first_atom, &
     582            0 :                                   mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, &
     583            0 :                                   mol_to_multiplicity)
     584              : 
     585              :       TYPE(molecule_type), DIMENSION(:), INTENT(IN)      :: molecule_set
     586              :       INTEGER, DIMENSION(:), INTENT(OUT), OPTIONAL :: atom_to_mol, mol_to_first_atom, &
     587              :          mol_to_last_atom, mol_to_nelectrons, mol_to_nbasis, mol_to_charge, mol_to_multiplicity
     588              : 
     589              :       INTEGER                                            :: first_atom, iatom, imol, last_atom, &
     590              :                                                             nbasis, nelec
     591              :       REAL(KIND=dp)                                      :: charge
     592              :       TYPE(molecule_kind_type), POINTER                  :: imol_kind
     593              : 
     594            0 :       DO imol = 1, SIZE(molecule_set)
     595              : 
     596              :          CALL get_molecule(molecule=molecule_set(imol), molecule_kind=imol_kind, &
     597            0 :                            first_atom=first_atom, last_atom=last_atom)
     598              : 
     599            0 :          IF (PRESENT(mol_to_nelectrons)) THEN
     600            0 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     601            0 :             mol_to_nelectrons(imol) = nelec
     602              :          END IF
     603              : 
     604            0 :          IF (PRESENT(mol_to_multiplicity)) THEN
     605              :             ! RZK-warning: At the moment we can only get the total number
     606              :             !  of electrons (alpha+beta) and we do not have a way to get the multiplicity of mols.
     607              :             !  Therefore, the best we can do is to assume the singlet state for even number of electrons
     608              :             !  and doublet state for odd number of electrons (assume ne_alpha > ne_beta).
     609              :             !  The best way to implement a correct multiplicity subroutine in the future is to get
     610              :             !  the number of alpha and beta e- for each atom from init_atom_electronic_state. This way (as opposed to
     611              :             !  reading the multiplicities from file) the number of occupied and virtual orbitals
     612              :             !  will be consistent with atomic guess. A guess with broken symmetry will be easy to
     613              :             !  implement as well.
     614            0 :             CALL get_molecule_kind(imol_kind, nelectron=nelec)
     615            0 :             IF (MOD(nelec, 2) == 0) THEN
     616            0 :                mol_to_multiplicity(imol) = 1
     617              :             ELSE
     618            0 :                mol_to_multiplicity(imol) = 2
     619              :             END IF
     620              :          END IF
     621              : 
     622            0 :          IF (PRESENT(mol_to_charge)) THEN
     623            0 :             CALL get_molecule_kind(imol_kind, charge=charge)
     624            0 :             mol_to_charge(imol) = NINT(charge)
     625              :          END IF
     626              : 
     627            0 :          IF (PRESENT(mol_to_nbasis)) THEN
     628            0 :             CALL get_molecule_kind(imol_kind, nsgf=nbasis)
     629            0 :             mol_to_nbasis(imol) = nbasis
     630              :          END IF
     631              : 
     632            0 :          IF (PRESENT(mol_to_first_atom)) THEN
     633            0 :             mol_to_first_atom(imol) = first_atom
     634              :          END IF
     635              : 
     636            0 :          IF (PRESENT(mol_to_last_atom)) THEN
     637            0 :             mol_to_last_atom(imol) = last_atom
     638              :          END IF
     639              : 
     640            0 :          IF (PRESENT(atom_to_mol)) THEN
     641            0 :             DO iatom = first_atom, last_atom
     642            0 :                atom_to_mol(iatom) = imol
     643              :             END DO ! iatom
     644              :          END IF
     645              : 
     646              :       END DO ! imol
     647              : 
     648            0 :    END SUBROUTINE get_domain_set_info
     649              : 
     650            0 : END MODULE molecule_types
        

Generated by: LCOV version 2.0-1