n2p2 - A neural network potential package
SymFncExpRad.cpp
Go to the documentation of this file.
1// n2p2 - A neural network potential package
2// Copyright (C) 2018 Andreas Singraber (University of Vienna)
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17#include "SymFncExpRad.h"
18#include "Atom.h"
19#include "ElementMap.h"
20#include "utility.h"
21#include "Vec3D.h"
22#include <cstdlib> // atof, atoi
23#include <cmath> // exp
24#include <stdexcept> // std::runtime_error
25
26using namespace std;
27using namespace nnp;
28
29SymFncExpRad::SymFncExpRad(ElementMap const& elementMap) :
30 SymFncBaseCutoff(2, elementMap),
31 e1 (0 ),
32 eta (0.0),
33 rs (0.0)
34{
35 minNeighbors = 1;
36 parameters.insert("e1");
37 parameters.insert("eta");
38 parameters.insert("rs/rl");
39}
40
41bool SymFncExpRad::operator==(SymFnc const& rhs) const
42{
43 if (ec != rhs.getEc() ) return false;
44 if (type != rhs.getType()) return false;
45 SymFncExpRad const& c = dynamic_cast<SymFncExpRad const&>(rhs);
46 if (cutoffType != c.cutoffType ) return false;
47 if (cutoffAlpha != c.cutoffAlpha) return false;
48 if (rc != c.rc ) return false;
49 if (eta != c.eta ) return false;
50 if (rs != c.rs ) return false;
51 if (e1 != c.e1 ) return false;
52 return true;
53}
54
55bool SymFncExpRad::operator<(SymFnc const& rhs) const
56{
57 if (ec < rhs.getEc() ) return true;
58 else if (ec > rhs.getEc() ) return false;
59 if (type < rhs.getType()) return true;
60 else if (type > rhs.getType()) return false;
61 SymFncExpRad const& c = dynamic_cast<SymFncExpRad const&>(rhs);
62 if (cutoffType < c.cutoffType ) return true;
63 else if (cutoffType > c.cutoffType ) return false;
64 if (cutoffAlpha < c.cutoffAlpha) return true;
65 else if (cutoffAlpha > c.cutoffAlpha) return false;
66 if (rc < c.rc ) return true;
67 else if (rc > c.rc ) return false;
68 if (eta < c.eta ) return true;
69 else if (eta > c.eta ) return false;
70 if (rs < c.rs ) return true;
71 else if (rs > c.rs ) return false;
72 if (e1 < c.e1 ) return true;
73 else if (e1 > c.e1 ) return false;
74 return false;
75}
76
77void SymFncExpRad::setParameters(string const& parameterString)
78{
79 vector<string> splitLine = split(reduce(parameterString));
80
81 if (type != (size_t)atoi(splitLine.at(1).c_str()))
82 {
83 throw runtime_error("ERROR: Incorrect symmetry function type.\n");
84 }
85
86 ec = elementMap[splitLine.at(0)];
87 e1 = elementMap[splitLine.at(2)];
88 eta = atof(splitLine.at(3).c_str());
89 rs = atof(splitLine.at(4).c_str());
90 rc = atof(splitLine.at(5).c_str());
91
94
95 return;
96}
97
98void SymFncExpRad::changeLengthUnit(double convLength)
99{
100 this->convLength = convLength;
102 rs *= convLength;
103 rc *= convLength;
104
107
108 return;
109}
110
112{
113 string s = strpr("symfunction_short %2s %2zu %2s %16.8E %16.8E %16.8E\n",
114 elementMap[ec].c_str(),
115 type,
116 elementMap[e1].c_str(),
118 rs / convLength,
119 rc / convLength);
120
121 return s;
122}
123
124void SymFncExpRad::calculate(Atom& atom, bool const derivatives) const
125{
126 double result = 0.0;
127#ifndef N2P2_NO_SF_CACHE
128 bool unique = true;
129 size_t c0 = 0;
130 size_t c1 = 0;
131 if (cacheIndices.at(e1).size() > 0)
132 {
133 unique = false;
134 c0 = cacheIndices.at(e1).at(0);
135 c1 = cacheIndices.at(e1).at(1);
136 }
137#endif
138
139 for (size_t j = 0; j < atom.getStoredMinNumNeighbors(rc); ++j)
140 {
141 Atom::Neighbor& n = atom.neighbors[j];
142 if (e1 == n.element && n.d < rc)
143 {
144 // Energy calculation.
145 double const rij = n.d;
146 double const pexp = exp(-eta * (rij - rs) * (rij - rs));
147
148 // Calculate cutoff function and derivative.
149 double pfc;
150 double pdfc;
151#ifndef N2P2_NO_SF_CACHE
152 if (unique) fc.fdf(rij, pfc, pdfc);
153 else
154 {
155 double& cfc = n.cache[c0];
156 double& cdfc = n.cache[c1];
157 if (cfc < 0) fc.fdf(rij, cfc, cdfc);
158 pfc = cfc;
159 pdfc = cdfc;
160 }
161#else
162 fc.fdf(rij, pfc, pdfc);
163#endif
164 result += pexp * pfc;
165 // Force calculation.
166 if (!derivatives) continue;
167 double const p1 = scalingFactor
168 * (pdfc - 2.0 * eta * (rij - rs)
169 * pfc) * pexp / rij;
170 Vec3D dij = p1 * n.dr;
171 // Save force contributions in Atom storage.
172 atom.dGdr[index] += dij;
173#ifndef N2P2_FULL_SFD_MEMORY
174 n.dGdr[indexPerElement[e1]] -= dij;
175#else
176 n.dGdr[index] -= dij;
177#endif
178 }
179 }
180
181 atom.G[index] = scale(result);
182
183 return;
184}
185
187{
188 return strpr(getPrintFormat().c_str(),
189 index + 1,
190 elementMap[ec].c_str(),
191 type,
192 subtype.c_str(),
193 elementMap[e1].c_str(),
195 rs / convLength,
196 rc / convLength,
198 lineNumber + 1);
199}
200
201vector<string> SymFncExpRad::parameterInfo() const
202{
203 vector<string> v = SymFncBaseCutoff::parameterInfo();
204 string s;
205 size_t w = sfinfoWidth;
206
207 s = "e1";
208 v.push_back(strpr((pad(s, w) + "%s" ).c_str(), elementMap[e1].c_str()));
209 s = "eta";
210 v.push_back(strpr((pad(s, w) + "%14.8E").c_str(),
212 s = "rs";
213 v.push_back(strpr((pad(s, w) + "%14.8E").c_str(), rs / convLength));
214
215 return v;
216}
217
218double SymFncExpRad::calculateRadialPart(double distance) const
219{
220 double const& r = distance * convLength;
221
222 return exp(-eta * (r - rs) * (r - rs)) * fc.f(r);
223}
224
225double SymFncExpRad::calculateAngularPart(double /* angle */) const
226{
227 return 1.0;
228}
229
231{
232 if (index == e1) return true;
233 else return false;
234}
235
236#ifndef N2P2_NO_SF_CACHE
238{
239 vector<string> v;
240 string s("");
241
242 s += subtype;
243 s += " ";
244 s += strpr("alpha = %16.8E", cutoffAlpha);
245 s += " ";
246 s += strpr("rc = %16.8E", rc / convLength);
247
248 v.push_back(strpr("%zu f ", e1) + s);
249 v.push_back(strpr("%zu df ", e1) + s);
250
251 return v;
252}
253#endif
double f(double r) const
Cutoff function .
void fdf(double r, double &fc, double &dfc) const
Calculate cutoff function and derivative .
void setCutoffParameter(double const alpha)
Set parameter for polynomial cutoff function (CT_POLY).
void setCutoffRadius(double const cutoffRadius)
Set cutoff radius.
Contains element map.
Definition: ElementMap.h:30
Intermediate class for SFs based on cutoff functions.
std::string subtype
Subtype string (specifies cutoff type).
CutoffFunction fc
Cutoff function used by this symmetry function.
CutoffFunction::CutoffType cutoffType
Cutoff type used by this symmetry function.
virtual std::vector< std::string > parameterInfo() const
Get description with parameter names and values.
double cutoffAlpha
Cutoff parameter .
Radial symmetry function (type 2)
Definition: SymFncExpRad.h:49
virtual bool checkRelevantElement(std::size_t index) const
Check whether symmetry function is relevant for given element.
std::size_t e1
Element index of neighbor atom.
Definition: SymFncExpRad.h:134
virtual void setParameters(std::string const &parameterString)
Set symmetry function parameters.
virtual void changeLengthUnit(double convLength)
Change length unit.
virtual double calculateRadialPart(double distance) const
Calculate (partial) symmetry function value for one given distance.
virtual bool operator<(SymFnc const &rhs) const
Overload < operator.
double eta
Width of gaussian.
Definition: SymFncExpRad.h:136
virtual double calculateAngularPart(double angle) const
Calculate (partial) symmetry function value for one given angle.
virtual std::vector< std::string > getCacheIdentifiers() const
Get unique cache identifiers.
virtual std::string parameterLine() const
Give symmetry function parameters in one line.
virtual bool operator==(SymFnc const &rhs) const
Overload == operator.
virtual std::vector< std::string > parameterInfo() const
Get description with parameter names and values.
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate symmetry function for one atom.
double rs
Shift of gaussian.
Definition: SymFncExpRad.h:138
virtual std::string getSettingsLine() const
Get settings file line from currently set parameters.
Symmetry function base class.
Definition: SymFnc.h:40
double convLength
Data set normalization length conversion factor.
Definition: SymFnc.h:296
std::size_t type
Symmetry function type.
Definition: SymFnc.h:268
std::set< std::string > parameters
Set with symmetry function parameter IDs (lookup for printing).
Definition: SymFnc.h:300
std::size_t index
Symmetry function index (per element).
Definition: SymFnc.h:272
double scalingFactor
Scaling factor.
Definition: SymFnc.h:294
std::size_t getType() const
Get private type member variable.
Definition: SymFnc.h:355
double rc
Cutoff radius .
Definition: SymFnc.h:292
std::vector< std::vector< std::size_t > > cacheIndices
Cache indices for each element.
Definition: SymFnc.h:306
ElementMap elementMap
Copy of element map.
Definition: SymFnc.h:270
double scale(double value) const
Apply symmetry function scaling and/or centering.
Definition: SymFnc.cpp:169
std::size_t getEc() const
Get private ec member variable.
Definition: SymFnc.h:356
std::vector< std::size_t > indexPerElement
Per-element index for derivative memory in Atom::Neighbor::dGdr arrays.
Definition: SymFnc.h:302
std::size_t ec
Element index of center atom.
Definition: SymFnc.h:276
static std::size_t const sfinfoWidth
Width of the SFINFO parameter description field (see parameterInfo()).
Definition: SymFnc.h:309
std::size_t minNeighbors
Minimum number of neighbors required.
Definition: SymFnc.h:278
std::size_t lineNumber
Line number.
Definition: SymFnc.h:274
std::string getPrintFormat() const
Generate format string for symmetry function parameter printing.
Definition: SymFnc.cpp:285
Definition: Atom.h:29
string pad(string const &input, size_t num, char fill, bool right)
Definition: utility.cpp:79
string strpr(const char *format,...)
String version of printf function.
Definition: utility.cpp:90
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
Struct to store information on neighbor atoms.
Definition: Atom.h:36
std::vector< double > cache
Symmetry function cache (e.g. for cutoffs, compact functions).
Definition: Atom.h:49
std::size_t element
Element index of neighbor atom.
Definition: Atom.h:42
double d
Distance to neighbor atom.
Definition: Atom.h:44
Vec3D dr
Distance vector to neighbor atom.
Definition: Atom.h:46
std::vector< Vec3D > dGdr
Derivatives of symmetry functions with respect to neighbor coordinates.
Definition: Atom.h:60
Storage for a single atom.
Definition: Atom.h:33
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
Definition: Atom.h:170
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
std::vector< Vec3D > dGdr
Derivative of symmetry functions with respect to this atom's coordinates.
Definition: Atom.h:161
std::vector< double > G
Symmetry function values.
Definition: Atom.h:146
Vector in 3 dimensional real space.
Definition: Vec3D.h:30