Callback Function Scheme¶
To use OpenRSP, users should also prepare different callback functions needed by OpenRSP. These callback functions will be invoked by OpenRSP during calculations to get integral matrices or expectation values of different one and twoelectron operators, exchangecorrelation functionals and nuclear contributions, or to solve the linear response equation. The callback functions are slightly different for C and Fortran users, which will be described separately in this chapter.
It should be noted that the arguments in the following callback functions are
over complete. For instance, from the knowledge of perturbations
(oper_num_pert
, oper_pert_labels
and oper_pert_orders
), the
dimension of integral matrices num_int
in the callback function
get_one_oper_mat()
can be computed.
Last but not least, users should be aware that:
 OpenRSP always ask for complex expectation values for different one and twoelectron operators, exchangecorrelation functionals and nuclear contributions, and these values are presented in memory that the real and imaginary parts of each value are consecutive. This affects:
 In order to reduce the use of temporary matrices and values, OpenRSP requires that calculated integral matrices and expectation values should be added to the returned argument. OpenRSP will zero the entries of these matrices and expectation values at first. This requirement affects the callback functions of one and twoelectron operators, exchangecorrelation functionals and nuclear contributions:
OpenRSP Callback Functions (C version)¶
Examples of C callback functions can be found in these files
tests/OpenRSP*Callback.c
. The detailed information of these callback
functions are given as follows.

void
get_pert_concatenation
(pert_label, first_cat_comp, num_cat_comps, num_sub_tuples, len_sub_tuples, user_ctx, rank_sub_comps)¶ User specified function for getting the ranks of components of subperturbation tuples (with the same perturbation label) for given components of the corresponding concatenated perturbation tuple, the last argument for the function
OpenRSPSetPerturbations()
.Parameters:  pert_label (const QcPertInt) – the perturbation label
 first_cat_comp (const QInt) – rank of the first component of the concatenated perturbation tuple
 num_cat_comps (const QInt) – number of components of the concatenated perturbation tuple
 num_sub_tuples (const QInt) – number of subperturbation tuples to construct the concatenated perturbation tuple
 len_sub_tuples (const QInt*) – length of each subperturbation tuple, size is
num_sub_tuples
; so that the length of the concatenated perturbation issum(len_sub_tuples)
 user_ctx (void*) – userdefined callback function context
Var rank_sub_comps: ranks of components of subperturbation tuples for the corresponding component of the concatenated perturbation tuple, i.e.
num_cat_comps
components starting from the one with rankfirst_cat_comp
, size is thereforenum_sub_tuples
\(\times\)num_cat_comps
, and arranged as[num_cat_comps][num_sub_tuples]
Vartype rank_sub_comps: QInt*
Return type: void
NOTE: get_pert_concatenation()
will not be invoked in the current
release so that users can use a “faked” function for it.

void
get_overlap_mat
(bra_num_pert, bra_pert_labels, bra_pert_orders, ket_num_pert, ket_pert_labels, ket_pert_orders, oper_num_pert, oper_pert_labels, oper_pert_orders, user_ctx, num_int, val_int)¶ Userspecified callback function to calculate integral matrices of overlap operator as well as its derivatives with respect to different perturbations, the second last argument for the function
OpenRSPSetOverlap()
.Parameters:  bra_num_pert (const QInt) – number of perturbations on the bra center
 bra_pert_labels (const QcPertInt*) – labels of perturbations on the bra center,
size is
bra_num_pert
 bra_pert_orders (const QInt*) – orders of perturbations on the bra center,
size is
bra_num_pert
 ket_num_pert (const QInt) – number of perturbations on the ket center
 ket_pert_labels (const QcPertInt*) – labels of perturbations on the ket center,
size is
ket_num_pert
 ket_pert_orders (const QInt*) – orders of perturbations on the ket center,
size is
ket_num_pert
 oper_num_pert (const QInt) – number of perturbations on the overlap operator [1]
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the overlap operator,
size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the overlap operator,
size is
oper_num_pert
[2]  user_ctx (void*) – userdefined callback function context
 num_int (const QInt) – number of the integral matrices, as the product of the sizes of perturbations on the bra, the ket and the overlap operator
Var val_int: the integral matrices to be added, size is
num_int
, and arranged as[oper_pert][bra_pert][ket_pert]
Vartype val_int: QcMat*[]
Return type: void
[1]  Here perturbations on the overlap operator represent those acting on the whole integral of the overlap operator, i.e. they can act on either the bra center or the ket center by applying the rule of derivatives of a product. 
[2]  Only overlap integrals perturbed on the bra and/or the ket, and those
perturbed on the whole integral are needed in the calculations. It means
that, OpenRSP will only ask for overlap integrals either with
perturbations on the bra and/or ket (oper_num_pert=0 ), or with
perturbations on the whole overlap integral (bra_num_pert=0 and
ket_num_pert=0 ). 

