n2p2 - A neural network potential package
CutoffFunction.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 "CutoffFunction.h"
18#include <stdexcept>
19#include <cmath> // cos, sin, tanh, exp, pow
20#include <limits> // std::numeric_limits
21
22using namespace std;
23using namespace nnp;
24
25double const CutoffFunction::PI = 4.0 * atan(1.0);
26double const CutoffFunction::PI_2 = 2.0 * atan(1.0);
27double const CutoffFunction::E = exp(1.0);
28double const CutoffFunction::TANH_PRE = pow((E + 1 / E) / (E - 1 / E), 3);
29
30CutoffFunction::CutoffFunction() : cutoffType(CT_HARD ),
31 rc (0.0 ),
32 rcinv (0.0 ),
33 rci (0.0 ),
34 alpha (0.0 ),
35 iw (0.0 ),
36 fPtr (&CutoffFunction:: fHARD),
37 dfPtr (&CutoffFunction:: dfHARD),
38 fdfPtr (&CutoffFunction::fdfHARD)
39{
40}
41
43{
44 this->cutoffType = cutoffType;
45
46 if (cutoffType == CT_HARD)
47 {
51 }
52 else if (cutoffType == CT_COS)
53 {
57 }
58 else if (cutoffType == CT_TANHU)
59 {
63 }
64 else if (cutoffType == CT_TANH)
65 {
69 }
70 else if (cutoffType == CT_POLY1 ||
75 {
76 using CFT = CoreFunction::Type;
77 if (cutoffType == CT_POLY1) core.setType(CFT::POLY1);
78 else if (cutoffType == CT_POLY2) core.setType(CFT::POLY2);
79 else if (cutoffType == CT_POLY3) core.setType(CFT::POLY3);
80 else if (cutoffType == CT_POLY4) core.setType(CFT::POLY4);
81 else if (cutoffType == CT_EXP) core.setType(CFT::EXP);
82
86 }
87 else
88 {
89 throw invalid_argument("ERROR: Unknown cutoff type.\n");
90 }
91
92 return;
93}
94
95void CutoffFunction::setCutoffRadius(double const cutoffRadius)
96{
97 rc = cutoffRadius;
98 rcinv = 1.0 / cutoffRadius;
99 return;
100}
101
103{
104 if (alpha < 0.0 || alpha >= 1.0)
105 {
106 throw invalid_argument("ERROR: 0 <= alpha < 1.0 is required.\n");
107 }
108 this->alpha = alpha;
109 rci = rc * alpha;
110 iw = 1.0 / (rc - rci);
111 return;
112}
113
114double CutoffFunction::fCOS(double r) const
115{
116 if (r < rci) return 1.0;
117 double const x = (r - rci) * iw;
118 return 0.5 * (cos(PI * x) + 1.0);
119}
120
121double CutoffFunction::dfCOS(double r) const
122{
123 if (r < rci) return 0.0;
124 double const x = (r - rci) * iw;
125 return -PI_2 * iw * sin(PI * x);
126}
127
128void CutoffFunction::fdfCOS(double r, double& fc, double& dfc) const
129{
130 if (r < rci)
131 {
132 fc = 1.0;
133 dfc = 0.0;
134 return;
135 }
136 double const x = (r - rci) * iw;
137 double const temp = cos(PI * x);
138 fc = 0.5 * (temp + 1.0);
139 dfc = -0.5 * iw * PI * sqrt(1.0 - temp * temp);
140 return;
141}
142
143double CutoffFunction::fTANHU(double r) const
144{
145 double const temp = tanh(1.0 - r * rcinv);
146 return temp * temp * temp;
147}
148
149double CutoffFunction::dfTANHU(double r) const
150{
151 double temp = tanh(1.0 - r * rcinv);
152 temp *= temp;
153 return 3.0 * temp * (temp - 1.0) * rcinv;
154}
155
156void CutoffFunction::fdfTANHU(double r, double& fc, double& dfc) const
157{
158 double const temp = tanh(1.0 - r * rcinv);
159 double const temp2 = temp * temp;
160 fc = temp * temp2;
161 dfc = 3.0 * temp2 * (temp2 - 1.0) * rcinv;
162 return;
163}
164
165double CutoffFunction::fTANH(double r) const
166{
167 double const temp = tanh(1.0 - r * rcinv);
168 return TANH_PRE * temp * temp * temp;
169}
170
171double CutoffFunction::dfTANH(double r) const
172{
173 double temp = tanh(1.0 - r * rcinv);
174 temp *= temp;
175 return 3.0 * TANH_PRE * temp * (temp - 1.0) * rcinv;
176}
177
178void CutoffFunction::fdfTANH(double r, double& fc, double& dfc) const
179{
180 double const temp = tanh(1.0 - r * rcinv);
181 double const temp2 = temp * temp;
182 fc = TANH_PRE * temp * temp2;
183 dfc = 3.0 * TANH_PRE * temp2 * (temp2 - 1.0) * rcinv;
184 return;
185}
186
187double CutoffFunction::fCORE(double r) const
188{
189 if (r < rci) return 1.0;
190 double const x = (r - rci) * iw;
191 return core.f(x);
192}
193
194double CutoffFunction::dfCORE(double r) const
195{
196 if (r < rci) return 0.0;
197 double const x = (r - rci) * iw;
198 return iw * core.df(x);
199}
200
201void CutoffFunction::fdfCORE(double r, double& fc, double& dfc) const
202{
203 if (r < rci)
204 {
205 fc = 1.0;
206 dfc = 0.0;
207 return;
208 }
209 double const x = (r - rci) * iw;
210 core.fdf(x, fc, dfc);
211 dfc *= iw;
212 return;
213}
void fdf(double x, double &fx, double &dfx) const
Calculate function and derivative at once.
Definition: CoreFunction.h:174
double df(double x) const
Calculate derivative of function at argument .
Definition: CoreFunction.h:164
void setType(Type const type)
Set function type.
double f(double x) const
Calculate function value .
Definition: CoreFunction.h:156
Type
List of available function types.
Definition: CoreFunction.h:31
double fHARD(double r) const
CutoffType
List of available cutoff function types.
double rci
Inner cutoff for cutoff function types which allow shifting.
static double const TANH_PRE
double fCORE(double r) const
void fdfCOS(double r, double &fc, double &dfc) const
void fdfHARD(double r, double &fc, double &dfc) const
void fdfTANH(double r, double &fc, double &dfc) const
double rcinv
Inverse cutoff radius .
double fTANHU(double r) const
void fdfTANHU(double r, double &fc, double &dfc) const
double iw
Inverse width of cutoff function .
static double const PI
void fdfCORE(double r, double &fc, double &dfc) const
static double const PI_2
double fTANH(double r) const
void setCutoffParameter(double const alpha)
Set parameter for polynomial cutoff function (CT_POLY).
double(CutoffFunction::* fPtr)(double r) const
Function pointer to f.
double dfCOS(double r) const
double fCOS(double r) const
double dfTANH(double r) const
double dfCORE(double r) const
double(CutoffFunction::* dfPtr)(double r) const
Function pointer to df.
double dfTANHU(double r) const
void setCutoffType(CutoffType const cutoffType)
Set cutoff type.
double rc
Outer cutoff radius .
CutoffType cutoffType
Cutoff function type.
double alpha
Cutoff function parameter for CT_POLYn and CT_EXP .
double dfHARD(double r) const
CoreFunction core
Core functions used by POLYN, if any.
void setCutoffRadius(double const cutoffRadius)
Set cutoff radius.
void(CutoffFunction::* fdfPtr)(double r, double &fc, double &dfc) const
Function pointer to fdf.
Definition: Atom.h:28
CutoffFunction fc
Definition: nnp-cutoff.cpp:27