Extract Common Base Class For Flat Tables With Record Copying
This commit introduces a new helper template class, FlatTableWithCopy<RecordType> which wraps a vector<RecordType>, provides constructors from DeckKeyword and initializer_list<RecordType> and handles copying tables for all-defaulted records. We reimplement the PVTW, DENSITY, and GRAVITY tables in terms of this helper class to reduce duplication. If the copy behaviour is generally useful/needed we expect to replace the existing FlatTable mechanism with the new helper. Suggested by: Markus Blatt
This commit is contained in:
parent
d35abfddb6
commit
254b2e2862
@ -3,6 +3,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
@ -24,6 +25,45 @@ struct FlatTable : public std::vector< T > {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RecordType>
|
||||
class FlatTableWithCopy
|
||||
{
|
||||
public:
|
||||
FlatTableWithCopy() = default;
|
||||
explicit FlatTableWithCopy(const DeckKeyword& kw,
|
||||
std::string_view expect = "");
|
||||
explicit FlatTableWithCopy(std::initializer_list<RecordType> records);
|
||||
|
||||
auto size() const { return this->table_.size(); }
|
||||
bool empty() const { return this->table_.empty(); }
|
||||
auto begin() const { return this->table_.begin(); }
|
||||
auto end() const { return this->table_.end(); }
|
||||
|
||||
const RecordType& operator[](const std::size_t tableID) const
|
||||
{
|
||||
return this->table_[tableID];
|
||||
}
|
||||
|
||||
const RecordType& at(const std::size_t tableID) const
|
||||
{
|
||||
return this->table_.at(tableID);
|
||||
}
|
||||
|
||||
bool operator==(const FlatTableWithCopy& other) const
|
||||
{
|
||||
return this->table_ == other.table_;
|
||||
}
|
||||
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer.vector(this->table_);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<RecordType> table_{};
|
||||
};
|
||||
|
||||
struct GRAVITYRecord {
|
||||
static constexpr std::size_t size = 3;
|
||||
|
||||
@ -46,33 +86,12 @@ struct GRAVITYRecord {
|
||||
}
|
||||
};
|
||||
|
||||
class GravityTable
|
||||
struct GravityTable : public FlatTableWithCopy<GRAVITYRecord>
|
||||
{
|
||||
public:
|
||||
GravityTable() = default;
|
||||
explicit GravityTable(const DeckKeyword& kw);
|
||||
explicit GravityTable(std::initializer_list<GRAVITYRecord> records);
|
||||
|
||||
auto size() const { return this->table_.size(); }
|
||||
bool empty() const { return this->table_.empty(); }
|
||||
auto begin() const { return this->table_.begin(); }
|
||||
auto end() const { return this->table_.end(); }
|
||||
|
||||
const GRAVITYRecord& operator[](const std::size_t tableID) const
|
||||
{
|
||||
return this->table_[tableID];
|
||||
}
|
||||
|
||||
const GRAVITYRecord& at(const std::size_t tableID) const
|
||||
{
|
||||
return this->table_.at(tableID);
|
||||
}
|
||||
|
||||
bool operator==(const GravityTable& other) const
|
||||
{
|
||||
return this->table_ == other.table_;
|
||||
}
|
||||
|
||||
static GravityTable serializeObject()
|
||||
{
|
||||
return GravityTable({{1.0, 2.0, 3.0}});
|
||||
@ -81,11 +100,8 @@ public:
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer.vector(this->table_);
|
||||
FlatTableWithCopy::serializeOp(serializer);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<GRAVITYRecord> table_{};
|
||||
};
|
||||
|
||||
struct DENSITYRecord {
|
||||
@ -110,33 +126,12 @@ struct DENSITYRecord {
|
||||
}
|
||||
};
|
||||
|
||||
class DensityTable
|
||||
struct DensityTable : public FlatTableWithCopy<DENSITYRecord>
|
||||
{
|
||||
public:
|
||||
DensityTable() = default;
|
||||
explicit DensityTable(const DeckKeyword& kw);
|
||||
explicit DensityTable(std::initializer_list<DENSITYRecord> records);
|
||||
explicit DensityTable(const GravityTable& gravity);
|
||||
|
||||
auto size() const { return this->table_.size(); }
|
||||
bool empty() const { return this->table_.empty(); }
|
||||
auto begin() const { return this->table_.begin(); }
|
||||
auto end() const { return this->table_.end(); }
|
||||
|
||||
const DENSITYRecord& operator[](const std::size_t tableID) const
|
||||
{
|
||||
return this->table_[tableID];
|
||||
}
|
||||
|
||||
const DENSITYRecord& at(const std::size_t tableID) const
|
||||
{
|
||||
return this->table_.at(tableID);
|
||||
}
|
||||
|
||||
bool operator==(const DensityTable& other) const
|
||||
{
|
||||
return this->table_ == other.table_;
|
||||
}
|
||||
explicit DensityTable(std::initializer_list<DENSITYRecord> records);
|
||||
|
||||
static DensityTable serializeObject()
|
||||
{
|
||||
@ -146,11 +141,8 @@ public:
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer.vector(this->table_);
|
||||
FlatTableWithCopy::serializeOp(serializer);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<DENSITYRecord> table_{};
|
||||
};
|
||||
|
||||
struct DiffCoeffRecord {
|
||||
@ -227,31 +219,12 @@ struct PVTWRecord {
|
||||
}
|
||||
};
|
||||
|
||||
class PvtwTable
|
||||
struct PvtwTable : public FlatTableWithCopy<PVTWRecord>
|
||||
{
|
||||
public:
|
||||
PvtwTable() = default;
|
||||
explicit PvtwTable(const DeckKeyword& kw);
|
||||
explicit PvtwTable(std::initializer_list<PVTWRecord> records);
|
||||
|
||||
auto size() const { return this->table_.size(); }
|
||||
bool empty() const { return this->table_.empty(); }
|
||||
|
||||
const PVTWRecord& operator[](const std::size_t tableID) const
|
||||
{
|
||||
return this->table_[tableID];
|
||||
}
|
||||
|
||||
const PVTWRecord& at(const std::size_t tableID) const
|
||||
{
|
||||
return this->table_.at(tableID);
|
||||
}
|
||||
|
||||
bool operator==(const PvtwTable& other) const
|
||||
{
|
||||
return this->table_ == other.table_;
|
||||
}
|
||||
|
||||
static PvtwTable serializeObject()
|
||||
{
|
||||
return PvtwTable({{1.0, 2.0, 3.0, 4.0, 5.0}});
|
||||
@ -260,11 +233,8 @@ public:
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer.vector(this->table_);
|
||||
FlatTableWithCopy::serializeOp(serializer);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PVTWRecord> table_{};
|
||||
};
|
||||
|
||||
struct ROCKRecord {
|
||||
|
@ -94,6 +94,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@ -1574,13 +1575,14 @@ bool all_defaulted(const DeckRecord& record)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
PvtwTable::PvtwTable(const DeckKeyword& kw)
|
||||
template <typename RecordType>
|
||||
FlatTableWithCopy<RecordType>::FlatTableWithCopy(const DeckKeyword& kw,
|
||||
std::string_view expect)
|
||||
{
|
||||
if (kw.name() != ParserKeywords::PVTW::keywordName) {
|
||||
if (!expect.empty() && (kw.name() != expect)) {
|
||||
throw std::invalid_argument {
|
||||
fmt::format("Keyword {} cannot be used to "
|
||||
"initialise {} table structures", kw.name(),
|
||||
ParserKeywords::PVTW::keywordName)
|
||||
"initialise {} table structures", kw.name(), expect)
|
||||
};
|
||||
}
|
||||
|
||||
@ -1588,9 +1590,9 @@ PvtwTable::PvtwTable(const DeckKeyword& kw)
|
||||
|
||||
for (const auto& record : kw) {
|
||||
if (all_defaulted(record)) {
|
||||
// All-defaulted records imply PVTW in region R is equal to PVTW
|
||||
// in region R-1. PVTW must not be defaulted in region 1 (i.e.,
|
||||
// when PVTNUM=1).
|
||||
// All-defaulted records imply table in region R is equal to
|
||||
// table in region R-1. Table must not be defaulted in region 1
|
||||
// (i.e., when PVTNUM=1).
|
||||
if (this->table_.empty()) {
|
||||
throw OpmInputError {
|
||||
"First record cannot be defaulted",
|
||||
@ -1601,89 +1603,34 @@ PvtwTable::PvtwTable(const DeckKeyword& kw)
|
||||
this->table_.push_back(this->table_.back());
|
||||
}
|
||||
else {
|
||||
this->table_.push_back(flat_get<PVTWRecord>(record, mkseq<PVTWRecord::size>{}));
|
||||
this->table_.push_back(flat_get<RecordType>(record, mkseq<RecordType::size>{}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PvtwTable::PvtwTable(std::initializer_list<PVTWRecord> records)
|
||||
: table_(records)
|
||||
template <typename RecordType>
|
||||
FlatTableWithCopy<RecordType>::FlatTableWithCopy(std::initializer_list<RecordType> records)
|
||||
: table_{ records }
|
||||
{}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
GravityTable::GravityTable(const DeckKeyword& kw)
|
||||
{
|
||||
if (kw.name() != ParserKeywords::GRAVITY::keywordName) {
|
||||
throw std::invalid_argument {
|
||||
fmt::format("Keyword {} cannot be used to "
|
||||
"initialise {} table structures", kw.name(),
|
||||
ParserKeywords::GRAVITY::keywordName)
|
||||
};
|
||||
}
|
||||
|
||||
this->table_.reserve(kw.size());
|
||||
|
||||
for (const auto& record : kw) {
|
||||
if (all_defaulted(record)) {
|
||||
// All-defaulted records imply GRAVITY in region R is equal to
|
||||
// GRAVITY in region R-1. GRAVITY must not be defaulted in
|
||||
// region 1 (i.e., when PVTNUM=1).
|
||||
if (this->table_.empty()) {
|
||||
throw OpmInputError {
|
||||
"First record cannot be defaulted",
|
||||
kw.location()
|
||||
};
|
||||
}
|
||||
|
||||
this->table_.push_back(this->table_.back());
|
||||
}
|
||||
else {
|
||||
this->table_.push_back(flat_get<GRAVITYRecord>(record, mkseq<GRAVITYRecord::size>{}));
|
||||
}
|
||||
}
|
||||
}
|
||||
: FlatTableWithCopy(kw, ParserKeywords::GRAVITY::keywordName)
|
||||
{}
|
||||
|
||||
GravityTable::GravityTable(std::initializer_list<GRAVITYRecord> records)
|
||||
: table_(records)
|
||||
: FlatTableWithCopy(records)
|
||||
{}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
DensityTable::DensityTable(const DeckKeyword& kw)
|
||||
{
|
||||
if (kw.name() != ParserKeywords::DENSITY::keywordName) {
|
||||
throw std::invalid_argument {
|
||||
fmt::format("Keyword {} cannot be used to "
|
||||
"initialise {} table structures", kw.name(),
|
||||
ParserKeywords::DENSITY::keywordName)
|
||||
};
|
||||
}
|
||||
|
||||
this->table_.reserve(kw.size());
|
||||
|
||||
for (const auto& record : kw) {
|
||||
if (all_defaulted(record)) {
|
||||
// All-defaulted records imply DENSITY in region R is equal to
|
||||
// DENSITY in region R-1. DENSITY must not be defaulted in
|
||||
// region 1 (i.e., when PVTNUM=1).
|
||||
if (this->table_.empty()) {
|
||||
throw OpmInputError {
|
||||
"First record cannot be defaulted",
|
||||
kw.location()
|
||||
};
|
||||
}
|
||||
|
||||
this->table_.push_back(this->table_.back());
|
||||
}
|
||||
else {
|
||||
this->table_.push_back(flat_get<DENSITYRecord>(record, mkseq<DENSITYRecord::size>{}));
|
||||
}
|
||||
}
|
||||
}
|
||||
: FlatTableWithCopy(kw, ParserKeywords::DENSITY::keywordName)
|
||||
{}
|
||||
|
||||
DensityTable::DensityTable(std::initializer_list<DENSITYRecord> records)
|
||||
: table_(records)
|
||||
: FlatTableWithCopy(records)
|
||||
{}
|
||||
|
||||
DensityTable::DensityTable(const GravityTable& gravity)
|
||||
@ -1716,6 +1663,16 @@ DensityTable::DensityTable(const GravityTable& gravity)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
PvtwTable::PvtwTable(const DeckKeyword& kw)
|
||||
: FlatTableWithCopy(kw, ParserKeywords::PVTW::keywordName)
|
||||
{}
|
||||
|
||||
PvtwTable::PvtwTable(std::initializer_list<PVTWRecord> records)
|
||||
: FlatTableWithCopy(records)
|
||||
{}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
template< typename T >
|
||||
FlatTable< T >::FlatTable( const DeckKeyword& kw ) :
|
||||
std::vector< T >( flat_records< T >( kw, mkseq< T::size >{} ) )
|
||||
|
Loading…
Reference in New Issue
Block a user