Add Restart File Output Support for Constant Flux Aquifers
We support constant flux aquifers (AQUFLUX keyword) entered both in the SOLUTION and in the SCHEDULE sections. The primary structural change is that we have to support analytic aquifers being introduced dynamically, whence the connection information (xCAQ) must be captured without knowing the full set of analytic aquifers. We therefore allocate those output arrays purely from the maximum sizes entered in the RUNSPEC section whereas we defer determining the maximum aquifer ID to the point of capturing the dynamic values. The xAAQ values for constant flux aquifers amount to a new aquifer type integer value (=2) in IAAQ[11] and the flux value in SAAQ[0].
This commit is contained in:
parent
53a7c2343a
commit
0adcc7dd07
@ -35,12 +35,13 @@ namespace Opm::RestartIO {
|
|||||||
} // Opm::RestartIO
|
} // Opm::RestartIO
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
struct SingleAquiferFlux {
|
struct SingleAquiferFlux
|
||||||
|
{
|
||||||
|
SingleAquiferFlux() = default;
|
||||||
explicit SingleAquiferFlux(const DeckRecord& record);
|
explicit SingleAquiferFlux(const DeckRecord& record);
|
||||||
|
|
||||||
// using id to create an inactive dummy aquifer
|
// using id to create an inactive dummy aquifer
|
||||||
explicit SingleAquiferFlux(int id);
|
explicit SingleAquiferFlux(int id);
|
||||||
SingleAquiferFlux() = default;
|
|
||||||
SingleAquiferFlux(int id, double flux, double sal, bool active_, double temp, double pres);
|
SingleAquiferFlux(int id, double flux, double sal, bool active_, double temp, double pres);
|
||||||
|
|
||||||
int id {0};
|
int id {0};
|
||||||
@ -52,7 +53,7 @@ namespace Opm {
|
|||||||
|
|
||||||
bool operator==(const SingleAquiferFlux& other) const;
|
bool operator==(const SingleAquiferFlux& other) const;
|
||||||
|
|
||||||
template<class Serializer>
|
template <class Serializer>
|
||||||
void serializeOp(Serializer& serializer)
|
void serializeOp(Serializer& serializer)
|
||||||
{
|
{
|
||||||
serializer(this->id);
|
serializer(this->id);
|
||||||
@ -66,12 +67,16 @@ namespace Opm {
|
|||||||
static SingleAquiferFlux serializationTestObject();
|
static SingleAquiferFlux serializationTestObject();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AquiferFlux {
|
class AquiferFlux
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
using AquFluxs = std::unordered_map<int, SingleAquiferFlux>;
|
using AquFluxs = std::unordered_map<int, SingleAquiferFlux>;
|
||||||
|
|
||||||
explicit AquiferFlux(const std::vector<const DeckKeyword*>& keywords);
|
|
||||||
AquiferFlux() = default;
|
AquiferFlux() = default;
|
||||||
|
explicit AquiferFlux(const std::vector<const DeckKeyword*>& keywords);
|
||||||
|
|
||||||
|
// Primarily for unit testing purposes.
|
||||||
|
explicit AquiferFlux(const std::vector<SingleAquiferFlux>& aquifers);
|
||||||
|
|
||||||
void appendAqufluxSchedule(const std::unordered_set<int>& ids);
|
void appendAqufluxSchedule(const std::unordered_set<int>& ids);
|
||||||
|
|
||||||
@ -86,15 +91,16 @@ namespace Opm {
|
|||||||
|
|
||||||
void loadFromRestart(const RestartIO::RstAquifer& rst);
|
void loadFromRestart(const RestartIO::RstAquifer& rst);
|
||||||
|
|
||||||
template<class Serializer>
|
template <class Serializer>
|
||||||
void serializeOp(Serializer& serializer) {
|
void serializeOp(Serializer& serializer)
|
||||||
|
{
|
||||||
serializer(this->m_aquifers);
|
serializer(this->m_aquifers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AquiferFlux serializationTestObject();
|
static AquiferFlux serializationTestObject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AquFluxs m_aquifers;
|
AquFluxs m_aquifers{};
|
||||||
};
|
};
|
||||||
} // end of namespace Opm
|
} // end of namespace Opm
|
||||||
|
|
||||||
|
@ -349,6 +349,11 @@ namespace Opm {
|
|||||||
|
|
||||||
bool has_gpmaint() const;
|
bool has_gpmaint() const;
|
||||||
|
|
||||||
|
bool hasAnalyticalAquifers() const
|
||||||
|
{
|
||||||
|
return ! this->aqufluxs.empty();
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
ptr_member<GConSale> gconsale;
|
ptr_member<GConSale> gconsale;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
namespace Opm {
|
namespace Opm {
|
||||||
class AquiferConfig;
|
class AquiferConfig;
|
||||||
class EclipseGrid;
|
class EclipseGrid;
|
||||||
|
class ScheduleState;
|
||||||
class SummaryState;
|
class SummaryState;
|
||||||
class UnitSystem;
|
class UnitSystem;
|
||||||
} // Opm
|
} // Opm
|
||||||
@ -60,11 +61,19 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
|||||||
/// Linearise dynamic information pertinent to analytic aquifers
|
/// Linearise dynamic information pertinent to analytic aquifers
|
||||||
/// into internal arrays.
|
/// into internal arrays.
|
||||||
///
|
///
|
||||||
|
/// \param[in] aqDims Aquifer dimensions including number of active
|
||||||
|
/// aquifers, maximum aquifer IDs, and number of data items per
|
||||||
|
/// aquifer (or connection) in the various output arrays.
|
||||||
|
///
|
||||||
/// \param[in] aqConfig Aquifer configuration object. Keeps track
|
/// \param[in] aqConfig Aquifer configuration object. Keeps track
|
||||||
/// of aquifer types (Carter-Tracy, Fetkovich, constant flux &c)
|
/// of aquifer types (Carter-Tracy, Fetkovich, constant flux &c)
|
||||||
/// and provides read-only access to the individual aquifer
|
/// and provides read-only access to the individual aquifer
|
||||||
/// objects.
|
/// objects.
|
||||||
///
|
///
|
||||||
|
/// \param[in] sched Schedule state at particular report step.
|
||||||
|
/// Keeps track of dynamically defined analytic aquifers, e.g.,
|
||||||
|
/// the constant flux aquifers entered in the SCHEDULE section.
|
||||||
|
///
|
||||||
/// \param[in] aquData Dynamic aquifer data, including time
|
/// \param[in] aquData Dynamic aquifer data, including time
|
||||||
/// constants, water mass densities, water viscosities, and
|
/// constants, water mass densities, water viscosities, and
|
||||||
/// initial aquifer pressures.
|
/// initial aquifer pressures.
|
||||||
@ -76,10 +85,12 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
|||||||
///
|
///
|
||||||
/// \param[in] usys Unit system. Needed to convert quantities from
|
/// \param[in] usys Unit system. Needed to convert quantities from
|
||||||
/// internal to output units.
|
/// internal to output units.
|
||||||
void captureDynamicdAquiferData(const AquiferConfig& aqConfig,
|
void captureDynamicAquiferData(const InteHEAD::AquiferDims& aqDims,
|
||||||
const data::Aquifers& aquData,
|
const AquiferConfig& aqConfig,
|
||||||
const SummaryState& summaryState,
|
const ScheduleState& sched,
|
||||||
const UnitSystem& usys);
|
const data::Aquifers& aquData,
|
||||||
|
const SummaryState& summaryState,
|
||||||
|
const UnitSystem& usys);
|
||||||
|
|
||||||
/// Retrieve the maximum active aquifer ID over all analytic
|
/// Retrieve the maximum active aquifer ID over all analytic
|
||||||
/// aquifers.
|
/// aquifers.
|
||||||
@ -187,11 +198,18 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
|||||||
/// connections. Separate array for each aquifer.
|
/// connections. Separate array for each aquifer.
|
||||||
std::vector<WindowedArray<double>> doubleprecAnalyticAquiferConn_;
|
std::vector<WindowedArray<double>> doubleprecAnalyticAquiferConn_;
|
||||||
|
|
||||||
|
void allocateDynamicBackingStorage(const InteHEAD::AquiferDims& aqDims);
|
||||||
|
|
||||||
void handleCarterTracy(const AquiferConfig& aqConfig,
|
void handleCarterTracy(const AquiferConfig& aqConfig,
|
||||||
const data::Aquifers& aquData,
|
const data::Aquifers& aquData,
|
||||||
const SummaryState& summaryState,
|
const SummaryState& summaryState,
|
||||||
const UnitSystem& usys);
|
const UnitSystem& usys);
|
||||||
|
|
||||||
|
void handleConstantFlux(const AquiferConfig& aqConfig,
|
||||||
|
const ScheduleState& sched,
|
||||||
|
const SummaryState& summaryState,
|
||||||
|
const UnitSystem& usys);
|
||||||
|
|
||||||
void handleFetkovich(const AquiferConfig& aqConfig,
|
void handleFetkovich(const AquiferConfig& aqConfig,
|
||||||
const data::Aquifers& aquData,
|
const data::Aquifers& aquData,
|
||||||
const SummaryState& summaryState,
|
const SummaryState& summaryState,
|
||||||
|
@ -30,8 +30,10 @@ namespace Opm {
|
|||||||
|
|
||||||
class EclipseGrid;
|
class EclipseGrid;
|
||||||
class EclipseState;
|
class EclipseState;
|
||||||
class UnitSystem;
|
|
||||||
class Phases;
|
class Phases;
|
||||||
|
class ScheduleState;
|
||||||
|
class UnitSystem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Opm { namespace RestartIO {
|
namespace Opm { namespace RestartIO {
|
||||||
@ -164,7 +166,7 @@ namespace Opm { namespace RestartIO {
|
|||||||
// Maximum aquifer ID across all of the model's analytic aquifers.
|
// Maximum aquifer ID across all of the model's analytic aquifers.
|
||||||
int maxAquiferID {0};
|
int maxAquiferID {0};
|
||||||
|
|
||||||
// Number of numeric aquifer records (lines of AQUNUM data)
|
// Number of numeric aquifer records (lines of AQUNUM data, AQUDIMS(1))
|
||||||
int numNumericAquiferRecords {0};
|
int numNumericAquiferRecords {0};
|
||||||
|
|
||||||
// Number of data elements per aquifer in IAAQ array.
|
// Number of data elements per aquifer in IAAQ array.
|
||||||
@ -250,6 +252,10 @@ namespace Opm { namespace RestartIO {
|
|||||||
|
|
||||||
InteHEAD::AquiferDims
|
InteHEAD::AquiferDims
|
||||||
inferAquiferDimensions(const EclipseState& es);
|
inferAquiferDimensions(const EclipseState& es);
|
||||||
|
|
||||||
|
InteHEAD::AquiferDims
|
||||||
|
inferAquiferDimensions(const EclipseState& es,
|
||||||
|
const ScheduleState& sched);
|
||||||
}} // Opm::RestartIO
|
}} // Opm::RestartIO
|
||||||
|
|
||||||
#endif // OPM_INTEHEAD_HEADER_INCLUDED
|
#endif // OPM_INTEHEAD_HEADER_INCLUDED
|
||||||
|
@ -31,7 +31,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
|||||||
WatPropTable = 1, // PVT number (ACUCT(10) or AQUFETP(7))
|
WatPropTable = 1, // PVT number (ACUCT(10) or AQUFETP(7))
|
||||||
|
|
||||||
CTInfluenceFunction = 9, // AQUCT(11)
|
CTInfluenceFunction = 9, // AQUCT(11)
|
||||||
TypeRelated1 = 10, // =1 for CT, =0 for FETP
|
TypeRelated1 = 10, // =0 for FETP, =1 for CT, =2 for FLUX
|
||||||
|
|
||||||
Unknown_1 = 11, // Unknown item. =1 in all cases seen thus far.
|
Unknown_1 = 11, // Unknown item. =1 in all cases seen thus far.
|
||||||
};
|
};
|
||||||
@ -40,6 +40,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
|||||||
enum ModelType : int {
|
enum ModelType : int {
|
||||||
Fetkovich = 0,
|
Fetkovich = 0,
|
||||||
CarterTracy = 1,
|
CarterTracy = 1,
|
||||||
|
ConstantFlux = 2,
|
||||||
};
|
};
|
||||||
} // Value
|
} // Value
|
||||||
} // IAnalyticAquifer
|
} // IAnalyticAquifer
|
||||||
@ -96,6 +97,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
|||||||
enum index : std::vector<float>::size_type {
|
enum index : std::vector<float>::size_type {
|
||||||
Compressibility = 0, // Total aquifer compressibility (AQUCT(6), AQUFETP(5))
|
Compressibility = 0, // Total aquifer compressibility (AQUCT(6), AQUFETP(5))
|
||||||
|
|
||||||
|
ConstFluxValue = 0, // Constant flux aquifer's flux value (AQUFLUX(2))
|
||||||
|
|
||||||
FetInitVol = 1, // Initial aquifer volume (AQUFETP(4))
|
FetInitVol = 1, // Initial aquifer volume (AQUFETP(4))
|
||||||
FetProdIndex = 2, // Aquifer productivity index (AQUFETP(6))
|
FetProdIndex = 2, // Aquifer productivity index (AQUFETP(6))
|
||||||
FetTimeConstant = 3, // Fetkovich Aquifer time constant (Compressibility * InitVol / ProdIndex)
|
FetTimeConstant = 3, // Fetkovich Aquifer time constant (Compressibility * InitVol / ProdIndex)
|
||||||
|
@ -88,6 +88,13 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AquiferFlux::AquiferFlux(const std::vector<SingleAquiferFlux>& aquifers)
|
||||||
|
{
|
||||||
|
for (const auto& aquifer : aquifers) {
|
||||||
|
this->m_aquifers.emplace(aquifer.id, aquifer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AquiferFlux::operator==(const AquiferFlux& other) const {
|
bool AquiferFlux::operator==(const AquiferFlux& other) const {
|
||||||
return this->m_aquifers == other.m_aquifers;
|
return this->m_aquifers == other.m_aquifers;
|
||||||
}
|
}
|
||||||
@ -118,4 +125,4 @@ namespace Opm {
|
|||||||
result.m_aquifers.insert({single_aquifer.id, single_aquifer});
|
result.m_aquifers.insert({single_aquifer.id, single_aquifer});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} // end of namespace Opm
|
} // end of namespace Opm
|
||||||
|
@ -28,10 +28,12 @@
|
|||||||
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferCT.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferCT.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/Aquifetp.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/Aquifetp.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Tables/FlatTable.hpp>
|
#include <opm/input/eclipse/EclipseState/Tables/FlatTable.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||||
|
|
||||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||||
@ -59,6 +61,11 @@ namespace {
|
|||||||
return summaryState.get(key, 0.0);
|
return summaryState.get(key, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t maxNumberOfAquifers(const Opm::RestartIO::InteHEAD::AquiferDims& aqDims)
|
||||||
|
{
|
||||||
|
return std::max(aqDims.maxNumAquifers, aqDims.numNumericAquiferRecords);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename AquiferCallBack>
|
template <typename AquiferCallBack>
|
||||||
void CarterTracyAquiferLoop(const Opm::AquiferConfig& aqConfig,
|
void CarterTracyAquiferLoop(const Opm::AquiferConfig& aqConfig,
|
||||||
AquiferCallBack&& aquiferOp)
|
AquiferCallBack&& aquiferOp)
|
||||||
@ -68,6 +75,27 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AquiferCallBack>
|
||||||
|
void ConstantFluxAquiferLoop(const Opm::AquiferConfig& aqConfig,
|
||||||
|
const Opm::ScheduleState& sched,
|
||||||
|
AquiferCallBack&& aquiferOp)
|
||||||
|
{
|
||||||
|
// Note: Loop 'aqConfig' before 'sched'. That way, dynamic settings
|
||||||
|
// in 'sched' will override the static settings in 'aqConfig'.
|
||||||
|
|
||||||
|
for (const auto& aquifer : aqConfig.aquflux()) {
|
||||||
|
if (aquifer.second.active) {
|
||||||
|
aquiferOp(aquifer.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& aquifer : sched.aqufluxs) {
|
||||||
|
if (aquifer.second.active) {
|
||||||
|
aquiferOp(aquifer.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename AquiferCallBack>
|
template <typename AquiferCallBack>
|
||||||
void FetkovichAquiferLoop(const Opm::AquiferConfig& aqConfig,
|
void FetkovichAquiferLoop(const Opm::AquiferConfig& aqConfig,
|
||||||
AquiferCallBack&& aquiferOp)
|
AquiferCallBack&& aquiferOp)
|
||||||
@ -100,10 +128,6 @@ namespace {
|
|||||||
ConnectionCallBack&& connectionOp)
|
ConnectionCallBack&& connectionOp)
|
||||||
{
|
{
|
||||||
for (const auto& [aquiferID, connections] : aqConfig.connections().data()) {
|
for (const auto& [aquiferID, connections] : aqConfig.connections().data()) {
|
||||||
if ( !aqConfig.hasAnalyticalAquifer(int(aquiferID)) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto tot_influx =
|
const auto tot_influx =
|
||||||
std::accumulate(connections.begin(), connections.end(), 0.0,
|
std::accumulate(connections.begin(), connections.end(), 0.0,
|
||||||
[](const double t, const Opm::Aquancon::AquancCell& connection) -> double
|
[](const double t, const Opm::Aquancon::AquancCell& connection) -> double
|
||||||
@ -163,6 +187,19 @@ namespace {
|
|||||||
}
|
}
|
||||||
} // CarterTracy
|
} // CarterTracy
|
||||||
|
|
||||||
|
namespace ConstantFlux
|
||||||
|
{
|
||||||
|
template <typename IAaqArray>
|
||||||
|
void staticContrib(const int numActiveConn, IAaqArray& iaaq)
|
||||||
|
{
|
||||||
|
namespace IAAQ = VI::IAnalyticAquifer;
|
||||||
|
|
||||||
|
Common::staticContrib(numActiveConn, iaaq);
|
||||||
|
|
||||||
|
iaaq[IAAQ::index::TypeRelated1] = IAAQ::Value::ModelType::ConstantFlux;
|
||||||
|
}
|
||||||
|
} // ConstantFlux
|
||||||
|
|
||||||
namespace Fetkovich
|
namespace Fetkovich
|
||||||
{
|
{
|
||||||
template <typename IAaqArray>
|
template <typename IAaqArray>
|
||||||
@ -218,7 +255,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
using WA = Opm::RestartIO::Helpers::WindowedArray<int>;
|
using WA = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||||
|
|
||||||
return std::vector<WA>(aqDims.maxAquiferID, WA {
|
return std::vector<WA>(maxNumberOfAquifers(aqDims), WA {
|
||||||
WA::NumWindows{ static_cast<WA::Idx>(aqDims.maxNumActiveAquiferConn) },
|
WA::NumWindows{ static_cast<WA::Idx>(aqDims.maxNumActiveAquiferConn) },
|
||||||
WA::WindowSize{ static_cast<WA::Idx>(aqDims.numIntConnElem) }
|
WA::WindowSize{ static_cast<WA::Idx>(aqDims.numIntConnElem) }
|
||||||
});
|
});
|
||||||
@ -317,6 +354,23 @@ namespace {
|
|||||||
}
|
}
|
||||||
} // CarterTracy
|
} // CarterTracy
|
||||||
|
|
||||||
|
namespace ConstantFlux {
|
||||||
|
template <typename SAaqArray>
|
||||||
|
void staticContrib(const Opm::SingleAquiferFlux& aquifer,
|
||||||
|
const Opm::UnitSystem& usys,
|
||||||
|
SAaqArray& saaq)
|
||||||
|
{
|
||||||
|
using M = Opm::UnitSystem::measure;
|
||||||
|
using Ix = VI::SAnalyticAquifer::index;
|
||||||
|
|
||||||
|
auto q = usys.from_si(M::liquid_surface_rate, aquifer.flux);
|
||||||
|
|
||||||
|
// Unit hack: *to_si()* here since we don't have an area unit.
|
||||||
|
saaq[Ix::ConstFluxValue] =
|
||||||
|
usys.to_si(M::length, usys.to_si(M::length, q));
|
||||||
|
}
|
||||||
|
} // ConstantFlux
|
||||||
|
|
||||||
namespace Fetkovich {
|
namespace Fetkovich {
|
||||||
template <typename SAaqArray>
|
template <typename SAaqArray>
|
||||||
void staticContrib(const Opm::Aquifetp::AQUFETP_data& aquifer,
|
void staticContrib(const Opm::Aquifetp::AQUFETP_data& aquifer,
|
||||||
@ -361,7 +415,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
using WA = Opm::RestartIO::Helpers::WindowedArray<float>;
|
using WA = Opm::RestartIO::Helpers::WindowedArray<float>;
|
||||||
|
|
||||||
return std::vector<WA>(aqDims.maxAquiferID, WA {
|
return std::vector<WA>(maxNumberOfAquifers(aqDims), WA {
|
||||||
WA::NumWindows{ static_cast<WA::Idx>(aqDims.maxNumActiveAquiferConn) },
|
WA::NumWindows{ static_cast<WA::Idx>(aqDims.maxNumActiveAquiferConn) },
|
||||||
WA::WindowSize{ static_cast<WA::Idx>(aqDims.numRealConnElem) }
|
WA::WindowSize{ static_cast<WA::Idx>(aqDims.numRealConnElem) }
|
||||||
});
|
});
|
||||||
@ -452,6 +506,18 @@ namespace {
|
|||||||
}
|
}
|
||||||
} // CarterTracy
|
} // CarterTracy
|
||||||
|
|
||||||
|
namespace ConstantFlux {
|
||||||
|
template <typename SummaryVariable, typename XAaqArray>
|
||||||
|
void dynamicContrib(SummaryVariable&& summaryVariable,
|
||||||
|
const double tot_influx,
|
||||||
|
const Opm::UnitSystem& usys,
|
||||||
|
XAaqArray& xaaq)
|
||||||
|
{
|
||||||
|
Common::dynamicContrib(std::forward<SummaryVariable>(summaryVariable),
|
||||||
|
tot_influx, usys, xaaq);
|
||||||
|
}
|
||||||
|
} // ConstantFlux
|
||||||
|
|
||||||
namespace Fetkovich {
|
namespace Fetkovich {
|
||||||
template <typename SummaryVariable, typename XAaqArray>
|
template <typename SummaryVariable, typename XAaqArray>
|
||||||
void dynamicContrib(SummaryVariable&& summaryVariable,
|
void dynamicContrib(SummaryVariable&& summaryVariable,
|
||||||
@ -525,7 +591,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
using WA = Opm::RestartIO::Helpers::WindowedArray<double>;
|
using WA = Opm::RestartIO::Helpers::WindowedArray<double>;
|
||||||
|
|
||||||
return std::vector<WA>(aqDims.maxAquiferID, WA {
|
return std::vector<WA>(maxNumberOfAquifers(aqDims), WA {
|
||||||
WA::NumWindows{ static_cast<WA::Idx>(aqDims.maxNumActiveAquiferConn) },
|
WA::NumWindows{ static_cast<WA::Idx>(aqDims.maxNumActiveAquiferConn) },
|
||||||
WA::WindowSize{ static_cast<WA::Idx>(aqDims.numDoubConnElem) }
|
WA::WindowSize{ static_cast<WA::Idx>(aqDims.numDoubConnElem) }
|
||||||
});
|
});
|
||||||
@ -538,8 +604,8 @@ AggregateAquiferData(const InteHEAD::AquiferDims& aqDims,
|
|||||||
const AquiferConfig& aqConfig,
|
const AquiferConfig& aqConfig,
|
||||||
const EclipseGrid& grid)
|
const EclipseGrid& grid)
|
||||||
: maxActiveAnalyticAquiferID_ { aqDims.maxAquiferID }
|
: maxActiveAnalyticAquiferID_ { aqDims.maxAquiferID }
|
||||||
, numActiveConn_ ( aqDims.maxAquiferID, 0 )
|
, numActiveConn_ ( maxNumberOfAquifers(aqDims), 0 )
|
||||||
, totalInflux_ ( aqDims.maxAquiferID, 0.0 )
|
, totalInflux_ ( maxNumberOfAquifers(aqDims), 0.0 )
|
||||||
, integerAnalyticAq_ { IntegerAnalyticAquifer:: allocate(aqDims) }
|
, integerAnalyticAq_ { IntegerAnalyticAquifer:: allocate(aqDims) }
|
||||||
, singleprecAnalyticAq_ { SinglePrecAnalyticAquifer:: allocate(aqDims) }
|
, singleprecAnalyticAq_ { SinglePrecAnalyticAquifer:: allocate(aqDims) }
|
||||||
, doubleprecAnalyticAq_ { DoublePrecAnalyticAquifer:: allocate(aqDims) }
|
, doubleprecAnalyticAq_ { DoublePrecAnalyticAquifer:: allocate(aqDims) }
|
||||||
@ -549,7 +615,7 @@ AggregateAquiferData(const InteHEAD::AquiferDims& aqDims,
|
|||||||
, singleprecAnalyticAquiferConn_{ SinglePrecAnalyticAquiferConn::allocate(aqDims) }
|
, singleprecAnalyticAquiferConn_{ SinglePrecAnalyticAquiferConn::allocate(aqDims) }
|
||||||
, doubleprecAnalyticAquiferConn_{ DoublePrecAnalyticAquiferConn::allocate(aqDims) }
|
, doubleprecAnalyticAquiferConn_{ DoublePrecAnalyticAquiferConn::allocate(aqDims) }
|
||||||
{
|
{
|
||||||
if (! aqConfig.hasAnalyticalAquifer()) {
|
if (! aqConfig.connections().active()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,20 +645,35 @@ AggregateAquiferData(const InteHEAD::AquiferDims& aqDims,
|
|||||||
|
|
||||||
void
|
void
|
||||||
Opm::RestartIO::Helpers::AggregateAquiferData::
|
Opm::RestartIO::Helpers::AggregateAquiferData::
|
||||||
captureDynamicdAquiferData(const AquiferConfig& aqConfig,
|
captureDynamicAquiferData(const InteHEAD::AquiferDims& aqDims,
|
||||||
const data::Aquifers& aquData,
|
const AquiferConfig& aqConfig,
|
||||||
const SummaryState& summaryState,
|
const ScheduleState& sched,
|
||||||
const UnitSystem& usys)
|
const data::Aquifers& aquData,
|
||||||
|
const SummaryState& summaryState,
|
||||||
|
const UnitSystem& usys)
|
||||||
{
|
{
|
||||||
|
if (! (aqConfig.active() || sched.hasAnalyticalAquifers())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->allocateDynamicBackingStorage(aqDims);
|
||||||
|
|
||||||
this->maxActiveAnalyticAquiferID_ = aqDims.maxAquiferID;
|
this->maxActiveAnalyticAquiferID_ = aqDims.maxAquiferID;
|
||||||
|
|
||||||
this->handleFetkovich(aqConfig, aquData, summaryState, usys);
|
this->handleFetkovich(aqConfig, aquData, summaryState, usys);
|
||||||
this->handleCarterTracy(aqConfig, aquData, summaryState, usys);
|
this->handleCarterTracy(aqConfig, aquData, summaryState, usys);
|
||||||
|
this->handleConstantFlux(aqConfig, sched, summaryState, usys);
|
||||||
this->handleNumeric(aqConfig, aquData, summaryState, usys);
|
this->handleNumeric(aqConfig, aquData, summaryState, usys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Opm::RestartIO::Helpers::AggregateAquiferData::
|
||||||
|
allocateDynamicBackingStorage(const InteHEAD::AquiferDims& aqDims)
|
||||||
|
{
|
||||||
|
this->integerAnalyticAq_ = IntegerAnalyticAquifer:: allocate(aqDims);
|
||||||
|
this->singleprecAnalyticAq_ = SinglePrecAnalyticAquifer::allocate(aqDims);
|
||||||
|
this->doubleprecAnalyticAq_ = DoublePrecAnalyticAquifer::allocate(aqDims);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Opm::RestartIO::Helpers::AggregateAquiferData::
|
Opm::RestartIO::Helpers::AggregateAquiferData::
|
||||||
@ -633,6 +714,36 @@ handleCarterTracy(const AquiferConfig& aqConfig,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Opm::RestartIO::Helpers::AggregateAquiferData::
|
||||||
|
handleConstantFlux(const AquiferConfig& aqConfig,
|
||||||
|
const ScheduleState& sched,
|
||||||
|
const SummaryState& summaryState,
|
||||||
|
const UnitSystem& usys)
|
||||||
|
{
|
||||||
|
ConstantFluxAquiferLoop(aqConfig, sched, [this, &usys, &summaryState]
|
||||||
|
(const SingleAquiferFlux& aquifer)
|
||||||
|
{
|
||||||
|
const auto aquIndex = static_cast<WindowedArray<int>::Idx>(aquifer.id - 1);
|
||||||
|
|
||||||
|
auto iaaq = this->integerAnalyticAq_[aquIndex];
|
||||||
|
const auto nActiveConn = this->numActiveConn_[aquIndex];
|
||||||
|
IntegerAnalyticAquifer::ConstantFlux::staticContrib(nActiveConn, iaaq);
|
||||||
|
|
||||||
|
auto saaq = this->singleprecAnalyticAq_[aquIndex];
|
||||||
|
SinglePrecAnalyticAquifer::ConstantFlux::staticContrib(aquifer, usys, saaq);
|
||||||
|
|
||||||
|
auto xaaq = this->doubleprecAnalyticAq_[aquIndex];
|
||||||
|
const auto tot_influx = this->totalInflux_[aquIndex];
|
||||||
|
auto sumVar = [&summaryState, &aquifer](const std::string& vector)
|
||||||
|
{
|
||||||
|
return getSummaryVariable(summaryState, vector, aquifer.id);
|
||||||
|
};
|
||||||
|
DoublePrecAnalyticAquifer::ConstantFlux::
|
||||||
|
dynamicContrib(sumVar, tot_influx, usys, xaaq);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Opm::RestartIO::Helpers::AggregateAquiferData::
|
Opm::RestartIO::Helpers::AggregateAquiferData::
|
||||||
handleFetkovich(const AquiferConfig& aqConfig,
|
handleFetkovich(const AquiferConfig& aqConfig,
|
||||||
|
@ -601,7 +601,7 @@ createInteHead(const EclipseState& es,
|
|||||||
.params_NWELZ (155 + num_water_tracer, 122 + 2*num_water_tracer, 130 + nxwelz_tracer_shift, 3) // n{isxz}welz: number of data elements per well in {ISXZ}WELL
|
.params_NWELZ (155 + num_water_tracer, 122 + 2*num_water_tracer, 130 + nxwelz_tracer_shift, 3) // n{isxz}welz: number of data elements per well in {ISXZ}WELL
|
||||||
.params_NCON (25, 41, 58 + 5*num_water_tracer) // n{isx}conz: number of data elements per completion in ICON
|
.params_NCON (25, 41, 58 + 5*num_water_tracer) // n{isx}conz: number of data elements per completion in ICON
|
||||||
.params_GRPZ (getNGRPZ(nwgmax, ngmax, num_water_tracer, rspec))
|
.params_GRPZ (getNGRPZ(nwgmax, ngmax, num_water_tracer, rspec))
|
||||||
.aquiferDimensions (inferAquiferDimensions(es))
|
.aquiferDimensions (inferAquiferDimensions(es, sched[lookup_step]))
|
||||||
.stepParam (num_solver_steps, report_step)
|
.stepParam (num_solver_steps, report_step)
|
||||||
.tuningParam (getTuningPars(sched[lookup_step].tuning()))
|
.tuningParam (getTuningPars(sched[lookup_step].tuning()))
|
||||||
.liftOptParam (getLiftOptPar(sched, report_step, lookup_step))
|
.liftOptParam (getLiftOptPar(sched, report_step, lookup_step))
|
||||||
|
@ -149,14 +149,12 @@ EclipseIO::Impl::Impl( const EclipseState& eclipseState,
|
|||||||
, summary( eclipseState, summaryConfig, grid , schedule, base_name, writeEsmry )
|
, summary( eclipseState, summaryConfig, grid , schedule, base_name, writeEsmry )
|
||||||
, output_enabled( eclipseState.getIOConfig().getOutputEnabled() )
|
, output_enabled( eclipseState.getIOConfig().getOutputEnabled() )
|
||||||
{
|
{
|
||||||
const auto& aqConfig = this->es.aquifer();
|
if (const auto& aqConfig = this->es.aquifer();
|
||||||
|
aqConfig.connections().active() || aqConfig.hasNumericalAquifer())
|
||||||
if (aqConfig.hasAnalyticalAquifer() || aqConfig.hasNumericalAquifer()) {
|
{
|
||||||
this->aquiferData = RestartIO::Helpers::AggregateAquiferData {
|
this->aquiferData
|
||||||
RestartIO::inferAquiferDimensions(this->es),
|
.emplace(RestartIO::inferAquiferDimensions(this->es),
|
||||||
aqConfig,
|
aqConfig, this->grid);
|
||||||
this->grid
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,19 +22,24 @@
|
|||||||
|
|
||||||
#include <opm/output/eclipse/VectorItems/intehead.hpp>
|
#include <opm/output/eclipse/VectorItems/intehead.hpp>
|
||||||
|
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||||
|
|
||||||
#include <opm/common/utility/TimeService.hpp>
|
#include <opm/common/utility/TimeService.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <initializer_list>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -881,11 +886,66 @@ Opm::RestartIO::getSimulationTimePoint(const std::time_t start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
template <typename T, class A>
|
||||||
|
int numUnique(std::vector<T, A> elems)
|
||||||
|
{
|
||||||
|
if (elems.empty()) { return 0; }
|
||||||
|
if (elems.size() == 1) { return 1; }
|
||||||
|
|
||||||
|
std::sort(elems.begin(), elems.end());
|
||||||
|
auto end = std::unique(elems.begin(), elems.end());
|
||||||
|
|
||||||
|
return std::distance(elems.begin(), end);
|
||||||
|
}
|
||||||
|
|
||||||
|
int numberOfCarterTracyAquifers(const Opm::AquiferConfig& cfg)
|
||||||
|
{
|
||||||
|
return cfg.ct().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int numberOfFetkovichAquifers(const Opm::AquiferConfig& cfg)
|
||||||
|
{
|
||||||
|
return cfg.fetp().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int numberOfConstantFluxAquifers(const Opm::AquiferConfig& cfg)
|
||||||
|
{
|
||||||
|
return cfg.aquflux().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int numberOfConstantFluxAquifers(const Opm::AquiferConfig& cfg,
|
||||||
|
const Opm::ScheduleState& sched)
|
||||||
|
{
|
||||||
|
auto aquiferIDs = std::vector<int>{};
|
||||||
|
aquiferIDs.reserve(numberOfConstantFluxAquifers(cfg)
|
||||||
|
+ sched.aqufluxs.size());
|
||||||
|
|
||||||
|
for (const auto& [id, aq] : cfg.aquflux()) {
|
||||||
|
if (aq.active) {
|
||||||
|
aquiferIDs.push_back(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& aq : sched.aqufluxs) {
|
||||||
|
aquiferIDs.push_back(aq.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return numUnique(std::move(aquiferIDs));
|
||||||
|
}
|
||||||
|
|
||||||
int getNumberOfAnalyticAquifers(const Opm::AquiferConfig& cfg)
|
int getNumberOfAnalyticAquifers(const Opm::AquiferConfig& cfg)
|
||||||
{
|
{
|
||||||
const auto numAnalyticAquifers = cfg.ct().size() + cfg.fetp().size() + cfg.aquflux().size();
|
return numberOfCarterTracyAquifers(cfg)
|
||||||
|
+ numberOfFetkovichAquifers(cfg)
|
||||||
|
+ numberOfConstantFluxAquifers(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
return static_cast<int>(numAnalyticAquifers);
|
int getNumberOfAnalyticAquifers(const Opm::AquiferConfig& cfg,
|
||||||
|
const Opm::ScheduleState& sched)
|
||||||
|
{
|
||||||
|
return numberOfCarterTracyAquifers(cfg)
|
||||||
|
+ numberOfFetkovichAquifers(cfg)
|
||||||
|
+ numberOfConstantFluxAquifers(cfg, sched);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMaximumNumberOfAnalyticAquifers(const Opm::Runspec& runspec)
|
int getMaximumNumberOfAnalyticAquifers(const Opm::Runspec& runspec)
|
||||||
@ -910,14 +970,47 @@ namespace {
|
|||||||
return maxNumActiveConn;
|
return maxNumActiveConn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AquiferCollection>
|
||||||
|
int maxAquID(const AquiferCollection& aquiferCollection)
|
||||||
|
{
|
||||||
|
return std::accumulate(aquiferCollection.begin(), aquiferCollection.end(), 0,
|
||||||
|
[](const int maxID, const auto& aquiferData)
|
||||||
|
{
|
||||||
|
return std::max(maxID, aquiferData.aquiferID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename AquFluxIter>
|
||||||
|
int maxAquID(AquFluxIter begin, AquFluxIter end)
|
||||||
|
{
|
||||||
|
auto maxIDPos =
|
||||||
|
std::max_element(begin, end,
|
||||||
|
[](const auto& aq1, const auto& aq2)
|
||||||
|
{
|
||||||
|
return aq1.first < aq2.first;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (maxIDPos == end) ? 0 : maxIDPos->first;
|
||||||
|
}
|
||||||
|
|
||||||
int getMaximumAnalyticAquiferID(const Opm::AquiferConfig& cfg)
|
int getMaximumAnalyticAquiferID(const Opm::AquiferConfig& cfg)
|
||||||
{
|
{
|
||||||
const auto& aquifer_ids = analyticAquiferIDs(cfg);
|
return std::max({
|
||||||
if (!aquifer_ids.empty()) {
|
maxAquID(cfg.ct()),
|
||||||
return *max_element(std::begin(aquifer_ids), std::end(aquifer_ids));
|
maxAquID(cfg.fetp()),
|
||||||
} else {
|
maxAquID(cfg.aquflux().begin(), cfg.aquflux().end())
|
||||||
return 0;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getMaximumAnalyticAquiferID(const int maxAquiferID,
|
||||||
|
const Opm::ScheduleState& sched)
|
||||||
|
{
|
||||||
|
return std::max(maxAquiferID, maxAquID(sched.aqufluxs.begin(), sched.aqufluxs.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasAnalyticalAquifer(const Opm::ScheduleState& sched)
|
||||||
|
{
|
||||||
|
return ! sched.aqufluxs.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,3 +1039,19 @@ Opm::RestartIO::inferAquiferDimensions(const EclipseState& es)
|
|||||||
|
|
||||||
return dim;
|
return dim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opm::RestartIO::InteHEAD::AquiferDims
|
||||||
|
Opm::RestartIO::inferAquiferDimensions(const EclipseState& es,
|
||||||
|
const ScheduleState& sched)
|
||||||
|
{
|
||||||
|
auto dim = inferAquiferDimensions(es);
|
||||||
|
|
||||||
|
if (const auto& cfg = es.aquifer();
|
||||||
|
cfg.hasAnalyticalAquifer() || hasAnalyticalAquifer(sched))
|
||||||
|
{
|
||||||
|
dim.numAquifers = getNumberOfAnalyticAquifers(cfg, sched);
|
||||||
|
dim.maxAquiferID = getMaximumAnalyticAquiferID(dim.maxAquiferID, sched);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dim;
|
||||||
|
}
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include <opm/output/eclipse/AggregateUDQData.hpp>
|
#include <opm/output/eclipse/AggregateUDQData.hpp>
|
||||||
#include <opm/output/eclipse/AggregateActionxData.hpp>
|
#include <opm/output/eclipse/AggregateActionxData.hpp>
|
||||||
#include <opm/output/eclipse/RestartValue.hpp>
|
#include <opm/output/eclipse/RestartValue.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/TracerConfig.hpp>
|
|
||||||
|
|
||||||
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
|
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
|
||||||
|
|
||||||
@ -43,16 +42,19 @@
|
|||||||
#include <opm/io/eclipse/OutputStream.hpp>
|
#include <opm/io/eclipse/OutputStream.hpp>
|
||||||
#include <opm/io/eclipse/PaddedOutputString.hpp>
|
#include <opm/io/eclipse/PaddedOutputString.hpp>
|
||||||
|
|
||||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/Tables/Eqldims.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/TracerConfig.hpp>
|
||||||
|
|
||||||
#include <opm/input/eclipse/Schedule/Action/Actions.hpp>
|
#include <opm/input/eclipse/Schedule/Action/Actions.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>
|
#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/Tuning.hpp>
|
#include <opm/input/eclipse/Schedule/Tuning.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
|
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
|
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Tables/Eqldims.hpp>
|
|
||||||
|
|
||||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||||
|
|
||||||
@ -463,16 +465,24 @@ namespace {
|
|||||||
rstFile.write("RAQN", aquiferData.getNumericAquiferDoublePrecData());
|
rstFile.write("RAQN", aquiferData.getNumericAquiferDoublePrecData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateAndWriteAquiferData(const AquiferConfig& aqConfig,
|
void updateAndWriteAquiferData(const EclipseState& es,
|
||||||
|
const ScheduleState& sched,
|
||||||
const data::Aquifers& aquData,
|
const data::Aquifers& aquData,
|
||||||
const SummaryState& summaryState,
|
const SummaryState& summaryState,
|
||||||
const UnitSystem& usys,
|
const UnitSystem& usys,
|
||||||
Helpers::AggregateAquiferData& aquiferData,
|
Helpers::AggregateAquiferData& aquiferData,
|
||||||
EclIO::OutputStream::Restart& rstFile)
|
EclIO::OutputStream::Restart& rstFile)
|
||||||
{
|
{
|
||||||
aquiferData.captureDynamicdAquiferData(aqConfig, aquData, summaryState, usys);
|
const auto& aqConfig = es.aquifer();
|
||||||
|
|
||||||
if (aqConfig.hasAnalyticalAquifer()) {
|
aquiferData.captureDynamicAquiferData(inferAquiferDimensions(es, sched),
|
||||||
|
aqConfig,
|
||||||
|
sched,
|
||||||
|
aquData,
|
||||||
|
summaryState,
|
||||||
|
usys);
|
||||||
|
|
||||||
|
if (aqConfig.hasAnalyticalAquifer() || sched.hasAnalyticalAquifers()) {
|
||||||
writeAnalyticAquiferData(aquiferData, rstFile);
|
writeAnalyticAquiferData(aquiferData, rstFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,9 +516,9 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write well and MSW data only when applicable (i.e., when present)
|
// Write well and MSW data only when applicable (i.e., when present)
|
||||||
const auto& wells = schedule.wellNames(sim_step);
|
if (const auto& wells = schedule.wellNames(sim_step);
|
||||||
|
! wells.empty())
|
||||||
if (! wells.empty()) {
|
{
|
||||||
const auto haveMSW =
|
const auto haveMSW =
|
||||||
std::any_of(std::begin(wells), std::end(wells),
|
std::any_of(std::begin(wells), std::end(wells),
|
||||||
[&schedule, sim_step](const std::string& well)
|
[&schedule, sim_step](const std::string& well)
|
||||||
@ -525,11 +535,16 @@ namespace {
|
|||||||
wells, wellSol, action_state, wtest_state, sumState, inteHD, rstFile);
|
wells, wellSol, action_state, wtest_state, sumState, inteHD, rstFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((es.aquifer().hasAnalyticalAquifer() || es.aquifer().hasNumericalAquifer()) &&
|
if (const auto& aqCfg = es.aquifer();
|
||||||
aquiferData.has_value())
|
aqCfg.active() && aquiferData.has_value())
|
||||||
{
|
{
|
||||||
updateAndWriteAquiferData(es.aquifer(), aquDynData, sumState,
|
updateAndWriteAquiferData(es,
|
||||||
schedule.getUnits(), aquiferData.value(), rstFile);
|
schedule[sim_step],
|
||||||
|
aquDynData,
|
||||||
|
sumState,
|
||||||
|
schedule.getUnits(),
|
||||||
|
aquiferData.value(),
|
||||||
|
rstFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,15 +31,17 @@
|
|||||||
|
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferCT.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferCT.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/Aquifetp.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/Aquifer/Aquifetp.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||||
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
|
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
|
||||||
#include <opm/input/eclipse/EclipseState/Tables/FlatTable.hpp>
|
#include <opm/input/eclipse/EclipseState/Tables/FlatTable.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
|
||||||
|
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
|
||||||
|
|
||||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||||
#include <opm/input/eclipse/Parser/Parser.hpp>
|
#include <opm/input/eclipse/Parser/Parser.hpp>
|
||||||
|
|
||||||
@ -50,6 +52,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -100,6 +103,15 @@ namespace {
|
|||||||
return Opm::UnitSystem::newMETRIC().to_si(M::pressure, 1.0);
|
return Opm::UnitSystem::newMETRIC().to_si(M::pressure, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double fluxUnit()
|
||||||
|
{
|
||||||
|
using M = Opm::UnitSystem::measure;
|
||||||
|
const auto usys = Opm::UnitSystem::newMETRIC();
|
||||||
|
|
||||||
|
auto q = usys.to_si(M::liquid_surface_rate, 1.0);
|
||||||
|
return usys.from_si(M::length, usys.from_si(M::length, q));
|
||||||
|
}
|
||||||
|
|
||||||
double compressibilityUnit()
|
double compressibilityUnit()
|
||||||
{
|
{
|
||||||
using M = Opm::UnitSystem::measure;
|
using M = Opm::UnitSystem::measure;
|
||||||
@ -205,7 +217,7 @@ AQUTAB
|
|||||||
const auto cartCell1 = std::size_t{699}; // one-based IJK = (20,5,7)
|
const auto cartCell1 = std::size_t{699}; // one-based IJK = (20,5,7)
|
||||||
const auto cartCell2 = std::size_t{799}; // one-based IJK = (20,5,8)
|
const auto cartCell2 = std::size_t{799}; // one-based IJK = (20,5,8)
|
||||||
const auto cartCell3 = std::size_t{899}; // one-based IJK = (20,5,9)
|
const auto cartCell3 = std::size_t{899}; // one-based IJK = (20,5,9)
|
||||||
const auto effFaceArea = 4.0 * 0.2; // DY * DZ
|
const auto effFaceArea = 4.0 * 0.2; // DY * DZ
|
||||||
const auto influxCoeff = effFaceArea;
|
const auto influxCoeff = effFaceArea;
|
||||||
|
|
||||||
aquancon.addConnection(aquiferID, cartCell1, 1.0*influxCoeff, 6.0*effFaceArea, FDir::XMinus);
|
aquancon.addConnection(aquiferID, cartCell1, 1.0*influxCoeff, 6.0*effFaceArea, FDir::XMinus);
|
||||||
@ -289,7 +301,8 @@ AQUTAB
|
|||||||
const auto effFaceArea = 4.0 * 0.2; // DY * DZ
|
const auto effFaceArea = 4.0 * 0.2; // DY * DZ
|
||||||
const auto influxCoeff = effFaceArea;
|
const auto influxCoeff = effFaceArea;
|
||||||
|
|
||||||
aquancon.addConnection(aquiferID, cartCell, influxCoeff, effFaceArea, FDir::YPlus);
|
aquancon.addConnection(aquiferID, cartCell, influxCoeff,
|
||||||
|
effFaceArea, FDir::YPlus);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -298,7 +311,8 @@ AQUTAB
|
|||||||
const auto effFaceArea = 4.0 * 0.2; // DY * DZ
|
const auto effFaceArea = 4.0 * 0.2; // DY * DZ
|
||||||
const auto influxCoeff = 1.0; // [m^2]
|
const auto influxCoeff = 1.0; // [m^2]
|
||||||
|
|
||||||
aquancon.addConnection(aquiferID, cartCell, influxCoeff, effFaceArea, FDir::ZPlus);
|
aquancon.addConnection(aquiferID, cartCell, influxCoeff,
|
||||||
|
effFaceArea, FDir::ZPlus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +333,8 @@ AQUTAB
|
|||||||
|
|
||||||
auto& fetp = properties
|
auto& fetp = properties
|
||||||
.emplace_back(aquiferID, pvtTable, prodIndex, compr,
|
.emplace_back(aquiferID, pvtTable, prodIndex, compr,
|
||||||
initialVolume, datumDepth, initialPressure, initialTemperature);
|
initialVolume, datumDepth,
|
||||||
|
initialPressure, initialTemperature);
|
||||||
|
|
||||||
fetp.finishInitialisation(waterProperties());
|
fetp.finishInitialisation(waterProperties());
|
||||||
}
|
}
|
||||||
@ -332,7 +347,8 @@ AQUTAB
|
|||||||
|
|
||||||
auto& fetp = properties
|
auto& fetp = properties
|
||||||
.emplace_back(aquiferID, pvtTable, prodIndex, compr,
|
.emplace_back(aquiferID, pvtTable, prodIndex, compr,
|
||||||
initialVolume, datumDepth, initialPressure, initialTemperature);
|
initialVolume, datumDepth,
|
||||||
|
initialPressure, initialTemperature);
|
||||||
|
|
||||||
fetp.finishInitialisation(waterProperties());
|
fetp.finishInitialisation(waterProperties());
|
||||||
}
|
}
|
||||||
@ -340,10 +356,47 @@ AQUTAB
|
|||||||
return Opm::Aquifetp(properties);
|
return Opm::Aquifetp(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
Opm::AquiferFlux createAquiferFluxs() {
|
void connectConstantFluxAquifers(AquiferConnections& aquancon)
|
||||||
// TODO: just for compilation for now, will complete it
|
{
|
||||||
Opm::AquiferFlux aquifers;
|
using FDir = Opm::FaceDir::DirEnum;
|
||||||
return aquifers;
|
|
||||||
|
{
|
||||||
|
const auto aquiferID = 3;
|
||||||
|
const auto cartCell1 = std::size_t{680}; // one-based IJK = (1,5, 7)
|
||||||
|
const auto cartCell2 = std::size_t{780}; // one-based IJK = (1,5, 8)
|
||||||
|
const auto cartCell3 = std::size_t{880}; // one-based IJK = (1,5, 9)
|
||||||
|
const auto cartCell4 = std::size_t{980}; // one-based IJK = (1,5,10)
|
||||||
|
const auto effFaceArea = 5.0 * 0.2; // DX * DZ
|
||||||
|
const auto influxCoeff = effFaceArea;
|
||||||
|
|
||||||
|
aquancon.addConnection(aquiferID, cartCell1, 1.0*influxCoeff, 6.0*effFaceArea, FDir::YPlus);
|
||||||
|
aquancon.addConnection(aquiferID, cartCell2, 2.0*influxCoeff, 12.0*effFaceArea, FDir::YPlus);
|
||||||
|
aquancon.addConnection(aquiferID, cartCell3, 3.0*influxCoeff, 18.0*effFaceArea, FDir::YPlus);
|
||||||
|
aquancon.addConnection(aquiferID, cartCell4, 4.0*influxCoeff, 24.0*effFaceArea, FDir::YPlus);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto aquiferID = 5;
|
||||||
|
const auto cartCell = std::size_t{490}; // one-based IJK = (11,5,5)
|
||||||
|
const auto effFaceArea = 5.0 * 0.2; // DX * DZ
|
||||||
|
const auto influxCoeff = 1.0; // [m^2]
|
||||||
|
|
||||||
|
aquancon.addConnection(aquiferID, cartCell, influxCoeff, effFaceArea, FDir::XPlus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Opm::AquiferFlux createConstantFluxAquifers()
|
||||||
|
{
|
||||||
|
const auto uQ = fluxUnit();
|
||||||
|
const auto uP = pressureUnit();
|
||||||
|
const auto salt = 0.0;
|
||||||
|
const auto temp = 300.0*temperatureUnit();
|
||||||
|
const auto active = true;
|
||||||
|
|
||||||
|
return Opm::AquiferFlux { std::vector {
|
||||||
|
Opm::SingleAquiferFlux { 3, 12.34*uQ, salt, active, temp, 234.5*uP },
|
||||||
|
Opm::SingleAquiferFlux { 5, 43.21*uQ, salt, active, temp, 345.6*uP },
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
Opm::AquiferConfig createAquiferConfig()
|
Opm::AquiferConfig createAquiferConfig()
|
||||||
@ -351,9 +404,28 @@ AQUTAB
|
|||||||
auto aquancon = AquiferConnections{};
|
auto aquancon = AquiferConnections{};
|
||||||
connectCarterTracy(aquancon);
|
connectCarterTracy(aquancon);
|
||||||
connectFetkovic(aquancon);
|
connectFetkovic(aquancon);
|
||||||
|
connectConstantFluxAquifers(aquancon);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createFetkovich(), createCarterTracy(), createAquiferFluxs(), Opm::Aquancon(aquancon.getAllConnections())
|
createFetkovich(),
|
||||||
|
createCarterTracy(),
|
||||||
|
createConstantFluxAquifers(),
|
||||||
|
Opm::Aquancon { aquancon.getAllConnections() }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Opm::AquiferConfig createEmptyAquiferConfig()
|
||||||
|
{
|
||||||
|
auto aquancon = AquiferConnections{};
|
||||||
|
connectCarterTracy(aquancon);
|
||||||
|
connectFetkovic(aquancon);
|
||||||
|
connectConstantFluxAquifers(aquancon);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Opm::Aquifetp{},
|
||||||
|
Opm::AquiferCT{},
|
||||||
|
Opm::AquiferFlux{},
|
||||||
|
Opm::Aquancon { aquancon.getAllConnections() }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,15 +501,41 @@ END
|
|||||||
{
|
{
|
||||||
auto aqDims = Opm::RestartIO::InteHEAD::AquiferDims{};
|
auto aqDims = Opm::RestartIO::InteHEAD::AquiferDims{};
|
||||||
|
|
||||||
aqDims.numAquifers = 4; // 1, 2, 4, 6
|
aqDims.numAquifers = 6; // 1, 2, 3, 4, 5, 6
|
||||||
aqDims.maxNumAquifers = 10; // >= 6
|
aqDims.maxNumAquifers = 10; // >= 6
|
||||||
aqDims.maxNumAquiferConn = 5; // >= 3
|
aqDims.maxNumAquiferConn = 5; // >= 4
|
||||||
aqDims.maxNumActiveAquiferConn = 3; // ID = 1
|
aqDims.maxNumActiveAquiferConn = 4; // ID = 3
|
||||||
aqDims.maxAquiferID = 6;
|
aqDims.maxAquiferID = 6;
|
||||||
|
|
||||||
return aqDims;
|
return aqDims;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opm::RestartIO::InteHEAD::AquiferDims syntheticDynamicAquiferDimensionsSOLUTION()
|
||||||
|
{
|
||||||
|
auto aqDims = Opm::RestartIO::InteHEAD::AquiferDims{};
|
||||||
|
|
||||||
|
aqDims.numAquifers = 0;
|
||||||
|
aqDims.maxNumAquifers = 10; // >= 5
|
||||||
|
aqDims.maxNumAquiferConn = 5; // >= 4
|
||||||
|
aqDims.maxNumActiveAquiferConn = 4; // ID = 3
|
||||||
|
aqDims.maxAquiferID = 0;
|
||||||
|
|
||||||
|
return aqDims;
|
||||||
|
}
|
||||||
|
|
||||||
|
Opm::RestartIO::InteHEAD::AquiferDims syntheticDynamicAquiferDimensionsSCHEDULE()
|
||||||
|
{
|
||||||
|
auto aqDims = Opm::RestartIO::InteHEAD::AquiferDims{};
|
||||||
|
|
||||||
|
aqDims.numAquifers = 2; // 3, 5
|
||||||
|
aqDims.maxNumAquifers = 10; // >= 5
|
||||||
|
aqDims.maxNumAquiferConn = 5; // >= 4
|
||||||
|
aqDims.maxNumActiveAquiferConn = 4; // ID = 3
|
||||||
|
aqDims.maxAquiferID = 5;
|
||||||
|
|
||||||
|
return aqDims;
|
||||||
|
}
|
||||||
|
|
||||||
Opm::RestartIO::InteHEAD::AquiferDims syntheticNumericAquiferDimensions()
|
Opm::RestartIO::InteHEAD::AquiferDims syntheticNumericAquiferDimensions()
|
||||||
{
|
{
|
||||||
auto aqDims = Opm::RestartIO::InteHEAD::AquiferDims{};
|
auto aqDims = Opm::RestartIO::InteHEAD::AquiferDims{};
|
||||||
@ -527,10 +625,18 @@ AQUANCON
|
|||||||
state.update("AAQR:2", 222.333);
|
state.update("AAQR:2", 222.333);
|
||||||
state.update("AAQT:2", 333.444);
|
state.update("AAQT:2", 333.444);
|
||||||
|
|
||||||
|
state.update("AAQP:3", 212.121);
|
||||||
|
state.update("AAQR:3", 333.222);
|
||||||
|
state.update("AAQT:3", 444.333);
|
||||||
|
|
||||||
state.update("AAQP:4", 555.444);
|
state.update("AAQP:4", 555.444);
|
||||||
state.update("AAQR:4", 333.222);
|
state.update("AAQR:4", 333.222);
|
||||||
state.update("AAQT:4", 222.111);
|
state.update("AAQT:4", 222.111);
|
||||||
|
|
||||||
|
state.update("AAQP:5", 444.555);
|
||||||
|
state.update("AAQR:5", 323.232);
|
||||||
|
state.update("AAQT:5", 232.131);
|
||||||
|
|
||||||
state.update("AAQP:6", 456.123);
|
state.update("AAQP:6", 456.123);
|
||||||
state.update("AAQR:6", 34.567);
|
state.update("AAQR:6", 34.567);
|
||||||
state.update("AAQT:6", 4444.5555);
|
state.update("AAQT:6", 4444.5555);
|
||||||
@ -620,17 +726,38 @@ AQUANCON
|
|||||||
return aquiferValues;
|
return aquiferValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opm::ScheduleState emptyScheduleState()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Opm::ScheduleState dynamicAquFluxState()
|
||||||
|
{
|
||||||
|
auto sched = emptyScheduleState();
|
||||||
|
const auto cfg = createAquiferConfig();
|
||||||
|
|
||||||
|
sched.aqufluxs.insert(cfg.aquflux().begin(),
|
||||||
|
cfg.aquflux().end());
|
||||||
|
|
||||||
|
return sched;
|
||||||
|
}
|
||||||
|
|
||||||
template <class Coll1, class Coll2>
|
template <class Coll1, class Coll2>
|
||||||
void check_is_close(const Coll1& coll1, const Coll2& coll2, const double tol)
|
void check_is_close(const Coll1& coll1,
|
||||||
|
const Coll2& coll2,
|
||||||
|
const double tol,
|
||||||
|
std::string_view context)
|
||||||
{
|
{
|
||||||
BOOST_REQUIRE_EQUAL(std::size(coll1), std::size(coll2));
|
BOOST_REQUIRE_EQUAL(std::size(coll1), std::size(coll2));
|
||||||
|
|
||||||
if (coll1.empty()) { return; }
|
if (coll1.empty()) { return; }
|
||||||
|
|
||||||
|
auto i = 0;
|
||||||
auto c1 = std::begin(coll1);
|
auto c1 = std::begin(coll1);
|
||||||
auto e1 = std::end (coll1);
|
auto e1 = std::end (coll1);
|
||||||
auto c2 = std::begin(coll2);
|
auto c2 = std::begin(coll2);
|
||||||
for (; c1 != e1; ++c1, ++c2) {
|
for (; c1 != e1; ++c1, ++c2, ++i) {
|
||||||
|
BOOST_TEST_MESSAGE(context << '[' << i << ']');
|
||||||
BOOST_CHECK_CLOSE(*c1, *c2, tol);
|
BOOST_CHECK_CLOSE(*c1, *c2, tol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -683,6 +810,8 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
20, 5, 8, 994, 3, 0, 0,
|
20, 5, 8, 994, 3, 0, 0,
|
||||||
// Connection 2
|
// Connection 2
|
||||||
20, 5, 9, 995, 5, 0, 0,
|
20, 5, 9, 995, 5, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(1);
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(1);
|
||||||
@ -699,11 +828,13 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
1.0f/3.0f, 2.0f,
|
1.0f/3.0f, 2.0f,
|
||||||
// Connection 2
|
// Connection 2
|
||||||
1.0f/2.0f, 3.0f,
|
1.0f/2.0f, 3.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(1);
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(1);
|
||||||
|
|
||||||
check_is_close(scaq, expect, 1.0e-7);
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICAQ:2
|
// ICAQ:2
|
||||||
@ -715,6 +846,8 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
// Connection 2 (nonexistent)
|
// Connection 2 (nonexistent)
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(2);
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(2);
|
||||||
@ -731,22 +864,26 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
// Connection 2 (nonexistent)
|
// Connection 2 (nonexistent)
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(2);
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(2);
|
||||||
|
|
||||||
check_is_close(scaq, expect, 1.0e-7);
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICAQ:3 (not activated/connected)
|
// ICAQ:3
|
||||||
{
|
{
|
||||||
const auto expect = std::vector<int> {
|
const auto expect = std::vector<int> {
|
||||||
// Connection 0
|
// Connection 0
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
1, 5, 7, 47, 4, 0, 0,
|
||||||
// Connection 1
|
// Connection 1
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
1, 5, 8, 48, 4, 0, 0,
|
||||||
// Connection 2
|
// Connection 2
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
1, 5, 9, 49, 4, 0, 0,
|
||||||
|
// Connection 3
|
||||||
|
1, 5, 10, 50, 4, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(3);
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(3);
|
||||||
@ -754,20 +891,22 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// SCAQ:3 (not activated/connected)
|
// SCAQ:3
|
||||||
{
|
{
|
||||||
const auto expect = std::vector<float> {
|
const auto expect = std::vector<float> {
|
||||||
// Connection 0
|
// Connection 0
|
||||||
0.0f, 0.0f,
|
1.0f/10.0f, 3.0f/5.0f,
|
||||||
// Connection 1
|
// Connection 1
|
||||||
0.0f, 0.0f,
|
1.0f/ 5.0f, 6.0f/5.0f,
|
||||||
// Connection 2
|
// Connection 2
|
||||||
0.0f, 0.0f,
|
3.0f/10.0f, 9.0f/5.0f,
|
||||||
|
// Connection 3
|
||||||
|
2.0f/ 5.0f, 12.0f/5.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(3);
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(3);
|
||||||
|
|
||||||
check_is_close(scaq, expect, 1.0e-7);
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:3");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICAQ:4
|
// ICAQ:4
|
||||||
@ -779,6 +918,8 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
// Connection 2 (nonexistent)
|
// Connection 2 (nonexistent)
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(4);
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(4);
|
||||||
@ -795,21 +936,25 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
// Connection 2 (nonexistent)
|
// Connection 2 (nonexistent)
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(4);
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(4);
|
||||||
|
|
||||||
check_is_close(scaq, expect, 1.0e-7);
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:4");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICAQ:5 (not activated/connected)
|
// ICAQ:5
|
||||||
{
|
{
|
||||||
const auto expect = std::vector<int> {
|
const auto expect = std::vector<int> {
|
||||||
// Connection 0
|
// Connection 0
|
||||||
|
11, 5, 5, 543, 2, 0, 0,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
// Connection 1
|
// Connection 2 (nonexistent)
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
// Connection 2
|
// Connection 3 (nonexistent)
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -818,20 +963,22 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// SCAQ:5 (not activated/connected)
|
// SCAQ:5
|
||||||
{
|
{
|
||||||
const auto expect = std::vector<float> {
|
const auto expect = std::vector<float> {
|
||||||
// Connection 0
|
// Connection 0
|
||||||
|
1.0f, 1.0f,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
// Connection 1
|
// Connection 2 (nonexistent)
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
// Connection 2
|
// Connection 3 (nonexistent)
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(5);
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(5);
|
||||||
|
|
||||||
check_is_close(scaq, expect, 1.0e-7);
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:5");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ICAQ:6
|
// ICAQ:6
|
||||||
@ -843,6 +990,8 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
// Connection 2 (nonexistent)
|
// Connection 2 (nonexistent)
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(6);
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(6);
|
||||||
@ -859,11 +1008,13 @@ BOOST_AUTO_TEST_CASE(Static_Information_Analytic_Aquifers)
|
|||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
// Connection 2 (nonexistent)
|
// Connection 2 (nonexistent)
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(6);
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(6);
|
||||||
|
|
||||||
check_is_close(scaq, expect, 1.0e-7);
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:6");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,8 +1026,11 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
auto aquiferData = Opm::RestartIO::Helpers::
|
auto aquiferData = Opm::RestartIO::Helpers::
|
||||||
AggregateAquiferData{ aqDims, aqConfig, createGrid() };
|
AggregateAquiferData{ aqDims, aqConfig, createGrid() };
|
||||||
|
|
||||||
aquiferData.captureDynamicdAquiferData(aqConfig, aquiferValues(aqConfig), sim_state(),
|
aquiferData.captureDynamicAquiferData(aqDims, aqConfig,
|
||||||
Opm::UnitSystem::newMETRIC());
|
emptyScheduleState(),
|
||||||
|
aquiferValues(aqConfig),
|
||||||
|
sim_state(),
|
||||||
|
Opm::UnitSystem::newMETRIC());
|
||||||
|
|
||||||
// IAAQ
|
// IAAQ
|
||||||
{
|
{
|
||||||
@ -886,11 +1040,11 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
// Aquifer 2
|
// Aquifer 2
|
||||||
1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||||
// Aquifer 3
|
// Aquifer 3
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0,
|
||||||
// Aquifer 4
|
// Aquifer 4
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||||
// Aquifer 5
|
// Aquifer 5
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0,
|
||||||
// Aquifer 6
|
// Aquifer 6
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0,
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
@ -914,9 +1068,9 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (40..47)
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (40..47)
|
||||||
|
|
||||||
// Aquifer 3
|
// Aquifer 3
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 (48..55)
|
12.34f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 (48..55)
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (56..63)
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (56..63)
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (64..71)
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (64..71)
|
||||||
|
|
||||||
// Aquifer 4
|
// Aquifer 4
|
||||||
1.5312e-4f, 2.0e10f, 910.0f, 3.365274725274725e+03f, 250.0f, 2000.0f, 0.0f, 0.0f, // 0.. 7 (72..79)
|
1.5312e-4f, 2.0e10f, 910.0f, 3.365274725274725e+03f, 250.0f, 2000.0f, 0.0f, 0.0f, // 0.. 7 (72..79)
|
||||||
@ -924,9 +1078,9 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (88..95)
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (88..95)
|
||||||
|
|
||||||
// Aquifer 5
|
// Aquifer 5
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 ( 96..103)
|
43.21f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 ( 96..103)
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (104..111)
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (104..111)
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (112..119)
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (112..119)
|
||||||
|
|
||||||
// Aquifer 6
|
// Aquifer 6
|
||||||
3.0e-5f, 900.0f, 5000.0f, 0.3f, 269.0f, 2000.0f, 10.0f, 1.0f, // 0.. 7 (120..127)
|
3.0e-5f, 900.0f, 5000.0f, 0.3f, 269.0f, 2000.0f, 10.0f, 1.0f, // 0.. 7 (120..127)
|
||||||
@ -936,7 +1090,7 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
|
|
||||||
const auto& saaq = aquiferData.getSinglePrecAquiferData();
|
const auto& saaq = aquiferData.getSinglePrecAquiferData();
|
||||||
|
|
||||||
check_is_close(saaq, expect, 1.0e-7);
|
check_is_close(saaq, expect, 1.0e-7, "SAAQ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// XAAQ
|
// XAAQ
|
||||||
@ -949,13 +1103,13 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
222.333, 121.212, 333.444, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
222.333, 121.212, 333.444, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
// Aquifer 3
|
// Aquifer 3
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
333.222, 212.121, 444.333, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
// Aquifer 4
|
// Aquifer 4
|
||||||
333.222, 555.444, 222.111, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
333.222, 555.444, 222.111, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
// Aquifer 5
|
// Aquifer 5
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
323.232, 444.555, 232.131, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
// Aquifer 6
|
// Aquifer 6
|
||||||
34.567, 456.123, 4444.5555, 1.0, 18.409712143375852, 458.0307, 0.0, 0.0, 100.321, 50.706,
|
34.567, 456.123, 4444.5555, 1.0, 18.409712143375852, 458.0307, 0.0, 0.0, 100.321, 50.706,
|
||||||
@ -963,7 +1117,7 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Analytic_Aquifers)
|
|||||||
|
|
||||||
const auto& xaaq = aquiferData.getDoublePrecAquiferData();
|
const auto& xaaq = aquiferData.getDoublePrecAquiferData();
|
||||||
|
|
||||||
check_is_close(xaaq, expect, 1.0e-7);
|
check_is_close(xaaq, expect, 1.0e-7, "XAAQ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -972,7 +1126,8 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Numeric_Aquifers)
|
|||||||
const auto aqDims = syntheticNumericAquiferDimensions();
|
const auto aqDims = syntheticNumericAquiferDimensions();
|
||||||
const auto aqConfig = createNumericAquiferConfig();
|
const auto aqConfig = createNumericAquiferConfig();
|
||||||
|
|
||||||
BOOST_REQUIRE_MESSAGE(aqConfig.hasNumericalAquifer(), "Aquifer configuration object must have numeric aquifers");
|
BOOST_REQUIRE_MESSAGE(aqConfig.hasNumericalAquifer(),
|
||||||
|
"Aquifer configuration object must have numeric aquifers");
|
||||||
|
|
||||||
auto aquiferData = Opm::RestartIO::Helpers::
|
auto aquiferData = Opm::RestartIO::Helpers::
|
||||||
AggregateAquiferData{ aqDims, aqConfig, createGrid() };
|
AggregateAquiferData{ aqDims, aqConfig, createGrid() };
|
||||||
@ -987,10 +1142,11 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Numeric_Aquifers)
|
|||||||
BOOST_CHECK_EQUAL(aquiferData.getNumericAquiferDoublePrecData().size(), 4u * 13);
|
BOOST_CHECK_EQUAL(aquiferData.getNumericAquiferDoublePrecData().size(), 4u * 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
aquiferData.captureDynamicdAquiferData(aqConfig,
|
aquiferData.captureDynamicAquiferData(aqDims, aqConfig,
|
||||||
numericAquiferValues(aqConfig),
|
emptyScheduleState(),
|
||||||
aqunum_sim_state(),
|
numericAquiferValues(aqConfig),
|
||||||
Opm::UnitSystem::newMETRIC());
|
aqunum_sim_state(),
|
||||||
|
Opm::UnitSystem::newMETRIC());
|
||||||
|
|
||||||
// IAQN
|
// IAQN
|
||||||
{
|
{
|
||||||
@ -1022,7 +1178,321 @@ BOOST_AUTO_TEST_CASE(Dynamic_Information_Numeric_Aquifers)
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto& raqn = aquiferData.getNumericAquiferDoublePrecData();
|
const auto& raqn = aquiferData.getNumericAquiferDoublePrecData();
|
||||||
check_is_close(raqn, expect, 1.0e-10);
|
check_is_close(raqn, expect, 1.0e-10, "RAQN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(Constant_Flux_Aquifer_SCHEDULE)
|
||||||
|
{
|
||||||
|
const auto aqConfig = createEmptyAquiferConfig();
|
||||||
|
|
||||||
|
BOOST_CHECK_MESSAGE(! aqConfig.active(), "Empty aquifer configuration object must not be active()");
|
||||||
|
|
||||||
|
auto aquiferData = Opm::RestartIO::Helpers::AggregateAquiferData {
|
||||||
|
syntheticDynamicAquiferDimensionsSOLUTION(), aqConfig, createGrid()
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(aquiferData.maximumActiveAnalyticAquiferID(), 0);
|
||||||
|
|
||||||
|
aquiferData.captureDynamicAquiferData(syntheticDynamicAquiferDimensionsSCHEDULE(),
|
||||||
|
aqConfig, dynamicAquFluxState(),
|
||||||
|
Opm::data::Aquifers{},
|
||||||
|
sim_state(), Opm::UnitSystem::newMETRIC());
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(aquiferData.maximumActiveAnalyticAquiferID(), 5);
|
||||||
|
|
||||||
|
// ICAQ:1
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Connection 0
|
||||||
|
20, 5, 7, 993, 1, 0, 0,
|
||||||
|
// Connection 1
|
||||||
|
20, 5, 8, 994, 3, 0, 0,
|
||||||
|
// Connection 2
|
||||||
|
20, 5, 9, 995, 5, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(1);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCAQ:1
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Connection 0
|
||||||
|
1.0f/6.0f, 1.0f,
|
||||||
|
// Connection 1
|
||||||
|
1.0f/3.0f, 2.0f,
|
||||||
|
// Connection 2
|
||||||
|
1.0f/2.0f, 3.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(1);
|
||||||
|
|
||||||
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:1");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICAQ:2
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Connection 0
|
||||||
|
20, 1, 7, 955, 4, 0, 0,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(2);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCAQ:2
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Connection 0
|
||||||
|
1.0f, 1.0f,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(2);
|
||||||
|
|
||||||
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:2");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICAQ:3
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Connection 0
|
||||||
|
1, 5, 7, 47, 4, 0, 0,
|
||||||
|
// Connection 1
|
||||||
|
1, 5, 8, 48, 4, 0, 0,
|
||||||
|
// Connection 2
|
||||||
|
1, 5, 9, 49, 4, 0, 0,
|
||||||
|
// Connection 3
|
||||||
|
1, 5, 10, 50, 4, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(3);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCAQ:3
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Connection 0
|
||||||
|
1.0f/10.0f, 3.0f/5.0f,
|
||||||
|
// Connection 1
|
||||||
|
1.0f/ 5.0f, 6.0f/5.0f,
|
||||||
|
// Connection 2
|
||||||
|
3.0f/10.0f, 9.0f/5.0f,
|
||||||
|
// Connection 3
|
||||||
|
2.0f/ 5.0f, 12.0f/5.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(3);
|
||||||
|
|
||||||
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:3");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICAQ:4
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Connection 0
|
||||||
|
20, 1, 5, 953, 6, 0, 0,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(4);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCAQ:4
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Connection 0
|
||||||
|
1.0f, 0.8f,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(4);
|
||||||
|
|
||||||
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:4");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICAQ:5
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Connection 0
|
||||||
|
11, 5, 5, 543, 2, 0, 0,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(5);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCAQ:5
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Connection 0
|
||||||
|
1.0f, 1.0f,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(5);
|
||||||
|
|
||||||
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:5");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICAQ:6
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Connection 0
|
||||||
|
20, 4, 6, 982, 2, 0, 0,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& icaq = aquiferData.getIntegerAquiferConnectionData(6);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(icaq.begin(), icaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCAQ:6
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Connection 0
|
||||||
|
1.0f, 0.8f,
|
||||||
|
// Connection 1 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 2 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
// Connection 3 (nonexistent)
|
||||||
|
0.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& scaq = aquiferData.getSinglePrecAquiferConnectionData(6);
|
||||||
|
|
||||||
|
check_is_close(scaq, expect, 1.0e-7, "SCAQ:6");
|
||||||
|
}
|
||||||
|
|
||||||
|
// IAAQ
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<int> {
|
||||||
|
// Aquifer 1 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Aquifer 2 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Aquifer 3
|
||||||
|
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Aquifer 4 (nonexistent)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
// Aquifer 5
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& iaaq = aquiferData.getIntegerAquiferData();
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(iaaq.begin(), iaaq.end(), expect.begin(), expect.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAAQ
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<float> {
|
||||||
|
// Aquifer 1
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23
|
||||||
|
|
||||||
|
// Aquifer 2
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 (24..38)
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (32..39)
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (40..47)
|
||||||
|
|
||||||
|
// Aquifer 3
|
||||||
|
12.34f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 (48..55)
|
||||||
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (56..63)
|
||||||
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (64..71)
|
||||||
|
|
||||||
|
// Aquifer 4
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 (72..79)
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (80..87)
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (88..95)
|
||||||
|
|
||||||
|
// Aquifer 5
|
||||||
|
43.21f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0.. 7 ( 96..103)
|
||||||
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 8..15 (104..111)
|
||||||
|
0.0f , 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 16..23 (112..119)
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& saaq = aquiferData.getSinglePrecAquiferData();
|
||||||
|
|
||||||
|
check_is_close(saaq, expect, 1.0e-7, "SAAQ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// XAAQ
|
||||||
|
{
|
||||||
|
const auto expect = std::vector<double> {
|
||||||
|
// Aquifer 1
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Aquifer 2
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Aquifer 3
|
||||||
|
333.222, 212.121, 444.333, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Aquifer 4
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Aquifer 5
|
||||||
|
323.232, 444.555, 232.131, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& xaaq = aquiferData.getDoublePrecAquiferData();
|
||||||
|
|
||||||
|
check_is_close(xaaq, expect, 1.0e-7, "XAAQ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user