n2p2 - A neural network potential package
SymFncCompRadWeighted.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
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
31SymFncCompRadWeighted::SymFncCompRadWeighted(ElementMap const& elementMap) :
32 SymFncBaseComp(23, elementMap)
33{
34 minNeighbors = 1;
35}
36
38{
39 if (ec != rhs.getEc() ) return false;
40 if (type != rhs.getType()) return false;
42 = dynamic_cast<SymFncCompRadWeighted const&>(rhs);
43 if (subtype != c.getSubtype()) return false;
44 if (rc != c.rc ) return false;
45 if (rl != c.rl ) return false;
46 return true;
47}
48
50{
51 if (ec < rhs.getEc() ) return true;
52 else if (ec > rhs.getEc() ) return false;
53 if (type < rhs.getType()) return true;
54 else if (type > rhs.getType()) return false;
56 = dynamic_cast<SymFncCompRadWeighted const&>(rhs);
57 if (subtype < c.getSubtype()) return true;
58 else if (subtype > c.getSubtype()) return false;
59 if (rc < c.rc ) return true;
60 else if (rc > c.rc ) return false;
61 if (rl < c.rl ) return true;
62 else if (rl > c.rl ) return false;
63 return false;
64}
65
66void SymFncCompRadWeighted::setParameters(string const& parameterString)
67{
68 vector<string> splitLine = split(reduce(parameterString));
69
70 if (type != (size_t)atoi(splitLine.at(1).c_str()))
71 {
72 throw runtime_error("ERROR: Incorrect symmetry function type.\n");
73 }
74
75 ec = elementMap[splitLine.at(0)];
76 rl = atof(splitLine.at(2).c_str());
77 rc = atof(splitLine.at(3).c_str());
78 subtype = splitLine.at(4);
79
80 if (rl > rc)
81 {
82 throw runtime_error("ERROR: Lower radial boundary >= upper "
83 "radial boundary.\n");
84 }
85 //if (rl < 0.0 && abs(rl + rc) > numeric_limits<double>::epsilon())
86 //{
87 // throw runtime_error("ERROR: Radial function not symmetric "
88 // "w.r.t. origin.\n");
89 //}
90
93
94 return;
95}
96
98{
99 this->convLength = convLength;
100 rl *= convLength;
101 rc *= convLength;
102
104
105 return;
106}
107
109{
110 string s = strpr("symfunction_short %2s %2zu %16.8E %16.8E %s\n",
111 elementMap[ec].c_str(),
112 type,
113 rl / convLength,
114 rc / convLength,
115 subtype.c_str());
116
117 return s;
118}
119
120void SymFncCompRadWeighted::calculate(Atom& atom, bool const derivatives) const
121{
122 double result = 0.0;
123
124 for (size_t j = 0; j < atom.numNeighbors; ++j)
125 {
126 Atom::Neighbor& n = atom.neighbors[j];
127 if (n.d > rl && n.d < rc)
128 {
129 // Energy calculation.
130 size_t const ne = n.element;
131 double const rij = n.d;
132
133 double rad;
134 double drad;
135 double r = rij;
136#ifndef N2P2_NO_SF_CACHE
137 if (cacheIndices[ne].size() == 0) cr.fdf(r, rad, drad);
138 else
139 {
140 double& crad = n.cache[cacheIndices[ne][0]];
141 double& cdrad = n.cache[cacheIndices[ne][1]];
142 if (crad < 0) cr.fdf(r, crad, cdrad);
143 rad = crad;
144 drad = cdrad;
145 }
146#else
147 cr.fdf(r, rad, drad);
148#endif
149 result += rad * elementMap.atomicNumber(ne);
150
151 // Force calculation.
152 if (!derivatives) continue;
153 double const p1 = scalingFactor * elementMap.atomicNumber(ne)
154 * drad / rij;
155 Vec3D dij = p1 * n.dr;
156 // Save force contributions in Atom storage.
157 atom.dGdr[index] += dij;
158#ifndef N2P2_FULL_SFD_MEMORY
159 n.dGdr[indexPerElement[ne]] -= dij;
160#else
161 n.dGdr[index] -= dij;
162#endif
163 }
164 }
165
166 atom.G[index] = scale(result);
167
168 return;
169}
170
172{
173 return strpr(getPrintFormat().c_str(),
174 index + 1,
175 elementMap[ec].c_str(),
176 type,
177 subtype.c_str(),
178 rl / convLength,
179 rc / convLength,
180 lineNumber + 1);
181}
182
184{
185 vector<string> v = SymFncBaseComp::parameterInfo();
186
187 return v;
188}
189
191{
192 double const& r = distance * convLength;
193
194 return cr.f(r);
195}
196
197double SymFncCompRadWeighted::calculateAngularPart(double /* angle */) const
198{
199 return 1.0;
200}
201
203{
204 return true;
205}
206
207#ifndef N2P2_NO_SF_CACHE
209{
210 vector<string> v;
211 string s("");
212
213 s += subtype;
214 s += " ";
215 s += strpr("rl = %16.8E", rl / convLength);
216 s += " ";
217 s += strpr("rc = %16.8E", rc / convLength);
218
219 for (size_t i = 0; i < elementMap.size(); ++i)
220 {
221 v.push_back(strpr("%zu f ", i) + s);
222 v.push_back(strpr("%zu df ", i) + s);
223 }
224
225 return v;
226}
227#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
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
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.
Weighted radial symmetry function with compact support (type 23)
virtual std::string getSettingsLine() const
Get settings file line from currently set parameters.
virtual std::vector< std::string > parameterInfo() const
Get description with parameter names and values.
virtual std::vector< std::string > getCacheIdentifiers() const
Get unique cache identifiers.
virtual void setParameters(std::string const &parameterString)
Set symmetry function parameters.
virtual void changeLengthUnit(double convLength)
Change length unit.
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 parameterLine() const
Give symmetry function parameters in one line.
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 double calculateAngularPart(double angle) const
Calculate (partial) symmetry function value for one given angle.
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate symmetry function for one atom.
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::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
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:28
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:35
std::vector< double > cache
Symmetry function cache (e.g. for cutoffs, compact functions).
Definition: Atom.h:48
std::size_t element
Element index of neighbor atom.
Definition: Atom.h:41
double d
Distance to neighbor atom.
Definition: Atom.h:43
Vec3D dr
Distance vector to neighbor atom.
Definition: Atom.h:45
std::vector< Vec3D > dGdr
Derivatives of symmetry functions with respect to neighbor coordinates.
Definition: Atom.h:59
Storage for a single atom.
Definition: Atom.h:32
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
Definition: Atom.h:148
std::vector< Vec3D > dGdr
Derivative of symmetry functions with respect to this atom's coordinates.
Definition: Atom.h:146
std::vector< double > G
Symmetry function values.
Definition: Atom.h:134
std::size_t numNeighbors
Total number of neighbors.
Definition: Atom.h:106
Vector in 3 dimensional real space.
Definition: Vec3D.h:29