n2p2 - A neural network potential package
nnp::Mode Class Reference

Base class for all NNP applications. More...

#include <Mode.h>

Inheritance diagram for nnp::Mode:
Collaboration diagram for nnp::Mode:

Classes

struct  NNSetup
 Setup data for one neural network. More...
 

Public Types

enum class  NNPType { HDNNP_2G = 2 , HDNNP_4G = 4 , HDNNP_Q = 10 }
 

Public Member Functions

 Mode ()
 
void initialize ()
 Write welcome message with version information. More...
 
void loadSettingsFile (std::string const &fileName="input.nn")
 Open settings file and load all keywords into memory. More...
 
void setupGeneric (std::string const &nnpDir="", bool skipNormalize=false, bool initialHardness=false)
 Combine multiple setup routines and provide a basic NNP setup. More...
 
void setupNormalization (bool standalone=true)
 Set up normalization. More...
 
virtual void setupElementMap ()
 Set up the element map. More...
 
virtual void setupElements ()
 Set up all Element instances. More...
 
void setupCutoff ()
 Set up cutoff function for all symmetry functions. More...
 
virtual void setupSymmetryFunctions ()
 Set up all symmetry functions. More...
 
void setupSymmetryFunctionScalingNone ()
 Set up "empy" symmetry function scaling. More...
 
virtual void setupSymmetryFunctionScaling (std::string const &fileName="scaling.data")
 Set up symmetry function scaling from file. More...
 
virtual void setupSymmetryFunctionGroups ()
 Set up symmetry function groups. More...
 
virtual void setupSymmetryFunctionCache (bool verbose=false)
 Set up symmetry function cache. More...
 
void setupSymmetryFunctionMemory (bool verbose=false)
 Extract required memory dimensions for symmetry function derivatives. More...
 
void setupSymmetryFunctionStatistics (bool collectStatistics, bool collectExtrapolationWarnings, bool writeExtrapolationWarnings, bool stopOnExtrapolationWarnings)
 Set up symmetry function statistics collection. More...
 
void setupCutoffMatrix ()
 Setup matrix storing all symmetry function cut-offs for each element. More...
 
virtual void setupNeuralNetwork ()
 Set up neural networks for all elements. More...
 
virtual void setupNeuralNetworkWeights (std::map< std::string, std::string > fileNameFormats=std::map< std::string, std::string >())
 Set up neural network weights from files with given name format. More...
 
virtual void setupNeuralNetworkWeights (std::string directoryPrefix, std::map< std::string, std::string > fileNameFormats=std::map< std::string, std::string >())
 Set up neural network weights from files with given name format. More...
 
virtual void setupElectrostatics (bool initialHardness=false, std::string directoryPrefix="", std::string fileNameFormat="hardness.%03zu.data")
 Set up electrostatics related stuff (hardness, screening, ...). More...
 
void calculateSymmetryFunctions (Structure &structure, bool const derivatives)
 Calculate all symmetry functions for all atoms in given structure. More...
 
void calculateSymmetryFunctionGroups (Structure &structure, bool const derivatives)
 Calculate all symmetry function groups for all atoms in given structure. More...
 
void calculateAtomicNeuralNetworks (Structure &structure, bool const derivatives, std::string id="")
 Calculate atomic neural networks for all atoms in given structure. More...
 
void chargeEquilibration (Structure &structure, bool const derivativesElec)
 Perform global charge equilibration method. More...
 
void calculateEnergy (Structure &structure) const
 Calculate potential energy for a given structure. More...
 
void calculateCharge (Structure &structure) const
 Calculate total charge for a given structure. More...
 
void calculateForces (Structure &structure) const
 Calculate forces for all atoms in given structure. More...
 
