8 #ifndef SPARROW_PAIRWISEREPULSION_H
9 #define SPARROW_PAIRWISEREPULSION_H
33 void calculate(
const Eigen::Vector3d& R, Utils::DerivativeOrder order);
35 double getRepulsionEnergy()
const {
return repulsionEnergy_; }
37 Eigen::RowVector3d getRepulsionGradient()
const {
return repulsionGradient_; }
40 template <Utils::Derivative O> Utils::AutomaticDifferentiation::DerivativeType<O> getDerivative()
const;
42 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> calculateRepulsion(
double R)
const;
43 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> baseTerm(
double R)
const;
44 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> additionalTerm(
double R)
const;
45 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> gaussianRepulsionTerm(
double R)
const;
46 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> gaussianRepulsion(
const AtomicParameters& P,
double R)
const;
48 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> parenthesisValue(
double R)
const;
49 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> standardParenthesis(
double R)
const;
50 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> NHOHParenthesis(
double R)
const;
51 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> CCParenthesis(
double R)
const;
52 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> SiOParenthesis(
double R)
const;
56 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> radius(
double R)
const;
57 template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> integral(
double R)
const;
59 const double cOfAdditiveTerm;
60 const double exponentCoefficient;
61 const double furtherExponentCC;
62 const double distanceSiO;
63 const double factorCC;
64 const double factorSiO;
70 double repulsionEnergy_;
71 Eigen::RowVector3d repulsionGradient_;
76 template<Utils::DerivativeOrder O>
77 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::calculateRepulsion(
double R)
const {
78 return baseTerm<O>(R) + additionalTerm<O>(R) + gaussianRepulsionTerm<O>(R);
81 template<Utils::DerivativeOrder O>
82 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::baseTerm(
double R)
const {
83 auto ssssIntegral = integral<O>(R);
84 return pA_.coreCharge() * pB_.coreCharge() * ssssIntegral * parenthesisValue<O>(R);
87 template<Utils::DerivativeOrder O>
88 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::parenthesisValue(
double R)
const {
89 if ((pA_.element() == Utils::ElementType::H && (pB_.element() == Utils::ElementType::O || pB_.element() == Utils::ElementType::N ||
90 pB_.element() == Utils::ElementType::C)) ||
91 (pB_.element() == Utils::ElementType::H && (pA_.element() == Utils::ElementType::O || pA_.element() == Utils::ElementType::N ||
92 pA_.element() == Utils::ElementType::C)))
93 return NHOHParenthesis<O>(R);
94 if (pA_.element() == Utils::ElementType::C && pB_.element() == Utils::ElementType::C)
95 return CCParenthesis<O>(R);
96 if ((pA_.element() == Utils::ElementType::Si && pB_.element() == Utils::ElementType::O) ||
97 (pA_.element() == Utils::ElementType::O && pB_.element() == Utils::ElementType::Si))
98 return SiOParenthesis<O>(R);
100 return standardParenthesis<O>(R);
103 template<Utils::DerivativeOrder O>
104 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::additionalTerm(
double R)
const {
105 auto RD = radius<O>(R);
108 auto v = Utils::AutomaticDifferentiation::constant1D<O>(za13 + zb13);
111 auto v6 = v2 * v2 * v2;
112 return cOfAdditiveTerm * v6 * v6 / Utils::Constants::ev_per_hartree;
115 template<Utils::DerivativeOrder O>
116 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::gaussianRepulsionTerm(
double R)
const {
117 auto RD = radius<O>(R);
118 return (gaussianRepulsion<O>(pA_, R) + gaussianRepulsion<O>(pB_, R)) / RD *
119 (pA_.coreCharge() * pB_.coreCharge() / Utils::Constants::ev_per_hartree);
122 template<Utils::DerivativeOrder O>
123 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::gaussianRepulsion(
const AtomicParameters& P,
125 if (P.hasGaussianRepulsionParameters()) {
126 const auto& gaussianPar = P.getGaussianRepulsionParameters();
127 for (
unsigned int i = 0; i < gaussianPar.size(); i += 1) {
128 auto DistC = std::get<2>(gaussianPar[i]);
129 auto RmC = radius<O>(R) - DistC;
130 return std::get<0>(gaussianPar[i]) * exp(-std::get<1>(gaussianPar[i]) * RmC * RmC);
134 return Utils::AutomaticDifferentiation::constant1D<O>(0);
137 template<Utils::DerivativeOrder O>
138 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::standardParenthesis(
double R)
const {
139 auto RD = radius<O>(R);
141 auto R6 = R2 * R2 * R2;
143 return res + (2 * pAB_.x()) * exp(-pAB_.alpha() * (RD + exponentCoefficient * R6));
146 template<Utils::DerivativeOrder O>
147 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::NHOHParenthesis(
double R)
const {
148 auto RD = radius<O>(R);
150 return res + 2 * pAB_.x() * exp(-pAB_.alpha() * (RD * RD));
153 template<Utils::DerivativeOrder O>
154 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::CCParenthesis(
double R)
const {
155 return standardParenthesis<O>(R) + factorCC * exp(-furtherExponentCC * radius<O>(R));
158 template<Utils::DerivativeOrder O>
159 Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::SiOParenthesis(
double R)
const {
160 auto r1 = radius<O>(R) - distanceSiO;
161 return standardParenthesis<O>(R) + factorSiO * exp(-r1 * r1);
164 template<Utils::DerivativeOrder O>
165 inline Utils::AutomaticDifferentiation::Value1DType<O> PM6PairwiseRepulsion::radius(
double R)
const {
166 return Utils::AutomaticDifferentiation::variableWithUnitDerivative<O>(R);
170 inline Utils::AutomaticDifferentiation::Value1DType<Utils::DerivativeOrder::Zero>
171 PM6PairwiseRepulsion::integral<Utils::DerivativeOrder::Zero>(
double R)
const {
172 double pSum = pA_.pCore() + pB_.pCore();
173 double igr = 1.0 / std::sqrt(R * R + pSum * pSum);
177 inline Utils::AutomaticDifferentiation::Value1DType<Utils::DerivativeOrder::One>
178 PM6PairwiseRepulsion::integral<Utils::DerivativeOrder::One>(
double R)
const {
179 double pSum = pA_.pCore() + pB_.pCore();
180 double igr = 1.0 / std::sqrt(R * R + pSum * pSum);
181 Utils::AutomaticDifferentiation::First1D integralD(igr, -igr * igr * igr * R);
185 inline Utils::AutomaticDifferentiation::Value1DType<Utils::DerivativeOrder::Two>
186 PM6PairwiseRepulsion::integral<Utils::DerivativeOrder::Two>(
double R)
const {
187 double pSum = pA_.pCore() + pB_.pCore();
188 double igr = 1.0 / std::sqrt(R * R + pSum * pSum);
189 double igr3 = igr * igr * igr;
190 Utils::AutomaticDifferentiation::Second1D integralD(igr, -igr3 * R, igr3 * igr * igr * (2 * R * R - pSum * pSum));
194 inline Utils::AutomaticDifferentiation::DerivativeType<Utils::Derivative::First>
195 PM6PairwiseRepulsion::getDerivative<Utils::Derivative::First>()
const {
196 return getRepulsionGradient();
199 inline Utils::AutomaticDifferentiation::DerivativeType<Utils::Derivative::SecondAtomic>
200 PM6PairwiseRepulsion::getDerivative<Utils::Derivative::SecondAtomic>()
const {
201 return getRepulsionHessian();
204 inline Utils::AutomaticDifferentiation::DerivativeType<Utils::Derivative::SecondFull>
205 PM6PairwiseRepulsion::getDerivative<Utils::Derivative::SecondFull>()
const {
206 return getRepulsionHessian();
213 #endif // PAIRWISEREPULSION_H
Definition: PM6DiatomicParameters.h:23
Definition: PM6PairwiseRepulsion.h:29
static constexpr unsigned Z(const ElementType e) noexcept
Definition: AtomicParameters.h:29