PR: double nodes and flat elements for ASTER calculations in progress

This commit is contained in:
prascle 2011-03-16 10:51:52 +00:00
parent 396e119df0
commit fcae5eda64
3 changed files with 125 additions and 23 deletions

View File

@ -741,6 +741,58 @@ int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsi
return nb; return nb;
} }
/*! get the volumes containing a face or an edge of the grid
* The edge or face belongs to the vtkUnstructuredGrid
* @param volVtkIds vector of parent volume ids to fill (reserve enough space!)
* @param vtkId vtk id of the face or edge
*/
int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int vtkId)
{
int vtkType = this->GetCellType(vtkId);
int dim = SMDS_Downward::getCellDimension(vtkType);
int nbFaces = 0;
int faces[1000];
unsigned char cellTypes[1000];
int downCellId[1000];
if (dim == 1)
{
int downId = this->CellIdToDownId(vtkId);
nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId);
const int *upCells = _downArray[vtkType]->getUpCells(downId);
const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId);
for (int i=0; i< nbFaces; i++)
{
faces[i] = _downArray[upTypes[i]]->getVtkCellId(upCells[i]);
cellTypes[i] = upTypes[i];
downCellId[i] = upCells[i];
}
}
else if (dim == 2)
{
nbFaces = 1;
faces[0] = vtkId;
cellTypes[0] = this->GetCellType(vtkId);
downCellId[0] = this->CellIdToDownId(vtkId);
}
int nbvol =0;
for (int i=0; i<nbFaces; i++)
{
int vtkTypeFace = cellTypes[i];
int downId = downCellId[i];
int nv = _downArray[vtkTypeFace]->getNumberOfUpCells(downId);
const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId);
const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId);
for (int j=0; j<nv; j++)
{
int vtkVolId = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
if (vtkVolId >= 0)
volVtkIds[nbvol++] = vtkVolId;
}
}
return nbvol;
}
/*! get the node id's of a cell. /*! get the node id's of a cell.
* The cell is defined by it's downward connectivity id and type. * The cell is defined by it's downward connectivity id and type.
* @param nodeSet set of of vtk node id's to fill. * @param nodeSet set of of vtk node id's to fill.

View File

@ -62,6 +62,7 @@ public:
void setCellIdToDownId(int vtkCellId, int downId); void setCellIdToDownId(int vtkCellId, int downId);
void BuildDownwardConnectivity(bool withEdges); void BuildDownwardConnectivity(bool withEdges);
int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId); int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId);
int GetParentVolumes(int* volVtkIds, int vtkId);
void GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType); void GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType);
void ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds); void ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds);
int getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes); int getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes);

View File

@ -10776,6 +10776,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
// --- new quad nodes on flat quad elements: oldId --> ((domain1 X domain2) --> newId) // --- new quad nodes on flat quad elements: oldId --> ((domain1 X domain2) --> newId)
// (domain1 X domain2) = domain1 + MAXINT*domain2 // (domain1 X domain2) = domain1 + MAXINT*domain2
std::map<int, std::map<long,int> > nodeQuadDomains; std::map<int, std::map<long,int> > nodeQuadDomains;
if (createJointElems) if (createJointElems)
@ -10799,41 +10800,89 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
} }
} }
// --- list the explicit faces and edges of the mesh that need to be modified,
// i.e. faces and edges built with one or more duplicated nodes.
// associate these faces or edges to their corresponding domain.
// only the first domain found is kept when a face or edge is shared
std::map<DownIdType, std::map<int,int>, DownIdCompare> faceOrEdgeDom; // cellToModify --> (id domain --> id cell)
std::map<int,int> feDom; // vtk id of cell to modify --> id domain
faceOrEdgeDom.clear();
feDom.clear();
for (int idomain = 0; idomain < theElems.size(); idomain++)
{
std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
for (; itnod != nodeDomains.end(); ++itnod)
{
int oldId = itnod->first;
//MESSAGE(" node " << oldId);
vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
for (int i = 0; i < l.ncells; i++)
{
int vtkId = l.cells[i];
int vtkType = grid->GetCellType(vtkId);
int downId = grid->CellIdToDownId(vtkId);
DownIdType aCell(downId, vtkType);
int volParents[1000];
int nbvol = grid->GetParentVolumes(volParents, vtkId);
for (int j = 0; j < nbvol; j++)
if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain))
if (!feDom.count(vtkId))
{
feDom[vtkId] = idomain;
faceOrEdgeDom[aCell] = emptyMap;
faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only
//MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain
// << " type " << vtkType << " downId " << downId);
}
}
}
}
// --- iterate on shared faces (volumes to modify, face to extrude) // --- iterate on shared faces (volumes to modify, face to extrude)
// get node id's of the face // get node id's of the face
// replace old nodes by new nodes in volumes, and update inverse connectivity // replace old nodes by new nodes in volumes, and update inverse connectivity
MESSAGE("cellDomains " << cellDomains.size()); std::map<DownIdType, std::map<int,int>, DownIdCompare>* maps[3] = {&faceDomains, &cellDomains, &faceOrEdgeDom};
faceDomains.insert(cellDomains.begin(), cellDomains.end()); for (int m=0; m<3; m++)
itface = faceDomains.begin();
for( ; itface != faceDomains.end();++itface )
{ {
DownIdType face = itface->first; std::map<DownIdType, std::map<int,int>, DownIdCompare>* amap = maps[m];
std::set<int> oldNodes; itface = (*amap).begin();
std::set<int>::iterator itn; for (; itface != (*amap).end(); ++itface)
oldNodes.clear();
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
std::map<int,int> localClonedNodeIds;
std::map<int,int> domvol = itface->second;
std::map<int,int>::iterator itdom = domvol.begin();
for(; itdom != domvol.end(); ++itdom)
{ {
int idom = itdom->first; DownIdType face = itface->first;
int vtkVolId = itdom->second; std::set<int> oldNodes;
localClonedNodeIds.clear(); std::set<int>::iterator itn;
for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) oldNodes.clear();
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
//MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType));
std::map<int, int> localClonedNodeIds;
std::map<int, int> domvol = itface->second;
std::map<int, int>::iterator itdom = domvol.begin();
for (; itdom != domvol.end(); ++itdom)
{ {
int oldId = *itn; int idom = itdom->first;
if (nodeDomains[oldId].count(idom)) int vtkVolId = itdom->second;
localClonedNodeIds[oldId] = nodeDomains[oldId][idom]; //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom);
localClonedNodeIds.clear();
for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
{
int oldId = *itn;
if (nodeDomains[oldId].count(idom))
{
localClonedNodeIds[oldId] = nodeDomains[oldId][idom];
//MESSAGE(" node " << oldId << " --> " << localClonedNodeIds[oldId]);
}
}
meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds);
} }
meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds);
} }
} }
grid->BuildLinks(); grid->BuildLinks();
// TODO replace also old nodes by new nodes in faces and edges
CHRONOSTOP(50); CHRONOSTOP(50);
counters::stats(); counters::stats();
return true; return true;