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