Added: Time-derivative of time-dependent spatial functions
This commit is contained in:
parent
cfa6a8b4a2
commit
e2c76eaa08
@ -15,6 +15,9 @@
|
|||||||
#include "Vec3.h"
|
#include "Vec3.h"
|
||||||
#include "Tensor.h"
|
#include "Tensor.h"
|
||||||
#include "expreval.h"
|
#include "expreval.h"
|
||||||
|
#ifdef USE_OPENMP
|
||||||
|
#include <omp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -181,7 +184,8 @@ Real EvalFunc::deriv (Real x) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EvalFunction::EvalFunction (const char* function) : gradient{}, dgradient{}
|
EvalFunction::EvalFunction (const char* function, Real epsX, Real epsT)
|
||||||
|
: gradient{}, dgradient{}, dx(epsX), dt(epsT)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
#ifdef USE_OPENMP
|
#ifdef USE_OPENMP
|
||||||
@ -318,10 +322,29 @@ Real EvalFunction::evaluate (const Vec3& X) const
|
|||||||
|
|
||||||
Real EvalFunction::deriv (const Vec3& X, int dir) const
|
Real EvalFunction::deriv (const Vec3& X, int dir) const
|
||||||
{
|
{
|
||||||
if (dir < 1 || dir > 3 || !gradient[--dir])
|
if (dir < 1)
|
||||||
return Real(0);
|
return Real(0);
|
||||||
|
else if (dir < 4)
|
||||||
|
{
|
||||||
|
if (gradient[--dir])
|
||||||
|
return gradient[dir]->evaluate(X);
|
||||||
|
|
||||||
return gradient[dir]->evaluate(X);
|
// Evaluate spatial derivative using central difference
|
||||||
|
Vec4 X0, X1;
|
||||||
|
X0.assign(X); X0[dir] -= 0.5*dx;
|
||||||
|
X1.assign(X); X1[dir] += 0.5*dx;
|
||||||
|
return (this->evaluate(X1) - this->evaluate(X0)) / dx;
|
||||||
|
}
|
||||||
|
else if (!IAmConstant)
|
||||||
|
{
|
||||||
|
// Evaluate time-derivative using central difference
|
||||||
|
Vec4 X0, X1;
|
||||||
|
X0.assign(X); X0.t -= 0.5*dt;
|
||||||
|
X1.assign(X); X1.t += 0.5*dt;
|
||||||
|
return (this->evaluate(X1) - this->evaluate(X0)) / dt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return Real(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include <array>
|
||||||
#ifdef USE_OPENMP
|
|
||||||
#include <omp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ExprEval {
|
namespace ExprEval {
|
||||||
class Expression;
|
class Expression;
|
||||||
@ -50,7 +47,8 @@ public:
|
|||||||
static int numError; //!< Error counter - set by the exception handler
|
static int numError; //!< Error counter - set by the exception handler
|
||||||
|
|
||||||
//! \brief The constructor parses the expression string.
|
//! \brief The constructor parses the expression string.
|
||||||
explicit EvalFunc(const char* function, const char* x = "x", Real eps = Real(1.0e-8));
|
explicit EvalFunc(const char* function, const char* x = "x",
|
||||||
|
Real eps = Real(1.0e-8));
|
||||||
//! \brief The destructor frees the dynamically allocated objects.
|
//! \brief The destructor frees the dynamically allocated objects.
|
||||||
virtual ~EvalFunc();
|
virtual ~EvalFunc();
|
||||||
|
|
||||||
@ -102,9 +100,13 @@ class EvalFunction : public RealFunc
|
|||||||
|
|
||||||
bool IAmConstant; //!< Indicates whether the time coordinate is given or not
|
bool IAmConstant; //!< Indicates whether the time coordinate is given or not
|
||||||
|
|
||||||
|
Real dx; //!< Domain increment for calculation of numerical derivative
|
||||||
|
Real dt; //!< Domain increment for calculation of numerical time-derivative
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief The constructor parses the expression string.
|
//! \brief The constructor parses the expression string.
|
||||||
explicit EvalFunction(const char* function);
|
explicit EvalFunction(const char* function,
|
||||||
|
Real epsX = Real(1.0e-8), Real epsT = Real(1.0e-12));
|
||||||
//! \brief The destructor frees the dynamically allocated objects.
|
//! \brief The destructor frees the dynamically allocated objects.
|
||||||
virtual ~EvalFunction();
|
virtual ~EvalFunction();
|
||||||
|
|
||||||
|
@ -241,6 +241,9 @@ class TractionFunc : public utl::Function2<Vec3,Vec3>
|
|||||||
public:
|
public:
|
||||||
//! \brief Returns whether the traction is always normal to the face or not.
|
//! \brief Returns whether the traction is always normal to the face or not.
|
||||||
virtual bool isNormalPressure() const { return false; }
|
virtual bool isNormalPressure() const { return false; }
|
||||||
|
|
||||||
|
//! \brief Returns the time-derivative of the function.
|
||||||
|
virtual Vec3 deriv(const Vec3&, const Vec3&) const { return Vec3(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -271,10 +271,16 @@ Real SineFunc::deriv (Real x) const
|
|||||||
Real ConstTimeFunc::evaluate (const Vec3& X) const
|
Real ConstTimeFunc::evaluate (const Vec3& X) const
|
||||||
{
|
{
|
||||||
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
||||||
if (Xt)
|
return (*tfunc)(Xt ? Xt->t : Real(0));
|
||||||
return (*tfunc)(Xt->t);
|
}
|
||||||
else
|
|
||||||
return (*tfunc)(Real(0));
|
|
||||||
|
Real ConstTimeFunc::deriv (const Vec3& X, int dir) const
|
||||||
|
{
|
||||||
|
if (dir < 4) return Real(0);
|
||||||
|
|
||||||
|
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
||||||
|
return tfunc->deriv(Xt ? Xt->t : Real(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,14 +294,24 @@ Real SpaceTimeFunc::evaluate (const Vec3& X) const
|
|||||||
Real SpaceTimeFunc::deriv (const Vec3& X, int dir) const
|
Real SpaceTimeFunc::deriv (const Vec3& X, int dir) const
|
||||||
{
|
{
|
||||||
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
||||||
return sfunc->deriv(X,dir) * (*tfunc)(Xt ? Xt->t : Real(0));
|
if (dir < 4)
|
||||||
|
return sfunc->deriv(X,dir) * (*tfunc)(Xt ? Xt->t : Real(0));
|
||||||
|
else
|
||||||
|
return (*sfunc)(X) * tfunc->deriv(Xt ? Xt->t : Real(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Real SpaceTimeFunc::dderiv (const Vec3& X, int dir1, int dir2) const
|
Real SpaceTimeFunc::dderiv (const Vec3& X, int dir1, int dir2) const
|
||||||
{
|
{
|
||||||
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
||||||
return sfunc->dderiv(X,dir1,dir2) * (*tfunc)(Xt ? Xt->t : Real(0));
|
if (dir1 < 4 && dir2 < 4)
|
||||||
|
return sfunc->dderiv(X,dir1,dir2) * (*tfunc)(Xt ? Xt->t : Real(0));
|
||||||
|
else if (dir1 < 4)
|
||||||
|
return sfunc->deriv(X,dir1) * tfunc->deriv(Xt ? Xt->t : Real(0));
|
||||||
|
else if (dir2 < 4)
|
||||||
|
return sfunc->deriv(X,dir2) * tfunc->deriv(Xt ? Xt->t : Real(0));
|
||||||
|
else
|
||||||
|
return Real(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -465,6 +481,26 @@ Real Interpolate1D::evaluate (const Vec3& X) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Real Interpolate1D::deriv (const Vec3& X, int ddir) const
|
||||||
|
{
|
||||||
|
Real res = Real(0);
|
||||||
|
if (ddir == dir+1)
|
||||||
|
res = lfunc.deriv(X[dir]);
|
||||||
|
else if (ddir > 3)
|
||||||
|
res = lfunc(X[dir]);
|
||||||
|
else
|
||||||
|
return res;
|
||||||
|
|
||||||
|
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
||||||
|
if (Xt && time > Real(0) && Xt->t < time)
|
||||||
|
res *= (ddir < 4 ? Xt->t : 1.0)/time;
|
||||||
|
else if (ddir > 3)
|
||||||
|
res = Real(0);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
The functions are assumed on the general form
|
The functions are assumed on the general form
|
||||||
\f[ f({\bf X},t) = A * g({\bf X}) * h(t) \f]
|
\f[ f({\bf X},t) = A * g({\bf X}) * h(t) \f]
|
||||||
|
@ -235,7 +235,7 @@ protected:
|
|||||||
|
|
||||||
class ConstTimeFunc : public RealFunc
|
class ConstTimeFunc : public RealFunc
|
||||||
{
|
{
|
||||||
const ScalarFunc* tfunc; //!< The time dependent function value
|
const ScalarFunc* tfunc; //!< The time-dependent function value
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief Constructor initializing the function value.
|
//! \brief Constructor initializing the function value.
|
||||||
@ -248,6 +248,9 @@ public:
|
|||||||
//! \brief Returns whether the function is time-independent or not.
|
//! \brief Returns whether the function is time-independent or not.
|
||||||
virtual bool isConstant() const { return tfunc->isZero(); }
|
virtual bool isConstant() const { return tfunc->isZero(); }
|
||||||
|
|
||||||
|
//! \brief Returns first-derivative of the function.
|
||||||
|
virtual Real deriv(const Vec3& X, int dir) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Evaluates the time-varying function.
|
//! \brief Evaluates the time-varying function.
|
||||||
virtual Real evaluate(const Vec3& X) const;
|
virtual Real evaluate(const Vec3& X) const;
|
||||||
@ -497,8 +500,8 @@ class StepXFunc : public RealFunc
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief Constructor initializing the function parameters.
|
//! \brief Constructor initializing the function parameters.
|
||||||
explicit StepXFunc(Real v, Real X0 = Real(0), Real X1 = Real(1), char dir = 'X')
|
explicit StepXFunc(Real v, Real a = Real(0), Real b = Real(1), char dir = 'X')
|
||||||
: fv(v), x0(X0), x1(X1), d(dir) {}
|
: fv(v), x0(a), x1(b), d(dir) {}
|
||||||
|
|
||||||
//! \brief Returns whether the function is identically zero or not.
|
//! \brief Returns whether the function is identically zero or not.
|
||||||
virtual bool isZero() const { return fv == Real(0); }
|
virtual bool isZero() const { return fv == Real(0); }
|
||||||
@ -561,6 +564,9 @@ public:
|
|||||||
//! \brief Returns whether the function is time-independent or not.
|
//! \brief Returns whether the function is time-independent or not.
|
||||||
virtual bool isConstant() const { return time <= Real(0); }
|
virtual bool isConstant() const { return time <= Real(0); }
|
||||||
|
|
||||||
|
//! \brief Returns first-derivative of the function.
|
||||||
|
virtual Real deriv(const Vec3&, int ddir) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Evaluates the function by interpolation.
|
//! \brief Evaluates the function by interpolation.
|
||||||
virtual Real evaluate(const Vec3& X) const;
|
virtual Real evaluate(const Vec3& X) const;
|
||||||
|
@ -41,6 +41,17 @@ Vec3 TractionField::evaluate (const Vec3& x, const Vec3& n) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 TractionField::deriv (const Vec3& x, const Vec3& n) const
|
||||||
|
{
|
||||||
|
if (sigma) // symmetric tensor field
|
||||||
|
return sigma->deriv(x,4) * n;
|
||||||
|
else if (sigmaN) // non-symmetric tensor field
|
||||||
|
return sigmaN->deriv(x,4) * n;
|
||||||
|
else // zero tensor field
|
||||||
|
return Vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TractionField::isZero () const
|
bool TractionField::isZero () const
|
||||||
{
|
{
|
||||||
if (sigma)
|
if (sigma)
|
||||||
@ -79,6 +90,31 @@ Vec3 PressureField::evaluate (const Vec3& x, const Vec3& n) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 PressureField::deriv (const Vec3& x, const Vec3& n) const
|
||||||
|
{
|
||||||
|
if (!pressure) // zero pressure field
|
||||||
|
return Vec3();
|
||||||
|
|
||||||
|
if (pdir < 1 && !pdfn) // normal pressure
|
||||||
|
return pressure->deriv(x,4) * n;
|
||||||
|
|
||||||
|
Vec3 t;
|
||||||
|
if (pdfn) // pressure direction specified as a function
|
||||||
|
{
|
||||||
|
t = (*pdfn)(x);
|
||||||
|
t.normalize();
|
||||||
|
t *= pressure->deriv(x,4);
|
||||||
|
}
|
||||||
|
else if (pdir > 0) // pressure acting in global pdir direction
|
||||||
|
t[(pdir-1)%3] = pressure->deriv(x,4);
|
||||||
|
|
||||||
|
if (pdir > 3) // normal pressure in global pdir direction
|
||||||
|
t = (t*n) * n;
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ForceDirField::~ForceDirField ()
|
ForceDirField::~ForceDirField ()
|
||||||
{
|
{
|
||||||
delete force;
|
delete force;
|
||||||
|
@ -47,6 +47,11 @@ public:
|
|||||||
//! \brief Returns whether the function is identically zero or not.
|
//! \brief Returns whether the function is identically zero or not.
|
||||||
virtual bool isZero() const;
|
virtual bool isZero() const;
|
||||||
|
|
||||||
|
//! \brief Returns the time-derivative of the function.
|
||||||
|
//! \param[in] x Global coordinates of evaluation point
|
||||||
|
//! \param[in] n Outward-directed unit normal vector at evaluation point
|
||||||
|
virtual Vec3 deriv(const Vec3& x, const Vec3& n) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Evaluates the traction field function at the specified point.
|
//! \brief Evaluates the traction field function at the specified point.
|
||||||
//! \param[in] x Global coordinates of evaluation point
|
//! \param[in] x Global coordinates of evaluation point
|
||||||
@ -95,6 +100,11 @@ public:
|
|||||||
//! \brief Returns whether the function is identically zero or not.
|
//! \brief Returns whether the function is identically zero or not.
|
||||||
virtual bool isZero() const { return pressure ? pressure->isZero() : true; }
|
virtual bool isZero() const { return pressure ? pressure->isZero() : true; }
|
||||||
|
|
||||||
|
//! \brief Returns the time-derivative of the function.
|
||||||
|
//! \param[in] x Global coordinates of evaluation point
|
||||||
|
//! \param[in] n Outward-directed unit normal vector at evaluation point
|
||||||
|
virtual Vec3 deriv(const Vec3& x, const Vec3& n) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Evaluates the traction field function at the specified point.
|
//! \brief Evaluates the traction field function at the specified point.
|
||||||
//! \param[in] x Global coordinates of evaluation point
|
//! \param[in] x Global coordinates of evaluation point
|
||||||
|
Loading…
Reference in New Issue
Block a user