36 "Needs to be overloaded by Func1 specialization.");
41 if (
type() ==
"functor" ||
type() != other->type() || m_c != other->m_c) {
48 if (!m_f1->isIdentical(other->m_f1)) {
56 if (!m_f2->isIdentical(other->m_f2)) {
76Sin1::Sin1(
const vector<double>& params)
78 if (params.size() != 1) {
80 "Constructor needs exactly one parameter (frequency).");
88 return fmt::format(
"\\sin({})", arg);
90 return fmt::format(
"\\sin({}{})", m_c, arg);
96 auto c = make_shared<Cos1>(m_c);
102Cos1::Cos1(
const vector<double>& params)
104 if (params.size() != 1) {
106 "Constructor needs exactly one parameter (frequency).");
113 auto s = make_shared<Sin1>(m_c);
120 return fmt::format(
"\\cos({})", arg);
122 return fmt::format(
"\\cos({}{})", m_c, arg);
128Exp1::Exp1(
const vector<double>& params)
130 if (params.size() != 1) {
132 "Constructor needs exactly one parameter (exponent factor).");
139 auto f = make_shared<Exp1>(m_c);
149 return fmt::format(
"\\exp({})", arg);
151 return fmt::format(
"\\exp({}{})", m_c, arg);
155Log1::Log1(
const vector<double>& params)
157 if (params.size() != 1) {
159 "Constructor needs exactly one parameter (factor).");
166 auto f = make_shared<Pow1>(-1.);
176 return fmt::format(
"\\log({})", arg);
178 return fmt::format(
"\\log({}{})", m_c, arg);
183Pow1::Pow1(
const vector<double>& params)
185 if (params.size() != 1) {
187 "Constructor needs exactly one parameter (exponent).");
195 return make_shared<Const1>(0.0);
198 return make_shared<Const1>(1.0);
200 auto f = make_shared<Pow1>(m_c - 1.);
206Const1::Const1(
const vector<double>& params)
208 if (params.size() != 1) {
210 "Constructor needs exactly one parameter (constant).");
215Poly1::Poly1(
const vector<double>& params)
217 if (params.size() == 0) {
219 "Constructor needs an array that is not empty.");
221 size_t n = params.size() - 1;
222 m_cpoly.resize(n + 1);
223 copy(params.data(), params.data() + m_cpoly.size(), m_cpoly.begin());
230 if (m_cpoly[m_cpoly.size()-1] != 0.) {
231 out = fmt::format(
"{}", m_cpoly[m_cpoly.size()-1]);
233 for (
size_t n=1; n<m_cpoly.size(); n++) {
234 if (m_cpoly[m_cpoly.size()-1-n] == 0.) {
238 if (m_cpoly[m_cpoly.size()-1-n] == 1.) {
239 term = fmt::format(
"{}", arg);
240 }
else if (m_cpoly[m_cpoly.size()-1-n] == -1.) {
241 term = fmt::format(
"-{}", arg);
243 term = fmt::format(
"{}{}", m_cpoly[m_cpoly.size()-1-n], arg);
246 term = fmt::format(
"{}^{{{}}}", term, n);
248 term = fmt::format(
"{}^{}", term, n);
252 }
else if (out[0] ==
'-') {
253 out = fmt::format(
"{} - {}", term, out.substr(1));
255 out = fmt::format(
"{} + {}", term, out);
261Fourier1::Fourier1(
const vector<double>& params)
263 if (params.size() < 4) {
265 "Constructor needs an array with at least 4 entries.");
267 if (params.size() % 2 != 0) {
269 "Constructor needs an array with an even number of entries.");
271 size_t n = params.size() / 2 - 1;
272 m_omega = params[n + 1];
273 m_a0_2 = 0.5 * params[0];
276 copy(params.data() + 1, params.data() + n + 1, m_ccos.begin());
277 copy(params.data() + n + 2, params.data() + 2 * n + 2, m_csin.begin());
280Gaussian1::Gaussian1(
const vector<double>& params)
282 if (params.size() != 3) {
284 "Constructor needs exactly 3 parameters (amplitude, center, width).");
288 m_tau = params[2] / (2. * sqrt(log(2.)));
291Arrhenius1::Arrhenius1(
const vector<double>& params)
293 if (params.size() < 3) {
295 "Constructor needs an array with at least 3 entries.");
297 if (params.size() % 3 != 0) {
299 "Constructor needs an array with multiples of 3 entries.");
301 size_t n = params.size() / 3;
305 for (
size_t i = 0; i < n; i++) {
307 m_A[i] = params[loc];
308 m_b[i] = params[loc + 1];
309 m_E[i] = params[loc + 2];
314 const string& method)
317 std::copy(tvals, tvals + n,
m_tvec.begin());
318 for (
auto it = std::begin(
m_tvec) + 1; it != std::end(
m_tvec); it++) {
319 if (*(it - 1) > *it) {
321 "time values are not increasing monotonically.");
325 std::copy(fvals, fvals + n,
m_fvec.begin());
331 if (params.size() < 4) {
333 "Constructor needs an array with at least 4 entries.");
335 if (params.size() % 2 != 0) {
337 "Constructor needs an array with an even number of entries.");
339 size_t n = params.size() / 2;
341 copy(params.data(), params.data() + n,
m_tvec.begin());
342 for (
auto it = std::begin(
m_tvec) + 1; it != std::end(
m_tvec); it++) {
343 if (*(it - 1) > *it) {
345 "Time values are not monotonically increasing.");
349 copy(params.data() + n, params.data() + 2 * n,
m_fvec.begin());
354 if (method ==
"linear") {
356 }
else if (method ==
"previous") {
360 "Interpolation method '{}' is not implemented.", method);
365 size_t siz =
m_tvec.size();
369 }
else if (t >=
m_tvec[siz-1]) {
373 while (t >
m_tvec[ix+1]) {
390 size_t siz =
m_tvec.size();
394 for (
size_t i=1; i<siz; i++) {
397 tvec.push_back(
m_tvec[i-1]);
401 tvec.push_back(
m_tvec[siz-1]);
405 tvec.push_back(
m_tvec[0]);
406 tvec.push_back(
m_tvec[siz-1]);
410 return make_shared<Tabulated1>(tvec.size(), &tvec[0], &dvec[0],
"previous");
417 return fmt::format(
"\\mathrm{{{}}}({})",
type(), arg);
423 return "\\sqrt{" + arg +
"}";
426 return "\\frac{1}{\\sqrt{" + arg +
"}}";
429 return fmt::format(
"\\left({}\\right)^{{{}}}", arg, m_c);
437 return fmt::format(
"\\mathrm{{Tabulated}}({})", arg);
442 return fmt::format(
"{}", m_c);
447 return "\\frac{" + m_f1->write(arg) +
"}{" + m_f2->write(arg) +
"}";
460 string s = m_f1->write(arg);
461 if (m_f1->order() <
order()) {
462 s =
"\\left(" + s +
"\\right)";
464 string s2 = m_f2->write(arg);
465 if (m_f2->order() <
order()) {
466 s2 =
"\\left(" + s2 +
"\\right)";
479 string s1 = m_f1->write(arg);
480 string s2 = m_f2->write(arg);
482 return s1 +
" - " + s2.substr(1,s2.size());
484 return s1 +
" + " + s2;
490 string s1 = m_f1->write(arg);
491 string s2 = m_f2->write(arg);
493 return s1 +
" + " + s2.substr(1,s2.size());
495 return s1 +
" - " + s2;
501 string g = m_f2->write(arg);
502 return m_f1->write(g);
506 auto d1 = m_f1->derivative();
507 auto d2 = m_f2->derivative();
514 string s = m_f1->write(arg);
515 if (m_f1->order() <
order()) {
516 s =
"\\left(" + s +
"\\right)";
525 if (n >=
'0' && n <=
'9') {
526 s =
"\\left(" + s +
"\\right)";
528 return fmt::format(
"{}{}", m_c, s);
534 return m_f1->write(arg);
536 return fmt::format(
"{} + {}", m_f1->write(arg), m_c);
541bool isConstant(
const shared_ptr<Func1>& f)
543 return f->type() ==
"constant";
546bool isZero(
const shared_ptr<Func1>& f)
548 return f->type() ==
"constant" && f->c() == 0.0;
551bool isOne(
const shared_ptr<Func1>& f)
553 return f->type() ==
"constant" && f->c() == 1.0;
556bool isTimesConst(
const shared_ptr<Func1>& f)
558 return f->type() ==
"times-constant";
561bool isExp(
const shared_ptr<Func1>& f)
563 return f->type() ==
"exp";
566bool isPow(
const shared_ptr<Func1>& f)
568 return f->type() ==
"pow";
571pair<bool, double> isProportional(
572 const shared_ptr<Func1>&f1,
const shared_ptr<Func1>&f2)
574 bool tc1 = isTimesConst(f1);
575 bool tc2 = isTimesConst(f2);
577 if (f1->isIdentical(f2)) {
583 if (f1->isIdentical((f2->func1_shared()))) {
584 return {
true, f2->c()};
589 if (f2->isIdentical((f1->func1_shared()))) {
590 return {
true, 1. / f1->c()};
594 if (f2->func1_shared()->isIdentical((f1->func1_shared()))) {
595 return {
true, f2->c() / f1->c()};
604 if (f1->isIdentical(f2)) {
613 if (isConstant(f2)) {
616 if (isConstant(f1)) {
619 auto [prop, c] = isProportional(f1, f2);
622 return make_shared<Const1>(0.);
626 return make_shared<Sum1>(f1, f2);
637 if (f1->isIdentical(f2)) {
638 return make_shared<Const1>(0.);
640 if (isConstant(f2)) {
643 auto [prop, c] = isProportional(f1, f2);
646 return make_shared<Const1>(0.);
650 return make_shared<Diff1>(f1, f2);
661 if (isZero(f1) || isZero(f2)) {
662 return make_shared<Const1>(0.);
664 if (isConstant(f1) && isConstant(f2)) {
665 return make_shared<Const1>(f1->c() * f2->c());
667 if (isConstant(f1)) {
670 if (isConstant(f2)) {
673 if (isPow(f1) && isPow(f2)) {
674 return make_shared<Pow1>(f1->c() + f2->c());
676 if (isExp(f1) && isExp(f2)) {
677 return make_shared<Exp1>(f1->c() + f2->c());
680 bool tc1 = isTimesConst(f1);
681 bool tc2 = isTimesConst(f2);
688 ff1 = f1->func1_shared();
694 ff2 = f2->func1_shared();
698 if (c1 * c2 != 1.0) {
703 return make_shared<Product1>(f1, f2);
712 return make_shared<Const1>(0.);
715 throw CanteraError(
"newRatioFunction",
"Division by zero.");
717 if (f1->isIdentical(f2)) {
718 return make_shared<Const1>(1.);
720 if (isConstant(f2)) {
723 if (isPow(f1) && isPow(f2)) {
724 return make_shared<Pow1>(f1->c() - f2->c());
726 if (isExp(f1) && isExp(f2)) {
727 return make_shared<Exp1>(f1->c() - f2->c());
729 return make_shared<Ratio1>(f1, f2);
735 return make_shared<Const1>(0.0);
737 if (isConstant(f1)) {
740 if (isPow(f1) && f1->c() == 1.0) {
743 if (isPow(f1) && f1->c() == 0.0) {
744 return make_shared<Const1>(1.);
746 if (isPow(f1) && isPow(f2)) {
747 return make_shared<Pow1>(f1->c() * f2->c());
749 return make_shared<Composite1>(f1, f2);
755 return make_shared<Const1>(0.0);
760 if (f->type() ==
"times-constant") {
761 return make_shared<TimesConstant1>(f->func1_shared(), f->c() * c);
763 return make_shared<TimesConstant1>(f, c);
772 return make_shared<Const1>(f->c() + c);
774 if (f->type() ==
"plus-constant") {
775 return make_shared<PlusConstant1>(f->func1_shared(), f->c() + c);
777 return make_shared<PlusConstant1>(f, c);
Base class for exceptions thrown by Cantera classes.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
string write(const string &arg) const override
Write LaTeX string describing function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
string write(const string &arg) const override
Write LaTeX string describing function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
string typeName() const
Returns a string with the class name of the functor.
virtual shared_ptr< Func1 > derivative() const
Creates a derivative to the current function.
virtual string type() const
Returns a string describing the type of the function.
virtual double eval(double t) const
Evaluate the function.
virtual string write(const string &arg) const
Write LaTeX string describing function.
double operator()(double t) const
Calls method eval to evaluate the function.
virtual bool isIdentical(shared_ptr< Func1 > other) const
Routine to determine if two functions are the same.
virtual int order() const
Return the order of the function, if it makes sense.
double c() const
Accessor function for the stored constant m_c.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
An error indicating that an unimplemented function has been called.
string write(const string &arg) const override
Write LaTeX string describing function.
string write(const string &arg) const override
Write LaTeX string describing function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
int order() const override
Return the order of the function, if it makes sense.
string write(const string &arg) const override
Write LaTeX string describing function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
string write(const string &arg) const override
Write LaTeX string describing function.
double eval(double t) const override
Evaluate the function.
shared_ptr< Func1 > derivative() const override
Creates a derivative to the current function.
string write(const string &arg) const override
Write LaTeX string describing function.
void setMethod(const string &method)
Set the interpolation method.
vector< double > m_tvec
Vector of time values.
bool m_isLinear
Boolean indicating interpolation method.
vector< double > m_fvec
Vector of function values.
Tabulated1(size_t n, const double *tvals, const double *fvals, const string &method="linear")
Constructor.
int order() const override
Return the order of the function, if it makes sense.
string write(const string &arg) const override
Write LaTeX string describing function.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
shared_ptr< Func1 > newCompositeFunction(shared_ptr< Func1 > f1, shared_ptr< Func1 > f2)
Composite of two functions.
shared_ptr< Func1 > newProdFunction(shared_ptr< Func1 > f1, shared_ptr< Func1 > f2)
Product of two functions.
shared_ptr< Func1 > newDiffFunction(shared_ptr< Func1 > f1, shared_ptr< Func1 > f2)
Difference of two functions.
shared_ptr< Func1 > newTimesConstFunction(shared_ptr< Func1 > f, double c)
Product of function and constant.
shared_ptr< Func1 > newSumFunction(shared_ptr< Func1 > f1, shared_ptr< Func1 > f2)
Sum of two functions.
shared_ptr< Func1 > newRatioFunction(shared_ptr< Func1 > f1, shared_ptr< Func1 > f2)
Ratio of two functions.
shared_ptr< Func1 > newPlusConstFunction(shared_ptr< Func1 > f, double c)
Sum of function and constant.
string demangle(const std::type_info &type)
Convert a type name to a human readable string, using boost::core::demangle if available.
Namespace for the Cantera kernel.
Contains declarations for string manipulation functions within Cantera.