mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-26 09:20:34 +05:00
EDF 30254 - quadratic to biquadratic : several problems
For biquadratic hexa was fixed next problems: * Volume and AspectRatio was equal 0 * Create boundary elements don't creating faces on this volume type * Fixed problem with free nodes after convert quadratic <-> bi-quadratic * Fixed problem when for volume with type BiQuadratic Pentahedron boundary elements for triangle side is quadratic and not bi-quadratic * Added missed fix for negative volume
This commit is contained in:
parent
9e961b5451
commit
82ab2838b5
@ -1131,6 +1131,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
|
|||||||
if (nbNodes==10) nbNodes=4; // quadratic tetrahedron
|
if (nbNodes==10) nbNodes=4; // quadratic tetrahedron
|
||||||
else if(nbNodes==13) nbNodes=5; // quadratic pyramid
|
else if(nbNodes==13) nbNodes=5; // quadratic pyramid
|
||||||
else if(nbNodes==15) nbNodes=6; // quadratic pentahedron
|
else if(nbNodes==15) nbNodes=6; // quadratic pentahedron
|
||||||
|
else if(nbNodes==18) nbNodes=6; // bi-quadratic pentahedron
|
||||||
else if(nbNodes==20) nbNodes=8; // quadratic hexahedron
|
else if(nbNodes==20) nbNodes=8; // quadratic hexahedron
|
||||||
else if(nbNodes==27) nbNodes=8; // tri-quadratic hexahedron
|
else if(nbNodes==27) nbNodes=8; // tri-quadratic hexahedron
|
||||||
else return aQuality;
|
else return aQuality;
|
||||||
|
@ -266,25 +266,25 @@ static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL)
|
|||||||
static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
|
static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// + N4
|
// + N4 +
|
||||||
// /|\
|
// /|\ /|\
|
||||||
// 9/ | \10
|
// 9/ | \10 + | +
|
||||||
// / | \
|
// / | \ / | \
|
||||||
// / | \
|
// / | \ / | \
|
||||||
// N3 +----+----+ N5
|
// N3 +----+----+ N5 +----+----+
|
||||||
// | |11 |
|
// | |11 | | | |
|
||||||
// | | |
|
// | | | | | | Central nodes
|
||||||
// | +13 | QUADRATIC
|
// | +13 | QUADRATIC | 16 + | of bi-quadratic
|
||||||
// | | | PENTAHEDRON
|
// | | | PENTAHEDRON | + | + | PENTAHEDRON
|
||||||
// 12+ | +14
|
// 12+ | +14 + | 17 +
|
||||||
// | | |
|
// | | | | 18| |
|
||||||
// | | |
|
// | | | | | |
|
||||||
// | + N1 |
|
// | + N1 | | + |
|
||||||
// | / \ |
|
// | / \ | | / \ |
|
||||||
// | 6/ \7 |
|
// | 6/ \7 | | + + |
|
||||||
// | / \ |
|
// | / \ | | / \ |
|
||||||
// |/ \|
|
// |/ \| |/ \|
|
||||||
// N0 +---------+ N2
|
// N0 +---------+ N2 +---------+
|
||||||
// 8
|
// 8
|
||||||
*/
|
*/
|
||||||
static int QuadPenta_F [5][9] = { // FORWARD
|
static int QuadPenta_F [5][9] = { // FORWARD
|
||||||
@ -301,6 +301,20 @@ static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL
|
|||||||
{ 0, 12,3, 11,5, 14,2, 8, 0 }};
|
{ 0, 12,3, 11,5, 14,2, 8, 0 }};
|
||||||
static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
|
static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
|
||||||
|
|
||||||
|
static int BiQuadPenta_F[5][9] = { // FORWARD
|
||||||
|
{ 0, 6, 1, 7, 2, 8, 0, 0, 0 },
|
||||||
|
{ 3, 11,5, 10,4, 9, 3, 3, 3 },
|
||||||
|
{ 0, 12,3, 9, 4, 13,1, 6, 16}, //!
|
||||||
|
{ 1, 13,4, 10,5, 14,2, 7, 17}, //!
|
||||||
|
{ 0, 8, 2, 14,5, 11,3, 12,18} }; //!
|
||||||
|
static int BiQuadPenta_RE[5][9] = { // REVERSED -> EXTERNAL
|
||||||
|
{ 0, 8, 2, 7, 1, 6, 0, 0, 0 },
|
||||||
|
{ 3, 9, 4, 10,5, 11,3, 3, 3 },
|
||||||
|
{ 0, 6, 1, 13,4, 9, 3, 12,17}, //!
|
||||||
|
{ 1, 7, 2, 14,5, 10,4, 13,16}, //!
|
||||||
|
{ 0, 12,3, 11,5, 14,2, 8, 18} }; //!
|
||||||
|
static int BiQuadPenta_nbN[] = { 6, 6, 9, 9, 9 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 13
|
// 13
|
||||||
// N5+-----+-----+N6 +-----+-----+
|
// N5+-----+-----+N6 +-----+-----+
|
||||||
@ -634,6 +648,14 @@ void SMDS_VolumeTool::Inverse ()
|
|||||||
SWAP_NODES( myVolumeNodes, 9, 11 );
|
SWAP_NODES( myVolumeNodes, 9, 11 );
|
||||||
SWAP_NODES( myVolumeNodes, 13, 14 );
|
SWAP_NODES( myVolumeNodes, 13, 14 );
|
||||||
break;
|
break;
|
||||||
|
case 18:
|
||||||
|
SWAP_NODES(myVolumeNodes, 1, 2);
|
||||||
|
SWAP_NODES(myVolumeNodes, 4, 5);
|
||||||
|
SWAP_NODES(myVolumeNodes, 6, 8);
|
||||||
|
SWAP_NODES(myVolumeNodes, 9, 11);
|
||||||
|
SWAP_NODES(myVolumeNodes, 13, 14);
|
||||||
|
SWAP_NODES(myVolumeNodes, 16, 17);
|
||||||
|
break;
|
||||||
case 20:
|
case 20:
|
||||||
SWAP_NODES( myVolumeNodes, 1, 3 );
|
SWAP_NODES( myVolumeNodes, 1, 3 );
|
||||||
SWAP_NODES( myVolumeNodes, 5, 7 );
|
SWAP_NODES( myVolumeNodes, 5, 7 );
|
||||||
@ -677,6 +699,7 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const
|
|||||||
case 10: return QUAD_TETRA;
|
case 10: return QUAD_TETRA;
|
||||||
case 13: return QUAD_PYRAM;
|
case 13: return QUAD_PYRAM;
|
||||||
case 15: return QUAD_PENTA;
|
case 15: return QUAD_PENTA;
|
||||||
|
case 18: return QUAD_PENTA;
|
||||||
case 20: return QUAD_HEXA;
|
case 20: return QUAD_HEXA;
|
||||||
case 27: return QUAD_HEXA;
|
case 27: return QUAD_HEXA;
|
||||||
default: break;
|
default: break;
|
||||||
@ -862,6 +885,8 @@ double SMDS_VolumeTool::GetSize() const
|
|||||||
myVolumeNodes[ vtab[i][2] ],
|
myVolumeNodes[ vtab[i][2] ],
|
||||||
myVolumeNodes[ vtab[i][3] ]);
|
myVolumeNodes[ vtab[i][3] ]);
|
||||||
}
|
}
|
||||||
|
if (!myVolForward && V < 0)
|
||||||
|
V *= -1;
|
||||||
}
|
}
|
||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
@ -1705,6 +1730,16 @@ int SMDS_VolumeTool::GetCenterNodeIndex( int faceIndex ) const
|
|||||||
return faceIndex + 19;
|
return faceIndex + 19;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (myAllFacesNbNodes && myVolumeNodes.size() == 18) // element with 18 nodes
|
||||||
|
{
|
||||||
|
switch (faceIndex) {
|
||||||
|
case 2: return 15;
|
||||||
|
case 3: return 16;
|
||||||
|
case 4: return 17;
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1727,6 +1762,7 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
|
|||||||
switch ( myVolumeNodes.size() ) {
|
switch ( myVolumeNodes.size() ) {
|
||||||
case 6:
|
case 6:
|
||||||
case 15:
|
case 15:
|
||||||
|
case 18:
|
||||||
if ( faceIndex == 0 || faceIndex == 1 )
|
if ( faceIndex == 0 || faceIndex == 1 )
|
||||||
ind = 1 - faceIndex;
|
ind = 1 - faceIndex;
|
||||||
break;
|
break;
|
||||||
@ -2469,6 +2505,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
|
|||||||
myMaxFaceNbNodes = sizeof(QuadPyram_F[0])/sizeof(QuadPyram_F[0][0]);
|
myMaxFaceNbNodes = sizeof(QuadPyram_F[0])/sizeof(QuadPyram_F[0][0]);
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
|
case 18:
|
||||||
myAllFacesNodeIndices_F = &QuadPenta_F [0][0];
|
myAllFacesNodeIndices_F = &QuadPenta_F [0][0];
|
||||||
//myAllFacesNodeIndices_FE = &QuadPenta_FE[0][0];
|
//myAllFacesNodeIndices_FE = &QuadPenta_FE[0][0];
|
||||||
myAllFacesNodeIndices_RE = &QuadPenta_RE[0][0];
|
myAllFacesNodeIndices_RE = &QuadPenta_RE[0][0];
|
||||||
@ -2535,7 +2572,8 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes)
|
|||||||
case 8: return HEXA;
|
case 8: return HEXA;
|
||||||
case 10: return QUAD_TETRA;
|
case 10: return QUAD_TETRA;
|
||||||
case 13: return QUAD_PYRAM;
|
case 13: return QUAD_PYRAM;
|
||||||
case 15: return QUAD_PENTA;
|
case 15:
|
||||||
|
case 18: return QUAD_PENTA;
|
||||||
case 20:
|
case 20:
|
||||||
case 27: return QUAD_HEXA;
|
case 27: return QUAD_HEXA;
|
||||||
case 12: return HEX_PRISM;
|
case 12: return HEX_PRISM;
|
||||||
|
@ -9483,7 +9483,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
|
|||||||
case SMDSEntity_TriQuad_Hexa:
|
case SMDSEntity_TriQuad_Hexa:
|
||||||
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
|
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
|
||||||
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
|
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
|
||||||
for ( size_t i = 20; i < nodes.size(); ++i ) // rm central nodes
|
for (size_t i = 8; i < nodes.size(); ++i) // rm central nodes from each edge
|
||||||
|
//for (size_t i = 20; i < nodes.size(); ++i) // rm central nodes from each edge
|
||||||
if ( nodes[i]->NbInverseElements() == 0 )
|
if ( nodes[i]->NbInverseElements() == 0 )
|
||||||
GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
|
GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
|
||||||
break;
|
break;
|
||||||
@ -9496,7 +9497,9 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
|
|||||||
case SMDSEntity_BiQuad_Penta:
|
case SMDSEntity_BiQuad_Penta:
|
||||||
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
|
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
|
||||||
nodes[3], nodes[4], nodes[5], id, theForce3d);
|
nodes[3], nodes[4], nodes[5], id, theForce3d);
|
||||||
for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes
|
|
||||||
|
for (size_t i = 6; i < nodes.size(); ++i) // rm central nodes
|
||||||
|
//for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes
|
||||||
if ( nodes[i]->NbInverseElements() == 0 )
|
if ( nodes[i]->NbInverseElements() == 0 )
|
||||||
GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
|
GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
|
||||||
break;
|
break;
|
||||||
@ -13037,15 +13040,58 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
|
|||||||
if (iQuad)
|
if (iQuad)
|
||||||
for ( inode = 1; inode < nbFaceNodes; inode += 2)
|
for ( inode = 1; inode < nbFaceNodes; inode += 2)
|
||||||
nodes.push_back( nn[inode] ); // add medium nodes
|
nodes.push_back( nn[inode] ); // add medium nodes
|
||||||
int iCenter = vTool.GetCenterNodeIndex(iface); // for HEX27
|
|
||||||
if ( iCenter > 0 )
|
|
||||||
nodes.push_back( vTool.GetNodes()[ iCenter ] );
|
|
||||||
|
|
||||||
if (const SMDS_MeshElement * f = aMesh->FindElement( nodes,
|
// for triangle face for Penta18 (BiQuadratic pentahedron) return -2
|
||||||
SMDSAbs_Face, /*noMedium=*/false ))
|
// because we haven't center node on triangle side, but it's need for create biquadratic face
|
||||||
presentBndElems.push_back( f );
|
int iCenter = vTool.GetCenterNodeIndex(iface); // for HEX27
|
||||||
|
|
||||||
|
// for triangle faces for Penta18 (BiQuadratic pentahedron) firstly check, exist face or not
|
||||||
|
// if not - create node in middle face
|
||||||
|
if (iCenter == -2)
|
||||||
|
{
|
||||||
|
SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
|
||||||
|
bool isFound = false;
|
||||||
|
while (itF->more())
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* e = itF->next();
|
||||||
|
int nbNodesToCheck = e->NbNodes();
|
||||||
|
if (nbNodesToCheck == (int)nodes.size() + 1)
|
||||||
|
{
|
||||||
|
for (size_t i = 1; e && i < nodes.size() - 1; ++i)
|
||||||
|
{
|
||||||
|
int nodeIndex = e->GetNodeIndex(nodes[i]);
|
||||||
|
if (nodeIndex < 0 || nodeIndex >= nbNodesToCheck)
|
||||||
|
e = 0;
|
||||||
|
}
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
presentBndElems.push_back(e);
|
||||||
|
isFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFound)
|
||||||
|
{
|
||||||
|
SMESH_MesherHelper aHelper(*myMesh);
|
||||||
|
double bc[3];
|
||||||
|
vTool.GetFaceBaryCenter(iface, bc[0], bc[1], bc[2]);
|
||||||
|
auto aNodeC = aHelper.AddNode(bc[0], bc[1], bc[2]);
|
||||||
|
nodes.push_back(aNodeC);
|
||||||
|
missingBndElems.push_back(nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
missingBndElems.push_back( nodes );
|
{
|
||||||
|
if (iCenter > 0)
|
||||||
|
nodes.push_back(vTool.GetNodes()[iCenter]);
|
||||||
|
|
||||||
|
if (const SMDS_MeshElement* f = aMesh->FindElement(nodes,
|
||||||
|
SMDSAbs_Face, /*noMedium=*/false))
|
||||||
|
presentBndElems.push_back(f);
|
||||||
|
else
|
||||||
|
missingBndElems.push_back(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
if ( targetMesh != myMesh )
|
if ( targetMesh != myMesh )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user