mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Support optimized surface export from grid model layers
* #7885 Update opm-common with optimized coordinate import * #7885 Allow null as default result from a script method * #7885 Propagate default parameter values to generated Python code * #7885 Add CommandRouter as hub for worker methods * #7885 Add support for use of CommadRouter from Python
This commit is contained in:
parent
2ef22f518c
commit
3a94078867
@ -37,6 +37,7 @@
|
||||
#include "RicfCommandFileExecutor.h"
|
||||
#include "RicfCommandObject.h"
|
||||
|
||||
#include "CommandRouter/RimCommandRouter.h"
|
||||
#include "Rim2dIntersectionViewCollection.h"
|
||||
#include "RimAnnotationCollection.h"
|
||||
#include "RimAnnotationInViewCollection.h"
|
||||
@ -149,6 +150,8 @@ RiaApplication::RiaApplication()
|
||||
#endif
|
||||
|
||||
setLastUsedDialogDirectory( "MULTICASEIMPORT", "/" );
|
||||
|
||||
m_commandRouter = std::make_unique<RimCommandRouter>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -301,6 +304,14 @@ RimProject* RiaApplication::project()
|
||||
return m_project.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCommandRouter* RiaApplication::commandRouter()
|
||||
{
|
||||
return m_commandRouter.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -52,6 +52,7 @@ class RiaSocketServer;
|
||||
class RigEclipseCaseData;
|
||||
|
||||
class RimCommandObject;
|
||||
class RimCommandRouter;
|
||||
class RimEclipseCase;
|
||||
class RimEclipseView;
|
||||
class RimWellPath;
|
||||
@ -116,6 +117,7 @@ public:
|
||||
int currentScriptCaseId() const;
|
||||
|
||||
RimProject* project();
|
||||
RimCommandRouter* commandRouter();
|
||||
|
||||
void createMockModel();
|
||||
void createResultsMockModel();
|
||||
@ -234,6 +236,8 @@ protected:
|
||||
caf::PdmPointer<Rim3dView> m_activeReservoirView;
|
||||
std::unique_ptr<RimProject> m_project;
|
||||
|
||||
std::unique_ptr<RimCommandRouter> m_commandRouter;
|
||||
|
||||
QPointer<RiaSocketServer> m_socketServer;
|
||||
std::unique_ptr<caf::UiProcess> m_workerProcess;
|
||||
|
||||
|
@ -184,6 +184,7 @@ list(
|
||||
ProjectDataModel/WellMeasurement/CMakeLists_files.cmake
|
||||
ProjectDataModel/WellPath/CMakeLists_files.cmake
|
||||
ProjectDataModelCommands/CMakeLists_files.cmake
|
||||
ProjectDataModelCommands/CommandRouter/CMakeLists_files.cmake
|
||||
GeoMech/GeoMechVisualization/CMakeLists_files.cmake
|
||||
ModelVisualization/CMakeLists_files.cmake
|
||||
ModelVisualization/GridBox/CMakeLists_files.cmake
|
||||
@ -400,7 +401,8 @@ target_link_libraries(${PROJECT_NAME} ${LINK_LIBRARIES}
|
||||
target_include_directories(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE ${CMAKE_BINARY_DIR}/Generated
|
||||
PUBLIC ${CMAKE_SOURCE_DIR}/ApplicationLibCode/Application
|
||||
PUBLIC ${CMAKE_SOURCE_DIR}/ApplicationLibCode
|
||||
${CMAKE_SOURCE_DIR}/ApplicationLibCode/Application
|
||||
${CMAKE_SOURCE_DIR}/ApplicationLibCode/Application/Tools
|
||||
${CMAKE_SOURCE_DIR}/ApplicationLibCode/CommandFileInterface
|
||||
${CMAKE_SOURCE_DIR}/ApplicationLibCode/CommandFileInterface/Core
|
||||
|
@ -0,0 +1,20 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCommandRouter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimcExtractSurfaces.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCommandRouter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimcExtractSurfaces.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
source_group( "ProjectDataModelCommands\\CommandRouter" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
@ -0,0 +1,74 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021 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 "RimCommandRouter.h"
|
||||
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimCommandRouter, "RimCommandRouter" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCommandRouter::RimCommandRouter()
|
||||
{
|
||||
CAF_PDM_InitScriptableObjectWithNameAndComment( "CommandRouter",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"CommandRouter",
|
||||
"The CommandRouter is used to call code independent to the "
|
||||
"project" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// RimCommandRouterMethod
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCommandRouterMethod::RimCommandRouterMethod( PdmObjectHandle* self )
|
||||
: caf::PdmObjectMethod( self )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCommandRouterMethod::isNullptrValidResult() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCommandRouterMethod::resultIsPersistent() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::unique_ptr<caf::PdmObjectHandle> RimCommandRouterMethod::defaultResult() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021 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 "cafPdmObject.h"
|
||||
#include "cafPdmObjectMethod.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Usually, command router classes will require only the execute() method. Derive from RimCommandRouterMethod to get
|
||||
/// default values for the other required virtual functions
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RimCommandRouterMethod : public caf::PdmObjectMethod
|
||||
{
|
||||
public:
|
||||
RimCommandRouterMethod( PdmObjectHandle* self );
|
||||
|
||||
bool isNullptrValidResult() const override;
|
||||
bool resultIsPersistent() const override;
|
||||
std::unique_ptr<PdmObjectHandle> defaultResult() const override;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// The command router object is used as a hub for data processing commands independent to a ResInsight project
|
||||
/// (RimProject). The intention for this object is to have a hub to connect to when using ResInsight as a data
|
||||
/// processing server. Avoid dependency on a GUI, and make sure the execute() commands works in headless mode.
|
||||
///
|
||||
/// The router object is made available from Python using
|
||||
///
|
||||
/// resinsight = rips.Instance.find()
|
||||
/// command_router = resinsight.command_router
|
||||
///
|
||||
/// Steps to add a new processing function
|
||||
/// 1) Create a new class deriving from RimCommandRouterMethod
|
||||
/// 2) Add Pdm fields to this class. These fields will be made available as parameters from Python
|
||||
/// 2) Implement data processing in execute() method using the input values specified in the Pdm fields
|
||||
///
|
||||
/// Example : RimcCommandRouter_extractSurfaces
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCommandRouter : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCommandRouter();
|
||||
};
|
@ -0,0 +1,134 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021- 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 "RimcExtractSurfaces.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RifSurfaceExporter.h"
|
||||
#include "RimCommandRouter.h"
|
||||
|
||||
#include "opm/io/eclipse/EGrid.hpp"
|
||||
|
||||
#include "cafPdmAbstractFieldScriptingCapability.h"
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <memory>
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimCommandRouter, RimcCommandRouter_extractSurfaces, "ExtractSurfaces" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimcCommandRouter_extractSurfaces::RimcCommandRouter_extractSurfaces( caf::PdmObjectHandle* self )
|
||||
: RimCommandRouterMethod( self )
|
||||
{
|
||||
CAF_PDM_InitObject( "Extract Layer Surface", "", "", "Extract Layer Surface" );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_gridModelFilename, "GridModelFilename", QString(), "Grid Model Case Filename", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_layers, "Layers", std::vector<int>(), "Layers", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_minimumI, "MinimumI", -1, "Minimum I", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_maximumI, "MaximumI", -1, "Maximum I", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_minimumJ, "MinimumJ", -1, "Minimum J", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_maximumJ, "MaximumJ", -1, "Maximum J", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmObjectHandle* RimcCommandRouter_extractSurfaces::execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string filename = m_gridModelFilename().toStdString();
|
||||
Opm::EclIO::EGrid grid1( filename );
|
||||
|
||||
auto dims = grid1.dimension();
|
||||
int minI = m_minimumI() == -1 ? 0 : m_minimumI();
|
||||
int maxI = m_maximumJ() == -1 ? dims[0] - 1 : m_maximumI();
|
||||
int minJ = m_minimumI() == -1 ? 0 : m_minimumJ();
|
||||
int maxJ = m_minimumI() == -1 ? dims[1] - 1 : m_maximumJ();
|
||||
|
||||
std::array<int, 4> range = { minI, maxI, minJ, maxJ };
|
||||
|
||||
for ( auto layer : m_layers() )
|
||||
{
|
||||
bool bottom = false;
|
||||
auto xyz_data = grid1.getXYZ_layer( layer, range, bottom );
|
||||
auto mapAxis = grid1.get_mapaxes();
|
||||
|
||||
// Create surface from coords
|
||||
|
||||
std::vector<unsigned> triangleIndices;
|
||||
std::vector<cvf::Vec3d> vertices;
|
||||
|
||||
unsigned startOfCellCoordIndex = 0;
|
||||
while ( startOfCellCoordIndex + 4 < xyz_data.size() )
|
||||
{
|
||||
for ( size_t cornerIdx = 0; cornerIdx < 4; cornerIdx++ )
|
||||
{
|
||||
auto coord1 = xyz_data[startOfCellCoordIndex + cornerIdx];
|
||||
auto cvfCoord = cvf::Vec3d( coord1[0], coord1[1], -coord1[2] );
|
||||
|
||||
if ( !mapAxis.empty() )
|
||||
{
|
||||
cvfCoord[0] += mapAxis[2];
|
||||
cvfCoord[1] += mapAxis[3];
|
||||
}
|
||||
vertices.push_back( cvfCoord );
|
||||
}
|
||||
|
||||
triangleIndices.push_back( startOfCellCoordIndex );
|
||||
triangleIndices.push_back( startOfCellCoordIndex + 3 );
|
||||
triangleIndices.push_back( startOfCellCoordIndex + 2 );
|
||||
|
||||
triangleIndices.push_back( startOfCellCoordIndex );
|
||||
triangleIndices.push_back( startOfCellCoordIndex + 1 );
|
||||
triangleIndices.push_back( startOfCellCoordIndex + 3 );
|
||||
|
||||
// Coordinates are given for each four corners for each cell of the surface
|
||||
startOfCellCoordIndex += 4;
|
||||
}
|
||||
|
||||
// Write to TS file on disk
|
||||
|
||||
QFileInfo fi( m_gridModelFilename );
|
||||
QString surfaceFilename = fi.absoluteDir().absolutePath() +
|
||||
QString( "/surfaceexport/layer-%1.ts" ).arg( layer );
|
||||
|
||||
// TODO: Add more info in surface comment
|
||||
if ( !RifSurfaceExporter::writeGocadTSurfFile( surfaceFilename, "Surface comment", vertices, triangleIndices ) )
|
||||
{
|
||||
RiaLogging::error( "Failed to export surface data to " + surfaceFilename );
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( "Successfully exported surface data to " + surfaceFilename );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
RiaLogging::error( "Error during creation of surface data for model " + m_gridModelFilename() );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021- 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 "RimCommandRouter.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimcCommandRouter_extractSurfaces : public RimCommandRouterMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimcCommandRouter_extractSurfaces( caf::PdmObjectHandle* self );
|
||||
|
||||
caf::PdmObjectHandle* execute() override;
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_gridModelFilename;
|
||||
caf::PdmField<std::vector<int>> m_layers;
|
||||
caf::PdmField<int> m_minimumI;
|
||||
caf::PdmField<int> m_maximumI;
|
||||
caf::PdmField<int> m_minimumJ;
|
||||
caf::PdmField<int> m_maximumJ;
|
||||
};
|
@ -182,16 +182,7 @@ QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vecto
|
||||
}
|
||||
else
|
||||
{
|
||||
QString valueString;
|
||||
|
||||
// Always make sure the default value for a ptrField is empty string
|
||||
if ( !field->hasPtrReferencedObjects() )
|
||||
{
|
||||
QTextStream valueStream( &valueString );
|
||||
scriptability->readFromField( valueStream, true, true );
|
||||
}
|
||||
if ( valueString.isEmpty() ) valueString = QString( "\"\"" );
|
||||
valueString = pythonifyDataValue( valueString );
|
||||
QString valueString = getDefaultValue( field );
|
||||
|
||||
QString fieldCode =
|
||||
QString( " self.%1 = %2\n" ).arg( snake_field_name ).arg( valueString );
|
||||
@ -264,16 +255,20 @@ QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vecto
|
||||
QStringList argumentComments;
|
||||
|
||||
outputArgumentStrings.push_back( QString( "\"%1\"" ).arg( methodName ) );
|
||||
QString returnComment = method->defaultResult()->xmlCapability()->classKeyword();
|
||||
QString returnComment;
|
||||
if ( method->defaultResult() ) returnComment = method->defaultResult()->xmlCapability()->classKeyword();
|
||||
|
||||
for ( auto field : arguments )
|
||||
{
|
||||
bool isList = field->xmlCapability()->isVectorField();
|
||||
QString defaultValue = isList ? "[]" : "None";
|
||||
auto scriptability = field->capability<PdmAbstractFieldScriptingCapability>();
|
||||
auto argumentName = camelToSnakeCase( scriptability->scriptFieldName() );
|
||||
auto dataType = dataTypeString( field, false );
|
||||
|
||||
bool isList = field->xmlCapability()->isVectorField();
|
||||
if ( isList ) dataType = "List of " + dataType;
|
||||
|
||||
QString defaultValue = getDefaultValue( field );
|
||||
|
||||
inputArgumentStrings.push_back( QString( "%1=%2" ).arg( argumentName ).arg( defaultValue ) );
|
||||
outputArgumentStrings.push_back( QString( "%1=%1" ).arg( argumentName ) );
|
||||
argumentComments.push_back(
|
||||
@ -406,6 +401,39 @@ QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vecto
|
||||
return generatedCode;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmPythonGenerator::getDefaultValue( PdmFieldHandle* field )
|
||||
{
|
||||
QString defaultValue = "None";
|
||||
|
||||
bool isList = field->xmlCapability()->isVectorField();
|
||||
if ( isList )
|
||||
{
|
||||
defaultValue = "[]";
|
||||
}
|
||||
else
|
||||
{
|
||||
QString valueString;
|
||||
|
||||
// Always make sure the default value for a ptrField is empty string
|
||||
if ( !field->hasPtrReferencedObjects() )
|
||||
{
|
||||
auto scriptability = field->template capability<PdmAbstractFieldScriptingCapability>();
|
||||
|
||||
QTextStream valueStream( &valueString );
|
||||
scriptability->readFromField( valueStream, true, true );
|
||||
}
|
||||
if ( valueString.isEmpty() ) valueString = QString( "\"\"" );
|
||||
valueString = pythonifyDataValue( valueString );
|
||||
|
||||
defaultValue = valueString;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -54,6 +54,9 @@ public:
|
||||
static QString dataTypeString( const PdmFieldHandle* field, bool useStrForUnknownDataTypes );
|
||||
|
||||
static QString pythonifyDataValue( const QString& dataValue );
|
||||
|
||||
private:
|
||||
static QString getDefaultValue( PdmFieldHandle* field );
|
||||
};
|
||||
|
||||
} // namespace caf
|
||||
|
@ -3,11 +3,13 @@ syntax = "proto3";
|
||||
package rips;
|
||||
|
||||
import "Definitions.proto";
|
||||
import "PdmObject.proto";
|
||||
|
||||
service App {
|
||||
rpc GetVersion(Empty) returns (Version) {}
|
||||
rpc Exit(Empty) returns (Empty) {}
|
||||
rpc GetRuntimeInfo(Empty) returns (RuntimeInfo) {}
|
||||
rpc GetPdmObject(Empty) returns (PdmObject) {}
|
||||
}
|
||||
|
||||
message Version {
|
||||
|
@ -13,6 +13,7 @@ home_dir = expanduser("~")
|
||||
export_folder = tempfile.mkdtemp()
|
||||
|
||||
directory_path = "resprojects/webviz-subsurface-testdata/reek_history_match/"
|
||||
# directory_path = "e:/gitroot/webviz-subsurface-testdata/reek_history_match"
|
||||
|
||||
|
||||
case_file_paths = []
|
||||
|
@ -0,0 +1,41 @@
|
||||
# Load ResInsight Processing Server Client Library
|
||||
import rips
|
||||
import tempfile
|
||||
from os.path import expanduser
|
||||
from pathlib import Path
|
||||
|
||||
# Connect to ResInsight instance
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
|
||||
home_dir = expanduser("~")
|
||||
|
||||
export_folder = tempfile.mkdtemp()
|
||||
|
||||
directory_path = "resprojects/webviz-subsurface-testdata/reek_history_match/"
|
||||
# directory_path = "e:/gitroot/webviz-subsurface-testdata/reek_history_match"
|
||||
|
||||
|
||||
case_file_paths = []
|
||||
num_realizations = 9
|
||||
num_iterations = 4
|
||||
|
||||
|
||||
for realization in range(0, num_realizations):
|
||||
for iteration in range(0, num_iterations):
|
||||
realization_dir = "realization-" + str(realization)
|
||||
iteration_dir = "iter-" + str(iteration)
|
||||
egrid_name = "eclipse/model/5_R001_REEK-" + str(realization) + ".EGRID"
|
||||
path = Path(
|
||||
home_dir, directory_path, realization_dir, iteration_dir, egrid_name
|
||||
)
|
||||
case_file_paths.append(path)
|
||||
|
||||
k_indexes = [4, 10]
|
||||
|
||||
command_router = resinsight.command_router
|
||||
|
||||
for path in case_file_paths:
|
||||
path_name = path.as_posix()
|
||||
|
||||
command_router.extract_surfaces(path_name, k_indexes)
|
@ -23,6 +23,7 @@ import RiaVersionInfo
|
||||
from .project import Project
|
||||
from .retry_policy import ExponentialBackoffRetryPolicy
|
||||
from .grpc_retry_interceptor import RetryOnRpcErrorClientInterceptor
|
||||
from .generated.generated_classes import CommandRouter
|
||||
|
||||
|
||||
class Instance:
|
||||
@ -202,12 +203,17 @@ class Instance:
|
||||
|
||||
intercepted_channel = grpc.intercept_channel(self.channel, *interceptors)
|
||||
|
||||
# Recreate ommand stubs with the retry policy
|
||||
# Recreate command stubs with the retry policy
|
||||
self.commands = Commands_pb2_grpc.CommandsStub(intercepted_channel)
|
||||
|
||||
# Service packages
|
||||
self.project = Project.create(intercepted_channel)
|
||||
|
||||
# Command Router object used as entry point for independent processing functions
|
||||
self.command_router = CommandRouter(
|
||||
self.app.GetPdmObject(Empty()), intercepted_channel
|
||||
)
|
||||
|
||||
path = os.getcwd()
|
||||
self.set_start_dir(path=path)
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "RiaGrpcServer.h"
|
||||
#include "RiaVersionInfo.h"
|
||||
|
||||
#include "ProjectDataModelCommands/CommandRouter/RimCommandRouter.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -51,7 +53,7 @@ grpc::Status
|
||||
RiaGrpcAppService::GetRuntimeInfo( grpc::ServerContext* context, const rips::Empty* request, rips::RuntimeInfo* reply )
|
||||
{
|
||||
rips::ApplicationTypeEnum appType = rips::CONSOLE_APPLICATION;
|
||||
if ( dynamic_cast<QApplication*>(RiaApplication::instance()))
|
||||
if ( dynamic_cast<QApplication*>( RiaApplication::instance() ) )
|
||||
{
|
||||
appType = rips::GUI_APPLICATION;
|
||||
}
|
||||
@ -70,7 +72,24 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcAppService::createCallbacks()
|
||||
new RiaGrpcUnaryCallback<Self, rips::Empty, rips::Empty>( this, &Self::Exit, &Self::RequestExit ),
|
||||
new RiaGrpcUnaryCallback<Self, rips::Empty, rips::RuntimeInfo>( this,
|
||||
&Self::GetRuntimeInfo,
|
||||
&Self::RequestGetRuntimeInfo ) };
|
||||
&Self::RequestGetRuntimeInfo ),
|
||||
new RiaGrpcUnaryCallback<Self, rips::Empty, rips::PdmObject>( this,
|
||||
&Self::GetPdmObject,
|
||||
&Self::RequestGetPdmObject ) };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status
|
||||
RiaGrpcAppService::GetPdmObject( grpc::ServerContext* context, const rips::Empty* request, rips::PdmObject* reply )
|
||||
{
|
||||
auto* commandRouter = RiaApplication::instance()->commandRouter();
|
||||
if ( commandRouter )
|
||||
{
|
||||
copyPdmObjectFromCafToRips( commandRouter, reply );
|
||||
}
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
static bool RiaGrpcAppInfoService_init =
|
||||
|
@ -46,4 +46,5 @@ public:
|
||||
grpc::Status Exit( grpc::ServerContext* context, const rips::Empty* request, rips::Empty* reply ) override;
|
||||
grpc::Status GetRuntimeInfo( grpc::ServerContext* context, const rips::Empty* request, rips::RuntimeInfo* reply ) override;
|
||||
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
|
||||
grpc::Status GetPdmObject( grpc::ServerContext* context, const rips::Empty* request, rips::PdmObject* reply ) override;
|
||||
};
|
||||
|
@ -17,7 +17,10 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiaGrpcPdmObjectService.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
|
||||
#include "ProjectDataModelCommands/CommandRouter/RimCommandRouter.h"
|
||||
#include "Rim3dView.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimProject.h"
|
||||
@ -613,11 +616,13 @@ caf::PdmObject* RiaGrpcPdmObjectService::findCafObjectFromRipsObject( const rips
|
||||
caf::PdmObject* RiaGrpcPdmObjectService::findCafObjectFromScriptNameAndAddress( const QString& scriptClassName,
|
||||
uint64_t address )
|
||||
{
|
||||
QString classKeyword = caf::PdmObjectScriptingCapabilityRegister::classKeywordFromScriptClassName( scriptClassName );
|
||||
|
||||
if ( classKeyword == RimCommandRouter::classKeywordStatic() ) return RiaApplication::instance()->commandRouter();
|
||||
|
||||
RimProject* project = RimProject::current();
|
||||
std::vector<caf::PdmObject*> objectsOfCurrentClass;
|
||||
|
||||
QString classKeyword = caf::PdmObjectScriptingCapabilityRegister::classKeywordFromScriptClassName( scriptClassName );
|
||||
|
||||
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
|
||||
|
||||
caf::PdmObject* matchingObject = nullptr;
|
||||
|
@ -34,7 +34,9 @@
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
#include <PdmObject.pb.h>
|
||||
#include <QDebug>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -137,6 +139,16 @@ void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf( const rips::PdmObject*
|
||||
destination->fields( fields );
|
||||
|
||||
auto parametersMap = source->parameters();
|
||||
|
||||
bool printContent = false; // Flag to control debug output to debugger
|
||||
if ( printContent )
|
||||
{
|
||||
for ( const auto& p : parametersMap )
|
||||
{
|
||||
qDebug() << QString::fromStdString( p.first ) << " : " << QString::fromStdString( p.second );
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto field : fields )
|
||||
{
|
||||
auto scriptability = field->template capability<caf::PdmAbstractFieldScriptingCapability>();
|
||||
|
@ -48,6 +48,9 @@ public:
|
||||
void getCellCorners(int globindex, std::array<double,8>& X, std::array<double,8>& Y, std::array<double,8>& Z);
|
||||
void getCellCorners(const std::array<int, 3>& ijk, std::array<double,8>& X, std::array<double,8>& Y, std::array<double,8>& Z);
|
||||
|
||||
std::vector<std::array<float, 3>> getXYZ_layer(int layer, bool bottom=false);
|
||||
std::vector<std::array<float, 3>> getXYZ_layer(int layer, std::array<int, 4>& box, bool bottom=false);
|
||||
|
||||
int activeCells() const { return nactive; }
|
||||
int totalNumberOfCells() const { return nijk[0] * nijk[1] * nijk[2]; }
|
||||
|
||||
@ -64,11 +67,17 @@ public:
|
||||
|
||||
const std::vector<std::string>& list_of_lgrs() const { return lgr_names; }
|
||||
|
||||
std::vector<float> get_mapaxes() const { return m_mapaxes; }
|
||||
std::string get_mapunits() const { return m_mapunits; }
|
||||
|
||||
private:
|
||||
Opm::filesystem::path inputFileName, initFileName;
|
||||
std::string m_grid_name;
|
||||
bool m_radial;
|
||||
|
||||
std::vector<float> m_mapaxes;
|
||||
std::string m_mapunits;
|
||||
|
||||
std::array<int, 3> nijk;
|
||||
std::array<int, 3> host_nijk;
|
||||
|
||||
@ -93,6 +102,12 @@ private:
|
||||
int actnum_array_index;
|
||||
int nnc1_array_index;
|
||||
int nnc2_array_index;
|
||||
|
||||
std::vector<float> get_zcorn_from_disk(int layer, bool bottom);
|
||||
|
||||
void getCellCorners(const std::array<int, 3>& ijk, const std::vector<float>& zcorn_layer,
|
||||
std::array<double,4>& X, std::array<double,4>& Y, std::array<double,4>& Z);
|
||||
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
@ -51,35 +51,7 @@ public:
|
||||
protected:
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& ImplgetInitData(const std::string& name, const std::string& grid_name = "global")
|
||||
{
|
||||
int arr_ind = get_array_index(name, grid_name);
|
||||
|
||||
if constexpr (std::is_same_v<T, int>)
|
||||
return getImpl(arr_ind, INTE, inte_array, "integer");
|
||||
|
||||
if constexpr (std::is_same_v<T, float>)
|
||||
return getImpl(arr_ind, REAL, real_array, "float");
|
||||
|
||||
if constexpr (std::is_same_v<T, double>)
|
||||
return getImpl(arr_ind, DOUB, doub_array, "double");
|
||||
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
return getImpl(arr_ind, LOGI, logi_array, "bool");
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>)
|
||||
{
|
||||
if (array_type[arr_ind] == Opm::EclIO::CHAR)
|
||||
return getImpl(arr_ind, array_type[arr_ind], char_array, "char");
|
||||
|
||||
if (array_type[arr_ind] == Opm::EclIO::C0NN)
|
||||
return getImpl(arr_ind, array_type[arr_ind], char_array, "c0nn");
|
||||
|
||||
OPM_THROW(std::runtime_error, "Array not of type CHAR or C0nn");
|
||||
}
|
||||
|
||||
OPM_THROW(std::runtime_error, "type not supported");
|
||||
}
|
||||
const std::vector<T>& ImplgetInitData(const std::string& name, const std::string& grid_name = "global");
|
||||
|
||||
private:
|
||||
std::array<int, 3> global_nijk;
|
||||
|
@ -53,9 +53,6 @@ public:
|
||||
template <typename T>
|
||||
const std::vector<T>& getRestartData(const std::string& name, int reportStepNumber, int occurrence);
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& getRestartData(const std::string& name, int reportStepNumber, const std::string& lgr_name);
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& getRestartData(int index, int reportStepNumber)
|
||||
{
|
||||
@ -64,16 +61,10 @@ public:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& getRestartData(int index, int reportStepNumber, const std::string& lgr_name)
|
||||
{
|
||||
auto indRange = this->getIndexRange(reportStepNumber);
|
||||
const std::vector<T>& getRestartData(const std::string& name, int reportStepNumber, const std::string& lgr_name);
|
||||
|
||||
if ((std::get<0>(indRange) + index) > std::get<1>(indRange))
|
||||
OPM_THROW(std::invalid_argument, "getRestartData, index out of range");
|
||||
|
||||
int start_ind = get_start_index_lgrname(reportStepNumber, lgr_name);
|
||||
return this->get<T>(index + start_ind);
|
||||
}
|
||||
template <typename T>
|
||||
const std::vector<T>& getRestartData(int index, int reportStepNumber, const std::string& lgr_name);
|
||||
|
||||
int occurrence_count(const std::string& name, int reportStepNumber) const;
|
||||
size_t numberOfReportSteps() const { return seqnum.size(); };
|
||||
|
@ -19,11 +19,10 @@
|
||||
#ifndef OPM_IO_ECLFILE_HPP
|
||||
#define OPM_IO_ECLFILE_HPP
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
@ -97,19 +96,7 @@ protected:
|
||||
template<class T>
|
||||
const std::vector<T>& getImpl(int arrIndex, eclArrType type,
|
||||
const std::unordered_map<int, std::vector<T>>& array,
|
||||
const std::string& typeStr)
|
||||
{
|
||||
if (array_type[arrIndex] != type) {
|
||||
std::string message = "Array with index " + std::to_string(arrIndex) + " is not of type " + typeStr;
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
if (!arrayLoaded[arrIndex]) {
|
||||
loadData(arrIndex);
|
||||
}
|
||||
|
||||
return array.at(arrIndex);
|
||||
}
|
||||
const std::string& typeStr);
|
||||
|
||||
std::streampos
|
||||
seekPosition(const std::vector<std::string>::size_type arrIndex) const;
|
||||
|
@ -3,9 +3,8 @@
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM 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.
|
||||
OPM 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.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -24,22 +23,28 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
using NNCentry = std::tuple<int, int, int, int, int,int, float>;
|
||||
|
||||
EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
EclFile(filename), inputFileName { filename }, m_grid_name {grid_name}
|
||||
namespace Opm
|
||||
{
|
||||
namespace EclIO
|
||||
{
|
||||
|
||||
using NNCentry = std::tuple<int, int, int, int, int, int, float>;
|
||||
|
||||
EGrid::EGrid(const std::string& filename, std::string grid_name)
|
||||
: EclFile(filename)
|
||||
, inputFileName {filename}
|
||||
, m_grid_name {grid_name}
|
||||
{
|
||||
initFileName = inputFileName.parent_path() / inputFileName.stem();
|
||||
|
||||
if (this->formattedInput())
|
||||
@ -54,6 +59,7 @@ EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
nnc1_array_index = -1;
|
||||
nnc2_array_index = -1;
|
||||
m_radial = false;
|
||||
m_mapunits = "";
|
||||
|
||||
int hostnum_index = -1;
|
||||
|
||||
@ -68,7 +74,7 @@ EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
lgr_names.push_back(lgr[0]);
|
||||
}
|
||||
|
||||
if (array_name[n] == "NNCHEAD"){
|
||||
if (array_name[n] == "NNCHEAD") {
|
||||
auto nnchead = this->get<int>(n);
|
||||
|
||||
if (nnchead[1] == 0)
|
||||
@ -77,6 +83,14 @@ EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
lgrname = lgr_names[nnchead[1] - 1];
|
||||
}
|
||||
|
||||
if (array_name[n] == "MAPUNITS") {
|
||||
auto mapunits = this->get<std::string>(n);
|
||||
m_mapunits = mapunits[0];
|
||||
}
|
||||
|
||||
if (array_name[n] == "MAPAXES")
|
||||
m_mapaxes = this->get<float>(n);
|
||||
|
||||
if (lgrname == grid_name) {
|
||||
if (array_name[n] == "GRIDHEAD") {
|
||||
auto gridhead = get<int>(n);
|
||||
@ -85,21 +99,21 @@ EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
nijk[2] = gridhead[3];
|
||||
|
||||
if (gridhead.size() > 26)
|
||||
m_radial = gridhead[26] > 0 ? true: false;
|
||||
m_radial = gridhead[26] > 0 ? true : false;
|
||||
}
|
||||
|
||||
if (array_name[n] == "COORD")
|
||||
coord_array_index= n;
|
||||
coord_array_index = n;
|
||||
else if (array_name[n] == "ZCORN")
|
||||
zcorn_array_index= n;
|
||||
zcorn_array_index = n;
|
||||
else if (array_name[n] == "ACTNUM")
|
||||
actnum_array_index= n;
|
||||
actnum_array_index = n;
|
||||
else if (array_name[n] == "NNC1")
|
||||
nnc1_array_index= n;
|
||||
nnc1_array_index = n;
|
||||
else if (array_name[n] == "NNC2")
|
||||
nnc2_array_index= n;
|
||||
nnc2_array_index = n;
|
||||
else if (array_name[n] == "HOSTNUM")
|
||||
hostnum_index= n;
|
||||
hostnum_index = n;
|
||||
}
|
||||
|
||||
if ((lgrname == "global") && (array_name[n] == "GRIDHEAD")) {
|
||||
@ -108,7 +122,6 @@ EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
host_nijk[1] = gridhead[2];
|
||||
host_nijk[2] = gridhead[3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (actnum_array_index != -1) {
|
||||
@ -131,21 +144,21 @@ EGrid::EGrid(const std::string &filename, std::string grid_name) :
|
||||
std::iota(glob_index.begin(), glob_index.end(), 0);
|
||||
}
|
||||
|
||||
if (hostnum_index > -1){
|
||||
if (hostnum_index > -1) {
|
||||
auto hostnum = getImpl(hostnum_index, INTE, inte_array, "integer");
|
||||
host_cells.reserve(hostnum.size());
|
||||
|
||||
for (auto val : hostnum)
|
||||
host_cells.push_back(val -1);
|
||||
host_cells.push_back(val - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::array<int, 3>> EGrid::hostCellsIJK()
|
||||
{
|
||||
std::vector<std::array<int, 3>> EGrid::hostCellsIJK()
|
||||
{
|
||||
std::vector<std::array<int, 3>> res_vect;
|
||||
res_vect.reserve(host_cells.size());
|
||||
|
||||
for (auto val : host_cells){
|
||||
for (auto val : host_cells) {
|
||||
std::array<int, 3> tmp;
|
||||
tmp[2] = val / (host_nijk[0] * host_nijk[1]);
|
||||
int rest = val % (host_nijk[0] * host_nijk[1]);
|
||||
@ -157,66 +170,69 @@ std::vector<std::array<int, 3>> EGrid::hostCellsIJK()
|
||||
}
|
||||
|
||||
return res_vect;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<NNCentry> EGrid::get_nnc_ijk()
|
||||
{
|
||||
std::vector<NNCentry> EGrid::get_nnc_ijk()
|
||||
{
|
||||
if (!m_nncs_loaded)
|
||||
load_nnc_data();
|
||||
|
||||
std::vector<NNCentry> res_vect;
|
||||
res_vect.reserve(nnc1_array.size());
|
||||
|
||||
for (size_t n=0; n< nnc1_array.size(); n++){
|
||||
for (size_t n = 0; n < nnc1_array.size(); n++) {
|
||||
auto ijk1 = ijk_from_global_index(nnc1_array[n] - 1);
|
||||
auto ijk2 = ijk_from_global_index(nnc2_array[n] - 1);
|
||||
|
||||
if (transnnc_array.size() > 0)
|
||||
res_vect.push_back({ijk1[0], ijk1[1], ijk1[2], ijk2[0], ijk2[1], ijk2[2], transnnc_array[n]});
|
||||
else
|
||||
res_vect.push_back({ijk1[0], ijk1[1], ijk1[2], ijk2[0], ijk2[1], ijk2[2], -1.0 });
|
||||
res_vect.push_back({ijk1[0], ijk1[1], ijk1[2], ijk2[0], ijk2[1], ijk2[2], -1.0});
|
||||
}
|
||||
|
||||
return res_vect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EGrid::load_grid_data()
|
||||
{
|
||||
void EGrid::load_grid_data()
|
||||
{
|
||||
coord_array = getImpl(coord_array_index, REAL, real_array, "float");
|
||||
zcorn_array = getImpl(zcorn_array_index, REAL, real_array, "float");
|
||||
}
|
||||
}
|
||||
|
||||
void EGrid::load_nnc_data()
|
||||
{
|
||||
void EGrid::load_nnc_data()
|
||||
{
|
||||
if ((nnc1_array_index > -1) && (nnc2_array_index > -1)) {
|
||||
|
||||
nnc1_array = getImpl(nnc1_array_index, Opm::EclIO::INTE, inte_array, "inte");
|
||||
nnc2_array = getImpl(nnc2_array_index, Opm::EclIO::INTE, inte_array, "inte");
|
||||
|
||||
if ((Opm::filesystem::exists(initFileName)) && (nnc1_array.size() > 0)){
|
||||
if ((Opm::filesystem::exists(initFileName)) && (nnc1_array.size() > 0)) {
|
||||
Opm::EclIO::EInit init(initFileName.string());
|
||||
|
||||
auto init_dims = init.grid_dimension(m_grid_name);
|
||||
int init_nactive = init.activeCells(m_grid_name);
|
||||
|
||||
if (init_dims != nijk){
|
||||
if (init_dims != nijk) {
|
||||
std::string message = "Dimensions of Egrid differ from dimensions found in init file. ";
|
||||
std::string grid_str = std::to_string(nijk[0]) + "x" + std::to_string(nijk[1]) + "x" + std::to_string(nijk[2]);
|
||||
std::string init_str = std::to_string(init_dims[0]) + "x" + std::to_string(init_dims[1]) + "x" + std::to_string(init_dims[2]);
|
||||
std::string grid_str
|
||||
= std::to_string(nijk[0]) + "x" + std::to_string(nijk[1]) + "x" + std::to_string(nijk[2]);
|
||||
std::string init_str = std::to_string(init_dims[0]) + "x" + std::to_string(init_dims[1]) + "x"
|
||||
+ std::to_string(init_dims[2]);
|
||||
message = message + "Egrid: " + grid_str + ". INIT file: " + init_str;
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
if (init_nactive != nactive){
|
||||
if (init_nactive != nactive) {
|
||||
std::string message = "Number of active cells are different in Egrid and Init file.";
|
||||
message = message + " Egrid: " + std::to_string(nactive) + ". INIT file: " + std::to_string(init_nactive);
|
||||
message = message + " Egrid: " + std::to_string(nactive)
|
||||
+ ". INIT file: " + std::to_string(init_nactive);
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
auto trans_data = init.getInitData<float>("TRANNNC", m_grid_name);
|
||||
|
||||
if (trans_data.size() != nnc1_array.size()){
|
||||
if (trans_data.size() != nnc1_array.size()) {
|
||||
std::string message = "inconsistent size of array TRANNNC in init file. ";
|
||||
message = message + " Size of NNC1 and NNC2: " + std::to_string(nnc1_array.size());
|
||||
message = message + " Size of TRANNNC: " + std::to_string(trans_data.size());
|
||||
@ -228,20 +244,20 @@ void EGrid::load_nnc_data()
|
||||
|
||||
m_nncs_loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EGrid::global_index(int i, int j, int k) const
|
||||
{
|
||||
int EGrid::global_index(int i, int j, int k) const
|
||||
{
|
||||
if (i < 0 || i >= nijk[0] || j < 0 || j >= nijk[1] || k < 0 || k >= nijk[2]) {
|
||||
OPM_THROW(std::invalid_argument, "i, j or/and k out of range");
|
||||
}
|
||||
|
||||
return i + j * nijk[0] + k * nijk[0] * nijk[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EGrid::active_index(int i, int j, int k) const
|
||||
{
|
||||
int EGrid::active_index(int i, int j, int k) const
|
||||
{
|
||||
int n = i + j * nijk[0] + k * nijk[0] * nijk[1];
|
||||
|
||||
if (i < 0 || i >= nijk[0] || j < 0 || j >= nijk[1] || k < 0 || k >= nijk[2]) {
|
||||
@ -249,11 +265,11 @@ int EGrid::active_index(int i, int j, int k) const
|
||||
}
|
||||
|
||||
return act_index[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::array<int, 3> EGrid::ijk_from_active_index(int actInd) const
|
||||
{
|
||||
std::array<int, 3> EGrid::ijk_from_active_index(int actInd) const
|
||||
{
|
||||
if (actInd < 0 || actInd >= nactive) {
|
||||
OPM_THROW(std::invalid_argument, "active index out of range");
|
||||
}
|
||||
@ -269,11 +285,11 @@ std::array<int, 3> EGrid::ijk_from_active_index(int actInd) const
|
||||
result[0] = rest % nijk[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::array<int, 3> EGrid::ijk_from_global_index(int globInd) const
|
||||
{
|
||||
std::array<int, 3> EGrid::ijk_from_global_index(int globInd) const
|
||||
{
|
||||
if (globInd < 0 || globInd >= nijk[0] * nijk[1] * nijk[2]) {
|
||||
OPM_THROW(std::invalid_argument, "global index out of range");
|
||||
}
|
||||
@ -287,14 +303,14 @@ std::array<int, 3> EGrid::ijk_from_global_index(int globInd) const
|
||||
result[0] = rest % nijk[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EGrid::getCellCorners(const std::array<int, 3>& ijk,
|
||||
std::array<double,8>& X,
|
||||
std::array<double,8>& Y,
|
||||
std::array<double,8>& Z)
|
||||
{
|
||||
void EGrid::getCellCorners(const std::array<int, 3>& ijk,
|
||||
std::array<double, 8>& X,
|
||||
std::array<double, 8>& Y,
|
||||
std::array<double, 8>& Z)
|
||||
{
|
||||
if (coord_array.empty())
|
||||
load_grid_data();
|
||||
|
||||
@ -302,21 +318,21 @@ void EGrid::getCellCorners(const std::array<int, 3>& ijk,
|
||||
std::vector<int> pind;
|
||||
|
||||
// calculate indices for grid pillars in COORD arrray
|
||||
pind.push_back(ijk[1]*(nijk[0]+1)*6 + ijk[0]*6);
|
||||
pind.push_back(ijk[1] * (nijk[0] + 1) * 6 + ijk[0] * 6);
|
||||
pind.push_back(pind[0] + 6);
|
||||
pind.push_back(pind[0] + (nijk[0]+1)*6);
|
||||
pind.push_back(pind[0] + (nijk[0] + 1) * 6);
|
||||
pind.push_back(pind[2] + 6);
|
||||
|
||||
// get depths from zcorn array in ZCORN array
|
||||
zind.push_back(ijk[2]*nijk[0]*nijk[1]*8 + ijk[1]*nijk[0]*4 + ijk[0]*2);
|
||||
zind.push_back(ijk[2] * nijk[0] * nijk[1] * 8 + ijk[1] * nijk[0] * 4 + ijk[0] * 2);
|
||||
zind.push_back(zind[0] + 1);
|
||||
zind.push_back(zind[0] + nijk[0]*2);
|
||||
zind.push_back(zind[0] + nijk[0] * 2);
|
||||
zind.push_back(zind[2] + 1);
|
||||
|
||||
for (int n = 0; n < 4; n++)
|
||||
zind.push_back(zind[n] + nijk[0]*nijk[1]*4);
|
||||
zind.push_back(zind[n] + nijk[0] * nijk[1] * 4);
|
||||
|
||||
for (int n = 0; n< 8; n++)
|
||||
for (int n = 0; n < 8; n++)
|
||||
Z[n] = zcorn_array[zind[n]];
|
||||
|
||||
for (int n = 0; n < 4; n++) {
|
||||
@ -331,8 +347,8 @@ void EGrid::getCellCorners(const std::array<int, 3>& ijk,
|
||||
if (m_radial) {
|
||||
xt = coord_array[pind[n]] * cos(coord_array[pind[n] + 1] / 180.0 * M_PI);
|
||||
yt = coord_array[pind[n]] * sin(coord_array[pind[n] + 1] / 180.0 * M_PI);
|
||||
xb = coord_array[pind[n]+3] * cos(coord_array[pind[n] + 4] / 180.0 * M_PI);
|
||||
yb = coord_array[pind[n]+3] * sin(coord_array[pind[n] + 4] / 180.0 * M_PI);
|
||||
xb = coord_array[pind[n] + 3] * cos(coord_array[pind[n] + 4] / 180.0 * M_PI);
|
||||
yb = coord_array[pind[n] + 3] * sin(coord_array[pind[n] + 4] / 180.0 * M_PI);
|
||||
} else {
|
||||
xt = coord_array[pind[n]];
|
||||
yt = coord_array[pind[n] + 1];
|
||||
@ -340,20 +356,216 @@ void EGrid::getCellCorners(const std::array<int, 3>& ijk,
|
||||
yb = coord_array[pind[n] + 4];
|
||||
}
|
||||
|
||||
X[n] = xt + (xb-xt) / (zt-zb) * (zt - Z[n]);
|
||||
X[n+4] = xt + (xb-xt) / (zt-zb) * (zt-Z[n+4]);
|
||||
X[n] = xt + (xb - xt) / (zt - zb) * (zt - Z[n]);
|
||||
X[n + 4] = xt + (xb - xt) / (zt - zb) * (zt - Z[n + 4]);
|
||||
|
||||
Y[n] = yt+(yb-yt)/(zt-zb)*(zt-Z[n]);
|
||||
Y[n+4] = yt+(yb-yt)/(zt-zb)*(zt-Z[n+4]);
|
||||
Y[n] = yt + (yb - yt) / (zt - zb) * (zt - Z[n]);
|
||||
Y[n + 4] = yt + (yb - yt) / (zt - zb) * (zt - Z[n + 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EGrid::getCellCorners(int globindex, std::array<double,8>& X,
|
||||
std::array<double,8>& Y, std::array<double,8>& Z)
|
||||
{
|
||||
return getCellCorners(ijk_from_global_index(globindex),X,Y,Z);
|
||||
}
|
||||
void
|
||||
EGrid::getCellCorners(int globindex, std::array<double, 8>& X, std::array<double, 8>& Y, std::array<double, 8>& Z)
|
||||
{
|
||||
return getCellCorners(ijk_from_global_index(globindex), X, Y, Z);
|
||||
}
|
||||
|
||||
}} // namespace Opm::ecl
|
||||
|
||||
std::vector<std::array<float, 3>> EGrid::getXYZ_layer(int layer, std::array<int, 4>& box, bool bottom)
|
||||
{
|
||||
// layer is layer index, zero based. The box array is i and j range (i1,i2,j1,j2), also zero based
|
||||
|
||||
if ((layer < 0) || (layer > (nijk[2] - 1))) {
|
||||
std::string message = "invalid layer index " + std::to_string(layer) + ". Valied range [0, ";
|
||||
message = message + std::to_string(nijk[2] - 1) + "]";
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
|
||||
if ((box[0] < 0) || (box[0] + 1 > nijk[0]) || (box[1] < 0) || (box[1] + 1 > nijk[0]) || (box[2] < 0)
|
||||
|| (box[2] + 1 > nijk[1]) || (box[3] < 0) || (box[3] + 1 > nijk[1]) || (box[0] > box[1])
|
||||
|| (box[2] > box[3])) {
|
||||
|
||||
throw std::invalid_argument("invalid box input, i1,i2,j1 or j2 out of valied range ");
|
||||
}
|
||||
|
||||
int nodes_pr_surf = nijk[0] * nijk[1] * 4;
|
||||
int zcorn_offset = nodes_pr_surf * layer * 2;
|
||||
|
||||
if (bottom)
|
||||
zcorn_offset += nodes_pr_surf;
|
||||
|
||||
std::vector<float> layer_zcorn;
|
||||
layer_zcorn.reserve(nodes_pr_surf);
|
||||
|
||||
std::vector<std::array<float, 3>> xyz_vector;
|
||||
|
||||
if (coord_array.size() == 0)
|
||||
coord_array = getImpl(coord_array_index, REAL, real_array, "float");
|
||||
|
||||
if (zcorn_array.size() > 0) {
|
||||
for (size_t n = 0; n < static_cast<size_t>(nodes_pr_surf); n++)
|
||||
layer_zcorn.push_back(zcorn_array[zcorn_offset + n]);
|
||||
|
||||
} else {
|
||||
layer_zcorn = get_zcorn_from_disk(layer, bottom);
|
||||
}
|
||||
|
||||
std::array<double, 4> X;
|
||||
std::array<double, 4> Y;
|
||||
std::array<double, 4> Z;
|
||||
|
||||
std::array<int, 3> ijk;
|
||||
ijk[2] = 0;
|
||||
|
||||
for (int j = box[2]; j < (box[3] + 1); j++) {
|
||||
for (int i = box[0]; i < (box[1] + 1); i++) {
|
||||
|
||||
ijk[0] = i;
|
||||
ijk[1] = j;
|
||||
|
||||
this->getCellCorners(ijk, layer_zcorn, X, Y, Z);
|
||||
|
||||
for (size_t n = 0; n < 4; n++) {
|
||||
std::array<float, 3> xyz;
|
||||
xyz[0] = X[n];
|
||||
xyz[1] = Y[n];
|
||||
xyz[2] = Z[n];
|
||||
|
||||
xyz_vector.push_back(xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xyz_vector;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::array<float, 3>> EGrid::getXYZ_layer(int layer, bool bottom)
|
||||
{
|
||||
std::array<int, 4> box = {0, nijk[0] - 1, 0, nijk[1] - 1};
|
||||
return this->getXYZ_layer(layer, box, bottom);
|
||||
}
|
||||
|
||||
std::vector<float> EGrid::get_zcorn_from_disk(int layer, bool bottom)
|
||||
{
|
||||
if (formatted)
|
||||
throw std::invalid_argument("partial loading of zcorn arrays not possible when using formatted input");
|
||||
|
||||
std::vector<float> zcorn_layer;
|
||||
std::fstream fileH;
|
||||
|
||||
int nodes_pr_surf = nijk[0] * nijk[1] * 4;
|
||||
int zcorn_offset = nodes_pr_surf * layer * 2;
|
||||
|
||||
if (bottom)
|
||||
zcorn_offset += nodes_pr_surf;
|
||||
|
||||
fileH.open(inputFileName, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH)
|
||||
throw std::runtime_error("Can not open EGrid file" + this->inputFilename);
|
||||
|
||||
std::string arrName(8, ' ');
|
||||
eclArrType arrType;
|
||||
int64_t num;
|
||||
int sizeOfElement;
|
||||
|
||||
uint64_t zcorn_pos = 0;
|
||||
|
||||
while (!isEOF(&fileH)) {
|
||||
|
||||
readBinaryHeader(fileH, arrName, num, arrType, sizeOfElement);
|
||||
|
||||
if (arrName == "ZCORN ") {
|
||||
zcorn_pos = fileH.tellg();
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t sizeOfNextArray = sizeOnDiskBinary(num, arrType, sizeOfElement);
|
||||
fileH.seekg(static_cast<std::streamoff>(sizeOfNextArray), std::ios_base::cur);
|
||||
}
|
||||
|
||||
int elements_pr_block = Opm::EclIO::MaxBlockSizeReal / Opm::EclIO::sizeOfReal;
|
||||
int num_blocks_start = zcorn_offset / elements_pr_block;
|
||||
|
||||
// adding size of zcorn real data before to ignored
|
||||
uint64_t start_pos = zcorn_pos + Opm::EclIO::sizeOfReal * zcorn_offset;
|
||||
|
||||
// adding size of blocks (head and tail flags)
|
||||
start_pos = start_pos + (1 + num_blocks_start * 2) * Opm::EclIO::sizeOfInte;
|
||||
|
||||
fileH.seekg(start_pos, std::ios_base::beg);
|
||||
|
||||
float value;
|
||||
int zcorn_to = zcorn_offset + nodes_pr_surf;
|
||||
|
||||
for (int ind = zcorn_offset; ind < zcorn_to; ind++) {
|
||||
|
||||
if ((ind > 0) && ((ind % elements_pr_block) == 0))
|
||||
fileH.seekg(static_cast<std::streamoff>(2 * Opm::EclIO::sizeOfInte), std::ios_base::cur);
|
||||
|
||||
fileH.read(reinterpret_cast<char*>(&value), Opm::EclIO::sizeOfReal);
|
||||
value = Opm::EclIO::flipEndianFloat(value);
|
||||
|
||||
zcorn_layer.push_back(value);
|
||||
}
|
||||
|
||||
fileH.close();
|
||||
|
||||
return zcorn_layer;
|
||||
}
|
||||
|
||||
void EGrid::getCellCorners(const std::array<int, 3>& ijk,
|
||||
const std::vector<float>& zcorn_layer,
|
||||
std::array<double, 4>& X,
|
||||
std::array<double, 4>& Y,
|
||||
std::array<double, 4>& Z)
|
||||
{
|
||||
std::vector<int> zind;
|
||||
std::vector<int> pind;
|
||||
|
||||
// calculate indices for grid pillars in COORD arrray
|
||||
pind.push_back(ijk[1] * (nijk[0] + 1) * 6 + ijk[0] * 6);
|
||||
pind.push_back(pind[0] + 6);
|
||||
pind.push_back(pind[0] + (nijk[0] + 1) * 6);
|
||||
pind.push_back(pind[2] + 6);
|
||||
|
||||
// get depths from zcorn array in ZCORN array
|
||||
zind.push_back(ijk[2] * nijk[0] * nijk[1] * 8 + ijk[1] * nijk[0] * 4 + ijk[0] * 2);
|
||||
zind.push_back(zind[0] + 1);
|
||||
zind.push_back(zind[0] + nijk[0] * 2);
|
||||
zind.push_back(zind[2] + 1);
|
||||
|
||||
for (int n = 0; n < 4; n++)
|
||||
Z[n] = zcorn_layer[zind[n]];
|
||||
|
||||
for (int n = 0; n < 4; n++) {
|
||||
double xt;
|
||||
double yt;
|
||||
double xb;
|
||||
double yb;
|
||||
|
||||
double zt = coord_array[pind[n] + 2];
|
||||
double zb = coord_array[pind[n] + 5];
|
||||
|
||||
xt = coord_array[pind[n]];
|
||||
yt = coord_array[pind[n] + 1];
|
||||
xb = coord_array[pind[n] + 3];
|
||||
yb = coord_array[pind[n] + 4];
|
||||
|
||||
if (zt == zb) {
|
||||
X[n] = xt;
|
||||
Y[n] = yt;
|
||||
} else {
|
||||
X[n] = xt + (xb - xt) / (zt - zb) * (zt - Z[n]);
|
||||
Y[n] = yt + (yb - yt) / (zt - zb) * (zt - Z[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace EclIO
|
||||
} // namespace Opm
|
||||
|
@ -157,5 +157,40 @@ std::vector<EclFile::EclEntry> EInit::list_arrays() const
|
||||
return array_list;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& EInit::ImplgetInitData(const std::string& name, const std::string& grid_name)
|
||||
{
|
||||
int arr_ind = get_array_index(name, grid_name);
|
||||
|
||||
if constexpr (std::is_same_v<T, int>)
|
||||
return getImpl(arr_ind, INTE, inte_array, "integer");
|
||||
|
||||
if constexpr (std::is_same_v<T, float>)
|
||||
return getImpl(arr_ind, REAL, real_array, "float");
|
||||
|
||||
if constexpr (std::is_same_v<T, double>)
|
||||
return getImpl(arr_ind, DOUB, doub_array, "double");
|
||||
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
return getImpl(arr_ind, LOGI, logi_array, "bool");
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>)
|
||||
{
|
||||
if (array_type[arr_ind] == Opm::EclIO::CHAR)
|
||||
return getImpl(arr_ind, array_type[arr_ind], char_array, "char");
|
||||
|
||||
if (array_type[arr_ind] == Opm::EclIO::C0NN)
|
||||
return getImpl(arr_ind, array_type[arr_ind], char_array, "c0nn");
|
||||
|
||||
OPM_THROW(std::runtime_error, "Array not of type CHAR or C0nn");
|
||||
}
|
||||
|
||||
OPM_THROW(std::runtime_error, "type not supported");
|
||||
}
|
||||
|
||||
template const std::vector<int>& EInit::ImplgetInitData(const std::string& name, const std::string& grid_name);
|
||||
template const std::vector<float>& EInit::ImplgetInitData(const std::string& name, const std::string& grid_name);
|
||||
template const std::vector<double>& EInit::ImplgetInitData(const std::string& name, const std::string& grid_name);
|
||||
template const std::vector<bool>& EInit::ImplgetInitData(const std::string& name, const std::string& grid_name);
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include <opm/io/eclipse/ERst.hpp>
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
@ -407,5 +409,22 @@ const std::vector<std::string>& ERst::getRestartData<std::string>(const std::str
|
||||
return getImpl(ind, CHAR, char_array, "char");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& ERst::getRestartData(int index, int reportStepNumber, const std::string& lgr_name)
|
||||
{
|
||||
auto indRange = this->getIndexRange(reportStepNumber);
|
||||
|
||||
if ((std::get<0>(indRange) + index) > std::get<1>(indRange))
|
||||
OPM_THROW(std::invalid_argument, "getRestartData, index out of range");
|
||||
|
||||
int start_ind = get_start_index_lgrname(reportStepNumber, lgr_name);
|
||||
return this->get<T>(index + start_ind);
|
||||
}
|
||||
|
||||
template const std::vector<int>& ERst::getRestartData(int index, int reportStepNumber, const std::string& lgr_name);
|
||||
template const std::vector<std::string>& ERst::getRestartData(int index, int reportStepNumber, const std::string& lgr_name);
|
||||
template const std::vector<float>& ERst::getRestartData(int index, int reportStepNumber, const std::string& lgr_name);
|
||||
template const std::vector<double>& ERst::getRestartData(int index, int reportStepNumber, const std::string& lgr_name);
|
||||
template const std::vector<bool>& ERst::getRestartData(int index, int reportStepNumber, const std::string& lgr_name);
|
||||
|
||||
}} // namespace Opm::ecl
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <opm/io/eclipse/EclUtil.hpp>
|
||||
#include <opm/io/eclipse/EclOutput.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
@ -3,9 +3,8 @@
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM 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.
|
||||
OPM 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.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -16,29 +15,33 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
#include <opm/io/eclipse/EclUtil.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
//#include <fmt/format.h>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
namespace Opm
|
||||
{
|
||||
namespace EclIO
|
||||
{
|
||||
|
||||
void EclFile::load(bool preload) {
|
||||
void EclFile::load(bool preload)
|
||||
{
|
||||
std::fstream fileH;
|
||||
|
||||
if (formatted) {
|
||||
@ -48,20 +51,20 @@ void EclFile::load(bool preload) {
|
||||
}
|
||||
|
||||
if (!fileH)
|
||||
//throw std::runtime_error(fmt::format("Can not open EclFile: {}", this->inputFilename));
|
||||
// throw std::runtime_error(fmt::format("Can not open EclFile: {}", this->inputFilename));
|
||||
throw std::runtime_error("Can not open EclFile: {}");
|
||||
|
||||
int n = 0;
|
||||
while (!isEOF(&fileH)) {
|
||||
std::string arrName(8,' ');
|
||||
std::string arrName(8, ' ');
|
||||
eclArrType arrType;
|
||||
int64_t num;
|
||||
int sizeOfElement;
|
||||
|
||||
if (formatted) {
|
||||
readFormattedHeader(fileH,arrName,num,arrType, sizeOfElement);
|
||||
readFormattedHeader(fileH, arrName, num, arrType, sizeOfElement);
|
||||
} else {
|
||||
readBinaryHeader(fileH,arrName,num, arrType, sizeOfElement);
|
||||
readBinaryHeader(fileH, arrName, num, arrType, sizeOfElement);
|
||||
}
|
||||
|
||||
array_size.push_back(num);
|
||||
@ -76,7 +79,7 @@ void EclFile::load(bool preload) {
|
||||
|
||||
arrayLoaded.push_back(false);
|
||||
|
||||
if (num > 0){
|
||||
if (num > 0) {
|
||||
if (formatted) {
|
||||
uint64_t sizeOfNextArray = sizeOnDiskFormatted(num, arrType, sizeOfElement);
|
||||
fileH.seekg(static_cast<std::streamoff>(sizeOfNextArray), std::ios_base::cur);
|
||||
@ -95,31 +98,32 @@ void EclFile::load(bool preload) {
|
||||
|
||||
if (preload)
|
||||
this->loadData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EclFile::EclFile(const std::string& filename, EclFile::Formatted fmt, bool preload) :
|
||||
formatted(fmt.value),
|
||||
inputFilename(filename)
|
||||
{
|
||||
EclFile::EclFile(const std::string& filename, EclFile::Formatted fmt, bool preload)
|
||||
: formatted(fmt.value)
|
||||
, inputFilename(filename)
|
||||
{
|
||||
this->load(preload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EclFile::EclFile(const std::string& filename, bool preload) :
|
||||
inputFilename(filename)
|
||||
{
|
||||
EclFile::EclFile(const std::string& filename, bool preload)
|
||||
: inputFilename(filename)
|
||||
{
|
||||
if (!fileExists(filename))
|
||||
// throw std::runtime_error(fmt::format("Can not open EclFile: {}", filename));
|
||||
throw std::runtime_error("Can not open EclFile: {}");
|
||||
|
||||
formatted = isFormatted(filename);
|
||||
this->load(preload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EclFile::loadBinaryArray(std::fstream& fileH, std::size_t arrIndex)
|
||||
{
|
||||
fileH.seekg (ifStreamPos[arrIndex], fileH.beg);
|
||||
void EclFile::loadBinaryArray(std::fstream& fileH, std::size_t arrIndex)
|
||||
{
|
||||
fileH.seekg(ifStreamPos[arrIndex], fileH.beg);
|
||||
|
||||
switch (array_type[arrIndex]) {
|
||||
case INTE:
|
||||
@ -148,10 +152,10 @@ void EclFile::loadBinaryArray(std::fstream& fileH, std::size_t arrIndex)
|
||||
}
|
||||
|
||||
arrayLoaded[arrIndex] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EclFile::loadFormattedArray(const std::string& fileStr, std::size_t arrIndex, int64_t fromPos)
|
||||
{
|
||||
void EclFile::loadFormattedArray(const std::string& fileStr, std::size_t arrIndex, int64_t fromPos)
|
||||
{
|
||||
|
||||
switch (array_type[arrIndex]) {
|
||||
case INTE:
|
||||
@ -170,7 +174,8 @@ void EclFile::loadFormattedArray(const std::string& fileStr, std::size_t arrInde
|
||||
char_array[arrIndex] = readFormattedCharArray(fileStr, array_size[arrIndex], fromPos, sizeOfChar);
|
||||
break;
|
||||
case C0NN:
|
||||
char_array[arrIndex] = readFormattedCharArray(fileStr, array_size[arrIndex], fromPos, array_element_size[arrIndex]);
|
||||
char_array[arrIndex]
|
||||
= readFormattedCharArray(fileStr, array_size[arrIndex], fromPos, array_element_size[arrIndex]);
|
||||
break;
|
||||
case MESS:
|
||||
break;
|
||||
@ -180,11 +185,11 @@ void EclFile::loadFormattedArray(const std::string& fileStr, std::size_t arrInde
|
||||
}
|
||||
|
||||
arrayLoaded[arrIndex] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EclFile::loadData()
|
||||
{
|
||||
void EclFile::loadData()
|
||||
{
|
||||
|
||||
if (formatted) {
|
||||
|
||||
@ -199,7 +204,7 @@ void EclFile::loadData()
|
||||
fileH.open(inputFilename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH) {
|
||||
std::string message="Could not open file: '" + inputFilename +"'";
|
||||
std::string message = "Could not open file: '" + inputFilename + "'";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
@ -209,11 +214,11 @@ void EclFile::loadData()
|
||||
|
||||
fileH.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EclFile::loadData(const std::string& name)
|
||||
{
|
||||
void EclFile::loadData(const std::string& name)
|
||||
{
|
||||
|
||||
if (formatted) {
|
||||
|
||||
@ -225,16 +230,15 @@ void EclFile::loadData(const std::string& name)
|
||||
|
||||
inFile.seekg(ifStreamPos[arrIndex]);
|
||||
|
||||
char* buffer;
|
||||
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])+1;
|
||||
buffer = new char [size];
|
||||
inFile.read (buffer, size);
|
||||
size_t size
|
||||
= sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])
|
||||
+ 1;
|
||||
std::vector<char> buffer(size);
|
||||
inFile.read(buffer.data(), size);
|
||||
|
||||
std::string fileStr = std::string(buffer, size);
|
||||
std::string fileStr = std::string(buffer.data(), size);
|
||||
|
||||
loadFormattedArray(fileStr, arrIndex, 0);
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +248,7 @@ void EclFile::loadData(const std::string& name)
|
||||
fileH.open(inputFilename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH) {
|
||||
std::string message="Could not open file: '" + inputFilename +"'";
|
||||
std::string message = "Could not open file: '" + inputFilename + "'";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
@ -256,11 +260,11 @@ void EclFile::loadData(const std::string& name)
|
||||
|
||||
fileH.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EclFile::loadData(const std::vector<int>& arrIndex)
|
||||
{
|
||||
void EclFile::loadData(const std::vector<int>& arrIndex)
|
||||
{
|
||||
|
||||
if (formatted) {
|
||||
|
||||
@ -270,16 +274,13 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
|
||||
|
||||
inFile.seekg(ifStreamPos[ind]);
|
||||
|
||||
char* buffer;
|
||||
size_t size = sizeOnDiskFormatted(array_size[ind], array_type[ind], array_element_size[ind])+1;
|
||||
buffer = new char [size];
|
||||
inFile.read (buffer, size);
|
||||
size_t size = sizeOnDiskFormatted(array_size[ind], array_type[ind], array_element_size[ind]) + 1;
|
||||
std::vector<char> buffer(size);
|
||||
inFile.read(buffer.data(), size);
|
||||
|
||||
std::string fileStr = std::string(buffer, size);
|
||||
std::string fileStr = std::string(buffer.data(), size);
|
||||
|
||||
loadFormattedArray(fileStr, ind, 0);
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -287,7 +288,7 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
|
||||
fileH.open(inputFilename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH) {
|
||||
std::string message="Could not open file: '" + inputFilename +"'";
|
||||
std::string message = "Could not open file: '" + inputFilename + "'";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
@ -297,35 +298,33 @@ void EclFile::loadData(const std::vector<int>& arrIndex)
|
||||
|
||||
fileH.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EclFile::loadData(int arrIndex)
|
||||
{
|
||||
void EclFile::loadData(int arrIndex)
|
||||
{
|
||||
if (formatted) {
|
||||
|
||||
std::ifstream inFile(inputFilename);
|
||||
|
||||
inFile.seekg(ifStreamPos[arrIndex]);
|
||||
|
||||
char* buffer;
|
||||
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])+1;
|
||||
buffer = new char [size];
|
||||
inFile.read (buffer, size);
|
||||
size_t size
|
||||
= sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex]) + 1;
|
||||
std::vector<char> buffer(size);
|
||||
inFile.read(buffer.data(), size);
|
||||
|
||||
std::string fileStr = std::string(buffer, size);
|
||||
std::string fileStr = std::string(buffer.data(), size);
|
||||
|
||||
loadFormattedArray(fileStr, arrIndex, 0);
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
|
||||
} else {
|
||||
std::fstream fileH;
|
||||
fileH.open(inputFilename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH) {
|
||||
std::string message="Could not open file: '" + inputFilename +"'";
|
||||
std::string message = "Could not open file: '" + inputFilename + "'";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
@ -333,10 +332,10 @@ void EclFile::loadData(int arrIndex)
|
||||
|
||||
fileH.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EclFile::is_ix() const
|
||||
{
|
||||
bool EclFile::is_ix() const
|
||||
{
|
||||
// assuming that array data type C0nn only are used in IX. This may change in future.
|
||||
|
||||
// Formatted files,
|
||||
@ -345,7 +344,7 @@ bool EclFile::is_ix() const
|
||||
// >> if logi array exists in file, look for IX spes binary representation of true value
|
||||
|
||||
if (formatted) {
|
||||
for (size_t n=0; n < array_type.size(); n++) {
|
||||
for (size_t n = 0; n < array_type.size(); n++) {
|
||||
if (array_type[n] == Opm::EclIO::C0NN) {
|
||||
return true;
|
||||
} else if (array_type[n] == Opm::EclIO::REAL) {
|
||||
@ -368,7 +367,7 @@ bool EclFile::is_ix() const
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t n=0; n < array_type.size(); n++) {
|
||||
for (size_t n = 0; n < array_type.size(); n++) {
|
||||
if (array_type[n] == Opm::EclIO::C0NN) {
|
||||
return true;
|
||||
} else if (array_type[n] == Opm::EclIO::LOGI) {
|
||||
@ -384,10 +383,10 @@ bool EclFile::is_ix() const
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> EclFile::get_bin_logi_raw_values(int arrIndex) const
|
||||
{
|
||||
std::vector<unsigned int> EclFile::get_bin_logi_raw_values(int arrIndex) const
|
||||
{
|
||||
if (array_type[arrIndex] != Opm::EclIO::LOGI)
|
||||
OPM_THROW(std::runtime_error, "Error, selected array is not of type LOGI");
|
||||
|
||||
@ -395,19 +394,19 @@ std::vector<unsigned int> EclFile::get_bin_logi_raw_values(int arrIndex) const
|
||||
fileH.open(inputFilename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH) {
|
||||
std::string message="Could not open file: '" + inputFilename +"'";
|
||||
std::string message = "Could not open file: '" + inputFilename + "'";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
fileH.seekg (ifStreamPos[arrIndex], fileH.beg);
|
||||
fileH.seekg(ifStreamPos[arrIndex], fileH.beg);
|
||||
|
||||
std::vector<unsigned int> raw_logi = readBinaryRawLogiArray(fileH, array_size[arrIndex]);
|
||||
|
||||
return raw_logi;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> EclFile::get_fmt_real_raw_str_values(int arrIndex) const
|
||||
{
|
||||
std::vector<std::string> EclFile::get_fmt_real_raw_str_values(int arrIndex) const
|
||||
{
|
||||
std::vector<std::string> real_vect;
|
||||
|
||||
if (array_type[arrIndex] != Opm::EclIO::REAL)
|
||||
@ -416,30 +415,28 @@ std::vector<std::string> EclFile::get_fmt_real_raw_str_values(int arrIndex) cons
|
||||
std::ifstream inFile(inputFilename);
|
||||
|
||||
if (!inFile) {
|
||||
std::string message="Could not open file: '" + inputFilename +"'";
|
||||
std::string message = "Could not open file: '" + inputFilename + "'";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
inFile.seekg(ifStreamPos[arrIndex]);
|
||||
|
||||
char* buffer;
|
||||
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex])+1;
|
||||
size_t size = sizeOnDiskFormatted(array_size[arrIndex], array_type[arrIndex], array_element_size[arrIndex]) + 1;
|
||||
|
||||
buffer = new char [size];
|
||||
inFile.read (buffer, size);
|
||||
std::vector<char> buffer(size);
|
||||
inFile.read(buffer.data(), size);
|
||||
|
||||
std::string fileStr = std::string(buffer, size);
|
||||
std::string fileStr = std::string(buffer.data(), size);
|
||||
|
||||
std::vector<std::string> real_vect_str;
|
||||
real_vect_str = readFormattedRealRawStrings(fileStr, array_size[arrIndex], 0);
|
||||
delete buffer;
|
||||
|
||||
return real_vect_str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<EclFile::EclEntry> EclFile::getList() const
|
||||
{
|
||||
std::vector<EclFile::EclEntry> EclFile::getList() const
|
||||
{
|
||||
std::vector<EclEntry> list;
|
||||
list.reserve(this->array_name.size());
|
||||
|
||||
@ -448,66 +445,64 @@ std::vector<EclFile::EclEntry> EclFile::getList() const
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<int>& EclFile::get<int>(int arrIndex)
|
||||
{
|
||||
template <>
|
||||
const std::vector<int>& EclFile::get<int>(int arrIndex)
|
||||
{
|
||||
return getImpl(arrIndex, INTE, inte_array, "integer");
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
const std::vector<float>&
|
||||
EclFile::get<float>(int arrIndex)
|
||||
{
|
||||
template <>
|
||||
const std::vector<float>& EclFile::get<float>(int arrIndex)
|
||||
{
|
||||
return getImpl(arrIndex, REAL, real_array, "float");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<double> &EclFile::get<double>(int arrIndex)
|
||||
{
|
||||
template <>
|
||||
const std::vector<double>& EclFile::get<double>(int arrIndex)
|
||||
{
|
||||
return getImpl(arrIndex, DOUB, doub_array, "double");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<bool>& EclFile::get<bool>(int arrIndex)
|
||||
{
|
||||
template <>
|
||||
const std::vector<bool>& EclFile::get<bool>(int arrIndex)
|
||||
{
|
||||
return getImpl(arrIndex, LOGI, logi_array, "bool");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<std::string>& EclFile::get<std::string>(int arrIndex)
|
||||
{
|
||||
if ((array_type[arrIndex] != Opm::EclIO::C0NN) && (array_type[arrIndex] != Opm::EclIO::CHAR)){
|
||||
template <>
|
||||
const std::vector<std::string>& EclFile::get<std::string>(int arrIndex)
|
||||
{
|
||||
if ((array_type[arrIndex] != Opm::EclIO::C0NN) && (array_type[arrIndex] != Opm::EclIO::CHAR)) {
|
||||
std::string message = "Array with index " + std::to_string(arrIndex) + " is not of type " + "std::string";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
return getImpl(arrIndex, array_type[arrIndex], char_array, "string");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EclFile::hasKey(const std::string &name) const
|
||||
{
|
||||
bool EclFile::hasKey(const std::string& name) const
|
||||
{
|
||||
auto search = array_index.find(name);
|
||||
return search != array_index.end();
|
||||
}
|
||||
}
|
||||
|
||||
size_t EclFile::count(const std::string &name) const
|
||||
{
|
||||
return std::count (array_name.begin(), array_name.end(), name);
|
||||
}
|
||||
size_t EclFile::count(const std::string& name) const
|
||||
{
|
||||
return std::count(array_name.begin(), array_name.end(), name);
|
||||
}
|
||||
|
||||
|
||||
std::streampos
|
||||
EclFile::seekPosition(const std::vector<std::string>::size_type arrIndex) const
|
||||
{
|
||||
std::streampos EclFile::seekPosition(const std::vector<std::string>::size_type arrIndex) const
|
||||
{
|
||||
if (arrIndex >= this->array_name.size()) {
|
||||
return { static_cast<std::streamoff>(this->ifStreamPos.back()) };
|
||||
return {static_cast<std::streamoff>(this->ifStreamPos.back())};
|
||||
}
|
||||
|
||||
// StreamPos is file position of start of data vector's control
|
||||
@ -552,89 +547,110 @@ EclFile::seekPosition(const std::vector<std::string>::size_type arrIndex) const
|
||||
|
||||
const auto headerSize = this->formatted ? 30ul : 24ul;
|
||||
const auto datapos = this->ifStreamPos[arrIndex];
|
||||
const auto seekpos = (datapos <= headerSize)
|
||||
? 0ul : datapos - headerSize;
|
||||
const auto seekpos = (datapos <= headerSize) ? 0ul : datapos - headerSize;
|
||||
|
||||
return { static_cast<std::streamoff>(seekpos) };
|
||||
}
|
||||
return {static_cast<std::streamoff>(seekpos)};
|
||||
}
|
||||
|
||||
template<>
|
||||
const std::vector<int>& EclFile::get<int>(const std::string& name)
|
||||
{
|
||||
template <>
|
||||
const std::vector<int>& EclFile::get<int>(const std::string& name)
|
||||
{
|
||||
auto search = array_index.find(name);
|
||||
|
||||
if (search == array_index.end()) {
|
||||
std::string message="key '"+name + "' not found";
|
||||
std::string message = "key '" + name + "' not found";
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
return getImpl(search->second, INTE, inte_array, "integer");
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
const std::vector<float>& EclFile::get<float>(const std::string& name)
|
||||
{
|
||||
template <>
|
||||
const std::vector<float>& EclFile::get<float>(const std::string& name)
|
||||
{
|
||||
auto search = array_index.find(name);
|
||||
|
||||
if (search == array_index.end()) {
|
||||
std::string message="key '"+name + "' not found";
|
||||
std::string message = "key '" + name + "' not found";
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
return getImpl(search->second, REAL, real_array, "float");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<double>& EclFile::get<double>(const std::string &name)
|
||||
{
|
||||
template <>
|
||||
const std::vector<double>& EclFile::get<double>(const std::string& name)
|
||||
{
|
||||
auto search = array_index.find(name);
|
||||
|
||||
if (search == array_index.end()) {
|
||||
std::string message="key '"+name + "' not found";
|
||||
std::string message = "key '" + name + "' not found";
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
return getImpl(search->second, DOUB, doub_array, "double");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<bool>& EclFile::get<bool>(const std::string &name)
|
||||
{
|
||||
template <>
|
||||
const std::vector<bool>& EclFile::get<bool>(const std::string& name)
|
||||
{
|
||||
auto search = array_index.find(name);
|
||||
|
||||
if (search == array_index.end()) {
|
||||
std::string message="key '"+name + "' not found";
|
||||
std::string message = "key '" + name + "' not found";
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
return getImpl(search->second, LOGI, logi_array, "bool");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const std::vector<std::string>& EclFile::get<std::string>(const std::string &name)
|
||||
{
|
||||
template <>
|
||||
const std::vector<std::string>& EclFile::get<std::string>(const std::string& name)
|
||||
{
|
||||
auto search = array_index.find(name);
|
||||
|
||||
if (search == array_index.end()) {
|
||||
std::string message="key '"+name + "' not found";
|
||||
std::string message = "key '" + name + "' not found";
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
if ((array_type[search->second] != Opm::EclIO::C0NN) && (array_type[search->second] != Opm::EclIO::CHAR)){
|
||||
std::string message = "Array with index " + std::to_string(search->second) + " is not of type " + "std::string";
|
||||
if ((array_type[search->second] != Opm::EclIO::C0NN) && (array_type[search->second] != Opm::EclIO::CHAR)) {
|
||||
std::string message
|
||||
= "Array with index " + std::to_string(search->second) + " is not of type " + "std::string";
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
return getImpl(search->second, array_type[search->second], char_array, "string");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t EclFile::size() const {
|
||||
template <class T>
|
||||
const std::vector<T>& EclFile::getImpl(int arrIndex,
|
||||
eclArrType type,
|
||||
const std::unordered_map<int, std::vector<T>>& array,
|
||||
const std::string& typeStr)
|
||||
{
|
||||
if (array_type[arrIndex] != type) {
|
||||
std::string message = "Array with index " + std::to_string(arrIndex) + " is not of type " + typeStr;
|
||||
OPM_THROW(std::runtime_error, message);
|
||||
}
|
||||
|
||||
if (!arrayLoaded[arrIndex]) {
|
||||
loadData(arrIndex);
|
||||
}
|
||||
|
||||
return array.at(arrIndex);
|
||||
}
|
||||
|
||||
|
||||
std::size_t EclFile::size() const
|
||||
{
|
||||
return this->array_name.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}} // namespace Opm::ecl
|
||||
} // namespace EclIO
|
||||
} // namespace Opm
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
#include <opm/io/eclipse/EclOutput.hpp>
|
||||
|
Loading…
Reference in New Issue
Block a user