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