#ifndef XT_FUNCTION_H #define XT_FUNCTION_H #include #include #include #include #include #include "Array.h" #include "ATC_TypeDefs.h" namespace ATC { /** * @class Function * @brief Base class for functions of fields, space and time */ class Function { public: Function(int nargs, char** args); virtual ~Function(void) {}; /** name */ const std::string & tag() { return tag_;} /** depdendencies */ virtual inline ARG_NAMES args(void) {ARG_NAMES names; return names;}; /** (1st) derivative of function wrt to a field */ virtual inline double dfd(FieldName /* field */, ARGS& /* args */) {return 0.0;}; virtual inline void dfd(FieldName /* field */, ARGS& /* args */, DENS_MAT /* vals */ ) {}; // addl: d2fd2(field1, field2, args), linearization(), grad_args protected: /** tag : name of function */ std::string tag_; }; /** * @class Function_Mgr * @brief Base class that constructs and returns UXT_Function objects based on requests */ class Function_Mgr { public: /** Static instance of this class */ static Function_Mgr * instance(); Function* function(char ** arg, int nargs); Function* copy_function(Function* other); protected: Function_Mgr() {}; ~Function_Mgr(); private: static Function_Mgr * myInstance_; /** set to store all generated objects for later deletion */ std::set pointerSet_; }; /** * @class LinearFieldFunction * @brief Class for functions returning values linear a given field */ class LinearFieldFunction : public Function { public: LinearFieldFunction(int nargs, char** args); virtual ~LinearFieldFunction(void) {}; inline double f(double* u, double* /* x */, double /* t */) {return c1_*u[0]-c0_;} inline double dfd(FieldName /* field */, ARGS& /* args */) {return c1_;} private : double c0_,c1_; }; /** * @class UXT_Function * @brief Base class for functions of fields, space and time */ class UXT_Function { public: UXT_Function(int nargs, double* args); virtual ~UXT_Function(void) {}; const std::string & tag() { return tag_;} /** function value */ virtual inline double f(double * /* u */, double* /* x */, double /* t */) {return 0.0;}; /** derivative of function wrt to field */ virtual inline double dfdu(double * /* u */, double* /* x */, double /* t */) {return 0.0;}; protected: /** tag : name of function */ std::string tag_; }; /** * @class UXT_Function_Mgr * @brief Base class that constructs and returns UXT_Function objects based on requests */ class UXT_Function_Mgr { public: /** Static instance of this class */ static UXT_Function_Mgr * instance(); UXT_Function* function(std::string & type, int nargs, double * arg); UXT_Function* function(char ** arg, int nargs); UXT_Function* linear_function(double c0, double c1); UXT_Function* copy_UXT_function(UXT_Function* other); protected: UXT_Function_Mgr() {}; ~UXT_Function_Mgr(); private: static UXT_Function_Mgr * myInstance_; /** set to store all generated objects for later deletion */ std::set pointerSet_; }; /** * @class ScalarLinearFunction * @brief Class for functions returning values linear in space */ class ScalarLinearFunction : public UXT_Function { public: ScalarLinearFunction(int nargs, double* args); virtual ~ScalarLinearFunction(void) {}; //inline double f(double* u, double* x, double t) {return c1_*(u[0]-c0_);} inline double f(double* u, double* /* x */, double /* t */) {return c1_*u[0]+c0_;} inline double dfdu(double* /* u */, double* /* x */, double /* t */) {return c1_;} private : double c0_,c1_; }; /** * @class XT_Function * @brief Base class for functions based on space and time variables */ class XT_Function { public: XT_Function(int nargs, double* args); virtual ~XT_Function(void) {}; const std::string & tag() { return tag_;} /** function value */ virtual inline double f(double* /* x */, double /* t */) {return 0.0;}; /** time derivative of function */ virtual inline double dfdt(double* /* x */, double /* t */) {return 0.0;}; /** 2nd time derivative of function */ virtual inline double ddfdt(double* /* x */, double /* t */) {return 0.0;}; /** 3rd time derivative of function */ virtual inline double dddfdt(double* /* x */, double /* t */) {return 0.0;}; protected: /** mask : masks x,y,z dependence, x0 : origin */ double mask[3], x0[3]; /** tag : name of function */ std::string tag_; }; /** * @class XT_Function_Mgr * @brief Base class that constructs and returns XT_Function objects based on requests */ class XT_Function_Mgr { public: /** Static instance of this class */ static XT_Function_Mgr * instance(); XT_Function* function(std::string & type, int nargs, double * arg); XT_Function* function(char ** arg, int nargs); XT_Function* constant_function(double c); XT_Function* copy_XT_function(XT_Function* other); protected: XT_Function_Mgr() {}; ~XT_Function_Mgr(); private: static XT_Function_Mgr * myInstance_; /** set to store all generated objects for later deletion */ std::set pointerSet_; }; //------------------------------------------------------------------------ // derived classes //------------------------------------------------------------------------ /** * @class ConstantFunction * @brief Class for functions returning constant values */ class ConstantFunction : public XT_Function { public: ConstantFunction(int nargs, double* args); ConstantFunction(double arg); virtual ~ConstantFunction(void) {}; inline double f(double* /* x */, double /* t */) {return C0;}; private : double C0; }; /** * @class LinearFunction * @brief Class for functions returning values linear in space */ class LinearFunction : public XT_Function { public: LinearFunction(int nargs, double* args); virtual ~LinearFunction(void) {}; double f(double* x, double /* t */) {return mask[0]*(x[0]-x0[0])+mask[1]*(x[1]-x0[1])+mask[2]*(x[2]-x0[2]) + C0;}; private : double C0; }; /** * @class PiecewiseLinearFunction * @brief Class for functions returning values piecewise linear in space * along given direction */ class PiecewiseLinearFunction : public XT_Function { public: PiecewiseLinearFunction(int nargs, double* args); virtual ~PiecewiseLinearFunction(void) {}; double f(double* x, double t) ; private : Array xi; Array fi; }; /** * @class LinearTemporalRamp * @brief Class for functions returning values linear in space and time */ class LinearTemporalRamp : public XT_Function { public: LinearTemporalRamp(int nargs, double* args); ~LinearTemporalRamp(void) {}; double f(double* x, double t); double dfdt(double* x, double t); protected : double mask_slope[3]; double C0_initial, C0_slope; }; /** * @class QuadraticFunction * @brief Class for functions returning values quadratic in space */ class QuadraticFunction : public XT_Function { public: QuadraticFunction(int nargs, double* args); virtual ~QuadraticFunction(void) {}; inline double f(double* x, double /* t */) {return C2[0]*(x[0]-x0[0])*(x[0]-x0[0])+ C2[1]*(x[1]-x0[1])*(x[1]-x0[1])+ C2[2]*(x[2]-x0[2])*(x[2]-x0[2])+ 2.0*C2[3]*(x[0]-x0[0])*(x[1]-x0[1]) + 2.0*C2[4]*(x[0]-x0[0])*(x[2]-x0[2]) + 2.0*C2[5]*(x[1]-x0[1])*(x[2]-x0[2]) + mask[0]*(x[0]-x0[0])+mask[1]*(x[1]-x0[1])+mask[2]*(x[2]-x0[2]) + C0;}; private : double C0, C2[6]; // C2 1:xx 2:yy 3:zz 4:xy|yx 5:xz|zx 6:yz|zy }; /** * @class SineFunction * @brief Class for functions returning values sinusoidally varying in space and time */ class SineFunction : public XT_Function { public: SineFunction(int nargs, double* args); virtual ~SineFunction(void){}; inline double f(double* x, double t) {return C*sin( mask[0]*(x[0]-x0[0]) +mask[1]*(x[1]-x0[1]) +mask[2]*(x[2]-x0[2]) - w*t) + C0;}; private : double C, C0, w; }; /** * @class GaussianFunction * @brief Class for functions returning values according to a Gaussian distribution in space */ class GaussianFunction : public XT_Function { public: GaussianFunction(int nargs, double* args); virtual ~GaussianFunction(void){}; // 1/(2 pi \sigma)^(n/2) exp(-1/2 x.x/\sigma^2 ) for n = dimension inline double f(double* x, double /* t */) {return C*exp(-(mask[0]*(x[0]-x0[0])*(x[0]-x0[0]) +mask[1]*(x[1]-x0[1])*(x[1]-x0[1]) +mask[2]*(x[2]-x0[2])*(x[2]-x0[2]))/tau/tau) + C0;}; protected: double tau, C, C0; }; /** * @class GaussianTemporalRamp * @brief Class for functions returning values according to a Gaussian distribution in space and linearly in time */ class GaussianTemporalRamp : public GaussianFunction { public: GaussianTemporalRamp(int nargs, double* args); virtual ~GaussianTemporalRamp(void){}; double f(double* x, double t); double dfdt(double* x, double t); protected: double tau_initial, tau_slope; double C_initial, C_slope; double C0_initial, C0_slope; }; /** * @class TemporalRamp * @brief Class for functions returning values constant in space and varying linearly in time */ class TemporalRamp : public XT_Function { public: TemporalRamp(int nargs, double* args); virtual ~TemporalRamp(void) {}; inline double f(double* /* x */, double t) {return f_initial + slope*t;}; inline double dfdt(double* /* x */, double /* t */) {return slope;}; private : double f_initial, slope; }; /** * @class RadialPower * @brief Class for functions returning values based on distance from a fix point raised to a specified power */ class RadialPower : public XT_Function { public: RadialPower(int nargs, double* args); virtual ~RadialPower(void) {}; inline double f(double* x, double /* t */) { double dx = x[0]-x0[0]; double dy = x[1]-x0[1]; double dz = x[2]-x0[2]; double r = mask[0]*dx*dx+mask[1]*dy*dy+mask[2]*dz*dz; r = sqrt(r); return C0*pow(r,n); }; private : double C0, n; }; /** * @class InterpolationFunction * @brief Base class for interpolation functions */ class InterpolationFunction { public: InterpolationFunction(void) : npts_(0) {}; virtual ~InterpolationFunction(void) {}; /** populate data */ void initialize(int npts,std::fstream &fileId, double coef = 1.); /** function value */ double f(const double t) const; /** derivative of function */ double dfdt(const double t) const; protected: double coordinate(double x, double & f0, double & fp0, double & f1, double & fp1, double & inv_dx) const; int npts_; Array xs_; Array fs_; Array fps_; }; } #endif