mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-12 00:29:17 +05:00
BUG: EDF 2655: Hexa splitting into tetra low performance
A better fix has been found by improving the getNextFree() method in ObjectPool.hxx. When there is no "hole" in the ID list we don't iterate on the _freeList to find the next free ID. We jump straight to the last occupied ID. This fix is simpler and can benefit to other methods of SMESH_Editor like QuadTo4Tri for example.
This commit is contained in:
parent
3f3beb8b95
commit
094287b4df
@ -42,9 +42,16 @@ private:
|
|||||||
int _nextFree;
|
int _nextFree;
|
||||||
int _maxAvail;
|
int _maxAvail;
|
||||||
int _chunkSize;
|
int _chunkSize;
|
||||||
|
int _maxOccupied;
|
||||||
|
int _nbHoles;
|
||||||
|
|
||||||
int getNextFree()
|
int getNextFree()
|
||||||
{
|
{
|
||||||
|
// Don't iterate on the _freeList if all the "holes"
|
||||||
|
// are filled. Go straight to the last occupied ID + 1
|
||||||
|
if ( _nbHoles == 0 )
|
||||||
|
return std::min(_maxOccupied + 1, _maxAvail);
|
||||||
|
|
||||||
for (int i = _nextFree; i < _maxAvail; i++)
|
for (int i = _nextFree; i < _maxAvail; i++)
|
||||||
if (_freeList[i] == true)
|
if (_freeList[i] == true)
|
||||||
{
|
{
|
||||||
@ -73,6 +80,8 @@ public:
|
|||||||
_chunkSize = nblk;
|
_chunkSize = nblk;
|
||||||
_nextFree = 0;
|
_nextFree = 0;
|
||||||
_maxAvail = 0;
|
_maxAvail = 0;
|
||||||
|
_maxOccupied = 0;
|
||||||
|
_nbHoles = 0;
|
||||||
_chunkList.clear();
|
_chunkList.clear();
|
||||||
_freeList.clear();
|
_freeList.clear();
|
||||||
}
|
}
|
||||||
@ -103,6 +112,14 @@ public:
|
|||||||
_freeList[_nextFree] = false;
|
_freeList[_nextFree] = false;
|
||||||
obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
|
obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
|
||||||
}
|
}
|
||||||
|
if (_nextFree < _maxOccupied)
|
||||||
|
{
|
||||||
|
_nbHoles-=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_maxOccupied = _nextFree;
|
||||||
|
}
|
||||||
//obj->init();
|
//obj->init();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -124,6 +141,8 @@ public:
|
|||||||
_freeList[toFree] = true;
|
_freeList[toFree] = true;
|
||||||
if (toFree < _nextFree)
|
if (toFree < _nextFree)
|
||||||
_nextFree = toFree;
|
_nextFree = toFree;
|
||||||
|
if (toFree < _maxOccupied)
|
||||||
|
_nbHoles += 1;
|
||||||
//obj->clean();
|
//obj->clean();
|
||||||
//checkDelete(i); compactage non fait
|
//checkDelete(i); compactage non fait
|
||||||
break;
|
break;
|
||||||
@ -134,6 +153,8 @@ public:
|
|||||||
{
|
{
|
||||||
_nextFree = 0;
|
_nextFree = 0;
|
||||||
_maxAvail = 0;
|
_maxAvail = 0;
|
||||||
|
_maxOccupied = 0;
|
||||||
|
_nbHoles = 0;
|
||||||
for (size_t i = 0; i < _chunkList.size(); i++)
|
for (size_t i = 0; i < _chunkList.size(); i++)
|
||||||
delete[] _chunkList[i];
|
delete[] _chunkList[i];
|
||||||
clearVector( _chunkList );
|
clearVector( _chunkList );
|
||||||
|
@ -1899,20 +1899,6 @@ namespace
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class TElemToDelete
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TElemToDelete(const SMDS_MeshElement* theElem, SMESHDS_SubMesh* theSubMesh)
|
|
||||||
{
|
|
||||||
elem = theElem;
|
|
||||||
subMesh = theSubMesh;
|
|
||||||
}
|
|
||||||
const SMDS_MeshElement* Elem() const {return elem;}
|
|
||||||
SMESHDS_SubMesh* Submesh() {return subMesh;}
|
|
||||||
const SMDS_MeshElement* elem;
|
|
||||||
SMESHDS_SubMesh* subMesh;
|
|
||||||
};
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SplitVolumesIntoTetra
|
//function : SplitVolumesIntoTetra
|
||||||
//purpose : Split volume elements into tetrahedra.
|
//purpose : Split volume elements into tetrahedra.
|
||||||
@ -1938,7 +1924,6 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
double bc[3];
|
double bc[3];
|
||||||
|
|
||||||
TIDSortedElemSet::const_iterator elem = theElems.begin();
|
TIDSortedElemSet::const_iterator elem = theElems.begin();
|
||||||
std::vector<TElemToDelete> elem_to_delete;
|
|
||||||
for ( ; elem != theElems.end(); ++elem )
|
for ( ; elem != theElems.end(); ++elem )
|
||||||
{
|
{
|
||||||
if ( (*elem)->GetType() != SMDSAbs_Volume )
|
if ( (*elem)->GetType() != SMDSAbs_Volume )
|
||||||
@ -2102,26 +2087,11 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
}
|
}
|
||||||
ReplaceElemInGroups( face, triangles, GetMeshDS() );
|
ReplaceElemInGroups( face, triangles, GetMeshDS() );
|
||||||
GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false );
|
GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false );
|
||||||
// TElemToDelete faceToDelete(face, fSubMesh);
|
|
||||||
// elem_to_delete.push_back(faceToDelete);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // loop on volume faces to split them into triangles
|
} // loop on volume faces to split them into triangles
|
||||||
|
|
||||||
// GetMeshDS()->RemoveFreeElement( *elem, subMesh, /*fromGroups=*/false );
|
GetMeshDS()->RemoveFreeElement( *elem, subMesh, /*fromGroups=*/false );
|
||||||
|
|
||||||
// rnc : don't delete the elem here because it results in a mesh with a free
|
|
||||||
// ID at the beginning of the ID list. The first tetra is then inserted in O(1)
|
|
||||||
// but the second one is inserted in O(n), then the whole procedure has almost a O(n^2)
|
|
||||||
// complexity. If all elements to remove are stored and removed after tetra creation
|
|
||||||
// we get a O(n) complexity for the whole procedure.
|
|
||||||
// The memory cost is at worst a 6*n*constant memory occupation (where n is the number of elements)
|
|
||||||
// before deletion of the hexas and then 5*n*constant instead of a maximum of 5*n*constant.
|
|
||||||
// So there is a transient 1/5*(memory occupation) additional cost.
|
|
||||||
|
|
||||||
// Store the elements to delete
|
|
||||||
TElemToDelete elemToDelete(*elem, subMesh);
|
|
||||||
elem_to_delete.push_back(elemToDelete);
|
|
||||||
|
|
||||||
if ( geomType == SMDSEntity_TriQuad_Hexa )
|
if ( geomType == SMDSEntity_TriQuad_Hexa )
|
||||||
{
|
{
|
||||||
@ -2132,13 +2102,6 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
|
|||||||
}
|
}
|
||||||
} // loop on volumes to split
|
} // loop on volumes to split
|
||||||
|
|
||||||
// Delete stored elements
|
|
||||||
std::vector<TElemToDelete>::iterator it;
|
|
||||||
for( it = elem_to_delete.begin(); it!= elem_to_delete.end(); it++)
|
|
||||||
{
|
|
||||||
GetMeshDS()->RemoveFreeElement( it->Elem(), it->Submesh(), /*fromGroups=*/false );
|
|
||||||
}
|
|
||||||
|
|
||||||
myLastCreatedNodes = newNodes;
|
myLastCreatedNodes = newNodes;
|
||||||
myLastCreatedElems = newElems;
|
myLastCreatedElems = newElems;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user