mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
WIP: generate well target candidates statistics
This commit is contained in:
parent
53a31c88c9
commit
b5cde7e883
@ -33,6 +33,7 @@
|
|||||||
#include "RimTools.h"
|
#include "RimTools.h"
|
||||||
|
|
||||||
#include "cafPdmUiDoubleSliderEditor.h"
|
#include "cafPdmUiDoubleSliderEditor.h"
|
||||||
|
#include "cafPdmUiPushButtonEditor.h"
|
||||||
#include "cafPdmUiSliderTools.h"
|
#include "cafPdmUiSliderTools.h"
|
||||||
|
|
||||||
#include "cvfMath.h"
|
#include "cvfMath.h"
|
||||||
@ -79,6 +80,7 @@ RimWellTargetCandidatesGenerator::RimWellTargetCandidatesGenerator()
|
|||||||
{
|
{
|
||||||
CAF_PDM_InitObject( "Well Target Candidates Generator" );
|
CAF_PDM_InitObject( "Well Target Candidates Generator" );
|
||||||
|
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_targetCase, "TargetCase", "Target Case" );
|
||||||
CAF_PDM_InitField( &m_timeStep, "TimeStep", 0, "Time Step" );
|
CAF_PDM_InitField( &m_timeStep, "TimeStep", 0, "Time Step" );
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault( &m_volumeType, "VolumeType", "Volume" );
|
CAF_PDM_InitFieldNoDefault( &m_volumeType, "VolumeType", "Volume" );
|
||||||
@ -100,6 +102,9 @@ RimWellTargetCandidatesGenerator::RimWellTargetCandidatesGenerator()
|
|||||||
CAF_PDM_InitField( &m_maxIterations, "Iterations", 10000, "Max Iterations" );
|
CAF_PDM_InitField( &m_maxIterations, "Iterations", 10000, "Max Iterations" );
|
||||||
CAF_PDM_InitField( &m_maxClusters, "MaxClusters", 5, "Max Clusters" );
|
CAF_PDM_InitField( &m_maxClusters, "MaxClusters", 5, "Max Clusters" );
|
||||||
|
|
||||||
|
CAF_PDM_InitField( &m_generateEnsembleStatistics, "GenerateEnsembleStatistics", true, "Generate Ensemble Statistics" );
|
||||||
|
caf::PdmUiPushButtonEditor::configureEditorLabelHidden( &m_generateEnsembleStatistics );
|
||||||
|
|
||||||
m_minimumVolume = cvf::UNDEFINED_DOUBLE;
|
m_minimumVolume = cvf::UNDEFINED_DOUBLE;
|
||||||
m_maximumVolume = cvf::UNDEFINED_DOUBLE;
|
m_maximumVolume = cvf::UNDEFINED_DOUBLE;
|
||||||
|
|
||||||
@ -126,8 +131,12 @@ RimWellTargetCandidatesGenerator::~RimWellTargetCandidatesGenerator()
|
|||||||
void RimWellTargetCandidatesGenerator::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
void RimWellTargetCandidatesGenerator::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
||||||
{
|
{
|
||||||
updateAllBoundaries();
|
updateAllBoundaries();
|
||||||
|
generateCandidates( m_targetCase() );
|
||||||
|
|
||||||
generateCandidates();
|
if ( changedField == &m_generateEnsembleStatistics )
|
||||||
|
{
|
||||||
|
generateEnsembleStatistics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -137,7 +146,19 @@ QList<caf::PdmOptionItemInfo> RimWellTargetCandidatesGenerator::calculateValueOp
|
|||||||
{
|
{
|
||||||
QList<caf::PdmOptionItemInfo> options;
|
QList<caf::PdmOptionItemInfo> options;
|
||||||
|
|
||||||
if ( fieldNeedingOptions == &m_timeStep )
|
if ( fieldNeedingOptions == &m_targetCase )
|
||||||
|
{
|
||||||
|
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
||||||
|
if ( !ensemble ) return options;
|
||||||
|
|
||||||
|
if ( ensemble->cases().empty() ) return options;
|
||||||
|
|
||||||
|
for ( auto eclipseCase : ensemble->cases() )
|
||||||
|
{
|
||||||
|
options.push_back( caf::PdmOptionItemInfo( eclipseCase->caseUserDescription(), eclipseCase, false, eclipseCase->uiIconProvider() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( fieldNeedingOptions == &m_timeStep )
|
||||||
{
|
{
|
||||||
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
||||||
if ( ensemble && !ensemble->cases().empty() )
|
if ( ensemble && !ensemble->cases().empty() )
|
||||||
@ -257,29 +278,42 @@ void RimWellTargetCandidatesGenerator::defineEditorAttribute( const caf::PdmFiel
|
|||||||
doubleAttributes->m_decimals = 3;
|
doubleAttributes->m_decimals = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( field == &m_generateEnsembleStatistics )
|
||||||
|
{
|
||||||
|
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
||||||
|
if ( attrib )
|
||||||
|
{
|
||||||
|
attrib->m_buttonText = "Create Ensemble Statistics";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RimWellTargetCandidatesGenerator::generateCandidates()
|
void RimWellTargetCandidatesGenerator::generateCandidates( RimEclipseCase* eclipseCase )
|
||||||
|
{
|
||||||
|
RigWellTargetCandidatesGenerator::ClusteringLimits limits = getClusteringLimits();
|
||||||
|
RigWellTargetCandidatesGenerator::generateCandidates( eclipseCase, m_timeStep(), m_volumeType(), m_volumesType(), m_volumeResultType(), limits );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimWellTargetCandidatesGenerator::generateEnsembleStatistics()
|
||||||
{
|
{
|
||||||
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
||||||
if ( !ensemble ) return;
|
if ( !ensemble ) return;
|
||||||
|
|
||||||
if ( ensemble->cases().empty() ) return;
|
RigWellTargetCandidatesGenerator::ClusteringLimits limits = getClusteringLimits();
|
||||||
|
RigWellTargetCandidatesGenerator::generateEnsembleCandidates( *m_targetCase(),
|
||||||
RimEclipseCase* eclipseCase = ensemble->cases().front();
|
*ensemble,
|
||||||
|
m_timeStep(),
|
||||||
RigWellTargetCandidatesGenerator::ClusteringLimits limits;
|
m_volumeType(),
|
||||||
limits.volume = m_volume;
|
m_volumesType(),
|
||||||
limits.permeability = m_permeability;
|
m_volumeResultType(),
|
||||||
limits.pressure = m_pressure;
|
limits );
|
||||||
limits.transmissibility = m_transmissibility;
|
|
||||||
limits.maxClusters = m_maxClusters;
|
|
||||||
limits.maxIterations = m_maxIterations;
|
|
||||||
|
|
||||||
RigWellTargetCandidatesGenerator::generateCandidates( eclipseCase, m_timeStep(), m_volumeType(), m_volumesType(), m_volumeResultType(), limits );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -294,3 +328,16 @@ void RimWellTargetCandidatesGenerator::defineUiOrdering( QString uiConfigName, c
|
|||||||
updateAllBoundaries();
|
updateAllBoundaries();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RigWellTargetCandidatesGenerator::ClusteringLimits RimWellTargetCandidatesGenerator::getClusteringLimits() const
|
||||||
|
{
|
||||||
|
RigWellTargetCandidatesGenerator::ClusteringLimits limits;
|
||||||
|
limits.volume = m_volume;
|
||||||
|
limits.permeability = m_permeability;
|
||||||
|
limits.pressure = m_pressure;
|
||||||
|
limits.transmissibility = m_transmissibility;
|
||||||
|
limits.maxClusters = m_maxClusters;
|
||||||
|
limits.maxIterations = m_maxIterations;
|
||||||
|
|
||||||
|
return limits;
|
||||||
|
}
|
||||||
|
@ -21,9 +21,12 @@
|
|||||||
#include "cafAppEnum.h"
|
#include "cafAppEnum.h"
|
||||||
#include "cafPdmField.h"
|
#include "cafPdmField.h"
|
||||||
#include "cafPdmObject.h"
|
#include "cafPdmObject.h"
|
||||||
|
#include "cafPdmPtrField.h"
|
||||||
|
|
||||||
#include "Well/RigWellTargetCandidatesGenerator.h"
|
#include "Well/RigWellTargetCandidatesGenerator.h"
|
||||||
|
|
||||||
|
class RimEclipseCase;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -43,10 +46,14 @@ protected:
|
|||||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generateCandidates();
|
void generateCandidates( RimEclipseCase* eclipseCase );
|
||||||
void updateAllBoundaries();
|
void updateAllBoundaries();
|
||||||
|
void generateEnsembleStatistics();
|
||||||
|
|
||||||
caf::PdmField<int> m_timeStep;
|
RigWellTargetCandidatesGenerator::ClusteringLimits getClusteringLimits() const;
|
||||||
|
|
||||||
|
caf::PdmPtrField<RimEclipseCase*> m_targetCase;
|
||||||
|
caf::PdmField<int> m_timeStep;
|
||||||
|
|
||||||
caf::PdmField<caf::AppEnum<RigWellTargetCandidatesGenerator::VolumeType>> m_volumeType;
|
caf::PdmField<caf::AppEnum<RigWellTargetCandidatesGenerator::VolumeType>> m_volumeType;
|
||||||
caf::PdmField<caf::AppEnum<RigWellTargetCandidatesGenerator::VolumeResultType>> m_volumeResultType;
|
caf::PdmField<caf::AppEnum<RigWellTargetCandidatesGenerator::VolumeResultType>> m_volumeResultType;
|
||||||
@ -57,8 +64,9 @@ private:
|
|||||||
caf::PdmField<double> m_permeability;
|
caf::PdmField<double> m_permeability;
|
||||||
caf::PdmField<double> m_transmissibility;
|
caf::PdmField<double> m_transmissibility;
|
||||||
|
|
||||||
caf::PdmField<int> m_maxIterations;
|
caf::PdmField<int> m_maxIterations;
|
||||||
caf::PdmField<int> m_maxClusters;
|
caf::PdmField<int> m_maxClusters;
|
||||||
|
caf::PdmField<bool> m_generateEnsembleStatistics;
|
||||||
|
|
||||||
double m_minimumVolume;
|
double m_minimumVolume;
|
||||||
double m_maximumVolume;
|
double m_maximumVolume;
|
||||||
|
@ -602,3 +602,53 @@ std::vector<RigWellTargetCandidatesGenerator::ClusterStatistics>
|
|||||||
|
|
||||||
return statistics;
|
return statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigWellTargetCandidatesGenerator::generateEnsembleCandidates( RimEclipseCase& targetCase,
|
||||||
|
RimEclipseCaseEnsemble& ensemble,
|
||||||
|
size_t timeStepIdx,
|
||||||
|
VolumeType volumeType,
|
||||||
|
VolumesType volumesType,
|
||||||
|
VolumeResultType volumeResultType,
|
||||||
|
const ClusteringLimits& limits )
|
||||||
|
{
|
||||||
|
for ( auto eclipseCase : ensemble.cases() )
|
||||||
|
{
|
||||||
|
generateCandidates( eclipseCase, timeStepIdx, volumeType, volumesType, volumeResultType, limits );
|
||||||
|
}
|
||||||
|
|
||||||
|
const RigCaseCellResultsData* targetResultsData = targetCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||||
|
const RigActiveCellInfo* targetActiveCellInfo = targetResultsData->activeCellInfo();
|
||||||
|
|
||||||
|
const size_t targetNumReservoirCells = targetActiveCellInfo->reservoirCellCount();
|
||||||
|
const size_t targetNumActiveCells = targetActiveCellInfo->reservoirActiveCellCount();
|
||||||
|
const int numGrids = ensemble.cases().size();
|
||||||
|
|
||||||
|
std::vector<int> occupancy( targetNumActiveCells, 0 );
|
||||||
|
std::vector<double> pressure( numGrids, std::numeric_limits<double>::infinity() );
|
||||||
|
for ( auto eclipseCase : ensemble.cases() )
|
||||||
|
{
|
||||||
|
const RigCaseCellResultsData* resultsData = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||||
|
const RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||||
|
const RigActiveCellInfo* activeCellInfo = resultsData->activeCellInfo();
|
||||||
|
|
||||||
|
std::vector<double> clusterNum;
|
||||||
|
for ( size_t targetCellIdx = 0; targetCellIdx < targetNumReservoirCells; targetCellIdx++ )
|
||||||
|
{
|
||||||
|
const RigCell& nativeCell = targetCase.mainGrid()->globalCellArray()[targetCellIdx];
|
||||||
|
cvf::Vec3d cellCenter = nativeCell.center();
|
||||||
|
|
||||||
|
size_t cellIdx = mainGrid->findReservoirCellIndexFromPoint( cellCenter );
|
||||||
|
if ( cellIdx != cvf::UNDEFINED_SIZE_T && activeCellInfo->isActive( cellIdx ) )
|
||||||
|
{
|
||||||
|
size_t resultIndex = targetResultsData->activeCellInfo()->cellResultIndex( cellIdx );
|
||||||
|
if ( clusterNum[resultIndex] > 0 )
|
||||||
|
{
|
||||||
|
occupancy[resultIndex]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
class RigActiveCellInfo;
|
class RigActiveCellInfo;
|
||||||
class RigCaseCellResultsData;
|
class RigCaseCellResultsData;
|
||||||
class RimEclipseCase;
|
class RimEclipseCase;
|
||||||
|
class RimEclipseCaseEnsemble;
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -77,6 +78,14 @@ public:
|
|||||||
VolumeResultType volumeResultType,
|
VolumeResultType volumeResultType,
|
||||||
size_t timeStepIdx );
|
size_t timeStepIdx );
|
||||||
|
|
||||||
|
static void generateEnsembleCandidates( RimEclipseCase& targetCase,
|
||||||
|
RimEclipseCaseEnsemble& ensemble,
|
||||||
|
size_t timeStepIdx,
|
||||||
|
VolumeType volumeType,
|
||||||
|
VolumesType volumesType,
|
||||||
|
VolumeResultType volumeResultType,
|
||||||
|
const ClusteringLimits& limits );
|
||||||
|
|
||||||
class ClusterStatistics
|
class ClusterStatistics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user