From 096e0e11c9f8f5acea777dc859501c85983e9955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 19 Sep 2024 19:30:55 +0200 Subject: [PATCH 1/2] Initialise Output Module's Boolean Flags While here, also insert a few blank lines in the copyright statement to make it more in line with the rest of opm-simulators. --- .../flow/GenericOutputBlackoilModule.cpp | 3 ++ .../flow/GenericOutputBlackoilModule.hpp | 47 ++++++++++--------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/opm/simulators/flow/GenericOutputBlackoilModule.cpp b/opm/simulators/flow/GenericOutputBlackoilModule.cpp index f57fe9a7b..c8b1d5cf9 100644 --- a/opm/simulators/flow/GenericOutputBlackoilModule.cpp +++ b/opm/simulators/flow/GenericOutputBlackoilModule.cpp @@ -2,14 +2,17 @@ // vi: set et ts=4 sw=4 sts=4: /* 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 2 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 . Consult the COPYING file in the top-level source directory of this diff --git a/opm/simulators/flow/GenericOutputBlackoilModule.hpp b/opm/simulators/flow/GenericOutputBlackoilModule.hpp index 76cd8ee6c..b1a6d50e0 100644 --- a/opm/simulators/flow/GenericOutputBlackoilModule.hpp +++ b/opm/simulators/flow/GenericOutputBlackoilModule.hpp @@ -2,14 +2,17 @@ // vi: set et ts=4 sw=4 sts=4: /* 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 2 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 . Consult the COPYING file in the top-level source directory of this @@ -387,30 +390,30 @@ protected: InterRegFlowMap interRegionFlows_; LogOutputHelper logOutput_; - bool enableEnergy_; - bool enableTemperature_; - bool enableMech_; + bool enableEnergy_{false}; + bool enableTemperature_{false}; + bool enableMech_{false}; - bool enableSolvent_; - bool enablePolymer_; - bool enableFoam_; - bool enableBrine_; - bool enableSaltPrecipitation_; - bool enableExtbo_; - bool enableMICP_; + bool enableSolvent_{false}; + bool enablePolymer_{false}; + bool enableFoam_{false}; + bool enableBrine_{false}; + bool enableSaltPrecipitation_{false}; + bool enableExtbo_{false}; + bool enableMICP_{false}; - bool forceDisableFipOutput_; - bool forceDisableFipresvOutput_; - bool outputFipRestart_; - bool computeFip_; + bool forceDisableFipOutput_{false}; + bool forceDisableFipresvOutput_{false}; + bool outputFipRestart_{false}; + bool computeFip_{false}; - bool anyFlows_; - bool anyFlores_; - bool blockFlows_; - bool enableFlows_; - bool enableFlores_; - bool enableFlowsn_; - bool enableFloresn_; + bool anyFlows_{false}; + bool anyFlores_{false}; + bool blockFlows_{false}; + bool enableFlows_{false}; + bool enableFlores_{false}; + bool enableFlowsn_{false}; + bool enableFloresn_{false}; std::unordered_map fip_; std::unordered_map> regions_; @@ -528,7 +531,7 @@ protected: std::vector> cnvData_; //!< Data for CNV_xxx arrays std::optional initialInplace_; - bool local_data_valid_; + bool local_data_valid_{false}; std::optional regionAvgDensity_; }; From a38704ecb04e6a399cce017fb2a599d36192c891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 19 Sep 2024 19:37:19 +0200 Subject: [PATCH 2/2] 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. --- .../flow/GenericOutputBlackoilModule.cpp | 82 ++++++++++++++----- .../flow/GenericOutputBlackoilModule.hpp | 25 +++++- 2 files changed, 86 insertions(+), 21 deletions(-) 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};