atomicrex  0.1
An advanced atomistic model building tool
ABOPotential.h
1 //
3 // Copyright (C) 2017, Alexander Stukowski and Paul Erhart
4 //
5 // This file is part of atomicrex.
6 //
7 // Atomicrex is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // Atomicrex is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //
21 
22 #pragma once
23 
24 #include "Potential.h"
25 #include <cmath>
26 #include "../dof/DegreeOfFreedom.h"
27 
28 namespace atomicrex {
29 
89 class ABOPotential : public Potential
90 {
91 public:
92 
94  ABOPotential(const FPString& id, FitJob* job, const FPString& tag = FPString("Tersoff"));
95 
97  virtual double cutoff() const override { return _cutoff; }
98 
100  virtual double computeEnergyAndForces(AtomicStructure& structure, NeighborList& neighborList) override;
101 
103  virtual double computeEnergy(AtomicStructure& structure, NeighborList& neighborList) override;
104 
106  virtual void outputResults() override;
107 
109  void writePotential(const FPString& filename) const;
110 
111 public:
112 
114  virtual void parse(XML::Element potentialElement) override;
115 
116 protected:
117 
118  struct ABOParamSet
119  {
120  ScalarDOF r0, D0, beta, S;
121  ScalarDOF gamma, c, d, h, twomu;
124  double powerm;
127 
128  double c1,c2,c3,c4;
129  int powermint;
130 
131  ABOParamSet() :
132  r0("r0", 0.0, 0.0),
133  D0("D0", 0.0, 0.0),
134  beta("beta"),
135  S("S", 0.0, 0.0),
136  gamma("gamma", 0.0, 0.0),
137  c("c"),
138  d("d", 0.0, 0.0),
139  h("h", 0.0, 0.0),
140  twomu("twomu", 0.0, 0.0),
141  beta2("beta2", 0.0, 0.0),
142  powern("powern", 0.0, 0.0),
143  bigr("bigr", 0.0, 0.0),
144  bigd("bigd", 0.0, 0.0)
145  {}
146 
147  double ters_fc(double r) const {
148  if(r < bigr-bigd) return 1.0;
149  if(r > bigr+bigd) return 0.0;
150  return 0.5*(1.0 - sin(M_PI/2*(r - bigr)/bigd));
151  }
152  double ters_fc_d(double r) const {
153  if(r < bigr-bigd) return 0.0;
154  if(r > bigr+bigd) return 0.0;
155  return -(M_PI/4/bigd) * cos(M_PI/2*(r - bigr)/bigd);
156  }
157  double cut() const {
158  return bigr + bigd;
159  }
160  double ters_fa(double r) const {
161  if(r > bigr + bigd) return 0.0;
162  return -D0*S/(S-1.0) * exp(-beta*sqrt(2/S)*(r-r0)) * ters_fc(r);
163  }
164  double ters_fa_d(double r) const {
165  if(r > bigr + bigd) return 0.0;
166  return D0*S/(S-1.0) * exp(-beta*sqrt(2/S)*(r-r0)) * (beta*sqrt(2/S) * ters_fc(r) - ters_fc_d(r));
167  }
168  double ters_gijk(double costheta) const {
169  double ters_c = c * c;
170  double ters_d = d * d;
171  double hcth = h + costheta;
172  return gamma * (1.0 + ters_c/ters_d - ters_c / (ters_d + hcth * hcth));
173  }
174  double ters_gijk_d(const double costheta) const {
175  double ters_c = c * c;
176  double ters_d = d * d;
177  double hcth = h + costheta;
178  double numerator = 2.0 * ters_c * hcth;
179  double denominator = 1.0/(ters_d + hcth*hcth);
180  return gamma * numerator * denominator * denominator;
181  }
182  double ters_bij(double zeta) const {
183  double tmp = beta2 * zeta;
184  if(tmp > c1) return 1.0 / sqrt(tmp);
185  if(tmp > c2) return (1.0 - pow(tmp,-powern) / (2.0*powern)) / sqrt(tmp);
186  if(tmp < c4) return 1.0;
187  if(tmp < c3) return 1.0 - pow(tmp,powern)/(2.0*powern);
188  return pow(1.0 + pow(tmp,powern), -1.0/(2.0*powern));
189  }
190  double ters_bij_d(double zeta) const {
191  double tmp = beta2 * zeta;
192  if(tmp > c1) return beta2 * -0.5*pow(tmp,-1.5);
193  if(tmp > c2) return beta2 * (-0.5*pow(tmp,-1.5) * (1.0 - 0.5*(1.0 + 1.0/(2.0*powern)) * pow(tmp,-powern)));
194  if(tmp < c4) return 0.0;
195  if(tmp < c3) return -0.5*beta2 * pow(tmp,powern-1.0);
196  double tmp_n = pow(tmp,powern);
197  return -0.5 * pow(1.0+tmp_n, -1.0-(1.0/(2.0*powern)))*tmp_n / zeta;
198  }
199  void setCorrectedInitialValue(ScalarDOF& dof, double value) {
200  // Due to the conversion between tersoff and abop format a parameter
201  // that is exactly on the lower or upper boundary may be a tiny bit
202  // outside of the boundary. This conversion errors are fixed here.
203  // #include <cmath> to import the floating point version of abs.
204  if(dof.hasLowerBound() && std::abs(value - dof.lowerBound()) < 1e-9) {
205  value = dof.lowerBound();
206  }
207  if(dof.hasUpperBound() && std::abs(value - dof.upperBound()) < 1e-9) {
208  value = dof.upperBound();
209  }
210  dof.setInitialValue(value);
211  }
212  void setInitialParams(double r0,double D0, double beta, double S,
213  double gamma, double c,double d,double h, double twomu,
214  double beta2, double powern, double powerm, double bigd, double bigr) {
215  // Store parameters.
216  setCorrectedInitialValue(this->r0, r0);
217  setCorrectedInitialValue(this->D0, D0);
218  setCorrectedInitialValue(this->beta, beta);
219  setCorrectedInitialValue(this->S, S);
220  this->gamma.setInitialValue(gamma);
221  this->c.setInitialValue(c);
222  this->d.setInitialValue(d);
223  this->h.setInitialValue(h);
224  this->twomu.setInitialValue(twomu);
225  this->beta2.setInitialValue(beta2);
226  this->powern.setInitialValue(powern);
227  this->bigd.setInitialValue(bigd);
228  this->bigr.setInitialValue(bigr);
229  this->powerm = powerm;
230 
231  // Compute dependent parameters.
232  this->powermint = (int)powerm;
233  this->c1 = pow(2.0*powern*1.0e-16,-1.0/powern);
234  this->c2 = pow(2.0*powern*1.0e-8,-1.0/powern);
235  this->c3 = 1.0/this->c2;
236  this->c4 = 1.0/this->c1;
237  }
238  };
239 
241  const ABOParamSet& getParamSet(int itype, int jtype, int ktype) const {
242  BOOST_ASSERT(itype >= 0 && itype < _numAtomTypes);
243  BOOST_ASSERT(jtype >= 0 && jtype < _numAtomTypes);
244  BOOST_ASSERT(ktype >= 0 && ktype < _numAtomTypes);
245  return _params[itype * _numAtomTypes * _numAtomTypes + jtype * _numAtomTypes + ktype];
246  }
247 
248  // The maximum cutoff radius of the potential.
249  double _cutoff;
250 
251  // Parameter sets for I-J-K interactions.
252  std::vector<ABOParamSet> _params;
253 
256 
258  void parseTersoffFile(const FPString& filename);
259 
261  void linkDOF();
262 
265 
267  int _dofMode;
268 };
269 
270 } // End of namespace
Base class for maintaining structures.
Definition: AtomicStructure.h:42
This class defines the ABOP potential format.
Definition: ABOPotential.h:89
const ABOParamSet & getParamSet(int itype, int jtype, int ktype) const
Returns the parameter set for the i-j-k triplet interaction.
Definition: ABOPotential.h:241
FPString _exportPotentialFile
Potential file that is written after fitting.
Definition: ABOPotential.h:264
virtual double cutoff() const override
Returns the maximum cutoff of the potential.
Definition: ABOPotential.h:97
double upperBound() const
Returns the upper bound if this DOF has a constraint applied to it.
Definition: DegreeOfFreedom.h:229
ScalarDOF beta2
ABOP three-body parameters (typically ik dependent)
Definition: ABOPotential.h:122
ScalarDOF bigr
Tersoff m parameter (1 in ABOP, 3 in original Tersoff)
Definition: ABOPotential.h:125
double c1
Half cutoff width D.
Definition: ABOPotential.h:128
Definition: NeighborList.h:58
void writePotential(const FPString &filename) const
Generates a potential file to be used with simulation codes.
Definition: ABOPotential.cpp:345
const FPString & tag() const
Returns the assigned tag string.
Definition: FitObject.h:144
bool hasUpperBound() const
Returns whether this DOF has an upper bound constraint applied to it.
Definition: DegreeOfFreedom.h:232
void setInitialValue(double value)
Sets the initial value of this DOF. This also changes the current value to the same value...
Definition: DegreeOfFreedom.h:199
virtual void outputResults() override
This function is called by the fit job on shutdown, i.e. after the fitting process has finished...
Definition: ABOPotential.cpp:332
void parseTersoffFile(const FPString &filename)
Parses Tersoff parameters from a LAMMPS potential file.
Definition: ABOPotential.cpp:532
int _dofMode
Constrain Mode (0 = All DOF independent, 1 = DOFs connected as in "classical" ABOP) ...
Definition: ABOPotential.h:267
void linkDOF()
Links the DOF together to get only doublett interaction as in the classical ABOP. ...
Definition: ABOPotential.cpp:485
virtual double computeEnergyAndForces(AtomicStructure &structure, NeighborList &neighborList) override
Computes the total energy and forces of the structure.
Definition: ABOPotential.cpp:163
This file collects the definition of classes that define various simple crystal structures.
Definition: Atomicrex.h:67
A simple scalar degree of freedom that consists of a single value.
Definition: DegreeOfFreedom.h:169
virtual double computeEnergy(AtomicStructure &structure, NeighborList &neighborList) override
Computes the total energy of the structure.
Definition: ABOPotential.cpp:86
Definition: ABOPotential.h:118
bool hasLowerBound() const
Returns whether this DOF has a lower bound constraint applied to it.
Definition: DegreeOfFreedom.h:223
std::string FPString
The default string type used throughout the code:
Definition: Atomicrex.h:70
Definition: XMLUtilities.h:69
Definition: FitJob.h:37
double lowerBound() const
Returns the lower bound if this DOF has a constraint applied to it.
Definition: DegreeOfFreedom.h:220
FitJob * job() const
Returns a pointer to the job to which this object belongs.
Definition: FitObject.h:150
ABOPotential(const FPString &id, FitJob *job, const FPString &tag=FPString("Tersoff"))
Constructor.
Definition: ABOPotential.cpp:36
ScalarDOF bigd
Cutoff centered at R.
Definition: ABOPotential.h:126
double powerm
Tersoff n parameter (1 in ABOP)
Definition: ABOPotential.h:124
virtual void parse(XML::Element potentialElement) override
Parses any potential-specific parameters in the XML element in the job file.
Definition: ABOPotential.cpp:433
ScalarDOF powern
Tersoff beta parameter (1 in ABOP)
Definition: ABOPotential.h:123
ScalarDOF gamma
ABOP two-body parameters (ij dependent)
Definition: ABOPotential.h:121
int _numAtomTypes
The number of atom types.
Definition: ABOPotential.h:255
Base class for potential.
Definition: Potential.h:41