ResInsight/ApplicationLibCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp
Magne Sjaastad cc292b197a
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>
2021-02-11 03:01:17 +01:00

344 lines
12 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 "RivReservoirFaultsPartMgr.h"
#include "RigMainGrid.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseFaultColors.h"
#include "RimEclipseView.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
#include "RivFaultPartMgr.h"
#include "cvfColor3.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfTransform.h"
#include "cafPdmFieldCvfColor.h"
#include <QDebug>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivReservoirFaultsPartMgr::RivReservoirFaultsPartMgr( const RigMainGrid* grid, RimEclipseView* reservoirView )
: m_reservoirView( reservoirView )
{
CVF_ASSERT( grid );
if ( reservoirView )
{
RimFaultInViewCollection* faultCollection = reservoirView->faultCollection();
if ( faultCollection )
{
for ( size_t i = 0; i < faultCollection->faults.size(); i++ )
{
m_faultParts.push_back( new RivFaultPartMgr( grid, faultCollection, faultCollection->faults[i] ) );
}
}
}
m_forceWatertightGeometry = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivReservoirFaultsPartMgr::~RivReservoirFaultsPartMgr()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::setTransform( cvf::Transform* scaleTransform )
{
m_scaleTransform = scaleTransform;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::setCellVisibility( cvf::UByteArray* cellVisibilities )
{
CVF_ASSERT( cellVisibilities );
for ( size_t i = 0; i < m_faultParts.size(); i++ )
{
m_faultParts.at( i )->setCellVisibility( cellVisibilities );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::appendPartsToModel( cvf::ModelBasicList* model )
{
CVF_ASSERT( model != nullptr );
RimFaultInViewCollection* faultCollection = m_reservoirView->faultCollection();
if ( !faultCollection ) return;
bool isShowingGrid = m_reservoirView->isMainGridVisible();
if ( !faultCollection->showFaultCollection() && !isShowingGrid ) return;
// Check match between model fault count and fault parts
CVF_ASSERT( faultCollection->faults.size() == m_faultParts.size() );
// Parts that is overridden by the grid settings
bool forceDisplayOfFault = false;
if ( !faultCollection->isShowingFaultsAndFaultsOutsideFilters() )
{
forceDisplayOfFault = isShowingGrid;
}
if ( m_forceWatertightGeometry && isShowingGrid )
{
forceDisplayOfFault = true;
}
// qDebug() << forceDisplayOfFault;
cvf::ModelBasicList parts;
for ( size_t i = 0; i < faultCollection->faults.size(); i++ )
{
const RimFaultInView* rimFault = faultCollection->faults[i];
cvf::ref<RivFaultPartMgr> rivFaultPart = m_faultParts[i];
CVF_ASSERT( rivFaultPart.notNull() );
if ( ( faultCollection->showFaultCollection() && rimFault->showFault() ) || forceDisplayOfFault )
{
if ( faultCollection->showFaultFaces() || forceDisplayOfFault )
{
rivFaultPart->appendNativeFaultFacesToModel( &parts );
}
if ( faultCollection->showOppositeFaultFaces() || forceDisplayOfFault )
{
rivFaultPart->appendOppositeFaultFacesToModel( &parts );
}
if ( faultCollection->showFaultFaces() || faultCollection->showOppositeFaultFaces() ||
faultCollection->showNNCs() || forceDisplayOfFault )
{
rivFaultPart->appendMeshLinePartsToModel( &parts );
}
}
// Parts that is not overridden by the grid settings
RimEclipseFaultColors* faultResultColors = m_reservoirView->faultResultSettings();
RimEclipseCellColors* cellResultColors = m_reservoirView->cellResult();
if ( rimFault->showFault() && faultCollection->showFaultCollection() )
{
if ( faultCollection->showNNCs() )
{
bool showNncs = true;
bool showCompleteNncGeo = false;
RigEclipseResultAddress eclipseResultAddress;
if ( faultResultColors->showCustomFaultResult() )
{
eclipseResultAddress = faultResultColors->customFaultResult()->eclipseResultAddress();
}
else
{
eclipseResultAddress = cellResultColors->eclipseResultAddress();
}
if ( eclipseResultAddress.resultCatType() == RiaDefines::ResultCatType::ALLAN_DIAGRAMS )
{
showCompleteNncGeo = true;
}
{
QStringList stringsToMatch{ RiaResultNames::combinedRiTranResultName(),
RiaResultNames::combinedRiMultResultName(),
RiaResultNames::combinedRiAreaNormTranResultName(),
RiaResultNames::combinedTransmissibilityResultName(),
RiaResultNames::combinedMultResultName() };
for ( const auto& s : stringsToMatch )
{
if ( eclipseResultAddress.resultName().contains( s, Qt::CaseInsensitive ) )
{
showCompleteNncGeo = true;
}
}
}
if ( faultCollection->hideNncsWhenNoResultIsAvailable() )
{
RigMainGrid* mainGrid = m_reservoirView->mainGrid();
if ( !( mainGrid && mainGrid->nncData()->hasScalarValues( eclipseResultAddress ) ) )
{
showNncs = false;
}
}
if ( showNncs )
{
RigMainGrid* mainGrid = m_reservoirView->mainGrid();
mainGrid->nncData()->ensureConnectionDataIsProcessed();
if ( showCompleteNncGeo )
{
rivFaultPart->appendCompleteNNCFacesToModel( &parts );
}
else
{
rivFaultPart->appendNativeNNCFacesToModel( &parts );
}
}
}
}
}
for ( size_t i = 0; i < parts.partCount(); i++ )
{
cvf::Part* part = parts.part( i );
part->setTransform( m_scaleTransform.p() );
model->addPart( part );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::applySingleColorEffect()
{
for ( size_t i = 0; i < m_faultParts.size(); i++ )
{
m_faultParts[i]->applySingleColorEffect();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::updateColors( size_t timeStepIndex, RimEclipseCellColors* cellResultColors )
{
if ( !m_reservoirView ) return;
RimFaultInViewCollection* faultCollection = m_reservoirView->faultCollection();
CVF_ASSERT( faultCollection );
for ( size_t i = 0; i < faultCollection->faults.size(); i++ )
{
if ( cellResultColors && ( cellResultColors->hasResult() || cellResultColors->isTernarySaturationSelected() ) )
{
m_faultParts[i]->updateCellResultColor( timeStepIndex, cellResultColors );
}
else
{
m_faultParts[i]->applySingleColorEffect();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::updateCellEdgeResultColor( size_t timeStepIndex,
RimEclipseCellColors* cellResultColors,
RimCellEdgeColors* cellEdgeResultColors )
{
for ( size_t i = 0; i < m_faultParts.size(); i++ )
{
m_faultParts[i]->updateCellEdgeResultColor( timeStepIndex, cellResultColors, cellEdgeResultColors );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::appendLabelPartsToModel( cvf::ModelBasicList* model )
{
CVF_ASSERT( model != nullptr );
if ( !m_reservoirView ) return;
RimFaultInViewCollection* faultCollection = m_reservoirView->faultCollection();
CVF_ASSERT( faultCollection );
if ( !faultCollection->showFaultCollection() ) return;
if ( !faultCollection->showFaultLabel() ) return;
// Check match between model fault count and fault parts
CVF_ASSERT( faultCollection->faults.size() == m_faultParts.size() );
cvf::ModelBasicList parts;
for ( size_t i = 0; i < faultCollection->faults.size(); i++ )
{
const RimFaultInView* rimFault = faultCollection->faults[i];
cvf::ref<RivFaultPartMgr> rivFaultPart = m_faultParts[i];
CVF_ASSERT( rivFaultPart.notNull() );
if ( rimFault->showFault() )
{
rivFaultPart->appendLabelPartsToModel( &parts );
}
}
for ( size_t i = 0; i < parts.partCount(); i++ )
{
cvf::Part* part = parts.part( i );
part->setTransform( m_scaleTransform.p() );
model->addPart( part );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::forceWatertightGeometryOn()
{
m_forceWatertightGeometry = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::clearWatertightGeometryFlag()
{
m_forceWatertightGeometry = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::setOpacityLevel( float opacity )
{
for ( size_t i = 0; i < m_faultParts.size(); i++ )
{
m_faultParts[i]->setOpacityLevel( opacity );
}
}