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.
|
||||
* Flat elements are mainly used by some types of mechanic calculations.
|
||||
*
|
||||
* 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.
|
||||
* In option, the internal faces are replaced by flat elements.
|
||||
@ -1021,6 +1023,16 @@ module SMESH
|
||||
boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
* 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
|
||||
|
||||
for (int i = 0; i < _downArray.size(); i++)
|
||||
{
|
||||
if (_downArray[i])
|
||||
delete _downArray[i];
|
||||
_downArray[i] = 0;
|
||||
}
|
||||
_cellIdToDownId.clear();
|
||||
this->CleanDownwardConnectivity();
|
||||
|
||||
// --- create SMDS_Downward structures (in _downArray vector[vtkCellType])
|
||||
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
|
||||
int CellIdToDownId(int vtkCellId);
|
||||
void setCellIdToDownId(int vtkCellId, int downId);
|
||||
void CleanDownwardConnectivity();
|
||||
void BuildDownwardConnectivity(bool withEdges);
|
||||
int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId);
|
||||
int GetParentVolumes(int* volVtkIds, int vtkId);
|
||||
|
@ -10862,7 +10862,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
||||
MESSAGE("----------------------------------------------");
|
||||
|
||||
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
|
||||
meshDS->BuildDownWardConnectivity(false);
|
||||
meshDS->BuildDownWardConnectivity(true);
|
||||
CHRONO(50);
|
||||
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();
|
||||
|
||||
CHRONOSTOP(50);
|
||||
@ -11293,6 +11294,151 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
||||
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
|
||||
|
@ -570,6 +570,8 @@ public:
|
||||
bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
|
||||
bool createJointElems);
|
||||
|
||||
bool CreateFlatElementsOnFacesGroups( const std::vector<TIDSortedElemSet>& theElems );
|
||||
|
||||
/*!
|
||||
* \brief Generated skin mesh (containing 2D cells) from 3D mesh
|
||||
* 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)
|
||||
{
|
||||
myGrid->BuildDownwardConnectivity(withEdges);
|
||||
|
@ -445,6 +445,7 @@ public:
|
||||
bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
|
||||
|
||||
virtual void compactMesh();
|
||||
void CleanDownWardConnectivity();
|
||||
void BuildDownWardConnectivity(bool withEdges);
|
||||
|
||||
~SMESHDS_Mesh();
|
||||
|
@ -5632,6 +5632,53 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::Li
|
||||
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 ===================================================================
|
||||
/*!
|
||||
* \brief Creates missing boundary elements
|
||||
|
@ -704,6 +704,16 @@ public:
|
||||
*/
|
||||
CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
|
||||
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
|
||||
|
@ -4169,6 +4169,16 @@ class Mesh:
|
||||
def DoubleNodesOnGroupBoundaries(self, 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):
|
||||
fn = self.smeshpyD.GetFunctor(funcType)
|
||||
fn.SetMesh(self.mesh)
|
||||
|
Loading…
Reference in New Issue
Block a user