n2p2 - A neural network potential package
SymGrpCompRad.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 "SymGrpCompRad.h"
19#include "Atom.h"
20#include "SymFnc.h"
21#include "SymFncCompRad.h"
22#include "Vec3D.h"
23#include "utility.h"
24#include <algorithm> // std::sort
25#include <cmath> // exp
26#include <stdexcept> // std::runtime_error
27
28using namespace std;
29using namespace nnp;
30
31SymGrpCompRad::
32SymGrpCompRad(ElementMap const& elementMap) :
33 SymGrpBaseComp(20, elementMap),
34 e1(0)
35{
36 parametersCommon.insert("e1");
37}
38
39bool SymGrpCompRad::operator==(SymGrp const& rhs) const
40{
41 if (ec != rhs.getEc() ) return false;
42 if (type != rhs.getType()) return false;
43 SymGrpCompRad const& c = dynamic_cast<SymGrpCompRad const&>(rhs);
44 if (e1 != c.e1) return false;
45 return true;
46}
47
48bool SymGrpCompRad::operator<(SymGrp const& rhs) const
49{
50 if (ec < rhs.getEc() ) return true;
51 else if (ec > rhs.getEc() ) return false;
52 if (type < rhs.getType()) return true;
53 else if (type > rhs.getType()) return false;
54 SymGrpCompRad const& c = dynamic_cast<SymGrpCompRad const&>(rhs);
55 if (e1 < c.e1) return true;
56 else if (e1 > c.e1) return false;
57 return false;
58}
59
60bool SymGrpCompRad::addMember(SymFnc const* const symmetryFunction)
61{
62 if (symmetryFunction->getType() != type) return false;
63
64 SymFncCompRad const* sf =
65 dynamic_cast<SymFncCompRad const*>(symmetryFunction);
66
67 if (members.empty())
68 {
69 ec = sf->getEc();
70 e1 = sf->getE1();
72 }
73
74 if (sf->getEc() != ec ) return false;
75 if (sf->getE1() != e1 ) return false;
76 if (sf->getConvLength() != convLength )
77 {
78 throw runtime_error("ERROR: Unable to add symmetry function members "
79 "with different conversion factors.\n");
80 }
81
82 if (sf->getRl() <= 0.0) rmin = 0.0;
83 else rmin = min( rmin, sf->getRl() );
84 rmax = max( rmax, sf->getRc() );
85
86 members.push_back(sf);
87
88 return true;
89}
90
92{
93 sort(members.begin(),
94 members.end(),
95 comparePointerTargets<SymFncCompRad const>);
96
97 for (size_t i = 0; i < members.size(); i++)
98 {
99 memberIndex.push_back(members[i]->getIndex());
100 memberIndexPerElement.push_back(members[i]->getIndexPerElement());
101 }
102
103 mrl.resize(members.size(), 0.0);
104 mrc.resize(members.size(), 0.0);
105 for (size_t i = 0; i < members.size(); i++)
106 {
107 mrl.at(i) = members[i]->getRl();
108 mrc.at(i) = members[i]->getRc();
109 }
110
111#ifndef N2P2_NO_SF_CACHE
112 mci.resize(members.size());
113 for (size_t k = 0; k < members.size(); ++k)
114 {
115 mci.at(k) = members.at(k)->getCacheIndices()[e1];
116 }
117#endif
118
119 return;
120}
121
123{
124 scalingFactors.resize(members.size(), 0.0);
125 for (size_t i = 0; i < members.size(); i++)
126 {
127 scalingFactors.at(i) = members[i]->getScalingFactor();
128 }
129
130 return;
131}
132
133// Depending on chosen symmetry functions this function may be very
134// time-critical when predicting new structures (e.g. in MD simulations). Thus,
135// lots of optimizations were used sacrificing some readablity. Vec3D
136// operations have been rewritten in simple C array style and the use of
137// temporary objects has been minimized. Some of the originally coded
138// expressions are kept in comments marked with "SIMPLE EXPRESSIONS:".
139void SymGrpCompRad::calculate(Atom& atom, bool const derivatives) const
140{
141 double* result = new double[members.size()];
142 for (size_t k = 0; k < members.size(); ++k)
143 {
144 result[k] = 0.0;
145 }
146
147 for (size_t j = 0; j < atom.numNeighbors; ++j)
148 {
149 Atom::Neighbor& n = atom.neighbors[j];
150 double const rij = n.d;
151 if (e1 == n.element && rij < rmax && rij > rmin)
152 {
153 // Energy calculation.
154 double const* const d1 = n.dr.r;
155 for (size_t k = 0; k < members.size(); ++k)
156 {
157 SymFncCompRad const& sf = *(members[k]);
158 if (rij <= mrl[k] || rij >= mrc[k]) continue;
159 double rad;
160 double drad;
161#ifndef N2P2_NO_SF_CACHE
162 if (mci[k].size() == 0) sf.getCompactOnly(rij, rad, drad);
163 else
164 {
165 double& crad = n.cache[mci[k][0]];
166 double& cdrad = n.cache[mci[k][1]];
167 if (crad < 0) sf.getCompactOnly(rij, crad, cdrad);
168 rad = crad;
169 drad = cdrad;
170 }
171#else
172 sf.getCompactOnly(rij, rad, drad);
173#endif
174 result[k] += rad;
175
176 // Force calculation.
177 if (!derivatives || drad == 0.0) continue;
178 drad *= scalingFactors[k] / rij;
179 // SIMPLE EXPRESSIONS:
180 //Vec3D const dij = p1 * atom.neighbors[j].dr;
181 double const p1drijx = drad * d1[0];
182 double const p1drijy = drad * d1[1];
183 double const p1drijz = drad * d1[2];
184
185 // Save force contributions in Atom storage.
186#ifndef N2P2_FULL_SFD_MEMORY
187 size_t ki = memberIndex[k];
188#else
189 size_t const ki = memberIndex[k];
190#endif
191 // SIMPLE EXPRESSIONS:
192 //atom.dGdr[ki] += dij;
193 //atom.neighbors[j].dGdr[ki] -= dij;
194
195 double* dGdr = atom.dGdr[ki].r;
196 dGdr[0] += p1drijx;
197 dGdr[1] += p1drijy;
198 dGdr[2] += p1drijz;
199
200#ifndef N2P2_FULL_SFD_MEMORY
201 ki = memberIndexPerElement[k][e1];
202#endif
203 dGdr = n.dGdr[ki].r;
204 dGdr[0] -= p1drijx;
205 dGdr[1] -= p1drijy;
206 dGdr[2] -= p1drijz;
207 }
208 }
209 }
210
211 for (size_t k = 0; k < members.size(); ++k)
212 {
213 atom.G[memberIndex[k]] = members[k]->scale(result[k]);
214 }
215
216 delete[] result;
217
218 return;
219}
220
221vector<string> SymGrpCompRad::parameterLines() const
222{
223 vector<string> v;
224
225 v.push_back(strpr(getPrintFormatCommon().c_str(),
226 index + 1,
227 elementMap[ec].c_str(),
228 type,
229 elementMap[e1].c_str(),
231 rmax / convLength));
232
233 for (size_t i = 0; i < members.size(); ++i)
234 {
235 v.push_back(strpr(getPrintFormatMember().c_str(),
236 members[i]->getSubtype().c_str(),
237 members[i]->getRl() / convLength,
238 members[i]->getRc() / convLength,
239 members[i]->getLineNumber() + 1,
240 i + 1,
241 members[i]->getIndex() + 1));
242 }
243
244 return v;
245}
Contains element map.
Definition: ElementMap.h:30
double getRl() const
Get private rl member variable.
Radial symmetry function with compact support (type 20)
Definition: SymFncCompRad.h:56
std::size_t getE1() const
Get private e1 member variable.
void getCompactOnly(double const x, double &fx, double &dfx) const
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 rmin
Minimum radius within group.
double rmax
Maximum radius within group.
Radial symmetry function with compact support (type 20)
Definition: SymGrpCompRad.h:48
virtual std::vector< std::string > parameterLines() const
Give symmetry function group parameters on multiple lines.
std::size_t e1
Element index of neighbor atom (common feature).
Definition: SymGrpCompRad.h:92
std::vector< double > mrc
Member rc.
Definition: SymGrpCompRad.h:98
virtual void setScalingFactors()
Fill scalingFactors with values from member symmetry functions.
virtual bool operator<(SymGrp const &rhs) const
Overload < operator.
std::vector< double > mrl
Member rl.
Definition: SymGrpCompRad.h:96
virtual bool operator==(SymGrp const &rhs) const
Overload == operator.
virtual void sortMembers()
Sort member symmetry functions.
std::vector< SymFncCompRad const * > members
Vector of all group member pointers.
Definition: SymGrpCompRad.h:94
std::vector< std::vector< std::size_t > > mci
Member cache indices for actual neighbor element.
virtual bool addMember(SymFnc const *const symmetryFunction)
Potentially add a member to group.
virtual void calculate(Atom &atom, bool const derivatives) const
Calculate all symmetry functions of this group for one atom.
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
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::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
double r[3]
cartesian coordinates.
Definition: Vec3D.h:32