From 544b8771bbfdbb3f8690cd150ffe1ddc24de8457 Mon Sep 17 00:00:00 2001 From: Tuomas Karna <tuomas.karna@uclouvain.be> Date: Tue, 9 Mar 2010 17:11:19 +0000 Subject: [PATCH] added dgGroupCollection::splitGroupsByVerticalLayer --- Geo/MPrism.h | 1 - Numeric/polynomialBasis.cpp | 2 +- Solver/dgGroupOfElements.cpp | 130 ++++++++++++++++++++++++++++++++++- Solver/dgGroupOfElements.h | 1 + 4 files changed, 130 insertions(+), 4 deletions(-) diff --git a/Geo/MPrism.h b/Geo/MPrism.h index 97a796eb18..68713e0920 100644 --- a/Geo/MPrism.h +++ b/Geo/MPrism.h @@ -142,7 +142,6 @@ class MPrism : public MElement { }*/ /* virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o) { - printf("here\n"); s[0][0] = -0.5 * (1. - w) ; s[0][1] = -0.5 * (1. - w) ; s[0][2] = -0.5 * (1. - u - v); diff --git a/Numeric/polynomialBasis.cpp b/Numeric/polynomialBasis.cpp index 95dbdb1f11..d9d5fc0e28 100644 --- a/Numeric/polynomialBasis.cpp +++ b/Numeric/polynomialBasis.cpp @@ -252,7 +252,7 @@ static fullMatrix<double> generatePascalPrism(int order) index ++; } } - monomials.print("Pri monoms"); +// monomials.print("Pri monoms"); return monomials; } diff --git a/Solver/dgGroupOfElements.cpp b/Solver/dgGroupOfElements.cpp index db2b5bd4f6..158aca05e6 100644 --- a/Solver/dgGroupOfElements.cpp +++ b/Solver/dgGroupOfElements.cpp @@ -342,9 +342,9 @@ void dgGroupCollection::buildGroupsOfElements(GModel *model, int dim, int order) std::map<int, std::vector<MElement *> >localElements; std::vector<std::map<int, std::vector<MElement *> > >ghostElements(Msg::GetCommSize()); // [partition][elementType] std::multimap<MElement*, short> &ghostsCells = _model->getGhostCells(); - for(unsigned int i = 0; i < entities.size(); i++) { + for(unsigned int i = 0; i < entities.size(); i++){ GEntity *entity = entities[i]; - if(entity->dim() == dim) { + if(entity->dim() == dim){ for (int iel=0; iel<entity->getNumMeshElements(); iel++){ MElement *el=entity->getMeshElement(iel); if(el->getPartition()==Msg::GetCommRank()+1 || el->getPartition()==0){ @@ -1010,6 +1010,129 @@ double dgGroupCollection::splitGroupsForMultirate(int maxLevels,dgConservationLa return dtRef; } +// Split the groups of elements into vertical layers (only for primsatic 3D meshes) +void dgGroupCollection::splitGroupsByVerticalLayer(std::vector<std::string> topLevelTags) { + + Msg::Info("Splitting Groups per vertical layers"); + + // Interfaces are not built yet, so we use a "mini" structure to deduce neighboring information + std::vector<dgMiniInterface> *miniInterfaceV=_createMiniInterfaces(*this); + // elementToNeighbors[oldGroupId][oldElementId][neighborId (i.e. 0 to 2 for triangles)]<neighborOldGroupId,neighborOldElementId> + std::vector<std::vector<std::vector<std::pair<int,int> > > >elementToNeighbors; + // id of the new group, indexed by [oldGroupId][oldElementId] + // -1 if the element is not yet in a new group + // -2 if the element is in a new group whose id is not determined yet + std::vector< dgGroupOfElements* >newGroups;// indexed by newGroupId + // isProcessed[oldGroupId][oldElementId] + std::vector<std::vector<int> >isProcessed; + + isProcessed.resize(getNbElementGroups()); + elementToNeighbors.resize(getNbElementGroups()); + for(int iGroup=0;iGroup<getNbElementGroups();iGroup++){ + dgGroupOfElements *g=getElementGroup(iGroup); + elementToNeighbors[iGroup].resize(g->getNbElements()); + isProcessed[iGroup].assign(g->getNbElements(),0); + } + + // Build elementToNeighbors table (needed to have random access to the neighbors) + for(int iInterface=0;iInterface<miniInterfaceV->size();iInterface++){ + dgMiniInterface &interface=miniInterfaceV->at(iInterface); + if (interface.numVertices == 3) { // only accept triangular interfaces + for(int iConn=0;iConn<interface.connections.size();iConn++){ + int gIdi=interface.connections[iConn].iGroup; + int eIdi=interface.connections[iConn].iElement; + for(int jConn=0;jConn<iConn;jConn++){ + int gIdj=interface.connections[jConn].iGroup; + int eIdj=interface.connections[jConn].iElement; + elementToNeighbors[gIdi][eIdi].push_back(std::pair<int,int>(gIdj,eIdj)); + elementToNeighbors[gIdj][eIdj].push_back(std::pair<int,int>(gIdi,eIdi)); + } + } + } + } + + std::vector< std::pair<int,int> > oldGroupElemIds; + std::vector< std::pair<int,int> > newGroupElemIds; + std::vector< std::vector< MElement* > > verticalGroupsVector; + std::vector< MElement* > newGroupElems; + int currentNewGroupId=0; + bool finalLayer = false; + + do { + newGroupElemIds.clear(); + newGroupElems.clear(); + if(currentNewGroupId==0) { + // create first element groups + for(int iInterface=0;iInterface<miniInterfaceV->size();iInterface++){ + dgMiniInterface &interface=miniInterfaceV->at(iInterface); + for(int iConn=0;iConn<interface.connections.size();iConn++){ + int gId=interface.connections[iConn].iGroup; + int eId=interface.connections[iConn].iElement; + bool topLevelTagFound = false; + for (int i = 0; i < topLevelTags.size(); i++) + if (_model->getPhysicalName(2, interface.physicalTag) == topLevelTags.at(i) ) { + topLevelTagFound = true; + break; + } + if (topLevelTagFound) { +// printf("Tag found: %d %d %s \n",gId,eId,_model->getPhysicalName(2, interface.physicalTag).c_str()); + newGroupElems.push_back(getElementGroup(gId)->getElement(eId)); + newGroupElemIds.push_back(std::pair<int,int>(gId,eId)); + isProcessed[gId][eId]=1; + } + } + } + if (newGroupElems.size() == 0) { + std::string errMsg = "No triangular boundary faces found with the given physical tag(s): "; + for (int i = 0; i < topLevelTags.size(); i++) + errMsg += topLevelTags.at(i) += " "; + Msg::Error(errMsg.c_str()); + } + } + else { + // find neighbors in next level + for (int iElems = 0; iElems<oldGroupElemIds.size();iElems++ ) { + int gId = oldGroupElemIds.at(iElems).first; + int eId = oldGroupElemIds.at(iElems).second; + bool newNeighborFound = false; + for (int iNeighbors = 0; iNeighbors < elementToNeighbors[gId][eId].size(); iNeighbors++) { + int nGId = elementToNeighbors[gId][eId].at(iNeighbors).first; + int nEId = elementToNeighbors[gId][eId].at(iNeighbors).second; + if (!isProcessed[nGId][nEId]) { + newGroupElemIds.push_back(std::pair<int,int>(nGId,nEId)); + newGroupElems.push_back(getElementGroup(nGId)->getElement(nEId)); + isProcessed[nGId][nEId]=1; + newNeighborFound = true; +// printf("adding neighbor eId: %d\n",nEId); + } + } + if (!newNeighborFound) { + finalLayer = true; + break; + } + } + } + + +// printf("new elems %d\n",newGroupElems.size()); + if (!finalLayer) { + dgGroupOfElements* oldGroup = getElementGroup(0); + dgGroupOfElements* newGroup=new dgGroupOfElements(newGroupElems,oldGroup->getOrder(),oldGroup->getGhostPartition()); + newGroup->copyPrivateDataFrom(oldGroup); + newGroups.resize(currentNewGroupId+1); + newGroups[currentNewGroupId]=newGroup; + printf("Created a new group ID:%d with %d elements.\n",currentNewGroupId,newGroup->getNbElements()); + currentNewGroupId++; + } + oldGroupElemIds = newGroupElemIds; + } while (!finalLayer); + + _elementGroups.clear(); + _elementGroups=newGroups; + delete miniInterfaceV; + +} + dgGroupCollection::dgGroupCollection() { _groupsOfElementsBuilt=false;_groupsOfInterfacesBuilt=false; @@ -1060,6 +1183,9 @@ void dgGroupCollection::registerBindings(binding *b) cm = cb->addMethod("splitGroupsForMultirate",&dgGroupCollection::splitGroupsForMultirate); cm->setDescription("Split the groups according to their own stable time step"); cm->setArgNames("maxLevels","claw","solution",NULL); + cm = cb->addMethod("splitGroupsByVerticalLayer",&dgGroupCollection::splitGroupsByVerticalLayer); + cm->setDescription("Split the groups according vertical layer structure. The first is defined by the topLevelTags."); + cm->setArgNames("topLevelTags",NULL); cm = cb->addMethod("getNbElementGroups", &dgGroupCollection::getNbElementGroups); cm->setDescription("return the number of dgGroupOfElements"); cm = cb->addMethod("getNbFaceGroups", &dgGroupCollection::getNbFaceGroups); diff --git a/Solver/dgGroupOfElements.h b/Solver/dgGroupOfElements.h index dc22cfcfd2..39bc4c2b9b 100644 --- a/Solver/dgGroupOfElements.h +++ b/Solver/dgGroupOfElements.h @@ -248,6 +248,7 @@ class dgGroupCollection { void buildGroupsOfInterfaces (); double splitGroupsForMultirate(int maxLevels,dgConservationLaw *claw, dgDofContainer *solution); + void splitGroupsByVerticalLayer(std::vector<std::string> topLevelTags); void find (MElement *elementToFind, int &iGroup, int &ithElementOfGroup); -- GitLab