diff --git a/opm/simulators/flow/GenericOutputBlackoilModule.cpp b/opm/simulators/flow/GenericOutputBlackoilModule.cpp index c8b1d5cf9..6ed735439 100644 --- a/opm/simulators/flow/GenericOutputBlackoilModule.cpp +++ b/opm/simulators/flow/GenericOutputBlackoilModule.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -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; + + auto fipArrays = std::vector {}; + 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(); + } } } diff --git a/opm/simulators/flow/GenericOutputBlackoilModule.hpp b/opm/simulators/flow/GenericOutputBlackoilModule.hpp index b1a6d50e0..add9a3635 100644 --- a/opm/simulators/flow/GenericOutputBlackoilModule.hpp +++ b/opm/simulators/flow/GenericOutputBlackoilModule.hpp @@ -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};