///////////////////////////////////////////////////////////////////////////////// // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once #include "cafVecIjk.h" #include "cvfBoundingBox.h" #include "cvfStructGrid.h" #include "RigEclipseResultAddress.h" #include #include class RigActiveCellInfo; class RigCaseCellResultsData; class RimEclipseCase; class RimEclipseCaseEnsemble; class RimRegularGridCase; //================================================================================================== /// /// //================================================================================================== class RigWellTargetCandidatesGenerator { public: enum class VolumeType { OIL, GAS, HYDROCARBON }; enum class VolumeResultType { MOBILE, TOTAL }; enum class VolumesType { RESERVOIR_VOLUMES, SURFACE_VOLUMES, COMPUTED_VOLUMES }; struct ClusteringLimits { double volume; double permeability; double pressure; double transmissibility; int maxClusters; int maxIterations; RigEclipseResultAddress filterAddress; }; static void generateCandidates( RimEclipseCase* eclipseCase, size_t timeStepIdx, VolumeType volumeType, VolumesType volumesType, VolumeResultType volumeResultType, const ClusteringLimits& limits ); static std::vector getVolumeVector( RigCaseCellResultsData& resultsData, VolumeType volumeType, VolumesType volumesType, VolumeResultType volumeResultType, size_t timeStepIdx ); static RimRegularGridCase* generateEnsembleCandidates( RimEclipseCaseEnsemble& ensemble, size_t timeStepIdx, const cvf::Vec3st& resultGridCellCount, VolumeType volumeType, VolumesType volumesType, VolumeResultType volumeResultType, const ClusteringLimits& limits ); class ClusterStatistics { public: ClusterStatistics() : id( -1 ) , numCells( 0 ) , totalPorvSoil( 0.0 ) , totalPorvSgas( 0.0 ) , totalPorvSoilAndSgas( 0.0 ) , totalFipOil( 0.0 ) , totalFipGas( 0.0 ) , permeability( 0.0 ) , pressure( 0.0 ) { } int id; size_t numCells; double totalPorvSoil; double totalPorvSgas; double totalPorvSoilAndSgas; double totalFipOil; double totalFipGas; double permeability; double pressure; }; private: static std::optional findStartCell( RimEclipseCase* eclipseCase, size_t timeStepIdx, const ClusteringLimits& limits, const std::vector& volume, const std::vector& pressure, const std::vector& permeabilityX, const std::vector& permeabilityY, const std::vector& permeabilityZ, const std::vector& transmissibilityX, const std::vector& transmissibilityY, const std::vector& transmissibilityZ, const std::vector& filterVector, const std::vector& clusters ); static void growCluster( RimEclipseCase* eclipseCase, const caf::VecIjk& startCell, const ClusteringLimits& limits, const std::vector& volume, const std::vector& pressure, const std::vector& permeabilityX, const std::vector& permeabilityY, const std::vector& permeabilityZ, const std::vector& transmissibilityX, const std::vector& transmissibilityY, const std::vector& transmissibilityZ, const std::vector& filterVector, std::vector& clusters, int clusterId, size_t timeStepIdx, int maxIterations ); static std::vector findCandidates( const RimEclipseCase& eclipseCase, const std::vector& previousCells, const ClusteringLimits& limits, const std::vector& volume, const std::vector& pressure, const std::vector& permeabilityX, const std::vector& permeabilityY, const std::vector& permeabilityZ, const std::vector& transmissibilityX, const std::vector& transmissibilityY, const std::vector& transmissibilityZ, const std::vector& filterVector, std::vector& clusters ); static void assignClusterIdToCells( const RigActiveCellInfo& activeCellInfo, const std::vector& cells, std::vector& clusters, int clusterId ); static std::optional getActiveCellCount( RimEclipseCase* eclipseCase ); static void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector& clusterIds ); static void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector& values ); static void createResultVector( RimEclipseCase& eclipseCase, const QString& resultName, const std::vector& clusterIds, double value ); static double getValueForFace( const std::vector& x, const std::vector& y, const std::vector& z, cvf::StructGridInterface::FaceType face, size_t resultIndex ); static double getTransmissibilityValueForFace( const std::vector& x, const std::vector& y, const std::vector& z, cvf::StructGridInterface::FaceType face, size_t resultIndex, size_t neighborResultIndex ); static std::vector generateStatistics( RimEclipseCase* eclipseCase, const std::vector& pressure, const std::vector& permeabilityX, const std::vector& permeabilityY, const std::vector& permeabilityZ, int numClustersFound, size_t timeStepIdx, const QString& clusterResultName ); static void computeStatisticsAndCreateVectors( RimEclipseCase& targetCase, const QString& resultName, const std::vector>& vec ); static void accumulateResultsForSingleCase( RimEclipseCase& eclipseCase, RimEclipseCase& targetCase, std::map>>& resultNamesAndSamples, std::vector& occupancy ); static cvf::BoundingBox computeBoundingBoxForResult( RimEclipseCase& eclipseCase, const QString& resultName, size_t timeStepIndex ); };