n2p2 - A neural network potential package
nnp::Structure Struct Reference

Storage for one atomic configuration. More...

#include <Structure.h>

Collaboration diagram for nnp::Structure:

Public Types

enum  SampleType { ST_UNKNOWN , ST_TRAINING , ST_VALIDATION , ST_TEST }
 Enumerates different sample types (e.g. More...
 

Public Member Functions

 Structure ()
 Constructor, initializes to zero. More...
 
void setElementMap (ElementMap const &elementMap)
 Set element map of structure. More...
 
void addAtom (Atom const &atom, std::string const &element)
 Add a single atom to structure. More...
 
void readFromFile (std::string const fileName="input.data")
 Read configuration from file. More...
 
void readFromFile (std::ifstream &file)
 Read configuration from file. More...
 
void readFromLines (std::vector< std::string > const &lines)
 Read configuration from lines. More...
 
void calculateMaxCutoffRadiusOverall (EwaldSetup &ewaldSetup, double rcutScreen, double maxCutoffRadius)
 Calculate maximal cut-off if cut-off of screening and real part Ewald summation are also considered. More...
 
void calculateNeighborList (double cutoffRadius, bool sortByDistance=false)
 Calculate neighbor list for all atoms. More...
 
void calculateNeighborList (double cutoffRadius, std::vector< std::vector< double > > &cutoffs)
 Calculate neighbor list for all atoms and setup neighbor cut-off map. More...
 
void sortNeighborList ()
 Sort all neighbor lists of this structure with respect to the distance. More...
 
void setupNeighborCutoffMap (std::vector< std::vector< double > > cutoffs)
 Set up a neighbor cut-off map which gives the index (value) of the last needed neighbor corresponding to a specific cut-off (key). More...
 
void calculatePbcCopies (double cutoffRadius, int(&pbc)[3])
 Calculate required PBC copies. More...
 
void calculateInverseBox ()
 Calculate inverse box. More...
 
bool canMinimumImageConventionBeApplied (double cutoffRadius)
 Check if cut-off radius is small enough to apply minimum image convention. More...
 
Vec3D applyMinimumImageConvention (Vec3D const &dr)
 Calculate distance between two atoms in the minimum image convention. More...
 
void calculateVolume ()
 Calculate volume from box vectors. More...
 
double calculateElectrostaticEnergy (EwaldSetup &ewaldSetup, Eigen::VectorXd hardness, Eigen::MatrixXd gammaSqrt2, Eigen::VectorXd sigmaSqrtPi, ScreeningFunction const &fs, double const fourPiEps, ErfcBuf &erfcBuf)
 Compute electrostatic energy with global charge equilibration. More...
 
double calculateScreeningEnergy (Eigen::MatrixXd gammaSqrt2, Eigen::VectorXd sigmaSqrtPi, ScreeningFunction const &fs, double const fourPiEps)
 Calculate screening energy which needs to be added (!) to the electrostatic energy in order to remove contributions in the short range domain. More...
 
void calculateDAdrQ (EwaldSetup &ewaldSetup, Eigen::MatrixXd gammaSqrt2, double const fourPiEps, ErfcBuf &erfcBuf)
 Calculates derivative of A-matrix with respect to the atoms positions and contract it with Q. More...
 
void calculateDQdChi (std::vector< Eigen::VectorXd > &dQdChi)
 Calculates derivative of the charges with respect to electronegativities. More...
 
void calculateDQdJ (std::vector< Eigen::VectorXd > &dQdJ)
 Calculates derivative of the charges with respect to atomic hardness. More...
 
void calculateDQdr (std::vector< size_t > const &atomsIndices, std::vector< size_t > const &compIndices, double const maxCutoffRadius, std::vector< Element > const &elements)
 Calculates derivative of the charges with respect to the atom's position. More...
 
void calculateElectrostaticEnergyDerivatives (Eigen::VectorXd hardness, Eigen::MatrixXd gammaSqrt2, Eigen::VectorXd sigmaSqrtPi, ScreeningFunction const &fs, double const fourPiEps)
 Calculates partial derivatives of electrostatic Energy with respect to atom's coordinates and charges. More...
 
Eigen::VectorXd const calculateForceLambdaTotal () const
 Calculate lambda_total vector which is needed for the total force calculation in 4G NN. More...
 
Eigen::VectorXd const calculateForceLambdaElec () const
 Calculate lambda_elec vector which is needed for the electrostatic force calculation in 4G NN. More...
 
void remap ()
 Translate all atoms back into box if outside. More...
 
void remap (Atom &atom)
 Translate atom back into box if outside. More...
 
void toNormalizedUnits (double meanEnergy, double convEnergy, double convLength, double convCharge)
 Normalize structure, shift energy and change energy, length and charge unit. More...
 
void toPhysicalUnits (double meanEnergy, double convEnergy, double convLength, double convCharge)
 Switch to physical units, shift energy and change energy, length and charge unit. More...
 
std::size_t getMaxNumNeighbors () const
 Find maximum number of neighbors. More...
 
void freeAtoms (bool all, double const maxCutoffRadius=0.0)
 Free symmetry function memory for all atoms, see free() in Atom class. More...
 
void reset ()
 Reset everything but elementMap. More...
 
void clearNeighborList ()
 Clear neighbor list of all atoms. More...
 
void clearElectrostatics (bool clearDQdr=false)
 Clear A-matrix, dAdrQ and optionally dQdr. More...
 
void updateError (std::string const &property, std::map< std::string, double > &error, std::size_t &count) const
 Update property error metrics with this structure. More...
 
std::string getEnergyLine () const
 Get reference and NN energy. More...
 
std::vector< std::string > getForcesLines () const
 Get reference and NN forces for all atoms. More...
 
std::vector< std::string > getChargesLines () const
 Get reference and NN charges for all atoms. More...
 
void writeToFile (std::string const fileName="output.data", bool const ref=true, bool const append=false) const
 Write configuration to file. More...
 
void writeToFile (std::ofstream *const &file, bool const ref=true) const
 Write configuration to file. More...
 
void writeToFileXyz (std::ofstream *const &file) const
 Write configuration to xyz file. More...
 
void writeToFilePoscar (std::ofstream *const &file) const
 Write configuration to POSCAR file. More...
 
void writeToFilePoscar (std::ofstream *const &file, std::string const elements) const
 Write configuration to POSCAR file. More...
 
std::vector< std::string > info () const
 Get structure information as a vector of strings. More...
 

Public Attributes

ElementMap elementMap
 Copy of element map provided as constructor argument. More...
 
bool isPeriodic
 If periodic boundary conditions apply. More...
 
bool isTriclinic
 If the simulation box is triclinic. More...
 
bool hasNeighborList
 If the neighbor list has been calculated. More...
 
bool NeighborListIsSorted
 If the neighbor list has been sorted by distance. More...
 
bool hasSymmetryFunctions
 If symmetry function values are saved for each atom. More...
 
bool hasSymmetryFunctionDerivatives
 If symmetry function derivatives are saved for each atom. More...
 
std::size_t index
 Index number of this structure. More...
 
std::size_t numAtoms
 Total number of atoms present in this structure. More...
 
std::size_t numElements
 Global number of elements (all structures). More...
 
std::size_t numElementsPresent
 Number of elements present in this structure. More...
 
int pbc [3]
 Number of PBC images necessary in each direction for max cut-off. More...
 
double energy
 Potential energy determined by neural network. More...
 
double energyRef
 Reference potential energy. More...
 
double energyShort
 Short-range part of the potential energy predicted by NNP. More...
 
double energyElec
 Electrostatics part of the potential energy predicted by NNP. More...
 
bool hasCharges
 If all charges of this structure have been calculated (and stay the same, e.g. More...
 
double charge
 Charge determined by neural network potential. More...
 
double chargeRef
 Reference charge. More...
 
double volume
 Simulation box volume. More...
 
double maxCutoffRadiusOverall
 Maximum cut-off radius with respect to symmetry functions, screening function and Ewald summation. More...
 
double lambda
 Lagrange multiplier used for charge equilibration. More...
 
SampleType sampleType
 Sample type (training or test set). More...
 
std::string comment
 Structure comment. More...
 
Vec3D box [3]
 Simulation box vectors. More...
 
Vec3D invbox [3]
 Inverse simulation box vectors. More...
 
Eigen::MatrixXd A
 Global charge equilibration matrix A'. More...
 
bool hasAMatrix
 If A matrix of this structure is currently stored. More...
 
std::vector< std::size_t > numAtomsPerElement
 Number of atoms of each element in this structure. More...
 
std::vector< Atomatoms
 Vector of all atoms in this structure. More...
 

Detailed Description

Storage for one atomic configuration.

Definition at line 38 of file Structure.h.

Member Enumeration Documentation

◆ SampleType

Enumerates different sample types (e.g.

training or test set).

Enumerator
ST_UNKNOWN 

Sample type not assigned yet.

ST_TRAINING 

Structure is part of the training set.

ST_VALIDATION 

Structure is part of validation set (currently unused).

ST_TEST 

Structure is part of the test set.

Definition at line 42 of file Structure.h.

43 {
56 };
@ ST_VALIDATION
Structure is part of validation set (currently unused).
Definition: Structure.h:52
@ ST_TRAINING
Structure is part of the training set.
Definition: Structure.h:49
@ ST_UNKNOWN
Sample type not assigned yet.
Definition: Structure.h:46
@ ST_TEST
Structure is part of the test set.
Definition: Structure.h:55

Constructor & Destructor Documentation

◆ Structure()

Structure::Structure ( )

Constructor, initializes to zero.

Definition at line 35 of file Structure.cpp.

35 :
36 isPeriodic (false ),
37 isTriclinic (false ),
38 hasNeighborList (false ),
39 NeighborListIsSorted (false ),
40 hasSymmetryFunctions (false ),
42 index (0 ),
43 numAtoms (0 ),
44 numElements (0 ),
46 energy (0.0 ),
47 energyRef (0.0 ),
48 energyShort (0.0 ),
49 energyElec (0.0 ),
50 hasCharges (false ),
51 charge (0.0 ),
52 chargeRef (0.0 ),
53 volume (0.0 ),
56 comment ("" ),
57 hasAMatrix (false )
58{
59 for (size_t i = 0; i < 3; i++)
60 {
61 pbc[i] = 0;
62 box[i][0] = 0.0;
63 box[i][1] = 0.0;
64 box[i][2] = 0.0;
65 invbox[i][0] = 0.0;
66 invbox[i][1] = 0.0;
67 invbox[i][2] = 0.0;
68 }
69}
Vec3D invbox[3]
Inverse simulation box vectors.
Definition: Structure.h:114
Vec3D box[3]
Simulation box vectors.
Definition: Structure.h:112
bool isTriclinic
If the simulation box is triclinic.
Definition: Structure.h:63
std::string comment
Structure comment.
Definition: Structure.h:110
bool isPeriodic
If periodic boundary conditions apply.
Definition: Structure.h:61
double maxCutoffRadiusOverall
Maximum cut-off radius with respect to symmetry functions, screening function and Ewald summation.
Definition: Structure.h:103
double charge
Charge determined by neural network potential.
Definition: Structure.h:96
bool NeighborListIsSorted
If the neighbor list has been sorted by distance.
Definition: Structure.h:67
std::size_t index
Index number of this structure.
Definition: Structure.h:73
double chargeRef
Reference charge.
Definition: Structure.h:98
SampleType sampleType
Sample type (training or test set).
Definition: Structure.h:108
double energyShort
Short-range part of the potential energy predicted by NNP.
Definition: Structure.h:88
bool hasAMatrix
If A matrix of this structure is currently stored.
Definition: Structure.h:118
bool hasSymmetryFunctionDerivatives
If symmetry function derivatives are saved for each atom.
Definition: Structure.h:71
double energyElec
Electrostatics part of the potential energy predicted by NNP.
Definition: Structure.h:91
double energy
Potential energy determined by neural network.
Definition: Structure.h:83
double energyRef
Reference potential energy.
Definition: Structure.h:85
int pbc[3]
Number of PBC images necessary in each direction for max cut-off.
Definition: Structure.h:81
double volume
Simulation box volume.
Definition: Structure.h:100
std::size_t numAtoms
Total number of atoms present in this structure.
Definition: Structure.h:75
std::size_t numElements
Global number of elements (all structures).
Definition: Structure.h:77
std::size_t numElementsPresent
Number of elements present in this structure.
Definition: Structure.h:79
bool hasNeighborList
If the neighbor list has been calculated.
Definition: Structure.h:65
bool hasCharges
If all charges of this structure have been calculated (and stay the same, e.g.
Definition: Structure.h:94
bool hasSymmetryFunctions
If symmetry function values are saved for each atom.
Definition: Structure.h:69

References box, invbox, and pbc.

Member Function Documentation

◆ setElementMap()

void Structure::setElementMap ( ElementMap const &  elementMap)

Set element map of structure.

Parameters
[in]elementMapReference to a map containing all possible (symbol, index)-pairs (see ElementMap).

Definition at line 71 of file Structure.cpp.

72{
73 this->elementMap = elementMap;
76
77 return;
78}
std::size_t size() const
Get element map size.
Definition: ElementMap.h:140
std::vector< std::size_t > numAtomsPerElement
Number of atoms of each element in this structure.
Definition: Structure.h:120
ElementMap elementMap
Copy of element map provided as constructor argument.
Definition: Structure.h:59

References elementMap, numAtomsPerElement, numElements, and nnp::ElementMap::size().

Referenced by nnp::Dataset::distributeStructures(), nnp::InterfaceLammps::initialize(), main(), nnp::Dataset::prepareNumericForces(), nnp::Prediction::readStructureFromFile(), and LAMMPS_NS::PairHDNNPExternal::settings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addAtom()

void Structure::addAtom ( Atom const &  atom,
std::string const &  element 
)

Add a single atom to structure.

Parameters
[in]atomAtom to insert.
[in]elementElement string of new atom.
Note
Be sure to set the element map properly before adding atoms. This function will only keep the atom's coordinates, energy, charge, tag and forces, all other members will be cleared or reset (in particular, the neighbor list and symmetry function data will be deleted).

Definition at line 80 of file Structure.cpp.

81{
82 atoms.push_back(Atom());
83 atoms.back() = atom;
84 // The number of elements may have changed.
85 atoms.back().numNeighborsPerElement.resize(elementMap.size(), 0);
86 atoms.back().clearNeighborList();
87 atoms.back().index = numAtoms;
88 atoms.back().indexStructure = index;
89 atoms.back().element = elementMap[element];
90 atoms.back().numSymmetryFunctions = 0;
91 numAtoms++;
93
94 return;
95}
Storage for a single atom.
Definition: Atom.h:33
std::vector< Atom > atoms
Vector of all atoms in this structure.
Definition: Structure.h:122

References atoms, elementMap, index, numAtoms, numAtomsPerElement, and nnp::ElementMap::size().

Here is the call graph for this function:

◆ readFromFile() [1/2]

void Structure::readFromFile ( std::string const  fileName = "input.data")

Read configuration from file.

Parameters
[in]fileNameInput file name.

Reads the first configuration found in the input file.

Definition at line 97 of file Structure.cpp.

98{
99 ifstream file;
100
101 file.open(fileName.c_str());
102 if (!file.is_open())
103 {
104 throw runtime_error("ERROR: Could not open file: \"" + fileName
105 + "\".\n");
106 }
107 readFromFile(file);
108 file.close();
109
110 return;
111}
void readFromFile(std::string const fileName="input.data")
Read configuration from file.
Definition: Structure.cpp:97

References readFromFile().

Referenced by nnp::Dataset::distributeStructures(), main(), readFromFile(), and nnp::Prediction::readStructureFromFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readFromFile() [2/2]

void Structure::readFromFile ( std::ifstream &  file)

Read configuration from file.

Parameters
[in]fileInput file stream (already opened).

Expects that a file with configurations is open, first keyword on first line should be begin. Reads until keyword is end.

Definition at line 113 of file Structure.cpp.

114{
115 string line;
116 vector<string> lines;
117 vector<string> splitLine;
118
119 // read first line, should be keyword "begin".
120 getline(file, line);
121 lines.push_back(line);
122 splitLine = split(reduce(line));
123 if (splitLine.at(0) != "begin")
124 {
125 throw runtime_error("ERROR: Unexpected file content, expected"
126 " \"begin\" keyword.\n");
127 }
128
129 while (getline(file, line))
130 {
131 lines.push_back(line);
132 splitLine = split(reduce(line));
133 if (splitLine.at(0) == "end") break;
134 }
135
136 readFromLines(lines);
137
138 return;
139}
vector< string > split(string const &input, char delimiter)
Split string at each delimiter.
Definition: utility.cpp:33
string reduce(string const &line, string const &whitespace, string const &fill)
Replace multiple whitespaces with fill.
Definition: utility.cpp:60
void readFromLines(std::vector< std::string > const &lines)
Read configuration from lines.
Definition: Structure.cpp:142

References readFromLines(), nnp::reduce(), and nnp::split().

Here is the call graph for this function:

◆ readFromLines()

void Structure::readFromLines ( std::vector< std::string > const &  lines)

Read configuration from lines.

Parameters
[in]linesOne configuration in form of a vector of strings.

Read the configuration from a vector of strings.

Definition at line 142 of file Structure.cpp.

143{
144 size_t iBoxVector = 0;
145 vector<string> splitLine;
146
147 // read first line, should be keyword "begin".
148 splitLine = split(reduce(lines.at(0)));
149 if (splitLine.at(0) != "begin")
150 {
151 throw runtime_error("ERROR: Unexpected line content, expected"
152 " \"begin\" keyword.\n");
153 }
154
155 for (vector<string>::const_iterator line = lines.begin();
156 line != lines.end(); ++line)
157 {
158 splitLine = split(reduce(*line));
159 if (splitLine.at(0) == "begin")
160 {
161 if (splitLine.size() > 1)
162 {
163 for (vector<string>::const_iterator word =
164 splitLine.begin() + 1; word != splitLine.end(); ++word)
165 {
166 if (*word == "set=train") sampleType = ST_TRAINING;
167 else if (*word == "set=test") sampleType = ST_TEST;
168 else
169 {
170 throw runtime_error("ERROR: Unknown keyword in "
171 "structure specification, check "
172 "\"begin\" arguments.\n");
173 }
174 }
175 }
176 }
177 else if (splitLine.at(0) == "comment")
178 {
179 size_t position = line->find("comment");
180 string tmpLine = *line;
181 comment = tmpLine.erase(position, splitLine.at(0).length() + 1);
182 }
183 else if (splitLine.at(0) == "lattice")
184 {
185 if (iBoxVector > 2)
186 {
187 throw runtime_error("ERROR: Too many box vectors.\n");
188 }
189 box[iBoxVector][0] = atof(splitLine.at(1).c_str());
190 box[iBoxVector][1] = atof(splitLine.at(2).c_str());
191 box[iBoxVector][2] = atof(splitLine.at(3).c_str());
192 iBoxVector++;
193 if (iBoxVector == 3)
194 {
195 isPeriodic = true;
196 if (box[0][1] > numeric_limits<double>::min() ||
197 box[0][2] > numeric_limits<double>::min() ||
198 box[1][0] > numeric_limits<double>::min() ||
199 box[1][2] > numeric_limits<double>::min() ||
200 box[2][0] > numeric_limits<double>::min() ||
201 box[2][1] > numeric_limits<double>::min())
202 {
203 isTriclinic = true;
204 }
207 }
208 }
209 else if (splitLine.at(0) == "atom")
210 {
211 atoms.push_back(Atom());
212 atoms.back().index = numAtoms;
213 atoms.back().indexStructure = index;
214 atoms.back().tag = numAtoms; // Implicit conversion!
215 atoms.back().r[0] = atof(splitLine.at(1).c_str());
216 atoms.back().r[1] = atof(splitLine.at(2).c_str());
217 atoms.back().r[2] = atof(splitLine.at(3).c_str());
218 atoms.back().element = elementMap[splitLine.at(4)];
219 atoms.back().chargeRef = atof(splitLine.at(5).c_str());
220 atoms.back().fRef[0] = atof(splitLine.at(7).c_str());
221 atoms.back().fRef[1] = atof(splitLine.at(8).c_str());
222 atoms.back().fRef[2] = atof(splitLine.at(9).c_str());
223 atoms.back().numNeighborsPerElement.resize(numElements, 0);
224 numAtoms++;
225 numAtomsPerElement[elementMap[splitLine.at(4)]]++;
226 }
227 else if (splitLine.at(0) == "energy")
228 {
229 energyRef = atof(splitLine[1].c_str());
230 }
231 else if (splitLine.at(0) == "charge")
232 {
233 chargeRef = atof(splitLine[1].c_str());
234 }
235 else if (splitLine.at(0) == "end")
236 {
237 if (!(iBoxVector == 0 || iBoxVector == 3))
238 {
239 throw runtime_error("ERROR: Strange number of box vectors.\n");
240 }
241 if (isPeriodic &&
242 abs(chargeRef) > 10*std::numeric_limits<double>::epsilon())
243 {
244 throw runtime_error("ERROR: In structure with index "
245 + to_string(index)
246 + "; if PBCs are applied, the\n"
247 "simulation cell has to be neutrally "
248 "charged.\n");
249 }
250 break;
251 }
252 else
253 {
254 throw runtime_error("ERROR: Unexpected file content, "
255 "unknown keyword \"" + splitLine.at(0) +
256 "\".\n");
257 }
258 }
259
260 for (size_t i = 0; i < numElements; i++)
261 {
262 if (numAtomsPerElement[i] > 0)
263 {
265 }
266 }
267
268 if (isPeriodic) remap();
269
270 return;
271}
void calculateVolume()
Calculate volume from box vectors.
Definition: Structure.cpp:581
void remap()
Translate all atoms back into box if outside.
Definition: Structure.cpp:1214
void calculateInverseBox()
Calculate inverse box.
Definition: Structure.cpp:519

References atoms, box, calculateInverseBox(), calculateVolume(), chargeRef, comment, elementMap, energyRef, index, isPeriodic, isTriclinic, numAtoms, numAtomsPerElement, numElements, numElementsPresent, nnp::reduce(), remap(), sampleType, nnp::split(), ST_TEST, and ST_TRAINING.

Referenced by readFromFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateMaxCutoffRadiusOverall()

void Structure::calculateMaxCutoffRadiusOverall ( EwaldSetup ewaldSetup,
double  rcutScreen,
double  maxCutoffRadius 
)

Calculate maximal cut-off if cut-off of screening and real part Ewald summation are also considered.

Parameters
[in]ewaldSetupSettings of Ewald summation.
[in]rcutScreenCut-off for Screening of the electrostatic interaction.
[in]maxCutoffRadiusmaximal cut-off of symmetry functions.

Definition at line 273 of file Structure.cpp.

277{
278 maxCutoffRadiusOverall = max(rcutScreen, maxCutoffRadius);
279 if (isPeriodic)
280 {
283 ewaldSetup.params.rCut);
284 }
285}
EwaldParameters params
Definition: EwaldSetup.h:39
void calculateParameters(double const newVolume, size_t const newNumAtoms)
Compute eta, rCut and kCut.
Definition: EwaldSetup.cpp:88
double rCut
Cutoff in real space.
Definition: IEwaldTrunc.h:42

References nnp::EwaldSetup::calculateParameters(), isPeriodic, maxCutoffRadiusOverall, numAtoms, nnp::EwaldSetup::params, nnp::EwaldParameters::rCut, and volume.

Referenced by nnp::Mode::evaluateNNP(), nnp::InterfaceLammps::finalizeNeighborList(), and nnp::InterfaceLammps::getMaxCutoffRadiusOverall().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateNeighborList() [1/2]

void Structure::calculateNeighborList ( double  cutoffRadius,
bool  sortByDistance = false 
)

Calculate neighbor list for all atoms.

Parameters
[in]cutoffRadiusAtoms are neighbors if there distance is smaller than the cutoff radius.
[in]sortByDistanceSort neighborlist from nearest to farthest neighbor.

Definition at line 287 of file Structure.cpp.

290{
291 cutoffRadius = max( cutoffRadius, maxCutoffRadiusOverall );
292 //cout << "CUTOFF: " << cutoffRadius << "\n";
293
294 if (isPeriodic)
295 {
296 calculatePbcCopies(cutoffRadius, pbc);
297
298 // Use square of cutoffRadius (faster).
299 cutoffRadius *= cutoffRadius;
300
301#ifdef _OPENMP
302 #pragma omp parallel for
303#endif
304 for (size_t i = 0; i < numAtoms; i++)
305 {
306 // Count atom i as unique neighbor.
307 atoms[i].neighborsUnique.push_back(i);
308 atoms[i].numNeighborsUnique++;
309 for (size_t j = 0; j < numAtoms; j++)
310 {
311 for (int bc0 = -pbc[0]; bc0 <= pbc[0]; bc0++)
312 {
313 for (int bc1 = -pbc[1]; bc1 <= pbc[1]; bc1++)
314 {
315 for (int bc2 = -pbc[2]; bc2 <= pbc[2]; bc2++)
316 {
317 if (!(i == j && bc0 == 0 && bc1 == 0 && bc2 == 0))
318 {
319 Vec3D dr = atoms[i].r - atoms[j].r
320 + bc0 * box[0]
321 + bc1 * box[1]
322 + bc2 * box[2];
323 if (dr.norm2() <= cutoffRadius)
324 {
325 atoms[i].neighbors.
326 push_back(Atom::Neighbor());
327 atoms[i].neighbors.
328 back().index = j;
329 atoms[i].neighbors.
330 back().tag = j; // Implicit conversion!
331 atoms[i].neighbors.
332 back().element = atoms[j].element;
333 atoms[i].neighbors.
334 back().d = dr.norm();
335 atoms[i].neighbors.
336 back().dr = dr;
337 atoms[i].numNeighborsPerElement[
338 atoms[j].element]++;
339 atoms[i].numNeighbors++;
340 // Count atom j only once as unique
341 // neighbor.
342 if (atoms[i].neighborsUnique.back() != j &&
343 i != j)
344 {
345 atoms[i].neighborsUnique.push_back(j);
346 atoms[i].numNeighborsUnique++;
347 }
348 }
349 }
350 }
351 }
352 }
353 }
354 atoms[i].hasNeighborList = true;
355 }
356 }
357 else
358 {
359 // Use square of cutoffRadius (faster).
360 cutoffRadius *= cutoffRadius;
361
362#ifdef _OPENMP
363 #pragma omp parallel for
364#endif
365 for (size_t i = 0; i < numAtoms; i++)
366 {
367 // Count atom i as unique neighbor.
368 atoms[i].neighborsUnique.push_back(i);
369 atoms[i].numNeighborsUnique++;
370 for (size_t j = 0; j < numAtoms; j++)
371 {
372 if (i != j)
373 {
374 Vec3D dr = atoms[i].r - atoms[j].r;
375 if (dr.norm2() <= cutoffRadius)
376 {
377 atoms[i].neighbors.push_back(Atom::Neighbor());
378 atoms[i].neighbors.back().index = j;
379 atoms[i].neighbors.back().tag = j; // Impl. conv.!
380 atoms[i].neighbors.back().element = atoms[j].element;
381 atoms[i].neighbors.back().d = dr.norm();
382 atoms[i].neighbors.back().dr = dr;
383 atoms[i].numNeighborsPerElement[atoms[j].element]++;
384 atoms[i].numNeighbors++;
385 atoms[i].neighborsUnique.push_back(j);
386 atoms[i].numNeighborsUnique++;
387 }
388 }
389 }
390 atoms[i].hasNeighborList = true;
391 }
392 }
393
394 hasNeighborList = true;
395
396 if (sortByDistance) sortNeighborList();
397
398 return;
399}
Struct to store information on neighbor atoms.
Definition: Atom.h:36
void sortNeighborList()
Sort all neighbor lists of this structure with respect to the distance.
Definition: Structure.cpp:409
void calculatePbcCopies(double cutoffRadius, int(&pbc)[3])
Calculate required PBC copies.
Definition: Structure.cpp:486
Vector in 3 dimensional real space.
Definition: Vec3D.h:30
double norm2() const
Calculate square of norm of vector.
Definition: Vec3D.h:299
double norm() const
Calculate norm of vector.
Definition: Vec3D.h:294

References atoms, box, calculatePbcCopies(), hasNeighborList, isPeriodic, maxCutoffRadiusOverall, nnp::Vec3D::norm(), nnp::Vec3D::norm2(), numAtoms, pbc, and sortNeighborList().

Referenced by calculateNeighborList(), nnp::Mode::evaluateNNP(), and main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateNeighborList() [2/2]

void Structure::calculateNeighborList ( double  cutoffRadius,
std::vector< std::vector< double > > &  cutoffs 
)

Calculate neighbor list for all atoms and setup neighbor cut-off map.

Parameters
[in]cutoffRadiusAtoms are neighbors if there distance is smaller than the cutoff radius.
[in]cutoffsVector of all needed cutoffs (needed for cut-off map construction).
Returns
Maximum of {maxCutoffRadius, rcutScreen, rCut}.

Definition at line 401 of file Structure.cpp.

404{
405 calculateNeighborList(cutoffRadius, true);
406 setupNeighborCutoffMap(cutoffs);
407}
void setupNeighborCutoffMap(std::vector< std::vector< double > > cutoffs)
Set up a neighbor cut-off map which gives the index (value) of the last needed neighbor corresponding...
Definition: Structure.cpp:423
void calculateNeighborList(double cutoffRadius, bool sortByDistance=false)
Calculate neighbor list for all atoms.
Definition: Structure.cpp:287

References calculateNeighborList(), and setupNeighborCutoffMap().

Here is the call graph for this function:

◆ sortNeighborList()

void Structure::sortNeighborList ( )

Sort all neighbor lists of this structure with respect to the distance.

Definition at line 409 of file Structure.cpp.

410{
411#ifdef _OPENMP
412 #pragma omp parallel for
413#endif
414 for (size_t i = 0; i < numAtoms; ++i)
415 {
416 sort(atoms[i].neighbors.begin(), atoms[i].neighbors.end());
417 //TODO: maybe sort neighborsUnique too?
418 atoms[i].NeighborListIsSorted = true;
419 }
421}

References atoms, NeighborListIsSorted, and numAtoms.

Referenced by calculateNeighborList(), and nnp::InterfaceLammps::finalizeNeighborList().

Here is the caller graph for this function:

◆ setupNeighborCutoffMap()

void Structure::setupNeighborCutoffMap ( std::vector< std::vector< double > >  cutoffs)

Set up a neighbor cut-off map which gives the index (value) of the last needed neighbor corresponding to a specific cut-off (key).

Parameters
[in]cutoffsVector of all needed symmetry function cutoffs. Note that a local copy gets extended with maxCutoffRadiusOverall.

Definition at line 423 of file Structure.cpp.

425{
427 throw runtime_error("NeighborCutoffs map needs a sorted neighbor list");
428
429 for ( auto& elementCutoffs : cutoffs )
430 {
431 if ( maxCutoffRadiusOverall > 0 &&
432 !vectorContains(elementCutoffs, maxCutoffRadiusOverall))
433 {
434 elementCutoffs.push_back(maxCutoffRadiusOverall);
435 }
436
437 if ( !is_sorted(elementCutoffs.begin(), elementCutoffs.end()) )
438 {
439 sort(elementCutoffs.begin(), elementCutoffs.end());
440 }
441 }
442
443 // Loop over all atoms in this structure and create its neighborCutoffs map
444 for( auto& a : atoms )
445 {
446 size_t const eIndex = a.element;
447 vector<double> const& elementCutoffs = cutoffs.at(eIndex);
448 size_t in = 0;
449 size_t ic = 0;
450
451 while( in < a.numNeighbors && ic < elementCutoffs.size() )
452 {
453 Atom::Neighbor const& n = a.neighbors[in];
454 // If neighbor distance is higher than current "desired cutoff"
455 // then add neighbor cutoff.
456 // Attention: a step in the neighbor list could jump over multiple
457 // params -> don't increment neighbor index
458 if( n.d > elementCutoffs[ic] )
459 {
460 a.neighborCutoffs.emplace( elementCutoffs.at(ic), in );
461 ++ic;
462 }
463 else if ( in == a.numNeighbors - 1 )
464 {
465 a.neighborCutoffs.emplace( elementCutoffs.at(ic), a.numNeighbors );
466 ++ic;
467 }
468 else ++in;
469 }
470 }
471}
bool vectorContains(std::vector< T > const &stdVec, T value)
Test if vector contains specified value.
Definition: utility.h:166
double d
Distance to neighbor atom.
Definition: Atom.h:44

References atoms, nnp::Atom::Neighbor::d, maxCutoffRadiusOverall, NeighborListIsSorted, and nnp::vectorContains().

Referenced by calculateNeighborList(), and nnp::InterfaceLammps::finalizeNeighborList().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculatePbcCopies()

void Structure::calculatePbcCopies ( double  cutoffRadius,
int(&)  pbc[3] 
)

Calculate required PBC copies.

Parameters
[in]cutoffRadiusCutoff radius for neighbor list.
[in]pbcArray for storing the result.

Called by calculateNeighborList().

Definition at line 486 of file Structure.cpp.

487{
488 Vec3D axb;
489 Vec3D axc;
490 Vec3D bxc;
491
492 axb = box[0].cross(box[1]).normalize();
493 axc = box[0].cross(box[2]).normalize();
494 bxc = box[1].cross(box[2]).normalize();
495
496 double proja = fabs(box[0] * bxc);
497 double projb = fabs(box[1] * axc);
498 double projc = fabs(box[2] * axb);
499
500 pbc[0] = 0;
501 pbc[1] = 0;
502 pbc[2] = 0;
503 while (pbc[0] * proja <= cutoffRadius)
504 {
505 pbc[0]++;
506 }
507 while (pbc[1] * projb <= cutoffRadius)
508 {
509 pbc[1]++;
510 }
511 while (pbc[2] * projc <= cutoffRadius)
512 {
513 pbc[2]++;
514 }
515
516 return;
517}
Vec3D & normalize()
Normalize vector, norm equals 1.0 afterwards.
Definition: Vec3D.h:309
Vec3D cross(Vec3D const &v) const
Cross product, argument vector is second in product.
Definition: Vec3D.h:319

References box, nnp::Vec3D::cross(), nnp::Vec3D::normalize(), and pbc.

Referenced by calculateNeighborList().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateInverseBox()

void Structure::calculateInverseBox ( )

Calculate inverse box.

Simulation box looks like this:

\[ h = \begin{pmatrix} \phantom{a_x} & \phantom{b_x} & \phantom{c_x} \\ \vec{\mathbf{a}} & \vec{\mathbf{b}} & \vec{\mathbf{c}} \\ \phantom{a_z} & \phantom{b_z} & \phantom{c_z} \\ \end{pmatrix} = \begin{pmatrix} a_x & b_x & c_x \\ a_y & b_y & c_y \\ a_z & b_z & c_z \\ \end{pmatrix}, \]

where \(\vec{\mathbf{a}} = \) box[0], \(\vec{\mathbf{b}} = \) box[1] and \(\vec{\mathbf{c}} = \) box[2]. Thus, indices are column first, row second:

\[ h = \begin{pmatrix} \texttt{box[0][0]} & \texttt{box[1][0]} & \texttt{box[2][0]} \\ \texttt{box[0][1]} & \texttt{box[1][1]} & \texttt{box[2][1]} \\ \texttt{box[0][2]} & \texttt{box[1][2]} & \texttt{box[2][2]} \\ \end{pmatrix}. \]

The inverse box matrix (same scheme as above but with invbox) can be used to calculate fractional coordinates:

\[ \begin{pmatrix} f_0 \\ f_1 \\ f_2 \end{pmatrix} = h^{-1} \; \vec{\mathbf{r}}. \]

Definition at line 519 of file Structure.cpp.

520{
521 double invdet = box[0][0] * box[1][1] * box[2][2]
522 + box[1][0] * box[2][1] * box[0][2]
523 + box[2][0] * box[0][1] * box[1][2]
524 - box[2][0] * box[1][1] * box[0][2]
525 - box[0][0] * box[2][1] * box[1][2]
526 - box[1][0] * box[0][1] * box[2][2];
527 invdet = 1.0 / invdet;
528
529 invbox[0][0] = box[1][1] * box[2][2] - box[2][1] * box[1][2];
530 invbox[0][1] = box[2][1] * box[0][2] - box[0][1] * box[2][2];
531 invbox[0][2] = box[0][1] * box[1][2] - box[1][1] * box[0][2];
532 invbox[0] *= invdet;
533
534 invbox[1][0] = box[2][0] * box[1][2] - box[1][0] * box[2][2];
535 invbox[1][1] = box[0][0] * box[2][2] - box[2][0] * box[0][2];
536 invbox[1][2] = box[1][0] * box[0][2] - box[0][0] * box[1][2];
537 invbox[1] *= invdet;
538
539 invbox[2][0] = box[1][0] * box[2][1] - box[2][0] * box[1][1];
540 invbox[2][1] = box[2][0] * box[0][1] - box[0][0] * box[2][1];
541 invbox[2][2] = box[0][0] * box[1][1] - box[1][0] * box[0][1];
542 invbox[2] *= invdet;
543
544 return;
545}

References box, and invbox.

Referenced by readFromLines(), and nnp::InterfaceLammps::setBoxVectors().

Here is the caller graph for this function:

◆ canMinimumImageConventionBeApplied()

bool Structure::canMinimumImageConventionBeApplied ( double  cutoffRadius)

Check if cut-off radius is small enough to apply minimum image convention.

Parameters
[in]cutoffRadiuscut-off radius for which condition should be checked.

Definition at line 548 of file Structure.cpp.

549{
550 Vec3D axb;
551 Vec3D axc;
552 Vec3D bxc;
553
554 axb = box[0].cross(box[1]).normalize();
555 axc = box[0].cross(box[2]).normalize();
556 bxc = box[1].cross(box[2]).normalize();
557
558 double proj[3];
559 proj[0] = fabs(box[0] * bxc);
560 proj[1] = fabs(box[1] * axc);
561 proj[2] = fabs(box[2] * axb);
562
563 double minProj = *min_element(proj, proj+3);
564 return (cutoffRadius < minProj / 2.0);
565}

References box, nnp::Vec3D::cross(), and nnp::Vec3D::normalize().

Here is the call graph for this function:

◆ applyMinimumImageConvention()

Vec3D Structure::applyMinimumImageConvention ( Vec3D const &  dr)

Calculate distance between two atoms in the minimum image convention.

Parameters
[in]drDistance vector between two atoms of the same box.

Definition at line 567 of file Structure.cpp.

568{
569 Vec3D ds = invbox * dr;
570 Vec3D dsNINT;
571
572 for (size_t i=0; i<3; ++i)
573 {
574 dsNINT[i] = round(ds[i]);
575 }
576 Vec3D drMin = box * (ds - dsNINT);
577
578 return drMin;
579}

References box, and invbox.

◆ calculateVolume()

void Structure::calculateVolume ( )

Calculate volume from box vectors.

Definition at line 581 of file Structure.cpp.

582{
583 volume = fabs(box[0] * (box[1].cross(box[2])));
584
585 return;
586}

References box, and volume.

Referenced by readFromLines(), and nnp::InterfaceLammps::setBoxVectors().

Here is the caller graph for this function:

◆ calculateElectrostaticEnergy()

double Structure::calculateElectrostaticEnergy ( EwaldSetup ewaldSetup,
Eigen::VectorXd  hardness,
Eigen::MatrixXd  gammaSqrt2,
Eigen::VectorXd  sigmaSqrtPi,
ScreeningFunction const &  fs,
double const  fourPiEps,
ErfcBuf erfcBuf 
)

Compute electrostatic energy with global charge equilibration.

Parameters
[in]ewaldSetupSettings of Ewald summation.
[in]hardnessVector containing the hardness of all elements.
[in]gammaSqrt2Matrix combining gamma with prefactor. \( \text{gammaSqrt2}_{ij} = \sqrt{2} \gamma_{ij} = \sqrt{2} \sqrt{(\sigma_i^2 + \sigma_j^2)} \)
[in]sigmaSqrtPiVector combining sigma with prefactor, \( \text{sigmaSqrtPi}_i = \sqrt{\pi} \sigma_i \)
[in]fsScreening function.
[in]fourPiEps\( \text{fourPiEps} = 4 \pi \varepsilon_0 \). Value depends on unit system (e.g. normalization).
[in]erfcBufhelper object to avoid repeated calculation of erfc().

Definition at line 588 of file Structure.cpp.

596{
597 A.resize(numAtoms + 1, numAtoms + 1);
598 A.setZero();
599 VectorXd b(numAtoms + 1);
600 VectorXd hardnessJ(numAtoms);
601 VectorXd Q;
602 erfcBuf.reset(atoms, 2);
603
604#ifdef _OPENMP
605#pragma omp parallel
606 {
607#endif
608 if (isPeriodic)
609 {
610#ifdef _OPENMP
611#pragma omp single
612 {
613#endif
615 {
616 throw runtime_error("ERROR: Neighbor list needs to "
617 "be sorted for Ewald summation!\n");
618 }
619
620 // Should always happen already before neighborlist construction.
621 //ewaldSetup.calculateParameters(volume, numAtoms);
622#ifdef _OPENMP
623 }
624#endif
625 KspaceGrid grid;
626 grid.setup(box, ewaldSetup);
627 double const rcutReal = ewaldSetup.params.rCut;
628 double const sqrt2eta = sqrt(2.0) * ewaldSetup.params.eta;
629
630#ifdef _OPENMP
631 #pragma omp for schedule(dynamic)
632#endif
633 for (size_t i = 0; i < numAtoms; ++i)
634 {
635 Atom const &ai = atoms.at(i);
636 size_t const ei = ai.element;
637
638 // diagonal including self interaction
639 A(i, i) += hardness(ei)
640 + (1.0 / sigmaSqrtPi(ei) - 2 / (sqrt2eta * sqrt(M_PI)))
641 / fourPiEps;
642
643 hardnessJ(i) = hardness(ei);
644 b(i) = -ai.chi;
645
646 // real part
647 size_t const numNeighbors = ai.getStoredMinNumNeighbors(rcutReal);
648 for (size_t k = 0; k < numNeighbors; ++k)
649 {
650 auto const &n = ai.neighbors[k];
651 size_t j = n.tag;
652 if (j < i) continue;
653
654 double const rij = n.d;
655 size_t const ej = n.element;
656
657 double erfcSqrt2Eta = erfcBuf.getf(i, k, 0, rij / sqrt2eta);
658 double erfcGammaSqrt2 =
659 erfcBuf.getf(i, k, 1, rij / gammaSqrt2(ei, ej));
660
661 A(i, j) += (erfcSqrt2Eta - erfcGammaSqrt2) / (rij * fourPiEps);
662 }
663
664 // reciprocal part
665 //for (size_t j = i + 1; j < numAtoms; ++j)
666 for (size_t j = i; j < numAtoms; ++j)
667 {
668 Atom const &aj = atoms.at(j);
669 for (auto const &gv: grid.kvectors)
670 {
671 // Multiply by 2 because our grid is only a half-sphere
672 // Vec3D const dr = applyMinimumImageConvention(ai.r - aj.r);
673 Vec3D const dr = ai.r - aj.r;
674 A(i, j) += 2 * gv.coeff * cos(gv.k * dr) / fourPiEps;
675 //A(i, j) += 2 * gv.coeff * cos(gv.k * (ai.r - aj.r));
676 }
677 A(j, i) = A(i, j);
678 }
679 }
680 }
681 else
682 {
683#ifdef _OPENMP
684#pragma omp for schedule(dynamic)
685#endif
686 for (size_t i = 0; i < numAtoms; ++i)
687 {
688 Atom const &ai = atoms.at(i);
689 size_t const ei = ai.element;
690
691 A(i, i) = hardness(ei)
692 + 1.0 / (sigmaSqrtPi(ei) * fourPiEps);
693 hardnessJ(i) = hardness(ei);
694 b(i) = -ai.chi;
695 for (size_t j = i + 1; j < numAtoms; ++j)
696 {
697 Atom const &aj = atoms.at(j);
698 size_t const ej = aj.element;
699 double const rij = (ai.r - aj.r).norm();
700
701 A(i, j) = erf(rij / gammaSqrt2(ei, ej)) / (rij * fourPiEps);
702 A(j, i) = A(i, j);
703
704 }
705 }
706 }
707#ifdef _OPENMP
708#pragma omp single
709 {
710#endif
711 A.col(numAtoms).setOnes();
712 A.row(numAtoms).setOnes();
713 A(numAtoms, numAtoms) = 0.0;
714 hasAMatrix = true;
715 b(numAtoms) = chargeRef;
716#ifdef _OPENMP
717 }
718#endif
719 //TODO: sometimes only recalculation of A matrix is needed, because
720 // Qs are stored.
721 Q = A.colPivHouseholderQr().solve(b);
722#ifdef _OPENMP
723 #pragma omp for nowait
724#endif
725 for (size_t i = 0; i < numAtoms; ++i)
726 {
727 atoms.at(i).charge = Q(i);
728 }
729#ifdef _OPENMP
730 } // end of parallel region
731#endif
732
733 lambda = Q(numAtoms);
734 hasCharges = true;
735 double error = (A * Q - b).norm() / b.norm();
736
737 // We need matrix E not A, which only differ by the hardness terms along the diagonal
738 energyElec = 0.5 * Q.head(numAtoms).transpose()
739 * (A.topLeftCorner(numAtoms, numAtoms) -
740 MatrixXd(hardnessJ.asDiagonal())) * Q.head(numAtoms);
741 energyElec += calculateScreeningEnergy(gammaSqrt2, sigmaSqrtPi, fs, fourPiEps);
742
743 return error;
744}
std::vector< Kvector > kvectors
Vector containing all k-vectors.
Definition: Kspace.h:61
void setup(Vec3D box[3], EwaldSetup &ewaldSetup)
Set up reciprocal box vectors and eta.
Definition: Kspace.cpp:45
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
Definition: Atom.h:170
Vec3D r
Cartesian coordinates.
Definition: Atom.h:125
std::size_t getStoredMinNumNeighbors(double const cutoffRadius) const
Return needed number of neighbors for a given cutoff radius from neighborCutoffs map.
Definition: Atom.cpp:329
double chi
Atomic electronegativity determined by neural network.
Definition: Atom.h:119
std::size_t element
Element index of this atom.
Definition: Atom.h:107
double getf(size_t const atomIndex, size_t const neighIndex, size_t const valIndex, double const x)
Either returns already stored value erfc(x) or calculates it if not yet stored.
Definition: ErfcBuf.cpp:21
void reset(std::vector< Atom > const &atoms, size_t const valuesPerPair)
Resizes and resets the storage array to fit the current structure.
Definition: ErfcBuf.cpp:10
double eta
Width of the gaussian screening charges.
Definition: IEwaldTrunc.h:40
double lambda
Lagrange multiplier used for charge equilibration.
Definition: Structure.h:106
Eigen::MatrixXd A
Global charge equilibration matrix A'.
Definition: Structure.h:116
double calculateScreeningEnergy(Eigen::MatrixXd gammaSqrt2, Eigen::VectorXd sigmaSqrtPi, ScreeningFunction const &fs, double const fourPiEps)
Calculate screening energy which needs to be added (!) to the electrostatic energy in order to remove...
Definition: Structure.cpp:746

References A, atoms, box, calculateScreeningEnergy(), chargeRef, nnp::Atom::chi, nnp::Atom::element, energyElec, nnp::EwaldParameters::eta, nnp::ErfcBuf::getf(), nnp::Atom::getStoredMinNumNeighbors(), hasAMatrix, hasCharges, isPeriodic, nnp::KspaceGrid::kvectors, lambda, NeighborListIsSorted, nnp::Atom::neighbors, numAtoms, nnp::EwaldSetup::params, nnp::Atom::r, nnp::EwaldParameters::rCut, nnp::ErfcBuf::reset(), and nnp::KspaceGrid::setup().

Referenced by nnp::Mode::chargeEquilibration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateScreeningEnergy()

double Structure::calculateScreeningEnergy ( Eigen::MatrixXd  gammaSqrt2,
Eigen::VectorXd  sigmaSqrtPi,
ScreeningFunction const &  fs,
double const  fourPiEps 
)

Calculate screening energy which needs to be added (!) to the electrostatic energy in order to remove contributions in the short range domain.

Parameters
[in]gammaSqrt2Matrix combining gamma with prefactor. \( \text{gammaSqrt2}_{ij} = \sqrt{2} \gamma_{ij} = \sqrt{2} \sqrt{(\sigma_i^2 + \sigma_j^2)} \)
[in]sigmaSqrtPiVector combining sigma with prefactor, \( \text{sigmaSqrtPi}_i = \sqrt{\pi} \sigma_i \)
[in]fsScreening function.
[in]fourPiEps\( \text{fourPiEps} = 4 \pi \varepsilon_0 \). Value depends on unit system (e.g. normalization).

Definition at line 746 of file Structure.cpp.

752{
753 double energyScreen = 0;
754 double const rcutScreen = fs.getOuter();
755
756#ifdef _OPENMP
757 #pragma omp parallel
758 {
759 double localEnergyScreen = 0;
760#endif
761 if (isPeriodic)
762 {
763#ifdef _OPENMP
764 #pragma omp for schedule(dynamic)
765#endif
766 for (size_t i = 0; i < numAtoms; ++i)
767 {
768 Atom const& ai = atoms.at(i);
769 size_t const ei = ai.element;
770 double const Qi = ai.charge;
771#ifdef _OPENMP
772 localEnergyScreen += -Qi * Qi
773 / (2 * sigmaSqrtPi(ei) * fourPiEps);
774#else
775 energyScreen += -Qi * Qi
776 / (2 * sigmaSqrtPi(ei) * fourPiEps);
777#endif
778
779 size_t const numNeighbors = ai.getStoredMinNumNeighbors(rcutScreen);
780 for (size_t k = 0; k < numNeighbors; ++k)
781 {
782 auto const& n = ai.neighbors[k];
783 size_t const j = n.tag;
784 if (j < i) continue;
785 double const rij = n.d;
786 size_t const ej = n.element;
787 //TODO: Maybe add charge to neighbor class?
788 double const Qj = atoms.at(j).charge;
789#ifdef _OPENMP
790 localEnergyScreen += Qi * Qj * erf(rij / gammaSqrt2(ei, ej))
791 * (fs.f(rij) - 1) / (rij * fourPiEps);
792#else
793 energyScreen += Qi * Qj * erf(rij / gammaSqrt2(ei, ej))
794 * (fs.f(rij) - 1) / (rij * fourPiEps);
795#endif
796
797 }
798 }
799 }
800 else
801 {
802#ifdef _OPENMP
803 #pragma omp for schedule(dynamic)
804#endif
805 for (size_t i = 0; i < numAtoms; ++i)
806 {
807 Atom const& ai = atoms.at(i);
808 size_t const ei = ai.element;
809 double const Qi = ai.charge;
810#ifdef _OPENMP
811 localEnergyScreen += -Qi * Qi
812 / (2 * sigmaSqrtPi(ei) * fourPiEps);
813#else
814 energyScreen += -Qi * Qi
815 / (2 * sigmaSqrtPi(ei) * fourPiEps);
816#endif
817
818 for (size_t j = i + 1; j < numAtoms; ++j)
819 {
820 Atom const& aj = atoms.at(j);
821 double const Qj = aj.charge;
822 double const rij = (ai.r - aj.r).norm();
823 if ( rij < rcutScreen )
824 {
825#ifdef _OPENMP
826 localEnergyScreen += Qi * Qj * A(i, j) * (fs.f(rij) - 1);
827#else
828 energyScreen += Qi * Qj * A(i, j) * (fs.f(rij) - 1);
829#endif
830 }
831 }
832 }
833 }
834#ifdef _OPENMP
835 #pragma omp atomic
836 energyScreen += localEnergyScreen;
837 }
838#endif
839 //cout << "energyScreen = " << energyScreen << endl;
840 return energyScreen;
841}
double charge
Atomic charge determined by neural network.
Definition: Atom.h:121

References A, atoms, nnp::Atom::charge, nnp::Atom::element, nnp::ScreeningFunction::f(), nnp::ScreeningFunction::getOuter(), nnp::Atom::getStoredMinNumNeighbors(), isPeriodic, nnp::Atom::neighbors, numAtoms, and nnp::Atom::r.

Referenced by calculateElectrostaticEnergy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateDAdrQ()

void Structure::calculateDAdrQ ( EwaldSetup ewaldSetup,
Eigen::MatrixXd  gammaSqrt2,
double const  fourPiEps,
ErfcBuf erfcBuf 
)

Calculates derivative of A-matrix with respect to the atoms positions and contract it with Q.

Parameters
[in]ewaldSetupSettings of Ewald summation.
[in]gammaSqrt2Matrix combining gamma with prefactor. \( \text{gammaSqrt2}_{ij} = \sqrt{2} \gamma_{ij} = \sqrt{2} \sqrt{(\sigma_i^2 + \sigma_j^2)} \)
[in]fourPiEps\( \text{fourPiEps} = 4 \pi \varepsilon_0 \). Value depends on unit system (e.g. normalization).
[in]erfcBufhelper object to avoid repeated calculation of erfc().

Definition at line 844 of file Structure.cpp.

849{
850
851#ifdef _OPENMP
852 vector<Vec3D> dAdrQDiag(numAtoms);
853 #pragma omp parallel
854 {
855
856 #pragma omp declare reduction(vec_Vec3D_plus : std::vector<Vec3D> : \
857 std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<Vec3D>())) \
858 initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
859 #pragma omp for
860#endif
861 // TODO: This initialization loop could probably be avoid, maybe use
862 // default constructor?
863 for (size_t i = 0; i < numAtoms; ++i)
864 {
865 Atom &ai = atoms.at(i);
866 // dAdrQ(numAtoms+1,:) entries are zero
867 ai.dAdrQ.resize(numAtoms + 1);
868 }
869
870 if (isPeriodic)
871 {
872 // TODO: We need same Kspace grid as in calculateScreeningEnergy, should
873 // we cache it for reuse? Note that we can't calculate dAdrQ already in
874 // the loops of calculateElectrostaticEnergy because at this point we don't
875 // have the charges.
876
877 KspaceGrid grid;
878 grid.setup(box, ewaldSetup);
879 double rcutReal = ewaldSetup.params.rCut;
880 double const sqrt2eta = sqrt(2.0) * ewaldSetup.params.eta;
881
882#ifdef _OPENMP
883 // This way of parallelization slightly changes the result because of
884 // numerical errors.
885 #pragma omp for reduction(vec_Vec3D_plus : dAdrQDiag) schedule(dynamic)
886#endif
887 for (size_t i = 0; i < numAtoms; ++i)
888 {
889 Atom &ai = atoms.at(i);
890 size_t const ei = ai.element;
891 double const Qi = ai.charge;
892
893 // real part
894 size_t const numNeighbors = ai.getStoredMinNumNeighbors(rcutReal);
895 for (size_t k = 0; k < numNeighbors; ++k)
896 {
897 auto const &n = ai.neighbors[k];
898 size_t j = n.tag;
899 //if (j < i) continue;
900 if (j <= i) continue;
901
902 double const rij = n.d;
903 Atom &aj = atoms.at(j);
904 size_t const ej = aj.element;
905 double const Qj = aj.charge;
906
907 double erfcSqrt2Eta = erfcBuf.getf(i, k, 0, rij / sqrt2eta);
908 double erfcGammaSqrt2 =
909 erfcBuf.getf(i, k, 1, rij / gammaSqrt2(ei, ej));
910
911 Vec3D dAijdri;
912 dAijdri = n.dr / pow(rij, 2)
913 * (2 / sqrt(M_PI) * (-exp(-pow(rij / sqrt2eta, 2))
914 / sqrt2eta + exp(-pow(rij / gammaSqrt2(ei, ej), 2))
915 / gammaSqrt2(ei, ej)) - 1 / rij
916 * (erfcSqrt2Eta - erfcGammaSqrt2));
917 dAijdri /= fourPiEps;
918 // Make use of symmetry: dA_{ij}/dr_i = dA_{ji}/dr_i
919 // = -dA_{ji}/dr_j = -dA_{ij}/dr_j
920 ai.dAdrQ[i] += dAijdri * Qj;
921 ai.dAdrQ[j] += dAijdri * Qi;
922 aj.dAdrQ[i] -= dAijdri * Qj;
923#ifdef _OPENMP
924 dAdrQDiag[j] -= dAijdri * Qi;
925#else
926 aj.dAdrQ[j] -= dAijdri * Qi;
927#endif
928 }
929
930 // reciprocal part
931 for (size_t j = i + 1; j < numAtoms; ++j)
932 {
933 Atom &aj = atoms.at(j);
934 double const Qj = aj.charge;
935 Vec3D dAijdri;
936 for (auto const &gv: grid.kvectors)
937 {
938 // Multiply by 2 because our grid is only a half-sphere
939 //Vec3D const dr = applyMinimumImageConvention(ai.r - aj.r);
940 Vec3D const dr = ai.r - aj.r;
941 dAijdri -= 2 * gv.coeff * sin(gv.k * dr) * gv.k;
942 }
943 dAijdri /= fourPiEps;
944
945 ai.dAdrQ[i] += dAijdri * Qj;
946 ai.dAdrQ[j] += dAijdri * Qi;
947 aj.dAdrQ[i] -= dAijdri * Qj;
948#ifdef _OPENMP
949 dAdrQDiag[j] -= dAijdri * Qi;
950#else
951 aj.dAdrQ[j] -= dAijdri * Qi;
952#endif
953 }
954 }
955
956 } else
957 {
958#ifdef _OPENMP
959 #pragma omp for reduction(vec_Vec3D_plus : dAdrQDiag) schedule(dynamic)
960#endif
961 for (size_t i = 0; i < numAtoms; ++i)
962 {
963 Atom &ai = atoms.at(i);
964 size_t const ei = ai.element;
965 double const Qi = ai.charge;
966
967 for (size_t j = i + 1; j < numAtoms; ++j)
968 {
969 Atom &aj = atoms.at(j);
970 size_t const ej = aj.element;
971 double const Qj = aj.charge;
972
973 double rij = (ai.r - aj.r).norm();
974 Vec3D dAijdri;
975 dAijdri = (ai.r - aj.r) / pow(rij, 2)
976 * (2 / (sqrt(M_PI) * gammaSqrt2(ei, ej))
977 * exp(-pow(rij / gammaSqrt2(ei, ej), 2))
978 - erf(rij / gammaSqrt2(ei, ej)) / rij);
979 dAijdri /= fourPiEps;
980 // Make use of symmetry: dA_{ij}/dr_i = dA_{ji}/dr_i
981 // = -dA_{ji}/dr_j = -dA_{ij}/dr_j
982 ai.dAdrQ[i] += dAijdri * Qj;
983 ai.dAdrQ[j] = dAijdri * Qi;
984 aj.dAdrQ[i] = -dAijdri * Qj;
985#ifdef _OPENMP
986 dAdrQDiag[j] -= dAijdri * Qi;
987#else
988 aj.dAdrQ[j] -= dAijdri * Qi;
989#endif
990 }
991 }
992 }
993#ifdef _OPENMP
994 #pragma omp for
995 for (size_t i = 0; i < numAtoms; ++i)
996 {
997 Atom& ai = atoms[i];
998 ai.dAdrQ[i] += dAdrQDiag[i];
999 }
1000 }
1001#endif
1002 return;
1003}
std::vector< Vec3D > dAdrQ
If dQdr has been calculated for respective components.
Definition: Atom.h:168

