mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#7912 Summary Data Import : Update selected opm-common files
This commit is contained in:
parent
c7917915cd
commit
2dbe0a0c9c
@ -21,10 +21,12 @@
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "opm/io/eclipse/ESmry.hpp"
|
||||
#include "opm/io/eclipse/ExtESmry.hpp"
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
#include "QFileInfo"
|
||||
|
||||
size_t RifOpmCommonEclipseSummary::sm_createdLodFileCount = 0;
|
||||
|
||||
@ -83,26 +85,34 @@ bool RifOpmCommonEclipseSummary::open( const QString& headerFileName,
|
||||
bool includeRestartFiles,
|
||||
RiaThreadSafeLogger* threadSafeLogger )
|
||||
{
|
||||
if ( !openESmryFile( headerFileName, includeRestartFiles, threadSafeLogger ) ) return false;
|
||||
|
||||
if ( m_createLodsmryFiles && !includeRestartFiles )
|
||||
if ( m_createLodsmryFiles )
|
||||
{
|
||||
// Create the lodsmry file, no-op if already present.
|
||||
bool hasFileBeenCreated = m_eSmry->make_lodsmry_file();
|
||||
|
||||
if ( hasFileBeenCreated )
|
||||
auto candidateFileName = extendedSummaryFilename( headerFileName );
|
||||
if ( !QFileInfo::exists( candidateFileName ) )
|
||||
{
|
||||
RifOpmCommonEclipseSummary::increaseLodFileCount();
|
||||
try
|
||||
{
|
||||
auto temporarySummaryFile =
|
||||
std::make_unique<Opm::EclIO::ESmry>(headerFileName.toStdString(), includeRestartFiles );
|
||||
|
||||
// If a LODSMRY file has been created, all data for all vectors has now been loaded into the summary file
|
||||
// object. Close the file object to make sure allocated data is released, and create a new file object
|
||||
// that will import only the meta data and no curve data. This is a relatively fast operation.
|
||||
temporarySummaryFile->make_esmry_file();
|
||||
|
||||
if ( !openESmryFile( headerFileName, includeRestartFiles, threadSafeLogger ) ) return false;
|
||||
RifOpmCommonEclipseSummary::increaseLodFileCount();
|
||||
}
|
||||
catch ( std::exception& e )
|
||||
{
|
||||
QString txt = QString( "Failed to create optimized summary file. Error text : %1" ).arg( e.what() );
|
||||
|
||||
if ( threadSafeLogger ) threadSafeLogger->error( txt );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_eSmry ) return false;
|
||||
if ( !openESmryFile( headerFileName, includeRestartFiles, threadSafeLogger ) ) return false;
|
||||
|
||||
if ( !m_eSmry && !m_exteSmry ) return false;
|
||||
|
||||
buildMetaData();
|
||||
|
||||
@ -122,6 +132,20 @@ const std::vector<time_t>& RifOpmCommonEclipseSummary::timeSteps( const RifEclip
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifOpmCommonEclipseSummary::values( const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values ) const
|
||||
{
|
||||
if ( m_exteSmry )
|
||||
{
|
||||
auto it = m_adrToSummaryNodeIndex.find( resultAddress );
|
||||
if ( it != m_adrToSummaryNodeIndex.end() )
|
||||
{
|
||||
// auto index = it->second;
|
||||
// auto node = m_exteSmry->summaryNodeList()[index];
|
||||
// auto fileValues = m_exteSmry->get( node );
|
||||
// values->insert( values->begin(), fileValues.begin(), fileValues.end() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( m_eSmry )
|
||||
{
|
||||
auto it = m_adrToSummaryNodeIndex.find( resultAddress );
|
||||
@ -195,10 +219,24 @@ bool RifOpmCommonEclipseSummary::openESmryFile( const QString& headerFileN
|
||||
bool includeRestartFiles,
|
||||
RiaThreadSafeLogger* threadSafeLogger )
|
||||
{
|
||||
if ( m_useLodsmryFiles )
|
||||
{
|
||||
try
|
||||
{
|
||||
auto candidateFileName = extendedSummaryFilename( headerFileName );
|
||||
m_exteSmry = std::make_unique<Opm::EclIO::ExtESmry>( candidateFileName.toStdString(), includeRestartFiles );
|
||||
|
||||
return true;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
// Do not do anything here, try to open the file using standard esmy reader
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_eSmry =
|
||||
std::make_unique<Opm::EclIO::ESmry>( headerFileName.toStdString(), includeRestartFiles, m_useLodsmryFiles );
|
||||
m_eSmry = std::make_unique<Opm::EclIO::ESmry>( headerFileName.toStdString(), includeRestartFiles );
|
||||
}
|
||||
catch ( std::exception& e )
|
||||
{
|
||||
@ -222,6 +260,15 @@ void RifOpmCommonEclipseSummary::increaseLodFileCount()
|
||||
sm_createdLodFileCount++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifOpmCommonEclipseSummary::extendedSummaryFilename( const QString& headerFileName)
|
||||
{
|
||||
QString s(headerFileName);
|
||||
return s.replace( ".SMSPEC", ".ESMRY" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -37,6 +37,7 @@ namespace Opm
|
||||
namespace EclIO
|
||||
{
|
||||
class ESmry;
|
||||
class ExtESmry;
|
||||
struct SummaryNode;
|
||||
} // namespace EclIO
|
||||
} // namespace Opm
|
||||
@ -81,9 +82,12 @@ private:
|
||||
bool openESmryFile( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
|
||||
|
||||
static void increaseLodFileCount();
|
||||
static QString extendedSummaryFilename(const QString& headerFileName);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Opm::EclIO::ESmry> m_eSmry;
|
||||
std::unique_ptr<Opm::EclIO::ExtESmry> m_exteSmry;
|
||||
|
||||
std::vector<std::string> m_eSmryKeywords;
|
||||
std::map<RifEclipseSummaryAddress, size_t> m_adrToSummaryNodeIndex;
|
||||
std::vector<time_t> m_timeSteps;
|
||||
|
@ -180,7 +180,7 @@ bool RifOpmHdf5Summary::openESmryFile( const QString& headerFileName,
|
||||
{
|
||||
try
|
||||
{
|
||||
m_eSmry = std::make_unique<Opm::EclIO::ESmry>( headerFileName.toStdString(), includeRestartFiles, false );
|
||||
m_eSmry = std::make_unique<Opm::EclIO::ESmry>( headerFileName.toStdString(), includeRestartFiles );
|
||||
}
|
||||
catch ( std::exception& e )
|
||||
{
|
||||
|
3
ThirdParty/custom-opm-common/CMakeLists.txt
vendored
3
ThirdParty/custom-opm-common/CMakeLists.txt
vendored
@ -16,7 +16,7 @@ endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions( "/wd4996 /wd4244 /wd4267" )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /permissive-")
|
||||
endif(MSVC)
|
||||
|
||||
project (custom-opm-common)
|
||||
@ -82,6 +82,7 @@ add_library(${PROJECT_NAME}
|
||||
opm-common/src/opm/io/eclipse/EclUtil.cpp
|
||||
opm-common/src/opm/io/eclipse/EGrid.cpp
|
||||
opm-common/src/opm/io/eclipse/ESmry.cpp
|
||||
opm-common/src/opm/io/eclipse/ExtESmry.cpp
|
||||
opm-common/src/opm/io/eclipse/EInit.cpp
|
||||
|
||||
# Required for use of static function RstConnection::inverse_peaceman
|
||||
|
@ -19,7 +19,8 @@
|
||||
#ifndef OPM_FILESYSTEM_HPP
|
||||
#define OPM_FILESYSTEM_HPP
|
||||
|
||||
#if !defined(_WIN32) && (__cplusplus < 201703L || (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)))
|
||||
#if !defined(_WIN32) && (__cplusplus < 201703L || \
|
||||
(defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)))
|
||||
#include <experimental/filesystem>
|
||||
#else
|
||||
#include <filesystem>
|
||||
@ -30,10 +31,14 @@
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
#if !defined(_WIN32) && (__cplusplus < 201703L || (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)))
|
||||
#if !defined(_WIN32) && (__cplusplus < 201703L || \
|
||||
(defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)))
|
||||
namespace filesystem = std::experimental::filesystem;
|
||||
filesystem::path proximate(const filesystem::path& p,
|
||||
const filesystem::path& base = filesystem::current_path());
|
||||
#else
|
||||
namespace filesystem = std::filesystem;
|
||||
using filesystem::proximate;
|
||||
#endif
|
||||
|
||||
// A poor man's filesystem::unique_path
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
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);
|
||||
std::vector<std::array<float, 3>> getXYZ_layer(int layer, const std::array<int, 4>& box, bool bottom=false);
|
||||
|
||||
int activeCells() const { return nactive; }
|
||||
int totalNumberOfCells() const { return nijk[0] * nijk[1] * nijk[2]; }
|
||||
@ -67,8 +67,8 @@ 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; }
|
||||
const std::vector<float>& get_mapaxes() const { return m_mapaxes; }
|
||||
const std::string& get_mapunits() const { return m_mapunits; }
|
||||
|
||||
private:
|
||||
Opm::filesystem::path inputFileName, initFileName;
|
||||
|
@ -35,15 +35,16 @@ namespace Opm { namespace EclIO {
|
||||
|
||||
using ArrSourceEntry = std::tuple<std::string, std::string, int, uint64_t>;
|
||||
using TimeStepEntry = std::tuple<int, int, uint64_t>;
|
||||
using RstEntry = std::tuple<std::string, int>;
|
||||
|
||||
class ESmry
|
||||
{
|
||||
public:
|
||||
|
||||
// input is smspec (or fsmspec file)
|
||||
explicit ESmry(const std::string& filename, bool loadBaseRunData=false, bool uselodsmry=false);
|
||||
explicit ESmry(const std::string& filename, bool loadBaseRunData=false);
|
||||
|
||||
int numberOfVectors() const { return nVect; }
|
||||
int numberOfVectors() const { return static_cast<int>(nVect); }
|
||||
|
||||
bool hasKey(const std::string& key) const;
|
||||
|
||||
@ -58,10 +59,7 @@ public:
|
||||
void LoadData(const std::vector<std::string>& vectList) const;
|
||||
void LoadData() const;
|
||||
|
||||
bool make_lodsmry_file();
|
||||
|
||||
// Added based on requirements from ResInsight
|
||||
void use_lodsmry_file(bool enable);
|
||||
bool make_esmry_file();
|
||||
|
||||
time_point startdate() const { return startdat; }
|
||||
|
||||
@ -77,16 +75,19 @@ public:
|
||||
const std::string& get_unit(const SummaryNode& node) const;
|
||||
|
||||
void write_rsm(std::ostream&) const;
|
||||
void write_rsm_file(std::optional<Opm::filesystem::path> = std::nullopt) const;
|
||||
void write_rsm_file(std::optional<filesystem::path> = std::nullopt) const;
|
||||
|
||||
bool all_steps_available();
|
||||
|
||||
void ijk_from_global_index(int glob, int &i, int &j, int &k) const;
|
||||
private:
|
||||
bool useLodsmryFile; // Added by ResInsight use
|
||||
|
||||
Opm::filesystem::path inputFileName, lodFileName;
|
||||
private:
|
||||
|
||||
filesystem::path inputFileName;
|
||||
RstEntry restart_info;
|
||||
|
||||
int nI, nJ, nK, nSpecFiles;
|
||||
bool fromSingleRun, lodEnabeled;
|
||||
uint64_t lod_offset, lod_arr_size;
|
||||
bool fromSingleRun;
|
||||
size_t nVect, nTstep;
|
||||
|
||||
std::vector<bool> formattedFiles;
|
||||
@ -94,6 +95,7 @@ private:
|
||||
mutable std::vector<std::vector<float>> vectorData;
|
||||
mutable std::vector<bool> vectorLoaded;
|
||||
std::vector<TimeStepEntry> timeStepList;
|
||||
std::vector<TimeStepEntry> miniStepList;
|
||||
std::vector<std::map<int, int>> arrayPos;
|
||||
std::vector<std::string> keyword;
|
||||
std::map<std::string, int> keyword_index;
|
||||
@ -102,6 +104,7 @@ private:
|
||||
std::vector<std::vector<std::string>> keywordListSpecFile;
|
||||
|
||||
std::vector<int> seqIndex;
|
||||
std::vector<int> mini_steps;
|
||||
|
||||
|
||||
std::vector<SummaryNode> summaryNodes;
|
||||
@ -109,15 +112,15 @@ private:
|
||||
|
||||
time_point startdat;
|
||||
|
||||
std::vector<std::string> checkForMultipleResultFiles(const Opm::filesystem::path& rootN, bool formatted) const;
|
||||
std::vector<std::string> checkForMultipleResultFiles(const filesystem::path& rootN, bool formatted) const;
|
||||
|
||||
void getRstString(const std::vector<std::string>& restartArray,
|
||||
Opm::filesystem::path& pathRst,
|
||||
Opm::filesystem::path& rootN) const;
|
||||
filesystem::path& pathRst,
|
||||
filesystem::path& rootN) const;
|
||||
|
||||
void updatePathAndRootName(Opm::filesystem::path& dir, Opm::filesystem::path& rootN) const;
|
||||
void updatePathAndRootName(filesystem::path& dir, filesystem::path& rootN) const;
|
||||
|
||||
std::string makeKeyString(const std::string& keyword, const std::string& wgname, int num, const std::string& lgr, int lgri, int lgrj, int lgrk) const;
|
||||
std::string makeKeyString(const std::string& keyword, const std::string& wgname, int num) const;
|
||||
|
||||
std::string unpackNumber(const SummaryNode&) const;
|
||||
std::string lookupKey(const SummaryNode&) const;
|
||||
@ -140,8 +143,9 @@ private:
|
||||
std::vector<std::tuple <std::string, uint64_t>> getListOfArrays(std::string filename, bool formatted);
|
||||
std::vector<int> makeKeywPosVector(int speInd) const;
|
||||
std::string read_string_from_disk(std::fstream& fileH, uint64_t size) const;
|
||||
void inspect_lodsmry();
|
||||
void Load_from_lodsmry(const std::vector<int>& keywIndVect) const;
|
||||
|
||||
void read_ministeps_from_disk();
|
||||
int read_ministep_formatted(std::fstream& fileH);
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
@ -20,7 +20,6 @@
|
||||
#define OPM_IO_ECLUTIL_HPP
|
||||
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
@ -38,9 +37,6 @@ namespace Opm { namespace EclIO {
|
||||
bool isFormatted(const std::string& filename);
|
||||
bool is_number(const std::string& numstr);
|
||||
|
||||
bool isEqualCaseInsensitive(const std::string& string1, const std::string& string2);
|
||||
Opm::filesystem::path findFileCaseInsensitive(const Opm::filesystem::path& folder, const std::string& filename);
|
||||
|
||||
std::tuple<int, int> block_size_data_binary(eclArrType arrType);
|
||||
std::tuple<int, int, int> block_size_data_formatted(eclArrType arrType);
|
||||
|
||||
|
106
ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/ExtESmry.hpp
vendored
Normal file
106
ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/ExtESmry.hpp
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
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 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_IO_ExtESmry_HPP
|
||||
#define OPM_IO_ExtESmry_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
using ArrSourceEntry = std::tuple<std::string, std::string, int, uint64_t>;
|
||||
using TimeStepEntry = std::tuple<int, int, uint64_t>;
|
||||
using RstEntry = std::tuple<std::string, int>;
|
||||
|
||||
// start, rstart + rstnum, keycheck, units, rstep, tstep
|
||||
using LodsmryHeadType = std::tuple<time_point, RstEntry, std::vector<std::string>, std::vector<std::string>,
|
||||
std::vector<int>, std::vector<int>>;
|
||||
|
||||
class ExtESmry
|
||||
{
|
||||
public:
|
||||
|
||||
// input is esmry, only binary supported.
|
||||
explicit ExtESmry(const std::string& filename, bool loadBaseRunData=false);
|
||||
|
||||
const std::vector<float>& get(const std::string& name);
|
||||
std::vector<float> get_at_rstep(const std::string& name);
|
||||
std::string& get_unit(const std::string& name);
|
||||
|
||||
void loadData();
|
||||
void loadData(const std::vector<std::string>& stringVect);
|
||||
|
||||
time_point startdate() const { return m_startdat; }
|
||||
|
||||
bool hasKey(const std::string& key) const;
|
||||
|
||||
size_t numberOfTimeSteps() const { return m_nTstep; }
|
||||
size_t numberOfVectors() const { return m_nVect; }
|
||||
|
||||
const std::vector<std::string>& keywordList() const { return m_keyword;}
|
||||
std::vector<std::string> keywordList(const std::string& pattern) const;
|
||||
|
||||
std::vector<time_point> dates();
|
||||
|
||||
bool all_steps_available();
|
||||
|
||||
|
||||
private:
|
||||
filesystem::path m_inputFileName;
|
||||
std::vector<filesystem::path> m_lodsmry_files;
|
||||
|
||||
bool m_loadBaseRun;
|
||||
std::vector<std::map<std::string, int>> m_keyword_index;
|
||||
std::vector<std::tuple<int,int>> m_tstep_range;
|
||||
std::vector<std::string> m_keyword;
|
||||
std::vector<int> m_rstep;
|
||||
std::vector<int> m_tstep;
|
||||
std::vector<std::vector<int>> m_rstep_v;
|
||||
std::vector<std::vector<int>> m_tstep_v;
|
||||
std::vector<std::vector<float>> m_vectorData;
|
||||
std::vector<bool> m_vectorLoaded;
|
||||
std::unordered_map<std::string, std::string> kwunits;
|
||||
|
||||
size_t m_nVect;
|
||||
std::vector<size_t> m_nTstep_v;
|
||||
size_t m_nTstep;
|
||||
std::vector<int> m_seqIndex;
|
||||
|
||||
std::vector<uint64_t> m_lod_offset;
|
||||
std::vector<uint64_t> m_lod_arr_size;
|
||||
|
||||
time_point m_startdat;
|
||||
|
||||
uint64_t open_esmry(Opm::filesystem::path& inputFileName, LodsmryHeadType& lodsmry_head);
|
||||
|
||||
void updatePathAndRootName(Opm::filesystem::path& dir, Opm::filesystem::path& rootN);
|
||||
};
|
||||
|
||||
}} // namespace Opm::EclIO
|
||||
|
||||
|
||||
#endif // OPM_IO_ExtESmry_HPP
|
70
ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/RestartFileView.hpp
vendored
Normal file
70
ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/RestartFileView.hpp
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright 2021 Equinor ASA.
|
||||
|
||||
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 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_RESTART_FILE_VIEW_HPP
|
||||
#define OPM_RESTART_FILE_VIEW_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
class ERst;
|
||||
}} // Opm::EclIO
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
class RestartFileView
|
||||
{
|
||||
public:
|
||||
explicit RestartFileView(std::shared_ptr<ERst> restart_file,
|
||||
const int report_step);
|
||||
|
||||
~RestartFileView();
|
||||
|
||||
RestartFileView(const RestartFileView& rhs) = delete;
|
||||
RestartFileView(RestartFileView&& rhs);
|
||||
|
||||
RestartFileView& operator=(const RestartFileView& rhs) = delete;
|
||||
RestartFileView& operator=(RestartFileView&& rhs);
|
||||
|
||||
std::size_t simStep() const;
|
||||
int reportStep() const;
|
||||
|
||||
int occurrenceCount(const std::string& vector) const;
|
||||
|
||||
template <typename ElmType>
|
||||
bool hasKeyword(const std::string& vector) const;
|
||||
|
||||
template <typename ElmType>
|
||||
const std::vector<ElmType>&
|
||||
getKeyword(const std::string& vector, const int occurrence = 0) const;
|
||||
|
||||
const std::vector<int>& intehead() const;
|
||||
const std::vector<bool>& logihead() const;
|
||||
const std::vector<double>& doubhead() const;
|
||||
|
||||
private:
|
||||
class Implementation;
|
||||
std::unique_ptr<Implementation> pImpl_;
|
||||
};
|
||||
|
||||
}} // Opm::RestartIO
|
||||
|
||||
#endif // OPM_RESTART_FILE_VIEW_HPP
|
@ -47,4 +47,134 @@ std::string unique_path(const std::string& input)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && (__cplusplus < 201703L || \
|
||||
(defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)))
|
||||
|
||||
// The following code has been extracted from libstdc++,
|
||||
// and slightly modified for use here.
|
||||
// License is replicated here for attribution.
|
||||
|
||||
// Copyright (C) 2014-2021 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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 for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace {
|
||||
|
||||
bool is_dot(Opm::filesystem::path::value_type c) { return c == '.'; }
|
||||
|
||||
bool is_dot(const Opm::filesystem::path& path)
|
||||
{
|
||||
const auto& filename = path.native();
|
||||
return filename.size() == 1 && is_dot(filename[0]);
|
||||
}
|
||||
|
||||
bool is_dotdot(const Opm::filesystem::path& path)
|
||||
{
|
||||
const auto& filename = path.native();
|
||||
return filename.size() == 2 && is_dot(filename[0]) && is_dot(filename[1]);
|
||||
}
|
||||
|
||||
Opm::filesystem::path lexically_relative(const Opm::filesystem::path& p,
|
||||
const Opm::filesystem::path& base)
|
||||
{
|
||||
Opm::filesystem::path ret;
|
||||
if (p.root_name() != base.root_name())
|
||||
return ret;
|
||||
|
||||
if (p.is_absolute() != base.is_absolute())
|
||||
return ret;
|
||||
if (!p.has_root_directory() && base.has_root_directory())
|
||||
return ret;
|
||||
auto [a, b] = std::mismatch(p.begin(), p.end(), base.begin(), base.end());
|
||||
if (a == p.end() && b == base.end())
|
||||
ret = ".";
|
||||
else
|
||||
{
|
||||
int n = 0;
|
||||
for (; b != base.end(); ++b)
|
||||
{
|
||||
const Opm::filesystem::path& p2 = *b;
|
||||
if (is_dotdot(p2))
|
||||
--n;
|
||||
else if (!p2.empty() && !is_dot(p2))
|
||||
++n;
|
||||
}
|
||||
if (n == 0 && (a == p.end() || a->empty()))
|
||||
ret = ".";
|
||||
else if (n >= 0)
|
||||
{
|
||||
const Opm::filesystem::path dotdot("..");
|
||||
while (n--)
|
||||
ret /= dotdot;
|
||||
for (; a != p.end(); ++a)
|
||||
ret /= *a;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Opm::filesystem::path
|
||||
lexically_proximate(const Opm::filesystem::path& p, const Opm::filesystem::path& base)
|
||||
{
|
||||
Opm::filesystem::path rel = lexically_relative(p, base);
|
||||
return rel.empty() ? p : rel;
|
||||
}
|
||||
|
||||
Opm::filesystem::path
|
||||
weakly_canonical(const Opm::filesystem::path& p)
|
||||
{
|
||||
Opm::filesystem::path result;
|
||||
if (exists(status(p)))
|
||||
return canonical(p);
|
||||
|
||||
Opm::filesystem::path tmp;
|
||||
auto iter = p.begin(), end = p.end();
|
||||
// find leading elements of p that exist:
|
||||
while (iter != end)
|
||||
{
|
||||
tmp = result / *iter;
|
||||
if (exists(status(tmp)))
|
||||
swap(result, tmp);
|
||||
else
|
||||
break;
|
||||
++iter;
|
||||
}
|
||||
// canonicalize:
|
||||
if (!result.empty())
|
||||
result = canonical(result);
|
||||
// append the non-existing elements:
|
||||
while (iter != end)
|
||||
result /= *iter++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
filesystem::path proximate(const filesystem::path& p, const filesystem::path& base)
|
||||
{
|
||||
return lexically_proximate(weakly_canonical(p), weakly_canonical(base));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -102,7 +102,7 @@ void EclOutput::write(const std::string& name, const std::vector<std::string>& d
|
||||
});
|
||||
|
||||
if (it->size() > static_cast<size_t>(element_size))
|
||||
OPM_THROW(std::runtime_error, "specified element size for type C0NN less than maximum string length in ouput data");
|
||||
OPM_THROW(std::runtime_error, "specified element size for type C0NN less than maximum string length in output data");
|
||||
}
|
||||
|
||||
if (isFormatted)
|
||||
@ -222,14 +222,9 @@ void EclOutput::writeBinaryHeader(const std::string&arrName, int64_t size, eclAr
|
||||
template <typename T>
|
||||
void EclOutput::writeBinaryArray(const std::vector<T>& data)
|
||||
{
|
||||
int num, rval;
|
||||
int64_t rest;
|
||||
int num;
|
||||
int64_t rest, offset;
|
||||
int dhead;
|
||||
float value_f;
|
||||
double value_d;
|
||||
int intVal;
|
||||
|
||||
int64_t n = 0;
|
||||
int64_t size = data.size();
|
||||
|
||||
eclArrType arrType = MESS;
|
||||
@ -257,6 +252,9 @@ void EclOutput::writeBinaryArray(const std::vector<T>& data)
|
||||
int logi_true_val = ix_standard ? true_value_ix : true_value_ecl;
|
||||
|
||||
rest = size * static_cast<int64_t>(sizeOfElement);
|
||||
|
||||
offset = 0;
|
||||
|
||||
while (rest > 0) {
|
||||
if (rest > maxBlockSize) {
|
||||
rest -= maxBlockSize;
|
||||
@ -270,27 +268,56 @@ void EclOutput::writeBinaryArray(const std::vector<T>& data)
|
||||
|
||||
ofileH.write(reinterpret_cast<char*>(&dhead), sizeof(dhead));
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (arrType == INTE) {
|
||||
rval = flipEndianInt(data[n]);
|
||||
ofileH.write(reinterpret_cast<char*>(&rval), sizeof(rval));
|
||||
} else if (arrType == REAL) {
|
||||
value_f = flipEndianFloat(data[n]);
|
||||
ofileH.write(reinterpret_cast<char*>(&value_f), sizeof(value_f));
|
||||
} else if (arrType == DOUB) {
|
||||
value_d = flipEndianDouble(data[n]);
|
||||
ofileH.write(reinterpret_cast<char*>(&value_d), sizeof(value_d));
|
||||
} else if (arrType == LOGI) {
|
||||
intVal = data[n] ? logi_true_val : false_value;
|
||||
ofileH.write(reinterpret_cast<char*>(&intVal), sizeOfElement);
|
||||
} else {
|
||||
std::cerr << "type not supported in write binaryarray\n";
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
if (arrType == INTE) {
|
||||
|
||||
n++;
|
||||
std::vector<int> flipped_data;
|
||||
flipped_data.resize(num, 0);
|
||||
|
||||
for (int m = 0; m < num; m++)
|
||||
flipped_data[m] = flipEndianInt(data[m + offset]);
|
||||
|
||||
ofileH.write((char*)(flipped_data.data()), flipped_data.size() * sizeof(int)) ;
|
||||
|
||||
} else if (arrType == REAL) {
|
||||
|
||||
std::vector<float> flipped_data;
|
||||
flipped_data.resize(num, 0);
|
||||
|
||||
for (int m = 0; m < num; m++)
|
||||
flipped_data[m] = flipEndianFloat(data[m + offset]);
|
||||
|
||||
ofileH.write((char*)(flipped_data.data()), flipped_data.size() * sizeof(float)) ;
|
||||
|
||||
} else if (arrType == DOUB) {
|
||||
|
||||
std::vector<double> flipped_data;
|
||||
flipped_data.resize(num, 0);
|
||||
|
||||
for (int m = 0; m < num; m++)
|
||||
flipped_data[m] = flipEndianDouble(data[m + offset]);
|
||||
|
||||
ofileH.write((char*)(flipped_data.data()), flipped_data.size() * sizeof(double)) ;
|
||||
|
||||
} else if (arrType == LOGI) {
|
||||
|
||||
std::vector<int> logi_data;
|
||||
logi_data.resize(num, 0);
|
||||
|
||||
for (int m = 0; m < num; m++)
|
||||
if (data[m + offset])
|
||||
logi_data[m] = logi_true_val;
|
||||
else
|
||||
logi_data[m] = false_value;
|
||||
|
||||
ofileH.write((char*)(logi_data.data()), logi_data.size() * sizeof(int)) ;
|
||||
|
||||
} else {
|
||||
|
||||
std::cerr << "type not supported in write binaryarray\n";
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
offset += num;
|
||||
ofileH.write(reinterpret_cast<char*>(&dhead), sizeof(dhead));
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
@ -83,28 +82,6 @@ bool Opm::EclIO::is_number(const std::string& numstr)
|
||||
}
|
||||
|
||||
|
||||
bool Opm::EclIO::isEqualCaseInsensitive(const std::string& string1, const std::string& string2)
|
||||
{
|
||||
std::string string1LowerCase(string1);
|
||||
std::string string2LowerCase(string2);
|
||||
|
||||
std::transform(string1.begin(), string1.end(), string1LowerCase.begin(), ::tolower);
|
||||
std::transform(string2.begin(), string2.end(), string2LowerCase.begin(), ::tolower);
|
||||
|
||||
return string1LowerCase == string2LowerCase;
|
||||
}
|
||||
|
||||
Opm::filesystem::path Opm::EclIO::findFileCaseInsensitive(const Opm::filesystem::path& folder, const std::string& filename)
|
||||
{
|
||||
for (auto& p : Opm::filesystem::directory_iterator(folder)) {
|
||||
std::string candidate = p.path().filename().string();
|
||||
|
||||
if (isEqualCaseInsensitive(filename, candidate)) return p.path();
|
||||
}
|
||||
|
||||
return { };
|
||||
}
|
||||
|
||||
bool Opm::EclIO::isFormatted(const std::string& filename)
|
||||
{
|
||||
const auto p = filename.find_last_of(".");
|
||||
@ -443,9 +420,9 @@ std::vector<T> Opm::EclIO::readBinaryArray(std::fstream& fileH, const int64_t si
|
||||
std::get<0>(sizeData) = elementSize;
|
||||
}
|
||||
|
||||
int sizeOfElement = std::get<0>(sizeData);
|
||||
int maxBlockSize = std::get<1>(sizeData);
|
||||
int maxNumberOfElements = maxBlockSize / sizeOfElement;
|
||||
const int sizeOfElement = std::get<0>(sizeData);
|
||||
const int maxBlockSize = std::get<1>(sizeData);
|
||||
const int maxNumberOfElements = maxBlockSize / sizeOfElement;
|
||||
|
||||
arr.reserve(size);
|
||||
|
||||
@ -455,22 +432,25 @@ std::vector<T> Opm::EclIO::readBinaryArray(std::fstream& fileH, const int64_t si
|
||||
int dhead;
|
||||
fileH.read(reinterpret_cast<char*>(&dhead), sizeof(dhead));
|
||||
dhead = Opm::EclIO::flipEndianInt(dhead);
|
||||
int num = dhead / sizeOfElement;
|
||||
const int num = dhead / sizeOfElement;
|
||||
|
||||
if ((num > maxNumberOfElements) || (num < 0)) {
|
||||
OPM_THROW(std::runtime_error, "Error reading binary data, inconsistent header data or incorrect number of elements");
|
||||
}
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
T2 value;
|
||||
|
||||
if constexpr (std::is_same_v<T2, std::string>) {
|
||||
if constexpr (std::is_same_v<T2, std::string>) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
T2 value;
|
||||
value.resize(sizeOfElement) ;
|
||||
fileH.read(&value[0], sizeOfElement);
|
||||
} else
|
||||
fileH.read(reinterpret_cast<char*>(&value), sizeOfElement);
|
||||
arr.push_back(flip(value));
|
||||
}
|
||||
} else {
|
||||
std::vector<T2> buf(num);
|
||||
fileH.read(reinterpret_cast<char*>(buf.data()), buf.size()*sizeof(T2));
|
||||
|
||||
arr.push_back(flip(value));
|
||||
for (const auto& value : buf)
|
||||
arr.push_back(flip(value));
|
||||
}
|
||||
|
||||
rest -= num;
|
||||
|
478
ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/ExtESmry.cpp
vendored
Normal file
478
ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/ExtESmry.cpp
vendored
Normal file
@ -0,0 +1,478 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
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 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/io/eclipse/ExtESmry.hpp>
|
||||
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
#include <opm/io/eclipse/EclUtil.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "cross-platform/windows/Substitutes.hpp"
|
||||
#else
|
||||
#include <fnmatch.h>
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
Opm::time_point make_date(const std::vector<int>& datetime) {
|
||||
auto day = datetime[0];
|
||||
auto month = datetime[1];
|
||||
auto year = datetime[2];
|
||||
auto hour = 0;
|
||||
auto minute = 0;
|
||||
auto second = 0;
|
||||
|
||||
if (datetime.size() == 6) {
|
||||
hour = datetime[3];
|
||||
minute = datetime[4];
|
||||
auto total_usec = datetime[5];
|
||||
second = total_usec / 1000000;
|
||||
}
|
||||
|
||||
|
||||
const auto ts = Opm::TimeStampUTC{ Opm::TimeStampUTC::YMD{ year, month, day}}.hour(hour).minutes(minute).seconds(second);
|
||||
return Opm::TimeService::from_time_t( Opm::asTimeT(ts) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
KEYWORDS WGNAMES NUMS | PARAM index Corresponding ERT key
|
||||
------------------------------------------------+--------------------------------------------------
|
||||
WGOR OP_1 0 | 0 WGOR:OP_1
|
||||
FOPT +-+-+-+- 0 | 1 FOPT
|
||||
WWCT OP_1 0 | 2 WWCT:OP_1
|
||||
WIR OP_1 0 | 3 WIR:OP_1
|
||||
WGOR WI_1 0 | 4 WWCT:OP_1
|
||||
WWCT W1_1 0 | 5 WWCT:WI_1
|
||||
BPR +-+-+- 12675 | 6 BPR:12675, BPR:i,j,k
|
||||
RPR +-+-+- 1 | 7 RPR:1
|
||||
FOPT +-+-+- 0 | 8 FOPT
|
||||
GGPR NORTH 0 | 9 GGPR:NORTH
|
||||
COPR OP_1 5628 | 10 COPR:OP_1:56286, COPR:OP_1:i,j,k
|
||||
RXF +-+-+- 32768*R1(R2 + 10) | 11 RXF:2-3
|
||||
SOFX OP_1 12675 | 12 SOFX:OP_1:12675, SOFX:OP_1:i,j,jk
|
||||
|
||||
*/
|
||||
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
ExtESmry::ExtESmry(const std::string &filename, bool loadBaseRunData) :
|
||||
m_inputFileName { filename },
|
||||
m_loadBaseRun(loadBaseRunData)
|
||||
{
|
||||
if (m_inputFileName.extension()=="")
|
||||
m_inputFileName+=".ESMRY";
|
||||
|
||||
if (m_inputFileName.extension()!=".ESMRY")
|
||||
throw std::invalid_argument("Input file should have extension .ESMRY");
|
||||
|
||||
m_lodsmry_files.push_back(m_inputFileName);
|
||||
|
||||
Opm::filesystem::path rootName = m_inputFileName.parent_path() / m_inputFileName.stem();
|
||||
Opm::filesystem::path path = Opm::filesystem::current_path();
|
||||
|
||||
Opm::filesystem::path rstRootN;
|
||||
|
||||
updatePathAndRootName(path, rootName);
|
||||
|
||||
LodsmryHeadType lodsmry_head;
|
||||
|
||||
auto lod_offset = open_esmry(m_inputFileName, lodsmry_head);
|
||||
|
||||
m_startdat = std::get<0>(lodsmry_head);
|
||||
|
||||
m_lod_offset.push_back(lod_offset);
|
||||
|
||||
std::map<std::string, int> key_index;
|
||||
|
||||
auto keyword = std::get<2>(lodsmry_head);
|
||||
auto units = std::get<3>(lodsmry_head);
|
||||
|
||||
for (size_t n = 0; n < keyword.size(); n++){
|
||||
key_index[keyword[n]] = n;
|
||||
m_keyword.push_back(keyword[n]);
|
||||
}
|
||||
|
||||
m_keyword_index.push_back(key_index);
|
||||
|
||||
for (size_t n = 0; n < m_keyword.size(); n++)
|
||||
kwunits[m_keyword[n]] = units[n];
|
||||
|
||||
RstEntry rst_entry = std::get<1>(lodsmry_head);
|
||||
|
||||
m_rstep_v.push_back(std::get<4>(lodsmry_head));
|
||||
m_tstep_v.push_back(std::get<5>(lodsmry_head));
|
||||
|
||||
m_nTstep_v.push_back(m_tstep_v.back().size());
|
||||
|
||||
auto lod_arr_size = sizeOnDiskBinary(m_nTstep_v.back(), Opm::EclIO::REAL, sizeOfReal);
|
||||
|
||||
m_lod_arr_size.push_back(lod_arr_size);
|
||||
|
||||
m_tstep_range.push_back(std::make_tuple(0, m_tstep_v.back().size() - 1));
|
||||
|
||||
if ((loadBaseRunData) && (!std::get<0>(rst_entry).empty())) {
|
||||
|
||||
auto restart = std::get<0>(rst_entry);
|
||||
auto rstNum = std::get<1>(rst_entry);
|
||||
|
||||
int sim_ind = 0;
|
||||
while (!restart.empty()){
|
||||
sim_ind++;
|
||||
|
||||
rstRootN = Opm::filesystem::path(restart);
|
||||
|
||||
updatePathAndRootName(path, rstRootN);
|
||||
|
||||
Opm::filesystem::path rstLodSmryFile = path / rstRootN;
|
||||
rstLodSmryFile += ".ESMRY";
|
||||
|
||||
m_lodsmry_files.push_back(rstLodSmryFile);
|
||||
|
||||
lod_offset = open_esmry(rstLodSmryFile, lodsmry_head);
|
||||
|
||||
m_lod_offset.push_back(lod_offset);
|
||||
|
||||
m_rstep_v.push_back(std::get<4>(lodsmry_head));
|
||||
m_tstep_v.push_back(std::get<5>(lodsmry_head));
|
||||
|
||||
m_nTstep_v.push_back(m_tstep_v.back().size());
|
||||
|
||||
lod_arr_size = sizeOnDiskBinary(m_nTstep_v.back(), Opm::EclIO::REAL, sizeOfReal);
|
||||
m_lod_arr_size.push_back(lod_arr_size);
|
||||
|
||||
int cidx = 0;
|
||||
|
||||
auto it = std::find_if(m_rstep_v[sim_ind].begin(), m_rstep_v[sim_ind].end(),
|
||||
[&cidx, &rstNum](const int & val)
|
||||
{
|
||||
if (val == 1)
|
||||
++cidx;
|
||||
|
||||
return cidx == rstNum;
|
||||
});
|
||||
|
||||
size_t ind = std::distance(m_rstep_v[sim_ind].begin(), it);
|
||||
|
||||
m_tstep_range.push_back(std::make_tuple(0, ind));
|
||||
|
||||
key_index.clear();
|
||||
keyword = std::get<2>(lodsmry_head);
|
||||
|
||||
for (size_t n = 0; n < keyword.size(); n++)
|
||||
key_index[keyword[n]] = n;
|
||||
|
||||
m_keyword_index.push_back(key_index);
|
||||
|
||||
rst_entry = std::get<1>(lodsmry_head);
|
||||
restart = std::get<0>(rst_entry);
|
||||
rstNum = std::get<1>(rst_entry);
|
||||
}
|
||||
}
|
||||
|
||||
m_nVect = m_keyword.size();
|
||||
|
||||
m_vectorData.resize(m_nVect, {});
|
||||
m_vectorLoaded.resize(m_nVect, false);
|
||||
|
||||
int ind = static_cast<int>(m_tstep_range.size()) - 1 ;
|
||||
|
||||
while (ind > -1) {
|
||||
int to_ind = std::get<1>(m_tstep_range[ind]);
|
||||
m_rstep.insert(m_rstep.end(), m_rstep_v[ind].begin(), m_rstep_v[ind].begin() + to_ind + 1);
|
||||
m_tstep.insert(m_tstep.end(), m_tstep_v[ind].begin(), m_tstep_v[ind].begin() + to_ind + 1);
|
||||
ind--;
|
||||
}
|
||||
|
||||
m_nTstep = m_rstep.size();
|
||||
|
||||
for (size_t m = 0; m < m_rstep.size(); m++)
|
||||
if (m_rstep[m] == 1)
|
||||
m_seqIndex.push_back(m);
|
||||
}
|
||||
|
||||
|
||||
std::vector<float> ExtESmry::get_at_rstep(const std::string& name)
|
||||
{
|
||||
auto full_vect = this->get(name);
|
||||
|
||||
std::vector<float> rs_vect;
|
||||
rs_vect.reserve(m_seqIndex.size());
|
||||
|
||||
for (auto r : m_seqIndex)
|
||||
rs_vect.push_back(full_vect[r]);
|
||||
|
||||
return rs_vect;
|
||||
}
|
||||
|
||||
std::string& ExtESmry::get_unit(const std::string& name)
|
||||
{
|
||||
if ( m_keyword_index[0].find(name) == m_keyword_index[0].end() )
|
||||
throw std::invalid_argument("summary key '" + name + "' not found");
|
||||
|
||||
return kwunits.at(name);
|
||||
}
|
||||
|
||||
bool ExtESmry::all_steps_available()
|
||||
{
|
||||
for (size_t n = 1; n < m_tstep.size(); n++)
|
||||
if ((m_tstep[n] - m_tstep[n-1]) > 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t ExtESmry::open_esmry(Opm::filesystem::path& inputFileName, LodsmryHeadType& lodsmry_head)
|
||||
{
|
||||
std::fstream fileH;
|
||||
|
||||
fileH.open(inputFileName, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH)
|
||||
throw std::runtime_error("Can not open file ");
|
||||
|
||||
|
||||
std::string arrName;
|
||||
int64_t arr_size;
|
||||
Opm::EclIO::eclArrType arrType;
|
||||
int sizeOfElement;
|
||||
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
|
||||
if ((arrName != "START ") or (arrType != Opm::EclIO::INTE))
|
||||
OPM_THROW(std::invalid_argument, "reading start, invalid lod file");
|
||||
|
||||
auto start_vect = Opm::EclIO::readBinaryInteArray(fileH, arr_size);
|
||||
|
||||
auto startdat = make_date(start_vect);
|
||||
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
|
||||
Opm::EclIO::RstEntry rst_entry = std::make_tuple("", 0);
|
||||
|
||||
if (arrName == "RESTART "){
|
||||
|
||||
if (m_loadBaseRun) {
|
||||
|
||||
std::vector<std::string> rstfile = Opm::EclIO::readBinaryC0nnArray(fileH, arr_size, sizeOfElement);
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
std::vector<int> rst_num = Opm::EclIO::readBinaryInteArray(fileH, arr_size);
|
||||
|
||||
rst_entry = std::make_tuple(rstfile[0], rst_num[0]);
|
||||
|
||||
} else {
|
||||
uint64_t numIgnore = sizeOnDiskBinary(arr_size, arrType, sizeOfElement);
|
||||
numIgnore = numIgnore + 24 + sizeOnDiskBinary(1, Opm::EclIO::INTE, Opm::EclIO::sizeOfInte);
|
||||
fileH.seekg(static_cast<std::streamoff>(numIgnore), std::ios_base::cur);
|
||||
}
|
||||
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
}
|
||||
|
||||
if (arrName != "KEYCHECK")
|
||||
OPM_THROW(std::invalid_argument, "!!reading keycheck, invalid lod file");
|
||||
|
||||
std::vector<std::string> keywords;
|
||||
|
||||
keywords = Opm::EclIO::readBinaryC0nnArray(fileH, arr_size, sizeOfElement);
|
||||
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
|
||||
if (arrName != "UNITS ")
|
||||
OPM_THROW(std::invalid_argument, "reading UNITS, invalid lod file");
|
||||
|
||||
auto units = Opm::EclIO::readBinaryC0nnArray(fileH, arr_size, sizeOfElement);
|
||||
|
||||
if (keywords.size() != units.size())
|
||||
throw std::runtime_error("invalied LODSMRY file, size of units not equal size of keywords");
|
||||
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
|
||||
if ((arrName != "RSTEP ") or (arrType != Opm::EclIO::INTE))
|
||||
OPM_THROW(std::invalid_argument, "reading RSTEP, invalid lod file");
|
||||
|
||||
auto rstep = Opm::EclIO::readBinaryInteArray(fileH, arr_size);
|
||||
|
||||
Opm::EclIO::readBinaryHeader(fileH, arrName, arr_size, arrType, sizeOfElement);
|
||||
|
||||
if ((arrName != "TSTEP ") or (arrType != Opm::EclIO::INTE))
|
||||
OPM_THROW(std::invalid_argument, "reading TSTEP, invalid lod file");
|
||||
|
||||
auto tstep = Opm::EclIO::readBinaryInteArray(fileH, arr_size);
|
||||
|
||||
lodsmry_head = std::make_tuple(startdat, rst_entry, keywords, units, rstep, tstep);
|
||||
|
||||
uint64_t lodsmry_offset = static_cast<uint64_t>(fileH.tellg());
|
||||
|
||||
fileH.close();
|
||||
|
||||
return lodsmry_offset;
|
||||
}
|
||||
|
||||
|
||||
void ExtESmry::updatePathAndRootName(Opm::filesystem::path& dir, Opm::filesystem::path& rootN) {
|
||||
|
||||
if (rootN.parent_path().is_absolute()){
|
||||
dir = rootN.parent_path();
|
||||
} else {
|
||||
dir = dir / rootN.parent_path();
|
||||
}
|
||||
|
||||
rootN = rootN.stem();
|
||||
}
|
||||
|
||||
|
||||
void ExtESmry::loadData(const std::vector<std::string>& stringVect)
|
||||
{
|
||||
std::vector<int> keyIndexVect;
|
||||
|
||||
for (const auto& key: stringVect)
|
||||
keyIndexVect.push_back(m_keyword_index[0].at(key));
|
||||
|
||||
std::fstream fileH;
|
||||
|
||||
int ind = static_cast<int>(m_tstep_range.size()) - 1 ;
|
||||
|
||||
while (ind > -1) {
|
||||
|
||||
int to_ind = std::get<1>(m_tstep_range[ind]);
|
||||
|
||||
fileH.open(m_lodsmry_files[ind], std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fileH)
|
||||
throw std::runtime_error("Can not open file lodFile");
|
||||
|
||||
for (size_t n = 0 ; n < stringVect.size(); n++) {
|
||||
|
||||
std::string key = stringVect[n];
|
||||
|
||||
std::string arrName;
|
||||
Opm::EclIO::eclArrType arrType;
|
||||
|
||||
if ( m_keyword_index[ind].find(key) == m_keyword_index[ind].end() ) {
|
||||
|
||||
for (int m = 0; m < to_ind + 1; m++)
|
||||
m_vectorData[keyIndexVect[n]].push_back(0.0);
|
||||
|
||||
} else {
|
||||
|
||||
int key_ind = m_keyword_index[ind].at(key);
|
||||
|
||||
uint64_t pos = m_lod_offset[ind] + m_lod_arr_size[ind]*static_cast<uint64_t>(key_ind);
|
||||
pos = pos + static_cast<uint64_t>(key_ind * 24); // adding size of binary headers
|
||||
|
||||
fileH.seekg (pos, fileH.beg);
|
||||
|
||||
int64_t size;
|
||||
int sizeOfElement;
|
||||
readBinaryHeader(fileH, arrName, size, arrType, sizeOfElement);
|
||||
|
||||
arrName = Opm::EclIO::trimr(arrName);
|
||||
|
||||
std::string checkName = "V" + std::to_string(key_ind);
|
||||
|
||||
if (arrName != checkName)
|
||||
OPM_THROW(std::invalid_argument, "lodsmry, wrong header expecting " + checkName + " found " + arrName);
|
||||
|
||||
auto smry_data = readBinaryRealArray(fileH, size);
|
||||
|
||||
m_vectorData[keyIndexVect[n]].insert(m_vectorData[keyIndexVect[n]].end(), smry_data.begin(), smry_data.begin() + to_ind + 1);
|
||||
}
|
||||
}
|
||||
|
||||
fileH.close();
|
||||
ind--;
|
||||
}
|
||||
|
||||
for (auto kind : keyIndexVect)
|
||||
m_vectorLoaded[kind] = true;
|
||||
}
|
||||
|
||||
void ExtESmry::loadData()
|
||||
{
|
||||
this->loadData(m_keyword);
|
||||
}
|
||||
|
||||
const std::vector<float>& ExtESmry::get(const std::string& name)
|
||||
{
|
||||
if ( m_keyword_index[0].find(name) == m_keyword_index[0].end() )
|
||||
throw std::invalid_argument("summary key '" + name + "' not found");
|
||||
|
||||
int index = m_keyword_index[0].at(name);
|
||||
|
||||
if (!m_vectorLoaded[index]){
|
||||
loadData({name});
|
||||
}
|
||||
|
||||
return m_vectorData[index];
|
||||
}
|
||||
|
||||
std::vector<Opm::time_point> ExtESmry::dates() {
|
||||
double time_unit = 24 * 3600;
|
||||
std::vector<Opm::time_point> d;
|
||||
|
||||
for (const auto& t : this->get("TIME"))
|
||||
d.push_back( this->m_startdat + std::chrono::duration_cast<std::chrono::seconds>( std::chrono::duration<double, std::chrono::seconds::period>( t * time_unit)));
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
std::vector<std::string> ExtESmry::keywordList(const std::string& pattern) const
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
|
||||
for (const auto& key : m_keyword)
|
||||
if (fnmatch( pattern.c_str(), key.c_str(), 0 ) == 0 )
|
||||
list.push_back(key);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
bool ExtESmry::hasKey(const std::string &key) const
|
||||
{
|
||||
return std::find(m_keyword.begin(), m_keyword.end(), key) != m_keyword.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace Opm::ecl
|
||||
|
Loading…
Reference in New Issue
Block a user