Reduce NNC memory use

This commit is contained in:
Gaute Lindkvist 2020-05-14 15:07:17 +02:00 committed by Magne Sjaastad
parent 34dcd3c737
commit 97dd891d38
9 changed files with 111 additions and 52 deletions

View File

@ -74,7 +74,7 @@ void RivNNCGeometryGenerator::computeArrays()
std::vector<cvf::Vec3f> vertices; std::vector<cvf::Vec3f> vertices;
std::vector<size_t> triangleToNNC; std::vector<size_t> triangleToNNC;
const cvf::Vec3d offset = m_offset; const cvf::Vec3f offset( m_offset );
long long numConnections = long long numConnections =
static_cast<long long>( m_nncIndexes.isNull() ? m_nncData->connections().size() : m_nncIndexes->size() ); static_cast<long long>( m_nncIndexes.isNull() ? m_nncData->connections().size() : m_nncIndexes->size() );
@ -122,14 +122,14 @@ void RivNNCGeometryGenerator::computeArrays()
if ( isVisible ) if ( isVisible )
{ {
cvf::Vec3f vx1 = cvf::Vec3f( conn.m_polygon[0] - offset ); cvf::Vec3f vx1 = conn.m_polygon[0] - offset;
cvf::Vec3f vx2; cvf::Vec3f vx2;
cvf::Vec3f vx3 = cvf::Vec3f( conn.m_polygon[1] - offset ); cvf::Vec3f vx3 = conn.m_polygon[1] - offset;
for ( size_t vxIdx = 2; vxIdx < conn.m_polygon.size(); ++vxIdx ) for ( size_t vxIdx = 2; vxIdx < conn.m_polygon.size(); ++vxIdx )
{ {
vx2 = vx3; vx2 = vx3;
vx3 = cvf::Vec3f( conn.m_polygon[vxIdx] - offset ); vx3 = conn.m_polygon[vxIdx] - offset;
#pragma omp critical( critical_section_RivNNCGeometryGenerator_computeArrays ) #pragma omp critical( critical_section_RivNNCGeometryGenerator_computeArrays )
{ {
vertices.push_back( vx1 ); vertices.push_back( vx1 );

View File

@ -2366,11 +2366,11 @@ void RigCaseCellResultsData::computeNncCombRiTrans()
// Connection geometry // Connection geometry
cvf::Vec3d faceAreaVec = cvf::Vec3d::ZERO; cvf::Vec3f faceAreaVec = cvf::Vec3f::ZERO;
cvf::Vec3d faceCenter = cvf::Vec3d::ZERO; cvf::Vec3f faceCenter = cvf::Vec3f::ZERO;
// Polygon center // Polygon center
const std::vector<cvf::Vec3d>& realPolygon = nncConnections[connIdx].m_polygon; const std::vector<cvf::Vec3f>& realPolygon = nncConnections[connIdx].m_polygon;
for ( size_t pIdx = 0; pIdx < realPolygon.size(); ++pIdx ) for ( size_t pIdx = 0; pIdx < realPolygon.size(); ++pIdx )
{ {
faceCenter += realPolygon[pIdx]; faceCenter += realPolygon[pIdx];
@ -2400,7 +2400,7 @@ void RigCaseCellResultsData::computeNncCombRiTrans()
ntg = ( *ntgResults )[ntgResIdx]; ntg = ( *ntgResults )[ntgResIdx];
} }
halfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, faceAreaVec ); halfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, cvf::Vec3d( faceAreaVec ) );
} }
// Neighbor cell half cell transm // Neighbor cell half cell transm
@ -2417,7 +2417,7 @@ void RigCaseCellResultsData::computeNncCombRiTrans()
ntg = ( *ntgResults )[ntgResIdx]; ntg = ( *ntgResults )[ntgResIdx];
} }
neighborHalfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, -faceAreaVec ); neighborHalfCellTrans = halfCellTransmissibility( perm, ntg, centerToFace, -cvf::Vec3d( faceAreaVec ) );
} }
double newtranTemp = newtran( cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans ); double newtranTemp = newtran( cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans );
@ -2686,8 +2686,8 @@ void RigCaseCellResultsData::computeNncCombRiTRANSbyArea()
for ( size_t nncConIdx = 0; nncConIdx < riAreaNormTransResults.size(); ++nncConIdx ) for ( size_t nncConIdx = 0; nncConIdx < riAreaNormTransResults.size(); ++nncConIdx )
{ {
const std::vector<cvf::Vec3d>& realPolygon = connections[nncConIdx].m_polygon; const std::vector<cvf::Vec3f>& realPolygon = connections[nncConIdx].m_polygon;
cvf::Vec3d faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D( realPolygon ); cvf::Vec3f faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D( realPolygon );
double areaOfOverlap = faceAreaVec.length(); double areaOfOverlap = faceAreaVec.length();
riAreaNormTransResults[nncConIdx] = ( *transResults )[nncConIdx] / areaOfOverlap; riAreaNormTransResults[nncConIdx] = ( *transResults )[nncConIdx] / areaOfOverlap;

View File

@ -119,9 +119,9 @@ cvf::StructGridInterface::FaceType
return cvf::StructGridInterface::NO_FACE; return cvf::StructGridInterface::NO_FACE;
} }
void assignThreadConnections( std::set<std::pair<size_t, size_t>>& existingPairs, void assignThreadConnections( std::set<std::pair<unsigned, unsigned>>& existingPairs,
RigConnectionContainer& allConnections, RigConnectionContainer& allConnections,
RigConnectionContainer& threadConnections ) RigConnectionContainer& threadConnections )
{ {
for ( size_t i = 0; i < threadConnections.size(); ++i ) for ( size_t i = 0; i < threadConnections.size(); ++i )
{ {
@ -150,7 +150,7 @@ RigConnectionContainer RigCellFaceGeometryTools::computeOtherNncs( const RigMain
// by Eclipse. Use faults as basis for subset of cells to find NNC connection for. The imported connections from // by Eclipse. Use faults as basis for subset of cells to find NNC connection for. The imported connections from
// Eclipse are located at the beginning of the connections vector. // Eclipse are located at the beginning of the connections vector.
std::set<std::pair<size_t, size_t>> nativeCellPairs; std::set<std::pair<unsigned, unsigned>> nativeCellPairs;
for ( size_t i = 0; i < nativeConnections.size(); ++i ) for ( size_t i = 0; i < nativeConnections.size(); ++i )
{ {
@ -168,8 +168,8 @@ RigConnectionContainer RigCellFaceGeometryTools::computeOtherNncs( const RigMain
const cvf::Collection<RigFault>& faults = mainGrid->faults(); const cvf::Collection<RigFault>& faults = mainGrid->faults();
std::set<std::pair<size_t, size_t>> existingPairs; std::set<std::pair<unsigned, unsigned>> existingPairs;
RigConnectionContainer otherConnections; RigConnectionContainer otherConnections;
for ( int faultIdx = 0; faultIdx < (int)faults.size(); faultIdx++ ) for ( int faultIdx = 0; faultIdx < (int)faults.size(); faultIdx++ )
{ {
@ -216,9 +216,9 @@ RigConnectionContainer RigCellFaceGeometryTools::computeOtherNncs( const RigMain
} }
RigConnectionContainer RigConnectionContainer
RigCellFaceGeometryTools::extractConnectionsForFace( const RigFault::FaultFace& face, RigCellFaceGeometryTools::extractConnectionsForFace( const RigFault::FaultFace& face,
const RigMainGrid* mainGrid, const RigMainGrid* mainGrid,
const std::set<std::pair<size_t, size_t>>& nativeCellPairs ) const std::set<std::pair<unsigned, unsigned>>& nativeCellPairs )
{ {
RigConnectionContainer faceConnections; RigConnectionContainer faceConnections;
size_t sourceReservoirCellIndex = face.m_nativeReservoirCellIndex; size_t sourceReservoirCellIndex = face.m_nativeReservoirCellIndex;
@ -317,7 +317,7 @@ RigConnectionContainer
} }
} }
std::pair<size_t, size_t> candidate( sourceReservoirCellIndex, candidateCellIndex ); std::pair<unsigned, unsigned> candidate( sourceReservoirCellIndex, candidateCellIndex );
if ( nativeCellPairs.count( candidate ) > 0 ) if ( nativeCellPairs.count( candidate ) > 0 )
{ {
@ -357,18 +357,18 @@ RigConnectionContainer
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RigCellFaceGeometryTools::extractPolygon( const std::vector<cvf::Vec3d>& nativeNodes, std::vector<cvf::Vec3f> RigCellFaceGeometryTools::extractPolygon( const std::vector<cvf::Vec3d>& nativeNodes,
const std::vector<size_t>& connectionPolygon, const std::vector<size_t>& connectionPolygon,
const std::vector<cvf::Vec3d>& connectionIntersections ) const std::vector<cvf::Vec3d>& connectionIntersections )
{ {
std::vector<cvf::Vec3d> allPolygonNodes; std::vector<cvf::Vec3f> allPolygonNodes;
for ( size_t polygonIndex : connectionPolygon ) for ( size_t polygonIndex : connectionPolygon )
{ {
if ( polygonIndex < nativeNodes.size() ) if ( polygonIndex < nativeNodes.size() )
allPolygonNodes.push_back( nativeNodes[polygonIndex] ); allPolygonNodes.push_back( cvf::Vec3f( nativeNodes[polygonIndex] ) );
else else
allPolygonNodes.push_back( connectionIntersections[polygonIndex - nativeNodes.size()] ); allPolygonNodes.push_back( cvf::Vec3f( connectionIntersections[polygonIndex - nativeNodes.size()] ) );
} }
return allPolygonNodes; return allPolygonNodes;

View File

@ -51,10 +51,11 @@ public:
const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* activeCellInfo,
bool includeInactiveCells ); bool includeInactiveCells );
static RigConnectionContainer extractConnectionsForFace( const RigFault::FaultFace& face, static RigConnectionContainer
const RigMainGrid* mainGrid, extractConnectionsForFace( const RigFault::FaultFace& face,
const std::set<std::pair<size_t, size_t>>& nativeCellPairs ); const RigMainGrid* mainGrid,
static std::vector<cvf::Vec3d> extractPolygon( const std::vector<cvf::Vec3d>& nativeNodes, const std::set<std::pair<unsigned, unsigned>>& nativeCellPairs );
static std::vector<cvf::Vec3f> extractPolygon( const std::vector<cvf::Vec3d>& nativeNodes,
const std::vector<size_t>& connectionPolygon, const std::vector<size_t>& connectionPolygon,
const std::vector<cvf::Vec3d>& connectionIntersections ); const std::vector<cvf::Vec3d>& connectionIntersections );
}; };

View File

@ -24,8 +24,8 @@
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigConnection::RigConnection() RigConnection::RigConnection()
: m_c1GlobIdx( cvf::UNDEFINED_SIZE_T ) : m_c1GlobIdx( cvf::UNDEFINED_UINT )
, m_c2GlobIdx( cvf::UNDEFINED_SIZE_T ) , m_c2GlobIdx( cvf::UNDEFINED_UINT )
, m_c1Face( cvf::StructGridInterface::NO_FACE ) , m_c1Face( cvf::StructGridInterface::NO_FACE )
{ {
} }
@ -33,10 +33,10 @@ RigConnection::RigConnection()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigConnection::RigConnection( size_t c1GlobIdx, RigConnection::RigConnection( unsigned c1GlobIdx,
size_t c2GlobIdx, unsigned c2GlobIdx,
cvf::StructGridInterface::FaceType c1Face, cvf::StructGridInterface::FaceType c1Face,
const std::vector<cvf::Vec3d>& polygon ) const std::vector<cvf::Vec3f>& polygon )
: m_c1GlobIdx( c1GlobIdx ) : m_c1GlobIdx( c1GlobIdx )
, m_c2GlobIdx( c2GlobIdx ) , m_c2GlobIdx( c2GlobIdx )
, m_c1Face( c1Face ) , m_c1Face( c1Face )
@ -94,13 +94,16 @@ bool RigConnection::operator<( const RigConnection& other ) const
RigConnection RigConnectionContainer::operator[]( size_t i ) const RigConnection RigConnectionContainer::operator[]( size_t i ) const
{ {
const auto& globIndices = m_globalIndices[i]; const auto& globIndices = m_globalIndices[i];
return RigConnection( globIndices.first, globIndices.second, m_faces[i], m_polygons[i] ); return RigConnection( globIndices.first,
globIndices.second,
static_cast<cvf::StructGridInterface::FaceType>( m_faces[i] ),
m_polygons[i] );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::pair<size_t, size_t>& RigConnectionContainer::indexPair( size_t i ) std::pair<unsigned, unsigned>& RigConnectionContainer::indexPair( size_t i )
{ {
return m_globalIndices[i]; return m_globalIndices[i];
} }
@ -108,7 +111,7 @@ std::pair<size_t, size_t>& RigConnectionContainer::indexPair( size_t i )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
cvf::StructGridInterface::FaceType& RigConnectionContainer::face( size_t i ) unsigned char& RigConnectionContainer::face( size_t i )
{ {
return m_faces[i]; return m_faces[i];
} }
@ -116,7 +119,7 @@ cvf::StructGridInterface::FaceType& RigConnectionContainer::face( size_t i )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d>& RigConnectionContainer::polygon( size_t i ) std::vector<cvf::Vec3f>& RigConnectionContainer::polygon( size_t i )
{ {
return m_polygons[i]; return m_polygons[i];
} }

View File

@ -31,20 +31,21 @@ class RigConnection
{ {
public: public:
RigConnection(); RigConnection();
RigConnection( size_t c1GlobIdx, RigConnection( unsigned c1GlobIdx,
size_t c2GlobIdx, unsigned c2GlobIdx,
cvf::StructGridInterface::FaceType c1Face, cvf::StructGridInterface::FaceType c1Face,
const std::vector<cvf::Vec3d>& polygon ); const std::vector<cvf::Vec3f>& polygon );
RigConnection( const RigConnection& rhs ); RigConnection( const RigConnection& rhs );
RigConnection& operator=( RigConnection& rhs ); RigConnection& operator=( RigConnection& rhs );
bool operator<( const RigConnection& other ) const; bool operator<( const RigConnection& other ) const;
bool hasCommonArea() const; bool hasCommonArea() const;
size_t m_c1GlobIdx; unsigned m_c1GlobIdx;
size_t m_c2GlobIdx; unsigned m_c2GlobIdx;
cvf::StructGridInterface::FaceType m_c1Face; cvf::StructGridInterface::FaceType m_c1Face;
std::vector<cvf::Vec3d> m_polygon; std::vector<cvf::Vec3f> m_polygon;
}; };
class RigConnectionContainer class RigConnectionContainer
@ -52,9 +53,9 @@ class RigConnectionContainer
public: public:
RigConnection operator[]( size_t i ) const; RigConnection operator[]( size_t i ) const;
std::pair<size_t, size_t>& indexPair( size_t i ); std::pair<unsigned, unsigned>& indexPair( size_t i );
cvf::StructGridInterface::FaceType& face( size_t i ); unsigned char& face( size_t i );
std::vector<cvf::Vec3d>& polygon( size_t i ); std::vector<cvf::Vec3f>& polygon( size_t i );
void push_back( const RigConnection& connection ); void push_back( const RigConnection& connection );
void insert( const RigConnectionContainer& other ); void insert( const RigConnectionContainer& other );
@ -63,7 +64,7 @@ public:
bool empty() const; bool empty() const;
private: private:
std::vector<std::pair<size_t, size_t>> m_globalIndices; std::vector<std::pair<unsigned, unsigned>> m_globalIndices;
std::vector<cvf::StructGridInterface::FaceType> m_faces; std::vector<unsigned char> m_faces;
std::vector<std::vector<cvf::Vec3d>> m_polygons; std::vector<std::vector<cvf::Vec3f>> m_polygons;
}; };

View File

@ -592,8 +592,8 @@ void RigReservoirBuilderMock::addNnc( RigMainGrid* grid,
size_t c2GlobalIndex = grid->cellIndexFromIJK( i2, j2, k2 ); size_t c2GlobalIndex = grid->cellIndexFromIJK( i2, j2, k2 );
RigConnection conn; RigConnection conn;
conn.m_c1GlobIdx = c1GlobalIndex; conn.m_c1GlobIdx = static_cast<unsigned>( c1GlobalIndex );
conn.m_c2GlobIdx = c2GlobalIndex; conn.m_c2GlobIdx = static_cast<unsigned>( c2GlobalIndex );
nncConnections.push_back( conn ); nncConnections.push_back( conn );
} }

View File

@ -786,6 +786,59 @@ cvf::Vec3d GeometryTools::polygonAreaNormal3D( const std::vector<cvf::Vec3d>& po
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3f GeometryTools::polygonAreaNormal3D( const std::vector<cvf::Vec3f>& polygon )
{
size_t pSize = polygon.size();
switch ( pSize )
{
case 0:
case 1:
case 2:
{
return cvf::Vec3f::ZERO;
}
break;
case 3:
{
return 0.5f * ( ( polygon[1] - polygon[0] ) ^ ( polygon[2] - polygon[0] ) );
}
break;
case 4:
{
// Cross product of diagonal = 2*A
return 0.5f * ( ( polygon[2] - polygon[0] ) ^ ( polygon[3] - polygon[1] ) );
}
break;
default:
{
/// JJS:
// This is possibly not the fastest approach with large polygons, where a scaled projections approach would
// be better, but I suspect this (simpler) approach is faster for small polygons, as long as we do not have
// the polygon normal up front.
//
cvf::Vec3f areaNormal( cvf::Vec3f::ZERO );
size_t h = ( pSize - 1 ) / 2;
size_t k = ( pSize % 2 ) ? 0 : pSize - 1;
// First quads
for ( size_t i = 1; i < h; ++i )
{
areaNormal += ( ( polygon[2 * i] - polygon[0] ) ^ ( polygon[2 * i + 1] - polygon[2 * i - 1] ) );
}
// Last triangle or quad
areaNormal += ( ( polygon[2 * h] - polygon[0] ) ^ ( polygon[k] - polygon[2 * h - 1] ) );
areaNormal *= 0.5;
return areaNormal;
}
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -76,6 +76,7 @@ public:
static double signedAreaPlanarPolygon( const cvf::Vec3d& planeNormal, const std::vector<cvf::Vec3d>& polygon ); static double signedAreaPlanarPolygon( const cvf::Vec3d& planeNormal, const std::vector<cvf::Vec3d>& polygon );
static cvf::Vec3d polygonAreaNormal3D( const std::vector<cvf::Vec3d>& polygon ); static cvf::Vec3d polygonAreaNormal3D( const std::vector<cvf::Vec3d>& polygon );
static cvf::Vec3f polygonAreaNormal3D( const std::vector<cvf::Vec3f>& polygon );
enum IntersectionStatus enum IntersectionStatus
{ {