votca 2024.1-dev
Loading...
Searching...
No Matches
vxc_potential.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20// Third party includes
21#include <boost/format.hpp>
22
23// VOTCA includes
25
26// Local VOTCA includes
28#include "votca/xtp/vxc_grid.h"
30
31namespace votca {
32namespace xtp {
33template <class Grid>
35 if (setXC_) {
36 xc_func_end(&xfunc);
37 if (use_separate_) {
38 xc_func_end(&cfunc);
39 }
40 }
41}
42template <class Grid>
43double Vxc_Potential<Grid>::getExactExchange(const std::string& functional) {
44
45 double exactexchange = 0.0;
47
48 std::vector<std::string> functional_names =
49 tools::Tokenizer(functional, " ").ToVector();
50
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");
55 }
56
57 for (const std::string& functional_name : functional_names) {
58
59 int func_id = map.getID(functional_name);
60 if (func_id < 0) {
61 exactexchange = 0.0;
62 break;
63 }
64 xc_func_type func;
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());
68 }
69 if (exactexchange > 0 && func.cam_alpha > 0) {
70 throw std::runtime_error(
71 "You have specified two functionals with exact exchange");
72 }
73 exactexchange += func.cam_alpha;
74 xc_func_end(&func);
75 }
76
77 return exactexchange;
78}
79template <class Grid>
80void Vxc_Potential<Grid>::setXCfunctional(const std::string& functional) {
81
83 std::vector<std::string> strs =
84 tools::Tokenizer(functional, " ,\n\t").ToVector();
85 xfunc_id = 0;
86 use_separate_ = false;
87 cfunc_id = 0;
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]);
93 use_separate_ = true;
94 } else {
95 throw std::runtime_error(
96 "LIBXC. Please specify one combined or an exchange and a correlation "
97 "functionals");
98 }
99
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());
103 }
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");
108 }
109 if (use_separate_) {
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());
113 }
114 if ((xfunc.info->kind + cfunc.info->kind) != 1) {
115 throw std::runtime_error(
116 "Your functionals are not one exchange and one correlation");
117 }
118 }
119 setXC_ = true;
120 return;
121}
122template <class Grid>
124 double rho, double sigma) const {
125
127 switch (xfunc.info->family) {
128 case XC_FAMILY_LDA:
129 xc_lda_exc_vxc(&xfunc, 1, &rho, &result.f_xc, &result.df_drho);
130 break;
131 case XC_FAMILY_GGA:
132 case XC_FAMILY_HYB_GGA:
133 xc_gga_exc_vxc(&xfunc, 1, &rho, &sigma, &result.f_xc, &result.df_drho,
134 &result.df_dsigma);
135 break;
136 }
137 if (use_separate_) {
138 typename Vxc_Potential<Grid>::XC_entry temp;
139 // via libxc correlation part only
140 switch (cfunc.info->family) {
141 case XC_FAMILY_LDA:
142 xc_lda_exc_vxc(&cfunc, 1, &rho, &temp.f_xc, &temp.df_drho);
143 break;
144 case XC_FAMILY_GGA:
145 case XC_FAMILY_HYB_GGA:
146 xc_gga_exc_vxc(&cfunc, 1, &rho, &sigma, &temp.f_xc, &temp.df_drho,
147 &temp.df_dsigma);
148 break;
149 }
150
151 result.f_xc += temp.f_xc;
152 result.df_drho += temp.df_drho;
153 result.df_dsigma += temp.df_dsigma;
154 }
155
156 return result;
157}
158template <class Grid>
160 const Eigen::MatrixXd& density_matrix) const {
161
162 assert(density_matrix.isApprox(density_matrix.transpose()) &&
163 "Density matrix has to be symmetric!");
164 Mat_p_Energy vxc = Mat_p_Energy(density_matrix.rows(), density_matrix.cols());
165
166#pragma omp parallel for schedule(guided) reduction(+ : vxc)
167 for (Index i = 0; i < grid_.getBoxesSize(); ++i) {
168 const GridBox& box = grid_[i];
169 if (!box.Matrixsize()) {
170 continue;
171 }
172 double EXC_box = 0.0;
173 // two because we have to use the density matrix and its transpose
174 const Eigen::MatrixXd DMAT_here = 2 * box.ReadFromBigMatrix(density_matrix);
175 double cutoff =
176 1.e-40 / double(density_matrix.rows()) / double(density_matrix.rows());
177 if (DMAT_here.cwiseAbs2().maxCoeff() < cutoff) {
178 continue;
179 }
180 Eigen::MatrixXd Vxc_here =
181 Eigen::MatrixXd::Zero(DMAT_here.rows(), DMAT_here.cols());
182 const std::vector<Eigen::Vector3d>& points = box.getGridPoints();
183 const std::vector<double>& weights = box.getGridWeights();
184
185 // iterate over gridpoints
186 for (Index p = 0; p < box.size(); p++) {
187 AOShell::AOValues ao = box.CalcAOValues(points[p]);
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) {
192 continue; // skip the rest, if density is very small
193 }
194 const Eigen::Vector3d rho_grad = temp.transpose() * ao.derivatives;
195
197 EvaluateXC(rho, rho_grad.squaredNorm());
198 EXC_box += weight * rho * xc.f_xc;
199 auto grad = ao.derivatives * rho_grad;
200 temp.noalias() =
201 weight * (0.5 * xc.df_drho * ao.values + 2.0 * xc.df_dsigma * grad);
202 Vxc_here.noalias() += temp * ao.values.transpose();
203 }
204 box.AddtoBigMatrix(vxc.matrix(), Vxc_here);
205 vxc.energy() += EXC_box;
206 }
207
208 return Mat_p_Energy(vxc.energy(), vxc.matrix() + vxc.matrix().transpose());
209}
210
211template class Vxc_Potential<Vxc_Grid>;
212
213} // namespace xtp
214} // namespace votca
break string into words
Definition tokenizer.h:72
std::vector< T > ToVector()
store all words in a vector of type T, does type conversion.
Definition tokenizer.h:109
const std::vector< Eigen::Vector3d > & getGridPoints() const
Definition gridbox.h:41
Eigen::MatrixXd ReadFromBigMatrix(const Eigen::MatrixXd &bigmatrix) const
Definition gridbox.cc:68
void AddtoBigMatrix(Eigen::MatrixXd &bigmatrix, const Eigen::MatrixXd &smallmatrix) const
Definition gridbox.cc:55
const std::vector< double > & getGridWeights() const
Definition gridbox.h:43
AOShell::AOValues CalcAOValues(const Eigen::Vector3d &point) const
Definition gridbox.cc:44
Index size() const
Definition gridbox.h:51
Index Matrixsize() const
Definition gridbox.h:55
Eigen::MatrixXd & matrix()
Definition eigen.h:80
double & energy()
Definition eigen.h:81
conversion of functional string into integer
XC_entry EvaluateXC(double rho, double sigma) const
Mat_p_Energy IntegrateVXC(const Eigen::MatrixXd &density_matrix) const
void setXCfunctional(const std::string &functional)
static double getExactExchange(const std::string &functional)
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
Eigen::MatrixX3d derivatives
Definition aoshell.h:131
double f_xc
double df_dsigma
double df_drho