Result Divided by Area: Establish concept used to compute flow velocity and normalized trans (#7349)

* 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>
This commit is contained in:
Magne Sjaastad
2021-02-11 03:01:17 +01:00
committed by GitHub
parent 424f66fd4e
commit cc292b197a
30 changed files with 631 additions and 321 deletions

View File

@@ -101,7 +101,7 @@ CAF_PDM_SOURCE_INIT( RimEclipseResultDefinition, "ResultDefinition" );
///
//--------------------------------------------------------------------------------------------------
RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::LabelPosType labelPosition )
: m_diffResultOptionsEnabled( false )
: m_isDeltaResultEnabled( false )
, m_labelPosition( labelPosition )
, m_ternaryEnabled( true )
{
@@ -135,6 +135,8 @@ RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::Labe
CAF_PDM_InitFieldNoDefault( &m_differenceCase, "DifferenceCase", "Difference Case", "", "", "" );
CAF_PDM_InitField( &m_divideByCellFaceArea, "DivideByCellFaceArea", false, "Divide By Area", "", "", "" );
// One single tracer list has been split into injectors and producers.
// The old list is defined as injectors and we'll have to move any producers in old projects.
CAF_PDM_InitFieldNoDefault( &m_selectedTracers_OBSOLETE, "SelectedTracers", "Tracers", "", "", "" );
@@ -238,6 +240,7 @@ void RimEclipseResultDefinition::simpleCopy( const RimEclipseResultDefinition* o
m_differenceCase = other->m_differenceCase();
m_timeLapseBaseTimestep = other->m_timeLapseBaseTimestep();
m_divideByCellFaceArea = other->m_divideByCellFaceArea();
}
//--------------------------------------------------------------------------------------------------
@@ -376,6 +379,11 @@ void RimEclipseResultDefinition::fieldChangedByUi( const caf::PdmFieldHandle* ch
loadDataAndUpdate();
}
if ( &m_divideByCellFaceArea == changedField )
{
loadDataAndUpdate();
}
if ( &m_flowTracerSelectionMode == changedField )
{
loadDataAndUpdate();
@@ -875,17 +883,21 @@ RigEclipseResultAddress RimEclipseResultDefinition::eclipseResultAddress() const
int timelapseTimeStep = RigEclipseResultAddress::noTimeLapseValue();
int diffCaseId = RigEclipseResultAddress::noCaseDiffValue();
if ( isTimeDiffResult() )
if ( isDeltaTimeStepActive() )
{
timelapseTimeStep = m_timeLapseBaseTimestep();
}
if ( isCaseDiffResult() )
if ( isDeltaCaseActive() )
{
diffCaseId = m_differenceCase->caseId();
}
return RigEclipseResultAddress( m_resultType(), m_resultVariable(), timelapseTimeStep, diffCaseId );
return RigEclipseResultAddress( m_resultType(),
m_resultVariable(),
timelapseTimeStep,
diffCaseId,
isDivideByCellFaceAreaActive() );
}
else
{
@@ -907,16 +919,17 @@ void RimEclipseResultDefinition::setFromEclipseResultAddress( const RigEclipseRe
if ( rinfo ) canonizedAddress = rinfo->eclipseResultAddress();
}
m_resultType = canonizedAddress.m_resultCatType;
m_resultVariable = canonizedAddress.m_resultName;
m_timeLapseBaseTimestep = canonizedAddress.m_timeLapseBaseFrameIdx;
m_resultType = canonizedAddress.resultCatType();
m_resultVariable = canonizedAddress.resultName();
m_timeLapseBaseTimestep = canonizedAddress.deltaTimeStepIndex();
m_divideByCellFaceArea = canonizedAddress.isDivideByCellFaceAreaActive();
if ( canonizedAddress.hasDifferenceCase() )
if ( canonizedAddress.isDeltaCaseActive() )
{
auto eclipseCases = RimProject::current()->eclipseCases();
for ( RimEclipseCase* c : eclipseCases )
{
if ( c && c->caseId() == canonizedAddress.m_differenceCaseId )
if ( c && c->caseId() == canonizedAddress.deltaCaseId() )
{
m_differenceCase = c;
}
@@ -1036,6 +1049,11 @@ QString RimEclipseResultDefinition::resultVariableUiName() const
return flowDiagResUiText( false, 32 );
}
if ( isDivideByCellFaceAreaActive() )
{
return m_resultVariable() + " /A";
}
return m_resultVariable();
}
@@ -1049,74 +1067,62 @@ QString RimEclipseResultDefinition::resultVariableUiShortName() const
return flowDiagResUiText( true, 24 );
}
if ( isDivideByCellFaceAreaActive() )
{
return m_resultVariable() + " /A";
}
return m_resultVariable();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimEclipseResultDefinition::diffResultUiName() const
QString RimEclipseResultDefinition::additionalResultText() const
{
QStringList diffResult;
if ( isTimeDiffResult() )
QStringList resultText;
if ( isDeltaTimeStepActive() )
{
std::vector<QDateTime> stepDates;
const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults();
if ( gridCellResults )
{
stepDates = gridCellResults->timeStepDates();
diffResult +=
resultText +=
QString( "<b>Base Time Step</b>: %1" )
.arg( stepDates[m_timeLapseBaseTimestep()].toString( RiaQDateTimeTools::dateFormatString() ) );
}
}
if ( isCaseDiffResult() )
if ( isDeltaCaseActive() )
{
diffResult += QString( "<b>Base Case</b>: %1" ).arg( m_differenceCase()->caseUserDescription() );
resultText += QString( "<b>Base Case</b>: %1" ).arg( m_differenceCase()->caseUserDescription() );
}
return diffResult.join( "\n" );
return resultText.join( "<br>" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimEclipseResultDefinition::diffResultUiShortName() const
QString RimEclipseResultDefinition::additionalResultTextShort() const
{
QStringList diffResult;
if ( isTimeDiffResult() || isCaseDiffResult() )
QString resultTextShort;
if ( isDeltaTimeStepActive() || isDeltaCaseActive() )
{
diffResult += QString( "Diff. Options:" );
QStringList resultTextLines;
resultTextLines += QString( "\nDiff. Options:" );
if ( isDeltaCaseActive() )
{
resultTextLines += QString( "Base Case: #%1" ).arg( m_differenceCase()->caseId() );
}
if ( isDeltaTimeStepActive() )
{
resultTextLines += QString( "Base Time: #%1" ).arg( m_timeLapseBaseTimestep() );
}
resultTextShort = resultTextLines.join( "\n" );
}
if ( isCaseDiffResult() )
{
diffResult += QString( "Base Case: #%1" ).arg( m_differenceCase()->caseId() );
}
if ( isTimeDiffResult() )
{
diffResult += QString( "Base Time: #%1" ).arg( m_timeLapseBaseTimestep() );
}
return diffResult.join( "\n" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimEclipseResultDefinition::diffResultUiShortNameHTML() const
{
QStringList diffResult;
if ( isTimeDiffResult() || isCaseDiffResult() )
{
diffResult += QString( "<b>Diff. Options:</b>" );
}
if ( isCaseDiffResult() )
{
diffResult += QString( "Base Case: #%1" ).arg( m_differenceCase()->caseId() );
}
if ( isTimeDiffResult() )
{
diffResult += QString( "Base Time: #%1" ).arg( m_timeLapseBaseTimestep() );
}
return diffResult.join( "<br>" );
return resultTextShort;
}
//--------------------------------------------------------------------------------------------------
@@ -1169,7 +1175,7 @@ void RimEclipseResultDefinition::loadResult()
RigCaseCellResultsData* gridCellResults = this->currentGridCellResults();
if ( gridCellResults )
{
if ( isTimeDiffResult() || isCaseDiffResult() )
if ( isDeltaTimeStepActive() || isDeltaCaseActive() || isDivideByCellFaceAreaActive() )
{
gridCellResults->createResultEntry( this->eclipseResultAddress(), false );
}
@@ -1444,9 +1450,9 @@ void RimEclipseResultDefinition::updateUiFieldsFromActiveResult()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultDefinition::setDiffResultOptionsEnabled( bool enabled )
void RimEclipseResultDefinition::enableDeltaResults( bool enable )
{
m_diffResultOptionsEnabled = true;
m_isDeltaResultEnabled = enable;
}
//--------------------------------------------------------------------------------------------------
@@ -1563,6 +1569,18 @@ void RimEclipseResultDefinition::defineUiOrdering( QString uiConfigName, caf::Pd
uiOrdering.add( &m_inputPropertyFileName );
}
if ( isDivideByCellFaceAreaPossible() )
{
uiOrdering.add( &m_divideByCellFaceArea );
QString resultPropertyLabel = "Result Property";
if ( isDivideByCellFaceAreaActive() )
{
resultPropertyLabel += QString( "\nDivided by Area" );
}
m_resultVariableUiField.uiCapability()->setUiName( resultPropertyLabel );
}
caf::PdmUiGroup* legendGroup = uiOrdering.addNewGroup( "Legend" );
legendGroup->add( &m_showOnlyVisibleTracersInLegend );
@@ -1570,21 +1588,21 @@ void RimEclipseResultDefinition::defineUiOrdering( QString uiConfigName, caf::Pd
m_resultVariableUiField() == RIG_FLD_MAX_FRACTION_TRACER_RESNAME );
legendGroup->setUiHidden( !showOnlyVisibleTracesOption );
if ( isCaseDiffResultAvailable() || isTimeDiffResultAvailable() )
if ( isDeltaCasePossible() || isDeltaTimeStepPossible() )
{
caf::PdmUiGroup* differenceGroup = uiOrdering.addNewGroup( "Difference Options" );
differenceGroup->setUiReadOnly( !( isTimeDiffResultAvailable() || isCaseDiffResultAvailable() ) );
differenceGroup->setUiReadOnly( !( isDeltaTimeStepPossible() || isDeltaCasePossible() ) );
m_differenceCase.uiCapability()->setUiReadOnly( !isCaseDiffResultAvailable() );
m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly( !isTimeDiffResultAvailable() );
m_differenceCase.uiCapability()->setUiReadOnly( !isDeltaCasePossible() );
m_timeLapseBaseTimestep.uiCapability()->setUiReadOnly( !isDeltaTimeStepPossible() );
if ( isCaseDiffResultAvailable() ) differenceGroup->add( &m_differenceCase );
if ( isTimeDiffResultAvailable() ) differenceGroup->add( &m_timeLapseBaseTimestep );
if ( isDeltaCasePossible() ) differenceGroup->add( &m_differenceCase );
if ( isDeltaTimeStepPossible() ) differenceGroup->add( &m_timeLapseBaseTimestep );
QString resultPropertyLabel = "Result Property";
if ( isTimeDiffResult() || isCaseDiffResult() )
if ( isDeltaTimeStepActive() || isDeltaCaseActive() )
{
resultPropertyLabel += QString( "\n%1" ).arg( diffResultUiShortName() );
resultPropertyLabel += QString( "\n%1" ).arg( additionalResultTextShort() );
}
m_resultVariableUiField.uiCapability()->setUiName( resultPropertyLabel );
}
@@ -2182,9 +2200,9 @@ void RimEclipseResultDefinition::updateRangesForExplicitLegends( RimRegularLegen
void RimEclipseResultDefinition::updateLegendTitle( RimRegularLegendConfig* legendConfig, const QString& legendHeading )
{
QString title = legendHeading + this->resultVariableUiName();
if ( !this->diffResultUiShortName().isEmpty() )
if ( !this->additionalResultTextShort().isEmpty() )
{
title += QString( "\n%1" ).arg( this->diffResultUiShortName() );
title += additionalResultTextShort();
}
if ( this->hasDualPorFractureResult() )
@@ -2565,34 +2583,34 @@ void RimEclipseResultDefinition::syncProducerToInjectorSelection()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::enableDiffResultOptions() const
bool RimEclipseResultDefinition::isDeltaResultEnabled() const
{
return m_diffResultOptionsEnabled;
return m_isDeltaResultEnabled;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::isTimeDiffResultAvailable() const
bool RimEclipseResultDefinition::isDeltaTimeStepPossible() const
{
return enableDiffResultOptions() && m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE &&
return isDeltaResultEnabled() && m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE &&
!isTernarySaturationSelected();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::isTimeDiffResult() const
bool RimEclipseResultDefinition::isDeltaTimeStepActive() const
{
return isTimeDiffResultAvailable() && m_timeLapseBaseTimestep() >= 0;
return isDeltaTimeStepPossible() && m_timeLapseBaseTimestep() >= 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::isCaseDiffResultAvailable() const
bool RimEclipseResultDefinition::isDeltaCasePossible() const
{
return enableDiffResultOptions() && !isTernarySaturationSelected() &&
return isDeltaResultEnabled() && !isTernarySaturationSelected() &&
( m_resultTypeUiField() == RiaDefines::ResultCatType::DYNAMIC_NATIVE ||
m_resultTypeUiField() == RiaDefines::ResultCatType::STATIC_NATIVE ||
m_resultTypeUiField() == RiaDefines::ResultCatType::GENERATED );
@@ -2601,9 +2619,49 @@ bool RimEclipseResultDefinition::isCaseDiffResultAvailable() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::isCaseDiffResult() const
bool RimEclipseResultDefinition::isDeltaCaseActive() const
{
return isCaseDiffResultAvailable() && m_differenceCase() != nullptr;
return isDeltaCasePossible() && m_differenceCase() != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::isDivideByCellFaceAreaPossible() const
{
QString str = m_resultVariable;
// TODO : Move to RiaDefines or a separate file for cell face results
if ( str == "FLRWATI+" ) return true;
if ( str == "FLRWATJ+" ) return true;
if ( str == "FLRWATK+" ) return true;
if ( str == "FLROILI+" ) return true;
if ( str == "FLROILJ+" ) return true;
if ( str == "FLROILK+" ) return true;
if ( str == "FLRGASI+" ) return true;
if ( str == "FLRGASJ+" ) return true;
if ( str == "FLRGASK+" ) return true;
if ( str == "TRANX" ) return true;
if ( str == "TRANY" ) return true;
if ( str == "TRANZ" ) return true;
if ( str == "riTRANX" ) return true;
if ( str == "riTRANY" ) return true;
if ( str == "riTRANZ" ) return true;
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultDefinition::isDivideByCellFaceAreaActive() const
{
return isDivideByCellFaceAreaPossible() && m_divideByCellFaceArea;
}
//--------------------------------------------------------------------------------------------------