@@ -276,6 +276,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQSet.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQState.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQToken.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDT.cpp
|
||||
src/opm/input/eclipse/Schedule/VFPInjTable.cpp
|
||||
src/opm/input/eclipse/Schedule/VFPProdTable.cpp
|
||||
src/opm/input/eclipse/Parser/ErrorGuard.cpp
|
||||
@@ -548,6 +549,7 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/TransMultTests.cpp
|
||||
tests/parser/TuningTests.cpp
|
||||
tests/parser/UDQTests.cpp
|
||||
tests/parser/UDTTests.cpp
|
||||
tests/parser/UnitTests.cpp
|
||||
tests/parser/integration/NNCTests.cpp
|
||||
tests/parser/WellSolventTests.cpp
|
||||
@@ -1316,6 +1318,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/UDQ/UDQSet.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQState.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQToken.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDT.hpp
|
||||
opm/input/eclipse/Deck/DeckItem.hpp
|
||||
opm/input/eclipse/Deck/Deck.hpp
|
||||
opm/input/eclipse/Deck/DeckView.hpp
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDT.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Util/OrderedMap.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Util/IOrderSet.hpp>
|
||||
@@ -101,6 +102,8 @@ namespace Opm {
|
||||
const std::vector<std::string>& expression,
|
||||
std::size_t report_step);
|
||||
|
||||
void add_table(const std::string& name, UDT udt);
|
||||
|
||||
bool clear_pending_assignments();
|
||||
|
||||
void eval_assign(std::size_t report_step,
|
||||
@@ -136,6 +139,7 @@ namespace Opm {
|
||||
std::vector<UDQAssign> assignments(UDQVarType var_type) const;
|
||||
const UDQParams& params() const;
|
||||
const UDQFunctionTable& function_table() const;
|
||||
const std::unordered_map<std::string, UDT>& tables() const;
|
||||
|
||||
bool operator==(const UDQConfig& config) const;
|
||||
void required_summary(std::unordered_set<std::string>& summary_keys) const;
|
||||
@@ -146,6 +150,7 @@ namespace Opm {
|
||||
serializer(udq_params);
|
||||
serializer(m_definitions);
|
||||
serializer(m_assignments);
|
||||
serializer(m_tables);
|
||||
serializer(units);
|
||||
serializer(input_index);
|
||||
serializer(type_count);
|
||||
@@ -171,6 +176,7 @@ namespace Opm {
|
||||
// currently DEFINE'ed or ASSIGN'ed.
|
||||
std::unordered_map<std::string, UDQDefine> m_definitions;
|
||||
std::unordered_map<std::string, UDQAssign> m_assignments;
|
||||
std::unordered_map<std::string, UDT> m_tables;
|
||||
std::unordered_map<std::string, std::string> units;
|
||||
|
||||
IOrderSet<std::string> define_order;
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Opm {
|
||||
class UDQFunctionTable;
|
||||
class UDQSet;
|
||||
class UDQState;
|
||||
class UDT;
|
||||
class WellMatcher;
|
||||
|
||||
} // namespace Opm
|
||||
@@ -49,6 +50,7 @@ namespace Opm {
|
||||
|
||||
UDQContext(const UDQFunctionTable& udqft,
|
||||
const WellMatcher& wm,
|
||||
const std::unordered_map<std::string, UDT>& tables,
|
||||
SegmentMatcherFactory create_segment_matcher,
|
||||
SummaryState& summary_state,
|
||||
UDQState& udq_state);
|
||||
@@ -57,6 +59,7 @@ namespace Opm {
|
||||
std::optional<double> get_well_var(const std::string& well, const std::string& var) const;
|
||||
std::optional<double> get_group_var(const std::string& group, const std::string& var) const;
|
||||
std::optional<double> get_segment_var(const std::string& well, const std::string& var, std::size_t segment) const;
|
||||
const UDT& get_udt(const std::string& name) const;
|
||||
|
||||
void add(const std::string& key, double value);
|
||||
void update_assign(const std::string& keyword, const UDQSet& udq_result);
|
||||
@@ -73,6 +76,7 @@ namespace Opm {
|
||||
private:
|
||||
const UDQFunctionTable& udqft;
|
||||
const WellMatcher& well_matcher;
|
||||
const std::unordered_map<std::string, UDT>& udt;
|
||||
|
||||
SegmentMatcherFactory create_segment_matcher;
|
||||
mutable std::unique_ptr<SegmentMatcher> segment_matcher;
|
||||
|
||||
66
opm/input/eclipse/Schedule/UDQ/UDT.hpp
Normal file
66
opm/input/eclipse/Schedule/UDQ/UDT.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2023 SINTEF Digital
|
||||
|
||||
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 UDT_HPP
|
||||
#define UDT_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
|
||||
class UDT
|
||||
{
|
||||
public:
|
||||
enum class InterpolationType {
|
||||
NearestNeighbour, //!< Corresponds to 'NV'
|
||||
LinearClamp, //!< Corresponds to 'LC'
|
||||
LinearExtrapolate //!< Corresponds to 'LL'
|
||||
};
|
||||
|
||||
UDT() = default;
|
||||
|
||||
UDT(const std::vector<double>& x_vals,
|
||||
const std::vector<double>& y_vals,
|
||||
InterpolationType interp_type);
|
||||
|
||||
static UDT serializationTestObject();
|
||||
|
||||
double operator()(const double x) const;
|
||||
|
||||
bool operator==(const UDT& data) const;
|
||||
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(xvals_);
|
||||
serializer(yvals_);
|
||||
serializer(interp_type_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<double> xvals_; //!< Data points
|
||||
std::vector<double> yvals_; //!< Data values
|
||||
InterpolationType interp_type_ = InterpolationType::LinearClamp; //!< Interpolation type
|
||||
};
|
||||
|
||||
} // Namespace Opm
|
||||
|
||||
#endif // UDT_HPP
|
||||
@@ -173,6 +173,7 @@ namespace Opm {
|
||||
result.udqft = UDQFunctionTable(result.udq_params);
|
||||
result.m_definitions = {{"test1", UDQDefine::serializationTestObject()}};
|
||||
result.m_assignments = {{"test2", UDQAssign::serializationTestObject()}};
|
||||
result.m_tables = {{"test3", UDT::serializationTestObject()}};
|
||||
result.units = {{"test3", "test4"}};
|
||||
result.input_index.insert({"test5", UDQIndex::serializationTestObject()});
|
||||
result.type_count = {{UDQVarType::SCALAR, 5}};
|
||||
@@ -338,6 +339,11 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void UDQConfig::add_table(const std::string& name, UDT udt)
|
||||
{
|
||||
m_tables.emplace(name, std::move(udt));
|
||||
}
|
||||
|
||||
bool UDQConfig::clear_pending_assignments()
|
||||
{
|
||||
const auto update = ! this->pending_assignments_.empty();
|
||||
@@ -526,12 +532,18 @@ namespace Opm {
|
||||
return this->udqft;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, UDT>& UDQConfig::tables() const
|
||||
{
|
||||
return m_tables;
|
||||
}
|
||||
|
||||
bool UDQConfig::operator==(const UDQConfig& data) const
|
||||
{
|
||||
return (this->params() == data.params())
|
||||
&& (this->function_table() == data.function_table())
|
||||
&& (this->m_definitions == data.m_definitions)
|
||||
&& (this->m_assignments == data.m_assignments)
|
||||
&& (this->m_tables == data.m_tables)
|
||||
&& (this->units == data.units)
|
||||
&& (this->input_index == data.input_index)
|
||||
&& (this->type_count == data.type_count)
|
||||
@@ -628,7 +640,7 @@ namespace Opm {
|
||||
UDQState& udq_state) const
|
||||
{
|
||||
UDQContext context {
|
||||
this->function_table(), wm, std::move(create_segment_matcher), st, udq_state
|
||||
this->function_table(), wm, m_tables, std::move(create_segment_matcher), st, udq_state
|
||||
};
|
||||
this->eval_assign(report_step, sched, context);
|
||||
this->eval_define(report_step, udq_state, context);
|
||||
@@ -642,7 +654,7 @@ namespace Opm {
|
||||
UDQState& udq_state) const
|
||||
{
|
||||
UDQContext context {
|
||||
this->function_table(), wm, std::move(create_segment_matcher), st, udq_state
|
||||
this->function_table(), wm, m_tables, std::move(create_segment_matcher), st, udq_state
|
||||
};
|
||||
this->eval_assign(report_step, sched, context);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <opm/input/eclipse/Schedule/MSW/SegmentMatcher.hpp>
|
||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDT.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp>
|
||||
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
@@ -52,11 +53,13 @@ namespace Opm {
|
||||
|
||||
UDQContext::UDQContext(const UDQFunctionTable& udqft_arg,
|
||||
const WellMatcher& wm,
|
||||
const std::unordered_map<std::string, UDT>& tables,
|
||||
SegmentMatcherFactory create_segment_matcher_arg,
|
||||
SummaryState& summary_state_arg,
|
||||
UDQState& udq_state_arg)
|
||||
: udqft (udqft_arg)
|
||||
, well_matcher (wm)
|
||||
, udt(tables)
|
||||
, create_segment_matcher(std::move(create_segment_matcher_arg))
|
||||
, summary_state (summary_state_arg)
|
||||
, udq_state (udq_state_arg)
|
||||
@@ -173,6 +176,18 @@ namespace Opm {
|
||||
};
|
||||
}
|
||||
|
||||
const UDT&
|
||||
UDQContext::get_udt(const std::string& name) const
|
||||
{
|
||||
const auto it = udt.find(name);
|
||||
if (it == udt.end()) {
|
||||
throw std::logic_error {
|
||||
fmt::format("Not such UDT defined: {}", name)
|
||||
};
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::vector<std::string> UDQContext::wells() const
|
||||
{
|
||||
return this->well_matcher.wells();
|
||||
|
||||
70
src/opm/input/eclipse/Schedule/UDQ/UDT.cpp
Normal file
70
src/opm/input/eclipse/Schedule/UDQ/UDT.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright 2023 SINTEF Digital
|
||||
|
||||
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/input/eclipse/Schedule/UDQ/UDT.hpp>
|
||||
|
||||
#include <opm/common/utility/numeric/linearInterpolation.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
UDT::UDT(const std::vector<double>& xvals,
|
||||
const std::vector<double>& yvals,
|
||||
InterpolationType interp_type)
|
||||
: xvals_(xvals)
|
||||
, yvals_(yvals)
|
||||
, interp_type_(interp_type)
|
||||
{
|
||||
}
|
||||
|
||||
UDT UDT::serializationTestObject()
|
||||
{
|
||||
return UDT({1.0, 2.0}, {3.0, 4.0}, InterpolationType::NearestNeighbour);
|
||||
}
|
||||
|
||||
bool UDT::operator==(const UDT& rhs) const
|
||||
{
|
||||
return this->xvals_ == rhs.xvals_ &&
|
||||
this->yvals_ == rhs.yvals_ &&
|
||||
this->interp_type_ == rhs.interp_type_;
|
||||
}
|
||||
|
||||
double UDT::operator()(const double x) const
|
||||
{
|
||||
switch (interp_type_) {
|
||||
case InterpolationType::NearestNeighbour:
|
||||
{
|
||||
const int idx = Opm::tableIndex(xvals_, x);
|
||||
const double dist1 = std::abs(x - xvals_[idx]);
|
||||
const double dist2 = std::abs(x - xvals_[idx+1]);
|
||||
return dist1 < dist2 ? yvals_[idx] : yvals_[idx+1];
|
||||
}
|
||||
case InterpolationType::LinearClamp:
|
||||
return linearInterpolationNoExtrapolation(xvals_, yvals_, x);
|
||||
case InterpolationType::LinearExtrapolate:
|
||||
// TOOD: Use std::lerp when available ?
|
||||
return linearInterpolation(xvals_, yvals_, x);
|
||||
}
|
||||
|
||||
assert(0); // Should be unreachable
|
||||
}
|
||||
|
||||
} // namespace Opm
|
||||
@@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(GROUP_VARIABLES)
|
||||
SummaryState st(TimeService::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, {}, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, {}, {}, segmentMatcherFactory, st, udq_state);
|
||||
double gopr_lower = 1234;
|
||||
double gopr_upper = 4321;
|
||||
|
||||
@@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(SINGLE_SEGMENT_VARIABLES)
|
||||
};
|
||||
|
||||
auto context = UDQContext {
|
||||
udqft, {}, segmentMatcherFactory, st, udq_state
|
||||
udqft, {}, {}, segmentMatcherFactory, st, udq_state
|
||||
};
|
||||
|
||||
const auto sofr_p1_3 = 1234.0;
|
||||
@@ -263,7 +263,7 @@ BOOST_AUTO_TEST_CASE(SUBTRACT)
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 4);
|
||||
auto res = def.eval(context);
|
||||
@@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(TEST)
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1", "P2"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_group_var("MAU", "GOPR", 4);
|
||||
st.update_group_var("XXX", "GOPR", 5);
|
||||
@@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(MIX_SCALAR) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
|
||||
@@ -352,7 +352,7 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1", "P2", "P3", "P4"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1.0);
|
||||
st.update_well_var("P2", "WOPR", 2.0);
|
||||
@@ -455,7 +455,7 @@ BOOST_AUTO_TEST_CASE(UDQ_GROUP_TEST) {
|
||||
SummaryState st(TimeService::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, {}, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, {}, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_group_var("G1", "GOPR", 1.0);
|
||||
st.update_group_var("G2", "GOPR", 2.0);
|
||||
@@ -478,7 +478,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"W1", "W2", "W3"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("W1", "WBHP", 11);
|
||||
st.update_well_var("W2", "WBHP", 2);
|
||||
@@ -499,7 +499,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"I1", "I2", "P1", "P2"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WBHP", 1);
|
||||
st.update_well_var("P2", "WBHP", 2);
|
||||
@@ -518,7 +518,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1", "P2", "I1", "I2"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
st.update_well_var("P1", "WBHP", 4);
|
||||
st.update_well_var("P2", "WBHP", 3);
|
||||
st.update_well_var("I1", "WBHP", 2);
|
||||
@@ -721,7 +721,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CONTEXT) {
|
||||
UDQParams udqp;
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext ctx(func_table, {}, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext ctx(func_table, {}, {}, segmentMatcherFactory, st, udq_state);
|
||||
BOOST_CHECK_EQUAL(*ctx.get("JAN"), 1.0);
|
||||
BOOST_CHECK_THROW(ctx.get("NO_SUCH_KEY"), std::out_of_range);
|
||||
|
||||
@@ -1179,7 +1179,7 @@ BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) {
|
||||
NameOrder wo; wo.add("P1");
|
||||
WellMatcher wm(wo);
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
st.update_well_var("P1", "WWPR", 2);
|
||||
@@ -1202,7 +1202,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1", "P2"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 0);
|
||||
st.update_well_var("P1", "WWPR", 10);
|
||||
@@ -1234,7 +1234,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"PA1", "PB2", "PC3", "PD4"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("PA1", "WOPR", 1);
|
||||
st.update_well_var("PB2", "WOPR", 2);
|
||||
@@ -1306,7 +1306,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"OP1", "OP2", "OP3", "OP4"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("OP1", "WWIR", 1.0);
|
||||
st.update_well_var("OP2", "WWIR", 2.0);
|
||||
@@ -1352,7 +1352,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"OPL01", "OPL02", "OPU01", "OPU02"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("OPL01", "WWCT", 0.7);
|
||||
st.update_well_var("OPL02", "WWCT", 0.8);
|
||||
@@ -1382,7 +1382,7 @@ BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1", "P2", "P3", "P4"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
st.update_well_var("P2", "WOPR", 2);
|
||||
@@ -1446,7 +1446,7 @@ BOOST_AUTO_TEST_CASE(DECK_TEST) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"OP1", "OP2", "OP3"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
st.update_well_var("OP1", "WOPR", 300);
|
||||
st.update_well_var("OP2", "WOPR", 3000);
|
||||
@@ -1502,7 +1502,7 @@ BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
st.update_well_var("P1", "WBHP", 1);
|
||||
|
||||
auto res = def1.eval(context);
|
||||
@@ -1530,7 +1530,7 @@ BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) {
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"P1", "P2"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
st.update_well_var("P1", "WBHP", 1);
|
||||
st.update_well_var("P2", "WBHP", 2);
|
||||
|
||||
@@ -1988,7 +1988,7 @@ UDQ
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, {}, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, {}, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
auto res0 = def0.eval(context);
|
||||
BOOST_CHECK_CLOSE( res0[0].get(), -0.00125*3, 1e-6);
|
||||
@@ -2014,7 +2014,7 @@ UDQ
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, {}, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, {}, {}, segmentMatcherFactory, st, udq_state);
|
||||
const double fwpr = 7;
|
||||
const double fopr = 4;
|
||||
const double fgpr = 7;
|
||||
@@ -2058,7 +2058,7 @@ UDQ
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
WellMatcher wm(NameOrder({"W1", "W2", "W3"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
st.update_well_var("W1", "WOPR", 1);
|
||||
st.update_well_var("W2", "WOPR", 2);
|
||||
st.update_well_var("W3", "WOPR", 3);
|
||||
@@ -2613,7 +2613,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DIV_TEST) {
|
||||
SummaryState st(TimeService::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, {}, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, {}, {}, segmentMatcherFactory, st, udq_state);
|
||||
|
||||
auto res_div = def_div.eval(context);
|
||||
BOOST_CHECK_EQUAL( res_div[0].get() , 2.0);
|
||||
@@ -2843,7 +2843,7 @@ UDQ
|
||||
UDQFunctionTable udqft;
|
||||
WellMatcher wm(NameOrder({"W1", "W2", "W3"}));
|
||||
auto segmentMatcherFactory = []() { return std::make_unique<SegmentMatcher>(ScheduleState {}); };
|
||||
UDQContext context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
UDQContext context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
st.update_well_var("W1", "WBHP", 400);
|
||||
st.update_well_var("W2", "WBHP", 300);
|
||||
st.update_well_var("W3", "WBHP", 200);
|
||||
|
||||
59
tests/parser/UDTTests.cpp
Normal file
59
tests/parser/UDTTests.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2023 SINTEF Digital
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE UDTTests
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDT.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDT_NV)
|
||||
{
|
||||
UDT udt({1.0, 4.0, 5.0}, {5.0, 10.0, 11.0}, UDT::InterpolationType::NearestNeighbour);
|
||||
|
||||
BOOST_CHECK_EQUAL(udt(0.0), 5.0);
|
||||
BOOST_CHECK_EQUAL(udt(1.5), 5.0);
|
||||
BOOST_CHECK_EQUAL(udt(4.0), 10.0);
|
||||
BOOST_CHECK_EQUAL(udt(4.7), 11.0);
|
||||
BOOST_CHECK_EQUAL(udt(5.2), 11.0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDT_LC)
|
||||
{
|
||||
UDT udt({1.0, 4.0, 5.0}, {5.0, 10.0, 11.0}, UDT::InterpolationType::LinearClamp);
|
||||
|
||||
BOOST_CHECK_EQUAL(udt(0.0), 5.0);
|
||||
BOOST_CHECK_EQUAL(udt(1.5), 5.0 + (10.0 - 5.0) * (1.5 - 1.0) / (4.0 - 1.0));
|
||||
BOOST_CHECK_EQUAL(udt(4.0), 10.0);
|
||||
BOOST_CHECK_EQUAL(udt(4.7), 10.0 + (11.0 - 10.0) * (4.7 - 4.0) / (5.0 - 4.0));
|
||||
BOOST_CHECK_EQUAL(udt(5.2), 11.0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDT_LL)
|
||||
{
|
||||
UDT udt({1.0, 4.0, 5.0}, {5.0, 10.0, 11.0}, UDT::InterpolationType::LinearExtrapolate);
|
||||
|
||||
BOOST_CHECK_EQUAL(udt(0.0), 5.0 + (10.0 - 5.0) * (0.0 - 1.0) / (4.0 - 1.0));
|
||||
BOOST_CHECK_EQUAL(udt(1.5), 5.0 + (10.0 - 5.0) * (1.5 - 1.0) / (4.0 - 1.0));
|
||||
BOOST_CHECK_EQUAL(udt(4.0), 10.0);
|
||||
BOOST_CHECK_EQUAL(udt(4.7), 10.0 + (11.0 - 10.0) * (4.7 - 4.0) / (5.0 - 4.0));
|
||||
BOOST_CHECK_EQUAL(udt(5.2), 10.0 + (11.0 - 10.0) * (5.2 - 4.0) / (5.0 - 4.0));
|
||||
}
|
||||
@@ -892,8 +892,8 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
|
||||
return std::make_unique<Opm::SegmentMatcher>(Opm::ScheduleState{});
|
||||
};
|
||||
|
||||
Opm::UDQContext input_context(udqft, wm, segmentMatcherFactory, st, udq_state);
|
||||
Opm::UDQContext rst_context(udqft, wm, segmentMatcherFactory, st, rst_udq_state);
|
||||
Opm::UDQContext input_context(udqft, wm, {}, segmentMatcherFactory, st, udq_state);
|
||||
Opm::UDQContext rst_context(udqft, wm, {}, segmentMatcherFactory, st, rst_udq_state);
|
||||
|
||||
rst_udq_state.load_rst(rst_state);
|
||||
for (const auto& input_def : input_config.definitions()) {
|
||||
|
||||
Reference in New Issue
Block a user