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