mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-24 16:30:34 +05:00
PR: create flat elements on face groups (ASTER calculations)
This commit is contained in:
parent
5f35b29326
commit
ecea4040f1
@ -1010,6 +1010,8 @@ module SMESH
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
|
||||||
|
* Flat elements are mainly used by some types of mechanic calculations.
|
||||||
|
*
|
||||||
* The list of groups must describe a partition of the mesh volumes.
|
* The list of groups must describe a partition of the mesh volumes.
|
||||||
* The nodes of the internal faces at the boundaries of the groups are doubled.
|
* The nodes of the internal faces at the boundaries of the groups are doubled.
|
||||||
* In option, the internal faces are replaced by flat elements.
|
* In option, the internal faces are replaced by flat elements.
|
||||||
@ -1021,6 +1023,16 @@ module SMESH
|
|||||||
boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
|
boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
|
||||||
in boolean createJointElems );
|
in boolean createJointElems );
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Double nodes on some external faces and create flat elements.
|
||||||
|
* Flat elements are mainly used by some types of mechanic calculations.
|
||||||
|
*
|
||||||
|
* Each group of the list must be constituted of faces.
|
||||||
|
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||||
|
* \param theGroupsOfFaces - list of groups of faces
|
||||||
|
* \return TRUE if operation has been completed successfully, FALSE otherwise
|
||||||
|
*/
|
||||||
|
boolean CreateFlatElementsOnFacesGroups( in ListOfGroups theGroupsOfFaces );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -322,6 +322,17 @@ void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
|
|||||||
_cellIdToDownId[vtkCellId] = downId;
|
_cellIdToDownId[vtkCellId] = downId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMDS_UnstructuredGrid::CleanDownwardConnectivity()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _downArray.size(); i++)
|
||||||
|
{
|
||||||
|
if (_downArray[i])
|
||||||
|
delete _downArray[i];
|
||||||
|
_downArray[i] = 0;
|
||||||
|
}
|
||||||
|
_cellIdToDownId.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/*! Build downward connectivity: to do only when needed because heavy memory load.
|
/*! Build downward connectivity: to do only when needed because heavy memory load.
|
||||||
* Downward connectivity is no more valid if vtkUnstructuredGrid is modified.
|
* Downward connectivity is no more valid if vtkUnstructuredGrid is modified.
|
||||||
*
|
*
|
||||||
@ -333,13 +344,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges)
|
|||||||
|
|
||||||
// --- erase previous data if any
|
// --- erase previous data if any
|
||||||
|
|
||||||
for (int i = 0; i < _downArray.size(); i++)
|
this->CleanDownwardConnectivity();
|
||||||
{
|
|
||||||
if (_downArray[i])
|
|
||||||
delete _downArray[i];
|
|
||||||
_downArray[i] = 0;
|
|
||||||
}
|
|
||||||
_cellIdToDownId.clear();
|
|
||||||
|
|
||||||
// --- create SMDS_Downward structures (in _downArray vector[vtkCellType])
|
// --- create SMDS_Downward structures (in _downArray vector[vtkCellType])
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
|
|
||||||
int CellIdToDownId(int vtkCellId);
|
int CellIdToDownId(int vtkCellId);
|
||||||
void setCellIdToDownId(int vtkCellId, int downId);
|
void setCellIdToDownId(int vtkCellId, int downId);
|
||||||
|
void CleanDownwardConnectivity();
|
||||||
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);
|
int GetParentVolumes(int* volVtkIds, int vtkId);
|
||||||
|
@ -10862,7 +10862,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
MESSAGE("----------------------------------------------");
|
MESSAGE("----------------------------------------------");
|
||||||
|
|
||||||
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
|
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
|
||||||
meshDS->BuildDownWardConnectivity(false);
|
meshDS->BuildDownWardConnectivity(true);
|
||||||
CHRONO(50);
|
CHRONO(50);
|
||||||
SMDS_UnstructuredGrid *grid = meshDS->getGrid();
|
SMDS_UnstructuredGrid *grid = meshDS->getGrid();
|
||||||
|
|
||||||
@ -11286,6 +11286,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meshDS->CleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory
|
||||||
grid->BuildLinks();
|
grid->BuildLinks();
|
||||||
|
|
||||||
CHRONOSTOP(50);
|
CHRONOSTOP(50);
|
||||||
@ -11293,6 +11294,151 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Double nodes on some external faces and create flat elements.
|
||||||
|
* Flat elements are mainly used by some types of mechanic calculations.
|
||||||
|
*
|
||||||
|
* Each group of the list must be constituted of faces.
|
||||||
|
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||||
|
* @param theElems - list of groups of faces, where a group of faces is a set of
|
||||||
|
* SMDS_MeshElements sorted by Id.
|
||||||
|
* @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||||
|
*/
|
||||||
|
bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSortedElemSet>& theElems)
|
||||||
|
{
|
||||||
|
MESSAGE("-------------------------------------------------");
|
||||||
|
MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups");
|
||||||
|
MESSAGE("-------------------------------------------------");
|
||||||
|
|
||||||
|
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
|
||||||
|
|
||||||
|
// --- For each group of faces
|
||||||
|
// duplicate the nodes, create a flat element based on the face
|
||||||
|
// replace the nodes of the faces by their clones
|
||||||
|
|
||||||
|
std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> clonedNodes;
|
||||||
|
std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> intermediateNodes;
|
||||||
|
clonedNodes.clear();
|
||||||
|
intermediateNodes.clear();
|
||||||
|
|
||||||
|
for (int idom = 0; idom < theElems.size(); idom++)
|
||||||
|
{
|
||||||
|
const TIDSortedElemSet& domain = theElems[idom];
|
||||||
|
TIDSortedElemSet::const_iterator elemItr = domain.begin();
|
||||||
|
for (; elemItr != domain.end(); ++elemItr)
|
||||||
|
{
|
||||||
|
SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
|
||||||
|
SMDS_MeshFace* aFace = dynamic_cast<SMDS_MeshFace*> (anElem);
|
||||||
|
if (!aFace)
|
||||||
|
continue;
|
||||||
|
// MESSAGE("aFace=" << aFace->GetID());
|
||||||
|
bool isQuad = aFace->IsQuadratic();
|
||||||
|
vector<const SMDS_MeshNode*> ln0, ln1, ln2, ln3, ln4;
|
||||||
|
|
||||||
|
// --- clone the nodes, create intermediate nodes for non medium nodes of a quad face
|
||||||
|
|
||||||
|
SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator();
|
||||||
|
while (nodeIt->more())
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*> (nodeIt->next());
|
||||||
|
bool isMedium = isQuad && (aFace->IsMediumNode(node));
|
||||||
|
if (isMedium)
|
||||||
|
ln2.push_back(node);
|
||||||
|
else
|
||||||
|
ln0.push_back(node);
|
||||||
|
|
||||||
|
const SMDS_MeshNode* clone = 0;
|
||||||
|
if (!clonedNodes.count(node))
|
||||||
|
{
|
||||||
|
clone = meshDS->AddNode(node->X(), node->Y(), node->Z());
|
||||||
|
clonedNodes[node] = clone;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
clone = clonedNodes[node];
|
||||||
|
|
||||||
|
if (isMedium)
|
||||||
|
ln3.push_back(clone);
|
||||||
|
else
|
||||||
|
ln1.push_back(clone);
|
||||||
|
|
||||||
|
const SMDS_MeshNode* inter = 0;
|
||||||
|
if (isQuad && (!isMedium))
|
||||||
|
{
|
||||||
|
if (!intermediateNodes.count(node))
|
||||||
|
{
|
||||||
|
inter = meshDS->AddNode(node->X(), node->Y(), node->Z());
|
||||||
|
intermediateNodes[node] = inter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inter = intermediateNodes[node];
|
||||||
|
ln4.push_back(inter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- extrude the face
|
||||||
|
|
||||||
|
vector<const SMDS_MeshNode*> ln;
|
||||||
|
SMDS_MeshVolume* vol = 0;
|
||||||
|
vtkIdType aType = aFace->GetVtkType();
|
||||||
|
switch (aType)
|
||||||
|
{
|
||||||
|
case VTK_TRIANGLE:
|
||||||
|
vol = meshDS->AddVolume(ln0[2], ln0[1], ln0[0], ln1[2], ln1[1], ln1[0]);
|
||||||
|
// MESSAGE("vol prism " << vol->GetID());
|
||||||
|
ln.push_back(ln1[0]);
|
||||||
|
ln.push_back(ln1[1]);
|
||||||
|
ln.push_back(ln1[2]);
|
||||||
|
break;
|
||||||
|
case VTK_QUAD:
|
||||||
|
vol = meshDS->AddVolume(ln0[3], ln0[2], ln0[1], ln0[0], ln1[3], ln1[2], ln1[1], ln1[0]);
|
||||||
|
// MESSAGE("vol hexa " << vol->GetID());
|
||||||
|
ln.push_back(ln1[0]);
|
||||||
|
ln.push_back(ln1[1]);
|
||||||
|
ln.push_back(ln1[2]);
|
||||||
|
ln.push_back(ln1[3]);
|
||||||
|
break;
|
||||||
|
case VTK_QUADRATIC_TRIANGLE:
|
||||||
|
vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln0[0], ln0[1], ln0[2], ln3[0], ln3[1], ln3[2],
|
||||||
|
ln2[0], ln2[1], ln2[2], ln4[0], ln4[1], ln4[2]);
|
||||||
|
// MESSAGE("vol quad prism " << vol->GetID());
|
||||||
|
ln.push_back(ln1[0]);
|
||||||
|
ln.push_back(ln1[1]);
|
||||||
|
ln.push_back(ln1[2]);
|
||||||
|
ln.push_back(ln3[0]);
|
||||||
|
ln.push_back(ln3[1]);
|
||||||
|
ln.push_back(ln3[2]);
|
||||||
|
break;
|
||||||
|
case VTK_QUADRATIC_QUAD:
|
||||||
|
// vol = meshDS->AddVolume(ln0[0], ln0[1], ln0[2], ln0[3], ln1[0], ln1[1], ln1[2], ln1[3],
|
||||||
|
// ln2[0], ln2[1], ln2[2], ln2[3], ln3[0], ln3[1], ln3[2], ln3[3],
|
||||||
|
// ln4[0], ln4[1], ln4[2], ln4[3]);
|
||||||
|
vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln1[3], ln0[0], ln0[1], ln0[2], ln0[3],
|
||||||
|
ln3[0], ln3[1], ln3[2], ln3[3], ln2[0], ln2[1], ln2[2], ln2[3],
|
||||||
|
ln4[0], ln4[1], ln4[2], ln4[3]);
|
||||||
|
// MESSAGE("vol quad hexa " << vol->GetID());
|
||||||
|
ln.push_back(ln1[0]);
|
||||||
|
ln.push_back(ln1[1]);
|
||||||
|
ln.push_back(ln1[2]);
|
||||||
|
ln.push_back(ln1[3]);
|
||||||
|
ln.push_back(ln3[0]);
|
||||||
|
ln.push_back(ln3[1]);
|
||||||
|
ln.push_back(ln3[2]);
|
||||||
|
ln.push_back(ln3[3]);
|
||||||
|
break;
|
||||||
|
case VTK_POLYGON:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- modify the face
|
||||||
|
|
||||||
|
aFace->ChangeNodes(&ln[0], ln.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates skin mesh (containing 2D cells) from 3D mesh
|
* \brief Generates skin mesh (containing 2D cells) from 3D mesh
|
||||||
|
@ -570,6 +570,8 @@ public:
|
|||||||
bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
|
bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
|
||||||
bool createJointElems);
|
bool createJointElems);
|
||||||
|
|
||||||
|
bool CreateFlatElementsOnFacesGroups( const std::vector<TIDSortedElemSet>& theElems );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
||||||
* The created 2D mesh elements based on nodes of free faces of boundary volumes
|
* The created 2D mesh elements based on nodes of free faces of boundary volumes
|
||||||
|
@ -1959,6 +1959,11 @@ void SMESHDS_Mesh::compactMesh()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMESHDS_Mesh::CleanDownWardConnectivity()
|
||||||
|
{
|
||||||
|
myGrid->CleanDownwardConnectivity();
|
||||||
|
}
|
||||||
|
|
||||||
void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
|
void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
|
||||||
{
|
{
|
||||||
myGrid->BuildDownwardConnectivity(withEdges);
|
myGrid->BuildDownwardConnectivity(withEdges);
|
||||||
|
@ -445,6 +445,7 @@ public:
|
|||||||
bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
|
bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
|
||||||
|
|
||||||
virtual void compactMesh();
|
virtual void compactMesh();
|
||||||
|
void CleanDownWardConnectivity();
|
||||||
void BuildDownWardConnectivity(bool withEdges);
|
void BuildDownWardConnectivity(bool withEdges);
|
||||||
|
|
||||||
~SMESHDS_Mesh();
|
~SMESHDS_Mesh();
|
||||||
|
@ -5632,6 +5632,53 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::Li
|
|||||||
return aResult;
|
return aResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Double nodes on some external faces and create flat elements.
|
||||||
|
* Flat elements are mainly used by some types of mechanic calculations.
|
||||||
|
*
|
||||||
|
* Each group of the list must be constituted of faces.
|
||||||
|
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||||
|
* @param theGroupsOfFaces - list of groups of faces
|
||||||
|
* @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
|
||||||
|
{
|
||||||
|
initData();
|
||||||
|
|
||||||
|
::SMESH_MeshEditor aMeshEditor( myMesh );
|
||||||
|
|
||||||
|
SMESHDS_Mesh* aMeshDS = GetMeshDS();
|
||||||
|
|
||||||
|
vector<TIDSortedElemSet> faceGroups;
|
||||||
|
faceGroups.clear();
|
||||||
|
|
||||||
|
for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
|
||||||
|
{
|
||||||
|
SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
|
||||||
|
if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
|
||||||
|
{
|
||||||
|
TIDSortedElemSet faceGroup;
|
||||||
|
faceGroup.clear();
|
||||||
|
faceGroups.push_back(faceGroup);
|
||||||
|
SMESH::long_array_var anIDs = aGrp->GetIDs();
|
||||||
|
arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
|
||||||
|
// TODO publish the groups of flat elements in study
|
||||||
|
|
||||||
|
storeResult( aMeshEditor) ;
|
||||||
|
myMesh->GetMeshDS()->Modified();
|
||||||
|
|
||||||
|
// Update Python script
|
||||||
|
TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
|
||||||
|
return aResult;
|
||||||
|
}
|
||||||
|
|
||||||
// issue 20749 ===================================================================
|
// issue 20749 ===================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates missing boundary elements
|
* \brief Creates missing boundary elements
|
||||||
|
@ -704,6 +704,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
|
CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
|
||||||
CORBA::Boolean createJointElems );
|
CORBA::Boolean createJointElems );
|
||||||
|
/*!
|
||||||
|
* \brief Double nodes on some external faces and create flat elements.
|
||||||
|
* Flat elements are mainly used by some types of mechanic calculations.
|
||||||
|
*
|
||||||
|
* Each group of the list must be constituted of faces.
|
||||||
|
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||||
|
* @param theGroupsOfFaces - list of groups of faces
|
||||||
|
* @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||||
|
*/
|
||||||
|
CORBA::Boolean CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
||||||
|
@ -4169,6 +4169,16 @@ class Mesh:
|
|||||||
def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ):
|
def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ):
|
||||||
return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems )
|
return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems )
|
||||||
|
|
||||||
|
## Double nodes on some external faces and create flat elements.
|
||||||
|
# Flat elements are mainly used by some types of mechanic calculations.
|
||||||
|
#
|
||||||
|
# Each group of the list must be constituted of faces.
|
||||||
|
# Triangles are transformed in prisms, and quadrangles in hexahedrons.
|
||||||
|
# @param theGroupsOfFaces - list of groups of faces
|
||||||
|
# @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||||
|
def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
|
||||||
|
return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
|
||||||
|
|
||||||
def _valueFromFunctor(self, funcType, elemId):
|
def _valueFromFunctor(self, funcType, elemId):
|
||||||
fn = self.smeshpyD.GetFunctor(funcType)
|
fn = self.smeshpyD.GetFunctor(funcType)
|
||||||
fn.SetMesh(self.mesh)
|
fn.SetMesh(self.mesh)
|
||||||
|
Loading…
Reference in New Issue
Block a user