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