Merge pull request #2975 from bska/restart-compat
Address Compatibility Issues in XWEL and ZUDL
This commit is contained in:
commit
74d7effe3f
@ -213,6 +213,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
|||||||
|
|
||||||
GasFVF = 34, // Well's producing gas formation volume factor.
|
GasFVF = 34, // Well's producing gas formation volume factor.
|
||||||
|
|
||||||
|
item36 = 35, // Unknown
|
||||||
item37 = 36, // Unknown
|
item37 = 36, // Unknown
|
||||||
item38 = 37, // Unknown
|
item38 = 37, // Unknown
|
||||||
|
|
||||||
|
@ -16,20 +16,25 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQToken.hpp>
|
#include <opm/input/eclipse/Schedule/UDQ/UDQToken.hpp>
|
||||||
|
|
||||||
namespace Opm {
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string format_double(double d) {
|
std::string format_double(const double d)
|
||||||
return fmt::format("{:g}", d);
|
{
|
||||||
}
|
// Use uppercase exponents for restart file compatibility.
|
||||||
}
|
return fmt::format("{:G}", d);
|
||||||
|
}
|
||||||
|
} // namespace anonymous
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
UDQToken::UDQToken(const std::string& string_token, UDQTokenType token_type_) :
|
UDQToken::UDQToken(const std::string& string_token, UDQTokenType token_type_) :
|
||||||
token_type(token_type_)
|
token_type(token_type_)
|
||||||
@ -74,5 +79,4 @@ std::string UDQToken::str() const {
|
|||||||
return format_double(std::get<double>(this->m_value));
|
return format_double(std::get<double>(this->m_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
}
|
|
||||||
|
@ -45,10 +45,9 @@
|
|||||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||||
#include <opm/input/eclipse/Units/Units.hpp>
|
#include <opm/input/eclipse/Units/Units.hpp>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
@ -58,6 +57,8 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
namespace VI = Opm::RestartIO::Helpers::VectorItems;
|
namespace VI = Opm::RestartIO::Helpers::VectorItems;
|
||||||
|
|
||||||
// #####################################################################
|
// #####################################################################
|
||||||
@ -806,12 +807,13 @@ namespace {
|
|||||||
xWell[Ix::HistWatInjTotal] = get("WWITH");
|
xWell[Ix::HistWatInjTotal] = get("WWITH");
|
||||||
xWell[Ix::HistGasInjTotal] = get("WGITH");
|
xWell[Ix::HistGasInjTotal] = get("WGITH");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class XWellArray>
|
template <class XWellArray>
|
||||||
void assignProducer(const std::string& well,
|
void assignProducer(const std::string& well,
|
||||||
const ::Opm::SummaryState& smry,
|
const ::Opm::SummaryState& smry,
|
||||||
XWellArray& xWell)
|
XWellArray& xWell)
|
||||||
{
|
{
|
||||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
|
using Ix = VI::XWell::index;
|
||||||
|
|
||||||
auto get = [&smry, &well](const std::string& vector)
|
auto get = [&smry, &well](const std::string& vector)
|
||||||
{
|
{
|
||||||
@ -832,6 +834,7 @@ namespace {
|
|||||||
xWell[Ix::GORatio] = get("WGOR");
|
xWell[Ix::GORatio] = get("WGOR");
|
||||||
|
|
||||||
// Not fully characterised.
|
// Not fully characterised.
|
||||||
|
xWell[Ix::item36] = xWell[Ix::OilPrRate];
|
||||||
xWell[Ix::item37] = xWell[Ix::WatPrRate];
|
xWell[Ix::item37] = xWell[Ix::WatPrRate];
|
||||||
xWell[Ix::item38] = xWell[Ix::GasPrRate];
|
xWell[Ix::item38] = xWell[Ix::GasPrRate];
|
||||||
|
|
||||||
@ -848,6 +851,16 @@ namespace {
|
|||||||
{
|
{
|
||||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
|
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
|
||||||
|
|
||||||
|
// Injection rates reported as negative.
|
||||||
|
xWell[Ix::OilPrRate] = -get("WOIR");
|
||||||
|
xWell[Ix::WatPrRate] = -get("WWIR");
|
||||||
|
xWell[Ix::GasPrRate] = -get("WGIR");
|
||||||
|
|
||||||
|
// Not fully characterised.
|
||||||
|
xWell[Ix::item36] = xWell[Ix::OilPrRate];
|
||||||
|
xWell[Ix::item37] = xWell[Ix::WatPrRate];
|
||||||
|
xWell[Ix::item38] = xWell[Ix::GasPrRate];
|
||||||
|
|
||||||
xWell[Ix::TubHeadPr] = get("WTHP");
|
xWell[Ix::TubHeadPr] = get("WTHP");
|
||||||
xWell[Ix::FlowBHP] = get("WBHP");
|
xWell[Ix::FlowBHP] = get("WBHP");
|
||||||
}
|
}
|
||||||
@ -861,20 +874,14 @@ namespace {
|
|||||||
|
|
||||||
auto get = [&smry, &well](const std::string& vector)
|
auto get = [&smry, &well](const std::string& vector)
|
||||||
{
|
{
|
||||||
return smry.get_well_var(well, vector, 0);
|
return smry.get_well_var(well, vector, 0.0);
|
||||||
};
|
};
|
||||||
|
|
||||||
assignCommonInjector(get, xWell);
|
assignCommonInjector(get, xWell);
|
||||||
|
|
||||||
// Injection rates reported as negative.
|
|
||||||
xWell[Ix::WatPrRate] = -get("WWIR");
|
|
||||||
xWell[Ix::LiqPrRate] = xWell[Ix::WatPrRate];
|
xWell[Ix::LiqPrRate] = xWell[Ix::WatPrRate];
|
||||||
|
|
||||||
// Not fully characterised.
|
|
||||||
xWell[Ix::item37] = xWell[Ix::WatPrRate];
|
|
||||||
|
|
||||||
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WWIGR");
|
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WWIGR");
|
||||||
|
|
||||||
xWell[Ix::WatVoidPrRate] = -get("WWVIR");
|
xWell[Ix::WatVoidPrRate] = -get("WWVIR");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -887,13 +894,12 @@ namespace {
|
|||||||
|
|
||||||
auto get = [&smry, &well](const std::string& vector)
|
auto get = [&smry, &well](const std::string& vector)
|
||||||
{
|
{
|
||||||
return smry.get_well_var(well, vector, 0);
|
return smry.get_well_var(well, vector, 0.0);
|
||||||
};
|
};
|
||||||
|
|
||||||
assignCommonInjector(get, xWell);
|
assignCommonInjector(get, xWell);
|
||||||
|
|
||||||
// Injection rates reported as negative production rates.
|
// Injection rates reported as negative production rates.
|
||||||
xWell[Ix::GasPrRate] = -get("WGIR");
|
|
||||||
xWell[Ix::VoidPrRate] = -get("WGVIR");
|
xWell[Ix::VoidPrRate] = -get("WGVIR");
|
||||||
|
|
||||||
xWell[Ix::GasFVF] = (std::abs(xWell[Ix::GasPrRate]) > 0.0)
|
xWell[Ix::GasFVF] = (std::abs(xWell[Ix::GasPrRate]) > 0.0)
|
||||||
@ -904,11 +910,7 @@ namespace {
|
|||||||
xWell[Ix::GasFVF] = 0.0;
|
xWell[Ix::GasFVF] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not fully characterised.
|
|
||||||
xWell[Ix::item38] = xWell[Ix::GasPrRate];
|
|
||||||
|
|
||||||
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WGIGR");
|
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WGIGR");
|
||||||
|
|
||||||
xWell[Ix::GasVoidPrRate] = xWell[Ix::VoidPrRate];
|
xWell[Ix::GasVoidPrRate] = xWell[Ix::VoidPrRate];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,16 +919,17 @@ namespace {
|
|||||||
const ::Opm::SummaryState& smry,
|
const ::Opm::SummaryState& smry,
|
||||||
XWellArray& xWell)
|
XWellArray& xWell)
|
||||||
{
|
{
|
||||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
|
using Ix = VI::XWell::index;
|
||||||
|
|
||||||
auto get = [&smry, &well](const std::string& vector)
|
auto get = [&smry, &well](const std::string& vector)
|
||||||
{
|
{
|
||||||
return smry.get_well_var(well, vector, 0);
|
return smry.get_well_var(well, vector, 0.0);
|
||||||
};
|
};
|
||||||
|
|
||||||
xWell[Ix::TubHeadPr] = get("WTHP");
|
assignCommonInjector(get, xWell);
|
||||||
xWell[Ix::FlowBHP] = get("WBHP");
|
|
||||||
|
|
||||||
|
// Injection rates reported as negative production rates.
|
||||||
|
xWell[Ix::VoidPrRate] = -get("WOVIR");
|
||||||
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WOIGR");
|
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WOIGR");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,13 +1094,13 @@ AggregateWellData(const std::vector<int>& inteHead)
|
|||||||
|
|
||||||
void
|
void
|
||||||
Opm::RestartIO::Helpers::AggregateWellData::
|
Opm::RestartIO::Helpers::AggregateWellData::
|
||||||
captureDeclaredWellData(const Schedule& sched,
|
captureDeclaredWellData(const Schedule& sched,
|
||||||
const TracerConfig& tracers,
|
const TracerConfig& tracers,
|
||||||
const std::size_t sim_step,
|
const std::size_t sim_step,
|
||||||
const ::Opm::Action::State& action_state,
|
const ::Opm::Action::State& action_state,
|
||||||
const Opm::WellTestState& wtest_state,
|
const Opm::WellTestState& wtest_state,
|
||||||
const ::Opm::SummaryState& smry,
|
const ::Opm::SummaryState& smry,
|
||||||
const std::vector<int>& inteHead)
|
const std::vector<int>& inteHead)
|
||||||
{
|
{
|
||||||
const auto& wells = sched.wellNames(sim_step);
|
const auto& wells = sched.wellNames(sim_step);
|
||||||
const auto& step_glo = sched.glo(sim_step);
|
const auto& step_glo = sched.glo(sim_step);
|
||||||
@ -1106,7 +1109,7 @@ captureDeclaredWellData(const Schedule& sched,
|
|||||||
{
|
{
|
||||||
//const auto grpNames = groupNames(sched.getGroups());
|
//const auto grpNames = groupNames(sched.getGroups());
|
||||||
const auto groupMapNameIndex = IWell::currentGroupMapNameIndex(sched, sim_step, inteHead);
|
const auto groupMapNameIndex = IWell::currentGroupMapNameIndex(sched, sim_step, inteHead);
|
||||||
auto msWellID = std::size_t{0};
|
auto msWellID = std::size_t{0};
|
||||||
|
|
||||||
wellLoop(wells, sched, sim_step, [&groupMapNameIndex, &msWellID, &step_glo, &wtest_state, &smry, &sched, &sim_step, this]
|
wellLoop(wells, sched, sim_step, [&groupMapNameIndex, &msWellID, &step_glo, &wtest_state, &smry, &sched, &sim_step, this]
|
||||||
(const Well& well, const std::size_t wellID) -> void
|
(const Well& well, const std::size_t wellID) -> void
|
||||||
@ -1155,7 +1158,7 @@ Opm::RestartIO::Helpers::AggregateWellData::
|
|||||||
captureDynamicWellData(const Opm::Schedule& sched,
|
captureDynamicWellData(const Opm::Schedule& sched,
|
||||||
const TracerConfig& tracers,
|
const TracerConfig& tracers,
|
||||||
const std::size_t sim_step,
|
const std::size_t sim_step,
|
||||||
const Opm::data::Wells& xw,
|
const Opm::data::Wells& xw,
|
||||||
const ::Opm::SummaryState& smry)
|
const ::Opm::SummaryState& smry)
|
||||||
{
|
{
|
||||||
const auto& wells = sched.wellNames(sim_step);
|
const auto& wells = sched.wellNames(sim_step);
|
||||||
|
@ -17,53 +17,65 @@ Copyright 2018 Statoil ASA.
|
|||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <opm/common/utility/OpmInputError.hpp>
|
#include <opm/common/utility/OpmInputError.hpp>
|
||||||
#include <opm/input/eclipse/Utility/Typetools.hpp>
|
#include <opm/common/utility/TimeService.hpp>
|
||||||
#include <opm/input/eclipse/Python/Python.hpp>
|
|
||||||
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
|
|
||||||
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
|
||||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
|
||||||
#include <opm/input/eclipse/Parser/Parser.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
|
||||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||||
#include <opm/input/eclipse/Deck/UDAValue.hpp>
|
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQEnums.hpp>
|
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
|
#include <opm/input/eclipse/Python/Python.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQSet.hpp>
|
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQContext.hpp>
|
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/UDQ/UDQActive.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQAssign.hpp>
|
#include <opm/input/eclipse/Schedule/UDQ/UDQAssign.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/UDQ/UDQContext.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/UDQ/UDQEnums.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQFunction.hpp>
|
#include <opm/input/eclipse/Schedule/UDQ/UDQFunction.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.hpp>
|
#include <opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQActive.hpp>
|
#include <opm/input/eclipse/Schedule/UDQ/UDQSet.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
|
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
|
||||||
#include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp>
|
|
||||||
#include <opm/input/eclipse/Schedule/Well/NameOrder.hpp>
|
#include <opm/input/eclipse/Schedule/Well/NameOrder.hpp>
|
||||||
#include <opm/common/utility/TimeService.hpp>
|
#include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Utility/Typetools.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
|
||||||
|
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
||||||
|
#include <opm/input/eclipse/Parser/Parser.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||||
|
#include <opm/input/eclipse/Deck/UDAValue.hpp>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
#include <limits>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace Opm;
|
using namespace Opm;
|
||||||
|
|
||||||
Schedule make_schedule(const std::string& input) {
|
namespace {
|
||||||
Parser parser;
|
Schedule make_schedule(const std::string& input) {
|
||||||
auto python = std::make_shared<Python>();
|
Parser parser;
|
||||||
|
auto python = std::make_shared<Python>();
|
||||||
|
|
||||||
auto deck = parser.parseString(input);
|
auto deck = parser.parseString(input);
|
||||||
if (deck.hasKeyword("DIMENS")) {
|
if (deck.hasKeyword("DIMENS")) {
|
||||||
EclipseState es(deck);
|
EclipseState es(deck);
|
||||||
return Schedule(deck, es, python);
|
return Schedule(deck, es, python);
|
||||||
} else {
|
} else {
|
||||||
EclipseGrid grid(10,10,10);
|
EclipseGrid grid(10,10,10);
|
||||||
TableManager table ( deck );
|
TableManager table ( deck );
|
||||||
FieldPropsManager fp( deck, Phases{true, true, true}, grid, table);
|
FieldPropsManager fp( deck, Phases{true, true, true}, grid, table);
|
||||||
Runspec runspec (deck);
|
Runspec runspec (deck);
|
||||||
return Schedule(deck, grid , fp, runspec, python);
|
return Schedule(deck, grid , fp, runspec, python);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace anonymous
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(TYPE_COERCION) {
|
BOOST_AUTO_TEST_CASE(TYPE_COERCION) {
|
||||||
BOOST_CHECK( UDQVarType::SCALAR == UDQ::coerce(UDQVarType::SCALAR, UDQVarType::SCALAR) );
|
BOOST_CHECK( UDQVarType::SCALAR == UDQ::coerce(UDQVarType::SCALAR, UDQVarType::SCALAR) );
|
||||||
@ -1278,6 +1290,25 @@ BOOST_AUTO_TEST_CASE(UDQPARSE_TEST1) {
|
|||||||
BOOST_CHECK_EQUAL( def2.input_string() , "2 * (1 + WBHP)");
|
BOOST_CHECK_EQUAL( def2.input_string() , "2 * (1 + WBHP)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(INPUT_STRING_SCIENTIFIC_NOTATION) {
|
||||||
|
const auto schedule = make_schedule(R"(
|
||||||
|
SCHEDULE
|
||||||
|
UDQ
|
||||||
|
DEFINE FU_THREE (3000000 + FU_ONE*1500000 + 1000000*FU_TWO)/365 /
|
||||||
|
/
|
||||||
|
)");
|
||||||
|
|
||||||
|
const auto& udq = schedule.getUDQConfig(0);
|
||||||
|
const auto def = udq.definitions();
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(def.size(), 1ULL);
|
||||||
|
|
||||||
|
const auto expect_input_string = std::string {
|
||||||
|
"(3E+06 + FU_ONE * 1.5E+06 + 1E+06 * FU_TWO) / 365"
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(def[0].input_string(), expect_input_string);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) {
|
BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) {
|
||||||
UDQParams udqp;
|
UDQParams udqp;
|
||||||
@ -1610,11 +1641,13 @@ BOOST_AUTO_TEST_CASE(IntegrationTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Schedule make_udq_schedule(const std::string& schedule_string) {
|
namespace {
|
||||||
|
Schedule make_udq_schedule(const std::string& schedule_string) {
|
||||||
#include "data/integration_tests/udq2.data"
|
#include "data/integration_tests/udq2.data"
|
||||||
deck_string += schedule_string;
|
deck_string += schedule_string;
|
||||||
return make_schedule(deck_string);
|
return make_schedule(deck_string);
|
||||||
}
|
}
|
||||||
|
} // Namespace anonymous
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(IntegrationTest2) {
|
BOOST_AUTO_TEST_CASE(IntegrationTest2) {
|
||||||
const std::string udq_string = R"(
|
const std::string udq_string = R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user