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;
|
||||
@ -115,7 +116,8 @@ public:
|
||||
RimGridView* activeMainOrComparisonGridView();
|
||||
int currentScriptCaseId() const;
|
||||
|
||||
RimProject* project();
|
||||
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 );
|
||||
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,336 +23,549 @@
|
||||
|
||||
#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
|
||||
{
|
||||
initFileName = inputFileName.parent_path() / inputFileName.stem();
|
||||
|
||||
if (this->formattedInput())
|
||||
initFileName += ".FINIT";
|
||||
else
|
||||
initFileName += ".INIT";
|
||||
|
||||
std::string lgrname = "global";
|
||||
|
||||
m_nncs_loaded = false;
|
||||
actnum_array_index = -1;
|
||||
nnc1_array_index = -1;
|
||||
nnc2_array_index = -1;
|
||||
m_radial = false;
|
||||
|
||||
int hostnum_index = -1;
|
||||
|
||||
for (size_t n = 0; n < array_name.size(); n++) {
|
||||
|
||||
if (array_name[n] == "ENDLGR")
|
||||
lgrname = "global";
|
||||
|
||||
if (array_name[n] == "LGR") {
|
||||
auto lgr = this->get<std::string>(n);
|
||||
lgrname = lgr[0];
|
||||
lgr_names.push_back(lgr[0]);
|
||||
}
|
||||
|
||||
if (array_name[n] == "NNCHEAD"){
|
||||
auto nnchead = this->get<int>(n);
|
||||
|
||||
if (nnchead[1] == 0)
|
||||
lgrname = "global";
|
||||
else
|
||||
lgrname = lgr_names[nnchead[1] - 1];
|
||||
}
|
||||
|
||||
if (lgrname == grid_name) {
|
||||
if (array_name[n] == "GRIDHEAD") {
|
||||
auto gridhead = get<int>(n);
|
||||
nijk[0] = gridhead[1];
|
||||
nijk[1] = gridhead[2];
|
||||
nijk[2] = gridhead[3];
|
||||
|
||||
if (gridhead.size() > 26)
|
||||
m_radial = gridhead[26] > 0 ? true: false;
|
||||
}
|
||||
|
||||
if (array_name[n] == "COORD")
|
||||
coord_array_index= n;
|
||||
else if (array_name[n] == "ZCORN")
|
||||
zcorn_array_index= n;
|
||||
else if (array_name[n] == "ACTNUM")
|
||||
actnum_array_index= n;
|
||||
else if (array_name[n] == "NNC1")
|
||||
nnc1_array_index= n;
|
||||
else if (array_name[n] == "NNC2")
|
||||
nnc2_array_index= n;
|
||||
else if (array_name[n] == "HOSTNUM")
|
||||
hostnum_index= n;
|
||||
}
|
||||
|
||||
if ((lgrname == "global") && (array_name[n] == "GRIDHEAD")) {
|
||||
auto gridhead = get<int>(n);
|
||||
host_nijk[0] = gridhead[1];
|
||||
host_nijk[1] = gridhead[2];
|
||||
host_nijk[2] = gridhead[3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (actnum_array_index != -1) {
|
||||
auto actnum = this->get<int>(actnum_array_index);
|
||||
nactive = 0;
|
||||
for (size_t i = 0; i < actnum.size(); i++) {
|
||||
if (actnum[i] > 0) {
|
||||
act_index.push_back(nactive);
|
||||
glob_index.push_back(i);
|
||||
nactive++;
|
||||
} else {
|
||||
act_index.push_back(-1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int nCells = nijk[0] * nijk[1] * nijk[2];
|
||||
act_index.resize(nCells);
|
||||
glob_index.resize(nCells);
|
||||
std::iota(act_index.begin(), act_index.end(), 0);
|
||||
std::iota(glob_index.begin(), glob_index.end(), 0);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::array<int, 3>> EGrid::hostCellsIJK()
|
||||
namespace EclIO
|
||||
{
|
||||
std::vector<std::array<int, 3>> res_vect;
|
||||
res_vect.reserve(host_cells.size());
|
||||
|
||||
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]);
|
||||
using NNCentry = std::tuple<int, int, int, int, int, int, float>;
|
||||
|
||||
tmp[1] = rest / host_nijk[0];
|
||||
tmp[0] = rest % host_nijk[0];
|
||||
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();
|
||||
|
||||
res_vect.push_back(tmp);
|
||||
}
|
||||
|
||||
return res_vect;
|
||||
}
|
||||
|
||||
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++){
|
||||
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]});
|
||||
if (this->formattedInput())
|
||||
initFileName += ".FINIT";
|
||||
else
|
||||
res_vect.push_back({ijk1[0], ijk1[1], ijk1[2], ijk2[0], ijk2[1], ijk2[2], -1.0 });
|
||||
}
|
||||
initFileName += ".INIT";
|
||||
|
||||
return res_vect;
|
||||
}
|
||||
std::string lgrname = "global";
|
||||
|
||||
m_nncs_loaded = false;
|
||||
actnum_array_index = -1;
|
||||
nnc1_array_index = -1;
|
||||
nnc2_array_index = -1;
|
||||
m_radial = false;
|
||||
m_mapunits = "";
|
||||
|
||||
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");
|
||||
}
|
||||
int hostnum_index = -1;
|
||||
|
||||
void EGrid::load_nnc_data()
|
||||
{
|
||||
if ((nnc1_array_index > -1) && (nnc2_array_index > -1)) {
|
||||
for (size_t n = 0; n < array_name.size(); n++) {
|
||||
|
||||
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 (array_name[n] == "ENDLGR")
|
||||
lgrname = "global";
|
||||
|
||||
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){
|
||||
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]);
|
||||
message = message + "Egrid: " + grid_str + ". INIT file: " + init_str;
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
if (array_name[n] == "LGR") {
|
||||
auto lgr = this->get<std::string>(n);
|
||||
lgrname = lgr[0];
|
||||
lgr_names.push_back(lgr[0]);
|
||||
}
|
||||
|
||||
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);
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
if (array_name[n] == "NNCHEAD") {
|
||||
auto nnchead = this->get<int>(n);
|
||||
|
||||
if (nnchead[1] == 0)
|
||||
lgrname = "global";
|
||||
else
|
||||
lgrname = lgr_names[nnchead[1] - 1];
|
||||
}
|
||||
|
||||
auto trans_data = init.getInitData<float>("TRANNNC", m_grid_name);
|
||||
|
||||
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());
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
if (array_name[n] == "MAPUNITS") {
|
||||
auto mapunits = this->get<std::string>(n);
|
||||
m_mapunits = mapunits[0];
|
||||
}
|
||||
|
||||
transnnc_array = trans_data;
|
||||
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);
|
||||
nijk[0] = gridhead[1];
|
||||
nijk[1] = gridhead[2];
|
||||
nijk[2] = gridhead[3];
|
||||
|
||||
if (gridhead.size() > 26)
|
||||
m_radial = gridhead[26] > 0 ? true : false;
|
||||
}
|
||||
|
||||
if (array_name[n] == "COORD")
|
||||
coord_array_index = n;
|
||||
else if (array_name[n] == "ZCORN")
|
||||
zcorn_array_index = n;
|
||||
else if (array_name[n] == "ACTNUM")
|
||||
actnum_array_index = n;
|
||||
else if (array_name[n] == "NNC1")
|
||||
nnc1_array_index = n;
|
||||
else if (array_name[n] == "NNC2")
|
||||
nnc2_array_index = n;
|
||||
else if (array_name[n] == "HOSTNUM")
|
||||
hostnum_index = n;
|
||||
}
|
||||
|
||||
if ((lgrname == "global") && (array_name[n] == "GRIDHEAD")) {
|
||||
auto gridhead = get<int>(n);
|
||||
host_nijk[0] = gridhead[1];
|
||||
host_nijk[1] = gridhead[2];
|
||||
host_nijk[2] = gridhead[3];
|
||||
}
|
||||
}
|
||||
|
||||
m_nncs_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
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 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]) {
|
||||
OPM_THROW(std::invalid_argument, "i, j or/and k out of range");
|
||||
}
|
||||
|
||||
return act_index[n];
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
int _glob = glob_index[actInd];
|
||||
|
||||
std::array<int, 3> result;
|
||||
result[2] = _glob / (nijk[0] * nijk[1]);
|
||||
|
||||
int rest = _glob % (nijk[0] * nijk[1]);
|
||||
|
||||
result[1] = rest / nijk[0];
|
||||
result[0] = rest % nijk[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
std::array<int, 3> result;
|
||||
result[2] = globInd / (nijk[0] * nijk[1]);
|
||||
|
||||
int rest = globInd % (nijk[0] * nijk[1]);
|
||||
|
||||
result[1] = rest / nijk[0];
|
||||
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)
|
||||
{
|
||||
if (coord_array.empty())
|
||||
load_grid_data();
|
||||
|
||||
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++)
|
||||
zind.push_back(zind[n] + nijk[0]*nijk[1]*4);
|
||||
|
||||
for (int n = 0; n< 8; n++)
|
||||
Z[n] = zcorn_array[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];
|
||||
|
||||
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);
|
||||
if (actnum_array_index != -1) {
|
||||
auto actnum = this->get<int>(actnum_array_index);
|
||||
nactive = 0;
|
||||
for (size_t i = 0; i < actnum.size(); i++) {
|
||||
if (actnum[i] > 0) {
|
||||
act_index.push_back(nactive);
|
||||
glob_index.push_back(i);
|
||||
nactive++;
|
||||
} else {
|
||||
act_index.push_back(-1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int nCells = nijk[0] * nijk[1] * nijk[2];
|
||||
act_index.resize(nCells);
|
||||
glob_index.resize(nCells);
|
||||
std::iota(act_index.begin(), act_index.end(), 0);
|
||||
std::iota(glob_index.begin(), glob_index.end(), 0);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
std::array<int, 3> tmp;
|
||||
tmp[2] = val / (host_nijk[0] * host_nijk[1]);
|
||||
int rest = val % (host_nijk[0] * host_nijk[1]);
|
||||
|
||||
tmp[1] = rest / host_nijk[0];
|
||||
tmp[0] = rest % host_nijk[0];
|
||||
|
||||
res_vect.push_back(tmp);
|
||||
}
|
||||
|
||||
return res_vect;
|
||||
}
|
||||
|
||||
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++) {
|
||||
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});
|
||||
}
|
||||
|
||||
return res_vect;
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
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)) {
|
||||
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) {
|
||||
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]);
|
||||
message = message + "Egrid: " + grid_str + ". INIT file: " + init_str;
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
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);
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
auto trans_data = init.getInitData<float>("TRANNNC", m_grid_name);
|
||||
|
||||
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());
|
||||
OPM_THROW(std::invalid_argument, message);
|
||||
}
|
||||
|
||||
transnnc_array = trans_data;
|
||||
}
|
||||
|
||||
m_nncs_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
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 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]) {
|
||||
OPM_THROW(std::invalid_argument, "i, j or/and k out of range");
|
||||
}
|
||||
|
||||
return act_index[n];
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
int _glob = glob_index[actInd];
|
||||
|
||||
std::array<int, 3> result;
|
||||
result[2] = _glob / (nijk[0] * nijk[1]);
|
||||
|
||||
int rest = _glob % (nijk[0] * nijk[1]);
|
||||
|
||||
result[1] = rest / nijk[0];
|
||||
result[0] = rest % nijk[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
std::array<int, 3> result;
|
||||
result[2] = globInd / (nijk[0] * nijk[1]);
|
||||
|
||||
int rest = globInd % (nijk[0] * nijk[1]);
|
||||
|
||||
result[1] = rest / nijk[0];
|
||||
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)
|
||||
{
|
||||
if (coord_array.empty())
|
||||
load_grid_data();
|
||||
|
||||
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++)
|
||||
zind.push_back(zind[n] + nijk[0] * nijk[1] * 4);
|
||||
|
||||
for (int n = 0; n < 8; n++)
|
||||
Z[n] = zcorn_array[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];
|
||||
|
||||
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);
|
||||
} else {
|
||||
xt = coord_array[pind[n]];
|
||||
yt = coord_array[pind[n] + 1];
|
||||
xb = coord_array[pind[n] + 3];
|
||||
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]);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
} // 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>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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