void
get_overlap_exp
(bra_num_pert, bra_pert_labels, bra_pert_orders, ket_num_pert, ket_pert_labels, ket_pert_orders, oper_num_pert, oper_pert_labels, oper_pert_orders, num_dmat, dens_mat, user_ctx, num_exp, val_exp)¶ Userspecified function for calculating expectation values of the overlap operator and its derivatives, the last argument for the function
OpenRSPSetOverlap()
.Parameters:  bra_num_pert (const QInt) – number of perturbations on the bra center
 bra_pert_labels (const QcPertInt*) – labels of perturbations on the bra center,
size is
bra_num_pert
 bra_pert_orders (const QInt*) – orders of perturbations on the bra center,
size is
bra_num_pert
 ket_num_pert (const QInt) – number of perturbations on the ket center
 ket_pert_labels (const QcPertInt*) – labels of perturbations on the ket center,
size is
ket_num_pert
 ket_pert_orders (const QInt*) – orders of perturbations on the ket center,
size is
ket_num_pert
 oper_num_pert (const QInt) – number of perturbations on the overlap operator [3]
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the overlap operator,
size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the overlap operator,
size is
oper_num_pert
 num_dmat (const QInt) – number of atomic orbital (AO) based density matrices
 dens_mat (QcMat*[]) – the AO based density matrices
 user_ctx (void*) – userdefined callback function context
 num_exp (const QInt) – number of the expectation values, as the product of sizes of
perturbations on the bra, the ket, the overlap operator and the number
of density matrices (
num_dmat
)
Var val_exp: the expectation values to be added, size is
2
\(\times\)num_exp
, and arranged as[num_dmat][oper_pert][bra_pert][ket_pert][2]
Vartype val_exp: QReal*
Return type: void
[3]  Similar to the callback function get_overlap_mat() , OpenRSP will
only ask for expectation values either with perturbations on the bra
and/or ket (oper_num_pert=0 ), or with perturbations on the whole
overlap integral (bra_num_pert=0 and ket_num_pert=0 ). 

void
get_one_oper_mat
(oper_num_pert, oper_pert_labels, oper_pert_orders, user_ctx, num_int, val_int)¶ Userspecified function for calculating integral matrices of the oneelectron operator and its derivatives, the second last argument for the function
OpenRSPAddOneOper()
.Parameters:  oper_num_pert (const QInt) – number of perturbations on the oneelectron operator
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the oneelectron
operator, size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the oneelectron
operator, size is
oper_num_pert
 user_ctx (void*) – userdefined callback function context
 num_int (const QInt) – number of the integral matrices, as the size of
perturbations that are specified by
oper_num_pert
,oper_pert_labels
andoper_pert_orders
Var val_int: the integral matrices to be added, size is
num_int
Vartype val_int: QcMat*[]
Return type: void

void
get_one_oper_exp
(oper_num_pert, oper_pert_labels, oper_pert_orders, num_dmat, dens_mat, user_ctx, num_exp, val_exp)¶ Userspecified callback function to calculate expectation values of oneelectron operator as well as its derivatives with respect to different perturbations, the last argument for the function
OpenRSPAddOneOper()
.Parameters:  oper_num_pert (const QInt) – number of perturbations on the oneelectron operator
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the oneelectron
operator, size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the oneelectron
operator, size is
oper_num_pert
 num_dmat (const QInt) – number of AO based density matrices
 dens_mat (QcMat*[]) – the AO based density matrices
 user_ctx (void*) – userdefined callback function context
 num_exp (const QInt) – number of expectation values, as the product of the size of
perturbations on the oneelectron operator (specified by
oper_num_pert
,oper_pert_labels
andoper_pert_orders
) and the number of density matrices (num_dmat
)
Var val_exp: the expectation values to be added, size is
2
\(\times\)num_exp
, and arranged as[num_dmat][oper_pert][2]
Vartype val_exp: QReal*
Return type: void

void
get_two_oper_mat
(oper_num_pert, oper_pert_labels, oper_pert_orders, num_dmat, dens_mat, user_ctx, num_int, val_int)¶ Userspecified function for calculating integral matrices of the twoelectron operator and its derivatives, the second last argument for the function
OpenRSPAddTwoOper()
.Parameters:  oper_num_pert (const QInt) – number of perturbations on the twoelectron operator
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the twoelectron
operator, size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the twoelectron
operator, size is
oper_num_pert
 num_dmat (const QInt) – number of AO based density matrices
 dens_mat (QcMat*[]) – the AO based density matrices (\(\boldsymbol{D}\))
