mirror of
https://github.com/OPM/ResInsight.git
synced 2026-09-03 20:53:13 -05:00
Merge branch 'fishbones' into pre-proto
This commit is contained in:
@@ -7,6 +7,7 @@ endif()
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseInputFileTools.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseOutputFileTools.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseOutputTableFormatter.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseRestartDataAccess.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseRestartFilesetAccess.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryTools.h
|
||||
@@ -19,6 +20,7 @@ ${CEE_CURRENT_LIST_DIR}RifReaderInterface.h
|
||||
${CEE_CURRENT_LIST_DIR}RifReaderMockModel.h
|
||||
${CEE_CURRENT_LIST_DIR}RifReaderSettings.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.h
|
||||
${CEE_CURRENT_LIST_DIR}RifWellPathImporter.h
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseWellCompletionExporter.h
|
||||
${CEE_CURRENT_LIST_DIR}RifFractureExportTools.h
|
||||
)
|
||||
@@ -26,6 +28,7 @@ ${CEE_CURRENT_LIST_DIR}RifFractureExportTools.h
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseInputFileTools.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseOutputFileTools.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseOutputTableFormatter.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseRestartDataAccess.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseRestartFilesetAccess.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.cpp
|
||||
@@ -38,6 +41,7 @@ ${CEE_CURRENT_LIST_DIR}RifReaderInterface.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifReaderMockModel.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifReaderSettings.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifWellPathImporter.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifEclipseWellCompletionExporter.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RifFractureExportTools.cpp
|
||||
)
|
||||
|
||||
@@ -121,22 +121,22 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigEclipseC
|
||||
bool allKwReadOk = true;
|
||||
|
||||
fseek(gridFilePointer, specgridPos, SEEK_SET);
|
||||
allKwReadOk = allKwReadOk && NULL != (specGridKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_INT_TYPE));
|
||||
allKwReadOk = allKwReadOk && NULL != (specGridKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_INT_TYPE)));
|
||||
progress.setProgress(1);
|
||||
|
||||
fseek(gridFilePointer, zcornPos, SEEK_SET);
|
||||
allKwReadOk = allKwReadOk && NULL != (zCornKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE));
|
||||
allKwReadOk = allKwReadOk && NULL != (zCornKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE)));
|
||||
progress.setProgress(2);
|
||||
|
||||
fseek(gridFilePointer, coordPos, SEEK_SET);
|
||||
allKwReadOk = allKwReadOk && NULL != (coordKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE));
|
||||
allKwReadOk = allKwReadOk && NULL != (coordKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE)));
|
||||
progress.setProgress(3);
|
||||
|
||||
// If ACTNUM is not defined, this pointer will be NULL, which is a valid condition
|
||||
if (actnumPos >= 0)
|
||||
{
|
||||
fseek(gridFilePointer, actnumPos, SEEK_SET);
|
||||
allKwReadOk = allKwReadOk && NULL != (actNumKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_INT_TYPE));
|
||||
allKwReadOk = allKwReadOk && NULL != (actNumKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_INT_TYPE)));
|
||||
progress.setProgress(4);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigEclipseC
|
||||
if (mapaxesPos >= 0)
|
||||
{
|
||||
fseek(gridFilePointer, mapaxesPos, SEEK_SET);
|
||||
mapAxesKw = ecl_kw_fscanf_alloc_current_grdecl__( gridFilePointer, false , ECL_FLOAT_TYPE);
|
||||
mapAxesKw = ecl_kw_fscanf_alloc_current_grdecl__( gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE));
|
||||
}
|
||||
|
||||
if (!allKwReadOk)
|
||||
@@ -228,7 +228,7 @@ std::map<QString, QString> RifEclipseInputFileTools::readProperties(const QStrin
|
||||
|
||||
fseek(gridFilePointer, fileKeywords[i].filePos, SEEK_SET);
|
||||
|
||||
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false, ECL_FLOAT_TYPE);
|
||||
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false, ecl_type_create_from_type(ECL_FLOAT_TYPE));
|
||||
if (eclipseKeywordData)
|
||||
{
|
||||
QString newResultName = caseData->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword);
|
||||
@@ -261,7 +261,7 @@ bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigEclipseC
|
||||
FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r");
|
||||
if (!filePointer) return false;
|
||||
|
||||
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_grdecl_dynamic__(filePointer, eclipseKeyWord.toLatin1().data(), false, ECL_FLOAT_TYPE);
|
||||
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_grdecl_dynamic__(filePointer, eclipseKeyWord.toLatin1().data(), false, ecl_type_create_from_type(ECL_FLOAT_TYPE));
|
||||
bool isOk = false;
|
||||
if (eclipseKeywordData)
|
||||
{
|
||||
@@ -474,18 +474,17 @@ bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName,
|
||||
/// Create and write a result vector with values for all cells.
|
||||
/// undefinedValue is used for cells with no result
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName,
|
||||
RigEclipseCaseData* eclipseCase,
|
||||
RifReaderInterface::PorosityModelResultType porosityModel,
|
||||
size_t timeStep,
|
||||
const QString& resultName,
|
||||
const QString& eclipseKeyWord,
|
||||
bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName,
|
||||
RigEclipseCaseData* eclipseCase,
|
||||
size_t timeStep,
|
||||
RimEclipseResultDefinition* resultDefinition,
|
||||
const QString& eclipseKeyWord,
|
||||
const double undefinedValue)
|
||||
{
|
||||
CVF_ASSERT(eclipseCase);
|
||||
|
||||
size_t resultIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(resultName);
|
||||
if (resultIndex == cvf::UNDEFINED_SIZE_T)
|
||||
cvf::ref<RigResultAccessor> resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase, eclipseCase->mainGrid()->gridIndex(), timeStep, resultDefinition);
|
||||
if (resultAccessor.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -496,12 +495,6 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa
|
||||
return false;
|
||||
}
|
||||
|
||||
cvf::ref<RigResultAccessor> resultAccessor = RigResultAccessorFactory::createFromUiResultName(eclipseCase, eclipseCase->mainGrid()->gridIndex(), porosityModel, timeStep, resultName);
|
||||
if (resultAccessor.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> resultData;
|
||||
size_t i, j, k;
|
||||
for (k = 0; k < eclipseCase->mainGrid()->cellCountK(); k++)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
class RigEclipseCaseData;
|
||||
class QFile;
|
||||
class RimEclipseResultDefinition;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -76,7 +77,7 @@ public:
|
||||
|
||||
|
||||
static bool writePropertyToTextFile(const QString& fileName, RigEclipseCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord);
|
||||
static bool writeBinaryResultToTextFile(const QString& fileName, RigEclipseCaseData* eclipseCase, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue);
|
||||
static bool writeBinaryResultToTextFile(const QString& fileName, RigEclipseCaseData* eclipseCase, size_t timeStep, RimEclipseResultDefinition* resultdefinition, const QString& eclipseKeyWord, const double undefinedValue);
|
||||
|
||||
static bool readFaultsAndParseIncludeStatementsRecursively( QFile& file,
|
||||
qint64 startPos,
|
||||
|
||||
@@ -115,7 +115,7 @@ void getDayMonthYear(const ecl_kw_type* intehead_kw, int* day, int* month, int*
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of time step texts (dates)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector<QDateTime>* timeSteps)
|
||||
void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart)
|
||||
{
|
||||
if (!ecl_file) return;
|
||||
|
||||
@@ -127,7 +127,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector<Q
|
||||
// Get the number of occurrences of the DOUBHEAD keyword
|
||||
int numDOUBHEAD = ecl_file_get_num_named_kw(ecl_file, DOUBHEAD_KW);
|
||||
|
||||
std::vector<double> dayFractions(numINTEHEAD, 0.0); // Init fraction to zero
|
||||
std::vector<double> dayValues(numINTEHEAD, 0.0); // Init fraction to zero
|
||||
|
||||
// Read out fraction of day if number of keywords are identical
|
||||
if (numINTEHEAD == numDOUBHEAD)
|
||||
@@ -137,12 +137,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector<Q
|
||||
ecl_kw_type* kwDOUBHEAD = ecl_file_iget_named_kw(ecl_file, DOUBHEAD_KW, i);
|
||||
if (kwDOUBHEAD)
|
||||
{
|
||||
double dayValue = ecl_kw_iget_double(kwDOUBHEAD, DOUBHEAD_DAYS_INDEX);
|
||||
double floorDayValue = cvf::Math::floor(dayValue);
|
||||
|
||||
double dayDelta = dayValue - floorDayValue;
|
||||
|
||||
dayFractions[i] = dayDelta;
|
||||
dayValues[i] = ecl_kw_iget_double(kwDOUBHEAD, DOUBHEAD_DAYS_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +154,8 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector<Q
|
||||
QDateTime reportDateTime(QDate(year, month, day));
|
||||
CVF_ASSERT(reportDateTime.isValid());
|
||||
|
||||
double dayFraction = dayFractions[i];
|
||||
double dayValue = dayValues[i];
|
||||
double dayFraction = dayValue - cvf::Math::floor(dayValue);
|
||||
int milliseconds = static_cast<int>(dayFraction * 24.0 * 60.0 * 60.0 * 1000.0);
|
||||
int seconds = milliseconds % 1000;
|
||||
milliseconds -= seconds * 1000;
|
||||
@@ -172,6 +168,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector<Q
|
||||
if (std::find(timeSteps->begin(), timeSteps->end(), reportDateTime) == timeSteps->end())
|
||||
{
|
||||
timeSteps->push_back(reportDateTime);
|
||||
daysSinceSimulationStart->push_back(dayValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,8 +379,9 @@ void RifEclipseOutputFileTools::createReportStepsMetaData(std::vector<ecl_file_t
|
||||
int namedKeywordCount = ecl_file_get_num_named_kw(ecl_file, kw);
|
||||
for (int iOcc = 0; iOcc < namedKeywordCount; iOcc++)
|
||||
{
|
||||
ecl_type_enum dataType = ecl_file_iget_named_type(ecl_file, kw, iOcc);
|
||||
if (dataType != ECL_DOUBLE_TYPE && dataType != ECL_FLOAT_TYPE && dataType != ECL_INT_TYPE)
|
||||
ecl_data_type dataType = ecl_file_iget_named_data_type(ecl_file, kw, iOcc);
|
||||
ecl_type_enum dataTypeEmum = ecl_type_get_type(dataType);
|
||||
if (dataTypeEmum != ECL_DOUBLE_TYPE && dataTypeEmum != ECL_FLOAT_TYPE && dataTypeEmum != ECL_INT_TYPE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
static bool keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<double>* values);
|
||||
static bool keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<int>* values);
|
||||
|
||||
static void timeSteps(ecl_file_type* ecl_file, std::vector<QDateTime>* timeSteps);
|
||||
static void timeSteps(ecl_file_type* ecl_file, std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart);
|
||||
|
||||
static bool findSiblingFilesWithSameBaseName(const QString& fileName, QStringList* fileSet);
|
||||
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil 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 "RifEclipseOutputTableFormatter.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter::RifEclipseOutputTableFormatter(QTextStream& out) : m_out(out)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter::~RifEclipseOutputTableFormatter()
|
||||
{
|
||||
CVF_ASSERT(m_buffer.empty());
|
||||
CVF_ASSERT(m_columns.empty());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputTableFormatter::outputBuffer()
|
||||
{
|
||||
if (m_columns.size() > 0)
|
||||
{
|
||||
m_out << "-- ";
|
||||
for (RifEclipseOutputTableColumn& column : m_columns)
|
||||
{
|
||||
m_out << formatColumn(column.title, column);
|
||||
}
|
||||
m_out << "\n";
|
||||
}
|
||||
|
||||
for (auto line : m_buffer)
|
||||
{
|
||||
if (line.lineType == COMMENT)
|
||||
{
|
||||
outputComment(line);
|
||||
}
|
||||
else if (line.lineType == CONTENTS)
|
||||
{
|
||||
m_out << " ";
|
||||
for (size_t i = 0; i < line.data.size(); ++i)
|
||||
{
|
||||
m_out << formatColumn(line.data[i], m_columns[i]);
|
||||
}
|
||||
m_out << " /" << "\n";
|
||||
}
|
||||
}
|
||||
m_columns.clear();
|
||||
m_buffer.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputTableFormatter::outputComment(RifEclipseOutputTableLine& comment)
|
||||
{
|
||||
m_out << "-- " << comment.data[0] << "\n";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputTableFormatter::tableCompleted()
|
||||
{
|
||||
outputBuffer();
|
||||
// Output an "empty" line after a finished table
|
||||
m_out << "/\n";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::keyword(const QString keyword)
|
||||
{
|
||||
CVF_ASSERT(m_buffer.empty());
|
||||
CVF_ASSERT(m_columns.empty());
|
||||
m_out << keyword << "\n";
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::header(const std::vector<RifEclipseOutputTableColumn> header)
|
||||
{
|
||||
outputBuffer();
|
||||
m_columns = header;
|
||||
for (RifEclipseOutputTableColumn& column : m_columns)
|
||||
{
|
||||
column.width = measure(column.title);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::comment(const QString comment)
|
||||
{
|
||||
RifEclipseOutputTableLine line;
|
||||
line.data.push_back(comment);
|
||||
line.lineType = COMMENT;
|
||||
if (m_columns.empty())
|
||||
{
|
||||
outputComment(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer.push_back(line);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::add(const QString str)
|
||||
{
|
||||
size_t column = m_lineBuffer.size();
|
||||
CVF_ASSERT(column < m_columns.size());
|
||||
m_columns[column].width = std::max(measure(str), m_columns[column].width);
|
||||
m_lineBuffer.push_back(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::add(double num)
|
||||
{
|
||||
size_t column = m_lineBuffer.size();
|
||||
CVF_ASSERT(column < m_columns.size());
|
||||
m_columns[column].width = std::max(measure(num), m_columns[column].width);
|
||||
m_lineBuffer.push_back(format(num));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::add(int num)
|
||||
{
|
||||
size_t column = m_lineBuffer.size();
|
||||
CVF_ASSERT(column < m_columns.size());
|
||||
m_columns[column].width = std::max(measure(num), m_columns[column].width);
|
||||
m_lineBuffer.push_back(format(num));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::add(size_t num)
|
||||
{
|
||||
size_t column = m_lineBuffer.size();
|
||||
CVF_ASSERT(column < m_columns.size());
|
||||
m_columns[column].width = std::max(measure(num), m_columns[column].width);
|
||||
m_lineBuffer.push_back(format(num));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseOutputTableFormatter& RifEclipseOutputTableFormatter::addZeroBasedCellIndex(size_t index)
|
||||
{
|
||||
size_t column = m_lineBuffer.size();
|
||||
CVF_ASSERT(column < m_columns.size());
|
||||
|
||||
// Increase index by 1 to use Eclipse 1-based cell index instead of ResInsight 0-based
|
||||
index++;
|
||||
|
||||
m_columns[column].width = std::max(measure(index), m_columns[column].width);
|
||||
m_lineBuffer.push_back(format(index));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputTableFormatter::rowCompleted()
|
||||
{
|
||||
RifEclipseOutputTableLine line;
|
||||
line.data = m_lineBuffer;
|
||||
line.lineType = CONTENTS;
|
||||
m_buffer.push_back(line);
|
||||
m_lineBuffer.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifEclipseOutputTableFormatter::measure(const QString str)
|
||||
{
|
||||
return str.length();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifEclipseOutputTableFormatter::measure(double num)
|
||||
{
|
||||
return format(num).length();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifEclipseOutputTableFormatter::measure(int num)
|
||||
{
|
||||
return format(num).length();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RifEclipseOutputTableFormatter::measure(size_t num)
|
||||
{
|
||||
return format(num).length();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseOutputTableFormatter::format(double num)
|
||||
{
|
||||
return QString("%1").arg(num, 0, 'f', m_doubleDecimals);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseOutputTableFormatter::format(int num)
|
||||
{
|
||||
return QString("%1").arg(num);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseOutputTableFormatter::format(size_t num)
|
||||
{
|
||||
return QString("%1").arg(num);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseOutputTableFormatter::formatColumn(const QString str, RifEclipseOutputTableColumn column)
|
||||
{
|
||||
if (column.alignment == LEFT)
|
||||
{
|
||||
return str.leftJustified(column.width + m_colSpacing, ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
return str.rightJustified(column.width, ' ').leftJustified(m_colSpacing, ' ');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil 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 <QString>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <vector>
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
enum RifEclipseOutputTableLineType
|
||||
{
|
||||
COMMENT,
|
||||
CONTENTS
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
enum RifEclipseOutputTableAlignment
|
||||
{
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
struct RifEclipseOutputTableLine
|
||||
{
|
||||
RifEclipseOutputTableLineType lineType;
|
||||
std::vector< QString > data;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
struct RifEclipseOutputTableColumn
|
||||
{
|
||||
RifEclipseOutputTableColumn(const QString& title, RifEclipseOutputTableAlignment alignment = LEFT, int width = -1)
|
||||
: title(title),
|
||||
alignment(alignment),
|
||||
width(width)
|
||||
{
|
||||
}
|
||||
|
||||
QString title;
|
||||
RifEclipseOutputTableAlignment alignment;
|
||||
int width;
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifEclipseOutputTableFormatter
|
||||
{
|
||||
public:
|
||||
RifEclipseOutputTableFormatter(QTextStream& out);
|
||||
virtual ~RifEclipseOutputTableFormatter();
|
||||
|
||||
RifEclipseOutputTableFormatter& keyword(const QString keyword);
|
||||
RifEclipseOutputTableFormatter& header(std::vector<RifEclipseOutputTableColumn> tableHeader);
|
||||
RifEclipseOutputTableFormatter& add(const QString str);
|
||||
RifEclipseOutputTableFormatter& add(double num);
|
||||
RifEclipseOutputTableFormatter& add(int num);
|
||||
RifEclipseOutputTableFormatter& add(size_t num);
|
||||
RifEclipseOutputTableFormatter& addZeroBasedCellIndex(size_t index);
|
||||
RifEclipseOutputTableFormatter& comment(const QString str);
|
||||
void rowCompleted();
|
||||
void tableCompleted();
|
||||
|
||||
private:
|
||||
int measure(const QString str);
|
||||
int measure(double num);
|
||||
int measure(int num);
|
||||
int measure(size_t num);
|
||||
|
||||
QString format(double num);
|
||||
QString format(int num);
|
||||
QString format(size_t num);
|
||||
QString formatColumn(const QString str, RifEclipseOutputTableColumn column);
|
||||
|
||||
void outputBuffer();
|
||||
void outputComment(RifEclipseOutputTableLine& comment);
|
||||
|
||||
private:
|
||||
std::vector<RifEclipseOutputTableColumn> m_columns;
|
||||
std::vector<RifEclipseOutputTableLine> m_buffer;
|
||||
std::vector<QString> m_lineBuffer;
|
||||
QTextStream& m_out;
|
||||
int m_doubleDecimals = 5;
|
||||
int m_colSpacing = 5;
|
||||
};
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
|
||||
virtual void setTimeSteps(const std::vector<QDateTime>& timeSteps) {};
|
||||
virtual size_t timeStepCount() = 0;
|
||||
virtual std::vector<QDateTime> timeSteps() = 0;
|
||||
virtual void timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart) = 0;
|
||||
virtual std::vector<int> reportNumbers() = 0;
|
||||
|
||||
virtual void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts) = 0;
|
||||
|
||||
@@ -119,7 +119,7 @@ size_t RifEclipseRestartFilesetAccess::timeStepCount()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QDateTime> RifEclipseRestartFilesetAccess::timeSteps()
|
||||
void RifEclipseRestartFilesetAccess::timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart)
|
||||
{
|
||||
if (m_timeSteps.size() == 0)
|
||||
{
|
||||
@@ -128,24 +128,28 @@ std::vector<QDateTime> RifEclipseRestartFilesetAccess::timeSteps()
|
||||
for (i = 0; i < numSteps; i++)
|
||||
{
|
||||
std::vector<QDateTime> stepTime;
|
||||
std::vector<double> stepDays;
|
||||
|
||||
openTimeStep(i);
|
||||
|
||||
RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime);
|
||||
RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime, &stepDays);
|
||||
|
||||
if (stepTime.size() == 1)
|
||||
{
|
||||
m_timeSteps.push_back(stepTime[0]);
|
||||
m_daysSinceSimulationStart.push_back(stepDays[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_timeSteps.push_back(QDateTime());
|
||||
m_daysSinceSimulationStart.push_back(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return m_timeSteps;
|
||||
*timeSteps = m_timeSteps;
|
||||
*daysSinceSimulationStart = m_daysSinceSimulationStart;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
void setTimeSteps(const std::vector<QDateTime>& timeSteps);
|
||||
size_t timeStepCount();
|
||||
std::vector<QDateTime> timeSteps();
|
||||
void timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart) override;
|
||||
std::vector<int> reportNumbers();
|
||||
|
||||
void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts);
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
private:
|
||||
QStringList m_fileNames;
|
||||
std::vector<QDateTime> m_timeSteps;
|
||||
std::vector<double> m_daysSinceSimulationStart;
|
||||
|
||||
std::vector< ecl_file_type* > m_ecl_files;
|
||||
};
|
||||
|
||||
@@ -85,23 +85,23 @@ size_t RifEclipseUnifiedRestartFileAccess::timeStepCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
std::vector<QDateTime> timeSteps;
|
||||
std::vector<double> daysSinceSimulationStart;
|
||||
|
||||
return timeSteps().size();
|
||||
this->timeSteps(&timeSteps, &daysSinceSimulationStart);
|
||||
|
||||
return timeSteps.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time steps
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QDateTime> RifEclipseUnifiedRestartFileAccess::timeSteps()
|
||||
void RifEclipseUnifiedRestartFileAccess::timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart)
|
||||
{
|
||||
std::vector<QDateTime> timeSteps;
|
||||
|
||||
if (openFile())
|
||||
{
|
||||
RifEclipseOutputFileTools::timeSteps(m_ecl_file, &timeSteps);
|
||||
RifEclipseOutputFileTools::timeSteps(m_ecl_file, timeSteps, daysSinceSimulationStart);
|
||||
}
|
||||
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
void close();
|
||||
|
||||
size_t timeStepCount();
|
||||
std::vector<QDateTime> timeSteps();
|
||||
void timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart) override;
|
||||
std::vector<int> reportNumbers();
|
||||
|
||||
void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts);
|
||||
|
||||
@@ -657,7 +657,7 @@ void RifReaderEclipseOutput::buildMetaData()
|
||||
progInfo.incrementProgress();
|
||||
|
||||
// Get time steps
|
||||
m_timeSteps = m_dynamicResultsAccess->timeSteps();
|
||||
m_dynamicResultsAccess->timeSteps(&m_timeSteps, &m_daysSinceSimulationStart);
|
||||
std::vector<int> reportNumbers = m_dynamicResultsAccess->reportNumbers();
|
||||
|
||||
QStringList resultNames;
|
||||
@@ -673,7 +673,7 @@ void RifReaderEclipseOutput::buildMetaData()
|
||||
for (int i = 0; i < matrixResultNames.size(); ++i)
|
||||
{
|
||||
size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, matrixResultNames[i], false);
|
||||
matrixModelResults->setTimeStepDates(resIndex, m_timeSteps, reportNumbers);
|
||||
matrixModelResults->setTimeStepDates(resIndex, m_timeSteps, m_daysSinceSimulationStart, reportNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,7 +686,7 @@ void RifReaderEclipseOutput::buildMetaData()
|
||||
for (int i = 0; i < fractureResultNames.size(); ++i)
|
||||
{
|
||||
size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, fractureResultNames[i], false);
|
||||
fractureModelResults->setTimeStepDates(resIndex, m_timeSteps, reportNumbers);
|
||||
fractureModelResults->setTimeStepDates(resIndex, m_timeSteps, m_daysSinceSimulationStart, reportNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,12 +723,17 @@ void RifReaderEclipseOutput::buildMetaData()
|
||||
RifEclipseOutputFileTools::findKeywordsAndItemCount(filesUsedToFindAvailableKeywords, &resultNames, &resultNamesDataItemCounts);
|
||||
|
||||
std::vector<QDateTime> staticDate;
|
||||
std::vector<double> staticDay;
|
||||
std::vector<int> staticReportNumber;
|
||||
{
|
||||
if ( m_timeSteps.size() > 0 )
|
||||
{
|
||||
staticDate.push_back(m_timeSteps.front());
|
||||
}
|
||||
if (m_daysSinceSimulationStart.size() > 0)
|
||||
{
|
||||
staticDay.push_back(m_daysSinceSimulationStart.front());
|
||||
}
|
||||
|
||||
std::vector<int> reportNumbers;
|
||||
if (m_dynamicResultsAccess.notNull())
|
||||
@@ -754,7 +759,7 @@ void RifReaderEclipseOutput::buildMetaData()
|
||||
for (int i = 0; i < matrixResultNames.size(); ++i)
|
||||
{
|
||||
size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i], false);
|
||||
matrixModelResults->setTimeStepDates(resIndex, staticDate, staticReportNumber);
|
||||
matrixModelResults->setTimeStepDates(resIndex, staticDate, staticDay, staticReportNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -769,7 +774,7 @@ void RifReaderEclipseOutput::buildMetaData()
|
||||
for (int i = 0; i < fractureResultNames.size(); ++i)
|
||||
{
|
||||
size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i], false);
|
||||
fractureModelResults->setTimeStepDates(resIndex, staticDate, staticReportNumber);
|
||||
fractureModelResults->setTimeStepDates(resIndex, staticDate, staticDay, staticReportNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -908,6 +913,9 @@ RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBa
|
||||
int cellK = well_conn_get_k( ert_connection );
|
||||
bool isCellOpen = well_conn_open( ert_connection );
|
||||
double volumeRate = well_conn_get_volume_rate( ert_connection);
|
||||
double oilRate = well_conn_get_oil_rate(ert_connection) ;
|
||||
double gasRate = well_conn_get_gas_rate(ert_connection);
|
||||
double waterRate = well_conn_get_water_rate(ert_connection);
|
||||
|
||||
// If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1
|
||||
// Adjust K so index is always in valid grid region
|
||||
@@ -960,6 +968,18 @@ RigWellResultPoint RifReaderEclipseOutput::createWellResultPoint(const RigGridBa
|
||||
resultPoint.m_ertBranchId = ertBranchId;
|
||||
resultPoint.m_ertSegmentId = ertSegmentId;
|
||||
resultPoint.m_flowRate = volumeRate;
|
||||
resultPoint.m_oilRate = oilRate;
|
||||
resultPoint.m_waterRate = waterRate;
|
||||
|
||||
// If field unit, the Gas is in Mega ft^3 while the others are in [stb] (barrel)
|
||||
// we convert gas to stb as well. Based on
|
||||
// 1 [stb] = 0.15898729492800007 [m^3]
|
||||
// 1 [ft] = 0.3048 [m]
|
||||
// megaFt3ToStbFactor = 1.0 / (1.0e-6 * 0.15898729492800007 * ( 1.0 / 0.3048 )^3 )
|
||||
double megaFt3ToStbFactor = 178107.60668;
|
||||
if (m_eclipseCase->unitsType() == RigEclipseCaseData::UNITS_FIELD) gasRate = megaFt3ToStbFactor * gasRate;
|
||||
|
||||
resultPoint.m_gasRate = gasRate;
|
||||
}
|
||||
|
||||
return resultPoint;
|
||||
@@ -1118,7 +1138,9 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid, boo
|
||||
|
||||
m_dynamicResultsAccess->readWellData(ert_well_info, importCompleteMswData);
|
||||
|
||||
std::vector<QDateTime> timeSteps = m_dynamicResultsAccess->timeSteps();
|
||||
std::vector<double> daysSinceSimulationStart;
|
||||
std::vector<QDateTime> timeSteps;
|
||||
m_dynamicResultsAccess->timeSteps(&timeSteps, &daysSinceSimulationStart);
|
||||
std::vector<int> reportNumbers = m_dynamicResultsAccess->reportNumbers();
|
||||
|
||||
bool sameCount = false;
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
|
||||
std::string ertGridName( size_t gridNr );
|
||||
|
||||
static RigWellResultPoint createWellResultPoint(const RigGridBase* grid, const well_conn_type* ert_connection, int ertBranchId, int ertSegmentId, const char* wellName);
|
||||
RigWellResultPoint createWellResultPoint(const RigGridBase* grid, const well_conn_type* ert_connection, int ertBranchId, int ertSegmentId, const char* wellName);
|
||||
|
||||
void importFaults(const QStringList& fileSet, cvf::Collection<RigFault>* faults);
|
||||
|
||||
@@ -93,6 +93,7 @@ private:
|
||||
RigEclipseCaseData* m_eclipseCase;
|
||||
|
||||
std::vector<QDateTime> m_timeSteps;
|
||||
std::vector<double> m_daysSinceSimulationStart;
|
||||
|
||||
ecl_file_type* m_ecl_init_file; // File access to static results
|
||||
cvf::ref<RifEclipseRestartDataAccess> m_dynamicResultsAccess; // File access to dynamic results
|
||||
|
||||
@@ -38,24 +38,28 @@ bool RifReaderMockModel::open(const QString& fileName, RigEclipseCaseData* eclip
|
||||
|
||||
|
||||
std::vector<QDateTime> dates;
|
||||
std::vector<double> days;
|
||||
std::vector<int> repNumbers;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(m_reservoirBuilder.timeStepCount()); i++)
|
||||
{
|
||||
dates.push_back(QDateTime(QDate(2012+i, 6, 1)));
|
||||
days.push_back(i);
|
||||
repNumbers.push_back(i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_reservoirBuilder.resultCount(); i++)
|
||||
{
|
||||
size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, QString("Dynamic_Result_%1").arg(i), false);
|
||||
cellResults->setTimeStepDates(resIdx, dates, repNumbers);
|
||||
cellResults->setTimeStepDates(resIdx, dates, days, repNumbers);
|
||||
}
|
||||
|
||||
if (m_reservoirBuilder.timeStepCount() == 0) return true;
|
||||
|
||||
std::vector<QDateTime> staticDates;
|
||||
staticDates.push_back(dates[0]);
|
||||
std::vector<double> staticDays;
|
||||
staticDays.push_back(days[0]);
|
||||
std::vector<int> staticRepNumbers;
|
||||
staticRepNumbers.push_back(0);
|
||||
|
||||
@@ -68,7 +72,7 @@ bool RifReaderMockModel::open(const QString& fileName, RigEclipseCaseData* eclip
|
||||
if (i > 1) resIndex = i;
|
||||
|
||||
size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, QString("Static_Result_%1%2").arg(resIndex).arg(varEnd), false);
|
||||
cellResults->setTimeStepDates(resIdx, staticDates, staticRepNumbers);
|
||||
cellResults->setTimeStepDates(resIdx, staticDates, staticDays, staticRepNumbers);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +81,7 @@ bool RifReaderMockModel::open(const QString& fileName, RigEclipseCaseData* eclip
|
||||
size_t resIdx; \
|
||||
QString resultName(Name); \
|
||||
resIdx = cellResults->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, resultName, false); \
|
||||
cellResults->setTimeStepDates(resIdx, staticDates, staticRepNumbers); \
|
||||
cellResults->setTimeStepDates(resIdx, staticDates, staticDays, staticRepNumbers); \
|
||||
cellResults->cellScalarResults(resIdx).resize(1); \
|
||||
std::vector<double>& values = cellResults->cellScalarResults(resIdx)[0]; \
|
||||
this->inputProperty(resultName, &values); \
|
||||
|
||||
@@ -31,13 +31,13 @@ RifReaderSettings::RifReaderSettings()
|
||||
{
|
||||
CAF_PDM_InitObject("RifReaderSettings", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&importFaults, "importFaults", true, "Import faults", "", "", "");
|
||||
CAF_PDM_InitField(&importFaults, "importFaults", true, "Import Faults", "", "", "");
|
||||
importFaults.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
CAF_PDM_InitField(&importNNCs, "importSimulationNNCs", true, "Import NNCs", "", "", "");
|
||||
importNNCs.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
CAF_PDM_InitField(&importAdvancedMswData, "importAdvancedMswData", false, "Import advanced MSW data", "", "", "");
|
||||
CAF_PDM_InitField(&importAdvancedMswData, "importAdvancedMswData", false, "Import Advanced MSW Data", "", "", "");
|
||||
importAdvancedMswData.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
CAF_PDM_InitField(&faultIncludeFileAbsolutePathPrefix, "faultIncludeFileAbsolutePathPrefix", QString(), "Fault Include File Absolute Path Prefix", "", "Path used to prefix absolute UNIX paths in fault include statements on Windows", "");
|
||||
@@ -52,7 +52,7 @@ void RifReaderSettings::defineEditorAttribute(const caf::PdmFieldHandle* field,
|
||||
field == &importAdvancedMswData ||
|
||||
field == &importNNCs)
|
||||
{
|
||||
caf::PdmUiCheckBoxEditorAttribute* myAttr = static_cast<caf::PdmUiCheckBoxEditorAttribute*>(attribute);
|
||||
caf::PdmUiCheckBoxEditorAttribute* myAttr = dynamic_cast<caf::PdmUiCheckBoxEditorAttribute*>(attribute);
|
||||
if (myAttr)
|
||||
{
|
||||
myAttr->m_useNativeCheckBoxLabel = true;
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// 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 "RifWellPathImporter.h"
|
||||
|
||||
#include "RifJsonEncodeDecode.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "cafUtils.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
#define ASCII_FILE_DEFAULT_START_INDEX 0
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellData RifWellPathImporter::readWellData(const QString& filePath, size_t indexInFile)
|
||||
{
|
||||
CVF_ASSERT(caf::Utils::fileExists(filePath));
|
||||
|
||||
if (isJsonFile(filePath))
|
||||
{
|
||||
return readJsonWellData(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return readAsciiWellData(filePath, indexInFile);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellData RifWellPathImporter::readWellData(const QString& filePath)
|
||||
{
|
||||
return readWellData(filePath, ASCII_FILE_DEFAULT_START_INDEX);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellMetaData RifWellPathImporter::readWellMetaData(const QString& filePath, size_t indexInFile)
|
||||
{
|
||||
CVF_ASSERT(caf::Utils::fileExists(filePath));
|
||||
|
||||
if (isJsonFile(filePath))
|
||||
{
|
||||
return readJsonWellMetaData(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return readAsciiWellMetaData(filePath, indexInFile);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellMetaData RifWellPathImporter::readWellMetaData(const QString& filePath)
|
||||
{
|
||||
return readWellMetaData(filePath, ASCII_FILE_DEFAULT_START_INDEX);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifWellPathImporter::wellDataCount(const QString& filePath)
|
||||
{
|
||||
if (isJsonFile(filePath))
|
||||
{
|
||||
// Only support JSON files with single well data currently
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<QString, std::vector<RifWellPathImporter::WellData> >::iterator it = m_fileNameToWellDataGroupMap.find(filePath);
|
||||
|
||||
// If we have the file in the map, assume it is already read.
|
||||
if (it != m_fileNameToWellDataGroupMap.end())
|
||||
{
|
||||
return it->second.size();
|
||||
}
|
||||
|
||||
readAllAsciiWellData(filePath);
|
||||
it = m_fileNameToWellDataGroupMap.find(filePath);
|
||||
CVF_ASSERT(it != m_fileNameToWellDataGroupMap.end());
|
||||
|
||||
return it->second.size();;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifWellPathImporter::isJsonFile(const QString & filePath)
|
||||
{
|
||||
QFileInfo fileInfo(filePath);
|
||||
|
||||
if (fileInfo.suffix().compare("json") == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellMetaData RifWellPathImporter::readJsonWellMetaData(const QString & filePath)
|
||||
{
|
||||
ResInsightInternalJson::JsonReader jsonReader;
|
||||
QMap<QString, QVariant> jsonMap = jsonReader.decodeFile(filePath);
|
||||
WellMetaData metadata;
|
||||
|
||||
metadata.m_id = jsonMap["id"].toString();
|
||||
metadata.m_name = jsonMap["name"].toString();
|
||||
metadata.m_sourceSystem = jsonMap["sourceSystem"].toString();
|
||||
metadata.m_utmZone = jsonMap["utmZone"].toString();
|
||||
metadata.m_updateUser = jsonMap["updateUser"].toString();
|
||||
metadata.m_surveyType = jsonMap["surveyType"].toString();
|
||||
|
||||
// Convert updateDate from the following format:
|
||||
// "Number of milliseconds elapsed since midnight Coordinated Universal Time (UTC)
|
||||
// of January 1, 1970, not counting leap seconds"
|
||||
QString updateDateStr = jsonMap["updateDate"].toString().trimmed();
|
||||
uint updateDateUint = updateDateStr.toULongLong() / 1000; // Should be within 32 bit, maximum number is 4294967295 which corresponds to year 2106
|
||||
metadata.m_updateDate.setTime_t(updateDateUint);
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellData RifWellPathImporter::readJsonWellData(const QString& filePath)
|
||||
{
|
||||
ResInsightInternalJson::JsonReader jsonReader;
|
||||
QMap<QString, QVariant> jsonMap = jsonReader.decodeFile(filePath);
|
||||
|
||||
double datumElevation = jsonMap["datumElevation"].toDouble();
|
||||
QList<QVariant> pathList = jsonMap["path"].toList();
|
||||
WellData wellData;
|
||||
wellData.m_wellPathGeometry->setDatumElevation(datumElevation);
|
||||
wellData.m_name = jsonMap["name"].toString();
|
||||
|
||||
foreach(QVariant point, pathList)
|
||||
{
|
||||
QMap<QString, QVariant> coordinateMap = point.toMap();
|
||||
cvf::Vec3d vec3d(coordinateMap["east"].toDouble(), coordinateMap["north"].toDouble(), -(coordinateMap["tvd"].toDouble() - datumElevation));
|
||||
wellData.m_wellPathGeometry->m_wellPathPoints.push_back(vec3d);
|
||||
double measuredDepth = coordinateMap["md"].toDouble();
|
||||
wellData.m_wellPathGeometry->m_measuredDepths.push_back(measuredDepth);
|
||||
}
|
||||
return wellData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifWellPathImporter::readAllAsciiWellData(const QString& filePath)
|
||||
{
|
||||
std::map<QString, std::vector<RifWellPathImporter::WellData> >::iterator it = m_fileNameToWellDataGroupMap.find(filePath);
|
||||
|
||||
// If we have the file in the map, assume it is already read.
|
||||
if (it != m_fileNameToWellDataGroupMap.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the data container
|
||||
std::vector<RifWellPathImporter::WellData>& fileWellDataArray = m_fileNameToWellDataGroupMap[filePath];
|
||||
|
||||
std::ifstream stream(filePath.toLatin1().data());
|
||||
double x(HUGE_VAL), y(HUGE_VAL), tvd(HUGE_VAL), md(HUGE_VAL);
|
||||
|
||||
bool hasReadWellPointInCurrentWell = false;
|
||||
|
||||
while (stream.good())
|
||||
{
|
||||
// First check if we can read a number
|
||||
stream >> x;
|
||||
if (stream.good()) // If we can, assume this line is a well point entry
|
||||
{
|
||||
stream >> y >> tvd >> md;
|
||||
if (!stream.good())
|
||||
{
|
||||
// -999 or otherwise to few numbers before some word
|
||||
if (x != -999)
|
||||
{
|
||||
// Error in file: missing numbers at this line
|
||||
|
||||
}
|
||||
stream.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fileWellDataArray.size())
|
||||
{
|
||||
fileWellDataArray.push_back(RifWellPathImporter::WellData());
|
||||
fileWellDataArray.back().m_wellPathGeometry = new RigWellPath();
|
||||
}
|
||||
|
||||
cvf::Vec3d wellPoint(x, y, -tvd);
|
||||
fileWellDataArray.back().m_wellPathGeometry->m_wellPathPoints.push_back(wellPoint);
|
||||
fileWellDataArray.back().m_wellPathGeometry->m_measuredDepths.push_back(md);
|
||||
|
||||
x = HUGE_VAL;
|
||||
y = HUGE_VAL;
|
||||
tvd = HUGE_VAL;
|
||||
md = HUGE_VAL;
|
||||
|
||||
hasReadWellPointInCurrentWell = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could not read one double.
|
||||
// we assume there is a comment line or a well path description
|
||||
stream.clear();
|
||||
|
||||
std::string line;
|
||||
std::getline(stream, line, '\n');
|
||||
// Skip possible comment lines (-- is used in eclipse, so Haakon Høgstøl considered it smart to skip these here as well)
|
||||
// The first "-" is eaten by the stream >> x above
|
||||
if (line.find("-") == 0 || line.find("#") == 0)
|
||||
{
|
||||
// Comment line, just ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the first and the last position of any quotes (and do not care to match quotes)
|
||||
size_t quoteStartIdx = line.find_first_of("'`´’‘");
|
||||
size_t quoteEndIdx = line.find_last_of("'`´’‘");
|
||||
|
||||
std::string wellName;
|
||||
bool haveAPossibleWellStart = false;
|
||||
|
||||
if (quoteStartIdx < line.size() -1)
|
||||
{
|
||||
// Extract the text between the quotes
|
||||
wellName = line.substr(quoteStartIdx + 1, quoteEndIdx - 1 - quoteStartIdx);
|
||||
haveAPossibleWellStart = true;
|
||||
}
|
||||
else if (quoteStartIdx > line.length())
|
||||
{
|
||||
// We did not find any quotes
|
||||
|
||||
// Supported alternatives are
|
||||
// name <WellNameA>
|
||||
// wellname: <WellNameA>
|
||||
std::string lineLowerCase = line;
|
||||
transform(lineLowerCase.begin(), lineLowerCase.end(), lineLowerCase.begin(), ::tolower);
|
||||
|
||||
std::string tokenName = "name";
|
||||
std::size_t foundNameIdx = lineLowerCase.find(tokenName);
|
||||
if (foundNameIdx != std::string::npos)
|
||||
{
|
||||
std::string tokenColon = ":";
|
||||
std::size_t foundColonIdx = lineLowerCase.find(tokenColon, foundNameIdx);
|
||||
if (foundColonIdx != std::string::npos)
|
||||
{
|
||||
wellName = line.substr(foundColonIdx + tokenColon.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
wellName = line.substr(foundNameIdx + tokenName.length());
|
||||
}
|
||||
|
||||
haveAPossibleWellStart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpret the whole line as the well name.
|
||||
|
||||
QString name = line.c_str();
|
||||
if (!name.trimmed().isEmpty())
|
||||
{
|
||||
wellName = name.trimmed().toStdString();
|
||||
haveAPossibleWellStart = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (haveAPossibleWellStart)
|
||||
{
|
||||
// Create a new Well data if we have read some data into the previous one.
|
||||
// if not, just overwrite the name
|
||||
if (hasReadWellPointInCurrentWell || fileWellDataArray.size() == 0)
|
||||
{
|
||||
fileWellDataArray.push_back(RifWellPathImporter::WellData());
|
||||
fileWellDataArray.back().m_wellPathGeometry = new RigWellPath();
|
||||
}
|
||||
|
||||
QString name = wellName.c_str();
|
||||
if (!name.trimmed().isEmpty())
|
||||
{
|
||||
// Do not overwrite the name aquired from a line above, if this line is empty
|
||||
fileWellDataArray.back().m_name = name.trimmed();
|
||||
}
|
||||
hasReadWellPointInCurrentWell = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellData RifWellPathImporter::readAsciiWellData(const QString& filePath, size_t indexInFile)
|
||||
{
|
||||
readAllAsciiWellData(filePath);
|
||||
|
||||
std::map<QString, std::vector<RifWellPathImporter::WellData> >::iterator it = m_fileNameToWellDataGroupMap.find(filePath);
|
||||
|
||||
CVF_ASSERT(it != m_fileNameToWellDataGroupMap.end());
|
||||
|
||||
if (indexInFile < it->second.size())
|
||||
{
|
||||
return it->second[indexInFile];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error : The ascii well path file does not contain that many well paths
|
||||
return RifWellPathImporter::WellData();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifWellPathImporter::WellMetaData RifWellPathImporter::readAsciiWellMetaData(const QString & filePath, size_t indexInFile)
|
||||
{
|
||||
// No metadata in ASCII files
|
||||
return WellMetaData();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifWellPathImporter::clear()
|
||||
{
|
||||
m_fileNameToWellDataGroupMap.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifWellPathImporter::removeFilePath(const QString& filePath)
|
||||
{
|
||||
m_fileNameToWellDataGroupMap.erase(filePath);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// 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 "RigWellPath.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RifWellPathImporter
|
||||
{
|
||||
public:
|
||||
struct WellData
|
||||
{
|
||||
QString m_name;
|
||||
cvf::ref<RigWellPath> m_wellPathGeometry;
|
||||
};
|
||||
|
||||
struct WellMetaData
|
||||
{
|
||||
QString m_name;
|
||||
QString m_id;
|
||||
QString m_sourceSystem;
|
||||
QString m_utmZone;
|
||||
QString m_updateUser;
|
||||
QString m_surveyType;
|
||||
QDateTime m_updateDate;
|
||||
};
|
||||
|
||||
WellData readWellData(const QString& filePath, size_t indexInFile);
|
||||
WellData readWellData(const QString& filePath);
|
||||
WellMetaData readWellMetaData(const QString& filePath, size_t indexInFile);
|
||||
WellMetaData readWellMetaData(const QString& filePath);
|
||||
size_t wellDataCount(const QString& filePath);
|
||||
|
||||
void clear();
|
||||
void removeFilePath(const QString& filePath);
|
||||
|
||||
private:
|
||||
WellData readJsonWellData(const QString& filePath);
|
||||
WellMetaData readJsonWellMetaData(const QString& filePath);
|
||||
WellData readAsciiWellData(const QString& filePath, size_t indexInFile);
|
||||
WellMetaData readAsciiWellMetaData(const QString& filePath, size_t indexInFile);
|
||||
void readAllAsciiWellData(const QString& filePath);
|
||||
|
||||
inline bool isJsonFile(const QString& filePath);
|
||||
|
||||
std::map<QString, std::vector<RifWellPathImporter::WellData> > m_fileNameToWellDataGroupMap;
|
||||
};
|
||||
Reference in New Issue
Block a user