1037 lines
22 KiB
C++
1037 lines
22 KiB
C++
/**
|
|
* @file Func1.h
|
|
*/
|
|
|
|
// Copyright 2001 California Institute of Technology
|
|
|
|
#ifndef CT_FUNC1_H
|
|
#define CT_FUNC1_H
|
|
|
|
#include "cantera/base/ct_defs.h"
|
|
|
|
#include <iostream>
|
|
|
|
namespace Cantera
|
|
{
|
|
|
|
const int FourierFuncType = 1;
|
|
const int PolyFuncType = 2;
|
|
const int ArrheniusFuncType = 3;
|
|
const int GaussianFuncType = 4;
|
|
const int SumFuncType = 20;
|
|
const int DiffFuncType = 25;
|
|
const int ProdFuncType = 30;
|
|
const int RatioFuncType = 40;
|
|
const int PeriodicFuncType = 50;
|
|
const int CompositeFuncType = 60;
|
|
const int TimesConstantFuncType = 70;
|
|
const int PlusConstantFuncType = 80;
|
|
const int SinFuncType = 100;
|
|
const int CosFuncType = 102;
|
|
const int ExpFuncType = 104;
|
|
const int PowFuncType = 106;
|
|
const int ConstFuncType = 110;
|
|
|
|
class TimesConstant1;
|
|
|
|
/**
|
|
* Base class for 'functor' classes that evaluate a function of one variable.
|
|
*/
|
|
class Func1
|
|
{
|
|
public:
|
|
Func1();
|
|
|
|
virtual ~Func1() {}
|
|
|
|
Func1(const Func1& right);
|
|
|
|
Func1& operator=(const Func1& right);
|
|
|
|
//! Duplicate the current function.
|
|
/*!
|
|
* This duplicates the current function, returning a
|
|
* reference to the new malloced function.
|
|
*/
|
|
virtual Func1& duplicate() const;
|
|
|
|
virtual int ID() const;
|
|
|
|
//! Calls method eval to evaluate the function
|
|
doublereal operator()(doublereal t) const;
|
|
|
|
/// Evaluate the function.
|
|
virtual doublereal eval(doublereal t) const;
|
|
|
|
//! Creates a derivative to the current function
|
|
/*!
|
|
* This will malloc a derivative function and
|
|
* return a reference to the function.
|
|
*/
|
|
virtual Func1& derivative() const;
|
|
|
|
//! Routine to determine if two functions are the same.
|
|
/*!
|
|
* Two functions are the same if they are the same function.
|
|
* This means that the ID and stored constant is the same.
|
|
* This means that the m_f1 and m_f2 are identical if they
|
|
* are non-null.
|
|
*/
|
|
bool isIdentical(Func1& other) const;
|
|
|
|
virtual doublereal isProportional(TimesConstant1& other);
|
|
virtual doublereal isProportional(Func1& other);
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
//! accessor function for the stored constant
|
|
doublereal c() const;
|
|
|
|
//! Function to set the stored constant
|
|
void setC(doublereal c);
|
|
|
|
//! accessor function for m_f1
|
|
Func1& func1() const;
|
|
|
|
//! accessor function for m_f2
|
|
Func1& func2() const;
|
|
|
|
//! Return the order of the function, if it makes sense
|
|
virtual int order() const;
|
|
|
|
Func1& func1_dup() const;
|
|
|
|
Func1& func2_dup() const;
|
|
|
|
Func1* parent() const;
|
|
|
|
void setParent(Func1* p);
|
|
|
|
protected:
|
|
doublereal m_c;
|
|
Func1* m_f1;
|
|
Func1* m_f2;
|
|
Func1* m_parent;
|
|
};
|
|
|
|
|
|
Func1& newSumFunction(Func1& f1, Func1& f2);
|
|
Func1& newDiffFunction(Func1& f1, Func1& f2);
|
|
Func1& newProdFunction(Func1& f1, Func1& f2);
|
|
Func1& newRatioFunction(Func1& f1, Func1& f2);
|
|
Func1& newCompositeFunction(Func1& f1, Func1& f2);
|
|
Func1& newTimesConstFunction(Func1& f1, doublereal c);
|
|
Func1& newPlusConstFunction(Func1& f1, doublereal c);
|
|
|
|
//! implements the sin() function
|
|
/*!
|
|
* The argument to sin() is in radians
|
|
*/
|
|
class Sin1 : public Func1
|
|
{
|
|
public:
|
|
Sin1(doublereal omega = 1.0) :
|
|
Func1() {
|
|
m_c = omega;
|
|
}
|
|
|
|
Sin1(const Sin1& b) :
|
|
Func1(b) {
|
|
}
|
|
|
|
Sin1& operator=(const Sin1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Sin1* nfunc = new Sin1(*this);
|
|
return (Func1&) *nfunc;
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
virtual int ID() const {
|
|
return SinFuncType;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return sin(m_c*t);
|
|
}
|
|
|
|
virtual Func1& derivative() const;
|
|
};
|
|
|
|
/// cos
|
|
class Cos1 : public Func1
|
|
{
|
|
public:
|
|
Cos1(doublereal omega = 1.0) :
|
|
Func1() {
|
|
m_c = omega;
|
|
}
|
|
|
|
Cos1(const Cos1& b) :
|
|
Func1(b) {
|
|
}
|
|
|
|
Cos1& operator=(const Cos1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Cos1* nfunc = new Cos1(*this);
|
|
return (Func1&) *nfunc;
|
|
}
|
|
virtual std::string write(const std::string& arg) const;
|
|
virtual int ID() const {
|
|
return CosFuncType;
|
|
}
|
|
virtual doublereal eval(doublereal t) const {
|
|
return cos(m_c * t);
|
|
}
|
|
virtual Func1& derivative() const;
|
|
};
|
|
|
|
/// exp
|
|
class Exp1 : public Func1
|
|
{
|
|
public:
|
|
Exp1(doublereal A = 1.0) :
|
|
Func1() {
|
|
m_c = A;
|
|
}
|
|
|
|
Exp1(const Exp1& b) :
|
|
Func1(b) {
|
|
}
|
|
Exp1& operator=(const Exp1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
return *this;
|
|
}
|
|
virtual std::string write(const std::string& arg) const;
|
|
virtual int ID() const {
|
|
return ExpFuncType;
|
|
}
|
|
virtual Func1& duplicate() const {
|
|
return *(new Exp1(m_c));
|
|
}
|
|
virtual doublereal eval(doublereal t) const {
|
|
return exp(m_c*t);
|
|
}
|
|
|
|
virtual Func1& derivative() const;
|
|
};
|
|
|
|
/// pow
|
|
class Pow1 : public Func1
|
|
{
|
|
public:
|
|
Pow1(doublereal n) :
|
|
Func1() {
|
|
m_c = n;
|
|
}
|
|
|
|
Pow1(const Pow1& b) :
|
|
Func1(b) {
|
|
}
|
|
Pow1& operator=(const Pow1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
return *this;
|
|
}
|
|
virtual std::string write(const std::string& arg) const;
|
|
virtual int ID() const {
|
|
return PowFuncType;
|
|
}
|
|
virtual Func1& duplicate() const {
|
|
return *(new Pow1(m_c));
|
|
}
|
|
virtual doublereal eval(doublereal t) const {
|
|
return pow(t, m_c);
|
|
}
|
|
virtual Func1& derivative() const;
|
|
};
|
|
|
|
/**
|
|
* Constant.
|
|
*/
|
|
class Const1 : public Func1
|
|
{
|
|
public:
|
|
Const1(doublereal A) :
|
|
Func1() {
|
|
m_c = A;
|
|
}
|
|
|
|
Const1(const Const1& b) :
|
|
Func1(b) {
|
|
}
|
|
|
|
Const1& operator=(const Const1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
return *this;
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
virtual int ID() const {
|
|
return ConstFuncType;
|
|
}
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_c;
|
|
}
|
|
virtual Func1& duplicate() const {
|
|
return *(new Const1(m_c));
|
|
}
|
|
|
|
virtual Func1& derivative() const {
|
|
Func1* z = new Const1(0.0);
|
|
return *z;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Sum of two functions.
|
|
*/
|
|
class Sum1 : public Func1
|
|
{
|
|
public:
|
|
Sum1(Func1& f1, Func1& f2) :
|
|
Func1() {
|
|
m_f1 = &f1;
|
|
m_f2 = &f2;
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
}
|
|
|
|
virtual ~Sum1() {
|
|
delete m_f1;
|
|
delete m_f2;
|
|
}
|
|
|
|
Sum1(const Sum1& b) :
|
|
Func1(b) {
|
|
*this = Sum1::operator=(b);
|
|
}
|
|
|
|
Sum1& operator=(const Sum1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f2 = &m_f2->duplicate();
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual int ID() const {
|
|
return SumFuncType;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(t) + m_f2->eval(t);
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1d = m_f1->duplicate();
|
|
Func1& f2d = m_f2->duplicate();
|
|
return newSumFunction(f1d, f2d);
|
|
}
|
|
|
|
virtual Func1& derivative() const {
|
|
Func1& d1 = m_f1->derivative();
|
|
Func1& d2 = m_f2->derivative();
|
|
return newSumFunction(d1, d2);
|
|
}
|
|
virtual int order() const {
|
|
return 0;
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
};
|
|
|
|
|
|
/**
|
|
* Difference of two functions.
|
|
*/
|
|
class Diff1 : public Func1
|
|
{
|
|
public:
|
|
Diff1(Func1& f1, Func1& f2) {
|
|
m_f1 = &f1;
|
|
m_f2 = &f2;
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
}
|
|
|
|
virtual ~Diff1() {
|
|
delete m_f1;
|
|
delete m_f2;
|
|
}
|
|
|
|
Diff1(const Diff1& b) :
|
|
Func1(b) {
|
|
*this = Diff1::operator=(b);
|
|
}
|
|
|
|
Diff1& operator=(const Diff1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f2 = &m_f2->duplicate();
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual int ID() const {
|
|
return DiffFuncType;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(t) - m_f2->eval(t);
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1d = m_f1->duplicate();
|
|
Func1& f2d = m_f2->duplicate();
|
|
return newDiffFunction(f1d, f2d);
|
|
}
|
|
virtual Func1& derivative() const {
|
|
return newDiffFunction(m_f1->derivative(), m_f2->derivative());
|
|
}
|
|
virtual int order() const {
|
|
return 0;
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
};
|
|
|
|
|
|
/**
|
|
* Product of two functions.
|
|
*/
|
|
class Product1 : public Func1
|
|
{
|
|
public:
|
|
Product1(Func1& f1, Func1& f2) :
|
|
Func1() {
|
|
m_f1 = &f1;
|
|
m_f2 = &f2;
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
}
|
|
|
|
virtual ~Product1() {
|
|
delete m_f1;
|
|
delete m_f2;
|
|
}
|
|
|
|
Product1(const Product1& b) :
|
|
Func1(b) {
|
|
*this = Product1::operator=(b);
|
|
}
|
|
|
|
Product1& operator=(const Product1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f2 = &m_f2->duplicate();
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual int ID() const {
|
|
return ProdFuncType;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1d = m_f1->duplicate();
|
|
Func1& f2d = m_f2->duplicate();
|
|
return newProdFunction(f1d, f2d);
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(t) * m_f2->eval(t);
|
|
}
|
|
|
|
virtual Func1& derivative() const {
|
|
Func1& a1 = newProdFunction(m_f1->duplicate(), m_f2->derivative());
|
|
Func1& a2 = newProdFunction(m_f2->duplicate(), m_f1->derivative());
|
|
return newSumFunction(a1, a2);
|
|
}
|
|
virtual int order() const {
|
|
return 1;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Product of two functions.
|
|
*/
|
|
class TimesConstant1 : public Func1
|
|
{
|
|
public:
|
|
TimesConstant1(Func1& f1, doublereal A) :
|
|
Func1() {
|
|
m_f1 = &f1;
|
|
m_c = A;
|
|
m_f1->setParent(this);
|
|
}
|
|
|
|
virtual ~TimesConstant1() {
|
|
delete m_f1;
|
|
}
|
|
|
|
TimesConstant1(const TimesConstant1& b) :
|
|
Func1(b) {
|
|
*this = TimesConstant1::operator=(b);
|
|
}
|
|
|
|
TimesConstant1& operator=(const TimesConstant1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f1->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
virtual int ID() const {
|
|
return TimesConstantFuncType;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1 = m_f1->duplicate();
|
|
Func1* dup = new TimesConstant1(f1, m_c);
|
|
return *dup;
|
|
}
|
|
|
|
virtual doublereal isProportional(TimesConstant1& other) {
|
|
if (func1().isIdentical(other.func1())) {
|
|
return (other.c()/c());
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
virtual doublereal isProportional(Func1& other) {
|
|
if (func1().isIdentical(other)) {
|
|
return 1.0/c();
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(t) * m_c;
|
|
}
|
|
|
|
virtual Func1& derivative() const {
|
|
Func1& f1d = m_f1->derivative();
|
|
Func1* d = &newTimesConstFunction(f1d, m_c);
|
|
return *d;
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
virtual int order() const {
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A function plus a constant.
|
|
*/
|
|
class PlusConstant1 : public Func1
|
|
{
|
|
public:
|
|
PlusConstant1(Func1& f1, doublereal A) :
|
|
Func1() {
|
|
m_f1 = &f1;
|
|
m_c = A;
|
|
m_f1->setParent(this);
|
|
}
|
|
|
|
virtual ~PlusConstant1() {
|
|
delete m_f1;
|
|
}
|
|
|
|
PlusConstant1(const PlusConstant1& b) :
|
|
Func1(b) {
|
|
*this = PlusConstant1::operator=(b);
|
|
}
|
|
|
|
PlusConstant1& operator=(const PlusConstant1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f1->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual int ID() const {
|
|
return PlusConstantFuncType;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1 = m_f1->duplicate();
|
|
Func1* dup = new PlusConstant1(f1, m_c);
|
|
return *dup;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(t) + m_c;
|
|
}
|
|
virtual Func1& derivative() const {
|
|
return m_f1->derivative();
|
|
}
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
virtual int order() const {
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Ratio of two functions.
|
|
*/
|
|
class Ratio1 : public Func1
|
|
{
|
|
public:
|
|
Ratio1(Func1& f1, Func1& f2) :
|
|
Func1() {
|
|
m_f1 = &f1;
|
|
m_f2 = &f2;
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
}
|
|
|
|
virtual ~Ratio1() {
|
|
delete m_f1;
|
|
delete m_f2;
|
|
}
|
|
|
|
Ratio1(const Ratio1& b) :
|
|
Func1(b) {
|
|
*this = Ratio1::operator=(b);
|
|
}
|
|
|
|
Ratio1& operator=(const Ratio1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f2 = &m_f2->duplicate();
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual int ID() const {
|
|
return RatioFuncType;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(t) / m_f2->eval(t);
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1d = m_f1->duplicate();
|
|
Func1& f2d = m_f2->duplicate();
|
|
return newRatioFunction(f1d, f2d);
|
|
}
|
|
|
|
virtual Func1& derivative() const {
|
|
Func1& a1 = newProdFunction(m_f1->derivative(), m_f2->duplicate());
|
|
Func1& a2 = newProdFunction(m_f1->duplicate(), m_f2->derivative());
|
|
Func1& s = newDiffFunction(a1, a2);
|
|
Func1& p = newProdFunction(m_f2->duplicate(), m_f2->duplicate());
|
|
return newRatioFunction(s, p);
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
virtual int order() const {
|
|
return 1;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Composite function.
|
|
*/
|
|
class Composite1 : public Func1
|
|
{
|
|
public:
|
|
Composite1(Func1& f1, Func1& f2) :
|
|
Func1() {
|
|
m_f1 = &f1;
|
|
m_f2 = &f2;
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
}
|
|
|
|
virtual ~Composite1() {
|
|
delete m_f1;
|
|
delete m_f2;
|
|
}
|
|
|
|
Composite1(const Composite1& b) :
|
|
Func1(b) {
|
|
*this = Composite1::operator=(b);
|
|
}
|
|
|
|
Composite1& operator=(const Composite1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_f1 = &m_f1->duplicate();
|
|
m_f2 = &m_f2->duplicate();
|
|
m_f1->setParent(this);
|
|
m_f2->setParent(this);
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual int ID() const {
|
|
return CompositeFuncType;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
return m_f1->eval(m_f2->eval(t));
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Func1& f1d = m_f1->duplicate();
|
|
Func1& f2d = m_f2->duplicate();
|
|
return newCompositeFunction(f1d, f2d);
|
|
}
|
|
|
|
virtual Func1& derivative() const {
|
|
Func1* d1 = &m_f1->derivative();
|
|
|
|
Func1* d3 = &newCompositeFunction(*d1, m_f2->duplicate());
|
|
Func1* d2 = &m_f2->derivative();
|
|
Func1* p = &newProdFunction(*d3, *d2);
|
|
return *p;
|
|
}
|
|
|
|
virtual std::string write(const std::string& arg) const;
|
|
|
|
virtual int order() const {
|
|
return 2;
|
|
}
|
|
};
|
|
|
|
// The functors below are the old-style ones. They still work,
|
|
// but can't do derivatives.
|
|
|
|
/**
|
|
* A Gaussian.
|
|
* \f[
|
|
* f(t) = A e^{-[(t - t_0)/\tau]^2}
|
|
* \f]
|
|
* where \f[ \tau = \frac{fwhm}{2\sqrt{\ln 2}} \f]
|
|
* @param A peak value
|
|
* @param t0 offset
|
|
* @param fwhm full width at half max
|
|
*/
|
|
class Gaussian : public Func1
|
|
{
|
|
public:
|
|
Gaussian(double A, double t0, double fwhm) :
|
|
Func1() {
|
|
m_A = A;
|
|
m_t0 = t0;
|
|
m_tau = fwhm/(2.0*std::sqrt(std::log(2.0)));
|
|
}
|
|
|
|
Gaussian(const Gaussian& b) :
|
|
Func1(b) {
|
|
*this = Gaussian::operator=(b);
|
|
}
|
|
|
|
Gaussian& operator=(const Gaussian& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_A = right.m_A;
|
|
m_t0 = right.m_t0;
|
|
m_tau = right.m_tau;
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Gaussian* np = new Gaussian(*this);
|
|
return *((Func1*)np);
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
doublereal x = (t - m_t0)/m_tau;
|
|
return m_A * std::exp(-x*x);
|
|
}
|
|
|
|
protected:
|
|
doublereal m_A, m_t0, m_tau;
|
|
};
|
|
|
|
|
|
/**
|
|
* Polynomial of degree n.
|
|
*/
|
|
class Poly1 : public Func1
|
|
{
|
|
public:
|
|
Poly1(size_t n, doublereal* c) :
|
|
Func1() {
|
|
m_n = n+1;
|
|
m_cpoly.resize(n+1);
|
|
std::copy(c, c+m_n, m_cpoly.begin());
|
|
}
|
|
|
|
Poly1(const Poly1& b) :
|
|
Func1(b) {
|
|
*this = Poly1::operator=(b);
|
|
}
|
|
|
|
Poly1& operator=(const Poly1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_cpoly = right.m_cpoly;
|
|
m_n = right.m_n;
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Poly1* np = new Poly1(*this);
|
|
return *((Func1*)np);
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
doublereal r = m_cpoly[m_n-1];
|
|
for (size_t n = 1; n < m_n; n++) {
|
|
r *= t;
|
|
r += m_cpoly[m_n - n - 1];
|
|
}
|
|
return r;
|
|
}
|
|
|
|
protected:
|
|
size_t m_n;
|
|
vector_fp m_cpoly;
|
|
};
|
|
|
|
|
|
/**
|
|
* Fourier cosine/sine series.
|
|
*
|
|
* \f[
|
|
* f(t) = \frac{A_0}{2} +
|
|
* \sum_{n=1}^N A_n \cos (n \omega t) + B_n \sin (n \omega t)
|
|
* \f]
|
|
*/
|
|
class Fourier1 : public Func1
|
|
{
|
|
public:
|
|
Fourier1(size_t n, doublereal omega, doublereal a0,
|
|
doublereal* a, doublereal* b) :
|
|
Func1() {
|
|
m_n = n;
|
|
m_omega = omega;
|
|
m_a0_2 = 0.5*a0;
|
|
m_ccos.resize(n);
|
|
m_csin.resize(n);
|
|
std::copy(a, a+n, m_ccos.begin());
|
|
std::copy(b, b+n, m_csin.begin());
|
|
}
|
|
|
|
Fourier1(const Fourier1& b) :
|
|
Func1(b) {
|
|
*this = Fourier1::operator=(b);
|
|
}
|
|
|
|
Fourier1& operator=(const Fourier1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_omega = right.m_omega;
|
|
m_a0_2 = right.m_a0_2;
|
|
m_ccos = right.m_ccos;
|
|
m_csin = right.m_csin;
|
|
m_n = right.m_n;
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Fourier1* np = new Fourier1(*this);
|
|
return *((Func1*)np);
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
size_t n, nn;
|
|
doublereal sum = m_a0_2;
|
|
for (n = 0; n < m_n; n++) {
|
|
nn = n + 1;
|
|
sum += m_ccos[n]*std::cos(m_omega*nn*t)
|
|
+ m_csin[n]*std::sin(m_omega*nn*t);
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
protected:
|
|
size_t m_n;
|
|
doublereal m_omega, m_a0_2;
|
|
vector_fp m_ccos, m_csin;
|
|
};
|
|
|
|
|
|
/**
|
|
* Sum of Arrhenius terms.
|
|
* \f[
|
|
* f(T) = \sum_{n=1}^N A_n T^b_n \exp(-E_n/T)
|
|
* \f]
|
|
*/
|
|
class Arrhenius1 : public Func1
|
|
{
|
|
public:
|
|
Arrhenius1(size_t n, doublereal* c) :
|
|
Func1() {
|
|
m_n = n;
|
|
m_A.resize(n);
|
|
m_b.resize(n);
|
|
m_E.resize(n);
|
|
for (size_t i = 0; i < n; i++) {
|
|
size_t loc = 3*i;
|
|
m_A[i] = c[loc];
|
|
m_b[i] = c[loc+1];
|
|
m_E[i] = c[loc+2];
|
|
}
|
|
}
|
|
|
|
Arrhenius1(const Arrhenius1& b) :
|
|
Func1() {
|
|
*this = Arrhenius1::operator=(b);
|
|
}
|
|
|
|
Arrhenius1& operator=(const Arrhenius1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_n = right.m_n;
|
|
m_A = right.m_A;
|
|
m_b = right.m_b;
|
|
m_E = right.m_E;
|
|
m_parent = 0;
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Arrhenius1* np = new Arrhenius1(*this);
|
|
return *((Func1*)np);
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
doublereal sum = 0.0;
|
|
for (size_t n = 0; n < m_n; n++) {
|
|
sum += m_A[n]*std::pow(t,m_b[n])*std::exp(-m_E[n]/t);
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
protected:
|
|
size_t m_n;
|
|
vector_fp m_A, m_b, m_E;
|
|
};
|
|
|
|
/**
|
|
* Periodic function. Takes any function and makes it
|
|
* periodic with period T.
|
|
*/
|
|
class Periodic1 : public Func1
|
|
{
|
|
public:
|
|
Periodic1(Func1& f, doublereal T) :
|
|
Func1() {
|
|
m_func = &f;
|
|
m_c = T;
|
|
}
|
|
|
|
Periodic1(const Periodic1& b) :
|
|
Func1() {
|
|
*this = Periodic1::operator=(b);
|
|
}
|
|
|
|
Periodic1& operator=(const Periodic1& right) {
|
|
if (&right == this) {
|
|
return *this;
|
|
}
|
|
Func1::operator=(right);
|
|
m_func = &right.m_func->duplicate();
|
|
return *this;
|
|
}
|
|
|
|
virtual Func1& duplicate() const {
|
|
Periodic1* np = new Periodic1(*this);
|
|
return *((Func1*)np);
|
|
}
|
|
|
|
virtual ~Periodic1() {
|
|
delete m_func;
|
|
}
|
|
|
|
virtual doublereal eval(doublereal t) const {
|
|
int np = int(t/m_c);
|
|
doublereal time = t - np*m_c;
|
|
return m_func->eval(time);
|
|
}
|
|
|
|
protected:
|
|
Func1* m_func;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|