1 #ifndef XT_FUNCTION_H
2 #define XT_FUNCTION_H
3 
4 #include <math.h>
5 #include <string>
6 #include <set>
7 #include <cstdlib>
8 #include <iostream>
9 
10 #include "Array.h"
11 #include "ATC_TypeDefs.h"
12 
13 namespace ATC {
14 
15   /**
16    *  @class Function
17    *  @brief Base class for functions of fields, space and time
18    */
19 
20   class Function {
21   public:
22     Function(int nargs, char** args);
~Function(void)23     virtual ~Function(void) {};
24 
25     /** name */
tag()26     const std::string & tag() { return tag_;}
27 
28     /** depdendencies */
args(void)29     virtual inline ARG_NAMES args(void) {ARG_NAMES names; return names;};
30 
31     /** function value */
f(ARGS & args)32     virtual inline double f(ARGS& args) {return 0.0;};
f(ARGS & args,DENS_MAT vals)33     virtual inline void   f(ARGS& args, DENS_MAT vals) {};
34 
35     /** (1st) derivative of function wrt to a field */
dfd(FieldName field,ARGS & args)36     virtual inline double dfd(FieldName field, ARGS& args ) {return 0.0;};
dfd(FieldName field,ARGS & args,DENS_MAT vals)37     virtual inline void   dfd(FieldName field, ARGS& args, DENS_MAT vals ) {};
38 
39     // addl: d2fd2(field1, field2, args), linearization(), grad_args
40 
41   protected:
42     /** tag : name of function */
43     std::string tag_;
44   };
45 
46   /**
47    *  @class Function_Mgr
48    *  @brief Base class that constructs and returns UXT_Function objects based on requests
49    */
50   class Function_Mgr {
51   public:
52     /** Static instance of this class */
53     static Function_Mgr * instance();
54 
55     Function* function(char ** arg, int nargs);
56     Function* copy_function(Function* other);
57    protected:
Function_Mgr()58     Function_Mgr() {};
59     ~Function_Mgr();
60    private:
61     static Function_Mgr * myInstance_;
62     /** set to store all generated objects for later deletion */
63     std::set<Function * > pointerSet_;
64   };
65 
66 
67   /**
68    *  @class LinearFieldFunction
69    *  @brief Class for functions returning values linear a given field
70    */
71 
72   class LinearFieldFunction : public Function {
73   public:
74     LinearFieldFunction(int nargs, char** args);
~LinearFieldFunction(void)75     virtual ~LinearFieldFunction(void) {};
76 
f(double * u,double * x,double t)77     inline double f(double* u, double* x, double t) {return c1_*u[0]-c0_;}
dfd(FieldName field,ARGS & args)78     inline double dfd(FieldName field, ARGS& args) {return c1_;}
79 
80     private :
81       double c0_,c1_;
82   };
83 
84   /**
85    *  @class UXT_Function
86    *  @brief Base class for functions of fields, space and time
87    */
88 
89   class UXT_Function {
90   public:
91     UXT_Function(int nargs, double* args);
~UXT_Function(void)92     virtual ~UXT_Function(void) {};
93 
tag()94     const std::string & tag() { return tag_;}
95 
96     /** function value */
f(double * u,double * x,double t)97     virtual inline double f(double * u, double* x, double t) {return 0.0;};
98     /** derivative of function wrt to field */
dfdu(double * u,double * x,double t)99     virtual inline double dfdu(double * u, double* x, double t) {return 0.0;};
100 
101   protected:
102     /** tag : name of function */
103     std::string tag_;
104   };
105 
106   /**
107    *  @class UXT_Function_Mgr
108    *  @brief Base class that constructs and returns UXT_Function objects based on requests
109    */
110 
111 
112   class UXT_Function_Mgr {
113   public:
114     /** Static instance of this class */
115     static UXT_Function_Mgr * instance();
116 
117     UXT_Function* function(std::string & type, int nargs, double * arg);
118     UXT_Function* function(char ** arg, int nargs);
119     UXT_Function* linear_function(double c0, double c1);
120     UXT_Function* copy_UXT_function(UXT_Function* other);
121    protected:
UXT_Function_Mgr()122     UXT_Function_Mgr() {};
123     ~UXT_Function_Mgr();
124    private:
125     static UXT_Function_Mgr * myInstance_;
126     /** set to store all generated objects for later deletion */
127     std::set<UXT_Function * > pointerSet_;
128   };
129 
130 
131   /**
132    *  @class ScalarLinearFunction
133    *  @brief Class for functions returning values linear in space
134    */
135 
136   class ScalarLinearFunction : public UXT_Function {
137   public:
138     ScalarLinearFunction(int nargs, double* args);
~ScalarLinearFunction(void)139     virtual ~ScalarLinearFunction(void) {};
140 
141     //inline double f(double* u, double* x, double t) {return c1_*(u[0]-c0_);}
142 
f(double * u,double * x,double t)143     inline double f(double* u, double* x, double t) {return c1_*u[0]+c0_;}
dfdu(double * u,double * x,double t)144     inline double dfdu(double* u, double* x, double t) {return c1_;}
145 
146     private :
147       double c0_,c1_;
148   };
149 
150   /**
151    *  @class XT_Function
152    *  @brief Base class for functions based on space and time variables
153    */
154 
155   class XT_Function {
156   public:
157     XT_Function(int nargs, double* args);
~XT_Function(void)158     virtual ~XT_Function(void) {};
159 
tag()160     const std::string & tag() { return tag_;}
161 
162     /** function value */
f(double * x,double t)163     virtual inline double f(double* x, double t) {return 0.0;};
164     /** time derivative of function */
dfdt(double * x,double t)165     virtual inline double dfdt(double* x, double t) {return 0.0;};
166     /** 2nd time derivative of function */
ddfdt(double * x,double t)167     virtual inline double ddfdt(double* x, double t) {return 0.0;};
168     /** 3rd time derivative of function */
dddfdt(double * x,double t)169     virtual inline double dddfdt(double* x, double t) {return 0.0;};
170 
171   protected:
172     /** mask : masks x,y,z dependence, x0 : origin */
173     double mask[3], x0[3];
174     /** tag : name of function */
175     std::string tag_;
176   };
177 
178   /**
179    *  @class XT_Function_Mgr
180    *  @brief Base class that constructs and returns XT_Function objects based on requests
181    */
182 
183   class XT_Function_Mgr {
184   public:
185     /** Static instance of this class */
186     static XT_Function_Mgr * instance();
187 
188     XT_Function* function(std::string & type, int nargs, double * arg);
189     XT_Function* function(char ** arg, int nargs);
190     XT_Function* constant_function(double c);
191     XT_Function* copy_XT_function(XT_Function* other);
192    protected:
XT_Function_Mgr()193     XT_Function_Mgr() {};
194     ~XT_Function_Mgr();
195    private:
196     static XT_Function_Mgr * myInstance_;
197     /** set to store all generated objects for later deletion */
198     std::set<XT_Function * > pointerSet_;
199 
200   };
201 
202   //------------------------------------------------------------------------
203   // derived classes
204   //------------------------------------------------------------------------
205 
206   /**
207    *  @class ConstantFunction
208    *  @brief Class for functions returning constant values
209    */
210 
211   class ConstantFunction : public XT_Function {
212   public:
213     ConstantFunction(int nargs, double* args);
214     ConstantFunction(double arg);
~ConstantFunction(void)215     virtual ~ConstantFunction(void) {};
216 
f(double * x,double t)217     inline double f(double* x, double t)
218     {return C0;};
219 
220     private :
221       double C0;
222   };
223 
224   /**
225    *  @class LinearFunction
226    *  @brief Class for functions returning values linear in space
227    */
228 
229   class LinearFunction : public XT_Function {
230   public:
231     LinearFunction(int nargs, double* args);
~LinearFunction(void)232     virtual ~LinearFunction(void) {};
233 
f(double * x,double t)234     double f(double* x, double t)
235       {return mask[0]*(x[0]-x0[0])+mask[1]*(x[1]-x0[1])+mask[2]*(x[2]-x0[2]) + C0;};
236 
237     private :
238       double C0;
239   };
240   /**
241    *  @class PiecewiseLinearFunction
242    *  @brief Class for functions returning values piecewise linear in space
243    *  along given direction
244    */
245 
246   class PiecewiseLinearFunction : public XT_Function {
247   public:
248     PiecewiseLinearFunction(int nargs, double* args);
~PiecewiseLinearFunction(void)249     virtual ~PiecewiseLinearFunction(void) {};
250 
251     double f(double* x, double t) ;
252 
253     private :
254       Array<double> xi;
255       Array<double> fi;
256   };
257 
258   /**
259    *  @class LinearTemporalRamp
260    *  @brief Class for functions returning values linear in space and time
261    */
262 
263   class LinearTemporalRamp : public XT_Function {
264   public:
265     LinearTemporalRamp(int nargs, double* args);
~LinearTemporalRamp(void)266     ~LinearTemporalRamp(void) {};
267 
268     double f(double* x, double t);
269     double dfdt(double* x, double t);
270 
271     protected :
272       double mask_slope[3];
273       double C0_initial, C0_slope;
274 
275   };
276 
277   /**
278    *  @class QuadraticFunction
279    *  @brief Class for functions returning values quadratic in space
280    */
281 
282   class QuadraticFunction : public XT_Function {
283   public:
284     QuadraticFunction(int nargs, double* args);
~QuadraticFunction(void)285     virtual ~QuadraticFunction(void) {};
286 
f(double * x,double t)287     inline double f(double* x, double t)
288       {return
289        C2[0]*(x[0]-x0[0])*(x[0]-x0[0])+
290        C2[1]*(x[1]-x0[1])*(x[1]-x0[1])+
291        C2[2]*(x[2]-x0[2])*(x[2]-x0[2])+
292        2.0*C2[3]*(x[0]-x0[0])*(x[1]-x0[1]) +
293        2.0*C2[4]*(x[0]-x0[0])*(x[2]-x0[2]) +
294        2.0*C2[5]*(x[1]-x0[1])*(x[2]-x0[2]) +
295        mask[0]*(x[0]-x0[0])+mask[1]*(x[1]-x0[1])+mask[2]*(x[2]-x0[2]) + C0;};
296 
297     private :
298       double C0, C2[6]; // C2 1:xx 2:yy 3:zz 4:xy|yx 5:xz|zx 6:yz|zy
299   };
300 
301   /**
302    *  @class SineFunction
303    *  @brief Class for functions returning values sinusoidally varying in space and time
304    */
305 
306   class SineFunction : public XT_Function {
307   public:
308     SineFunction(int nargs, double* args);
~SineFunction(void)309     virtual ~SineFunction(void){};
310 
f(double * x,double t)311     inline double f(double* x, double t)
312       {return  C*sin( mask[0]*(x[0]-x0[0])
313                      +mask[1]*(x[1]-x0[1])
314                      +mask[2]*(x[2]-x0[2]) - w*t) + C0;};
315 
316     private :
317       double C, C0, w;
318   };
319 
320   /**
321    *  @class GaussianFunction
322    *  @brief Class for functions returning values according to a Gaussian distribution in space
323    */
324 
325   class GaussianFunction : public XT_Function {
326   public:
327     GaussianFunction(int nargs, double* args);
~GaussianFunction(void)328     virtual ~GaussianFunction(void){};
329 
330     // 1/(2 pi \sigma)^(n/2) exp(-1/2 x.x/\sigma^2 ) for n = dimension
f(double * x,double t)331     inline double f(double* x, double t)
332       {return  C*exp(-(mask[0]*(x[0]-x0[0])*(x[0]-x0[0])
333                       +mask[1]*(x[1]-x0[1])*(x[1]-x0[1])
334                       +mask[2]*(x[2]-x0[2])*(x[2]-x0[2]))/tau/tau) + C0;};
335 
336     protected:
337       double tau, C, C0;
338   };
339 
340   /**
341    *  @class GaussianTemporalRamp
342    *  @brief Class for functions returning values according to a Gaussian distribution in space and linearly in time
343    */
344 
345   class GaussianTemporalRamp : public GaussianFunction {
346   public:
347     GaussianTemporalRamp(int nargs, double* args);
~GaussianTemporalRamp(void)348     virtual ~GaussianTemporalRamp(void){};
349 
350     double f(double* x, double t);
351     double dfdt(double* x, double t);
352 
353   protected:
354     double tau_initial, tau_slope;
355     double C_initial, C_slope;
356     double C0_initial, C0_slope;
357   };
358 
359   /**
360    *  @class TemporalRamp
361    *  @brief Class for functions returning values constant in space and varying linearly in time
362    */
363 
364   class TemporalRamp : public XT_Function {
365   public:
366     TemporalRamp(int nargs, double* args);
~TemporalRamp(void)367     virtual ~TemporalRamp(void) {};
368 
f(double * x,double t)369     inline double f(double* x, double t)
370     {return f_initial + slope*t;};
371 
dfdt(double * x,double t)372     inline double dfdt(double* x, double t)
373     {return slope;};
374 
375     private :
376       double f_initial, slope;
377   };
378 
379   /**
380    *  @class RadialPower
381    *  @brief Class for functions returning values based on distance from a fix point raised to a specified power
382    */
383 
384   class RadialPower : public XT_Function {
385   public:
386     RadialPower(int nargs, double* args);
~RadialPower(void)387     virtual ~RadialPower(void) {};
388 
f(double * x,double t)389     inline double f(double* x, double t)
390     {
391       double dx = x[0]-x0[0]; double dy = x[1]-x0[1]; double dz = x[2]-x0[2];
392       double r = mask[0]*dx*dx+mask[1]*dy*dy+mask[2]*dz*dz; r = sqrt(r);
393       return C0*pow(r,n);
394     };
395 
396   private :
397     double C0, n;
398   };
399 
400   /**
401    *  @class InterpolationFunction
402    *  @brief Base class for interpolation functions
403    */
404 
405   class InterpolationFunction {
406   public:
InterpolationFunction(void)407     InterpolationFunction(void) : npts_(0) {};
~InterpolationFunction(void)408     virtual ~InterpolationFunction(void) {};
409 
410     /** populate data */
411     void initialize(int npts,std::fstream &fileId, double coef = 1.);
412 
413     /** function value */
414     double f(const double t) const;
415     /** derivative of function */
416     double dfdt(const double t) const;
417 
418   protected:
419     double coordinate(double x,
420       double & f0, double & fp0, double & f1, double & fp1, double & inv_dx) const;
421     int npts_;
422     Array<double> xs_;
423     Array<double> fs_;
424     Array<double> fps_;
425   };
426 
427 }
428 #endif
429