PR: flat elements on 2D meshes

This commit is contained in:
prascle 2012-02-02 17:06:56 +00:00
parent 24df7fa1ab
commit fda2d7b99e
7 changed files with 249 additions and 124 deletions

View File

@ -78,6 +78,7 @@ public:
virtual const unsigned char* getUpTypes(int cellId) = 0; virtual const unsigned char* getUpTypes(int cellId) = 0;
virtual void getNodeIds(int cellId, std::set<int>& nodeSet) = 0; virtual void getNodeIds(int cellId, std::set<int>& nodeSet) = 0;
virtual int getNodes(int cellId, int* nodevec) {return 0; } virtual int getNodes(int cellId, int* nodevec) {return 0; }
virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes) {};
int getVtkCellId(int cellId) int getVtkCellId(int cellId)
{ {
return _vtkCellIds[cellId]; return _vtkCellIds[cellId];
@ -178,7 +179,6 @@ public:
virtual const int* getUpCells(int cellId); virtual const int* getUpCells(int cellId);
virtual const unsigned char* getUpTypes(int cellId); virtual const unsigned char* getUpTypes(int cellId);
virtual void getNodeIds(int cellId, std::set<int>& nodeSet); virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes) = 0;
protected: protected:
SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells); SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells);
~SMDS_Down3D(); ~SMDS_Down3D();

View File

@ -1507,6 +1507,53 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdTyp
return volvtk; return volvtk;
} }
SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
{
int ID = myElementIDFactory->GetFreeID();
SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
if (f == NULL) myElementIDFactory->ReleaseID(ID);
return f;
}
SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
{
SMDS_VtkFace *facevtk = myFacePool->getNew();
facevtk->init(vtkNodeIds, this);
if (!this->registerElement(ID,facevtk))
{
this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
myFacePool->destroy(facevtk);
return 0;
}
adjustmyCellsCapacity(ID);
myCells[ID] = facevtk;
vtkIdType aVtkType = facevtk->GetVtkType();
switch (aVtkType)
{
case VTK_TRIANGLE:
myInfo.myNbTriangles++;
break;
case VTK_QUAD:
myInfo.myNbQuadrangles++;
break;
case VTK_QUADRATIC_TRIANGLE:
myInfo.myNbQuadTriangles++;
break;
case VTK_QUADRATIC_QUAD:
myInfo.myNbQuadQuadrangles++;
break;
case VTK_BIQUADRATIC_QUAD:
myInfo.myNbBiQuadQuadrangles++;
break;
case VTK_POLYGON:
myInfo.myNbPolygons++;
break;
default:
myInfo.myNbPolygons++;
}
return facevtk;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Registers element with the given ID, maintains inverse connections /// Registers element with the given ID, maintains inverse connections
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -568,6 +568,11 @@ public:
virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds,
const int ID); const int ID);
virtual SMDS_MeshFace* AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds);
virtual SMDS_MeshFace* AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds,
const int ID);
virtual void RemoveElement(const SMDS_MeshElement * elem, virtual void RemoveElement(const SMDS_MeshElement * elem,
std::list<const SMDS_MeshElement *>& removedElems, std::list<const SMDS_MeshElement *>& removedElems,
std::list<const SMDS_MeshElement *>& removedNodes, std::list<const SMDS_MeshElement *>& removedNodes,

View File

@ -929,15 +929,17 @@ void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> loc
* @param orderedNodes list of nodes to reorder (in out) * @param orderedNodes list of nodes to reorder (in out)
* @return size of the list * @return size of the list
*/ */
int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes) int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector<vtkIdType>& orderedNodes)
{ {
int vtkType = this->GetCellType(vtkVolId); int vtkType = this->GetCellType(vtkVolId);
int cellDim = SMDS_Downward::getCellDimension(vtkType); dim = SMDS_Downward::getCellDimension(vtkType);
if (cellDim != 3) if (dim == 3)
return 0; {
SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]); SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
int downVolId = this->_cellIdToDownId[vtkVolId]; int downVolId = this->_cellIdToDownId[vtkVolId];
downvol->getOrderedNodesOfFace(downVolId, orderedNodes); downvol->getOrderedNodesOfFace(downVolId, orderedNodes);
}
// else nothing to do;
return orderedNodes.size(); return orderedNodes.size();
} }
@ -970,7 +972,7 @@ void SMDS_UnstructuredGrid::BuildLinks()
* @param nodeDomains: map(original id --> map(domain --> duplicated node id)) * @param nodeDomains: map(original id --> map(domain --> duplicated node id))
* @return ok if success. * @return ok if success.
*/ */
SMDS_MeshVolume* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId,
int domain1, int domain1,
int domain2, int domain2,
std::set<int>& originalNodes, std::set<int>& originalNodes,
@ -984,20 +986,27 @@ SMDS_MeshVolume* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId,
for (; it != originalNodes.end(); ++it) for (; it != originalNodes.end(); ++it)
orderedOriginals.push_back(*it); orderedOriginals.push_back(*it);
int nbNodes = this->getOrderedNodesOfFace(vtkVolId, orderedOriginals); int dim = 0;
int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals);
vector<vtkIdType> orderedNodes; vector<vtkIdType> orderedNodes;
bool isQuadratic = false;
switch (orderedOriginals.size()) switch (orderedOriginals.size())
{ {
case 3: case 3:
case 4: if (dim == 2)
for (int i = 0; i < nbNodes; i++) isQuadratic = true;
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
for (int i = 0; i < nbNodes; i++)
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
break; break;
case 6: case 6:
case 8: case 8:
isQuadratic = true;
break;
default:
isQuadratic = false;
break;
}
if (isQuadratic)
{ {
long dom1 = domain1; long dom1 = domain1;
long dom2 = domain2; long dom2 = domain2;
@ -1036,13 +1045,30 @@ SMDS_MeshVolume* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId,
orderedNodes.push_back(newId); orderedNodes.push_back(newId);
} }
} }
break; else
default: {
ASSERT(0); for (int i = 0; i < nbNodes; i++)
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
if (dim == 3)
for (int i = 0; i < nbNodes; i++)
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
else
for (int i = nbNodes-1; i >= 0; i--)
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
} }
if (dim == 3)
{
SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes);
// TODO update sub-shape list of elements and nodes
return vol; return vol;
} }
else if (dim == 2)
{
SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes);
return face;
}
// TODO update sub-shape list of elements and nodes
return 0;
}

