added: add dedicated class for output of logs

start by moving output of cumulative logs to the new class
This commit is contained in:
Arne Morten Kvarving 2023-08-04 12:12:28 +02:00
parent 43acfb6142
commit 91a4701fa4
5 changed files with 333 additions and 217 deletions

View File

@ -48,6 +48,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/flow/ExtraConvergenceOutputThread.cpp opm/simulators/flow/ExtraConvergenceOutputThread.cpp
opm/simulators/flow/FlowMainEbos.cpp opm/simulators/flow/FlowMainEbos.cpp
opm/simulators/flow/KeywordValidation.cpp opm/simulators/flow/KeywordValidation.cpp
opm/simulators/flow/LogOutputHelper.cpp
opm/simulators/flow/Main.cpp opm/simulators/flow/Main.cpp
opm/simulators/flow/NonlinearSolverEbos.cpp opm/simulators/flow/NonlinearSolverEbos.cpp
opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp
@ -425,6 +426,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/flow/NonlinearSolverEbos.hpp opm/simulators/flow/NonlinearSolverEbos.hpp
opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp
opm/simulators/flow/KeywordValidation.hpp opm/simulators/flow/KeywordValidation.hpp
opm/simulators/flow/LogOutputHelper.hpp
opm/simulators/flow/ValidationFunctions.hpp opm/simulators/flow/ValidationFunctions.hpp
opm/simulators/flow/partitionCells.hpp opm/simulators/flow/partitionCells.hpp
opm/simulators/flow/SubDomain.hpp opm/simulators/flow/SubDomain.hpp

View File

