Liebe Gitlab-Nutzerin, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind über den Reiter "Standard" erreichbar.
Die Administratoren


Dear Gitlab user,
it is now possible to log in to our service using the ZIH login/LDAP. The accounts of external users can be accessed via the "Standard" tab.
The administrators

Commit 30debe8f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

several changes in integrate routines of DOFVectors

parent 63c967c1
...@@ -8,8 +8,8 @@ SET(SOURCE_DIR ${AMDIS_SOURCE_DIR}/src) ...@@ -8,8 +8,8 @@ SET(SOURCE_DIR ${AMDIS_SOURCE_DIR}/src)
#TODO: use the cmake build type #TODO: use the cmake build type
SET(MTL_INCLUDE_DIR ${LIB_DIR}/mtl4/ CACHE PATH "mtl4 directory") SET(MTL_INCLUDE_DIR ${LIB_DIR}/mtl4/ CACHE PATH "mtl4 directory")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -Wall -DDEBUG=0") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -Wall -Wno-unused-but-set-variable -DDEBUG=0")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -DDEBUG=1 -O0") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wno-unused-but-set-variable -DDEBUG=1 -O0")
if(NOT CurrentRevision) if(NOT CurrentRevision)
find_package(Subversion) find_package(Subversion)
if(Subversion_FOUND) if(Subversion_FOUND)
......
...@@ -714,193 +714,6 @@ namespace AMDiS { ...@@ -714,193 +714,6 @@ namespace AMDiS {
} }
double integrate(const DOFVector<double> &vec1,
const DOFVector<double> &vec2,
BinaryAbstractFunction<double, double, double> *fct)
{
if (vec1.getFeSpace()->getMesh() == vec2.getFeSpace()->getMesh())
return intSingleMesh(vec1, vec2, fct);
else
return intDualMesh(vec1, vec2, fct);
}
double intSingleMesh(const DOFVector<double> &vec1,
const DOFVector<double> &vec2,
BinaryAbstractFunction<double, double, double> *fct)
{
FUNCNAME("intDualmesh()");
TEST_EXIT(fct)("No function defined!\n");
int deg = std::max(fct->getDegree(),
2 * vec1.getFeSpace()->getBasisFcts()->getDegree());
Quadrature* quad =
Quadrature::provideQuadrature(vec1.getFeSpace()->getMesh()->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(vec1.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
mtl::dense_vector<double> qp1(fastQuad->getNumPoints());
mtl::dense_vector<double> qp2(fastQuad->getNumPoints());
double value = 0.0;
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(vec1.getFeSpace()->getMesh(), -1, traverseFlag);
while (elInfo) {
vec1.getVecAtQPs(elInfo, quad, fastQuad, qp1);
vec2.getVecAtQPs(elInfo, quad, fastQuad, qp2);
double tmp = 0.0;
for (int iq = 0; iq < fastQuad->getNumPoints(); iq++)
tmp += fastQuad->getWeight(iq) * (*fct)(qp1[iq], qp2[iq]);
value += tmp * elInfo->getDet();
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localValue = value;
MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM);
#endif
return value;
}
double intDualMesh(const DOFVector<double> &vec1,
const DOFVector<double> &vec2,
BinaryAbstractFunction<double, double, double> *fct)
{
FUNCNAME("intDualmesh()");
TEST_EXIT(fct)("No function defined!\n");
int deg = std::max(fct->getDegree(),
2 * vec1.getFeSpace()->getBasisFcts()->getDegree());
Quadrature* quad =
Quadrature::provideQuadrature(vec1.getFeSpace()->getMesh()->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(vec1.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
mtl::dense_vector<double> qp1(fastQuad->getNumPoints());
mtl::dense_vector<double> qp2(fastQuad->getNumPoints());
double value = 0.0;
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
DualTraverse dualTraverse;
DualElInfo dualElInfo;
bool cont = dualTraverse.traverseFirst(vec1.getFeSpace()->getMesh(),
vec2.getFeSpace()->getMesh(),
-1, -1, traverseFlag, traverseFlag,
dualElInfo);
while (cont) {
vec1.getVecAtQPs(dualElInfo.smallElInfo, dualElInfo.largeElInfo, quad, NULL, qp1);
vec2.getVecAtQPs(dualElInfo.smallElInfo, dualElInfo.largeElInfo, quad, NULL, qp2);
double tmp = 0.0;
for (int iq = 0; iq < quad->getNumPoints(); iq++)
tmp += quad->getWeight(iq) * (*fct)(qp1[iq], qp2[iq]);
value += tmp * dualElInfo.smallElInfo->getDet();
cont = dualTraverse.traverseNext(dualElInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localValue = value;
MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM);
#endif
return value;
}
double integrate(const DOFVector<double> &vec,
AbstractFunction<double, WorldVector<double> > *fct)
{
FUNCNAME("integrate()");
TEST_EXIT(fct)("No function defined!\n");
const FiniteElemSpace *feSpace = vec.getFeSpace();
Mesh *mesh = feSpace->getMesh();
int deg = std::max(fct->getDegree(), 2 * feSpace->getBasisFcts()->getDegree());
Quadrature* quad = Quadrature::provideQuadrature(mesh->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *quad, INIT_PHI);
mtl::dense_vector<double> qp(fastQuad->getNumPoints());
WorldVector<double> coords;
double value = 0.0;
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
while (elInfo) {
vec.getVecAtQPs(elInfo, quad, fastQuad, qp);
double tmp = 0.0;
for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
elInfo->coordToWorld(fastQuad->getLambda(iq), coords);
tmp += fastQuad->getWeight(iq) * (qp[iq] * (*fct)(coords));
}
value += tmp * elInfo->getDet();
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localValue = value;
MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM);
#endif
return value;
}
double integrate(const FiniteElemSpace* feSpace,
AbstractFunction<double, WorldVector<double> > *fct)
{
FUNCNAME("integrate()");
TEST_EXIT(fct)("No function defined!\n");
int deg = std::max(fct->getDegree(), feSpace->getBasisFcts()->getDegree());
Quadrature* quad =
Quadrature::provideQuadrature(feSpace->getMesh()->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *quad, INIT_PHI);
WorldVector<double> coords;
double value = 0.0;
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag);
while (elInfo) {
double tmp = 0.0;
for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
elInfo->coordToWorld(fastQuad->getLambda(iq), coords);
tmp += fastQuad->getWeight(iq) * (*fct)(coords);
}
value += tmp * elInfo->getDet();
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localValue = value;
MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM);
#endif
return value;
}
double integrateGeneral(const std::vector<DOFVector<double>*> &vecs, double integrateGeneral(const std::vector<DOFVector<double>*> &vecs,
AbstractFunction<double, std::vector<double> > *fct) AbstractFunction<double, std::vector<double> > *fct)
{ {
......
...@@ -873,45 +873,88 @@ namespace AMDiS { ...@@ -873,45 +873,88 @@ namespace AMDiS {
std::vector<DOFVector<double>*> *transform(DOFVector<typename GradientType<T>::type> *vec, std::vector<DOFVector<double>*> *transform(DOFVector<typename GradientType<T>::type> *vec,
std::vector<DOFVector<double>*> *res); std::vector<DOFVector<double>*> *res);
/// Computes the integral: \f$ \int f(\vec{x})\,\text{d}\vec{x}\f$
template<typename TOut>
TOut integrate_Coords(const FiniteElemSpace* feSpace,
AbstractFunction<TOut, WorldVector<double> > *fct);
template<typename TOut>
TOut integrate(const FiniteElemSpace* feSpace,
AbstractFunction<TOut, WorldVector<double> > *fct)
{
return integrate_Coords(feSpace, fct);
}
/// Computes the integral: \f$ \int f(v(\vec{x}))\,\text{d}\vec{x}\f$
template<typename TOut, typename T>
TOut integrate_Vec(const DOFVector<T> &vec,
AbstractFunction<TOut, T> *fct);
template<typename TOut, typename T>
TOut integrate(const DOFVector<T> &vec,
AbstractFunction<TOut, T> *fct)
{
return integrate_Vec(vec, fct);
}
/** \brief /** \brief
* Computes the integral of a function that includes two different DOFVectors. This * Computes the integral of a function that includes two different DOFVectors:
* function works also for the case that the DOFVectors are defined on two different * \f$ \int f(v(\vec{x}), w(\vec{x}))\,\text{d}\vec{x}\f$
* This function works also for the case that the DOFVectors are defined on two different
* meshes. * meshes.
*/ */
double integrate(const DOFVector<double> &vec1, template<typename TOut, typename T1, typename T2>
const DOFVector<double> &vec2, TOut integrate_Vec2(const DOFVector<T1> &vec1,
BinaryAbstractFunction<double, double, double> *fct); const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct);
template<typename TOut, typename T1, typename T2>
TOut integrate(const DOFVector<T1> &vec1,
const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct)
{
return integrate_Vec2(vec1, vec2, fct);
}
/// Computes the integral of a function with two DOFVectors defined on the same mesh. /// Computes the integral of a function with two DOFVectors defined on the same mesh.
double intSingleMesh(const DOFVector<double> &vec1, template<typename TOut, typename T1, typename T2>
const DOFVector<double> &vec2, TOut int_Vec2_SingleMesh(const DOFVector<T1> &vec1,
BinaryAbstractFunction<double, double, double> *fct); const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct);
/// Computes the integral of a function with two DOFVectors defined on different meshes. /// Computes the integral of a function with two DOFVectors defined on different meshes.
double intDualMesh(const DOFVector<double> &vec1, template<typename TOut, typename T1, typename T2>
const DOFVector<double> &vec2, TOut int_Vec2_DualMesh(const DOFVector<T1> &vec1,
BinaryAbstractFunction<double, double, double> *fct); const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct);
double integrate(const DOFVector<double> &vec, /// Computes the integral: \f$ \int v(\vec{x}) f(\vec{x})\,\text{d}\vec{x}\f$
AbstractFunction<double, WorldVector<double> > *fct); template<typename T1, typename T2>
typename ProductType<T1,T2>::type integrate_VecTimesCoords(const DOFVector<T1> &vec,
AbstractFunction<T2, WorldVector<double> > *fct);
double integrate(const FiniteElemSpace* feSpace, /// Computes the integral: \f$ \int f(v(\vec{x}), \vec{x})\,\text{d}\vec{x}\f$
AbstractFunction<double, WorldVector<double> > *fct); template<typename TOut, typename T>
TOut integrate_VecAndCoords(const DOFVector<T> &vec,
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$
double integrateGeneral(const std::vector<DOFVector<double>*> &vecs, double integrateGeneral(const std::vector<DOFVector<double>*> &vecs,
AbstractFunction<double, std::vector<double> > *fct); AbstractFunction<double, std::vector<double> > *fct);
/// Computes the integral: \f$ \int f(\{v_i(\vec{x})\}_i,\{\nabla w_i(\vec{x})\}_i)\,\text{d}\vec{x}\f$
double integrateGeneralGradient(const std::vector<DOFVector<double>*> &vecs, double integrateGeneralGradient(const std::vector<DOFVector<double>*> &vecs,
const std::vector<DOFVector<double>*> &grds, const std::vector<DOFVector<double>*> &grds,
BinaryAbstractFunction<double, std::vector<double>, std::vector<WorldVector<double> > > *fct); BinaryAbstractFunction<double, std::vector<double>, std::vector<WorldVector<double> > > *fct);
template<typename T>
T integrate_VecAndCoords(const DOFVector<double> &vec,
BinaryAbstractFunction<T, double, WorldVector<double> > *fct);
template<typename T1, typename T2>
T2 integrate_Vec(const DOFVector<T1> &vec,
AbstractFunction<T2, T1> *fct);
} }
#include "DOFVector.hh" #include "DOFVector.hh"
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include "Operator.h" #include "Operator.h"
#include "Initfile.h" #include "Initfile.h"
#include "Traverse.h" #include "Traverse.h"
#include "DualTraverse.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#include "MpiHelper.h"
#endif
// Defining the interface for MTL4 // Defining the interface for MTL4
namespace mtl { namespace mtl {
...@@ -516,7 +521,7 @@ namespace AMDiS { ...@@ -516,7 +521,7 @@ namespace AMDiS {
FastQuadrature *quadFast = FastQuadrature *quadFast =
FastQuadrature::provideFastQuadrature(this->feSpace->getBasisFcts(), *q, INIT_PHI); FastQuadrature::provideFastQuadrature(this->feSpace->getBasisFcts(), *q, INIT_PHI);
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;
...@@ -524,7 +529,7 @@ namespace AMDiS { ...@@ -524,7 +529,7 @@ namespace AMDiS {
Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET); Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET);
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]);
...@@ -534,18 +539,58 @@ namespace AMDiS { ...@@ -534,18 +539,58 @@ namespace AMDiS {
} }
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localResult = result; mpi::globalAdd(result);
MPI::COMM_WORLD.Allreduce(&localResult, &result, 1, MPI_DOUBLE, MPI_SUM);
#endif #endif
return result; return result;
} }
template<typename T>
T integrate_VecAndCoords(const DOFVector<double> &vec, template<typename TOut>
BinaryAbstractFunction<T, double, WorldVector<double> > *fct) TOut integrate_Coords(const FiniteElemSpace* feSpace,
AbstractFunction<TOut, WorldVector<double> > *fct)
{ {
FUNCNAME("integrate_VecAndCoords()"); FUNCNAME("integrate_Coords()");
TEST_EXIT(fct)("No function defined!\n");
int deg = std::max(fct->getDegree(), feSpace->getBasisFcts()->getDegree());
Quadrature* quad =
Quadrature::provideQuadrature(feSpace->getMesh()->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *quad, INIT_PHI);
WorldVector<double> coords;
TOut value; nullify(value);
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag);
while (elInfo) {
TOut tmp; nullify(tmp);
for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
elInfo->coordToWorld(fastQuad->getLambda(iq), coords);
tmp += fastQuad->getWeight(iq) * (*fct)(coords);
}
value += tmp * elInfo->getDet();
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
mpi::globalAdd(value);
#endif
return value;
}
template<typename TOut, typename T>
TOut integrate_Vec(const DOFVector<T> &vec,
AbstractFunction<TOut, T> *fct)
{
FUNCNAME("integrate_Vec()");
TEST_EXIT(fct)("No function defined!\n"); TEST_EXIT(fct)("No function defined!\n");
...@@ -556,39 +601,184 @@ namespace AMDiS { ...@@ -556,39 +601,184 @@ namespace AMDiS {
FastQuadrature *fastQuad = FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(vec.getFeSpace()->getBasisFcts(), *quad, INIT_PHI); FastQuadrature::provideFastQuadrature(vec.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
mtl::dense_vector<double> qp(fastQuad->getNumPoints()); mtl::dense_vector<T> qp(fastQuad->getNumPoints());
WorldVector<double> coordsAtQP;
T value; TOut value; nullify(value);
nullify(value);
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET; Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(vec.getFeSpace()->getMesh(), -1, traverseFlag); ElInfo *elInfo = stack.traverseFirst(vec.getFeSpace()->getMesh(), -1, traverseFlag);
while (elInfo) { while (elInfo) {
vec.getVecAtQPs(elInfo, quad, fastQuad, qp); vec.getVecAtQPs(elInfo, quad, fastQuad, qp);
T tmp; TOut tmp; nullify(tmp);
nullify(tmp);
for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) { for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
elInfo->coordToWorld(fastQuad->getLambda(iq), coordsAtQP); tmp += fastQuad->getWeight(iq) * (*fct)(qp[iq]);
tmp += fastQuad->getWeight(iq) * (*fct)(qp[iq], coordsAtQP);
} }
value += tmp * elInfo->getDet(); value += tmp * elInfo->getDet();
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
// #ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
// double localValue = value; mpi::globalAdd(value);
// MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM); #endif
// #endif
return value; return value;
} }
template<typename TOut, typename T1, typename T2>
TOut integrate_Vec2(const DOFVector<T1> &vec1,
const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct)
{
if (vec1.getFeSpace()->getMesh() == vec2.getFeSpace()->getMesh())
return int_Vec2_SingleMesh(vec1, vec2, fct);
else
return int_Vec2_DualMesh(vec1, vec2, fct);
}
template<typename TOut, typename T1, typename T2>
TOut int_Vec2_SingleMesh(const DOFVector<T1> &vec1,
const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct)
{
FUNCNAME("intDualmesh()");
TEST_EXIT(fct)("No function defined!\n");
int deg = std::max(fct->getDegree(),
2 * vec1.getFeSpace()->getBasisFcts()->getDegree());
Quadrature* quad =
Quadrature::provideQuadrature(vec1.getFeSpace()->getMesh()->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(vec1.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
mtl::dense_vector<T1> qp1(fastQuad->getNumPoints());
mtl::dense_vector<T2> qp2(fastQuad->getNumPoints());
TOut value; nullify(value);
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(vec1.getFeSpace()->getMesh(), -1, traverseFlag);
while (elInfo) {
vec1.getVecAtQPs(elInfo, quad, fastQuad, qp1);
vec2.getVecAtQPs(elInfo, quad, fastQuad, qp2);
TOut tmp; nullify(tmp);
for (int iq = 0; iq < fastQuad->getNumPoints(); iq++)
tmp += fastQuad->getWeight(iq) * (*fct)(qp1[iq], qp2[iq]);
value += tmp * elInfo->getDet();
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
mpi::globalAdd(value);
#endif
return value;
}
template<typename TOut, typename T1, typename T2>
TOut int_Vec2_DualMesh(const DOFVector<T1> &vec1,
const DOFVector<T2> &vec2,
BinaryAbstractFunction<TOut, T1, T2> *fct)
{
FUNCNAME("intDualmesh()");
TEST_EXIT(fct)("No function defined!\n");
int deg = std::max(fct->getDegree(),
2 * vec1.getFeSpace()->getBasisFcts()->getDegree());
Quadrature* quad =
Quadrature::provideQuadrature(vec1.getFeSpace()->getMesh()->getDim(), deg);
FastQuadrature *fastQuad =
FastQuadrature::provideFastQuadrature(vec1.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
mtl::dense_vector<T1> qp1(fastQuad->getNumPoints());
mtl::dense_vector<T2> qp2(fastQuad->getNumPoints());
TOut value; nullify(value);
Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
DualTraverse dualTraverse;
DualElInfo dualElInfo;
bool cont = dualTraverse.traverseFirst(vec1.getFeSpace()->getMesh(),
vec2.getFeSpace()->getMesh(),
-1, -1, traverseFlag, traverseFlag,
dualElInfo);
while (cont) {
vec1.getVecAtQPs(dualElInfo.smallElInfo, dualElInfo.largeElInfo, quad, NULL, qp1);
vec2.getVecAtQPs(dualElInfo.smallElInfo, dualElInfo.largeElInfo, quad, NULL, qp2);
TOut tmp; nullify(tmp);