References atoms, box, nnp::Atom::charge, nnp::Atom::dAdrQ, nnp::Atom::element, nnp::EwaldParameters::eta, nnp::ErfcBuf::getf(), nnp::Atom::getStoredMinNumNeighbors(), isPeriodic, nnp::KspaceGrid::kvectors, nnp::Atom::neighbors, numAtoms, nnp::EwaldSetup::params, nnp::Atom::r, nnp::EwaldParameters::rCut, and nnp::KspaceGrid::setup().

Referenced by nnp::Mode::chargeEquilibration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateDQdChi()

void Structure::calculateDQdChi ( std::vector< Eigen::VectorXd > &  dQdChi)

Calculates derivative of the charges with respect to electronegativities.

Parameters
[in]dQdChivector to store the result. dQdChi[i](j) represents the derivative for the i-th electronegativity and the j-th charge.

Definition at line 1005 of file Structure.cpp.

1006{
1007 dQdChi.clear();
1008 dQdChi.reserve(numAtoms);
1009 for (size_t i = 0; i < numAtoms; ++i)
1010 {
1011 // Including Lagrange multiplier equation.
1012 VectorXd b(numAtoms+1);
1013 b.setZero();
1014 b(i) = -1.;
1015 dQdChi.push_back(A.colPivHouseholderQr().solve(b).head(numAtoms));
1016 }
1017 return;
1018}

