LCOV - code coverage report
Current view: top level - src - mscfg_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:561f475) Lines: 99.3 % 153 152
Test Date: 2026-06-21 06:48:54 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           16 :    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           16 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
      88              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      89              : 
      90           16 :       CALL force_env_get(force_env, qs_env=qs_env)
      91           16 :       CPASSERT(ASSOCIATED(qs_env))
      92              :       CALL get_qs_env(qs_env, &
      93           16 :                       molecule_set=molecule_set)
      94              : 
      95           16 :       nmols = SIZE(molecule_set)
      96              : 
      97           48 :       ALLOCATE (first_atom_of_frag(nmols))
      98           32 :       ALLOCATE (last_atom_of_frag(nmols))
      99           32 :       ALLOCATE (charge_of_frag(nmols))
     100           32 :       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           16 :                                  mol_to_multiplicity=multip_of_frag)
     107              : 
     108              :       CALL calcs_on_isolated_molecules(force_env, globenv, nmols, &
     109           16 :                                        first_atom_of_frag, last_atom_of_frag, charge_of_frag, multip_of_frag)
     110              : 
     111           16 :       DEALLOCATE (first_atom_of_frag)
     112           16 :       DEALLOCATE (last_atom_of_frag)
     113           16 :       DEALLOCATE (charge_of_frag)
     114           16 :       DEALLOCATE (multip_of_frag)
     115              : 
     116           16 :    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           96 :    SUBROUTINE calcs_on_isolated_molecules(force_env, globenv, nfrags, &
     134           16 :                                           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(INOUT)               :: 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           16 :          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           16 :       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           16 :       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           16 :       CALL timeset(routineN, handle)
     165              : 
     166           16 :       NULLIFY (subsys_loc, subsys, particles, para_env, atom_index, atom_type, &
     167           16 :                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           16 :                          qs_env=qs_env)
     170           16 :       CALL section_vals_val_get(force_env_section, "METHOD", i_val=force_method)
     171           16 :       CPASSERT(force_method == do_qs)
     172           16 :       root_section => force_env%root_section
     173           16 :       subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
     174           16 :       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           16 :       CALL section_vals_val_get(dft_section, "CHARGE", i_val=global_charge)
     180           16 :       CALL section_vals_val_get(dft_section, "MULTIPLICITY", i_val=global_multpl)
     181           16 :       qs_section => section_vals_get_subs_vals(dft_section, "QS")
     182           16 :       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           16 :       CALL force_env_get(force_env=force_env, subsys=subsys, para_env=para_env)
     187           16 :       CALL cp_subsys_get(subsys, particles=particles)
     188           16 :       CALL get_qs_env(qs_env, mscfg_env=mscfg_env, almo_scf_env=almo_scf_env)
     189           16 :       CPASSERT(ASSOCIATED(mscfg_env))
     190           16 :       IF (global_almo_scf_keyword) THEN !! Check if smearing is on, and retrieve smearing parameters accordingly
     191           16 :          smear_almo_scf = qs_env%scf_control%smear%do_smear
     192           16 :          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           16 :       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           60 :       DO ifrag = 1, nfrags
     240              :          !
     241              :          ! Turn ALMO SCF flag off
     242              :          !
     243           44 :          CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=.FALSE.)
     244              :          !
     245              :          ! Setup the charge and multiplicity of the molecule
     246              :          !
     247              : 
     248           44 :          IF (almo_scf_env%activate(1) == 1) THEN
     249           12 :             multip_of_frag(ifrag) = almo_scf_env%multiplicity_of_domain(ifrag)
     250           12 :             charge_of_frag(ifrag) = almo_scf_env%charge_of_domain(ifrag)
     251              :          ELSE
     252           32 :             CALL section_vals_val_set(dft_section, "CHARGE", i_val=charge_of_frag(ifrag))
     253           32 :             CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=multip_of_frag(ifrag))
     254              :          END IF
     255              : 
     256              :          !
     257              :          ! Create a list of atoms in the current molecule
     258              :          !
     259              :          ! Assume that atoms arranged consecutively (in ALMO SCF it is always the case)
     260              :          ! It is important to have a linear scaling procedure here
     261           44 :          first_atom = first_atom_of_frag(ifrag)
     262           44 :          last_atom = last_atom_of_frag(ifrag)
     263           44 :          isize = last_atom - first_atom + 1
     264          132 :          ALLOCATE (atom_index(isize))
     265          432 :          atom_index(1:isize) = [(i, i=first_atom, last_atom)]
     266              :          !
     267              :          ! Get atom type names
     268              :          !
     269          132 :          ALLOCATE (atom_type(isize))
     270          216 :          DO j = 1, isize
     271          172 :             my_targ = atom_index(j)
     272          462 :             DO k = 1, SIZE(particles%els)
     273          462 :                CALL get_atomic_kind(particles%els(k)%atomic_kind, atom_list=atom_list, name=name)
     274         3768 :                IF (ANY(atom_list == my_targ)) EXIT
     275              :             END DO
     276          216 :             atom_type(j) = name
     277              :          END DO
     278              :          !
     279              :          ! If smearing requested, setup ADDED_MOS correctly for each fragment (i.e. number of atoms in fragment)
     280              :          !
     281           44 :          IF (smear_almo_scf) THEN
     282            8 :             CALL section_vals_val_set(scf_section, "added_mos", i_val=isize)
     283              :          END IF
     284              :          !
     285              :          ! Create the environment of a subsystem
     286              :          !
     287              :          CALL create_small_subsys(subsys_loc, big_subsys=subsys, small_para_env=para_env, &
     288              :                                   small_cell=subsys%cell, sub_atom_index=atom_index, &
     289              :                                   sub_atom_kind_name=atom_type, para_env=para_env, &
     290           44 :                                   force_env_section=force_env_section, subsys_section=subsys_section)
     291           44 :          ALLOCATE (qs_env_loc)
     292           44 :          CALL qs_env_create(qs_env_loc, globenv)
     293              :          CALL qs_init(qs_env_loc, para_env, root_section, globenv=globenv, cp_subsys=subsys_loc, &
     294              :                       force_env_section=force_env_section, subsys_section=subsys_section, &
     295           44 :                       use_motion_section=.FALSE., multip=multip_of_frag(ifrag), charge=charge_of_frag(ifrag))
     296           44 :          CALL cp_subsys_release(subsys_loc)
     297              : 
     298              :          !
     299              :          ! Print-out fragment info
     300              :          !
     301              :          CALL print_frag_info(atom_index, atom_type, ifrag, nfrags, &
     302           44 :                               charge_of_frag(ifrag), multip_of_frag(ifrag))
     303              :          !
     304              :          !  Run calculations on a subsystem
     305              :          !
     306           44 :          CALL qs_energies(qs_env_loc)
     307              :          !
     308              :          !  Get the desired results (energy and MOs) out
     309              :          !
     310           44 :          CALL get_qs_env(qs_env_loc, mos=mos_of_frag, energy=qs_energy)
     311              :          !
     312              :          ! Store all desired results of fragment calculations in the fragment_env
     313              :          ! of the qs_env to use them later as needed
     314              :          !
     315           44 :          mscfg_env%energy_of_frag(ifrag) = qs_energy%total
     316           44 :          nmosets_of_frag = SIZE(mos_of_frag)
     317           44 :          CPASSERT(nmosets_of_frag <= mscfg_max_moset_size)
     318           44 :          mscfg_env%nmosets_of_frag(ifrag) = nmosets_of_frag
     319          100 :          DO imo = 1, nmosets_of_frag
     320              :             !! Forcing compatibility for ALMO smearing
     321           56 :             IF (global_almo_scf_keyword) THEN
     322              :                !! Manually add compatibility between ALMO SCF and diag SCF (used for smearing compatibility)
     323              :                !! MOs are required to compute ALMO orbitals, but not stored with diag SCF algorithm...
     324              :                !! RS-WARNING: Should be properly fixed, this is just a raw fix.
     325              :                CALL copy_fm_to_dbcsr(mos_of_frag(imo)%mo_coeff, &
     326           56 :                                      mos_of_frag(imo)%mo_coeff_b)
     327           56 :                IF (smear_almo_scf) THEN
     328              :                   !! Store MOs energies for ALMO smearing purpose
     329            8 :                   nmo_of_frag = SIZE(mos_of_frag(imo)%eigenvalues)
     330              :                   almo_scf_env%mo_energies(nb_eigenval_stored + 1:nb_eigenval_stored + nmo_of_frag, imo) &
     331          272 :                      = mos_of_frag(imo)%eigenvalues(:)
     332              :                   !! update stored energies offset. Assumes nmosets_of_frag == 1 (general smearing ALMO assumption)
     333            8 :                   nb_eigenval_stored = nb_eigenval_stored + nmo_of_frag
     334              :                END IF
     335              :             END IF !! ALMO
     336              : 
     337              :             ! the matrices have been allocated already - copy the results there
     338              :             CALL dbcsr_create(mscfg_env%mos_of_frag(ifrag, imo), &
     339              :                               template=mos_of_frag(imo)%mo_coeff_b, &
     340           56 :                               matrix_type=dbcsr_type_no_symmetry)
     341              :             CALL dbcsr_copy(mscfg_env%mos_of_frag(ifrag, imo), &
     342          100 :                             mos_of_frag(imo)%mo_coeff_b)
     343              :          END DO
     344              :          !
     345              :          ! Clean up
     346              :          !
     347           44 :          NULLIFY (qs_energy)
     348           44 :          CALL qs_env_release(qs_env_loc)
     349           44 :          DEALLOCATE (qs_env_loc)
     350           44 :          DEALLOCATE (atom_index)
     351          104 :          DEALLOCATE (atom_type)
     352              : 
     353              :       END DO
     354              : 
     355           16 :       CALL section_vals_val_set(dft_section, "CHARGE", i_val=global_charge)
     356           16 :       CALL section_vals_val_set(dft_section, "MULTIPLICITY", i_val=global_multpl)
     357           16 :       CALL section_vals_val_set(qs_section, "ALMO_SCF", l_val=global_almo_scf_keyword)
     358              : 
     359           16 :       CALL timestop(handle)
     360              : 
     361           16 :    END SUBROUTINE calcs_on_isolated_molecules
     362              : 
     363              : ! **************************************************************************************************
     364              : !> \brief Print info about fragment
     365              : !> \param atom_index ...
     366              : !> \param atom_type ...
     367              : !> \param frag ...
     368              : !> \param nfrags ...
     369              : !> \param charge ...
     370              : !> \param multpl ...
     371              : !> \par History
     372              : !>      07.2005 created as a part of BSSE calculations [tlaino]
     373              : !>      10.2014 adapted to ALMO guess calculations [Rustam Z Khaliullin]
     374              : !> \author Rustam Z Khaliullin
     375              : ! **************************************************************************************************
     376           44 :    SUBROUTINE print_frag_info(atom_index, atom_type, frag, nfrags, charge, &
     377              :                               multpl)
     378              : 
     379              :       INTEGER, DIMENSION(:), POINTER                     :: atom_index
     380              :       CHARACTER(len=default_string_length), &
     381              :          DIMENSION(:), POINTER                           :: atom_type
     382              :       INTEGER, INTENT(IN)                                :: frag, nfrags, charge, multpl
     383              : 
     384              :       CHARACTER(len=11)                                  :: charI
     385              :       INTEGER                                            :: i, iw
     386              :       TYPE(cp_logger_type), POINTER                      :: logger
     387              : 
     388           44 :       NULLIFY (logger)
     389           44 :       logger => cp_get_default_logger()
     390           44 :       IF (logger%para_env%is_source()) THEN
     391           22 :          iw = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     392              :       ELSE
     393              :          iw = -1
     394              :       END IF
     395              : 
     396           22 :       IF (iw > 0) THEN
     397              : 
     398           22 :          WRITE (UNIT=iw, FMT="(/,T2,A)") REPEAT("-", 79)
     399           22 :          WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
     400              :          WRITE (UNIT=iw, FMT="(T2,A,T5,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") &
     401           22 :             "-", "MOLECULAR GUESS:", "FRAGMENT", frag, "OUT OF", nfrags, "-"
     402           22 :          WRITE (UNIT=iw, FMT="(T2,A,T25,A,T40,I11,T53,A,T67,I11,T80,A)") "-", "CHARGE", charge, "MULTIPLICITY", &
     403           44 :             multpl, "-"
     404           22 :          WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
     405           22 :          WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "ATOM INDEX", "ATOM NAME", "-"
     406           22 :          WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", "----------", "---------", "-"
     407          108 :          DO i = 1, SIZE(atom_index)
     408           86 :             WRITE (charI, '(I11)') atom_index(i)
     409          108 :             WRITE (UNIT=iw, FMT="(T2,A,T25,A,T53,A,T80,A)") "-", ADJUSTL(charI), TRIM(atom_type(i)), "-"
     410              :          END DO
     411           22 :          WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
     412              :       END IF
     413              : 
     414           44 :    END SUBROUTINE print_frag_info
     415              : 
     416              : ! **************************************************************************************************
     417              : !> \brief Is the loop over molecules requested?
     418              : !> \param force_env ...
     419              : !> \return ...
     420              : !> \par History
     421              : !>       10.2014 created [Rustam Z. Khaliullin]
     422              : !> \author Rustam Z. Khaliullin
     423              : ! **************************************************************************************************
     424        11692 :    FUNCTION do_mol_loop(force_env)
     425              : 
     426              :       TYPE(force_env_type), POINTER                      :: force_env
     427              :       LOGICAL                                            :: do_mol_loop
     428              : 
     429              :       INTEGER                                            :: almo_guess_type, frz_term_type, &
     430              :                                                             method_name_id, scf_guess_type
     431              :       LOGICAL                                            :: almo_scf_is_on, is_crystal, is_fast_dirty
     432              :       TYPE(molecular_scf_guess_env_type), POINTER        :: mscfg_env
     433              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     434              :       TYPE(section_vals_type), POINTER                   :: force_env_section, subsection
     435              : 
     436         5846 :       do_mol_loop = .FALSE.
     437              :       ! What kind of options are we using in the loop ?
     438         5846 :       is_fast_dirty = .TRUE.
     439         5846 :       is_crystal = .FALSE.
     440              :       almo_scf_is_on = .FALSE.
     441              : 
     442         5846 :       NULLIFY (qs_env, mscfg_env, force_env_section, subsection)
     443         5846 :       CALL force_env_get(force_env, force_env_section=force_env_section)
     444         5846 :       CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
     445              : 
     446         5846 :       IF (method_name_id == do_qs) THEN
     447              : 
     448         5156 :          CALL force_env_get(force_env, qs_env=qs_env)
     449         5156 :          CPASSERT(ASSOCIATED(qs_env))
     450              : 
     451         5156 :          CALL get_qs_env(qs_env, mscfg_env=mscfg_env)
     452         5156 :          CPASSERT(ASSOCIATED(mscfg_env))
     453              : 
     454              :          !!!! RZK-warning: All decisions are based on the values of input keywords
     455              :          !!!! The real danger is that many of these keywords might not be even
     456              :          !!!! in control of the job. They might be simply present in the input
     457              :          !!!! This section must be re-written more accurately
     458              : 
     459              :          ! check ALMO SCF guess option
     460         5156 :          NULLIFY (subsection)
     461         5156 :          subsection => section_vals_get_subs_vals(force_env_section, "DFT%ALMO_SCF")
     462         5156 :          CALL section_vals_val_get(subsection, "ALMO_SCF_GUESS", i_val=almo_guess_type)
     463              :          ! check whether ALMO SCF is on
     464         5156 :          NULLIFY (subsection)
     465         5156 :          subsection => section_vals_get_subs_vals(force_env_section, "DFT%QS")
     466         5156 :          CALL section_vals_val_get(subsection, "ALMO_SCF", l_val=almo_scf_is_on)
     467              : 
     468              :          ! check SCF guess option
     469         5156 :          NULLIFY (subsection)
     470         5156 :          subsection => section_vals_get_subs_vals(force_env_section, "DFT%SCF")
     471         5156 :          CALL section_vals_val_get(subsection, "SCF_GUESS", i_val=scf_guess_type)
     472              : 
     473              :          ! check ALMO EDA options
     474         5156 :          NULLIFY (subsection)
     475              :          !!!LATER subsection    => section_vals_get_subs_vals(force_env_section,"DFT%ALMO_SCF%ALMO_DA")
     476              :          !!!LATER CALL section_vals_val_get(subsection,"FRZ_TERM",i_val=frz_term_type)
     477         5156 :          frz_term_type = almo_frz_none
     478              : 
     479              :          ! Are we doing the loop ?
     480              :          IF (scf_guess_type == molecular_guess .OR. & ! SCF guess is molecular
     481         5156 :              (almo_guess_type == molecular_guess .AND. almo_scf_is_on) .OR. & ! ALMO SCF guess is molecular
     482              :              frz_term_type /= almo_frz_none) THEN ! ALMO FRZ term is requested
     483              : 
     484           16 :             do_mol_loop = .TRUE.
     485              : 
     486              :             ! If we are calculating molecular guess it is OK to do fast and dirty loop
     487              :             ! It is NOT ok to be sloppy with ALMO EDA calculations of the FRZ term
     488              :             IF (frz_term_type /= almo_frz_none) THEN
     489              :                is_fast_dirty = .FALSE.
     490              :                IF (frz_term_type == almo_frz_crystal) THEN
     491              :                   is_crystal = .TRUE.
     492              :                END IF
     493              :             END IF
     494              : 
     495              :          END IF
     496              : 
     497         5156 :          mscfg_env%is_fast_dirty = is_fast_dirty
     498         5156 :          mscfg_env%is_crystal = is_crystal
     499              : 
     500              :       END IF
     501              : 
     502              :       RETURN
     503              : 
     504              :    END FUNCTION do_mol_loop
     505              : 
     506              : END MODULE mscfg_methods
     507              : 
        

Generated by: LCOV version 2.0-1