@ -161,6 +161,7 @@ EclGenericOutputBlackoilModule(const EclipseState& eclState,
, summaryConfig_(summaryConfig) , summaryConfig_(summaryConfig)
, summaryState_(summaryState) , summaryState_(summaryState)
, interRegionFlows_(numCells(eclState), defineInterRegionFlowArrays(eclState, summaryConfig)) , interRegionFlows_(numCells(eclState), defineInterRegionFlowArrays(eclState, summaryConfig))
, logOutput_(eclState, schedule, summaryState)
, enableEnergy_(enableEnergy) , enableEnergy_(enableEnergy)
, enableTemperature_(enableTemperature) , enableTemperature_(enableTemperature)
, enableSolvent_(enableSolvent) , enableSolvent_(enableSolvent)
@ -222,160 +223,10 @@ template<class FluidSystem, class Scalar>
void EclGenericOutputBlackoilModule<FluidSystem,Scalar>:: void EclGenericOutputBlackoilModule<FluidSystem,Scalar>::
outputCumLog(size_t reportStepNum, const bool substep, bool forceDisableCumOutput) outputCumLog(size_t reportStepNum, const bool substep, bool forceDisableCumOutput)
{ {
if (!substep) { if (!substep && !forceDisableCumOutput) {
ScalarBuffer tmp_values(WellCumDataType::numWCValues, 0.0); logOutput_.cumulative(reportStepNum,
StringBuffer tmp_names(WellCumDataType::numWCNames, ""); [this](const std::string& name)
outputCumulativeReport_(tmp_values, tmp_names, forceDisableCumOutput); { return this->isDefunctParallelWell(name); });
const auto& st = summaryState_;
for (const auto& gname: schedule_.groupNames()) {
auto gName = static_cast<std::string>(gname);
auto get = [&st, &gName](const std::string& vector)
{
const auto key = vector + ':' + gName;
return st.has(key) ? st.get(key) : 0.0;
};
tmp_names[0] = gname;
if (tmp_names[0] == "FIELD"){
tmp_values[2] = st.get("FOPT", 0.0); //WellCumDataType::OilProd
tmp_values[3] = st.get("FWPT", 0.0); //WellCumDataType::WaterProd
tmp_values[4] = st.get("FGPT", 0.0); //WellCumDataType::GasProd
tmp_values[5] = st.get("FVPT", 0.0);//WellCumDataType::FluidResVolProd
tmp_values[6] = st.get("FOIT", 0.0); //WellCumDataType::OilInj
tmp_values[7] = st.get("FWIT", 0.0); //WellCumDataType::WaterInj
tmp_values[8] = st.get("FGIT", 0.0); //WellCumDataType::GasInj
tmp_values[9] = st.get("FVIT", 0.0);//WellCumDataType::FluidResVolInj
}
else {
tmp_values[2] = get("GOPT"); //WellCumDataType::OilProd
tmp_values[3] = get("GWPT"); //WellCumDataType::WaterProd
tmp_values[4] = get("GGPT"); //WellCumDataType::GasProd
tmp_values[5] = get("GVPT");//WellCumDataType::FluidResVolProd
tmp_values[6] = get("GOIT"); //WellCumDataType::OilInj
tmp_values[7] = get("GWIT"); //WellCumDataType::WaterInj
tmp_values[8] = get("GGIT"); //WellCumDataType::GasInj
tmp_values[9] = get("GVIT");//WellCumDataType::FluidResVolInj
}
outputCumulativeReport_(tmp_values, tmp_names, forceDisableCumOutput);
}
for (const auto& wname : schedule_.wellNames(reportStepNum)) {
// don't bother with wells not on this process
if (isDefunctParallelWell(wname)) {
continue;
}
const auto& well = schedule_.getWell(wname, reportStepNum);
tmp_names[0] = wname; //WellCumDataType::WellName
auto wName = static_cast<std::string>(wname);
auto get = [&st, &wName](const std::string& vector)
{
const auto key = vector + ':' + wName;
return st.has(key) ? st.get(key) : 0.0;
};
if (well.isInjector()) {
const auto& controls = well.injectionControls(st);
const auto ctlMode = controls.cmode;
const auto injType = controls.injector_type;
using CMode = ::Opm::Well::InjectorCMode;
using WType = ::Opm::InjectorType;
auto ftype = [](const auto wtype) -> std::string
{
switch (wtype) {
case WType::OIL: return "Oil";
case WType::WATER: return "Wat";
case WType::GAS: return "Gas";
case WType::MULTI: return "Multi";
default:
{
return "";
}
}
};
auto fctl = [](const auto wmctl) -> std::string
{
switch (wmctl) {
case CMode::RATE: return "RATE";
case CMode::RESV: return "RESV";
case CMode::THP: return "THP";
case CMode::BHP: return "BHP";
case CMode::GRUP: return "GRUP";
default:
{
return "";
}
}
};
tmp_names[1] = "INJ"; //WellCumDataType::WellType
const auto flowctl = fctl(ctlMode);
if (flowctl == "RATE") //WellCumDataType::WellCTRL
{
const auto flowtype = ftype(injType);
if(flowtype == "Oil"){ tmp_names[2] = "ORAT"; }
else if(flowtype == "Wat"){ tmp_names[2] = "WRAT"; }
else if(flowtype == "Gas"){ tmp_names[2] = "GRAT"; }
}
else
{
tmp_names[2] = flowctl;
}
}
else if (well.isProducer()) {
const auto& controls = well.productionControls(st);
using CMode = ::Opm::Well::ProducerCMode;
auto fctl = [](const auto wmctl) -> std::string
{
switch (wmctl) {
case CMode::ORAT: return "ORAT";
case CMode::WRAT: return "WRAT";
case CMode::GRAT: return "GRAT";
case CMode::LRAT: return "LRAT";
case CMode::RESV: return "RESV";
case CMode::THP: return "THP";
case CMode::BHP: return "BHP";
case CMode::CRAT: return "CRAT";
case CMode::GRUP: return "GRUP";
default:
{
return "none";
}
}
};
tmp_names[1] = "PROD"; //WellProdDataType::CTRLMode
tmp_names[2] = fctl(controls.cmode); //WellProdDataType::CTRLMode
}
tmp_values[0] = well.getHeadI() + 1; //WellCumDataType::wellLocationi
tmp_values[1] = well.getHeadJ() + 1; //WellCumDataType::wellLocationj
tmp_values[2] = get("WOPT"); //WellCumDataType::OilProd
tmp_values[3] = get("WWPT"); //WellCumDataType::WaterProd
tmp_values[4] = get("WGPT"); //WellCumDataType::GasProd
tmp_values[5] = get("WVPT");//WellCumDataType::FluidResVolProd
tmp_values[6] = get("WOIT"); //WellCumDataType::OilInj
tmp_values[7] = get("WWIT"); //WellCumDataType::WaterInj
tmp_values[8] = get("WGIT"); //WellCumDataType::GasInj
tmp_values[9] = get("WVIT");//WellCumDataType::FluidResVolInj
outputCumulativeReport_(tmp_values, tmp_names, forceDisableCumOutput);
}
} }
} }
@ -1637,44 +1488,6 @@ outputInjectionReport_(const ScalarBuffer& wellInj,
OpmLog::note(ss.str()); OpmLog::note(ss.str());
} }
template<class FluidSystem,class Scalar>
void EclGenericOutputBlackoilModule<FluidSystem,Scalar>::
outputCumulativeReport_(const ScalarBuffer& wellCum,
const StringBuffer& wellCumNames,
const bool forceDisableCumOutput)
{
if (forceDisableCumOutput)
return;
const UnitSystem& units = eclState_.getUnits();
std::ostringstream ss;
if (wellCumNames[WellCumDataType::WellName].empty()) {
ss << "=================================================== CUMULATIVE PRODUCTION/INJECTION REPORT =========================================\n"
<< ": WELL : LOCATION : WELL :CTRL: OIL : WATER : GAS : Prod : OIL : WATER : GAS : INJ :\n"
<< ": NAME : (I,J,K) : TYPE :MODE: PROD : PROD : PROD : RES.VOL. : INJ : INJ : INJ : RES.VOL. :\n";
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_METRIC) {
ss << ": : : : : MSCM : MSCM : MMSCM : MRCM : MSCM : MSCM : MMSCM : MRCM :\n";
}
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
ss << ": : : : : MSTB : MSTB : MMSCF : MRB : MSTB : MSTB : MMSCF : MRB :\n";
}
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_LAB) {
ss << ": : : : : MSCC : MSCC : MMSCC : MRCC : MSCC : MSCC : MMSCC : MRCC :\n";
}
ss << "====================================================================================================================================\n";
}
else {
if (wellCum[WellCumDataType::WellLocationi] < 1) {
ss << std::right << std::fixed << std::setprecision(0) << ":" << std::setw (8) << wellCumNames[WellCumDataType::WellName] << ":" << std::setw(11) << "" << ":" << std::setw(8) << wellCumNames[WellCumDataType::WellType] << ":" << std::setw(4) << wellCumNames[WellCumDataType::WellCTRL] << ":" << std::setprecision(1) << std::setw(11) << wellCum[WellCumDataType::OilProd]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::WaterProd]/1000 << ":" << std::setw(11)<< wellCum[WellCumDataType::GasProd]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::FluidResVolProd]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::OilInj]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::WaterInj]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::GasInj]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::FluidResVolInj]/1000 << ": \n";
}
else {
ss << std::right << std::fixed << std::setprecision(0) << ":" << std::setw (8) << wellCumNames[WellCumDataType::WellName] << ":" << std::setw(5) << wellCum[WellCumDataType::WellLocationi] << "," << std::setw(5) << wellCum[WellCumDataType::WellLocationj] << ":" << std::setw(8) << wellCumNames[WellCumDataType::WellType] << ":" << std::setw(4) << wellCumNames[WellCumDataType::WellCTRL] << ":" << std::setprecision(1) << std::setw(11) << wellCum[WellCumDataType::OilProd]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::WaterProd]/1000 << ":" << std::setw(11)<< wellCum[WellCumDataType::GasProd]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::FluidResVolProd]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::OilInj]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::WaterInj]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::GasInj]/1000 << ":" << std::setw(11) << wellCum[WellCumDataType::FluidResVolInj]/1000 << ": \n";
}
ss << ":--------:-----------:--------:----:------------:----------:-----------:-----------:------------:----------:-----------:-----------: \n";
}
OpmLog::note(ss.str());
}
template<class FluidSystem,class Scalar> template<class FluidSystem,class Scalar>
bool EclGenericOutputBlackoilModule<FluidSystem,Scalar>:: bool EclGenericOutputBlackoilModule<FluidSystem,Scalar>::
isOutputCreationDirective_(const std::string& keyword) isOutputCreationDirective_(const std::string& keyword)

