From c03f794f9ce42559d7eb2fc4dfd2ae9f319ad371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 8 Dec 2023 13:44:33 +0100 Subject: [PATCH] Remove Dashed Lines Between Records in PRT File Reports This commit splits the production, injection, and cumulative *Report_() functions into three logically distinct parts, one for outputting the report header (begin*Report_()), one for outputting a single report record (output*ReportRecord_()), and one for ending the report (end*Report_()). This simplifies the logic of the *Record_() member functions since they no longer need to infer the context which is already available in the caller and can perform a more narrow task than before. With this separation we're also able to remove the dashed lines which would previously separate each report record, thereby creating PRT file report sheets which have a more expected layout. Moreover, as an aid to future maintenance, we also factor out common code for the well and group cases in each *Record_() function. Finally, fix a unit conversion problem in the report values for cumulative gas quantities. The sheet header states that we should be outputting values in 'MM' prefixed units, but we were only scaling the gas values by a factor of 1000 instead of 1000*1000. In other words, the injection and production gas values in the cumulative sheet were off by a factor of 1000. --- opm/simulators/flow/LogOutputHelper.cpp | 391 ++++++++++++++---------- opm/simulators/flow/LogOutputHelper.hpp | 18 +- tests/test_LogOutputHelper.cpp | 31 +- 3 files changed, 253 insertions(+), 187 deletions(-) diff --git a/opm/simulators/flow/LogOutputHelper.cpp b/opm/simulators/flow/LogOutputHelper.cpp index ef0833610..0d02e8557 100644 --- a/opm/simulators/flow/LogOutputHelper.cpp +++ b/opm/simulators/flow/LogOutputHelper.cpp @@ -94,9 +94,10 @@ void LogOutputHelper:: cumulative(const std::size_t reportStepNum, std::function isDefunct) const { + this->beginCumulativeReport_(); + std::vector tmp_values(WellCumDataType::numWCValues, 0.0); std::vector tmp_names(WellCumDataType::numWCNames, ""); - this->outputCumulativeReport_(tmp_values, tmp_names); const auto& st = summaryState_; for (const auto& gname : schedule_.groupNames()) { @@ -129,7 +130,7 @@ cumulative(const std::size_t reportStepNum, tmp_values[9] = get("GVIT"); // WellCumDataType::FluidResVolInj } - this->outputCumulativeReport_(tmp_values, tmp_names); + this->outputCumulativeReportRecord_(tmp_values, tmp_names); } for (const auto& wname : schedule_.wellNames(reportStepNum)) { @@ -225,8 +226,10 @@ cumulative(const std::size_t reportStepNum, tmp_values[8] = get("WGIT"); // WellCumDataType::GasInj tmp_values[9] = get("WVIT"); // WellCumDataType::FluidResVolInj - this->outputCumulativeReport_(tmp_values, tmp_names); + this->outputCumulativeReportRecord_(tmp_values, tmp_names); } + + this->endCumulativeReport_(); } template @@ -336,9 +339,10 @@ void LogOutputHelper:: injection(const std::size_t reportStepNum, std::function isDefunct) const { + this->beginInjectionReport_(); + std::vector tmp_values(WellInjDataType::numWIValues, 0.0); std::vector tmp_names(WellInjDataType::numWINames, ""); - this->outputInjectionReport_(tmp_values, tmp_names); const auto& st = summaryState_; for (const auto& gname : schedule_.groupNames()) { @@ -362,7 +366,7 @@ injection(const std::size_t reportStepNum, tmp_values[5] = get("GVIR"); // WellInjDataType::FluidResVol } - this->outputInjectionReport_(tmp_values, tmp_names); + this->outputInjectionReportRecord_(tmp_values, tmp_names); } for (const auto& wname : schedule_.wellNames(reportStepNum)) { @@ -450,8 +454,10 @@ injection(const std::size_t reportStepNum, tmp_values[7] = get("WTHP"); // WellInjDataType::THP //tmp_values[8] = 0; // WellInjDataType::SteadyStateII - this->outputInjectionReport_(tmp_values, tmp_names); + this->outputInjectionReportRecord_(tmp_values, tmp_names); } + + this->endInjectionReport_(); } template @@ -459,9 +465,10 @@ void LogOutputHelper:: production(const std::size_t reportStepNum, std::function isDefunct) const { + this->beginProductionReport_(); + std::vector tmp_values(WellProdDataType::numWPValues, 0.0); std::vector tmp_names(WellProdDataType::numWPNames, ""); - this->outputProductionReport_(tmp_values, tmp_names); const auto& st = summaryState_; for (const auto& gname : schedule_.groupNames()) { @@ -494,7 +501,7 @@ production(const std::size_t reportStepNum, tmp_values[8] = 0.0; } - this->outputProductionReport_(tmp_values, tmp_names); + this->outputProductionReportRecord_(tmp_values, tmp_names); } for (const auto& wname : schedule_.wellNames(reportStepNum)) { @@ -559,181 +566,237 @@ production(const std::size_t reportStepNum, tmp_values[8] = 0.0; } - this->outputProductionReport_(tmp_values, tmp_names); + this->outputProductionReportRecord_(tmp_values, tmp_names); } + + this->endProductionReport_(); +} + +template +void LogOutputHelper::beginCumulativeReport_() const +{ + const auto unitType = this->eclState_.getUnits().getType(); + + std::ostringstream ss; + + ss << "\n=================================================== 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 (unitType == UnitSystem::UnitType::UNIT_TYPE_METRIC) { + ss << ": : : : : MSCM : MSCM : MMSCM : MRCM : MSCM : MSCM : MMSCM : MRCM :\n"; + } else if (unitType == UnitSystem::UnitType::UNIT_TYPE_FIELD) { + ss << ": : : : : MSTB : MSTB : MMSCF : MRB : MSTB : MSTB : MMSCF : MRB :\n"; + } else if (unitType == UnitSystem::UnitType::UNIT_TYPE_LAB) { + ss << ": : : : : MSCC : MSCC : MMSCC : MRCC : MSCC : MSCC : MMSCC : MRCC :\n"; + } + + ss << "===================================================================================================================================="; + + OpmLog::note(ss.str()); +} + +template +void LogOutputHelper::endCumulativeReport_() const +{ + const auto ss = std::string { ":--------:-----------:--------:----:-----------:-----------:-----------:-----------:-----------:-----------:-----------:-----------:" }; + + OpmLog::note(ss); } template void LogOutputHelper:: -outputCumulativeReport_(const std::vector& wellCum, - const std::vector& wellCumNames) const +outputCumulativeReportRecord_(const std::vector& wellCum, + const std::vector& wellCumNames) const { - const UnitSystem& units = eclState_.getUnits(); std::ostringstream ss; - if (wellCumNames[WellCumDataType::WellName].empty()) { - ss << "\n=================================================== 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 << ":--------:-----------:--------:----:-----------:-----------:-----------:-----------:------------:----------:-----------:-----------:"; - } - ss << "===================================================================================================================================="; + + ss << std::right << std::fixed << std::setprecision(0) << ':' + << std::setw(8) << wellCumNames[WellCumDataType::WellName] << ':'; + + if (wellCum[WellCumDataType::WellLocationi] < 1) { + ss << std::setw(11) << "" << ':'; } 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 << ":--------:-----------:--------:----:-----------:-----------:-----------:-----------:------------:----------:-----------:-----------:"; + ss << std::setw( 5) << wellCum[WellCumDataType::WellLocationi] << ',' + << std::setw( 5) << wellCum[WellCumDataType::WellLocationj] << ':'; } + + auto scaledValue = [&wellCum](const typename WellCumDataType::WCId quantity) + { + // Unit M* + return wellCum[quantity] / 1000.0; + }; + + auto scaledGasValue = [&wellCum](const typename WellCumDataType::WCId quantity) + { + // Unit MM* + return wellCum[quantity] / (1000.0 * 1000.0); + }; + + ss << std::setw( 8) << wellCumNames[WellCumDataType::WCId::WellType] << ':' + << std::setw( 4) << wellCumNames[WellCumDataType::WCId::WellCTRL] << ':' << std::setprecision(1) + << std::setw(11) << scaledValue(WellCumDataType::WCId::OilProd) << ':' + << std::setw(11) << scaledValue(WellCumDataType::WCId::WaterProd) << ':' + << std::setw(11) << scaledGasValue(WellCumDataType::WCId::GasProd) << ':' + << std::setw(11) << scaledValue(WellCumDataType::WCId::FluidResVolProd) << ':' + << std::setw(11) << scaledValue(WellCumDataType::WCId::OilInj) << ':' + << std::setw(11) << scaledValue(WellCumDataType::WCId::WaterInj) << ':' + << std::setw(11) << scaledGasValue(WellCumDataType::WCId::GasInj) << ':' + << std::setw(11) << scaledValue(WellCumDataType::WCId::FluidResVolInj) << ':'; + + OpmLog::note(ss.str()); +} + +template +void LogOutputHelper::beginInjectionReport_() const +{ + const auto unitType = this->eclState_.getUnits().getType(); + + std::ostringstream ss; + ss << "\n=================================================== INJECTION REPORT ========================================\n"//===================== \n" + << ": WELL : LOCATION : CTRL : CTRL : CTRL : OIL : WATER : GAS : FLUID : BHP OR : THP OR :\n"// STEADY-ST II :\n" + << ": NAME : (I,J,K) : MODE : MODE : MODE : RATE : RATE : RATE : RES.VOL. : CON.PR.: BLK.PR.:\n";// OR POTENTIAL :\n"; + + if (unitType == UnitSystem::UnitType::UNIT_TYPE_METRIC) { + ss << ": : : OIL : WAT : GAS : SCM/DAY : SCM/DAY : SCM/DAY : RCM/DAY : BARSA : BARSA :\n";// :\n"; + } else if (unitType == UnitSystem::UnitType::UNIT_TYPE_FIELD) { + ss << ": : : OIL : WAT : GAS : STB/DAY : STB/DAY : MSCF/DAY : RB/DAY : PSIA : PSIA :\n";// :\n"; + } else if (unitType == UnitSystem::UnitType::UNIT_TYPE_LAB) { + ss << ": : : OIL : WAT : GAS : SCC/HR : SCC/HR : SCC/HR : RCC/HR : ATMA : ATMA :\n";// :\n"; + } + + ss << "=============================================================================================================";//====================="; + + OpmLog::note(ss.str()); +} + +template +void LogOutputHelper::endInjectionReport_() const +{ + const auto ss = std::string { ":--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------:" }; + + OpmLog::note(ss); +} + +template +void LogOutputHelper:: +outputInjectionReportRecord_(const std::vector& wellInj, + const std::vector& wellInjNames) const +{ + const auto isWellRecord = + wellInj[WellProdDataType::WellLocationi] >= 1; + + std::ostringstream ss; + + ss << std::right << std::fixed << std::setprecision(0) << ':' + << std::setw(8) << wellInjNames[WellInjDataType::WellName] << ':'; + + if (! isWellRecord) { + ss << std::setw(11) << "" << ':'; + } else { + ss << std::setw( 5) << wellInj[WellInjDataType::WellLocationi] << ',' + << std::setw( 5) << wellInj[WellInjDataType::WellLocationj] << ':'; + } + + ss << std::setw( 6) << wellInjNames[WellInjDataType::CTRLModeOil] << ':' + << std::setw( 6) << wellInjNames[WellInjDataType::CTRLModeWat] << ':' + << std::setw( 6) << wellInjNames[WellInjDataType::CTRLModeGas] << ':' << std::setprecision(1) + << std::setw(11) << wellInj[WellInjDataType::OilRate] << ':' + << std::setw(11) << wellInj[WellInjDataType::WaterRate] << ':' + << std::setw(11) << wellInj[WellInjDataType::GasRate] << ':' + << std::setw(11) << wellInj[WellInjDataType::FluidResVol] << ':'; + + if (! isWellRecord) { + ss << std::setw(8) << "" << ':' << std::setw(8) << "" << ':'; //wellInj[WellInjDataType::SteadyStateII] << std::setw(10) << "\n" + } else { + ss << std::setw(8) << wellInj[WellInjDataType::BHP] << ':' + << std::setw(8) << wellInj[WellInjDataType::THP] << ':'; //wellInj[WellInjDataType::SteadyStateII] << std::setw(10) << "\n" + } + + OpmLog::note(ss.str()); +} + +template +void LogOutputHelper::beginProductionReport_() const +{ + const auto unitType = this->eclState_.getUnits().getType(); + + std::ostringstream ss; + ss << "\n======================================================= PRODUCTION REPORT =======================================================\n"//=================== \n" + << ": WELL : LOCATION :CTRL: OIL : WATER : GAS : FLUID : WATER : GAS/OIL : WAT/GAS : BHP OR : THP OR :\n"// STEADY-ST PI :\n" + << ": NAME : (I,J,K) :MODE: RATE : RATE : RATE : RES.VOL. : CUT : RATIO : RATIO : CON.PR.: BLK.PR.:\n";// OR POTN OF PREF. PH:\n"; + + if (unitType == UnitSystem::UnitType::UNIT_TYPE_METRIC) { + ss << ": : : : SCM/DAY : SCM/DAY : SCM/DAY : RCM/DAY : SCM/SCM : SCM/SCM : SCM/SCM : BARSA : BARSA :\n";// :\n"; + } else if (unitType == UnitSystem::UnitType::UNIT_TYPE_FIELD) { + ss << ": : : : STB/DAY : STB/DAY : MSCF/DAY : RB/DAY : : MSCF/STB : STB/MSCF : PSIA : PSIA :\n";// :\n"; + } else if (unitType == UnitSystem::UnitType::UNIT_TYPE_LAB) { + ss << ": : : : SCC/HR : SCC/HR : SCC/HR : RCC : SCC/SCC : SCC/SCC : SCC/SCC : ATMA : ATMA :\n";// :\n"; + } + + ss << "=================================================================================================================================";//==================="; + + OpmLog::note(ss.str()); +} + +template +void LogOutputHelper::endProductionReport_() const +{ + std::ostringstream ss; + + ss << ':' << std::setfill ('-') << std::setw (9) << ':' + << std::setfill ('-') << std::setw (12) << ':' + << std::setfill ('-') << std::setw ( 5) << ':' + << std::setfill ('-') << std::setw (12) << ':' + << std::setfill ('-') << std::setw (12) << ':' + << std::setfill ('-') << std::setw (12) << ':' + << std::setfill ('-') << std::setw (12) << ':' + << std::setfill ('-') << std::setw (12) << ':' + << std::setfill ('-') << std::setw (11) << ':' + << std::setfill ('-') << std::setw (13) << ':' + << std::setfill ('-') << std::setw ( 9) << ':' + << std::setfill ('-') << std::setw ( 9) << ':'; + OpmLog::note(ss.str()); } template void LogOutputHelper:: -outputInjectionReport_(const std::vector& wellInj, - const std::vector& wellInjNames) const +outputProductionReportRecord_(const std::vector& wellProd, + const std::vector& wellProdNames) const { - const UnitSystem& units = eclState_.getUnits(); - std::ostringstream ss; - if (wellInjNames[WellInjDataType::WellName].empty()) { - ss << "\n=================================================== INJECTION REPORT ========================================\n"//===================== \n" - << ": WELL : LOCATION : CTRL : CTRL : CTRL : OIL : WATER : GAS : FLUID : BHP OR : THP OR :\n"// STEADY-ST II :\n" - << ": NAME : (I,J,K) : MODE : MODE : MODE : RATE : RATE : RATE : RES.VOL. : CON.PR.: BLK.PR.:\n";// OR POTENTIAL :\n"; - if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_METRIC) { - ss << ": : : OIL : WAT : GAS : SCM/DAY : SCM/DAY : SCM/DAY : RCM/DAY : BARSA : BARSA :\n";// :\n"; - } else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) { - ss << ": : : OIL : WAT : GAS : STB/DAY : STB/DAY : MSCF/DAY : RB/DAY : PSIA : PSIA :\n";// :\n"; - } else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_LAB) { - ss << ": : : OIL : WAT : GAS : SCC/HR : SCC/HR : SCC/HR : RCC/HR : ATMA : ATMA :\n";// :\n"; - ss << ":--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------:";//--------------------:"; - } - ss << "==============================================================================================================";//====================="; - } else { - if (wellInj[WellInjDataType::WellLocationi] < 1) { - ss << std::right << std::fixed << std::setprecision(0) << ":" - << std::setw (8) << wellInjNames[WellInjDataType::WellName] << ":" - << std::setw(11) << "" << ":" - << std::setw(6) << wellInjNames[WellInjDataType::CTRLModeOil] << ":" - << std::setw(6) << wellInjNames[WellInjDataType::CTRLModeWat] << ":" - << std::setw(6) << wellInjNames[WellInjDataType::CTRLModeGas] << ":" - << std::setprecision(1) << std::setw(11) << wellInj[WellInjDataType::OilRate] << ":" - << std::setw(11) << wellInj[WellInjDataType::WaterRate] << ":" - << std::setw(11)<< wellInj[WellInjDataType::GasRate] << ":" - << std::setw(11) << wellInj[WellInjDataType::FluidResVol] << ":" - << std::setw(8)<< "" << ":" << std::setw(8)<< "" << ": \n";//wellInj[WellInjDataType::SteadyStateII] << std::setw(10) << "\n" - } else { - ss << std::right << std::fixed << std::setprecision(0) << ":" - << std::setw (8) << wellInjNames[WellInjDataType::WellName] << ":" - << std::setw(5) << wellInj[WellInjDataType::WellLocationi] << "," - << std::setw(5) << wellInj[WellInjDataType::WellLocationj] << ":" - << std::setw(6) << wellInjNames[WellInjDataType::CTRLModeOil] << ":" - << std::setw(6) << wellInjNames[WellInjDataType::CTRLModeWat] << ":" - << std::setw(6) << wellInjNames[WellInjDataType::CTRLModeGas] << ":" - << std::setprecision(1) << std::setw(11) << wellInj[WellInjDataType::OilRate] << ":" - << std::setw(11) << wellInj[WellInjDataType::WaterRate] << ":" - << std::setw(11) << wellInj[WellInjDataType::GasRate] << ":" - << std::setw(11) << wellInj[WellInjDataType::FluidResVol] << ":" - << std::setw(8) << wellInj[WellInjDataType::BHP] << ":" - << std::setw(8)<< wellInj[WellInjDataType::THP] << ": \n";//wellInj[WellInjDataType::SteadyStateII] << std::setw(10) << "\n" - } - ss << ":--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------:";//--------------------:"; - } - OpmLog::note(ss.str()); -} + const auto isWellRecord = + wellProd[WellProdDataType::WellLocationi] >= 1; -template -void LogOutputHelper:: -outputProductionReport_(const std::vector& wellProd, - const std::vector& wellProdNames) const -{ - const UnitSystem& units = eclState_.getUnits(); std::ostringstream ss; - if (wellProdNames[WellProdDataType::WellName].empty()) { - ss << "\n======================================================= PRODUCTION REPORT =======================================================\n"//=================== \n" - << ": WELL : LOCATION :CTRL: OIL : WATER : GAS : FLUID : WATER : GAS/OIL : WAT/GAS : BHP OR : THP OR :\n"// STEADY-ST PI :\n" - << ": NAME : (I,J,K) :MODE: RATE : RATE : RATE : RES.VOL. : CUT : RATIO : RATIO : CON.PR.: BLK.PR.:\n";// OR POTN OF PREF. PH:\n"; - if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_METRIC) { - ss << ": : : : SCM/DAY : SCM/DAY : SCM/DAY : RCM/DAY : SCM/SCM : SCM/SCM : SCM/SCM : BARSA : BARSA :\n";// :\n"; - } else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) { - ss << ": : : : STB/DAY : STB/DAY : MSCF/DAY : RB/DAY : : MSCF/STB : STB/MSCF : PSIA : PSIA :\n";// :\n"; - } else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_LAB) { - ss << ": : : : SCC/HR : SCC/HR : SCC/HR : RCC : SCC/SCC : SCC/SCC : SCC/SCC : ATMA : ATMA :\n";// :\n"; - } - ss << "=================================================================================================================================";//==================="; + + ss << std::right << std::fixed << ':' + << std::setw(8) << wellProdNames[WellProdDataType::WellName] << ':'; + + if (! isWellRecord) { + ss << std::setprecision(0) << std::setw(11) << "" << ':'; } else { - if (wellProd[WellProdDataType::WellLocationi] < 1) { - ss << std::right << std::fixed << ":" - << std::setw(8) << wellProdNames[WellProdDataType::WellName] << ":" - << std::setprecision(0) << std::setw(11) << "" << ":" - << std::setw(4) << wellProdNames[WellProdDataType::CTRLMode] << ":" - << std::setprecision(1) << std::setw(11) << wellProd[WellProdDataType::OilRate] << ":" - << std::setw(11) << wellProd[WellProdDataType::WaterRate] << ":" - << std::setw(11)<< wellProd[WellProdDataType::GasRate] << ":" - << std::setw(11) << wellProd[WellProdDataType::FluidResVol] << std::setprecision(3) << ":" - << std::setw(11) << wellProd[WellProdDataType::WaterCut] << std::setprecision(2) << ":" - << std::setw(10) << wellProd[WellProdDataType::GasOilRatio] << std::setprecision(4) << ":" - << std::setw(12) << wellProd[WellProdDataType::WatGasRatio] << std::setprecision(1) << ":" - << std::setw(8) << "" << ":" << std::setw(8) << "" << ": \n"; - } else { - ss << std::right << std::fixed << ":" - << std::setw (8) << wellProdNames[WellProdDataType::WellName] << ":" - << std::setprecision(0) << std::setw(5) << wellProd[WellProdDataType::WellLocationi] << "," - << std::setw(5) << wellProd[WellProdDataType::WellLocationj] << ":" - << std::setw(4) << wellProdNames[WellProdDataType::CTRLMode] << ":" - << std::setprecision(1) << std::setw(11) << wellProd[WellProdDataType::OilRate] << ":" - << std::setw(11) << wellProd[WellProdDataType::WaterRate] << ":" - << std::setw(11)<< wellProd[WellProdDataType::GasRate] << ":" - << std::setw(11) << wellProd[WellProdDataType::FluidResVol] << std::setprecision(3) << ":" - << std::setw(11) << wellProd[WellProdDataType::WaterCut] << std::setprecision(2) << ":" - << std::setw(10) << wellProd[WellProdDataType::GasOilRatio] << std::setprecision(4) << ":" - << std::setw(12) << wellProd[WellProdDataType::WatGasRatio] << std::setprecision(1) << ":" - << std::setw(8) << wellProd[WellProdDataType::BHP] << ":" - << std::setw(8) << wellProd[WellProdDataType::THP] << ": \n"; - } - ss << ":"<< std::setfill ('-') << std::setw (9) << ":" - << std::setfill ('-') << std::setw (12) << ":" - << std::setfill ('-') << std::setw (5) << ":" - << std::setfill ('-') << std::setw (12) << ":" - << std::setfill ('-') << std::setw (12) << ":" - << std::setfill ('-') << std::setw (12) << ":" - << std::setfill ('-') << std::setw (12) << ":" - << std::setfill ('-') << std::setw (12) << ":" - << std::setfill ('-') << std::setw (11) << ":" - << std::setfill ('-') << std::setw (13) << ":" - << std::setfill ('-') << std::setw (9) << ":" - << std::setfill ('-') << std::setw (9) << ':'; + ss << std::setprecision(0) + << std::setw(5) << wellProd[WellProdDataType::WellLocationi] << ',' + << std::setw(5) << wellProd[WellProdDataType::WellLocationj] << ':'; } + + ss << std::setw( 4) << wellProdNames[WellProdDataType::CTRLMode] << ':' << std::setprecision(1) + << std::setw(11) << wellProd[WellProdDataType::OilRate] << ':' + << std::setw(11) << wellProd[WellProdDataType::WaterRate] << ':' + << std::setw(11) << wellProd[WellProdDataType::GasRate] << ':' + << std::setw(11) << wellProd[WellProdDataType::FluidResVol] << ':' << std::setprecision(3) + << std::setw(11) << wellProd[WellProdDataType::WaterCut] << ':' << std::setprecision(2) + << std::setw(10) << wellProd[WellProdDataType::GasOilRatio] << ':' << std::setprecision(4) + << std::setw(12) << wellProd[WellProdDataType::WatGasRatio] << ':' << std::setprecision(1); + + if (! isWellRecord) { + ss << std::setw(8) << "" << ':' << std::setw(8) << "" << ':'; + } else { + ss << std::setw(8) << wellProd[WellProdDataType::BHP] << ':' + << std::setw(8) << wellProd[WellProdDataType::THP] << ':'; + } + OpmLog::note(ss.str()); } diff --git a/opm/simulators/flow/LogOutputHelper.hpp b/opm/simulators/flow/LogOutputHelper.hpp index dfade6a40..7719db05e 100644 --- a/opm/simulators/flow/LogOutputHelper.hpp +++ b/opm/simulators/flow/LogOutputHelper.hpp @@ -69,8 +69,10 @@ public: std::function isDefunct) const; private: - void outputCumulativeReport_(const std::vector& wellCum, - const std::vector& wellCumNames) const; + void beginCumulativeReport_() const; + void endCumulativeReport_() const; + void outputCumulativeReportRecord_(const std::vector& wellCum, + const std::vector& wellCumNames) const; void outputRegionFluidInPlace_(std::unordered_map oip, std::unordered_map cip, @@ -81,11 +83,15 @@ private: void outputResvFluidInPlace_(std::unordered_map cipr, const int reg) const; - void outputInjectionReport_(const std::vector& wellInj, - const std::vector& wellInjNames) const; + void beginInjectionReport_() const; + void endInjectionReport_() const; + void outputInjectionReportRecord_(const std::vector& wellInj, + const std::vector& wellInjNames) const; - void outputProductionReport_(const std::vector& wellProd, - const std::vector& wellProdNames) const; + void beginProductionReport_() const; + void endProductionReport_() const; + void outputProductionReportRecord_(const std::vector& wellProd, + const std::vector& wellProdNames) const; void fipUnitConvert_(std::unordered_map& fip) const; void pressureUnitConvert_(Scalar& pav) const; diff --git a/tests/test_LogOutputHelper.cpp b/tests/test_LogOutputHelper.cpp index 9efda8ecf..b602bf633 100644 --- a/tests/test_LogOutputHelper.cpp +++ b/tests/test_LogOutputHelper.cpp @@ -99,13 +99,10 @@ BOOST_AUTO_TEST_CASE(Cumulative) : : : : : MSTB : MSTB : MMSCF : MRB : MSTB : MSTB : MMSCF : MRB : ==================================================================================================================================== : FIELD: : : : 1.0: 2.0: 3.0: 4.0: 5.0: 6.0: 7.0: 8.0: -:--------:-----------:--------:----:-----------:-----------:-----------:-----------:------------:----------:-----------:-----------: : G1: : : : 9.0: 10.0: 11.0: 12.0: 13.0: 14.0: 15.0: 15.0: -:--------:-----------:--------:----:-----------:-----------:-----------:-----------:------------:----------:-----------:-----------: : PROD: 10, 10: PROD:ORAT: 16.0: 17.0: 18.0: 19.0: 20.0: 21.0: 22.0: 23.0: -:--------:-----------:--------:----:-----------:-----------:-----------:-----------:------------:----------:-----------:-----------: : INJ: 1, 1: INJ:GRAT: 24.0: 25.0: 26.0: 27.0: 28.0: 29.0: 30.0: 31.0: -:--------:-----------:--------:----:-----------:-----------:-----------:-----------:------------:----------:-----------:-----------: +:--------:-----------:--------:----:-----------:-----------:-----------:-----------:-----------:-----------:-----------:-----------: )"; std::stringstream str; @@ -124,38 +121,42 @@ BOOST_AUTO_TEST_CASE(Cumulative) Opm::EclipseState eclState(deck); Opm::SummaryState st; + + // Note: Cumulative gas values--e.g., FGPT--multiplied by an additional + // factor of 1000, for a total multiplicative factor of one million, in + // order to produce the expected balance sheet output in MM* units. constexpr auto fields = std::array { std::pair{"FOPT", 1.0}, std::pair{"FWPT", 2.0}, - std::pair{"FGPT", 3.0}, + std::pair{"FGPT", 3.0e3}, std::pair{"FVPT", 4.0}, std::pair{"FOIT", 5.0}, std::pair{"FWIT", 6.0}, - std::pair{"FGIT", 7.0}, + std::pair{"FGIT", 7.0e3}, std::pair{"FVIT", 8.0}, std::pair{"GOPT:G1", 9.0}, std::pair{"GWPT:G1", 10.0}, - std::pair{"GGPT:G1", 11.0}, + std::pair{"GGPT:G1", 11.0e3}, std::pair{"GVPT:G1", 12.0}, std::pair{"GOIT:G1", 13.0}, std::pair{"GWIT:G1", 14.0}, - std::pair{"GGIT:G1", 15.0}, + std::pair{"GGIT:G1", 15.0e3}, std::pair{"GVIT:G1", 15.0}, std::pair{"WOPT:PROD", 16.0}, std::pair{"WWPT:PROD", 17.0}, - std::pair{"WGPT:PROD", 18.0}, + std::pair{"WGPT:PROD", 18.0e3}, std::pair{"WVPT:PROD", 19.0}, std::pair{"WOIT:PROD", 20.0}, std::pair{"WWIT:PROD", 21.0}, - std::pair{"WGIT:PROD", 22.0}, + std::pair{"WGIT:PROD", 22.0e3}, std::pair{"WVIT:PROD", 23.0}, std::pair{"WOPT:INJ", 24.0}, std::pair{"WWPT:INJ", 25.0}, - std::pair{"WGPT:INJ", 26.0}, + std::pair{"WGPT:INJ", 26.0e3}, std::pair{"WVPT:INJ", 27.0}, std::pair{"WOIT:INJ", 28.0}, std::pair{"WWIT:INJ", 29.0}, - std::pair{"WGIT:INJ", 30.0}, + std::pair{"WGIT:INJ", 30.0e3}, std::pair{"WVIT:INJ", 31.0}, }; for (const auto& p : fields) { @@ -333,11 +334,9 @@ BOOST_AUTO_TEST_CASE(Injection) : WELL : LOCATION : CTRL : CTRL : CTRL : OIL : WATER : GAS : FLUID : BHP OR : THP OR : : NAME : (I,J,K) : MODE : MODE : MODE : RATE : RATE : RATE : RES.VOL. : CON.PR.: BLK.PR.: : : : OIL : WAT : GAS : STB/DAY : STB/DAY : MSCF/DAY : RB/DAY : PSIA : PSIA : -============================================================================================================== +============================================================================================================= : FIELD: : : : : 1.0: 2.0: 3.0: 4.0: : : -:--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------: : G1: : : : : 5.0: 6.0: 7.0: 8.0: : : -:--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------: : INJ: 1, 1: : : GRAT: 9.0: 10.0: 11.0: 12.0: 13.0: 14.0: :--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------: )"; @@ -391,9 +390,7 @@ BOOST_AUTO_TEST_CASE(Production) : : : : STB/DAY : STB/DAY : MSCF/DAY : RB/DAY : : MSCF/STB : STB/MSCF : PSIA : PSIA : ================================================================================================================================= : FIELD: : : 1.0: 2.0: 3.0: 4.0: 5.000: 6.00: 0.6667: : : -:--------:-----------:----:-----------:-----------:-----------:-----------:-----------:----------:------------:--------:--------: : G1: : : 7.0: 8.0: 9.0: 10.0: 11.000: 12.00: 0.8889: : : -:--------:-----------:----:-----------:-----------:-----------:-----------:-----------:----------:------------:--------:--------: : PROD: 10, 10:ORAT: 13.0: 14.0: 15.0: 16.0: 17.000: 18.00: 0.9333: 19.0: 20.0: :--------:-----------:----:-----------:-----------:-----------:-----------:-----------:----------:------------:--------:--------: )";