mirror of
https://github.com/OPM/ResInsight.git
synced 2026-09-03 20:53:13 -05:00
The map size of the sample grid was recomputed from the expanded bounding box and the sample spacing stored in the project file. The expanded bounding box is an exact multiple of the sample spacing, but after the limited precision of the project file the division can land just above a whole number of cells, and the map size gets one extra cell. The cache files were then rejected, and the ensemble statistics recomputed. Store the map size in the project file, and use it directly when the sample grid is restored from the cache. Identify the input grids of the cache validity key by file path, size and modification time, so that the cache is also invalidated when a grid file is modified in place. Label and count the primary case and the ensemble cases, so that a primary case can not be mistaken for the first ensemble case.
181 lines
7.2 KiB
C++
181 lines
7.2 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "RimNamedObject.h"
|
|
|
|
#include "ContourMap/RimContourMapResolutionTools.h"
|
|
#include "RimContourMapProjection.h"
|
|
|
|
#include "cafPdmChildArrayField.h"
|
|
#include "cafPdmField.h"
|
|
#include "cafPdmPtrArrayField.h"
|
|
#include "cafPdmPtrField.h"
|
|
|
|
#include "cvfVector3.h"
|
|
|
|
#include <map>
|
|
#include <optional>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
class RigContourMapGrid;
|
|
class RimEclipseCase;
|
|
class RimEclipseResultDefinition;
|
|
class RimEclipseCaseEnsemble;
|
|
class RimFormationNames;
|
|
class RimReservoirGridEnsemble;
|
|
class RimEclipseContourMapView;
|
|
class RimStatisticsContourMapView;
|
|
class RimPolygon;
|
|
class RigPolyLinesData;
|
|
|
|
//==================================================================================================
|
|
//
|
|
//==================================================================================================
|
|
class RimStatisticsContourMap : public RimNamedObject
|
|
{
|
|
CAF_PDM_HEADER_INIT;
|
|
|
|
public:
|
|
enum class StatisticsType
|
|
{
|
|
P10,
|
|
P50,
|
|
P90,
|
|
MEAN,
|
|
MIN,
|
|
MAX
|
|
};
|
|
|
|
enum class GridImportMode
|
|
{
|
|
SHARED_GRID,
|
|
INDIVIDUAL_GRIDS
|
|
};
|
|
|
|
RimStatisticsContourMap();
|
|
|
|
void setEclipseCase( RimEclipseCase* eclipseCase );
|
|
RimEclipseCase* eclipseCase() const;
|
|
|
|
void setGridImportMode( GridImportMode mode );
|
|
|
|
QString ensembleName() const;
|
|
|
|
RigContourMapGrid* contourMapGrid() const;
|
|
std::vector<double> result( size_t timeStep, StatisticsType statisticsType ) const;
|
|
|
|
void addView( RimStatisticsContourMapView* view );
|
|
std::vector<RimStatisticsContourMapView*> views() const;
|
|
|
|
void ensureResultsComputed();
|
|
|
|
static void computeStatisticsForMaps( const std::vector<RimStatisticsContourMap*>& maps );
|
|
|
|
QString resultAggregationText() const;
|
|
QString resultVariable() const;
|
|
double sampleSpacingFactor() const;
|
|
bool isColumnResult() const;
|
|
|
|
std::vector<int> selectedTimeSteps() const;
|
|
std::vector<QDateTime> selectedTimeStepDates() const;
|
|
QString timeStepName( int timeStep ) const;
|
|
|
|
std::vector<QString> selectedFormations() const;
|
|
std::vector<std::vector<cvf::Vec3d>> selectedPolygons() const;
|
|
|
|
protected:
|
|
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
|
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
|
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
|
void initAfterRead() override;
|
|
void setupBeforeSave() override;
|
|
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
|
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
|
|
|
void switchToSelectedSourceCase();
|
|
|
|
private:
|
|
using TimestepResultsMap = std::map<size_t, std::vector<std::vector<double>>>;
|
|
|
|
void computeStatistics();
|
|
void onComputeStatisticsClicked();
|
|
void doStatisticsCalculation( TimestepResultsMap& timestep_results );
|
|
|
|
// Project-adjacent statistics cache, keyed by a hash of all settings affecting the results.
|
|
// The results are stored as one GRI surface file per statistics type per time step, so that
|
|
// the cached maps can also be imported as regular surfaces.
|
|
QString computeCacheValidityKey() const;
|
|
bool loadCachedResults();
|
|
bool writeCachedResults( const QString& baseName ) const;
|
|
QString cacheFileName( const QString& baseName, StatisticsType statisticsType, size_t timeStep ) const;
|
|
QString getValidCacheFileBaseName() const;
|
|
void deleteCacheFiles() const;
|
|
void clearCacheFields();
|
|
static QString getCacheDirectoryPath();
|
|
|
|
RimFormationNames* activeFormationNames() const;
|
|
std::vector<RimEclipseCase*> ensembleCases() const;
|
|
std::set<RimEclipseCase*> ensembleCasesInViews() const;
|
|
|
|
std::vector<std::pair<int, int>> mapLocalToGlobalTimeSteps( std::vector<QDateTime> localDates ) const;
|
|
|
|
private:
|
|
caf::PdmField<double> m_boundingBoxExpPercent;
|
|
caf::PdmField<RimContourMapProjection::ResultAggregation> m_resultAggregation;
|
|
caf::PdmField<std::vector<int>> m_selectedTimeSteps;
|
|
caf::PdmChildField<RimEclipseResultDefinition*> m_resultDefinition;
|
|
caf::PdmField<bool> m_enableFormationFilter;
|
|
caf::PdmField<std::vector<QString>> m_selectedFormations;
|
|
caf::PdmPtrField<RimEclipseCase*> m_primaryCase;
|
|
caf::PdmPtrArrayField<RimPolygon*> m_selectedPolygons;
|
|
|
|
caf::PdmField<caf::AppEnum<GridImportMode>> m_gridImportMode;
|
|
caf::PdmField<caf::AppEnum<RimContourMapResolutionTools::SamplingResolution>> m_resolution;
|
|
|
|
caf::PdmField<caf::AppEnum<RigFloodingSettings::FloodingType>> m_oilFloodingType;
|
|
caf::PdmField<caf::AppEnum<RigFloodingSettings::FloodingType>> m_gasFloodingType;
|
|
caf::PdmField<double> m_userDefinedFloodingGas;
|
|
caf::PdmField<double> m_userDefinedFloodingOil;
|
|
|
|
// Base file name of the cache files within the project cache directory. Stored as a plain file
|
|
// name to stay relocatable with the project and out of reach of the global path list macros.
|
|
// The contour map grid definition is stored in fields, since the GRI files only hold the 2D
|
|
// sample grid and values.
|
|
caf::PdmField<QString> m_cacheFileBaseName;
|
|
caf::PdmField<QString> m_cacheValidityKey;
|
|
caf::PdmField<std::vector<int>> m_cacheTimeSteps;
|
|
caf::PdmField<double> m_cacheSampleSpacing;
|
|
caf::PdmField<std::vector<double>> m_cacheOriginalBoundingBox;
|
|
caf::PdmField<std::vector<double>> m_cacheExpandedBoundingBox;
|
|
caf::PdmField<std::vector<int>> m_cacheMapSize;
|
|
|
|
std::unique_ptr<RigContourMapGrid> m_contourMapGrid;
|
|
std::map<size_t, std::map<StatisticsType, std::vector<double>>> m_timeResults;
|
|
|
|
caf::PdmChildArrayField<RimStatisticsContourMapView*> m_views;
|
|
|
|
RimEclipseCase* m_openEclipseCase;
|
|
|
|
// Validity key captured when the results were computed or loaded from cache, so that results
|
|
// from outdated settings are never written to the cache
|
|
QString m_computedValidityKey;
|
|
};
|