38 if (
ec != rhs.
getEc() )
return false;
41 if (
e1 != c.
e1)
return false;
42 if (
e2 != c.
e2)
return false;
48 if (
ec < rhs.
getEc() )
return true;
49 else if (
ec > rhs.
getEc() )
return false;
53 if (
e1 < c.
e1)
return true;
54 else if (
e1 > c.
e1)
return false;
55 if (
e2 < c.
e2)
return true;
56 else if (
e2 > c.
e2)
return false;
62 if (symmetryFunction->
getType() !=
type)
return false;
75 if (sf->
getEc() !=
ec )
return false;
76 if (sf->
getE1() !=
e1 )
return false;
77 if (sf->
getE2() !=
e2 )
return false;
80 throw runtime_error(
"ERROR: Unable to add symmetry function members "
81 "with different conversion factors.\n");
97 comparePointerTargets<SymFncCompAngn const>);
103 for (
size_t i = 0; i <
members.size(); i++)
107 mal.at(i) =
members[i]->getAngleLeft() * M_PI / 180.0;
108 mar.at(i) =
members[i]->getAngleRight() * M_PI / 180.0;
129#ifndef N2P2_NO_SF_CACHE
131 for (
size_t k = 0; k <
members.size(); ++k)
148 double* result =
new double[
members.size()];
149 double* radij =
new double[
members.size()];
150 double* dradij =
new double[
members.size()];
151 for (
size_t l = 0; l <
members.size(); ++l)
163 if (numNeighbors == 0) numNeighbors = 1;
165 for (
size_t j = 0; j < numNeighbors - 1; j++)
169 double const rij = nj.
d;
171 if ((
e1 == nej ||
e2 == nej) && rij < rmax && rij >
rmin)
175 for (
size_t l = 0; l <
members.size(); ++l)
177 if (rij >
mrl[l] && rij <
mrc[l])
180#ifndef N2P2_NO_SF_CACHE
181 if (
mci[l][nej].size() == 0)
187 double& crad = nj.
cache[
mci[l][nej][0]];
188 double& cdrad = nj.
cache[
mci[l][nej][1]];
202 double const*
const dr1 = nj.
dr.
r;
204 for (
size_t k = j + 1; k < numNeighbors; k++)
208 if ((
e1 == nej &&
e2 == nek) ||
209 (
e2 == nej &&
e1 == nek))
211 double const rik = nk.
d;
212 if (rik < rmax && rik >
rmin)
217 double const*
const dr2 = nk.
dr.
r;
218 double const dr30 = dr2[0] - dr1[0];
219 double const dr31 = dr2[1] - dr1[1];
220 double const dr32 = dr2[2] - dr1[2];
222 double rjk = dr30 * dr30
225 if ((rjk >= r2max) || (rjk <= r2min))
continue;
229 double const rinvijik = 1.0 / (rij * rik);
230 double const costijk = (dr1[0] * dr2[0] +
232 dr1[2] * dr2[2]) * rinvijik;
236 if (costijk <= -1.0 || costijk >= 1.0)
continue;
238 double const acostijk = acos(costijk);
240 double const rinvij = rinvijik * rik;
241 double const rinvik = rinvijik * rij;
242 double const rinvjk = 1.0 / rjk;
243 double const phiijik0 = rinvij
244 * (rinvik - rinvij * costijk);
245 double const phiikij0 = rinvik
246 * (rinvij - rinvik * costijk);
247 double dacostijk = 0.0;
250 dacostijk = -1.0 / sqrt(1.0 - costijk * costijk);
261 for (
size_t l = 0; l <
members.size(); ++l)
264 if (radij[l] == 0.0 ||
265 rik <=
mrl[l] || rik >=
mrc[l] ||
266 rjk <=
mrl[l] || rjk >=
mrc[l] ||
267 acostijk <=
mal[l] || acostijk >=
mar[l])
275#ifndef N2P2_NO_SF_CACHE
276 if (
mci[l][nek].size() == 0)
282 double& crad = nk.
cache[
mci[l][nek][0]];
283 double& cdrad = nk.
cache[
mci[l][nek][1]];
300 double rad = radij[l] * radik * radjk;
301 result[l] += rad * ang;
304 if (!derivatives)
continue;
307 double const phiijik = phiijik0 * dang;
308 double const phiikij = phiikij0 * dang;
309 double const psiijik = rinvijik * dang;
311 double const chiij = rinvij * dradij[l]
313 double const chiik = rinvik * radij[l]
315 double const chijk = -rinvjk * radij[l]
322 if (dang != 0.0 && rad != 0.0)
326 p1 = rad * phiijik + ang * chiij;
327 p2 = rad * phiikij + ang * chiik;
328 p3 = rad * psiijik + ang * chijk;
351 double const p1drijx = p1 * dr1[0];
352 double const p1drijy = p1 * dr1[1];
353 double const p1drijz = p1 * dr1[2];
355 double const p2drikx = p2 * dr2[0];
356 double const p2driky = p2 * dr2[1];
357 double const p2drikz = p2 * dr2[2];
359 double const p3drjkx = p3 * dr30;
360 double const p3drjky = p3 * dr31;
361 double const p3drjkz = p3 * dr32;
363#ifndef N2P2_FULL_SFD_MEMORY
368 double* dGdr = atom.
dGdr[li].r;
369 dGdr[0] += p1drijx + p2drikx;
370 dGdr[1] += p1drijy + p2driky;
371 dGdr[2] += p1drijz + p2drikz;
373#ifndef N2P2_FULL_SFD_MEMORY
376 dGdr = nj.
dGdr[li].r;
377 dGdr[0] -= p1drijx + p3drjkx;
378 dGdr[1] -= p1drijy + p3drjky;
379 dGdr[2] -= p1drijz + p3drjkz;
381#ifndef N2P2_FULL_SFD_MEMORY
384 dGdr = nk.
dGdr[li].r;
385 dGdr[0] -= p2drikx - p3drjkx;
386 dGdr[1] -= p2driky - p3drjky;
387 dGdr[2] -= p2drikz - p3drjkz;
395 for (
size_t l = 0; l <
members.size(); ++l)
std::size_t getE2() const
Get private e2 member variable.
std::size_t getE1() const
Get private e1 member variable.
void getCompactRadial(double const x, double &fx, double &dfx) const
void getCompactAngle(double const x, double &fx, double &dfx) const
double getRl() const
Get private rl member variable.
Narrow angular symmetry function with compact support (type 21)
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.
std::vector< std::vector< std::vector< std::size_t > > > mci
Member cache indices for actual neighbor element.
std::size_t e1
Element index of neighbor atom 1 (common feature).
std::vector< double > mrl
Member rl.
std::vector< double > mal
Member angleLeft.
std::size_t e2
Element index of neighbor atom 2 (common feature).
std::vector< double > mar
Member angleRight.
std::vector< bool > calculateComp
Vector indicating whether compact function needs to be recalculated.
std::vector< double > mrc
Member rc.
double rmin
Minimum radius within group.
double rmax
Maximum radius within group.
Narrow angular symmetry function with compact support (type 21)
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate all symmetry functions of this group for one atom.
virtual bool addMember(SymFnc const *const symmetryFunction)
Potentially add a member to group.
virtual void sortMembers()
Sort member symmetry functions.
virtual bool operator==(SymGrp const &rhs) const
Overload == operator.
virtual bool operator<(SymGrp const &rhs) const
Overload < operator.
std::vector< SymFncCompAngn const * > members
Vector of all group member pointers.
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.
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::vector< Vec3D > dGdr
Derivative of symmetry functions with respect to this atom's coordinates.
std::vector< double > G
Symmetry function values.
std::size_t numNeighbors
Total number of neighbors.
double r[3]
cartesian coordinates.