References A, and numAtoms.

Referenced by nnp::Training::update().

Here is the caller graph for this function:

◆ calculateDQdJ()

void Structure::calculateDQdJ ( std::vector< Eigen::VectorXd > &  dQdJ)

Calculates derivative of the charges with respect to atomic hardness.

Parameters
[in]dQdJvector to store the result. dQdJ[i](j) represents the derivative for the i-th hardness and the j-th charge.

Definition at line 1020 of file Structure.cpp.

1021{
1022 dQdJ.clear();
1023 dQdJ.reserve(numElements);
1024 for (size_t i = 0; i < numElements; ++i)
1025 {
1026 // Including Lagrange multiplier equation.
1027 VectorXd b(numAtoms+1);
1028 b.setZero();
1029 for (size_t j = 0; j < numAtoms; ++j)
1030 {
1031 Atom const &aj = atoms.at(j);
1032 if (i == aj.element) b(j) = -aj.charge;
1033 }
1034 dQdJ.push_back(A.colPivHouseholderQr().solve(b).head(numAtoms));
1035 }
1036 return;
1037}

References A, atoms, nnp::Atom::charge, nnp::Atom::element, numAtoms, and numElements.

Referenced by nnp::Training::update().

Here is the caller graph for this function:

◆ calculateDQdr()

