LCOV - code coverage report
Current view: top level - src - mscfg_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cb5d5fc) Lines: 99.3 % 151 150
Test Date: 2026-04-24 07:01:27 Functions: 100.0 % 4 4

            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 Subroutines to perform calculations on molecules from a bigger
      10              : !>        system. Useful to generate a high-quality MO guess for systems
      11              : !>        of many molecules with complex electronic structure, to bootstrap
      12              : !>        ALMO simulations, etc.
      13              : !> \par History
      14              : !>      10.2014 Rustam Z Khaliullin
      15              : !>      09.2018 ALMO smearing support and ALMO diag+molecular_guess patch [Ruben Staub]
      16              : !> \author Rustam Z Khaliullin
      17              : ! **************************************************************************************************
      18              : MODULE mscfg_methods
      19              :    USE almo_scf_types,                  ONLY: almo_scf_env_type
      20              :    USE atomic_kind_types,               ONLY: get_atomic_kind
      21              :    USE cp_dbcsr_api,                    ONLY: dbcsr_copy,&
      22              :                                               dbcsr_create,&
      23              :                                               dbcsr_type_no_symmetry
      24              :    USE cp_dbcsr_operations,             ONLY: copy_fm_to_dbcsr
      25              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      26              :                                               cp_logger_get_default_unit_nr,&
      27              :                                               cp_logger_type
      28              :    USE cp_subsys_methods,               ONLY: create_small_subsys
      29              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      30              :                                               cp_subsys_release,&
      31              :                                               cp_subsys_type
      32              :    USE force_env_types,                 ONLY: force_env_get,&
      33              :                                               force_env_type
      34              :    USE global_types,                    ONLY: global_environment_type
      35              :    USE input_constants,                 ONLY: almo_frz_crystal,&
      36              :                                               almo_frz_none,&
      37              :                                               do_qs,&
      38              :                                               molecular_guess
      39              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      40              :                                               section_vals_type,&
      41              :                                               section_vals_val_get,&
      42              :                                               section_vals_val_set
      43              :    USE kinds,                           ONLY: default_string_length
      44              :    USE message_passing,                 ONLY: mp_para_env_type
      45              :    USE molecule_types,                  ONLY: get_molecule_set_info,&
      46              :                                               molecule_type
      47              :    USE mscfg_types,                     ONLY: molecular_scf_guess_env_init,&
      48              :                                               molecular_scf_guess_env_type,&
      49              :                                               mscfg_max_moset_size
      50              :    USE particle_list_types,             ONLY: particle_list_type
      51              :    USE qs_energy,                       ONLY: qs_energies
      52              :    USE qs_energy_types,                 ONLY: qs_energy_type
      53              :    USE qs_environment,                  ONLY: qs_init
      54              :    USE qs_environment_types,            ONLY: get_qs_env,&
      55              :                                               qs_env_create,&
      56              :                                               qs_env_release,&
      57              :                                               qs_environment_type
      58              :    USE qs_mo_types,                     ONLY: get_mo_set,&
      59              :                                               mo_set_type
      60              : #include "./base/base_uses.f90"
      61              : 
      62              :    IMPLICIT NONE
      63              :    PRIVATE
      64              : 
      65              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mscfg_methods'
      66              : 
      67              :    PUBLIC :: loop_over_molecules, do_mol_loop
      68              : 
      69              : CONTAINS
      70              : 
      71              : ! **************************************************************************************************
      72              : !> \brief Prepare data for calculations on isolated molecules.
      73              : !> \param globenv ...
      74              : !> \param force_env ...
      75              : !> \par   History
      76              : !>        10.2014 created [Rustam Z Khaliullin]
      77              : !> \author Rustam Z Khaliullin
      78              : ! **************************************************************************************************
      79           10 :    SUBROUTINE loop_over_molecules(globenv, force_env)
      80              : 
      81              :       TYPE(global_environment_type), POINTER             :: globenv
      82              :       TYPE(force_env_type), POINTER                      :: force_env
      83              : 
      84              :       INTEGER                                            :: nmols
      85              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: charge_of_frag, first_atom_of_frag, &
      86              :                                                             last_atom_of_frag, multip_of_frag
      87           10 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
      88              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      89              : 
      90           10 :       CALL force_env_get(force_env, qs_env=qs_env)
      91           10 :       CPASSERT(ASSOCIATED(qs_env))
      92              :       CALL get_qs_env(qs_env, &
      93           10 :                       molecule_set=molecule_set)
      94              : 
      95           10 :       nmols = SIZE(molecule_set)
      96              : 
      97           30 :       ALLOCATE (first_atom_of_frag(nmols))
      98           30 :       ALLOCATE (last_atom_of_frag(nmols))
      99           30 :       ALLOCATE (charge_of_frag(nmols))
     100           30 :       ALLOCATE (multip_of_frag(nmols))
     101              : 
     102              :       CALL get_molecule_set_info(molecule_set, &
     103              :                                  mol_to_first_atom=first_atom_of_frag, &
     104              :                                  mol_to_last_atom=last_atom_of_frag, &
     105              :                                  mol_to_charge=charge_of_frag, &
     106           10 :                                  mol_to_multiplicity=multip_of_frag)
     107              : 
     108              :       CALL calcs_on_isolated_molecules(force_env, globenv, nmols, &
     109           10 :                                        first_atom_of_frag, last_atom_of_frag, charge_of_frag, multip_of_frag)
     110              : 
     111           10 :       DEALLOCATE (first_atom_of_frag)
     112           10 :       DEALLOCATE (last_atom_of_frag)
     113           10 :       DEALLOCATE (charge_of_frag)
     114           10 :       DEALLOCATE (multip_of_frag)
     115              : 
     116           10 :    END SUBROUTINE loop_over_molecules
     117              : 
     118              : ! **************************************************************************************************
     119              : !> \brief Run calculations on isolated molecules. The ideas for setting up
     120              : !>        the calculations are borrowed from BSSE files
     121              : !> \param force_env ...
     122              : !> \param globenv ...
     123              : !> \param nfrags ...
     124              : !> \param first_atom_of_frag ...
     125              : !> \param last_atom_of_frag ...
     126              : !> \param charge_of_frag ...
     127              : !> \param multip_of_frag ...
     128              : !> \par   History
     129              : !>        10.2014 created
     130              : !>        09.2018 ALMO smearing support, and ALMO diag+molecular_guess patch [Ruben Staub]
     131              : !> \author Rustam Z Khaliullin
     132              : ! **************************************************************************************************
     133           60 :    SUBROUTINE calcs_on_isolated_molecules(force_env, globenv, nfrags, &
     134           10 :                                           first_atom_of_frag, last_atom_of_frag, charge_of_frag, multip_of_frag)
     135              : 
     136              :       TYPE(force_env_type), POINTER                      :: force_env
     137              :       TYPE(global_environment_type), POINTER             :: globenv
     138              :       INTEGER, INTENT(IN)                                :: nfrags
     139              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: first_atom_of_frag, last_atom_of_frag, &
     140              :                                                             charge_of_frag, multip_of_frag
     141              : 
     142              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calcs_on_isolated_molecules'
     143              : 
     144              :       CHARACTER(LEN=default_string_length)               :: name
     145              :       CHARACTER(LEN=default_string_length), &
     146           10 :          DIMENSION(:), POINTER                           :: atom_type
     147              :       INTEGER :: first_atom, force_method, global_charge, global_multpl, handle, i, ifrag, imo, &
     148              :          isize, j, k, last_atom, my_targ, nb_eigenval_stored, nmo, nmo_of_frag, nmosets_of_frag, &
     149              :          tot_added_mos, tot_isize
     150           10 :       INTEGER, DIMENSION(:), POINTER                     :: atom_index, atom_list
     151              :       LOGICAL                                            :: global_almo_scf_keyword, smear_almo_scf
     152              :       TYPE(almo_scf_env_type), POINTER                   :: almo_scf_env
     153              :       TYPE(cp_subsys_type), POINTER                      :: subsys, subsys_loc
     154           10 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos, mos_of_frag
     155              :       TYPE(molecular_scf_guess_env_type), POINTER        :: mscfg_env
     156              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     157              :       TYPE(particle_list_type), POINTER                  :: particles
     158              :       TYPE(qs_energy_type), POINTER                      :: qs_energy
     159              :       TYPE(qs_environment_type), POINTER                 :: qs_env, qs_env_loc
     160              :       TYPE(section_vals_type), POINTER                   :: dft_section, force_env_section, &
     161              :                                                             qs_section, root_section, scf_section, &
     162              :                                                             subsys_section
     163              : 
     164           10 :       CALL timeset(routineN, handle)
     165              : 
     166           10 :       NULLIFY (subsys_loc, subsys, particles, para_env, atom_index, atom_type, &
     167           10 :                force_env_section, qs_env_loc, mscfg_env, qs_env, qs_energy)
     168              :       CALL force_env_get(force_env, force_env_section=force_env_section, &
     169           10 :                          qs_env=qs_env)
     170           10 :       CALL section_vals_val_get(force_env_section, "METHOD", i_val=force_method)
     171           10 :       CPASSERT(force_method == do_qs)
     172           10 :       root_section => force_env%root_section
     173           10 :       subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
     174           10 :       dft_section => section_vals_get_subs_vals(force_env_section, "DFT")
     175              :       !
     176              :       ! Save several global settings to restore them after the loop:
     177              :       !  charge, multiplicity, ALMO flag
     178              :       !
     179           10 :       CALL section_vals_val_get(dft_section, "CHARGE", i_val=global_charge)
     180           10 :       CALL section_vals_val_get(dft_section, "MULTIPLICITY", i_val=global_multpl)
     181           10 :       qs_section => section_vals_get_subs_vals(dft_section, "QS")
     182           10 :       CALL section_vals_val_get(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
     183              :       !
     184              :       ! Get access to critical data before the loop
     185              :       !
     186           10 :       CALL force_env_get(force_env=force_env, subsys=subsys, para_env=para_env)
     187           10 :       CALL cp_subsys_get(subsys, particles=particles)
     188           10 :       CALL get_qs_env(qs_env, mscfg_env=mscfg_env, almo_scf_env=almo_scf_env)
     189           10 :       CPASSERT(ASSOCIATED(mscfg_env))
     190           10 :       IF (global_almo_scf_keyword) THEN !! Check if smearing is on, and retrieve smearing parameters accordingly
     191           10 :          smear_almo_scf = qs_env%scf_control%smear%do_smear
     192           10 :          IF (smear_almo_scf) THEN
     193            4 :             scf_section => section_vals_get_subs_vals(dft_section, "SCF")
     194            4 :             CALL section_vals_val_get(scf_section, "added_mos", i_val=tot_added_mos) !! Get total number of added MOs
     195            4 :             tot_isize = last_atom_of_frag(nfrags) - first_atom_of_frag(1) + 1 !! Get total number of atoms (assume consecutive atoms)
     196              :             !! Check that number of added MOs matches the number of atoms
     197              :             !! (to ensure compatibility, since each fragment will be computed with such parameters)
     198            4 :             IF (tot_isize /= tot_added_mos) THEN
     199            0 :                CPABORT("ALMO smearing currently requires ADDED_MOS == total number of atoms")
     200              :             END IF
     201              :             !! Get total number of MOs
     202            4 :             CALL get_qs_env(qs_env, mos=mos)
     203            4 :             IF (SIZE(mos) > 1) CPABORT("Unrestricted ALMO methods are NYI") !! Unrestricted ALMO is not implemented yet
     204            4 :             CALL get_mo_set(mo_set=mos(1), nmo=nmo)
     205              :             !! Initialize storage of MO energies for ALMO smearing
     206            4 :             CPASSERT(ASSOCIATED(almo_scf_env))
     207           16 :             ALLOCATE (almo_scf_env%mo_energies(nmo, SIZE(mos)))
     208           12 :             ALLOCATE (almo_scf_env%kTS(SIZE(mos)))
     209           12 :             nb_eigenval_stored = 0 !! Keep track of how many eigenvalues were stored in mo_energies
     210              :          END IF
     211              :       ELSE
     212              :          smear_almo_scf = .FALSE.
     213              :       END IF
     214              :       !
     215              :       ! These flags determine the options of molecular runs (e.g. cell size)
     216              :       !
     217              :       !!!LATER is_fast_dirty = mscfg_env%is_fast_dirty - shrink the cell
     218              :       !!!LATER is_crystal = mscfg_env%is_crystal - remove periodicity
     219              :       !
     220              :       ! Prepare storage for the results
     221              :       ! Until molecular_scf_guess_env is destroyed it will keep
     222              :       ! the results of fragment calculations
     223              :       !
     224           10 :       CALL molecular_scf_guess_env_init(mscfg_env, nfrags)
     225              : 
     226              :       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     227              :       !
     228              :       ! Start the loop over molecules
     229              :       !
     230              :       ! Here is the list of modifications necessary to run isolated molecules:
     231              :       ! * Atom list of a subsystem and their names
     232              :       ! * Charge and multiplicity of a subsystem
     233              :       ! * ALMO SCF flag off (unless several levels of recursion is desired)
     234              :       ! * Smaller cell can be provided if a fast-and-dirty approach is ok
     235              :       ! * Set ADDED_MOS to number of atoms in the fragment, if smearing requested (VASP default)
     236              :       ! * ... add your own and explain it here ...
     237              :       !
     238              :       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     239           42 :       DO ifrag = 1, nfrags
     240              :          !
     241              :          ! Turn ALMO SCF flag off
     242              :          !
     243           32 :          CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=.FALSE.)
     244              :          !
     245              :          ! Setup the charge and multiplicity of the molecule
     246              :          !
     247           32 :          CALL section_vals_val_set(dft_section, "CHARGE", i_val=charge_of_frag(ifrag))
     248           32 :          CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=multip_of_frag(ifrag))
     249              :          !
     250              :          ! Create a list of atoms in the current molecule
     251              :          !
     252              :          ! Assume that atoms arranged consecutively (in ALMO SCF it is always the case)
     253              :          ! It is important to have a linear scaling procedure here
     254           32 :          first_atom = first_atom_of_frag(ifrag)
     255           32 :          last_atom = last_atom_of_frag(ifrag)
     256           32 :          isize = last_atom - first_atom + 1
     257           96 :          ALLOCATE (atom_index(isize))
     258          352 :          atom_index(1:isize) = [(i, i=first_atom, last_atom)]
     259              :          !
     260              :          ! Get atom type names
     261              :          !
     262           96 :          ALLOCATE (atom_type(isize))
     263          176 :          DO j = 1, isize
     264          144 :             my_targ = atom_index(j)
     265          416 :             DO k = 1, SIZE(particles%els)
     266          416 :                CALL get_atomic_kind(particles%els(k)%atomic_kind, atom_list=atom_list, name=name)
     267         3658 :                IF (ANY(atom_list == my_targ)) EXIT
     268              :             END DO
     269          176 :             atom_type(j) = name
     270              :          END DO
     271              :          !
     272              :          ! If smearing requested, setup ADDED_MOS correctly for each fragment (i.e. number of atoms in fragment)
     273              :          !
     274           32 :          IF (smear_almo_scf) THEN
     275            8 :             CALL section_vals_val_set(scf_section, "added_mos", i_val=isize)
     276              :          END IF
     277              :          !
     278              :          ! Create the environment of a subsystem
     279              :          !
     280              :          CALL create_small_subsys(subsys_loc, big_subsys=subsys, small_para_env=para_env, &
     281              :                                   small_cell=subsys%cell, sub_atom_index=atom_index, &
     282              :                                   sub_atom_kind_name=atom_type, para_env=para_env, &
     283           32 :                                   force_env_section=force_env_section, subsys_section=subsys_section)
     284           32 :          ALLOCATE (qs_env_loc)
     285           32 :          CALL qs_env_create(qs_env_loc, globenv)
     286              :          CALL qs_init(qs_env_loc, para_env, root_section, globenv=globenv, cp_subsys=subsys_loc, &
     287              :                       force_env_section=force_env_section, subsys_section=subsys_section, &
     288           32 :                       use_motion_section=.FALSE.)
     289           32 :          CALL cp_subsys_release(subsys_loc)
     290              : 
     291              :          !
     292              :          ! Print-out fragment info
     293              :          !
     294              :          CALL print_frag_info(atom_index, atom_type, ifrag, nfrags, &
     295           32 :                               charge_of_frag(ifrag), multip_of_frag(ifrag))
     296              :          !
     297              :          !  Run calculations on a subsystem
     298              :          !
     299           32 :          CALL qs_energies(qs_env_loc)
     300              :          !
     301              :          !  Get the desired results (energy and MOs) out
     302              :          !
     303           32 :          CALL get_qs_env(qs_env_loc, mos=mos_of_frag, energy=qs_energy)
     304              :          !
     305              :          ! Store all desired results of fragment calculations in the fragment_env
     306              :          ! of the qs_env to use them later as needed
     307              :          !
     308           32 :          mscfg_env%energy_of_frag(ifrag) = qs_energy%total
     309           32 :          nmosets_of_frag = SIZE(mos_of_frag)
     310           32 :          CPASSERT(nmosets_of_frag <= mscfg_max_moset_size)
     311           32 :          mscfg_env%nmosets_of_frag(ifrag) = nmosets_of_frag
     312           64 :          DO imo = 1, nmosets_of_frag
     313              :             !! Forcing compatibility for ALMO smearing
     314           32 :             IF (global_almo_scf_keyword) THEN
     315              :                !! Manually add compatibility between ALMO SCF and diag SCF (used for smearing compatibility)
     316              :                !! MOs are required to compute ALMO orbitals, but not stored with diag SCF algorithm...
     317              :                !! RS-WARNING: Should be properly fixed, this is just a raw fix.
     318              :                CALL copy_fm_to_dbcsr(mos_of_frag(imo)%mo_coeff, &
     319           32 :                                      mos_of_frag(imo)%mo_coeff_b)
     320           32 :                IF (smear_almo_scf) THEN
     321              :                   !! Store MOs energies for ALMO smearing purpose
     322            8 :                   nmo_of_frag = SIZE(mos_of_frag(imo)%eigenvalues)
     323              :                   almo_scf_env%mo_energies(nb_eigenval_stored + 1:nb_eigenval_stored + nmo_of_frag, imo) &
     324          272 :                      = mos_of_frag(imo)%eigenvalues(:)
     325              :                   !! update stored energies offset. Assumes nmosets_of_frag == 1 (general smearing ALMO assumption)
     326            8 :                   nb_eigenval_stored = nb_eigenval_stored + nmo_of_frag
     327              :                END IF
     328              :             END IF !! ALMO
     329              : 
     330              :             ! the matrices have been allocated already - copy the results there
     331              :             CALL dbcsr_create(mscfg_env%mos_of_frag(ifrag, imo), &
     332              :                               template=mos_of_frag(imo)%mo_coeff_b, &
     333           32 :                               matrix_type=dbcsr_type_no_symmetry)
     334              :             CALL dbcsr_copy(mscfg_env%mos_of_frag(ifrag, imo), &
     335           64 :                             mos_of_frag(imo)%mo_coeff_b)
     336              :          END DO
     337              :          !
     338              :          ! Clean up
     339              :          !
     340           32 :          NULLIFY (qs_energy)
     341           32 :          CALL qs_env_release(qs_env_loc)
     342           32 :          DEALLOCATE (qs_env_loc)
     343           32 :          DEALLOCATE (atom_index)
     344           74 :          DEALLOCATE (atom_type)
     345              : 
     346              :       END DO
     347              : 
     348           10 :       CALL section_vals_val_set(dft_section, "CHARGE", i_val=global_charge)
     349           10 :       CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=global_multpl)
     350           10 :       CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
     351              : 
     352           10 :       CALL timestop(handle)
     353              : 
     354           10 :    END SUBROUTINE calcs_on_isolated_molecules
     355              : 
     356              : ! **************************************************************************************************
     357              : !> \brief Print info about fragment
     358              : !> \param atom_index ...
     359              : !> \param atom_type ...
     360              : !> \param frag ...
     361              : !> \param nfrags ...
     362              : !> \param charge ...
     363              : !> \param multpl ...
     364              : !> \par History
     365              : !>      07.2005 created as a part of BSSE calculations [tlaino]
     366              : !>      10.2014 adapted to ALMO guess calculations [Rustam Z Khaliullin]
     367              : !> \author Rustam Z Khaliullin
     368              : ! **************************************************************************************************
     369           32 :    SUBROUTINE print_frag_info(atom_index, atom_type, frag, nfrags, charge, &
     370              :                               multpl)
     371              : 
     372              :       INTEGER, DIMENSION(:), POINTER                     :: atom_index
     373              :       CHARACTER(len=default_string_length), &
     374              :          DIMENSION(:), POINTER                           :: atom_type
     375              :       INTEGER, INTENT(IN)                                :: frag, nfrags, charge, multpl
     376              : 
     377              :       CHARACTER(len=11)                                  :: charI
     378              :       INTEGER                                            :: i, iw
     379              :       TYPE(cp_logger_type), POINTER                      :: logger
     380              : 
     381           32 :       NULLIFY (logger)
     382           32 :       logger => cp_get_default_logger()
     383           32 :       IF (logger%para_env%is_source()) THEN
     384           16 :          iw = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     385              :       ELSE
     386              :          iw = -1
     387              :       END IF
     388              : 
     389           16 :       IF (iw > 0) THEN
     390              : 
     391           16 :          WRITE (UNIT=iw, FMT="(/,T2,A)") REPEAT("-", 79)
     392           16 :          WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
     393              :          WRITE (UNIT=iw, FMT="(T2,A,T5,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") &
     394           16 :             "-", "MOLECULAR GUESS:", "FRAGMENT", frag, "OUT OF", nfrags, "-"
     395           16 :          WRITE (UNIT=iw, FMT="(T2,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") "-", "CHARGE", charge, "MULTIPLICITY", &
     396           32 :             multpl, "-"
     397           16 :          WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
     398           16 :          WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "ATOM INDEX", "ATOM NAME", "-"
     399           16 :          WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "----------", "---------", "-"
     400           88 :          DO i = 1, SIZE(atom_index)
     401           72 :             WRITE (charI, '(I11)') atom_index(i)
     402           88 :             WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", ADJUSTL(charI), TRIM(atom_type(i)), "-"
     403              :          END DO
     404           16 :          WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
     405              :       END IF
     406              : 
     407           32 :    END SUBROUTINE print_frag_info
     408              : 
     409              : ! **************************************************************************************************
     410              : !> \brief Is the loop over molecules requested?
     411              : !> \param force_env ...
     412              : !> \return ...
     413              : !> \par History
     414              : !>       10.2014 created [Rustam Z. Khaliullin]
     415              : !> \author Rustam Z. Khaliullin
     416              : ! **************************************************************************************************
     417        10572 :    FUNCTION do_mol_loop(force_env)
     418              : 
     419              :       TYPE(force_env_type), POINTER                      :: force_env
     420              :       LOGICAL                                            :: do_mol_loop
     421              : 
     422              :       INTEGER                                            :: almo_guess_type, frz_term_type, &
     423              :                                                             method_name_id, scf_guess_type
     424              :       LOGICAL                                            :: almo_scf_is_on, is_crystal, is_fast_dirty
     425              :       TYPE(molecular_scf_guess_env_type), POINTER        :: mscfg_env
     426              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     427              :       TYPE(section_vals_type), POINTER                   :: force_env_section, subsection
     428              : 
     429         5286 :       do_mol_loop = .FALSE.
     430              :       ! What kind of options are we using in the loop ?
     431         5286 :       is_fast_dirty = .TRUE.
     432         5286 :       is_crystal = .FALSE.
     433         5286 :       almo_scf_is_on = .FALSE.
     434              : 
     435         5286 :       NULLIFY (qs_env, mscfg_env, force_env_section, subsection)
     436         5286 :       CALL force_env_get(force_env, force_env_section=force_env_section)
     437         5286 :       CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
     438              : 
     439         5286 :       IF (method_name_id == do_qs) THEN
     440              : 
     441         4604 :          CALL force_env_get(force_env, qs_env=qs_env)
     442         4604 :          CPASSERT(ASSOCIATED(qs_env))
     443              : 
     444         4604 :          CALL get_qs_env(qs_env, mscfg_env=mscfg_env)
     445         4604 :          CPASSERT(ASSOCIATED(mscfg_env))
     446              : 
     447              :          !!!! RZK-warning: All decisions are based on the values of input keywords
     448              :          !!!! The real danger is that many of these keywords might not be even
     449              :          !!!! in control of the job. They might be simply present in the input
     450              :          !!!! This section must be re-written more accurately
     451              : 
     452              :          ! check ALMO SCF guess option
     453         4604 :          NULLIFY (subsection)
     454         4604 :          subsection => section_vals_get_subs_vals(force_env_section, "DFT%ALMO_SCF")
     455         4604 :          CALL section_vals_val_get(subsection, "ALMO_SCF_GUESS", i_val=almo_guess_type)
     456              :          ! check whether ALMO SCF is on
     457         4604 :          NULLIFY (subsection)
     458         4604 :          subsection => section_vals_get_subs_vals(force_env_section, "DFT%QS")
     459         4604 :          CALL section_vals_val_get(subsection, "ALMO_SCF", l_val=almo_scf_is_on)
     460              : 
     461              :          ! check SCF guess option
     462         4604 :          NULLIFY (subsection)
     463         4604 :          subsection => section_vals_get_subs_vals(force_env_section, "DFT%SCF")
     464         4604 :          CALL section_vals_val_get(subsection, "SCF_GUESS", i_val=scf_guess_type)
     465              : 
     466              :          ! check ALMO EDA options
     467         4604 :          NULLIFY (subsection)
     468              :          !!!LATER subsection    => section_vals_get_subs_vals(force_env_section,"DFT%ALMO_SCF%ALMO_DA")
     469              :          !!!LATER CALL section_vals_val_get(subsection,"FRZ_TERM",i_val=frz_term_type)
     470         4604 :          frz_term_type = almo_frz_none
     471              : 
     472              :          ! Are we doing the loop ?
     473              :          IF (scf_guess_type == molecular_guess .OR. & ! SCF guess is molecular
     474         4604 :              (almo_guess_type == molecular_guess .AND. almo_scf_is_on) .OR. & ! ALMO SCF guess is molecular
     475              :              frz_term_type /= almo_frz_none) THEN ! ALMO FRZ term is requested
     476              : 
     477           10 :             do_mol_loop = .TRUE.
     478              : 
     479              :             ! If we are calculating molecular guess it is OK to do fast and dirty loop
     480              :             ! It is NOT ok to be sloppy with ALMO EDA calculations of the FRZ term
     481              :             IF (frz_term_type /= almo_frz_none) THEN
     482              :                is_fast_dirty = .FALSE.
     483              :                IF (frz_term_type == almo_frz_crystal) THEN
     484              :                   is_crystal = .TRUE.
     485              :                END IF
     486              :             END IF
     487              : 
     488              :          END IF
     489              : 
     490         4604 :          mscfg_env%is_fast_dirty = is_fast_dirty
     491         4604 :          mscfg_env%is_crystal = is_crystal
     492              : 
     493              :       END IF
     494              : 
     495              :       RETURN
     496              : 
     497              :    END FUNCTION do_mol_loop
     498              : 
     499              : END MODULE mscfg_methods
     500              : 
        

Generated by: LCOV version 2.0-1