void evaluateNNP (Structure &structure, bool useForces=true, bool useDEdG=true)
 Evaluate neural network potential (includes total energy, optionally forces and in some cases charges. More...
 
void addEnergyOffset (Structure &structure, bool ref=true)
 Add atomic energy offsets to reference energy. More...
 
void removeEnergyOffset (Structure &structure, bool ref=true)
 Remove atomic energy offsets from reference energy. More...
 
double getEnergyOffset (Structure const &structure) const
 Get atomic energy offset for given structure. More...
 
double getEnergyWithOffset (Structure const &structure, bool ref=true) const
 Add atomic energy offsets and return energy. More...
 
double normalized (std::string const &property, double value) const
 Apply normalization to given property. More...
 
double normalizedEnergy (Structure const &structure, bool ref=true) const
 Apply normalization to given energy of structure. More...
 
double physical (std::string const &property, double value) const
 Undo normalization for a given property. More...
 
double physicalEnergy (Structure const &structure, bool ref=true) const
 Undo normalization for a given energy of structure. More...
 
void convertToNormalizedUnits (Structure &structure) const
 Convert one structure to normalized units. More...
 
void convertToPhysicalUnits (Structure &structure) const
 Convert one structure to physical units. More...
 
void logEwaldCutoffs ()
 Logs Ewald params whenever they change. More...
 
std::size_t getNumExtrapolationWarnings () const
 Count total number of extrapolation warnings encountered for all elements and symmetry functions. More...
 
void resetExtrapolationWarnings ()
 Erase all extrapolation warnings and reset counters. More...
 
NNPType getNnpType () const
 Getter for Mode::nnpType. More...
 
double getMeanEnergy () const
 Getter for Mode::meanEnergy. More...
 
double getConvEnergy () const
 Getter for Mode::convEnergy. More...
 
double getConvLength () const
 Getter for Mode::convLength. More...
 
double getConvCharge () const
 Getter for Mode::convCharge. More...
 
double getMaxCutoffRadius () const
 Getter for Mode::maxCutoffRadius. More...
 
std::size_t getNumElements () const
 Getter for Mode::numElements. More...
 
std::vector< std::size_t > getNumSymmetryFunctions () const
 Get number of symmetry functions per element. More...
 
bool useNormalization () const
 Check if normalization is enabled. More...
 
bool settingsKeywordExists (std::string const &keyword) const
 Check if keyword was found in settings file. More...
 
std::string settingsGetValue (std::string const &keyword) const
 Get value for given keyword in Settings instance. More...
 
std::vector< std::size_t > pruneSymmetryFunctionsRange (double threshold)
 Prune symmetry functions according to their range and write settings file. More...
 
std::vector< std::size_t > pruneSymmetryFunctionsSensitivity (double threshold, std::vector< std::vector< double > > sensitivity)
 Prune symmetry functions with sensitivity analysis data. More...
 
void writePrunedSettingsFile (std::vector< std::size_t > prune, std::string fileName="output.nn") const
 Copy settings file but comment out lines provided. More...
 
void writeSettingsFile (std::ofstream *const &file) const
 Write complete settings file. More...
 

Public Attributes

ElementMap elementMap
 Global element map, populated by setupElementMap(). More...
 
Log log
 Global log file. More...
 

Protected Member Functions

void readNeuralNetworkWeights (std::string const &id, std::string const &fileName)
 Read in weights for a specific type of neural network. More...
 

Protected Attributes

NNPType nnpType
 
bool normalize
 
bool checkExtrapolationWarnings
 
std::size_t numElements
 
std::vector< std::size_t > minNeighbors
 
std::vector< double > minCutoffRadius
 
double maxCutoffRadius
 
double cutoffAlpha
 
double meanEnergy
 
double convEnergy
 
double convLength
 
double convCharge
 
double fourPiEps
 
EwaldSetup ewaldSetup
 
settings::Settings settings
 
SymFnc::ScalingType scalingType
 
CutoffFunction::CutoffType cutoffType
 
ScreeningFunction screeningFunction
 
std::vector< Elementelements
 
std::vector< std::string > nnk
 
std::map< std::string, NNSetupnns
 
std::vector< std::vector< double > > cutoffs
 Matrix storing all symmetry function cut-offs for all elements. More...
 
ErfcBuf erfcBuf
 

Detailed Description

Base class for all NNP applications.

This top-level class is the anchor point for existing and future applications. It contains functions to set up an existing neural network potential and calculate energies and forces for configurations given as Structure. A minimal setup requires some consecutive functions calls as this minimal example shows:

Mode mode;
mode.initialize();
mode.setupCutoff();
mode.setupSymmetryFunctionStatistics(false, false, true, false);
Base class for all NNP applications.
Definition: Mode.h:87
void initialize()
Write welcome message with version information.
Definition: Mode.cpp:55
virtual void setupElementMap()
Set up the element map.
Definition: Mode.cpp:301
virtual void setupNeuralNetwork()
Set up neural networks for all elements.
Definition: Mode.cpp:1158
virtual void setupSymmetryFunctionGroups()
Set up symmetry function groups.
Definition: Mode.cpp:842
virtual void setupSymmetryFunctions()
Set up all symmetry functions.
Definition: Mode.cpp:615
void setupSymmetryFunctionStatistics(bool collectStatistics, bool collectExtrapolationWarnings, bool writeExtrapolationWarnings, bool stopOnExtrapolationWarnings)
Set up symmetry function statistics collection.
Definition: Mode.cpp:1103
void setupCutoff()
Set up cutoff function for all symmetry functions.
Definition: Mode.cpp:520
void loadSettingsFile(std::string const &fileName="input.nn")
Open settings file and load all keywords into memory.
Definition: Mode.cpp:161
virtual void setupElements()
Set up all Element instances.
Definition: Mode.cpp:322

To load weights and scaling information from files add these lines:

virtual void setupNeuralNetworkWeights(std::map< std::string, std::string > fileNameFormats=std::map< std::string, std::string >())
Set up neural network weights from files with given name format.
Definition: Mode.cpp:1445
virtual void setupSymmetryFunctionScaling(std::string const &fileName="scaling.data")
Set up symmetry function scaling from file.
Definition: Mode.cpp:712

The NNP is now ready! If we load a structure from a data file:

Structure structure;
ifstream file;
file.open("input.data");
structure.setupElementMap(mode.elementMap);
structure.readFromFile(file);
file.close();
ElementMap elementMap
Global element map, populated by setupElementMap().
Definition: Mode.h:591
Storage for one atomic configuration.
Definition: Structure.h:39
void readFromFile(std::string const fileName="input.data")
Read configuration from file.
Definition: Structure.cpp:97

we can finally predict the energy and forces from the neural network potential:

mode.calculateSymmetryFunctionGroups(structure, true);
mode.calculateAtomicNeuralNetworks(structure, true);
mode.calculateEnergy(structure);
mode.calculateForces(structure);
cout << structure.energy << '\n';
void calculateAtomicNeuralNetworks(Structure &structure, bool const derivatives, std::string id="")
Calculate atomic neural networks for all atoms in given structure.
Definition: Mode.cpp:1642
double getMaxCutoffRadius() const
Getter for Mode::maxCutoffRadius.
Definition: Mode.h:693
void calculateEnergy(Structure &structure) const
Calculate potential energy for a given structure.
Definition: Mode.cpp:1803
void calculateSymmetryFunctionGroups(Structure &structure, bool const derivatives)
Calculate all symmetry function groups for all atoms in given structure.
Definition: Mode.cpp:1561
void calculateForces(Structure &structure) const
Calculate forces for all atoms in given structure.
Definition: Mode.cpp:1849
double energy
Potential energy determined by neural network.
Definition: Structure.h:83
void calculateNeighborList(double cutoffRadius, bool sortByDistance=false)
Calculate neighbor list for all atoms.
Definition: Structure.cpp:287

The resulting potential energy is stored in Structure::energy, the forces on individual atoms are located within the Structure::atoms vector in Atom::f.

Definition at line 86 of file Mode.h.

Member Enumeration Documentation

◆ NNPType

enum class nnp::Mode::NNPType
strong
Enumerator
HDNNP_2G 

Short range NNP (2G-HDNNP).

HDNNP_4G 

NNP with electrostatics and non-local charge transfer (4G-HDNNP).

HDNNP_Q 

Short range NNP with charge NN, no electrostatics/Qeq (M.

Bircher).

   This is a simplified version of a 4G-HDNNP. Two neural networks are
   used: the first one predicts atomic charges, which will be used for
   the second NN as additional input neuron. There is no electrostatic
   energy and no global charge equilibration as in 4G-HDNNP.

Definition at line 89 of file Mode.h.

90 {
92 HDNNP_2G = 2,
94 HDNNP_4G = 4,
102 HDNNP_Q = 10
103 };

Constructor & Destructor Documentation

◆ Mode()

Mode::Mode ( )

Definition at line 40 of file Mode.cpp.

41 normalize (false ),
43 numElements (0 ),
44 maxCutoffRadius (0.0 ),
45 cutoffAlpha (0.0 ),
46 meanEnergy (0.0 ),
47 convEnergy (1.0 ),
48 convLength (1.0 ),
49 convCharge (1.0 ),
50 fourPiEps (1.0 ),
51 ewaldSetup {}
52{
53}
bool checkExtrapolationWarnings
Definition: Mode.h:630
bool normalize
Definition: Mode.h:629
double convEnergy
Definition: Mode.h:637
NNPType nnpType
Definition: Mode.h:628
double fourPiEps
Definition: Mode.h:640
double convLength
Definition: Mode.h:638
double maxCutoffRadius
Definition: Mode.h:634
@ HDNNP_2G
Short range NNP (2G-HDNNP).
double meanEnergy
Definition: Mode.h:636
std::size_t numElements
Definition: Mode.h:631
double convCharge
Definition: Mode.h:639
double cutoffAlpha
Definition: Mode.h:635
EwaldSetup ewaldSetup
Definition: Mode.h:641

Member Function Documentation

◆ initialize()

void Mode::initialize ( )

Write welcome message with version information.

Definition at line 55 of file Mode.cpp.

56{
57 log << "\n";
58 log << "*****************************************"
59 "**************************************\n";
60 log << "\n";
61 log << "WELCOME TO n²p², A SOFTWARE PACKAGE FOR NEURAL NETWORK "
62 "POTENTIALS!\n";
63 log << "-------------------------------------------------------"
64 "-----------\n";
65 log << "\n";
66 log << "n²p² version (from git): " N2P2_GIT_VERSION "\n";
67 log << " (version.h): " N2P2_VERSION "\n";
68 log << "------------------------------------------------------------\n";
69 log << "Git branch : " N2P2_GIT_BRANCH "\n";
70 log << "Git revision : " N2P2_GIT_REV "\n";
71 log << "Compile date/time : " __DATE__ " " __TIME__ "\n";
72 log << "------------------------------------------------------------\n";
73 log << "\n";
74 log << "Features/Flags:\n";
75 log << "------------------------------------------------------------\n";
76 log << "Symmetry function groups : ";
77#ifndef N2P2_NO_SF_GROUPS
78 log << "enabled\n";
79#else
80 log << "disabled\n";
81#endif
82 log << "Symmetry function cache : ";
83#ifndef N2P2_NO_SF_CACHE
84 log << "enabled\n";
85#else
86 log << "disabled\n";
87#endif
88 log << "Timing function available : ";
89#ifndef N2P2_NO_TIME
90 log << "available\n";
91#else
92 log << "disabled\n";
93#endif
94 log << "Asymmetric polynomial SFs : ";
95#ifndef N2P2_NO_ASYM_POLY
96 log << "available\n";
97#else
98 log << "disabled\n";
99#endif
100 log << "SF low neighbor number check : ";
101#ifndef N2P2_NO_NEIGH_CHECK
102 log << "enabled\n";
103#else
104 log << "disabled\n";
105#endif
106 log << "SF derivative memory layout : ";
107#ifndef N2P2_FULL_SFD_MEMORY
108 log << "reduced\n";
109#else
110 log << "full\n";
111#endif
112 log << "MPI explicitly disabled : ";
113#ifndef N2P2_NO_MPI
114 log << "no\n";
115#else
116 log << "yes\n";
117#endif
118#ifdef _OPENMP
119 log << strpr("OpenMP threads : %d\n", omp_get_max_threads());
120#endif
121 log << "------------------------------------------------------------\n";
122 log << "\n";
123
124 log << "Please cite the following papers when publishing results "
125 "obtained with n²p²:\n";
126 log << "-----------------------------------------"
127 "--------------------------------------\n";
128 log << " * General citation for n²p² and the LAMMPS interface:\n";
129 log << "\n";
130 log << " Singraber, A.; Behler, J.; Dellago, C.\n";
131 log << " Library-Based LAMMPS Implementation of High-Dimensional\n";
132 log << " Neural Network Potentials.\n";
133 log << " J. Chem. Theory Comput. 2019 15 (3), 1827–1840.\n";
134 log << " https://doi.org/10.1021/acs.jctc.8b00770\n";
135 log << "-----------------------------------------"
136 "--------------------------------------\n";
137 log << " * Additionally, if you use the NNP training features of n²p²:\n";
138 log << "\n";
139 log << " Singraber, A.; Morawietz, T.; Behler, J.; Dellago, C.\n";
140 log << " Parallel Multistream Training of High-Dimensional Neural\n";
141 log << " Network Potentials.\n";
142 log << " J. Chem. Theory Comput. 2019, 15 (5), 3075–3092.\n";
143 log << " https://doi.org/10.1021/acs.jctc.8b01092\n";
144 log << "-----------------------------------------"
145 "--------------------------------------\n";
146 log << " * Additionally, if polynomial symmetry functions are used:\n";
147 log << "\n";
148 log << " Bircher, M. P.; Singraber, A.; Dellago, C.\n";
149 log << " Improved Description of Atomic Environments Using Low-Cost\n";
150 log << " Polynomial Functions with Compact Support.\n";
151 log << " arXiv:2010.14414 [cond-mat, physics:physics] 2020.\n";
152 log << " https://arxiv.org/abs/2010.14414\n";
153
154
155 log << "*****************************************"
156 "**************************************\n";
157
158 return;
159}
Log log
Global log file.
Definition: Mode.h:593
string strpr(const char *format,...)
String version of printf function.
Definition: utility.cpp:90
#define N2P2_GIT_BRANCH
Definition: version.h:23
#define N2P2_GIT_VERSION
Definition: version.h:21
#define N2P2_VERSION
Definition: version.h:20
#define N2P2_GIT_REV
Definition: version.h:22

References log, N2P2_GIT_BRANCH, N2P2_GIT_REV, N2P2_GIT_VERSION, and N2P2_VERSION.

Referenced by nnp::InterfaceLammps::initialize(), main(), and nnp::Prediction::setup().

Here is the caller graph for this function:

◆ loadSettingsFile()

void Mode::loadSettingsFile ( std::string const &  fileName = "input.nn")

Open settings file and load all keywords into memory.

Parameters
[in]fileNameSettings file name.

Definition at line 161 of file Mode.cpp.

162{
163 log << "\n";
164 log << "*** SETUP: SETTINGS FILE ****************"
165 "**************************************\n";
166 log << "\n";
167
168 size_t numCriticalProblems = settings.loadFile(fileName);
169 log << settings.info();
170 if (numCriticalProblems > 0)
171 {
172 throw runtime_error(strpr("ERROR: %zu critical problem(s) were found "
173 "in settings file.\n", numCriticalProblems));
174 }
175
176 if (settings.keywordExists("nnp_type"))
177 {
178 string nnpTypeString = settings["nnp_type"];
179 if (nnpTypeString == "2G-HDNNP") nnpType = NNPType::HDNNP_2G;
180 else if (nnpTypeString == "4G-HDNNP") nnpType = NNPType::HDNNP_4G;
181 else if (nnpTypeString == "Q-HDNNP") nnpType = NNPType::HDNNP_Q;
182 else nnpType = (NNPType)atoi(settings["nnp_type"].c_str());
183 }
184
186 {
187 log << "This settings file defines a short-range NNP (2G-HDNNP).\n";
188 }
189 else if (nnpType == NNPType::HDNNP_4G)
190 {
191 log << "This settings file defines a NNP with electrostatics and\n"
192 "non-local charge transfer (4G-HDNNP).\n";
193 }
194 else if (nnpType == NNPType::HDNNP_Q)
195 {
196 log << "This settings file defines a short-range NNP similar to\n"
197 "4G-HDNNP with additional charge NN but with neither\n"
198 "electrostatics nor global charge equilibration\n"
199 "(method by M. Bircher).\n";
200 }
201 else
202 {
203 throw runtime_error("ERROR: Unknown NNP type.\n");
204 }
205
206 log << "*****************************************"
207 "**************************************\n";
208
209 return;
210}
NNPType
Definition: Mode.h:90
@ HDNNP_Q
Short range NNP with charge NN, no electrostatics/Qeq (M.
@ HDNNP_4G
NNP with electrostatics and non-local charge transfer (4G-HDNNP).
settings::Settings settings
Definition: Mode.h:642
std::vector< std::string > info() const
Get logged information about settings file.
Definition: Settings.cpp:266
std::size_t loadFile(std::string const &fileName="input.nn")
Load a file with settings.
Definition: Settings.cpp:187
bool keywordExists(Key const &key, bool const exact=false) const override
Definition: Settings.cpp:194

References HDNNP_2G, HDNNP_4G, HDNNP_Q, nnp::settings::Settings::info(), nnp::settings::Settings::keywordExists(), nnp::settings::Settings::loadFile(), log, nnpType, settings, and nnp::strpr().

Referenced by nnp::InterfaceLammps::initialize(), main(), and nnp::Prediction::setup().

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

◆ setupGeneric()

void Mode::setupGeneric ( std::string const &  nnpDir = "",
bool  skipNormalize = false,
bool  initialHardness = false 
)

Combine multiple setup routines and provide a basic NNP setup.

Parameters
[in]nnpDirOptional directory where NNP files reside.
[in]skipNormalizeWhether to skip normalization setup.
[in]initialHardnessSignalizes to use initial hardness in NN settings.

Sets up elements, symmetry functions, symmetry function groups, neural networks. No symmetry function scaling data is read, no weights are set.

Definition at line 212 of file Mode.cpp.

215{
216 if (!skipNormalize) setupNormalization();
220 setupElectrostatics(initialHardness, nnpDir);
221 setupCutoff();
224#ifndef N2P2_FULL_SFD_MEMORY
226#endif
227#ifndef N2P2_NO_SF_CACHE
229#endif
230#ifndef N2P2_NO_SF_GROUPS
232#endif
234
235 return;
236}
void setupNormalization(bool standalone=true)
Set up normalization.
Definition: Mode.cpp:238
virtual void setupSymmetryFunctionCache(bool verbose=false)
Set up symmetry function cache.
Definition: Mode.cpp:984
virtual void setupElectrostatics(bool initialHardness=false, std::string directoryPrefix="", std::string fileNameFormat="hardness.%03zu.data")
Set up electrostatics related stuff (hardness, screening, ...).
Definition: Mode.cpp:368
void setupCutoffMatrix()
Setup matrix storing all symmetry function cut-offs for each element.
Definition: Mode.cpp:1143
void setupSymmetryFunctionMemory(bool verbose=false)
Extract required memory dimensions for symmetry function derivatives.
Definition: Mode.cpp:894

References HDNNP_4G, nnpType, setupCutoff(), setupCutoffMatrix(), setupElectrostatics(), setupElementMap(), setupElements(), setupNeuralNetwork(), setupNormalization(), setupSymmetryFunctionCache(), setupSymmetryFunctionGroups(), setupSymmetryFunctionMemory(), and setupSymmetryFunctions().

Referenced by nnp::InterfaceLammps::initialize(), main(), and nnp::Prediction::setup().

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

◆ setupNormalization()

void Mode::setupNormalization ( bool  standalone = true)

Set up normalization.

Parameters
[in]standaloneWhether to write section header and footer.

If the keywords mean_energy, conv_length and conv_length are present, the provided conversion factors are used to internally use a different unit system.

Definition at line 238 of file Mode.cpp.

239{
240 if (standalone)
241 {
242 log << "\n";
243 log << "*** SETUP: NORMALIZATION ****************"
244 "**************************************\n";
245 log << "\n";
246 }
247
248 if (settings.keywordExists("mean_energy") &&
249 settings.keywordExists("conv_energy") &&
250 settings.keywordExists("conv_length"))
251 {
252 normalize = true;
253 meanEnergy = atof(settings["mean_energy"].c_str());
254 convEnergy = atof(settings["conv_energy"].c_str());
255 convLength = atof(settings["conv_length"].c_str());
256
257 log << "Data set normalization is used.\n";
258 log << strpr("Mean energy per atom : %24.16E\n", meanEnergy);
259 log << strpr("Conversion factor energy : %24.16E\n", convEnergy);
260 log << strpr("Conversion factor length : %24.16E\n", convLength);
261 if (settings.keywordExists("conv_charge"))
262 {
263 convCharge = atof(settings["conv_charge"].c_str());
264 log << strpr("Conversion factor charge : %24.16E\n",
265 convCharge);
266 }
267 if (settings.keywordExists("atom_energy"))
268 {
269 log << "\n";
270 log << "Atomic energy offsets are used in addition to"
271 " data set normalization.\n";
272 log << "Offsets will be subtracted from reference energies BEFORE"
273 " normalization is applied.\n";
274 }
275 }
276 else if ((!settings.keywordExists("mean_energy")) &&
277 (!settings.keywordExists("conv_energy")) &&
278 (!settings.keywordExists("conv_length")) &&
279 (!settings.keywordExists("conv_charge")))
280 {
281 normalize = false;
282 log << "Data set normalization is not used.\n";
283 }
284 else
285 {
286 throw runtime_error("ERROR: Incorrect usage of normalization"
287 " keywords.\n"
288 " Use all or none of \"mean_energy\", \"conv_energy\""
289 " and \"conv_length\".\n");
290 }
291
292 if (standalone)
293 {
294 log << "*****************************************"
295 "**************************************\n";
296 }
297
298 return;
299}

References convCharge, convEnergy, convLength, nnp::settings::Settings::keywordExists(), log, meanEnergy, normalize, settings, and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), and setupGeneric().

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

◆ setupElementMap()

void Mode::setupElementMap ( )
virtual

Set up the element map.

Uses keyword elements. This function should follow immediately after settings are loaded via loadSettingsFile().

Reimplemented in nnp::ModeCabana< t_device >.

Definition at line 301 of file Mode.cpp.

302{
303 log << "\n";
304 log << "*** SETUP: ELEMENT MAP ******************"
305 "**************************************\n";
306 log << "\n";
307
309 log << strpr("Number of element strings found: %d\n", elementMap.size());
310 for (size_t i = 0; i < elementMap.size(); ++i)
311 {
312 log << strpr("Element %2zu: %2s (%3zu)\n", i, elementMap[i].c_str(),
314 }
315
316 log << "*****************************************"
317 "**************************************\n";
318
319 return;
320}
std::size_t registerElements(std::string const &elementLine)
Extract all elements and store in element map.
Definition: ElementMap.cpp:36
std::size_t size() const
Get element map size.
Definition: ElementMap.h:140
std::size_t atomicNumber(std::size_t index) const
Get atomic number from element index.
Definition: ElementMap.h:145

References nnp::ElementMap::atomicNumber(), elementMap, log, nnp::ElementMap::registerElements(), settings, nnp::ElementMap::size(), and nnp::strpr().

Referenced by main(), and setupGeneric().

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

◆ setupElements()

void Mode::setupElements ( )
virtual

Set up all Element instances.

Uses keywords number_of_elements and atom_energy. This function should follow immediately after setupElementMap().

Reimplemented in nnp::ModeCabana< t_device >.

Definition at line 322 of file Mode.cpp.

323{
324 log << "\n";
325 log << "*** SETUP: ELEMENTS *********************"
326 "**************************************\n";
327 log << "\n";
328
329 numElements = (size_t)atoi(settings["number_of_elements"].c_str());
330 if (numElements != elementMap.size())
331 {
332 throw runtime_error("ERROR: Inconsistent number of elements.\n");
333 }
334 log << strpr("Number of elements is consistent: %zu\n", numElements);
335
336 for (size_t i = 0; i < numElements; ++i)
337 {
338 elements.push_back(Element(i, elementMap));
339 }
340
341 if (settings.keywordExists("atom_energy"))
342 {
344 for (settings::Settings::KeyMap::const_iterator it = r.first;
345 it != r.second; ++it)
346 {
347 vector<string> args = split(reduce(it->second.first));
348 size_t element = elementMap[args.at(0)];
349 elements.at(element).
350 setAtomicEnergyOffset(atof(args.at(1).c_str()));
351 }
352 }
353 log << "Atomic energy offsets per element:\n";
354 for (size_t i = 0; i < elementMap.size(); ++i)
355 {
356 log << strpr("Element %2zu: %16.8E\n",
357 i, elements.at(i).getAtomicEnergyOffset());
358 }
359 log << "Energy offsets are automatically subtracted from reference "
360 "energies.\n";
361
362 log << "*****************************************"
363 "**************************************\n";
364
365 return;
366}
Contains element-specific data.
Definition: Element.h:39
std::vector< Element > elements
Definition: Mode.h:646
std::pair< KeyMap::const_iterator, KeyMap::const_iterator > KeyRange
Definition: Settings.h:44
KeyRange getValues(std::string const &keyword) const
Get all keyword-value pairs for given keyword.
Definition: Settings.cpp:261
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

References elementMap, elements, nnp::settings::Settings::getValues(), nnp::settings::Settings::keywordExists(), log, numElements, nnp::reduce(), settings, nnp::ElementMap::size(), nnp::split(), and nnp::strpr().

Referenced by main(), and setupGeneric().

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

◆ setupCutoff()

void Mode::setupCutoff ( )

Set up cutoff function for all symmetry functions.

Uses keyword cutoff_type. Cutoff parameters are read from settings keywords and stored internally. As soon as setupSymmetryFunctions() is called the settings are restored and used for all symmetry functions. Thus, this function must be called before setupSymmetryFunctions().

Definition at line 520 of file Mode.cpp.

521{
522 log << "\n";
523 log << "*** SETUP: CUTOFF FUNCTIONS *************"
524 "**************************************\n";
525 log << "\n";
526
527 vector<string> args = split(settings["cutoff_type"]);
528
529 cutoffType = (CutoffFunction::CutoffType) atoi(args.at(0).c_str());
530 if (args.size() > 1)
531 {
532 cutoffAlpha = atof(args.at(1).c_str());
533 if (0.0 < cutoffAlpha && cutoffAlpha >= 1.0)
534 {
535 throw invalid_argument("ERROR: 0 <= alpha < 1.0 is required.\n");
536 }
537 }
538 log << strpr("Parameter alpha for inner cutoff: %f\n", cutoffAlpha);
539 log << "Inner cutoff = Symmetry function cutoff * alpha\n";
540
541 log << "Equal cutoff function type for all symmetry functions:\n";
543 {
544 log << strpr("CutoffFunction::CT_COS (%d)\n", cutoffType);
545 log << "x := (r - rc * alpha) / (rc - rc * alpha)\n";
546 log << "f(x) = 1/2 * (cos(pi*x) + 1)\n";
547 }
549 {
550 log << strpr("CutoffFunction::CT_TANHU (%d)\n", cutoffType);
551 log << "f(r) = tanh^3(1 - r/rc)\n";
552 if (cutoffAlpha > 0.0)
553 {
554 log << "WARNING: Inner cutoff parameter not used in combination"
555 " with this cutoff function.\n";
556 }
557 }
559 {
560 log << strpr("CutoffFunction::CT_TANH (%d)\n", cutoffType);
561 log << "f(r) = c * tanh^3(1 - r/rc), f(0) = 1\n";
562 if (cutoffAlpha > 0.0)
563 {
564 log << "WARNING: Inner cutoff parameter not used in combination"
565 " with this cutoff function.\n";
566 }
567 }
569 {
570 log << strpr("CutoffFunction::CT_POLY1 (%d)\n", cutoffType);
571 log << "x := (r - rc * alpha) / (rc - rc * alpha)\n";
572 log << "f(x) = (2x - 3)x^2 + 1\n";
573 }
575 {
576 log << strpr("CutoffFunction::CT_POLY2 (%d)\n", cutoffType);
577 log << "x := (r - rc * alpha) / (rc - rc * alpha)\n";
578 log << "f(x) = ((15 - 6x)x - 10)x^3 + 1\n";
579 }
581 {
582 log << strpr("CutoffFunction::CT_POLY3 (%d)\n", cutoffType);
583 log << "x := (r - rc * alpha) / (rc - rc * alpha)\n";
584 log << "f(x) = (x(x(20x - 70) + 84) - 35)x^4 + 1\n";
585 }
587 {
588 log << strpr("CutoffFunction::CT_POLY4 (%d)\n", cutoffType);
589 log << "x := (r - rc * alpha) / (rc - rc * alpha)\n";
590 log << "f(x) = (x(x((315 - 70x)x - 540) + 420) - 126)x^5 + 1\n";
591 }
593 {
594 log << strpr("CutoffFunction::CT_EXP (%d)\n", cutoffType);
595 log << "x := (r - rc * alpha) / (rc - rc * alpha)\n";
596 log << "f(x) = exp(-1 / 1 - x^2)\n";
597 }
599 {
600 log << strpr("CutoffFunction::CT_HARD (%d)\n", cutoffType);
601 log << "f(r) = 1\n";
602 log << "WARNING: Hard cutoff used!\n";
603 }
604 else
605 {
606 throw invalid_argument("ERROR: Unknown cutoff type.\n");
607 }
608
609 log << "*****************************************"
610 "**************************************\n";
611
612 return;
613}
CutoffType
List of available cutoff function types.
CutoffFunction::CutoffType cutoffType
Definition: Mode.h:644

References nnp::CutoffFunction::CT_COS, nnp::CutoffFunction::CT_EXP, nnp::CutoffFunction::CT_HARD, nnp::CutoffFunction::CT_POLY1, nnp::CutoffFunction::CT_POLY2, nnp::CutoffFunction::CT_POLY3, nnp::CutoffFunction::CT_POLY4, nnp::CutoffFunction::CT_TANH, nnp::CutoffFunction::CT_TANHU, cutoffAlpha, cutoffType, log, settings, nnp::split(), and nnp::strpr().

Referenced by main(), and setupGeneric().

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

◆ setupSymmetryFunctions()

void Mode::setupSymmetryFunctions ( )
virtual

Set up all symmetry functions.

Uses keyword symfunction_short. Reads all symmetry functions from settings and automatically assigns them to the correct element.

Reimplemented in nnp::ModeCabana< t_device >.

Definition at line 615 of file Mode.cpp.

616{
617 log << "\n";
618 log << "*** SETUP: SYMMETRY FUNCTIONS ***********"
619 "**************************************\n";
620 log << "\n";
621
622 settings::Settings::KeyRange r = settings.getValues("symfunction_short");
623 for (settings::Settings::KeyMap::const_iterator it = r.first; it != r.second; ++it)
624 {
625 vector<string> args = split(reduce(it->second.first));
626 size_t element = elementMap[args.at(0)];
627
628 elements.at(element).addSymmetryFunction(it->second.first,
629 it->second.second);
630 }
631
632 log << "Abbreviations:\n";
633 log << "--------------\n";
634 log << "ind .... Symmetry function index.\n";
635 log << "ec ..... Central atom element.\n";
636 log << "tp ..... Symmetry function type.\n";
637 log << "sbtp ... Symmetry function subtype (e.g. cutoff type).\n";
638 log << "e1 ..... Neighbor 1 element.\n";
639 log << "e2 ..... Neighbor 2 element.\n";
640 log << "eta .... Gaussian width eta.\n";
641 log << "rs/rl... Shift distance of Gaussian or left cutoff radius "
642 "for polynomial.\n";
643 log << "angl.... Left cutoff angle for polynomial.\n";
644 log << "angr.... Right cutoff angle for polynomial.\n";
645 log << "la ..... Angle prefactor lambda.\n";
646 log << "zeta ... Angle term exponent zeta.\n";
647 log << "rc ..... Cutoff radius / right cutoff radius for polynomial.\n";
648 log << "a ...... Free parameter alpha (e.g. cutoff alpha).\n";
649 log << "ln ..... Line number in settings file.\n";
650 log << "\n";
651 maxCutoffRadius = 0.0;
652 for (vector<Element>::iterator it = elements.begin();
653 it != elements.end(); ++it)
654 {
655 if (normalize) it->changeLengthUnitSymmetryFunctions(convLength);
656 it->sortSymmetryFunctions();
657 maxCutoffRadius = max(it->getMaxCutoffRadius(), maxCutoffRadius);
658 it->setCutoffFunction(cutoffType, cutoffAlpha);
659 log << strpr("Short range atomic symmetry functions element %2s :\n",
660 it->getSymbol().c_str());
661 log << "--------------------------------------------------"
662 "-----------------------------------------------\n";
663 log << " ind ec tp sbtp e1 e2 eta rs/rl "
664 "rc angl angr la zeta a ln\n";
665 log << "--------------------------------------------------"
666 "-----------------------------------------------\n";
667 log << it->infoSymmetryFunctionParameters();
668 log << "--------------------------------------------------"
669 "-----------------------------------------------\n";
670 }
671 minNeighbors.clear();
672 minNeighbors.resize(numElements, 0);
673 minCutoffRadius.clear();
675 for (size_t i = 0; i < numElements; ++i)
676 {
677 minNeighbors.at(i) = elements.at(i).getMinNeighbors();
678 minCutoffRadius.at(i) = elements.at(i).getMinCutoffRadius();
679 log << strpr("Minimum cutoff radius for element %2s: %f\n",
680 elements.at(i).getSymbol().c_str(),
682 }
683 log << strpr("Maximum cutoff radius (global) : %f\n",
685
686 log << "*****************************************"
687 "**************************************\n";
688
689 return;
690}
std::vector< double > minCutoffRadius
Definition: Mode.h:633
std::vector< std::size_t > minNeighbors
Definition: Mode.h:632

References convLength, cutoffAlpha, cutoffType, elementMap, elements, nnp::settings::Settings::getValues(), log, maxCutoffRadius, minCutoffRadius, minNeighbors, normalize, numElements, nnp::reduce(), settings, nnp::split(), and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), main(), and setupGeneric().

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

◆ setupSymmetryFunctionScalingNone()

void Mode::setupSymmetryFunctionScalingNone ( )

Set up "empy" symmetry function scaling.

Does not use any keywords. Sets no scaling for all symmetry functions. Call after setupSymmetryFunctions(). Alternatively set scaling via setupSymmetryFunctionScaling().

Definition at line 692 of file Mode.cpp.

693{
694 log << "\n";
695 log << "*** SETUP: SYMMETRY FUNCTION SCALING ****"
696 "**************************************\n";
697 log << "\n";
698
699 log << "No scaling for symmetry functions.\n";
700 for (vector<Element>::iterator it = elements.begin();
701 it != elements.end(); ++it)
702 {
703 it->setScalingNone();
704 }
705
706 log << "*****************************************"
707 "**************************************\n";
708
709 return;
710}

References elements, and log.

Referenced by main().

Here is the caller graph for this function:

◆ setupSymmetryFunctionScaling()

void Mode::setupSymmetryFunctionScaling ( std::string const &  fileName = "scaling.data")
virtual

Set up symmetry function scaling from file.

Parameters
[in]fileNameScaling file name.

Uses keywords scale_symmetry_functions, center_symmetry_functions, scale_symmetry_functions_sigma, scale_min_short and scale_max_short. Reads in scaling information and sets correct scaling behavior for all symmetry functions. Call after setupSymmetryFunctions().

Reimplemented in nnp::ModeCabana< t_device >.

Definition at line 712 of file Mode.cpp.

713{
714 log << "\n";
715 log << "*** SETUP: SYMMETRY FUNCTION SCALING ****"
716 "**************************************\n";
717 log << "\n";
718
719 log << "Equal scaling type for all symmetry functions:\n";
720 if ( ( settings.keywordExists("scale_symmetry_functions" ))
721 && (!settings.keywordExists("center_symmetry_functions")))
722 {
724 log << strpr("Scaling type::ST_SCALE (%d)\n", scalingType);
725 log << "Gs = Smin + (Smax - Smin) * (G - Gmin) / (Gmax - Gmin)\n";
726 }
727 else if ( (!settings.keywordExists("scale_symmetry_functions" ))
728 && ( settings.keywordExists("center_symmetry_functions")))
729 {
731 log << strpr("Scaling type::ST_CENTER (%d)\n", scalingType);
732 log << "Gs = G - Gmean\n";
733 }
734 else if ( ( settings.keywordExists("scale_symmetry_functions" ))
735 && ( settings.keywordExists("center_symmetry_functions")))
736 {
738 log << strpr("Scaling type::ST_SCALECENTER (%d)\n", scalingType);
739 log << "Gs = Smin + (Smax - Smin) * (G - Gmean) / (Gmax - Gmin)\n";
740 }
741 else if (settings.keywordExists("scale_symmetry_functions_sigma"))
742 {
744 log << strpr("Scaling type::ST_SCALESIGMA (%d)\n", scalingType);
745 log << "Gs = Smin + (Smax - Smin) * (G - Gmean) / Gsigma\n";
746 }
747 else
748 {
750 log << strpr("Scaling type::ST_NONE (%d)\n", scalingType);
751 log << "Gs = G\n";
752 log << "WARNING: No symmetry function scaling!\n";
753 }
754
755 double Smin = 0.0;
756 double Smax = 0.0;
760 {
761 if (settings.keywordExists("scale_min_short"))
762 {
763 Smin = atof(settings["scale_min_short"].c_str());
764 }
765 else
766 {
767 log << "WARNING: Keyword \"scale_min_short\" not found.\n";
768 log << " Default value for Smin = 0.0.\n";
769 Smin = 0.0;
770 }
771
772 if (settings.keywordExists("scale_max_short"))
773 {
774 Smax = atof(settings["scale_max_short"].c_str());
775 }
776 else
777 {
778 log << "WARNING: Keyword \"scale_max_short\" not found.\n";
779 log << " Default value for Smax = 1.0.\n";
780 Smax = 1.0;
781 }
782
783 log << strpr("Smin = %f\n", Smin);
784 log << strpr("Smax = %f\n", Smax);
785 }
786
787 log << strpr("Symmetry function scaling statistics from file: %s\n",
788 fileName.c_str());
789 log << "-----------------------------------------"
790 "--------------------------------------\n";
791 ifstream file;
792 file.open(fileName.c_str());
793 if (!file.is_open())
794 {
795 throw runtime_error("ERROR: Could not open file: \"" + fileName
796 + "\".\n");
797 }
798 string line;
799 vector<string> lines;
800 while (getline(file, line))
801 {
802 if (line.at(0) != '#') lines.push_back(line);
803 }
804 file.close();
805
806 log << "\n";
807 log << "Abbreviations:\n";
808 log << "--------------\n";
809 log << "ind ..... Symmetry function index.\n";
810 log << "min ..... Minimum symmetry function value.\n";
811 log << "max ..... Maximum symmetry function value.\n";
812 log << "mean .... Mean symmetry function value.\n";
813 log << "sigma ... Standard deviation of symmetry function values.\n";
814 log << "sf ...... Scaling factor for derivatives.\n";
815 log << "Smin .... Desired minimum scaled symmetry function value.\n";
816 log << "Smax .... Desired maximum scaled symmetry function value.\n";
817 log << "t ....... Scaling type.\n";
818 log << "\n";
819 for (vector<Element>::iterator it = elements.begin();
820 it != elements.end(); ++it)
821 {
822 it->setScaling(scalingType, lines, Smin, Smax);
823 log << strpr("Scaling data for symmetry functions element %2s :\n",
824 it->getSymbol().c_str());
825 log << "-----------------------------------------"
826 "--------------------------------------\n";
827 log << " ind min max mean sigma sf Smin Smax t\n";
828 log << "-----------------------------------------"
829 "--------------------------------------\n";
830 log << it->infoSymmetryFunctionScaling();
831 log << "-----------------------------------------"
832 "--------------------------------------\n";
833 lines.erase(lines.begin(), lines.begin() + it->numSymmetryFunctions());
834 }
835
836 log << "*****************************************"
837 "**************************************\n";
838
839 return;
840}
SymFnc::ScalingType scalingType
Definition: Mode.h:643
@ ST_NONE
Definition: SymFnc.h:47
@ ST_SCALESIGMA
Definition: SymFnc.h:64
@ ST_SCALECENTER
Definition: SymFnc.h:60
@ ST_CENTER
Definition: SymFnc.h:55
@ ST_SCALE
Definition: SymFnc.h:52

References elements, nnp::settings::Settings::keywordExists(), log, scalingType, settings, nnp::SymFnc::ST_CENTER, nnp::SymFnc::ST_NONE, nnp::SymFnc::ST_SCALE, nnp::SymFnc::ST_SCALECENTER, nnp::SymFnc::ST_SCALESIGMA, and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), nnp::InterfaceLammps::initialize(), main(), and nnp::Prediction::setup().

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

◆ setupSymmetryFunctionGroups()

void Mode::setupSymmetryFunctionGroups ( )
virtual

Set up symmetry function groups.

Does not use any keywords. Call after setupSymmetryFunctions() and ensure that correct scaling behavior has already been set.

Reimplemented in nnp::ModeCabana< t_device >.

Definition at line 842 of file Mode.cpp.

843{
844 log << "\n";
845 log << "*** SETUP: SYMMETRY FUNCTION GROUPS *****"
846 "**************************************\n";
847 log << "\n";
848
849 log << "Abbreviations:\n";
850 log << "--------------\n";
851 log << "ind .... Symmetry function index.\n";
852 log << "ec ..... Central atom element.\n";
853 log << "tp ..... Symmetry function type.\n";
854 log << "sbtp ... Symmetry function subtype (e.g. cutoff type).\n";
855 log << "e1 ..... Neighbor 1 element.\n";
856 log << "e2 ..... Neighbor 2 element.\n";
857 log << "eta .... Gaussian width eta.\n";
858 log << "rs/rl... Shift distance of Gaussian or left cutoff radius "
859 "for polynomial.\n";
860 log << "angl.... Left cutoff angle for polynomial.\n";
861 log << "angr.... Right cutoff angle for polynomial.\n";
862 log << "la ..... Angle prefactor lambda.\n";
863 log << "zeta ... Angle term exponent zeta.\n";
864 log << "rc ..... Cutoff radius / right cutoff radius for polynomial.\n";
865 log << "a ...... Free parameter alpha (e.g. cutoff alpha).\n";
866 log << "ln ..... Line number in settings file.\n";
867 log << "mi ..... Member index.\n";
868 log << "sfi .... Symmetry function index.\n";
869 log << "e ...... Recalculate exponential term.\n";
870 log << "\n";
871 for (vector<Element>::iterator it = elements.begin();
872 it != elements.end(); ++it)
873 {
874 it->setupSymmetryFunctionGroups();
875 log << strpr("Short range atomic symmetry function groups "
876 "element %2s :\n", it->getSymbol().c_str());
877 log << "------------------------------------------------------"
878 "----------------------------------------------------\n";
879 log << " ind ec tp sbtp e1 e2 eta rs/rl "
880 "rc angl angr la zeta a ln mi sfi e\n";
881 log << "------------------------------------------------------"
882 "----------------------------------------------------\n";
883 log << it->infoSymmetryFunctionGroups();
884 log << "------------------------------------------------------"
885 "----------------------------------------------------\n";
886 }
887
888 log << "*****************************************"
889 "**************************************\n";
890
891 return;
892}

References elements, log, and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), and setupGeneric().

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

◆ setupSymmetryFunctionCache()

void Mode::setupSymmetryFunctionCache ( bool  verbose = false)
virtual

Set up symmetry function cache.

Parameters
[in]verboseIf true, print more cache information.

Searches symmetry functions for identical cutoff functions or compact function (i.e. all cachable stuff) and sets up a caching index.

Definition at line 984 of file Mode.cpp.

985{
986 log << "\n";
987 log << "*** SETUP: SYMMETRY FUNCTION CACHE ******"
988 "**************************************\n";
989 log << "\n";
990
991 for (size_t i = 0; i < numElements; ++i)
992 {
993 using SFCacheList = Element::SFCacheList;
994 vector<vector<SFCacheList>> cacheLists(numElements);
995 Element& e = elements.at(i);
996 for (size_t j = 0; j < e.numSymmetryFunctions(); ++j)
997 {
998 SymFnc const& s = e.getSymmetryFunction(j);
999 for (auto identifier : s.getCacheIdentifiers())
1000 {
1001 size_t ne = atoi(split(identifier)[0].c_str());
1002 bool unknown = true;
1003 for (auto& c : cacheLists.at(ne))
1004 {
1005 if (identifier == c.identifier)
1006 {
1007 c.indices.push_back(s.getIndex());
1008 unknown = false;
1009 break;
1010 }
1011 }
1012 if (unknown)
1013 {
1014 cacheLists.at(ne).push_back(SFCacheList());
1015 cacheLists.at(ne).back().element = ne;
1016 cacheLists.at(ne).back().identifier = identifier;
1017 cacheLists.at(ne).back().indices.push_back(s.getIndex());
1018 }
1019 }
1020 }
1021 if (verbose)
1022 {
1023 log << strpr("Multiple cache identifiers for element %2s:\n\n",
1024 e.getSymbol().c_str());
1025 }
1026 double cacheUsageMean = 0.0;
1027 size_t cacheCount = 0;
1028 for (size_t j = 0; j < numElements; ++j)
1029 {
1030 if (verbose)
1031 {
1032 log << strpr("Neighbor %2s:\n", elementMap[j].c_str());
1033 }
1034 vector<SFCacheList>& c = cacheLists.at(j);
1035 c.erase(remove_if(c.begin(),
1036 c.end(),
1037 [](SFCacheList l)
1038 {
1039 return l.indices.size() <= 1;
1040 }), c.end());
1041 cacheCount += c.size();
1042 for (size_t k = 0; k < c.size(); ++k)
1043 {
1044 cacheUsageMean += c.at(k).indices.size();
1045 if (verbose)
1046 {
1047 log << strpr("Cache %zu, Identifier \"%s\", "
1048 "Symmetry functions",
1049 k, c.at(k).identifier.c_str());
1050 for (auto si : c.at(k).indices)
1051 {
1052 log << strpr(" %zu", si);
1053 }
1054 log << "\n";
1055 }
1056 }
1057 }
1058 e.setCacheIndices(cacheLists);
1059 //for (size_t j = 0; j < e.numSymmetryFunctions(); ++j)
1060 //{
1061 // SymFnc const& sf = e.getSymmetryFunction(j);
1062 // auto indices = sf.getCacheIndices();
1063 // size_t count = 0;
1064 // for (size_t k = 0; k < numElements; ++k)
1065 // {
1066 // count += indices.at(k).size();
1067 // }
1068 // if (count > 0)
1069 // {
1070 // log << strpr("SF %4zu:\n", sf.getIndex());
1071 // }
1072 // for (size_t k = 0; k < numElements; ++k)
1073 // {
1074 // if (indices.at(k).size() > 0)
1075 // {
1076 // log << strpr("- Neighbor %2s:", elementMap[k].c_str());
1077 // for (size_t l = 0; l < indices.at(k).size(); ++l)
1078 // {
1079 // log << strpr(" %zu", indices.at(k).at(l));
1080 // }
1081 // log << "\n";
1082 // }
1083 // }
1084 //}
1085 cacheUsageMean /= cacheCount;
1086 log << strpr("Element %2s: in total %zu caches, "
1087 "used %3.2f times on average.\n",
1088 e.getSymbol().c_str(), cacheCount, cacheUsageMean);
1089 if (verbose)
1090 {
1091 log << "-----------------------------------------"
1092 "--------------------------------------\n";
1093 }
1094 }
1095
1096 log << "*****************************************"
1097 "**************************************\n";
1098
1099 return;
1100}
void setCacheIndices(std::vector< std::vector< SFCacheList > > cacheLists)
Set cache indices for all symmetry functions of this element.
Definition: Element.cpp:544
SymFnc const & getSymmetryFunction(std::size_t index) const
Get symmetry function instance.
Definition: Element.h:358
std::string getSymbol() const
Get symbol.
Definition: Element.h:330
std::size_t numSymmetryFunctions() const
Get number of symmetry functions.
Definition: Element.h:353
Symmetry function base class.
Definition: SymFnc.h:40
virtual std::vector< std::string > getCacheIdentifiers() const
Get unique cache identifiers.
Definition: SymFnc.cpp:101
std::size_t getIndex() const
Get private index member variable.
Definition: SymFnc.h:357
List of symmetry functions corresponding to one cache identifier.
Definition: Element.h:45

References elementMap, elements, nnp::SymFnc::getCacheIdentifiers(), nnp::SymFnc::getIndex(), nnp::Element::getSymbol(), nnp::Element::getSymmetryFunction(), log, numElements, nnp::Element::numSymmetryFunctions(), nnp::Element::setCacheIndices(), nnp::split(), and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), and setupGeneric().

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

