(git:be2ee82)
Loading...
Searching...
No Matches
qs_active_space_fci.F
Go to the documentation of this file.
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! **************************************************************************************************
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
21#if defined(__LIBFCI)
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
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
54CONTAINS
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 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 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eri_aa, eri_ab, eri_bb, fock_a, fock_b, &
79 p_beta
80
81 nmo_active = active_space_env%nmo_active
82 nspins = active_space_env%nspins
83 restricted_orbitals = active_space_env%restricted_orbitals
84 n2 = nmo_active*nmo_active
85 n4 = n2*n2
86 ionode = para_env%is_source()
87
88 ALLOCATE (fock_a(n2), eri_aa(n4), p_act_mo_a(n2))
89 ALLOCATE (fock_b(max(1, n2)), eri_ab(max(1, n4)), eri_bb(max(1, n4)), p_beta(max(1, n2)))
90 fock_b(:) = 0.0_dp
91 eri_ab(:) = 0.0_dp
92 eri_bb(:) = 0.0_dp
93 p_beta(:) = 0.0_dp
94
95 associate(act_indices => active_space_env%active_orbitals(:, 1))
96 CALL subspace_matrix_to_array(active_space_env%fock_sub(1), fock_a, act_indices, act_indices)
97 END associate
98 CALL eri_to_array(active_space_env%eri, eri_aa, active_space_env%active_orbitals, 1, 1)
99
100 IF (nspins == 2) THEN
101 IF (.NOT. PRESENT(p_act_mo_b)) THEN
102 cpabort("Missing beta output buffer for local active-space FCI solver.")
103 END IF
104 ALLOCATE (p_act_mo_b(n2))
105 associate(act_indices => active_space_env%active_orbitals(:, 2))
106 CALL subspace_matrix_to_array(active_space_env%fock_sub(2), fock_b(1:n2), act_indices, act_indices)
107 END associate
108 IF (restricted_orbitals) THEN
109 eri_ab(1:n4) = eri_aa
110 eri_bb(1:n4) = eri_aa
111 ELSE
112 CALL eri_to_array(active_space_env%eri, eri_ab(1:n4), active_space_env%active_orbitals, 1, 2)
113 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 status = 0
118 energy_active = 0.0_dp
119 error_text = ""
120 c_error(:) = c_null_char
121 ms2 = active_space_env%multiplicity - 1
122 max_iter = 2048
123 threshold = 1.0e-8_dp
124
125 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 energy_active, p_act_mo_a, p_beta, c_error, int(size(c_error), c_int))
131 error_text = c_string(c_error)
132 END IF
133
134 CALL para_env%bcast(status, para_env%source)
135 CALL para_env%bcast(error_text, para_env%source)
136 IF (status /= 0) THEN
137 IF (len_trim(error_text) > 0) THEN
138 cpabort("Local active-space FCI solver failed: "//trim(error_text))
139 ELSE
140 cpabort("Local active-space FCI solver failed.")
141 END IF
142 END IF
143
144 CALL para_env%bcast(energy_active, para_env%source)
145 CALL para_env%bcast(p_act_mo_a, para_env%source)
146 active_space_env%energy_active = energy_active
147 IF (nspins == 2) THEN
148 p_act_mo_b(:) = p_beta(1:n2)
149 CALL para_env%bcast(p_act_mo_b, para_env%source)
150 END IF
151
152 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 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 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 text = ""
178 DO i = 1, min(SIZE(buffer), len(text))
179 IF (buffer(i) == c_null_char) EXIT
180 text(i:i) = buffer(i)
181 END DO
182 END FUNCTION c_string
183#endif
184
185END MODULE qs_active_space_fci
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
Local FCI solver interface for active-space embedding.
subroutine, public solve_active_space_fci(active_space_env, para_env, p_act_mo_a, p_act_mo_b)
Solve the current active-space Hamiltonian with the local FCI kernel.
The types needed for the calculation of active space Hamiltonians.
Contains utility routines for the active space module.
subroutine, public eri_to_array(eri_env, array, active_orbitals, spin1, spin2)
Copy the eri tensor for spins isp1 and isp2 to a standard 1D Fortran array.
subroutine, public subspace_matrix_to_array(source_matrix, target_array, row_index, col_index)
Copy a (square portion) of a cp_fm_type matrix to a standard 1D Fortran array.
stores all the informations relevant to an mpi environment