void Structure::calculateDQdr ( std::vector< size_t > const &  atomsIndices,
std::vector< size_t > const &  compIndices,
double const  maxCutoffRadius,
std::vector< Element > const &  elements 
)

Calculates derivative of the charges with respect to the atom's position.

Parameters
[in]atomIndicesVector containing indices of atoms for which the derivative should be calculated.
[in]compIndicesVector containing indices of vector components for which the derivative should be calculated.
[in]maxCutoffRadiusMax. cutoff radius of symmetry functions.
[in]elementsVector containing all elements (needed for symmetry function table).

Definition at line 1039 of file Structure.cpp.

1043{
1044 if (atomIndices.size() != compIndices.size())
1045 throw runtime_error("ERROR: In calculation of dQ/dr both atom index and"
1046 " component index must be specified.");
1047 for (size_t i = 0; i < atomIndices.size(); ++i)
1048 {
1049 Atom& a = atoms.at(atomIndices[i]);
1050 if ( a.dAdrQ.size() == 0 )
1051 throw runtime_error("ERROR: dAdrQ needs to be calculated before "
1052 "calculating dQdr");
1053 a.dQdr.resize(numAtoms);
1054
1055 // b stores (-dChidr - dAdrQ), last element for charge conservation.
1056 VectorXd b(numAtoms + 1);
1057 b.setZero();
1058 for (size_t j = 0; j < numAtoms; ++j)
1059 {
1060 Atom const& aj = atoms.at(j);
1061
1062#ifndef N2P2_FULL_SFD_MEMORY
1063 vector<vector<size_t> > const *const tableFull
1064 = &(elements.at(aj.element).getSymmetryFunctionTable());
1065#else
1066 vector<vector<size_t> > const *const tableFull = nullptr;
1067#endif
1068 b(j) -= aj.calculateDChidr(atomIndices[i],
1069 maxCutoffRadius,
1070 tableFull)[compIndices[i]];
1071 b(j) -= a.dAdrQ.at(j)[compIndices[i]];
1072 }
1073 VectorXd dQdr = A.colPivHouseholderQr().solve(b).head(numAtoms);
1074 for (size_t j = 0; j < numAtoms; ++j)
1075 {
1076 a.dQdr.at(j)[compIndices[i]] = dQdr(j);
1077 }
1078 }
1079 return;
1080}
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.
Definition: Atom.cpp:403
std::vector< Vec3D > dQdr
Derivative of charges with respect to this atom's coordinates.
Definition: Atom.h:163

