Files
opm-simulators/tests/test_rftcontainer.cpp
T
Santiago Ospina De Los Ríos fe37175c99 Clean up compiler warnings
* Remove unused parameters
* Declare equality operator of AdaptiveTimeStepping to be const
* Remove warning on lambda captures.
2025-11-27 14:00:07 +01:00

2071 lines
69 KiB
C++

/*
Copyright 2025 Equinor AS
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 <config.h>
#define BOOST_TEST_MODULE Test_RFTContainer_Parallel
#define BOOST_TEST_NO_MAIN
#ifndef HAVE_MPI
// Suppress GCC diagnostics of the form
//
// warning: "HAVE_MPI" is not defined, evaluates to 0
//
// when compiling with "-Wundef".
#define HAVE_MPI 0
#endif // HAVE_MPI
#include <boost/test/unit_test.hpp>
#include <opm/simulators/flow/RFTContainer.hpp>
#include <opm/simulators/utils/ParallelCommunication.hpp>
#include <opm/material/fluidsystems/BlackOilDefaultFluidSystemIndices.hpp>
#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <array>
#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
namespace {
#if HAVE_MPI
struct MPIError
{
MPIError(std::string_view errstr, const int ec)
: errorstring { errstr }
, errorcode { ec }
{}
std::string errorstring;
int errorcode;
};
void MPI_err_handler(MPI_Comm*, int* err_code, ...)
{
std::array<char, MPI_MAX_ERROR_STRING> err_string_vec{'\0'};
auto err_length = 0;
MPI_Error_string(*err_code, err_string_vec.data(), &err_length);
auto err_string = std::string_view {
err_string_vec.data(),
static_cast<std::string_view::size_type>(err_length)
};
std::cerr << "An MPI Error ocurred:\n -> " << err_string << '\n';
throw MPIError { err_string, *err_code };
}
// Register a throwing error handler to allow for debugging with
//
// catch throw
//
// in GDB.
void register_error_handler()
{
MPI_Errhandler handler{};
MPI_Comm_create_errhandler(MPI_err_handler, &handler);
MPI_Comm_set_errhandler(MPI_COMM_WORLD, handler);
}
#else // !HAVE_MPI
void register_error_handler()
{}
#endif // HAVE_MPI
class NProc_Is
{
public:
explicit NProc_Is(const int expectNP)
: expectNP_ { expectNP }
{}
boost::test_tools::assertion_result
operator()(boost::unit_test::test_unit_id) const
{
auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
if (comm.size() == this->expectNP_) {
return true;
}
boost::test_tools::assertion_result response(false);
response.message() << "Number of MPI processes ("
<< comm.size()
<< ") differs from expected "
<< this->expectNP_;
return response;
}
private:
int expectNP_{};
};
bool init_unit_test_func()
{
return true;
}
using TestFluidSystem = Opm::BlackOilFluidSystem
<double, Opm::BlackOilDefaultFluidSystemIndices>;
using RFTContainer = Opm::RFTContainer<TestFluidSystem>;
struct Case
{
explicit Case(const std::string& spec)
: Case { Opm::Parser{}.parseString(spec) }
{}
explicit Case(const Opm::Deck& deck)
: es { deck }
, sched { deck, es, std::make_shared<Opm::Python>() }
{}
Opm::EclipseState es{};
Opm::Schedule sched{};
};
Case singleCentreWell()
{
return Case { R"(RUNSPEC
DIMENS
3 3 3 /
START
3 SEP 2025 /
TABDIMS
/
OIL
GAS
WATER
GRID
DXV
3*100 /
DYV
3*100 /
DZV
3*5 /
DEPTHZ
16*2000 /
EQUALS
PERMX 100 /
PERMY 100 /
PERMZ 10 /
PORO 0.3 /
/
PROPS
DENSITY
800 1000 0.5 /
SCHEDULE
WELSPECS
R G 2 2 1* OIL /
/
COMPDAT
R 1* 1* 1 3 OPEN /
/
WCONPROD
R SHUT ORAT 0.0 /
/
WRFTPLT
R 'YES' /
/
DATES
10 SEP 2025 /
20 SEP 2025 /
30 SEP 2025 /
/
END
)" };
}
Case quarterFiveSpot()
{
return Case { R"(RUNSPEC
DIMENS
3 3 3 /
START
3 SEP 2025 /
TABDIMS
/
OIL
GAS
WATER
GRID
DXV
3*100 /
DYV
3*100 /
DZV
3*5 /
DEPTHZ
16*2000 /
EQUALS
PERMX 100 /
PERMY 100 /
PERMZ 10 /
PORO 0.3 /
/
PROPS
DENSITY
800 1000 0.5 /
SCHEDULE
WELSPECS
R1 G 1 1 1* OIL /
R2 G 3 3 1* OIL /
/
COMPDAT
R* 1* 1* 1 3 OPEN /
/
WCONPROD
R* SHUT ORAT 0.0 /
/
WRFTPLT
R* 'YES' /
/
DATES
10 SEP 2025 /
20 SEP 2025 /
30 SEP 2025 /
/
END
)" };
}
} // Anonymous namespace
BOOST_AUTO_TEST_SUITE(Single_Rank)
BOOST_AUTO_TEST_CASE(Single_Well)
{
const auto cse = singleCentreWell();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string&) { return r == 0; },
[r = comm.rank()](const std::string&) { return r == 0; }
};
rftc.allocate(0);
// IJK = (2,2,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (2,2,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (2,2,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
if (comm.rank() != 0) {
return;
}
const auto rPos = xw.find("R");
BOOST_REQUIRE_MESSAGE(rPos != xw.end(),
R"(There must be dynamic results for well "R")");
BOOST_CHECK_EQUAL(rPos->second.connections.size(), std::size_t{3});
// (2,2,1)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (2,2,2)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (2,2,3)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string&) { return r == 0; },
[r = comm.rank()](const std::string&) { return r == 0; }
};
rftc.allocate(0);
// --------------------------------------------------------------------
// IJK = (1,1,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (1,1,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (1,1,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
// --------------------------------------------------------------------
// IJK = (3,3,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
// IJK = (3,3,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
// IJK = (3,3,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
if (comm.rank() != 0) {
return;
}
// --------------------------------------------------------------------
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
// --------------------------------------------------------------------
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
BOOST_AUTO_TEST_SUITE_END()
// ===========================================================================
BOOST_AUTO_TEST_SUITE(NProc_2, * boost::unit_test::precondition(NProc_Is{2}))
BOOST_AUTO_TEST_CASE(Single_Split_Well)
{
const auto cse = singleCentreWell();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string&) { return r == 0; },
[](const std::string&) { return true; }
};
rftc.allocate(0);
if (comm.rank() == 0) {
// IJK = (2,2,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
}
else {
// IJK = (2,2,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (2,2,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
if (comm.rank() != 0) {
return;
}
const auto rPos = xw.find("R");
BOOST_REQUIRE_MESSAGE(rPos != xw.end(),
R"(There must be dynamic results for well "R")");
BOOST_CHECK_EQUAL(rPos->second.connections.size(), std::size_t{3});
// (2,2,1)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (2,2,2)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (2,2,3)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Non_Split_Wells)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 0) && (wname == "R2"))
|| ((r == 1) && (wname == "R1"));
},
[r = comm.rank()](const std::string& wname) {
return ((r == 0) && (wname == "R2"))
|| ((r == 1) && (wname == "R1"));
}
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (1,1,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (1,1,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (1,1,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
// --------------------------------------------------------------------
if (comm.rank() == 0) {
// IJK = (3,3,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
// IJK = (3,3,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
// IJK = (3,3,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 1) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 0) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Split_Wells)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// Rank 0 owns R2, rank 1 ownes R1. Both wells intersected on both
// ranks.
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 0) && (wname == "R2"))
|| ((r == 1) && (wname == "R1"));
},
[](const std::string&) { return true; }
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (1,1,1) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (3,3,1) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
// IJK = (3,3,2) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
}
// --------------------------------------------------------------------
if (comm.rank() == 0) {
// IJK = (1,1,2) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (1,1,3) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
// IJK = (3,3,3) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 1) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 0) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_SUITE_END() // NProc_2
// ===========================================================================
BOOST_AUTO_TEST_SUITE(NProc_3, * boost::unit_test::precondition(NProc_Is{3}))
BOOST_AUTO_TEST_CASE(Single_Split_Well)
{
const auto cse = singleCentreWell();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// Well owned by rank 2, but intersected on all ranks.
constexpr int owner = 2;
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string&) { return r == owner; },
[](const std::string&) { return true; }
};
rftc.allocate(0);
if (comm.rank() == 0) {
// IJK = (2,2,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
}
else if (comm.rank() == 1) {
// IJK = (2,2,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
}
else {
// IJK = (2,2,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
if (comm.rank() != owner) {
return;
}
const auto rPos = xw.find("R");
BOOST_REQUIRE_MESSAGE(rPos != xw.end(),
R"(There must be dynamic results for well "R")");
BOOST_CHECK_EQUAL(rPos->second.connections.size(), std::size_t{3});
// (2,2,1)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (2,2,2)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (2,2,3)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Owned_And_Split)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// R1 is owned by rank 2 and intersected on rank 2. R2 is owned by rank
// 1 and intersected on ranks 0 and 1.
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 2) && (wname == "R1"))
|| ((r == 1) && (wname == "R2"));
},
[r = comm.rank()](const std::string& wname) {
return (((r == 0) || (r == 1)) && (wname == "R2"))
|| ((r == 2) && (wname == "R1"));
}
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
// IJK = (1,1,1) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (1,1,2) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (1,1,3) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (3,3,1) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
// IJK = (3,3,2) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
}
if (comm.rank() == 0) {
// IJK = (3,3,3) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Split_Wells)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// R1 is owned by rank 2. R2 is owned by rank 1. Both wells
// intersected on all ranks.
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 2) && (wname == "R1"))
|| ((r == 1) && (wname == "R2"));
},
[](const std::string&) { return true; }
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
// IJK = (1,1,1) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (3,3,1) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (3,3,3) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
// IJK = (1,1,3) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
if (comm.rank() == 0) {
// IJK = (1,1,2) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (3,3,2) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_SUITE_END() // NProc_3
// ===========================================================================
BOOST_AUTO_TEST_SUITE(NProc_4, * boost::unit_test::precondition(NProc_Is{4}))
BOOST_AUTO_TEST_CASE(Single_Split_Well)
{
const auto cse = singleCentreWell();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// Well owned by rank 2, but intersected on ranks 0, 1, and 3. Does
// typically not happen in a real simulator run...
constexpr int owner = 2;
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string&) { return r == owner; },
[r = comm.rank()](const std::string&) { return r != owner; }
};
rftc.allocate(0);
if (comm.rank() == 0) {
// IJK = (2,2,1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
}
else if (comm.rank() == 1) {
// IJK = (2,2,2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
}
else if (comm.rank() == 3) {
// IJK = (2,2,3)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(1, 1, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
if (comm.rank() != owner) {
return;
}
const auto rPos = xw.find("R");
BOOST_REQUIRE_MESSAGE(rPos != xw.end(),
R"(There must be dynamic results for well "R")");
BOOST_CHECK_EQUAL(rPos->second.connections.size(), std::size_t{3});
// (2,2,1)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (2,2,2)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (2,2,3)
{
const auto* xc = rPos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(1, 1, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R" must have dynamic results in connection (2,2,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Owned_And_Split)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// R1 is owned by rank 2 and intersected on rank 2. R2 is owned by rank
// 3 and intersected on ranks 0, 1, and 3.
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 2) && (wname == "R1"))
|| ((r == 3) && (wname == "R2"));
},
[r = comm.rank()](const std::string& wname) {
return (((r == 0) || (r == 1) || (r == 3)) && (wname == "R2"))
|| ((r == 2) && (wname == "R1"));
}
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
// IJK = (1,1,1) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (1,1,2) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
// IJK = (1,1,3) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (3,3,1) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
}
if (comm.rank() == 3) {
// IJK = (3,3,2) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
}
if (comm.rank() == 0) {
// IJK = (3,3,3) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 3) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Split_Wells_Even_Odd)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// R1 is owned by rank 2 and intersected on ranks 0 and 2. R2 is owned
// by rank 1 and intersected on ranks 1 and 3.
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 2) && (wname == "R1"))
|| ((r == 1) && (wname == "R2"));
},
[r = comm.rank()](const std::string& wname) {
return ((r % 2 == 0) && (wname == "R1"))
|| ((r % 2 == 1) && (wname == "R2"));
}
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 0) {
// IJK = (1,1,3) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
if (comm.rank() == 2) {
// IJK = (1,1,1) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (1,1,2) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (3,3,3) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
}
if (comm.rank() == 3) {
// IJK = (3,3,2) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
// IJK = (3,3,1) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_CASE(Quarter_Five_Spot_Split_Wells_Cross)
{
const auto cse = quarterFiveSpot();
const auto comm = Opm::Parallel::Communication {
Dune::MPIHelper::getCommunicator()
};
// R1 is owned by rank 2 and intersected on ranks 1 and 2. R2 is owned
// by rank 0 and intersected on ranks 0, 2 and 3.
auto rftc = RFTContainer {
cse.es, cse.sched,
[r = comm.rank()](const std::string& wname) {
return ((r == 2) && (wname == "R1"))
|| ((r == 0) && (wname == "R2"));
},
[r = comm.rank()](const std::string& wname) {
return (((r == 1) || (r == 2)) && (wname == "R1"))
|| ((r != 1) && (wname == "R2"));
}
};
rftc.allocate(0);
// --------------------------------------------------------------------
if (comm.rank() == 0) {
// IJK = (3,3,3) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 2),
/* Po = */ []() { return 199; },
/* Sw = */ []() { return 0.42; },
/* Sg = */ []() { return 0.07; });
}
if (comm.rank() == 2) {
// IJK = (1,1,1) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 0),
/* Po = */ []() { return 100; },
/* Sw = */ []() { return 0.01; },
/* Sg = */ []() { return 0.8; });
// IJK = (3,3,2) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 1),
/* Po = */ []() { return 152; },
/* Sw = */ []() { return 0.12; },
/* Sg = */ []() { return 0.48; });
// IJK = (1,1,2) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 1),
/* Po = */ []() { return 150; },
/* Sw = */ []() { return 0.1; },
/* Sg = */ []() { return 0.5; });
}
// --------------------------------------------------------------------
if (comm.rank() == 1) {
// IJK = (1,1,3) (R1)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(0, 0, 2),
/* Po = */ []() { return 215; },
/* Sw = */ []() { return 0.4; },
/* Sg = */ []() { return 0.1; });
}
if (comm.rank() == 3) {
// IJK = (3,3,1) (R2)
rftc.assign(cse.es.getInputGrid().getGlobalIndex(2, 2, 0),
/* Po = */ []() { return 123; },
/* Sw = */ []() { return 0.02; },
/* Sg = */ []() { return 0.63; });
}
// --------------------------------------------------------------------
auto xw = Opm::data::Wells{};
rftc.addToWells(xw, 0, comm);
// --------------------------------------------------------------------
if (comm.rank() == 2) {
const auto r1Pos = xw.find("R1");
BOOST_REQUIRE_MESSAGE(r1Pos != xw.end(),
R"(There must be dynamic results for well "R1")");
BOOST_CHECK_EQUAL(r1Pos->second.connections.size(), std::size_t{3});
// (1,1,1)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 100.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.01, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.8 , 1.0e-8);
}
// (1,1,2)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 150.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.1, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.5, 1.0e-8);
}
// (1,1,3)
{
const auto* xc = r1Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(0, 0, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R1" must have dynamic results in connection (1,1,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 215.0, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.4, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.1, 1.0e-8);
}
}
// --------------------------------------------------------------------
if (comm.rank() == 0) {
const auto r2Pos = xw.find("R2");
BOOST_REQUIRE_MESSAGE(r2Pos != xw.end(),
R"(There must be dynamic results for well "R2")");
BOOST_CHECK_EQUAL(r2Pos->second.connections.size(), std::size_t{3});
// (3,3,1)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 0));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,1))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 123.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.02, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.63, 1.0e-8);
}
// (3,3,2)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 1));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,2))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 152.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.12, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.48, 1.0e-8);
}
// (3,3,3)
{
const auto* xc = r2Pos->second.find_connection
(cse.es.getInputGrid().getGlobalIndex(2, 2, 2));
BOOST_REQUIRE_MESSAGE(xc != nullptr,
R"(Well "R2" must have dynamic results in connection (3,3,3))");
BOOST_CHECK_CLOSE(xc->cell_pressure , 199.0 , 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_water, 0.42, 1.0e-8);
BOOST_CHECK_CLOSE(xc->cell_saturation_gas , 0.07, 1.0e-8);
}
}
}
BOOST_AUTO_TEST_SUITE_END() // NProc_4
// ===========================================================================
int main(int argc, char** argv)
{
Dune::MPIHelper::instance(argc, argv);
register_error_handler();
// Just enough initialisation for a working TestFluidSystem::phaseIsActive().
//
// This is a **massive** hack.
TestFluidSystem::initBegin(1);
return boost::unit_test::unit_test_main(&init_unit_test_func, argc, argv);
}