Commit 1891d309 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Integration over boundary parts

parent 5a0a3a72
...@@ -160,6 +160,146 @@ namespace AMDiS { ...@@ -160,6 +160,146 @@ namespace AMDiS {
}; };
template<>
double DOFVector<double>::IntOnBoundary(BoundaryType boundaryType,
Quadrature* q) const
{
FUNCNAME("DOFVector<T>::IntOnBoundary()");
Mesh* mesh = this->feSpace->getMesh();
int dim = mesh->getDim();
if (!q) {
int deg = 2 * this->feSpace->getBasisFcts()->getDegree();
q = Quadrature::provideQuadrature(dim - 1, deg);
} else {
TEST_EXIT(q->getDim() == dim-1)
("Provided quadrature has wrong dimension for surfaceQuadrature!\n");
}
// create barycentric coords for each vertex of each side
const Element *refElement = Global::getReferenceElement(dim);
VectorOfFixVecs<DimVec<double> >**coords;
coords = new VectorOfFixVecs<DimVec<double> >*[dim + 1];
// for all element sides
for (int i = 0; i < dim + 1; i++) {
coords[i] = new VectorOfFixVecs<DimVec<double> >(dim, dim, DEFAULT_VALUE,
DimVec<double>(dim, DEFAULT_VALUE, 0.0));
// for each vertex of the side
for (int k = 0; k < dim; k++) {
int index = refElement->getVertexOfPosition(INDEX_OF_DIM(dim - 1, dim),
i, k);
(*coords[i])[k][index] = 1.0;
}
}
std::vector<SurfaceQuadrature*> quadSurfaces(dim + 1);
for (int i = 0; i < dim + 1; i++)
quadSurfaces[i] = new SurfaceQuadrature(q, *coords[i]);
double result = 0.0;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1,
Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS);
while (elInfo) {
for (int face = 0; face < dim + 1; face++) {
if (elInfo->getBoundary(face) == boundaryType) {
int nPoints = quadSurfaces[face]->getNumPoints();
mtl::dense_vector<double> uh_vec(nPoints);
double det = elInfo->calcSurfaceDet(*coords[face]);
double normT = 0.0;
this->getVecAtQPs(elInfo, quadSurfaces[face], NULL, uh_vec);
for (int iq = 0; iq < nPoints; iq++)
normT += quadSurfaces[face]->getWeight(iq) * (uh_vec[iq]);
result += det * normT;
}
}
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localResult = result;
MPI::COMM_WORLD.Allreduce(&localResult, &result, 1, MPI_DOUBLE, MPI_SUM);
#endif
return result;
}
template<>
double DOFVector<WorldVector<double> >::IntOnBoundaryNormal(
BoundaryType boundaryType, Quadrature* q) const
{
FUNCNAME("DOFVector<T>::IntOnBoundary()");
Mesh* mesh = this->feSpace->getMesh();
int dim = mesh->getDim();
if (!q) {
int deg = 2 * this->feSpace->getBasisFcts()->getDegree();
q = Quadrature::provideQuadrature(dim - 1, deg);
} else {
TEST_EXIT(q->getDim() == dim-1)
("Provided quadrature has wrong dimension for surfaceQuadrature!\n");
}
// create barycentric coords for each vertex of each side
const Element *refElement = Global::getReferenceElement(dim);
VectorOfFixVecs<DimVec<double> >**coords;
coords = new VectorOfFixVecs<DimVec<double> >*[dim + 1];
// for all element sides
for (int i = 0; i < dim + 1; i++) {
coords[i] = new VectorOfFixVecs<DimVec<double> >(dim, dim, DEFAULT_VALUE,
DimVec<double>(dim, DEFAULT_VALUE, 0.0));
// for each vertex of the side
for (int k = 0; k < dim; k++) {
int index = refElement->getVertexOfPosition(INDEX_OF_DIM(dim - 1, dim),
i, k);
(*coords[i])[k][index] = 1.0;
}
}
std::vector<SurfaceQuadrature*> quadSurfaces(dim + 1);
for (int i = 0; i < dim + 1; i++)
quadSurfaces[i] = new SurfaceQuadrature(q, *coords[i]);
double result = 0.0;
WorldVector<double> normal;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1,
Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS);
while (elInfo) {
for (int face = 0; face < dim + 1; face++) {
if (elInfo->getBoundary(face) == boundaryType) {
elInfo->getNormal(face, normal);
double det = elInfo->calcSurfaceDet(*coords[face]);
int nPoints = quadSurfaces[face]->getNumPoints();
mtl::dense_vector<WorldVector<double> > uh_vec(nPoints);
WorldVector<double> normT; normT.set(0.0);
this->getVecAtQPs(elInfo, quadSurfaces[face], NULL, uh_vec);
for (int iq = 0; iq < nPoints; iq++)
normT += quadSurfaces[face]->getWeight(iq) * (uh_vec[iq]);
// scalar product between vector-valued solution and normal vector
result += det * (normT * normal);
}
}
elInfo = stack.traverseNext(elInfo);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
double localResult = result;
MPI::COMM_WORLD.Allreduce(&localResult, &result, 1, MPI_DOUBLE, MPI_SUM);
#endif
return result;
}
template<> template<>
DOFVector<WorldVector<double> >* DOFVector<WorldVector<double> >*
DOFVector<double>::getGradient(DOFVector<WorldVector<double> > *grad) const DOFVector<double>::getGradient(DOFVector<WorldVector<double> > *grad) const
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "DOFMatrix.h" #include "DOFMatrix.h"
#include "BasisFunction.h" #include "BasisFunction.h"
#include "FiniteElemSpace.h" #include "FiniteElemSpace.h"
#include "SurfaceQuadrature.h"
namespace AMDiS { namespace AMDiS {
...@@ -446,6 +447,29 @@ namespace AMDiS { ...@@ -446,6 +447,29 @@ namespace AMDiS {
/// Calculates Integral of this DOFVector /// Calculates Integral of this DOFVector
double Int(Quadrature* q = NULL) const; double Int(Quadrature* q = NULL) const;
/** \brief
* Calculates Integral of this DOFVector over parts of the domain
* boundary, indicated by boundaryType. Implemented for DOFVector<double>
**/
T IntOnBoundary(BoundaryType boundary, Quadrature* q = NULL) const
{
FUNCNAME("DOFVector::IntOnBoundary())");
TEST_EXIT(false)("Please implement your integration\n");
return 0.0;
}
/** \brief
* Calculates Integral of this DOFVector times normal vector over parts
* of the domain boundary, indicated by boundaryType. Implemented for
* DOFVector<WorldVector<double> >
**/
double IntOnBoundaryNormal(BoundaryType boundary, Quadrature* q = NULL) const
{
FUNCNAME("DOFVector::IntOnBoundaryNormal())");
TEST_EXIT(false)("Please implement your integration\n");
return 0.0;
}
/// Calculates L1 norm of this DOFVector /// Calculates L1 norm of this DOFVector
double L1Norm(Quadrature* q = NULL) const; double L1Norm(Quadrature* q = NULL) const;
...@@ -544,7 +568,8 @@ namespace AMDiS { ...@@ -544,7 +568,8 @@ namespace AMDiS {
* starts from oldElInfo. * starts from oldElInfo.
* implemented for: double, WorldVector< double > * implemented for: double, WorldVector< double >
*/ */
inline const T& evalAtPoint(WorldVector<double> &p, ElInfo *oldElInfo = NULL, T* value = NULL) const inline const T& evalAtPoint(
WorldVector<double> &p, ElInfo *oldElInfo = NULL, T* value = NULL) const
{ {
FUNCNAME("DOFVector::evalAtPoint())"); FUNCNAME("DOFVector::evalAtPoint())");
TEST_EXIT(false)("Please implement your evaluation\n"); TEST_EXIT(false)("Please implement your evaluation\n");
...@@ -575,6 +600,7 @@ namespace AMDiS { ...@@ -575,6 +600,7 @@ namespace AMDiS {
DOFVector<WorldVector<T> >* getRecoveryGradient(DOFVector<WorldVector<T> >*) const; DOFVector<WorldVector<T> >* getRecoveryGradient(DOFVector<WorldVector<T> >*) const;
protected: protected:
/// Data container /// Data container
std::vector<T> vec; std::vector<T> vec;
...@@ -590,10 +616,20 @@ namespace AMDiS { ...@@ -590,10 +616,20 @@ namespace AMDiS {
template<> template<>
const double& DOFVector<double>::evalAtPoint(WorldVector<double> &p, ElInfo *oldElInfo, double* value) const; double DOFVector<double>::IntOnBoundary(
BoundaryType boundaryType, Quadrature* q) const;
template<>
double DOFVector<WorldVector<double> >::IntOnBoundaryNormal(
BoundaryType boundaryType, Quadrature* q) const;
template<>
const double& DOFVector<double>::evalAtPoint(
WorldVector<double> &p, ElInfo *oldElInfo, double* value) const;
template<> template<>
const WorldVector<double>& DOFVector<WorldVector<double> >::evalAtPoint(WorldVector<double> &p, ElInfo *oldElInfo, WorldVector<double>* value) const; const WorldVector<double>& DOFVector<WorldVector<double> >::evalAtPoint(
WorldVector<double> &p, ElInfo *oldElInfo, WorldVector<double>* value) const;
template<> template<>
void DOFVector<double>::refineInterpol(RCNeighbourList&, int); void DOFVector<double>::refineInterpol(RCNeighbourList&, int);
......
...@@ -520,8 +520,7 @@ namespace AMDiS { ...@@ -520,8 +520,7 @@ namespace AMDiS {
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 = ElInfo *elInfo = stack.traverseFirst(mesh, -1,
stack.traverseFirst(mesh, -1,
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();
......
...@@ -156,6 +156,24 @@ namespace AMDiS { ...@@ -156,6 +156,24 @@ namespace AMDiS {
} }
double ElInfo::calcSurfaceDet(VectorOfFixVecs<DimVec<double> > &surfVert) const
{
double surfDet;
int dim = surfVert[0].getSize() - 1;
FixVec<WorldVector<double>, VERTEX> worldCoords(dim - 1, NO_INIT);
// transform barycentric coords to world coords
for (int i = 0; i < dim; i++) {
coordToWorld(surfVert[i], worldCoords[i]);
}
// calculate determinant for surface
surfDet = calcDet(worldCoords);
return surfDet;
}
void ElInfo::testFlag(const Flag& flags) const void ElInfo::testFlag(const Flag& flags) const
{ {
TEST_EXIT_DBG(fillFlag.isSet(flags))("flag not set\n"); TEST_EXIT_DBG(fillFlag.isSet(flags))("flag not set\n");
......
...@@ -368,6 +368,9 @@ namespace AMDiS { ...@@ -368,6 +368,9 @@ namespace AMDiS {
*/ */
double calcDet(const FixVec<WorldVector<double>, VERTEX> &coords) const; double calcDet(const FixVec<WorldVector<double>, VERTEX> &coords) const;
/// from CFE_Integration
double calcSurfaceDet(VectorOfFixVecs<DimVec<double> > &surfVert) const;
/// Checks whether flag is set in ElInfo's \ref fillFlag. If not, the program exits. /// Checks whether flag is set in ElInfo's \ref fillFlag. If not, the program exits.
void testFlag(const Flag& flag) const; void testFlag(const Flag& flag) const;
......
...@@ -68,7 +68,7 @@ namespace AMDiS { ...@@ -68,7 +68,7 @@ namespace AMDiS {
/// Fill an initfile from an input stream /// Fill an initfile from an input stream
void Initfile::read(istream& in) void Initfile::read(istream& in)
{ {
unsigned line_length = 256; unsigned line_length = 512;
char swap[line_length]; char swap[line_length];
in.getline(swap, line_length); in.getline(swap, line_length);
while (in.good()) { while (in.good()) {
...@@ -76,11 +76,14 @@ namespace AMDiS { ...@@ -76,11 +76,14 @@ namespace AMDiS {
std::string sw(swap); std::string sw(swap);
size_t pos0 = sw.find_first_not_of(whitespaces); size_t pos0 = sw.find_first_not_of(whitespaces);
if (pos0 != std::string::npos && sw[pos0] != '%' if (pos0 != std::string::npos
&& sw[pos0] != '#' && sw[pos0] != 0) { && sw[pos0] != '%'
&& sw[pos0] != '#'
&& sw[pos0] != 0) {
// parse line and extract map: tag->value // parse line and extract map: tag->value
Parser parser(sw); Parser parser(sw);
// add parameter to map after variable replacement
operator[](variableReplacement(InitfileInternal::trim(parser.name))) = variableReplacement(InitfileInternal::trim(parser.value)); operator[](variableReplacement(InitfileInternal::trim(parser.name))) = variableReplacement(InitfileInternal::trim(parser.value));
} else if (sw[pos0] == '#' } else if (sw[pos0] == '#'
&& static_cast<size_t>(sw.find("#include")) == pos0) { && static_cast<size_t>(sw.find("#include")) == pos0) {
...@@ -130,7 +133,7 @@ namespace AMDiS { ...@@ -130,7 +133,7 @@ namespace AMDiS {
std::string varName = inputSwap.substr(posVarBegin + 1 , posVarEnd - posVarBegin - 1); std::string varName = inputSwap.substr(posVarBegin + 1 , posVarEnd - posVarBegin - 1);
std::string varParam = checkedGet(varName); std::string varParam = checkedGet(varName);
// if varname is found in parameter list then replace variable by value // if varname is found in parameter list then replace variable by value
// otherwise throw tarNotFound exception // otherwise throw tagNotFound exception
std::string replaceName = inputSwap.substr(posVar , posVarEnd - posVar + (posVarBegin - posVar)); std::string replaceName = inputSwap.substr(posVar , posVarEnd - posVar + (posVarBegin - posVar));
inputSwap.replace(inputSwap.find(replaceName), replaceName.length(), varParam); inputSwap.replace(inputSwap.find(replaceName), replaceName.length(), varParam);
......
...@@ -45,6 +45,9 @@ namespace AMDiS { ...@@ -45,6 +45,9 @@ namespace AMDiS {
public: public:
virtual ~ProblemTimeInterface() {}; virtual ~ProblemTimeInterface() {};
/// Called at the beginning of the adaption loop before any other call
virtual void initTimeInterface() {};
/// Executes all needed operations when the simulation time changes. /// Executes all needed operations when the simulation time changes.
virtual void setTime(AdaptInfo *adaptInfo) = 0; virtual void setTime(AdaptInfo *adaptInfo) = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment