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<SymFncCompAngw 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;
114#ifndef N2P2_NO_SF_CACHE
116 for (
size_t k = 0; k <
members.size(); ++k)
136 double* result =
new double[
members.size()];
137 double* radij =
new double[
members.size()];
138 double* dradij =
new double[
members.size()];
139 for (
size_t l = 0; l <
members.size(); ++l)
148 if (numNeighbors == 0) numNeighbors = 1;
150 for (
size_t j = 0; j < numNeighbors - 1; j++)
154 double const rij = nj.
d;
156 if ((
e1 == nej ||
e2 == nej) && rij < rmax && rij >
rmin)
160 for (
size_t l = 0; l <
members.size(); ++l)
162 if (rij >
mrl[l] && rij <
mrc[l])
165#ifndef N2P2_NO_SF_CACHE
166 if (
mci[l][nej].size() == 0)
172 double& crad = nj.
cache[
mci[l][nej][0]];
173 double& cdrad = nj.
cache[
mci[l][nej][1]];
187 double const*
const dr1 = nj.
dr.
r;
189 for (
size_t k = j + 1; k < numNeighbors; k++)
193 if ((
e1 == nej &&
e2 == nek) ||
194 (
e2 == nej &&
e1 == nek))
196 double const rik = nk.
d;
197 if (rik < rmax && rik >
rmin)
202 double const*
const dr2 = nk.
dr.
r;
203 double const dr30 = dr2[0] - dr1[0];
204 double const dr31 = dr2[1] - dr1[1];
205 double const dr32 = dr2[2] - dr1[2];
208 double const rinvijik = 1.0 / (rij * rik);
209 double const costijk = (dr1[0] * dr2[0] +
211 dr1[2] * dr2[2]) * rinvijik;
215 if (costijk <= -1.0 || costijk >= 1.0)
continue;
217 double const acostijk = acos(costijk);
219 double const rinvij = rinvijik * rik;
220 double const rinvik = rinvijik * rij;
221 double const phiijik0 = rinvij
222 * (rinvik - rinvij * costijk);
223 double const phiikij0 = rinvik
224 * (rinvij - rinvik * costijk);
225 double dacostijk = 0.0;
228 dacostijk = -1.0 / sqrt(1.0 - costijk * costijk);
236 for (
size_t l = 0; l <
members.size(); ++l)
239 if (radij[l] == 0.0 ||
240 rik <=
mrl[l] || rik >=
mrc[l] ||
241 acostijk <=
mal[l] || acostijk >=
mar[l])
247#ifndef N2P2_NO_SF_CACHE
248 if (
mci[l][nek].size() == 0)
254 double& crad = nk.
cache[
mci[l][nek][0]];
255 double& cdrad = nk.
cache[
mci[l][nek][1]];
265 double rad = radij[l] * radik;
266 result[l] += rad * ang;
269 if (!derivatives)
continue;
272 double const phiijik = phiijik0 * dang;
273 double const phiikij = phiikij0 * dang;
274 double const psiijik = rinvijik * dang;
276 double const chiij = rinvij * radik * dradij[l];
277 double const chiik = rinvik * radij[l] * dradik;
283 if (dang != 0.0 && rad != 0.0)
287 p1 = rad * phiijik + ang * chiij;
288 p2 = rad * phiikij + ang * chiik;
312 double const p1drijx = p1 * dr1[0];
313 double const p1drijy = p1 * dr1[1];
314 double const p1drijz = p1 * dr1[2];
316 double const p2drikx = p2 * dr2[0];
317 double const p2driky = p2 * dr2[1];
318 double const p2drikz = p2 * dr2[2];
320 double const p3drjkx = p3 * dr30;
321 double const p3drjky = p3 * dr31;
322 double const p3drjkz = p3 * dr32;
324#ifndef N2P2_FULL_SFD_MEMORY
329 double* dGdr = atom.
dGdr[li].r;
330 dGdr[0] += p1drijx + p2drikx;
331 dGdr[1] += p1drijy + p2driky;
332 dGdr[2] += p1drijz + p2drikz;
334#ifndef N2P2_FULL_SFD_MEMORY
337 dGdr = nj.
dGdr[li].r;
338 dGdr[0] -= p1drijx + p3drjkx;
339 dGdr[1] -= p1drijy + p3drjky;
340 dGdr[2] -= p1drijz + p3drjkz;
342#ifndef N2P2_FULL_SFD_MEMORY
345 dGdr = nk.
dGdr[li].r;
346 dGdr[0] -= p2drikx - p3drjkx;
347 dGdr[1] -= p2driky - p3drjky;
348 dGdr[2] -= p2drikz - p3drjkz;
356 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.
Wide angular symmetry function with compact support (type 22)
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.
Wide angular symmetry function with compact support (type 22)
std::vector< SymFncCompAngw const * > members
Vector of all group member pointers.
virtual void sortMembers()
Sort member symmetry functions.
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 bool operator==(SymGrp const &rhs) const
Overload == operator.
virtual bool operator<(SymGrp const &rhs) const
Overload < operator.
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.