Scine::Sparrow  5.0.0
Library for fast and agile quantum chemical calculations with semiempirical methods.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
MNDOPairwiseRepulsion.h
Go to the documentation of this file.
1 
8 #ifndef SPARROW_MNDOPAIRWISEREPULSION_H
9 #define SPARROW_MNDOPAIRWISEREPULSION_H
10 
13 #include <Utils/Constants.h>
16 #include <Utils/Typenames.h>
17 #include <Eigen/Core>
18 
19 namespace Scine {
20 namespace Utils {
21 enum class DerivativeOrder;
22 }
23 namespace Sparrow {
24 
25 namespace nddo {
26 
27 // clang-format off
32  public:
34 
35  void calculate(const Eigen::Ref<Eigen::Vector3d>& R, Utils::DerivativeOrder order);
36 
37  double getRepulsionEnergy() const { return repulsionEnergy_; }
38 
39  Eigen::RowVector3d getRepulsionGradient() const { return repulsionGradient_; }
40 
41  Utils::AutomaticDifferentiation::Second3D getRepulsionHessian() const { return repulsionHessian_; }
42  template <Utils::Derivative O> Utils::AutomaticDifferentiation::DerivativeType<O> getDerivative() const;
43 
44  template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> calculateRepulsion(double R) const;
45  template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> baseTerm(double R) const;
46  template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> parenthesisValue(double R) const;
47  template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> standardParenthesis(double R) const;
48 
49  private:
50  template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> radius(double R) const;
51  template <Utils::DerivativeOrder O> Utils::AutomaticDifferentiation::Value1DType<O> integral(double R) const;
52 
53  const AtomicParameters& pA_;
54  const AtomicParameters& pB_;
55 
56  double repulsionEnergy_;
57  Eigen::RowVector3d repulsionGradient_;
59 };
60 // clang-format on
61 
62 template<Utils::DerivativeOrder O>
63 Utils::AutomaticDifferentiation::Value1DType<O> MNDOPairwiseRepulsion::calculateRepulsion(double R) const {
64  return baseTerm<O>(R);
65 }
66 
67 template<Utils::DerivativeOrder O>
68 Utils::AutomaticDifferentiation::Value1DType<O> MNDOPairwiseRepulsion::baseTerm(double R) const {
69  auto ssssIntegral = integral<O>(R);
70  return pA_.coreCharge() * pB_.coreCharge() * ssssIntegral * parenthesisValue<O>(R);
71 }
72 
73 template<Utils::DerivativeOrder O>
74 Utils::AutomaticDifferentiation::Value1DType<O> MNDOPairwiseRepulsion::parenthesisValue(double R) const {
75  return standardParenthesis<O>(R);
76 }
77 
78 template<Utils::DerivativeOrder O>
79 Utils::AutomaticDifferentiation::Value1DType<O> MNDOPairwiseRepulsion::standardParenthesis(double R) const {
80  auto radiusDeriv = radius<O>(R);
81  auto res = 1.0;
82  if (pA_.element() == Utils::ElementType::H &&
83  (pB_.element() == Utils::ElementType::N || pB_.element() == Utils::ElementType::O)) {
84  return res + exp(-pA_.alpha() * radiusDeriv) +
85  radiusDeriv * Utils::Constants::angstrom_per_bohr * exp(-pB_.alpha() * radiusDeriv);
86  }
87  else if (pB_.element() == Utils::ElementType::H &&
88  (pA_.element() == Utils::ElementType::N || pA_.element() == Utils::ElementType::O)) {
89  return res + radiusDeriv * Utils::Constants::angstrom_per_bohr * exp(-pA_.alpha() * radiusDeriv) +
90  exp(-pB_.alpha() * radiusDeriv);
91  }
92  else {
93  return res + exp(-pA_.alpha() * radiusDeriv) + exp(-pB_.alpha() * radiusDeriv);
94  }
95 }
96 
97 template<Utils::DerivativeOrder O>
98 inline Utils::AutomaticDifferentiation::Value1DType<O> MNDOPairwiseRepulsion::radius(double R) const {
99  return Utils::AutomaticDifferentiation::variableWithUnitDerivative<O>(R);
100 }
101 
102 template<>
103 inline Utils::AutomaticDifferentiation::Value1DType<Utils::DerivativeOrder::Zero>
104 MNDOPairwiseRepulsion::integral<Utils::DerivativeOrder::Zero>(double R) const {
105  double pSum = pA_.pCore() + pB_.pCore();
106  double igr = 1.0 / std::sqrt(R * R + pSum * pSum);
107  return igr;
108 }
109 template<>
110 inline Utils::AutomaticDifferentiation::Value1DType<Utils::DerivativeOrder::One>
111 MNDOPairwiseRepulsion::integral<Utils::DerivativeOrder::One>(double R) const {
112  double pSum = pA_.pCore() + pB_.pCore();
113  double igr = 1.0 / std::sqrt(R * R + pSum * pSum);
114  Utils::AutomaticDifferentiation::First1D integralD(igr, -igr * igr * igr * R);
115  return integralD;
116 }
117 template<>
118 inline Utils::AutomaticDifferentiation::Value1DType<Utils::DerivativeOrder::Two>
119 MNDOPairwiseRepulsion::integral<Utils::DerivativeOrder::Two>(double R) const {
120  double pSum = pA_.pCore() + pB_.pCore();
121  double igr = 1.0 / std::sqrt(R * R + pSum * pSum);
122  double igr3 = igr * igr * igr;
123  Utils::AutomaticDifferentiation::Second1D integralD(igr, -igr3 * R, igr3 * igr * igr * (2 * R * R - pSum * pSum));
124  return integralD;
125 }
126 template<>
127 inline Utils::AutomaticDifferentiation::DerivativeType<Utils::Derivative::First>
128 MNDOPairwiseRepulsion::getDerivative<Utils::Derivative::First>() const {
129  return getRepulsionGradient();
130 }
131 template<>
132 inline Utils::AutomaticDifferentiation::DerivativeType<Utils::Derivative::SecondAtomic>
133 MNDOPairwiseRepulsion::getDerivative<Utils::Derivative::SecondAtomic>() const {
134  return getRepulsionHessian();
135 }
136 template<>
137 inline Utils::AutomaticDifferentiation::DerivativeType<Utils::Derivative::SecondFull>
138 MNDOPairwiseRepulsion::getDerivative<Utils::Derivative::SecondFull>() const {
139  return getRepulsionHessian();
140 }
141 
142 } // namespace nddo
143 
144 } // namespace Sparrow
145 } // namespace Scine
146 #endif // SPARROW_PAIRWISEREPULSION_H
This class calculates the core-core repulsion between two atoms.
Definition: MNDOPairwiseRepulsion.h:31
Definition: AtomicParameters.h:29