View File

@ -48,6 +48,7 @@
class SMDS_Downward; class SMDS_Downward;
class SMDS_Mesh; class SMDS_Mesh;
class SMDS_MeshCell;
class SMDS_MeshVolume; class SMDS_MeshVolume;
class SMDS_EXPORT SMDS_CellLinks: public vtkCellLinks class SMDS_EXPORT SMDS_CellLinks: public vtkCellLinks
@ -86,9 +87,9 @@ public:
int GetParentVolumes(int* volVtkIds, int downId, unsigned char downType); int GetParentVolumes(int* volVtkIds, int downId, unsigned char downType);
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, int& dim, std::vector<vtkIdType>& orderedNodes);
void BuildLinks(); void BuildLinks();
SMDS_MeshVolume* extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2, std::set<int>& originalNodes, SMDS_MeshCell* extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2, std::set<int>& originalNodes,
std::map<int, std::map<int, int> >& nodeDomains, std::map<int, std::map<int, int> >& nodeDomains,
std::map<int, std::map<long,int> >& nodeQuadDomains); std::map<int, std::map<long,int> >& nodeQuadDomains);
vtkCellLinks* GetLinks() vtkCellLinks* GetLinks()

View File

@ -10727,6 +10727,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
// and corresponding volume of this domain, for each shared face. // and corresponding volume of this domain, for each shared face.
// a volume has a face shared by 2 domains if it has a neighbor which is not in is domain. // a volume has a face shared by 2 domains if it has a neighbor which is not in is domain.
//MESSAGE("Domain " << idom);
const TIDSortedElemSet& domain = theElems[idom]; const TIDSortedElemSet& domain = theElems[idom];
TIDSortedElemSet::const_iterator elemItr = domain.begin(); TIDSortedElemSet::const_iterator elemItr = domain.begin();
for (; elemItr != domain.end(); ++elemItr) for (; elemItr != domain.end(); ++elemItr)
@ -10735,6 +10736,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
if (!anElem) if (!anElem)
continue; continue;
int vtkId = anElem->getVtkId(); int vtkId = anElem->getVtkId();
//MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID());
int neighborsVtkIds[NBMAXNEIGHBORS]; int neighborsVtkIds[NBMAXNEIGHBORS];
int downIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS];
unsigned char downTypes[NBMAXNEIGHBORS]; unsigned char downTypes[NBMAXNEIGHBORS];
@ -10752,6 +10754,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
{ {
faceDomains[face][idom] = vtkId; // volume associated to face in this domain faceDomains[face][idom] = vtkId; // volume associated to face in this domain
celldom[vtkId] = idom; celldom[vtkId] = idom;
//MESSAGE(" cell with a border " << vtkId << " domain " << idom);
} }
} }
} }
@ -10767,6 +10770,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
for (int idomain = 0; idomain < theElems.size(); idomain++) for (int idomain = 0; idomain < theElems.size(); idomain++)
{ {
//MESSAGE("Domain " << idomain);
const TIDSortedElemSet& domain = theElems[idomain]; const TIDSortedElemSet& domain = theElems[idomain];
itface = faceDomains.begin(); itface = faceDomains.begin();
for (; itface != faceDomains.end(); ++itface) for (; itface != faceDomains.end(); ++itface)
@ -10806,6 +10810,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
continue; continue;
cellDomains[aCell][idomain] = vtkId; cellDomains[aCell][idomain] = vtkId;
celldom[vtkId] = idomain; celldom[vtkId] = idomain;
//MESSAGE(" cell " << vtkId << " domain " << idomain);
} }
} }
} }
@ -10820,7 +10825,8 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
// the value is the ordered domain ids. (more than 4 domains not taken into account) // the value is the ordered domain ids. (more than 4 domains not taken into account)
std::map<std::vector<int>, std::vector<int> > edgesMultiDomains; // nodes of edge --> ordered domains std::map<std::vector<int>, std::vector<int> > edgesMultiDomains; // nodes of edge --> ordered domains
std::map<int, std::vector<int> > mutipleNodes; // nodes muti domains with domain order std::map<int, std::vector<int> > mutipleNodes; // nodes multi domains with domain order
std::map<int, std::vector<int> > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains)
for (int idomain = 0; idomain < theElems.size(); idomain++) for (int idomain = 0; idomain < theElems.size(); idomain++)
{ {
@ -10890,6 +10896,18 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
//MESSAGE("multiple Nodes detected on a shared face"); //MESSAGE("multiple Nodes detected on a shared face");
int downId = itface->first.cellId; int downId = itface->first.cellId;
unsigned char cellType = itface->first.cellType; unsigned char cellType = itface->first.cellType;
// --- shared edge or shared face ?
if ((cellType == VTK_LINE) || (cellType == VTK_QUADRATIC_EDGE)) // shared edge (between two faces)
{
int nodes[3];
int nbNodes = grid->getDownArray(cellType)->getNodes(downId, nodes);
for (int i=0; i< nbNodes; i=i+nbNodes-1) // i=0 , i=nbNodes-1
if (mutipleNodes.count(nodes[i]))
if (!mutipleNodesToFace.count(nodes[i]))
mutipleNodesToFace[nodes[i]] = mutipleNodes[nodes[i]];
}
else // shared face (between two volumes)
{
int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId); int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId);
const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId); const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId);
const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId); const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId);
@ -10966,6 +10984,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
} }
} }
} }
}
// --- 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 (id SMDS = id VTK) // get node id's of the face (id SMDS = id VTK)
@ -10994,7 +11013,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
int vtkVolId = itdom->second; int vtkVolId = itdom->second;
itdom++; itdom++;
int dom2 = itdom->first; int dom2 = itdom->first;
SMDS_MeshVolume *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains,
nodeQuadDomains); nodeQuadDomains);
stringstream grpname; stringstream grpname;
grpname << "j_"; grpname << "j_";
@ -11005,7 +11024,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
int idg; int idg;
string namegrp = grpname.str(); string namegrp = grpname.str();
if (!mapOfJunctionGroups.count(namegrp)) if (!mapOfJunctionGroups.count(namegrp))
mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg);
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS()); SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
if (sgrp) if (sgrp)
sgrp->Add(vol->GetID()); sgrp->Add(vol->GetID());
@ -11013,10 +11032,37 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
} }
// --- create volumes on multiple domain intersection if requested // --- create volumes on multiple domain intersection if requested
// iterate on mutipleNodesToFace
// iterate on edgesMultiDomains // iterate on edgesMultiDomains
if (createJointElems) if (createJointElems)
{ {
// --- iterate on mutipleNodesToFace
std::map<int, std::vector<int> >::iterator itn = mutipleNodesToFace.begin();
for (; itn != mutipleNodesToFace.end(); ++itn)
{
int node = itn->first;
vector<int> orderDom = itn->second;
vector<vtkIdType> orderedNodes;
for (int idom = 0; idom <orderDom.size(); idom++)
orderedNodes.push_back( nodeDomains[node][orderDom[idom]] );
SMDS_MeshFace* face = this->GetMeshDS()->AddFaceFromVtkIds(orderedNodes);
stringstream grpname;
grpname << "m2j_";
grpname << 0 << "_" << 0;
int idg;
string namegrp = grpname.str();
if (!mapOfJunctionGroups.count(namegrp))
mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg);
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
if (sgrp)
sgrp->Add(face->GetID());
}
// --- iterate on edgesMultiDomains
std::map<std::vector<int>, std::vector<int> >::iterator ite = edgesMultiDomains.begin(); std::map<std::vector<int>, std::vector<int> >::iterator ite = edgesMultiDomains.begin();
for (; ite != edgesMultiDomains.end(); ++ite) for (; ite != edgesMultiDomains.end(); ++ite)
{ {
@ -11048,7 +11094,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
} }
else else
{ {
//MESSAGE("Quadratic multiple joints not implemented"); MESSAGE("Quadratic multiple joints not implemented");
// TODO quadratic nodes // TODO quadratic nodes
} }
} }

View File

@ -5739,8 +5739,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::Li
SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ]; SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ ) if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
{ {
if ( aGrp->GetType() != SMESH::VOLUME ) // if ( aGrp->GetType() != SMESH::VOLUME )
THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM); // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
TIDSortedElemSet domain; TIDSortedElemSet domain;
domain.clear(); domain.clear();
domains.push_back(domain); domains.push_back(domain);