30SymGrpExpAngn::SymGrpExpAngn(
ElementMap const& elementMap) :
37 if (
ec != rhs.
getEc() )
return false;
42 if (
rc != c.
rc )
return false;
43 if (
e1 != c.
e1 )
return false;
44 if (
e2 != c.
e2 )
return false;
50 if (
ec < rhs.
getEc() )
return true;
51 else if (
ec > rhs.
getEc() )
return false;
59 if (
rc < c.
rc )
return true;
60 else if (
rc > c.
rc )
return false;
61 if (
e1 < c.
e1 )
return true;
62 else if (
e1 > c.
e1 )
return false;
63 if (
e2 < c.
e2 )
return true;
64 else if (
e2 > c.
e2 )
return false;
70 if (symmetryFunction->
getType() !=
type)
return false;
93 if (sf->
getEc() !=
ec )
return false;
94 if (sf->
getRc() !=
rc )
return false;
95 if (sf->
getE1() !=
e1 )
return false;
96 if (sf->
getE2() !=
e2 )
return false;
99 throw runtime_error(
"ERROR: Unable to add symmetry function members "
100 "with different conversion factors.\n");
112 comparePointerTargets<SymFncExpAngn const>);
115 for (
size_t i = 0; i <
members.size(); i++)
158#ifndef N2P2_NO_SF_CACHE
161 auto cacheIndices =
members.at(0)->getCacheIndices();
163 double* result =
new double[
members.size()];
164 for (
size_t l = 0; l <
members.size(); ++l)
169 double const rc2 =
rc *
rc;
173 if (numNeighbors == 0) numNeighbors = 1;
175 for (
size_t j = 0; j < numNeighbors - 1; j++)
179 double const rij = nj.
d;
180 if ((
e1 == nej ||
e2 == nej) && rij <
rc)
182 double const r2ij = rij * rij;
187#ifndef N2P2_NO_SF_CACHE
188 if (cacheIndices[nej].size() == 0)
fc.
fdf(rij, pfcij, pdfcij);
191 double& cfc = nj.
cache[cacheIndices[nej][0]];
192 double& cdfc = nj.
cache[cacheIndices[nej][1]];
193 if (cfc < 0)
fc.
fdf(rij, cfc, cdfc);
198 fc.
fdf(rij, pfcij, pdfcij);
203 double const*
const dr1 = nj.
dr.
r;
205 for (
size_t k = j + 1; k < numNeighbors; k++)
209 if ((
e1 == nej &&
e2 == nek) ||
210 (
e2 == nej &&
e1 == nek))
212 double const rik = nk.
d;
219 double const*
const dr2 = nk.
dr.
r;
221 dr3[0] = dr2[0] - dr1[0];
222 dr3[1] = dr2[1] - dr1[1];
223 dr3[2] = dr2[2] - dr1[2];
224 double rjk = dr3[0] * dr3[0]
232#ifndef N2P2_NO_SF_CACHE
233 if (cacheIndices[nek].size() == 0)
235 fc.
fdf(rik, pfcik, pdfcik);
239 double& cfc = nk.
cache[cacheIndices[nek][0]];
240 double& cdfc = nk.
cache[cacheIndices[nek][1]];
241 if (cfc < 0)
fc.
fdf(rik, cfc, cdfc);
246 fc.
fdf(rik, pfcik, pdfcik);
252 fc.
fdf(rjk, pfcjk, pdfcjk);
258 double const rinvijik = 1.0 / rij / rik;
261 double const costijk = (dr1[0] * dr2[0] +
263 dr1[2] * dr2[2]) * rinvijik;
264 double const pfc = pfcij * pfcik * pfcjk;
265 double const r2ik = rik * rik;
266 double const r2sum = r2ij + r2ik + rjk * rjk;
267 double const pr1 = pfcik * pfcjk * pdfcij / rij;
268 double const pr2 = pfcij * pfcjk * pdfcik / rik;
269 double const pr3 = pfcij * pfcik * pdfcjk / rjk;
274 for (
size_t l = 0; l <
members.size(); ++l)
283 vexp = exp(-
eta[l] * (rijs * rijs
289 vexp = exp(-
eta[l] * r2sum);
292 double const plambda = 1.0
295 if (plambda <= 0.0) fg = 0.0;
304 fg *= pow(plambda,
zeta[l] - 1.0);
307 result[l] += fg * plambda * pfc;
310 if (!derivatives)
continue;
319 p1 = fg * (pfczl * (rinvijik
320 - costijk / r2ij - p2etapl
321 * rijs / rij) + pr1 * plambda);
322 p2 = fg * (pfczl * (rinvijik
323 - costijk / r2ik - p2etapl
324 * riks / rik) + pr2 * plambda);
325 p3 = fg * (pfczl * (rinvijik
326 + p2etapl * rjks / rjk)
331 p1 = fg * (pfczl * (rinvijik - costijk
332 / r2ij - p2etapl) + pr1 * plambda);
333 p2 = fg * (pfczl * (rinvijik - costijk
334 / r2ik - p2etapl) + pr2 * plambda);
335 p3 = fg * (pfczl * (rinvijik + p2etapl)
349 double const p1drijx = p1 * dr1[0];
350 double const p1drijy = p1 * dr1[1];
351 double const p1drijz = p1 * dr1[2];
353 double const p2drikx = p2 * dr2[0];
354 double const p2driky = p2 * dr2[1];
355 double const p2drikz = p2 * dr2[2];
357 double const p3drjkx = p3 * dr3[0];
358 double const p3drjky = p3 * dr3[1];
359 double const p3drjkz = p3 * dr3[2];
361#ifndef N2P2_FULL_SFD_MEMORY
366 double* dGdr = atom.
dGdr[li].r;
367 dGdr[0] += p1drijx + p2drikx;
368 dGdr[1] += p1drijy + p2driky;
369 dGdr[2] += p1drijz + p2drikz;
371#ifndef N2P2_FULL_SFD_MEMORY
374 dGdr = nj.
dGdr[li].r;
375 dGdr[0] -= p1drijx + p3drjkx;
376 dGdr[1] -= p1drijy + p3drjky;
377 dGdr[2] -= p1drijz + p3drjkz;
379#ifndef N2P2_FULL_SFD_MEMORY
382 dGdr = nk.
dGdr[li].r;
383 dGdr[0] -= p2drikx - p3drjkx;
384 dGdr[1] -= p2driky - p3drjky;
385 dGdr[2] -= p2drikz - p3drjkz;
394 for (
size_t l = 0; l <
members.size(); ++l)
void fdf(double r, double &fc, double &dfc) const
Calculate cutoff function and derivative .
void setCutoffParameter(double const alpha)
Set parameter for polynomial cutoff function (CT_POLY).
void setCutoffType(CutoffType const cutoffType)
Set cutoff type.
void setCutoffRadius(double const cutoffRadius)
Set cutoff radius.
std::string getSubtype() const
Get private subtype member variable.
double getCutoffAlpha() const
Get private cutoffAlpha member variable.
CutoffFunction::CutoffType getCutoffType() const
Get private cutoffType member variable.
std::size_t getE1() const
Get private e1 member variable.
std::size_t getE2() const
Get private e2 member variable.
Angular symmetry function (type 3)
Symmetry function base class.
double getConvLength() const
Get private convLength member variable.
double getRc() const
Get private rc member variable.
std::size_t getType() const
Get private type member variable.
std::size_t getEc() const
Get private ec member variable.
double cutoffAlpha
Cutoff function parameter (common feature).
std::string subtype
Subtype string (specifies cutoff type) (common feature).
CutoffFunction fc
Cutoff function used by this symmetry function group.
double rc
Cutoff radius (common feature).
CutoffFunction::CutoffType cutoffType
Cutoff type used by this symmetry function group (common feature).
std::vector< double > zeta
Vector containing values of all member symmetry functions.
std::vector< double > lambda
Vector containing values of all member symmetry functions.
std::vector< double > rs
Vector containing values of all member symmetry functions.
std::vector< double > factorNorm
Vector containing precalculated normalizing factor for each zeta.
std::vector< int > zetaInt
Vector containing values of all member symmetry functions.
std::vector< double > zetaLambda
Vector containing values of all member symmetry functions.
std::size_t e2
Element index of neighbor atom 2 (common feature).
std::vector< bool > calculateExp
Vector indicating whether exponential term needs to be calculated.
std::vector< double > eta
Vector containing values of all member symmetry functions.
std::vector< bool > useIntegerPow
Vector containing values of all member symmetry functions.
std::vector< double > factorDeriv
Vector containing precalculated normalizing factor for derivatives.
std::size_t e1
Element index of neighbor atom 1 (common feature).
Angular symmetry function group (type 3)
virtual bool operator==(SymGrp const &rhs) const
Overload == operator.
virtual void sortMembers()
Sort member symmetry functions.
virtual bool operator<(SymGrp const &rhs) const
Overload < operator.
std::vector< SymFncExpAngn const * > members
Vector of all group member pointers.
virtual bool addMember(SymFnc const *const symmetryFunction)
Potentially add a member to group.
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate all symmetry functions of this group for one atom.
std::size_t type
Symmetry function type.
std::size_t getType() const
Get private type member variable.
std::vector< size_t > memberIndex
Vector containing indices of all member symmetry functions.
std::size_t ec
Element index of center atom (common feature).
std::vector< std::vector< std::size_t > > memberIndexPerElement
Vector containing per-element indices of all member symmetry functions.
std::size_t getEc() const
Get private ec member variable.
double convLength
Data set normalization length conversion factor.
std::size_t getIndex() const
Get private index member variable.
std::vector< double > scalingFactors
Scaling factors of all member symmetry functions.
double pow_int(double x, int n)
Integer version of power function, "fast exponentiation algorithm".
Struct to store information on neighbor atoms.
std::vector< double > cache
Symmetry function cache (e.g. for cutoffs, compact functions).
std::size_t element
Element index of neighbor atom.
double d
Distance to neighbor atom.
Vec3D dr
Distance vector to neighbor atom.
std::vector< Vec3D > dGdr
Derivatives of symmetry functions with respect to neighbor coordinates.
Storage for a single atom.
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
std::size_t getStoredMinNumNeighbors(double const cutoffRadius) const
Return needed number of neighbors for a given cutoff radius from neighborCutoffs map.
std::vector< Vec3D > dGdr
Derivative of symmetry functions with respect to this atom's coordinates.
std::vector< double > G
Symmetry function values.
double r[3]
cartesian coordinates.