ResInsight/ApplicationLibCode/ReservoirDataModel/RigVisibleCategoriesCalculator.cpp
Magne Sjaastad 681acfb0e0 Create Intersection: Crash for Intersection along Simulation well
Check if any geometry is present before accessing geometry data
2023-12-11 12:32:19 +01:00

251 lines
9.4 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021- Equinor ASA
//
// 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 "RigVisibleCategoriesCalculator.h"
#include "RiaResultNames.h"
#include "RigEclipseCaseData.h"
#include "RigEclipseNativeVisibleCellsStatCalc.h"
#include "RigFault.h"
#include "RigFlowDiagResults.h"
#include "RigFlowDiagVisibleCellsStatCalc.h"
#include "RigMainGrid.h"
#include "RigNNCData.h"
#include "RigResultAccessorFactory.h"
#include "RimBoxIntersection.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseFaultColors.h"
#include "RimEclipseView.h"
#include "RimExtrudedCurveIntersection.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
#include "RimIntersection.h"
#include "RimIntersectionCollection.h"
#include "RimIntersectionResultsDefinitionCollection.h"
#include "RimSurface.h"
#include "RimSurfaceCollection.h"
#include "RimSurfaceInView.h"
#include "RimSurfaceInViewCollection.h"
#include "RivIntersectionGeometryGeneratorInterface.h"
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> RigVisibleCategoriesCalculator::visibleFlowDiagCategories( RimEclipseView& eclView,
RigFlowDiagResults& flowDiagResults,
const RigFlowDiagResultAddress& resVarAddr,
size_t timeStepIndex )
{
cvf::ref<cvf::UByteArray> cellVisibilities = eclView.currentTotalCellVisibility();
cvf::ref<RigFlowDiagVisibleCellsStatCalc> calculator =
cvf::make_ref<RigFlowDiagVisibleCellsStatCalc>( &flowDiagResults, resVarAddr, cellVisibilities.p() );
std::set<int> visibleTracers;
calculator->uniqueValues( timeStepIndex, visibleTracers );
return visibleTracers;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<size_t> RigVisibleCategoriesCalculator::visibleAllanCategories( RimEclipseView* eclView )
{
if ( !( eclView && eclView->mainGrid() ) ) return {};
RigNNCData* nncData = eclView->mainGrid()->nncData();
std::set<size_t> usedAllanIndices;
auto fnAllanNncResults = nncData->staticConnectionScalarResultByName( RiaResultNames::formationAllanResultName() );
if ( fnAllanNncResults )
{
auto visibleConnectionIndices = visibleNncConnectionIndices( eclView );
for ( auto connIdx : visibleConnectionIndices )
{
auto allanValue = fnAllanNncResults->at( connIdx );
usedAllanIndices.insert( allanValue );
}
}
return usedAllanIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> RigVisibleCategoriesCalculator::visibleCategories( RimEclipseView* eclView )
{
std::set<int> visibleCategoryValues;
{
// Visible eclipse grid cells
RimEclipseResultDefinition* resDef = eclView->cellResult();
RigEclipseNativeVisibleCellsStatCalc calc( resDef->currentGridCellResults(),
resDef->eclipseResultAddress(),
eclView->currentTotalCellVisibility().p() );
calc.uniqueValues( eclView->currentTimeStep(), visibleCategoryValues );
}
{
// Visible cells in faults and intersections
std::set<size_t> visibleReservoirCells;
RigVisibleCategoriesCalculator::appendVisibleFaultCells( eclView, visibleReservoirCells );
RigVisibleCategoriesCalculator::appendVisibleIntersectionCells( eclView, visibleReservoirCells );
RimEclipseResultDefinition* resDef = eclView->cellResult();
cvf::ref<RigResultAccessor> resultAccessor =
RigResultAccessorFactory::createFromResultDefinition( eclView->eclipseCase()->eclipseCaseData(), 0, eclView->currentTimeStep(), resDef );
if ( resultAccessor.notNull() )
{
for ( auto cIdx : visibleReservoirCells )
{
const auto resultVal = resultAccessor->cellScalarGlobIdx( cIdx );
if ( resultVal != HUGE_VAL )
{
visibleCategoryValues.insert( resultVal );
}
}
}
}
return visibleCategoryValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<size_t> RigVisibleCategoriesCalculator::visibleNncConnectionIndices( RimEclipseView* eclView )
{
if ( !eclView->faultCollection() || !eclView->faultCollection()->isActive() ) return {};
std::set<size_t> visibleConnectionIndices;
std::vector<RimFaultInView*> visibleFaults;
for ( auto f : eclView->faultCollection()->faults() )
{
if ( f->showFault() )
{
visibleFaults.push_back( f );
auto nncConnectionIndices = f->faultGeometry()->connectionIndices();
for ( const auto& c : nncConnectionIndices )
{
visibleConnectionIndices.insert( c );
}
}
}
return visibleConnectionIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigVisibleCategoriesCalculator::appendVisibleFaultCells( RimEclipseView* eclView, std::set<size_t>& visibleCells )
{
if ( eclView->faultCollection() && eclView->faultCollection()->isActive() && !eclView->faultResultSettings()->showCustomFaultResult() )
{
for ( const auto& f : eclView->faultCollection()->faults() )
{
if ( f->showFault() )
{
for ( const auto& faultFace : f->faultGeometry()->faultFaces() )
{
visibleCells.insert( faultFace.m_nativeReservoirCellIndex );
visibleCells.insert( faultFace.m_oppositeReservoirCellIndex );
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigVisibleCategoriesCalculator::appendVisibleIntersectionCells( RimEclipseView* eclView, std::set<size_t>& visibleCells )
{
// Intersections
std::vector<const RivIntersectionGeometryGeneratorInterface*> intersectionGeoGenerators;
if ( !eclView->separateIntersectionResultsCollection()->isActive() )
{
if ( eclView->intersectionCollection()->isActive() )
{
for ( auto intersection : eclView->intersectionCollection()->intersections() )
{
if ( intersection->isActive() )
{
auto geoGenerator = intersection->intersectionGeometryGenerator();
if ( geoGenerator )
{
intersectionGeoGenerators.push_back( geoGenerator );
}
}
}
for ( auto intersection : eclView->intersectionCollection()->intersectionBoxes() )
{
if ( intersection->isActive() )
{
auto geoGenerator = intersection->intersectionGeometryGenerator();
if ( geoGenerator )
{
intersectionGeoGenerators.push_back( geoGenerator );
}
}
}
}
}
if ( eclView->separateSurfaceResultsCollection()->isActive() )
{
// Surfaces in view
if ( eclView->surfaceInViewCollection() && eclView->surfaceInViewCollection()->isChecked() )
{
auto geoGenerators = eclView->surfaceInViewCollection()->intersectionGeometryGenerators();
intersectionGeoGenerators.insert( intersectionGeoGenerators.end(), geoGenerators.begin(), geoGenerators.end() );
}
}
for ( const auto geoGenerator : intersectionGeoGenerators )
{
if ( !geoGenerator->isAnyGeometryPresent() ) continue;
for ( const auto& cIdx : geoGenerator->triangleToCellIndex() )
{
visibleCells.insert( cIdx );
}
}
}