mirror of
https://github.com/OPM/ResInsight.git
synced 2024-12-28 01:41:42 -06:00
Generate well target candidates statistics for ensembles.
This commit is contained in:
parent
4f3b7d2675
commit
fb90844901
@ -102,6 +102,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifAsciiDataParseOptions.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifByteArrayArrowRandomAccessFile.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifArrowTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderRegularGridModel.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -201,6 +202,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifOsduWellLogReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifByteArrayArrowRandomAccessFile.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifArrowTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderRegularGridModel.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
@ -0,0 +1,94 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024- 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 "RifReaderRegularGridModel.h"
|
||||
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderRegularGridModel::RifReaderRegularGridModel()
|
||||
: m_reservoir( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderRegularGridModel::~RifReaderRegularGridModel()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderRegularGridModel::open( const QString& fileName, RigEclipseCaseData* eclipseCase )
|
||||
{
|
||||
m_reservoirBuilder.createGridsAndCells( eclipseCase );
|
||||
m_reservoir = eclipseCase;
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderRegularGridModel::staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector<double>* values )
|
||||
{
|
||||
CAF_ASSERT( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderRegularGridModel::dynamicResult( const QString& result,
|
||||
RiaDefines::PorosityModelType matrixOrFracture,
|
||||
size_t stepIndex,
|
||||
std::vector<double>* values )
|
||||
{
|
||||
CAF_ASSERT( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderRegularGridModel::setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate )
|
||||
{
|
||||
m_reservoirBuilder.setWorldCoordinates( minWorldCoordinate, maxWorldCoordinate );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderRegularGridModel::setGridPointDimensions( const cvf::Vec3st& gridPointDimensions )
|
||||
{
|
||||
m_reservoirBuilder.setIJKCount( gridPointDimensions );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderRegularGridModel::addLocalGridRefinement( const cvf::Vec3st& minCellPosition,
|
||||
const cvf::Vec3st& maxCellPosition,
|
||||
const cvf::Vec3st& singleCellRefinementFactors )
|
||||
{
|
||||
m_reservoirBuilder.addLocalGridRefinement( minCellPosition, maxCellPosition, singleCellRefinementFactors );
|
||||
}
|
45
ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h
Normal file
45
ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h
Normal file
@ -0,0 +1,45 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024- 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifReaderInterface.h"
|
||||
#include "RigReservoirBuilder.h"
|
||||
|
||||
class RifReaderRegularGridModel : public RifReaderInterface
|
||||
{
|
||||
public:
|
||||
RifReaderRegularGridModel();
|
||||
~RifReaderRegularGridModel() override;
|
||||
|
||||
void setWorldCoordinates( cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate );
|
||||
void setGridPointDimensions( const cvf::Vec3st& gridPointDimensions );
|
||||
|
||||
void addLocalGridRefinement( const cvf::Vec3st& minCellPosition,
|
||||
const cvf::Vec3st& maxCellPosition,
|
||||
const cvf::Vec3st& singleCellRefinementFactors );
|
||||
|
||||
bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) override;
|
||||
|
||||
bool staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector<double>* values ) override;
|
||||
bool dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values ) override;
|
||||
|
||||
private:
|
||||
RigReservoirBuilder m_reservoirBuilder;
|
||||
RigEclipseCaseData* m_reservoir;
|
||||
};
|
@ -137,6 +137,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimStatisticsContourMap.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimStatisticsContourMapProjection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimStatisticsContourMapView.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRegularGridCase.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -274,6 +275,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimStatisticsContourMap.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimStatisticsContourMapProjection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimStatisticsContourMapView.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRegularGridCase.cpp
|
||||
)
|
||||
|
||||
if(RESINSIGHT_USE_QT_CHARTS)
|
||||
|
86
ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp
Normal file
86
ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024- 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 "RimRegularGridCase.h"
|
||||
|
||||
#include "RifReaderRegularGridModel.h"
|
||||
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimRegularGridCase, "EclipseBoundingBoxCase" );
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularGridCase::RimRegularGridCase()
|
||||
{
|
||||
CAF_PDM_InitObject( "Bounding Box Case", ":/Case48x48.png", "", "Bounding Box Case" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_minimum, "Minimum", "Minimum" );
|
||||
m_minimum.uiCapability()->setUiReadOnly( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_maximum, "Maximum", "Maximum" );
|
||||
m_maximum.uiCapability()->setUiReadOnly( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RimRegularGridCase::setBoundingBox( const cvf::BoundingBox& boundingBox )
|
||||
{
|
||||
m_minimum = boundingBox.min();
|
||||
m_maximum = boundingBox.max();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<RifReaderInterface> RimRegularGridCase::createModel( QString modelName )
|
||||
{
|
||||
cvf::ref<RifReaderRegularGridModel> reader = new RifReaderRegularGridModel;
|
||||
cvf::ref<RigEclipseCaseData> reservoir = new RigEclipseCaseData( this );
|
||||
|
||||
reader->setWorldCoordinates( m_minimum, m_maximum );
|
||||
|
||||
cvf::Vec3st gridPointDimensions( 50, 50, 10 );
|
||||
reader->setGridPointDimensions( gridPointDimensions );
|
||||
|
||||
reader->open( "", reservoir.p() );
|
||||
|
||||
setReservoirData( reservoir.p() );
|
||||
|
||||
return reader.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimRegularGridCase::openEclipseGridFile()
|
||||
{
|
||||
if ( eclipseCaseData() ) return true;
|
||||
|
||||
auto readerInterface = createModel( "" );
|
||||
|
||||
results( RiaDefines::PorosityModelType::MATRIX_MODEL )->setReaderInterface( readerInterface.p() );
|
||||
results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->setReaderInterface( readerInterface.p() );
|
||||
|
||||
computeCachedData();
|
||||
|
||||
return true;
|
||||
}
|
49
ApplicationLibCode/ProjectDataModel/RimRegularGridCase.h
Normal file
49
ApplicationLibCode/ProjectDataModel/RimRegularGridCase.h
Normal file
@ -0,0 +1,49 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024- 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include "RimEclipseResultCase.h"
|
||||
|
||||
#include "cafPdmFieldCvfVec3d.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RimRegularGridCase : public RimEclipseResultCase
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimRegularGridCase();
|
||||
|
||||
void setBoundingBox( const cvf::BoundingBox& boundingBox );
|
||||
|
||||
bool openEclipseGridFile() override;
|
||||
|
||||
cvf::ref<RifReaderInterface> createModel( QString modelName );
|
||||
|
||||
private:
|
||||
caf::PdmField<cvf::Vec3d> m_minimum;
|
||||
caf::PdmField<cvf::Vec3d> m_maximum;
|
||||
};
|
@ -18,21 +18,29 @@
|
||||
|
||||
#include "RimWellTargetCandidatesGenerator.h"
|
||||
|
||||
#include "RiaGuiApplication.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPorosityModel.h"
|
||||
#include "RiaResultNames.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseResultAddress.h"
|
||||
#include "Well/RigWellTargetCandidatesGenerator.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCaseCollection.h"
|
||||
#include "RimEclipseCaseEnsemble.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRegularGridCase.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
#include "cafPdmUiSliderTools.h"
|
||||
|
||||
#include "cvfMath.h"
|
||||
@ -100,6 +108,9 @@ RimWellTargetCandidatesGenerator::RimWellTargetCandidatesGenerator()
|
||||
CAF_PDM_InitField( &m_maxIterations, "Iterations", 10000, "Max Iterations" );
|
||||
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_maximumVolume = cvf::UNDEFINED_DOUBLE;
|
||||
|
||||
@ -126,8 +137,12 @@ RimWellTargetCandidatesGenerator::~RimWellTargetCandidatesGenerator()
|
||||
void RimWellTargetCandidatesGenerator::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
||||
{
|
||||
updateAllBoundaries();
|
||||
generateCandidates( firstCase() );
|
||||
|
||||
generateCandidates();
|
||||
if ( changedField == &m_generateEnsembleStatistics )
|
||||
{
|
||||
generateEnsembleStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -139,12 +154,9 @@ QList<caf::PdmOptionItemInfo> RimWellTargetCandidatesGenerator::calculateValueOp
|
||||
|
||||
if ( fieldNeedingOptions == &m_timeStep )
|
||||
{
|
||||
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
||||
if ( ensemble && !ensemble->cases().empty() )
|
||||
if ( auto fc = firstCase() )
|
||||
{
|
||||
RimEclipseCase* eclipseCase = ensemble->cases().front();
|
||||
|
||||
RimTools::timeStepsForCase( eclipseCase, &options );
|
||||
RimTools::timeStepsForCase( fc, &options );
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,29 +269,61 @@ void RimWellTargetCandidatesGenerator::defineEditorAttribute( const caf::PdmFiel
|
||||
doubleAttributes->m_decimals = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if ( field == &m_generateEnsembleStatistics )
|
||||
{
|
||||
if ( auto attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute ) )
|
||||
{
|
||||
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>();
|
||||
if ( !ensemble ) return;
|
||||
|
||||
if ( ensemble->cases().empty() ) return;
|
||||
RigWellTargetCandidatesGenerator::ClusteringLimits limits = getClusteringLimits();
|
||||
RimRegularGridCase* regularGridCase = RigWellTargetCandidatesGenerator::generateEnsembleCandidates( *ensemble,
|
||||
m_timeStep(),
|
||||
m_volumeType(),
|
||||
m_volumesType(),
|
||||
m_volumeResultType(),
|
||||
limits );
|
||||
|
||||
RimEclipseCase* eclipseCase = ensemble->cases().front();
|
||||
RimProject* project = RimProject::current();
|
||||
if ( !project ) return;
|
||||
|
||||
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;
|
||||
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels() : nullptr;
|
||||
if ( !analysisModels ) return;
|
||||
|
||||
RigWellTargetCandidatesGenerator::generateCandidates( eclipseCase, m_timeStep(), m_volumeType(), m_volumesType(), m_volumeResultType(), limits );
|
||||
analysisModels->cases.push_back( regularGridCase );
|
||||
|
||||
auto eclipseView = regularGridCase->createAndAddReservoirView();
|
||||
|
||||
eclipseView->cellResult()->setResultType( RiaDefines::ResultCatType::GENERATED );
|
||||
|
||||
if ( RiaGuiApplication::isRunning() || RiuMainWindow::instance() )
|
||||
{
|
||||
RiuMainWindow::instance()->selectAsCurrentItem( eclipseView->cellResult() );
|
||||
}
|
||||
|
||||
eclipseView->loadDataAndUpdate();
|
||||
|
||||
analysisModels->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -294,3 +338,26 @@ void RimWellTargetCandidatesGenerator::defineUiOrdering( QString uiConfigName, c
|
||||
updateAllBoundaries();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellTargetCandidatesGenerator::ClusteringLimits RimWellTargetCandidatesGenerator::getClusteringLimits() const
|
||||
{
|
||||
return { .volume = m_volume,
|
||||
.permeability = m_permeability,
|
||||
.pressure = m_pressure,
|
||||
.transmissibility = m_transmissibility,
|
||||
.maxClusters = m_maxClusters,
|
||||
.maxIterations = m_maxIterations };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase* RimWellTargetCandidatesGenerator::firstCase() const
|
||||
{
|
||||
auto ensemble = firstAncestorOrThisOfType<RimEclipseCaseEnsemble>();
|
||||
if ( !ensemble || ensemble->cases().empty() ) return nullptr;
|
||||
return ensemble->cases()[0];
|
||||
}
|
||||
|
@ -21,9 +21,12 @@
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include "Well/RigWellTargetCandidatesGenerator.h"
|
||||
|
||||
class RimEclipseCase;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
@ -43,8 +46,13 @@ protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
private:
|
||||
void generateCandidates();
|
||||
void generateCandidates( RimEclipseCase* eclipseCase );
|
||||
void updateAllBoundaries();
|
||||
void generateEnsembleStatistics();
|
||||
|
||||
RimEclipseCase* firstCase() const;
|
||||
|
||||
RigWellTargetCandidatesGenerator::ClusteringLimits getClusteringLimits() const;
|
||||
|
||||
caf::PdmField<int> m_timeStep;
|
||||
|
||||
@ -57,8 +65,9 @@ private:
|
||||
caf::PdmField<double> m_permeability;
|
||||
caf::PdmField<double> m_transmissibility;
|
||||
|
||||
caf::PdmField<int> m_maxIterations;
|
||||
caf::PdmField<int> m_maxClusters;
|
||||
caf::PdmField<int> m_maxIterations;
|
||||
caf::PdmField<int> m_maxClusters;
|
||||
caf::PdmField<bool> m_generateEnsembleStatistics;
|
||||
|
||||
double m_minimumVolume;
|
||||
double m_maximumVolume;
|
||||
|
@ -27,16 +27,20 @@
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseResultAddress.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCaseEnsemble.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimPropertyFilterCollection.h"
|
||||
#include "RimRegularGridCase.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafProgressInfo.h"
|
||||
#include "cafVecIjk.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfMath.h"
|
||||
#include "cvfStructGrid.h"
|
||||
|
||||
@ -53,6 +57,8 @@ void RigWellTargetCandidatesGenerator::generateCandidates( RimEclipseCase*
|
||||
VolumeResultType volumeResultType,
|
||||
const ClusteringLimits& limits )
|
||||
{
|
||||
if ( !eclipseCase->ensureReservoirCaseIsOpen() ) return;
|
||||
|
||||
auto activeCellCount = getActiveCellCount( eclipseCase );
|
||||
if ( !activeCellCount )
|
||||
{
|
||||
@ -174,6 +180,22 @@ void RigWellTargetCandidatesGenerator::generateCandidates( RimEclipseCase*
|
||||
|
||||
std::vector<ClusterStatistics> statistics =
|
||||
generateStatistics( eclipseCase, pressure, permeabilityX, permeabilityY, permeabilityZ, numClustersFound, timeStepIdx, resultName );
|
||||
std::vector<double> totalPorvSoil( clusters.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> totalPorvSgas( clusters.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> totalPorvSoilAndSgas( clusters.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> totalFipOil( clusters.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> totalFipGas( clusters.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
auto addValuesForClusterId = []( std::vector<double>& values, const std::vector<int>& clusters, int clusterId, double value )
|
||||
{
|
||||
#pragma omp parallel for
|
||||
for ( int i = 0; i < static_cast<int>( clusters.size() ); i++ )
|
||||
{
|
||||
if ( clusters[i] == clusterId ) values[i] = value;
|
||||
}
|
||||
};
|
||||
|
||||
int clusterId = 1;
|
||||
for ( auto s : statistics )
|
||||
{
|
||||
RiaLogging::info( QString( "Cluster #%1 Statistics" ).arg( s.id ) );
|
||||
@ -185,7 +207,30 @@ void RigWellTargetCandidatesGenerator::generateCandidates( RimEclipseCase*
|
||||
RiaLogging::info( QString( "Total FIPGAS: %1" ).arg( s.totalFipGas ) );
|
||||
RiaLogging::info( QString( "Average Permeability: %1" ).arg( s.permeability ) );
|
||||
RiaLogging::info( QString( "Average Pressure: %1" ).arg( s.pressure ) );
|
||||
|
||||
addValuesForClusterId( totalPorvSoil, clusters, clusterId, s.totalPorvSoil );
|
||||
addValuesForClusterId( totalPorvSgas, clusters, clusterId, s.totalPorvSgas );
|
||||
addValuesForClusterId( totalPorvSoilAndSgas, clusters, clusterId, s.totalPorvSoilAndSgas );
|
||||
addValuesForClusterId( totalFipOil, clusters, clusterId, s.totalFipOil );
|
||||
addValuesForClusterId( totalFipGas, clusters, clusterId, s.totalFipGas );
|
||||
|
||||
clusterId++;
|
||||
}
|
||||
|
||||
QString clusterPorvSoil = "TOTAL_PORV_SOIL";
|
||||
createResultVector( *eclipseCase, clusterPorvSoil, totalPorvSoil );
|
||||
|
||||
QString clusterPorvSgas = "TOTAL_PORV_SGAS";
|
||||
createResultVector( *eclipseCase, clusterPorvSgas, totalPorvSgas );
|
||||
|
||||
QString clusterPorvSoilAndSgas = "TOTAL_PORV_SOIL_SGAS";
|
||||
createResultVector( *eclipseCase, clusterPorvSoilAndSgas, totalPorvSoilAndSgas );
|
||||
|
||||
QString clusterFipOil = "TOTAL_FIPOIL";
|
||||
createResultVector( *eclipseCase, clusterFipOil, totalFipOil );
|
||||
|
||||
QString clusterFipGas = "TOTAL_FIPGAS";
|
||||
createResultVector( *eclipseCase, clusterFipGas, totalFipGas );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -401,6 +446,55 @@ void RigWellTargetCandidatesGenerator::createResultVector( RimEclipseCase&
|
||||
resultsData->recalculateStatistics( resultAddress );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellTargetCandidatesGenerator::createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<double>& values )
|
||||
{
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::GENERATED, resultName );
|
||||
|
||||
auto resultsData = eclipseCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
|
||||
resultsData->addStaticScalarResult( RiaDefines::ResultCatType::GENERATED, resultName, false, values.size() );
|
||||
|
||||
std::vector<double>* resultVector = resultsData->modifiableCellScalarResult( resultAddress, 0 );
|
||||
resultVector->resize( values.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
std::copy( values.begin(), values.end(), resultVector->begin() );
|
||||
|
||||
resultsData->recalculateStatistics( resultAddress );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellTargetCandidatesGenerator::createResultVector( RimEclipseCase& eclipseCase,
|
||||
const QString& resultName,
|
||||
const std::vector<int>& clusterIds,
|
||||
double value )
|
||||
{
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::GENERATED, resultName );
|
||||
|
||||
auto resultsData = eclipseCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
|
||||
resultsData->addStaticScalarResult( RiaDefines::ResultCatType::GENERATED, resultName, false, clusterIds.size() );
|
||||
|
||||
std::vector<double>* resultVector = resultsData->modifiableCellScalarResult( resultAddress, 0 );
|
||||
resultVector->resize( clusterIds.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
std::fill( resultVector->begin(), resultVector->end(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
for ( size_t idx = 0; idx < clusterIds.size(); idx++ )
|
||||
{
|
||||
if ( clusterIds[idx] > 0 )
|
||||
{
|
||||
resultVector->at( idx ) = value;
|
||||
}
|
||||
}
|
||||
|
||||
resultsData->recalculateStatistics( resultAddress );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -602,3 +696,223 @@ std::vector<RigWellTargetCandidatesGenerator::ClusterStatistics>
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularGridCase* RigWellTargetCandidatesGenerator::generateEnsembleCandidates( RimEclipseCaseEnsemble& ensemble,
|
||||
size_t timeStepIdx,
|
||||
VolumeType volumeType,
|
||||
VolumesType volumesType,
|
||||
VolumeResultType volumeResultType,
|
||||
const ClusteringLimits& limits )
|
||||
{
|
||||
RiaLogging::debug( "Generating ensemble statistics" );
|
||||
|
||||
caf::ProgressInfo progInfo( ensemble.cases().size() * 2, "Generating ensemble statistics" );
|
||||
|
||||
for ( auto eclipseCase : ensemble.cases() )
|
||||
{
|
||||
auto task = progInfo.task( "Generating realization statistics.", 1 );
|
||||
|
||||
generateCandidates( eclipseCase, timeStepIdx, volumeType, volumesType, volumeResultType, limits );
|
||||
}
|
||||
|
||||
cvf::BoundingBox boundingBox;
|
||||
for ( auto eclipseCase : ensemble.cases() )
|
||||
{
|
||||
cvf::BoundingBox bb = computeBoundingBoxForResult( *eclipseCase, "CLUSTERS_NUM", 0 );
|
||||
boundingBox.add( bb );
|
||||
}
|
||||
|
||||
RiaLogging::debug(
|
||||
QString( "Clusters bounding box min: [%1 %2 %3]" ).arg( boundingBox.min().x() ).arg( boundingBox.min().y() ).arg( boundingBox.min().z() ) );
|
||||
RiaLogging::debug(
|
||||
QString( "Clusters bounding box max: [%1 %2 %3]" ).arg( boundingBox.max().x() ).arg( boundingBox.max().y() ).arg( boundingBox.max().z() ) );
|
||||
|
||||
RimRegularGridCase* targetCase = new RimRegularGridCase;
|
||||
targetCase->setBoundingBox( boundingBox );
|
||||
targetCase->createModel( "" );
|
||||
|
||||
std::vector<int> occupancy;
|
||||
|
||||
std::map<QString, std::vector<std::vector<double>>> resultNamesAndSamples;
|
||||
resultNamesAndSamples["TOTAL_PORV_SOIL"] = {};
|
||||
resultNamesAndSamples["TOTAL_PORV_SGAS"] = {};
|
||||
resultNamesAndSamples["TOTAL_PORV_SOIL_SGAS"] = {};
|
||||
resultNamesAndSamples["TOTAL_FIPOIL"] = {};
|
||||
resultNamesAndSamples["TOTAL_FIPGAS"] = {};
|
||||
|
||||
for ( auto eclipseCase : ensemble.cases() )
|
||||
{
|
||||
auto task = progInfo.task( "Accumulating results.", 1 );
|
||||
|
||||
accumulateResultsForSingleCase( *eclipseCase, *targetCase, resultNamesAndSamples, occupancy );
|
||||
}
|
||||
|
||||
createResultVector( *targetCase, "OCCUPANCY", occupancy );
|
||||
|
||||
for ( auto [resultName, vec] : resultNamesAndSamples )
|
||||
{
|
||||
computeStatisticsAndCreateVectors( *targetCase, resultName, vec );
|
||||
}
|
||||
|
||||
return targetCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellTargetCandidatesGenerator::computeStatisticsAndCreateVectors( RimEclipseCase& targetCase,
|
||||
const QString& resultName,
|
||||
const std::vector<std::vector<double>>& vec )
|
||||
{
|
||||
const RigCaseCellResultsData* targetResultsData = targetCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
if ( !targetResultsData ) return;
|
||||
|
||||
const RigActiveCellInfo* targetActiveCellInfo = targetResultsData->activeCellInfo();
|
||||
if ( !targetActiveCellInfo ) return;
|
||||
|
||||
const size_t targetNumActiveCells = targetActiveCellInfo->reservoirActiveCellCount();
|
||||
|
||||
int nCells = static_cast<int>( targetNumActiveCells );
|
||||
std::vector<double> p10Results( nCells, std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> p50Results( nCells, std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> p90Results( nCells, std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> meanResults( nCells, std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> minResults( nCells, std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> maxResults( nCells, std::numeric_limits<double>::infinity() );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int i = 0; i < nCells; i++ )
|
||||
{
|
||||
size_t numSamples = vec.size();
|
||||
std::vector<double> samples( numSamples, 0.0 );
|
||||
for ( size_t s = 0; s < numSamples; s++ )
|
||||
samples[s] = vec[s][i];
|
||||
|
||||
double p10, p50, p90, mean;
|
||||
RigStatisticsMath::calculateStatisticsCurves( samples, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
|
||||
if ( RiaStatisticsTools::isValidNumber( p10 ) ) p10Results[i] = p10;
|
||||
if ( RiaStatisticsTools::isValidNumber( p50 ) ) p50Results[i] = p50;
|
||||
if ( RiaStatisticsTools::isValidNumber( p90 ) ) p90Results[i] = p90;
|
||||
if ( RiaStatisticsTools::isValidNumber( mean ) ) meanResults[i] = mean;
|
||||
|
||||
double minValue = RiaStatisticsTools::minimumValue( samples );
|
||||
if ( RiaStatisticsTools::isValidNumber( minValue ) && minValue < std::numeric_limits<double>::max() ) minResults[i] = minValue;
|
||||
|
||||
double maxValue = RiaStatisticsTools::maximumValue( samples );
|
||||
if ( RiaStatisticsTools::isValidNumber( maxValue ) && maxValue > -std::numeric_limits<double>::max() ) maxResults[i] = maxValue;
|
||||
}
|
||||
|
||||
createResultVector( targetCase, "ENSEMBLE_" + resultName + "_P10", p10Results );
|
||||
createResultVector( targetCase, "ENSEMBLE_" + resultName + "_P50", p50Results );
|
||||
createResultVector( targetCase, "ENSEMBLE_" + resultName + "_P90", p90Results );
|
||||
createResultVector( targetCase, "ENSEMBLE_" + resultName + "_MEAN", meanResults );
|
||||
createResultVector( targetCase, "ENSEMBLE_" + resultName + "_MIN", minResults );
|
||||
createResultVector( targetCase, "ENSEMBLE_" + resultName + "_MAX", maxResults );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellTargetCandidatesGenerator::accumulateResultsForSingleCase( RimEclipseCase& eclipseCase,
|
||||
RimEclipseCase& targetCase,
|
||||
std::map<QString, std::vector<std::vector<double>>>& resultNamesAndSamples,
|
||||
std::vector<int>& occupancy )
|
||||
{
|
||||
RigCaseCellResultsData* resultsData = eclipseCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
if ( !resultsData ) return;
|
||||
const RigMainGrid* mainGrid = eclipseCase.mainGrid();
|
||||
if ( !mainGrid ) return;
|
||||
const RigActiveCellInfo* activeCellInfo = resultsData->activeCellInfo();
|
||||
if ( !activeCellInfo ) return;
|
||||
|
||||
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();
|
||||
|
||||
occupancy.resize( targetNumActiveCells, 0 );
|
||||
|
||||
RigEclipseResultAddress clustersNumAddress( RiaDefines::ResultCatType::GENERATED, "CLUSTERS_NUM" );
|
||||
resultsData->ensureKnownResultLoaded( clustersNumAddress );
|
||||
const std::vector<double>& clusterNum = resultsData->cellScalarResults( clustersNumAddress, 0 );
|
||||
|
||||
std::map<QString, const std::vector<double>*> namedInputVector;
|
||||
|
||||
for ( auto [resultName, vec] : resultNamesAndSamples )
|
||||
{
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::GENERATED, resultName );
|
||||
resultsData->ensureKnownResultLoaded( resultAddress );
|
||||
const std::vector<double>& resultVector = resultsData->cellScalarResults( resultAddress, 0 );
|
||||
namedInputVector[resultName] = &resultVector;
|
||||
}
|
||||
|
||||
std::map<QString, std::vector<double>> namedOutputVector;
|
||||
for ( auto [resultName, vec] : resultNamesAndSamples )
|
||||
{
|
||||
namedOutputVector[resultName] = std::vector( targetNumActiveCells, std::numeric_limits<double>::infinity() );
|
||||
}
|
||||
|
||||
for ( size_t targetCellIdx = 0; targetCellIdx < targetNumReservoirCells; targetCellIdx++ )
|
||||
{
|
||||
const RigCell& nativeCell = targetCase.mainGrid()->cell( targetCellIdx );
|
||||
cvf::Vec3d cellCenter = nativeCell.center();
|
||||
|
||||
size_t targetResultIndex = targetActiveCellInfo->cellResultIndex( targetCellIdx );
|
||||
|
||||
size_t cellIdx = mainGrid->findReservoirCellIndexFromPoint( cellCenter );
|
||||
if ( cellIdx != cvf::UNDEFINED_SIZE_T && activeCellInfo->isActive( cellIdx ) && targetResultIndex != cvf::UNDEFINED_SIZE_T )
|
||||
{
|
||||
size_t resultIndex = resultsData->activeCellInfo()->cellResultIndex( cellIdx );
|
||||
if ( !std::isinf( clusterNum[resultIndex] ) && clusterNum[resultIndex] > 0 )
|
||||
{
|
||||
occupancy[targetResultIndex]++;
|
||||
for ( auto [resultName, vec] : resultNamesAndSamples )
|
||||
{
|
||||
namedOutputVector[resultName][targetResultIndex] = namedInputVector[resultName]->at( resultIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto [resultName, vec] : resultNamesAndSamples )
|
||||
{
|
||||
resultNamesAndSamples[resultName].push_back( namedOutputVector[resultName] );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::BoundingBox RigWellTargetCandidatesGenerator::computeBoundingBoxForResult( RimEclipseCase& eclipseCase,
|
||||
const QString& resultName,
|
||||
size_t timeStepIndex )
|
||||
{
|
||||
RigCaseCellResultsData* resultsData = eclipseCase.results( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
const RigMainGrid* mainGrid = eclipseCase.mainGrid();
|
||||
const RigActiveCellInfo* activeCellInfo = resultsData->activeCellInfo();
|
||||
const size_t numReservoirCells = activeCellInfo->reservoirCellCount();
|
||||
|
||||
RigEclipseResultAddress clustersNumAddress( RiaDefines::ResultCatType::GENERATED, resultName );
|
||||
resultsData->ensureKnownResultLoaded( clustersNumAddress );
|
||||
const std::vector<double>& clusterNum = resultsData->cellScalarResults( clustersNumAddress, timeStepIndex );
|
||||
|
||||
cvf::BoundingBox boundingBox;
|
||||
for ( size_t reservoirCellIndex = 0; reservoirCellIndex < numReservoirCells; reservoirCellIndex++ )
|
||||
{
|
||||
size_t targetResultIndex = activeCellInfo->cellResultIndex( reservoirCellIndex );
|
||||
if ( reservoirCellIndex != cvf::UNDEFINED_SIZE_T && activeCellInfo->isActive( reservoirCellIndex ) &&
|
||||
targetResultIndex != cvf::UNDEFINED_SIZE_T && !std::isinf( clusterNum[targetResultIndex] ) && clusterNum[targetResultIndex] > 0 )
|
||||
{
|
||||
const RigCell& nativeCell = mainGrid->cell( reservoirCellIndex );
|
||||
boundingBox.add( nativeCell.boundingBox() );
|
||||
}
|
||||
}
|
||||
|
||||
return boundingBox;
|
||||
}
|
||||
|
@ -20,13 +20,18 @@
|
||||
|
||||
#include "cafVecIjk.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfStructGrid.h"
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
class RigActiveCellInfo;
|
||||
class RigCaseCellResultsData;
|
||||
class RimEclipseCase;
|
||||
class RimEclipseCaseEnsemble;
|
||||
class RimRegularGridCase;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
@ -77,6 +82,13 @@ public:
|
||||
VolumeResultType volumeResultType,
|
||||
size_t timeStepIdx );
|
||||
|
||||
static RimRegularGridCase* generateEnsembleCandidates( RimEclipseCaseEnsemble& ensemble,
|
||||
size_t timeStepIdx,
|
||||
VolumeType volumeType,
|
||||
VolumesType volumesType,
|
||||
VolumeResultType volumeResultType,
|
||||
const ClusteringLimits& limits );
|
||||
|
||||
class ClusterStatistics
|
||||
{
|
||||
public:
|
||||
@ -156,6 +168,10 @@ private:
|
||||
|
||||
static void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<int>& clusterIds );
|
||||
|
||||
static void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<double>& values );
|
||||
|
||||
static void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector<int>& clusterIds, double value );
|
||||
|
||||
static double getValueForFace( const std::vector<double>& x,
|
||||
const std::vector<double>& y,
|
||||
const std::vector<double>& z,
|
||||
@ -177,4 +193,15 @@ private:
|
||||
int numClustersFound,
|
||||
size_t timeStepIdx,
|
||||
const QString& clusterResultName );
|
||||
|
||||
static void computeStatisticsAndCreateVectors( RimEclipseCase& targetCase,
|
||||
const QString& resultName,
|
||||
const std::vector<std::vector<double>>& vec );
|
||||
|
||||
static void accumulateResultsForSingleCase( RimEclipseCase& eclipseCase,
|
||||
RimEclipseCase& targetCase,
|
||||
std::map<QString, std::vector<std::vector<double>>>& resultNamesAndSamples,
|
||||
std::vector<int>& occupancy );
|
||||
|
||||
static cvf::BoundingBox computeBoundingBoxForResult( RimEclipseCase& eclipseCase, const QString& resultName, size_t timeStepIndex );
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user