Skip to content

Commit

Permalink
[unittest] Test Func1 in C++
Browse files Browse the repository at this point in the history
  • Loading branch information
ischoegl authored and speth committed Jun 29, 2023
1 parent 4acc7ef commit 7b89929
Showing 1 changed file with 330 additions and 0 deletions.
330 changes: 330 additions & 0 deletions test/general/test_numerics.cpp
@@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "cantera/numerics/polyfit.h"
#include "cantera/numerics/funcs.h"
#include "cantera/numerics/Func1Factory.h"

using namespace Cantera;

Expand Down Expand Up @@ -125,3 +126,332 @@ TEST(Simpson, even)
// This data was generated by scipy.integrate.simpson(f, x, even='first')
EXPECT_NEAR(simpson(f, x), 3.34127, 1e-5);
}

TEST(ctfunc, functor)
{
auto functor = newFunc1("functor");
ASSERT_EQ(functor->type(), "functor");
ASSERT_THROW(functor->derivative3(), CanteraError);
}

TEST(ctfunc, invalid)
{
// exceptions return -1
ASSERT_THROW(newFunc1("spam"), CanteraError);
vector<double> pars = {1., 2.};
ASSERT_THROW(newFunc1("eggs", pars), CanteraError);
}

TEST(ctfunc, sin)
{
double omega = 2.;
auto functor = newFunc1("sin", omega);
ASSERT_EQ(functor->type(), "sin");
EXPECT_DOUBLE_EQ(functor->eval(0.), 0.);
EXPECT_DOUBLE_EQ(functor->eval(.5), sin(omega * .5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.), omega);
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), omega * cos(omega * .5));

ASSERT_THROW(newFunc1("sin", {}, npos), CanteraError);
}

TEST(ctfunc, cos)
{
double omega = 2.;
auto functor = newFunc1("cos", omega);
ASSERT_EQ(functor->type(), "cos");
EXPECT_DOUBLE_EQ(functor->eval(0.), 1.);
EXPECT_DOUBLE_EQ(functor->eval(.5), cos(omega * .5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.), 0.);
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), -omega * sin(omega * .5));

ASSERT_THROW(newFunc1("cos", {1., 2.}, npos), CanteraError);
}

TEST(ctfunc, exp)
{
double omega = 2.;
auto functor = newFunc1("exp", omega);
ASSERT_EQ(functor->type(), "exp");
EXPECT_DOUBLE_EQ(functor->eval(0.), 1.);
EXPECT_DOUBLE_EQ(functor->eval(.5), exp(omega * .5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.), omega);
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), omega * exp(omega * .5));

ASSERT_THROW(newFunc1("exp", {1., 2.}, npos), CanteraError);
}

TEST(ctfunc, log)
{
double omega = 2.;
auto functor = newFunc1("log", omega);
ASSERT_EQ(functor->type(), "log");
EXPECT_DOUBLE_EQ(functor->eval(0.1), log(omega * .1));
EXPECT_DOUBLE_EQ(functor->eval(1. / omega), 0.);
EXPECT_DOUBLE_EQ(functor->eval(10.), log(omega * 10.));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(.1), omega / .1);
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), omega / .5);

ASSERT_THROW(newFunc1("log", {}, npos), CanteraError);
}

TEST(ctfunc, pow)
{
double exp = .5;
auto functor = newFunc1("pow", exp);
EXPECT_DOUBLE_EQ(functor->eval(0.), 0.);
EXPECT_DOUBLE_EQ(functor->eval(.5), pow(.5, exp));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), exp * pow(.5, exp - 1));

ASSERT_THROW(newFunc1("pow", {}, npos), CanteraError);
}

TEST(ctfunc, constant)
{
double a = .5;
auto functor = newFunc1("constant", a);
EXPECT_EQ(functor->type(), "constant");
EXPECT_DOUBLE_EQ(functor->eval(0.), a);
EXPECT_DOUBLE_EQ(functor->eval(.5), a);

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.), 0.);
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), 0.);

ASSERT_THROW(newFunc1("constant", {1., 2., 3.}, npos), CanteraError);
}