References A, atoms, nnp::Atom::calculateDChidr(), nnp::Atom::dAdrQ, nnp::Atom::dQdr, nnp::Atom::element, and numAtoms.

Referenced by nnp::Training::update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateElectrostaticEnergyDerivatives()

void Structure::calculateElectrostaticEnergyDerivatives ( Eigen::VectorXd  hardness,
Eigen::MatrixXd  gammaSqrt2,
Eigen::VectorXd  sigmaSqrtPi,
ScreeningFunction const &  fs,
double const  fourPiEps 
)

Calculates partial derivatives of electrostatic Energy with respect to atom's coordinates and charges.

Parameters
[in]hardnessVector containing the hardness of all elements.
[in]gammaSqrt2Matrix combining gamma with prefactor. \( \text{gammaSqrt2}_{ij} = \sqrt{2} \gamma_{ij} = \sqrt{2} \sqrt{(\sigma_i^2 + \sigma_j^2)} \)
[in]sigmaSqrtPiVector combining sigma with prefactor, \( \text{sigmaSqrtPi}_i = \sqrt{\pi} \sigma_i \)
[in]fsScreening function.
[in]fourPiEps\( \text{fourPiEps} = 4 \pi \varepsilon_0 \). Value depends on unit system (e.g. normalization).

