Commit 62841d3c authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

ElementFileWriter updated and some corrections in DOFVector

parent f5e012b5
...@@ -324,6 +324,9 @@ namespace AMDiS { ...@@ -324,6 +324,9 @@ namespace AMDiS {
calculateElementMatrix(elInfo, elementMatrix); calculateElementMatrix(elInfo, elementMatrix);
} }
// eventuell einfach
// vec = elementMatrix*uhOldLoc;
// schreiben
for (int i = 0; i < nRow; i++) { for (int i = 0; i < nRow; i++) {
double val = 0.0; double val = 0.0;
for (int j = 0; j < nCol; j++) for (int j = 0; j < nCol; j++)
......
...@@ -43,9 +43,10 @@ namespace AMDiS { ...@@ -43,9 +43,10 @@ namespace AMDiS {
void CouplingIterationInterface::beginIteration(AdaptInfo *adaptInfo) void CouplingIterationInterface::beginIteration(AdaptInfo *adaptInfo)
{ FUNCNAME("CouplingIterationInterface::beginIteration()"); { FUNCNAME("CouplingIterationInterface::beginIteration()");
MSG("\n"); MSG("\n");
int nTimesteps = (adaptInfo->getNumberOfTimesteps() ? adaptInfo->getNumberOfTimesteps() : (adaptInfo->getEndTime()-adaptInfo->getStartTime())/adaptInfo->getTimestep());
MSG("begin of iteration number: %d/%d\n", MSG("begin of iteration number: %d/%d\n",
adaptInfo->getTimestepNumber() + 1, adaptInfo->getTimestepNumber() + 1,
adaptInfo->getNumberOfTimesteps()); nTimesteps);
MSG("==================================================\n"); MSG("==================================================\n");
}; };
......
...@@ -166,7 +166,6 @@ namespace AMDiS { ...@@ -166,7 +166,6 @@ namespace AMDiS {
if (initMesh && meshes[i]) if (initMesh && meshes[i])
refinementManager->globalRefine(meshes[i], globalRefinements); refinementManager->globalRefine(meshes[i], globalRefinements);
} }
} }
void createRefCoarseManager() void createRefCoarseManager()
......
...@@ -934,13 +934,6 @@ namespace AMDiS { ...@@ -934,13 +934,6 @@ namespace AMDiS {
TOut integrate_VecAndCoords(const DOFVector<T> &vec, TOut integrate_VecAndCoords(const DOFVector<T> &vec,
BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct); BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct);
template<typename TOut, typename T>
TOut integrate_VecAndCoords(const DOFVector<T> &vec,
BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct)
{
return integrate(vec, fct);
}
/// Computes the integral: \f$ \int f(\{v_i(\vec{x})\}_i)\,\text{d}\vec{x}\f$ /// Computes the integral: \f$ \int f(\{v_i(\vec{x})\}_i)\,\text{d}\vec{x}\f$
double integrateGeneral(const vector<DOFVector<double>*> &vecs, double integrateGeneral(const vector<DOFVector<double>*> &vecs,
AbstractFunction<double, vector<double> > *fct); AbstractFunction<double, vector<double> > *fct);
......
...@@ -475,7 +475,7 @@ namespace AMDiS { ...@@ -475,7 +475,7 @@ namespace AMDiS {
const DOFAdmin* admin = this->getFeSpace()->getAdmin(); const DOFAdmin* admin = this->getFeSpace()->getAdmin();
int nBasFcts = basFct->getNumber(); int nBasFcts = basFct->getNumber();
std::vector<DegreeOfFreedom> myLocalIndices(nBasFcts); std::vector<DegreeOfFreedom> myLocalIndices(nBasFcts);
mtl::dense_vector<double> fctInterpolValues(nBasFcts); mtl::dense_vector<T> fctInterpolValues(nBasFcts);
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(this->getFeSpace()->getMesh(), -1, ElInfo *elInfo = stack.traverseFirst(this->getFeSpace()->getMesh(), -1,
...@@ -513,14 +513,14 @@ namespace AMDiS { ...@@ -513,14 +513,14 @@ namespace AMDiS {
else else
flag |= Mesh::CALL_EL_LEVEL; flag |= Mesh::CALL_EL_LEVEL;
double result = 0.0; T result; nullify(result);
int nPoints = quadFast->getNumPoints(); int nPoints = quadFast->getNumPoints();
mtl::dense_vector<T> uh_vec(nPoints); mtl::dense_vector<T> uh_vec(nPoints);
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, meshLevel, flag); ElInfo *elInfo = stack.traverseFirst(mesh, meshLevel, flag);
while (elInfo) { while (elInfo) {
double det = elInfo->getDet(); double det = elInfo->getDet();
double normT = 0.0; T normT; nullify(normT);
this->getVecAtQPs(elInfo, NULL, quadFast, uh_vec); this->getVecAtQPs(elInfo, NULL, quadFast, uh_vec);
for (int iq = 0; iq < nPoints; iq++) for (int iq = 0; iq < nPoints; iq++)
normT += quadFast->getWeight(iq) * (uh_vec[iq]); normT += quadFast->getWeight(iq) * (uh_vec[iq]);
...@@ -769,7 +769,7 @@ namespace AMDiS { ...@@ -769,7 +769,7 @@ namespace AMDiS {
template<typename TOut, typename T> template<typename TOut, typename T>
TOut integrate_VecAndCoords(const DOFVector<T> &vec, TOut integrate_VecAndCoords(const DOFVector<T> &vec,
BinaryAbstractFunction<T, T, WorldVector<double> > *fct) BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct)
{ {
FUNCNAME("integrate_VecAndCoords()"); FUNCNAME("integrate_VecAndCoords()");
......
...@@ -106,7 +106,7 @@ namespace AMDiS { ...@@ -106,7 +106,7 @@ namespace AMDiS {
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
ElementFileWriter::writeFile(vec, mesh, filename, "", level); ElementFileWriter::writeFile(vec, mesh, filename, ".vtu", level);
} }
......
...@@ -195,6 +195,11 @@ namespace AMDiS { ...@@ -195,6 +195,11 @@ namespace AMDiS {
void ElInfo::fillElInfo(const MacroElement *mel, int refinementPathLength, unsigned long refinementPath) void ElInfo::fillElInfo(const MacroElement *mel, int refinementPathLength, unsigned long refinementPath)
{ {
if (refinementPathLength == 0) {
fillMacroInfo(mel);
return;
}
std::vector<ElInfo*> elInfo; std::vector<ElInfo*> elInfo;
elInfo.push_back(mesh->createNewElInfo()); elInfo.push_back(mesh->createNewElInfo());
elInfo.push_back(this); elInfo.push_back(this);
...@@ -208,6 +213,7 @@ namespace AMDiS { ...@@ -208,6 +213,7 @@ namespace AMDiS {
} }
if (i%2 == 0) if (i%2 == 0)
*this = *elInfo[0]; *this = *elInfo[0];
delete elInfo[0]; delete elInfo[0];
} }
......
...@@ -181,6 +181,15 @@ struct Norm2Sqr_comp3 : public TertiaryAbstractFunction<T,T,T,T> ...@@ -181,6 +181,15 @@ struct Norm2Sqr_comp3 : public TertiaryAbstractFunction<T,T,T,T>
T operator()(const T &v1, const T &v2, const T &v3) const { return sqr(v1)+sqr(v2)+sqr(v3); } T operator()(const T &v1, const T &v2, const T &v3) const { return sqr(v1)+sqr(v2)+sqr(v3); }
}; };
template<typename T>
struct Vec1WorldVec : public AbstractFunction<WorldVector<T>,T>
{
WorldVector<T> operator()(const T &v0) const {
WorldVector<T> result;
result[0]=v0;
return result;
}
};
template<typename T> template<typename T>
struct Vec2WorldVec : public BinaryAbstractFunction<WorldVector<T>,T,T> struct Vec2WorldVec : public BinaryAbstractFunction<WorldVector<T>,T,T>
{ {
......
...@@ -438,6 +438,11 @@ namespace AMDiS { ...@@ -438,6 +438,11 @@ namespace AMDiS {
initIntern(); initIntern();
if (debugInfo == -1) if (debugInfo == -1)
debugInfo = singlett->getMsgInfo(); debugInfo = singlett->getMsgInfo();
else {
int swap(debugInfo);
debugInfo = singlett->getMsgInfo();
singlett->msgInfo=swap;
}
std::string valStr; std::string valStr;
int error_code = singlett->checkedGet(tag, valStr); int error_code = singlett->checkedGet(tag, valStr);
...@@ -456,6 +461,7 @@ namespace AMDiS { ...@@ -456,6 +461,7 @@ namespace AMDiS {
std::cout << "Parameter '" << tag << "'" std::cout << "Parameter '" << tag << "'"
<< " initialized with: " << value << std::endl; << " initialized with: " << value << std::endl;
} }
singlett->msgInfo = debugInfo;
} }
......
...@@ -215,6 +215,7 @@ namespace AMDiS { ...@@ -215,6 +215,7 @@ namespace AMDiS {
friend class MacroInfo; friend class MacroInfo;
friend class MacroReader; friend class MacroReader;
friend class ElInfo;
friend class ElInfo1d; friend class ElInfo1d;
friend class ElInfo2d; friend class ElInfo2d;
friend class ElInfo3d; friend class ElInfo3d;
......
...@@ -1015,7 +1015,7 @@ namespace AMDiS { ...@@ -1015,7 +1015,7 @@ namespace AMDiS {
out << name << "\n"; out << name << "\n";
SerUtil::serialize(out, dim); // SerUtil::serialize(out, dim);
SerUtil::serialize(out, nVertices); SerUtil::serialize(out, nVertices);
SerUtil::serialize(out, nEdges); SerUtil::serialize(out, nEdges);
SerUtil::serialize(out, nLeaves); SerUtil::serialize(out, nLeaves);
...@@ -1095,8 +1095,8 @@ namespace AMDiS { ...@@ -1095,8 +1095,8 @@ namespace AMDiS {
in.get(); in.get();
int oldVal = dim; int oldVal = dim;
SerUtil::deserialize(in, dim); // SerUtil::deserialize(in, dim);
TEST_EXIT_DBG(oldVal == 0 || dim == oldVal)("Invalid dimension!\n"); // TEST_EXIT_DBG(oldVal == 0 || dim == oldVal)("Invalid dimension!\n");
SerUtil::deserialize(in, nVertices); SerUtil::deserialize(in, nVertices);
SerUtil::deserialize(in, nEdges); SerUtil::deserialize(in, nEdges);
......
...@@ -1365,4 +1365,87 @@ namespace AMDiS { ...@@ -1365,4 +1365,87 @@ namespace AMDiS {
} }
// ========== Vec2AtQP_IJ_SOT ==========
Vec2AtQP_IJ_SOT::Vec2AtQP_IJ_SOT(DOFVectorBase<double> *dv1,
DOFVectorBase<double> *dv2,
BinaryAbstractFunction<double, double, double> *af,
int x_i, int x_j)
: SecondOrderTerm(af ? af->getDegree() : dv1->getFeSpace()->getBasisFcts()->getDegree()+dv2->getFeSpace()->getBasisFcts()->getDegree()),
vec1(dv1),
vec2(dv2),
f(af),
xi(x_i), xj(x_j)
{
setSymmetric(xi == xj);
TEST_EXIT(dv1)("No vector 1!\n");
TEST_EXIT(dv2)("No vector 2!\n");
auxFeSpaces.insert(dv1->getFeSpace());
auxFeSpaces.insert(dv2->getFeSpace());
}
void Vec2AtQP_IJ_SOT::initElement(const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
getVectorAtQPs(vec1, elInfo, subAssembler, quad, vecAtQPs1);
getVectorAtQPs(vec2, elInfo, subAssembler, quad, vecAtQPs2);
}
void Vec2AtQP_IJ_SOT::getLALt(const ElInfo *elInfo,
vector<mtl::dense2D<double> > &LALt) const
{
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
const int nPoints = static_cast<int>(LALt.size());
if (f) {
for (int iq = 0; iq < nPoints; iq++)
lalt_kl(grdLambda, xi, xj, LALt[iq], (*f)(vecAtQPs1[iq], vecAtQPs2[iq]));
} else {
for (int iq = 0; iq < nPoints; iq++)
lalt_kl(grdLambda, xi, xj, LALt[iq], vecAtQPs1[iq] * vecAtQPs2[iq]);
}
}
void Vec2AtQP_IJ_SOT::eval(int nPoints,
const mtl::dense_vector<double>& uhAtQP,
const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
mtl::dense_vector<double>& result,
double fac)
{
if (num_rows(D2UhAtQP) > 0) {
if (f) {
for (int iq = 0; iq < nPoints; iq++) {
double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]);
result[iq] += D2UhAtQP[iq][xi][xj] * factor * fac;
}
} else {
for (int iq = 0; iq < nPoints; iq++) {
double factor = vecAtQPs1[iq] * vecAtQPs2[iq];
result[iq] += D2UhAtQP[iq][xi][xj] * factor * fac;
}
}
}
}
void Vec2AtQP_IJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
std::vector<WorldVector<double> > &result)
{
int nPoints = grdUhAtQP.size();
if (f) {
for (int iq = 0; iq < nPoints; iq++) {
double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]);
result[iq][xi] += grdUhAtQP[iq][xj] * factor;
}
} else {
for (int iq = 0; iq < nPoints; iq++) {
double factor = vecAtQPs1[iq] * vecAtQPs2[iq];
result[iq][xi] += grdUhAtQP[iq][xj] * factor;
}
}
}
} }
...@@ -361,7 +361,7 @@ namespace AMDiS { ...@@ -361,7 +361,7 @@ namespace AMDiS {
{ {
public: public:
/// Constructor. /// Constructor.
VecAtQP_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af); VecAtQP_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af = NULL);
/// Implementation of \ref OperatorTerm::initElement(). /// Implementation of \ref OperatorTerm::initElement().
void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
...@@ -411,8 +411,9 @@ namespace AMDiS { ...@@ -411,8 +411,9 @@ namespace AMDiS {
{ {
public: public:
/// Constructor. /// Constructor.
Vec2AtQP_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, Vec2AtQP_SOT(DOFVectorBase<double> *dv1,
BinaryAbstractFunction<double, double, double> *af); DOFVectorBase<double> *dv2,
BinaryAbstractFunction<double, double, double> *af = NULL);
/// Implementation of \ref OperatorTerm::initElement(). /// Implementation of \ref OperatorTerm::initElement().
void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
...@@ -1145,7 +1146,8 @@ namespace AMDiS { ...@@ -1145,7 +1146,8 @@ namespace AMDiS {
{ {
public: public:
/// Constructor. /// Constructor.
VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af, VecAtQP_IJ_SOT(DOFVectorBase<double> *dv,
AbstractFunction<double, double> *af,
int x_i, int x_j); int x_i, int x_j);
/// Implementation of \ref OperatorTerm::initElement(). /// Implementation of \ref OperatorTerm::initElement().
...@@ -1182,6 +1184,59 @@ namespace AMDiS { ...@@ -1182,6 +1184,59 @@ namespace AMDiS {
int xi, xj; int xi, xj;
}; };
/**
* \ingroup Assembler
*
* \brief
* SecondOrderTerm where A is a WorldMatrix having a in all positions
* except possibly the position IJ, multiplied with a function
* evaluated at the quadrature points of two given DOFVectors:
* \f$ \nabla \cdot f(v(\vec{x}),w(\vec{x})) A \nabla u(\vec{x}) \f$
*/
class Vec2AtQP_IJ_SOT : public SecondOrderTerm
{
public:
/// Constructor.
Vec2AtQP_IJ_SOT(DOFVectorBase<double> *dv1,
DOFVectorBase<double> *dv2,
BinaryAbstractFunction<double, double, double> *af,
int x_i, int x_j);
/// Implementation of \ref OperatorTerm::initElement().
void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
Quadrature *quad = NULL);
/// Implements SecondOrderTerm::getLALt().
void getLALt(const ElInfo *elInfo, vector<mtl::dense2D<double> > &LALt) const;
/// Implements SecondOrderTerm::eval().
void eval(int nPoints,
const mtl::dense_vector<double>& uhAtQP,
const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
mtl::dense_vector<double>& result,
double factor);
/// Implements SecondOrderTerm::weakEval().
void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
std::vector<WorldVector<double> > &result);
protected:
/// DOFVector to be evaluated at quadrature points.
DOFVectorBase<double>* vec1;
DOFVectorBase<double>* vec2;
/// Pointer to an array containing the DOFVector evaluated at quadrature points.
mtl::dense_vector<double> vecAtQPs1;
mtl::dense_vector<double> vecAtQPs2;
/// Function evaluated at \ref vecAtQPs.
BinaryAbstractFunction<double, double, double> *f;
private:
/// Directions for the derivatives.
int xi, xj;
};
} }
#endif #endif
...@@ -681,6 +681,7 @@ template<typename T1, typename T2, typename T3, typename T4> ...@@ -681,6 +681,7 @@ template<typename T1, typename T2, typename T3, typename T4>
inline void transformDOF(T1 val, DOFVector<T2> &vec2, DOFVector<T3> &vec3, DOFVector<T4> &result, TertiaryAbstractFunction<T4, T1, T2, T3> &tertiary_op) inline void transformDOF(T1 val, DOFVector<T2> &vec2, DOFVector<T3> &vec3, DOFVector<T4> &result, TertiaryAbstractFunction<T4, T1, T2, T3> &tertiary_op)
{ transformDOF(val, &vec2, &vec3, &result, &tertiary_op); } { transformDOF(val, &vec2, &vec3, &result, &tertiary_op); }
// =========================================================================================== // ===========================================================================================
// return binary_op(vec, interpol(fct)) // return binary_op(vec, interpol(fct))
...@@ -716,6 +717,40 @@ template<typename T> inline void transformDOFInterpolation( ...@@ -716,6 +717,40 @@ template<typename T> inline void transformDOFInterpolation(
DOFVector<T> &vec, AbstractFunction<T, WorldVector<double> > &fct, DOFVector<T> &result, BinaryAbstractFunction<T, T, T> &binary_op) DOFVector<T> &vec, AbstractFunction<T, WorldVector<double> > &fct, DOFVector<T> &result, BinaryAbstractFunction<T, T, T> &binary_op)
{ transformDOFInterpolation(&vec, &fct, &result, &binary_op); } { transformDOFInterpolation(&vec, &fct, &result, &binary_op); }
// ====================================================================================
template<typename T>
T accumulateDOF_simple(DOFVector<T> *vec,
T value0,
BinaryAbstractFunction<T, T, T> *binary_op)
{
DOFIterator<T> vecIter(vec, USED_DOFS);
T value = value0;
for(vecIter.reset(); !vecIter.end(); ++vecIter)
{
value = (*binary_op)(value, *vecIter);
}
return value;
}
template<typename TOut, typename T1, typename T2>
TOut accumulateDOF_simple(DOFVector<T1> *vec1,
DOFVector<T2> *vec2,
TOut value0,
TertiaryAbstractFunction<TOut, TOut, T1, T2> *tertiary_op)
{
TEST_EXIT(vec1->getFeSpace() == vec2->getFeSpace())("FeSpaces must be equal!\n");
DOFIterator<T1> vec1Iter(vec1, USED_DOFS);
DOFIterator<T2> vec2Iter(vec2, USED_DOFS);
TOut value = value0;
for(vec1Iter.reset(),vec2Iter.reset(); !vec1Iter.end(); ++vec1Iter,++vec2Iter)
{
value = (*tertiary_op)(value, *vec1Iter, *vec2Iter);
}
return value;
}
} }
#endif // AMDIS_TRANSFORM_DOF_H #endif // AMDIS_TRANSFORM_DOF_H
...@@ -126,7 +126,10 @@ namespace AMDiS { ...@@ -126,7 +126,10 @@ namespace AMDiS {
Vec2AtQP_ZOT::Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, Vec2AtQP_ZOT::Vec2AtQP_ZOT(DOFVectorBase<double> *dv1,
DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv2,
BinaryAbstractFunction<double, double, double> *af) BinaryAbstractFunction<double, double, double> *af)
: ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) : ZeroOrderTerm((af ? af->getDegree() : dv1->getFeSpace()->getBasisFcts()->getDegree()+dv2->getFeSpace()->getBasisFcts()->getDegree())),
vec1(dv1),
vec2(dv2),
f(af)
{ {
TEST_EXIT(dv1)("No first vector!\n"); TEST_EXIT(dv1)("No first vector!\n");
TEST_EXIT(dv2)("No second vector!\n"); TEST_EXIT(dv2)("No second vector!\n");
...@@ -156,9 +159,14 @@ namespace AMDiS { ...@@ -156,9 +159,14 @@ namespace AMDiS {
} }
void Vec2AtQP_ZOT::getC(const ElInfo *, int nPoints, ElementVector& C) void Vec2AtQP_ZOT::getC(const ElInfo *, int nPoints, ElementVector& C)
{ {
for (int iq = 0; iq < nPoints; iq++) if (f) {
C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); for (int iq = 0; iq < nPoints; iq++)
C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]);
} else {
for (int iq = 0; iq < nPoints; iq++)
C[iq] += vecAtQPs1[iq] * vecAtQPs2[iq];
}
} }
void Vec2AtQP_ZOT::eval(int nPoints, void Vec2AtQP_ZOT::eval(int nPoints,
...@@ -168,8 +176,13 @@ namespace AMDiS { ...@@ -168,8 +176,13 @@ namespace AMDiS {
mtl::dense_vector<double>& result, mtl::dense_vector<double>& result,
double fac) double fac)
{ {
for (int iq = 0; iq < nPoints; iq++) if (f) {
result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq]; for (int iq = 0; iq < nPoints; iq++)
result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq];
} else {
for (int iq = 0; iq < nPoints; iq++)
result[iq] += fac * vecAtQPs1[iq] * vecAtQPs2[iq] * uhAtQP[iq];
}
} }
...@@ -179,7 +192,13 @@ namespace AMDiS { ...@@ -179,7 +192,13 @@ namespace AMDiS {
DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv2,
DOFVectorBase<double> *dv3, DOFVectorBase<double> *dv3,
TertiaryAbstractFunction<double, double, double, double> *af) TertiaryAbstractFunction<double, double, double, double> *af)
: ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vec3(dv3), f(af) : ZeroOrderTerm((af ? af->getDegree() : dv1->getFeSpace()->getBasisFcts()->getDegree()
+ dv2->getFeSpace()->getBasisFcts()->getDegree()
+ dv3->getFeSpace()->getBasisFcts()->getDegree())),
vec1(dv1),
vec2(dv2),
vec3(dv3),
f(af)