mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Roff support with submodule
* Roff: Add initial roff support (with roffcpp as submodule). * Roff: Create viewer when importing roff files. * Roff: add timing for roff import. * Roff: precompute active cell indexes. * Roff: parallelize using OpenMP. * Roff: Handle exceptions when importing. * Roff: improvements from review. * Invert ordering Co-authored-by: Magne Sjaastad <magne.sjaastad@ceetronsolutions.com>
This commit is contained in:
parent
38bfa9ef1f
commit
8b51160ac4
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -13,3 +13,6 @@
|
||||
[submodule "ThirdParty/custom-opm-common/opm-common"]
|
||||
path = ThirdParty/custom-opm-common/opm-common
|
||||
url = https://github.com/CeetronSolutions/opm-common
|
||||
[submodule "ThirdParty/roffcpp"]
|
||||
path = ThirdParty/roffcpp
|
||||
url = https://github.com/CeetronSolutions/roffcpp
|
||||
|
@ -271,6 +271,10 @@ RiaDefines::ImportFileType RiaDefines::obtainFileTypeFromFileName( const QString
|
||||
{
|
||||
return ImportFileType::ECLIPSE_INPUT_FILE;
|
||||
}
|
||||
else if ( fileName.endsWith( "ROFF", Qt::CaseInsensitive ) || fileName.endsWith( "ROFFASC", Qt::CaseInsensitive ) )
|
||||
{
|
||||
return ImportFileType::ROFF_FILE;
|
||||
}
|
||||
else if ( fileName.endsWith( "SMSPEC", Qt::CaseInsensitive ) )
|
||||
{
|
||||
return ImportFileType::ECLIPSE_SUMMARY_FILE;
|
||||
|
@ -126,8 +126,9 @@ enum class ImportFileType
|
||||
ECLIPSE_SUMMARY_FILE = 0x08,
|
||||
GEOMECH_ODB_FILE = 0x10,
|
||||
RESINSIGHT_PROJECT_FILE = 0x20,
|
||||
ROFF_FILE = 0x30,
|
||||
ECLIPSE_RESULT_GRID = ECLIPSE_GRID_FILE | ECLIPSE_EGRID_FILE,
|
||||
ANY_ECLIPSE_FILE = ECLIPSE_RESULT_GRID | ECLIPSE_INPUT_FILE | ECLIPSE_SUMMARY_FILE,
|
||||
ANY_ECLIPSE_FILE = ECLIPSE_RESULT_GRID | ECLIPSE_INPUT_FILE | ECLIPSE_SUMMARY_FILE | ROFF_FILE,
|
||||
ANY_IMPORT_FILE = 0xFF
|
||||
};
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRoffCase.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimSummaryCaseMainCollection.h"
|
||||
@ -508,3 +509,51 @@ bool RiaImportEclipseCaseTools::addEclipseCases( const QStringList& fil
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiaImportEclipseCaseTools::openRoffCaseFromFileNames( const QStringList& fileNames, bool createDefaultView )
|
||||
{
|
||||
CAF_ASSERT( !fileNames.empty() );
|
||||
|
||||
auto* roffCase = new RimRoffCase();
|
||||
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
RimProject* project = app->project();
|
||||
project->assignCaseIdToCase( roffCase );
|
||||
roffCase->setGridFileName( fileNames[0] );
|
||||
|
||||
bool gridImportSuccess = roffCase->openEclipseGridFile();
|
||||
if ( !gridImportSuccess )
|
||||
{
|
||||
RiaLogging::error( "Failed to import grid" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels()
|
||||
: nullptr;
|
||||
if ( !analysisModels ) return -1;
|
||||
|
||||
analysisModels->cases.push_back( roffCase );
|
||||
|
||||
RimEclipseView* eclipseView = nullptr;
|
||||
if ( createDefaultView )
|
||||
{
|
||||
eclipseView = roffCase->createAndAddReservoirView();
|
||||
|
||||
eclipseView->cellResult()->setResultType( RiaDefines::ResultCatType::INPUT_PROPERTY );
|
||||
|
||||
if ( RiaGuiApplication::isRunning() )
|
||||
{
|
||||
if ( RiuMainWindow::instance() )
|
||||
RiuMainWindow::instance()->selectAsCurrentItem( eclipseView->cellResult() );
|
||||
}
|
||||
|
||||
eclipseView->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
analysisModels->updateConnectedEditors();
|
||||
|
||||
return roffCase->caseId();
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ public:
|
||||
bool createView,
|
||||
std::shared_ptr<RifReaderSettings> readerSettings = nullptr );
|
||||
|
||||
static int openRoffCaseFromFileNames( const QStringList& fileNames, bool createDefaultView );
|
||||
|
||||
private:
|
||||
static int openEclipseCaseShowTimeStepFilterImpl( const QString& fileName,
|
||||
bool showTimeStepFilter,
|
||||
|
@ -19,6 +19,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicEclipseHideFaultFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicEclipseShowOnlyFaultFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicRenameCaseFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportRoffCaseFeature.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -42,6 +43,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicEclipseHideFaultFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicEclipseShowOnlyFaultFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicRenameCaseFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportRoffCaseFeature.cpp
|
||||
)
|
||||
|
||||
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
@ -0,0 +1,48 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicImportRoffCaseFeature.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicImportRoffCaseFeature, "RicImportRoffCaseFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicImportRoffCaseFeature::isCommandEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportRoffCaseFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
RicImportGeneralDataFeature::openFileDialog( RiaDefines::ImportFileType::ROFF_FILE );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportRoffCaseFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setIcon( QIcon( ":/EclipseInput48x48.png" ) );
|
||||
actionToSetup->setText( "Import Roff Case" );
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RicImportGeneralDataFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicImportRoffCaseFeature : public RicImportGeneralDataFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
@ -55,6 +55,7 @@ RicImportGeneralDataFeature::OpenCaseResults
|
||||
QStringList eclipseCaseFiles;
|
||||
QStringList eclipseInputFiles;
|
||||
QStringList eclipseSummaryFiles;
|
||||
QStringList roffFiles;
|
||||
|
||||
for ( const QString& fileName : fileNames )
|
||||
{
|
||||
@ -71,6 +72,10 @@ RicImportGeneralDataFeature::OpenCaseResults
|
||||
{
|
||||
eclipseSummaryFiles.push_back( fileName );
|
||||
}
|
||||
else if ( fileTypeAsInt & int( ImportFileType::ROFF_FILE ) )
|
||||
{
|
||||
roffFiles.push_back( fileName );
|
||||
}
|
||||
}
|
||||
|
||||
OpenCaseResults results;
|
||||
@ -104,6 +109,17 @@ RicImportGeneralDataFeature::OpenCaseResults
|
||||
RiaApplication::instance()->setLastUsedDialogDirectory( defaultDirectoryLabel( ImportFileType::ECLIPSE_SUMMARY_FILE ),
|
||||
defaultDir );
|
||||
}
|
||||
if ( !roffFiles.empty() )
|
||||
{
|
||||
if ( !openRoffCaseFromFileNames( roffFiles, createDefaultView, results.createdCaseIds ) )
|
||||
{
|
||||
return OpenCaseResults();
|
||||
}
|
||||
results.roffFiles = roffFiles;
|
||||
RiaApplication::instance()->setLastUsedDialogDirectory( defaultDirectoryLabel( ImportFileType::ROFF_FILE ),
|
||||
defaultDir );
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -167,6 +183,7 @@ QStringList RicImportGeneralDataFeature::getEclipseFileNamesWithDialog( RiaDefin
|
||||
QString eclipseEGridFilePattern( "*.EGRID" );
|
||||
QString eclipseInputFilePattern( "*.GRDECL" );
|
||||
QString eclipseSummaryFilePattern( "*.SMSPEC" );
|
||||
QString roffFilePattern( "*.ROFF *.ROFFASC" );
|
||||
|
||||
QStringList filePatternTexts;
|
||||
if ( fileType == ImportFileType::ANY_ECLIPSE_FILE )
|
||||
@ -196,6 +213,10 @@ QStringList RicImportGeneralDataFeature::getEclipseFileNamesWithDialog( RiaDefin
|
||||
{
|
||||
filePatternTexts += QString( "Eclipse Summary File (%1)" ).arg( eclipseSummaryFilePattern );
|
||||
}
|
||||
if ( fileTypeAsInt & int( ImportFileType::ROFF_FILE ) )
|
||||
{
|
||||
filePatternTexts += QString( "Roff File (%1)" ).arg( roffFilePattern );
|
||||
}
|
||||
|
||||
QString fullPattern = filePatternTexts.join( ";;" );
|
||||
|
||||
@ -289,3 +310,22 @@ bool RicImportGeneralDataFeature::openSummaryCaseFromFileNames( const QStringLis
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicImportGeneralDataFeature::openRoffCaseFromFileNames( const QStringList& fileNames,
|
||||
bool createDefaultView,
|
||||
std::vector<int>& createdCaseIds )
|
||||
{
|
||||
CAF_ASSERT( !fileNames.empty() );
|
||||
|
||||
auto generatedCaseId = RiaImportEclipseCaseTools::openRoffCaseFromFileNames( fileNames, createDefaultView );
|
||||
if ( generatedCaseId >= 0 )
|
||||
{
|
||||
RiaApplication::instance()->addToRecentFiles( fileNames[0] );
|
||||
createdCaseIds.push_back( generatedCaseId );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -42,12 +42,14 @@ public:
|
||||
QStringList eclipseCaseFiles;
|
||||
QStringList eclipseInputFiles;
|
||||
QStringList eclipseSummaryFiles;
|
||||
QStringList roffFiles;
|
||||
|
||||
std::vector<int> createdCaseIds;
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return !( eclipseCaseFiles.empty() && eclipseInputFiles.empty() && eclipseSummaryFiles.empty() );
|
||||
return !( eclipseCaseFiles.empty() && eclipseInputFiles.empty() && eclipseSummaryFiles.empty() &&
|
||||
roffFiles.empty() );
|
||||
}
|
||||
};
|
||||
|
||||
@ -73,4 +75,7 @@ protected:
|
||||
bool createDefaultView,
|
||||
std::vector<int>& createdCaseIds );
|
||||
static bool openSummaryCaseFromFileNames( const QStringList& fileNames, bool doCreateDefaultPlot = true );
|
||||
static bool openRoffCaseFromFileNames( const QStringList& fileNames,
|
||||
bool createDefaultView,
|
||||
std::vector<int>& createdCaseIds );
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifTextDataTableFormatter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseInputFileTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifRoffFileTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseOutputFileTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartDataAccess.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartFilesetAccess.h
|
||||
@ -78,6 +79,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifTextDataTableFormatter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseInputFileTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifRoffFileTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseOutputFileTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartDataAccess.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseRestartFilesetAccess.cpp
|
||||
|
510
ApplicationLibCode/FileInterface/RifRoffFileTools.cpp
Normal file
510
ApplicationLibCode/FileInterface/RifRoffFileTools.cpp
Normal file
@ -0,0 +1,510 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifRoffFileTools.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "cafProgressInfo.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "Reader.hpp"
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifRoffFileTools::RifRoffFileTools()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifRoffFileTools::~RifRoffFileTools()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifRoffFileTools::openGridFile( const QString& fileName, RigEclipseCaseData* eclipseCase, QString* errorMessages )
|
||||
{
|
||||
RiaLogging::info( QString( "Opening roff file: %1" ).arg( fileName ) );
|
||||
|
||||
std::string filename = fileName.toStdString();
|
||||
|
||||
std::ifstream stream( filename, std::ios::binary );
|
||||
if ( !stream.good() )
|
||||
{
|
||||
if ( errorMessages ) *errorMessages = QString( "Unable to open roff file" );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto getInt = []( auto values, const std::string& name ) {
|
||||
auto v = std::find_if( values.begin(), values.end(), [&name]( const auto& arg ) { return arg.first == name; } );
|
||||
if ( v != values.end() )
|
||||
return std::get<int>( v->second );
|
||||
else
|
||||
throw std::runtime_error( "Missing parameter (integer): " + name );
|
||||
};
|
||||
|
||||
auto getFloat = []( auto values, const std::string& name ) {
|
||||
auto v = std::find_if( values.begin(), values.end(), [&name]( const auto& arg ) { return arg.first == name; } );
|
||||
if ( v != values.end() )
|
||||
return std::get<float>( v->second );
|
||||
else
|
||||
throw std::runtime_error( "Missing parameter (float): " + name );
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
const auto totalStart = high_resolution_clock::now();
|
||||
|
||||
Reader reader( stream );
|
||||
reader.parse();
|
||||
|
||||
const auto tokenizeDone = high_resolution_clock::now();
|
||||
|
||||
std::vector<std::pair<std::string, RoffScalar>> values = reader.scalarNamedValues();
|
||||
std::vector<std::pair<std::string, Token::Kind>> arrayTypes = reader.getNamedArrayTypes();
|
||||
|
||||
size_t nx = getInt( values, "dimensions.nX" );
|
||||
size_t ny = getInt( values, "dimensions.nY" );
|
||||
size_t nz = getInt( values, "dimensions.nZ" );
|
||||
RiaLogging::info( QString( "Grid dimensions: %1 %2 %3" ).arg( nx ).arg( ny ).arg( nz ) );
|
||||
|
||||
float xOffset = getFloat( values, "translate.xoffset" );
|
||||
float yOffset = getFloat( values, "translate.yoffset" );
|
||||
float zOffset = getFloat( values, "translate.zoffset" );
|
||||
RiaLogging::info( QString( "Offset: %1 %2 %3" ).arg( xOffset ).arg( yOffset ).arg( zOffset ) );
|
||||
|
||||
float xScale = getFloat( values, "scale.xscale" );
|
||||
float yScale = getFloat( values, "scale.yscale" );
|
||||
float zScale = getFloat( values, "scale.zscale" );
|
||||
RiaLogging::info( QString( "Scale: %1 %2 %3" ).arg( xScale ).arg( yScale ).arg( zScale ) );
|
||||
|
||||
std::vector<int> layers = reader.getIntArray( "subgrids.nLayers" );
|
||||
std::vector<float> cornerLines = reader.getFloatArray( "cornerLines.data" );
|
||||
std::vector<float> zValues = reader.getFloatArray( "zvalues.data" );
|
||||
std::vector<char> splitEnz = reader.getByteArray( "zvalues.splitEnz" );
|
||||
std::vector<char> active = reader.getByteArray( "active.data" );
|
||||
|
||||
const auto parsingDone = high_resolution_clock::now();
|
||||
|
||||
RiaLogging::info( QString( "Layers: %1" ).arg( layers.size() ) );
|
||||
RiaLogging::info( QString( "Corner lines: %1" ).arg( cornerLines.size() ) );
|
||||
RiaLogging::info( QString( "Z values: %1" ).arg( zValues.size() ) );
|
||||
RiaLogging::info( QString( "Splitenz: %1" ).arg( splitEnz.size() ) );
|
||||
RiaLogging::info( QString( "Active: %1" ).arg( active.size() ) );
|
||||
|
||||
unsigned int zCornerSize = static_cast<unsigned int>( ( nx + 1 ) * ( ny + 1 ) * ( nz + 1 ) * 4u );
|
||||
std::vector<float> zCorners( zCornerSize, 0.0 );
|
||||
|
||||
interpretSplitenzData( static_cast<int>( nz ) + 1, zOffset, zScale, splitEnz, zValues, zCorners );
|
||||
|
||||
RiaLogging::info( QString( "zCorners: %1" ).arg( zCorners.size() ) );
|
||||
|
||||
RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
CVF_ASSERT( activeCellInfo );
|
||||
|
||||
RigActiveCellInfo* fractureActiveCellInfo =
|
||||
eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL );
|
||||
CVF_ASSERT( fractureActiveCellInfo );
|
||||
|
||||
RigMainGrid* mainGrid = eclipseCase->mainGrid();
|
||||
CVF_ASSERT( mainGrid );
|
||||
|
||||
cvf::Vec3st gridPointDim( nx + 1, ny + 1, nz + 1 );
|
||||
mainGrid->setGridPointDimensions( gridPointDim );
|
||||
mainGrid->setGridName( "Main grid" );
|
||||
|
||||
size_t totalCellCount = nx * ny * nz;
|
||||
|
||||
activeCellInfo->setGridCount( 1 );
|
||||
fractureActiveCellInfo->setGridCount( 1 );
|
||||
|
||||
activeCellInfo->setReservoirCellCount( totalCellCount );
|
||||
fractureActiveCellInfo->setReservoirCellCount( totalCellCount );
|
||||
|
||||
// Reserve room for the cells and nodes and fill them with data
|
||||
mainGrid->globalCellArray().reserve( totalCellCount );
|
||||
mainGrid->nodes().reserve( 8 * totalCellCount );
|
||||
|
||||
int progTicks = 100;
|
||||
caf::ProgressInfo progInfo( progTicks, "" );
|
||||
|
||||
int cellCount = static_cast<int>( totalCellCount );
|
||||
size_t cellStartIndex = mainGrid->globalCellArray().size();
|
||||
size_t nodeStartIndex = mainGrid->nodes().size();
|
||||
|
||||
RigCell defaultCell;
|
||||
defaultCell.setHostGrid( mainGrid );
|
||||
mainGrid->globalCellArray().resize( cellStartIndex + cellCount, defaultCell );
|
||||
|
||||
mainGrid->nodes().resize( nodeStartIndex + static_cast<size_t>( cellCount ) * 8, cvf::Vec3d( 0, 0, 0 ) );
|
||||
|
||||
const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
|
||||
|
||||
cvf::Vec3d offset( xOffset, yOffset, zOffset );
|
||||
cvf::Vec3d scale( xScale, yScale, zScale );
|
||||
|
||||
std::vector<int> activeCells;
|
||||
convertToReservoirIndexOrder( nx, ny, nz, active, activeCells );
|
||||
|
||||
// Precompute the active cell matrix index
|
||||
size_t numActiveCells = computeActiveCellMatrixIndex( activeCells );
|
||||
|
||||
// Loop over cells and fill them with data
|
||||
#pragma omp parallel
|
||||
{
|
||||
int cellCountPerThread = cellCount;
|
||||
#ifdef USE_OPENMP
|
||||
cellCountPerThread = std::max( 1, cellCount / omp_get_num_threads() );
|
||||
#endif
|
||||
|
||||
int computedThreadCellCount = 0;
|
||||
|
||||
int cellsPrProgressTick = std::max( 1, cellCountPerThread / progTicks );
|
||||
int maxProgressCell = cellsPrProgressTick * progTicks;
|
||||
|
||||
#pragma omp for
|
||||
for ( int gridLocalCellIndex = 0; gridLocalCellIndex < cellCount; ++gridLocalCellIndex )
|
||||
{
|
||||
RigCell& cell = mainGrid->globalCellArray()[cellStartIndex + gridLocalCellIndex];
|
||||
|
||||
cell.setGridLocalCellIndex( gridLocalCellIndex );
|
||||
|
||||
// Active cell index
|
||||
int matrixActiveIndex = activeCells[gridLocalCellIndex];
|
||||
if ( matrixActiveIndex != -1 )
|
||||
{
|
||||
activeCellInfo->setCellResultIndex( cellStartIndex + gridLocalCellIndex, matrixActiveIndex );
|
||||
}
|
||||
|
||||
cell.setParentCellIndex( cvf::UNDEFINED_SIZE_T );
|
||||
|
||||
// Corner coordinates
|
||||
for ( int cIdx = 0; cIdx < 8; ++cIdx )
|
||||
{
|
||||
double* point =
|
||||
mainGrid->nodes()[nodeStartIndex + (size_t)gridLocalCellIndex * 8 + cellMappingECLRi[cIdx]].ptr();
|
||||
auto corner = getCorner( *mainGrid, cornerLines, zCorners, gridLocalCellIndex, cIdx, offset, scale );
|
||||
|
||||
point[0] = corner.x();
|
||||
point[1] = corner.y();
|
||||
point[2] = corner.z();
|
||||
|
||||
cell.cornerIndices()[cIdx] = nodeStartIndex + (size_t)gridLocalCellIndex * 8 + cIdx;
|
||||
}
|
||||
|
||||
// Mark inactive long pyramid looking cells as invalid
|
||||
cell.setInvalid( cell.isLongPyramidCell() );
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
if ( omp_get_thread_num() == 0 )
|
||||
{
|
||||
computedThreadCellCount++;
|
||||
if ( computedThreadCellCount <= maxProgressCell && computedThreadCellCount % cellsPrProgressTick == 0 )
|
||||
progInfo.incrementProgress();
|
||||
}
|
||||
#else
|
||||
computedThreadCellCount++;
|
||||
if ( computedThreadCellCount <= maxProgressCell && computedThreadCellCount % cellsPrProgressTick == 0 )
|
||||
progInfo.incrementProgress();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
activeCellInfo->setGridActiveCellCounts( 0, numActiveCells );
|
||||
fractureActiveCellInfo->setGridActiveCellCounts( 0, 0 );
|
||||
|
||||
mainGrid->initAllSubGridsParentGridPointer();
|
||||
activeCellInfo->computeDerivedData();
|
||||
fractureActiveCellInfo->computeDerivedData();
|
||||
|
||||
auto gridConstructionDone = high_resolution_clock::now();
|
||||
|
||||
auto tokenizeDuration = duration_cast<milliseconds>( tokenizeDone - totalStart );
|
||||
RiaLogging::info( QString( "Tokenizing: %1 ms" ).arg( tokenizeDuration.count() ) );
|
||||
|
||||
auto parsingDuration = duration_cast<milliseconds>( parsingDone - tokenizeDone );
|
||||
RiaLogging::info( QString( "Parsing: %1 ms" ).arg( parsingDuration.count() ) );
|
||||
|
||||
auto gridConstructionDuration = duration_cast<milliseconds>( gridConstructionDone - parsingDone );
|
||||
RiaLogging::info( QString( "Grid Construction: %1 ms" ).arg( gridConstructionDuration.count() ) );
|
||||
|
||||
auto totalDuration = duration_cast<milliseconds>( gridConstructionDone - totalStart );
|
||||
RiaLogging::info( QString( "Total: %1 ms" ).arg( totalDuration.count() ) );
|
||||
}
|
||||
catch ( std::runtime_error& err )
|
||||
{
|
||||
RiaLogging::error( QString( "Roff file import failed: %1" ).arg( err.what() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// The indexing conventions for vertices in Roff file
|
||||
//
|
||||
// 1-------------0
|
||||
// /| /|
|
||||
// / | / | /j
|
||||
// / | / | /
|
||||
// 3-------------2 | *---i
|
||||
// | | | | |
|
||||
// | 5---------|---4 |
|
||||
// | / | / |k
|
||||
// | / | /
|
||||
// |/ |/
|
||||
// 7-------------6
|
||||
// vertex indices
|
||||
//
|
||||
|
||||
//
|
||||
// The indexing conventions for vertices in ResInsight
|
||||
//
|
||||
// 7-------------6 |k
|
||||
// /| /| | /j
|
||||
// / | / | |/
|
||||
// / | / | *---i
|
||||
// 4-------------5 |
|
||||
// | | | |
|
||||
// | 3---------|---2
|
||||
// | / | /
|
||||
// | / | /
|
||||
// |/ |/
|
||||
// 0-------------1
|
||||
// vertex indices
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RifRoffFileTools::getCorner( const RigMainGrid& grid,
|
||||
const std::vector<float>& cornerLines,
|
||||
const std::vector<float>& zcorn,
|
||||
size_t cellIdx,
|
||||
int cornerIdx,
|
||||
const cvf::Vec3d& offset,
|
||||
const cvf::Vec3d& scale )
|
||||
{
|
||||
size_t iOffset = 0;
|
||||
if ( !( cornerIdx == 1 || cornerIdx == 3 || cornerIdx == 5 || cornerIdx == 7 ) )
|
||||
{
|
||||
iOffset = 1;
|
||||
}
|
||||
|
||||
size_t jOffset = 0;
|
||||
if ( !( cornerIdx == 2 || cornerIdx == 3 || cornerIdx == 6 || cornerIdx == 7 ) )
|
||||
{
|
||||
jOffset = 1;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t k;
|
||||
grid.ijkFromCellIndex( cellIdx, &i, &j, &k );
|
||||
|
||||
size_t ny = grid.cellCountJ();
|
||||
size_t nz = grid.cellCountK();
|
||||
|
||||
size_t cOffset = ( ( i + iOffset ) * ( ny + 1 ) + ( j + jOffset ) ) * 6;
|
||||
|
||||
cvf::Vec3d top( cornerLines[cOffset], cornerLines[cOffset + 1], cornerLines[cOffset + 2] );
|
||||
cvf::Vec3d bottom( cornerLines[cOffset + 3], cornerLines[cOffset + 4], cornerLines[cOffset + 5] );
|
||||
|
||||
int adjustedCornerIdx = cornerIdx;
|
||||
if ( cornerIdx == 4 ) adjustedCornerIdx = 0;
|
||||
if ( cornerIdx == 5 ) adjustedCornerIdx = 1;
|
||||
if ( cornerIdx == 6 ) adjustedCornerIdx = 2;
|
||||
if ( cornerIdx == 7 ) adjustedCornerIdx = 3;
|
||||
|
||||
// Find the correct offset k direction
|
||||
size_t kOffset = 0;
|
||||
if ( cornerIdx > 3 )
|
||||
{
|
||||
kOffset = 1;
|
||||
}
|
||||
|
||||
size_t zOffset = ( ( i + iOffset ) * ( ny + 1 ) * ( nz + 1 ) + ( j + jOffset ) * ( nz + 1 ) + ( k + kOffset ) ) * 4 +
|
||||
adjustedCornerIdx;
|
||||
|
||||
double z = -zcorn[zOffset];
|
||||
double x = interpolate( top, bottom, z, 0 ) + offset.x();
|
||||
double y = interpolate( top, bottom, z, 1 ) + offset.y();
|
||||
|
||||
cvf::Vec3d result = cvf::Vec3d( x, y, z );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Adapted from xtgeo
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RifRoffFileTools::interpolate( const cvf::Vec3d& top, const cvf::Vec3d& bottom, double z, int idx )
|
||||
{
|
||||
if ( fabs( bottom[idx] - top[idx] ) > 0.01 )
|
||||
{
|
||||
return top[idx] - ( z - top.z() ) * ( top[idx] - bottom[idx] ) / ( bottom.z() - top.z() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return top[idx];
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Adapted from xtgeo: https://github.com/equinor/xtgeo/blob/master/src/clib/xtg/grd3d_roff2xtgeo_splitenz.c
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifRoffFileTools::interpretSplitenzData( int nz,
|
||||
float zoffset,
|
||||
float zscale,
|
||||
const std::vector<char>& splitenz,
|
||||
const std::vector<float>& zdata,
|
||||
std::vector<float>& zcornsv )
|
||||
|
||||
{
|
||||
// We Read one corner line (pillar) from zdata at a time (one for each
|
||||
// i,j), transform it according to zoffset and zscale, and put it in to
|
||||
// zcornsv in reverse order.
|
||||
|
||||
// As i and j order and size is the same for both zcornsv and zdata, we can
|
||||
// ignore it here and place one pillar at the time regardless of how many
|
||||
// pillars there are.
|
||||
|
||||
size_t nzcorn = zcornsv.size();
|
||||
size_t nsplitenz = splitenz.size();
|
||||
size_t nzdata = zdata.size();
|
||||
|
||||
size_t num_row = 4 * static_cast<size_t>( nz );
|
||||
if ( nzcorn % num_row != 0 ) throw std::runtime_error( "Incorrect size of zcorn." );
|
||||
if ( nsplitenz != nzcorn / 4 ) throw std::runtime_error( "Incorrect size of splitenz." );
|
||||
|
||||
std::vector<float> pillar( num_row, 0.0 );
|
||||
size_t it_zdata = 0, it_splitenz = 0, it_zcorn = 0;
|
||||
while ( it_zcorn < nzcorn )
|
||||
{
|
||||
for ( size_t it_pillar = 0; it_pillar < num_row; )
|
||||
{
|
||||
char split = splitenz[it_splitenz++];
|
||||
if ( split == 1 )
|
||||
{
|
||||
// There is one value for this corner which
|
||||
// we must duplicate 4 times in zcornsv
|
||||
if ( it_zdata >= nzdata ) throw std::runtime_error( "Incorrect size of zdata" );
|
||||
float val = ( zdata[it_zdata++] + zoffset ) * zscale;
|
||||
for ( int n = 0; n < 4; n++ )
|
||||
{
|
||||
pillar[it_pillar++] = val;
|
||||
}
|
||||
}
|
||||
else if ( split == 4 )
|
||||
{
|
||||
// There are four value for this corner which
|
||||
// we must duplicate 4 times in zcornsv
|
||||
if ( it_zdata + 3 >= nzdata ) throw std::runtime_error( "Incorrect size of zdata" );
|
||||
// As we place the pillar in reverse order into zcornsv,
|
||||
// we must put zdata in reverse order into pillar to
|
||||
// preserve n,s,w,e directions.
|
||||
pillar[it_pillar + 3] = ( zdata[it_zdata++] + zoffset ) * zscale;
|
||||
pillar[it_pillar + 2] = ( zdata[it_zdata++] + zoffset ) * zscale;
|
||||
pillar[it_pillar + 1] = ( zdata[it_zdata++] + zoffset ) * zscale;
|
||||
pillar[it_pillar] = ( zdata[it_zdata++] + zoffset ) * zscale;
|
||||
it_pillar += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error( "Unsupported split type" );
|
||||
}
|
||||
}
|
||||
// Put the pillar into zcornsv in reverse order
|
||||
for ( size_t it_pillar = num_row; it_pillar >= 1; )
|
||||
{
|
||||
zcornsv[it_zcorn++] = pillar[--it_pillar];
|
||||
}
|
||||
}
|
||||
|
||||
if ( it_splitenz != nsplitenz ) throw std::runtime_error( "Incorrect size of splitenz." );
|
||||
if ( it_zdata != nzdata ) throw std::runtime_error( "Incorrect size of zdata" );
|
||||
if ( it_zcorn != nzcorn ) throw std::runtime_error( "Incorrect size of zcorn." );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifRoffFileTools::convertToReservoirIndexOrder( int nx,
|
||||
int ny,
|
||||
int nz,
|
||||
const std::vector<char>& activeIn,
|
||||
std::vector<int>& activeOut )
|
||||
{
|
||||
CAF_ASSERT( static_cast<size_t>( nx ) * ny * nz == activeIn.size() );
|
||||
|
||||
activeOut.resize( activeIn.size(), -1 );
|
||||
|
||||
int outIdx = 0;
|
||||
for ( int k = 0; k < nz; k++ )
|
||||
{
|
||||
for ( int j = 0; j < ny; j++ )
|
||||
{
|
||||
for ( int i = 0; i < nx; i++ )
|
||||
{
|
||||
int inIdx = i * ny * nz + j * nz + k;
|
||||
activeOut[outIdx] = static_cast<int>( activeIn[inIdx] );
|
||||
outIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RifRoffFileTools::computeActiveCellMatrixIndex( std::vector<int>& activeCells )
|
||||
{
|
||||
size_t activeMatrixIndex = 0;
|
||||
int cellCount = static_cast<int>( activeCells.size() );
|
||||
for ( int gridLocalCellIndex = 0; gridLocalCellIndex < cellCount; gridLocalCellIndex++ )
|
||||
{
|
||||
if ( activeCells[gridLocalCellIndex] != 0 )
|
||||
{
|
||||
activeCells[gridLocalCellIndex] = activeMatrixIndex;
|
||||
activeMatrixIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeCells[gridLocalCellIndex] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return activeMatrixIndex;
|
||||
}
|
66
ApplicationLibCode/FileInterface/RifRoffFileTools.h
Normal file
66
ApplicationLibCode/FileInterface/RifRoffFileTools.h
Normal file
@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RigEclipseCaseData;
|
||||
class RigMainGrid;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Class for access to Roff grids.
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifRoffFileTools : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifRoffFileTools();
|
||||
~RifRoffFileTools() override;
|
||||
|
||||
static bool openGridFile( const QString& fileName, RigEclipseCaseData* eclipseCase, QString* errorMessages );
|
||||
|
||||
private:
|
||||
static void interpretSplitenzData( int nz,
|
||||
float zoffset,
|
||||
float zscale,
|
||||
const std::vector<char>& splitenz,
|
||||
const std::vector<float>& zdata,
|
||||
std::vector<float>& zcornsv );
|
||||
|
||||
static void
|
||||
convertToReservoirIndexOrder( int nx, int ny, int nz, const std::vector<char>& activeIn, std::vector<int>& activeOut );
|
||||
|
||||
static size_t computeActiveCellMatrixIndex( std::vector<int>& activeCells );
|
||||
|
||||
static cvf::Vec3d getCorner( const RigMainGrid& grid,
|
||||
const std::vector<float>& cornerLines,
|
||||
const std::vector<float>& zcorn,
|
||||
size_t cellIdx,
|
||||
int cornerIdx,
|
||||
const cvf::Vec3d& offset,
|
||||
const cvf::Vec3d& scale );
|
||||
|
||||
static double interpolate( const cvf::Vec3d& top, const cvf::Vec3d& bottom, double z, int idx );
|
||||
};
|
@ -126,6 +126,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSurfaceIntersectionCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEclipseResultAddress.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEclipseResultAddressCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRoffCase.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEclipseCaseTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimMultipleEclipseResults.h
|
||||
)
|
||||
@ -253,6 +254,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSurfaceIntersectionCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEclipseResultAddress.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEclipseResultAddressCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimRoffCase.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEclipseCaseTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimMultipleEclipseResults.cpp
|
||||
)
|
||||
|
140
ApplicationLibCode/ProjectDataModel/RimRoffCase.cpp
Normal file
140
ApplicationLibCode/ProjectDataModel/RimRoffCase.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimRoffCase.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RifRoffFileTools.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RimEclipseInputProperty.h"
|
||||
#include "RimEclipseInputPropertyCollection.h"
|
||||
#include "RimReservoirCellResultsStorage.h"
|
||||
|
||||
#include "cafProgressInfo.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimRoffCase, "RimRoffCase" );
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRoffCase::RimRoffCase()
|
||||
: RimEclipseCase()
|
||||
{
|
||||
CAF_PDM_InitObject( "RimRoffCase", ":/EclipseInput48x48.png" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRoffCase::~RimRoffCase()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimRoffCase::openEclipseGridFile()
|
||||
{
|
||||
if ( eclipseCaseData() )
|
||||
{
|
||||
// Early exit if reservoir data is created
|
||||
return true;
|
||||
}
|
||||
|
||||
setReservoirData( new RigEclipseCaseData( this ) );
|
||||
|
||||
QString fileName = gridFileName();
|
||||
|
||||
// First find and read the grid data
|
||||
if ( eclipseCaseData()->mainGrid()->gridPointDimensions() == cvf::Vec3st( 0, 0, 0 ) )
|
||||
{
|
||||
QString errorMessages;
|
||||
if ( RifRoffFileTools::openGridFile( fileName, this->eclipseCaseData(), &errorMessages ) )
|
||||
{
|
||||
QFileInfo gridFileInfo( fileName );
|
||||
QString caseName = gridFileInfo.completeBaseName();
|
||||
|
||||
setCaseUserDescription( caseName );
|
||||
eclipseCaseData()->mainGrid()->setFlipAxis( m_flipXAxis, m_flipYAxis );
|
||||
computeCachedData();
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( errorMessages );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
results( RiaDefines::PorosityModelType::MATRIX_MODEL )->createPlaceholderResultEntries();
|
||||
|
||||
if ( RiaPreferences::current()->autocomputeDepthRelatedProperties )
|
||||
{
|
||||
results( RiaDefines::PorosityModelType::MATRIX_MODEL )->computeDepthRelatedResults();
|
||||
results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->computeDepthRelatedResults();
|
||||
}
|
||||
|
||||
results( RiaDefines::PorosityModelType::MATRIX_MODEL )->computeCellVolumes();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimRoffCase::reloadEclipseGridFile()
|
||||
{
|
||||
setReservoirData( nullptr );
|
||||
openReserviorCase();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimRoffCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_caseUserDescription );
|
||||
uiOrdering.add( &m_displayNameOption );
|
||||
uiOrdering.add( &m_caseId );
|
||||
uiOrdering.add( &m_caseFileName );
|
||||
|
||||
auto group = uiOrdering.addNewGroup( "Case Options" );
|
||||
group->add( &m_activeFormationNames );
|
||||
group->add( &m_flipXAxis );
|
||||
group->add( &m_flipYAxis );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimRoffCase::locationOnDisc() const
|
||||
{
|
||||
if ( gridFileName().isEmpty() ) return QString();
|
||||
|
||||
QFileInfo fi( gridFileName() );
|
||||
return fi.absolutePath();
|
||||
}
|
49
ApplicationLibCode/ProjectDataModel/RimRoffCase.h
Normal file
49
ApplicationLibCode/ProjectDataModel/RimRoffCase.h
Normal file
@ -0,0 +1,49 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimEclipseCase.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RimRoffCase : public RimEclipseCase
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimRoffCase();
|
||||
~RimRoffCase() override;
|
||||
|
||||
// RimCase overrides
|
||||
bool openEclipseGridFile() override;
|
||||
void reloadEclipseGridFile() override;
|
||||
|
||||
// Overrides from RimCase
|
||||
QString locationOnDisc() const override;
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
};
|
@ -449,6 +449,7 @@ void RiuMainWindow::createMenus()
|
||||
importEclipseMenu->addAction( cmdFeatureMgr->action( "RicImportEclipseCasesFeature" ) );
|
||||
importEclipseMenu->addAction( cmdFeatureMgr->action( "RicImportEclipseCaseTimeStepFilterFeature" ) );
|
||||
importEclipseMenu->addAction( cmdFeatureMgr->action( "RicImportInputEclipseCaseFeature" ) );
|
||||
importEclipseMenu->addAction( cmdFeatureMgr->action( "RicImportRoffCaseFeature" ) );
|
||||
importEclipseMenu->addAction( cmdFeatureMgr->action( "RicCreateGridCaseGroupFromFilesFeature" ) );
|
||||
|
||||
importMenu->addSeparator();
|
||||
|
@ -495,6 +495,13 @@ endif()
|
||||
|
||||
list(APPEND THIRD_PARTY_LIBRARIES clipper)
|
||||
|
||||
# ##############################################################################
|
||||
# roffcpp
|
||||
# ##############################################################################
|
||||
|
||||
add_subdirectory(ThirdParty/roffcpp)
|
||||
list(APPEND THIRD_PARTY_LIBRARIES roffcpp)
|
||||
|
||||
# ##############################################################################
|
||||
# Thirdparty libraries are put in ThirdParty solution folder
|
||||
# ##############################################################################
|
||||
|
1
ThirdParty/roffcpp
vendored
Submodule
1
ThirdParty/roffcpp
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 2b5e846161a504afd1cbf1a1fa7e7388759cd300
|
Loading…
Reference in New Issue
Block a user