Fixed: isConstant() for some function types

This commit is contained in:
Knut Morten Okstad 2022-03-29 15:12:29 +02:00
parent e2c76eaa08
commit f9370d3e67
4 changed files with 43 additions and 27 deletions

View File

@ -51,32 +51,31 @@ namespace Chebyshev
double eval2Der1(int polnum, double xi);
}
/*!
\brief A scalar-valued spatial function, chebyshev polynomials.
*/
class ChebyshevFunc : public RealFunc
{
std::vector<Real> coefs; //!< Coefficients
std::array<int, 3> n; //!< Number of coefficients
std::vector<Real> coefs; //!< Function coefficients
std::array<int,3> n; //!< Number of coefficients
public:
//! \brief The constructor initializes the function parameters from a file.
//! \param[in] file Name of file to read coefs from
//! \param[in] file Name of file to read \ref coefs from
ChebyshevFunc(const char* file);
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return n[0] == n[1] == n[2] == 0; }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return true; }
//! \brief Returns a const ref to the coefficients.
//! \brief Returns a const reference to the coefficients.
const std::vector<Real>& getCoefs() const { return coefs; }
//! \brief Returns the number of polymials in each parameter direction.
//! \brief Returns the number of polynomials in each parameter direction.
const std::array<int,3>& getSize() const { return n; }
protected:
//! \brief Evaluates the function by interpolating the 1D grid.
//! \brief Evaluates the function at point \a X.
virtual Real evaluate(const Vec3& X) const;
};
@ -88,29 +87,28 @@ protected:
class ChebyshevVecFunc : public VecFunc
{
std::array<std::unique_ptr<ChebyshevFunc>,3> f; //!< Functions
bool secondDer; //!< True to take second derivatives
public:
//! \brief The constructor initializes the function parameters from a file.
//! \param[in] file Name of files to read coefs from
//! \param[in] second True to take second derivatives
ChebyshevVecFunc(const std::vector<const char*>& file,
bool second = false);
ChebyshevVecFunc(const std::vector<const char*>& file, bool second = false);
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return f[0]->isZero(); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return true; }
protected:
//! \brief Evaluates the function.
//! \brief Evaluates the function at point \a X.
virtual Vec3 evaluate(const Vec3& X) const;
bool secondDer; //!< True to take second derivatives
};
/*!
\brief A tensor-valued spatial function, chebyshev polynomials.
\details If 2 or 3 functions: Take the derivative of the interpolants.
If 4 or 9 functions: Each component has their own interpolant.
*/
class ChebyshevTensorFunc : public TensorFunc
@ -121,15 +119,13 @@ public:
//! \brief The constructor initializes the function parameters from files.
//! \param[in] file Name of files to read from
//! \param[in] second True to take second derivatives
//! \details If 2 or 3 functions: Take the derivative of the interpolants.
//! If 4 or 9 functions: Each component has their own interpolant.
ChebyshevTensorFunc(const std::vector<const char*>& file, bool second);
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return !(f[0] || f[1] || f[2]); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return true; }
//! \brief Returns the function value as an array.
protected:
//! \brief Evaluates the function at point \a X.
virtual Tensor evaluate(const Vec3& X) const;
};

View File

@ -223,9 +223,14 @@ EvalFunction::EvalFunction (const char* function, Real epsX, Real epsT)
}
// Checking if the expression is time-independent
// Note, this will also catch things like tan(x), but...
// by searching for the occurance of 't' where the next character is not a letter
IAmConstant = true;
std::string expr(function);
IAmConstant = expr.find_first_of('t') > expr.size();
for (size_t i = expr.find_first_of('t'); IAmConstant; i = expr.find_first_of('t',i+1))
if (i >= expr.size())
return;
else if (i+1 == expr.size() || !isalpha(expr[i+1]))
IAmConstant = false;
}

View File

@ -127,6 +127,8 @@ public:
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return fval == Real(0); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return xmax <= Real(0); }
//! \brief Returns the first-derivative of the function.
virtual Real deriv(Real x) const;
@ -198,6 +200,8 @@ public:
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return scale == Real(0); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return this->isZero(); }
//! \brief Returns the first-derivative of the function.
virtual Real deriv(Real x) const;
@ -246,7 +250,7 @@ public:
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return tfunc->isZero(); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return tfunc->isZero(); }
virtual bool isConstant() const { return tfunc->isConstant(); }
//! \brief Returns first-derivative of the function.
virtual Real deriv(const Vec3& X, int dir) const;
@ -277,7 +281,7 @@ public:
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return sfunc->isZero() || tfunc->isZero(); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return this->isZero(); }
virtual bool isConstant() const { return this->isConstant(); }
//! \brief Returns first-derivative of the function.
virtual Real deriv(const Vec3& X, int dir) const;
@ -476,7 +480,7 @@ public:
//! \brief Returns whether the function is identically zero or not.
virtual bool isZero() const { return A == Real(0); }
//! \brief Returns whether the function is time-independent or not.
virtual bool isConstant() const { return A == Real(0); }
virtual bool isConstant() const { return this->isZero(); }
//! \brief Returns first-derivative of the function.
virtual Real deriv(const Vec3&, int dir) const;

View File

@ -29,6 +29,9 @@ TEST(TestScalarFunc, ParseDerivative)
ASSERT_TRUE(f1 != nullptr);
ASSERT_TRUE(f2 != nullptr);
EXPECT_FALSE(f1->isConstant());
EXPECT_FALSE(f2->isConstant());
double t = 0.0;
for (int i = 0; i < 20; i++)
{
@ -45,8 +48,7 @@ TEST(TestScalarFunc, ParseDerivative)
TEST(TestEvalFunction, ExtraParam)
{
const char* func1 = "x*foo";
EvalFunction f(func1);
EvalFunction f("x*foo");
f.setParam("foo", 2.0);
Vec3 X(1.0,0.0,0.0);
EXPECT_FLOAT_EQ(f(X), 2.0);
@ -54,3 +56,12 @@ TEST(TestEvalFunction, ExtraParam)
f.setParam("foo", 4.0);
EXPECT_FLOAT_EQ(f(X), 2.0);
}
TEST(TestEvalFunction, isConstant)
{
EXPECT_TRUE (EvalFunction("2.0*x*y").isConstant());
EXPECT_FALSE(EvalFunction("2.0*x*t").isConstant());
EXPECT_TRUE (EvalFunction("1.8*tan(x)*x").isConstant());
EXPECT_FALSE(EvalFunction("2.0*x*tan(t*3)+y").isConstant());
}