mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4143 First implementation of export sector model
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "cvfMath.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
|
||||
@@ -282,6 +283,25 @@ bool RifEclipseOutputFileTools::isValidEclipseFileName(const QString& fileName)
|
||||
return ecl_util_valid_basename(RiaStringEncodingTools::toNativeEncoded(fileNameBase).data());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QByteArray RifEclipseOutputFileTools::md5sum(const QString& fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (file.open(QFile::ReadOnly))
|
||||
{
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
QByteArray fileContent = file.readAll();
|
||||
if (!fileContent.isEmpty())
|
||||
{
|
||||
hash.addData(fileContent);
|
||||
return hash.result();
|
||||
}
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get set of Eclipse files based on an input file and its path
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -524,6 +544,26 @@ ecl_kw_type* RifEclipseOutputFileTools::createActnumFromPorv(ecl_file_type* ecl_
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Convenience method to hide C fopen calls in #pragma declarations to avoid warnings on Windows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
FILE* RifEclipseOutputFileTools::fopen(const QString& filePath, const QString& mode)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
FILE* filePtr = std::fopen(RiaStringEncodingTools::toNativeEncoded(filePath).data(), RiaStringEncodingTools::toNativeEncoded(mode).data());
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
return filePtr;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
typedef struct ecl_file_struct ecl_file_type;
|
||||
|
||||
class RifEclipseRestartDataAccess;
|
||||
|
||||
class QByteArray;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
static void timeSteps(ecl_file_type* ecl_file, std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart);
|
||||
|
||||
static bool isValidEclipseFileName(const QString& fileName);
|
||||
static QByteArray md5sum(const QString& fileName);
|
||||
static bool findSiblingFilesWithSameBaseName(const QString& fileName, QStringList* fileSet);
|
||||
|
||||
static QString firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
@@ -79,6 +80,8 @@ public:
|
||||
|
||||
static ecl_kw_type* createActnumFromPorv(ecl_file_type* ecl_file);
|
||||
|
||||
static FILE* fopen(const QString& filePath, const QString& mode);
|
||||
|
||||
private:
|
||||
static void createReportStepsMetaData(std::vector<ecl_file_type*> ecl_files, std::vector<RifRestartReportStep>* reportSteps);
|
||||
};
|
||||
|
||||
@@ -351,6 +351,182 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid,
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseOutput::saveEclipseGrid(const QString& fileName, RigEclipseCaseData* eclipseCase, const cvf::Vec3st* min, const cvf::Vec3st* max)
|
||||
{
|
||||
if (!eclipseCase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RiaDefines::MATRIX_MODEL);
|
||||
const RigActiveCellInfo* fractureActiveCellInfo = eclipseCase->activeCellInfo(RiaDefines::FRACTURE_MODEL);
|
||||
|
||||
CVF_ASSERT(activeCellInfo && fractureActiveCellInfo);
|
||||
|
||||
const RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
|
||||
int ecl_nx = (int) mainGrid->cellCountI();
|
||||
int ecl_ny = (int) mainGrid->cellCountJ();
|
||||
int ecl_nz = (int) mainGrid->cellCountK();
|
||||
|
||||
if (min && max)
|
||||
{
|
||||
ecl_nx = (int) (max->x() - min->x()) + 1;
|
||||
ecl_ny = (int) (max->y() - min->y()) + 1;
|
||||
ecl_nz = (int) (max->z() - min->z()) + 1;
|
||||
}
|
||||
|
||||
int ecl_cell_count = (int) mainGrid->cellCount();
|
||||
|
||||
caf::ProgressInfo progress(ecl_cell_count * 2, "Save Eclipse Grid");
|
||||
int cellProgressInterval = 1000;
|
||||
|
||||
std::vector<float*> ecl_corners; ecl_corners.reserve(ecl_cell_count);
|
||||
std::vector<int*> ecl_coords; ecl_coords.reserve(ecl_cell_count);
|
||||
|
||||
int incrementalIndex = 0;
|
||||
for (int index = 0; index < ecl_cell_count; ++index)
|
||||
{
|
||||
size_t i, j, k;
|
||||
mainGrid->ijkFromCellIndex(index, &i, &j, &k);
|
||||
|
||||
if (i < min->x() || i > max->x() ||
|
||||
j < min->y() || j > max->y() ||
|
||||
k < min->z() || k > max->z())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int active = activeCellInfo->isActive(index) ? 1 : 0;
|
||||
|
||||
int* ecl_cell_coords = new int[5];
|
||||
ecl_cell_coords[0] = (int) (i + 1 - min->x());
|
||||
ecl_cell_coords[1] = (int) (j + 1 - min->y());
|
||||
ecl_cell_coords[2] = (int) (k + 1 - min->z());
|
||||
ecl_cell_coords[3] = incrementalIndex++;
|
||||
ecl_cell_coords[4] = active;
|
||||
ecl_coords.push_back(ecl_cell_coords);
|
||||
|
||||
cvf::Vec3d cellCorners[8];
|
||||
mainGrid->cellCornerVertices(index, cellCorners);
|
||||
|
||||
float* ecl_cell_corners = new float[24];
|
||||
for (size_t corner = 0; corner < 8; ++corner)
|
||||
{
|
||||
ecl_cell_corners[cellMappingECLRi[corner] * 3 ] = cellCorners[corner][0];
|
||||
ecl_cell_corners[cellMappingECLRi[corner] * 3 + 1] = cellCorners[corner][1];
|
||||
ecl_cell_corners[cellMappingECLRi[corner] * 3 + 2] = -cellCorners[corner][2];
|
||||
}
|
||||
ecl_corners.push_back(ecl_cell_corners);
|
||||
|
||||
if (index % cellProgressInterval == 0)
|
||||
{
|
||||
progress.setProgress(index);
|
||||
}
|
||||
}
|
||||
|
||||
ecl_grid_type* mainEclGrid = ecl_grid_alloc_GRID_data((int) ecl_coords.size(), ecl_nx, ecl_ny, ecl_nz, 5, &ecl_coords[0], &ecl_corners[0], false, NULL);
|
||||
progress.setProgress(ecl_cell_count * 2);
|
||||
|
||||
for (float* floatArray : ecl_corners)
|
||||
{
|
||||
delete floatArray;
|
||||
}
|
||||
|
||||
for (int* intArray : ecl_coords)
|
||||
{
|
||||
delete intArray;
|
||||
}
|
||||
|
||||
FILE* filePtr = RifEclipseOutputFileTools::fopen(fileName, "w");
|
||||
|
||||
if (!filePtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecl_grid_fprintf_grdecl(mainEclGrid, filePtr);
|
||||
ecl_grid_free(mainEclGrid);
|
||||
fclose(filePtr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderEclipseOutput::saveEclipseResults(const QString& resultFileName,
|
||||
RigEclipseCaseData* eclipseCase,
|
||||
const std::vector<QString>& keywords,
|
||||
const QString& fileWriteMode,
|
||||
const cvf::Vec3st* min,
|
||||
const cvf::Vec3st* max)
|
||||
{
|
||||
FILE* filePtr = RifEclipseOutputFileTools::fopen(resultFileName, fileWriteMode);
|
||||
if (!filePtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
RigCaseCellResultsData* cellResultsData = eclipseCase->results(RiaDefines::MATRIX_MODEL);
|
||||
RigActiveCellInfo* activeCells = cellResultsData->activeCellInfo();
|
||||
RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
|
||||
caf::ProgressInfo progress(keywords.size(), "Saving Keywords");
|
||||
|
||||
for (const QString& keyword : keywords)
|
||||
{
|
||||
std::vector<double> resultValues;
|
||||
|
||||
RigEclipseResultAddress resAddr(RiaDefines::STATIC_NATIVE, keyword);
|
||||
cellResultsData->ensureKnownResultLoaded(resAddr);
|
||||
resultValues = cellResultsData->cellScalarResults(resAddr)[0];
|
||||
CVF_ASSERT(!resultValues.empty());
|
||||
|
||||
std::vector<double> filteredResults;
|
||||
filteredResults.reserve(resultValues.size());
|
||||
for (size_t index = 0; index < mainGrid->cellCount(); ++index)
|
||||
{
|
||||
size_t i, j, k;
|
||||
mainGrid->ijkFromCellIndex(index, &i, &j, &k);
|
||||
if (i < min->x() || i > max->x() || j < min->y() || j > max->y() || k < min->z() || k > max->z())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
size_t resIndex = activeCells->cellResultIndex(index);
|
||||
if (resIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
filteredResults.push_back(resultValues[resIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
ecl_kw_type* ecl_kw = nullptr;
|
||||
|
||||
if (keyword.endsWith("NUM"))
|
||||
{
|
||||
std::vector<int> resultValuesInt; resultValuesInt.reserve(filteredResults.size());
|
||||
for (double val : filteredResults)
|
||||
{
|
||||
resultValuesInt.push_back(static_cast<int>(val));
|
||||
}
|
||||
ecl_kw = ecl_kw_alloc_new(keyword.toLatin1().data(), (int) resultValuesInt.size(), ECL_INT, resultValuesInt.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
ecl_kw = ecl_kw_alloc_new(keyword.toLatin1().data(), (int) filteredResults.size(), ECL_DOUBLE, filteredResults.data());
|
||||
}
|
||||
|
||||
ecl_kw_fprintf_grdecl(ecl_kw, filePtr);
|
||||
ecl_kw_free(ecl_kw);
|
||||
progress.incrementProgress();
|
||||
}
|
||||
|
||||
fclose(filePtr);
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Open file and read geometry into given reservoir object
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "RifReaderInterface.h"
|
||||
|
||||
#include "cvfCollection.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -66,6 +67,14 @@ public:
|
||||
std::vector<QDateTime> allTimeSteps() const;
|
||||
|
||||
static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigEclipseCaseData* eclipseCase);
|
||||
static bool saveEclipseGrid(const QString& gridFileName, RigEclipseCaseData* eclipseCase, const cvf::Vec3st* min = nullptr, const cvf::Vec3st* max = nullptr);
|
||||
static bool saveEclipseResults(const QString& resultFileName,
|
||||
RigEclipseCaseData* eclipseCase,
|
||||
const std::vector<QString>& keywords,
|
||||
const QString& fileWriteMode = "w",
|
||||
const cvf::Vec3st* min = nullptr,
|
||||
const cvf::Vec3st* max = nullptr);
|
||||
|
||||
static void transferCoarseningInfo(const ecl_grid_type* eclGrid, RigGridBase* grid);
|
||||
|
||||
std::set<RiaDefines::PhaseType> availablePhases() const override;
|
||||
|
||||
Reference in New Issue
Block a user