Loading...
Searching...
No Matches
potential_base.hpp
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
12#pragma once
13
14#include <cassert>
15#include <cmath>
16
23namespace forcefields {
25public:
27 PotentialBase(double cutoff, double switchingWidth);
28 virtual ~PotentialBase() {};
29 double getCutoff() const;
30 void setCutoff(double cutoff);
31 double getSwitchingWidth() const;
32 void setSwitchingWidth(double width);
33 static double applyPeriodicity0(double r, double const period);
34 static void applyPeriodicity0(double r[], double const periods[]);
35
36protected:
37 //----------------------------------------Bond Pair
38 // interactions--------------------------------------------------
41 static double isoscelesBase(double length, double angle);
42 void restrainLength(const double R1[], const double R2[], double F1[],
43 double F2[], double &u, const double k, const double r0);
46
47 void restrainAngle(double const r1[], double const r2[], double const r3[],
48 double f1[], double f2[], double f3[], double &u,
49 const double k, const double aeq);
51 //----------------------------------------coulomb--------------------------------------------------
54 static const double ONE_OVER_4_PI_EPSILON0;
55 void calculateCentre(double const r1[], double const r2[], double rc[]);
56 void calculateCentre(double const r1[], double const r2[], double const r3[],
57 double rc[]);
58 void calculateWeightedCentre(double const w1, double const w2,
59 double const w3, double const r1[],
60 double const r2[], double const r3[],
61 double rc[]);
62 void coulombWithCutoff(const double r1[], const double r2[], double f1[],
63 double f2[], double &u, double const qq);
64 void coulomb(const double r1[], const double r2[], double f1[], double f2[],
65 double &u, double const qq);
66 void coulomb(double distance, double &force, double &energy, double const qq);
67 void spreadForce(double f1[], double f2[], double const fc[]);
68 void spreadForce(double f1[], double f2[], double f3[], double const fc[]);
69 void spreadWeightedForce(double const w1, double const w2, double const w3,
70 double f1[], double f2[], double f3[],
71 double const fc[]);
72 template <int N, class R = double (*const)[N], class F = double (*const)[N]>
73 struct ChargeGroup {
74 double const *const centre_;
77 };
78 template <int N, class R, class F>
80 template <int N, class R, class F>
82 double &energy, double cutoff, double switchingWidth);
83 //-------------------------------------------Lennard-Jones---------------------------------------------------------
86 static double epsilon(double const A, double const B);
87 void lennardJones(double const distance, double &force, double &energy,
88 double const epsilon, double const sigma);
89 void lennardJones(const double R1[], const double R2[], double F1[],
90 double F2[], double &E, double const epsilon,
91 double const sigma);
92 void lennardJonesWithCutoff(double const r1[], double const r2[], double f1[],
93 double f2[], double &energy, double const epsilon,
94 double const sigma);
95 static double sigma(double const A, double const B);
96 static double smithKongEpsilon(double sigma1, double epsilon1, double sigma2,
97 double epsilon2);
98 static double smithKongSigma(double sigma1, double epsilon1, double sigma2,
99 double epsilon2);
100 void switching(double const distance, double &force, double &energy);
101 void switching(double const r1[], double const r2[], double f1[], double f2[],
102 double &energy);
104 //------------------------------------Periodicity and
105 // distances---------------------------------------------
109 struct Vector3 {
110 double v[3];
111 double _1;
112 double _2;
113 };
114 double applyPeriodicity1(double r, int const axis);
115 void applyPeriodicity1(double r[]);
116 void distance(const double x[], const double y[], double z[], double &z1,
117 double &z2);
118 void distance(const double x[], const double y[], double z[], double &z1);
119 void distance(const double x[], const double y[], double z[]);
120 void distance(const double x[], const double y[], double &z1);
121 void distance(const double x[], const double y[], Vector3 &z);
122 void setPeriodicity(const double periods[]);
123 static double unBreak0(double const r, double const ref, double const period);
124 static void unBreak0(double r[], double const ref[], double const periods[]);
125 double unBreak1(double const r, double const ref, int const axis);
126 void unBreak1(double r[], double const ref[]);
128 //----------------------------------Common potential for platinum
129 //--------------------------------------
130 void computePt(int const nAtoms, double positions[], double forces[],
131 double &energy, double const periods[], bool const fixed[]);
132 static const double EPSILON_PT;
133 static const double SIGMA_PT;
134 //-----------------------------------------3D vector
135 // functions---------------------------------------------------
139 static inline void divide(double v[], double const divisor);
140 static inline double *crossProduct(const double v[], const double w[],
141 double e[]);
142 static inline double dotProduct(double const v[], double const w[]);
143 static inline void multiply(double v[], double const factor);
144 static inline double norm(double const v[]);
145 static inline void normalise(double v[]);
147 double cutoff_;
148 double periods_[3];
150};
151} // namespace forcefields
152
156template <int N, class R, class F>
161
162template <int N, class R, class F>
165 double &energy, double cutoff,
166 double switchingWidth) {
167 double z[3], z1;
168 distance(g1.centre_, g2.centre_, z, z1);
169 assert(z1 <= cutoff);
170 assert(z1 >= cutoff - switchingWidth);
171 double x = (z1 - cutoff + switchingWidth) / switchingWidth;
172 double S = (2 * x - 3) * x * x + 1;
173 double dS = 6 * x * (x - 1);
174 double const u = energy;
175 for (int i = 0; i < N; ++i) {
176 for (int k = 0; k < 3; ++k) {
177 g1.force_[i][k] =
178 g1.force_[i][k] * S - u * dS / switchingWidth * z[k] / z1 / N;
179 g2.force_[i][k] =
180 g2.force_[i][k] * S + u * dS / switchingWidth * z[k] / z1 / N;
181 }
182 };
183 energy *= S;
184}
185
193 const double w[], double e[]) {
194 e[0] = v[1] * w[2] - v[2] * w[1];
195 e[1] = v[2] * w[0] - v[0] * w[2];
196 e[2] = v[0] * w[1] - v[1] * w[0];
197 return e;
198}
199
204void forcefields::PotentialBase::divide(double v[], double const divisor) {
205 v[0] /= divisor;
206 v[1] /= divisor;
207 v[2] /= divisor;
208}
209
217 double const w[]) {
218 return v[0] * w[0] + v[1] * w[1] + v[2] * w[2];
219}
220
225void forcefields::PotentialBase::multiply(double v[], double const factor) {
226 v[0] *= factor;
227 v[1] *= factor;
228 v[2] *= factor;
229}
230
236double forcefields::PotentialBase::norm(double const v[]) {
237 return sqrt(dotProduct(v, v));
238}
239
245 double const n = norm(v);
246 divide(v, n);
247}
PotentialBase()
Non bond interaction cutoff.
static double sigma(double const A, double const B)
Conversion for Lennard-Jones.
void spreadWeightedForce(double const w1, double const w2, double const w3, double f1[], double f2[], double f3[], double const fc[])
Spread force on barycentre to atoms.
static double applyPeriodicity0(double r, double const period)
Minimum image representation.
double unBreak1(double const r, double const ref, int const axis)
Undo the separation of two atoms created by the periodic boundaries.
void switching(ChargeGroup< N, R, F > &g1, ChargeGroup< N, R, F > &g2, double &energy, double cutoff, double switchingWidth)
static double unBreak0(double const r, double const ref, double const period)
Undo the separation of two atoms created by the periodic boundaries.
void restrainLength(const double R1[], const double R2[], double F1[], double F2[], double &u, const double k, const double r0)
Compute quadratic restraints between two atoms.
void restrainAngle(double const r1[], double const r2[], double const r3[], double f1[], double f2[], double f3[], double &u, const double k, const double aeq)
Angular quadratic restraints.
static double smithKongSigma(double sigma1, double epsilon1, double sigma2, double epsilon2)
Smith and Kong combination rules.
void setCutoff(double cutoff)
void coulomb(const double r1[], const double r2[], double f1[], double f2[], double &u, double const qq)
Compute Coulomb interaction between two charges.
void lennardJones(double const distance, double &force, double &energy, double const epsilon, double const sigma)
Lennard-Jones 12-6 between two atoms.
void calculateCentre(double const r1[], double const r2[], double rc[])
Calculate centre of two points.
void setPeriodicity(const double periods[])
Set periodicity.
void distance(const double x[], const double y[], double z[], double &z1, double &z2)
Distance vector, norm and norm square.
void setSwitchingWidth(double width)
void lennardJonesWithCutoff(double const r1[], double const r2[], double f1[], double f2[], double &energy, double const epsilon, double const sigma)
Lennard Jones 12-6 Potential with cutoff.
void addForces(ChargeGroup< N, R, F > const &g1, ChargeGroup< N, R, F > &g2)
Increment forces.
static const double EPSILON_PT
Platinum Lennard-Jones.
double applyPeriodicity1(double r, int const axis)
Minimum image representation.
void computePt(int const nAtoms, double positions[], double forces[], double &energy, double const periods[], bool const fixed[])
Potential for Platinum.
static const double SIGMA_PT
static double smithKongEpsilon(double sigma1, double epsilon1, double sigma2, double epsilon2)
Smith and Kong combination rules.
static double epsilon(double const A, double const B)
Conversion for Lennard-Jones.
void spreadForce(double f1[], double f2[], double const fc[])
Spread force on centre to other points.
double getSwitchingWidth() const
Width of the switching zone.
void coulombWithCutoff(const double r1[], const double r2[], double f1[], double f2[], double &u, double const qq)
Coulomb interaction with single charge based cutoff.
static double isoscelesBase(double length, double angle)
Calculate the base of an isosceles triangle.
void calculateWeightedCentre(double const w1, double const w2, double const w3, double const r1[], double const r2[], double const r3[], double rc[])
Calculate barycentre.
static const double ONE_OVER_4_PI_EPSILON0
static double norm(double const v[])
Norm of 3D vector.
static void divide(double v[], double const divisor)
Divide vector.
static double dotProduct(double const v[], double const w[])
Dot product.
static void multiply(double v[], double const factor)
Multiply vector.
static double * crossProduct(const double v[], const double w[], double e[])
Cross product.
static void normalise(double v[])
Normalise 3D vector .
double _2
Vector's norm square.