45 double exactexchange = 0.0;
48 std::vector<std::string> functional_names =
51 if (functional_names.size() > 2) {
52 throw std::runtime_error(
"Too many functional names");
53 }
else if (functional_names.size() < 1) {
54 throw std::runtime_error(
"Specify at least one functional");
57 for (
const std::string& functional_name : functional_names) {
59 int func_id = map.getID(functional_name);
65 if (xc_func_init(&func, func_id, XC_UNPOLARIZED) != 0) {
66 throw std::runtime_error(
67 (boost::format(
"Functional %s not found\n") % functional_name).str());
69 if (exactexchange > 0 && func.cam_alpha > 0) {
70 throw std::runtime_error(
71 "You have specified two functionals with exact exchange");
73 exactexchange += func.cam_alpha;
83 std::vector<std::string> strs =
86 use_separate_ =
false;
88 if (strs.size() == 1) {
89 xfunc_id = map.getID(strs[0]);
90 }
else if (strs.size() == 2) {
91 xfunc_id = map.getID(strs[0]);
92 cfunc_id = map.getID(strs[1]);
95 throw std::runtime_error(
96 "LIBXC. Please specify one combined or an exchange and a correlation "
100 if (xc_func_init(&xfunc, xfunc_id, XC_UNPOLARIZED) != 0) {
101 throw std::runtime_error(
102 (boost::format(
"Functional %s not found\n") % strs[0]).str());
104 if (xfunc.info->kind != 2 && !use_separate_) {
105 throw std::runtime_error(
106 "Your functional misses either correlation or exchange, please specify "
107 "another functional, separated by whitespace");
110 if (xc_func_init(&cfunc, cfunc_id, XC_UNPOLARIZED) != 0) {
111 throw std::runtime_error(
112 (boost::format(
"Functional %s not found\n") % strs[1]).str());
114 if ((xfunc.info->kind + cfunc.info->kind) != 1) {
115 throw std::runtime_error(
116 "Your functionals are not one exchange and one correlation");
124 double rho,
double sigma)
const {
127 switch (xfunc.info->family) {
129 xc_lda_exc_vxc(&xfunc, 1, &rho, &result.
f_xc, &result.
df_drho);
132 case XC_FAMILY_HYB_GGA:
133 xc_gga_exc_vxc(&xfunc, 1, &rho, &sigma, &result.
f_xc, &result.
df_drho,
140 switch (cfunc.info->family) {
142 xc_lda_exc_vxc(&cfunc, 1, &rho, &temp.
f_xc, &temp.
df_drho);
145 case XC_FAMILY_HYB_GGA:
146 xc_gga_exc_vxc(&cfunc, 1, &rho, &sigma, &temp.
f_xc, &temp.
df_drho,
160 const Eigen::MatrixXd& density_matrix)
const {
162 assert(density_matrix.isApprox(density_matrix.transpose()) &&
163 "Density matrix has to be symmetric!");
166#pragma omp parallel for schedule(guided) reduction(+ : vxc)
167 for (
Index i = 0; i < grid_.getBoxesSize(); ++i) {
172 double EXC_box = 0.0;
176 1.e-40 / double(density_matrix.rows()) / double(density_matrix.rows());
177 if (DMAT_here.cwiseAbs2().maxCoeff() < cutoff) {
180 Eigen::MatrixXd Vxc_here =
181 Eigen::MatrixXd::Zero(DMAT_here.rows(), DMAT_here.cols());
182 const std::vector<Eigen::Vector3d>& points = box.
getGridPoints();
188 Eigen::VectorXd temp = ao.
values.transpose() * DMAT_here;
189 double rho = 0.5 * temp.dot(ao.
values);
190 const double weight = weights[p];
191 if (rho * weight < 1.e-20) {
194 const Eigen::Vector3d rho_grad = temp.transpose() * ao.
derivatives;
197 EvaluateXC(rho, rho_grad.squaredNorm());
198 EXC_box += weight * rho * xc.
f_xc;
202 Vxc_here.noalias() += temp * ao.
values.transpose();