Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare for Restarting Models With Segment Level UDQs #4224

Merged
merged 1 commit into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions opm/input/eclipse/Schedule/Well/WellTestState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@
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/Well/WellTestState.hpp>

#include <opm/common/OpmLog/OpmLog.hpp>

#include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <ctime>
#include <optional>
#include <stdexcept>

#include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>
#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <string>
#include <unordered_set>
#include <vector>

namespace Opm {

Expand Down
3 changes: 3 additions & 0 deletions opm/input/eclipse/Schedule/Well/WellTestState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@
#define WELLTEST_STATE_H

#include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>

#include <opm/io/eclipse/rst/state.hpp>

#include <cstddef>
#include <ctime>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

namespace {
Expand Down
1 change: 1 addition & 0 deletions test_util/EclRegressionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <iostream>
#include <set>
#include <typeinfo>
#include <unordered_set>
#include <vector>

// helper macro to handle error throws or not
Expand Down
166 changes: 92 additions & 74 deletions tests/parser/ScheduleRestartTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,59 @@

#include <boost/test/unit_test.hpp>

#include <opm/io/eclipse/rst/state.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <opm/io/eclipse/RestartFileView.hpp>

#include <opm/common/utility/TimeService.hpp>
#include <opm/input/eclipse/Units/UnitSystem.hpp>
#include <opm/input/eclipse/Python/Python.hpp>

#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>

#include <opm/input/eclipse/Python/Python.hpp>

#include <opm/input/eclipse/Schedule/Action/Actions.hpp>
#include <opm/input/eclipse/Schedule/Action/State.hpp>
#include <opm/input/eclipse/Schedule/OilVaporizationProperties.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/Action/Actions.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/input/eclipse/Schedule/Well/WListManager.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Units/UnitSystem.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
#include <opm/input/eclipse/Schedule/Action/State.hpp>
#include <opm/input/eclipse/Schedule/Well/WListManager.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>

#include <opm/input/eclipse/Units/UnitSystem.hpp>

#include <opm/input/eclipse/Parser/ParserKeywords/D.hpp>

#include <opm/input/eclipse/Deck/DeckValue.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Deck/FileDeck.hpp>

#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/io/eclipse/rst/state.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <opm/io/eclipse/RestartFileView.hpp>

#include <algorithm>
#include <cstddef>
#include <filesystem>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace fs = std::filesystem;

using namespace Opm;

void compare_connections(const RestartIO::RstConnection& rst_conn, const Connection& sched_conn) {
namespace {

void compare_connections(const RestartIO::RstConnection& rst_conn,
const Connection& sched_conn)
{
BOOST_CHECK_EQUAL(rst_conn.ijk[0], sched_conn.getI());
BOOST_CHECK_EQUAL(rst_conn.ijk[1], sched_conn.getJ());
BOOST_CHECK_EQUAL(rst_conn.ijk[2], sched_conn.getK());
Expand All @@ -71,9 +85,9 @@ void compare_connections(const RestartIO::RstConnection& rst_conn, const Connect
BOOST_CHECK_CLOSE( rst_conn.cf, sched_conn.CF() , 1e-6);
}



void compare_wells(const RestartIO::RstWell& rst_well, const Well& sched_well) {
void compare_wells(const RestartIO::RstWell& rst_well,
const Well& sched_well)
{
BOOST_CHECK_EQUAL(rst_well.name, sched_well.name());
BOOST_CHECK_EQUAL(rst_well.group, sched_well.groupName());

Expand All @@ -87,6 +101,7 @@ void compare_wells(const RestartIO::RstWell& rst_well, const Well& sched_well) {
}
}

} // Anonymous namespace

BOOST_AUTO_TEST_CASE(LoadRST) {
Parser parser;
Expand All @@ -108,11 +123,14 @@ BOOST_AUTO_TEST_CASE(LoadRST) {
}
}

namespace {

std::tuple<Schedule, Schedule, RestartIO::RstState> load_schedule_pair(const std::string& base_deck,
const std::string& rst_deck,
const std::string& rst_fname,
std::size_t restart_step) {
std::tuple<Schedule, Schedule, RestartIO::RstState>
load_schedule_pair(const std::string& base_deck,
const std::string& rst_deck,
const std::string& rst_fname,
const std::size_t restart_step)
{
Parser parser;
auto python = std::make_shared<Python>();
auto deck = parser.parseFile(base_deck);
Expand All @@ -133,7 +151,7 @@ std::tuple<Schedule, Schedule, RestartIO::RstState> load_schedule_pair(const std
void compare_sched(const std::string& base_deck,
const std::string& rst_deck,
const std::string& rst_fname,
std::size_t restart_step)
const std::size_t restart_step)
{
const auto& [sched, restart_sched, _] = load_schedule_pair(base_deck, rst_deck, rst_fname, restart_step);
(void) _;
Expand All @@ -152,14 +170,14 @@ void compare_sched(const std::string& base_deck,
}
}

} // Anonymous namespace


BOOST_AUTO_TEST_CASE(LoadRestartSim) {
BOOST_AUTO_TEST_CASE(LoadRestartSim)
{
compare_sched("SPE1CASE2.DATA", "SPE1CASE2_RESTART_SKIPREST.DATA", "SPE1CASE2.X0060", 60);
compare_sched("SPE1CASE2.DATA", "SPE1CASE2_RESTART.DATA", "SPE1CASE2.X0060", 60);
}


BOOST_AUTO_TEST_CASE(LoadUDQRestartSim)
{
const auto& [sched, restart_sched, rst_state] =
Expand Down Expand Up @@ -196,65 +214,73 @@ BOOST_AUTO_TEST_CASE(LoadUDQRestartSim)
udq_state.load_rst(rst_state);
}

BOOST_AUTO_TEST_CASE(LoadActionRestartSim) {
const auto& [sched, restart_sched, rst_state] = load_schedule_pair("UDQ_ACTIONX.DATA", "UDQ_ACTIONX_RESTART.DATA", "UDQ_ACTIONX.X0007", 7);
BOOST_AUTO_TEST_CASE(LoadActionRestartSim)
{
const auto& [sched, restart_sched, rst_state] =
load_schedule_pair("UDQ_ACTIONX.DATA", "UDQ_ACTIONX_RESTART.DATA", "UDQ_ACTIONX.X0007", 7);

const auto& input_actions = sched[7].actions();
const auto& rst_actions = restart_sched[7].actions();

BOOST_CHECK_EQUAL(input_actions.ecl_size(), rst_actions.ecl_size());
for (std::size_t iact = 0; iact < input_actions.ecl_size(); iact++) {
for (std::size_t iact = 0; iact < input_actions.ecl_size(); ++iact) {
const auto& input_action = input_actions[iact];
const auto& rst_action = rst_actions[iact];

BOOST_REQUIRE_EQUAL(std::distance(input_action.begin(), input_action.end()),
std::distance(rst_action.begin(), rst_action.end()));

auto input_iter = input_action.begin();
auto rst_iter = rst_action.begin();

BOOST_REQUIRE_EQUAL( std::distance(input_action.begin(), input_action.end()),
std::distance(rst_action.begin(), rst_action.end()) );

while (input_iter != input_action.end()) {
BOOST_CHECK( *input_iter == *rst_iter );
input_iter++;
rst_iter++;
BOOST_CHECK(*input_iter == *rst_iter);
++input_iter;
++rst_iter;
}
}

Action::State action_state;
action_state.load_rst(rst_actions, rst_state);
}

BOOST_AUTO_TEST_CASE(LoadUDQRestartSim0) {
const auto& [sched, restart_sched, _] = load_schedule_pair("ACTIONX_M1.DATA", "ACTIONX_M1_RESTART.DATA", "ACTIONX_M1.X0010", 10);
(void)_;
std::size_t report_step = 12;
BOOST_AUTO_TEST_CASE(LoadUDQRestartSim0)
{
const auto& [sched, restart_sched, _] =
load_schedule_pair("ACTIONX_M1.DATA", "ACTIONX_M1_RESTART.DATA", "ACTIONX_M1.X0010", 10);

static_cast<void>(_);

const std::size_t report_step = 12;

const auto& group = sched.getGroup("TEST", report_step);
const auto& rst_group = restart_sched.getGroup("TEST", report_step);

// The GCONINJE which connects a UDA with the water injection control
// in group TEST is evaluated in an ACTIONX statement, i.e. it has not
// been initialized in the normal deck.
BOOST_CHECK_NO_THROW( rst_group.injectionProperties(Phase::WATER) );
BOOST_CHECK_THROW( group.injectionProperties(Phase::WATER), std::exception );
// The GCONINJE which connects a UDA with the water injection control in
// group TEST is evaluated in an ACTIONX statement, i.e. it has not been
// initialized in the normal deck.
BOOST_CHECK_NO_THROW(rst_group.injectionProperties(Phase::WATER));
BOOST_CHECK_THROW(group.injectionProperties(Phase::WATER), std::exception);
}

BOOST_AUTO_TEST_CASE(LoadWLISTRestartSim) {
const auto& [sched, restart_sched, _] = load_schedule_pair("ACTIONX_M1.DATA", "ACTIONX_M1_RESTART.DATA", "ACTIONX_M1.X0010", 10);
(void)_;
std::size_t report_step = 12;
BOOST_AUTO_TEST_CASE(LoadWLISTRestartSim)
{
const auto& [sched, restart_sched, _] =
load_schedule_pair("ACTIONX_M1.DATA", "ACTIONX_M1_RESTART.DATA", "ACTIONX_M1.X0010", 10);

static_cast<void>(_);

const std::size_t report_step = 12;

const auto& wlm = sched[report_step].wlist_manager();
const auto& rst_wlm = restart_sched[report_step].wlist_manager();

BOOST_CHECK(wlm == rst_wlm);
}


BOOST_AUTO_TEST_CASE(TestFileDeck)
{
Parser parser;
auto python = std::make_shared<Python>();
auto deck = parser.parseFile("UDQ_WCONPROD.DATA");
const auto deck = Parser{}.parseFile("UDQ_WCONPROD.DATA");
FileDeck fd(deck);

{
Expand All @@ -267,11 +293,11 @@ BOOST_AUTO_TEST_CASE(TestFileDeck)

{
auto index = fd.stop();
for (std::size_t deck_index = deck.size(); deck_index > 0; deck_index--)
for (std::size_t deck_index = deck.size(); deck_index > 0; --deck_index) {
BOOST_CHECK(deck[deck_index - 1] == fd[--index]);
}
}


const auto& index1 = fd.find("RADIAL");
BOOST_CHECK( !index1.has_value() );
BOOST_CHECK_EQUAL( fd.count("RADIAL"), 0);
Expand Down Expand Up @@ -314,9 +340,7 @@ BOOST_AUTO_TEST_CASE(TestFileDeck)

BOOST_AUTO_TEST_CASE(RestartTest2)
{
Parser parser;
auto python = std::make_shared<Python>();
auto deck = parser.parseFile("UDQ_WCONPROD.DATA");
const auto deck = Parser{}.parseFile("UDQ_WCONPROD.DATA");
FileDeck fd(deck);

fd.rst_solution("RESTART", 6);
Expand All @@ -336,28 +360,24 @@ BOOST_AUTO_TEST_CASE(RestartTest2)

BOOST_AUTO_TEST_CASE(RestartTest23)
{
Parser parser;
auto python = std::make_shared<Python>();
auto deck = parser.parseFile("UDQ_WCONPROD.DATA");
const auto deck = Parser{}.parseFile("UDQ_WCONPROD.DATA");
FileDeck fd(deck);

fd.skip(7);
BOOST_CHECK_EQUAL(fd.count("DATES"), 1);
BOOST_CHECK(fd.find("SCHEDULE").has_value());

auto dates_index = fd.find("DATES");
const auto dates_index = fd.find("DATES");
BOOST_CHECK(dates_index.has_value());
auto kw = fd[dates_index.value()];
auto rec0 = kw[0];
const auto kw = fd[dates_index.value()];
const auto rec0 = kw[0];
BOOST_CHECK_EQUAL( rec0.getItem<ParserKeywords::DATES::MONTH>().get<std::string>(0), "APR");
BOOST_CHECK_EQUAL( kw.size() , 5);
}

BOOST_AUTO_TEST_CASE(RestartTest24)
{
Parser parser;
auto python = std::make_shared<Python>();
auto deck = parser.parseFile("UDQ_WCONPROD.DATA");
const auto deck = Parser{}.parseFile("UDQ_WCONPROD.DATA");
FileDeck fd(deck);

fd.skip(4);
Expand All @@ -367,9 +387,8 @@ BOOST_AUTO_TEST_CASE(RestartTest24)

BOOST_AUTO_TEST_CASE(RestartTest)
{
Parser parser;
auto python = std::make_shared<Python>();
auto deck = parser.parseFile("UDQ_WCONPROD.DATA");
auto parser = Parser{};
const auto deck = parser.parseFile("UDQ_WCONPROD.DATA");
FileDeck fd(deck);

const auto solution = fd.find("SOLUTION");
Expand All @@ -378,15 +397,17 @@ BOOST_AUTO_TEST_CASE(RestartTest)
auto index = solution.value();
while (true) {
const auto& keyword = fd[++index];
if (keyword.name() == "EQUIL")
if (keyword.name() == "EQUIL") {
fd.erase(index);
}

if (index == schedule)
if (index == schedule) {
break;
}
}

UnitSystem units;
std::vector<DeckValue> values{ DeckValue{"RESTART_BASE"}, DeckValue{100} };
const std::vector<DeckValue> values{ DeckValue{"RESTART_BASE"}, DeckValue{100} };
DeckKeyword restart(parser.getKeyword("RESTART"), std::vector<std::vector<DeckValue>>{ values }, units, units);

index = solution.value();
Expand Down Expand Up @@ -414,7 +435,4 @@ BOOST_AUTO_TEST_CASE(RestartTest)
// return date == tp;
// }
// };



}
Loading