0021468: EDF 2073 SMESH: Body-fitting algo creates elements in hole

This commit is contained in:
eap 2012-01-17 13:17:19 +00:00
parent 2633709b28
commit 5c991bb2b7

View File

@ -173,9 +173,9 @@ namespace
_name1 = nv1; _name2 = nv2; _nameConst = nConst; _name1 = nv1; _name2 = nv2; _nameConst = nConst;
} }
size_t I() { return _curInd[0]; } size_t I() const { return _curInd[0]; }
size_t J() { return _curInd[1]; } size_t J() const { return _curInd[1]; }
size_t K() { return _curInd[2]; } size_t K() const { return _curInd[2]; }
void SetIJK( size_t i, size_t j, size_t k ) void SetIJK( size_t i, size_t j, size_t k )
{ {
_curInd[0] = i; _curInd[1] = j; _curInd[2] = k; _curInd[0] = i; _curInd[1] = j; _curInd[2] = k;
@ -204,6 +204,7 @@ namespace
double _tol, _minCellSize; double _tol, _minCellSize;
vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
vector< bool > _isBndNode; // is mesh node at intersection with geometry
size_t NodeIndex( size_t i, size_t j, size_t k ) const size_t NodeIndex( size_t i, size_t j, size_t k ) const
{ {
@ -321,6 +322,7 @@ namespace
vector< _Node> _intNodes; // _Node's at GridLine intersections vector< _Node> _intNodes; // _Node's at GridLine intersections
vector< _Link > _splits; vector< _Link > _splits;
vector< _Face*> _faces; vector< _Face*> _faces;
const GridLine* _line;
}; };
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
struct _OrientedLink struct _OrientedLink
@ -336,11 +338,6 @@ namespace
} }
_Node* FirstNode() const { return _link->_nodes[ _reverse ]; } _Node* FirstNode() const { return _link->_nodes[ _reverse ]; }
_Node* LastNode() const { return _link->_nodes[ !_reverse ]; } _Node* LastNode() const { return _link->_nodes[ !_reverse ]; }
// int NbNodes() const { return 2 + _link->_intNodes.size(); }
// _Node* GetNode(const int i)
// {
// return ( 0 < i && i < NbNodes()-1 ) ? _link->_intNodes[i-1] : ( _link->_nodes[bool(i)]);
// }
}; };
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
struct _Face struct _Face
@ -361,13 +358,14 @@ namespace
double _sizeThreshold, _sideLength[3]; double _sizeThreshold, _sideLength[3];
int _nbCornerNodes, _nbIntNodes; int _nbCornerNodes, _nbIntNodes, _nbBndNodes;
public: public:
Hexahedron(const double sizeThreshold, Grid* grid); Hexahedron(const double sizeThreshold, Grid* grid);
void Init( size_t i, size_t j, size_t k ); void Init( size_t i, size_t j, size_t k );
int MakeElements(SMESH_MesherHelper& helper); int MakeElements(SMESH_MesherHelper& helper);
private: private:
bool isInHole() const;
bool checkPolyhedronSize() const; bool checkPolyhedronSize() const;
bool addHexa (SMESH_MesherHelper& helper); bool addHexa (SMESH_MesherHelper& helper);
bool addTetra(SMESH_MesherHelper& helper); bool addTetra(SMESH_MesherHelper& helper);
@ -528,8 +526,10 @@ namespace
void Grid::ComputeNodes(SMESH_MesherHelper& helper) void Grid::ComputeNodes(SMESH_MesherHelper& helper)
{ {
// state of each node of the grid relative to the geomerty // state of each node of the grid relative to the geomerty
vector< bool > isNodeOut( _coords[0].size() * _coords[1].size() * _coords[2].size(), false ); const size_t nbGridNodes = _coords[0].size() * _coords[1].size() * _coords[2].size();
_nodes.resize( isNodeOut.size(), 0 ); vector< bool > isNodeOut( nbGridNodes, false );
_nodes.resize( nbGridNodes, 0 );
_isBndNode.resize( nbGridNodes, false );
for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
{ {
@ -590,7 +590,9 @@ namespace
li.SetIndexOnLine( nodeCoord-coord0 ); li.SetIndexOnLine( nodeCoord-coord0 );
double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]}; double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]};
_nodes[ nodeIndex ] = helper.AddNode( xyz[0], xyz[1], xyz[2] ); _nodes[ nodeIndex ] = helper.AddNode( xyz[0], xyz[1], xyz[2] );
_isBndNode[ nodeIndex ] = true;
} }
ip->_node = _nodes[ nodeIndex ];
if ( ++nodeCoord < coordEnd ) if ( ++nodeCoord < coordEnd )
nodeParam = *nodeCoord - *coord0; nodeParam = *nodeCoord - *coord0;
} }
@ -1059,12 +1061,14 @@ namespace
void Hexahedron::Init( size_t i, size_t j, size_t k ) void Hexahedron::Init( size_t i, size_t j, size_t k )
{ {
// set nodes of grid to nodes of the hexahedron and // set nodes of grid to nodes of the hexahedron and
// count nodes at hexahedron corners located IN geometry // count nodes at hexahedron corners located IN and ON geometry
_nbCornerNodes = _nbIntNodes = 0; _nbCornerNodes = _nbIntNodes = _nbBndNodes = 0;
size_t i000 = _grid->NodeIndex( i,j,k ); size_t i000 = _grid->NodeIndex( i,j,k );
for ( int iN = 0; iN < 8; ++iN ) for ( int iN = 0; iN < 8; ++iN )
{
_nbCornerNodes += bool(( _hexNodes[iN]._node = _grid->_nodes[ i000 + _nodeShift[iN] ])); _nbCornerNodes += bool(( _hexNodes[iN]._node = _grid->_nodes[ i000 + _nodeShift[iN] ]));
_nbBndNodes += _grid->_isBndNode[ i000 + _nodeShift[iN] ];
}
// set intersection nodes from GridLine's to hexahedron links // set intersection nodes from GridLine's to hexahedron links
int linkID = 0; int linkID = 0;
_Link split; _Link split;
@ -1087,6 +1091,7 @@ namespace
{ {
GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]]; GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]];
_Link& link = _hexLinks[ linkID++ ]; _Link& link = _hexLinks[ linkID++ ];
link._line = &line;
link._intNodes.clear(); link._intNodes.clear();
link._splits.clear(); link._splits.clear();
split._nodes[ 0 ] = link._nodes[0]; split._nodes[ 0 ] = link._nodes[0];
@ -1123,7 +1128,7 @@ namespace
int Hexahedron::MakeElements(SMESH_MesherHelper& helper) int Hexahedron::MakeElements(SMESH_MesherHelper& helper)
{ {
int nbAddedVols = 0; int nbAddedVols = 0;
if ( _nbCornerNodes == 8 && _nbIntNodes == 0 ) if ( _nbCornerNodes == 8 && _nbIntNodes == 0 && _nbBndNodes < _nbCornerNodes )
{ {
// order of _hexNodes is defined by enum SMESH_Block::TShapeID // order of _hexNodes is defined by enum SMESH_Block::TShapeID
helper.AddVolume( _hexNodes[0].Node(), _hexNodes[2].Node(), helper.AddVolume( _hexNodes[0].Node(), _hexNodes[2].Node(),
@ -1135,6 +1140,9 @@ namespace
if ( _nbCornerNodes + _nbIntNodes < 4 ) if ( _nbCornerNodes + _nbIntNodes < 4 )
return nbAddedVols; return nbAddedVols;
if ( _nbBndNodes == _nbCornerNodes && isInHole() )
return nbAddedVols;
_polygons.clear(); _polygons.clear();
vector<const SMDS_MeshNode* > polyhedraNodes; vector<const SMDS_MeshNode* > polyhedraNodes;
@ -1148,7 +1156,7 @@ namespace
_Link polyLink; _Link polyLink;
polyLink._faces.reserve( 1 ); polyLink._faces.reserve( 1 );
for ( int iF = 0; iF < 6; ++iF ) for ( int iF = 0; iF < 6; ++iF ) // loop on 6 sides on a hexahedron
{ {
const _Face& quad = _hexQuads[ iF ] ; const _Face& quad = _hexQuads[ iF ] ;
@ -1160,7 +1168,7 @@ namespace
// add splits of a link to a polygon and collect info on nodes // add splits of a link to a polygon and collect info on nodes
//int nbIn = 0, nbOut = 0, nbCorners = 0; //int nbIn = 0, nbOut = 0, nbCorners = 0;
nodes.clear(); nodes.clear();
for ( int iE = 0; iE < 4; ++iE ) for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle
{ {
int nbSpits = quad._links[ iE ].NbResultLinks(); int nbSpits = quad._links[ iE ].NbResultLinks();
for ( int iS = 0; iS < nbSpits; ++iS ) for ( int iS = 0; iS < nbSpits; ++iS )
@ -1306,6 +1314,48 @@ namespace
return nbAddedVols; return nbAddedVols;
} }
//================================================================================
/*!
* \brief Return true if the element is in a hole
*/
bool Hexahedron::isInHole() const
{
const int ijk[3] = { _lineInd[0].I(), _lineInd[0].J(), _lineInd[0].K() };
IntersectionPoint curIntPnt;
for ( int iDir = 0; iDir < 3; ++iDir )
{
const vector<double>& coords = _grid->_coords[ iDir ];
bool allLinksOut = true;
int linkID = iDir * 4;
for ( int i = 0; i < 4 && allLinksOut; ++i )
{
const _Link& link = _hexLinks[ linkID++ ];
if ( link._splits.empty() ) continue;
// check transition of the first node of a link
const IntersectionPoint* firstIntPnt = 0;
if ( link._nodes[0]->Node() ) // 1st node is a hexa corner
{
curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0];
multiset< IntersectionPoint >::const_iterator ip =
link._line->_intPoints.upper_bound( curIntPnt );
--ip;
firstIntPnt = &(*ip);
}
else if ( !link._intNodes.empty() )
{
firstIntPnt = link._intNodes[0]._intPoint;
}
if ( firstIntPnt && firstIntPnt->_transition == Trans_IN )
allLinksOut = false;
}
if ( allLinksOut )
return true;
}
return false;
}
//================================================================================ //================================================================================
/*! /*!
* \brief Return true if a polyhedron passes _sizeThreshold criterion * \brief Return true if a polyhedron passes _sizeThreshold criterion