for calculating
\(\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D})\),
where \(\texttt{perturbations}\) are specified by
oper_num_pert
,oper_pert_labels
andoper_pert_orders
.  user_ctx (void*) – userdefined callback function context
 num_int (const QInt) – number of the integral matrices, as the product of the size
of perturbations on the twoelectron operator (specified by
oper_num_pert
,oper_pert_labels
andoper_pert_orders
) and the number of AO based density matrices (num_dmat
)
Var val_int: the integral matrices to be added, size is
num_int
, and arranged as[num_dmat][oper_pert]
Vartype val_int: QcMat*[]
Return type: void

void
get_two_oper_exp
(oper_num_pert, oper_pert_labels, oper_pert_orders, dmat_len_tuple, num_LHS_dmat, LHS_dens_mat, num_RHS_dmat, RHS_dens_mat, user_ctx, num_exp, val_exp)¶ Userspecified callback function to calculate expectation values of twoelectron operator as well as its derivatives with respect to different perturbations, the last argument for the function
OpenRSPAddTwoOper()
.Parameters:  oper_num_pert (const QInt) – number of perturbations on the twoelectron operator
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the twoelectron
operator, size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the twoelectron
operator, size is
oper_num_pert
 dmat_len_tuple (const QInt) – length of different perturbation tuples of the
lefthandside (LHS) and righthandside (RHS) AO based density
matrices passed; for instance, if the LHS density matrices passed
are (\(\boldsymbol{D}\), \(\boldsymbol{D}^{a}\),
\(\boldsymbol{D}^{b}\), \(\boldsymbol{D}^{ab}\)), and the
RHS density matrices passed are (\(\boldsymbol{D}^{b}\),
\(\boldsymbol{D}^{c}\), \(\boldsymbol{D}^{bc}\),
\(\boldsymbol{D}^{d}\)), then
dmat_len_tuple
equals to 4, and that means we want to calculate \(\mathrm{Tr}[\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D})\boldsymbol{D}^{b}]\), \(\mathrm{Tr}[\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D}^{a})\boldsymbol{D}^{c}]\), \(\mathrm{Tr}[\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D}^{b})\boldsymbol{D}^{bc}]\), and \(\mathrm{Tr}[\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D}^{ab})\boldsymbol{D}^{d}]\), where \(\texttt{perturbations}\) are specified byoper_num_pert
,oper_pert_labels
andoper_pert_orders
.  num_LHS_dmat (const QInt*) – number of LHS AO based density matrices passed for
each LHS density matrix perturbation tuple, size is
dmat_len_tuple
; sticking with the above example,num_LHS_dmat
will be{1, N_a, N_b, N_ab}
whereN_a
,N_b
andN_ab
are respectively the numbers of density matrices for the density matrix perturbation tuplesa
,b
andab
 LHS_dens_mat (QcMat*[]) – the LHS AO based density matrices (\(\boldsymbol{D}_{\text{LHS}}\))
for calculating
\(\mathrm{Tr}[\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D}_{\text{LHS}})\boldsymbol{D}_{\text{RHS}}]\),
size is the sum of
num_LHS_dmat
 num_RHS_dmat (const QInt*) – number of RHS AO based density matrices passed for
each RHS density matrix perturbation tuple, size is
dmat_len_tuple
; sticking with the above example,num_RHS_dmat
will be{N_b, N_c, N_bc, N_d}
whereN_b
,N_c
N_bc
andN_d
are respectively the numbers of density matrices for the density matrix perturbation tuplesb
,c
,bc
andd
 RHS_dens_mat (QcMat*[]) – the RHS AO based density matrices (\(\boldsymbol{D}_{\text{RHS}}\))
for calculating
\(\mathrm{Tr}[\boldsymbol{G}^{\texttt{perturbations}}(\boldsymbol{D}_{\text{LHS}})\boldsymbol{D}_{\text{RHS}}]\),
size is the sum of
num_RHS_dmat
 user_ctx (void*) – userdefined callback function context
 num_exp (const QInt) – number of expectation values, as the product of the size
