mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 22:50:25 -05:00
Well target mapping: option to avoid growing across faults
Add AvoidFaults option that blocks cluster growth across fault faces and fault NNCs, and generate a WELL_TARGET_FAULT_FACES result with the number of fault faces per cell.
This commit is contained in:
1 parent
19f94395a7
commit
a789bdb4b4
7 files changed
+110
-1
No files matched your search
@@ -146,6 +146,8 @@ void RigWellTargetMapping::generateCandidates( RimEclipseCase* eclips
|
||||
data.transmissibilityNNC = nullptr;
|
||||
}
|
||||
|
||||
if ( limits.avoidFaults && mainGrid != nullptr ) data.isFaultNnc = RigWellTargetMappingTools::findFaultNncs( mainGrid );
|
||||
|
||||
// Evaluate for each realization after opening its grid, using the mapping's time step.
|
||||
auto computeFilterVector = [&]( RimCellFilter* dataFilter ) -> std::vector<double>
|
||||
{
|
||||
@@ -245,6 +247,15 @@ void RigWellTargetMapping::generateCandidates( RimEclipseCase* eclips
|
||||
QString resultName = RigWellTargetMapping::wellTargetResultName();
|
||||
RigWellTargetMappingTools::createResultVector( *eclipseCase, resultName, clusters, timeStepIdx );
|
||||
|
||||
if ( limits.avoidFaults && mainGrid != nullptr )
|
||||
{
|
||||
RigWellTargetMappingTools::createResultVector( *eclipseCase,
|
||||
wellTargetFaultFacesResultName(),
|
||||
RigWellTargetMappingTools::countFaultFacesPerActiveCell( mainGrid,
|
||||
resultsData->activeCellInfo() ),
|
||||
timeStepIdx );
|
||||
}
|
||||
|
||||
std::vector<RigWellTargetMappingTools::ClusterStatistics> statistics =
|
||||
RigWellTargetMappingTools::generateStatistics( eclipseCase, data.pressure, data.permeabilityX, numClustersFound, timeStepIdx, resultName );
|
||||
std::vector<double> totalPorvSoil( clusters.size(), std::numeric_limits<double>::infinity() );
|
||||
@@ -520,3 +531,11 @@ QString RigWellTargetMapping::wellTargetResultName()
|
||||
{
|
||||
return "WELL_TARGET_NUM";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RigWellTargetMapping::wellTargetFaultFacesResultName()
|
||||
{
|
||||
return "WELL_TARGET_FAULT_FACES";
|
||||
}
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
double transmissibility;
|
||||
int maxNumTargets;
|
||||
int maxIterations;
|
||||
bool avoidFaults = false; // do not grow across fault faces and fault NNCs
|
||||
RigEclipseResultAddress filterAddress;
|
||||
RimCellFilter* startDataFilter = nullptr; // falls back to growDataFilter if null
|
||||
RimCellFilter* growDataFilter = nullptr;
|
||||
@@ -102,4 +103,5 @@ public:
|
||||
double expandBoundingBoxZPercent );
|
||||
|
||||
static QString wellTargetResultName();
|
||||
static QString wellTargetFaultFacesResultName();
|
||||
};
|
||||
@@ -24,10 +24,12 @@
|
||||
#include "RiaResultNames.h"
|
||||
#include "RiaWeightedMeanCalculator.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigCell.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseResultInfo.h"
|
||||
#include "RigFault.h"
|
||||
#include "RigFloodingSettings.h"
|
||||
#include "RigGridBase.h"
|
||||
#include "RigHydrocarbonFlowTools.h"
|
||||
@@ -159,6 +161,46 @@ void RigWellTargetMappingTools::assignClusterIdToCells( const RigActiveCellInfo&
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Flags the NNCs that connect cells across a fault
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<bool> RigWellTargetMappingTools::findFaultNncs( RigMainGrid* mainGrid )
|
||||
{
|
||||
if ( mainGrid->nncData() == nullptr ) return {};
|
||||
|
||||
std::vector<bool> isFaultNnc( mainGrid->nncData()->allConnections().size(), false );
|
||||
for ( const auto& fault : mainGrid->faults() )
|
||||
{
|
||||
for ( size_t nncIdx : fault->connectionIndices() )
|
||||
{
|
||||
if ( nncIdx < isFaultNnc.size() ) isFaultNnc[nncIdx] = true;
|
||||
}
|
||||
}
|
||||
return isFaultNnc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> RigWellTargetMappingTools::countFaultFacesPerActiveCell( const RigMainGrid* mainGrid, const RigActiveCellInfo* activeCellInfo )
|
||||
{
|
||||
const std::vector<CellFaceType> faces =
|
||||
{ CellFaceType::POS_I, CellFaceType::NEG_I, CellFaceType::POS_J, CellFaceType::NEG_J, CellFaceType::POS_K, CellFaceType::NEG_K };
|
||||
|
||||
std::vector<int> result( activeCellInfo->reservoirActiveCellCount(), 0 );
|
||||
for ( size_t reservoirIdx = 0; reservoirIdx < activeCellInfo->reservoirCellCount(); reservoirIdx++ )
|
||||
{
|
||||
ActiveCellIndex resultIdx = activeCellInfo->cellResultIndex( ReservoirCellIndex( reservoirIdx ) );
|
||||
if ( resultIdx.value() == cvf::UNDEFINED_SIZE_T ) continue;
|
||||
|
||||
for ( CellFaceType face : faces )
|
||||
{
|
||||
if ( mainGrid->findFaultFromCellIndexAndCellFace( reservoirIdx, face ) != nullptr ) result[resultIdx.value()]++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -442,6 +484,8 @@ std::vector<ReservoirCellIndex> RigWellTargetMappingTools::findCandidates( RimEc
|
||||
ActiveCellIndex neighborResultIndex = resultsData->activeCellInfo()->cellResultIndex( neighborResvCellIdx );
|
||||
if ( neighborResultIndex.value() != cvf::UNDEFINED_SIZE_T && clusters[neighborResultIndex.value()] == 0 )
|
||||
{
|
||||
if ( limits.avoidFaults && mainGrid->findFaultFromCellIndexAndCellFace( cellIdx.value(), face ) != nullptr ) continue;
|
||||
|
||||
double permeability = data.permeabilityX[neighborResultIndex.value()];
|
||||
double transmissibility = getTransmissibilityValueForFace( data.transmissibilityX,
|
||||
data.transmissibilityY,
|
||||
@@ -471,7 +515,8 @@ std::vector<ReservoirCellIndex> RigWellTargetMappingTools::findCandidates( RimEc
|
||||
for ( auto& [cellInfo, nncResultIdx] : nncCells )
|
||||
{
|
||||
auto& [otherCellIdx, face] = cellInfo;
|
||||
double transmissibility = data.transmissibilityNNC->at( nncResultIdx );
|
||||
if ( limits.avoidFaults && nncResultIdx < data.isFaultNnc.size() && data.isFaultNnc[nncResultIdx] ) continue;
|
||||
double transmissibility = data.transmissibilityNNC->at( nncResultIdx );
|
||||
|
||||
ActiveCellIndex otherResultIndex = resultsData->activeCellInfo()->cellResultIndex( otherCellIdx );
|
||||
if ( otherResultIndex.value() == cvf::UNDEFINED_SIZE_T ) continue;
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
std::vector<double> transmissibilityY;
|
||||
std::vector<double> transmissibilityZ;
|
||||
const std::vector<double>* transmissibilityNNC;
|
||||
std::vector<bool> isFaultNnc; // empty if fault barriers are not used
|
||||
};
|
||||
|
||||
class ClusterStatistics
|
||||
@@ -100,6 +101,9 @@ public:
|
||||
double pressure;
|
||||
};
|
||||
|
||||
static std::vector<bool> findFaultNncs( RigMainGrid* mainGrid );
|
||||
static std::vector<int> countFaultFacesPerActiveCell( const RigMainGrid* mainGrid, const RigActiveCellInfo* activeCellInfo );
|
||||
|
||||
static double getValueForFace( const std::vector<double>& x,
|
||||
const std::vector<double>& y,
|
||||
const std::vector<double>& z,
|
||||
|
||||
Reference in new issue
Block a user