From e09a839228977c72f3f5f4377c6a8277fc16294d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Mar 2022 18:19:49 +0100 Subject: [PATCH] Merge pull request #8402 from OPM/8401-flow-vector-result 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.... --- .../RivElementVectorResultPartMgr.cpp | 22 +++++++++++++------ .../RimElementVectorResult.cpp | 16 +++++++------- .../ProjectDataModel/RimElementVectorResult.h | 8 +++---- .../RigCaseCellResultCalculator.cpp | 2 ++ .../RigResultModifierFactory.cpp | 2 ++ 5 files changed, 31 insertions(+), 19 deletions(-) diff --git a/ApplicationLibCode/ModelVisualization/RivElementVectorResultPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivElementVectorResultPartMgr.cpp index ba9a37efd9..4ab81b28ee 100644 --- a/ApplicationLibCode/ModelVisualization/RivElementVectorResultPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivElementVectorResultPartMgr.cpp @@ -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( 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( 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( 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( 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, diff --git a/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.cpp b/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.cpp index bdc6c455f8..5cb36dcc89 100644 --- a/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.cpp @@ -93,17 +93,17 @@ RimElementVectorResult::RimElementVectorResult() m_vectorSurfaceCrossingLocation.uiCapability()->setUiReadOnly( m_vectorView() == RimElementVectorResult::VectorView::CELL_CENTER_TOTAL ); - CAF_PDM_InitField( &m_showVectorI, "ShowVectorI", true, "I", "", "", "" ); - 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_showVectorI, "ShowVectorI", true, "I" ); + 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.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" ); } //-------------------------------------------------------------------------------------------------- @@ -209,7 +209,7 @@ RimElementVectorResult::VectorSurfaceCrossingLocation RimElementVectorResult::ve //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -float RimElementVectorResult::threshold() const +double RimElementVectorResult::threshold() const { return m_threshold(); } @@ -217,7 +217,7 @@ float RimElementVectorResult::threshold() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -float RimElementVectorResult::sizeScale() const +double RimElementVectorResult::sizeScale() const { return m_sizeScale(); } diff --git a/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.h b/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.h index 079e67a8b7..024a347354 100644 --- a/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.h +++ b/ApplicationLibCode/ProjectDataModel/RimElementVectorResult.h @@ -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 m_showVectorK; caf::PdmField m_showNncData; caf::PdmField> m_vectorSurfaceCrossingLocation; - caf::PdmField m_threshold; + caf::PdmField m_threshold; caf::PdmField> m_vectorColor; caf::PdmField m_uniformVectorColor; - caf::PdmField m_sizeScale; + caf::PdmField m_sizeScale; caf::PdmField m_rangeMode; caf::PdmChildField m_legendConfig; }; diff --git a/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp index 19ab6b596d..c35e6826e2 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp @@ -264,6 +264,8 @@ bool RigCaseCellResultCalculator::computeDivideByCellFaceArea( RigMainGrid* cvf::ref resultModifier = RigResultModifierFactory::createResultModifier( destination, gridIdx, porosityModel, fIdx, address ); + if ( resultModifier.isNull() ) continue; + #pragma omp parallel for for ( int localGridCellIdx = 0; localGridCellIdx < static_cast( grid->cellCount() ); localGridCellIdx++ ) { diff --git a/ApplicationLibCode/ReservoirDataModel/RigResultModifierFactory.cpp b/ApplicationLibCode/ReservoirDataModel/RigResultModifierFactory.cpp index cf63145cba..bec5e662d5 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigResultModifierFactory.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigResultModifierFactory.cpp @@ -65,6 +65,8 @@ cvf::ref RigResultModifierFactory::createResultModifier( RigE resultValues = &( scalarSetResults->at( timeStepIndex ) ); } + if ( resultValues->empty() ) return nullptr; + bool useGlobalActiveIndex = eclipseCase->results( porosityModel )->isUsingGlobalActiveIndex( resVarAddr ); if ( useGlobalActiveIndex ) {