Files
opm-common/tests/parser/WTEST.cpp
Joakim Hove 2e832f0fbe Changes to Well status implementation
o The status of a well is maintened as a small object which is managed by a new
   std::shared_ptr member in the well objects. The consequence of this is that
   several well objects can share the same underlying status object. The
   advantage of this is that runtime (i.e. ACTIONX) updates of well status will
   affect the correct set of wells.

 o The general Schedule::updateWell() will use the DynamicState::upadte_equal()
2020-12-08 09:36:45 +01:00

216 lines
8.2 KiB
C++

/*
Copyright 2018 Statoil 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 <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE WTEST
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleTypes.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
using namespace Opm;
BOOST_AUTO_TEST_CASE(CreateWellTestConfig) {
WellTestConfig wc;
BOOST_CHECK_EQUAL(wc.size() , 0U);
wc.add_well("NAME", WellTestConfig::Reason::PHYSICAL, 10, 10, 10, 1);
BOOST_CHECK_EQUAL(wc.size(), 1U);
BOOST_CHECK_THROW(wc.add_well("NAME2", "", 10.0,10,10.0, 1), std::invalid_argument);
BOOST_CHECK_THROW(wc.add_well("NAME3", "X", 1,2,3, 1), std::invalid_argument);
wc.add_well("NAME", "PEGDC", 10, 10, 10, 1);
BOOST_CHECK_EQUAL(wc.size(), 5U);
wc.add_well("NAMEX", "PGDC", 10, 10, 10, 1);
BOOST_CHECK_EQUAL(wc.size(), 9U);
wc.drop_well("NAME");
BOOST_CHECK_EQUAL(wc.size(), 4U);
BOOST_CHECK(wc.has("NAMEX"));
BOOST_CHECK(wc.has("NAMEX", WellTestConfig::Reason::PHYSICAL));
BOOST_CHECK(!wc.has("NAMEX", WellTestConfig::Reason::ECONOMIC));
BOOST_CHECK(!wc.has("NAME"));
BOOST_CHECK_THROW(wc.get("NAMEX", WellTestConfig::Reason::ECONOMIC), std::invalid_argument);
BOOST_CHECK_THROW(wc.get("NO_NAME", WellTestConfig::Reason::ECONOMIC), std::invalid_argument);
const auto& wt = wc.get("NAMEX", WellTestConfig::Reason::PHYSICAL);
BOOST_CHECK_EQUAL(wt.name, "NAMEX");
}
BOOST_AUTO_TEST_CASE(WTEST_STATE2) {
WellTestConfig wc;
WellTestState st;
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 0, 0, 0, 0);
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100);
BOOST_CHECK_EQUAL(st.sizeWells(), 1U);
const UnitSystem us{};
std::vector<Well> wells;
wells.emplace_back("WELL_NAME", "A", 0, 0, 1, 1, 200., WellType(Phase::OIL), Well::ProducerCMode::NONE, Connection::Order::TRACK, us, 0., 1.0, true, true, 0, Well::GasInflowEquation::STD);
{
wells[0].updateStatus(Well::Status::SHUT, false, false);
auto shut_wells = st.updateWells(wc, wells, 5000);
BOOST_CHECK_EQUAL(shut_wells.size(), 0U);
}
{
wells[0].updateStatus(Well::Status::OPEN, false, false);
auto shut_wells = st.updateWells(wc, wells, 5000);
BOOST_CHECK_EQUAL( shut_wells.size(), 1U);
}
}
BOOST_AUTO_TEST_CASE(WTEST_STATE) {
const double day = 86400.;
WellTestState st;
st.closeWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100. * day);
BOOST_CHECK_EQUAL(st.sizeWells(), 1U);
st.openWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC);
BOOST_CHECK_EQUAL(st.sizeWells(), 1U);
st.closeWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100. * day);
BOOST_CHECK_EQUAL(st.sizeWells(), 1U);
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100. * day);
BOOST_CHECK_EQUAL(st.sizeWells(), 2U);
st.closeWell("WELLX", WellTestConfig::Reason::PHYSICAL, 100. * day);
BOOST_CHECK_EQUAL(st.sizeWells(), 3U);
const UnitSystem us{};
std::vector<Well> wells;
wells.emplace_back("WELL_NAME", "A", 0, 0, 1, 1, 200., WellType(Phase::OIL), Well::ProducerCMode::NONE, Connection::Order::TRACK, us, 0., 1.0, true, true, 0, Well::GasInflowEquation::STD);
wells.emplace_back("WELLX", "A", 0, 0, 2, 2, 200., WellType(Phase::OIL), Well::ProducerCMode::NONE, Connection::Order::TRACK, us, 0., 1.0, true, true, 0, Well::GasInflowEquation::STD);
WellTestConfig wc;
{
wells[0].updateStatus(Well::Status::SHUT, false, false);
auto shut_wells = st.updateWells(wc, wells, 110. * day);
BOOST_CHECK_EQUAL(shut_wells.size(), 0U);
}
{
wells[0].updateStatus(Well::Status::OPEN, false, false);
auto shut_wells = st.updateWells(wc, wells, 110. * day);
BOOST_CHECK_EQUAL(shut_wells.size(), 0U);
}
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000. * day, 2, 0, 1);
// Not sufficient time has passed.
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 200. * day).size(), 0U);
// We should test it:
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 1200. * day).size(), 1U);
// Not sufficient time has passed.
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 1700. * day).size(), 0U);
st.openWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL);
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1900. * day);
// We should not test it:
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 2400. * day).size(), 0U);
// We should test it now:
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 3000. * day).size(), 1U);
// Too many attempts:
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 4000. * day).size(), 0U);
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000. * day, 3, 0, 5);
wells[0].updateStatus(Well::Status::SHUT, false, false);
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 4100. * day).size(), 0U);
wells[0].updateStatus(Well::Status::OPEN, false, false);
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 4100. * day).size(), 1U);
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 5200. * day).size(), 1U);
wc.drop_well("WELL_NAME");
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 6300. * day).size(), 0U);
}
BOOST_AUTO_TEST_CASE(WTEST_STATE_COMPLETIONS) {
WellTestConfig wc;
WellTestState st;
st.addClosedCompletion("WELL_NAME", 2, 100);
BOOST_CHECK_EQUAL(st.sizeCompletions(), 1U);
st.addClosedCompletion("WELL_NAME", 2, 100);
BOOST_CHECK_EQUAL(st.sizeCompletions(), 1U);
st.addClosedCompletion("WELL_NAME", 3, 100);
BOOST_CHECK_EQUAL(st.sizeCompletions(), 2U);
st.addClosedCompletion("WELLX", 3, 100);
BOOST_CHECK_EQUAL(st.sizeCompletions(), 3U);
const UnitSystem us{};
std::vector<Well> wells;
wells.emplace_back("WELL_NAME", "A", 0, 0, 1, 1, 200., WellType(Phase::OIL), Well::ProducerCMode::NONE, Connection::Order::TRACK, us, 0., 1.0, true, true, 0, Well::GasInflowEquation::STD);
wells[0].updateStatus(Well::Status::OPEN, false, false);
wells.emplace_back("WELLX", "A", 0, 0, 2, 2, 200., WellType(Phase::OIL), Well::ProducerCMode::NONE, Connection::Order::TRACK, us, 0., 1.0, true, true, 0, Well::GasInflowEquation::STD);
wells[1].updateStatus(Well::Status::OPEN, false, false);
auto closed_completions = st.updateWells(wc, wells, 5000);
BOOST_CHECK_EQUAL( closed_completions.size(), 0U);
wc.add_well("WELL_NAME", WellTestConfig::Reason::COMPLETION, 1000, 2, 0, 0);
// Not sufficient time has passed.
BOOST_CHECK_EQUAL( st.updateCompletion(wc, 200).size(), 0U);
// We should test it:
BOOST_CHECK_EQUAL( st.updateCompletion(wc, 1200).size(), 2U);
// Not sufficient time has passed.
BOOST_CHECK_EQUAL( st.updateCompletion(wc, 1700).size(), 0U);
// We should test it:
BOOST_CHECK_EQUAL( st.updateCompletion(wc, 2400).size(), 2U);
// Too many attempts:
BOOST_CHECK_EQUAL( st.updateCompletion(wc, 24000).size(), 0U);
st.dropCompletion("WELL_NAME", 2);
st.dropCompletion("WELLX", 3);
BOOST_CHECK_EQUAL(st.sizeCompletions(), 1U);
}