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

* Output support for higher order Lagrange Elements

parent a12fef07
...@@ -116,6 +116,7 @@ namespace AMDiS { ...@@ -116,6 +116,7 @@ namespace AMDiS {
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
// Remove all interpolation marks and, instead, set to each // Remove all interpolation marks and, instead, set to each
// interpolation point its continous index starting from 0. // interpolation point its continous index starting from 0.
int i = 0; int i = 0;
...@@ -126,7 +127,8 @@ namespace AMDiS { ...@@ -126,7 +127,8 @@ namespace AMDiS {
} }
// Traverse elements to create interpolation values. // Traverse elements to create interpolation values.
elInfo = stack.traverseFirst(mesh_, level_, traverseFlag_); counter = 0;
elInfo = stack.traverseFirst(mesh_, level_, traverseFlag_ | Mesh::FILL_COORDS);
while (elInfo) { while (elInfo) {
if (!writeElem_ || writeElem_(elInfo)) if (!writeElem_ || writeElem_(elInfo))
addInterpData(elInfo); addInterpData(elInfo);
...@@ -268,102 +270,73 @@ namespace AMDiS { ...@@ -268,102 +270,73 @@ namespace AMDiS {
{ {
FUNCNAME("DataCollector::addValueData()"); FUNCNAME("DataCollector::addValueData()");
const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); const BasisFunction *basisFcts = feSpace_->getBasisFcts();
const DegreeOfFreedom *localDOFs = basisFcts->getLocalIndices(elInfo->getElement(), localAdmin_, NULL);
/* vertex dofs */ const int nBasisFcts = basisFcts->getNumber();
int dof_offset = localAdmin_->getNumberOfPreDOFs(VERTEX);
for (int i = 0; i < mesh_->getGeo(VERTEX); i++) { for (int i = 0; i < mesh_->getGeo(VERTEX); i++) {
(*interpPointInd_)[dof[i][dof_offset]] = -2; // mark as vertex (*interpPointInd_)[localDOFs[i]] = -2; // mark as vertex
// get coords of this vertex // get coords of this vertex
WorldVector<double> vertexCoords = elInfo->getCoord(i); WorldVector<double> vertexCoords = elInfo->getCoord(i);
// search for coords at this dof // search for coords at this dof
::std::list<WorldVector<double> >::iterator it = ::std::list<WorldVector<double> >::iterator it =
find((*dofCoords_)[dof[i][dof_offset]].begin(), find((*dofCoords_)[localDOFs[i]].begin(),
(*dofCoords_)[dof[i][dof_offset]].end(), (*dofCoords_)[localDOFs[i]].end(),
vertexCoords); vertexCoords);
// coords not yet in list? // coords not yet in list?
if (it == (*dofCoords_)[dof[i][dof_offset]].end()) { if (it == (*dofCoords_)[localDOFs[i]].end()) {
// add new coords to list // add new coords to list
(*dofCoords_)[dof[i][dof_offset]].push_back(vertexCoords); (*dofCoords_)[localDOFs[i]].push_back(vertexCoords);
} }
} }
int nInterpPoints = 0; for (int i = mesh_->getGeo(VERTEX); i < nBasisFcts; i++) {
const BasisFunction *basisFcts = feSpace_->getBasisFcts(); WorldVector<double> interpolCoords;
elInfo->coordToWorld(*basisFcts->getCoords(i), &interpolCoords);
for (int i = 1; i <= dim_; i++) {
int num_dofs = localAdmin_->getNumberOfDOFs(INDEX_OF_DIM(i, dim_)); if ((*interpPointInd_)[localDOFs[i]] == -1) {
int node_offset = mesh_->getNode(INDEX_OF_DIM(i, dim_)); // mark as interpolation point
dof_offset = localAdmin_->getNumberOfPreDOFs(INDEX_OF_DIM(i, dim_)); (*interpPointInd_)[localDOFs[i]] = -3;
for (int j = 0; j < mesh_->getGeo(INDEX_OF_DIM(i, dim_)); j++) { // search for interpolation point coordinates, and insert them to the
int node = node_offset + j; // dof-entry, if not contained in the list
::std::list<WorldVector<double> >::iterator it =
for (int k = 0; k < num_dofs; k++) { find((*interpPointCoords_)[localDOFs[i]].begin(),
int dof_index = dof_offset + k; (*interpPointCoords_)[localDOFs[i]].end(),
WorldVector<double> interpolCoords;
elInfo->coordToWorld((*basisFcts->getCoords(mesh_->getGeo(VERTEX) + nInterpPoints)),
&interpolCoords);
nInterpPoints++;
if ((*interpPointInd_)[dof[node][dof_index]] == -1) {
// mark as interpolation point
(*interpPointInd_)[dof[node][dof_index]] = -3;
// search for interpolation point coordinates, and insert them to the
// dof-entry, if not contained in the list
::std::list<WorldVector<double> >::iterator it =
find((*interpPointCoords_)[dof[node][dof_index]].begin(),
(*interpPointCoords_)[dof[node][dof_index]].end(),
interpolCoords); interpolCoords);
if (it == (*interpPointCoords_)[dof[node][dof_index]].end()) {
(*interpPointCoords_)[dof[node][dof_index]].push_back(interpolCoords); if (it == (*interpPointCoords_)[localDOFs[i]].end()) {
} (*interpPointCoords_)[localDOFs[i]].push_back(interpolCoords);
nInterpPoints_++;
nInterpPoints_++;
}
} }
} }
} }
return(0); return(0);
} }
int DataCollector::addInterpData(ElInfo *elInfo) int DataCollector::addInterpData(ElInfo *elInfo)
{ {
FUNCNAME("DataCollector::addInterpData()"); FUNCNAME("DataCollector::addInterpData()");
const DegreeOfFreedom **dof = elInfo->getElement()->getDOF();
::std::vector<int> elemInterpPoints; ::std::vector<int> elemInterpPoints;
elemInterpPoints.clear(); elemInterpPoints.clear();
for (int i = 1; i <= dim_; i++) { const BasisFunction *basisFcts = feSpace_->getBasisFcts();
int num_dofs = localAdmin_->getNumberOfDOFs(INDEX_OF_DIM(i, dim_)); const DegreeOfFreedom *localDOFs = basisFcts->getLocalIndices(elInfo->getElement(), localAdmin_, NULL);
int node_offset = mesh_->getNode(INDEX_OF_DIM(i, dim_)); const int nBasisFcts = basisFcts->getNumber();
int dof_offset = localAdmin_->getNumberOfPreDOFs(INDEX_OF_DIM(i, dim_));
for (int j = 0; j < mesh_->getGeo(INDEX_OF_DIM(i, dim_)); j++) {
int node = node_offset + j;
for (int k = 0; k < num_dofs; k++) { for (int i = mesh_->getGeo(VERTEX); i < nBasisFcts; i++) {
int dof_index = dof_offset + k; elemInterpPoints.push_back((*interpPointInd_)[localDOFs[i]]);
elemInterpPoints.push_back((*interpPointInd_)[dof[node][dof_index]]);
}
}
} }
interpPoints_.push_back(elemInterpPoints); interpPoints_.push_back(elemInterpPoints);
return(0); return(0);
} }
......
...@@ -294,6 +294,8 @@ namespace AMDiS { ...@@ -294,6 +294,8 @@ namespace AMDiS {
* Pointer to a function which decides whether an element is considered. * Pointer to a function which decides whether an element is considered.
*/ */
bool (*writeElem_)(ElInfo*); bool (*writeElem_)(ElInfo*);
int counter;
}; };
} }
......
...@@ -12,8 +12,11 @@ namespace AMDiS { ...@@ -12,8 +12,11 @@ namespace AMDiS {
{ {
ElementRegion_ED* red_; ElementRegion_ED* red_;
if (!elementData) return -1; if (!elementData)
red_=dynamic_cast<ElementRegion_ED*>(elementData->getElementData(ELEMENT_REGION)); return -1;
red_ = dynamic_cast<ElementRegion_ED*>(elementData->getElementData(ELEMENT_REGION));
if (red_) if (red_)
return red_->getRegion(); return red_->getRegion();
...@@ -22,8 +25,9 @@ namespace AMDiS { ...@@ -22,8 +25,9 @@ namespace AMDiS {
void Element::setDOFPtrs() void Element::setDOFPtrs()
{ {
FUNCNAME("Element::setDOFPtrs"); FUNCNAME("Element::setDOFPtrs()");
TEST_EXIT(mesh)("no mesh!\n"); TEST_EXIT(mesh)("no mesh!\n");
dof = mesh->createDOFPtrs(); dof = mesh->createDOFPtrs();
} }
...@@ -33,27 +37,30 @@ namespace AMDiS { ...@@ -33,27 +37,30 @@ namespace AMDiS {
index = mesh ? mesh->getNextElementIndex() : -1; index = mesh ? mesh->getNextElementIndex() : -1;
child[0] = NULL; child[0] = NULL;
child[1] = NULL; child[1] = NULL;
dof = mesh ? mesh->createDOFPtrs() : NULL;
newCoord = NULL; newCoord = NULL;
elementData = NULL; elementData = NULL;
if (mesh) {
setDOFPtrs();
} else {
mesh = NULL;
}
} }
// call destructor through Mesh::freeElement !!! // call destructor through Mesh::freeElement !!!
Element::~Element() Element::~Element()
{ {
if(child[0]) DELETE child[0]; if (child[0])
if(child[1]) DELETE child[1]; DELETE child[0];
if (child[1])
//if(elementData) DELETE elementData; DELETE child[1];
if (newCoord) if (newCoord) {
{ DELETE newCoord;
DELETE newCoord; }
}
} }
/****************************************************************************/ /****************************************************************************/
...@@ -65,7 +72,7 @@ namespace AMDiS { ...@@ -65,7 +72,7 @@ namespace AMDiS {
/* CHANGE_DOFS_1 changes old dofs to NEGATIVE new dofs */ /* CHANGE_DOFS_1 changes old dofs to NEGATIVE new dofs */
#define CHANGE_DOFS_1(el) \ #define CHANGE_DOFS_1(el) \
ldof = el->dof[n0+i] + nd0; \ ldof = el->dof[n0 + i] + nd0; \
for (j = 0; j < nd; j++) { \ for (j = 0; j < nd; j++) { \
if ((k = ldof[j]) >= 0) { \ if ((k = ldof[j]) >= 0) { \
/* do it only once! (dofs are visited more than once) */ \ /* do it only once! (dofs are visited more than once) */ \
...@@ -99,7 +106,7 @@ namespace AMDiS { ...@@ -99,7 +106,7 @@ namespace AMDiS {
} }
} }
if(mesh->getDim() > 1) { if (mesh->getDim() > 1) {
if ((nd = admin->getNumberOfDOFs(EDGE))) { if ((nd = admin->getNumberOfDOFs(EDGE))) {
nd0 = admin->getNumberOfPreDOFs(EDGE); nd0 = admin->getNumberOfPreDOFs(EDGE);
n0 = admin->getMesh()->getNode(EDGE); n0 = admin->getMesh()->getNode(EDGE);
...@@ -109,7 +116,7 @@ namespace AMDiS { ...@@ -109,7 +116,7 @@ namespace AMDiS {
} }
} }
if (3==mesh->getDim()) { if (mesh->getDim() == 3) {
if ((nd = admin->getNumberOfDOFs(FACE))) { if ((nd = admin->getNumberOfDOFs(FACE))) {
nd0 = admin->getNumberOfPreDOFs(FACE); nd0 = admin->getNumberOfPreDOFs(FACE);
n0 = admin->getMesh()->getNode(FACE); n0 = admin->getMesh()->getNode(FACE);
...@@ -145,7 +152,7 @@ namespace AMDiS { ...@@ -145,7 +152,7 @@ namespace AMDiS {
} }
} }
if(mesh->getDim() > 1) { if (mesh->getDim() > 1) {
if ((nd = admin->getNumberOfDOFs(EDGE))) { if ((nd = admin->getNumberOfDOFs(EDGE))) {
nd0 = admin->getNumberOfPreDOFs(EDGE); nd0 = admin->getNumberOfPreDOFs(EDGE);
n0 = admin->getMesh()->getNode(EDGE); n0 = admin->getMesh()->getNode(EDGE);
...@@ -155,7 +162,7 @@ namespace AMDiS { ...@@ -155,7 +162,7 @@ namespace AMDiS {
} }
} }
if (3==mesh->getDim()) { if (mesh->getDim() == 3) {
if ((nd = admin->getNumberOfDOFs(FACE))) { if ((nd = admin->getNumberOfDOFs(FACE))) {
nd0 = admin->getNumberOfPreDOFs(FACE); nd0 = admin->getNumberOfPreDOFs(FACE);
n0 = admin->getMesh()->getNode(FACE); n0 = admin->getMesh()->getNode(FACE);
...@@ -183,30 +190,30 @@ namespace AMDiS { ...@@ -183,30 +190,30 @@ namespace AMDiS {
int Element::oppVertex(FixVec<DegreeOfFreedom*, DIMEN> pdof) const int Element::oppVertex(FixVec<DegreeOfFreedom*, DIMEN> pdof) const
{ {
int i, j, nv = 0, ov = 0; int nv = 0, ov = 0;
int vertices = mesh->getGeo(VERTEX); int vertices = mesh->getGeo(VERTEX);
int dim = mesh->getDim(); int dim = mesh->getDim();
for (i = 0; i < vertices; i++) for (int i = 0; i < vertices; i++) {
{ if (nv < i-1)
if (nv < i-1) return(-1); return(-1);
for (j = 0; j < dim; j++) for (int j = 0; j < dim; j++) {
{ if (dof[i] == pdof[j]) {
if (dof[i] == pdof[j]) /****************************************************************************/
{ /* i is a common vertex */
/****************************************************************************/ /****************************************************************************/
/* i is a common vertex */ ov += i;
/****************************************************************************/ nv++;
ov += i; break;
nv++; }
break;
}
}
} }
if (nv != mesh->getDim()) return(-1);
}
if (nv != mesh->getDim())
return(-1);
/****************************************************************************/ /****************************************************************************/
/* the opposite vertex is 3(6) - (sum of indices of common vertices) in */ /* the opposite vertex is 3(6) - (sum of indices of common vertices) in */
/* 2d(3d) */ /* 2d(3d) */
...@@ -243,7 +250,7 @@ namespace AMDiS { ...@@ -243,7 +250,7 @@ namespace AMDiS {
newCoord=NULL; newCoord=NULL;
}; };
} }
void Element::serialize(::std::ostream &out) void Element::serialize(::std::ostream &out)
{ {
// write children // write children
......
...@@ -305,9 +305,9 @@ namespace AMDiS { ...@@ -305,9 +305,9 @@ namespace AMDiS {
/** \brief /** \brief
* Sets the pointer to the DOFs of the i-th node of Element * Sets the pointer to the DOFs of the i-th node of Element
*/ */
DegreeOfFreedom* setDOF(int i, DegreeOfFreedom* p) { DegreeOfFreedom* setDOF(int pos, DegreeOfFreedom* p) {
dof[i] = p; dof[pos] = p;
return dof[i]; return dof[pos];
}; };
/** \brief /** \brief
......
...@@ -360,7 +360,9 @@ namespace AMDiS { ...@@ -360,7 +360,9 @@ namespace AMDiS {
} }
} }
Lagrange::Phi::~Phi() { DELETE [] vertices; } Lagrange::Phi::~Phi() {
DELETE [] vertices;
}
Lagrange::GrdPhi::GrdPhi(Lagrange* owner_, Lagrange::GrdPhi::GrdPhi(Lagrange* owner_,
...@@ -1003,16 +1005,17 @@ namespace AMDiS { ...@@ -1003,16 +1005,17 @@ namespace AMDiS {
DegreeOfFreedom* result; DegreeOfFreedom* result;
if(indices) { if (indices) {
result = indices; result = indices;
} else { } else {
if(localVec) FREE_MEMORY(localVec, DegreeOfFreedom, localVecSize); if (localVec)
FREE_MEMORY(localVec, DegreeOfFreedom, localVecSize);
localVec = GET_MEMORY(DegreeOfFreedom, nBasFcts); localVec = GET_MEMORY(DegreeOfFreedom, nBasFcts);
localVecSize = nBasFcts; localVecSize = nBasFcts;
result = localVec; result = localVec;
} }
for(pos=0, j=0; pos <= dim; pos++) { for (pos = 0, j = 0; pos <= dim; pos++) {
posIndex = INDEX_OF_DIM(pos, dim); posIndex = INDEX_OF_DIM(pos, dim);
n0 = admin->getNumberOfPreDOFs(posIndex); n0 = admin->getNumberOfPreDOFs(posIndex);
node0 = admin->getMesh()->getNode(posIndex); node0 = admin->getMesh()->getNode(posIndex);
...@@ -1032,33 +1035,6 @@ namespace AMDiS { ...@@ -1032,33 +1035,6 @@ namespace AMDiS {
return result; return result;
} }
// const double* Lagrange::getVec(const Element* el, const DOFVector<double> * dv,
// double * d) const
// {
// static double* localVec = NULL;
// const DOFAdmin* admin = dv->getFESpace()->getAdmin();
// int i;
// double* result;
// if(d) {
// result = d;
// } else {
// if(localVec) FREE_MEMORY(localVec, double, nBasFcts);
// localVec = GET_MEMORY(double, nBasFcts);
// result = localVec;
// }
// const DegreeOfFreedom *localIndices = getLocalIndices(el, admin, NULL);
// for(i = 0; i < nBasFcts; i++) {
// result[i] = (*dv)[localIndices[i]];
// }
// return result;
// }
void Lagrange::l2ScpFctBas(Quadrature *q, void Lagrange::l2ScpFctBas(Quadrature *q,
AbstractFunction<WorldVector<double>, WorldVector<double> >* f, AbstractFunction<WorldVector<double>, WorldVector<double> >* f,
DOFVector<WorldVector<double> >* fh) DOFVector<WorldVector<double> >* fh)
...@@ -1234,12 +1210,13 @@ namespace AMDiS { ...@@ -1234,12 +1210,13 @@ namespace AMDiS {
RCNeighbourList* list, RCNeighbourList* list,
int n, BasisFunction* basFct) int n, BasisFunction* basFct)
{ {
FUNCNAME("Lagrange::refineInter2_2d"); FUNCNAME("Lagrange::refineInter2_2d()");
if (n < 1) return; if (n < 1)
return;
Element *el; Element *el;
int node, n0; int node, n0;
DegreeOfFreedom cdof; DegreeOfFreedom cdof;
const DegreeOfFreedom *pdof; const DegreeOfFreedom *pdof;
const DOFAdmin *admin = drv->getFESpace()->getAdmin(); const DOFAdmin *admin = drv->getFESpace()->getAdmin();
...@@ -1267,7 +1244,7 @@ namespace AMDiS { ...@@ -1267,7 +1244,7 @@ namespace AMDiS {
cdof = el->getChild(0)->getDOF(node, n0); cdof = el->getChild(0)->getDOF(node, n0);
(*drv)[cdof] = (*drv)[cdof] =
0.375*(*drv)[pdof[0]] - 0.125*(*drv)[pdof[1]] + 0.75*(*drv)[pdof[5]]; 0.375 * (*drv)[pdof[0]] - 0.125 * (*drv)[pdof[1]] + 0.75 * (*drv)[pdof[5]];
/****************************************************************************/ /****************************************************************************/
/* node in the common edge of child[0] and child[1] */ /* node in the common edge of child[0] and child[1] */
...@@ -1275,8 +1252,8 @@ namespace AMDiS { ...@@ -1275,8 +1252,8 @@ namespace AMDiS {
cdof = el->getChild(0)->getDOF(node+1, n0); cdof = el->getChild(0)->getDOF(node+1, n0);
(*drv)[cdof] = (*drv)[cdof] =
-0.125*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[5]] -0.125 * ((*drv)[pdof[0]] + (*drv)[pdof[1]]) + 0.25 * (*drv)[pdof[5]]
+ 0.5*((*drv)[pdof[3]] + (*drv)[pdof[4]]); + 0.5 * ((*drv)[pdof[3]] + (*drv)[pdof[4]]);
/****************************************************************************/ /****************************************************************************/
/* midpoint of edge on child[1] at the refinement edge */ /* midpoint of edge on child[1] at the refinement edge */
...@@ -1284,22 +1261,20 @@ namespace AMDiS { ...@@ -1284,22 +1261,20 @@ namespace AMDiS {
cdof = el->getChild(1)->getDOF(node+1, n0); cdof = el->getChild(1)->getDOF(node+1, n0);
(*drv)[cdof] = (*drv)[cdof] =
-0.125*(*drv)[pdof[0]] + 0.375*(*drv)[pdof[1]] + 0.75*(*drv)[pdof[5]]; -0.125 * (*drv)[pdof[0]] + 0.375 * (*drv)[pdof[1]] + 0.75 * (*drv)[pdof[5]];
if (n > 1) if (n > 1) {
{ /****************************************************************************/
/****************************************************************************/ /* adjust the value at the midpoint of the common edge of neigh's children */
/* adjust the value at the midpoint of the common edge of neigh's children */ /****************************************************************************/
/****************************************************************************/ el = list->getElement(1);
el = list->getElement(1); pdof = basFct->getLocalIndices(el, admin, NULL);
pdof = basFct->getLocalIndices(el, admin, NULL);
cdof = el->getChild(0)->getDOF(node+1, n0);
cdof = el->getChild(0)->getDOF(node+1, n0); (*drv)[cdof] =
(*drv)[cdof] = -0.125 * ((*drv)[pdof[0]] + (*drv)[pdof[1]]) + 0.25 * (*drv)[pdof[5]]
-0.125*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[5]] + 0.5 * ((*drv)[pdof[3]] + (*drv)[pdof[4]]);
+ 0.5*((*drv)[pdof[3]] + (*drv)[pdof[4]]); }
}
return;
} }
void Lagrange::refineInter2_3d(DOFIndexed<double> *drv, void Lagrange::refineInter2_3d(DOFIndexed<double> *drv,
......
...@@ -152,20 +152,6 @@ namespace AMDiS { ...@@ -152,20 +152,6 @@ namespace AMDiS {
const DOFAdmin*,