changed: use a common implementation for setNoDims()
add a helper template and specialize this for the types instead. preparation for upcoming changes to workaround c++'s inability to partially specialize member functions
This commit is contained in:
parent
abbf8a2dd1
commit
09cf3e55e5
|
@ -119,6 +119,63 @@ std::vector<std::string> splitComps (const std::string& functions,
|
|||
return comps;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Helper template to get size and dimension of a return type.
|
||||
*/
|
||||
|
||||
template<class ArgType>
|
||||
std::pair<size_t,size_t> getNoDims(size_t psize);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Template specialization for Vec3.
|
||||
*/
|
||||
|
||||
template<>
|
||||
std::pair<size_t,size_t> getNoDims<Vec3>(size_t psize)
|
||||
{
|
||||
return {psize, psize};
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Template specialization for Tensor.
|
||||
*/
|
||||
|
||||
template<>
|
||||
std::pair<size_t,size_t> getNoDims<Tensor>(size_t psize)
|
||||
{
|
||||
size_t nsd = 0;
|
||||
if (psize > 8)
|
||||
nsd = 3;
|
||||
else if (psize > 3)
|
||||
nsd = 2;
|
||||
else if (psize > 0)
|
||||
nsd = 1;
|
||||
|
||||
return {nsd, nsd*nsd};
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Template specialization for SymmTensor.
|
||||
*/
|
||||
|
||||
template<>
|
||||
std::pair<size_t,size_t> getNoDims<SymmTensor>(size_t psize)
|
||||
{
|
||||
size_t nsd = 0;
|
||||
if (psize > 5)
|
||||
nsd = 3;
|
||||
else if (psize > 2)
|
||||
nsd = 2;
|
||||
else if (psize > 0)
|
||||
nsd = 1;
|
||||
|
||||
return {nsd, psize == 4 ? 4 : (nsd+1)*nsd/2};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -402,6 +459,13 @@ Ret EvalMultiFunction<ParentFunc,Ret>::evaluate (const Vec3& X) const
|
|||
}
|
||||
|
||||
|
||||
template <class ParentFunc, class Ret>
|
||||
void EvalMultiFunction<ParentFunc,Ret>::setNoDims ()
|
||||
{
|
||||
std::tie(nsd, this->ncmp) = getNoDims<Ret>(this->p.size());
|
||||
}
|
||||
|
||||
|
||||
template<class ParentFunc, class Ret>
|
||||
Ret EvalMultiFunction<ParentFunc,Ret>::deriv (const Vec3& X, int dir) const
|
||||
{
|
||||
|
@ -424,34 +488,6 @@ Ret EvalMultiFunction<ParentFunc,Ret>::dderiv (const Vec3& X, int d1, int d2) co
|
|||
}
|
||||
|
||||
|
||||
template<>
|
||||
void TensorFuncExpr::setNoDims ()
|
||||
{
|
||||
if (p.size() > 8)
|
||||
nsd = 3;
|
||||
else if (p.size() > 3)
|
||||
nsd = 2;
|
||||
else if (p.size() > 0)
|
||||
nsd = 1;
|
||||
|
||||
ncmp = nsd*nsd;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void STensorFuncExpr::setNoDims ()
|
||||
{
|
||||
if (p.size() > 5)
|
||||
nsd = 3;
|
||||
else if (p.size() > 2)
|
||||
nsd = 2;
|
||||
else if (p.size() > 0)
|
||||
nsd = 1;
|
||||
|
||||
ncmp = p.size() == 4 ? 4 : (nsd+1)*nsd/2;
|
||||
}
|
||||
|
||||
|
||||
template class EvalMultiFunction<VecFunc,Vec3>;
|
||||
template class EvalMultiFunction<TensorFunc,Tensor>;
|
||||
template class EvalMultiFunction<STensorFunc,SymmTensor>;
|
||||
|
|
|
@ -214,9 +214,12 @@ public:
|
|||
func->setParam(name, value);
|
||||
}
|
||||
|
||||
//! \brief Returns number of spatial dimension.
|
||||
size_t getNoSpaceDim() const { return nsd; }
|
||||
|
||||
protected:
|
||||
//! \brief Sets the number of spatial dimensions (default implementation).
|
||||
void setNoDims() { ParentFunc::ncmp = nsd = p.size(); }
|
||||
void setNoDims();
|
||||
|
||||
//! \brief Evaluates the function expressions.
|
||||
Ret evaluate(const Vec3& X) const override;
|
||||
|
@ -229,10 +232,4 @@ using TensorFuncExpr = EvalMultiFunction<TensorFunc,Tensor>;
|
|||
//! Symmetric tensor-valued function expression
|
||||
using STensorFuncExpr = EvalMultiFunction<STensorFunc,SymmTensor>;
|
||||
|
||||
//! \brief Specialization for tensor functions.
|
||||
template<> void TensorFuncExpr::setNoDims();
|
||||
|
||||
//! \brief Specialization for symmetric tensor functions.
|
||||
template<> void STensorFuncExpr::setNoDims();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,24 @@ TEST(TestVecFunc, Evaluate)
|
|||
}
|
||||
|
||||
|
||||
TEST(TestVecFuncExpr, NumDimensions)
|
||||
{
|
||||
const char* func1 = "x";
|
||||
const char* func2 = "x | y";
|
||||
const char* func3 = "x | y | z";
|
||||
|
||||
VecFuncExpr f1(func1);
|
||||
EXPECT_EQ(f1.getNoSpaceDim(), 1);
|
||||
EXPECT_EQ(f1.dim(), 1);
|
||||
VecFuncExpr f2(func2);
|
||||
EXPECT_EQ(f2.getNoSpaceDim(), 2);
|
||||
EXPECT_EQ(f2.dim(), 2);
|
||||
VecFuncExpr f3(func3);
|
||||
EXPECT_EQ(f3.getNoSpaceDim(), 3);
|
||||
EXPECT_EQ(f3.dim(), 3);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestTensorFunc, Evaluate)
|
||||
{
|
||||
const char* func = "sin(x) | cos (y) | exp(z) | sin(x)*cos(y)";
|
||||
|
@ -381,6 +399,24 @@ TEST(TestTensorFunction, Hessian3D)
|
|||
}
|
||||
|
||||
|
||||
TEST(TestTensorFuncExpr, NumDimensions)
|
||||
{
|
||||
const char* func1 = "x";
|
||||
const char* func2 = "x | y | z | x";
|
||||
const char* func3 = "x | y | z | x | y | z | x | y | z";
|
||||
|
||||
TensorFuncExpr f1(func1);
|
||||
EXPECT_EQ(f1.getNoSpaceDim(), 1);
|
||||
EXPECT_EQ(f1.dim(), 1);
|
||||
TensorFuncExpr f2(func2);
|
||||
EXPECT_EQ(f2.getNoSpaceDim(), 2);
|
||||
EXPECT_EQ(f2.dim(), 4);
|
||||
TensorFuncExpr f3(func3);
|
||||
EXPECT_EQ(f3.getNoSpaceDim(), 3);
|
||||
EXPECT_EQ(f3.dim(), 9);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestSTensorFunc, Evaluate2D)
|
||||
{
|
||||
const char* func = "sin(x) | cos (y) | exp(z)";
|
||||
|
@ -639,6 +675,24 @@ TEST(TestSTensorFunction, Gradient3DFD)
|
|||
}
|
||||
|
||||
|
||||
TEST(TestSTensorFuncExpr, NumDimensions)
|
||||
{
|
||||
const char* func1 = "x";
|
||||
const char* func2 = "x | y | z";
|
||||
const char* func3 = "x | y | z | x | y | z";
|
||||
|
||||
STensorFuncExpr f1(func1);
|
||||
EXPECT_EQ(f1.getNoSpaceDim(), 1);
|
||||
EXPECT_EQ(f1.dim(), 1);
|
||||
STensorFuncExpr f2(func2);
|
||||
EXPECT_EQ(f2.getNoSpaceDim(), 2);
|
||||
EXPECT_EQ(f2.dim(), 3);
|
||||
STensorFuncExpr f3(func3);
|
||||
EXPECT_EQ(f3.getNoSpaceDim(), 3);
|
||||
EXPECT_EQ(f3.dim(), 6);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalFunction, ExtraParam)
|
||||
{
|
||||
EvalFunction f("x*foo");
|
||||
|
|
Loading…
Reference in New Issue
Block a user