View File

@ -28,6 +28,7 @@
#include <opm/output/data/Wells.hpp> #include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/Inplace.hpp> #include <opm/output/eclipse/Inplace.hpp>
#include <opm/simulators/flow/LogOutputHelper.hpp>
#include <opm/simulators/utils/ParallelCommunication.hpp> #include <opm/simulators/utils/ParallelCommunication.hpp>
#include <array> #include <array>
@ -339,28 +340,6 @@ protected:
static constexpr int numWINames = 4; static constexpr int numWINames = 4;
}; };
struct WellCumDataType
{
enum WCId
{
WellLocationi = 0, //WLi
WellLocationj = 1, //WLj
OilProd = 2, //OP
WaterProd = 3, //WP
GasProd = 4, //GP
FluidResVolProd = 5, //FRVP
OilInj = 6, //OI
WaterInj = 7, //WI
GasInj = 8, //GI
FluidResVolInj = 9, //FRVI
WellName = 0, //WName
WellType = 1, //WType
WellCTRL = 2, //WCTRL
};
static constexpr int numWCValues = 10;
static constexpr int numWCNames = 3;
};
void doAllocBuffers(unsigned bufferSize, void doAllocBuffers(unsigned bufferSize,
unsigned reportStepNum, unsigned reportStepNum,
const bool substep, const bool substep,
@ -386,9 +365,6 @@ protected:
void outputInjectionReport_(const ScalarBuffer& wellInj, void outputInjectionReport_(const ScalarBuffer& wellInj,
const StringBuffer& wellInjNames, const StringBuffer& wellInjNames,
const bool forceDisableInjOutput); const bool forceDisableInjOutput);
void outputCumulativeReport_(const ScalarBuffer& wellCum,
const StringBuffer& wellCumNames,
const bool forceDisableCumOutput);
void outputFipLogImpl(const Inplace& inplace) const; void outputFipLogImpl(const Inplace& inplace) const;
@ -444,6 +420,7 @@ protected:
const SummaryState& summaryState_; const SummaryState& summaryState_;
EclInterRegFlowMap interRegionFlows_; EclInterRegFlowMap interRegionFlows_;
LogOutputHelper<Scalar> logOutput_;
bool enableEnergy_; bool enableEnergy_;
bool enableTemperature_; bool enableTemperature_;

View File

@ -0,0 +1,245 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// 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 <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
#include <config.h>
#include <opm/simulators/flow/LogOutputHelper.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <iomanip>
#include <sstream>
#include <vector>
namespace Opm {
template<class Scalar>
LogOutputHelper<Scalar>::LogOutputHelper(const EclipseState& eclState,
const Schedule& schedule,
const SummaryState& summaryState)
: eclState_(eclState)
, schedule_(schedule)
, summaryState_(summaryState)
{}
template<class Scalar>
void LogOutputHelper<Scalar>::
cumulative(const std::size_t reportStepNum,
std::function<bool(const std::string&)> isDefunct) const
{
std::vector<Scalar> tmp_values(WellCumDataType::numWCValues, 0.0);
std::vector<std::string> tmp_names(WellCumDataType::numWCNames, "");
this->outputCumulativeReport_(tmp_values, tmp_names);
const auto& st = summaryState_;
for (const auto& gname : schedule_.groupNames()) {
auto gName = static_cast<std::string>(gname);
auto get = [&st, &gName](const std::string& vector)
{
const auto key = vector + ':' + gName;
return st.has(key) ? st.get(key) : 0.0;
};
tmp_names[0] = gname;
if (tmp_names[0] == "FIELD") {
tmp_values[2] = st.get("FOPT", 0.0); // WellCumDataType::OilProd
tmp_values[3] = st.get("FWPT", 0.0); // WellCumDataType::WaterProd
tmp_values[4] = st.get("FGPT", 0.0); // WellCumDataType::GasProd
tmp_values[5] = st.get("FVPT", 0.0); // WellCumDataType::FluidResVolProd
tmp_values[6] = st.get("FOIT", 0.0); // WellCumDataType::OilInj
tmp_values[7] = st.get("FWIT", 0.0); // WellCumDataType::WaterInj
tmp_values[8] = st.get("FGIT", 0.0); // WellCumDataType::GasInj
tmp_values[9] = st.get("FVIT", 0.0); // WellCumDataType::FluidResVolInj
} else {
tmp_values[2] = get("GOPT"); // WellCumDataType::OilProd
tmp_values[3] = get("GWPT"); // WellCumDataType::WaterProd
tmp_values[4] = get("GGPT"); // WellCumDataType::GasProd
tmp_values[5] = get("GVPT"); // WellCumDataType::FluidResVolProd
tmp_values[6] = get("GOIT"); // WellCumDataType::OilInj
tmp_values[7] = get("GWIT"); // WellCumDataType::WaterInj
tmp_values[8] = get("GGIT"); // WellCumDataType::GasInj
tmp_values[9] = get("GVIT"); // WellCumDataType::FluidResVolInj
}
this->outputCumulativeReport_(tmp_values, tmp_names);
}
for (const auto& wname : schedule_.wellNames(reportStepNum)) {
// don't bother with wells not on this process
if (isDefunct(wname)) {
continue;
}
const auto& well = schedule_.getWell(wname, reportStepNum);
tmp_names[0] = wname; // WellCumDataType::WellName
auto wName = static_cast<std::string>(wname);
auto get = [&st, &wName](const std::string& vector)
{
const auto key = vector + ':' + wName;
return st.has(key) ? st.get(key) : 0.0;
};
if (well.isInjector()) {
const auto& controls = well.injectionControls(st);
const auto ctlMode = controls.cmode;
const auto injType = controls.injector_type;
using CMode = ::Opm::Well::InjectorCMode;
using WType = ::Opm::InjectorType;
auto ftype = [](const auto wtype) -> std::string
{
switch (wtype) {
case WType::OIL: return "Oil";
case WType::WATER: return "Wat";
case WType::GAS: return "Gas";
case WType::MULTI: return "Multi";
default: return "";
}
};
auto fctl = [](const auto wmctl) -> std::string
{
switch (wmctl) {
case CMode::RATE: return "RATE";
case CMode::RESV: return "RESV";
case CMode::THP: return "THP";
case CMode::BHP: return "BHP";
case CMode::GRUP: return "GRUP";
default: return "";
}
};
tmp_names[1] = "INJ"; // WellCumDataType::WellType
const auto flowctl = fctl(ctlMode);
if (flowctl == "RATE") { // WellCumDataType::WellCTRL
const auto flowtype = ftype(injType);
if (flowtype == "Oil") {
tmp_names[2] = "ORAT";
} else if (flowtype == "Wat") {
tmp_names[2] = "WRAT";
} else if (flowtype == "Gas") {
tmp_names[2] = "GRAT";
}
} else {
tmp_names[2] = flowctl;
}
} else if (well.isProducer()) {
const auto& controls = well.productionControls(st);
using CMode = ::Opm::Well::ProducerCMode;
auto fctl = [](const auto wmctl) -> std::string
{
switch (wmctl) {
case CMode::ORAT: return "ORAT";
case CMode::WRAT: return "WRAT";
case CMode::GRAT: return "GRAT";
case CMode::LRAT: return "LRAT";
case CMode::RESV: return "RESV";
case CMode::THP: return "THP";
case CMode::BHP: return "BHP";
case CMode::CRAT: return "CRAT";
case CMode::GRUP: return "GRUP";
default:
{
return "none";
}
}
};
tmp_names[1] = "PROD"; //WellProdDataType::CTRLMode
tmp_names[2] = fctl(controls.cmode); //WellProdDataType::CTRLMode
}
tmp_values[0] = well.getHeadI() + 1; //WellCumDataType::wellLocationi
tmp_values[1] = well.getHeadJ() + 1; //WellCumDataType::wellLocationj
tmp_values[2] = get("WOPT"); //WellCumDataType::OilProd
tmp_values[3] = get("WWPT"); //WellCumDataType::WaterProd
tmp_values[4] = get("WGPT"); //WellCumDataType::GasProd
tmp_values[5] = get("WVPT");//WellCumDataType::FluidResVolProd
tmp_values[6] = get("WOIT"); //WellCumDataType::OilInj
tmp_values[7] = get("WWIT"); //WellCumDataType::WaterInj
tmp_values[8] = get("WGIT"); //WellCumDataType::GasInj
tmp_values[9] = get("WVIT");//WellCumDataType::FluidResVolInj
outputCumulativeReport_(tmp_values, tmp_names);
}
}
template<class Scalar>
void LogOutputHelper<Scalar>::
outputCumulativeReport_(const std::vector<Scalar>& wellCum,
const std::vector<std::string>& wellCumNames) const
{
const UnitSystem& units = eclState_.getUnits();
std::ostringstream ss;
if (wellCumNames[WellCumDataType::WellName].empty()) {
ss << "=================================================== CUMULATIVE PRODUCTION/INJECTION REPORT =========================================\n"
<< ": WELL : LOCATION : WELL :CTRL: OIL : WATER : GAS : Prod : OIL : WATER : GAS : INJ :\n"
<< ": NAME : (I,J,K) : TYPE :MODE: PROD : PROD : PROD : RES.VOL. : INJ : INJ : INJ : RES.VOL. :\n";
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_METRIC) {
ss << ": : : : : MSCM : MSCM : MMSCM : MRCM : MSCM : MSCM : MMSCM : MRCM :\n";
} else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
ss << ": : : : : MSTB : MSTB : MMSCF : MRB : MSTB : MSTB : MMSCF : MRB :\n";
} else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_LAB) {
ss << ": : : : : MSCC : MSCC : MMSCC : MRCC : MSCC : MSCC : MMSCC : MRCC :\n";
}
ss << "====================================================================================================================================\n";
} else {
if (wellCum[WellCumDataType::WellLocationi] < 1) {
ss << std::right << std::fixed << std::setprecision(0) << ":" << std::setw (8)
<< wellCumNames[WellCumDataType::WellName] << ":"
<< std::setw(11) << "" << ":"
<< std::setw(8) << wellCumNames[WellCumDataType::WellType] << ":"
<< std::setw(4) << wellCumNames[WellCumDataType::WellCTRL] << ":"
<< std::setprecision(1) << std::setw(11) << wellCum[WellCumDataType::OilProd] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::WaterProd] / 1000.0 << ":"
<< std::setw(11)<< wellCum[WellCumDataType::GasProd] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::FluidResVolProd] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::OilInj] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::WaterInj] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::GasInj] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::FluidResVolInj] / 1000.0 << ": \n";
} else {
ss << std::right << std::fixed << std::setprecision(0) << ":"
<< std::setw (8) << wellCumNames[WellCumDataType::WellName] << ":"
<< std::setw(5) << wellCum[WellCumDataType::WellLocationi] << ","
<< std::setw(5) << wellCum[WellCumDataType::WellLocationj] << ":"
<< std::setw(8) << wellCumNames[WellCumDataType::WellType] << ":"
<< std::setw(4) << wellCumNames[WellCumDataType::WellCTRL] << ":"
<< std::setprecision(1) << std::setw(11) << wellCum[WellCumDataType::OilProd] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::WaterProd] / 1000.0 << ":"
<< std::setw(11)<< wellCum[WellCumDataType::GasProd] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::FluidResVolProd] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::OilInj] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::WaterInj] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::GasInj] / 1000.0 << ":"
<< std::setw(11) << wellCum[WellCumDataType::FluidResVolInj] / 1000.0 << ": \n";
}
ss << ":--------:-----------:--------:----:------------:----------:-----------:-----------:------------:----------:-----------:-----------: \n";
}
OpmLog::note(ss.str());
}
template class LogOutputHelper<double>;
} // namespace Opm

