Merge pull request #8402 from OPM/8401-flow-vector-result

#8401 Flow Vector Result: Handle empty results for first time step
Use OpenMP for vector calculations

Janitor: Use field of double instead of float to avoid rounding errors. If float is used in field, the current editor is has rounding effects that makes the text representation of 0.1 turn into 0.09999999....
This commit is contained in:
Magne Sjaastad 2022-01-04 07:29:56 +01:00 committed by GitHub
parent 57e4283d26
commit 8defab9bc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 15 deletions

View File

@ -121,7 +121,8 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
if ( fluidIndex == 0 ) directions.push_back( cvf::StructGridInterface::POS_I );
auto candidate = addresses[0 + fluidIndex];
if ( resultsData->hasResultEntry( candidate ) )
if ( resultsData->hasResultEntry( candidate ) &&
!resultsData->cellScalarResults( candidate, timeStepIndex ).empty() )
{
resultAddresses.push_back( candidate );
}
@ -130,7 +131,8 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
{
if ( fluidIndex == 0 ) directions.push_back( cvf::StructGridInterface::POS_J );
auto candidate = addresses[1 + fluidIndex];
if ( resultsData->hasResultEntry( candidate ) )
if ( resultsData->hasResultEntry( candidate ) &&
!resultsData->cellScalarResults( candidate, timeStepIndex ).empty() )
{
resultAddresses.push_back( candidate );
}
@ -139,7 +141,8 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
{
if ( fluidIndex == 0 ) directions.push_back( cvf::StructGridInterface::POS_K );
auto candidate = addresses[2 + fluidIndex];
if ( resultsData->hasResultEntry( candidate ) )
if ( resultsData->hasResultEntry( candidate ) &&
!resultsData->cellScalarResults( candidate, timeStepIndex ).empty() )
{
resultAddresses.push_back( candidate );
}
@ -161,7 +164,8 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
faceNormal = ( faceCenter - cellCenter ).getNormalized() * arrowScaling;
};
for ( size_t gcIdx = 0; gcIdx < cells.size(); ++gcIdx )
#pragma omp parallel for
for ( int gcIdx = 0; gcIdx < static_cast<int>( cells.size() ); ++gcIdx )
{
if ( !cells[gcIdx].isInvalid() && activeCellInfo->isActive( gcIdx ) )
{
@ -181,9 +185,10 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
{
cvf::Vec3d faceCenter;
cvf::Vec3d faceNormal;
getFaceCenterAndNormal( gcIdx, directions[dir], faceCenter, faceNormal );
getFaceCenterAndNormal( static_cast<size_t>( gcIdx ), directions[dir], faceCenter, faceNormal );
faceNormal *= std::abs( resultValue );
#pragma omp critical( critical_section_RivElementVectorResultPartMgr_add_1 )
tensorVisualizations.push_back(
ElementVectorResultVisualization( faceCenter,
faceNormal,
@ -215,6 +220,7 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
}
if ( aggregatedResult.length() >= result->threshold() )
{
#pragma omp critical( critical_section_RivElementVectorResultPartMgr_add_2 )
tensorVisualizations.push_back(
ElementVectorResultVisualization( displayCordXf->transformToDisplayCoord( cells[gcIdx].center() ),
aggregatedVector,
@ -245,7 +251,8 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
}
}
for ( size_t nIdx = 0; nIdx < nncData->eclipseConnectionCount(); ++nIdx )
#pragma omp parallel for
for ( int nIdx = 0; nIdx < static_cast<int>( nncData->eclipseConnectionCount() ); ++nIdx )
{
const RigConnection& conn = nncData->availableConnections()[nIdx];
if ( conn.polygon().size() )
@ -253,7 +260,7 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
double resultValue = 0.0;
for ( size_t flIdx = 0; flIdx < nncResultVals.size(); flIdx++ )
{
if ( nIdx < nncResultVals.at( flIdx )->at( timeStepIndex ).size() )
if ( nIdx < static_cast<int>( nncResultVals.at( flIdx )->at( timeStepIndex ).size() ) )
{
resultValue += nncResultVals.at( flIdx )->at( timeStepIndex )[nIdx];
}
@ -269,6 +276,7 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
if ( std::abs( resultValue ) >= result->threshold() )
{
#pragma omp critical( critical_section_RivElementVectorResultPartMgr_add_nnc )
tensorVisualizations.push_back(
ElementVectorResultVisualization( displayCordXf->transformToDisplayCoord( connCenter ),
connNormal,

View File

@ -94,13 +94,13 @@ RimElementVectorResult::RimElementVectorResult()
CAF_PDM_InitField( &m_showVectorJ, "ShowVectorJ", true, "J" );
CAF_PDM_InitField( &m_showVectorK, "ShowVectorK", true, "K" );
CAF_PDM_InitField( &m_showNncData, "ShowNncData", true, "Show NNC Data" );
CAF_PDM_InitField( &m_threshold, "Threshold", 0.0f, "Threshold" );
CAF_PDM_InitField( &m_threshold, "Threshold", 0.0, "Threshold" );
CAF_PDM_InitFieldNoDefault( &m_vectorColor, "VectorColor", "Color" );
cvf::Color3f defaultUniformColor = cvf::Color3f::BLACK;
CAF_PDM_InitField( &m_uniformVectorColor, "UniformVectorColor", defaultUniformColor, "Uniform Vector Color" );
CAF_PDM_InitField( &m_sizeScale, "SizeScale", 1.0f, "Size Scale" );
CAF_PDM_InitField( &m_sizeScale, "SizeScale", 1.0, "Size Scale" );
}
//--------------------------------------------------------------------------------------------------
@ -206,7 +206,7 @@ RimElementVectorResult::VectorSurfaceCrossingLocation RimElementVectorResult::ve
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RimElementVectorResult::threshold() const
double RimElementVectorResult::threshold() const
{
return m_threshold();
}
@ -214,7 +214,7 @@ float RimElementVectorResult::threshold() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RimElementVectorResult::sizeScale() const
double RimElementVectorResult::sizeScale() const
{
return m_sizeScale();
}

View File

@ -77,8 +77,8 @@ public:
bool showVectorK() const;
bool showNncData() const;
VectorSurfaceCrossingLocation vectorSuraceCrossingLocation() const;
float threshold() const;
float sizeScale() const;
double threshold() const;
double sizeScale() const;
TensorColors vectorColors() const;
const cvf::Color3f& getUniformVectorColor() const;
@ -108,10 +108,10 @@ private:
caf::PdmField<bool> m_showVectorK;
caf::PdmField<bool> m_showNncData;
caf::PdmField<caf::AppEnum<VectorSurfaceCrossingLocation>> m_vectorSurfaceCrossingLocation;
caf::PdmField<float> m_threshold;
caf::PdmField<double> m_threshold;
caf::PdmField<caf::AppEnum<TensorColors>> m_vectorColor;
caf::PdmField<cvf::Color3f> m_uniformVectorColor;
caf::PdmField<float> m_sizeScale;
caf::PdmField<double> m_sizeScale;
caf::PdmField<RimRegularLegendConfig::RangeModeEnum> m_rangeMode;
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
};

View File

@ -264,6 +264,8 @@ bool RigCaseCellResultCalculator::computeDivideByCellFaceArea( RigMainGrid*
cvf::ref<RigResultModifier> resultModifier =
RigResultModifierFactory::createResultModifier( destination, gridIdx, porosityModel, fIdx, address );
if ( resultModifier.isNull() ) continue;
#pragma omp parallel for
for ( int localGridCellIdx = 0; localGridCellIdx < static_cast<int>( grid->cellCount() ); localGridCellIdx++ )
{

View File

@ -65,6 +65,8 @@ cvf::ref<RigResultModifier> RigResultModifierFactory::createResultModifier( RigE
resultValues = &( scalarSetResults->at( timeStepIndex ) );
}
if ( resultValues->empty() ) return nullptr;
bool useGlobalActiveIndex = eclipseCase->results( porosityModel )->isUsingGlobalActiveIndex( resVarAddr );
if ( useGlobalActiveIndex )
{