mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
GeoMech Intersection updates: support multiple parts (#8160)
* Rearrange intersection classes, split single file into one-per-class * Support multi-part geomech case intersections
This commit is contained in:
@@ -92,6 +92,14 @@ int RigFemPart::elementCount() const
|
||||
return static_cast<int>( m_elementId.size() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigFemPart::allConnectivitiesCount() const
|
||||
{
|
||||
return static_cast<int>( m_allElementConnectivities.size() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
void appendElement( RigElementType elmType, int elementId, const int* connectivities );
|
||||
|
||||
int elementCount() const;
|
||||
int allConnectivitiesCount() const;
|
||||
|
||||
int elmId( size_t elementIdx ) const;
|
||||
RigElementType elementType( size_t elementIdx ) const;
|
||||
|
||||
@@ -39,7 +39,24 @@ RigFemPartCollection::~RigFemPartCollection()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFemPartCollection::addFemPart( RigFemPart* part )
|
||||
{
|
||||
size_t globalElementOffset = 0;
|
||||
size_t globalNodeOffset = 0;
|
||||
size_t globalConnectivityOffset = 0;
|
||||
if ( m_femParts.size() > 0 )
|
||||
{
|
||||
size_t lastIndex = m_femParts.size() - 1;
|
||||
globalElementOffset += m_femParts[lastIndex]->elementCount();
|
||||
globalElementOffset += m_partElementOffset[lastIndex];
|
||||
globalNodeOffset += m_femParts[lastIndex]->nodes().nodeIds.size();
|
||||
globalNodeOffset += m_partNodeOffset[lastIndex];
|
||||
globalConnectivityOffset += m_femParts[lastIndex]->allConnectivitiesCount();
|
||||
globalConnectivityOffset += m_partConnectivityOffset[lastIndex];
|
||||
}
|
||||
|
||||
m_femParts.push_back( part );
|
||||
m_partElementOffset.push_back( globalElementOffset );
|
||||
m_partNodeOffset.push_back( globalNodeOffset );
|
||||
m_partConnectivityOffset.push_back( globalConnectivityOffset );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -108,3 +125,74 @@ cvf::BoundingBox RigFemPartCollection::boundingBox() const
|
||||
}
|
||||
return bBox;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// convert from global element index to part and part-local index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<int, size_t> RigFemPartCollection::partIdAndElementIndex( size_t globalIndex ) const
|
||||
{
|
||||
const size_t nParts = m_partElementOffset.size();
|
||||
|
||||
CVF_ASSERT( nParts > 0 );
|
||||
|
||||
for ( size_t i = 1; i < nParts; i++ )
|
||||
{
|
||||
if ( globalIndex < m_partElementOffset[i] )
|
||||
{
|
||||
return std::make_pair( (int)( i - 1 ), globalIndex - m_partElementOffset[i - 1] );
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair( (int)( nParts - 1 ), globalIndex - m_partElementOffset.back() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// convert from global element index to part and part-local index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<const RigFemPart*, size_t> RigFemPartCollection::partAndElementIndex( size_t globalIndex ) const
|
||||
{
|
||||
auto [partId, elementIdx] = partIdAndElementIndex( globalIndex );
|
||||
return std::make_pair( part( partId ), elementIdx );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// convert from part and part-local index to global index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigFemPartCollection::globalIndex( int partId, size_t localIndex ) const
|
||||
{
|
||||
return localIndex + m_partElementOffset[partId];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigFemPartCollection::nodeIdxFromElementNodeResultIdx( size_t globalIndex ) const
|
||||
{
|
||||
const size_t nParts = m_partConnectivityOffset.size();
|
||||
CVF_ASSERT( nParts > 0 );
|
||||
|
||||
int partId = (int)( nParts - 1 );
|
||||
size_t partIdx = globalIndex - m_partConnectivityOffset.back();
|
||||
|
||||
for ( size_t i = 1; i < nParts; i++ )
|
||||
{
|
||||
if ( globalIndex < m_partConnectivityOffset[i] )
|
||||
{
|
||||
partId = (int)( i - 1 );
|
||||
partIdx = globalIndex - m_partConnectivityOffset[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const RigFemPart* part = this->part( partId );
|
||||
|
||||
return (int)m_partNodeOffset[partId] + part->nodeIdxFromElementNodeResultIdx( partIdx );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigFemPartCollection::globalElementNodeResultIdx( int partId, int elementIdx, int elmLocalNodeIdx ) const
|
||||
{
|
||||
return m_partElementOffset[partId] * 8 + part( partId )->elementNodeResultIdx( elementIdx, elmLocalNodeIdx );
|
||||
}
|
||||
|
||||
@@ -38,6 +38,19 @@ public:
|
||||
float characteristicElementSize() const;
|
||||
cvf::BoundingBox boundingBox() const;
|
||||
|
||||
std::pair<int, size_t> partIdAndElementIndex( size_t globalIndex ) const;
|
||||
std::pair<const RigFemPart*, size_t> partAndElementIndex( size_t globalIndex ) const;
|
||||
size_t globalIndex( int partId, size_t localIndex ) const;
|
||||
|
||||
std::pair<int, size_t> partIdAndNodeIndex( size_t globalNodeIndex ) const;
|
||||
|
||||
int nodeIdxFromElementNodeResultIdx( size_t globalResultIdx ) const;
|
||||
|
||||
size_t globalElementNodeResultIdx( int part, int elementIdx, int elmLocalNodeIdx ) const;
|
||||
|
||||
private:
|
||||
cvf::Collection<RigFemPart> m_femParts;
|
||||
std::vector<size_t> m_partElementOffset;
|
||||
std::vector<size_t> m_partNodeOffset;
|
||||
std::vector<size_t> m_partConnectivityOffset;
|
||||
};
|
||||
|
||||
@@ -146,6 +146,8 @@ RigFemScalarResultFrames*
|
||||
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
|
||||
{
|
||||
const std::vector<float>& s11 = s11Frames->frameData( fIdx );
|
||||
if ( s11.empty() ) continue;
|
||||
|
||||
const std::vector<float>& s22 = s22Frames->frameData( fIdx );
|
||||
const std::vector<float>& s33 = s33Frames->frameData( fIdx );
|
||||
const std::vector<float>& s12 = s12Frames->frameData( fIdx );
|
||||
|
||||
@@ -1043,6 +1043,54 @@ const std::vector<float>&
|
||||
return scalarResults->frameData( frameIndex );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigFemPartResultsCollection::globalResultValues( const RigFemResultAddress& resVarAddr,
|
||||
int timeStepIndex,
|
||||
std::vector<float>& resultValues )
|
||||
{
|
||||
CVF_ASSERT( resVarAddr.isValid() );
|
||||
|
||||
for ( int i = 0; i < partCount(); i++ )
|
||||
{
|
||||
const std::vector<float>& partResults = this->resultValues( resVarAddr, i, (int)timeStepIndex );
|
||||
if ( partResults.empty() )
|
||||
{
|
||||
size_t expectedSize = 0;
|
||||
|
||||
switch ( resVarAddr.resultPosType )
|
||||
{
|
||||
case RIG_NODAL:
|
||||
expectedSize = m_femParts->part( i )->nodes().nodeIds.size();
|
||||
break;
|
||||
|
||||
case RIG_ELEMENT_NODAL:
|
||||
case RIG_INTEGRATION_POINT:
|
||||
expectedSize = m_femParts->part( i )->elementNodeResultCount();
|
||||
break;
|
||||
|
||||
case RIG_ELEMENT_NODAL_FACE:
|
||||
expectedSize = m_femParts->part( i )->elementCount() * 6;
|
||||
break;
|
||||
|
||||
case RIG_ELEMENT:
|
||||
expectedSize = m_femParts->part( i )->elementCount();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
resultValues.resize( resultValues.size() + expectedSize, NAN );
|
||||
}
|
||||
else
|
||||
{
|
||||
resultValues.insert( resultValues.end(), partResults.begin(), partResults.end() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -125,7 +125,9 @@ public:
|
||||
std::vector<RigFemResultAddress> loadedResults() const;
|
||||
|
||||
const std::vector<float>& resultValues( const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex );
|
||||
std::vector<caf::Ten3f> tensors( const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex );
|
||||
void globalResultValues( const RigFemResultAddress& resVarAddr, int timeStepIndex, std::vector<float>& resultValues );
|
||||
|
||||
std::vector<caf::Ten3f> tensors( const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex );
|
||||
|
||||
const RigFemPartCollection* parts() const;
|
||||
int partCount() const;
|
||||
|
||||
Reference in New Issue
Block a user