of perturbations on the twoelectron operator (specified by
oper_num_pert
,oper_pert_labels
andoper_pert_orders
) and the number of pairs of LHS and RHS density matrices, and the number of pairs of LHS and RHS density matrices can be computed as the dot product ofnum_LHS_dmat
andnum_RHS_dmat
Var val_exp: the expectation values to be added, size is
2
\(\times\)num_exp
, and arranged as[dmat_len_tuple][num_LHS_dmat][num_RHS_dmat][oper_pert][2]
Vartype val_exp: QReal*
Return type: void

void
get_xc_fun_mat
(xc_len_tuple, xc_pert_tuple, num_freq_configs, pert_freq_category, dmat_num_tuple, dmat_idx_tuple, num_dmat, dens_mat, user_ctx, num_int, val_int)¶ Userspecified function for calculating integral matrices of the XC functional and its derivatives, the second last argument for the function
OpenRSPAddXCFun()
.Parameters:  xc_len_tuple (const QInt) – length of the perturbation tuple on the XC functional
 xc_pert_tuple (const QcPertInt*) – perturbation tuple on the XC functional, size is
xc_len_tuple
 num_freq_configs (const QInt) – the number of different frequency configurations to
be considered for the perturbation tuple specified by
xc_pert_tuple
 pert_freq_category (const QInt*) – category of perturbation frequencies, size is
[num_freq_configs][xc_len_tuple]
. Take \(\mathcal{E}^{gfff}\) as an example, suppose we have four different frequency configurations: “0.0,0.0,0.0,0.0” (\(3N\times 10\) unique elements), “0.0,0.2,0.1,0.1” (\(3N\times 18\) unique elements), “0.0,0,3,0.1,0.2” (\(3N\times 27\) unique elements) and “0.0,0.1,0.1,0.0” (\(3N\times 27\) unique elements), thepert_freq_category
argument would then be(1,1,1,1, 1,2,3,3, 1,2,3,4, 1,2,3,1)
.  dmat_num_tuple (const QInt) – the number of different perturbation tuples of the
AO based density matrices passed; for instance, the complete density
matrix perturbation tuples (canonically ordered) for a property
\(\mathcal{E}^{abc}\) (i.e. the perturbation tuple
xc_pert_tuple
isabc
) are (\(\boldsymbol{D}\), \(\boldsymbol{D}^{a}\), \(\boldsymbol{D}^{b}\), \(\boldsymbol{D}^{ab}\), \(\boldsymbol{D}^{c}\), \(\boldsymbol{D}^{ac}\), \(\boldsymbol{D}^{bc}\)), and with the \((0,2)\) rule, the relevant density matrix perturbation tuples become (\(\boldsymbol{D}\), \(\boldsymbol{D}^{b}\), \(\boldsymbol{D}^{c}\), \(\boldsymbol{D}^{bc}\)) that gives thedmat_num_tuple
as 4  dmat_idx_tuple (const QInt*) – indices of the density matrix perturbation tuples
passed (canonically ordered), size is
dmat_num_tuple
; sticking with the above example, the density matrix perturbation tuples passed are (\(\boldsymbol{D}\), \(\boldsymbol{D}^{b}\), \(\boldsymbol{D}^{c}\), \(\boldsymbol{D}^{bc}\)) and their associated indicesdmat_idx_tuple
is{1, 3, 5, 7}
because these numbers correspond to the positions of the “\((k,n)\)surviving” perturbation tuples in the canonically ordered complete density matrix perturbation tuples  num_dmat (const QInt) – number of collected AO based density matrices for the
passed density matrix perturbation tuples (specified by
dmat_idx_tuple
) and all frequency configurations, that isnum_freq_configs
\(\times\sum_{\text{i}}N_{\text{i}}\), where \(N_{\text{i}}\) is the number of density matrices for the density matrix perturbation tupledmat_idx_tuple[i]
for a frequency configuration  dens_mat (QcMat*[]) – the collected AO based density matrices, size is
num_dmat
, and arranged as[num_freq_configs][dmat_idx_tuple]
 user_ctx (void*) – userdefined callback function context
 num_int (const QInt) – number of the integral matrices, equals to the product of
the size of perturbations on the XC functional (specified by the
perturbation tuple
xc_pert_tuple
) and the number of different frequency configurationsnum_freq_configs
Var val_int: the integral matrices to be added, size is
num_int
, and arranged as[num_freq_configs][xc_pert_tuple]
Vartype val_int: QcMat*[]
Return type: void

void
get_xc_fun_exp
(xc_len_tuple, xc_pert_tuple, num_freq_configs, pert_freq_category, dmat_num_tuple, dmat_idx_tuple, num_dmat, dens_mat, user_ctx, num_exp, val_exp)¶ Userspecified function for calculating expectation values of the XC functional and its derivatives, the last argument for the function
OpenRSPAddXCFun()
.Parameters:  xc_len_tuple (const QInt) – length of the perturbation tuple on the XC functional
 xc_pert_tuple (const QcPertInt*) – perturbation tuple on the XC functional, size is
