LCOV - code coverage report
Current view: top level - src - et_coupling_proj.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:32ddf85) Lines: 473 616 76.8 %
Date: 2025-05-17 08:08:58 Functions: 15 20 75.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief calculates the electron transfer coupling elements by projection-operator approach
      10             : !>        Kondov et al. J.Phys.Chem.C 2007, 111, 11970-11981
      11             : !> \author Z. Futera (02.2017)
      12             : ! **************************************************************************************************
      13             : MODULE et_coupling_proj
      14             : 
      15             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      16             :                                               get_atomic_kind
      17             :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      18             :                                               gto_basis_set_type
      19             :    USE bibliography,                    ONLY: Futera2017,&
      20             :                                               cite_reference
      21             :    USE cell_types,                      ONLY: cell_type
      22             :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      23             :    USE cp_control_types,                ONLY: dft_control_type
      24             :    USE cp_dbcsr_api,                    ONLY: dbcsr_p_type
      25             :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      26             :                                               cp_dbcsr_sm_fm_multiply
      27             :    USE cp_fm_basic_linalg,              ONLY: cp_fm_column_scale
      28             :    USE cp_fm_diag,                      ONLY: choose_eigv_solver,&
      29             :                                               cp_fm_power
      30             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      31             :                                               cp_fm_struct_equivalent,&
      32             :                                               cp_fm_struct_release,&
      33             :                                               cp_fm_struct_type
      34             :    USE cp_fm_types,                     ONLY: &
      35             :         cp_fm_create, cp_fm_get_element, cp_fm_get_submatrix, cp_fm_release, cp_fm_set_all, &
      36             :         cp_fm_set_element, cp_fm_to_fm, cp_fm_to_fm_submat, cp_fm_type, cp_fm_vectorssum
      37             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      38             :                                               cp_logger_type,&
      39             :                                               cp_to_string
      40             :    USE cp_output_handling,              ONLY: cp_p_file,&
      41             :                                               cp_print_key_finished_output,&
      42             :                                               cp_print_key_should_output,&
      43             :                                               cp_print_key_unit_nr
      44             :    USE cp_realspace_grid_cube,          ONLY: cp_pw_to_cube
      45             :    USE input_section_types,             ONLY: section_get_ivals,&
      46             :                                               section_get_lval,&
      47             :                                               section_vals_get,&
      48             :                                               section_vals_get_subs_vals,&
      49             :                                               section_vals_type,&
      50             :                                               section_vals_val_get
      51             :    USE kinds,                           ONLY: default_path_length,&
      52             :                                               default_string_length,&
      53             :                                               dp
      54             :    USE kpoint_types,                    ONLY: kpoint_type
      55             :    USE message_passing,                 ONLY: mp_para_env_type
      56             :    USE orbital_pointers,                ONLY: nso
      57             :    USE parallel_gemm_api,               ONLY: parallel_gemm
      58             :    USE particle_list_types,             ONLY: particle_list_type
      59             :    USE particle_types,                  ONLY: particle_type
      60             :    USE physcon,                         ONLY: evolt
      61             :    USE pw_env_types,                    ONLY: pw_env_get,&
      62             :                                               pw_env_type
      63             :    USE pw_pool_types,                   ONLY: pw_pool_p_type,&
      64             :                                               pw_pool_type
      65             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      66             :                                               pw_r3d_rs_type
      67             :    USE qs_collocate_density,            ONLY: calculate_wavefunction
      68             :    USE qs_environment_types,            ONLY: get_qs_env,&
      69             :                                               qs_environment_type
      70             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      71             :                                               get_qs_kind_set,&
      72             :                                               qs_kind_type
      73             :    USE qs_mo_methods,                   ONLY: make_mo_eig
      74             :    USE qs_mo_occupation,                ONLY: set_mo_occupation
      75             :    USE qs_mo_types,                     ONLY: allocate_mo_set,&
      76             :                                               deallocate_mo_set,&
      77             :                                               mo_set_type
      78             :    USE qs_subsys_types,                 ONLY: qs_subsys_get,&
      79             :                                               qs_subsys_type
      80             :    USE scf_control_types,               ONLY: scf_control_type
      81             : #include "./base/base_uses.f90"
      82             : 
      83             :    IMPLICIT NONE
      84             : 
      85             :    PRIVATE
      86             : 
      87             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'et_coupling_proj'
      88             : 
      89             :    ! Electronic-coupling calculation data structure
      90             :    !
      91             :    ! n_atoms      - number of atoms in the blocks
      92             :    ! n_blocks     - number of atomic blocks (donor,acceptor,bridge,...)
      93             :    ! fermi        - system Fermi level (alpha/beta spin component)
      94             :    ! m_transf     - transformation matrix for basis-set orthogonalization (S^{-1/2})
      95             :    ! m_transf_inv - inversion transformation matrix
      96             :    ! block        - atomic data blocks
      97             :    TYPE et_cpl
      98             :       INTEGER                                            :: n_atoms = 0
      99             :       INTEGER                                            :: n_blocks = 0
     100             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: fermi => NULL()
     101             :       TYPE(cp_fm_type), POINTER                          :: m_transf => NULL()
     102             :       TYPE(cp_fm_type), POINTER                          :: m_transf_inv => NULL()
     103             :       TYPE(et_cpl_block), DIMENSION(:), POINTER          :: block => NULL()
     104             :    END TYPE et_cpl
     105             : 
     106             :    ! Electronic-coupling data block
     107             :    !
     108             :    ! n_atoms     - number of atoms
     109             :    ! n_electrons - number of electrons
     110             :    ! n_ao        - number of AO basis functions
     111             :    ! atom        - list of atoms
     112             :    ! mo          - electronic states
     113             :    ! hab         - electronic-coupling elements
     114             :    TYPE et_cpl_block
     115             :       INTEGER                                            :: n_atoms = 0
     116             :       INTEGER                                            :: n_electrons = 0
     117             :       INTEGER                                            :: n_ao = 0
     118             :       TYPE(et_cpl_atom), DIMENSION(:), POINTER           :: atom => NULL()
     119             :       TYPE(mo_set_type), DIMENSION(:), POINTER         :: mo => NULL()
     120             :       TYPE(cp_fm_type), DIMENSION(:, :), POINTER        :: hab => NULL()
     121             :    END TYPE et_cpl_block
     122             : 
     123             :    ! Electronic-coupling block-atom data
     124             :    ! id     - atom ID
     125             :    ! n_ao   - number of AO basis functions
     126             :    ! ao_pos - position of atom in array of AO functions
     127             :    TYPE et_cpl_atom
     128             :       INTEGER                                            :: id = 0
     129             :       INTEGER                                            :: n_ao = 0
     130             :       INTEGER                                            :: ao_pos = 0
     131             :    END TYPE et_cpl_atom
     132             : 
     133             :    PUBLIC :: calc_et_coupling_proj
     134             : 
     135             : CONTAINS
     136             : 
     137             : ! **************************************************************************************************
     138             : !> \brief Release memory allocate for electronic coupling data structures
     139             : !> \param ec electronic coupling data structure
     140             : !> \author Z. Futera (02.2017)
     141             : ! **************************************************************************************************
     142          10 :    SUBROUTINE release_ec_data(ec)
     143             : 
     144             :       ! Routine arguments
     145             :       TYPE(et_cpl), POINTER                              :: ec
     146             : 
     147             :       INTEGER                                            :: i, j
     148             : 
     149             : ! Routine name for debug purposes
     150             : 
     151          10 :       IF (ASSOCIATED(ec)) THEN
     152             : 
     153          10 :          IF (ASSOCIATED(ec%fermi)) &
     154          10 :             DEALLOCATE (ec%fermi)
     155          10 :          IF (ASSOCIATED(ec%m_transf)) THEN
     156          10 :             CALL cp_fm_release(matrix=ec%m_transf)
     157          10 :             DEALLOCATE (ec%m_transf)
     158          10 :             NULLIFY (ec%m_transf)
     159             :          END IF
     160          10 :          IF (ASSOCIATED(ec%m_transf_inv)) THEN
     161          10 :             CALL cp_fm_release(matrix=ec%m_transf_inv)
     162          10 :             DEALLOCATE (ec%m_transf_inv)
     163          10 :             NULLIFY (ec%m_transf_inv)
     164             :          END IF
     165             : 
     166          10 :          IF (ASSOCIATED(ec%block)) THEN
     167             : 
     168          30 :             DO i = 1, SIZE(ec%block)
     169          20 :                IF (ASSOCIATED(ec%block(i)%atom)) &
     170          20 :                   DEALLOCATE (ec%block(i)%atom)
     171          20 :                IF (ASSOCIATED(ec%block(i)%mo)) THEN
     172          60 :                   DO j = 1, SIZE(ec%block(i)%mo)
     173          60 :                      CALL deallocate_mo_set(ec%block(i)%mo(j))
     174             :                   END DO
     175          20 :                   DEALLOCATE (ec%block(i)%mo)
     176             :                END IF
     177          30 :                CALL cp_fm_release(ec%block(i)%hab)
     178             :             END DO
     179             : 
     180          10 :             DEALLOCATE (ec%block)
     181             : 
     182             :          END IF
     183             : 
     184          10 :          DEALLOCATE (ec)
     185             : 
     186             :       END IF
     187             : 
     188          10 :    END SUBROUTINE release_ec_data
     189             : 
     190             : ! **************************************************************************************************
     191             : !> \brief check the electronic-coupling input section and set the atomic block data
     192             : !> \param qs_env QuickStep environment containing all system data
     193             : !> \param et_proj_sec the electronic-coupling input section
     194             : !> \param ec electronic coupling data structure
     195             : !> \author Z. Futera (02.2017)
     196             : ! **************************************************************************************************
     197          10 :    SUBROUTINE set_block_data(qs_env, et_proj_sec, ec)
     198             : 
     199             :       ! Routine arguments
     200             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     201             :       TYPE(section_vals_type), POINTER                   :: et_proj_sec
     202             :       TYPE(et_cpl), POINTER                              :: ec
     203             : 
     204             :       INTEGER                                            :: i, j, k, l, n, n_ao, n_atoms, n_set
     205          10 :       INTEGER, DIMENSION(:), POINTER                     :: atom_id, atom_nf, atom_ps, n_shell, t
     206          10 :       INTEGER, DIMENSION(:, :), POINTER                  :: ang_mom_id
     207             :       LOGICAL                                            :: found
     208             :       TYPE(gto_basis_set_type), POINTER                  :: ao_basis_set
     209          10 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     210          10 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     211             :       TYPE(section_vals_type), POINTER                   :: block_sec
     212             : 
     213             : ! Routine name for debug purposes
     214             : 
     215          10 :       NULLIFY (ao_basis_set)
     216          10 :       NULLIFY (particle_set)
     217          10 :       NULLIFY (qs_kind_set)
     218          10 :       NULLIFY (n_shell)
     219          10 :       NULLIFY (ang_mom_id)
     220          10 :       NULLIFY (atom_nf)
     221          10 :       NULLIFY (atom_id)
     222          10 :       NULLIFY (block_sec)
     223             : 
     224             :       ! Initialization
     225          10 :       ec%n_atoms = 0
     226          10 :       ec%n_blocks = 0
     227          10 :       NULLIFY (ec%fermi)
     228          10 :       NULLIFY (ec%m_transf)
     229          10 :       NULLIFY (ec%m_transf_inv)
     230          10 :       NULLIFY (ec%block)
     231             : 
     232             :       ! Number of atoms / atom types
     233          10 :       CALL get_qs_env(qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, natom=n_atoms)
     234             :       ! Number of AO basis functions
     235          10 :       CALL get_qs_kind_set(qs_kind_set, nsgf=n_ao)
     236             : 
     237             :       ! Number of AO functions per atom
     238          30 :       ALLOCATE (atom_nf(n_atoms))
     239          10 :       CPASSERT(ASSOCIATED(atom_nf))
     240             : 
     241          82 :       atom_nf = 0
     242          82 :       DO i = 1, n_atoms
     243          72 :          CALL get_atomic_kind(particle_set(i)%atomic_kind, kind_number=j)
     244          72 :          CALL get_qs_kind(qs_kind_set(j), basis_set=ao_basis_set)
     245          72 :          IF (.NOT. ASSOCIATED(ao_basis_set)) &
     246           0 :             CPABORT('Unsupported basis set type. ')
     247             :          CALL get_gto_basis_set(gto_basis_set=ao_basis_set, &
     248          72 :                                 nset=n_set, nshell=n_shell, l=ang_mom_id)
     249         238 :          DO j = 1, n_set
     250         280 :             DO k = 1, n_shell(j)
     251         208 :                atom_nf(i) = atom_nf(i) + nso(ang_mom_id(k, j))
     252             :             END DO
     253             :          END DO
     254             :       END DO
     255             : 
     256             :       ! Sanity check
     257          10 :       n = 0
     258          82 :       DO i = 1, n_atoms
     259          82 :          n = n + atom_nf(i)
     260             :       END DO
     261          10 :       CPASSERT(n == n_ao)
     262             : 
     263             :       ! Atom position in AO array
     264          30 :       ALLOCATE (atom_ps(n_atoms))
     265          10 :       CPASSERT(ASSOCIATED(atom_ps))
     266          82 :       atom_ps = 1
     267          72 :       DO i = 1, n_atoms - 1
     268          72 :          atom_ps(i + 1) = atom_ps(i) + atom_nf(i)
     269             :       END DO
     270             : 
     271             :       ! Number of blocks
     272          10 :       block_sec => section_vals_get_subs_vals(et_proj_sec, 'BLOCK')
     273          10 :       CALL section_vals_get(block_sec, n_repetition=ec%n_blocks)
     274          50 :       ALLOCATE (ec%block(ec%n_blocks))
     275          10 :       CPASSERT(ASSOCIATED(ec%block))
     276             : 
     277             :       ! Block data
     278          30 :       ALLOCATE (t(n_atoms))
     279          10 :       CPASSERT(ASSOCIATED(t))
     280             : 
     281          10 :       ec%n_atoms = 0
     282          30 :       DO i = 1, ec%n_blocks
     283             : 
     284             :          ! Initialization
     285          20 :          ec%block(i)%n_atoms = 0
     286          20 :          ec%block(i)%n_electrons = 0
     287          20 :          ec%block(i)%n_ao = 0
     288          20 :          NULLIFY (ec%block(i)%atom)
     289          20 :          NULLIFY (ec%block(i)%mo)
     290          20 :          NULLIFY (ec%block(i)%hab)
     291             : 
     292             :          ! Number of electrons
     293             :          CALL section_vals_val_get(block_sec, i_rep_section=i, &
     294          20 :                                    keyword_name='NELECTRON', i_val=ec%block(i)%n_electrons)
     295             : 
     296             :          ! User-defined atom array
     297             :          CALL section_vals_val_get(block_sec, i_rep_section=i, &
     298          20 :                                    keyword_name='ATOMS', i_vals=atom_id)
     299             : 
     300             :          ! Count unique atoms
     301          92 :          DO j = 1, SIZE(atom_id)
     302             :             ! Check atom ID validity
     303          72 :             IF (atom_id(j) < 1 .OR. atom_id(j) > n_atoms) &
     304           0 :                CPABORT('invalid fragment atom ID ('//TRIM(ADJUSTL(cp_to_string(atom_id(j))))//')')
     305             :             ! Check if the atom is not in previously-defined blocks
     306             :             found = .FALSE.
     307         108 :             DO k = 1, i - 1
     308         348 :                DO l = 1, ec%block(k)%n_atoms
     309         276 :                   IF (ec%block(k)%atom(l)%id == atom_id(j)) THEN
     310           0 :                      CPWARN('multiple definition of atom'//TRIM(ADJUSTL(cp_to_string(atom_id(j)))))
     311           0 :                      found = .TRUE.
     312           0 :                      EXIT
     313             :                   END IF
     314             :                END DO
     315             :             END DO
     316             :             ! Check if the atom is not in already defined in the present block
     317          72 :             IF (.NOT. found) THEN
     318         276 :                DO k = 1, ec%block(i)%n_atoms
     319         276 :                   IF (t(k) == atom_id(j)) THEN
     320           0 :                      CPWARN('multiple definition of atom'//TRIM(ADJUSTL(cp_to_string(atom_id(j)))))
     321             :                      found = .TRUE.
     322             :                      EXIT
     323             :                   END IF
     324             :                END DO
     325             :             END IF
     326             :             ! Save the atom
     327          20 :             IF (.NOT. found) THEN
     328          72 :                ec%block(i)%n_atoms = ec%block(i)%n_atoms + 1
     329          72 :                t(ec%block(i)%n_atoms) = atom_id(j)
     330             :             END IF
     331             :          END DO
     332             : 
     333             :          ! Memory allocation
     334         132 :          ALLOCATE (ec%block(i)%atom(ec%block(i)%n_atoms))
     335          20 :          CPASSERT(ASSOCIATED(ec%block(i)%atom))
     336             : 
     337             :          ! Save atom IDs and number of AOs
     338          92 :          DO j = 1, ec%block(i)%n_atoms
     339          72 :             ec%block(i)%atom(j)%id = t(j)
     340          72 :             ec%block(i)%atom(j)%n_ao = atom_nf(ec%block(i)%atom(j)%id)
     341          72 :             ec%block(i)%atom(j)%ao_pos = atom_ps(ec%block(i)%atom(j)%id)
     342          92 :             ec%block(i)%n_ao = ec%block(i)%n_ao + ec%block(i)%atom(j)%n_ao
     343             :          END DO
     344             : 
     345          30 :          ec%n_atoms = ec%n_atoms + ec%block(i)%n_atoms
     346             :       END DO
     347             : 
     348             :       ! Clean memory
     349          10 :       IF (ASSOCIATED(atom_nf)) &
     350          10 :          DEALLOCATE (atom_nf)
     351          10 :       IF (ASSOCIATED(atom_ps)) &
     352          10 :          DEALLOCATE (atom_ps)
     353          10 :       IF (ASSOCIATED(t)) &
     354          10 :          DEALLOCATE (t)
     355             : 
     356          10 :    END SUBROUTINE set_block_data
     357             : 
     358             : ! **************************************************************************************************
     359             : !> \brief check the electronic-coupling input section and set the atomic block data
     360             : !> \param ec electronic coupling data structure
     361             : !> \param fa system Fermi level (alpha spin)
     362             : !> \param fb system Fermi level (beta spin)
     363             : !> \author Z. Futera (02.2017)
     364             : ! **************************************************************************************************
     365          10 :    SUBROUTINE set_fermi(ec, fa, fb)
     366             : 
     367             :       ! Routine arguments
     368             :       TYPE(et_cpl), POINTER                              :: ec
     369             :       REAL(KIND=dp)                                      :: fa
     370             :       REAL(KIND=dp), OPTIONAL                            :: fb
     371             : 
     372             : ! Routine name for debug purposes
     373             : 
     374          10 :       NULLIFY (ec%fermi)
     375             : 
     376          10 :       IF (PRESENT(fb)) THEN
     377             : 
     378          10 :          ALLOCATE (ec%fermi(2))
     379          10 :          CPASSERT(ASSOCIATED(ec%fermi))
     380          10 :          ec%fermi(1) = fa
     381          10 :          ec%fermi(2) = fb
     382             : 
     383             :       ELSE
     384             : 
     385           0 :          ALLOCATE (ec%fermi(1))
     386           0 :          CPASSERT(ASSOCIATED(ec%fermi))
     387           0 :          ec%fermi(1) = fa
     388             : 
     389             :       END IF
     390             : 
     391          10 :    END SUBROUTINE set_fermi
     392             : 
     393             : ! **************************************************************************************************
     394             : !> \brief reorder Hamiltonian matrix according to defined atomic blocks
     395             : !> \param ec electronic coupling data structure
     396             : !> \param mat_h the Hamiltonian matrix
     397             : !> \param mat_w working matrix of the same dimension
     398             : !> \author Z. Futera (02.2017)
     399             : ! **************************************************************************************************
     400          20 :    SUBROUTINE reorder_hamiltonian_matrix(ec, mat_h, mat_w)
     401             : 
     402             :       ! Routine arguments
     403             :       TYPE(et_cpl), POINTER                              :: ec
     404             :       TYPE(cp_fm_type), INTENT(IN)                       :: mat_h, mat_w
     405             : 
     406             :       INTEGER                                            :: ic, ir, jc, jr, kc, kr, mc, mr, nc, nr
     407             :       REAL(KIND=dp)                                      :: xh
     408             : 
     409             : ! Routine name for debug purposes
     410             : ! Local variables
     411             : 
     412          20 :       IF (.NOT. cp_fm_struct_equivalent(mat_h%matrix_struct, mat_w%matrix_struct)) &
     413           0 :          CPABORT('cannot reorder Hamiltonian, working-matrix structure is not equivalent')
     414             : 
     415             :       ! Matrix-element reordering
     416          20 :       nr = 1
     417             :       ! Rows
     418          60 :       DO ir = 1, ec%n_blocks
     419         204 :          DO jr = 1, ec%block(ir)%n_atoms
     420         592 :             DO kr = 1, ec%block(ir)%atom(jr)%n_ao
     421             :                ! Columns
     422         408 :                nc = 1
     423        1224 :                DO ic = 1, ec%n_blocks
     424        6072 :                   DO jc = 1, ec%block(ic)%n_atoms
     425       18384 :                      DO kc = 1, ec%block(ic)%atom(jc)%n_ao
     426       12720 :                         mr = ec%block(ir)%atom(jr)%ao_pos + kr - 1
     427       12720 :                         mc = ec%block(ic)%atom(jc)%ao_pos + kc - 1
     428       12720 :                         CALL cp_fm_get_element(mat_h, nr, nc, xh)
     429       12720 :                         CALL cp_fm_set_element(mat_w, nr, nc, xh)
     430       30288 :                         nc = nc + 1
     431             :                      END DO
     432             :                   END DO
     433             :                END DO
     434         552 :                nr = nr + 1
     435             :             END DO
     436             :          END DO
     437             :       END DO
     438             : 
     439             :       ! Copy the reordered matrix to original data array
     440          20 :       CALL cp_fm_to_fm(mat_w, mat_h)
     441             : 
     442          20 :    END SUBROUTINE reorder_hamiltonian_matrix
     443             : 
     444             : ! **************************************************************************************************
     445             : !> \brief calculated transformation matrix for basis-set orthogonalization (S^{-1/2})
     446             : !> \param qs_env QuickStep environment containing all system data
     447             : !> \param mat_t storage for the transformation matrix
     448             : !> \param mat_i storage for the inversion transformation matrix
     449             : !> \param mat_w working matrix of the same dimension
     450             : !> \author Z. Futera (02.2017)
     451             : ! **************************************************************************************************
     452          10 :    SUBROUTINE get_s_half_inv_matrix(qs_env, mat_t, mat_i, mat_w)
     453             : 
     454             :       ! Routine arguments
     455             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     456             :       TYPE(cp_fm_type), INTENT(INOUT)                    :: mat_t, mat_i
     457             :       TYPE(cp_fm_type), INTENT(IN)                       :: mat_w
     458             : 
     459             :       INTEGER                                            :: n_deps
     460          10 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mat_s
     461             :       TYPE(scf_control_type), POINTER                    :: scf_cntrl
     462             : 
     463             : ! Routine name for debug purposes
     464             : 
     465          10 :       NULLIFY (mat_s)
     466          10 :       NULLIFY (scf_cntrl)
     467             : 
     468          10 :       CALL get_qs_env(qs_env, matrix_s=mat_s)
     469          10 :       CALL copy_dbcsr_to_fm(mat_s(1)%matrix, mat_t)
     470          10 :       CALL copy_dbcsr_to_fm(mat_s(1)%matrix, mat_i)
     471             : 
     472             :       ! Transformation S -> S^{-1/2}
     473          10 :       CALL get_qs_env(qs_env, scf_control=scf_cntrl)
     474          10 :       CALL cp_fm_power(mat_t, mat_w, -0.5_dp, scf_cntrl%eps_eigval, n_deps)
     475          10 :       CALL cp_fm_power(mat_i, mat_w, +0.5_dp, scf_cntrl%eps_eigval, n_deps)
     476             :       ! Sanity check
     477          10 :       IF (n_deps /= 0) THEN
     478             :          CALL cp_warn(__LOCATION__, &
     479             :                       "Overlap matrix exhibits linear dependencies. At least some "// &
     480           0 :                       "eigenvalues have been quenched.")
     481             :       END IF
     482             : 
     483          10 :    END SUBROUTINE get_s_half_inv_matrix
     484             : 
     485             : ! **************************************************************************************************
     486             : !> \brief transform KS hamiltonian to orthogonalized block-separated basis set
     487             : !> \param qs_env QuickStep environment containing all system data
     488             : !> \param ec electronic coupling data structure
     489             : !> \param fm_s full-matrix structure used for allocation of KS matrices
     490             : !> \param mat_t storage for pointers to the transformed KS matrices
     491             : !> \param mat_w working matrix of the same dimension
     492             : !> \param n_ao total number of AO basis functions
     493             : !> \param n_spins number of spin components
     494             : !> \author Z. Futera (02.2017)
     495             : ! **************************************************************************************************
     496          10 :    SUBROUTINE get_block_hamiltonian(qs_env, ec, fm_s, mat_t, mat_w, n_ao, n_spins)
     497             : 
     498             :       ! Routine arguments
     499             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     500             :       TYPE(et_cpl), POINTER                              :: ec
     501             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_s
     502             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
     503             :          INTENT(OUT)                                     :: mat_t
     504             :       TYPE(cp_fm_type), INTENT(IN)                       :: mat_w
     505             :       INTEGER                                            :: n_ao, n_spins
     506             : 
     507             :       INTEGER                                            :: i
     508          10 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mat_h
     509             : 
     510             : ! Routine name for debug purposes
     511             : 
     512          10 :       NULLIFY (mat_h)
     513             : 
     514             :       ! Memory allocation
     515          50 :       ALLOCATE (mat_t(n_spins))
     516             : 
     517             :       ! KS Hamiltonian
     518          10 :       CALL get_qs_env(qs_env, matrix_ks=mat_h)
     519             :       ! Transformation matrix
     520          10 :       ALLOCATE (ec%m_transf, ec%m_transf_inv)
     521             :       CALL cp_fm_create(matrix=ec%m_transf, matrix_struct=fm_s, &
     522          10 :                         name='S^(-1/2) TRANSFORMATION MATRIX')
     523             :       CALL cp_fm_create(matrix=ec%m_transf_inv, matrix_struct=fm_s, &
     524          10 :                         name='S^(+1/2) TRANSFORMATION MATRIX')
     525          10 :       CALL get_s_half_inv_matrix(qs_env, ec%m_transf, ec%m_transf_inv, mat_w)
     526             : 
     527          30 :       DO i = 1, n_spins
     528             : 
     529             :          ! Full-matrix format
     530             :          CALL cp_fm_create(matrix=mat_t(i), matrix_struct=fm_s, &
     531          20 :                            name='KS HAMILTONIAN IN SEPARATED ORTHOGONALIZED BASIS SET')
     532          20 :          CALL copy_dbcsr_to_fm(mat_h(i)%matrix, mat_t(i))
     533             : 
     534             :          ! Transform KS Hamiltonian to the orthogonalized AO basis set
     535          20 :          CALL parallel_gemm("N", "N", n_ao, n_ao, n_ao, 1.0_dp, ec%m_transf, mat_t(i), 0.0_dp, mat_w)
     536          20 :          CALL parallel_gemm("N", "N", n_ao, n_ao, n_ao, 1.0_dp, mat_w, ec%m_transf, 0.0_dp, mat_t(i))
     537             : 
     538             :          ! Reorder KS Hamiltonain elements to defined block structure
     539          30 :          CALL reorder_hamiltonian_matrix(ec, mat_t(i), mat_w)
     540             : 
     541             :       END DO
     542             : 
     543          10 :    END SUBROUTINE get_block_hamiltonian
     544             : 
     545             : ! **************************************************************************************************
     546             : !> \brief Diagonalize diagonal blocks of the KS hamiltonian in separated orthogonalized basis set
     547             : !> \param qs_env QuickStep environment containing all system data
     548             : !> \param ec electronic coupling data structure
     549             : !> \param mat_h Hamiltonian in separated orthogonalized basis set
     550             : !> \author Z. Futera (02.2017)
     551             : ! **************************************************************************************************
     552          10 :    SUBROUTINE hamiltonian_block_diag(qs_env, ec, mat_h)
     553             : 
     554             :       ! Routine arguments
     555             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     556             :       TYPE(et_cpl), POINTER                              :: ec
     557             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: mat_h
     558             : 
     559             :       INTEGER                                            :: i, j, k, l, n_spins, spin
     560          10 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: vec_e
     561             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     562             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_s
     563             :       TYPE(cp_fm_type)                                   :: mat_u
     564          10 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: dat
     565             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     566             : 
     567             : ! Routine name for debug purposes
     568             : 
     569          10 :       NULLIFY (vec_e)
     570          10 :       NULLIFY (blacs_env)
     571          10 :       NULLIFY (para_env)
     572          10 :       NULLIFY (fm_s)
     573             : 
     574             :       ! Parallel environment
     575          10 :       CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
     576             : 
     577             :       ! Storage for block sub-matrices
     578          50 :       ALLOCATE (dat(ec%n_blocks))
     579          10 :       CPASSERT(ALLOCATED(dat))
     580             : 
     581             :       ! Storage for electronic states and couplings
     582          10 :       n_spins = SIZE(mat_h)
     583          30 :       DO i = 1, ec%n_blocks
     584         100 :          ALLOCATE (ec%block(i)%mo(n_spins))
     585          20 :          CPASSERT(ASSOCIATED(ec%block(i)%mo))
     586         200 :          ALLOCATE (ec%block(i)%hab(n_spins, ec%n_blocks))
     587          30 :          CPASSERT(ASSOCIATED(ec%block(i)%hab))
     588             :       END DO
     589             : 
     590             :       ! Spin components
     591          30 :       DO spin = 1, n_spins
     592             : 
     593             :          ! Diagonal blocks
     594          20 :          j = 1
     595          60 :          DO i = 1, ec%n_blocks
     596             : 
     597             :             ! Memory allocation
     598             :             CALL cp_fm_struct_create(fmstruct=fm_s, para_env=para_env, context=blacs_env, &
     599          40 :                                      nrow_global=ec%block(i)%n_ao, ncol_global=ec%block(i)%n_ao)
     600             :             CALL cp_fm_create(matrix=dat(i), matrix_struct=fm_s, &
     601          40 :                               name='H_KS DIAGONAL BLOCK')
     602             : 
     603         120 :             ALLOCATE (vec_e(ec%block(i)%n_ao))
     604          40 :             CPASSERT(ASSOCIATED(vec_e))
     605             : 
     606             :             ! Copy block data
     607             :             CALL cp_fm_to_fm_submat(mat_h(spin), &
     608             :                                     dat(i), ec%block(i)%n_ao, &
     609          40 :                                     ec%block(i)%n_ao, j, j, 1, 1)
     610             : 
     611             :             ! Diagonalization
     612          40 :             CALL cp_fm_create(matrix=mat_u, matrix_struct=fm_s, name='UNITARY MATRIX')
     613          40 :             CALL choose_eigv_solver(dat(i), mat_u, vec_e)
     614          40 :             CALL cp_fm_to_fm(mat_u, dat(i))
     615             : 
     616             :             ! Save state energies / vectors
     617          40 :             CALL create_block_mo_set(qs_env, ec, i, spin, mat_u, vec_e)
     618             : 
     619             :             ! Clean memory
     620          40 :             CALL cp_fm_struct_release(fmstruct=fm_s)
     621          40 :             CALL cp_fm_release(matrix=mat_u)
     622          40 :             DEALLOCATE (vec_e)
     623             : 
     624             :             ! Off-set for next block
     625         100 :             j = j + ec%block(i)%n_ao
     626             : 
     627             :          END DO
     628             : 
     629             :          ! Off-diagonal blocks
     630          20 :          k = 1
     631          60 :          DO i = 1, ec%n_blocks
     632          40 :             l = 1
     633         120 :             DO j = 1, ec%n_blocks
     634          80 :                IF (i /= j) THEN
     635             : 
     636             :                   ! Memory allocation
     637             :                   CALL cp_fm_struct_create(fmstruct=fm_s, para_env=para_env, context=blacs_env, &
     638          40 :                                            nrow_global=ec%block(i)%n_ao, ncol_global=ec%block(j)%n_ao)
     639             :                   CALL cp_fm_create(matrix=ec%block(i)%hab(spin, j), matrix_struct=fm_s, &
     640          40 :                                     name='H_KS OFF-DIAGONAL BLOCK')
     641             : 
     642             :                   ! Copy block data
     643             :                   CALL cp_fm_to_fm_submat(mat_h(spin), &
     644             :                                           ec%block(i)%hab(spin, j), ec%block(i)%n_ao, &
     645          40 :                                           ec%block(j)%n_ao, k, l, 1, 1)
     646             : 
     647             :                   ! Transformation
     648          40 :                   CALL cp_fm_create(matrix=mat_u, matrix_struct=fm_s, name='FULL WORK MATRIX')
     649             :                   CALL parallel_gemm("T", "N", ec%block(i)%n_ao, ec%block(j)%n_ao, ec%block(i)%n_ao, &
     650          40 :                                      1.0_dp, dat(i), ec%block(i)%hab(spin, j), 0.0_dp, mat_u)
     651             :                   CALL parallel_gemm("N", "N", ec%block(i)%n_ao, ec%block(j)%n_ao, ec%block(j)%n_ao, &
     652          40 :                                      1.0_dp, mat_u, dat(j), 0.0_dp, ec%block(i)%hab(spin, j))
     653             : 
     654             :                   ! Clean memory
     655          40 :                   CALL cp_fm_struct_release(fmstruct=fm_s)
     656          40 :                   CALL cp_fm_release(matrix=mat_u)
     657             : 
     658             :                END IF
     659             :                ! Off-set for next block
     660         120 :                l = l + ec%block(j)%n_ao
     661             :             END DO
     662             :             ! Off-set for next block
     663          60 :             k = k + ec%block(i)%n_ao
     664             :          END DO
     665             : 
     666             :          ! Clean memory
     667          30 :          IF (ALLOCATED(dat)) THEN
     668          60 :             DO i = 1, SIZE(dat)
     669          60 :                CALL cp_fm_release(dat(i))
     670             :             END DO
     671             :          END IF
     672             :       END DO
     673             : 
     674             :       ! Clean memory
     675          10 :       IF (ALLOCATED(dat)) &
     676          10 :          DEALLOCATE (dat)
     677             : 
     678          20 :    END SUBROUTINE hamiltonian_block_diag
     679             : 
     680             : ! **************************************************************************************************
     681             : !> \brief Return sum of selected squared MO coefficients
     682             : !> \param blk_at list of atoms in the block
     683             : !> \param mo array of MO sets
     684             : !> \param id state index
     685             : !> \param atom list of atoms for MO coefficient summing
     686             : !> \return ...
     687             : !> \author Z. Futera (02.2017)
     688             : ! **************************************************************************************************
     689           0 :    FUNCTION get_mo_c2_sum(blk_at, mo, id, atom) RESULT(c2)
     690             : 
     691             :       ! Routine arguments
     692             :       TYPE(et_cpl_atom), DIMENSION(:), POINTER           :: blk_at
     693             :       TYPE(cp_fm_type), INTENT(IN)                       :: mo
     694             :       INTEGER, INTENT(IN)                                :: id
     695             :       INTEGER, DIMENSION(:), POINTER                     :: atom
     696             :       REAL(KIND=dp)                                      :: c2
     697             : 
     698             :       INTEGER                                            :: i, ir, j, k
     699             :       LOGICAL                                            :: found
     700             :       REAL(KIND=dp)                                      :: c
     701             : 
     702             : ! Returning value
     703             : ! Routine name for debug purposes
     704             : ! Local variables
     705             : 
     706             :       ! initialization
     707           0 :       c2 = 0.0d0
     708             : 
     709             :       ! selected atoms
     710           0 :       DO i = 1, SIZE(atom)
     711             : 
     712             :          ! find atomic function offset
     713           0 :          found = .FALSE.
     714           0 :          DO j = 1, SIZE(blk_at)
     715           0 :             IF (blk_at(j)%id == atom(i)) THEN
     716             :                found = .TRUE.
     717             :                EXIT
     718             :             END IF
     719             :          END DO
     720             : 
     721           0 :          IF (.NOT. found) &
     722           0 :             CPABORT('MO-fraction atom ID not defined in the block')
     723             : 
     724             :          ! sum MO coefficients from the atom
     725           0 :          DO k = 1, blk_at(j)%n_ao
     726           0 :             ir = blk_at(j)%ao_pos + k - 1
     727           0 :             CALL cp_fm_get_element(mo, ir, id, c)
     728           0 :             c2 = c2 + c*c
     729             :          END DO
     730             : 
     731             :       END DO
     732             : 
     733           0 :    END FUNCTION get_mo_c2_sum
     734             : 
     735             : ! **************************************************************************************************
     736             : !> \brief Print out specific MO coefficients
     737             : !> \param output_unit unit number of the open output stream
     738             : !> \param qs_env QuickStep environment containing all system data
     739             : !> \param ec electronic coupling data structure
     740             : !> \param blk atomic-block ID
     741             : !> \param n_spins number of spin components
     742             : !> \author Z. Futera (02.2017)
     743             : ! **************************************************************************************************
     744          20 :    SUBROUTINE print_mo_coeff(output_unit, qs_env, ec, blk, n_spins)
     745             : 
     746             :       ! Routine arguments
     747             :       INTEGER, INTENT(IN)                                :: output_unit
     748             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     749             :       TYPE(et_cpl), POINTER                              :: ec
     750             :       INTEGER, INTENT(IN)                                :: blk, n_spins
     751             : 
     752             :       INTEGER                                            :: j, k, l, m, n, n_ao, n_mo
     753          20 :       INTEGER, DIMENSION(:), POINTER                     :: list_at, list_mo
     754             :       REAL(KIND=dp)                                      :: c1, c2
     755          20 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: mat_w
     756          20 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     757             :       TYPE(section_vals_type), POINTER                   :: block_sec, print_sec
     758             : 
     759             : ! Routine name for debug purposes
     760             : 
     761          20 :       NULLIFY (block_sec)
     762          20 :       NULLIFY (print_sec)
     763          20 :       NULLIFY (qs_kind_set)
     764             : 
     765             :       ! Atomic block data
     766             :       block_sec => section_vals_get_subs_vals(qs_env%input, &
     767          40 :                                               'PROPERTIES%ET_COUPLING%PROJECTION%BLOCK')
     768             : 
     769          20 :       print_sec => section_vals_get_subs_vals(block_sec, 'PRINT', i_rep_section=blk)
     770             : 
     771             :       ! List of atoms
     772          20 :       CALL section_vals_val_get(print_sec, keyword_name='MO_COEFF_ATOM', n_rep_val=n)
     773             : 
     774          20 :       IF (n > 0) THEN
     775             : 
     776           0 :          IF (output_unit > 0) &
     777           0 :             WRITE (output_unit, '(/,T3,A/)') 'Block state fractions:'
     778             : 
     779             :          ! Number of AO functions
     780           0 :          CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
     781           0 :          CALL get_qs_kind_set(qs_kind_set, nsgf=n_ao)
     782             : 
     783             :          ! MOs in orthonormal basis set
     784           0 :          ALLOCATE (mat_w(n_spins))
     785           0 :          DO j = 1, n_spins
     786           0 :             n_mo = ec%block(blk)%n_ao
     787             :             CALL cp_fm_create(matrix=mat_w(j), &
     788             :                               matrix_struct=ec%block(blk)%mo(j)%mo_coeff%matrix_struct, &
     789           0 :                               name='BLOCK MOs IN ORTHONORMAL BASIS SET')
     790             :             CALL parallel_gemm("N", "N", n_ao, n_mo, n_ao, 1.0_dp, ec%m_transf_inv, &
     791           0 :                                ec%block(blk)%mo(j)%mo_coeff, 0.0_dp, mat_w(j))
     792             :          END DO
     793             : 
     794           0 :          DO j = 1, n
     795           0 :             NULLIFY (list_at)
     796             :             CALL section_vals_val_get(print_sec, keyword_name='MO_COEFF_ATOM', &
     797           0 :                                       i_rep_val=j, i_vals=list_at)
     798           0 :             IF (ASSOCIATED(list_at)) THEN
     799             : 
     800             :                ! List of states
     801           0 :                CALL section_vals_val_get(print_sec, keyword_name='MO_COEFF_ATOM_STATE', n_rep_val=m)
     802             : 
     803           0 :                IF (m > 0) THEN
     804             : 
     805           0 :                   DO k = 1, m
     806           0 :                      NULLIFY (list_mo)
     807             :                      CALL section_vals_val_get(print_sec, keyword_name='MO_COEFF_ATOM_STATE', &
     808           0 :                                                i_rep_val=k, i_vals=list_mo)
     809           0 :                      IF (ASSOCIATED(list_mo)) THEN
     810             : 
     811           0 :                         IF (j > 1) THEN
     812           0 :                            IF (output_unit > 0) &
     813           0 :                               WRITE (output_unit, *)
     814             :                         END IF
     815             : 
     816           0 :                         DO l = 1, SIZE(list_mo)
     817             : 
     818           0 :                            IF (n_spins > 1) THEN
     819             :                               c1 = get_mo_c2_sum(ec%block(blk)%atom, mat_w(1), &
     820           0 :                                                  list_mo(l), list_at)
     821             :                               c2 = get_mo_c2_sum(ec%block(blk)%atom, mat_w(2), &
     822           0 :                                                  list_mo(l), list_at)
     823           0 :                               IF (output_unit > 0) &
     824           0 :                                  WRITE (output_unit, '(I5,A,I5,2F20.10)') j, ' /', list_mo(l), c1, c2
     825             :                            ELSE
     826             :                               c1 = get_mo_c2_sum(ec%block(blk)%atom, mat_w(1), &
     827           0 :                                                  list_mo(l), list_at)
     828           0 :                               IF (output_unit > 0) &
     829           0 :                                  WRITE (output_unit, '(I5,A,I5,F20.10)') j, ' /', list_mo(l), c1
     830             :                            END IF
     831             : 
     832             :                         END DO
     833             : 
     834             :                      END IF
     835             :                   END DO
     836             : 
     837             :                END IF
     838             : 
     839             :             END IF
     840             :          END DO
     841             : 
     842             :          ! Clean memory
     843           0 :          CALL cp_fm_release(mat_w)
     844             : 
     845             :       END IF
     846             : 
     847          40 :    END SUBROUTINE print_mo_coeff
     848             : 
     849             : ! **************************************************************************************************
     850             : !> \brief Print out electronic states (MOs)
     851             : !> \param output_unit unit number of the open output stream
     852             : !> \param mo array of MO sets
     853             : !> \param n_spins number of spin components
     854             : !> \param label output label
     855             : !> \param mx_mo_a maximum number of alpha states to print out
     856             : !> \param mx_mo_b maximum number of beta states to print out
     857             : !> \param fermi print out Fermi level and number of electrons
     858             : !> \author Z. Futera (02.2017)
     859             : ! **************************************************************************************************
     860          40 :    SUBROUTINE print_states(output_unit, mo, n_spins, label, mx_mo_a, mx_mo_b, fermi)
     861             : 
     862             :       ! Routine arguments
     863             :       INTEGER, INTENT(IN)                                :: output_unit
     864             :       TYPE(mo_set_type), DIMENSION(:), INTENT(IN)        :: mo
     865             :       INTEGER, INTENT(IN)                                :: n_spins
     866             :       CHARACTER(LEN=*), INTENT(IN)                       :: label
     867             :       INTEGER, INTENT(IN), OPTIONAL                      :: mx_mo_a, mx_mo_b
     868             :       LOGICAL, INTENT(IN), OPTIONAL                      :: fermi
     869             : 
     870             :       INTEGER                                            :: i, mx_a, mx_b, n
     871             :       LOGICAL                                            :: prnt_fm
     872             : 
     873             : ! Routine name for debug purposes
     874             : 
     875          20 :       prnt_fm = .FALSE.
     876          20 :       IF (PRESENT(fermi)) &
     877          20 :          prnt_fm = fermi
     878             : 
     879          20 :       IF (output_unit > 0) THEN
     880             : 
     881          15 :          WRITE (output_unit, '(/,T3,A/)') 'State energies ('//TRIM(ADJUSTL(label))//'):'
     882             : 
     883             :          ! Spin-polarized calculation
     884          15 :          IF (n_spins > 1) THEN
     885             : 
     886          15 :             mx_a = mo(1)%nmo
     887          15 :             IF (PRESENT(mx_mo_a)) &
     888          10 :                mx_a = MIN(mo(1)%nmo, mx_mo_a)
     889          15 :             mx_b = mo(2)%nmo
     890          15 :             IF (PRESENT(mx_mo_b)) &
     891          10 :                mx_b = MIN(mo(2)%nmo, mx_mo_b)
     892          15 :             n = MAX(mx_a, mx_b)
     893             : 
     894         181 :             DO i = 1, n
     895         166 :                WRITE (output_unit, '(T3,I10)', ADVANCE='no') i
     896         166 :                IF (i <= mx_a) THEN
     897             :                   WRITE (output_unit, '(2F12.4)', ADVANCE='no') &
     898         166 :                      mo(1)%occupation_numbers(i), mo(1)%eigenvalues(i)
     899             :                ELSE
     900           0 :                   WRITE (output_unit, '(A)', ADVANCE='no') '                        '
     901             :                END IF
     902         166 :                WRITE (output_unit, '(A)', ADVANCE='no') '     '
     903         181 :                IF (i <= mx_b) THEN
     904             :                   WRITE (output_unit, '(2F12.4)') &
     905         161 :                      mo(2)%occupation_numbers(i), mo(2)%eigenvalues(i)
     906             :                ELSE
     907           5 :                   WRITE (output_unit, *)
     908             :                END IF
     909             :             END DO
     910             : 
     911          15 :             IF (prnt_fm) THEN
     912             :                WRITE (output_unit, '(/,T3,I10,F24.4,I10,F19.4)') &
     913          15 :                   mo(1)%nelectron, mo(1)%mu, &
     914          30 :                   mo(2)%nelectron, mo(2)%mu
     915             :             END IF
     916             : 
     917             :             ! Spin-restricted calculation
     918             :          ELSE
     919             : 
     920           0 :             mx_a = mo(1)%nmo
     921           0 :             IF (PRESENT(mx_mo_a)) &
     922           0 :                mx_a = MIN(mo(1)%nmo, mx_mo_a)
     923             : 
     924           0 :             DO i = 1, mx_a
     925             :                WRITE (output_unit, '(T3,I10,2F12.4)') &
     926           0 :                   i, mo(1)%occupation_numbers(i), mo(1)%eigenvalues(i)
     927             :             END DO
     928             : 
     929           0 :             IF (prnt_fm) THEN
     930             :                WRITE (output_unit, '(/,T3,I10,F24.4)') &
     931           0 :                   mo(1)%nelectron, mo(1)%mu
     932             :             END IF
     933             : 
     934             :          END IF
     935             : 
     936             :       END IF
     937             : 
     938          20 :    END SUBROUTINE print_states
     939             : 
     940             : ! **************************************************************************************************
     941             : !> \brief Print out donor-acceptor state couplings
     942             : !> \param ec_sec ...
     943             : !> \param output_unit unit number of the open output stream
     944             : !> \param logger ...
     945             : !> \param ec electronic coupling data structure
     946             : !> \param mo ...
     947             : !> \author Z. Futera (02.2017)
     948             : ! **************************************************************************************************
     949          10 :    SUBROUTINE print_couplings(ec_sec, output_unit, logger, ec, mo)
     950             : 
     951             :       ! Routine arguments
     952             :       TYPE(section_vals_type), POINTER                   :: ec_sec
     953             :       INTEGER, INTENT(IN)                                :: output_unit
     954             :       TYPE(cp_logger_type), POINTER                      :: logger
     955             :       TYPE(et_cpl), POINTER                              :: ec
     956             :       TYPE(mo_set_type), DIMENSION(:), INTENT(IN)        :: mo
     957             : 
     958             :       CHARACTER(LEN=default_path_length)                 :: filename, my_pos, title
     959             :       INTEGER                                            :: i, j, k, l, n_states(2), nc, nr, nspins, &
     960             :                                                             unit_nr
     961             :       LOGICAL                                            :: append
     962          10 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: w1, w2
     963             :       TYPE(section_vals_type), POINTER                   :: print_key
     964             : 
     965             : ! Routine name for debug purposes
     966             : ! Local variables
     967             : 
     968          10 :       n_states = 0
     969          30 :       DO i = 1, SIZE(mo)
     970          30 :          n_states(i) = mo(i)%nmo
     971             :       END DO
     972          10 :       nspins = 1
     973          10 :       IF (n_states(2) > 0) nspins = 2
     974             : 
     975             :       print_key => section_vals_get_subs_vals(section_vals=ec_sec, &
     976          10 :                                               subsection_name="PRINT%COUPLINGS")
     977             : 
     978          10 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), &
     979             :                 cp_p_file)) THEN
     980             : 
     981          10 :          my_pos = "REWIND"
     982          10 :          append = section_get_lval(print_key, "APPEND")
     983          10 :          IF (append) THEN
     984           0 :             my_pos = "APPEND"
     985             :          END IF
     986             : 
     987          10 :          IF (output_unit > 0) &
     988           5 :             WRITE (output_unit, '(/,T3,A/)') 'Printing coupling elements to output files'
     989             : 
     990          30 :          DO i = 1, ec%n_blocks
     991          40 :             DO j = i + 1, ec%n_blocks
     992             : 
     993          10 :                nr = ec%block(i)%hab(1, j)%matrix_struct%nrow_global
     994          10 :                nc = ec%block(i)%hab(1, j)%matrix_struct%ncol_global
     995             : 
     996          40 :                ALLOCATE (w1(nr, nc))
     997          10 :                CPASSERT(ASSOCIATED(w1))
     998          10 :                CALL cp_fm_get_submatrix(ec%block(i)%hab(1, j), w1)
     999          10 :                IF (nspins > 1) THEN
    1000          30 :                   ALLOCATE (w2(nr, nc))
    1001          10 :                   CPASSERT(ASSOCIATED(w2))
    1002          10 :                   CALL cp_fm_get_submatrix(ec%block(i)%hab(2, j), w2)
    1003             :                END IF
    1004             : 
    1005          10 :                IF (output_unit > 0) THEN
    1006             : 
    1007           5 :                   WRITE (filename, '(a5,I1.1,a1,I1.1)') "ET_BL_", i, "-", j
    1008             :                   unit_nr = cp_print_key_unit_nr(logger, ec_sec, "PRINT%COUPLINGS", extension=".elcoup", &
    1009           5 :                                                  middle_name=TRIM(filename), file_position=my_pos, log_filename=.FALSE.)
    1010             : 
    1011           5 :                   WRITE (title, *) 'Coupling elements [meV] between blocks:', i, j
    1012             : 
    1013           5 :                   WRITE (unit_nr, *) TRIM(title)
    1014           5 :                   IF (nspins > 1) THEN
    1015           5 :                      WRITE (unit_nr, '(T3,A8,T13,A8,T28,A,A)') 'State A', 'State B', 'Coupling spin 1', '  Coupling spin 2'
    1016             :                   ELSE
    1017           0 :                      WRITE (unit_nr, '(T3,A8,T13,A8,T28,A)') 'State A', 'State B', 'Coupling'
    1018             :                   END IF
    1019             : 
    1020          55 :                   DO k = 1, MIN(ec%block(i)%n_ao, n_states(1))
    1021         836 :                      DO l = 1, MIN(ec%block(j)%n_ao, n_states(1))
    1022             : 
    1023         836 :                         IF (nspins > 1) THEN
    1024             : 
    1025             :                            WRITE (unit_nr, '(T3,I5,T13,I5,T22,E20.6)', ADVANCE='no') &
    1026         786 :                               k, l, w1(k, l)*evolt*1000.0_dp
    1027         786 :                            IF ((k <= n_states(2)) .AND. (l <= n_states(2))) THEN
    1028             :                               WRITE (unit_nr, '(E20.6)') &
    1029         779 :                                  w2(k, l)*evolt*1000.0_dp
    1030             :                            ELSE
    1031           7 :                               WRITE (unit_nr, *)
    1032             :                            END IF
    1033             : 
    1034             :                         ELSE
    1035             : 
    1036             :                            WRITE (unit_nr, '(T3,I5,T13,I5,T22,E20.6)') &
    1037           0 :                               k, l, w1(k, l)*evolt*1000.0_dp
    1038             :                         END IF
    1039             : 
    1040             :                      END DO
    1041          55 :                      WRITE (unit_nr, *)
    1042             :                   END DO
    1043           5 :                   CALL cp_print_key_finished_output(unit_nr, logger, ec_sec, "PRINT%COUPLINGS")
    1044             : 
    1045             :                END IF
    1046             : 
    1047          10 :                IF (ASSOCIATED(w1)) DEALLOCATE (w1)
    1048          30 :                IF (ASSOCIATED(w2)) DEALLOCATE (w2)
    1049             : 
    1050             :             END DO
    1051             :          END DO
    1052             : 
    1053             :       END IF
    1054          10 :    END SUBROUTINE print_couplings
    1055             : 
    1056             : ! **************************************************************************************************
    1057             : !> \brief Normalize set of MO vectors
    1058             : !> \param qs_env QuickStep environment containing all system data
    1059             : !> \param mo storage for the MO data set
    1060             : !> \param n_ao number of AO basis functions
    1061             : !> \param n_mo number of block states
    1062             : !> \author Z. Futera (02.2017)
    1063             : ! **************************************************************************************************
    1064          40 :    SUBROUTINE normalize_mo_vectors(qs_env, mo, n_ao, n_mo)
    1065             : 
    1066             :       ! Routine arguments
    1067             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1068             :       TYPE(mo_set_type), POINTER                         :: mo
    1069             :       INTEGER, INTENT(IN)                                :: n_ao, n_mo
    1070             : 
    1071             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: vec_t
    1072             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    1073             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_s
    1074             :       TYPE(cp_fm_type)                                   :: mat_sc, mat_t
    1075          40 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mat_s
    1076             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1077             : 
    1078             : ! Routine name for debug purposes
    1079             : 
    1080             :       ! Initialization
    1081          40 :       NULLIFY (blacs_env)
    1082          40 :       NULLIFY (para_env)
    1083          40 :       NULLIFY (fm_s)
    1084          40 :       NULLIFY (mat_s)
    1085             :       NULLIFY (vec_t)
    1086             : 
    1087             :       ! Overlap matrix
    1088          40 :       CALL get_qs_env(qs_env, matrix_s=mat_s)
    1089             : 
    1090             :       ! Calculate S*C product
    1091             :       CALL cp_fm_create(matrix=mat_sc, matrix_struct=mo%mo_coeff%matrix_struct, &
    1092          40 :                         name='S*C PRODUCT MATRIX')
    1093          40 :       CALL cp_dbcsr_sm_fm_multiply(mat_s(1)%matrix, mo%mo_coeff, mat_sc, n_mo)
    1094             : 
    1095             :       ! Calculate C^T*S*C
    1096          40 :       CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
    1097             :       CALL cp_fm_struct_create(fmstruct=fm_s, para_env=para_env, context=blacs_env, &
    1098          40 :                                nrow_global=n_mo, ncol_global=n_mo)
    1099             :       CALL cp_fm_create(matrix=mat_t, matrix_struct=fm_s, &
    1100          40 :                         name='C^T*S*C OVERLAP PRODUCT MATRIX')
    1101          40 :       CALL parallel_gemm('T', 'N', n_mo, n_mo, n_ao, 1.0_dp, mo%mo_coeff, mat_sc, 0.0_dp, mat_t)
    1102             : 
    1103             :       ! Normalization
    1104         120 :       ALLOCATE (vec_t(n_mo))
    1105          40 :       CPASSERT(ASSOCIATED(vec_t))
    1106          40 :       CALL cp_fm_vectorssum(mat_t, vec_t)
    1107         448 :       vec_t = 1.0_dp/DSQRT(vec_t)
    1108          40 :       CALL cp_fm_column_scale(mo%mo_coeff, vec_t)
    1109             : 
    1110             :       ! Clean memory
    1111          40 :       CALL cp_fm_struct_release(fmstruct=fm_s)
    1112          40 :       CALL cp_fm_release(matrix=mat_sc)
    1113          40 :       CALL cp_fm_release(matrix=mat_t)
    1114          40 :       IF (ASSOCIATED(vec_t)) &
    1115          40 :          DEALLOCATE (vec_t)
    1116             : 
    1117          80 :    END SUBROUTINE normalize_mo_vectors
    1118             : 
    1119             : ! **************************************************************************************************
    1120             : !> \brief Transform block MO coefficients to original non-orthogonal basis set and save them
    1121             : !> \param qs_env QuickStep environment containing all system data
    1122             : !> \param ec electronic coupling data structure
    1123             : !> \param id block ID
    1124             : !> \param mo storage for the MO data set
    1125             : !> \param mat_u matrix of the block states
    1126             : !> \param n_ao number of AO basis functions
    1127             : !> \param n_mo number of block states
    1128             : !> \author Z. Futera (02.2017)
    1129             : ! **************************************************************************************************
    1130          40 :    SUBROUTINE set_mo_coefficients(qs_env, ec, id, mo, mat_u, n_ao, n_mo)
    1131             : 
    1132             :       ! Routine arguments
    1133             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1134             :       TYPE(et_cpl), POINTER                              :: ec
    1135             :       INTEGER, INTENT(IN)                                :: id
    1136             :       TYPE(mo_set_type), POINTER                         :: mo
    1137             :       TYPE(cp_fm_type), INTENT(IN)                       :: mat_u
    1138             :       INTEGER, INTENT(IN)                                :: n_ao, n_mo
    1139             : 
    1140             :       INTEGER                                            :: ic, ir, jc, jr, mr, nc, nr
    1141             :       REAL(KIND=dp)                                      :: xu
    1142             :       TYPE(cp_fm_type)                                   :: mat_w
    1143             : 
    1144             : ! Routine name for debug purposes
    1145             : ! Local variables
    1146             : 
    1147             :       ! Working matrix
    1148             :       CALL cp_fm_create(matrix=mat_w, matrix_struct=mo%mo_coeff%matrix_struct, &
    1149          40 :                         name='BLOCK MO-TRANSFORMATION WORKING MATRIX')
    1150          40 :       CALL cp_fm_set_all(mat_w, 0.0_dp)
    1151             : 
    1152             :       ! Matrix-element reordering
    1153          40 :       nr = 1
    1154             :       ! Rows
    1155         184 :       DO ir = 1, ec%block(id)%n_atoms
    1156         592 :          DO jr = 1, ec%block(id)%atom(ir)%n_ao
    1157             :             ! Columns
    1158         408 :             nc = 1
    1159        2832 :             DO ic = 1, ec%block(id)%n_atoms
    1160        9192 :                DO jc = 1, ec%block(id)%atom(ic)%n_ao
    1161        6360 :                   mr = ec%block(id)%atom(ir)%ao_pos + jr - 1
    1162        6360 :                   CALL cp_fm_get_element(mat_u, nr, nc, xu)
    1163        6360 :                   CALL cp_fm_set_element(mat_w, mr, nc, xu)
    1164       15144 :                   nc = nc + 1
    1165             :                END DO
    1166             :             END DO
    1167         552 :             nr = nr + 1
    1168             :          END DO
    1169             :       END DO
    1170             : 
    1171             :       ! Transformation to original non-orthogonal basis set
    1172          40 :       CALL parallel_gemm("N", "N", n_ao, n_mo, n_ao, 1.0_dp, ec%m_transf, mat_w, 0.0_dp, mo%mo_coeff)
    1173          40 :       CALL normalize_mo_vectors(qs_env, mo, n_ao, n_mo)
    1174             : 
    1175             :       ! Clean memory
    1176          40 :       CALL cp_fm_release(matrix=mat_w)
    1177             : 
    1178          40 :    END SUBROUTINE set_mo_coefficients
    1179             : 
    1180             : ! **************************************************************************************************
    1181             : !> \brief Creates MO set corresponding to one atomic data block
    1182             : !> \param qs_env QuickStep environment containing all system data
    1183             : !> \param ec electronic coupling data structure
    1184             : !> \param id block ID
    1185             : !> \param spin spin component
    1186             : !> \param mat_u matrix of the block states
    1187             : !> \param vec_e array of the block eigenvalues
    1188             : !> \author Z. Futera (02.2017)
    1189             : ! **************************************************************************************************
    1190          40 :    SUBROUTINE create_block_mo_set(qs_env, ec, id, spin, mat_u, vec_e)
    1191             : 
    1192             :       ! Routine arguments
    1193             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1194             :       TYPE(et_cpl), POINTER                              :: ec
    1195             :       INTEGER, INTENT(IN)                                :: id, spin
    1196             :       TYPE(cp_fm_type), INTENT(IN)                       :: mat_u
    1197             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: vec_e
    1198             : 
    1199             :       INTEGER                                            :: n_ao, n_el, n_mo
    1200             :       REAL(KIND=dp)                                      :: mx_occ
    1201             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    1202             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_s
    1203             :       TYPE(dft_control_type), POINTER                    :: dft_cntrl
    1204             :       TYPE(mo_set_type), POINTER                         :: mo
    1205             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1206          40 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1207             :       TYPE(scf_control_type), POINTER                    :: scf_cntrl
    1208             : 
    1209             : ! Routine name for debug purposes
    1210             : 
    1211          40 :       NULLIFY (blacs_env)
    1212          40 :       NULLIFY (dft_cntrl)
    1213          40 :       NULLIFY (para_env)
    1214          40 :       NULLIFY (qs_kind_set)
    1215          40 :       NULLIFY (fm_s)
    1216          40 :       NULLIFY (scf_cntrl)
    1217          40 :       NULLIFY (mo)
    1218             : 
    1219             :       ! Number of basis functions
    1220          40 :       CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
    1221          40 :       CALL get_qs_kind_set(qs_kind_set, nsgf=n_ao)
    1222             : 
    1223             :       ! Number of states
    1224          40 :       n_mo = mat_u%matrix_struct%nrow_global
    1225          40 :       IF (n_mo /= mat_u%matrix_struct%ncol_global) &
    1226           0 :          CPABORT('block state matrix is not square')
    1227          40 :       IF (n_mo /= SIZE(vec_e)) &
    1228           0 :          CPABORT('inconsistent number of states / energies')
    1229             : 
    1230             :       ! Maximal occupancy
    1231          40 :       CALL get_qs_env(qs_env, dft_control=dft_cntrl)
    1232          40 :       mx_occ = 2.0_dp
    1233          40 :       IF (dft_cntrl%nspins > 1) &
    1234          40 :          mx_occ = 1.0_dp
    1235             : 
    1236             :       ! Number of electrons
    1237          40 :       n_el = ec%block(id)%n_electrons
    1238          40 :       IF (dft_cntrl%nspins > 1) THEN
    1239          40 :          n_el = n_el/2
    1240          40 :          IF (MOD(ec%block(id)%n_electrons, 2) == 1) THEN
    1241          28 :             IF (spin == 1) &
    1242          14 :                n_el = n_el + 1
    1243             :          END IF
    1244             :       END IF
    1245             : 
    1246             :       ! Memory allocation (Use deallocate_mo_set to prevent accidental memory leaks)
    1247          40 :       CALL deallocate_mo_set(ec%block(id)%mo(spin))
    1248          40 :       CALL allocate_mo_set(ec%block(id)%mo(spin), n_ao, n_mo, n_el, REAL(n_el, dp), mx_occ, 0.0_dp)
    1249          40 :       mo => ec%block(id)%mo(spin)
    1250             : 
    1251             :       ! State energies
    1252         120 :       ALLOCATE (mo%eigenvalues(n_mo))
    1253          40 :       CPASSERT(ASSOCIATED(mo%eigenvalues))
    1254         896 :       mo%eigenvalues = vec_e
    1255             : 
    1256             :       ! States coefficients
    1257          40 :       CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
    1258             :       CALL cp_fm_struct_create(fmstruct=fm_s, para_env=para_env, context=blacs_env, &
    1259          40 :                                nrow_global=n_ao, ncol_global=n_mo)
    1260          40 :       ALLOCATE (mo%mo_coeff)
    1261          40 :       CALL cp_fm_create(matrix=mo%mo_coeff, matrix_struct=fm_s, name='BLOCK STATES')
    1262             : 
    1263             :       ! Transform MO coefficients to original non-orthogonal basis set
    1264          40 :       CALL set_mo_coefficients(qs_env, ec, id, mo, mat_u, n_ao, n_mo)
    1265             : 
    1266             :       ! Occupancies
    1267         120 :       ALLOCATE (mo%occupation_numbers(n_mo))
    1268          40 :       CPASSERT(ASSOCIATED(mo%occupation_numbers))
    1269         448 :       mo%occupation_numbers = 0.0_dp
    1270             : 
    1271          40 :       IF (n_el > 0) THEN
    1272          28 :          CALL get_qs_env(qs_env, scf_control=scf_cntrl)
    1273          28 :          CALL set_mo_occupation(mo_set=mo, smear=scf_cntrl%smear)
    1274             :       END IF
    1275             : 
    1276             :       ! Clean memory
    1277          40 :       CALL cp_fm_struct_release(fmstruct=fm_s)
    1278             : 
    1279          40 :    END SUBROUTINE create_block_mo_set
    1280             : 
    1281             : ! **************************************************************************************************
    1282             : !> \brief save given electronic state to cube files
    1283             : !> \param qs_env QuickStep environment containing all system data
    1284             : !> \param logger output logger
    1285             : !> \param input input-file block print setting section
    1286             : !> \param mo electronic states data
    1287             : !> \param ib block ID
    1288             : !> \param im state ID
    1289             : !> \param is spin ID
    1290             : !> \author Z. Futera (02.2017)
    1291             : ! **************************************************************************************************
    1292           0 :    SUBROUTINE save_mo_cube(qs_env, logger, input, mo, ib, im, is)
    1293             : 
    1294             :       ! Routine arguments
    1295             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1296             :       TYPE(cp_logger_type), POINTER                      :: logger
    1297             :       TYPE(section_vals_type), POINTER                   :: input
    1298             :       TYPE(mo_set_type), POINTER                         :: mo
    1299             :       INTEGER, INTENT(IN)                                :: ib, im, is
    1300             : 
    1301             :       CHARACTER(LEN=default_path_length)                 :: filename
    1302             :       CHARACTER(LEN=default_string_length)               :: title
    1303             :       INTEGER                                            :: unit_nr
    1304           0 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1305             :       TYPE(cell_type), POINTER                           :: cell
    1306             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1307             :       TYPE(particle_list_type), POINTER                  :: particles
    1308           0 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1309             :       TYPE(pw_c1d_gs_type)                               :: wf_g
    1310             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1311           0 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
    1312             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1313             :       TYPE(pw_r3d_rs_type)                               :: wf_r
    1314           0 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1315             :       TYPE(qs_subsys_type), POINTER                      :: subsys
    1316             : 
    1317             : ! Routine name for debug purposes
    1318             : 
    1319             :       ! Initialization
    1320           0 :       NULLIFY (particles)
    1321           0 :       NULLIFY (subsys)
    1322             : 
    1323           0 :       NULLIFY (pw_env)
    1324           0 :       NULLIFY (pw_pools)
    1325           0 :       NULLIFY (auxbas_pw_pool)
    1326             : 
    1327           0 :       NULLIFY (atomic_kind_set)
    1328           0 :       NULLIFY (cell)
    1329           0 :       NULLIFY (dft_control)
    1330           0 :       NULLIFY (particle_set)
    1331           0 :       NULLIFY (qs_kind_set)
    1332             : 
    1333             :       ! Name of the cube file
    1334           0 :       WRITE (filename, '(A4,I1.1,A1,I5.5,A1,I1.1)') 'BWF_', ib, '_', im, '_', is
    1335             :       ! Open the file
    1336             :       unit_nr = cp_print_key_unit_nr(logger, input, 'MO_CUBES', extension='.cube', &
    1337           0 :                                      middle_name=TRIM(filename), file_position='REWIND', log_filename=.FALSE.)
    1338             :       ! Title of the file
    1339           0 :       WRITE (title, *) 'WAVEFUNCTION ', im, ' block ', ib, ' spin ', is
    1340             : 
    1341             :       ! List of all atoms
    1342           0 :       CALL get_qs_env(qs_env, subsys=subsys)
    1343           0 :       CALL qs_subsys_get(subsys, particles=particles)
    1344             : 
    1345             :       ! Grids for wavefunction
    1346           0 :       CALL get_qs_env(qs_env, pw_env=pw_env)
    1347           0 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
    1348           0 :       CALL auxbas_pw_pool%create_pw(wf_r)
    1349           0 :       CALL auxbas_pw_pool%create_pw(wf_g)
    1350             : 
    1351             :       ! Calculate the grid values
    1352             :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
    1353           0 :                       cell=cell, dft_control=dft_control, particle_set=particle_set)
    1354             :       CALL calculate_wavefunction(mo%mo_coeff, im, wf_r, wf_g, atomic_kind_set, &
    1355           0 :                                   qs_kind_set, cell, dft_control, particle_set, pw_env)
    1356             :       CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, &
    1357           0 :                          stride=section_get_ivals(input, 'MO_CUBES%STRIDE'))
    1358             : 
    1359             :       ! Close file
    1360           0 :       CALL cp_print_key_finished_output(unit_nr, logger, input, 'MO_CUBES')
    1361             : 
    1362             :       ! Clean memory
    1363           0 :       CALL auxbas_pw_pool%give_back_pw(wf_r)
    1364           0 :       CALL auxbas_pw_pool%give_back_pw(wf_g)
    1365             : 
    1366           0 :    END SUBROUTINE save_mo_cube
    1367             : 
    1368             : ! **************************************************************************************************
    1369             : !> \brief save specified electronic states to cube files
    1370             : !> \param qs_env QuickStep environment containing all system data
    1371             : !> \param ec electronic coupling data structure
    1372             : !> \param n_spins number of spin states
    1373             : !> \author Z. Futera (02.2017)
    1374             : ! **************************************************************************************************
    1375          10 :    SUBROUTINE save_el_states(qs_env, ec, n_spins)
    1376             : 
    1377             :       ! Routine arguments
    1378             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1379             :       TYPE(et_cpl), POINTER                              :: ec
    1380             :       INTEGER, INTENT(IN)                                :: n_spins
    1381             : 
    1382             :       INTEGER                                            :: i, j, k, l, n
    1383          10 :       INTEGER, DIMENSION(:), POINTER                     :: list
    1384             :       TYPE(cp_logger_type), POINTER                      :: logger
    1385             :       TYPE(mo_set_type), POINTER                         :: mo
    1386             :       TYPE(section_vals_type), POINTER                   :: block_sec, mo_sec, print_sec
    1387             : 
    1388             : ! Routine name for debug purposes
    1389             : 
    1390          10 :       NULLIFY (logger)
    1391          10 :       NULLIFY (block_sec)
    1392          10 :       NULLIFY (print_sec)
    1393          10 :       NULLIFY (mo_sec)
    1394             : 
    1395             :       ! Output logger
    1396          20 :       logger => cp_get_default_logger()
    1397             :       block_sec => section_vals_get_subs_vals(qs_env%input, &
    1398          10 :                                               'PROPERTIES%ET_COUPLING%PROJECTION%BLOCK')
    1399             : 
    1400             :       ! Print states of all blocks
    1401          30 :       DO i = 1, ec%n_blocks
    1402             : 
    1403          20 :          print_sec => section_vals_get_subs_vals(block_sec, 'PRINT', i_rep_section=i)
    1404             : 
    1405             :          ! Check if the print input section is active
    1406          20 :          IF (BTEST(cp_print_key_should_output(logger%iter_info, &
    1407          10 :                                               print_sec, 'MO_CUBES'), cp_p_file)) THEN
    1408             : 
    1409           0 :             mo_sec => section_vals_get_subs_vals(print_sec, 'MO_CUBES')
    1410             : 
    1411             :             ! Spin states
    1412           0 :             DO j = 1, n_spins
    1413             : 
    1414           0 :                mo => ec%block(i)%mo(j)
    1415             : 
    1416           0 :                CALL section_vals_val_get(mo_sec, keyword_name='MO_LIST', n_rep_val=n)
    1417             : 
    1418             :                ! List of specific MOs
    1419           0 :                IF (n > 0) THEN
    1420             : 
    1421           0 :                   DO k = 1, n
    1422           0 :                      NULLIFY (list)
    1423             :                      CALL section_vals_val_get(mo_sec, keyword_name='MO_LIST', &
    1424           0 :                                                i_rep_val=k, i_vals=list)
    1425           0 :                      IF (ASSOCIATED(list)) THEN
    1426           0 :                         DO l = 1, SIZE(list)
    1427           0 :                            CALL save_mo_cube(qs_env, logger, print_sec, mo, i, list(l), j)
    1428             :                         END DO
    1429             :                      END IF
    1430             :                   END DO
    1431             : 
    1432             :                   ! Frontier MOs
    1433             :                ELSE
    1434             : 
    1435             :                   ! Occupied states
    1436           0 :                   CALL section_vals_val_get(mo_sec, keyword_name='NHOMO', i_val=n)
    1437             : 
    1438           0 :                   IF (n > 0) THEN
    1439           0 :                      DO k = MAX(1, mo%homo - n + 1), mo%homo
    1440           0 :                         CALL save_mo_cube(qs_env, logger, print_sec, mo, i, k, j)
    1441             :                      END DO
    1442             :                   END IF
    1443             : 
    1444             :                   ! Unoccupied states
    1445           0 :                   CALL section_vals_val_get(mo_sec, keyword_name='NLUMO', i_val=n)
    1446             : 
    1447           0 :                   IF (n > 0) THEN
    1448           0 :                      DO k = mo%lfomo, MIN(mo%lfomo + n - 1, mo%nmo)
    1449           0 :                         CALL save_mo_cube(qs_env, logger, print_sec, mo, i, k, j)
    1450             :                      END DO
    1451             :                   END IF
    1452             : 
    1453             :                END IF
    1454             : 
    1455             :             END DO
    1456             : 
    1457             :          END IF
    1458             : 
    1459             :       END DO
    1460             : 
    1461          10 :    END SUBROUTINE save_el_states
    1462             : 
    1463             : ! **************************************************************************************************
    1464             : !> \brief calculates the electron transfer coupling elements by projection-operator approach
    1465             : !>        Kondov et al. J.Phys.Chem.C 2007, 111, 11970-11981
    1466             : !> \param qs_env QuickStep environment containing all system data
    1467             : !> \author Z. Futera (02.2017)
    1468             : ! **************************************************************************************************
    1469          10 :    SUBROUTINE calc_et_coupling_proj(qs_env)
    1470             : 
    1471             :       ! Routine arguments
    1472             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1473             : 
    1474             :       INTEGER                                            :: i, j, k, n_ao, n_atoms, output_unit
    1475             :       LOGICAL                                            :: do_kp, master
    1476             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
    1477             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_s
    1478             :       TYPE(cp_fm_type)                                   :: mat_w
    1479          10 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: mat_h
    1480             :       TYPE(cp_logger_type), POINTER                      :: logger
    1481          10 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: ks, mo_der
    1482             :       TYPE(dft_control_type), POINTER                    :: dft_cntrl
    1483             :       TYPE(et_cpl), POINTER                              :: ec
    1484             :       TYPE(kpoint_type), POINTER                         :: kpoints
    1485          10 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mo
    1486             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1487          10 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1488             :       TYPE(scf_control_type), POINTER                    :: scf_control
    1489             :       TYPE(section_vals_type), POINTER                   :: et_proj_sec
    1490             : 
    1491             : ! Routine name for debug purposes
    1492             : 
    1493             :       ! Pointer initialization
    1494          10 :       NULLIFY (logger)
    1495             : 
    1496          10 :       NULLIFY (blacs_env)
    1497          10 :       NULLIFY (para_env)
    1498          10 :       NULLIFY (dft_cntrl)
    1499          10 :       NULLIFY (kpoints)
    1500          10 :       NULLIFY (qs_kind_set)
    1501             :       NULLIFY (et_proj_sec)
    1502             : 
    1503          10 :       NULLIFY (fm_s)
    1504          10 :       NULLIFY (ks, mo_der)
    1505             : 
    1506          10 :       NULLIFY (ec)
    1507             : 
    1508             :       ! Reference
    1509          10 :       CALL cite_reference(Futera2017)
    1510             : 
    1511             :       ! Stream for output to LOG file
    1512          10 :       logger => cp_get_default_logger()
    1513             : 
    1514          10 :       et_proj_sec => section_vals_get_subs_vals(qs_env%input, 'PROPERTIES%ET_COUPLING%PROJECTION')
    1515             : 
    1516             :       output_unit = cp_print_key_unit_nr(logger, et_proj_sec, &
    1517          10 :                                          'PROGRAM_RUN_INFO', extension='.log')
    1518             : 
    1519             :       ! Parallel calculation - master thread
    1520          10 :       master = .FALSE.
    1521          10 :       IF (output_unit > 0) &
    1522             :          master = .TRUE.
    1523             : 
    1524             :       ! Header
    1525             :       IF (master) THEN
    1526             :          WRITE (output_unit, '(/,T2,A)') &
    1527           5 :             '!-----------------------------------------------------------------------------!'
    1528             :          WRITE (output_unit, '(T17,A)') &
    1529           5 :             'Electronic coupling - Projection-operator method'
    1530             :       END IF
    1531             : 
    1532             :       ! Main data structure
    1533          10 :       ALLOCATE (ec)
    1534          10 :       CPASSERT(ASSOCIATED(ec))
    1535          10 :       CALL set_block_data(qs_env, et_proj_sec, ec)
    1536             : 
    1537             :       ! Number of atoms and AO functions
    1538          10 :       CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, natom=n_atoms)
    1539          10 :       CALL get_qs_kind_set(qs_kind_set, nsgf=n_ao)
    1540             : 
    1541             :       ! Print out info about system partitioning
    1542          10 :       IF (master) THEN
    1543             : 
    1544             :          WRITE (output_unit, '(/,T3,A,I10)') &
    1545           5 :             'Number of atoms                    = ', n_atoms
    1546             :          WRITE (output_unit, '(T3,A,I10)') &
    1547           5 :             'Number of fragments                = ', ec%n_blocks
    1548             :          WRITE (output_unit, '(T3,A,I10)') &
    1549           5 :             'Number of fragment atoms           = ', ec%n_atoms
    1550             :          WRITE (output_unit, '(T3,A,I10)') &
    1551           5 :             'Number of unassigned atoms         = ', n_atoms - ec%n_atoms
    1552             :          WRITE (output_unit, '(T3,A,I10)') &
    1553           5 :             'Number of AO basis functions       = ', n_ao
    1554             : 
    1555          15 :          DO i = 1, ec%n_blocks
    1556             : 
    1557             :             WRITE (output_unit, '(/,T3,A,I0,A)') &
    1558          10 :                'Block ', i, ':'
    1559             :             WRITE (output_unit, '(T3,A,I10)') &
    1560          10 :                'Number of block atoms              = ', ec%block(i)%n_atoms
    1561             :             WRITE (output_unit, '(T3,A,I10)') &
    1562          10 :                'Number of block electrons          = ', ec%block(i)%n_electrons
    1563             :             WRITE (output_unit, '(T3,A,I10)') &
    1564          10 :                'Number of block AO functions       = ', ec%block(i)%n_ao
    1565             : 
    1566          15 :             IF (ec%block(i)%n_atoms < 10) THEN
    1567             : 
    1568             :                WRITE (output_unit, '(T3,A,10I6)') &
    1569          10 :                   'Block atom IDs                     =     ', &
    1570          56 :                   (ec%block(i)%atom(j)%id, j=1, ec%block(i)%n_atoms)
    1571             : 
    1572             :             ELSE
    1573             : 
    1574           0 :                WRITE (output_unit, '(T3,A)') 'Block atom IDs                     ='
    1575           0 :                DO j = 1, ec%block(i)%n_atoms/10
    1576           0 :                   WRITE (output_unit, '(T3,A,10I6)') '      ', &
    1577           0 :                      (ec%block(i)%atom((j - 1)*10 + k)%id, k=1, 10)
    1578             :                END DO
    1579           0 :                IF (MOD(ec%block(i)%n_atoms, 10) /= 0) THEN
    1580           0 :                   WRITE (output_unit, '(T3,A,10I6)') '      ', &
    1581           0 :                      (ec%block(i)%atom(k + 10*(ec%block(i)%n_atoms/10))%id, &
    1582           0 :                       k=1, MOD(ec%block(i)%n_atoms, 10))
    1583             :                END IF
    1584             : 
    1585             :             END IF
    1586             : 
    1587             :          END DO
    1588             : 
    1589             :       END IF
    1590             : 
    1591             :       ! Full matrix data structure
    1592          10 :       CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
    1593             :       CALL cp_fm_struct_create(fmstruct=fm_s, para_env=para_env, context=blacs_env, &
    1594          10 :                                nrow_global=n_ao, ncol_global=n_ao)
    1595          10 :       CALL cp_fm_create(matrix=mat_w, matrix_struct=fm_s, name='FULL WORK MATRIX')
    1596             : 
    1597             :       ! Spin polarization / K-point sampling
    1598          10 :       CALL get_qs_env(qs_env, dft_control=dft_cntrl, do_kpoints=do_kp)
    1599          10 :       CALL get_qs_env(qs_env, mos=mo, matrix_ks=ks, mo_derivs=mo_der, scf_control=scf_control)
    1600          10 :       CALL make_mo_eig(mo, dft_cntrl%nspins, ks, scf_control, mo_der)
    1601             : 
    1602          10 :       IF (do_kp) THEN
    1603           0 :          CPABORT('ET_COUPLING not implemented with kpoints')
    1604             :       ELSE
    1605             :          !  no K-points
    1606          10 :          IF (master) &
    1607           5 :             WRITE (output_unit, '(T3,A)') 'No K-point sampling (Gamma point only)'
    1608             :       END IF
    1609             : 
    1610          10 :       IF (dft_cntrl%nspins == 2) THEN
    1611             : 
    1612          10 :          IF (master) &
    1613           5 :             WRITE (output_unit, '(/,T3,A)') 'Spin-polarized calculation'
    1614             : 
    1615             :          !<--- Open shell / No K-points ------------------------------------------------>!
    1616             : 
    1617             :          ! State eneries of the whole system
    1618          10 :          IF (mo(1)%nao /= mo(2)%nao) &
    1619           0 :             CPABORT('different number of alpha/beta AO basis functions')
    1620          10 :          IF (master) THEN
    1621             :             WRITE (output_unit, '(/,T3,A,I10)') &
    1622           5 :                'Number of AO basis functions       = ', mo(1)%nao
    1623             :             WRITE (output_unit, '(T3,A,I10)') &
    1624           5 :                'Number of alpha states             = ', mo(1)%nmo
    1625             :             WRITE (output_unit, '(T3,A,I10)') &
    1626           5 :                'Number of beta states              = ', mo(2)%nmo
    1627             :          END IF
    1628          10 :          CALL print_states(output_unit, mo, dft_cntrl%nspins, 'the whole system', fermi=.TRUE.)
    1629          10 :          CALL set_fermi(ec, mo(1)%mu, mo(2)%mu)
    1630             : 
    1631             :          ! KS Hamiltonian
    1632          10 :          CALL get_block_hamiltonian(qs_env, ec, fm_s, mat_h, mat_w, n_ao, dft_cntrl%nspins)
    1633             : 
    1634             :          ! Block diagonization
    1635          10 :          CALL hamiltonian_block_diag(qs_env, ec, mat_h)
    1636             : 
    1637             :          ! Print out energies and couplings
    1638          30 :          DO i = 1, ec%n_blocks
    1639          20 :             IF (output_unit > 0) THEN
    1640             :                CALL print_states(output_unit, ec%block(i)%mo, dft_cntrl%nspins, &
    1641             :                                  'block '//TRIM(ADJUSTL(cp_to_string(i)))//' states', &
    1642          10 :                                  mx_mo_a=mo(1)%nmo, mx_mo_b=mo(2)%nmo, fermi=.TRUE.)
    1643             :             END IF
    1644          30 :             CALL print_mo_coeff(output_unit, qs_env, ec, i, dft_cntrl%nspins)
    1645             :          END DO
    1646             : 
    1647          10 :          CALL print_couplings(et_proj_sec, output_unit, logger, ec, mo)
    1648             : 
    1649             :       ELSE
    1650             : 
    1651           0 :          IF (master) &
    1652           0 :             WRITE (output_unit, '(/,T3,A)') 'Spin-restricted calculation'
    1653             : 
    1654             :          !<--- Close shell / No K-points ----------------------------------------------->!
    1655             : 
    1656             :          ! State eneries of the whole system
    1657             :          IF (master) THEN
    1658             :             WRITE (output_unit, '(/,T3,A,I10)') &
    1659           0 :                'Number of AO basis functions       = ', mo(1)%nao
    1660             :             WRITE (output_unit, '(T3,A,I10)') &
    1661           0 :                'Number of states                   = ', mo(1)%nmo
    1662             :          END IF
    1663           0 :          CALL print_states(output_unit, mo, dft_cntrl%nspins, 'the whole system', fermi=.TRUE.)
    1664           0 :          CALL set_fermi(ec, mo(1)%mu)
    1665             : 
    1666             :          ! KS Hamiltonian
    1667           0 :          CALL get_block_hamiltonian(qs_env, ec, fm_s, mat_h, mat_w, n_ao, dft_cntrl%nspins)
    1668             : 
    1669             :          ! Block diagonization
    1670           0 :          CALL hamiltonian_block_diag(qs_env, ec, mat_h)
    1671             : 
    1672             :          ! Print out energies and couplings
    1673           0 :          DO i = 1, ec%n_blocks
    1674           0 :             IF (output_unit > 0) THEN
    1675             :                CALL print_states(output_unit, ec%block(i)%mo, dft_cntrl%nspins, &
    1676             :                                  'block '//TRIM(ADJUSTL(cp_to_string(i)))//' states', &
    1677           0 :                                  mx_mo_a=mo(1)%nmo, fermi=.TRUE.)
    1678             :             END IF
    1679           0 :             CALL print_mo_coeff(output_unit, qs_env, ec, i, dft_cntrl%nspins)
    1680             :          END DO
    1681             : 
    1682           0 :          CALL print_couplings(et_proj_sec, output_unit, logger, ec, mo)
    1683             : 
    1684             :       END IF
    1685             : 
    1686             :       ! Save electronic states
    1687          10 :       CALL save_el_states(qs_env, ec, dft_cntrl%nspins)
    1688             : 
    1689             :       ! Footer
    1690          10 :       IF (master) WRITE (output_unit, '(/,T2,A)') &
    1691           5 :          '!-----------------------------------------------------------------------------!'
    1692             : 
    1693             :       ! Clean memory
    1694          10 :       CALL cp_fm_struct_release(fmstruct=fm_s)
    1695          10 :       CALL cp_fm_release(matrix=mat_w)
    1696          10 :       IF (ALLOCATED(mat_h)) THEN
    1697          30 :          DO i = 1, SIZE(mat_h)
    1698          30 :             CALL cp_fm_release(matrix=mat_h(i))
    1699             :          END DO
    1700          10 :          DEALLOCATE (mat_h)
    1701             :       END IF
    1702          10 :       CALL release_ec_data(ec)
    1703             : 
    1704             :       ! Close output stream
    1705          10 :       CALL cp_print_key_finished_output(output_unit, logger, et_proj_sec, 'PROGRAM_RUN_INFO')
    1706             : 
    1707          20 :    END SUBROUTINE calc_et_coupling_proj
    1708             : 
    1709           0 : END MODULE et_coupling_proj

Generated by: LCOV version 1.15