Commit cc0849b7 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Work on residual estimator for multiple meshes in problem definition.

parent d51a4a4b
...@@ -133,16 +133,13 @@ namespace AMDiS { ...@@ -133,16 +133,13 @@ namespace AMDiS {
ElementMatrix m(nRow, nRow); ElementMatrix m(nRow, nRow);
smallElInfo->getSubElemCoordsMat(m, rowFESpace->getBasisFcts()->getDegree()); smallElInfo->getSubElemCoordsMat(m, rowFESpace->getBasisFcts()->getDegree());
#if 0
std::cout << "ASM MAT:" << std::endl;
std::cout << mat << std::endl;
std::cout << "MULT MAT:" << std::endl;
std::cout << m << std::endl;
#endif
ElementMatrix tmpMat(nRow, nRow); ElementMatrix tmpMat(nRow, nRow);
//tmpMat = m * mat;
tmpMat = mat * m; if (smallElInfo == colElInfo)
tmpMat = m * mat;
else
tmpMat = mat * trans(m);
mat = tmpMat; mat = tmpMat;
} }
......
...@@ -11,32 +11,32 @@ namespace AMDiS { ...@@ -11,32 +11,32 @@ namespace AMDiS {
void SingleComponentInfo::updateStatus() void SingleComponentInfo::updateStatus()
{ {
if (rowFESpace == NULL) { if (rowFeSpace == NULL) {
status = SingleComponentInfo::EMPTY; status = SingleComponentInfo::EMPTY;
return; return;
} }
if (colFESpace == NULL || if (colFeSpace == NULL ||
(colFESpace != NULL && rowFESpace->getMesh() == colFESpace->getMesh())) { (colFeSpace != NULL && rowFeSpace->getMesh() == colFeSpace->getMesh())) {
if (auxFESpaces.size() == 0) { if (auxFeSpaces.size() == 0) {
status = SingleComponentInfo::EQ_SPACES_NO_AUX; status = SingleComponentInfo::EQ_SPACES_NO_AUX;
} else { } else {
status = SingleComponentInfo::EQ_SPACES_WITH_AUX; status = SingleComponentInfo::EQ_SPACES_WITH_AUX;
for (int i = 0; i < static_cast<int>(auxFESpaces.size()); i++) { for (int i = 0; i < static_cast<int>(auxFeSpaces.size()); i++) {
if (auxFESpaces[i]->getMesh() != rowFESpace->getMesh()) { if (auxFeSpaces[i]->getMesh() != rowFeSpace->getMesh()) {
status = SingleComponentInfo::EQ_SPACES_WITH_DIF_AUX; status = SingleComponentInfo::EQ_SPACES_WITH_DIF_AUX;
break; break;
} }
} }
} }
} else { } else {
if (auxFESpaces.size() == 0) { if (auxFeSpaces.size() == 0) {
status = SingleComponentInfo::DIF_SPACES_NO_AUX; status = SingleComponentInfo::DIF_SPACES_NO_AUX;
} else { } else {
status = SingleComponentInfo::DIF_SPACES_WITH_AUX; status = SingleComponentInfo::DIF_SPACES_WITH_AUX;
for (int i = 0; i < static_cast<int>(auxFESpaces.size()); i++) { for (int i = 0; i < static_cast<int>(auxFeSpaces.size()); i++) {
if (auxFESpaces[i]->getMesh() != rowFESpace->getMesh() && if (auxFeSpaces[i]->getMesh() != rowFeSpace->getMesh() &&
auxFESpaces[i]->getMesh() != colFESpace->getMesh()) { auxFeSpaces[i]->getMesh() != colFeSpace->getMesh()) {
status = SingleComponentInfo::DIF_SPACES_WITH_DIF_AUX; status = SingleComponentInfo::DIF_SPACES_WITH_DIF_AUX;
break; break;
} }
...@@ -45,4 +45,41 @@ namespace AMDiS { ...@@ -45,4 +45,41 @@ namespace AMDiS {
} }
} }
const FiniteElemSpace* ComponentTraverseInfo::getRowFeSpace(int row)
{
FUNCNAME("ComponentTraverseInfo::getRowFeSpace()");
TEST_EXIT_DBG(row < nComponents)("No component traverse info for this row!\n");
TEST_EXIT_DBG(matrixComponents[row][row].getRowFeSpace() ==
matrixComponents[row][row].getColFeSpace())
("Should not happen!\n");
return matrixComponents[row][row].getRowFeSpace();
}
const FiniteElemSpace* ComponentTraverseInfo::getNonRowFeSpace(int row)
{
FUNCNAME("ComponentTraverseInfo::getNonRowFeSpace()");
TEST_EXIT_DBG(row < nComponents)("No component traverse info for this row!\n");
const FiniteElemSpace* rowFeSpace = getRowFeSpace(row);
TEST_EXIT_DBG(rowFeSpace != NULL)("No row FE space!\n");
for (int i = 0; i < nComponents; i++) {
if (matrixComponents[row][i].getColFeSpace() != rowFeSpace)
return matrixComponents[row][i].getColFeSpace();
if (matrixComponents[row][i].getAuxFeSpace(0) != rowFeSpace)
return matrixComponents[row][i].getAuxFeSpace(0);
}
if (vectorComponents[row].getAuxFeSpace(0) != rowFeSpace)
return vectorComponents[row].getAuxFeSpace(0);
return NULL;
}
} }
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#define AMDIS_COMPONENTTRAVERSEINFO_H #define AMDIS_COMPONENTTRAVERSEINFO_H
#include <vector> #include <vector>
#include "Global.h"
#include "FiniteElemSpace.h" #include "FiniteElemSpace.h"
namespace AMDiS { namespace AMDiS {
...@@ -32,58 +32,58 @@ namespace AMDiS { ...@@ -32,58 +32,58 @@ namespace AMDiS {
{ {
public: public:
SingleComponentInfo() SingleComponentInfo()
: rowFESpace(NULL), : rowFeSpace(NULL),
colFESpace(NULL), colFeSpace(NULL),
auxFESpaces(0), auxFeSpaces(0),
status(0) status(0)
{} {}
void setFESpace(FiniteElemSpace *row, FiniteElemSpace *col = NULL) void setFeSpace(FiniteElemSpace *row, FiniteElemSpace *col = NULL)
{ {
rowFESpace = row; rowFeSpace = row;
colFESpace = col; colFeSpace = col;
} }
void setAuxFESpaces(std::vector<const FiniteElemSpace*> feSpaces) void setAuxFeSpaces(std::vector<const FiniteElemSpace*> feSpaces)
{ {
auxFESpaces = feSpaces; auxFeSpaces = feSpaces;
} }
void addAuxFESpace(const FiniteElemSpace *fe) void addAuxFeSpace(const FiniteElemSpace *fe)
{ {
auxFESpaces.push_back(fe); auxFeSpaces.push_back(fe);
} }
bool hasFESpace() bool hasFeSpace()
{ {
return rowFESpace != NULL; return rowFeSpace != NULL;
} }
void updateStatus(); void updateStatus();
int getNumAuxFESpaces() int getNumAuxFeSpaces()
{ {
return auxFESpaces.size(); return auxFeSpaces.size();
} }
FiniteElemSpace *getRowFESpace() FiniteElemSpace *getRowFeSpace()
{ {
return rowFESpace; return rowFeSpace;
} }
FiniteElemSpace *getColFESpace() FiniteElemSpace *getColFeSpace()
{ {
return colFESpace; return colFeSpace;
} }
const FiniteElemSpace *getAuxFESpace(int i) const FiniteElemSpace *getAuxFeSpace(int i)
{ {
return ((i < static_cast<int>(auxFESpaces.size())) ? auxFESpaces[i] : NULL); return ((i < static_cast<int>(auxFeSpaces.size())) ? auxFeSpaces[i] : NULL);
} }
void setAuxFESpace(const FiniteElemSpace* fe, int pos) void setAuxFeSpace(const FiniteElemSpace* fe, int pos)
{ {
auxFESpaces[pos] = fe; auxFeSpaces[pos] = fe;
} }
int getStatus() int getStatus()
...@@ -92,11 +92,11 @@ namespace AMDiS { ...@@ -92,11 +92,11 @@ namespace AMDiS {
} }
protected: protected:
FiniteElemSpace *rowFESpace; FiniteElemSpace *rowFeSpace;
FiniteElemSpace *colFESpace; FiniteElemSpace *colFeSpace;
std::vector<const FiniteElemSpace*> auxFESpaces; std::vector<const FiniteElemSpace*> auxFeSpaces;
/// Status of the component, see the possible status flags below. /// Status of the component, see the possible status flags below.
int status; int status;
...@@ -175,15 +175,36 @@ namespace AMDiS { ...@@ -175,15 +175,36 @@ namespace AMDiS {
return vectorComponents[row].getStatus(); return vectorComponents[row].getStatus();
} }
const FiniteElemSpace* getAuxFESpace(int row, int col) const FiniteElemSpace* getAuxFeSpace(int row, int col)
{ {
return matrixComponents[row][col].getAuxFESpace(0); return matrixComponents[row][col].getAuxFeSpace(0);
} }
const FiniteElemSpace* getAuxFESpace(int row) const FiniteElemSpace* getAuxFeSpace(int row)
{ {
return vectorComponents[row].getAuxFESpace(0); return vectorComponents[row].getAuxFeSpace(0);
} }
/** \brief
* Returns the row FE space for a given row number, i.e., the FE space
* of the diagonal matrix.
*
* \param[in] row Row number of the matrix line for which the FE space
* should be returned.
*/
const FiniteElemSpace* getRowFeSpace(int row);
/** \brief
* Returns the non row FE space for a given row number. This is either the
* col FE space of an off diagonal matrix or the aux fe space of another
* matrix in the row or of the right hand side vector. If there is no non row
* FE space, this function returns a null pointer.
*
* \param[in] row Row number of the matrix line for which the non FE space
* should be returned.
*/
const FiniteElemSpace* getNonRowFeSpace(int row);
protected: protected:
int nComponents; int nComponents;
......
...@@ -346,17 +346,17 @@ namespace AMDiS { ...@@ -346,17 +346,17 @@ namespace AMDiS {
bool symmetric(); bool symmetric();
inline std::vector<Operator*> getOperators() inline std::vector<Operator*>& getOperators()
{ {
return operators; return operators;
} }
inline std::vector<double*> getOperatorFactor() inline std::vector<double*>& getOperatorFactor()
{ {
return operatorFactor; return operatorFactor;
} }
inline std::vector<double*> getOperatorEstFactor() inline std::vector<double*>& getOperatorEstFactor()
{ {
return operatorEstFactor; return operatorEstFactor;
} }
......
...@@ -923,8 +923,9 @@ namespace AMDiS { ...@@ -923,8 +923,9 @@ namespace AMDiS {
return result; return result;
} }
template<typename T> template<typename T>
inline const DOFVector<T>& add(const DOFVector<T>& v1, inline const DOFVector<T>& add(const DOFVector<T>& v1,
const DOFVector<T>& v2, const DOFVector<T>& v2,
DOFVector<T>& result) DOFVector<T>& result)
{ {
...@@ -938,9 +939,15 @@ namespace AMDiS { ...@@ -938,9 +939,15 @@ namespace AMDiS {
return result; return result;
} }
template<typename T> template<typename T>
const T *DOFVectorBase<T>::getLocalVector(const Element *el, T *d) const const T *DOFVectorBase<T>::getLocalVector(const Element *el, T *d) const
{ {
FUNCNAME("DOFVectorBase<T>::getLocalVector()");
TEST_EXIT_DBG(feSpace->getMesh() == el->getMesh())
("Element is defined on a different mesh than the DOF vector!\n");
static T* localVec = NULL; static T* localVec = NULL;
static int localVecSize = 0; static int localVecSize = 0;
const DOFAdmin* admin = feSpace->getAdmin(); const DOFAdmin* admin = feSpace->getAdmin();
...@@ -956,6 +963,7 @@ namespace AMDiS { ...@@ -956,6 +963,7 @@ namespace AMDiS {
delete [] localVec; delete [] localVec;
localVec = new T[nBasFcts]; localVec = new T[nBasFcts];
} }
if (!localVec) if (!localVec)
localVec = new T[nBasFcts]; localVec = new T[nBasFcts];
...@@ -977,6 +985,7 @@ namespace AMDiS { ...@@ -977,6 +985,7 @@ namespace AMDiS {
return result; return result;
} }
template<typename T> template<typename T>
const T *DOFVectorBase<T>::getVecAtQPs(const ElInfo *elInfo, const T *DOFVectorBase<T>::getVecAtQPs(const ElInfo *elInfo,
const Quadrature *quad, const Quadrature *quad,
......
...@@ -56,11 +56,12 @@ namespace AMDiS { ...@@ -56,11 +56,12 @@ namespace AMDiS {
// call standard traverse // call standard traverse
*elInfo1 = stack1.traverseFirst(mesh1, level1, flag1); *elInfo1 = stack1.traverseFirst(mesh1, level1, flag1);
while (*elInfo1 != NULL && skipEl1(*elInfo1)) { while (*elInfo1 != NULL && skipEl1(*elInfo1)) {
*elInfo1 = stack1.traverseNext(*elInfo1); *elInfo1 = stack1.traverseNext(*elInfo1);
} }
*elInfo2 = stack2.traverseFirst(mesh2, level2, flag2); *elInfo2 = stack2.traverseFirst(mesh2, level2, flag2);
while (*elInfo2 != NULL && skipEl2(*elInfo2)) { while (*elInfo2 != NULL && skipEl2(*elInfo2)) {
*elInfo2 = stack2.traverseNext(*elInfo2); *elInfo2 = stack2.traverseNext(*elInfo2);
} }
// finished ? // finished ?
...@@ -87,28 +88,29 @@ namespace AMDiS { ...@@ -87,28 +88,29 @@ namespace AMDiS {
return true; return true;
} }
bool DualTraverse::traverseNext(ElInfo **elInfo1, bool DualTraverse::traverseNext(ElInfo **elInfo1,
ElInfo **elInfo2, ElInfo **elInfo2,
ElInfo **elInfoSmall, ElInfo **elInfoSmall,
ElInfo **elInfoLarge) ElInfo **elInfoLarge)
{ {
// call standard traverse // call standard traverse
if (inc1) { if (inc1) {
do { do {
*elInfo1 = stack1.traverseNext(*elInfo1); *elInfo1 = stack1.traverseNext(*elInfo1);
} while(*elInfo1 != NULL && skipEl1(*elInfo1)); } while(*elInfo1 != NULL && skipEl1(*elInfo1));
} }
if (inc2) { if (inc2) {
do { do {
*elInfo2 = stack2.traverseNext(*elInfo2); *elInfo2 = stack2.traverseNext(*elInfo2);
} while (*elInfo2 != NULL && skipEl2(*elInfo2)); } while (*elInfo2 != NULL && skipEl2(*elInfo2));
} }
// finished ? // finished ?
if (*elInfo1 == NULL || *elInfo2 == NULL) { if (*elInfo1 == NULL || *elInfo2 == NULL) {
TEST_EXIT(*elInfo1 == *elInfo2)("invalid dual traverse\n"); TEST_EXIT(*elInfo1 == *elInfo2)("invalid dual traverse\n");
return false; return false;
} }
// finished ? // finished ?
if (*elInfo1 == NULL || *elInfo2 == NULL) { if (*elInfo1 == NULL || *elInfo2 == NULL) {
...@@ -132,6 +134,7 @@ namespace AMDiS { ...@@ -132,6 +134,7 @@ namespace AMDiS {
return true; return true;
} }
void DualTraverse::prepareNextStep(ElInfo **elInfo1, void DualTraverse::prepareNextStep(ElInfo **elInfo1,
ElInfo **elInfo2, ElInfo **elInfo2,
ElInfo **elInfoSmall, ElInfo **elInfoSmall,
...@@ -170,18 +173,18 @@ namespace AMDiS { ...@@ -170,18 +173,18 @@ namespace AMDiS {
if (!fillSubElemMat) if (!fillSubElemMat)
return; return;
// mtl::dense2D<double>& subCoordsMat = // mtl::dense2D<double>& subCoordsMat =
// const_cast<mtl::dense2D<double>&>(elInfoSmall->getSubElemCoordsMat()); // const_cast<mtl::dense2D<double>&>(elInfoSmall->getSubElemCoordsMat());
// mtl::dense2D<double>& subCoordsMat_so = // mtl::dense2D<double>& subCoordsMat_so =
// const_cast<mtl::dense2D<double>&>(elInfoSmall->getSubElemCoordsMat_so()); // const_cast<mtl::dense2D<double>&>(elInfoSmall->getSubElemCoordsMat_so());
if (elInfo1 == elInfoSmall) { if (elInfo1 == elInfoSmall) {
// stack1.getCoordsInElem(elInfo2, basisFcts, subCoordsMat); // stack1.getCoordsInElem(elInfo2, basisFcts, subCoordsMat);
// stack1.getCoordsInElem_so(elInfo2, basisFcts, subCoordsMat_so); // stack1.getCoordsInElem_so(elInfo2, basisFcts, subCoordsMat_so);
stack1.fillRefinementPath(*elInfoSmall, *elInfo2); stack1.fillRefinementPath(*elInfoSmall, *elInfo2);
} else { } else {
// stack2.getCoordsInElem(elInfo1, basisFcts, subCoordsMat); // stack2.getCoordsInElem(elInfo1, basisFcts, subCoordsMat);
// stack2.getCoordsInElem_so(elInfo1, basisFcts, subCoordsMat_so); // stack2.getCoordsInElem_so(elInfo1, basisFcts, subCoordsMat_so);
stack2.fillRefinementPath(*elInfoSmall, *elInfo1); stack2.fillRefinementPath(*elInfoSmall, *elInfo1);
} }
} }
......
...@@ -28,6 +28,18 @@ ...@@ -28,6 +28,18 @@
namespace AMDiS { namespace AMDiS {
/** \brief
* Stores the four pointers to element info structures, that are required for the
* dual mesh traverse.
*/
struct DualElInfo
{
ElInfo *rowElInfo;
ElInfo *colElInfo;
ElInfo *smallElInfo;
ElInfo *largeElInfo;
};
/// Parallel traversal of two meshes. /// Parallel traversal of two meshes.
class DualTraverse class DualTraverse
{ {
...@@ -51,12 +63,34 @@ namespace AMDiS { ...@@ -51,12 +63,34 @@ namespace AMDiS {
ElInfo **elInfoSmall, ElInfo **elInfoSmall,
ElInfo **elInfoLarge); ElInfo **elInfoLarge);
/// Alternative use for starting dual traversal.
inline bool traverseFirst(Mesh *mesh1, Mesh *mesh2,
int level1, int level2,
Flag flag1, Flag flag2,
DualElInfo &dualElInfo)
{
return traverseFirst(mesh1, mesh2, level1, level2, flag1, flag2,
&(dualElInfo.rowElInfo),
&(dualElInfo.colElInfo),
&(dualElInfo.smallElInfo),
&(dualElInfo.largeElInfo));
}
/// Get next ElInfo combination /// Get next ElInfo combination
bool traverseNext(ElInfo **elInfoNext1, bool traverseNext(ElInfo **elInfoNext1,
ElInfo **elInfoNext2, ElInfo **elInfoNext2,
ElInfo **elInfoSmall, ElInfo **elInfoSmall,
ElInfo **elInfoLarge); ElInfo **elInfoLarge);
/// Alternative use for getting the next elements in the dual traversal.
inline bool traverseNext(DualElInfo &dualElInfo)
{
return traverseNext(&(dualElInfo.rowElInfo),
&(dualElInfo.colElInfo),
&(dualElInfo.smallElInfo),
&(dualElInfo.largeElInfo));
}
bool check(ElInfo **elInfo1, bool check(ElInfo **elInfo1,
ElInfo **elInfo2, ElInfo **elInfo2,
ElInfo **elInfoSmall, ElInfo **elInfoSmall,
......
#include "Estimator.h" #include "Estimator.h"