View File

@ -0,0 +1,79 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// 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 <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*/
#ifndef LOG_OUTPUT_HELPER_HPP
#define LOG_OUTPUT_HELPER_HPP
#include <cstddef>
#include <functional>
#include <string>
namespace Opm {
class EclipseState;
class Schedule;
class SummaryState;
template<class Scalar>
class LogOutputHelper {
public:
LogOutputHelper(const EclipseState& eclState,
const Schedule& schedule,
const SummaryState& st);
//! \brief Write cumulative production and injection reports to output.
void cumulative(const std::size_t reportStepNum,
std::function<bool(const std::string&)> isDefunct) const;
private:
void outputCumulativeReport_(const std::vector<Scalar>& wellCum,
const std::vector<std::string>& wellCumNames) const;
struct WellCumDataType
{
enum WCId
{
WellLocationi = 0, // WLi
WellLocationj = 1, // WLj
OilProd = 2, // OP
WaterProd = 3, // WP
GasProd = 4, // GP
FluidResVolProd = 5, // FRVP
OilInj = 6, // OI
WaterInj = 7, // WI
GasInj = 8, // GI
FluidResVolInj = 9, // FRVI
WellName = 0, // WName
WellType = 1, // WType
WellCTRL = 2, // WCTRL
};
static constexpr int numWCValues = 10;
static constexpr int numWCNames = 3;
};
const EclipseState& eclState_;
const Schedule& schedule_;
const SummaryState& summaryState_;
};
} // namespace Opm
#endif // LOG_OUTPUT_HELPER_HPP