Definition at line 1083 of file Structure.cpp.

1089{
1090 // Reset in case structure is used again (e.g. during training)
1091 for (Atom &ai : atoms)
1092 {
1093 ai.pEelecpr = Vec3D{};
1094 ai.dEelecdQ = 0.0;
1095 }
1096
1097 double rcutScreen = fs.getOuter();
1098 for (size_t i = 0; i < numAtoms; ++i)
1099 {
1100 Atom& ai = atoms.at(i);
1101 size_t const ei = ai.element;
1102 double const Qi = ai.charge;
1103
1104 // TODO: This loop could be reduced by making use of symmetry, j>=i or
1105 // so
1106 for (size_t j = 0; j < numAtoms; ++j)
1107 {
1108 Atom& aj = atoms.at(j);
1109 double const Qj = aj.charge;
1110
1111 ai.pEelecpr += 0.5 * Qj * ai.dAdrQ[j];
1112
1113 // Diagonal terms contain self-interaction --> screened
1114 if (i != j) ai.dEelecdQ += Qj * A(i,j);
1115 else if (isPeriodic)
1116 {
1117 ai.dEelecdQ += Qi * (A(i,i) - hardness(ei)
1118 - 1 / (sigmaSqrtPi(ei) * fourPiEps));
1119 }
1120 }
1121
1122 if (isPeriodic)
1123 {
1124 for (auto const& ajN : ai.neighbors)
1125 {
1126 size_t j = ajN.tag;
1127 Atom& aj = atoms.at(j);
1128 if (j < i) continue;
1129 double const rij = ajN.d;
1130 if (rij >= rcutScreen) break;
1131
1132 size_t const ej = aj.element;
1133 double const Qj = atoms.at(j).charge;
1134
1135 double erfRij = erf(rij / gammaSqrt2(ei,ej));
1136 double fsRij = fs.f(rij);
1137
1138 // corrections due to screening
1139 Vec3D Tij = Qi * Qj * ajN.dr / pow(rij,2)
1140 * (2 / (sqrt(M_PI) * gammaSqrt2(ei,ej))
1141 * exp(- pow(rij / gammaSqrt2(ei,ej),2))
1142 * (fsRij - 1) + erfRij * fs.df(rij) - erfRij
1143 * (fsRij - 1) / rij);
1144 Tij /= fourPiEps;
1145 ai.pEelecpr += Tij;
1146 aj.pEelecpr -= Tij;
1147
1148 double Sij = erfRij * (fsRij - 1) / rij;
1149 Sij /= fourPiEps;
1150 ai.dEelecdQ += Qj * Sij;
1151 aj.dEelecdQ += Qi * Sij;
1152 }
1153 }
1154 else
1155 {
1156 for (size_t j = i + 1; j < numAtoms; ++j)
1157 {
1158 Atom& aj = atoms.at(j);
1159 double const rij = (ai.r - aj.r).norm();
1160 if (rij >= rcutScreen) continue;
1161
1162 size_t const ej = aj.element;
1163 double const Qj = atoms.at(j).charge;
1164
1165 double erfRij = erf(rij / gammaSqrt2(ei,ej));
1166 double fsRij = fs.f(rij);
1167
1168 // corrections due to screening
1169 Vec3D Tij = Qi * Qj * (ai.r - aj.r) / pow(rij,2)
1170 * (2 / (sqrt(M_PI) * gammaSqrt2(ei,ej))
1171 * exp(- pow(rij / gammaSqrt2(ei,ej),2))
1172 * (fsRij - 1) + erfRij * fs.df(rij) - erfRij
1173 * (fsRij - 1) / rij);
1174 Tij /= fourPiEps;
1175 ai.pEelecpr += Tij;
1176 aj.pEelecpr -= Tij;
1177
1178 double Sij = erfRij * (fsRij - 1) / rij;
1179 Sij /= fourPiEps;
1180 ai.dEelecdQ += Qj * Sij;
1181 aj.dEelecdQ += Qi * Sij;
1182 }
1183 }
1184 }
1185 return;
1186}
Vec3D pEelecpr
Partial derivative of electrostatic energy with respect to this atom's coordinates.
Definition: Atom.h:134
double dEelecdQ
Derivative of electrostatic energy with respect to this atom's charge.
Definition: Atom.h:117

References A, atoms, nnp::Atom::charge, nnp::Atom::dAdrQ, nnp::Atom::dEelecdQ, nnp::ScreeningFunction::df(), nnp::Atom::element, nnp::ScreeningFunction::f(), nnp::ScreeningFunction::getOuter(), isPeriodic, nnp::Atom::neighbors, numAtoms, nnp::Atom::pEelecpr, and nnp::Atom::r.

Referenced by nnp::Mode::chargeEquilibration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateForceLambdaTotal()

VectorXd const Structure::calculateForceLambdaTotal ( ) const

Calculate lambda_total vector which is needed for the total force calculation in 4G NN.

Definition at line 1188 of file Structure.cpp.

1189{
1190 VectorXd dEdQ(numAtoms+1);
1191 for (size_t i = 0; i < numAtoms; ++i)
1192 {
1193 Atom const& ai = atoms.at(i);
1194 dEdQ(i) = ai.dEelecdQ + ai.dEdG.back();
1195 }
1196 dEdQ(numAtoms) = 0;
1197 VectorXd const lambdaTotal = A.colPivHouseholderQr().solve(-dEdQ);
1198 return lambdaTotal;
1199}
std::vector< double > dEdG
Derivative of atomic energy with respect to symmetry functions.
Definition: Atom.h:149

References A, atoms, nnp::Atom::dEdG, nnp::Atom::dEelecdQ, and numAtoms.

Referenced by nnp::Mode::calculateForces(), and nnp::InterfaceLammps::getForces().

Here is the caller graph for this function:

◆ calculateForceLambdaElec()

VectorXd const Structure::calculateForceLambdaElec ( ) const

Calculate lambda_elec vector which is needed for the electrostatic force calculation in 4G NN.

Definition at line 1201 of file Structure.cpp.

1202{
1203 VectorXd dEelecdQ(numAtoms+1);
1204 for (size_t i = 0; i < numAtoms; ++i)
1205 {
1206 Atom const& ai = atoms.at(i);
1207 dEelecdQ(i) = ai.dEelecdQ;
1208 }
1209 dEelecdQ(numAtoms) = 0;
1210 VectorXd const lambdaElec = A.colPivHouseholderQr().solve(-dEelecdQ);
1211 return lambdaElec;
1212}

References A, atoms, nnp::Atom::dEelecdQ, and numAtoms.

Referenced by nnp::Mode::calculateForces().

Here is the caller graph for this function:

◆ remap() [1/2]

void Structure::remap ( )

Translate all atoms back into box if outside.

Definition at line 1214 of file Structure.cpp.

1215{
1216 for (vector<Atom>::iterator it = atoms.begin(); it != atoms.end(); ++it)
1217 {
1218 remap((*it));
1219 }
1220 return;
1221}

References atoms, and remap().

Referenced by nnp::Dataset::prepareNumericForces(), readFromLines(), and remap().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remap() [2/2]

void Structure::remap ( Atom atom)

Translate atom back into box if outside.

Parameters
[in,out]atomAtom to be remapped.

Definition at line 1223 of file Structure.cpp.

1224{
1225 Vec3D f = atom.r[0] * invbox[0]
1226 + atom.r[1] * invbox[1]
1227 + atom.r[2] * invbox[2];
1228
1229 // Quick and dirty... there may be a more elegant way!
1230 if (f[0] > 1.0) f[0] -= (int)f[0];
1231 if (f[1] > 1.0) f[1] -= (int)f[1];
1232 if (f[2] > 1.0) f[2] -= (int)f[2];
1233
1234 if (f[0] < 0.0) f[0] += 1.0 - (int)f[0];
1235 if (f[1] < 0.0) f[1] += 1.0 - (int)f[1];
1236 if (f[2] < 0.0) f[2] += 1.0 - (int)f[2];
1237
1238 if (f[0] == 1.0) f[0] = 0.0;
1239 if (f[1] == 1.0) f[1] = 0.0;
1240 if (f[2] == 1.0) f[2] = 0.0;
1241
1242 atom.r = f[0] * box[0]
1243 + f[1] * box[1]
1244 + f[2] * box[2];
1245
1246 return;
1247}

References box, invbox, and nnp::Atom::r.

◆ toNormalizedUnits()

void Structure::toNormalizedUnits ( double  meanEnergy,
double  convEnergy,
double  convLength,
double  convCharge 
)

Normalize structure, shift energy and change energy, length and charge unit.

Parameters
[in]meanEnergyMean energy per atom (in old units).
[in]convEnergyMultiplicative energy unit conversion factor.
[in]convLengthMultiplicative length unit conversion factor.
[in]convChargeMultiplicative charge unit conversion factor.

Definition at line 1249 of file Structure.cpp.

1253{
1254 if (isPeriodic)
1255 {
1256 box[0] *= convLength;
1257 box[1] *= convLength;
1258 box[2] *= convLength;
1259 invbox[0] /= convLength;
1260 invbox[1] /= convLength;
1261 invbox[2] /= convLength;
1262 }
1263
1264 energyRef = (energyRef - numAtoms * meanEnergy) * convEnergy;
1265 energy = (energy - numAtoms * meanEnergy) * convEnergy;
1266 chargeRef *= convCharge;
1267 charge *= convCharge;
1268 volume *= convLength * convLength * convLength;
1269
1270 for (vector<Atom>::iterator it = atoms.begin(); it != atoms.end(); ++it)
1271 {
1272 it->toNormalizedUnits(convEnergy, convLength, convCharge);
1273 }
1274
1275 return;
1276}

References atoms, box, charge, chargeRef, energy, energyRef, invbox, isPeriodic, numAtoms, and volume.

Referenced by nnp::Mode::convertToNormalizedUnits(), nnp::Prediction::readStructureFromFile(), and nnp::InterfaceLammps::writeToFile().

Here is the caller graph for this function:

◆ toPhysicalUnits()

void Structure::toPhysicalUnits ( double  meanEnergy,
double  convEnergy,
double  convLength,
double  convCharge 
)

Switch to physical units, shift energy and change energy, length and charge unit.

Parameters
[in]meanEnergyMean energy per atom (in old units).
[in]convEnergyMultiplicative energy unit conversion factor.
[in]convLengthMultiplicative length unit conversion factor.
[in]convChargeMultiplicative charge unit conversion factor.

Definition at line 1278 of file Structure.cpp.

1282{
1283 if (isPeriodic)
1284 {
1285 box[0] /= convLength;
1286 box[1] /= convLength;
1287 box[2] /= convLength;
1288 invbox[0] *= convLength;
1289 invbox[1] *= convLength;
1290 invbox[2] *= convLength;
1291 }
1292
1293 energyRef = energyRef / convEnergy + numAtoms * meanEnergy;
1294 energy = energy / convEnergy + numAtoms * meanEnergy;
1295 chargeRef /= convCharge;
1296 charge /= convCharge;
1297 volume /= convLength * convLength * convLength;
1298
1299 for (vector<Atom>::iterator it = atoms.begin(); it != atoms.end(); ++it)
1300 {
1301 it->toPhysicalUnits(convEnergy, convLength, convCharge);
1302 }
1303
1304 return;
1305}

References atoms, box, charge, chargeRef, energy, energyRef, invbox, isPeriodic, numAtoms, and volume.

Referenced by nnp::Mode::convertToPhysicalUnits(), nnp::Prediction::predict(), and nnp::InterfaceLammps::writeToFile().

Here is the caller graph for this function:

◆ getMaxNumNeighbors()

size_t Structure::getMaxNumNeighbors ( ) const

Find maximum number of neighbors.

Returns
Maximum numbor of neighbors of all atoms in this structure.

Definition at line 473 of file Structure.cpp.

474{
475 size_t maxNumNeighbors = 0;
476
477 for(vector<Atom>::const_iterator it = atoms.begin();
478 it != atoms.end(); ++it)
479 {
480 maxNumNeighbors = max(maxNumNeighbors, it->numNeighbors);
481 }
482
483 return maxNumNeighbors;
484}

References atoms.

◆ freeAtoms()

void Structure::freeAtoms ( bool  all,
double const  maxCutoffRadius = 0.0 
)

Free symmetry function memory for all atoms, see free() in Atom class.

Parameters
[in]allSee description in Atom.
[in]maxCutoffRadiusMaximum cutoff radius of symmetry functions.

Definition at line 1307 of file Structure.cpp.

