Files
ResInsight/ApplicationLibCode/ProjectDataModel/RimGridCalculation.h
T
Kristian Bendiksen 996e18426c #14345 Grid Calculation: add filtering with view-independent data filters
Add a filter type option to the grid calculation: None, Cell Filter
View or Data Filter. In data filter mode a single filter from the
destination case's Data Filters collection is selected, and the filter
is evaluated per calculation case and time step using each case's own
active cells and result values. Property based filtering of ensemble
calculations then uses each realization's own property values, which is
not possible with view based filtering.

Old projects with a cell filter view are migrated to the cell filter
view mode. Complex filtering is composed with a combined filter (AND/OR)
in the Data Filters collection.
2026-09-16 10:53:31 +02:00

174 lines
7.5 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 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 "RiaPorosityModel.h"
#include "RimEclipseCaseEnsemble.h"
#include "RimGridCalculationVariable.h"
#include "RimUserDefinedCalculation.h"
#include "cafPdmChildField.h"
#include "cafSignal.h"
#include "cvfArray.h"
#include <optional>
class RimCellFilter;
class RimEclipseCase;
class RimGridView;
class RigEclipseResultAddress;
class RimEclipseResultAddress;
class RimIdenticalGridCaseGroup;
class RigActiveCellInfo;
//==================================================================================================
///
///
//==================================================================================================
class RimGridCalculation : public RimUserDefinedCalculation
{
CAF_PDM_HEADER_INIT;
public:
enum class DefaultValueType
{
POSITIVE_INFINITY,
FROM_PROPERTY,
USER_DEFINED
};
enum class AdditionalCasesType
{
NONE,
GRID_CASE_GROUP,
ENSEMBLE,
ALL_CASES
};
enum class FilterType
{
NO_FILTER,
CELL_FILTER_VIEW,
DATA_FILTER
};
RimGridCalculation();
bool preCalculate() const override;
bool calculate() override;
void updateDependentObjects() override;
void removeDependentObjects() override;
std::vector<RimEclipseCase*> outputEclipseCases() const;
RigEclipseResultAddress outputAddress() const;
bool calculateForCases( const std::vector<RimEclipseCase*>& calculationCases,
cvf::UByteArray* inputValueVisibilityFilter,
std::optional<std::vector<size_t>> timeSteps,
bool evaluateDependentCalculations );
void findAndEvaluateDependentCalculations( const std::vector<RimEclipseCase*>& calculationCases,
cvf::UByteArray* inputValueVisibilityFilter,
std::optional<std::vector<size_t>> timeSteps );
void assignEclipseCaseForNullPointers( RimEclipseCase* eclipseCase );
std::vector<RimEclipseCase*> inputCases() const;
RimGridCalculationVariable* createVariable() override;
static size_t replaceInvalidValuesWithDefaultValue( double defaultValue, std::vector<double>& values );
protected:
void onChildrenUpdated( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& updatedObjects ) override;
std::pair<bool, QString> validateVariables();
std::vector<double> getActiveCellValuesForVariable( RimGridCalculationVariable* variable,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const;
std::vector<double> getActiveCellValues( const QString& resultName,
const RiaDefines::ResultCatType resultCategoryType,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const;
void filterResults( cvf::UByteArray* visibility,
const std::vector<std::vector<double>>& values,
size_t timeStep,
RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* outputEclipseCase ) const;
static void replaceFilteredValuesWithVector( const std::vector<double>& inputValues,
cvf::ref<cvf::UByteArray> visibility,
std::vector<double>& resultValues,
RigActiveCellInfo* activeCellInfo );
static size_t replaceFilteredValuesWithDefaultValue( double defaultValue,
cvf::ref<cvf::UByteArray> visibility,
std::vector<double>& resultValues,
RigActiveCellInfo* activeCellInfo );
using DefaultValueConfig = std::pair<RimGridCalculation::DefaultValueType, double>;
DefaultValueConfig defaultValueConfiguration() const;
QString nonVisibleResultAddressText() const;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
void initAfterRead() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
private:
void onVariableUpdated( const SignalEmitter* emitter );
bool allSourceCasesAreEqualToDestinationCase() const;
void onEditNonVisibleResultAddressButtonPressed();
static std::pair<bool, QStringList> createStatisticsText( const std::vector<std::vector<double>>& values );
private:
caf::PdmField<caf::AppEnum<FilterType>> m_filterType;
caf::PdmPtrField<RimGridView*> m_cellFilterView;
caf::PdmPtrField<RimCellFilter*> m_dataFilter;
caf::PdmField<caf::AppEnum<DefaultValueType>> m_defaultValueType;
caf::PdmField<double> m_defaultValue;
caf::PdmPtrField<RimEclipseCase*> m_destinationCase;
caf::PdmField<caf::AppEnum<AdditionalCasesType>> m_additionalCasesType;
caf::PdmPtrField<RimIdenticalGridCaseGroup*> m_additionalCaseGroup;
caf::PdmPtrField<RimEclipseCaseEnsemble*> m_additionalEnsemble;
caf::PdmField<std::vector<int>> m_selectedTimeSteps;
caf::PdmProxyValueField<QString> m_nonVisibleResultText;
caf::PdmChildField<RimEclipseResultAddress*> m_nonVisibleResultAddress;
caf::PdmField<bool> m_applyToAllCases_OBSOLETE;
bool m_releaseMemoryAfterDataIsExtracted = false;
};