LCOV - code coverage report
Current view: top level - src - et_coupling_proj.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 76.8 % 616 473
Test Date: 2025-07-25 12:55:17 Functions: 75.0 % 20 15

            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 2.0-1