Implement 'RFIP' and 'SFIP' Mnemonics For RPTRST

The 'FIP' mnemonic continues to be an alias for 'SFIP' in the
current implementation, and the output layer will create the 'SFIP'
arrays as copies of 'FIP' if passed only the 'FIP' arrays.

To this end, make 'outputFipRestart_' into a structure that tracks
which of the *FIP mnemonics have been requested, and insert the
pertinent solution arrays into the data::Solution object when
needed.
This commit is contained in:
Bård Skaflestad 2024-09-19 19:37:19 +02:00
parent 096e0e11c9
commit a38704ecb0
2 changed files with 86 additions and 21 deletions

View File

@ -50,6 +50,7 @@
#include <cassert>
#include <cstddef>
#include <functional>
#include <initializer_list>
#include <stdexcept>
#include <string>
#include <string_view>
@ -684,14 +685,41 @@ assignToSolution(data::Solution& sol)
// Fluid in place
if (this->outputFipRestart_) {
const auto baseFIPArrays = std::array {
DataEntry{"FIPOIL", UnitSystem::measure::liquid_surface_volume, fip_[Inplace::Phase::OIL]},
DataEntry{"FIPWAT", UnitSystem::measure::liquid_surface_volume, fip_[Inplace::Phase::WATER]},
DataEntry{"FIPGAS", UnitSystem::measure::gas_surface_volume, fip_[Inplace::Phase::GAS]},
};
using namespace std::string_literals;
for (const auto& fipArray : baseFIPArrays) {
doInsert(fipArray, data::TargetType::RESTART_SOLUTION);
using M = UnitSystem::measure;
using FIPEntry = std::tuple<std::string, M, Inplace::Phase>;
auto fipArrays = std::vector<FIPEntry> {};
if (this->outputFipRestart_.surface) {
fipArrays.insert(fipArrays.end(), {
FIPEntry {"SFIPOIL"s, M::liquid_surface_volume, Inplace::Phase::OIL },
FIPEntry {"SFIPWAT"s, M::liquid_surface_volume, Inplace::Phase::WATER },
FIPEntry {"SFIPGAS"s, M::gas_surface_volume, Inplace::Phase::GAS },
});
}
if (this->outputFipRestart_.reservoir) {
fipArrays.insert(fipArrays.end(), {
FIPEntry {"RFIPOIL"s, M::volume, Inplace::Phase::OilResVolume },
FIPEntry {"RFIPWAT"s, M::volume, Inplace::Phase::WaterResVolume },
FIPEntry {"RFIPGAS"s, M::volume, Inplace::Phase::GasResVolume },
});
}
if (this->outputFipRestart_.noPrefix && !this->outputFipRestart_.surface) {
fipArrays.insert(fipArrays.end(), {
FIPEntry { "FIPOIL"s, M::liquid_surface_volume, Inplace::Phase::OIL },
FIPEntry { "FIPWAT"s, M::liquid_surface_volume, Inplace::Phase::WATER },
FIPEntry { "FIPGAS"s, M::gas_surface_volume, Inplace::Phase::GAS },
});
}
for (const auto& [mnemonic, unit, phase] : fipArrays) {
if (! this->fip_[phase].empty()) {
sol.insert(mnemonic, unit, std::move(this->fip_[phase]),
data::TargetType::RESTART_SOLUTION);
}
}
for (const auto& phase : Inplace::mixingPhases()) {
@ -884,22 +912,36 @@ doAllocBuffers(const unsigned bufferSize,
norst = 0;
}
this->outputFipRestart_ = false;
this->computeFip_ = false;
// Fluid in place
for (const auto& phase : Inplace::phases()) {
if (!substep || summaryConfig_.require3DField(EclString(phase))) {
if (auto& fip = rstKeywords["FIP"]; fip > 0) {
fip = 0;
this->outputFipRestart_ = true;
}
{
using namespace std::string_literals;
this->fip_[phase].resize(bufferSize, 0.0);
this->computeFip_ = true;
const auto fipctrl = std::array {
std::pair { "FIP"s , &OutputFIPRestart::noPrefix },
std::pair { "SFIP"s, &OutputFIPRestart::surface },
std::pair { "RFIP"s, &OutputFIPRestart::reservoir },
};
this->outputFipRestart_.clearBits();
this->computeFip_ = false;
for (const auto& [mnemonic, kind] : fipctrl) {
if (auto fipPos = rstKeywords.find(mnemonic);
fipPos != rstKeywords.end())
{
fipPos->second = 0;
this->outputFipRestart_.*kind = true;
}
}
else {
this->fip_[phase].clear();
for (const auto& phase : Inplace::phases()) {
if (!substep || summaryConfig_.require3DField(EclString(phase))) {
this->fip_[phase].resize(bufferSize, 0.0);
this->computeFip_ = true;
}
else {
this->fip_[phase].clear();
}
}
}

View File

@ -404,9 +404,32 @@ protected:
bool forceDisableFipOutput_{false};
bool forceDisableFipresvOutput_{false};
bool outputFipRestart_{false};
bool computeFip_{false};
struct OutputFIPRestart {
/// Whether or not run requests (surface condition) fluid-in-place
/// restart file output using the 'FIP' mnemonic.
bool noPrefix {false};
/// Whether or not run requests surface condition fluid-in-place
/// restart file output using the 'SFIP' mnemonic.
bool surface {false};
/// Whether or not run requests reservoir condition fluid-in-place
/// restart file output using the 'RFIP' mnemonic.
bool reservoir {false};
void clearBits()
{
this->noPrefix = this->surface = this->reservoir = false;
}
explicit operator bool() const
{
return this->noPrefix || this->surface || this->reservoir;
}
} outputFipRestart_{};
bool anyFlows_{false};
bool anyFlores_{false};
bool blockFlows_{false};