#include "RefinementManager.h" #include "Mesh.h" #include "Traverse.h" #include "ElInfo.h" #include "DOFAdmin.h" #include "AdaptStationary.h" #include "AdaptInstationary.h" #include "FixVec.h" #include "RCNeighbourList.h" #include "ProblemStatBase.h" #include "DOFIndexed.h" #include "Projection.h" namespace AMDiS { int RefinementManager1d::recursiveRefineFunction(ElInfo* elInfo) { Line *el = dynamic_cast(const_cast(elInfo->getElement())), *child[2]; Mesh* mesh = elInfo->getMesh(); if (elInfo->getProjection(0)) { traversePtr->newCoord(true); } if (el->getMark() <= 0) return 0; child[0] = dynamic_cast(mesh->createNewElement(el)); child[1] = dynamic_cast(mesh->createNewElement(el)); int mark = max(0, el->getMark() - 1); child[0]->setMark(mark); child[1]->setMark(mark); el->setMark(0); /*--------------------------------------------------------------------------*/ /* transfer hided data from parent to children */ /*--------------------------------------------------------------------------*/ el->refineElementData(child[0], child[1]); el->setFirstChild(child[0]); el->setSecondChild(child[1]); if (child[0]->getMark() > 0) traversePtr->doMoreRecursiveRefine = true; DegreeOfFreedom *newVertexDOFs = mesh->getDOF(VERTEX); child[0]->setDOF(1, newVertexDOFs); child[1]->setDOF(0, newVertexDOFs); /*--------------------------------------------------------------------------*/ /* the other vertices are handed on from the parent */ /*--------------------------------------------------------------------------*/ child[0]->setDOF(0, const_cast(el->getDOF(0))); child[1]->setDOF(1, const_cast(el->getDOF(1))); /*--------------------------------------------------------------------------*/ /* there is one more leaf element, two hierachical elements, */ /* one more vertex */ /*--------------------------------------------------------------------------*/ mesh->incrementNumberOfLeaves(1); mesh->incrementNumberOfVertices(1); mesh->incrementNumberOfElements(2); if (mesh->getNumberOfDOFs(CENTER)) { /*--------------------------------------------------------------------------*/ /* there are dofs at the barycenter of the triangles */ /*--------------------------------------------------------------------------*/ child[0]->setDOF(mesh->getNode(CENTER), const_cast(mesh->getDOF(CENTER))); child[1]->setDOF(mesh->getNode(CENTER), const_cast(mesh->getDOF(CENTER))); } /*--------------------------------------------------------------------------*/ /* if there are functions to interpolate data to the finer grid, do so */ /*--------------------------------------------------------------------------*/ RCNeighbourList ref_list(1); // = {{nil, 0, 0}}; ref_list.setElement(0, el); int nrAdmin = mesh->getNumberOfDOFAdmin(); for (int iadmin = 0; iadmin < nrAdmin; iadmin++) { std::list::iterator it; DOFAdmin* admin = const_cast(&mesh->getDOFAdmin(iadmin)); std::list::iterator end = admin->endDOFIndexed(); for (it = admin->beginDOFIndexed(); it != end; it++) (*it)->refineInterpol(ref_list, 1); } if (!mesh->queryCoarseDOFs() && mesh->getNumberOfDOFs(CENTER)) { mesh->freeDOF(const_cast( el->getDOF(mesh->getNode(CENTER))), CENTER); el->setDOF(mesh->getNode(CENTER), NULL); } return 0; } Flag RefinementManager1d::refineMesh(Mesh *aMesh) { mesh = aMesh; int nElements = mesh->getNumberOfLeaves(); doMoreRecursiveRefine = true; while (doMoreRecursiveRefine) { doMoreRecursiveRefine = false; traversePtr = this; mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS, recursiveRefineFunction); } nElements = mesh->getNumberOfLeaves() - nElements; if (newCoords) { setNewCoords(); // call of sub-class method } return (nElements ? MESH_REFINED : Flag(0)); } int RefinementManager1d::newCoordsFct(ElInfo *elInfo) { Element *el = elInfo->getElement(); int dow = Global::getGeo(WORLD); Projection *projector = elInfo->getProjection(0); if (el->getFirstChild() && projector && (!el->isNewCoordSet())) { WorldVector *new_coord = new WorldVector; for (int j = 0; j < dow; j++) (*new_coord)[j] = (elInfo->getCoord(0)[j] + elInfo->getCoord(1)[j]) * 0.5; projector->project(*new_coord); el->setNewCoord(new_coord); } return 0; } void RefinementManager1d::setNewCoords() { Flag fillFlag = Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_BOUND | Mesh::FILL_COORDS; mesh->traverse(-1, fillFlag, newCoordsFct); } }