TEST(ctfunc, tabulated_linear)
{
vector<double> params = {0., 1., 2., 1., 0., 1.};

auto functor = newFunc1("tabulated-linear", params, 3);
ASSERT_EQ(functor->type(), "tabulated-linear");
EXPECT_DOUBLE_EQ(functor->eval(0.), 1.);
EXPECT_DOUBLE_EQ(functor->eval(.5), .5);
EXPECT_DOUBLE_EQ(functor->eval(1.), 0.);
EXPECT_DOUBLE_EQ(functor->eval(1.2), 0.2);
EXPECT_DOUBLE_EQ(functor->eval(2.), 1.);

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), -1.);
EXPECT_DOUBLE_EQ(dfunctor->eval(1.5), 1.);

ASSERT_THROW(newFunc1("tabulated-linear", params, 2), CanteraError);
}

TEST(ctfunc, tabulated_previous)
{
vector<double> params = {0., 1., 2., 1., 0., 1.};

auto functor = newFunc1("tabulated-previous", params, 3);
ASSERT_EQ(functor->type(), "tabulated-previous");
EXPECT_DOUBLE_EQ(functor->eval(0.), 1.);
EXPECT_DOUBLE_EQ(functor->eval(.5), 1.);
EXPECT_DOUBLE_EQ(functor->eval(1. - 1.e-12), 1.);
EXPECT_DOUBLE_EQ(functor->eval(1. + 1.e-12), 0.);
EXPECT_DOUBLE_EQ(functor->eval(1.2), 0.);
EXPECT_DOUBLE_EQ(functor->eval(2. - 1.e-12), 0.);
EXPECT_DOUBLE_EQ(functor->eval(2. + 1.e-12), 1.);

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), 0.);
EXPECT_DOUBLE_EQ(dfunctor->eval(1.5), 0.);
}

TEST(ctfunc, poly)
{
int n = 2;
double a0 = .5;
double a1 = .25;
double a2 = .125;
vector<double> params = {a0, a1, a2};
auto functor = newFunc1("polynomial", params, n);
ASSERT_EQ(functor->type(), "polynomial");
EXPECT_DOUBLE_EQ(functor->eval(0.), a0);
EXPECT_DOUBLE_EQ(functor->eval(.5), (a2 * .5 + a1) * .5 + a0);

ASSERT_THROW(functor->derivative3(), CanteraError);

ASSERT_THROW(newFunc1("polynomial", params, 3), CanteraError);
}

TEST(ctfunc, Fourier)
{
int n = 1;
double a0 = .5;
double a1 = .25;
double b1 = .125;
double omega = 2.;
vector<double> params = {a0, a1, omega, b1};
auto functor = newFunc1("Fourier", params, n);
ASSERT_EQ(functor->type(), "Fourier");
EXPECT_DOUBLE_EQ(functor->eval(0.), .5 * a0 + a1);
EXPECT_DOUBLE_EQ(
functor->eval(.5), .5 * a0 + a1 * cos(omega * .5) + b1 * sin(omega * .5));

ASSERT_THROW(functor->derivative3(), CanteraError);

ASSERT_THROW(newFunc1("polynomial", params, 2 * n), CanteraError);
}

TEST(ctfunc, Gaussian)
{
double A = .5;
double t0 = .6;
double fwhm = .25;
vector<double> params = {A, t0, fwhm};
auto functor = newFunc1("Gaussian", params);
ASSERT_EQ(functor->type(), "Gaussian");
double tau = fwhm / (2. * sqrt(log(2.)));
double x = - t0 / tau;
EXPECT_DOUBLE_EQ(functor->eval(0.), A * exp(-x * x));
x = (.5 - t0) / tau;
EXPECT_DOUBLE_EQ(functor->eval(.5), A * exp(-x * x));

ASSERT_THROW(functor->derivative3(), CanteraError);
}

TEST(ctfunc, Arrhenius)
{
double A = 38.7;
double b = 2.7;
double E = 2.619184e+07 / GasConstant;
vector<double> params = {A, b, E};
auto functor = newFunc1("Arrhenius", params, 1);
ASSERT_EQ(functor->type(), "Arrhenius");
EXPECT_DOUBLE_EQ(functor->eval(1000.), A * pow(1000., b) * exp(-E/1000.));

ASSERT_THROW(functor->derivative3(), CanteraError);
}

