mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-03 12:10:57 -06:00
cc292b197a
* Geometry Tools : Add convenience functions for polygon area * #7232 Result Divided by Area: Add cell face result and show in GUI Native support for flow rate is given by mass rate (mass per time) over a cell face. Add a derived result that takes flow rate divided by cell face area to get velocity (distance per time). Add support for this concept on relevant native results, and indicate this result type in UI using a "/A" postfix * Speed up divided-by-area calculations by using openmp * Some refactoring of result data access. * Make sure NNC data is scaled correctly in vector flow viz. Co-authored-by: jonjenssen <jon@soundsoft.no>
692 lines
26 KiB
C++
692 lines
26 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) Statoil ASA
|
|
// Copyright (C) Ceetron Solutions AS
|
|
//
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RigNNCData.h"
|
|
|
|
#include "RigCellFaceGeometryTools.h"
|
|
#include "RigEclipseResultAddress.h"
|
|
#include "RigMainGrid.h"
|
|
|
|
#include "RiaLogging.h"
|
|
|
|
#include "cafProgressInfo.h"
|
|
|
|
#include "cvfGeometryTools.h"
|
|
|
|
#include <QString>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigNNCData::RigNNCData()
|
|
: m_nativeConnectionCount( 0 )
|
|
, m_connectionsAreProcessed( false )
|
|
, m_mainGrid( nullptr )
|
|
, m_activeCellInfo( nullptr )
|
|
, m_computeNncForInactiveCells( false )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RigNNCData::setSourceDataForProcessing( RigMainGrid* mainGrid,
|
|
const RigActiveCellInfo* activeCellInfo,
|
|
bool includeInactiveCells )
|
|
{
|
|
m_mainGrid = mainGrid;
|
|
m_activeCellInfo = activeCellInfo;
|
|
m_computeNncForInactiveCells = includeInactiveCells;
|
|
|
|
m_connectionsAreProcessed = false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RigNNCData::processNativeConnections( const RigMainGrid& mainGrid )
|
|
{
|
|
// cvf::Trace::show("NNC: Total number: " + cvf::String((int)m_connections.size()));
|
|
|
|
#pragma omp parallel for
|
|
for ( int cnIdx = 0; cnIdx < (int)m_connections.size(); ++cnIdx )
|
|
{
|
|
const RigCell& c1 = mainGrid.globalCellArray()[m_connections[cnIdx].c1GlobIdx()];
|
|
const RigCell& c2 = mainGrid.globalCellArray()[m_connections[cnIdx].c2GlobIdx()];
|
|
|
|
std::vector<size_t> connectionPolygon;
|
|
std::vector<cvf::Vec3d> connectionIntersections;
|
|
cvf::StructGridInterface::FaceType connectionFace = cvf::StructGridInterface::NO_FACE;
|
|
|
|
connectionFace =
|
|
RigCellFaceGeometryTools::calculateCellFaceOverlap( c1, c2, mainGrid, &connectionPolygon, &connectionIntersections );
|
|
|
|
if ( connectionFace != cvf::StructGridInterface::NO_FACE )
|
|
{
|
|
m_connections[cnIdx].setFace( connectionFace );
|
|
m_connections[cnIdx].setPolygon(
|
|
RigCellFaceGeometryTools::extractPolygon( mainGrid.nodes(), connectionPolygon, connectionIntersections ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RigNNCData::computeCompleteSetOfNncs( const RigMainGrid* mainGrid,
|
|
const RigActiveCellInfo* activeCellInfo,
|
|
bool includeInactiveCells )
|
|
{
|
|
RigConnectionContainer otherConnections =
|
|
RigCellFaceGeometryTools::computeOtherNncs( mainGrid, m_connections, activeCellInfo, includeInactiveCells );
|
|
|
|
if ( !otherConnections.empty() )
|
|
{
|
|
m_connections.push_back( otherConnections );
|
|
|
|
// Transmissibility values from Eclipse has been read into propertyNameCombTrans in
|
|
// RifReaderEclipseOutput::transferStaticNNCData(). Initialize computed NNCs with zero transmissibility
|
|
auto it = m_connectionResults.find( RiaDefines::propertyNameCombTrans() );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( !it->second.empty() )
|
|
{
|
|
it->second[0].resize( m_connections.size(), 0.0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t RigNNCData::connectionsWithNoCommonArea( QStringList& connectionTextFirstItems, size_t maxItemCount )
|
|
{
|
|
size_t connectionWithNoCommonAreaCount = 0;
|
|
|
|
for ( size_t connIndex = 0; connIndex < m_connections.size(); connIndex++ )
|
|
{
|
|
if ( !m_connections[connIndex].hasCommonArea() )
|
|
{
|
|
connectionWithNoCommonAreaCount++;
|
|
|
|
if ( connectionTextFirstItems.size() < static_cast<int>( maxItemCount ) )
|
|
{
|
|
QString firstConnectionText;
|
|
QString secondConnectionText;
|
|
|
|
{
|
|
size_t gridLocalCellIndex;
|
|
const RigGridBase* hostGrid =
|
|
m_mainGrid->gridAndGridLocalIdxFromGlobalCellIdx( m_connections[connIndex].c1GlobIdx(),
|
|
&gridLocalCellIndex );
|
|
|
|
size_t i, j, k;
|
|
if ( hostGrid->ijkFromCellIndex( gridLocalCellIndex, &i, &j, &k ) )
|
|
{
|
|
// Adjust to 1-based Eclipse indexing
|
|
i++;
|
|
j++;
|
|
k++;
|
|
|
|
if ( !hostGrid->isMainGrid() )
|
|
{
|
|
QString gridName = QString::fromStdString( hostGrid->gridName() );
|
|
firstConnectionText = gridName + " ";
|
|
}
|
|
firstConnectionText += QString( "[%1 %2 %3] - " ).arg( i ).arg( j ).arg( k );
|
|
}
|
|
}
|
|
|
|
{
|
|
size_t gridLocalCellIndex;
|
|
const RigGridBase* hostGrid =
|
|
m_mainGrid->gridAndGridLocalIdxFromGlobalCellIdx( m_connections[connIndex].c2GlobIdx(),
|
|
&gridLocalCellIndex );
|
|
|
|
size_t i, j, k;
|
|
if ( hostGrid->ijkFromCellIndex( gridLocalCellIndex, &i, &j, &k ) )
|
|
{
|
|
// Adjust to 1-based Eclipse indexing
|
|
i++;
|
|
j++;
|
|
k++;
|
|
|
|
if ( !hostGrid->isMainGrid() )
|
|
{
|
|
QString gridName = QString::fromStdString( hostGrid->gridName() );
|
|
secondConnectionText = gridName + " ";
|
|
}
|
|
secondConnectionText += QString( "[%1 %2 %3]" ).arg( i ).arg( j ).arg( k );
|
|
}
|
|
}
|
|
|
|
connectionTextFirstItems.push_back( firstConnectionText + secondConnectionText );
|
|
}
|
|
}
|
|
}
|
|
|
|
return connectionWithNoCommonAreaCount;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RigNNCData::ensureConnectionDataIsProcessed()
|
|
{
|
|
if ( m_connectionsAreProcessed ) return false;
|
|
|
|
if ( m_mainGrid )
|
|
{
|
|
caf::ProgressInfo progressInfo( 3, "Computing NNC Data" );
|
|
|
|
RiaLogging::info( "NNC geometry computation - starting process" );
|
|
|
|
processNativeConnections( *m_mainGrid );
|
|
progressInfo.incrementProgress();
|
|
|
|
computeCompleteSetOfNncs( m_mainGrid, m_activeCellInfo, m_computeNncForInactiveCells );
|
|
progressInfo.incrementProgress();
|
|
|
|
m_connectionsAreProcessed = true;
|
|
|
|
m_mainGrid->distributeNNCsToFaults();
|
|
|
|
QStringList noCommonAreaText;
|
|
const size_t maxItemCount = 20;
|
|
|
|
size_t noCommonAreaCount = connectionsWithNoCommonArea( noCommonAreaText, maxItemCount );
|
|
|
|
RiaLogging::info( "NNC geometry computation - completed process" );
|
|
|
|
RiaLogging::info( QString( "Native NNC count : %1" ).arg( nativeConnectionCount() ) );
|
|
RiaLogging::info( QString( "Computed NNC count : %1" ).arg( m_connections.size() ) );
|
|
|
|
RiaLogging::info( QString( "NNCs with no common area count : %1" ).arg( noCommonAreaCount ) );
|
|
|
|
if ( !noCommonAreaText.isEmpty() )
|
|
{
|
|
RiaLogging::info( QString( "Listing first %1 NNCs with no common area " ).arg( noCommonAreaText.size() ) );
|
|
|
|
for ( const auto& s : noCommonAreaText )
|
|
{
|
|
RiaLogging::info( s );
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RigNNCData::setNativeConnections( RigConnectionContainer& connections )
|
|
{
|
|
m_connections = connections;
|
|
m_nativeConnectionCount = m_connections.size();
|
|
|
|
m_connectionsAreProcessed = false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t RigNNCData::nativeConnectionCount() const
|
|
{
|
|
return m_nativeConnectionCount;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigConnectionContainer& RigNNCData::connections()
|
|
{
|
|
ensureConnectionDataIsProcessed();
|
|
|
|
return m_connections;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<double>& RigNNCData::makeStaticConnectionScalarResult( QString nncDataType )
|
|
{
|
|
ensureConnectionDataIsProcessed();
|
|
|
|
std::vector<std::vector<double>>& results = m_connectionResults[nncDataType];
|
|
results.resize( 1 );
|
|
results[0].resize( m_connections.size(), HUGE_VAL );
|
|
return results[0];
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RigNNCData::makeScalarResultAndSetValues( const QString& nncDataType, const std::vector<double>& values )
|
|
{
|
|
std::vector<std::vector<double>>& results = m_connectionResults[nncDataType];
|
|
results.resize( 1 );
|
|
results[0] = values;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<double>* RigNNCData::staticConnectionScalarResult( const RigEclipseResultAddress& resVarAddr ) const
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
std::map<QString, std::vector<std::vector<double>>>::const_iterator it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
CVF_ASSERT( it->second.size() == 1 );
|
|
return &( it->second[0] );
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<double>* RigNNCData::staticConnectionScalarResultByName( const QString& nncDataType ) const
|
|
{
|
|
std::map<QString, std::vector<std::vector<double>>>::const_iterator it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
CVF_ASSERT( it->second.size() == 1 );
|
|
return &( it->second[0] );
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::vector<double>>& RigNNCData::makeDynamicConnectionScalarResult( QString nncDataType, size_t timeStepCount )
|
|
{
|
|
auto& results = m_connectionResults[nncDataType];
|
|
results.resize( timeStepCount );
|
|
return results;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<std::vector<double>>*
|
|
RigNNCData::dynamicConnectionScalarResult( const RigEclipseResultAddress& resVarAddr ) const
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
return &( it->second );
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<double>* RigNNCData::dynamicConnectionScalarResult( const RigEclipseResultAddress& resVarAddr,
|
|
size_t timeStep ) const
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( it->second.size() > timeStep )
|
|
{
|
|
return &( it->second[timeStep] );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<std::vector<double>>* RigNNCData::dynamicConnectionScalarResultByName( const QString& nncDataType ) const
|
|
{
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
return &( it->second );
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<double>* RigNNCData::dynamicConnectionScalarResultByName( const QString& nncDataType, size_t timeStep ) const
|
|
{
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( it->second.size() > timeStep )
|
|
{
|
|
return &( it->second[timeStep] );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::vector<double>>& RigNNCData::makeGeneratedConnectionScalarResult( QString nncDataType, size_t timeStepCount )
|
|
{
|
|
auto& results = m_connectionResults[nncDataType];
|
|
results.resize( timeStepCount );
|
|
return results;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<std::vector<double>>*
|
|
RigNNCData::generatedConnectionScalarResult( const RigEclipseResultAddress& resVarAddr ) const
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
return &( it->second );
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<double>* RigNNCData::generatedConnectionScalarResult( const RigEclipseResultAddress& resVarAddr,
|
|
size_t timeStep ) const
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( it->second.size() > timeStep )
|
|
{
|
|
return &( it->second[timeStep] );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::vector<double>>* RigNNCData::generatedConnectionScalarResult( const RigEclipseResultAddress& resVarAddr )
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
return &( it->second );
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<double>* RigNNCData::generatedConnectionScalarResult( const RigEclipseResultAddress& resVarAddr, size_t timeStep )
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return nullptr;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( it->second.size() > timeStep )
|
|
{
|
|
return &( it->second[timeStep] );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<std::vector<double>>* RigNNCData::generatedConnectionScalarResultByName( const QString& nncDataType ) const
|
|
{
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
return &( it->second );
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const std::vector<double>* RigNNCData::generatedConnectionScalarResultByName( const QString& nncDataType,
|
|
size_t timeStep ) const
|
|
{
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( it->second.size() > timeStep )
|
|
{
|
|
return &( it->second[timeStep] );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::vector<double>>* RigNNCData::generatedConnectionScalarResultByName( const QString& nncDataType )
|
|
{
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
return &( it->second );
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<double>* RigNNCData::generatedConnectionScalarResultByName( const QString& nncDataType, size_t timeStep )
|
|
{
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
if ( it != m_connectionResults.end() )
|
|
{
|
|
if ( it->second.size() > timeStep )
|
|
{
|
|
return &( it->second[timeStep] );
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<QString> RigNNCData::availableProperties( NNCResultType resultType ) const
|
|
{
|
|
std::vector<QString> properties;
|
|
|
|
for ( auto it : m_connectionResults )
|
|
{
|
|
if ( resultType == NNCResultType::NNC_STATIC && it.second.size() == 1 && it.second[0].size() > 0 &&
|
|
isNative( it.first ) )
|
|
{
|
|
properties.push_back( it.first );
|
|
}
|
|
else if ( resultType == NNCResultType::NNC_DYNAMIC && it.second.size() > 1 && it.second[0].size() > 0 &&
|
|
isNative( it.first ) )
|
|
{
|
|
properties.push_back( it.first );
|
|
}
|
|
else if ( resultType == NNCResultType::NNC_GENERATED && !isNative( it.first ) )
|
|
{
|
|
properties.push_back( it.first );
|
|
}
|
|
}
|
|
|
|
return properties;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RigNNCData::setEclResultAddress( const QString& nncDataType, const RigEclipseResultAddress& resVarAddr )
|
|
{
|
|
m_resultAddrToNNCDataType[resVarAddr] = nncDataType;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RigNNCData::hasScalarValues( const RigEclipseResultAddress& resVarAddr )
|
|
{
|
|
QString nncDataType = getNNCDataTypeFromScalarResultIndex( resVarAddr );
|
|
if ( nncDataType.isNull() ) return false;
|
|
|
|
auto it = m_connectionResults.find( nncDataType );
|
|
return ( it != m_connectionResults.end() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RigNNCData::generateScalarValues( const RigEclipseResultAddress& resVarAddr )
|
|
{
|
|
if ( hasScalarValues( resVarAddr ) ) return true;
|
|
|
|
if ( resVarAddr.isDivideByCellFaceAreaActive() && resVarAddr.resultCatType() == RiaDefines::ResultCatType::DYNAMIC_NATIVE )
|
|
{
|
|
RigEclipseResultAddress tmpAddr = resVarAddr;
|
|
tmpAddr.enableDivideByCellFaceArea( false );
|
|
|
|
auto nameit = m_resultAddrToNNCDataType.find( tmpAddr );
|
|
if ( nameit == m_resultAddrToNNCDataType.end() ) return false;
|
|
|
|
auto it = m_connectionResults.find( nameit->second );
|
|
if ( it == m_connectionResults.end() ) return false;
|
|
|
|
auto& srcdata = it->second;
|
|
|
|
auto& dstdata = makeDynamicConnectionScalarResult( resVarAddr.resultName(), srcdata.size() );
|
|
|
|
const double epsilon = 1.0e-3;
|
|
|
|
std::vector<double> areas( m_connections.size() );
|
|
|
|
for ( size_t dataIdx = 0; dataIdx < m_connections.size(); dataIdx++ )
|
|
{
|
|
double area = 0.0;
|
|
if ( m_connections[dataIdx].hasCommonArea() )
|
|
area = cvf::GeometryTools::polygonArea( m_connections[dataIdx].polygon() );
|
|
areas[dataIdx] = area;
|
|
}
|
|
|
|
#pragma omp parallel for
|
|
for ( int i = 0; i < static_cast<int>( srcdata.size() ); i++ )
|
|
{
|
|
size_t timeIdx = i;
|
|
dstdata[timeIdx].resize( srcdata[timeIdx].size() );
|
|
|
|
for ( size_t dataIdx = 0; dataIdx < srcdata[timeIdx].size(); dataIdx++ )
|
|
{
|
|
double scaledVal = 0.0;
|
|
if ( areas[dataIdx] > epsilon ) scaledVal = srcdata[timeIdx][dataIdx] / areas[dataIdx];
|
|
dstdata[timeIdx][dataIdx] = scaledVal;
|
|
}
|
|
}
|
|
|
|
m_resultAddrToNNCDataType[resVarAddr] = resVarAddr.resultName();
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const QString RigNNCData::getNNCDataTypeFromScalarResultIndex( const RigEclipseResultAddress& resVarAddr ) const
|
|
{
|
|
auto it = m_resultAddrToNNCDataType.find( resVarAddr );
|
|
if ( it != m_resultAddrToNNCDataType.end() )
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RigNNCData::isNative( QString nncDataType ) const
|
|
{
|
|
if ( nncDataType == RiaDefines::propertyNameCombTrans() || nncDataType == RiaDefines::propertyNameFluxGas() ||
|
|
nncDataType == RiaDefines::propertyNameFluxOil() || nncDataType == RiaDefines::propertyNameFluxWat() ||
|
|
nncDataType == RiaDefines::propertyNameRiCombMult() || nncDataType == RiaDefines::propertyNameRiCombTrans() ||
|
|
nncDataType == RiaDefines::propertyNameRiCombTransByArea() )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|