◆ setupSymmetryFunctionMemory()

void Mode::setupSymmetryFunctionMemory ( bool  verbose = false)

Extract required memory dimensions for symmetry function derivatives.

Parameters
[in]verboseIf true, print all symmetry function lines.

Call after symmetry functions have been set up and sorted.

Definition at line 894 of file Mode.cpp.

895{
896 log << "\n";
897 log << "*** SETUP: SYMMETRY FUNCTION MEMORY *****"
898 "**************************************\n";
899 log << "\n";
900
901 for (auto& e : elements)
902 {
903 e.setupSymmetryFunctionMemory();
904 vector<size_t> symmetryFunctionNumTable
905 = e.getSymmetryFunctionNumTable();
906 vector<vector<size_t>> symmetryFunctionTable
907 = e.getSymmetryFunctionTable();
908 log << strpr("Symmetry function derivatives memory table "
909 "for element %2s :\n", e.getSymbol().c_str());
910 log << "-----------------------------------------"
911 "--------------------------------------\n";
912 log << "Relevant symmetry functions for neighbors with element:\n";
913 for (size_t i = 0; i < numElements; ++i)
914 {
915 log << strpr("- %2s: %4zu of %4zu (%5.1f %)\n",
916 elementMap[i].c_str(),
917 symmetryFunctionNumTable.at(i),
918 e.numSymmetryFunctions(),
919 (100.0 * symmetryFunctionNumTable.at(i))
920 / e.numSymmetryFunctions());
921 if (verbose)
922 {
923 log << "-----------------------------------------"
924 "--------------------------------------\n";
925 for (auto isf : symmetryFunctionTable.at(i))
926 {
927 SymFnc const& sf = e.getSymmetryFunction(isf);
928 log << sf.parameterLine();
929 }
930 log << "-----------------------------------------"
931 "--------------------------------------\n";
932 }
933 }
934 log << "-----------------------------------------"
935 "--------------------------------------\n";
936 }
937 if (verbose)
938 {
939 for (auto& e : elements)
940 {
941 log << strpr("%2s - symmetry function per-element index table:\n",
942 e.getSymbol().c_str());
943 log << "-----------------------------------------"
944 "--------------------------------------\n";
945 log << " ind";
946 for (size_t i = 0; i < numElements; ++i)
947 {
948 log << strpr(" %4s", elementMap[i].c_str());
949 }
950 log << "\n";
951 log << "-----------------------------------------"
952 "--------------------------------------\n";
953 for (size_t i = 0; i < e.numSymmetryFunctions(); ++i)
954 {
955 SymFnc const& sf = e.getSymmetryFunction(i);
956 log << strpr("%4zu", sf.getIndex() + 1);
957 vector<size_t> indexPerElement = sf.getIndexPerElement();
958 for (auto ipe : sf.getIndexPerElement())
959 {
960 if (ipe == numeric_limits<size_t>::max())
961 {
962 log << strpr(" ");
963 }
964 else
965 {
966 log << strpr(" %4zu", ipe + 1);
967 }
968 }
969 log << "\n";
970 }
971 log << "-----------------------------------------"
972 "--------------------------------------\n";
973 }
974
975 }
976
977 log << "*****************************************"
978 "**************************************\n";
979
980 return;
981}
virtual std::string parameterLine() const =0
Give symmetry function parameters in one line.
std::vector< std::size_t > getIndexPerElement() const
Get private indexPerElement member variable.
Definition: SymFnc.h:383

