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