LCOV - code coverage report
Current view: top level - src - qs_active_space_fci.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:06f838d) Lines: 93.0 % 57 53
Test Date: 2026-06-05 07:04:50 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Local FCI solver interface for active-space embedding.
      10              : ! **************************************************************************************************
      11              : MODULE qs_active_space_fci
      12              : #if defined(__LIBFCI)
      13              :    USE ISO_C_BINDING, ONLY: C_CHAR, &
      14              :                             C_DOUBLE, &
      15              :                             C_INT, &
      16              :                             C_NULL_CHAR
      17              : #endif
      18              :    USE kinds, ONLY: dp
      19              :    USE message_passing, ONLY: mp_para_env_type
      20              :    USE qs_active_space_types, ONLY: active_space_type
      21              : #if defined(__LIBFCI)
      22              :    USE qs_active_space_utils, ONLY: eri_to_array, &
      23              :                                     subspace_matrix_to_array
      24              : #endif
      25              : #include "./base/base_uses.f90"
      26              : 
      27              :    IMPLICIT NONE
      28              :    PRIVATE
      29              : 
      30              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_active_space_fci'
      31              : 
      32              :    PUBLIC :: solve_active_space_fci
      33              : 
      34              : #if defined(__LIBFCI)
      35              :    INTERFACE
      36              :       FUNCTION libfci_solve(nspins, norb, nelec, ms2, h1_a, h1_b, eri_aa, eri_ab, eri_bb, &
      37              :                             max_iter, threshold, pspace, project_spin, verbose, energy, &
      38              :                             rdm1_a, rdm1_b, err_msg, err_msg_len) RESULT(status) &
      39              :          BIND(C, name="libfci_solve")
      40              :          IMPORT :: C_CHAR, C_DOUBLE, C_INT
      41              :          INTEGER(C_INT), VALUE                         :: nspins, norb, nelec, ms2
      42              :          REAL(C_DOUBLE), DIMENSION(*), INTENT(IN)      :: h1_a, h1_b, eri_aa, eri_ab, eri_bb
      43              :          INTEGER(C_INT), VALUE                         :: max_iter, pspace, project_spin, verbose
      44              :          REAL(C_DOUBLE), VALUE                         :: threshold
      45              :          REAL(C_DOUBLE), INTENT(OUT)                   :: energy
      46              :          REAL(C_DOUBLE), DIMENSION(*), INTENT(OUT)     :: rdm1_a, rdm1_b
      47              :          CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(OUT) :: err_msg
      48              :          INTEGER(C_INT), VALUE                         :: err_msg_len
      49              :          INTEGER(C_INT)                                :: status
      50              :       END FUNCTION libfci_solve
      51              :    END INTERFACE
      52              : #endif
      53              : 
      54              : CONTAINS
      55              : 
      56              : ! **************************************************************************************************
      57              : !> \brief Solve the current active-space Hamiltonian with the local FCI kernel.
      58              : !> \param active_space_env active-space environment
      59              : !> \param para_env parallel environment
      60              : !> \param p_act_mo_a alpha or spin-summed active-space 1-RDM
      61              : !> \param p_act_mo_b beta active-space 1-RDM for unrestricted calculations
      62              : ! **************************************************************************************************
      63            8 :    SUBROUTINE solve_active_space_fci(active_space_env, para_env, p_act_mo_a, p_act_mo_b)
      64              :       TYPE(active_space_type), INTENT(INOUT), POINTER    :: active_space_env
      65              :       TYPE(mp_para_env_type), INTENT(IN), POINTER        :: para_env
      66              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
      67              :          INTENT(OUT)                                     :: p_act_mo_a
      68              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
      69              :          INTENT(OUT), OPTIONAL                           :: p_act_mo_b
      70              : 
      71              : #if defined(__LIBFCI)
      72              :       CHARACTER(KIND=C_CHAR), DIMENSION(512)             :: c_error
      73              :       CHARACTER(LEN=512)                                 :: error_text
      74              :       INTEGER                                            :: max_iter, ms2, n2, n4, nmo_active, &
      75              :                                                             nspins, status
      76              :       LOGICAL                                            :: ionode, restricted_orbitals
      77              :       REAL(KIND=dp)                                      :: energy_active, threshold
      78            8 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eri_aa, eri_ab, eri_bb, fock_a, fock_b, &
      79            8 :                                                             p_beta
      80              : 
      81            8 :       nmo_active = active_space_env%nmo_active
      82            8 :       nspins = active_space_env%nspins
      83            8 :       restricted_orbitals = active_space_env%restricted_orbitals
      84            8 :       n2 = nmo_active*nmo_active
      85            8 :       n4 = n2*n2
      86            8 :       ionode = para_env%is_source()
      87              : 
      88           48 :       ALLOCATE (fock_a(n2), eri_aa(n4), p_act_mo_a(n2))
      89           56 :       ALLOCATE (fock_b(MAX(1, n2)), eri_ab(MAX(1, n4)), eri_bb(MAX(1, n4)), p_beta(MAX(1, n2)))
      90            8 :       fock_b(:) = 0.0_dp
      91            8 :       eri_ab(:) = 0.0_dp
      92            8 :       eri_bb(:) = 0.0_dp
      93            8 :       p_beta(:) = 0.0_dp
      94              : 
      95              :       ASSOCIATE (act_indices => active_space_env%active_orbitals(:, 1))
      96            8 :          CALL subspace_matrix_to_array(active_space_env%fock_sub(1), fock_a, act_indices, act_indices)
      97              :       END ASSOCIATE
      98            8 :       CALL eri_to_array(active_space_env%eri, eri_aa, active_space_env%active_orbitals, 1, 1)
      99              : 
     100            8 :       IF (nspins == 2) THEN
     101            6 :          IF (.NOT. PRESENT(p_act_mo_b)) THEN
     102            0 :             CPABORT("Missing beta output buffer for local active-space FCI solver.")
     103              :          END IF
     104           12 :          ALLOCATE (p_act_mo_b(n2))
     105              :          ASSOCIATE (act_indices => active_space_env%active_orbitals(:, 2))
     106            6 :             CALL subspace_matrix_to_array(active_space_env%fock_sub(2), fock_b(1:n2), act_indices, act_indices)
     107              :          END ASSOCIATE
     108            6 :          IF (restricted_orbitals) THEN
     109           34 :             eri_ab(1:n4) = eri_aa
     110           34 :             eri_bb(1:n4) = eri_aa
     111              :          ELSE
     112            4 :             CALL eri_to_array(active_space_env%eri, eri_ab(1:n4), active_space_env%active_orbitals, 1, 2)
     113            4 :             CALL eri_to_array(active_space_env%eri, eri_bb(1:n4), active_space_env%active_orbitals, 2, 2)
     114              :          END IF
     115              :       END IF
     116              : 
     117            8 :       status = 0
     118            8 :       energy_active = 0.0_dp
     119            8 :       error_text = ""
     120         4104 :       c_error(:) = C_NULL_CHAR
     121            8 :       ms2 = active_space_env%multiplicity - 1
     122            8 :       max_iter = 2048
     123            8 :       threshold = 1.0E-8_dp
     124              : 
     125            8 :       IF (ionode) THEN
     126              :          status = libfci_solve(INT(nspins, C_INT), INT(nmo_active, C_INT), &
     127              :                                INT(active_space_env%nelec_active, C_INT), INT(ms2, C_INT), &
     128              :                                fock_a, fock_b, eri_aa, eri_ab, eri_bb, INT(max_iter, C_INT), &
     129              :                                REAL(threshold, C_DOUBLE), INT(200, C_INT), INT(1, C_INT), INT(0, C_INT), &
     130            4 :                                energy_active, p_act_mo_a, p_beta, c_error, INT(SIZE(c_error), C_INT))
     131            4 :          error_text = c_string(c_error)
     132              :       END IF
     133              : 
     134            8 :       CALL para_env%bcast(status, para_env%source)
     135            8 :       CALL para_env%bcast(error_text, para_env%source)
     136            8 :       IF (status /= 0) THEN
     137            0 :          IF (LEN_TRIM(error_text) > 0) THEN
     138            0 :             CPABORT("Local active-space FCI solver failed: "//TRIM(error_text))
     139              :          ELSE
     140            0 :             CPABORT("Local active-space FCI solver failed.")
     141              :          END IF
     142              :       END IF
     143              : 
     144            8 :       CALL para_env%bcast(energy_active, para_env%source)
     145            8 :       CALL para_env%bcast(p_act_mo_a, para_env%source)
     146            8 :       active_space_env%energy_active = energy_active
     147            8 :       IF (nspins == 2) THEN
     148           30 :          p_act_mo_b(:) = p_beta(1:n2)
     149            6 :          CALL para_env%bcast(p_act_mo_b, para_env%source)
     150              :       END IF
     151              : 
     152            8 :       DEALLOCATE (fock_a, fock_b, eri_aa, eri_ab, eri_bb, p_beta)
     153              : #else
     154              :       MARK_USED(active_space_env)
     155              :       MARK_USED(para_env)
     156              :       MARK_USED(p_act_mo_a)
     157              :       IF (PRESENT(p_act_mo_b)) THEN
     158              :          MARK_USED(p_act_mo_b)
     159              :       END IF
     160              :       CPABORT("AS_SOLVER FCI requires CP2K to be built with LibFCI support.")
     161              : #endif
     162              : 
     163            8 :    END SUBROUTINE solve_active_space_fci
     164              : 
     165              : #if defined(__LIBFCI)
     166              : ! **************************************************************************************************
     167              : !> \brief Convert a C null-terminated string buffer to a Fortran string.
     168              : !> \param buffer ...
     169              : !> \return ...
     170              : ! **************************************************************************************************
     171            4 :    FUNCTION c_string(buffer) RESULT(text)
     172              :       CHARACTER(KIND=C_CHAR), DIMENSION(:), INTENT(IN)   :: buffer
     173              :       CHARACTER(LEN=512)                                 :: text
     174              : 
     175              :       INTEGER                                            :: i
     176              : 
     177            4 :       text = ""
     178            4 :       DO i = 1, MIN(SIZE(buffer), LEN(text))
     179            4 :          IF (buffer(i) == C_NULL_CHAR) EXIT
     180            4 :          text(i:i) = buffer(i)
     181              :       END DO
     182            4 :    END FUNCTION c_string
     183              : #endif
     184              : 
     185              : END MODULE qs_active_space_fci
        

Generated by: LCOV version 2.0-1