References elementMap, elements, nnp::SymFnc::getIndex(), nnp::SymFnc::getIndexPerElement(), log, numElements, nnp::SymFnc::parameterLine(), and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), and setupGeneric().

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

◆ setupSymmetryFunctionStatistics()

void Mode::setupSymmetryFunctionStatistics ( bool  collectStatistics,
bool  collectExtrapolationWarnings,
bool  writeExtrapolationWarnings,
bool  stopOnExtrapolationWarnings 
)

Set up symmetry function statistics collection.

Parameters
[in]collectStatisticsWhether statistics (min, max, mean, sigma) is collected.
[in]collectExtrapolationWarningsWhether extrapolation warnings are logged.
[in]writeExtrapolationWarningsWrite extrapolation warnings immediately when they occur.
[in]stopOnExtrapolationWarningsThrow error immediately when an extrapolation warning occurs.

Does not use any keywords. Calling this setup function is not required, by default no statistics collection is enabled (all arguments false). Call after setupElements().

Definition at line 1103 of file Mode.cpp.

1107{
1108 log << "\n";
1109 log << "*** SETUP: SYMMETRY FUNCTION STATISTICS *"
1110 "**************************************\n";
1111 log << "\n";
1112
1113 log << "Equal symmetry function statistics for all elements.\n";
1114 log << strpr("Collect min/max/mean/sigma : %d\n",
1115 (int)collectStatistics);
1116 log << strpr("Collect extrapolation warnings : %d\n",
1117 (int)collectExtrapolationWarnings);
1118 log << strpr("Write extrapolation warnings immediately to stderr: %d\n",
1119 (int)writeExtrapolationWarnings);
1120 log << strpr("Halt on any extrapolation warning : %d\n",
1121 (int)stopOnExtrapolationWarnings);
1122 for (vector<Element>::iterator it = elements.begin();
1123 it != elements.end(); ++it)
1124 {
1125 it->statistics.collectStatistics = collectStatistics;
1126 it->statistics.collectExtrapolationWarnings =
1127 collectExtrapolationWarnings;
1128 it->statistics.writeExtrapolationWarnings = writeExtrapolationWarnings;
1129 it->statistics.stopOnExtrapolationWarnings =
1130 stopOnExtrapolationWarnings;
1131 }
1132
1133 checkExtrapolationWarnings = collectStatistics
1134 || collectExtrapolationWarnings
1135 || writeExtrapolationWarnings
1136 || stopOnExtrapolationWarnings;
1137
1138 log << "*****************************************"
1139 "**************************************\n";
1140 return;
1141}

References checkExtrapolationWarnings, elements, log, and nnp::strpr().

Referenced by nnp::Training::dataSetNormalization(), nnp::InterfaceLammps::initialize(), main(), and nnp::Prediction::setup().

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

◆ setupCutoffMatrix()

void Mode::setupCutoffMatrix ( )

Setup matrix storing all symmetry function cut-offs for each element.

Definition at line 1143 of file Mode.cpp.

1144{
1145 double rCutScreen = screeningFunction.getOuter();
1146 cutoffs.resize(numElements);
1147 for(auto const& e : elements)
1148 {
1149 e.getCutoffRadii(cutoffs.at(e.getIndex()));
1150 if ( rCutScreen > 0 &&
1151 !vectorContains(cutoffs.at(e.getIndex()), rCutScreen) )
1152 {
1153 cutoffs.at(e.getIndex()).push_back(rCutScreen);
1154 }
1155 }
1156}
std::vector< std::vector< double > > cutoffs
Matrix storing all symmetry function cut-offs for all elements.
Definition: Mode.h:652
ScreeningFunction screeningFunction
Definition: Mode.h:645
double getOuter() const
Getter for outer.
bool vectorContains(std::vector< T > const &stdVec, T value)
Test if vector contains specified value.
Definition: utility.h:166

References cutoffs, elements, nnp::ScreeningFunction::getOuter(), numElements, screeningFunction, and nnp::vectorContains().

Referenced by setupGeneric().

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

◆ setupNeuralNetwork()

void Mode::setupNeuralNetwork ( )
virtual

Set up neural networks for all elements.

Uses keywords global_hidden_layers_short, global_nodes_short, global_activation_short, normalize_nodes. Call after setupSymmetryFunctions(), only then the number of input layer neurons is known.

Reimplemented in nnp::ModeCabana< t_device >.

Definition at line 1158 of file Mode.cpp.

