27Atom::Atom() : hasNeighborList (false),
28 NeighborListIsSorted (false),
29 hasSymmetryFunctions (false),
30 hasSymmetryFunctionDerivatives(false),
31 useChargeNeuron (false),
37 numNeighborsUnique (0 ),
38 numSymmetryFunctions (0 ),
47#ifdef N2P2_FULL_SFD_MEMORY
48void Atom::collectDGdxia(
size_t indexAtom,
49 size_t indexComponent,
50 double maxCutoffRadius)
52 for (
size_t i = 0; i < dGdxia.size(); i++)
62 dGdxia[j] +=
neighbors[i].dGdr[j][indexComponent];
66 if (
index == indexAtom)
70 dGdxia[i] +=
dGdr[i][indexComponent];
84 f *= convEnergy / convLength;
85 fRef *= convEnergy / convLength;
92 dEdG.at(i) *= convEnergy;
93 dGdr.at(i) /= convLength;
94#ifdef N2P2_FULL_SFD_MEMORY
95 dGdxia.at(i) /= convLength;
105 for (vector<Neighbor>::iterator it =
neighbors.begin();
109 it->dr *= convLength;
112 for (
size_t i = 0; i <
dGdr.size(); ++i)
114 dGdr.at(i) /= convLength;
129 f /= convEnergy / convLength;
130 fRef /= convEnergy / convLength;
137 dEdG.at(i) /= convEnergy;
138 dGdr.at(i) *= convLength;
139#ifdef N2P2_FULL_SFD_MEMORY
140 dGdxia.at(i) *= convLength;
150 for (vector<Neighbor>::iterator it =
neighbors.begin();
154 it->dr /= convLength;
157 for (
size_t i = 0; i <
dGdr.size(); ++i)
159 dGdr.at(i) *= convLength;
172 throw range_error(
"ERROR: Number of symmetry functions set to"
173 "zero, cannot allocate.\n");
181#ifdef N2P2_FULL_SFD_MEMORY
189 for (
size_t i = 0; i < numSymFuncNeighbors; ++i)
192#ifndef N2P2_NO_SF_CACHE
206#ifndef N2P2_FULL_SFD_MEMORY
209 throw range_error(
"ERROR: Number of symmetry function derivatives"
210 " unset, cannot allocate.\n");
217#ifdef N2P2_FULL_SFD_MEMORY
222 for (
size_t i = 0; i < numSymFuncNeighbors; ++i)
225#ifndef N2P2_NO_SF_CACHE
227 -numeric_limits<double>::max());
231#ifndef N2P2_FULL_SFD_MEMORY
248 vector<double>(
G).swap(
G);
251#ifndef N2P2_NO_SF_CACHE
252 for (
size_t i = 0; i < numSymFuncNeighbors; ++i)
267#ifdef N2P2_FULL_SFD_MEMORY
269 vector<double>(dGdxia).swap(dGdxia);
274 for (
size_t i = 0; i < numSymFuncNeighbors; ++i)
314 size_t numNeighborsLocal = 0;
316 for (vector<Neighbor>::const_iterator it =
neighbors.begin();
319 if (it->d <= cutoffRadius)
325 return numNeighborsLocal;
342 for (
auto const& n :
neighbors)
if (n.index ==
index)
return true;
348 map<string, double>& error,
351 if (property ==
"force")
354 error.at(
"RMSE") += (
fRef -
f).norm2();
355 error.at(
"MAE") += (
fRef -
f).l1norm();
357 else if (property ==
"charge")
365 throw runtime_error(
"ERROR: Unknown property for error update.\n");
376 selfForce -=
dEdG.at(i) *
dGdr.at(i);
382 vector<vector<size_t> >
383 const *
const tableFull)
const
386#ifndef NNP_FULL_SFD_MEMORY
387 if (!tableFull)
throw runtime_error(
388 "ERROR: tableFull must not be null pointer");
389 vector<size_t>
const& table = tableFull->at(neighbor.
element);
390 for (
size_t i = 0; i < neighbor.
dGdr.size(); ++i)
392 pairForce -=
dEdG.at(table.at(i)) * neighbor.
dGdr.at(i);
397 pairForce -=
dEdG.at(i) * neighbor.
dGdr.at(i);
404 double const maxCutoffRadius,
405 vector<vector<size_t> >
const *
const tableFull)
const
407#ifndef NNP_FULL_SFD_MEMORY
408 if (!tableFull)
throw runtime_error(
409 "ERROR: tableFull must not be null pointer");
414 if (atomIndexOfR ==
index)
427 if (n.
tag == (int64_t)atomIndexOfR)
429#ifndef NNP_FULL_SFD_MEMORY
430 vector<size_t>
const& table = tableFull->at(n.
element);
431 for (
size_t k = 0; k < n.
dGdr.size(); ++k)
433 dChidr +=
dChidG.at(table.at(k)) * n.
dGdr.at(k);
449 for (
size_t i = 0; i < 3; ++i)
451 v.push_back(
strpr(
"%10zu %10zu %16.8E %16.8E\n",
463 return strpr(
"%10zu %10zu %16.8E %16.8E\n",
474 v.push_back(
strpr(
"********************************\n"));
475 v.push_back(
strpr(
"ATOM \n"));
476 v.push_back(
strpr(
"********************************\n"));
483 v.push_back(
strpr(
"tag : %" PRId64
"\n",
tag));
489 v.push_back(
strpr(
"chi : %16.8E\n",
chi));
492 v.push_back(
strpr(
"r : %16.8E %16.8E %16.8E\n",
r[0],
r[1],
r[2]));
493 v.push_back(
strpr(
"f : %16.8E %16.8E %16.8E\n",
f[0],
f[1],
f[2]));
495 v.push_back(
strpr(
"--------------------------------\n"));
497 v.push_back(
strpr(
"--------------------------------\n"));
502 v.push_back(
strpr(
"--------------------------------\n"));
503 v.push_back(
strpr(
"--------------------------------\n"));
505 v.push_back(
strpr(
"--------------------------------\n"));
510 v.push_back(
strpr(
"--------------------------------\n"));
511 v.push_back(
strpr(
"--------------------------------\n"));
513 v.push_back(
strpr(
"--------------------------------\n"));
518#ifndef N2P2_NO_SF_CACHE
519 v.push_back(
strpr(
"--------------------------------\n"));
520 v.push_back(
strpr(
"--------------------------------\n"));
522 v.push_back(
strpr(
"--------------------------------\n"));
528 v.push_back(
strpr(
"--------------------------------\n"));
529 v.push_back(
strpr(
"--------------------------------\n"));
530 v.push_back(
strpr(
"G [*] : %d\n",
G.size()));
531 v.push_back(
strpr(
"--------------------------------\n"));
532 for (
size_t i = 0; i <
G.size(); ++i)
534 v.push_back(
strpr(
"%29d : %16.8E\n", i,
G.at(i)));
536 v.push_back(
strpr(
"--------------------------------\n"));
537 v.push_back(
strpr(
"--------------------------------\n"));
538 v.push_back(
strpr(
"dEdG [*] : %d\n",
dEdG.size()));
539 v.push_back(
strpr(
"--------------------------------\n"));
540 for (
size_t i = 0; i <
dEdG.size(); ++i)
542 v.push_back(
strpr(
"%29d : %16.8E\n", i,
dEdG.at(i)));
544 v.push_back(
strpr(
"--------------------------------\n"));
545 v.push_back(
strpr(
"--------------------------------\n"));
546 v.push_back(
strpr(
"dQdG [*] : %d\n",
dQdG.size()));
547 v.push_back(
strpr(
"--------------------------------\n"));
548 for (
size_t i = 0; i <
dQdG.size(); ++i)
550 v.push_back(
strpr(
"%29d : %16.8E\n", i,
dQdG.at(i)));
552 v.push_back(
strpr(
"--------------------------------\n"));
553#ifdef N2P2_FULL_SFD_MEMORY
554 v.push_back(
strpr(
"--------------------------------\n"));
555 v.push_back(
strpr(
"dGdxia [*] : %d\n", dGdxia.size()));
556 v.push_back(
strpr(
"--------------------------------\n"));
557 for (
size_t i = 0; i < dGdxia.size(); ++i)
559 v.push_back(
strpr(
"%29d : %16.8E\n", i, dGdxia.at(i)));
561 v.push_back(
strpr(
"--------------------------------\n"));
563 v.push_back(
strpr(
"--------------------------------\n"));
564 v.push_back(
strpr(
"dGdr [*] : %d\n",
dGdr.size()));
565 v.push_back(
strpr(
"--------------------------------\n"));
566 for (
size_t i = 0; i <
dGdr.size(); ++i)
568 v.push_back(
strpr(
"%29d : %16.8E %16.8E %16.8E\n", i,
dGdr.at(i)[0],
dGdr.at(i)[1],
dGdr.at(i)[2]));
570 v.push_back(
strpr(
"--------------------------------\n"));
571 v.push_back(
strpr(
"--------------------------------\n"));
573 v.push_back(
strpr(
"--------------------------------\n"));
574 for (
size_t i = 0; i <
neighbors.size(); ++i)
576 v.push_back(
strpr(
"%29d :\n", i));
578 v.insert(v.end(), vn.begin(), vn.end());
580 v.push_back(
strpr(
"--------------------------------\n"));
581 v.push_back(
strpr(
"********************************\n"));
596 if (
d != rhs.
d )
return false;
607 if (
d < rhs.
d )
return true;
608 else if (
d > rhs.
d )
return false;
616 v.push_back(
strpr(
"********************************\n"));
617 v.push_back(
strpr(
"NEIGHBOR \n"));
618 v.push_back(
strpr(
"********************************\n"));
620 v.push_back(
strpr(
"tag : %" PRId64
"\n",
tag));
622 v.push_back(
strpr(
"d : %16.8E\n",
d));
623 v.push_back(
strpr(
"dr : %16.8E %16.8E %16.8E\n", dr[0], dr[1], dr[2]));
624 v.push_back(
strpr(
"--------------------------------\n"));
625#ifndef N2P2_NO_SF_CACHE
626 v.push_back(
strpr(
"cache [*] : %d\n", cache.size()));
627 v.push_back(
strpr(
"--------------------------------\n"));
628 for (
size_t i = 0; i < cache.size(); ++i)
630 v.push_back(
strpr(
"%29d : %16.8E\n", i, cache.at(i)));
632 v.push_back(
strpr(
"--------------------------------\n"));
633 v.push_back(
strpr(
"--------------------------------\n"));
635 v.push_back(
strpr(
"dGdr [*] : %d\n",
dGdr.size()));
636 v.push_back(
strpr(
"--------------------------------\n"));
637 for (
size_t i = 0; i <
dGdr.size(); ++i)
639 v.push_back(
strpr(
"%29d : %16.8E %16.8E %16.8E\n", i,
dGdr.at(i)[0],
dGdr.at(i)[1],
dGdr.at(i)[2]));
641 v.push_back(
strpr(
"--------------------------------\n"));
642 v.push_back(
strpr(
"********************************\n"));
string strpr(const char *format,...)
String version of printf function.
bool unorderedMapContainsKey(std::unordered_map< T, U > const &stdMap, T key)
Test if unordered map contains specified key.
Struct to store information on neighbor atoms.
Neighbor()
Neighbor constructor, initialize to zero.
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.
bool operator==(Neighbor const &rhs) const
Overload == operator.
int64_t tag
Tag of neighbor atom.
std::vector< std::string > info() const
Get atom information as a vector of strings.
std::vector< Vec3D > dGdr
Derivatives of symmetry functions with respect to neighbor coordinates.
bool operator<(Neighbor const &rhs) const
Overload < operator.
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
std::vector< std::string > info() const
Get atom information as a vector of strings.
std::size_t numSymmetryFunctions
Number of symmetry functions used to describe the atom environment.
Vec3D r
Cartesian coordinates.
std::vector< double > dEdG
Derivative of atomic energy with respect to symmetry functions.
Vec3D calculateDChidr(size_t const atomIndexOfR, double const maxCutoffRadius, std::vector< std::vector< size_t > > const *const tableFull=nullptr) const
Calculate dChi/dr of this atom's Chi with respect to the coordinates of the given atom.
Vec3D f
Force vector calculated by neural network.
Vec3D calculatePairForceShort(Neighbor const &neighbor, std::vector< std::vector< std::size_t > > const *const tableFull=nullptr) const
Calculate force resulting from gradient of this atom's (short-ranged) energy contribution with respec...
bool hasSymmetryFunctionDerivatives
If symmetry function derivatives are saved for this atom.
std::vector< double > dQdG
Derivative of atomic charge with respect to symmetry functions.
double charge
Atomic charge determined by neural network.
bool isNeighbor(std::size_t index) const
Return whether atom is a neighbor.
std::size_t index
Index number of this atom.
Vec3D calculateSelfForceShort() const
Calculate force resulting from gradient of this atom's (short-ranged) energy contribution with respec...
std::size_t getStoredMinNumNeighbors(double const cutoffRadius) const
Return needed number of neighbors for a given cutoff radius from neighborCutoffs map.
std::vector< std::size_t > numSymmetryFunctionDerivatives
Number of neighbor atom symmetry function derivatives per element.
Vec3D fRef
Reference force vector from data set.
bool useChargeNeuron
If an additional charge neuron in the short-range NN is present.
std::vector< Vec3D > dGdr
Derivative of symmetry functions with respect to this atom's coordinates.
double chi
Atomic electronegativity determined by neural network.
void toPhysicalUnits(double convEnergy, double convLength, double convCharge)
Switch to physical length, energy and charge units.
void clearNeighborList()
Clear neighbor list.
void free(bool all, double const maxCutoffRadius=0.0)
Free vectors related to symmetry functions, opposite of allocate().
std::size_t indexStructure
Index number of structure this atom belongs to.
int64_t tag
Tag number of this atom.
std::size_t element
Element index of this atom.
std::unordered_map< double, size_t > neighborCutoffs
Map stores number of neighbors needed for the corresponding cut-off.
void allocate(bool all, double const maxCutoffRadius=0.0)
Allocate vectors related to symmetry functions (G, dEdG).
void toNormalizedUnits(double convEnergy, double convLength, double convCharge)
Switch to normalized length, energy and charge units.
bool hasSymmetryFunctions
If symmetry function values are saved for this atom.
std::size_t calculateNumNeighbors(double const cutoffRadius) const
Calculate number of neighbors for a given cutoff radius.
void updateError(std::string const &property, std::map< std::string, double > &error, std::size_t &count) const
Update property error metrics with data from this atom.
std::vector< std::size_t > cacheSizePerElement
Cache size for each element.
bool hasNeighborList
If the neighbor list has been calculated for this atom.
double energy
Atomic energy determined by neural network.
std::vector< double > G
Symmetry function values.
std::vector< std::size_t > neighborsUnique
List of unique neighbor indices (don't count multiple PBC images).
double chargeRef
Atomic reference charge.
std::vector< std::size_t > numNeighborsPerElement
Number of neighbors per element.
std::vector< std::string > getForcesLines() const
Get reference and NN forces for this atoms.
std::string getChargeLine() const
Get reference and NN charge for this atoms.
std::size_t numNeighborsUnique
Number of unique neighbor indices (don't count multiple PBC images).
std::vector< double > dChidG
Derivative of electronegativity with respect to symmetry functions.
std::size_t numNeighbors
Total number of neighbors.
Vector in 3 dimensional real space.