26 const std::array<double, 3> &posK,
double cutoff,
double nu) {
27 using namespace autopas::utils::ArrayMath::literals;
30 const auto posIToPosJ = posI - posJ;
31 const auto posIToPosK = posI - posK;
32 const auto posJToPosK = posJ - posK;
44 if (distIJ > cutoff or distIK > cutoff or distJK > cutoff) {
55 const auto rrr = distIJ * distJK * distIK;
56 const auto rrr3 = rrr * rrr * rrr;
59 const auto potentialEnergy = nu * (3 * cosI * cosJ * cosK + 1.) / rrr3;
61 return potentialEnergy;
73constexpr std::array<std::array<double, 3>, 3>
calculateATForce(
const std::array<double, 3> &posI,
74 const std::array<double, 3> &posJ,
75 const std::array<double, 3> &posK,
double cutoff,
77 using namespace autopas::utils::ArrayMath::literals;
80 const auto posJToPosI = posJ - posI;
81 const auto posIToPosK = posI - posK;
82 const auto posKToPosJ = posK - posJ;
86 const auto distJI = autopas::utils::ConstexprMath::sqrt(distJISquared, 1e-16);
88 const auto distIK = autopas::utils::ConstexprMath::sqrt(distIKSquared, 1e-16);
90 const auto distKJ = autopas::utils::ConstexprMath::sqrt(distKJSquared, 1e-16);
94 if (distJI > cutoff or distIK > cutoff or distKJ > cutoff) {
95 return {std::array<double, 3>{0., 0., 0.}, std::array<double, 3>{0., 0., 0.}, std::array<double, 3>{0., 0., 0.}};
103 const double cos6 = cosI * cosJ * cosK;
104 const double distSquaredAll = distJI * distJI * distIK * distIK * distKJ * distKJ;
105 const double dist5All = distSquaredAll * distSquaredAll * std::sqrt(distSquaredAll);
107 auto forceI = std::array<double, 3>{0., 0., 0.};
108 auto forceJ = std::array<double, 3>{0., 0., 0.};
109 auto forceK = std::array<double, 3>{0., 0., 0.};
112 for (
size_t i = 0; i < 3; i++) {
113 forceI[i] = posIToPosK[i] * cosI * (cosJ - cosK) +
114 posJToPosI[i] * (cosJ * cosK - distKJSquared * distIKSquared + 5.0 * cos6 / distJISquared) +
115 posIToPosK[i] * (-cosJ * cosK + distJISquared * distKJSquared - 5.0 * cos6 / distIKSquared);
117 forceJ[i] = posIToPosK[i] * cosJ * (cosK - cosI) +
118 posKToPosJ[i] * (cosI * cosK - distJISquared * distIKSquared + 5.0 * cos6 / distKJSquared) +
119 posJToPosI[i] * (-cosI * cosK + distKJSquared * distIKSquared - 5.0 * cos6 / distJISquared);
121 forceK[i] = posJToPosI[i] * cosK * (cosI - cosJ) +
122 posIToPosK[i] * (cosI * cosJ - distJISquared * distKJSquared + 5.0 * cos6 / distIKSquared) +
123 posKToPosJ[i] * (-cosI * cosJ + distJISquared * distIKSquared - 5.0 * cos6 / distKJSquared);
125 forceI *= 3.0 * nu / dist5All;
126 forceJ *= 3.0 * nu / dist5All;
127 forceK *= 3.0 * nu / dist5All;
129 return {forceI, forceJ, forceK};
142 const std::array<double, 3> &posJ,
143 const std::array<double, 3> &posK,
double cutoff,
145 using namespace autopas::utils::ArrayMath::literals;
149 const auto forceI = forces[0];
150 const auto forceJ = forces[1];
151 const auto forceK = forces[2];
153 const auto virialI = forceI * posI;
154 const auto virialJ = forceJ * posJ;
155 const auto virialK = forceK * posK;
157 return {virialI, virialJ, virialK};
170 const std::array<double, 3> &posK,
double cutoff,
double nu) {
171 using namespace autopas::utils::ArrayMath::literals;
172 const auto [virialI, virialJ, virialK] =
calculateATVirials(posI, posJ, posK, cutoff, nu);
173 const auto virialSum = virialI + virialJ + virialK;
174 return virialSum[0] + virialSum[1] + virialSum[2];
188 const std::array<double, 3> &posJ,
189 const std::array<double, 3> &posK,
double cutoff,
191 using namespace autopas::utils::ArrayMath::literals;
192 const auto [virialI, virialJ, virialK] =
calculateATVirials(posI, posJ, posK, cutoff, nu);
193 const auto virialSumI = virialI[0] + virialI[1] + virialI[2];
194 const auto virialSumJ = virialJ[0] + virialJ[1] + virialJ[2];
195 const auto virialSumK = virialK[0] + virialK[1] + virialK[2];
196 return {virialSumI, virialSumJ, virialSumK};
constexpr std::array< std::array< double, 3 >, 3 > calculateATVirials(const std::array< double, 3 > &posI, const std::array< double, 3 > &posJ, const std::array< double, 3 > &posK, double cutoff, double nu)
Calculates the virial between three particles i,j,k from the Axilrod-Teller potential.
Definition: ATPotential.h:141
constexpr std::array< double, 3 > calculateATVirialTotalPerParticle(const std::array< double, 3 > &posI, const std::array< double, 3 > &posJ, const std::array< double, 3 > &posK, double cutoff, double nu)
Returns the sum of all components of the virial for each particle i, j, k individually using the Axil...
Definition: ATPotential.h:187
constexpr double calculateATVirialTotal(const std::array< double, 3 > &posI, const std::array< double, 3 > &posJ, const std::array< double, 3 > &posK, double cutoff, double nu)
Calculates the sum of all components of the virial between particle i, j, k using the Axilrod-Teller ...
Definition: ATPotential.h:169
constexpr double calculateATPotential(const std::array< double, 3 > &posI, const std::array< double, 3 > &posJ, const std::array< double, 3 > &posK, double cutoff, double nu)
Calculates the potential energy between particles i, j and k using the Axilrod Teller potential.
Definition: ATPotential.h:25
constexpr std::array< std::array< double, 3 >, 3 > calculateATForce(const std::array< double, 3 > &posI, const std::array< double, 3 > &posJ, const std::array< double, 3 > &posK, double cutoff, double nu)
Calculates the forces exerted on three particles using the Axilrod-Teller potential.
Definition: ATPotential.h:73
constexpr T dot(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Generates the dot product of two arrays.
Definition: ArrayMath.h:233