1308{
1309 for (vector<Atom>::iterator it = atoms.begin(); it != atoms.end(); ++it)
1310 {
1311 it->free(all, maxCutoffRadius);
1312 }
1313 if (all) hasSymmetryFunctions = false;
1315
1316 return;
1317}

References atoms, hasSymmetryFunctionDerivatives, and hasSymmetryFunctions.

Referenced by nnp::Training::update().

Here is the caller graph for this function:

◆ reset()

void Structure::reset ( )

Reset everything but elementMap.

Definition at line 1319 of file Structure.cpp.

1320{
1321 isPeriodic = false ;
1322 isTriclinic = false ;
1323 hasNeighborList = false ;
1324 hasSymmetryFunctions = false ;
1326 index = 0 ;
1327 numAtoms = 0 ;
1328 numElementsPresent = 0 ;
1329 energy = 0.0 ;
1330 energyRef = 0.0 ;
1331 charge = 0.0 ;
1332 chargeRef = 0.0 ;
1333 volume = 0.0 ;
1335 comment = "" ;
1336
1337 for (size_t i = 0; i < 3; ++i)
1338 {
1339 pbc[i] = 0;
1340 for (size_t j = 0; j < 3; ++j)
1341 {
1342 box[i][j] = 0.0;
1343 invbox[i][j] = 0.0;
1344 }
1345 }
1346
1348 numAtomsPerElement.clear();
1350 atoms.clear();
1351 vector<Atom>(atoms).swap(atoms);
1352
1353 return;
1354}

References atoms, box, charge, chargeRef, comment, elementMap, energy, energyRef, hasNeighborList, hasSymmetryFunctionDerivatives, hasSymmetryFunctions, index, invbox, isPeriodic, isTriclinic, numAtoms, numAtomsPerElement, numElements, numElementsPresent, pbc, sampleType, nnp::ElementMap::size(), ST_UNKNOWN, and volume.

Referenced by LAMMPS_NS::PairHDNNPExternal::compute(), main(), and nnp::Prediction::readStructureFromFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clearNeighborList()

void Structure::clearNeighborList ( )

Clear neighbor list of all atoms.

Definition at line 1356 of file Structure.cpp.

1357{
1358 for (size_t i = 0; i < numAtoms; i++)
1359 {
1360 Atom& a = atoms.at(i);
1361 // This may have changed if atoms are added via addAtoms().
1364 }
1365 hasNeighborList = false;
1366 hasSymmetryFunctions = false;
1368
1369 return;
1370}
void clearNeighborList()
Clear neighbor list.
Definition: Atom.cpp:285
std::vector< std::size_t > numNeighborsPerElement
Number of neighbors per element.
Definition: Atom.h:138

References atoms, nnp::Atom::clearNeighborList(), hasNeighborList, hasSymmetryFunctionDerivatives, hasSymmetryFunctions, numAtoms, numElements, and nnp::Atom::numNeighborsPerElement.

Here is the call graph for this function:

◆ clearElectrostatics()

void Structure::clearElectrostatics ( bool  clearDQdr = false)

Clear A-matrix, dAdrQ and optionally dQdr.

Parameters
[in]clearDqdrSpecify if dQdr should also be cleared.

Definition at line 1372 of file Structure.cpp.

1373{
1374 A.resize(0,0);
1375 hasAMatrix = false;
1376 for (auto& a : atoms)
1377 {
1378 vector<Vec3D>().swap(a.dAdrQ);
1379 if (clearDQdr)
1380 {
1381 vector<Vec3D>().swap(a.dQdr);
1382 }
1383 }
1384}

References A, atoms, and hasAMatrix.

Referenced by nnp::Training::update().

Here is the caller graph for this function:

◆ updateError()

void Structure::updateError ( std::string const &  property,
std::map< std::string, double > &  error,
std::size_t &  count 
) const

Update property error metrics with this structure.

Parameters
[in]propertyOne of "energy", "force" or "charge".
[in,out]errorInput error metric map to be updated.
[in,out]countInput counter to be updated.

The "energy" error metric map stores temporary sums for the following metrics:

key "RMSEpa": RMSE of energy per atom key "RMSE" : RMSE of energy key "MAEpa" : MAE of energy per atom key "MAE" : MAE of energy

The "force" error metric map stores temporary sums for the following metrics:

key "RMSE" : RMSE of forces key "MAE" : MAE of forces

The "charge" error metric map stores temporary sums for the following metrics:

key "RMSE" : RMSE of charges key "MAE" : MAE of charges

Definition at line 1386 of file Structure.cpp.

1389{
1390 if (property == "energy")
1391 {
1392 count++;
1393 double diff = energyRef - energy;
1394 error.at("RMSEpa") += diff * diff / (numAtoms * numAtoms);
1395 error.at("RMSE") += diff * diff;
1396 diff = fabs(diff);
1397 error.at("MAEpa") += diff / numAtoms;
1398 error.at("MAE") += diff;
1399 }
1400 else if (property == "force" || property == "charge")
1401 {
1402 for (vector<Atom>::const_iterator it = atoms.begin();
1403 it != atoms.end(); ++it)
1404 {
1405 it->updateError(property, error, count);
1406 }
1407 }
1408 else
1409 {
1410 throw runtime_error("ERROR: Unknown property for error update.\n");
1411 }
1412
1413 return;
1414}

References atoms, energy, energyRef, and numAtoms.

◆ getEnergyLine()

string Structure::getEnergyLine ( ) const

Get reference and NN energy.

Returns
String with index, energyRef and energy values.

Definition at line 1416 of file Structure.cpp.

1417{
1418 return strpr("%10zu %16.8E %16.8E\n",
1419 index,
1421 energy / numAtoms);
1422}
string strpr(const char *format,...)
String version of printf function.
Definition: utility.cpp:90

References energy, energyRef, index, numAtoms, and nnp::strpr().

Here is the call graph for this function:

◆ getForcesLines()

vector< string > Structure::getForcesLines ( ) const

Get reference and NN forces for all atoms.

Returns
Vector of strings with force comparison.

Definition at line 1424 of file Structure.cpp.

1425{
1426 vector<string> v;
1427 for (vector<Atom>::const_iterator it = atoms.begin();
1428 it != atoms.end(); ++it)
1429 {
1430 vector<string> va = it->getForcesLines();
1431 v.insert(v.end(), va.begin(), va.end());
1432 }
1433
1434 return v;
1435}

References atoms.

◆ getChargesLines()

vector< string > Structure::getChargesLines ( ) const

Get reference and NN charges for all atoms.

Returns
Vector of strings with charge comparison.

Definition at line 1437 of file Structure.cpp.

1438{
1439 vector<string> v;
1440 for (vector<Atom>::const_iterator it = atoms.begin();
1441 it != atoms.end(); ++it)
1442 {
1443 v.push_back(it->getChargeLine());
1444 }
1445
1446 return v;
1447}

References atoms.

◆ writeToFile() [1/2]

void Structure::writeToFile ( std::string const  fileName = "output.data",
bool const  ref = true,
bool const  append = false 
) const

Write configuration to file.

Parameters
[in,out]fileNameOuptut file name.
[in]refIf true, write reference energy and forces, if false, write NNP results instead.
[in]appendIf true, append to existing file.

Definition at line 1449 of file Structure.cpp.

1452{
1453 ofstream file;
1454
1455 if (append)
1456 {
1457 file.open(fileName.c_str(), ofstream::app);
1458 }
1459 else
1460 {
1461 file.open(fileName.c_str());
1462 }
1463 if (!file.is_open())
1464 {
1465 throw runtime_error("ERROR: Could not open file: \"" + fileName
1466 + "\".\n");
1467 }
1468 writeToFile(&file, ref );
1469 file.close();
1470
1471 return;
1472}
void writeToFile(std::string const fileName="output.data", bool const ref=true, bool const append=false) const
Write configuration to file.
Definition: Structure.cpp:1449

References writeToFile().

Referenced by LAMMPS_NS::PairHDNNPExternal::compute(), main(), nnp::InterfaceLammps::writeToFile(), and writeToFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeToFile() [2/2]

void Structure::writeToFile ( std::ofstream *const &  file,
bool const  ref = true 
) const

Write configuration to file.

Parameters
[in,out]fileOuptut file.
[in]refIf true, write reference energy and forces, if false, write NNP results instead.

Definition at line 1474 of file Structure.cpp.

1475{
1476 if (!file->is_open())
1477 {
1478 runtime_error("ERROR: Cannot write to file, file is not open.\n");
1479 }
1480
1481 (*file) << "begin\n";
1482 (*file) << strpr("comment %s\n", comment.c_str());
1483 if (isPeriodic)
1484 {
1485 for (size_t i = 0; i < 3; ++i)
1486 {
1487 (*file) << strpr("lattice %24.16E %24.16E %24.16E\n",
1488 box[i][0], box[i][1], box[i][2]);
1489 }
1490 }
1491 for (vector<Atom>::const_iterator it = atoms.begin();
1492 it != atoms.end(); ++it)
1493 {
1494 if (ref)
1495 {
1496 (*file) << strpr("atom %24.16E %24.16E %24.16E %2s %24.16E %24.16E"
1497 " %24.16E %24.16E %24.16E\n",
1498 it->r[0],
1499 it->r[1],
1500 it->r[2],
1501 elementMap[it->element].c_str(),
1502 it->chargeRef,
1503 0.0,
1504 it->fRef[0],
1505 it->fRef[1],
1506 it->fRef[2]);
1507 }
1508 else
1509 {
1510 (*file) << strpr("atom %24.16E %24.16E %24.16E %2s %24.16E %24.16E"
1511 " %24.16E %24.16E %24.16E\n",
1512 it->r[0],
1513 it->r[1],
1514 it->r[2],
1515 elementMap[it->element].c_str(),
1516 it->charge,
1517 0.0,
1518 it->f[0],
1519 it->f[1],
1520 it->f[2]);
1521
1522 }
1523 }
1524 if (ref) (*file) << strpr("energy %24.16E\n", energyRef);
1525 else (*file) << strpr("energy %24.16E\n", energy);
1526 if (ref) (*file) << strpr("charge %24.16E\n", chargeRef);
1527 else (*file) << strpr("charge %24.16E\n", charge);
1528 (*file) << strpr("end\n");
1529
1530 return;
1531}

References atoms, box, charge, chargeRef, comment, elementMap, energy, energyRef, isPeriodic, and nnp::strpr().

Here is the call graph for this function:

◆ writeToFileXyz()

void Structure::writeToFileXyz ( std::ofstream *const &  file) const

Write configuration to xyz file.

Parameters
[in,out]filexyz output file.

Definition at line 1533 of file Structure.cpp.

1534{
1535 if (!file->is_open())
1536 {
1537 runtime_error("ERROR: Could not write to file.\n");
1538 }
1539
1540 (*file) << strpr("%d\n", numAtoms);
1541 if (isPeriodic)
1542 {
1543 (*file) << "Lattice=\"";
1544 (*file) << strpr("%24.16E %24.16E %24.16E " ,
1545 box[0][0], box[0][1], box[0][2]);
1546 (*file) << strpr("%24.16E %24.16E %24.16E " ,
1547 box[1][0], box[1][1], box[1][2]);
1548 (*file) << strpr("%24.16E %24.16E %24.16E\"\n",
1549 box[2][0], box[2][1], box[2][2]);
1550 }
1551 else
1552 {
1553 (*file) << "\n";
1554 }
1555 for (vector<Atom>::const_iterator it = atoms.begin();
1556 it != atoms.end(); ++it)
1557 {
1558 (*file) << strpr("%-2s %24.16E %24.16E %24.16E\n",
1559 elementMap[it->element].c_str(),
1560 it->r[0],
1561 it->r[1],
1562 it->r[2]);
1563 }
1564
1565 return;
1566}

References atoms, box, elementMap, isPeriodic, numAtoms, and nnp::strpr().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeToFilePoscar() [1/2]

void Structure::writeToFilePoscar ( std::ofstream *const &  file) const

Write configuration to POSCAR file.

Parameters
[in,out]filePOSCAR output file.
Warning
Elements in POTCAR file must be ordered according to periodic table.

Definition at line 1568 of file Structure.cpp.

1569{
1571
1572 return;
1573}
std::string getElementsString() const
Get sorted list of elements in one string (space separated).
Definition: ElementMap.cpp:56
void writeToFilePoscar(std::ofstream *const &file) const
Write configuration to POSCAR file.
Definition: Structure.cpp:1568

References elementMap, nnp::ElementMap::getElementsString(), and writeToFilePoscar().

Referenced by main(), and writeToFilePoscar().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeToFilePoscar() [2/2]

void Structure::writeToFilePoscar ( std::ofstream *const &  file,
std::string const  elements 
) const

Write configuration to POSCAR file.

Parameters
[in,out]filePOSCAR output file.
[in,out]elementsUser-defined order of elements, e.g. "Zn O Cu".

Definition at line 1575 of file Structure.cpp.

