diff --git a/opm/input/eclipse/EclipseState/Grid/FieldProps.hpp b/opm/input/eclipse/EclipseState/Grid/FieldProps.hpp index 72938acfc..701994e09 100644 --- a/opm/input/eclipse/EclipseState/Grid/FieldProps.hpp +++ b/opm/input/eclipse/EclipseState/Grid/FieldProps.hpp @@ -19,22 +19,32 @@ #ifndef FIELDPROPS_HPP #define FIELDPROPS_HPP -#include -#include -#include -#include -#include - -#include -#include -#include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace Opm { @@ -324,8 +334,6 @@ public: } }; - - enum class GetStatus { OK = 1, INVALID_DATA = 2, // std::runtime_error @@ -333,8 +341,6 @@ public: NOT_SUPPPORTED_KEYWORD = 4 // std::logic_error }; - - template struct FieldDataManager { const std::string& keyword; @@ -385,10 +391,9 @@ public: }; - - /// Normal constructor for FieldProps. FieldProps(const Deck& deck, const Phases& phases, const EclipseGrid& grid, const TableManager& table_arg); + /// Special case constructor used to process ACTNUM only. FieldProps(const Deck& deck, const EclipseGrid& grid); @@ -410,102 +415,120 @@ public: template std::vector keys() const; - template - FieldDataManager try_get(const std::string& keyword, - bool allow_unsupported=false) { - if (!allow_unsupported && !FieldProps::supported(keyword)) - return FieldDataManager(keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr); - - const Fieldprops::FieldData * field_data; - bool has0 = this->has(keyword); - - field_data = std::addressof(this->init_get(keyword, - std::is_same::value && allow_unsupported)); - if (field_data->valid() || allow_unsupported) - return FieldDataManager(keyword, GetStatus::OK, field_data); - - if (!has0) { - this->erase(keyword); - return FieldDataManager(keyword, GetStatus::MISSING_KEYWORD, nullptr); + FieldDataManager + try_get(const std::string& keyword, const bool allow_unsupported = false) + { + if (!allow_unsupported && !FieldProps::supported(keyword)) { + return { keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr }; } - return FieldDataManager(keyword, GetStatus::INVALID_DATA, nullptr); - } + const auto has0 = this->has(keyword); + const auto& field_data = + this->init_get(keyword, std::is_same::value && allow_unsupported); - template - const std::vector& get(const std::string& keyword) { - const auto& data = this->try_get(keyword); - return data.data(); + if (field_data.valid() || allow_unsupported) { + // Note: FieldDataManager depends on init_get<>() producing a + // long-lived FieldData instance. + return { keyword, GetStatus::OK, &field_data }; + } + + if (! has0) { + this->erase(keyword); + + return { keyword, GetStatus::MISSING_KEYWORD, nullptr }; + } + + return { keyword, GetStatus::INVALID_DATA, nullptr }; } template - std::vector get_global(const std::string& keyword) { - const auto& managed_field_data = this->try_get(keyword); + const std::vector& get(const std::string& keyword) + { + return this->try_get(keyword).data(); + } + + template + std::vector get_global(const std::string& keyword) + { + const auto managed_field_data = this->try_get(keyword); const auto& field_data = managed_field_data.field_data(); + const auto& kw_info = Fieldprops::keywords::global_kw_info(keyword); - if (kw_info.global) - return *field_data.global_data; - else - return this->global_copy(field_data.data, kw_info.scalar_init); + + return kw_info.global + ? *field_data.global_data + : this->global_copy(field_data.data, kw_info.scalar_init); } - template - std::vector get_copy(const std::string& keyword, bool global) { - bool has0 = this->has(keyword); - const auto& field_data = this->try_get(keyword).field_data(); + std::vector get_copy(const std::string& keyword, bool global) + { + const auto has0 = this->template has(keyword); + + // Recall: FieldDataManager::field_data() will throw various + // exception types if the 'status' is anything other than 'OK'. + // + // Get_copy() depends on this behaviour to not proceed to extracting + // values in such cases. In other words, get_copy() uses exceptions + // for control flow, and we cannot move this try_get() call into the + // 'has0' branch even though the actual 'field_data' object returned + // from try_get() is only needed/used there. + const auto& field_data = this->template try_get(keyword).field_data(); if (has0) { - if (global) - return this->global_copy(field_data.data, field_data.kw_info.scalar_init); - else - return field_data.data; - } else { - if (global) { - const auto& kw_info = Fieldprops::keywords::global_kw_info(keyword); - return this->global_copy(this->extract(keyword), kw_info.scalar_init); - } else - return this->extract(keyword); + return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global); } + + const auto initial_value = Fieldprops::keywords:: + template global_kw_info(keyword).scalar_init; + + return this->get_copy(this->template extract(keyword), initial_value, global); } - template - std::vector defaulted(const std::string& keyword) { + std::vector defaulted(const std::string& keyword) + { const auto& field = this->init_get(keyword); std::vector def(field.size()); - for (std::size_t i=0; i < def.size(); i++) - def[i] = value::defaulted( field.value_status[i]); + for (std::size_t i = 0; i < def.size(); ++i) { + def[i] = value::defaulted(field.value_status[i]); + } return def; } - template - std::vector global_copy(const std::vector& data, const std::optional& default_value) const { - T fill_value = default_value.has_value() ? *default_value : 0; + std::vector global_copy(const std::vector& data, + const std::optional& default_value) const + { + const T fill_value = default_value.has_value() ? *default_value : 0; + std::vector global_data(this->global_size, fill_value); + std::size_t i = 0; for (std::size_t g = 0; g < this->global_size; g++) { if (this->m_actnum[g]) { global_data[g] = data[i]; - i++; + ++i; } } + return global_data; } std::size_t active_size; std::size_t global_size; - std::size_t num_int() const { + std::size_t num_int() const + { return this->int_data.size(); } - std::size_t num_double() const { + std::size_t num_double() const + { return this->double_data.size(); } @@ -535,6 +558,22 @@ private: template std::vector extract(const std::string& keyword); + template + std::vector get_copy(const std::vector& x, + const std::optional& initial_value, + const bool global) const + { + return (! global) ? x : this->global_copy(x, initial_value); + } + + template + std::vector get_copy(std::vector&& x, + const std::optional& initial_value, + const bool global) const + { + return (! global) ? std::move(x) : this->global_copy(x, initial_value); + } + template void operate(const DeckRecord& record, Fieldprops::FieldData& target_data, const Fieldprops::FieldData& src_data, const std::vector& index_list); diff --git a/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp b/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp index 33200e643..024cd3e48 100644 --- a/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp +++ b/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp @@ -69,6 +69,7 @@ public: bool operator==(const FieldPropsManager& other) const; static bool rst_cmp(const FieldPropsManager& full_arg, const FieldPropsManager& rst_arg); + /* Because the FieldProps class can autocreate properties the semantics of get() and has() is slightly non intuitve: @@ -136,8 +137,8 @@ public: contain said keyword, or if the keyword has not been fully initialized. If you ask for a totally unknown keyword the method will return nullptr. */ - template const std::vector* try_get(const - std::string& keyword) const; + template + const std::vector* try_get(const std::string& keyword) const; /* You can ask whether the elements in the keyword have a default value - diff --git a/src/opm/input/eclipse/EclipseState/Grid/FieldProps.cpp b/src/opm/input/eclipse/EclipseState/Grid/FieldProps.cpp index bde6d0f87..cff52ccda 100644 --- a/src/opm/input/eclipse/EclipseState/Grid/FieldProps.cpp +++ b/src/opm/input/eclipse/EclipseState/Grid/FieldProps.cpp @@ -18,17 +18,25 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include -#include #include +#include +#include +#include +#include // Layering violation. Needed for apply_tran() function. +#include +#include +#include +#include +#include + +#include + +#include + #include #include #include @@ -38,22 +46,23 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - #include "Operate.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include namespace { Opm::Box makeGlobalGridBox(const Opm::EclipseGrid* gridPtr) @@ -425,9 +434,9 @@ bool FieldProps::operator==(const FieldProps& other) const { this->m_default_region == other.m_default_region && this->m_rtep == other.m_rtep && this->tables == other.tables && + this->multregp == other.multregp && this->int_data == other.int_data && this->double_data == other.double_data && - this->multregp == other.multregp && this->tran == other.tran; } @@ -1403,7 +1412,7 @@ const std::string& FieldProps::default_region() const { } void FieldProps::apply_tran(const std::string& keyword, std::vector& data) { - Opm::apply_tran(this->tran, this->double_data, this->active_size, keyword, data); + ::Opm::apply_tran(this->tran, this->double_data, this->active_size, keyword, data); } bool FieldProps::tran_active(const std::string& keyword) const { diff --git a/src/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.cpp b/src/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.cpp index 84df0aaae..a14be8ec5 100644 --- a/src/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.cpp +++ b/src/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.cpp @@ -18,15 +18,15 @@ #include -#include +#include #include #include #include -#include + +#include namespace Opm { - bool FieldPropsManager::operator==(const FieldPropsManager& other) const { return *this->fp == *other.fp; } @@ -237,4 +237,4 @@ template std::vector FieldPropsManager::get_copy(const std::string& keyw template const std::vector* FieldPropsManager::try_get(const std::string& keyword) const; template const std::vector* FieldPropsManager::try_get(const std::string& keyword) const; -} +} // namespace Opm