Cantera  2.0
Func1.h
Go to the documentation of this file.
1 /**
2  * @file Func1.h
3  */
4 
5 // Copyright 2001 California Institute of Technology
6 
7 #ifndef CT_FUNC1_H
8 #define CT_FUNC1_H
9 
10 #include "cantera/base/ct_defs.h"
11 
12 #include <iostream>
13 #include <string>
14 
15 namespace Cantera
16 {
17 
18 const int FourierFuncType = 1;
19 const int PolyFuncType = 2;
20 const int ArrheniusFuncType = 3;
21 const int GaussianFuncType = 4;
22 const int SumFuncType = 20;
23 const int DiffFuncType = 25;
24 const int ProdFuncType = 30;
25 const int RatioFuncType = 40;
26 const int PeriodicFuncType = 50;
27 const int CompositeFuncType = 60;
28 const int TimesConstantFuncType = 70;
29 const int PlusConstantFuncType = 80;
30 const int SinFuncType = 100;
31 const int CosFuncType = 102;
32 const int ExpFuncType = 104;
33 const int PowFuncType = 106;
34 const int ConstFuncType = 110;
35 
36 class Sin1;
37 class Cos1;
38 class Exp1;
39 class Pow1;
40 class TimesConstant1;
41 
42 /**
43  * Base class for 'functor' classes that evaluate a function of
44  * one variable.
45  */
46 class Func1
47 {
48 public:
49  Func1();
50 
51  virtual ~Func1();
52 
53 
54  Func1(const Func1& right);
55 
56  Func1& operator=(const Func1& right);
57 
58  //! Duplicate the current function.
59  /*!
60  * This duplicates the current function, returning a
61  * reference to the new malloced function.
62  */
63  virtual Func1& duplicate() const;
64 
65  virtual int ID() const;
66 
67  //! Calls method eval to evaluate the function
68  doublereal operator()(doublereal t) const;
69 
70  /// Evaluate the function.
71  virtual doublereal eval(doublereal t) const;
72 
73  //! Creates a derivative to the current function
74  /*!
75  * This will malloc a derivative function and
76  * return a reference to the function.
77  */
78  virtual Func1& derivative() const;
79 
80  //! Routine to determine if two functions are the same.
81  /*!
82  * Two functions are the same if they are the same function.
83  * This means that the ID and stored constant is the same.
84  * This means that the m_f1 and m_f2 are identical if they
85  * are non-null.
86  */
87  bool isIdentical(Func1& other) const;
88 
89  virtual doublereal isProportional(TimesConstant1& other);
90  virtual doublereal isProportional(Func1& other);
91 
92  virtual std::string write(std::string arg) const;
93 
94 
95  //! accessor function for the stored constant
96  doublereal c() const;
97 
98  //! Function to set the stored constant
99  void setC(doublereal c);
100 
101  //! accessor function for m_f1
102  Func1& func1() const;
103 
104  //! accessor function for m_f2
105  Func1& func2() const;
106 
107  //! Return the order of the function, if it makes sense
108  virtual int order() const;
109 
110 
111  Func1& func1_dup() const;
112 
113 
114  Func1& func2_dup() const;
115 
116  Func1* parent() const;
117 
118 
119  void setParent(Func1* p);
120 
121 protected:
122  doublereal m_c;
123  Func1* m_f1;
124  Func1* m_f2;
125  Func1* m_parent;
126 };
127 
128 
129 Func1& newSumFunction(Func1& f1, Func1& f2);
130 Func1& newDiffFunction(Func1& f1, Func1& f2);
131 Func1& newProdFunction(Func1& f1, Func1& f2);
132 Func1& newRatioFunction(Func1& f1, Func1& f2);
133 Func1& newCompositeFunction(Func1& f1, Func1& f2);
134 Func1& newTimesConstFunction(Func1& f1, doublereal c);
135 Func1& newPlusConstFunction(Func1& f1, doublereal c);
136 
137 //! implements the sin() function
138 /*!
139  * The argument to sin() is in radians
140  */
141 class Sin1 : public Func1
142 {
143 public:
144 
145  Sin1(doublereal omega = 1.0) :
146  Func1() {
147  m_c = omega;
148  }
149 
150  virtual ~Sin1() {}
151 
152  Sin1(const Sin1& b) :
153  Func1(b) {
154  }
155 
156  Sin1& operator=(const Sin1& right) {
157  if (&right == this) {
158  return *this;
159  }
160  Func1::operator=(right);
161  return *this;
162  }
163 
164  virtual Func1& duplicate() const {
165  Sin1* nfunc = new Sin1(*this);
166  return (Func1&) *nfunc;
167  }
168 
169  virtual std::string write(std::string arg) const;
170 
171  virtual int ID() const {
172  return SinFuncType;
173  }
174 
175  virtual doublereal eval(doublereal t) const {
176  return sin(m_c*t);
177  }
178 
179  virtual Func1& derivative() const;
180 };
181 
182 /// cos
183 class Cos1 : public Func1
184 {
185 public:
186  Cos1(doublereal omega = 1.0) :
187  Func1() {
188  m_c = omega;
189  }
190  virtual ~Cos1() {}
191  Cos1(const Cos1& b) :
192  Func1(b) {
193  }
194 
195  Cos1& operator=(const Cos1& right) {
196  if (&right == this) {
197  return *this;
198  }
199  Func1::operator=(right);
200  return *this;
201  }
202 
203  virtual Func1& duplicate() const {
204  Cos1* nfunc = new Cos1(*this);
205  return (Func1&) *nfunc;
206  }
207  virtual std::string write(std::string arg) const;
208  virtual int ID() const {
209  return CosFuncType;
210  }
211  virtual doublereal eval(doublereal t) const {
212  return cos(m_c * t);
213  }
214  virtual Func1& derivative() const;
215 
216 protected:
217 };
218 
219 /// exp
220 class Exp1 : public Func1
221 {
222 public:
223  Exp1(doublereal A = 1.0) :
224  Func1() {
225  m_c = A;
226  }
227  virtual ~Exp1() {
228  }
229  Exp1(const Exp1& b) :
230  Func1(b) {
231  }
232  Exp1& operator=(const Exp1& right) {
233  if (&right == this) {
234  return *this;
235  }
236  Func1::operator=(right);
237  return *this;
238  }
239  virtual std::string write(std::string arg) const;
240  virtual int ID() const {
241  return ExpFuncType;
242  }
243  virtual Func1& duplicate() const {
244  return *(new Exp1(m_c));
245  }
246  virtual doublereal eval(doublereal t) const {
247  return exp(m_c*t);
248  }
249 
250  virtual Func1& derivative() const;
251 
252 protected:
253 
254 };
255 
256 /// pow
257 class Pow1 : public Func1
258 {
259 public:
260  Pow1(doublereal n) :
261  Func1() {
262  m_c = n;
263  }
264  virtual ~Pow1() {}
265  Pow1(const Pow1& b) :
266  Func1(b) {
267  }
268  Pow1& operator=(const Pow1& right) {
269  if (&right == this) {
270  return *this;
271  }
272  Func1::operator=(right);
273  return *this;
274  }
275  virtual std::string write(std::string arg) const;
276  virtual int ID() const {
277  return PowFuncType;
278  }
279  virtual Func1& duplicate() const {
280  return *(new Pow1(m_c));
281  }
282  virtual doublereal eval(doublereal t) const {
283  return pow(t, m_c);
284  }
285  virtual Func1& derivative() const;
286 
287 protected:
288 
289 };
290 
291 /**
292  * Constant.
293  */
294 class Const1 : public Func1
295 {
296 public:
297  Const1(doublereal A) :
298  Func1() {
299  m_c = A;
300  }
301  virtual ~Const1() {
302  }
303 
304  Const1(const Const1& b) :
305  Func1(b) {
306  }
307 
308  Const1& operator=(const Const1& right) {
309  if (&right == this) {
310  return *this;
311  }
312  Func1::operator=(right);
313  return *this;
314  }
315 
316  virtual std::string write(std::string arg) const;
317  virtual int ID() const {
318  return ConstFuncType;
319  }
320  virtual doublereal eval(doublereal t) const {
321  return m_c;
322  }
323  virtual Func1& duplicate() const {
324  return *(new Const1(m_c));
325  }
326 
327  virtual Func1& derivative() const {
328  Func1* z = new Const1(0.0);
329  return *z;
330  }
331 };
332 
333 
334 
335 /**
336  * Sum of two functions.
337  */
338 class Sum1 : public Func1
339 {
340 public:
341  Sum1(Func1& f1, Func1& f2) :
342  Func1() {
343  m_f1 = &f1;
344  m_f2 = &f2;
345  m_f1->setParent(this);
346  m_f2->setParent(this);
347  }
348 
349  virtual ~Sum1() {
350  delete m_f1;
351  delete m_f2;
352  }
353 
354  Sum1(const Sum1& b) :
355  Func1(b) {
356  *this = Sum1::operator=(b);
357  }
358 
359  Sum1& operator=(const Sum1& right) {
360  if (&right == this) {
361  return *this;
362  }
363  Func1::operator=(right);
364  m_f1 = &(m_f1->duplicate());
365  m_f2 = &(m_f2->duplicate());
366  m_f1->setParent(this);
367  m_f2->setParent(this);
368  m_parent = 0;
369  return *this;
370  }
371 
372  virtual int ID() const {
373  return SumFuncType;
374  }
375 
376  virtual doublereal eval(doublereal t) const {
377  return m_f1->eval(t) + m_f2->eval(t);
378  }
379 
380  virtual Func1& duplicate() const {
381  Func1& f1d = m_f1->duplicate();
382  Func1& f2d = m_f2->duplicate();
383  Func1& dup = newSumFunction(f1d, f2d);
384  return dup;
385  }
386 
387  virtual Func1& derivative() const {
388  Func1& d1 = m_f1->derivative();
389  Func1& d2 = m_f2->derivative();
390  Func1& d = newSumFunction(d1, d2);
391  return d;
392  }
393  virtual int order() const {
394  return 0;
395  }
396 
397  virtual std::string write(std::string arg) const;
398 };
399 
400 
401 /**
402  * Difference of two functions.
403  */
404 class Diff1 : public Func1
405 {
406 public:
407  Diff1(Func1& f1, Func1& f2) {
408  m_f1 = &f1;
409  m_f2 = &f2;
410  m_f1->setParent(this);
411  m_f2->setParent(this);
412  }
413 
414  virtual ~Diff1() {
415  delete m_f1;
416  delete m_f2;
417  }
418 
419  Diff1(const Diff1& b) :
420  Func1(b) {
421  *this = Diff1::operator=(b);
422  }
423 
424  Diff1& operator=(const Diff1& right) {
425  if (&right == this) {
426  return *this;
427  }
428  Func1::operator=(right);
429  m_f1 = &(m_f1->duplicate());
430  m_f2 = &(m_f2->duplicate());
431  m_f1->setParent(this);
432  m_f2->setParent(this);
433  m_parent = 0;
434  return *this;
435  }
436 
437  virtual int ID() const {
438  return DiffFuncType;
439  }
440 
441  virtual doublereal eval(doublereal t) const {
442  return m_f1->eval(t) - m_f2->eval(t);
443  }
444 
445  virtual Func1& duplicate() const {
446  Func1& f1d = m_f1->duplicate();
447  Func1& f2d = m_f2->duplicate();
448  Func1& dup = newDiffFunction(f1d, f2d);
449  return dup;
450  }
451  virtual Func1& derivative() const {
452  Func1& d = newDiffFunction(m_f1->derivative(), m_f2->derivative());
453  return d;
454  }
455  virtual int order() const {
456  return 0;
457  }
458 
459  virtual std::string write(std::string arg) const;
460 
461 };
462 
463 
464 /**
465  * Product of two functions.
466  */
467 class Product1 : public Func1
468 {
469 public:
470  Product1(Func1& f1, Func1& f2) :
471  Func1() {
472  m_f1 = &f1;
473  m_f2 = &f2;
474  m_f1->setParent(this);
475  m_f2->setParent(this);
476  }
477 
478  virtual ~Product1() {
479  delete m_f1;
480  delete m_f2;
481  }
482 
483  Product1(const Product1& b) :
484  Func1(b) {
485  *this = Product1::operator=(b);
486  }
487 
488  Product1& operator=(const Product1& right) {
489  if (&right == this) {
490  return *this;
491  }
492  Func1::operator=(right);
493  m_f1 = &(m_f1->duplicate());
494  m_f2 = &(m_f2->duplicate());
495  m_f1->setParent(this);
496  m_f2->setParent(this);
497  m_parent = 0;
498  return *this;
499  }
500 
501  virtual int ID() const {
502  return ProdFuncType;
503  }
504 
505  virtual Func1& duplicate() const {
506  Func1& f1d = m_f1->duplicate();
507  Func1& f2d = m_f2->duplicate();
508  Func1& dup = newProdFunction(f1d, f2d);
509  return dup;
510  }
511 
512  virtual std::string write(std::string arg) const;
513 
514  virtual doublereal eval(doublereal t) const {
515  return m_f1->eval(t) * m_f2->eval(t);
516  }
517 
518  virtual Func1& derivative() const {
519  Func1& a1 = newProdFunction(m_f1->duplicate(), m_f2->derivative());
520  Func1& a2 = newProdFunction(m_f2->duplicate(), m_f1->derivative());
521  Func1& s = newSumFunction(a1, a2);
522  return s;
523  }
524  virtual int order() const {
525  return 1;
526  }
527 
528 protected:
529 };
530 
531 /**
532  * Product of two functions.
533  */
534 class TimesConstant1 : public Func1
535 {
536 public:
537  TimesConstant1(Func1& f1, doublereal A) :
538  Func1() {
539  m_f1 = &f1;
540  m_c = A;
541  m_f1->setParent(this);
542  }
543 
544  virtual ~TimesConstant1() {
545  delete m_f1;
546  }
547 
548  TimesConstant1(const TimesConstant1& b) :
549  Func1(b) {
550  *this = TimesConstant1::operator=(b);
551  }
552 
553  TimesConstant1& operator=(const TimesConstant1& right) {
554  if (&right == this) {
555  return *this;
556  }
557  Func1::operator=(right);
558  m_f1 = &(m_f1->duplicate());
559  m_f1->setParent(this);
560  m_parent = 0;
561  return *this;
562  }
563  virtual int ID() const {
564  return TimesConstantFuncType;
565  }
566 
567  virtual Func1& duplicate() const {
568  Func1& f1 = m_f1->duplicate();
569  Func1* dup = new TimesConstant1(f1, m_c);
570  return *dup;
571  }
572 
573  virtual doublereal isProportional(TimesConstant1& other) {
574  if (func1().isIdentical(other.func1())) {
575  return (other.c()/c());
576  } else {
577  return 0.0;
578  }
579  }
580 
581  virtual doublereal isProportional(Func1& other) {
582  if (func1().isIdentical(other)) {
583  return 1.0/c();
584  } else {
585  return 0.0;
586  }
587  }
588 
589  virtual doublereal eval(doublereal t) const {
590  return m_f1->eval(t) * m_c;
591  }
592 
593  virtual Func1& derivative() const {
594  Func1& f1d = m_f1->derivative();
595  Func1* d = &newTimesConstFunction(f1d, m_c);
596  return *d;
597  }
598 
599  virtual std::string write(std::string arg) const;
600 
601  virtual int order() const {
602  return 0;
603  }
604 protected:
605 };
606 
607 /**
608  * A function plus a constant.
609  */
610 class PlusConstant1 : public Func1
611 {
612 public:
613  PlusConstant1(Func1& f1, doublereal A) :
614  Func1() {
615  m_f1 = &f1;
616  m_c = A;
617  m_f1->setParent(this);
618  }
619 
620  virtual ~PlusConstant1() {
621  delete m_f1;
622  }
623 
624  PlusConstant1(const PlusConstant1& b) :
625  Func1(b) {
626  *this = PlusConstant1::operator=(b);
627  }
628 
629  PlusConstant1& operator=(const PlusConstant1& right) {
630  if (&right == this) {
631  return *this;
632  }
633  Func1::operator=(right);
634  m_f1 = &(m_f1->duplicate());
635  m_f1->setParent(this);
636  m_parent = 0;
637  return *this;
638  }
639 
640  virtual int ID() const {
641  return PlusConstantFuncType;
642  }
643 
644  virtual Func1& duplicate() const {
645  Func1& f1 = m_f1->duplicate();
646  Func1* dup = new PlusConstant1(f1, m_c);
647  return *dup;
648  }
649 
650  virtual doublereal eval(doublereal t) const {
651  return m_f1->eval(t) + m_c;
652  }
653  virtual Func1& derivative() const {
654  Func1& f1d = m_f1->derivative();
655  return f1d;
656  }
657  virtual std::string write(std::string arg) const;
658 
659  virtual int order() const {
660  return 0;
661  }
662 
663 protected:
664 };
665 
666 
667 /**
668  * Ratio of two functions.
669  */
670 class Ratio1 : public Func1
671 {
672 public:
673  Ratio1(Func1& f1, Func1& f2) :
674  Func1() {
675  m_f1 = &f1;
676  m_f2 = &f2;
677  m_f1->setParent(this);
678  m_f2->setParent(this);
679  }
680 
681  virtual ~Ratio1() {
682  delete m_f1;
683  delete m_f2;
684  }
685 
686  Ratio1(const Ratio1& b) :
687  Func1(b) {
688  *this = Ratio1::operator=(b);
689  }
690 
691  Ratio1& operator=(const Ratio1& right) {
692  if (&right == this) {
693  return *this;
694  }
695  Func1::operator=(right);
696  m_f1 = &(m_f1->duplicate());
697  m_f2 = &(m_f2->duplicate());
698  m_f1->setParent(this);
699  m_f2->setParent(this);
700  m_parent = 0;
701  return *this;
702  }
703 
704  virtual int ID() const {
705  return RatioFuncType;
706  }
707 
708  virtual doublereal eval(doublereal t) const {
709  return m_f1->eval(t) / m_f2->eval(t);
710  }
711 
712  virtual Func1& duplicate() const {
713  Func1& f1d = m_f1->duplicate();
714  Func1& f2d = m_f2->duplicate();
715  Func1& dup = newRatioFunction(f1d, f2d);
716  return dup;
717  }
718 
719  virtual Func1& derivative() const {
720  Func1& a1 = newProdFunction(m_f1->derivative(), m_f2->duplicate());
721  Func1& a2 = newProdFunction(m_f1->duplicate(), m_f2->derivative());
722  Func1& s = newDiffFunction(a1, a2);
723  Func1& p = newProdFunction(m_f2->duplicate(), m_f2->duplicate());
724  Func1& r = newRatioFunction(s, p);
725  return r;
726  }
727 
728  virtual std::string write(std::string arg) const;
729 
730  virtual int order() const {
731  return 1;
732  }
733 
734 protected:
735 };
736 
737 /**
738  * Composite function.
739  */
740 class Composite1 : public Func1
741 {
742 public:
743  Composite1(Func1& f1, Func1& f2) :
744  Func1() {
745  m_f1 = &f1;
746  m_f2 = &f2;
747  m_f1->setParent(this);
748  m_f2->setParent(this);
749  }
750 
751  virtual ~Composite1() {
752  delete m_f1;
753  delete m_f2;
754  }
755 
756  Composite1(const Composite1& b) :
757  Func1(b) {
758  *this = Composite1::operator=(b);
759  }
760 
761  Composite1& operator=(const Composite1& right) {
762  if (&right == this) {
763  return *this;
764  }
765  Func1::operator=(right);
766  m_f1 = &(m_f1->duplicate());
767  m_f2 = &(m_f2->duplicate());
768  m_f1->setParent(this);
769  m_f2->setParent(this);
770  m_parent = 0;
771  return *this;
772  }
773 
774  virtual int ID() const {
775  return CompositeFuncType;
776  }
777 
778  virtual doublereal eval(doublereal t) const {
779  return m_f1->eval(m_f2->eval(t));
780  }
781 
782  virtual Func1& duplicate() const {
783  Func1& f1d = m_f1->duplicate();
784  Func1& f2d = m_f2->duplicate();
785  Func1& dup = newCompositeFunction(f1d, f2d);
786  return dup;
787  }
788 
789  virtual Func1& derivative() const {
790  Func1* d1 = &m_f1->derivative();
791 
792  Func1* d3 = &newCompositeFunction(*d1, m_f2->duplicate());
793  Func1* d2 = &m_f2->derivative();
794  Func1* p = &newProdFunction(*d3, *d2);
795  return *p;
796  }
797 
798  virtual std::string write(std::string arg) const;
799 
800  virtual int order() const {
801  return 2;
802  }
803 
804 protected:
805 };
806 
807 //
808 // The functors below are the old-style ones. They still work,
809 // but can't do derivatives.
810 //
811 
812 /**
813  * A Gaussian.
814  * \f[
815  * f(t) = A e^{-[(t - t_0)/\tau]^2}
816  * \f]
817  * where \f[ \tau = \frac{fwhm}{2\sqrt{\ln 2}} \f]
818  * @param A peak value
819  * @param t0 offset
820  * @param fwhm full width at half max
821  */
822 class Gaussian : public Func1
823 {
824 public:
825  Gaussian(double A, double t0, double fwhm) :
826  Func1() {
827  m_A = A;
828  m_t0 = t0;
829  m_tau = fwhm/(2.0*std::sqrt(std::log(2.0)));
830  }
831 
832  virtual ~Gaussian() {}
833 
834  Gaussian(const Gaussian& b) :
835  Func1(b) {
836  *this = Gaussian::operator=(b);
837  }
838 
839  Gaussian& operator=(const Gaussian& right) {
840  if (&right == this) {
841  return *this;
842  }
843  Func1::operator=(right);
844  m_A = right.m_A;
845  m_t0 = right.m_t0;
846  m_tau = right.m_tau;
847  m_parent = 0;
848  return *this;
849  }
850 
851  virtual Func1& duplicate() const {
852  Gaussian* np = new Gaussian(*this);
853  return *((Func1*)np);
854  }
855 
856  virtual doublereal eval(doublereal t) const {
857  doublereal x = (t - m_t0)/m_tau;
858  return m_A * std::exp(-x*x);
859  }
860 
861 protected:
862  doublereal m_A, m_t0, m_tau;
863 private:
864 };
865 
866 
867 /**
868  * Polynomial of degree n.
869  */
870 class Poly1 : public Func1
871 {
872 public:
873  Poly1(size_t n, doublereal* c) :
874  Func1() {
875  m_n = n+1;
876  m_cpoly.resize(n+1);
877  std::copy(c, c+m_n, m_cpoly.begin());
878  }
879 
880  virtual ~Poly1() {
881  }
882 
883  Poly1(const Poly1& b) :
884  Func1(b) {
885  *this = Poly1::operator=(b);
886  }
887 
888  Poly1& operator=(const Poly1& right) {
889  if (&right == this) {
890  return *this;
891  }
892  Func1::operator=(right);
893  m_cpoly = right.m_cpoly;
894  m_n = right.m_n;
895  m_parent = 0;
896  return *this;
897  }
898 
899 
900  virtual Func1& duplicate() const {
901  Poly1* np = new Poly1(*this);
902  return *((Func1*)np);
903  }
904 
905  virtual doublereal eval(doublereal t) const {
906  doublereal r = m_cpoly[m_n-1];
907  for (size_t n = 1; n < m_n; n++) {
908  r *= t;
909  r += m_cpoly[m_n - n - 1];
910  }
911  return r;
912  }
913 
914 protected:
915  size_t m_n;
916  vector_fp m_cpoly;
917 };
918 
919 
920 /**
921  * Fourier cosine/sine series.
922  *
923  * \f[
924  * f(t) = \frac{A_0}{2} +
925  * \sum_{n=1}^N A_n \cos (n \omega t) + B_n \sin (n \omega t)
926  * \f]
927  */
928 class Fourier1 : public Func1
929 {
930 public:
931  Fourier1(size_t n, doublereal omega, doublereal a0,
932  doublereal* a, doublereal* b) :
933  Func1() {
934  m_n = n;
935  m_omega = omega;
936  m_a0_2 = 0.5*a0;
937  m_ccos.resize(n);
938  m_csin.resize(n);
939  std::copy(a, a+n, m_ccos.begin());
940  std::copy(b, b+n, m_csin.begin());
941  }
942 
943  virtual ~Fourier1() {}
944 
945  Fourier1(const Fourier1& b) :
946  Func1(b) {
947  *this = Fourier1::operator=(b);
948  }
949 
950  Fourier1& operator=(const Fourier1& right) {
951  if (&right == this) {
952  return *this;
953  }
954  Func1::operator=(right);
955  m_omega = right.m_omega;
956  m_a0_2 = right.m_a0_2;
957  m_ccos = right.m_ccos;
958  m_csin = right.m_csin;
959  m_n = right.m_n;
960  m_parent = 0;
961  return *this;
962  }
963 
964  virtual Func1& duplicate() const {
965  Fourier1* np = new Fourier1(*this);
966  return *((Func1*)np);
967  }
968 
969  virtual doublereal eval(doublereal t) const {
970  size_t n, nn;
971  doublereal sum = m_a0_2;
972  for (n = 0; n < m_n; n++) {
973  nn = n + 1;
974  sum += m_ccos[n]*std::cos(m_omega*nn*t)
975  + m_csin[n]*std::sin(m_omega*nn*t);
976  }
977  return sum;
978  }
979 
980 protected:
981  size_t m_n;
982  doublereal m_omega, m_a0_2;
983  vector_fp m_ccos, m_csin;
984 };
985 
986 
987 /**
988  * Sum of Arrhenius terms.
989  * \f[
990  * f(T) = \sum_{n=1}^N A_n T^b_n \exp(-E_n/T)
991  * \f]
992  */
993 class Arrhenius1 : public Func1
994 {
995 public:
996  Arrhenius1(size_t n, doublereal* c) :
997  Func1() {
998  m_n = n;
999  m_A.resize(n);
1000  m_b.resize(n);
1001  m_E.resize(n);
1002  for (size_t i = 0; i < n; i++) {
1003  size_t loc = 3*i;
1004  m_A[i] = c[loc];
1005  m_b[i] = c[loc+1];
1006  m_E[i] = c[loc+2];
1007  }
1008  }
1009  virtual ~Arrhenius1() {
1010  }
1011 
1012 
1013  Arrhenius1(const Arrhenius1& b) :
1014  Func1() {
1015  *this = Arrhenius1::operator=(b);
1016  }
1017 
1018  Arrhenius1& operator=(const Arrhenius1& right) {
1019  if (&right == this) {
1020  return *this;
1021  }
1022  Func1::operator=(right);
1023  m_n = right.m_n;
1024  m_A = right.m_A;
1025  m_b = right.m_b;
1026  m_E = right.m_E;
1027  m_parent = 0;
1028  return *this;
1029  }
1030 
1031  virtual Func1& duplicate() const {
1032  Arrhenius1* np = new Arrhenius1(*this);
1033  return *((Func1*)np);
1034  }
1035 
1036  virtual doublereal eval(doublereal t) const {
1037  doublereal sum = 0.0;
1038  for (size_t n = 0; n < m_n; n++) {
1039  sum += m_A[n]*std::pow(t,m_b[n])*std::exp(-m_E[n]/t);
1040  }
1041  return sum;
1042  }
1043 
1044 protected:
1045  size_t m_n;
1046  vector_fp m_A, m_b, m_E;
1047 };
1048 
1049 /**
1050  * Periodic function. Takes any function and makes it
1051  * periodic with period T.
1052  */
1053 class Periodic1 : public Func1
1054 {
1055 public:
1056  Periodic1(Func1& f, doublereal T) :
1057  Func1() {
1058  m_func = &f;
1059  m_c = T;
1060  }
1061 
1062  Periodic1(const Periodic1& b) :
1063  Func1() {
1064  *this = Periodic1::operator=(b);
1065  }
1066 
1067  Periodic1& operator=(const Periodic1& right) {
1068  if (&right == this) {
1069  return *this;
1070  }
1071  Func1::operator=(right);
1072  m_func = &(right.m_func->duplicate());
1073  return *this;
1074  }
1075 
1076  virtual Func1& duplicate() const {
1077  Periodic1* np = new Periodic1(*this);
1078  return *((Func1*)np);
1079  }
1080 
1081  virtual ~Periodic1() {
1082  delete m_func;
1083  }
1084 
1085  virtual doublereal eval(doublereal t) const {
1086  int np = int(t/m_c);
1087  doublereal time = t - np*m_c;
1088  return m_func->eval(time);
1089  }
1090 
1091 protected:
1092  Func1* m_func;
1093 
1094 private:
1095 };
1096 
1097 }
1098 
1099 
1100 #endif