atomicrex  0.1
An advanced atomistic model building tool
Functions.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 "../../job/FitObject.h"
25 #include "../../util/NumericalIntegration.h"
26 #include "../../dof/DegreeOfFreedom.h"
27 
28 namespace atomicrex {
29 
36 {
37 public:
38 
46  };
47 
48 public:
49 
51  FunctionBase(const FPString& id, FitJob* job, const FPString& tag = FPString())
52  : FitObject(id, job, tag), _normalizationMode(NONE), _prefactor(0), _cutoff(FLOATTYPE_MAX) {}
53 
55  bool hasCutoff() const { return cutoff() != FLOATTYPE_MAX; }
56 
59  double cutoff() const { return _cutoff; }
60 
63  void setCutoff(double cutoff) { _cutoff = cutoff; }
64 
66  double prefactor() const { return _prefactor; }
67 
69  double evaluate(double r);
70 
72  double evaluate(double r, double& deriv);
73 
81  void writeTabulated(std::ostream& out, double rmin, double rmax, double dr);
82 
85 
88 
91  void computePrefactor();
92 
95  virtual void dofValueChanged(DegreeOfFreedom& dof) override {
97  _prefactor = 0;
98  }
99 
101  const std::shared_ptr<FunctionBase>& screeningFunction() const { return _screeningFunction; }
102 
105  void setScreeningFunction(const std::shared_ptr<FunctionBase>& func) {
106  BOOST_ASSERT(!_screeningFunction);
107  _screeningFunction = func;
108  registerSubObject(func.get());
109  }
110 
113  void verifyDerivative();
114 
117  void checkDerivativeNumerically(double r);
118 
121  double centralDerivative(double r, double h, double& abserr_trunc, double& abserr_round);
122 
123 public:
124 
126  virtual void parse(XML::Element functionElement) override;
127 
129  static std::shared_ptr<FunctionBase> createAndParse(XML::Element functionElement, const FPString& id, FitJob* job);
130 
132  virtual XML::OElement generateXMLDefinition(const FPString& elementName);
133 
134 protected:
135 
138  virtual double evaluateInternal(double r) override = 0;
139 
142  virtual double evaluateInternal(double r, double& deriv) = 0;
143 
148  virtual std::vector<DegreeOfFreedom*> DOFToExport() { return DOF(); }
149 
150 protected:
151 
153  double _cutoff;
154 
156  double _prefactor;
157 
160 
162  std::shared_ptr<FunctionBase> _screeningFunction;
163 };
164 
165 
166 /************************************************************
167  * exp[1/(r-rc)]
168  ************************************************************/
170 {
171 public:
172  FunctionExpA(const FPString& id, FitJob* job)
173  : FunctionBase(id, job, "exp") {}
174 
175 protected:
176  double evaluateInternal(double r) override;
177  double evaluateInternal(double r, double& deriv) override;
178 };
179 
180 
181 /************************************************************
182  * exp[sgn(n)*alpha/(1-(r/rc)^n)]
183  ************************************************************/
185 {
186 public:
187  FunctionExpB(const FPString& id, FitJob* job);
188 
190  virtual void parse(XML::Element functionElement) override;
191 
193  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
194 
195 protected:
196  double evaluateInternal(double r) override;
197  double evaluateInternal(double r, double& deriv) override;
198 
199 private:
200  ScalarDOF _alpha, _exponent, _rc;
201 };
202 
203 
204 /************************************************************
205  * ExpB * gaussian
206  ************************************************************/
208 {
209 public:
210  FunctionExpGaussian(const FPString& id, FitJob* job);
211 
213  virtual void parse(XML::Element functionElement) override;
214 
216  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
217 
218 protected:
219  double evaluateInternal(double r) override;
220  double evaluateInternal(double r, double& deriv) override;
221 
222 private:
223  ScalarDOF _stddev, _alpha, _exponent;
224 };
225 
226 /************************************************************
227  * Standard Morse potential (type A).
228  *
229  * D0 * [exp(-2*alpha*(r-r0)) - 2*exp(-alpha*(r-r0))]
230  ************************************************************/
232 {
233 public:
234 
236  FunctionMorseA(const FPString& id, FitJob* job);
237 
239  virtual void parse(XML::Element functionElement) override;
240 
242  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
243 
244 protected:
245  double evaluateInternal(double r) override;
246  double evaluateInternal(double r, double& deriv) override;
247 
248 private:
249  ScalarDOF _D0, _alpha, _r0;
250 };
251 
252 /************************************************************
253  * Modified Morse potential - type B.
254  *
255  * [D0 / (S-1) * exp(-beta sqrt(2 S) (r - r0)] - [D0 S / (S-1) * exp(-beta sqrt(2 S) (r - r0))] + delta
256  ************************************************************/
258 {
259 public:
260  FunctionMorseB(const FPString& id, FitJob* job);
261 
263  virtual void parse(XML::Element functionElement) override;
264 
266  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
267 
268 protected:
269  double evaluateInternal(double r) override;
270  double evaluateInternal(double r, double& deriv) override;
271 
272 private:
273  ScalarDOF _D0, _r0, _S, _beta, _delta;
274 };
275 
276 /************************************************************
277  * Modified Morse potential - type C.
278  ************************************************************/
280 {
281 public:
282  FunctionMorseC(const FPString& id, FitJob* job);
283 
285  virtual void parse(XML::Element functionElement) override;
286 
288  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
289 
290 protected:
291  double evaluateInternal(double r) override;
292  double evaluateInternal(double r, double& deriv) override;
293 
294 private:
295  ScalarDOF _A, _B, _mu, _lambda, _delta;
296 };
297 
298 /************************************************************
299  * Polynomial
300  ************************************************************/
302 {
303 public:
304 
305  FunctionPoly(const FPString& id, FitJob* job)
306  : FunctionBase(id, job, "poly"), _isPrepared(false) {}
307 
308  double integrateSpherical(double a, double b) override;
309 
311  virtual void parse(XML::Element functionElement) override;
312 
314  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
315 
317  virtual void dofValueChanged(DegreeOfFreedom& dof) override {
319  if(&dof != &_nodes.back().coeff) {
320  _isPrepared = false;
321  }
322  }
323 
324 protected:
325 
326  double evaluateInternal(double r) override;
327  double evaluateInternal(double r, double& deriv) override;
328 
329  void imposeBoundaryConditions();
330 
333  virtual std::vector<DegreeOfFreedom*> DOFToExport() override { return std::vector<DegreeOfFreedom*>(); }
334 
335 private:
336 
337  struct PolyNode {
338  ScalarDOF coeff;
339  int exponent;
340  };
341 
343  bool _isPrepared;
344 
345  std::vector<PolyNode> _nodes;
346 
347  int _degree;
348 };
349 
350 
351 /************************************************************
352  * Cubic spline
353  ************************************************************/
355 {
356 public:
357 
360  : FunctionBase(id, job, "spline"), _isPrepared(false) {}
361 
363  virtual void parse(XML::Element functionElement) override;
364 
366  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
367 
369  virtual void dofValueChanged(DegreeOfFreedom& dof) override {
371  _isPrepared = false;
372  }
373 
374 protected:
375 
376  double evaluateInternal(double r) override;
377  double evaluateInternal(double r, double& deriv) override;
378  void prepareSpline();
379 
382  virtual std::vector<DegreeOfFreedom*> DOFToExport() override { return std::vector<DegreeOfFreedom*>(); }
383 
384 private:
385 
386  struct SplineNode {
387  double x, y2;
388  ScalarDOF y;
389 
390  bool operator<(const SplineNode& other) const { return x < other.x; } // Used for node sorting.
391  };
392 
394  bool _isPrepared;
395 
396  // Vector of spline nodes.
397  std::vector<SplineNode> _nodes;
398 
399  // Derivatives at left and right most nodes.
400  ScalarDOF _deriv0, _derivN;
401 };
402 
403 /************************************************************
404  * Function of function of 1-x
405  ************************************************************/
407 {
408 public:
409 
411  FunctionInverseArgument(const FPString& id, FitJob* job, const std::shared_ptr<FunctionBase>& func)
412  : FunctionBase(id, job, "functionInverseArgument"), _innerFunction(func) {}
413 
415  const std::shared_ptr<FunctionBase>& innerFunction() const { return _innerFunction; }
416 
417 protected:
418 
419  double evaluateInternal(double r) override {
420  return _innerFunction->evaluate(1.0 - r);
421  }
422 
423  double evaluateInternal(double r, double& deriv) override {
424  double h = _innerFunction->evaluate(1.0 - r, deriv);
425  deriv = -deriv;
426  return h;
427  }
428 
429 private:
430  std::shared_ptr<FunctionBase> _innerFunction;
431 };
432 
433 /************************************************************
434  * Sum of two or more functions.
435  ************************************************************/
436 class FunctionSum : public FunctionBase
437 {
438 public:
439 
441  FunctionSum(const FPString& id, FitJob* job) : FunctionBase(id, job, "functionSum") {}
442 
444  virtual void parse(XML::Element functionElement) override;
445 
446 protected:
447 
448  double evaluateInternal(double r) override {
449  double s = 0;
450  for(const auto& f : _functions)
451  s += f->evaluate(r);
452  return s;
453  }
454 
455  double evaluateInternal(double r, double& deriv) override {
456  double s = 0;
457  deriv = 0;
458  for(const auto& f : _functions) {
459  double d;
460  s += f->evaluate(r, d);
461  deriv += d;
462  }
463  return s;
464  }
465 
466 private:
467 
468  std::vector<std::shared_ptr<FunctionBase>> _functions;
469 };
470 
471 /************************************************************
472  * A constant function, with the constant being a degree of freedom.
473  ************************************************************/
475 {
476 public:
477 
479  FunctionConstant(const FPString& id, FitJob* job);
480 
482  virtual void parse(XML::Element functionElement) override;
483 
485  virtual XML::OElement generateXMLDefinition(const FPString& elementName) override;
486 
487 protected:
488 
489  double evaluateInternal(double r) override;
490  double evaluateInternal(double r, double& deriv) override;
491 
492 private:
493 
494  ScalarDOF _const;
495 };
496 
497 /************************************************************
498  * Product of two functions.
499  ************************************************************/
501 {
502 public:
503 
505  FunctionProduct(const FPString& id, FitJob* job) : FunctionBase(id, job, "functionProduct") {}
506 
508  virtual void parse(XML::Element functionElement) override;
509 
510 protected:
511 
512  double evaluateInternal(double r) override {
513  return _function1->evaluate(r) * _function2->evaluate(r);
514  }
515 
516  double evaluateInternal(double r, double& deriv) override {
517  double p1, p2;
518  double d1, d2;
519  p1 = _function1->evaluate(r, d1);
520  p2 = _function2->evaluate(r, d2);
521  deriv = p1 * d2 + p2 * d1;
522  return p1 * p2;
523  }
524 
525 private:
526 
527  std::shared_ptr<FunctionBase> _function1;
528  std::shared_ptr<FunctionBase> _function2;
529 };
530 
531 } // End of namespace
virtual void parse(XML::Element functionElement) override
Parses function parameters from the given XML element.
Definition: Functions.cpp:86
FunctionSum(const FPString &id, FitJob *job)
Constructor.
Definition: Functions.h:441
Function is one at origin, .
Definition: Functions.h:45
double evaluateInternal(double r, double &deriv) override
Definition: Functions.h:423
FunctionProduct(const FPString &id, FitJob *job)
Constructor.
Definition: Functions.h:505
Definition: Functions.h:500
void setCutoff(double cutoff)
Definition: Functions.h:63
void setScreeningFunction(const std::shared_ptr< FunctionBase > &func)
Definition: Functions.h:105
double evaluateInternal(double r, double &deriv) override
Definition: Functions.h:516
FunctionBase(const FPString &id, FitJob *job, const FPString &tag=FPString())
Constructor.
Definition: Functions.h:51
double centralDerivative(double r, double h, double &abserr_trunc, double &abserr_round)
Definition: Functions.cpp:325
void setNormalizationMode(NormalizationMode mode)
Specifies the normalization mode to be used for this function.
Definition: Functions.h:87
virtual void dofValueChanged(DegreeOfFreedom &dof) override
This callback function is called by the DOFs of this function each time when their values changes...
Definition: Functions.h:317
double evaluateInternal(double r) override
Definition: Functions.h:448
double _prefactor
The constant prefactor used to normalize the function.
Definition: Functions.h:156
const std::shared_ptr< FunctionBase > & screeningFunction() const
Returns the screening function applied to this function, or NULL.
Definition: Functions.h:101
void computePrefactor()
Definition: Functions.cpp:234
void registerSubObject(FitObject *subobject, bool deleteOnShutdown=false)
Registers a sub-object.
Definition: FitObject.cpp:57
Definition: Functions.h:474
std::shared_ptr< FunctionBase > _screeningFunction
Optional screening function.
Definition: Functions.h:162
const std::vector< DegreeOfFreedom * > & DOF() const
Returns a list of degrees of freedom of this object.
Definition: FitObject.h:86
const FPString & tag() const
Returns the assigned tag string.
Definition: FitObject.h:144
bool hasCutoff() const
Returns whether this function has a cutoff.
Definition: Functions.h:55
FunctionInverseArgument(const FPString &id, FitJob *job, const std::shared_ptr< FunctionBase > &func)
Constructor.
Definition: Functions.h:411
NormalizationMode normalizationMode() const
Returns the normalization mode set for this function.
Definition: Functions.h:84
static std::shared_ptr< FunctionBase > createAndParse(XML::Element functionElement, const FPString &id, FitJob *job)
Parses an XML element and creates a function object out of it.
Definition: Functions.cpp:40
virtual void dofValueChanged(DegreeOfFreedom &dof)
This callback function is called by the DOFs of this fit object each time when their values changes...
Definition: FitObject.h:95
FunctionSpline(const FPString &id, FitJob *job)
Constructor.
Definition: Functions.h:359
Definition: Functions.h:169
NormalizationMode _normalizationMode
Controls the type of normalization applied to the function.
Definition: Functions.h:159
virtual std::vector< DegreeOfFreedom * > DOFToExport() override
Definition: Functions.h:333
virtual std::vector< DegreeOfFreedom * > DOFToExport()
Definition: Functions.h:148
double evaluate(double r)
Evaluates the function at the given r and multiplies the value with the proper normalization factor...
Definition: Functions.cpp:186
Definition: Functions.h:406
virtual std::vector< DegreeOfFreedom * > DOFToExport() override
Definition: Functions.h:382
double cutoff() const
Definition: Functions.h:59
Definition: Functions.h:354
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 evaluateInternal(double r) override=0
Definition: Functions.h:301
virtual void dofValueChanged(DegreeOfFreedom &dof) override
Definition: Functions.h:95
Definition: Functions.h:184
void verifyDerivative()
Definition: Functions.cpp:267
std::string FPString
The default string type used throughout the code:
Definition: Atomicrex.h:70
Do not perform any normalization; use unmodified function.
Definition: Functions.h:41
Definition: Functions.h:231
Definition: XMLUtilities.h:226
Definition: Functions.h:279
Definition: XMLUtilities.h:69
double _cutoff
The function cutoff.
Definition: Functions.h:153
Definition: FitObject.h:42
Definition: FitJob.h:37
Definition: Functions.h:436
void checkDerivativeNumerically(double r)
Definition: Functions.cpp:280
FitJob * job() const
Returns a pointer to the job to which this object belongs.
Definition: FitObject.h:150
double evaluateInternal(double r, double &deriv) override
Definition: Functions.h:455
Spherical integral over [0,cutoff] is unity, .
Definition: Functions.h:43
virtual double integrateSpherical(double a, double b)
Definition: NumericalIntegration.h:52
Base class for all degrees of freedom a potential or a structure may have.
Definition: DegreeOfFreedom.h:46
Base class for all one-dimensional functions that can be fitted.
Definition: Functions.h:35
Definition: Functions.h:207
double prefactor() const
Returns the constant prefactor the function is multiplied with.
Definition: Functions.h:66
Definition: Functions.h:257
const std::shared_ptr< FunctionBase > & innerFunction() const
Returns the inner function.
Definition: Functions.h:415
void writeTabulated(std::ostream &out, double rmin, double rmax, double dr)
Write tabulated function to stream for visualization with Gnuplot.
Definition: Functions.cpp:166
NormalizationMode
Definition: Functions.h:39
virtual XML::OElement generateXMLDefinition(const FPString &elementName)
Produces an XML representation of the function&#39;s current parameters and DOFs.
Definition: Functions.cpp:133
virtual void dofValueChanged(DegreeOfFreedom &dof) override
This callback function is called by the DOFs of this function each time their value changes...
Definition: Functions.h:369
double evaluateInternal(double r) override
Definition: Functions.h:419
Definition: NumericalIntegration.h:31
double evaluateInternal(double r) override
Definition: Functions.h:512