diff --git a/Cantera/src/Func1.cpp b/Cantera/src/Func1.cpp index a23b24477..d4d39a453 100644 --- a/Cantera/src/Func1.cpp +++ b/Cantera/src/Func1.cpp @@ -13,18 +13,18 @@ namespace Cantera { Func1& Sin1::derivative() const { Func1* c = new Cos1(m_c); - return *(new TimesConstant1(*c, m_c)); + return newTimesConstFunction(*c, m_c); } Func1& Cos1::derivative() const { Func1* s = new Sin1(m_c); - return *(new TimesConstant1(*s, -m_c)); + return newTimesConstFunction(*s, -m_c); } Func1& Exp1::derivative() const { Func1* f = new Exp1(m_c); if (m_c != 1.0) - return *(new TimesConstant1(*f, m_c)); + return newTimesConstFunction(*f, m_c); else return *f; } @@ -32,7 +32,7 @@ namespace Cantera { Func1& Pow1::derivative() const { Func1* f = new Pow1(m_c - 1.0); if (m_c != 1.0) - return *(new TimesConstant1(*f, m_c)); + return newTimesConstFunction(*f, m_c); else return *(new Const1(1.0)); } @@ -54,6 +54,7 @@ namespace Cantera { } string Pow1::write(string arg) const { + //cout << "Pow1" << endl; string c = ""; if (m_c == 0.5) { return "\\sqrt{" + arg + "}"; @@ -77,17 +78,20 @@ namespace Cantera { } string Const1::write(string arg) const { + //cout << "Const1" << endl; string c = ""; c = fp2str(m_c); return c; } string Ratio1::write(string arg) const { + //cout << "Ratio1" << endl; return "\\frac{" + m_f1->write(arg) + "}{" + m_f2->write(arg) + "}"; } string Product1::write(string arg) const { + //cout << "Product1" << endl; string s = m_f1->write(arg); if (m_f1->order() < order()) s = "\\left(" + s + "\\right)"; string s2 = m_f2->write(arg); @@ -96,6 +100,7 @@ namespace Cantera { } string Sum1::write(string arg) const { + //cout << "Sum1" << endl; string s1 = m_f1->write(arg); string s2 = m_f2->write(arg); if (s2[0] == '-') return s1 + " - " + s2.substr(1,s2.size()); @@ -103,6 +108,7 @@ namespace Cantera { } string Diff1::write(string arg) const { + //cout << "Diff1" << endl; string s1 = m_f1->write(arg); string s2 = m_f2->write(arg); if (s2[0] == '-') return s1 + " + " + s2.substr(1,s2.size()); @@ -110,11 +116,13 @@ namespace Cantera { } string Composite1::write(string arg) const { + //cout << "Composite1" << endl; string g = m_f2->write(arg); return m_f1->write(g); } string TimesConstant1::write(string arg) const { + //cout << "TimesConstant1" << endl; string s = m_f1->write(arg); if (m_f1->order() < order()) s = "\\left(" + s + "\\right)"; if (m_c == 1.0) return s; @@ -126,6 +134,7 @@ namespace Cantera { } string PlusConstant1::write(string arg) const { + //cout << "PlusConstant1" << endl; if (m_c == 0.0) return m_f1->write(arg); return m_f1->write(arg) + " + " + fp2str(m_c); } @@ -139,6 +148,13 @@ namespace Cantera { else return 0.0; } + static bool isConstant(Func1& f) { + if (f.ID() == ConstFuncType) + return true; + else + return false; + } + static bool isZero(Func1& f) { if (f.ID() == ConstFuncType && f.c() == 0.0) return true; @@ -160,6 +176,20 @@ namespace Cantera { return false; } + static bool isExp(Func1& f) { + if (f.ID() == ExpFuncType) + return true; + else + return false; + } + + static bool isPow(Func1& f) { + if (f.ID() == PowFuncType) + return true; + else + return false; + } + Func1& newSumFunction(Func1& f1, Func1& f2) { if (f1.isIdentical(f2)) return newTimesConstFunction(f1, 2.0); @@ -191,7 +221,7 @@ namespace Cantera { return *(new Const1(0.0)); } doublereal c = f1.isProportional(f2); - if (c != 0) { + if (c != 0.0) { if (c == 1.0) return *(new Const1(0.0)); else return newTimesConstFunction(f1, 1.0 - c); } @@ -209,25 +239,53 @@ namespace Cantera { delete &f1; delete &f2; return *(new Const1(0.0)); } + if (isConstant(f1) && isConstant(f2)) { + doublereal c1c2 = f1.c() * f2.c(); + delete &f1; delete &f2; + return *(new Const1(c1c2)); + } + if (isConstant(f1)) { + doublereal c = f1.c(); + delete &f1; + return newTimesConstFunction(f2, c); + } + if (isConstant(f2)) { + doublereal c = f2.c(); + delete &f2; + return newTimesConstFunction(f1, c); + } + + if (isPow(f1) && isPow(f2)) { + Func1& p = *(new Pow1(f1.c() + f2.c())); + delete &f1; delete &f2; + return p; + } + + if (isExp(f1) && isExp(f2)) { + Func1& p = *(new Exp1(f1.c() + f2.c())); + delete &f1; delete &f2; + return p; + } + bool tc1 = isTimesConst(f1); bool tc2 = isTimesConst(f2); - //cout << "product: " << f1.write("t") << " " << f2.write("t") << endl; - //cout << tc1 << " " << tc2 << " " << f1.ID() << " " << f2.ID() << endl; + if (tc1 || tc2) { doublereal c1 = 1.0, c2 = 1.0; Func1 *ff1 = 0, *ff2 = 0; if (tc1) { c1 = f1.c(); ff1 = &f1.func1_dup(); + delete &f1; } else ff1 = &f1; if (tc2) { c2 = f2.c(); ff2 = &f2.func1_dup(); + delete &f2; } else ff2 = &f2; Func1& p = newProdFunction(*ff1, *ff2); - //cout << "p = " << p.write("t") << endl; if (c1*c2 != 1.0) { return newTimesConstFunction(p, c1*c2); @@ -246,6 +304,12 @@ namespace Cantera { delete &f1; delete &f2; return *(new Const1(1.0)); } + if (f1.ID() == PowFuncType && f2.ID() == PowFuncType) { + return *(new Pow1(f1.c() - f2.c())); + } + if (f1.ID() == ExpFuncType && f2.ID() == ExpFuncType) { + return *(new Exp1(f1.c() - f2.c())); + } return *(new Ratio1(f1, f2)); } @@ -254,6 +318,30 @@ namespace Cantera { delete &f1; delete &f2; return *(new Const1(0.0)); } + if (isConstant(f1)) { + delete &f2; + return f1; + } + if (isPow(f1) && f1.c() == 1.0) { + delete &f1; + return f2; + } + if (isPow(f1) && f1.c() == 0.0) { + delete &f1; + delete &f2; + return *(new Const1(1.0)); + } + if (isPow(f1) && isPow(f2)) { + doublereal c1c2 = f1.c() * f2.c(); + delete &f1; + delete &f2; + return *(new Pow1(c1c2)); + } + if (isTimesConst(f1)) { + Func1& p = newTimesConstFunction(f2, f1.c()); + delete &f1; + return p; + } return *(new Composite1(f1, f2)); } diff --git a/Cantera/src/Func1.h b/Cantera/src/Func1.h index c495c8fa3..4e5b47775 100644 --- a/Cantera/src/Func1.h +++ b/Cantera/src/Func1.h @@ -360,7 +360,7 @@ namespace Cantera { } virtual Func1& derivative() const { Func1& f1d = m_f1->derivative(); - Func1* d = new TimesConstant1(f1d, m_c); + Func1* d = &newTimesConstFunction(f1d, m_c); return *d; } virtual std::string write(std::string arg) const;