1159{
1160 log << "\n";
1161 log << "*** SETUP: NEURAL NETWORKS **************"
1162 "**************************************\n";
1163 log << "\n";
1164
1165 string id;
1166
1167 // Some NNP types require extra NNs.
1169 {
1170 id = "elec";
1171 nnk.push_back(id);
1172 nns[id].id = id;
1173 nns.at(id).name = "electronegativity";
1174 nns.at(id).weightFileFormat = "weightse.%03zu.data";
1175 nns.at(id).keywordSuffix = "_electrostatic";
1176 nns.at(id).keywordSuffix2 = "_charge";
1177 }
1178 else if(nnpType == NNPType::HDNNP_Q)
1179 {
1180 id = "elec";
1181 nnk.push_back(id);
1182 nns[id].id = id;
1183 nns.at(id).name = "charge";
1184 nns.at(id).weightFileFormat = "weightse.%03zu.data";
1185 nns.at(id).keywordSuffix = "_electrostatic";
1186 nns.at(id).keywordSuffix2 = "_charge";
1187 }
1188
1189 // All NNP types contain a short range NN.
1190 id = "short";
1191 nnk.push_back(id);
1192 nns[id].id = id;
1193 nns.at(id).name = "short range";
1194 nns.at(id).weightFileFormat = "weights.%03zu.data";
1195 nns.at(id).keywordSuffix = "_short";
1196 nns.at(id).keywordSuffix2 = "_short";
1197
1198 // Loop over all NNs and set global properties.
1199 for (auto& k : nnk)
1200 {
1201 // Each elements number of hidden layers.
1202 size_t globalNumHiddenLayers = 0;
1203 // Abbreviation for current NN.
1204 NNSetup& nn = nns.at(k);
1205 // Set size of NN topology vector.
1206 nn.topology.resize(numElements);
1207 // First, check for global number of hidden layers.
1208 string keyword = "global_hidden_layers" + nn.keywordSuffix;
1209 if (settings.keywordExists(keyword))
1210 {
1211 globalNumHiddenLayers = atoi(settings[keyword].c_str());
1212 for (auto& t : nn.topology)
1213 {
1214 t.numLayers = globalNumHiddenLayers + 2;
1215 }
1216 }
1217 // Now, check for per-element number of hidden layers.
1218 keyword = "element_hidden_layers" + nn.keywordSuffix;
1219 if (settings.keywordExists(keyword))
1220 {
1222 for (settings::Settings::KeyMap::const_iterator it = r.first;
1223 it != r.second; ++it)
1224 {
1225 vector<string> args = split(reduce(it->second.first));
1226 size_t const e = elementMap[args.at(0)];
1227 size_t const n = atoi(args.at(1).c_str());
1228 nn.topology.at(e).numLayers = n + 2;
1229 }
1230 }
1231 // Check whether user has set all NN's number of layers correctly.
1232 for (auto& t : nn.topology)
1233 {
1234 if (t.numLayers == 0)
1235 {
1236 throw runtime_error("ERROR: Number of neural network hidden "
1237 "layers unset for some elements.\n");
1238 }
1239 }
1240 // Finally, allocate NN topologies data.
1241 for (auto& t : nn.topology)
1242 {
1243 t.numNeuronsPerLayer.resize(t.numLayers, 0);
1244 t.activationFunctionsPerLayer.resize(t.numLayers,
1246 }
1247
1248 // Now read global number of neurons and activation functions.
1249 vector<string> globalNumNeuronsPerHiddenLayer;
1250 keyword = "global_nodes" + nn.keywordSuffix;
1251 if (settings.keywordExists(keyword))
1252 {
1253 globalNumNeuronsPerHiddenLayer = split(reduce(settings[keyword]));
1254 if (globalNumHiddenLayers != globalNumNeuronsPerHiddenLayer.size())
1255 {
1256 throw runtime_error(strpr("ERROR: Inconsistent global NN "
1257 "topology keyword \"%s\".\n",
1258 keyword.c_str()));
1259 }
1260 }
1261 vector<string> globalActivationFunctions;
1262 keyword = "global_activation" + nn.keywordSuffix;
1263 if (settings.keywordExists(keyword))
1264 {
1265 globalActivationFunctions = split(reduce(settings[keyword]));
1266 if (globalNumHiddenLayers != globalActivationFunctions.size() - 1)
1267 {
1268 throw runtime_error(strpr("ERROR: Inconsistent global NN "
1269 "topology keyword \"%s\".\n",
1270 keyword.c_str()));
1271 }
1272 }
1273 // Set global number of neurons and activation functions if provided.
1274 bool globalNumNeurons = (globalNumNeuronsPerHiddenLayer.size() != 0);
1275 bool globalActivation = (globalActivationFunctions.size() != 0);
1276 for (size_t i = 0; i < numElements; ++i)
1277 {
1278 NNSetup::Topology& t = nn.topology.at(i);
1279 size_t const nsf = elements.at(i).numSymmetryFunctions();
1280 // Set input layer. Number of input layer neurons depends on NNP
1281 // type and NN purpose.
1283 {
1284 // Can assume NN id is "short".
1285 t.numNeuronsPerLayer.at(0) = nsf;
1286 }
1287 else if (nnpType == NNPType::HDNNP_4G ||
1289 {
1290 // NN with id "elec" requires only SFs.
1291 if (k == "elec") t.numNeuronsPerLayer.at(0) = nsf;
1292 // "short" NN needs extra charge neuron.
1293 else if (k == "short") t.numNeuronsPerLayer.at(0) = nsf + 1;
1294 }
1295 // Set dummy input neuron activation function.
1296 t.activationFunctionsPerLayer.at(0) = NeuralNetwork::AF_IDENTITY;
1297 // Set output layer. Assume single output neuron.
1298 t.numNeuronsPerLayer.at(t.numLayers - 1) = 1;
1299 // If this element's NN does not use the global number of hidden
1300 // layers it makes no sense to set the global number of hidden
1301 // neurons or activation functions. Hence, skip the settings here,
1302 // appropriate settings should follow later in the per-element
1303 // section.
1304 if ((size_t)t.numLayers != globalNumHiddenLayers + 2) continue;
1305 for (int j = 1; j < t.numLayers; ++j)
1306 {
1307 if ((j == t.numLayers - 1) && globalActivation)
1308 {
1309 t.activationFunctionsPerLayer.at(j) = activationFromString(
1310 globalActivationFunctions.at(t.numLayers - 2));
1311 }
1312 else
1313 {
1314 if (globalNumNeurons)
1315 {
1316 t.numNeuronsPerLayer.at(j) = atoi(
1317 globalNumNeuronsPerHiddenLayer.at(j - 1).c_str());
1318 }
1319 if (globalActivation)
1320 {
1321 t.activationFunctionsPerLayer.at(j) =
1323 globalActivationFunctions.at(j - 1));
1324 }
1325 }
1326 }
1327 }
1328 // Override global number of neurons with per-element keyword.
1329 keyword = "element_nodes" + nn.keywordSuffix;
1330 if (settings.keywordExists(keyword))
1331 {
1333 for (settings::Settings::KeyMap::const_iterator it = r.first;
1334 it != r.second; ++it)
1335 {
1336 vector<string> args = split(reduce(it->second.first));
1337 size_t e = elementMap[args.at(0)];
1338 size_t n = args.size() - 1;
1339 NNSetup::Topology& t = nn.topology.at(e);
1340 if ((size_t)t.numLayers != n + 2)
1341 {
1342 throw runtime_error(strpr("ERROR: Inconsistent per-element"
1343 " NN topology keyword \"%s\".\n",
1344 keyword.c_str()));
1345 }
1346 for (int j = 1; j < t.numLayers - 2; ++j)
1347 {
1348 t.numNeuronsPerLayer.at(j) = atoi(args.at(j).c_str());
1349 }
1350 }
1351 }
1352 // Override global activation functions with per-element keyword.
1353 keyword = "element_activation" + nn.keywordSuffix;
1354 if (settings.keywordExists(keyword))
1355 {
1357 for (settings::Settings::KeyMap::const_iterator it = r.first;
1358 it != r.second; ++it)
1359 {
1360 vector<string> args = split(reduce(it->second.first));
1361 size_t e = elementMap[args.at(0)];
1362 size_t n = args.size() - 1;
1363 NNSetup::Topology& t = nn.topology.at(e);
1364 if ((size_t)t.numLayers != n + 1)
1365 {
1366 throw runtime_error(strpr("ERROR: Inconsistent per-element"
1367 " NN topology keyword \"%s\".\n",
1368 keyword.c_str()));
1369 }
1370 for (int j = 1; j < t.numLayers - 1; ++j)
1371 {
1372 t.activationFunctionsPerLayer.at(j) =
1373 activationFromString(args.at(j).c_str());
1374 }
1375 }
1376 }
1377
1378 // Finally check everything for any unset NN property.
1379 for (size_t i = 0; i < numElements; ++i)
1380 {
1381 NNSetup::Topology const& t = nn.topology.at(i);
1382 for (int j = 0; j < t.numLayers; ++j)
1383 {
1384 if (t.numNeuronsPerLayer.at(j) == 0)
1385 {
1386 throw runtime_error(strpr(
1387 "ERROR: NN \"%s\", element %2s: number of "
1388 "neurons for layer %d unset.\n",
1389 nn.id.c_str(),
1390 elements.at(i).getSymbol().c_str(),
1391 j));
1392 }
1393 if (t.activationFunctionsPerLayer.at(j)
1395 {
1396 throw runtime_error(strpr(
1397 "ERROR: NN \"%s\", element %2s: activation "
1398 "functions for layer %d unset.\n",
1399 nn.id.c_str(),
1400 elements.at(i).getSymbol().c_str(),
1401 j));
1402 }
1403 }
1404 }
1405 }
1406
1407
1408 bool normalizeNeurons = settings.keywordExists("normalize_nodes");
1409 log << strpr("Normalize neurons (all elements): %d\n",
1410 (int)normalizeNeurons);
1411 log << "-----------------------------------------"
1412 "--------------------------------------\n";
1413
1414 // Finally, allocate all neural networks.
1415 for (auto& k : nnk)
1416 {
1417 for (size_t i = 0; i < numElements; ++i)
1418 {
1419 Element& e = elements.at(i);
1420 NNSetup::Topology const& t = nns.at(k).topology.at(i);
1421 e.neuralNetworks.emplace(
1422 piecewise_construct,
1423 forward_as_tuple(k),
1424 forward_as_tuple(
1425 t.numLayers,
1426 t.numNeuronsPerLayer.data(),
1427 t.activationFunctionsPerLayer.data()));
1428 e.neuralNetworks.at(k).setNormalizeNeurons(normalizeNeurons);
1429 log << strpr("Atomic %s NN for "
1430 "element %2s :\n",
1431 nns.at(k).name.c_str(),
1432 e.getSymbol().c_str());
1433 log << e.neuralNetworks.at(k).info();
1434 log << "-----------------------------------------"
1435 "--------------------------------------\n";
1436 }
1437 }
1438
1439 log << "*****************************************"
1440 "**************************************\n";
1441
1442 return;
1443}
std::map< std::string, NeuralNetwork > neuralNetworks
Neural networks for this element.
Definition: Element.h:247
std::vector< std::string > nnk
Definition: Mode.h:647
std::map< std::string, NNSetup > nns
Definition: Mode.h:649
@ AF_UNSET
Unset activation function.
Definition: NeuralNetwork.h:35
NeuralNetwork::ActivationFunction activationFromString(std::string c)
Convert string to activation function.

References nnp::activationFromString(), nnp::Mode::NNSetup::Topology::activationFunctionsPerLayer, nnp::NeuralNetwork::AF_IDENTITY, nnp::NeuralNetwork::AF_UNSET, elementMap, elements, nnp::Element::getSymbol(), nnp::settings::Settings::getValues(), HDNNP_2G, HDNNP_4G, HDNNP_Q, nnp::Mode::NNSetup::id, nnp::settings::Settings::keywordExists(), nnp::Mode::NNSetup::keywordSuffix, log, nnp::Element::neuralNetworks, nnk, nnpType, nns, numElements, nnp::Mode::NNSetup::Topology::numLayers, nnp::Mode::NNSetup::Topology::numNeuronsPerLayer, nnp::reduce(), settings, nnp::ElementMap::size(), nnp::split(), nnp::strpr(), and nnp::Mode::NNSetup::topology.

Referenced by setupGeneric().

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

◆ setupNeuralNetworkWeights() [1/2]

void Mode::setupNeuralNetworkWeights ( std::map< std::string, std::string >  fileNameFormats = std::map<std::string, std::string>())
virtual

Set up neural network weights from files with given name format.

Parameters
[in]fileNameFormatsMap of NN ids to format for weight file names. Must contain a placeholder "%zu" for the element atomic number. Map keys are "short", "elec". Map argument may be ommitted, then default name formats are used.

Does not use any keywords. The weight files should contain one weight per line, see NeuralNetwork::setConnections() for the correct order.

Definition at line 1445 of file Mode.cpp.

1446{
1447 setupNeuralNetworkWeights("", fileNameFormats);
1448 return;
1449}

References setupNeuralNetworkWeights().

Referenced by nnp::InterfaceLammps::initialize(), main(), nnp::Prediction::setup(), and setupNeuralNetworkWeights().

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

◆ setupNeuralNetworkWeights() [2/2]

void Mode::setupNeuralNetworkWeights ( std::string  directoryPrefix,
std::map< std::string, std::string >  fileNameFormats = std::map<std::string, std::string>() 
)
virtual

Set up neural network weights from files with given name format.

Parameters
[in]directoryPrefixDirectory prefix which is applied to all fileNameFormats.
[in]fileNameFormatsMap of NN ids to format for weight file names. Must contain a placeholder "%zu" for the element atomic number. Map keys are "short", "elec". Map argument may be ommitted, then default name formats are used.

Does not use any keywords. The weight files should contain one weight per line, see NeuralNetwork::setConnections() for the correct order.

Definition at line 1451 of file Mode.cpp.

1453{
1454 log << "\n";
1455 log << "*** SETUP: NEURAL NETWORK WEIGHTS *******"
1456 "**************************************\n";
1457 log << "\n";
1458
1459 for (auto k : nnk)
1460 {
1461 string actualFileNameFormat;
1462 if (fileNameFormats.find(k) != fileNameFormats.end())
1463 {
1464 actualFileNameFormat = fileNameFormats.at(k);
1465 }
1466 else actualFileNameFormat = nns.at(k).weightFileFormat;
1467 actualFileNameFormat = directoryPrefix + actualFileNameFormat;
1468 log << strpr("%s weight file name format: %s\n",
1469 cap(nns.at(k).name).c_str(),
1470 actualFileNameFormat.c_str());
1471 readNeuralNetworkWeights(k, actualFileNameFormat);
1472 }
1473
1474 log << "*****************************************"
1475 "**************************************\n";
1476
1477 return;
1478}
void readNeuralNetworkWeights(std::string const &id, std::string const &fileName)
Read in weights for a specific type of neural network.
Definition: Mode.cpp:2270
string cap(string word)
Capitalize first letter of word.
Definition: utility.cpp:104

References nnp::cap(), log, nnk, nns, readNeuralNetworkWeights(), and nnp::strpr().

Here is the call graph for this function:

◆ setupElectrostatics()

void Mode::setupElectrostatics ( bool  initialHardness = false,
std::string  directoryPrefix = "",
std::string  fileNameFormat = "hardness.%03zu.data" 
)
virtual

Set up electrostatics related stuff (hardness, screening, ...).

Parameters
[in]initialHardnessUse initial hardness from keyword in settings file (useful for training).
[in]directoryPrefixDirectory prefix which is applied to fileNameFormat.
[in]fileNameFormatName format of file containing atomic hardness data.

Definition at line 368 of file Mode.cpp.

371{
372 log << "\n";
373 log << "*** SETUP: ELECTROSTATICS ***************"
374 "**************************************\n";
375 log << "\n";
376
377 // Atomic hardness.
378 if (initialHardness)
379 {
380 settings::Settings::KeyRange r = settings.getValues("initial_hardness");
381 for (settings::Settings::KeyMap::const_iterator it = r.first;
382 it != r.second; ++it)
383 {
384 vector<string> args = split(reduce(it->second.first));
385 size_t element = elementMap[args.at(0)];
386 double hardness = atof(args.at(1).c_str());
387 if (normalize) hardness = normalized("hardness", hardness);
388 elements.at(element).setHardness(hardness);
389 }
390 for (size_t i = 0; i < numElements; ++i)
391 {
392 double hardness = elements.at(i).getHardness();
393 if (normalize) hardness = physical("hardness", hardness);
394 log << strpr("Initial atomic hardness for element %2s: %16.8E\n",
395 elements.at(i).getSymbol().c_str(),
396 hardness);
397 }
398 }
399 else
400 {
401 string actualFileNameFormat = directoryPrefix + fileNameFormat;
402 log << strpr("Atomic hardness file name format: %s\n",
403 actualFileNameFormat.c_str());
404 for (size_t i = 0; i < numElements; ++i)
405 {
406 string fileName = strpr(actualFileNameFormat.c_str(),
407 elements.at(i).getAtomicNumber());
408 log << strpr("Atomic hardness for element %2s from file %s: ",
409 elements.at(i).getSymbol().c_str(),
410 fileName.c_str());
411 vector<double> const data = readColumnsFromFile(fileName,
412 {0}).at(0);
413 if (data.size() != 1)
414 {
415 throw runtime_error("ERROR: Atomic hardness data is "
416 "inconsistent.\n");
417 }
418 double hardness = data.at(0);
419 if (normalize) hardness = normalized("hardness", hardness);
420 elements.at(i).setHardness(hardness);
421 if (normalize) hardness = physical("hardness", hardness);
422 log << strpr("%16.8E\n", hardness);
423 }
424 }
425 log << "\n";
426
427 // Gaussian width of charges.
428 double maxQsigma = 0.0;
429 settings::Settings::KeyRange r = settings.getValues("fixed_gausswidth");
430 for (settings::Settings::KeyMap::const_iterator it = r.first;
431 it != r.second; ++it)
432 {
433 vector<string> args = split(reduce(it->second.first));
434 size_t element = elementMap[args.at(0)];
435 double qsigma = atof(args.at(1).c_str());
436 if (normalize) qsigma *= convLength;
437 elements.at(element).setQsigma(qsigma);
438
439 maxQsigma = max(qsigma, maxQsigma);
440 }
441 log << "Gaussian width of charge distribution per element:\n";
442 for (size_t i = 0; i < elementMap.size(); ++i)
443 {
444 double qsigma = elements.at(i).getQsigma();
445 if (normalize) qsigma /= convLength;
446 log << strpr("Element %2zu: %16.8E\n",
447 i, qsigma);
448 }
449 log << "\n";
450
451 // Ewald truncation error method.
452 if (settings.keywordExists("ewald_truncation_error_method"))
453 {
454 string truncation_method_string =
455 settings["ewald_truncation_error_method"];
456 if (truncation_method_string == "0")
458 if (truncation_method_string == "1")
460 }
461 else
463
464 // Ewald precision.
465 if (settings.keywordExists("ewald_prec"))
466 {
467 vector<string> args = split(settings["ewald_prec"]);
469 ewaldSetup.setMaxQSigma(maxQsigma);
470 if (normalize)
472 }
474 {
475 throw runtime_error("ERROR: ewald_truncation_error_method 1 requires "
476 "ewald_prec.");
477 }
478 log << strpr("Ewald truncation error method: %16d\n",
480 log << strpr("Ewald precision: %16.8E\n",
483 log << strpr("Ewald expected maximum charge: %16.8E\n",
485 log << "\n";
486
487 // 4 * pi * epsilon
488 if (settings.keywordExists("four_pi_epsilon"))
489 fourPiEps = atof(settings["four_pi_epsilon"].c_str());
490 if (normalize)
491 fourPiEps *= pow(convCharge, 2) / (convLength * convEnergy);
492
493 // Screening function.
494 if (settings.keywordExists("screen_electrostatics"))
495 {
496 vector<string> args = split(settings["screen_electrostatics"]);
497 double inner = atof(args.at(0).c_str());
498 double outer = atof(args.at(1).c_str());
499 string type = "c"; // Default core function is cosine.
500 if (args.size() > 2) type = args.at(2);
501 screeningFunction.setInnerOuter(inner, outer);
503 for (auto s : screeningFunction.info()) log << s;
505 }
506 else
507 {
508 // Set screening function in such way that it will always be 1.0.
509 // This may not be very efficient, may optimize later.
511 log << "Screening function not used.\n";
512 }
513
514 log << "*****************************************"
515 "**************************************\n";
516
517 return;
518}
void setTruncMethod(EWALDTruncMethod const m)
Definition: EwaldSetup.h:93
void toNormalizedUnits(double const convEnergy, double const convLength)
Convert cutoff parameters to normalized units.
Definition: EwaldSetup.cpp:74
double getPrecision() const
Definition: EwaldSetup.h:45
void setMaxQSigma(double const maxWidth)
Setter for maximum width of charges.
Definition: EwaldSetup.h:88
EWALDTruncMethod getTruncMethod() const
Definition: EwaldSetup.h:43
double getMaxCharge() const
Definition: EwaldSetup.h:44
void readFromArgs(std::vector< std::string > const &args)
Setup parameters from argument vector.
Definition: EwaldSetup.cpp:36
double physical(std::string const &property, double value) const
Undo normalization for a given property.
Definition: Mode.cpp:2110
double normalized(std::string const &property, double value) const
Apply normalization to given property.
Definition: Mode.cpp:2084
void setCoreFunction(CoreFunction::Type const type)
Set functional form of transition region.
void changeLengthUnits(double const conv)
Change length units of screening function.
std::vector< std::string > info() const
Get string with information of screening function.
void setInnerOuter(double inner, double outer)
Set inner and outer limit of transition region.
@ KOLAFA_PERRAM
Method 1: Optimized in n2p2 (DOI: 10.1080/08927029208049126).
@ JACKSON_CATLOW
Method 0: Used by RuNNer (DOI: 10.1080/08927028808080944).
map< size_t, vector< double > > readColumnsFromFile(string fileName, vector< size_t > columns, char comment)
Definition: utility.cpp:247

References nnp::ScreeningFunction::changeLengthUnits(), convCharge, convEnergy, convLength, elementMap, elements, ewaldSetup, fourPiEps, nnp::EwaldSetup::getMaxCharge(), nnp::EwaldSetup::getPrecision(), nnp::EwaldSetup::getTruncMethod(), nnp::settings::Settings::getValues(), nnp::ScreeningFunction::info(), nnp::JACKSON_CATLOW, nnp::settings::Settings::keywordExists(), nnp::KOLAFA_PERRAM, log, normalize, normalized(), numElements, physical(), nnp::readColumnsFromFile(), nnp::EwaldSetup::readFromArgs(), nnp::reduce(), screeningFunction, nnp::ScreeningFunction::setCoreFunction(), nnp::ScreeningFunction::setInnerOuter(), nnp::EwaldSetup::setMaxQSigma(), settings, nnp::EwaldSetup::setTruncMethod(), nnp::ElementMap::size(), nnp::split(), nnp::strpr(), and nnp::EwaldSetup::toNormalizedUnits().

Referenced by setupGeneric().

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

◆ calculateSymmetryFunctions()

void Mode::calculateSymmetryFunctions ( Structure structure,
bool const  derivatives 
)

Calculate all symmetry functions for all atoms in given structure.

Parameters
[in]structureInput structure.
[in]derivativesIf true calculate also derivatives of symmetry functions.

This function should be replaced by calculateSymmetryFunctionGroups() whenever possible. Results are stored in Atom::G. If derivatives are calculated, additional results are stored in Atom::dGdr and Atom::Neighbor::dGdr.

Definition at line 1480 of file Mode.cpp.

1482{
1483 // Skip calculation for whole structure if results are already saved.
1484 if (structure.hasSymmetryFunctionDerivatives) return;
1485 if (structure.hasSymmetryFunctions && !derivatives) return;
1486
1487 Atom* a = NULL;
1488 Element* e = NULL;
1489#ifdef _OPENMP
1490 #pragma omp parallel for private (a, e)
1491#endif
1492 for (size_t i = 0; i < structure.atoms.size(); ++i)
1493 {
1494 // Pointer to atom.
1495 a = &(structure.atoms.at(i));
1496
1497 // Skip calculation for individual atom if results are already saved.
1498 if (a->hasSymmetryFunctionDerivatives) continue;
1499 if (a->hasSymmetryFunctions && !derivatives) continue;
1500
1501 // Inform atom if extra charge neuron is present in short-range NN.
1502 if (nnpType == NNPType::HDNNP_4G ||
1504
1505 // Get element of atom and set number of symmetry functions.
1506 e = &(elements.at(a->element));
1508 if (derivatives)
1509 {
1512 }
1513#ifndef N2P2_NO_SF_CACHE
1515#endif
1516
1517#ifndef N2P2_NO_NEIGH_CHECK
1518 // Check if atom has low number of neighbors.
1519 size_t numNeighbors = a->calculateNumNeighbors(
1520 minCutoffRadius.at(e->getIndex()));
1521 if (numNeighbors < minNeighbors.at(e->getIndex()))
1522 {
1523 log << strpr("WARNING: Structure %6zu Atom %6zu : %zu "
1524 "neighbors.\n",
1525 a->indexStructure,
1526 a->index,
1527 numNeighbors);
1528 }
1529#endif
1530
1531 // Allocate symmetry function data vectors in atom.
1532 a->allocate(derivatives, maxCutoffRadius);
1533
1534 // Calculate symmetry functions (and derivatives).
1535 e->calculateSymmetryFunctions(*a, derivatives);
1536
1537 // Remember that symmetry functions of this atom have been calculated.
1538 a->hasSymmetryFunctions = true;
1539 if (derivatives) a->hasSymmetryFunctionDerivatives = true;
1540 }
1541
1542 // If requested, check extrapolation warnings or update statistics.
1543 // Needed to shift this out of the loop above to make it thread-safe.
1545 {
1546 for (size_t i = 0; i < structure.atoms.size(); ++i)
1547 {
1548 a = &(structure.atoms.at(i));
1549 e = &(elements.at(a->element));
1551 }
1552 }
1553
1554 // Remember that symmetry functions of this structure have been calculated.
1555 structure.hasSymmetryFunctions = true;
1556 if (derivatives) structure.hasSymmetryFunctionDerivatives = true;
1557
1558 return;
1559}
void calculateSymmetryFunctions(Atom &atom, bool const derivatives) const
Calculate symmetry functions.
Definition: Element.cpp:436
std::vector< std::size_t > getCacheSizes() const
Get cache sizes for each neighbor atom element.
Definition: Element.cpp:563
std::size_t getIndex() const
Get index.
Definition: Element.h:305
std::size_t updateSymmetryFunctionStatistics(Atom const &atom)
Update symmetry function statistics.
Definition: Element.cpp:462
std::vector< std::size_t > const & getSymmetryFunctionNumTable() const
Get number of relevant symmetry functions per element.
Definition: Element.h:336
Storage for a single atom.
Definition: Atom.h:33
std::size_t numSymmetryFunctions
Number of symmetry functions used to describe the atom environment.
Definition: Atom.h:113
bool hasSymmetryFunctionDerivatives
If symmetry function derivatives are saved for this atom.
Definition: Atom.h:97
std::size_t index
Index number of this atom.
Definition: Atom.h:101
std::vector< std::size_t > numSymmetryFunctionDerivatives
Number of neighbor atom symmetry function derivatives per element.
Definition: Atom.h:140
bool useChargeNeuron
If an additional charge neuron in the short-range NN is present.
Definition: Atom.h:99
std::size_t indexStructure
Index number of structure this atom belongs to.
Definition: Atom.h:103
std::size_t element
Element index of this atom.
Definition: Atom.h:107
void allocate(bool all, double const maxCutoffRadius=0.0)
Allocate vectors related to symmetry functions (G, dEdG).
Definition: Atom.cpp:168
bool hasSymmetryFunctions
If symmetry function values are saved for this atom.
Definition: Atom.h:95
std::size_t calculateNumNeighbors(double const cutoffRadius) const
Calculate number of neighbors for a given cutoff radius.
Definition: Atom.cpp:307
std::vector< std::size_t > cacheSizePerElement
Cache size for each element.
Definition: Atom.h:143
bool hasSymmetryFunctionDerivatives
If symmetry function derivatives are saved for each atom.
Definition: Structure.h:71
std::vector< Atom > atoms
Vector of all atoms in this structure.
Definition: Structure.h:122
bool hasSymmetryFunctions
If symmetry function values are saved for each atom.
Definition: Structure.h:69

References nnp::Atom::allocate(), nnp::Structure::atoms, nnp::Atom::cacheSizePerElement, nnp::Atom::calculateNumNeighbors(), nnp::Element::calculateSymmetryFunctions(), checkExtrapolationWarnings, nnp::Atom::element, elements, nnp::Element::getCacheSizes(), nnp::Element::getIndex(), nnp::Element::getSymmetryFunctionNumTable(), nnp::Atom::hasSymmetryFunctionDerivatives, nnp::Structure::hasSymmetryFunctionDerivatives, nnp::Atom::hasSymmetryFunctions, nnp::Structure::hasSymmetryFunctions, HDNNP_4G, HDNNP_Q, nnp::Atom::index, nnp::Atom::indexStructure, log, maxCutoffRadius, minCutoffRadius, minNeighbors, nnpType, nnp::Atom::numSymmetryFunctionDerivatives, nnp::Atom::numSymmetryFunctions, nnp::Element::numSymmetryFunctions(), nnp::strpr(), nnp::Element::updateSymmetryFunctionStatistics(), and nnp::Atom::useChargeNeuron.

Referenced by nnp::Training::calculateError(), nnp::Training::calculateWeightDerivatives(), nnp::Training::dataSetNormalization(), evaluateNNP(), main(), nnp::InterfaceLammps::process(), and nnp::Training::update().

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

◆ calculateSymmetryFunctionGroups()

void Mode::calculateSymmetryFunctionGroups ( Structure structure,
bool const  derivatives 
)

Calculate all symmetry function groups for all atoms in given structure.

Parameters
[in]structureInput structure.
[in]derivativesIf true calculate also derivatives of symmetry functions.

This function replaces calculateSymmetryFunctions() when symmetry function groups are enabled (faster, default behavior). Results are stored in Atom::G. If derivatives are calculated, additional results are stored in Atom::dGdr and Atom::Neighbor::dGdr.

Definition at line 1561 of file Mode.cpp.

1563{
1564 // Skip calculation for whole structure if results are already saved.
1565 if (structure.hasSymmetryFunctionDerivatives) return;
1566 if (structure.hasSymmetryFunctions && !derivatives) return;
1567
1568 Atom* a = NULL;
1569 Element* e = NULL;
1570#ifdef _OPENMP
1571 #pragma omp parallel for private (a, e)
1572#endif
1573 for (size_t i = 0; i < structure.atoms.size(); ++i)
1574 {
1575 // Pointer to atom.
1576 a = &(structure.atoms.at(i));
1577
1578 // Skip calculation for individual atom if results are already saved.
1579 if (a->hasSymmetryFunctionDerivatives) continue;
1580 if (a->hasSymmetryFunctions && !derivatives) continue;
1581
1582 // Inform atom if extra charge neuron is present in short-range NN.
1583 if (nnpType == NNPType::HDNNP_4G ||
1585
1586 // Get element of atom and set number of symmetry functions.
1587 e = &(elements.at(a->element));
1589 if (derivatives)
1590 {
1593 }
1594#ifndef N2P2_NO_SF_CACHE
1596#endif
1597
1598#ifndef N2P2_NO_NEIGH_CHECK
1599 // Check if atom has low number of neighbors.
1600 size_t numNeighbors = a->calculateNumNeighbors(
1601 minCutoffRadius.at(e->getIndex()));
1602 if (numNeighbors < minNeighbors.at(e->getIndex()))
1603 {
1604 log << strpr("WARNING: Structure %6zu Atom %6zu : %zu "
1605 "neighbors.\n",
1606 a->indexStructure,
1607 a->index,
1608 numNeighbors);
1609 }
1610#endif
1611
1612 // Allocate symmetry function data vectors in atom.
1613 a->allocate(derivatives, maxCutoffRadius);
1614
1615 // Calculate symmetry functions (and derivatives).
1616 e->calculateSymmetryFunctionGroups(*a, derivatives);
1617
1618 // Remember that symmetry functions of this atom have been calculated.
1619 a->hasSymmetryFunctions = true;
1620 if (derivatives) a->hasSymmetryFunctionDerivatives = true;
1621 }
1622
1623 // If requested, check extrapolation warnings or update statistics.
1624 // Needed to shift this out of the loop above to make it thread-safe.
1626 {
1627 for (size_t i = 0; i < structure.atoms.size(); ++i)
1628 {
1629 a = &(structure.atoms.at(i));
1630 e = &(elements.at(a->element));
1632 }
1633 }
1634
1635 // Remember that symmetry functions of this structure have been calculated.
1636 structure.hasSymmetryFunctions = true;
1637 if (derivatives) structure.hasSymmetryFunctionDerivatives = true;
1638
1639 return;
1640}
void calculateSymmetryFunctionGroups(Atom &atom, bool const derivatives) const
Calculate symmetry functions via groups.
Definition: Element.cpp:449

References nnp::Atom::allocate(), nnp::Structure::atoms, nnp::Atom::cacheSizePerElement, nnp::Atom::calculateNumNeighbors(), nnp::Element::calculateSymmetryFunctionGroups(), checkExtrapolationWarnings, nnp::Atom::element, elements, nnp::Element::getCacheSizes(), nnp::Element::getIndex(), nnp::Element::getSymmetryFunctionNumTable(), nnp::Atom::hasSymmetryFunctionDerivatives, nnp::Structure::hasSymmetryFunctionDerivatives, nnp::Atom::hasSymmetryFunctions, nnp::Structure::hasSymmetryFunctions, HDNNP_4G, HDNNP_Q, nnp::Atom::index, nnp::Atom::indexStructure, log, maxCutoffRadius, minCutoffRadius, minNeighbors, nnpType, nnp::Atom::numSymmetryFunctionDerivatives, nnp::Atom::numSymmetryFunctions, nnp::Element::numSymmetryFunctions(), nnp::strpr(), nnp::Element::updateSymmetryFunctionStatistics(), and nnp::Atom::useChargeNeuron.

Referenced by nnp::Training::calculateError(), nnp::Training::calculateWeightDerivatives(), nnp::Training::dataSetNormalization(), evaluateNNP(), main(), nnp::InterfaceLammps::process(), and nnp::Training::update().

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

◆ calculateAtomicNeuralNetworks()

void Mode::calculateAtomicNeuralNetworks ( Structure structure,
bool const  derivatives,
std::string  id = "" 
)

Calculate atomic neural networks for all atoms in given structure.

Parameters
[in]structureInput structure.
[in]derivativesIf true calculate also derivatives of neural networks with respect to input layer neurons (required for force calculation).
[in]idNeural network ID to use. If empty, the first entry nnk.front() is used.

Definition at line 1642 of file Mode.cpp.

1645{
1646 if (id == "") id = nnk.front();
1647
1649 {
1650 for (vector<Atom>::iterator it = structure.atoms.begin();
1651 it != structure.atoms.end(); ++it)
1652 {
1653 NeuralNetwork& nn = elements.at(it->element)
1654 .neuralNetworks.at(id);
1655 nn.setInput(&((it->G).front()));
1656 nn.propagate();
1657 if (derivatives)
1658 {
1659 nn.calculateDEdG(&((it->dEdG).front()));
1660 }
1661 nn.getOutput(&(it->energy));
1662 }
1663 }
1664 else if (nnpType == NNPType::HDNNP_4G)
1665 {
1666 if (id == "elec")
1667 {
1668 for (auto& a : structure.atoms)
1669 {
1670 NeuralNetwork& nn = elements.at(a.element)
1671 .neuralNetworks.at(id);
1672 nn.setInput(&((a.G).front()));
1673 nn.propagate();
1674 if (derivatives)
1675 {
1676 // Calculation of dEdG is identical to dChidG
1677 nn.calculateDEdG(&((a.dChidG).front()));
1678 if (normalize)
1679 {
1680 for (auto& dChidGi : a.dChidG)
1681 dChidGi = normalized("negativity", dChidGi);
1682 }
1683 }
1684 nn.getOutput(&(a.chi));
1685 //double chi = a.chi;
1686 if (normalize) a.chi = normalized("negativity", a.chi);
1687 }
1688 }
1689 else if (id == "short")
1690 {
1691 for (auto& a : structure.atoms)
1692 {
1693 NeuralNetwork& nn = elements.at(a.element)
1694 .neuralNetworks.at(id);
1695 // This line is probably obsolete
1696 //nn.setInput(&((a.G).front()));
1697 // TODO: This part should simplify with improved NN class.
1698 for (size_t i = 0; i < a.G.size(); ++i)
1699 {
1700 nn.setInput(i, a.G.at(i));
1701 }
1702 // Set additional charge neuron.
1703 nn.setInput(a.G.size(), a.charge);
1704 nn.propagate();
1705 if (derivatives)
1706 {
1707 // last element of vector dEdG is dEdQ
1708 nn.calculateDEdG(&((a.dEdG).front()));
1709 }
1710 nn.getOutput(&(a.energy));
1711 }
1712 }
1713 }
1714 else if (nnpType == NNPType::HDNNP_Q)
1715 {
1716 // Ignore ID, both NNs are computed here.
1717 for (vector<Atom>::iterator it = structure.atoms.begin();
1718 it != structure.atoms.end(); ++it)
1719 {
1720 // First the charge NN.
1721 NeuralNetwork& nnCharge = elements.at(it->element)
1722 .neuralNetworks.at("elec");
1723 nnCharge.setInput(&((it->G).front()));
1724 nnCharge.propagate();
1725 if (derivatives)
1726 {
1727 nnCharge.calculateDEdG(&((it->dQdG).front()));
1728 }
1729 nnCharge.getOutput(&(it->charge));
1730
1731 // Now the short-range NN (have to set input neurons individually).
1732 NeuralNetwork& nnShort = elements.at(it->element)
1733 .neuralNetworks.at("short");
1734 // TODO: This part should simplify with improved NN class.
1735 for (size_t i = 0; i < it->G.size(); ++i)
1736 {
1737 nnShort.setInput(i, it->G.at(i));
1738 }
1739 // Set additional charge neuron.
1740 nnShort.setInput(it->G.size(), it->charge);
1741 nnShort.propagate();
1742 if (derivatives)
1743 {
1744 nnShort.calculateDEdG(&((it->dEdG).front()));
1745 }
1746 nnShort.getOutput(&(it->energy));
1747 }
1748 }
1749
1750 return;
1751}
This class implements a feed-forward neural network.
Definition: NeuralNetwork.h:29
void setInput(double const *const &input) const
Set neural network input layer node values.
void propagate()
Propagate input information through all layers.
void calculateDEdG(double *dEdG) const
Calculate derivative of output neuron with respect to input neurons.
void getOutput(double *output) const
Get neural network output layer node values.

References nnp::Structure::atoms, nnp::NeuralNetwork::calculateDEdG(), elements, nnp::NeuralNetwork::getOutput(), HDNNP_2G, HDNNP_4G, HDNNP_Q, nnk, nnpType, normalize, normalized(), nnp::NeuralNetwork::propagate(), and nnp::NeuralNetwork::setInput().

Referenced by nnp::Training::calculateError(), nnp::Training::dataSetNormalization(), nnp::Training::dPdcN(), evaluateNNP(), main(), nnp::InterfaceLammps::process(), and nnp::Training::update().

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

◆ chargeEquilibration()

void Mode::chargeEquilibration ( Structure structure,
bool const  derivativesElec 
)

Perform global charge equilibration method.

Parameters
[in]structureInput structure.
[in]derivativesElecTurn on/off calculation of dElecdQ and pElecpr (Typically needed for elecstrosttic forces).

Definition at line 1754 of file Mode.cpp.

1756{
1757 Structure& s = structure;
1758
1759 // Prepare hardness vector and precalculate gamma(i, j).
1760 VectorXd hardness(numElements);
1761 MatrixXd gammaSqrt2(numElements, numElements);
1762 VectorXd sigmaSqrtPi(numElements);
1763
1764 for (size_t i = 0; i < numElements; ++i)
1765 {
1766 hardness(i) = elements.at(i).getHardness();
1767 double const iSigma = elements.at(i).getQsigma();
1768 sigmaSqrtPi(i) = sqrt(M_PI) * iSigma;
1769 for (size_t j = 0; j < numElements; ++j)
1770 {
1771 double const jSigma = elements.at(j).getQsigma();
1772 gammaSqrt2(i, j) = sqrt(2.0 * (iSigma * iSigma + jSigma * jSigma));
1773 }
1774 }
1775
1777 hardness,
1778 gammaSqrt2,
1779 sigmaSqrtPi,
1781 fourPiEps,
1782 erfcBuf);
1783
1784 // TODO: leave these 2 functions here or move it to e.g. forces? Needs to be
1785 // executed after calculateElectrostaticEnergy.
1786 if (derivativesElec)
1787 {
1788 s.calculateDAdrQ(ewaldSetup, gammaSqrt2, fourPiEps, erfcBuf);
1790 gammaSqrt2,
1791 sigmaSqrtPi,
1793 fourPiEps);
1794 }
1795
1796 //for (auto const& a : structure.atoms)
1797 //{
1798 // //structure.charge += a.charge;
1799 //}
1800 return;
1801}
ErfcBuf erfcBuf
Definition: Mode.h:653
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.
Definition: Structure.cpp:588
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...
Definition: Structure.cpp:1083
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.
Definition: Structure.cpp:844

References nnp::Structure::calculateDAdrQ(), nnp::Structure::calculateElectrostaticEnergy(), nnp::Structure::calculateElectrostaticEnergyDerivatives(), elements, erfcBuf, ewaldSetup, fourPiEps, numElements, and screeningFunction.

Referenced by nnp::Training::calculateError(), evaluateNNP(), nnp::InterfaceLammps::process(), and nnp::Training::update().

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

◆ calculateEnergy()

void Mode::calculateEnergy ( Structure structure) const

Calculate potential energy for a given structure.

Parameters
[in]structureInput structure.

Sum up potential energy from atomic energy contributions. Result is stored in Structure::energy.

Definition at line 1803 of file Mode.cpp.

1804{
1805 // Loop over all atoms and add atomic contributions to total energy.
1806 structure.energy = 0.0;
1807 structure.energyShort = 0.0;
1808 for (vector<Atom>::iterator it = structure.atoms.begin();
1809 it != structure.atoms.end(); ++it)
1810 {
1811 structure.energyShort += it->energy;
1812 }
1813 structure.energy = structure.energyShort + structure.energyElec;
1814
1815 //cout << strpr("Electrostatic energy: %24.16E\n", structure.energyElec);
1816 //cout << strpr("Short-range energy: %24.16E\n", structure.energyShort);
1817 //cout << strpr("Sum energy: %24.16E\n", structure.energy);
1818 //cout << strpr("Offset energy: %24.16E\n", getEnergyOffset(structure));
1819 //cout << "---------------------\n";
1820 //cout << strpr("Total energy: %24.16E\n", structure.energy + getEnergyOffset(structure));
1821 //cout << strpr("Reference energy: %24.16E\n", structure.energyRef + getEnergyOffset(structure));
1822 //cout << "---------------------\n";
1823 //cout << "without offset: \n";
1824 //cout << strpr("Total energy: %24.16E\n", structure.energy);
1825 //cout << strpr("Reference energy: %24.16E\n", structure.energyRef);
1826
1827 return;
1828}
double energyShort
Short-range part of the potential energy predicted by NNP.
Definition: Structure.h:88
double energyElec
Electrostatics part of the potential energy predicted by NNP.
Definition: Structure.h:91

References nnp::Structure::atoms, nnp::Structure::energy, nnp::Structure::energyElec, and nnp::Structure::energyShort.

Referenced by nnp::Training::calculateError(), nnp::Training::dataSetNormalization(), nnp::Training::dPdcN(), evaluateNNP(), main(), nnp::InterfaceLammps::process(), and nnp::Training::update().

Here is the caller graph for this function:

◆ calculateCharge()

void Mode::calculateCharge ( Structure structure) const

Calculate total charge for a given structure.

Parameters
[in]structureInput structure.

Sum up charge from atomic charge contributions. Result is stored in Structure::charge.

Definition at line 1830 of file Mode.cpp.

1831{
1832 // Loop over all atoms and add atomic charge contributions to total charge.
1833 structure.charge = 0.0;
1834 for (vector<Atom>::iterator it = structure.atoms.begin();
1835 it != structure.atoms.end(); ++it)
1836 {
1837 structure.charge += it->charge;
1838 }
1839
1840 //cout << "---------------------\n";
1841 //cout << strpr("Total charge: %24.16E\n", structure.charge);
1842 //cout << strpr("Reference charge: %24.16E\n", structure.chargeRef);
1843
1844 //throw runtime_error("ERROR: Here ends code for 4G-HDNNPs\n");
1845
1846 return;
1847}
double charge
Charge determined by neural network potential.
Definition: Structure.h:96

References nnp::Structure::atoms, and nnp::Structure::charge.

Referenced by evaluateNNP(), and nnp::InterfaceLammps::process().

Here is the caller graph for this function:

◆ calculateForces()

void Mode::calculateForces ( Structure structure) const

Calculate forces for all atoms in given structure.

Parameters
[in]structureInput structure.

Combine intermediate results from symmetry function and neural network computation to atomic forces. Results are stored in Atom::f.

Definition at line 1849 of file Mode.cpp.

1850{
1852 {
1853 throw runtime_error("WARNING: Forces are not implemented yet.\n");
1854 return;
1855 }
1856
1857 // Loop over all atoms, center atom i (ai).
1858#ifdef _OPENMP
1859 #pragma omp parallel
1860 {
1861 #pragma omp for
1862#endif
1863 for (size_t i = 0; i < structure.atoms.size(); ++i)
1864 {
1865 // Set pointer to atom.
1866 Atom &ai = structure.atoms.at(i);
1867
1868 // Reset forces.
1869 ai.f = Vec3D{};
1870
1871 // First add force contributions from atom i itself (gradient of
1872 // atomic energy E_i).
1873 ai.f += ai.calculateSelfForceShort();
1874
1875 // Now loop over all neighbor atoms j of atom i. These may hold
1876 // non-zero derivatives of their symmetry functions with respect to
1877 // atom i's coordinates. Some atoms may appear multiple times in the
1878 // neighbor list because of periodic boundary conditions. To avoid
1879 // that the same contributions are added multiple times use the
1880 // "unique neighbor" list. This list contains also the central atom
1881 // index as first entry and hence also adds contributions of periodic
1882 // images of the central atom (happens when cutoff radii larger than
1883 // cell vector lengths are used, but this is already considered in the
1884 // self-interaction).
1885 for (vector<size_t>::const_iterator it =
1886 ai.neighborsUnique.begin() + 1;
1887 it != ai.neighborsUnique.end(); ++it)
1888 {
1889 // Define shortcut for atom j (aj).
1890 Atom &aj = structure.atoms.at(*it);
1891#ifndef N2P2_FULL_SFD_MEMORY
1892 vector<vector<size_t> > const& tableFull
1893 = elements.at(aj.element).getSymmetryFunctionTable();
1894#endif
1895 // Loop over atom j's neighbors (n), atom i should be one of them.
1896 // TODO: Could implement maxCutoffRadiusSymFunc for each element and
1897 // use this instead of maxCutoffRadius.
1898 size_t const numNeighbors =
1900 for (size_t k = 0; k < numNeighbors; ++k) {
1901 Atom::Neighbor const &n = aj.neighbors[k];
1902 // If atom j's neighbor is atom i add force contributions.
1903 if (n.index == ai.index)
1904 {
1905#ifndef N2P2_FULL_SFD_MEMORY
1906 ai.f += aj.calculatePairForceShort(n, &tableFull);
1907#else
1908 ai.f += aj.calculatePairForceShort(n);
1909#endif
1910 }
1911 }
1912 }
1913 }
1914
1916 {
1917 Structure &s = structure;
1918
1919 VectorXd lambdaTotal = s.calculateForceLambdaTotal();
1920 VectorXd lambdaElec = s.calculateForceLambdaElec();
1921
1922#ifdef _OPENMP
1923 #pragma omp for
1924#endif
1925 // OpenMP 4.0 doesn't support range based loops
1926 for (size_t i = 0; i < s.numAtoms; ++i)
1927 {
1928 auto &ai = s.atoms[i];
1929 ai.f -= ai.pEelecpr;
1930 ai.fElec = -ai.pEelecpr;
1931
1932 for (size_t j = 0; j < s.numAtoms; ++j)
1933 {
1934 Atom const &aj = s.atoms.at(j);
1935
1936#ifndef NNP_FULL_SFD_MEMORY
1937 vector<vector<size_t> > const &tableFull
1938 = elements.at(aj.element).getSymmetryFunctionTable();
1939 Vec3D dChidr = aj.calculateDChidr(ai.index,
1941 &tableFull);
1942#else
1943 Vec3D dChidr = aj.calculateDChidr(ai.index,
1945#endif
1946 ai.f -= lambdaTotal(j) * (ai.dAdrQ[j] + dChidr);
1947 ai.fElec -= lambdaElec(j) * (ai.dAdrQ[j] + dChidr);
1948
1949 /*
1950 loopFile << "i: " << ai.index << ", j: " << j << endl
1951 << "ai.f: " << ai.f[0] << " " << ai.f[1] << " " << ai.f[2] << endl
1952 << "lambda: " << lambdaTotal(j) << endl
1953 << "dChidr: " << dChidr[0] << " " << dChidr[1] << " " << dChidr[2] << endl
1954 << "dAdrQ: " << ai.dAdrQ[j][0] << " " << ai.dAdrQ[j][1] << " " << ai.dAdrQ[j][2] << endl
1955 << endl;
1956 */
1957 }
1958 }
1959 }
1960#ifdef _OPENMP
1961 }
1962#endif
1963 return;
1964}
Struct to store information on neighbor atoms.
Definition: Atom.h:36
std::size_t index
Index of neighbor atom.
Definition: Atom.h:38
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
Definition: Atom.h:170
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
Vec3D f
Force vector calculated by neural network.
Definition: Atom.h:127
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...
Definition: Atom.cpp:381
Vec3D calculateSelfForceShort() const
Calculate force resulting from gradient of this atom's (short-ranged) energy contribution with respec...
Definition: Atom.cpp:371
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
Vec3D fElec
Force vector resulting from electrostatics.
Definition: Atom.h:129
Vec3D pEelecpr
Partial derivative of electrostatic energy with respect to this atom's coordinates.
Definition: Atom.h:134
std::vector< Vec3D > dAdrQ
If dQdr has been calculated for respective components.
Definition: Atom.h:168
std::vector< std::size_t > neighborsUnique
List of unique neighbor indices (don't count multiple PBC images).
Definition: Atom.h:136
Eigen::VectorXd const calculateForceLambdaElec() const
Calculate lambda_elec vector which is needed for the electrostatic force calculation in 4G NN.
Definition: Structure.cpp:1201
Eigen::VectorXd const calculateForceLambdaTotal() const
Calculate lambda_total vector which is needed for the total force calculation in 4G NN.
Definition: Structure.cpp:1188
std::size_t numAtoms
Total number of atoms present in this structure.
Definition: Structure.h:75
Vector in 3 dimensional real space.
Definition: Vec3D.h:30

References nnp::Structure::atoms, nnp::Atom::calculateDChidr(), nnp::Structure::calculateForceLambdaElec(), nnp::Structure::calculateForceLambdaTotal(), nnp::Atom::calculatePairForceShort(), nnp::Atom::calculateSelfForceShort(), nnp::Atom::element, elements, nnp::Atom::f, nnp::Atom::getStoredMinNumNeighbors(), HDNNP_4G, HDNNP_Q, nnp::Atom::Neighbor::index, nnp::Atom::index, maxCutoffRadius, nnp::Atom::neighbors, nnp::Atom::neighborsUnique, nnpType, and nnp::Structure::numAtoms.

Referenced by nnp::Training::calculateError(), nnp::Training::dataSetNormalization(), nnp::Training::dPdcN(), evaluateNNP(), main(), and nnp::Training::update().

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

◆ evaluateNNP()

void Mode::evaluateNNP ( Structure structure,
bool  useForces = true,
bool  useDEdG = true 
)

Evaluate neural network potential (includes total energy, optionally forces and in some cases charges.

Parameters
[in]structureInput structure.
[in]useForcesIf true, calculate forces too.
[in]useDEdGIf true, calculate dE/dG too.

Definition at line 1967 of file Mode.cpp.

1968{
1969 useDEdG = (useForces || useDEdG);
1970 if (nnpType == NNPType::HDNNP_4G) {
1972 ewaldSetup,
1976 cutoffs);
1977
1978 }
1979 // TODO: For the moment sort neighbors only for 4G-HDNNPs (breaks some
1980 // CI tests because of small numeric changes).
1981 else structure.calculateNeighborList(maxCutoffRadius, false);
1982
1983#ifdef NNP_NO_SF_GROUPS
1984 calculateSymmetryFunctions(structure, true);
1985#else
1986 calculateSymmetryFunctionGroups(structure, useForces);
1987#endif
1988
1989 // Needed if useForces == false but sensitivity data is requested.
1990 if (useDEdG && !useForces)
1991 {
1992 // Manually allocate dEdG vectors.
1993 for (auto& a : structure.atoms)
1994 {
1996 {
1997 a.dEdG.resize(a.numSymmetryFunctions + 1, 0.0);
1998 a.dChidG.resize(a.numSymmetryFunctions, 0.0);
1999 }
2000 else
2001 a.dEdG.resize(a.numSymmetryFunctions, 0.0);
2002 }
2003 }
2004
2005 calculateAtomicNeuralNetworks(structure, useDEdG);
2007 {
2008 chargeEquilibration(structure, useForces);
2009 calculateAtomicNeuralNetworks(structure, useDEdG, "short");
2010 }
2011 calculateEnergy(structure);
2012 if (nnpType == NNPType::HDNNP_4G ||
2014 calculateCharge(structure);
2015 if (useForces) calculateForces(structure);
2016}
void calculateCharge(Structure &structure) const
Calculate total charge for a given structure.
Definition: Mode.cpp:1830
void chargeEquilibration(Structure &structure, bool const derivativesElec)
Perform global charge equilibration method.
Definition: Mode.cpp:1754
void calculateSymmetryFunctions(Structure &structure, bool const derivatives)
Calculate all symmetry functions for all atoms in given structure.
Definition: Mode.cpp:1480
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.
Definition: Structure.cpp:273

References nnp::Structure::atoms, calculateAtomicNeuralNetworks(), calculateCharge(), calculateEnergy(), calculateForces(), nnp::Structure::calculateMaxCutoffRadiusOverall(), nnp::Structure::calculateNeighborList(), calculateSymmetryFunctionGroups(), calculateSymmetryFunctions(), chargeEquilibration(), cutoffs, ewaldSetup, nnp::ScreeningFunction::getOuter(), HDNNP_4G, HDNNP_Q, maxCutoffRadius, nnpType, and screeningFunction.

Referenced by main(), and nnp::Prediction::predict().

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

◆ addEnergyOffset()

void Mode::addEnergyOffset ( Structure structure,
bool  ref = true 
)

Add atomic energy offsets to reference energy.

Parameters
[in]structureInput structure.
[in]refIf true, use reference energy, otherwise use NN energy.

Definition at line 2018 of file Mode.cpp.

2019{
2020 for (size_t i = 0; i < numElements; ++i)
2021 {
2022 if (ref)
2023 {
2024 structure.energyRef += structure.numAtomsPerElement.at(i)
2025 * elements.at(i).getAtomicEnergyOffset();
2026 }
2027 else
2028 {
2029 structure.energy += structure.numAtomsPerElement.at(i)
2030 * elements.at(i).getAtomicEnergyOffset();
2031 }
2032 }
2033
2034 return;
2035}
std::vector< std::size_t > numAtomsPerElement
Number of atoms of each element in this structure.
Definition: Structure.h:120
double energyRef
Reference potential energy.
Definition: Structure.h:85

References elements, nnp::Structure::energy, nnp::Structure::energyRef, nnp::Structure::numAtomsPerElement, and numElements.

Referenced by main(), nnp::Prediction::predict(), nnp::InterfaceLammps::process(), and nnp::Training::writeSetsToFiles().

Here is the caller graph for this function:

◆ removeEnergyOffset()

void Mode::removeEnergyOffset ( Structure structure,
bool  ref = true 
)

Remove atomic energy offsets from reference energy.

Parameters
[in]structureInput structure.
[in]refIf true, use reference energy, otherwise use NN energy.

This function should be called immediately after structures are read in.

Definition at line 2037 of file Mode.cpp.

2038{
2039 for (size_t i = 0; i < numElements; ++i)
2040 {
2041 if (ref)
2042 {
2043 structure.energyRef -= structure.numAtomsPerElement.at(i)
2044 * elements.at(i).getAtomicEnergyOffset();
2045 }
2046 else
2047 {
2048 structure.energy -= structure.numAtomsPerElement.at(i)
2049 * elements.at(i).getAtomicEnergyOffset();
2050 }
2051 }
2052
2053 return;
2054}

References elements, nnp::Structure::energy, nnp::Structure::energyRef, nnp::Structure::numAtomsPerElement, and numElements.

Referenced by nnp::Dataset::distributeStructures(), nnp::Prediction::readStructureFromFile(), and nnp::Training::writeSetsToFiles().

Here is the caller graph for this function:

◆ getEnergyOffset()

double Mode::getEnergyOffset ( Structure const &  structure) const

Get atomic energy offset for given structure.

Parameters
[in]structureInput structure.
Returns
Summed atomic energy offsets for structure.

Definition at line 2056 of file Mode.cpp.

2057{
2058 double result = 0.0;
2059
2060 for (size_t i = 0; i < numElements; ++i)
2061 {
2062 result += structure.numAtomsPerElement.at(i)
2063 * elements.at(i).getAtomicEnergyOffset();
2064 }
2065
2066 return result;
2067}

References elements, nnp::Structure::numAtomsPerElement, and numElements.

Referenced by main(), and nnp::Dataset::writeSymmetryFunctionFile().

Here is the caller graph for this function:

◆ getEnergyWithOffset()

double Mode::getEnergyWithOffset ( Structure const &  structure,
bool  ref = true 
) const

Add atomic energy offsets and return energy.

Parameters
[in]structureInput structure.
[in]refIf true, use reference energy, otherwise use NN energy.
Returns
Reference or NNP energy with energy offsets added.
Note
If normalization is used, ensure that structure energy is already in physical units.

Definition at line 2069 of file Mode.cpp.

2070{
2071 double result;
2072 if (ref) result = structure.energyRef;
2073 else result = structure.energy;
2074
2075 for (size_t i = 0; i < numElements; ++i)
2076 {
2077 result += structure.numAtomsPerElement.at(i)
2078 * elements.at(i).getAtomicEnergyOffset();
2079 }
2080
2081 return result;
2082}

References elements, nnp::Structure::energy, nnp::Structure::energyRef, nnp::Structure::numAtomsPerElement, and numElements.

Referenced by nnp::Training::dataSetNormalization(), and main().

Here is the caller graph for this function:

◆ normalized()

double Mode::normalized ( std::string const &  property,
double  value 
) const

Apply normalization to given property.

Parameters
[in]propertyOne of "energy", "force", "charge", "hardness" "negativity".
[in]valueInput property value in physical units.
Returns
Property in normalized units.

Definition at line 2084 of file Mode.cpp.

2085{
2086 if (property == "energy") return value * convEnergy;
2087 else if (property == "force") return value * convEnergy / convLength;
2088 else if (property == "charge") return value * convCharge;
2089 else if (property == "hardness")
2090 return value * convEnergy / pow(convCharge, 2);
2091 else if (property == "negativity") return value * convEnergy / convCharge;
2092 else throw runtime_error("ERROR: Unknown property to convert to "
2093 "normalized units.\n");
2094}

References convCharge, convEnergy, and convLength.

Referenced by calculateAtomicNeuralNetworks(), setupElectrostatics(), and nnp::Training::update().

Here is the caller graph for this function:

◆ normalizedEnergy()

double Mode::normalizedEnergy ( Structure const &  structure,
bool  ref = true 
) const

Apply normalization to given energy of structure.

Parameters
[in]structureInput structure with energy in physical units.
[in]refIf true, use reference energy, otherwise use NN energy.
Returns
Energy in normalized units.

Definition at line 2096 of file Mode.cpp.

2097{
2098 if (ref)
2099 {
2100 return (structure.energyRef - structure.numAtoms * meanEnergy)
2101 * convEnergy;
2102 }
2103 else
2104 {
2105 return (structure.energy - structure.numAtoms * meanEnergy)
2106 * convEnergy;
2107 }
2108}

References convEnergy, nnp::Structure::energy, nnp::Structure::energyRef, meanEnergy, and nnp::Structure::numAtoms.

◆ physical()

double Mode::physical ( std::string const &  property,
double  value 
) const

Undo normalization for a given property.

Parameters
[in]propertyOne of "energy", "force", "charge", "hardness", "negativity".
[in]valueInput property value in normalized units.
Returns
Property in physical units.

Definition at line 2110 of file Mode.cpp.

2111{
2112 if (property == "energy") return value / convEnergy;
2113 else if (property == "force") return value * convLength / convEnergy;
2114 else if (property == "charge") return value / convCharge;
2115 else if (property == "hardness")
2116 return value / (convEnergy / pow(convCharge, 2));
2117 else if (property == "negativity") return value * convCharge / convEnergy;
2118 else throw runtime_error("ERROR: Unknown property to convert to physical "
2119 "units.\n");
2120}

References convCharge, convEnergy, and convLength.

Referenced by nnp::InterfaceLammps::getAtomicEnergy(), main(), nnp::Training::printEpoch(), setupElectrostatics(), nnp::Training::writeHardness(), and nnp::Training::writeLearningCurve().

Here is the caller graph for this function:

◆ physicalEnergy()

double Mode::physicalEnergy ( Structure const &  structure,
bool  ref = true 
) const

Undo normalization for a given energy of structure.

Parameters
[in]structureInput structure with energy in normalized units.
[in]refIf true, use reference energy, otherwise use NN energy.
Returns
Energy in physical units.

Definition at line 2122 of file Mode.cpp.

2123{
2124 if (ref)
2125 {
2126 return structure.energyRef / convEnergy + structure.numAtoms
2127 * meanEnergy;
2128 }
2129 else
2130 {
2131 return structure.energy / convEnergy + structure.numAtoms * meanEnergy;
2132 }
2133}

References convEnergy, nnp::Structure::energy, nnp::Structure::energyRef, meanEnergy, and nnp::Structure::numAtoms.

Referenced by main(), nnp::InterfaceLammps::process(), and nnp::Dataset::writeSymmetryFunctionFile().

Here is the caller graph for this function:

◆ convertToNormalizedUnits()

void Mode::convertToNormalizedUnits ( Structure structure) const

Convert one structure to normalized units.

Parameters
[in,out]structureInput structure.

Definition at line 2135 of file Mode.cpp.

2136{
2138
2139 return;
2140}
void toNormalizedUnits(double meanEnergy, double convEnergy, double convLength, double convCharge)
Normalize structure, shift energy and change energy, length and charge unit.
Definition: Structure.cpp:1249

References convCharge, convEnergy, convLength, meanEnergy, and nnp::Structure::toNormalizedUnits().

Here is the call graph for this function:

◆ convertToPhysicalUnits()

void Mode::convertToPhysicalUnits ( Structure structure) const

Convert one structure to physical units.

Parameters
[in,out]structureInput structure.

Definition at line 2142 of file Mode.cpp.

2143{
2145
2146 return;
2147}
void toPhysicalUnits(double meanEnergy, double convEnergy, double convLength, double convCharge)
Switch to physical units, shift energy and change energy, length and charge unit.
Definition: Structure.cpp:1278

References convCharge, convEnergy, convLength, meanEnergy, and nnp::Structure::toPhysicalUnits().

Referenced by main().

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

◆ logEwaldCutoffs()

void Mode::logEwaldCutoffs ( )

Logs Ewald params whenever they change.

Definition at line 2149 of file Mode.cpp.

2150{
2151 if (nnpType != NNPType::HDNNP_4G) return;
2153}
void logEwaldCutoffs(Log &log, double const lengthConversion) const
Use after Ewald summation!
Definition: EwaldSetup.cpp:95

References convLength, ewaldSetup, HDNNP_4G, log, nnp::EwaldSetup::logEwaldCutoffs(), and nnpType.

Referenced by main().

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

◆ getNumExtrapolationWarnings()

size_t Mode::getNumExtrapolationWarnings ( ) const

Count total number of extrapolation warnings encountered for all elements and symmetry functions.

Returns
Number of extrapolation warnings.

Definition at line 2166 of file Mode.cpp.

2167{
2168 size_t numExtrapolationWarnings = 0;
2169
2170 for (vector<Element>::const_iterator it = elements.begin();
2171 it != elements.end(); ++it)
2172 {
2173 numExtrapolationWarnings +=
2174 it->statistics.countExtrapolationWarnings();
2175 }
2176
2177 return numExtrapolationWarnings;
2178}

References elements.

Referenced by LAMMPS_NS::PairHDNNP::handleExtrapolationWarnings(), and main().

Here is the caller graph for this function:

◆ resetExtrapolationWarnings()

void Mode::resetExtrapolationWarnings ( )

Erase all extrapolation warnings and reset counters.

Definition at line 2155 of file Mode.cpp.

2156{
2157 for (vector<Element>::iterator it = elements.begin();
2158 it != elements.end(); ++it)
2159 {
2160 it->statistics.resetExtrapolationWarnings();
2161 }
2162
2163 return;
2164}

References elements.

Referenced by main().

Here is the caller graph for this function:

◆ getNnpType()

Mode::NNPType nnp::Mode::getNnpType ( ) const
inline

Getter for Mode::nnpType.

Returns
HDNNP type (2G, 4G,..) that was set up.

Definition at line 668 of file Mode.h.

669{
670 return nnpType;
671}

References nnpType.

Referenced by main().

Here is the caller graph for this function:

◆ getMeanEnergy()

double nnp::Mode::getMeanEnergy ( ) const
inline

Getter for Mode::meanEnergy.

Returns
Mean energy per atom.

Definition at line 673 of file Mode.h.

674{
675 return meanEnergy;
676}

References meanEnergy.

Referenced by main().

Here is the caller graph for this function:

◆ getConvEnergy()

double nnp::Mode::getConvEnergy ( ) const
inline

Getter for Mode::convEnergy.

Returns
Energy unit conversion factor.

Definition at line 678 of file Mode.h.

679{
680 return convEnergy;
681}

References convEnergy.

Referenced by main().

Here is the caller graph for this function:

◆ getConvLength()

double nnp::Mode::getConvLength ( ) const
inline

Getter for Mode::convLength.

Returns
Length unit conversion factor.

Definition at line 683 of file Mode.h.

684{
685 return convLength;
686}

References convLength.

Referenced by main().

Here is the caller graph for this function:

◆ getConvCharge()

double nnp::Mode::getConvCharge ( ) const
inline

Getter for Mode::convCharge.

Returns
Charge unit conversion factor.

Definition at line 688 of file Mode.h.

689{
690 return convCharge;
691}

References convCharge.

Referenced by main().

Here is the caller graph for this function:

◆ getMaxCutoffRadius()

double nnp::Mode::getMaxCutoffRadius ( ) const
inline

Getter for Mode::maxCutoffRadius.

Returns
Maximum cutoff radius of all symmetry functions.

The maximum cutoff radius is determined by setupSymmetryFunctions().

Definition at line 693 of file Mode.h.

694{
695 return maxCutoffRadius;
696}

References maxCutoffRadius.

Referenced by main(), and nnp::SetupAnalysis::writeSymmetryFunctionShape().

Here is the caller graph for this function:

◆ getNumElements()

std::size_t nnp::Mode::getNumElements ( ) const
inline

Getter for Mode::numElements.

Returns
Number of elements defined.

The number of elements is determined by setupElements().

Definition at line 698 of file Mode.h.

699{
700 return numElements;
701}

References numElements.

Referenced by main().

Here is the caller graph for this function:

◆ getNumSymmetryFunctions()

vector< size_t > Mode::getNumSymmetryFunctions ( ) const

Get number of symmetry functions per element.

Returns
Vector with number of symmetry functions for each element.

Definition at line 2180 of file Mode.cpp.

2181{
2182 vector<size_t> v;
2183
2184 for (vector<Element>::const_iterator it = elements.begin();
2185 it != elements.end(); ++it)
2186 {
2187 v.push_back(it->numSymmetryFunctions());
2188 }
2189
2190 return v;
2191}

References elements.

Referenced by main().

Here is the caller graph for this function:

◆ useNormalization()

bool nnp::Mode::useNormalization ( ) const
inline

Check if normalization is enabled.

Returns
Value of normalize.

Definition at line 703 of file Mode.h.

704{
705 return normalize;
706}

References normalize.

Referenced by main().

Here is the caller graph for this function:

◆ settingsKeywordExists()

bool Mode::settingsKeywordExists ( std::string const &  keyword) const

Check if keyword was found in settings file.

Parameters
[in]keywordKeyword for which value is requested.
Returns
true if keyword exists, false otherwise.

Definition at line 2193 of file Mode.cpp.

2194{
2195 return settings.keywordExists(keyword);
2196}

References nnp::settings::Settings::keywordExists(), and settings.

Referenced by main().

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

◆ settingsGetValue()

string Mode::settingsGetValue ( std::string const &  keyword) const

Get value for given keyword in Settings instance.

Parameters
[in]keywordKeyword for which value is requested.
Returns
Value string corresponding to keyword.

Definition at line 2198 of file Mode.cpp.

2199{
2200 return settings.getValue(keyword);
2201}
std::string getValue(Key const &key) const override
Definition: Settings.cpp:251

References nnp::settings::Settings::getValue(), and settings.

Here is the call graph for this function:

◆ pruneSymmetryFunctionsRange()

vector< size_t > Mode::pruneSymmetryFunctionsRange ( double  threshold)

Prune symmetry functions according to their range and write settings file.

Parameters
[in]thresholdSymmetry functions with range (max - min) smaller than this threshold will be pruned.
Returns
List of line numbers with symmetry function to be removed.

Definition at line 2228 of file Mode.cpp.

2229{
2230 vector<size_t> prune;
2231
2232 // Check if symmetry functions have low range.
2233 for (vector<Element>::const_iterator it = elements.begin();
2234 it != elements.end(); ++it)
2235 {
2236 for (size_t i = 0; i < it->numSymmetryFunctions(); ++i)
2237 {
2238 SymFnc const& s = it->getSymmetryFunction(i);
2239 if (fabs(s.getGmax() - s.getGmin()) < threshold)
2240 {
2241 prune.push_back(it->getSymmetryFunction(i).getLineNumber());
2242 }
2243 }
2244 }
2245
2246 return prune;
2247}
double getGmin() const
Get private Gmin member variable.
Definition: SymFnc.h:361
double getGmax() const
Get private Gmax member variable.
Definition: SymFnc.h:362

References elements, nnp::SymFnc::getGmax(), and nnp::SymFnc::getGmin().

Referenced by main().

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

◆ pruneSymmetryFunctionsSensitivity()

vector< size_t > Mode::pruneSymmetryFunctionsSensitivity ( double  threshold,
std::vector< std::vector< double > >  sensitivity 
)

Prune symmetry functions with sensitivity analysis data.

Parameters
[in]thresholdSymmetry functions with sensitivity lower than this threshold will be pruned.
[in]sensitivitySensitivity data for each element and symmetry function.
Returns
List of line numbers with symmetry function to be removed.

Definition at line 2249 of file Mode.cpp.

2252{
2253 vector<size_t> prune;
2254
2255 for (size_t i = 0; i < numElements; ++i)
2256 {
2257 for (size_t j = 0; j < elements.at(i).numSymmetryFunctions(); ++j)
2258 {
2259 if (sensitivity.at(i).at(j) < threshold)
2260 {
2261 prune.push_back(
2262 elements.at(i).getSymmetryFunction(j).getLineNumber());
2263 }
2264 }
2265 }
2266
2267 return prune;
2268}

References elements, and numElements.

Referenced by main().

Here is the caller graph for this function:

◆ writePrunedSettingsFile()

void Mode::writePrunedSettingsFile ( std::vector< std::size_t >  prune,
std::string  fileName = "output.nn" 
) const

Copy settings file but comment out lines provided.

Parameters
[in]pruneList of line numbers to comment out.
[in]fileNameOutput file name.

Definition at line 2204 of file Mode.cpp.

2205{
2206 ofstream file(fileName.c_str());
2207 vector<string> settingsLines = settings.getSettingsLines();
2208 for (size_t i = 0; i < settingsLines.size(); ++i)
2209 {
2210 if (find(prune.begin(), prune.end(), i) != prune.end())
2211 {
2212 file << "# ";
2213 }
2214 file << settingsLines.at(i) << '\n';
2215 }
2216 file.close();
2217
2218 return;
2219}
std::vector< std::string > getSettingsLines() const
Get complete settings file.
Definition: Settings.cpp:271

References nnp::settings::Settings::getSettingsLines(), and settings.

Referenced by main().

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

◆ writeSettingsFile()

void Mode::writeSettingsFile ( std::ofstream *const &  file) const

Write complete settings file.

Parameters
[in,out]fileSettings file.

Definition at line 2221 of file Mode.cpp.

2222{
2224
2225 return;
2226}
void writeSettingsFile(std::ofstream *const &file, std::map< std::size_t, std::string > const &replacements={}) const
Write complete settings file.
Definition: Settings.cpp:301

References settings, and nnp::settings::Settings::writeSettingsFile().

Referenced by nnp::Training::dataSetNormalization(), and main().

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

◆ readNeuralNetworkWeights()

void Mode::readNeuralNetworkWeights ( std::string const &  id,
std::string const &  fileName 
)
protected

Read in weights for a specific type of neural network.

Parameters
[in]idActual network type to initialize ("short" or "elec").
[in]fileNameFormatWeights file name format.

Definition at line 2270 of file Mode.cpp.

2272{
2273 for (vector<Element>::iterator it = elements.begin();
2274 it != elements.end(); ++it)
2275 {
2276 string fileName = strpr(fileNameFormat.c_str(),
2277 it->getAtomicNumber());
2278 log << strpr("Setting weights for element %2s from file: %s\n",
2279 it->getSymbol().c_str(),
2280 fileName.c_str());
2281 vector<double> weights = readColumnsFromFile(fileName,
2282 vector<size_t>(1, 0)
2283 ).at(0);
2284 NeuralNetwork& nn = it->neuralNetworks.at(id);
2285 nn.setConnections(&(weights.front()));
2286 }
2287
2288 return;
2289}
void setConnections(double const *const &connections)
Set neural network weights and biases.

References elements, log, nnp::readColumnsFromFile(), nnp::NeuralNetwork::setConnections(), and nnp::strpr().

Referenced by nnp::Training::initializeWeights(), setupNeuralNetworkWeights(), and nnp::Training::setupNumericDerivCheck().

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

Member Data Documentation

◆ elementMap

◆ log

Log nnp::Mode::log

Global log file.

Definition at line 593 of file Mode.h.

Referenced by nnp::Training::allocateArrays(), nnp::Training::calculateNeighborLists(), calculateSymmetryFunctionGroups(), calculateSymmetryFunctions(), nnp::Training::checkSelectionMode(), nnp::Dataset::collectSymmetryFunctionStatistics(), nnp::Training::dataSetNormalization(), nnp::Dataset::distributeStructures(), LAMMPS_NS::PairHDNNP::init_style(), initialize(), nnp::InterfaceLammps::initialize(), nnp::Training::initializeWeights(), nnp::Training::initializeWeightsMemory(), loadSettingsFile(), logEwaldCutoffs(), nnp::Training::loop(), main(), nnp::Training::printEpoch(), nnp::Training::printHeader(), nnp::InterfaceLammps::process(), nnp::Training::randomizeNeuralNetworkWeights(), readNeuralNetworkWeights(), nnp::Training::selectSets(), setupCutoff(), setupElectrostatics(), setupElementMap(), setupElements(), nnp::Training::setupFileOutput(), nnp::Dataset::setupMPI(), setupNeuralNetwork(), setupNeuralNetworkWeights(), setupNormalization(), nnp::Training::setupNumericDerivCheck(), nnp::Dataset::setupRandomNumberGenerator(), nnp::Training::setupSelectionMode(), setupSymmetryFunctionCache(), setupSymmetryFunctionGroups(), setupSymmetryFunctionMemory(), setupSymmetryFunctions(), setupSymmetryFunctionScaling(), setupSymmetryFunctionScalingNone(), setupSymmetryFunctionStatistics(), nnp::Training::setupTraining(), nnp::Training::setupUpdatePlan(), nnp::Dataset::sortNeighborLists(), nnp::Dataset::writeAtomicEnvironmentFile(), nnp::InterfaceLammps::writeExtrapolationWarnings(), nnp::Dataset::writeNeighborHistogram(), nnp::Dataset::writeNeighborLists(), nnp::Training::writeSetsToFiles(), nnp::Dataset::writeSymmetryFunctionFile(), nnp::Dataset::writeSymmetryFunctionHistograms(), nnp::Dataset::writeSymmetryFunctionScaling(), and nnp::SetupAnalysis::writeSymmetryFunctionShape().

◆ nnpType

◆ normalize

◆ checkExtrapolationWarnings

bool nnp::Mode::checkExtrapolationWarnings
protected

◆ numElements

◆ minNeighbors

std::vector<std::size_t> nnp::Mode::minNeighbors
protected

◆ minCutoffRadius

std::vector<double> nnp::Mode::minCutoffRadius
protected

◆ maxCutoffRadius

◆ cutoffAlpha

double nnp::Mode::cutoffAlpha
protected

Definition at line 635 of file Mode.h.

Referenced by setupCutoff(), and setupSymmetryFunctions().

◆ meanEnergy

◆ convEnergy

◆ convLength

◆ convCharge

◆ fourPiEps

double nnp::Mode::fourPiEps
protected

Definition at line 640 of file Mode.h.

Referenced by chargeEquilibration(), and setupElectrostatics().

◆ ewaldSetup

◆ settings

◆ scalingType

SymFnc::ScalingType nnp::Mode::scalingType
protected

Definition at line 643 of file Mode.h.

Referenced by setupSymmetryFunctionScaling().

◆ cutoffType

CutoffFunction::CutoffType nnp::Mode::cutoffType
protected

Definition at line 644 of file Mode.h.

Referenced by setupCutoff(), and setupSymmetryFunctions().

◆ screeningFunction

◆ elements

std::vector<Element> nnp::Mode::elements
protected

Definition at line 646 of file Mode.h.

Referenced by addEnergyOffset(), calculateAtomicNeuralNetworks(), calculateForces(), calculateSymmetryFunctionGroups(), calculateSymmetryFunctions(), nnp::Training::calculateWeightDerivatives(), chargeEquilibration(), nnp::InterfaceLammps::clearExtrapolationWarnings(), nnp::Training::collectDGdxia(), nnp::Dataset::collectSymmetryFunctionStatistics(), nnp::Training::dataSetNormalization(), nnp::Training::dPdc(), nnp::InterfaceLammps::extractEWBuffer(), nnp::InterfaceLammps::fillEWBuffer(), nnp::InterfaceLammps::getAtomicEnergy(), nnp::Training::getConnectionOffsets(), getEnergyOffset(), getEnergyWithOffset(), nnp::InterfaceLammps::getEWBufferSize(), nnp::InterfaceLammps::getForces(), nnp::Training::getNumConnections(), nnp::Training::getNumConnectionsPerElement(), getNumExtrapolationWarnings(), getNumSymmetryFunctions(), nnp::Training::getWeights(), nnp::Training::initializeWeightsMemory(), pruneSymmetryFunctionsRange(), pruneSymmetryFunctionsSensitivity(), nnp::Training::randomizeNeuralNetworkWeights(), readNeuralNetworkWeights(), removeEnergyOffset(), resetExtrapolationWarnings(), nnp::Training::resetNeuronStatistics(), setupCutoffMatrix(), setupElectrostatics(), setupElements(), setupNeuralNetwork(), setupSymmetryFunctionCache(), setupSymmetryFunctionGroups(), setupSymmetryFunctionMemory(), setupSymmetryFunctions(), setupSymmetryFunctionScaling(), setupSymmetryFunctionScalingNone(), setupSymmetryFunctionStatistics(), nnp::Training::setupTraining(), nnp::Training::setWeights(), nnp::Training::update(), nnp::InterfaceLammps::writeExtrapolationWarnings(), nnp::Training::writeHardness(), nnp::Training::writeNeuronStatistics(), nnp::Dataset::writeSymmetryFunctionHistograms(), nnp::Dataset::writeSymmetryFunctionScaling(), nnp::SetupAnalysis::writeSymmetryFunctionShape(), and nnp::Training::writeWeights().

◆ nnk

std::vector<std::string> nnp::Mode::nnk
protected

◆ nns

◆ cutoffs

std::vector< std::vector<double> > nnp::Mode::cutoffs
protected

Matrix storing all symmetry function cut-offs for all elements.

Definition at line 652 of file Mode.h.

Referenced by nnp::Training::calculateNeighborLists(), evaluateNNP(), nnp::InterfaceLammps::finalizeNeighborList(), and setupCutoffMatrix().

◆ erfcBuf

ErfcBuf nnp::Mode::erfcBuf
protected

Definition at line 653 of file Mode.h.

Referenced by chargeEquilibration().


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