Promote RestartFileView to Public Access
In preparation of loading analytic aquifers from the restart file.
This commit is contained in:
parent
423b4a39e6
commit
82ccd15580
@ -280,6 +280,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
src/opm/io/eclipse/ESmry.cpp
|
||||
src/opm/io/eclipse/ESmry_write_rsm.cpp
|
||||
src/opm/io/eclipse/OutputStream.cpp
|
||||
src/opm/io/eclipse/RestartFileView.cpp
|
||||
src/opm/io/eclipse/SummaryNode.cpp
|
||||
src/opm/io/eclipse/rst/connection.cpp
|
||||
src/opm/io/eclipse/rst/group.cpp
|
||||
@ -343,6 +344,7 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/rst_test.cpp
|
||||
tests/test_ERsm.cpp
|
||||
tests/test_GuideRate.cpp
|
||||
tests/test_RestartFileView.cpp
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferTests.cpp
|
||||
@ -845,6 +847,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
opm/io/eclipse/ESmry.hpp
|
||||
opm/io/eclipse/PaddedOutputString.hpp
|
||||
opm/io/eclipse/OutputStream.hpp
|
||||
opm/io/eclipse/RestartFileView.hpp
|
||||
opm/io/eclipse/SummaryNode.hpp
|
||||
opm/io/eclipse/rst/connection.hpp
|
||||
opm/io/eclipse/rst/group.hpp
|
||||
|
66
opm/io/eclipse/RestartFileView.hpp
Normal file
66
opm/io/eclipse/RestartFileView.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
class Implementation;
|
||||
std::unique_ptr<Implementation> pImpl_;
|
||||
};
|
||||
|
||||
}} // Opm::RestartIO
|
||||
|
||||
#endif // OPM_RESTART_FILE_VIEW_HPP
|
261
src/opm/io/eclipse/RestartFileView.cpp
Normal file
261
src/opm/io/eclipse/RestartFileView.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
Copyright (c) 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/>.
|
||||
*/
|
||||
|
||||
#include <opm/io/eclipse/RestartFileView.hpp>
|
||||
|
||||
#include <opm/io/eclipse/ERst.hpp>
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
struct ArrayType;
|
||||
|
||||
template<>
|
||||
struct ArrayType<int>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ArrayType<float>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ArrayType<double>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ArrayType<std::string>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
Opm::EclIO::eclArrType ArrayType<int>::T = ::Opm::EclIO::eclArrType::INTE;
|
||||
Opm::EclIO::eclArrType ArrayType<float>::T = ::Opm::EclIO::eclArrType::REAL;
|
||||
Opm::EclIO::eclArrType ArrayType<double>::T = ::Opm::EclIO::eclArrType::DOUB;
|
||||
Opm::EclIO::eclArrType ArrayType<std::string>::T = ::Opm::EclIO::eclArrType::CHAR;
|
||||
}
|
||||
|
||||
class Opm::EclIO::RestartFileView::Implementation
|
||||
{
|
||||
public:
|
||||
explicit Implementation(std::shared_ptr<ERst> restart_file,
|
||||
const int report_step);
|
||||
|
||||
~Implementation() = default;
|
||||
|
||||
Implementation(const Implementation& rhs) = delete;
|
||||
Implementation(Implementation&& rhs);
|
||||
|
||||
Implementation& operator=(const Implementation& rhs) = delete;
|
||||
Implementation& operator=(Implementation&& rhs);
|
||||
|
||||
std::size_t simStep() const
|
||||
{
|
||||
return this->sim_step_;
|
||||
}
|
||||
|
||||
int reportStep() const
|
||||
{
|
||||
return this->report_step_;
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
bool hasKeyword(const std::string& vector) const
|
||||
{
|
||||
if (this->rst_file_ == nullptr) { return false; }
|
||||
|
||||
auto coll_iter = this->vectors_.find(ArrayType<ElmType>::T);
|
||||
return (coll_iter != this->vectors_.end())
|
||||
&& this->collectionContains(coll_iter->second, vector);
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
const std::vector<ElmType>&
|
||||
getKeyword(const std::string& vector, const int occurrence)
|
||||
{
|
||||
return this->rst_file_->
|
||||
getRestartData<ElmType>(vector, this->report_step_, occurrence);
|
||||
}
|
||||
|
||||
const std::vector<int>& intehead()
|
||||
{
|
||||
const auto ihkw = std::string { "INTEHEAD" };
|
||||
|
||||
if (! this->hasKeyword<int>(ihkw)) {
|
||||
throw std::domain_error {
|
||||
"Purported Restart File Does not Have Integer Header"
|
||||
};
|
||||
}
|
||||
|
||||
return this->getKeyword<int>(ihkw, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
using RstFile = std::shared_ptr<ERst>;
|
||||
|
||||
using VectorColl = std::unordered_set<std::string>;
|
||||
using TypedColl = std::unordered_map<
|
||||
eclArrType, VectorColl, std::hash<int>
|
||||
>;
|
||||
|
||||
RstFile rst_file_;
|
||||
int report_step_;
|
||||
std::size_t sim_step_;
|
||||
TypedColl vectors_;
|
||||
|
||||
bool collectionContains(const VectorColl& coll,
|
||||
const std::string& vector) const
|
||||
{
|
||||
return coll.find(vector) != coll.end();
|
||||
}
|
||||
};
|
||||
|
||||
Opm::EclIO::RestartFileView::Implementation::
|
||||
Implementation(std::shared_ptr<ERst> restart_file,
|
||||
const int report_step)
|
||||
: rst_file_ { std::move(restart_file) }
|
||||
, report_step_(report_step)
|
||||
, sim_step_ (std::max(report_step - 1, 0))
|
||||
{
|
||||
if (! this->rst_file_->hasReportStepNumber(this->report_step_)) {
|
||||
this->rst_file_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
this->rst_file_->loadReportStepNumber(this->report_step_);
|
||||
|
||||
for (const auto& vector : this->rst_file_->listOfRstArrays(this->report_step_)) {
|
||||
const auto& type = std::get<1>(vector);
|
||||
|
||||
switch (type) {
|
||||
case ::Opm::EclIO::eclArrType::LOGI:
|
||||
case ::Opm::EclIO::eclArrType::MESS:
|
||||
// Currently ignored
|
||||
continue;
|
||||
|
||||
default:
|
||||
this->vectors_[type].emplace(std::get<0>(vector));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Opm::EclIO::RestartFileView::Implementation::
|
||||
Implementation(Implementation&& rhs)
|
||||
: rst_file_ (std::move(rhs.rst_file_))
|
||||
, report_step_(rhs.report_step_)
|
||||
, sim_step_ (rhs.sim_step_) // Scalar (size_t)
|
||||
, vectors_ (std::move(rhs.vectors_))
|
||||
{}
|
||||
|
||||
Opm::EclIO::RestartFileView::Implementation&
|
||||
Opm::EclIO::RestartFileView::Implementation::operator=(Implementation&& rhs)
|
||||
{
|
||||
this->rst_file_ = std::move(rhs.rst_file_);
|
||||
this->report_step_ = rhs.report_step_; // Scalar (int)
|
||||
this->sim_step_ = rhs.sim_step_; // Scalar (size_t)
|
||||
this->vectors_ = std::move(rhs.vectors_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Opm::EclIO::RestartFileView::RestartFileView(std::shared_ptr<ERst> restart_file,
|
||||
const int report_step)
|
||||
: pImpl_{ new Implementation{ std::move(restart_file), report_step } }
|
||||
{}
|
||||
|
||||
Opm::EclIO::RestartFileView::~RestartFileView()
|
||||
{}
|
||||
|
||||
Opm::EclIO::RestartFileView::RestartFileView(RestartFileView&& rhs)
|
||||
: pImpl_{ std::move(rhs.pImpl_) }
|
||||
{}
|
||||
|
||||
Opm::EclIO::RestartFileView&
|
||||
Opm::EclIO::RestartFileView::operator=(RestartFileView&& rhs)
|
||||
{
|
||||
this->pImpl_ = std::move(rhs.pImpl_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t Opm::EclIO::RestartFileView::simStep() const
|
||||
{
|
||||
return this->pImpl_->simStep();
|
||||
}
|
||||
|
||||
int Opm::EclIO::RestartFileView::reportStep() const
|
||||
{
|
||||
return this->pImpl_->reportStep();
|
||||
}
|
||||
|
||||
const std::vector<int>& Opm::EclIO::RestartFileView::intehead() const
|
||||
{
|
||||
return this->pImpl_->intehead();
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
bool Opm::EclIO::RestartFileView::hasKeyword(const std::string& vector) const
|
||||
{
|
||||
return this->pImpl_->template hasKeyword<ElmType>(vector);
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
const std::vector<ElmType>&
|
||||
Opm::EclIO::RestartFileView::getKeyword(const std::string& vector,
|
||||
const int occurrence) const
|
||||
{
|
||||
return this->pImpl_->template getKeyword<ElmType>(vector, occurrence);
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
|
||||
namespace Opm { namespace EclIO {
|
||||
|
||||
template bool RestartFileView::hasKeyword<int> (const std::string&) const;
|
||||
template bool RestartFileView::hasKeyword<float> (const std::string&) const;
|
||||
template bool RestartFileView::hasKeyword<double> (const std::string&) const;
|
||||
template bool RestartFileView::hasKeyword<std::string>(const std::string&) const;
|
||||
|
||||
template const std::vector<int>&
|
||||
RestartFileView::getKeyword<int>(const std::string&, const int) const;
|
||||
|
||||
template const std::vector<float>&
|
||||
RestartFileView::getKeyword<float>(const std::string&, const int) const;
|
||||
|
||||
template const std::vector<double>&
|
||||
RestartFileView::getKeyword<double>(const std::string&, const int) const;
|
||||
|
||||
template const std::vector<std::string>&
|
||||
RestartFileView::getKeyword<std::string>(const std::string&, const int) const;
|
||||
|
||||
}} // Opm::EclIO
|
@ -25,7 +25,7 @@
|
||||
#include <opm/output/eclipse/RestartIO.hpp>
|
||||
|
||||
#include <opm/io/eclipse/ERst.hpp>
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
#include <opm/io/eclipse/RestartFileView.hpp>
|
||||
|
||||
#include <opm/output/data/Aquifer.hpp>
|
||||
#include <opm/output/data/Cells.hpp>
|
||||
@ -74,165 +74,6 @@
|
||||
|
||||
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
struct ArrayType;
|
||||
|
||||
template<>
|
||||
struct ArrayType<int>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ArrayType<float>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ArrayType<double>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ArrayType<std::string>
|
||||
{
|
||||
static Opm::EclIO::eclArrType T;
|
||||
};
|
||||
|
||||
Opm::EclIO::eclArrType ArrayType<int>::T = ::Opm::EclIO::eclArrType::INTE;
|
||||
Opm::EclIO::eclArrType ArrayType<float>::T = ::Opm::EclIO::eclArrType::REAL;
|
||||
Opm::EclIO::eclArrType ArrayType<double>::T = ::Opm::EclIO::eclArrType::DOUB;
|
||||
Opm::EclIO::eclArrType ArrayType<std::string>::T = ::Opm::EclIO::eclArrType::CHAR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class RestartFileView
|
||||
{
|
||||
public:
|
||||
explicit RestartFileView(const std::string& filename,
|
||||
const int report_step);
|
||||
|
||||
~RestartFileView() = default;
|
||||
|
||||
RestartFileView(const RestartFileView& rhs) = delete;
|
||||
RestartFileView(RestartFileView&& rhs);
|
||||
|
||||
RestartFileView& operator=(const RestartFileView& rhs) = delete;
|
||||
RestartFileView& operator=(RestartFileView&& rhs);
|
||||
|
||||
std::size_t simStep() const
|
||||
{
|
||||
return this->sim_step_;
|
||||
}
|
||||
|
||||
int reportStep() const
|
||||
{
|
||||
return this->report_step_;
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
bool hasKeyword(const std::string& vector) const
|
||||
{
|
||||
if (this->rst_file_ == nullptr) { return false; }
|
||||
|
||||
const auto& coll_iter = this->vectors_.find(ArrayType<ElmType>::T);
|
||||
return (coll_iter != this->vectors_.end() && this->collectionContains(coll_iter->second, vector));
|
||||
}
|
||||
|
||||
template <typename ElmType>
|
||||
const std::vector<ElmType>&
|
||||
getKeyword(const std::string& vector)
|
||||
{
|
||||
return this->rst_file_->getRestartData<ElmType>(vector, this->report_step_, 0);
|
||||
}
|
||||
|
||||
const std::vector<int>& intehead()
|
||||
{
|
||||
const auto& ihkw = std::string { "INTEHEAD" };
|
||||
|
||||
if (! this->hasKeyword<int>(ihkw)) {
|
||||
throw std::domain_error {
|
||||
"Purported Restart File Does not Have Integer Header"
|
||||
};
|
||||
}
|
||||
|
||||
return this->getKeyword<int>(ihkw);
|
||||
}
|
||||
|
||||
private:
|
||||
using RstFile = std::unique_ptr<Opm::EclIO::ERst>;
|
||||
|
||||
using VectorColl = std::unordered_set<std::string>;
|
||||
using TypedColl = std::unordered_map<
|
||||
Opm::EclIO::eclArrType, VectorColl, std::hash<int>
|
||||
>;
|
||||
|
||||
RstFile rst_file_;
|
||||
int report_step_;
|
||||
std::size_t sim_step_;
|
||||
TypedColl vectors_;
|
||||
|
||||
bool collectionContains(const VectorColl& coll,
|
||||
const std::string& vector) const
|
||||
{
|
||||
return coll.find(vector) != coll.end();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
RestartFileView::RestartFileView(const std::string& filename,
|
||||
const int report_step)
|
||||
: rst_file_ { new Opm::EclIO::ERst{filename} }
|
||||
, report_step_(report_step)
|
||||
, sim_step_ (std::max(report_step - 1, 0))
|
||||
{
|
||||
if (! rst_file_->hasReportStepNumber(this->report_step_)) {
|
||||
rst_file_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
this->rst_file_->loadReportStepNumber(this->report_step_);
|
||||
|
||||
for (const auto& vector : this->rst_file_->listOfRstArrays(this->report_step_)) {
|
||||
const auto& type = std::get<1>(vector);
|
||||
|
||||
switch (type) {
|
||||
case ::Opm::EclIO::eclArrType::LOGI:
|
||||
case ::Opm::EclIO::eclArrType::MESS:
|
||||
// Currently ignored
|
||||
continue;
|
||||
|
||||
default:
|
||||
this->vectors_[type].emplace(std::get<0>(vector));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RestartFileView::RestartFileView(RestartFileView&& rhs)
|
||||
: rst_file_ (std::move(rhs.rst_file_))
|
||||
, report_step_(rhs.report_step_)
|
||||
, sim_step_ (rhs.sim_step_) // Scalar (size_t)
|
||||
, vectors_ (std::move(rhs.vectors_))
|
||||
{}
|
||||
|
||||
RestartFileView& RestartFileView::operator=(RestartFileView&& rhs)
|
||||
{
|
||||
this->rst_file_ = std::move(rhs.rst_file_);
|
||||
this->report_step_ = rhs.report_step_; // Scalar (int)
|
||||
this->sim_step_ = rhs.sim_step_; // Scalar (size_t)
|
||||
this->vectors_ = std::move(rhs.vectors_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
boost::iterator_range<typename std::vector<T>::const_iterator>
|
||||
@ -251,47 +92,53 @@ namespace {
|
||||
return { begin, end };
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
class UDQVectors
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
using Window = boost::iterator_range<typename std::vector<T>::const_iterator>;
|
||||
|
||||
UDQVectors(std::shared_ptr<RestartFileView> rst_view) :
|
||||
rstView_(rst_view)
|
||||
UDQVectors(std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
: rstView_{ std::move(rst_view) }
|
||||
{
|
||||
const auto& intehead = rst_view->getKeyword<int>("INTEHEAD");
|
||||
const auto& intehead = this->rstView_->getKeyword<int>("INTEHEAD");
|
||||
this->num_wells = intehead[VI::intehead::NWMAXZ];
|
||||
this->num_groups = intehead[VI::intehead::NGMAXZ];
|
||||
}
|
||||
|
||||
Window<double> next_dudw() {
|
||||
Window<double> next_dudw() const
|
||||
{
|
||||
return getDataWindow(this->rstView_->getKeyword<double>("DUDW"),
|
||||
this->num_wells, this->udq_well_index++);
|
||||
}
|
||||
|
||||
Window<double> next_dudg() {
|
||||
Window<double> next_dudg() const
|
||||
{
|
||||
return getDataWindow(this->rstView_->getKeyword<double>("DUDG"),
|
||||
this->num_groups, this->udq_group_index++);
|
||||
}
|
||||
|
||||
double next_dudf() {
|
||||
double next_dudf() const
|
||||
{
|
||||
return this->rstView_->getKeyword<double>("DUDF")[ this->udq_field_index++ ];
|
||||
}
|
||||
|
||||
const std::vector<std::string>& zudn() {
|
||||
const std::vector<std::string>& zudn() const
|
||||
{
|
||||
return this->rstView_->getKeyword<std::string>("ZUDN");
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t num_wells;
|
||||
std::size_t num_groups;
|
||||
std::shared_ptr<RestartFileView> rstView_;
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rstView_;
|
||||
|
||||
std::size_t udq_well_index = 0;
|
||||
std::size_t udq_group_index = 0;
|
||||
std::size_t udq_field_index = 0;
|
||||
mutable std::size_t udq_well_index = 0;
|
||||
mutable std::size_t udq_group_index = 0;
|
||||
mutable std::size_t udq_field_index = 0;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@ -304,8 +151,8 @@ public:
|
||||
typename std::vector<T>::const_iterator
|
||||
>;
|
||||
|
||||
explicit WellVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view);
|
||||
explicit WellVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view);
|
||||
|
||||
bool hasDefinedWellValues() const;
|
||||
bool hasDefinedConnectionValues() const;
|
||||
@ -326,11 +173,11 @@ private:
|
||||
std::size_t numIConElem_;
|
||||
std::size_t numXConElem_;
|
||||
|
||||
std::shared_ptr<RestartFileView> rstView_;
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rstView_;
|
||||
};
|
||||
|
||||
WellVectors::WellVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
WellVectors::WellVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
: maxConnPerWell_(intehead[VI::intehead::NCWMAX])
|
||||
, numIWelElem_ (intehead[VI::intehead::NIWELZ])
|
||||
, numXWelElem_ (intehead[VI::intehead::NXWELZ])
|
||||
@ -415,8 +262,8 @@ public:
|
||||
typename std::vector<T>::const_iterator
|
||||
>;
|
||||
|
||||
explicit GroupVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view);
|
||||
explicit GroupVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view);
|
||||
|
||||
bool hasDefinedValues() const;
|
||||
|
||||
@ -430,11 +277,11 @@ private:
|
||||
std::size_t numIGrpElem_;
|
||||
std::size_t numXGrpElem_;
|
||||
|
||||
std::shared_ptr<RestartFileView> rstView_;
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rstView_;
|
||||
};
|
||||
|
||||
GroupVectors::GroupVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
GroupVectors::GroupVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
: maxNumGroups_(intehead[VI::intehead::NGMAXZ] - 1) // -FIELD
|
||||
, numIGrpElem_ (intehead[VI::intehead::NIGRPZ])
|
||||
, numXGrpElem_ (intehead[VI::intehead::NXGRPZ])
|
||||
@ -488,8 +335,8 @@ public:
|
||||
typename std::vector<T>::const_iterator
|
||||
>;
|
||||
|
||||
explicit SegmentVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view);
|
||||
explicit SegmentVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view);
|
||||
|
||||
bool hasDefinedValues() const;
|
||||
|
||||
@ -504,11 +351,11 @@ private:
|
||||
std::size_t numISegElm_;
|
||||
std::size_t numRSegElm_;
|
||||
|
||||
std::shared_ptr<RestartFileView> rstView_;
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rstView_;
|
||||
};
|
||||
|
||||
SegmentVectors::SegmentVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
SegmentVectors::SegmentVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
: maxSegPerWell_(intehead[VI::intehead::NSEGMX])
|
||||
, numISegElm_ (intehead[VI::intehead::NISEGZ])
|
||||
, numRSegElm_ (intehead[VI::intehead::NRSEGZ])
|
||||
@ -559,8 +406,8 @@ public:
|
||||
typename std::vector<T>::const_iterator
|
||||
>;
|
||||
|
||||
explicit AquiferVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view);
|
||||
explicit AquiferVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view);
|
||||
|
||||
bool hasDefinedValues() const;
|
||||
|
||||
@ -573,11 +420,11 @@ private:
|
||||
std::size_t numFloatAnalyticAquiferElm_;
|
||||
std::size_t numDoubleAnalyticAquiferElm_;
|
||||
|
||||
std::shared_ptr<RestartFileView> rstView_;
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rstView_;
|
||||
};
|
||||
|
||||
AquiferVectors::AquiferVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
AquiferVectors::AquiferVectors(const std::vector<int>& intehead,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
: numIntAnalyticAquiferElm_ (intehead[VI::intehead::NIAAQZ])
|
||||
, numFloatAnalyticAquiferElm_ (intehead[VI::intehead::NSAAQZ])
|
||||
, numDoubleAnalyticAquiferElm_(intehead[VI::intehead::NXAAQZ])
|
||||
@ -644,18 +491,18 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool hasAnalyticAquifers(const RestartFileView& rst_view)
|
||||
bool hasAnalyticAquifers(const Opm::EclIO::RestartFileView& rst_view)
|
||||
{
|
||||
return rst_view.hasKeyword<double>("XAAQ");
|
||||
}
|
||||
|
||||
std::size_t maximumAnalyticAquiferID(RestartFileView& rst_view)
|
||||
std::size_t maximumAnalyticAquiferID(const Opm::EclIO::RestartFileView& rst_view)
|
||||
{
|
||||
return rst_view.intehead()[VI::intehead::MAX_AN_AQUIFER_ID];
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
double_vector(const std::string& key, RestartFileView& rst_view)
|
||||
double_vector(const std::string& key, const Opm::EclIO::RestartFileView& rst_view)
|
||||
{
|
||||
if (rst_view.hasKeyword<double>(key)) {
|
||||
// Data exists as type DOUB. Return unchanged.
|
||||
@ -691,7 +538,7 @@ namespace {
|
||||
|
||||
void loadIfAvailable(const Opm::RestartKey& value,
|
||||
const std::vector<double>::size_type numcells,
|
||||
RestartFileView& rst_view,
|
||||
const Opm::EclIO::RestartFileView& rst_view,
|
||||
Opm::data::Solution& sol)
|
||||
{
|
||||
const auto& kwdata = double_vector(value.key, rst_view);
|
||||
@ -711,7 +558,7 @@ namespace {
|
||||
void loadHysteresisIfAvailable(const std::string& primary,
|
||||
const Opm::RestartKey& fallback_key,
|
||||
const std::vector<double>::size_type numcells,
|
||||
RestartFileView& rst_view,
|
||||
const Opm::EclIO::RestartFileView& rst_view,
|
||||
Opm::data::Solution& sol)
|
||||
{
|
||||
auto kwdata = double_vector(primary, rst_view);
|
||||
@ -745,10 +592,10 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
|
||||
void restoreHysteresisVector(const Opm::RestartKey& value,
|
||||
const int numcells,
|
||||
RestartFileView& rst_view,
|
||||
Opm::data::Solution& sol)
|
||||
void restoreHysteresisVector(const Opm::RestartKey& value,
|
||||
const int numcells,
|
||||
const Opm::EclIO::RestartFileView& rst_view,
|
||||
Opm::data::Solution& sol)
|
||||
{
|
||||
const auto& key = value.key;
|
||||
|
||||
@ -769,9 +616,9 @@ namespace {
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
getOpmExtraFromDoubHEAD(const bool required,
|
||||
const Opm::UnitSystem& usys,
|
||||
RestartFileView& rst_view)
|
||||
getOpmExtraFromDoubHEAD(const bool required,
|
||||
const Opm::UnitSystem& usys,
|
||||
const Opm::EclIO::RestartFileView& rst_view)
|
||||
{
|
||||
using M = Opm::UnitSystem::measure;
|
||||
|
||||
@ -789,7 +636,7 @@ namespace {
|
||||
Opm::data::Solution
|
||||
restoreSOLUTION(const std::vector<Opm::RestartKey>& solution_keys,
|
||||
const int numcells,
|
||||
RestartFileView& rst_view)
|
||||
const Opm::EclIO::RestartFileView& rst_view)
|
||||
{
|
||||
Opm::data::Solution sol(/* init_si = */ false);
|
||||
|
||||
@ -811,7 +658,7 @@ namespace {
|
||||
|
||||
void restoreExtra(const std::vector<Opm::RestartKey>& extra_keys,
|
||||
const Opm::UnitSystem& usys,
|
||||
RestartFileView& rst_view,
|
||||
const Opm::EclIO::RestartFileView& rst_view,
|
||||
Opm::RestartValue& rst_value)
|
||||
{
|
||||
for (const auto& extra : extra_keys) {
|
||||
@ -889,10 +736,10 @@ namespace {
|
||||
}
|
||||
|
||||
Opm::data::Wells
|
||||
restore_wells_opm(const ::Opm::EclipseState& es,
|
||||
const ::Opm::EclipseGrid& grid,
|
||||
const ::Opm::Schedule& schedule,
|
||||
RestartFileView& rst_view)
|
||||
restore_wells_opm(const ::Opm::EclipseState& es,
|
||||
const ::Opm::EclipseGrid& grid,
|
||||
const ::Opm::Schedule& schedule,
|
||||
const Opm::EclIO::RestartFileView& rst_view)
|
||||
{
|
||||
if (! (rst_view.hasKeyword<int> ("OPM_IWEL") &&
|
||||
rst_view.hasKeyword<double>("OPM_XWEL")))
|
||||
@ -1260,10 +1107,10 @@ namespace {
|
||||
}
|
||||
|
||||
Opm::data::Wells
|
||||
restore_wells_ecl(const ::Opm::EclipseState& es,
|
||||
const ::Opm::EclipseGrid& grid,
|
||||
const ::Opm::Schedule& schedule,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
restore_wells_ecl(const ::Opm::EclipseState& es,
|
||||
const ::Opm::EclipseGrid& grid,
|
||||
const ::Opm::Schedule& schedule,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
{
|
||||
auto soln = ::Opm::data::Wells{};
|
||||
|
||||
@ -1331,8 +1178,8 @@ namespace {
|
||||
}
|
||||
|
||||
Opm::data::Aquifers
|
||||
restore_aquifers(const ::Opm::EclipseState& es,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
restore_aquifers(const ::Opm::EclipseState& es,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
{
|
||||
using M = ::Opm::UnitSystem::measure;
|
||||
using Ix = VI::XAnalyticAquifer::index;
|
||||
@ -1450,10 +1297,9 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void restore_udq(::Opm::SummaryState& smry,
|
||||
const ::Opm::Schedule& schedule,
|
||||
std::shared_ptr<RestartFileView>& rst_view)
|
||||
void restore_udq(::Opm::SummaryState& smry,
|
||||
const ::Opm::Schedule& schedule,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
{
|
||||
if (!rst_view->hasKeyword<std::string>(std::string("ZUDN")))
|
||||
return;
|
||||
@ -1461,7 +1307,7 @@ namespace {
|
||||
const auto sim_step = rst_view->simStep();
|
||||
const auto& wnames = schedule.wellNames(sim_step);
|
||||
const auto& groups = schedule.restart_groups(sim_step);
|
||||
UDQVectors udq_vectors(rst_view);
|
||||
const auto udq_vectors = UDQVectors{ std::move(rst_view) };
|
||||
|
||||
for (const auto& udq : udq_vectors.zudn()) {
|
||||
if (udq[0] == 'W') {
|
||||
@ -1492,9 +1338,9 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void restore_cumulative(::Opm::SummaryState& smry,
|
||||
const ::Opm::Schedule& schedule,
|
||||
std::shared_ptr<RestartFileView> rst_view)
|
||||
void restore_cumulative(::Opm::SummaryState& smry,
|
||||
const ::Opm::Schedule& schedule,
|
||||
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
|
||||
{
|
||||
const auto sim_step = rst_view->simStep();
|
||||
const auto& intehead = rst_view->intehead();
|
||||
@ -1554,8 +1400,9 @@ namespace Opm { namespace RestartIO {
|
||||
const Schedule& schedule,
|
||||
const std::vector<RestartKey>& extra_keys)
|
||||
{
|
||||
auto rst_view =
|
||||
std::make_shared<RestartFileView>(filename, report_step);
|
||||
auto rst_file = std::make_shared<Opm::EclIO::ERst>(filename);
|
||||
auto rst_view = std::make_shared<Opm::EclIO::RestartFileView>
|
||||
(std::move(rst_file), report_step);
|
||||
|
||||
auto xr = restoreSOLUTION(solution_keys,
|
||||
grid.getNumActive(), *rst_view);
|
||||
|
89
tests/test_RestartFileView.cpp
Normal file
89
tests/test_RestartFileView.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <opm/io/eclipse/RestartFileView.hpp>
|
||||
|
||||
#define BOOST_TEST_MODULE Test_RestartFileView
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/io/eclipse/ERst.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <random>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
T calcSum(const std::vector<T>& x)
|
||||
{
|
||||
return std::accumulate(x.begin(), x.end(), T(0));
|
||||
}
|
||||
|
||||
std::unique_ptr<Opm::EclIO::RestartFileView>
|
||||
openRestart(const std::string& filename,
|
||||
const int report_step)
|
||||
{
|
||||
auto rst = std::make_shared<Opm::EclIO::ERst>(filename);
|
||||
return std::make_unique<Opm::EclIO::RestartFileView>
|
||||
(std::move(rst), report_step);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Restart_File_View)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Load_Step_10)
|
||||
{
|
||||
const std::vector<int> ref_icon_10 = {
|
||||
1,10,10,3,0,1,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,
|
||||
0,1,1,1,1,0,1,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
const std::vector<std::string> ref_zwel_10 = {"PROD","","","INJ","",""};
|
||||
|
||||
const auto rst1 = openRestart("SPE1_TESTCASE.UNRST", 10);
|
||||
|
||||
BOOST_CHECK_EQUAL(rst1->simStep(), 9ull);
|
||||
BOOST_CHECK_EQUAL(rst1->reportStep(), 10);
|
||||
|
||||
BOOST_REQUIRE_MESSAGE(rst1->hasKeyword<int>("ICON"), "Restart file view must have ICON");
|
||||
BOOST_REQUIRE_MESSAGE(rst1->hasKeyword<float>("PRESSURE"), "Restart file view must have PRESSURE");
|
||||
BOOST_REQUIRE_MESSAGE(rst1->hasKeyword<double>("XGRP"), "Restart file view must have XGRP");
|
||||
BOOST_REQUIRE_MESSAGE(rst1->hasKeyword<std::string>("ZWEL"), "Restart file view must have ZWEL");
|
||||
|
||||
const auto icon = rst1->getKeyword<int>("ICON");
|
||||
const auto pres = rst1->getKeyword<float>("PRESSURE");
|
||||
const auto xgrp = rst1->getKeyword<double>("XGRP");
|
||||
const auto zwel = rst1->getKeyword<std::string>("ZWEL");
|
||||
|
||||
BOOST_CHECK_MESSAGE(icon == ref_icon_10, "ICON must equal reference");
|
||||
BOOST_CHECK_EQUAL(pres.size(), 300ull);
|
||||
BOOST_CHECK_CLOSE(calcSum(pres), 1.68803e+06, 1e-3);
|
||||
|
||||
BOOST_CHECK_EQUAL(xgrp.size(), 360ull);
|
||||
BOOST_CHECK_CLOSE(calcSum(xgrp), 1.81382e+08, 1e-3);
|
||||
|
||||
BOOST_CHECK_MESSAGE(zwel == ref_zwel_10, "ZWEL must equal reference");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue
Block a user