xc_len_tuple
 num_freq_configs (const QInt) – the number of different frequency configurations to
be considered for the perturbation tuple specified by
xc_pert_tuple
 pert_freq_category (const QInt*) – category of perturbation frequencies, size is
[num_freq_configs][xc_len_tuple]
.  dmat_num_tuple (const QInt) – the number of different perturbation tuples of the AO based density matrices passed
 dmat_idx_tuple (const QInt*) – indices of the density matrix perturbation tuples
passed (canonically ordered), size is
dmat_num_tuple
 num_dmat (const QInt) – number of collected AO based density matrices for the
passed density matrix perturbation tuples (specified by
dmat_idx_tuple
) and all frequency configurations, that isnum_freq_configs
\(\times\sum_{\text{i}}N_{\text{i}}\), where \(N_{\text{i}}\) is the number of density matrices for the density matrix perturbation tupledmat_idx_tuple[i]
for a frequency configuration  dens_mat (QcMat*[]) – the collected AO based density matrices, size is
num_dmat
, and arranged as[num_freq_configs][dmat_idx_tuple]
 user_ctx (void*) – userdefined callback function context
 num_exp (const QInt) – number of the expectation values, equals to the product of
the size of perturbations on the XC functional (specified by the
perturbation tuple
xc_pert_tuple
) and the number of different frequency configurationsnum_freq_configs
Var val_exp: the expectation values to be added, size is
2
\(\times\)num_exp
, and arranged as[num_freq_configs][xc_pert_tuple][2]
Vartype val_exp: QReal*
Return type: void

void
get_zero_oper_contrib
(oper_num_pert, oper_pert_labels, oper_pert_orders, user_ctx, size_pert, val_oper)¶ Userspecified callback function to calculate contributions from the zeroelectron operator, the last argument for the function
OpenRSPAddZeroOper()
.Parameters:  oper_num_pert (const QInt) – number of perturbations on the zeroelectron operator
 oper_pert_labels (const QcPertInt*) – labels of perturbations on the zeroelectron operator,
size is
oper_num_pert
 oper_pert_orders (const QInt*) – orders of perturbations on the zeroelectron operator,
size is
oper_num_pert
 user_ctx (void*) – userdefined callback function context
 size_pert (const QInt) – size of the perturbations on the zeroelectron operator
Var val_oper: contributions from the zeroelectron operator to be added, arranged as
[size_pert][2]
Vartype val_oper: QReal*
Return type: void

void
get_linear_rsp_solution
(num_pert, num_comps, num_freq_sums, freq_sums, RHS_mat, user_ctx, rsp_param)¶ Userspecified callback function of linear response equation solver, the last argument for the function
OpenRSPSetLinearRSPSolver()
.Parameters:  num_pert (const QInt) – number of different perturbations on the right hand side of the linear response equation
 num_comps (const QInt*) – number of components of each perturbation, size is
num_pert
 num_freq_sums (const QInt*) – for each perturbation, number of complex frequency
sums on the left hand side of the linear response equation, size is
num_pert
 freq_sums (const QReal*) – the complex frequency sums on the left hand side of the
linear response equation, size is twice of the sum of
num_freq_sums
, the real and imaginary parts of each frequency sum are consecutive in memory  RHS_mat (QcMat*[]) – RHS matrices, size is the dot product of
num_comps
andnum_freq_sums
, and index ofnum_freq_sums
runs faster in memory  user_ctx (void*) – userdefined callback function context
Var rsp_param: solved response parameters, size is the dot product of
num_comps
andnum_freq_sums
, and index ofnum_freq_sums
runs faster in memoryVartype rsp_param: QcMat*[]
Return type: void
OpenRSP Callback Subroutines (Fortran version)¶
The callback subroutines of Fortran codes take almost the exact arguments as
the callback functions of C codes. One difference is the type convention
between C and Fortran, which has been discussed in Secion
Functions of OpenRSP API (Fortran version). Moreover, the pointers of basic types
(integer and real numbers) in the C codes should be converted to corresponding
array in Fortran. The array of QcMat
pointers should be converted to an
array of type(QcMat)
in Fortran. Last, the userdefined callback
function/subroutine context should be replaced by type(C_PTR)
.
We will develop Fortran unit testing in next release. For the time being, interested users can refer to LSDalton for examples of Fortran callback subroutines.