n2p2 - A neural network potential package
SymGrpExpRad.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 "SymGrpExpRad.h"
18#include "Atom.h"
19#include "SymFnc.h"
20#include "SymFncExpRad.h"
21#include "Vec3D.h"
22#include "utility.h"
23#include <algorithm> // std::sort
24#include <cmath> // exp
25#include <stdexcept> // std::runtime_error
26
27using namespace std;
28using namespace nnp;
29
30SymGrpExpRad::SymGrpExpRad(ElementMap const& elementMap) :
31 SymGrpBaseCutoff(2, elementMap),
32 e1(0)
33{
34 parametersCommon.insert("e1");
35
36 parametersMember.insert("eta");
37 parametersMember.insert("rs/rl");
38 parametersMember.insert("mindex");
39 parametersMember.insert("sfindex");
40}
41
42bool SymGrpExpRad::operator==(SymGrp const& rhs) const
43{
44 if (ec != rhs.getEc() ) return false;
45 if (type != rhs.getType()) return false;
46 SymGrpExpRad const& c = dynamic_cast<SymGrpExpRad const&>(rhs);
47 if (cutoffType != c.cutoffType ) return false;
48 if (cutoffAlpha != c.cutoffAlpha) return false;
49 if (rc != c.rc ) return false;
50 if (e1 != c.e1 ) return false;
51 return true;
52}
53
54bool SymGrpExpRad::operator<(SymGrp const& rhs) const
55{
56 if (ec < rhs.getEc() ) return true;
57 else if (ec > rhs.getEc() ) return false;
58 if (type < rhs.getType()) return true;
59 else if (type > rhs.getType()) return false;
60 SymGrpExpRad const& c = dynamic_cast<SymGrpExpRad const&>(rhs);
61 if (cutoffType < c.cutoffType ) return true;
62 else if (cutoffType > c.cutoffType ) return false;
63 if (cutoffAlpha < c.cutoffAlpha) return true;
64 else if (cutoffAlpha > c.cutoffAlpha) return false;
65 if (rc < c.rc ) return true;
66 else if (rc > c.rc ) return false;
67 if (e1 < c.e1 ) return true;
68 else if (e1 > c.e1 ) return false;
69 return false;
70}
71
72bool SymGrpExpRad::addMember(SymFnc const* const symmetryFunction)
73{
74 if (symmetryFunction->getType() != type) return false;
75
76 SymFncExpRad const* sf =
77 dynamic_cast<SymFncExpRad const*>(symmetryFunction);
78
79 if (members.empty())
80 {
82 subtype = sf->getSubtype();
84 ec = sf->getEc();
85 rc = sf->getRc();
86 e1 = sf->getE1();
88
92 }
93
94 if (sf->getCutoffType() != cutoffType ) return false;
95 if (sf->getCutoffAlpha() != cutoffAlpha) return false;
96 if (sf->getEc() != ec ) return false;
97 if (sf->getRc() != rc ) return false;
98 if (sf->getE1() != e1 ) return false;
99 if (sf->getConvLength() != convLength )
100 {
101 throw runtime_error("ERROR: Unable to add symmetry function members "
102 "with different conversion factors.\n");
103 }
104
105 members.push_back(sf);
106
107 return true;
108}
109
111{
112 sort(members.begin(),
113 members.end(),
114 comparePointerTargets<SymFncExpRad const>);
115
116 for (size_t i = 0; i < members.size(); i++)
117 {
118 memberIndex.push_back(members[i]->getIndex());
119 eta.push_back(members[i]->getEta());
120 rs.push_back(members[i]->getRs());
121 memberIndexPerElement.push_back(members[i]->getIndexPerElement());
122 }
123
124 return;
125}
126
128{
129 scalingFactors.resize(members.size(), 0.0);
130 for (size_t i = 0; i < members.size(); i++)
131 {
132 scalingFactors.at(i) = members[i]->getScalingFactor();
133 }
134
135 return;
136}
137
138// Depending on chosen symmetry functions this function may be very
139// time-critical when predicting new structures (e.g. in MD simulations). Thus,
140// lots of optimizations were used sacrificing some readablity. Vec3D
141// operations have been rewritten in simple C array style and the use of
142// temporary objects has been minmized. Some of the originally coded
143// expressions are kept in comments marked with "SIMPLE EXPRESSIONS:".
144void SymGrpExpRad::calculate(Atom& atom, bool const derivatives) const
145{
146#ifndef N2P2_NO_SF_CACHE
147 // Can use cache indices of any member because this group is defined via
148 // identical symmetry function type, neighbors and cutoff functions.
149 auto cacheIndices = members.at(0)->getCacheIndices();
150 bool unique = true;
151 size_t c0 = 0;
152 size_t c1 = 0;
153 if (cacheIndices.at(e1).size() > 0)
154 {
155 unique = false;
156 c0 = cacheIndices.at(e1).at(0);
157 c1 = cacheIndices.at(e1).at(1);
158 }
159#endif
160 double* result = new double[members.size()];
161 for (size_t k = 0; k < members.size(); ++k)
162 {
163 result[k] = 0.0;
164 }
165
166 for (size_t j = 0; j < atom.getStoredMinNumNeighbors(rc); ++j)
167 {
168 Atom::Neighbor& n = atom.neighbors[j];
169 if (e1 == n.element && n.d < rc)
170 {
171 // Energy calculation.
172 double const rij = n.d;
173
174 // Calculate cutoff function and derivative.
175 double pfc;
176 double pdfc;
177#ifndef N2P2_NO_SF_CACHE
178 if (unique) fc.fdf(rij, pfc, pdfc);
179 else
180 {
181 double& cfc = n.cache[c0];
182 double& cdfc = n.cache[c1];
183 if (cfc < 0) fc.fdf(rij, cfc, cdfc);
184 pfc = cfc;
185 pdfc = cdfc;
186 }
187#else
188 fc.fdf(rij, pfc, pdfc);
189#endif
190 double const* const d1 = n.dr.r;
191 for (size_t k = 0; k < members.size(); ++k)
192 {
193 double pexp = exp(-eta[k] * (rij - rs[k]) * (rij - rs[k]));
194 result[k] += pexp * pfc;
195 // Force calculation.
196 if (!derivatives) continue;
197 double const p1 = scalingFactors[k] * (pdfc - 2.0 * eta[k]
198 * (rij - rs[k]) * pfc) * pexp / rij;
199 // SIMPLE EXPRESSIONS:
200 //Vec3D const dij = p1 * atom.neighbors[j].dr;
201 double const p1drijx = p1 * d1[0];
202 double const p1drijy = p1 * d1[1];
203 double const p1drijz = p1 * d1[2];
204
205 // Save force contributions in Atom storage.
206#ifndef N2P2_FULL_SFD_MEMORY
207 size_t ki = memberIndex[k];
208#else
209 size_t const ki = memberIndex[k];
210#endif
211 // SIMPLE EXPRESSIONS:
212 //atom.dGdr[ki] += dij;
213 //atom.neighbors[j].dGdr[ki] -= dij;
214
215 double* dGdr = atom.dGdr[ki].r;
216 dGdr[0] += p1drijx;
217 dGdr[1] += p1drijy;
218 dGdr[2] += p1drijz;
219
220#ifndef N2P2_FULL_SFD_MEMORY
221 ki = memberIndexPerElement[k][e1];
222#endif
223 dGdr = n.dGdr[ki].r;
224 dGdr[0] -= p1drijx;
225 dGdr[1] -= p1drijy;
226 dGdr[2] -= p1drijz;
227 }
228 }
229 }
230
231 for (size_t k = 0; k < members.size(); ++k)
232 {
233 atom.G[memberIndex[k]] = members[k]->scale(result[k]);
234 }
235
236 delete[] result;
237
238 return;
239}
240
241vector<string> SymGrpExpRad::parameterLines() const
242{
243 vector<string> v;
244
245 v.push_back(strpr(getPrintFormatCommon().c_str(),
246 index + 1,
247 elementMap[ec].c_str(),
248 type,
249 subtype.c_str(),
250 elementMap[e1].c_str(),
251 rc / convLength,
252 cutoffAlpha));
253
254 for (size_t i = 0; i < members.size(); ++i)
255 {
256 v.push_back(strpr(getPrintFormatMember().c_str(),
257 members[i]->getEta() * convLength * convLength,
258 members[i]->getRs() / convLength,
259 members[i]->getLineNumber() + 1,
260 i + 1,
261 members[i]->getIndex() + 1));
262 }
263
264 return v;
265}
266
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 setCutoffType(CutoffType const cutoffType)
Set cutoff type.
void setCutoffRadius(double const cutoffRadius)
Set cutoff radius.
Contains element map.
Definition: ElementMap.h:30
std::string getSubtype() const
Get private subtype member variable.
double getCutoffAlpha() const
Get private cutoffAlpha member variable.
CutoffFunction::CutoffType getCutoffType() const
Get private cutoffType member variable.
Radial symmetry function (type 2)
Definition: SymFncExpRad.h:49
std::size_t getE1() const
Get private e1 member variable.
Definition: SymFncExpRad.h:145
Symmetry function base class.
Definition: SymFnc.h:40
double getConvLength() const
Get private convLength member variable.
Definition: SymFnc.h:364
double getRc() const
Get private rc member variable.
Definition: SymFnc.h:360
std::size_t getType() const
Get private type member variable.
Definition: SymFnc.h:355
std::size_t getEc() const
Get private ec member variable.
Definition: SymFnc.h:356
double cutoffAlpha
Cutoff function parameter (common feature).
std::string subtype
Subtype string (specifies cutoff type) (common feature).
CutoffFunction fc
Cutoff function used by this symmetry function group.
double rc
Cutoff radius (common feature).
CutoffFunction::CutoffType cutoffType
Cutoff type used by this symmetry function group (common feature).
Radial symmetry function group (type 2)
Definition: SymGrpExpRad.h:47
std::vector< double > rs
Vector containing values of all member symmetry functions.
Definition: SymGrpExpRad.h:97
virtual std::vector< std::string > parameterLines() const
Give symmetry function group parameters on multiple lines.
virtual bool operator==(SymGrp const &rhs) const
Overload == operator.
virtual bool addMember(SymFnc const *const symmetryFunction)
Potentially add a member to group.
virtual void setScalingFactors()
Fill scalingFactors with values from member symmetry functions.
virtual bool operator<(SymGrp const &rhs) const
Overload < operator.
std::vector< SymFncExpRad const * > members
Vector of all group member pointers.
Definition: SymGrpExpRad.h:93
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate all symmetry functions of this group for one atom.
virtual void sortMembers()
Sort member symmetry functions.
std::size_t e1
Element index of neighbor atom (common feature).
Definition: SymGrpExpRad.h:91
std::vector< double > eta
Vector containing values of all member symmetry functions.
Definition: SymGrpExpRad.h:95
std::size_t type
Symmetry function type.
Definition: SymGrp.h:106
std::size_t getType() const
Get private type member variable.
Definition: SymGrp.h:185
std::size_t index
Symmetry function group index.
Definition: SymGrp.h:110
std::vector< size_t > memberIndex
Vector containing indices of all member symmetry functions.
Definition: SymGrp.h:116
std::string getPrintFormatCommon() const
Get common parameter line format string.
Definition: SymGrp.cpp:97
std::size_t ec
Element index of center atom (common feature).
Definition: SymGrp.h:112
std::vector< std::vector< std::size_t > > memberIndexPerElement
Vector containing per-element indices of all member symmetry functions.
Definition: SymGrp.h:124
std::size_t getEc() const
Get private ec member variable.
Definition: SymGrp.h:186
double convLength
Data set normalization length conversion factor.
Definition: SymGrp.h:114
std::set< std::string > parametersCommon
Set of common parameters IDs.
Definition: SymGrp.h:120
ElementMap elementMap
Copy of element map.
Definition: SymGrp.h:108
std::size_t getIndex() const
Get private index member variable.
Definition: SymGrp.h:184
std::string getPrintFormatMember() const
Get member parameter line format string.
Definition: SymGrp.cpp:130
std::vector< double > scalingFactors
Scaling factors of all member symmetry functions.
Definition: SymGrp.h:118
std::set< std::string > parametersMember
Set of common parameters IDs.
Definition: SymGrp.h:122
Definition: Atom.h:29
string strpr(const char *format,...)
String version of printf function.
Definition: utility.cpp:90
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
double r[3]
cartesian coordinates.
Definition: Vec3D.h:32