1577{
1578 if (!file->is_open())
1579 {
1580 runtime_error("ERROR: Could not write to file.\n");
1581 }
1582
1583 vector<string> ve = split(elements);
1584 vector<size_t> elementOrder;
1585 for (size_t i = 0; i < ve.size(); ++i)
1586 {
1587 elementOrder.push_back(elementMap[ve.at(i)]);
1588 }
1589 if (elementOrder.size() != elementMap.size())
1590 {
1591 runtime_error("ERROR: Inconsistent element declaration.\n");
1592 }
1593
1594 (*file) << strpr("%s, ", comment.c_str());
1595 (*file) << strpr("ATOM=%s", elementMap[elementOrder.at(0)].c_str());
1596 for (size_t i = 1; i < elementOrder.size(); ++i)
1597 {
1598 (*file) << strpr(" %s", elementMap[elementOrder.at(i)].c_str());
1599 }
1600 (*file) << "\n";
1601 (*file) << "1.0\n";
1602 if (isPeriodic)
1603 {
1604 (*file) << strpr("%24.16E %24.16E %24.16E\n",
1605 box[0][0], box[0][1], box[0][2]);
1606 (*file) << strpr("%24.16E %24.16E %24.16E\n",
1607 box[1][0], box[1][1], box[1][2]);
1608 (*file) << strpr("%24.16E %24.16E %24.16E\n",
1609 box[2][0], box[2][1], box[2][2]);
1610 }
1611 else
1612 {
1613 runtime_error("ERROR: Writing non-periodic structure to POSCAR file "
1614 "is not implemented.\n");
1615 }
1616 (*file) << strpr("%d", numAtomsPerElement.at(elementOrder.at(0)));
1617 for (size_t i = 1; i < numAtomsPerElement.size(); ++i)
1618 {
1619 (*file) << strpr(" %d", numAtomsPerElement.at(elementOrder.at(i)));
1620 }
1621 (*file) << "\n";
1622 (*file) << "Cartesian\n";
1623 for (size_t i = 0; i < elementOrder.size(); ++i)
1624 {
1625 for (vector<Atom>::const_iterator it = atoms.begin();
1626 it != atoms.end(); ++it)
1627 {
1628 if (it->element == elementOrder.at(i))
1629 {
1630 (*file) << strpr("%24.16E %24.16E %24.16E\n",
1631 it->r[0],
1632 it->r[1],
1633 it->r[2]);
1634 }
1635 }
1636 }
1637
1638 return;
1639}

References atoms, box, comment, elementMap, isPeriodic, numAtomsPerElement, nnp::ElementMap::size(), nnp::split(), and nnp::strpr().

Here is the call graph for this function:

◆ info()

vector< string > Structure::info ( ) const

Get structure information as a vector of strings.

Returns
Lines with structure information.

Definition at line 1641 of file Structure.cpp.

1642{
1643 vector<string> v;
1644
1645 v.push_back(strpr("********************************\n"));
1646 v.push_back(strpr("STRUCTURE \n"));
1647 v.push_back(strpr("********************************\n"));
1648 vector<string> vm = elementMap.info();
1649 v.insert(v.end(), vm.begin(), vm.end());
1650 v.push_back(strpr("index : %d\n", index));
1651 v.push_back(strpr("isPeriodic : %d\n", isPeriodic ));
1652 v.push_back(strpr("isTriclinic : %d\n", isTriclinic ));
1653 v.push_back(strpr("hasNeighborList : %d\n", hasNeighborList ));
1654 v.push_back(strpr("hasSymmetryFunctions : %d\n", hasSymmetryFunctions));
1655 v.push_back(strpr("hasSymmetryFunctionDerivatives : %d\n", hasSymmetryFunctionDerivatives));
1656 v.push_back(strpr("numAtoms : %d\n", numAtoms ));
1657 v.push_back(strpr("numElements : %d\n", numElements ));
1658 v.push_back(strpr("numElementsPresent : %d\n", numElementsPresent));
1659 v.push_back(strpr("pbc : %d %d %d\n", pbc[0], pbc[1], pbc[2]));
1660 v.push_back(strpr("energy : %16.8E\n", energy ));
1661 v.push_back(strpr("energyRef : %16.8E\n", energyRef ));
1662 v.push_back(strpr("charge : %16.8E\n", charge ));
1663 v.push_back(strpr("chargeRef : %16.8E\n", chargeRef ));
1664 v.push_back(strpr("volume : %16.8E\n", volume ));
1665 v.push_back(strpr("sampleType : %d\n", (int)sampleType));
1666 v.push_back(strpr("comment : %s\n", comment.c_str() ));
1667 v.push_back(strpr("box[0] : %16.8E %16.8E %16.8E\n", box[0][0], box[0][1], box[0][2]));
1668 v.push_back(strpr("box[1] : %16.8E %16.8E %16.8E\n", box[1][0], box[1][1], box[1][2]));
1669 v.push_back(strpr("box[2] : %16.8E %16.8E %16.8E\n", box[2][0], box[2][1], box[2][2]));
1670 v.push_back(strpr("invbox[0] : %16.8E %16.8E %16.8E\n", invbox[0][0], invbox[0][1], invbox[0][2]));
1671 v.push_back(strpr("invbox[1] : %16.8E %16.8E %16.8E\n", invbox[1][0], invbox[1][1], invbox[1][2]));
1672 v.push_back(strpr("invbox[2] : %16.8E %16.8E %16.8E\n", invbox[2][0], invbox[2][1], invbox[2][2]));
1673 v.push_back(strpr("--------------------------------\n"));
1674 v.push_back(strpr("numAtomsPerElement [*] : %d\n", numAtomsPerElement.size()));
1675 v.push_back(strpr("--------------------------------\n"));
1676 for (size_t i = 0; i < numAtomsPerElement.size(); ++i)
1677 {
1678 v.push_back(strpr("%29d : %d\n", i, numAtomsPerElement.at(i)));
1679 }
1680 v.push_back(strpr("--------------------------------\n"));
1681 v.push_back(strpr("--------------------------------\n"));
1682 v.push_back(strpr("atoms [*] : %d\n", atoms.size()));
1683 v.push_back(strpr("--------------------------------\n"));
1684 for (size_t i = 0; i < atoms.size(); ++i)
1685 {
1686 v.push_back(strpr("%29d :\n", i));
1687 vector<string> va = atoms[i].info();
1688 v.insert(v.end(), va.begin(), va.end());
1689 }
1690 v.push_back(strpr("--------------------------------\n"));
1691 v.push_back(strpr("********************************\n"));
1692
1693 return v;
1694}
std::vector< std::string > info() const
Get map information as a vector of strings.
Definition: ElementMap.cpp:125

References atoms, box, charge, chargeRef, comment, elementMap, energy, energyRef, hasNeighborList, hasSymmetryFunctionDerivatives, hasSymmetryFunctions, index, nnp::ElementMap::info(), invbox, isPeriodic, isTriclinic, numAtoms, numAtomsPerElement, numElements, numElementsPresent, pbc, sampleType, nnp::strpr(), and volume.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ elementMap

ElementMap nnp::Structure::elementMap

Copy of element map provided as constructor argument.

Definition at line 59 of file Structure.h.

Referenced by addAtom(), info(), readFromLines(), reset(), setElementMap(), writeToFile(), writeToFilePoscar(), and writeToFileXyz().

◆ isPeriodic

◆ isTriclinic

bool nnp::Structure::isTriclinic

◆ hasNeighborList

bool nnp::Structure::hasNeighborList

◆ NeighborListIsSorted

bool nnp::Structure::NeighborListIsSorted

If the neighbor list has been sorted by distance.

Definition at line 67 of file Structure.h.

Referenced by calculateElectrostaticEnergy(), setupNeighborCutoffMap(), and sortNeighborList().

◆ hasSymmetryFunctions

bool nnp::Structure::hasSymmetryFunctions

◆ hasSymmetryFunctionDerivatives

bool nnp::Structure::hasSymmetryFunctionDerivatives

◆ index

◆ numAtoms

◆ numElements

std::size_t nnp::Structure::numElements

Global number of elements (all structures).

Definition at line 77 of file Structure.h.

Referenced by calculateDQdJ(), clearNeighborList(), info(), main(), readFromLines(), nnp::Dataset::recvStructure(), reset(), nnp::Dataset::sendStructure(), and setElementMap().

◆ numElementsPresent

std::size_t nnp::Structure::numElementsPresent

Number of elements present in this structure.

Definition at line 79 of file Structure.h.

Referenced by info(), readFromLines(), nnp::Dataset::recvStructure(), reset(), and nnp::Dataset::sendStructure().

◆ pbc

int nnp::Structure::pbc[3]

Number of PBC images necessary in each direction for max cut-off.

Definition at line 81 of file Structure.h.

Referenced by calculateNeighborList(), calculatePbcCopies(), info(), nnp::Dataset::recvStructure(), reset(), nnp::Dataset::sendStructure(), and Structure().

◆ energy

◆ energyRef

◆ energyShort

double nnp::Structure::energyShort

Short-range part of the potential energy predicted by NNP.

Definition at line 88 of file Structure.h.

Referenced by nnp::Mode::calculateEnergy().

◆ energyElec

double nnp::Structure::energyElec

Electrostatics part of the potential energy predicted by NNP.

Definition at line 91 of file Structure.h.

Referenced by calculateElectrostaticEnergy(), nnp::Mode::calculateEnergy(), and main().

◆ hasCharges

bool nnp::Structure::hasCharges

If all charges of this structure have been calculated (and stay the same, e.g.

for stage 2).

Definition at line 94 of file Structure.h.

Referenced by calculateElectrostaticEnergy(), and nnp::Training::update().

◆ charge

double nnp::Structure::charge

Charge determined by neural network potential.

Definition at line 96 of file Structure.h.

Referenced by nnp::Mode::calculateCharge(), info(), main(), nnp::Dataset::recvStructure(), reset(), nnp::Dataset::sendStructure(), toNormalizedUnits(), toPhysicalUnits(), and writeToFile().

◆ chargeRef

◆ volume

double nnp::Structure::volume

◆ maxCutoffRadiusOverall

double nnp::Structure::maxCutoffRadiusOverall

Maximum cut-off radius with respect to symmetry functions, screening function and Ewald summation.

Definition at line 103 of file Structure.h.

Referenced by calculateMaxCutoffRadiusOverall(), calculateNeighborList(), nnp::InterfaceLammps::getMaxCutoffRadiusOverall(), and setupNeighborCutoffMap().

◆ lambda

double nnp::Structure::lambda

Lagrange multiplier used for charge equilibration.

Definition at line 106 of file Structure.h.

Referenced by calculateElectrostaticEnergy().

◆ sampleType

SampleType nnp::Structure::sampleType

Sample type (training or test set).

Definition at line 108 of file Structure.h.

Referenced by info(), readFromLines(), nnp::Dataset::recvStructure(), reset(), nnp::Training::selectSets(), and nnp::Dataset::sendStructure().

◆ comment

◆ box

◆ invbox

◆ A

◆ hasAMatrix

bool nnp::Structure::hasAMatrix

If A matrix of this structure is currently stored.

Definition at line 118 of file Structure.h.

Referenced by calculateElectrostaticEnergy(), clearElectrostatics(), and nnp::Training::update().

◆ numAtomsPerElement

◆ atoms

std::vector<Atom> nnp::Structure::atoms

Vector of all atoms in this structure.

Definition at line 122 of file Structure.h.

Referenced by addAtom(), nnp::InterfaceLammps::addNeighbor(), nnp::InterfaceLammps::allocateNeighborlists(), nnp::Mode::calculateAtomicNeuralNetworks(), nnp::Dataset::calculateBufferSize(), nnp::Mode::calculateCharge(), nnp::Training::calculateChargeErrorVec(), calculateDAdrQ(), calculateDQdJ(), calculateDQdr(), calculateElectrostaticEnergy(), calculateElectrostaticEnergyDerivatives(), nnp::Mode::calculateEnergy(), calculateForceLambdaElec(), calculateForceLambdaTotal(), nnp::Mode::calculateForces(), calculateNeighborList(), calculateScreeningEnergy(), nnp::Mode::calculateSymmetryFunctionGroups(), nnp::Mode::calculateSymmetryFunctions(), nnp::Training::calculateWeightDerivatives(), clearElectrostatics(), clearNeighborList(), LAMMPS_NS::PairHDNNPExternal::compute(), nnp::Training::dPdc(), nnp::Training::dPdcN(), nnp::Mode::evaluateNNP(), nnp::InterfaceLammps::finalizeNeighborList(), freeAtoms(), nnp::InterfaceLammps::getAtomicEnergy(), nnp::InterfaceLammps::getCharges(), getChargesLines(), nnp::InterfaceLammps::getForces(), getForcesLines(), getMaxNumNeighbors(), info(), main(), nnp::Dataset::prepareNumericForces(), readFromLines(), nnp::Dataset::recvStructure(), remap(), reset(), nnp::Training::selectSets(), nnp::Dataset::sendStructure(), nnp::InterfaceLammps::setLocalAtomPositions(), nnp::InterfaceLammps::setLocalAtoms(), nnp::InterfaceLammps::setLocalTags(), setupNeighborCutoffMap(), sortNeighborList(), nnp::Training::sortUpdateCandidates(), toNormalizedUnits(), toPhysicalUnits(), nnp::Training::update(), updateError(), writeToFile(), writeToFilePoscar(), and writeToFileXyz().


The documentation for this struct was generated from the following files: