n2p2 - A neural network potential package
SymFncCompRad.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// Copyright (C) 2020 Martin P. Bircher
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18#include "SymFncCompRad.h"
19#include "Atom.h"
20#include "ElementMap.h"
21#include "utility.h"
22#include "Vec3D.h"
23#include <cstdlib> // atof, atoi
24#include <cmath> // exp
25#include <limits> // std::numeric_limits
26#include <stdexcept> // std::runtime_error
27
28using namespace std;
29using namespace nnp;
30
31SymFncCompRad::SymFncCompRad(ElementMap const& elementMap) :
32 SymFncBaseComp(20, elementMap),
33 e1(0)
34{
35 minNeighbors = 1;
36 parameters.insert("e1");
37}
38
39bool SymFncCompRad::operator==(SymFnc const& rhs) const
40{
41 if (ec != rhs.getEc() ) return false;
42 if (type != rhs.getType()) return false;
43 SymFncCompRad const& c = dynamic_cast<SymFncCompRad const&>(rhs);
44 if (subtype != c.getSubtype()) return false;
45 if (e1 != c.e1 ) return false;
46 if (rc != c.rc ) return false;
47 if (rl != c.rl ) return false;
48 return true;
49}
50
51bool SymFncCompRad::operator<(SymFnc const& rhs) const
52{
53 if (ec < rhs.getEc() ) return true;
54 else if (ec > rhs.getEc() ) return false;
55 if (type < rhs.getType()) return true;
56 else if (type > rhs.getType()) return false;
57 SymFncCompRad const& c = dynamic_cast<SymFncCompRad const&>(rhs);
58 if (subtype < c.getSubtype()) return true;
59 else if (subtype > c.getSubtype()) return false;
60 if (e1 < c.e1 ) return true;
61 else if (e1 > c.e1 ) return false;
62 if (rc < c.rc ) return true;
63 else if (rc > c.rc ) return false;
64 if (rl < c.rl ) return true;
65 else if (rl > c.rl ) return false;
66 return false;
67}
68
69void SymFncCompRad::setParameters(string const& parameterString)
70{
71 vector<string> splitLine = split(reduce(parameterString));
72
73 if (type != (size_t)atoi(splitLine.at(1).c_str()))
74 {
75 throw runtime_error("ERROR: Incorrect symmetry function type.\n");
76 }
77
78 ec = elementMap[splitLine.at(0)];
79 e1 = elementMap[splitLine.at(2)];
80 rl = atof(splitLine.at(3).c_str());
81 rc = atof(splitLine.at(4).c_str());
82 subtype = splitLine.at(5);
83
84 if (rl > rc)
85 {
86 throw runtime_error("ERROR: Lower radial boundary >= upper "
87 "radial boundary.\n");
88 }
89 //if (rl < 0.0 && abs(rl + rc) > numeric_limits<double>::epsilon())
90 //{
91 // throw runtime_error("ERROR: Radial function not symmetric "
92 // "w.r.t. origin.\n");
93 //}
94
97
98 return;
99}
100
101void SymFncCompRad::changeLengthUnit(double convLength)
102{
103 this->convLength = convLength;
104 rl *= convLength;
105 rc *= convLength;
106
108
109 return;
110}
111
113{
114 string s = strpr("symfunction_short %2s %2zu %2s %16.8E %16.8E %s\n",
115 elementMap[ec].c_str(),
116 type,
117 elementMap[e1].c_str(),
118 rl / convLength,
119 rc / convLength,
120 subtype.c_str());
121
122 return s;
123}
124
125void SymFncCompRad::calculate(Atom& atom, bool const derivatives) const
126{
127 double result = 0.0;
128#ifndef N2P2_NO_SF_CACHE
129 bool unique = true;
130 size_t c0 = 0;
131 size_t c1 = 0;
132 if (cacheIndices.at(e1).size() > 0)
133 {
134 unique = false;
135 c0 = cacheIndices.at(e1).at(0);
136 c1 = cacheIndices.at(e1).at(1);
137 }
138#endif
139
140 for (size_t j = 0; j < atom.numNeighbors; ++j)
141 {
142 Atom::Neighbor& n = atom.neighbors[j];
143 if (e1 == n.element && n.d > rl && n.d < rc)
144 {
145 // Energy calculation.
146 double const rij = n.d;
147
148 double rad;
149 double drad;
150 double r = rij;
151#ifndef N2P2_NO_SF_CACHE
152 if (unique) cr.fdf(r, rad, drad);
153 else
154 {
155 double& crad = n.cache[c0];
156 double& cdrad = n.cache[c1];
157 if (crad < 0) cr.fdf(r, crad, cdrad);
158 rad = crad;
159 drad = cdrad;
160 }
161#else
162 cr.fdf(r, rad, drad);
163#endif
164 result += rad;
165
166 // Force calculation.
167 if (!derivatives) continue;
168 double const p1 = scalingFactor * drad / rij;
169 Vec3D dij = p1 * n.dr;
170 // Save force contributions in Atom storage.
171 atom.dGdr[index] += dij;
172#ifndef N2P2_FULL_SFD_MEMORY
173 n.dGdr[indexPerElement[e1]] -= dij;
174#else
175 n.dGdr[index] -= dij;
176#endif
177 }
178 }
179
180 atom.G[index] = scale(result);
181
182 return;
183}
184
186{
187 return strpr(getPrintFormat().c_str(),
188 index + 1,
189 elementMap[ec].c_str(),
190 type,
191 subtype.c_str(),
192 elementMap[e1].c_str(),
193 rl / convLength,
194 rc / convLength,
195 lineNumber + 1);
196}
197
198vector<string> SymFncCompRad::parameterInfo() const
199{
200 vector<string> v = SymFncBaseComp::parameterInfo();
201 string s;
202 size_t w = sfinfoWidth;
203
204 s = "e1";
205 v.push_back(strpr((pad(s, w) + "%s").c_str(), elementMap[e1].c_str()));
206
207 return v;
208}
209
210double SymFncCompRad::calculateRadialPart(double distance) const
211{
212 double const& r = distance * convLength;
213
214 return cr.f(r);
215}
216
217double SymFncCompRad::calculateAngularPart(double /* angle */) const
218{
219 return 1.0;
220}
221
223{
224 if (index == e1) return true;
225 else return false;
226}
227
228#ifndef N2P2_NO_SF_CACHE
230{
231 vector<string> v;
232 string s("");
233
234 s += subtype;
235 s += " ";
236 s += strpr("rl = %16.8E", rl / convLength);
237 s += " ";
238 s += strpr("rc = %16.8E", rc / convLength);
239
240 v.push_back(strpr("%zu f ", e1) + s);
241 v.push_back(strpr("%zu df ", e1) + s);
242
243 return v;
244}
245#endif
void fdf(double a, double &fa, double &dfa) const
Calculate compact function and derivative at once.
double f(double a) const
Compact function .
void setLeftRight(double left, double right)
Set left and right boundary.
Contains element map.
Definition: ElementMap.h:30
Symmetry function base class for SFs with compact support.
std::string getSubtype() const
Get private subtype member variable.
double rl
Lower bound of compact function, .
virtual std::vector< std::string > parameterInfo() const
Get description with parameter names and values.
CompactFunction cr
Compact function for radial part.
std::string subtype
Subtype string (specifies e.g. polynom type).
void setCompactFunction(std::string subtype)
Set radial compact function.
Radial symmetry function with compact support (type 20)
Definition: SymFncCompRad.h:56
virtual double calculateAngularPart(double angle) const
Calculate (partial) symmetry function value for one given angle.
std::size_t e1
Element index of neighbor atom.
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate symmetry function for one atom.
virtual std::vector< std::string > parameterInfo() const
Get description with parameter names and values.
virtual std::string parameterLine() const
Give symmetry function parameters in one line.
virtual void changeLengthUnit(double convLength)
Change length unit.
virtual bool operator<(SymFnc const &rhs) const
Overload < operator.
virtual double calculateRadialPart(double distance) const
Calculate (partial) symmetry function value for one given distance.
virtual void setParameters(std::string const &parameterString)
Set symmetry function parameters.
virtual std::vector< std::string > getCacheIdentifiers() const
Get unique cache identifiers.
virtual bool checkRelevantElement(std::size_t index) const
Check whether symmetry function is relevant for given element.
virtual bool operator==(SymFnc const &rhs) const
Overload == operator.
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::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
std::size_t numNeighbors
Total number of neighbors.
Definition: Atom.h:109
Vector in 3 dimensional real space.
Definition: Vec3D.h:30