TEST(ctmath, invalid)
{
auto functor0 = newFunc1("sin");
auto functor1 = newFunc1("cos");
ASSERT_THROW(newFunc1("foo", functor0, functor1), CanteraError);
ASSERT_THROW(newFunc1("bar", functor0, 0.), CanteraError);
}

TEST(ctmath, sum)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
auto functor1 = newFunc1("cos", omega);
auto functor = newFunc1("sum", functor0, functor1);
EXPECT_EQ(functor->type(), "sum");
EXPECT_DOUBLE_EQ(functor->eval(0.), 1.);
EXPECT_DOUBLE_EQ(functor->eval(.5), sin(omega * .5) + cos(omega * .5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), omega * (cos(omega * .5) - sin(omega * .5)));
}

TEST(ctmath, diff)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
auto functor1 = newFunc1("cos", omega);
auto functor = newFunc1("diff", functor0, functor1);
EXPECT_EQ(functor->type(), "diff");
EXPECT_DOUBLE_EQ(functor->eval(0.), -1.);
EXPECT_DOUBLE_EQ(functor->eval(.5), sin(omega * .5) - cos(omega * .5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(.5), omega * (cos(omega * .5) + sin(omega * .5)));
}

TEST(ctmath, prod)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
auto functor1 = newFunc1("cos", omega);
auto functor = newFunc1("product", functor0, functor1);
EXPECT_EQ(functor->type(), "product");
EXPECT_DOUBLE_EQ(functor->eval(0.), 0);
EXPECT_DOUBLE_EQ(functor->eval(0.5), sin(omega * 0.5) * cos(omega * 0.5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.5),
omega * (pow(cos(omega * 0.5), 2) - pow(sin(omega * 0.5), 2)));
}

TEST(ctmath, ratio)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
auto functor1 = newFunc1("cos", omega);
auto functor = newFunc1("ratio", functor0, functor1);
EXPECT_EQ(functor->type(), "ratio");
EXPECT_DOUBLE_EQ(functor->eval(0.), 0.);
EXPECT_DOUBLE_EQ(functor->eval(0.5), sin(omega * 0.5) / cos(omega * 0.5));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.5), omega / pow(cos(omega * 0.5), 2));
}

TEST(ctmath, composite)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
auto functor1 = newFunc1("cos", omega);
auto functor = newFunc1("composite", functor0, functor1);
EXPECT_EQ(functor->type(), "composite");
EXPECT_DOUBLE_EQ(functor->eval(0.), sin(omega));
EXPECT_DOUBLE_EQ(functor->eval(0.5), sin(omega * cos(omega * 0.5)));

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.5),
- omega * omega * sin(omega * 0.5) * cos(omega * cos(omega * 0.5)));
}

TEST(ctmath, times_constant)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
double A = 1.234;
auto functor = newFunc1("times-constant", functor0, A);
EXPECT_EQ(functor->type(), "times-constant");
EXPECT_DOUBLE_EQ(functor->eval(0.), 0.);
EXPECT_DOUBLE_EQ(functor->eval(0.5), sin(omega * 0.5) * A);

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.5), A * omega * cos(omega * 0.5));
}

TEST(ctmath, plus_constant)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
double A = 1.234;
auto functor = newFunc1("plus-constant", functor0, A);
EXPECT_EQ(functor->type(), "plus-constant");
EXPECT_DOUBLE_EQ(functor->eval(0.), A);
EXPECT_DOUBLE_EQ(functor->eval(0.5), sin(omega * 0.5) + A);

auto dfunctor = functor->derivative3();
EXPECT_DOUBLE_EQ(dfunctor->eval(0.5), omega * cos(omega * 0.5));
}

TEST(ctmath, periodic)
{
double omega = 2.;
auto functor0 = newFunc1("sin", omega);
double A = 1.234;
auto functor = newFunc1("periodic", functor0, A);
EXPECT_EQ(functor->type(), "periodic");
EXPECT_DOUBLE_EQ(functor->eval(0.), functor->eval(A));
EXPECT_DOUBLE_EQ(functor->eval(0.5), functor->eval(0.5 + A));

ASSERT_THROW(functor->derivative3(), CanteraError);
}

0 comments on commit 7b89929

Please sign in to comment.