Cantera  2.3.0
Func1.cpp
Go to the documentation of this file.
1 //! @file Func1.cpp
2 
3 // This file is part of Cantera. See License.txt in the top-level directory or
4 // at http://www.cantera.org/license.txt for license and copyright information.
5 
8 
9 using namespace std;
10 
11 namespace Cantera
12 {
13 
14 Func1::Func1() :
15  m_c(0.0),
16  m_f1(0),
17  m_f2(0),
18  m_parent(0)
19 {
20 }
21 
22 Func1::Func1(const Func1& right) :
23  m_c(right.m_c),
24  m_f1(right.m_f1),
25  m_f2(right.m_f2),
26  m_parent(right.m_parent)
27 {
28 }
29 
30 Func1& Func1::operator=(const Func1& right)
31 {
32  if (&right == this) {
33  return *this;
34  }
35  m_c = right.m_c;
36  m_f1 = right.m_f1;
37  m_f2 = right.m_f2;
38  m_parent = right.m_parent;
39  return *this;
40 }
41 
43 {
44  Func1* nfunc = new Func1(*this);
45  return *nfunc;
46 }
47 
48 int Func1::ID() const
49 {
50  return 0;
51 }
52 
53 // Calls method eval to evaluate the function
54 doublereal Func1::operator()(doublereal t) const
55 {
56  return eval(t);
57 }
58 
59 // Evaluate the function.
60 doublereal Func1::eval(doublereal t) const
61 {
62  return 0.0;
63 }
64 
66 {
67  cout << "derivative error... ERR: ID = " << ID() << endl;
68  cout << write("x") << endl;
69  return *(new Func1);
70 }
71 
72 bool Func1::isIdentical(Func1& other) const
73 {
74  if (ID() != other.ID() || m_c != other.m_c) {
75  return false;
76  }
77  if (m_f1) {
78  if (!other.m_f1) {
79  return false;
80  }
81  if (!m_f1->isIdentical(*other.m_f1)) {
82  return false;
83  }
84  }
85  if (m_f2) {
86  if (!other.m_f2) {
87  return false;
88  }
89  if (!m_f2->isIdentical(*other.m_f2)) {
90  return false;
91  }
92  }
93  return true;
94 }
95 
96 //! accessor function for the returned constant
97 doublereal Func1::c() const
98 {
99  return m_c;
100 }
101 
102 // Function to set the stored constant
103 void Func1::setC(doublereal c)
104 {
105  m_c = c;
106 }
107 
108 //! accessor function for m_f1
110 {
111  return *m_f1;
112 }
113 
115 {
116  return *m_f2;
117 }
118 
119 int Func1::order() const
120 {
121  return 3;
122 }
123 
124 Func1& Func1::func1_dup() const
125 {
126  return m_f1->duplicate();
127 }
128 
129 Func1& Func1::func2_dup() const
130 {
131  return m_f2->duplicate();
132 }
133 
134 Func1* Func1::parent() const
135 {
136  return m_parent;
137 }
138 
139 void Func1::setParent(Func1* p)
140 {
141  m_parent = p;
142 }
143 
144 /*****************************************************************************/
145 
146 string Sin1::write(const string& arg) const
147 {
148  if (m_c == 1.0) {
149  return fmt::format("\\sin({})", arg);
150  } else {
151  return fmt::format("\\sin({}{})", m_c, arg);
152  }
153 }
154 
156 {
157  Func1* c = new Cos1(m_c);
158  Func1* r = &newTimesConstFunction(*c, m_c);
159  return *r;
160 }
161 /*****************************************************************************/
162 
164 {
165  Func1* s = new Sin1(m_c);
166  Func1* r = &newTimesConstFunction(*s, -m_c);
167  return *r;
168 }
169 
170 std::string Cos1::write(const std::string& arg) const
171 {
172  if (m_c == 1.0) {
173  return fmt::format("\\cos({})", arg);
174  } else {
175  return fmt::format("\\cos({}{})", m_c, arg);
176  }
177 }
178 
179 /**************************************************************************/
180 
182 {
183  Func1* f = new Exp1(m_c);
184  if (m_c != 1.0) {
185  return newTimesConstFunction(*f, m_c);
186  } else {
187  return *f;
188  }
189 }
190 
191 std::string Exp1::write(const std::string& arg) const
192 {
193  if (m_c == 1.0) {
194  return fmt::format("\\exp({})", arg);
195  } else {
196  return fmt::format("\\exp({}{})", m_c, arg);
197  }
198 }
199 
200 /******************************************************************************/
201 
203 {
204  Func1* r;
205  if (m_c == 0.0) {
206  r = new Const1(0.0);
207  } else if (m_c == 1.0) {
208  r = new Const1(1.0);
209  } else {
210  Func1* f = new Pow1(m_c - 1.0);
211  r = &newTimesConstFunction(*f, m_c);
212  }
213  return *r;
214 }
215 
216 string Func1::write(const std::string& arg) const
217 {
218  return fmt::format("<unknown {}>({})", ID(), arg);
219 }
220 
221 string Pow1::write(const std::string& arg) const
222 {
223  if (m_c == 0.5) {
224  return "\\sqrt{" + arg + "}";
225  }
226  if (m_c == -0.5) {
227  return "\\frac{1}{\\sqrt{" + arg + "}}";
228  }
229  if (m_c != 1.0) {
230  return fmt::format("\\left({}\\right)^{{{}}}", arg, m_c);
231  } else {
232  return arg;
233  }
234 }
235 
236 string Const1::write(const std::string& arg) const
237 {
238  return fmt::format("{}", m_c);
239 }
240 
241 string Ratio1::write(const std::string& arg) const
242 {
243  return "\\frac{" + m_f1->write(arg) + "}{"
244  + m_f2->write(arg) + "}";
245 }
246 
247 string Product1::write(const std::string& arg) const
248 {
249  string s = m_f1->write(arg);
250  if (m_f1->order() < order()) {
251  s = "\\left(" + s + "\\right)";
252  }
253  string s2 = m_f2->write(arg);
254  if (m_f2->order() < order()) {
255  s2 = "\\left(" + s2 + "\\right)";
256  }
257  return s + " " + s2;
258 }
259 
260 string Sum1::write(const std::string& arg) const
261 {
262  string s1 = m_f1->write(arg);
263  string s2 = m_f2->write(arg);
264  if (s2[0] == '-') {
265  return s1 + " - " + s2.substr(1,s2.size());
266  } else {
267  return s1 + " + " + s2;
268  }
269 }
270 
271 string Diff1::write(const std::string& arg) const
272 {
273  string s1 = m_f1->write(arg);
274  string s2 = m_f2->write(arg);
275  if (s2[0] == '-') {
276  return s1 + " + " + s2.substr(1,s2.size());
277  } else {
278  return s1 + " - " + s2;
279  }
280 }
281 
282 string Composite1::write(const std::string& arg) const
283 {
284  string g = m_f2->write(arg);
285  return m_f1->write(g);
286 }
287 
288 string TimesConstant1::write(const std::string& arg) const
289 {
290  string s = m_f1->write(arg);
291  if (m_f1->order() < order()) {
292  s = "\\left(" + s + "\\right)";
293  }
294  if (m_c == 1.0) {
295  return s;
296  }
297  if (m_c == -1.0) {
298  return "-"+s;
299  }
300  char n = s[0];
301  if (n >= '0' && n <= '9') {
302  s = "\\left(" + s + "\\right)";
303  }
304  return fmt::format("{}{}", m_c, s);
305 }
306 
307 string PlusConstant1::write(const std::string& arg) const
308 {
309  if (m_c == 0.0) {
310  return m_f1->write(arg);
311  }
312  return fmt::format("{} + {}", m_f1->write(arg), m_c);
313 }
314 
315 doublereal Func1::isProportional(TimesConstant1& other)
316 {
317  if (isIdentical(other.func1())) {
318  return other.c();
319  }
320  return 0.0;
321 }
322 doublereal Func1::isProportional(Func1& other)
323 {
324  if (isIdentical(other)) {
325  return 1.0;
326  } else {
327  return 0.0;
328  }
329 }
330 
331 static bool isConstant(Func1& f)
332 {
333  if (f.ID() == ConstFuncType) {
334  return true;
335  } else {
336  return false;
337  }
338 }
339 
340 static bool isZero(Func1& f)
341 {
342  if (f.ID() == ConstFuncType && f.c() == 0.0) {
343  return true;
344  } else {
345  return false;
346  }
347 }
348 
349 static bool isOne(Func1& f)
350 {
351  if (f.ID() == ConstFuncType && f.c() == 1.0) {
352  return true;
353  } else {
354  return false;
355  }
356 }
357 
358 static bool isTimesConst(Func1& f)
359 {
360  if (f.ID() == TimesConstantFuncType) {
361  return true;
362  } else {
363  return false;
364  }
365 }
366 
367 static bool isExp(Func1& f)
368 {
369  if (f.ID() == ExpFuncType) {
370  return true;
371  } else {
372  return false;
373  }
374 }
375 
376 static bool isPow(Func1& f)
377 {
378  if (f.ID() == PowFuncType) {
379  return true;
380  } else {
381  return false;
382  }
383 }
384 
385 Func1& newSumFunction(Func1& f1, Func1& f2)
386 {
387  if (f1.isIdentical(f2)) {
388  return newTimesConstFunction(f1, 2.0);
389  }
390  if (isZero(f1)) {
391  delete &f1;
392  return f2;
393  }
394  if (isZero(f2)) {
395  delete &f2;
396  return f1;
397  }
398  doublereal c = f1.isProportional(f2);
399  if (c != 0) {
400  if (c == -1.0) {
401  return *(new Const1(0.0));
402  } else {
403  return newTimesConstFunction(f1, c + 1.0);
404  }
405  }
406  return *(new Sum1(f1, f2));
407 }
408 
409 Func1& newDiffFunction(Func1& f1, Func1& f2)
410 {
411  if (isZero(f2)) {
412  delete &f2;
413  return f1;
414  }
415  if (f1.isIdentical(f2)) {
416  delete &f1;
417  delete &f2;
418  return *(new Const1(0.0));
419  }
420  doublereal c = f1.isProportional(f2);
421  if (c != 0.0) {
422  if (c == 1.0) {
423  return *(new Const1(0.0));
424  } else {
425  return newTimesConstFunction(f1, 1.0 - c);
426  }
427  }
428  return *(new Diff1(f1, f2));
429 }
430 
431 Func1& newProdFunction(Func1& f1, Func1& f2)
432 {
433  if (isOne(f1)) {
434  delete &f1;
435  return f2;
436  }
437  if (isOne(f2)) {
438  delete &f2;
439  return f1;
440  }
441  if (isZero(f1) || isZero(f2)) {
442  delete &f1;
443  delete &f2;
444  return *(new Const1(0.0));
445  }
446  if (isConstant(f1) && isConstant(f2)) {
447  doublereal c1c2 = f1.c() * f2.c();
448  delete &f1;
449  delete &f2;
450  return *(new Const1(c1c2));
451  }
452  if (isConstant(f1)) {
453  doublereal c = f1.c();
454  delete &f1;
455  return newTimesConstFunction(f2, c);
456  }
457  if (isConstant(f2)) {
458  doublereal c = f2.c();
459  delete &f2;
460  return newTimesConstFunction(f1, c);
461  }
462 
463  if (isPow(f1) && isPow(f2)) {
464  Func1& p = *(new Pow1(f1.c() + f2.c()));
465  delete &f1;
466  delete &f2;
467  return p;
468  }
469 
470  if (isExp(f1) && isExp(f2)) {
471  Func1& p = *(new Exp1(f1.c() + f2.c()));
472  delete &f1;
473  delete &f2;
474  return p;
475  }
476 
477  bool tc1 = isTimesConst(f1);
478  bool tc2 = isTimesConst(f2);
479 
480  if (tc1 || tc2) {
481  doublereal c1 = 1.0, c2 = 1.0;
482  Func1* ff1 = 0, *ff2 = 0;
483  if (tc1) {
484  c1 = f1.c();
485  ff1 = &f1.func1_dup();
486  delete &f1;
487  } else {
488  ff1 = &f1;
489  }
490  if (tc2) {
491  c2 = f2.c();
492  ff2 = &f2.func1_dup();
493  delete &f2;
494  } else {
495  ff2 = &f2;
496  }
497  Func1& p = newProdFunction(*ff1, *ff2);
498 
499  if (c1* c2 != 1.0) {
500  return newTimesConstFunction(p, c1*c2);
501  } else {
502  return p;
503  }
504  } else {
505  return *(new Product1(f1, f2));
506  }
507 }
508 
509 Func1& newRatioFunction(Func1& f1, Func1& f2)
510 {
511  if (isOne(f2)) {
512  return f1;
513  }
514  if (isZero(f1)) {
515  return *(new Const1(0.0));
516  }
517  if (f1.isIdentical(f2)) {
518  delete &f1;
519  delete &f2;
520  return *(new Const1(1.0));
521  }
522  if (f1.ID() == PowFuncType && f2.ID() == PowFuncType) {
523  return *(new Pow1(f1.c() - f2.c()));
524  }
525  if (f1.ID() == ExpFuncType && f2.ID() == ExpFuncType) {
526  return *(new Exp1(f1.c() - f2.c()));
527  }
528  return *(new Ratio1(f1, f2));
529 }
530 
531 Func1& newCompositeFunction(Func1& f1, Func1& f2)
532 {
533  if (isZero(f1)) {
534  delete &f1;
535  delete &f2;
536  return *(new Const1(0.0));
537  }
538  if (isConstant(f1)) {
539  delete &f2;
540  return f1;
541  }
542  if (isPow(f1) && f1.c() == 1.0) {
543  delete &f1;
544  return f2;
545  }
546  if (isPow(f1) && f1.c() == 0.0) {
547  delete &f1;
548  delete &f2;
549  return *(new Const1(1.0));
550  }
551  if (isPow(f1) && isPow(f2)) {
552  doublereal c1c2 = f1.c() * f2.c();
553  delete &f1;
554  delete &f2;
555  return *(new Pow1(c1c2));
556  }
557  return *(new Composite1(f1, f2));
558 }
559 
560 Func1& newTimesConstFunction(Func1& f, doublereal c)
561 {
562  if (c == 0.0) {
563  delete &f;
564  return *(new Const1(0.0));
565  }
566  if (c == 1.0) {
567  return f;
568  }
569  if (f.ID() == TimesConstantFuncType) {
570  f.setC(f.c() * c);
571  return f;
572  }
573  return *(new TimesConstant1(f, c));
574 }
575 
576 Func1& newPlusConstFunction(Func1& f, doublereal c)
577 {
578  if (c == 0.0) {
579  return f;
580  }
581  if (isConstant(f)) {
582  doublereal cc = f.c() + c;
583  delete &f;
584  return *(new Const1(cc));
585  }
586  if (f.ID() == PlusConstantFuncType) {
587  f.setC(f.c() + c);
588  return f;
589  }
590  return *(new PlusConstant1(f, c));
591 }
592 
593 }
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:202
virtual int order() const
Return the order of the function, if it makes sense.
Definition: Func1.cpp:119
exp
Definition: Func1.h:204
bool isIdentical(Func1 &other) const
Routine to determine if two functions are the same.
Definition: Func1.cpp:72
virtual Func1 & duplicate() const
Duplicate the current function.
Definition: Func1.cpp:42
doublereal operator()(doublereal t) const
Calls method eval to evaluate the function.
Definition: Func1.cpp:54
pow
Definition: Func1.h:237
STL namespace.
doublereal c() const
accessor function for the stored constant
Definition: Func1.cpp:97
virtual doublereal eval(doublereal t) const
Evaluate the function.
Definition: Func1.cpp:60
implements the sin() function
Definition: Func1.h:130
virtual int order() const
Return the order of the function, if it makes sense.
Definition: Func1.h:566
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:65
cos
Definition: Func1.h:169
void setC(doublereal c)
Function to set the stored constant.
Definition: Func1.cpp:103
Base class for &#39;functor&#39; classes that evaluate a function of one variable.
Definition: Func1.h:41
Func1 & func1() const
accessor function for m_f1
Definition: Func1.cpp:109
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:155
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:181
Func1 & func2() const
accessor function for m_f2
Definition: Func1.cpp:114
virtual int order() const
Return the order of the function, if it makes sense.
Definition: Func1.h:491
Contains declarations for string manipulation functions within Cantera.
Namespace for the Cantera kernel.
Definition: application.cpp:29
Constant.
Definition: Func1.h:271
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:163