Support alternate FIPxxx regions in region summary keywords

As part of support the RPR__xxx summary keywords the ecloutputblackoilmodule.hh
file hase been refactored significantly:

 - std::optional<> is used to manage the calculate once initial values.

 - several small functions are extracted from the outputFipLog() function.

 - std::array<> is used instead of ScalarBuffer to manage containers over all
   FipTypes.

 - SummaryConfig nodes for the requested summary output is stored in the class.

 - A small struct RegionSum is created to hold the region summed properties.
This commit is contained in:
Joakim Hove 2020-09-07 10:22:42 +02:00
parent 03852825d5
commit 4be8240771

View File

@ -27,6 +27,11 @@
#ifndef EWOMS_ECL_OUTPUT_BLACK_OIL_MODULE_HH #ifndef EWOMS_ECL_OUTPUT_BLACK_OIL_MODULE_HH
#define EWOMS_ECL_OUTPUT_BLACK_OIL_MODULE_HH #define EWOMS_ECL_OUTPUT_BLACK_OIL_MODULE_HH
#include <array>
#include <numeric>
#include <optional>
#include <stdexcept>
#include <opm/models/blackoil/blackoilproperties.hh> #include <opm/models/blackoil/blackoilproperties.hh>
#include <opm/models/utils/propertysystem.hh> #include <opm/models/utils/propertysystem.hh>
@ -65,6 +70,8 @@ struct ForceDisableFluidInPlaceOutput<TypeTag, TTag::EclOutputBlackOil> {
namespace Opm { namespace Opm {
// forward declaration // forward declaration
template <class TypeTag> template <class TypeTag>
class EcfvDiscretization; class EcfvDiscretization;
@ -114,7 +121,22 @@ class EclOutputBlackOilModule
GasInPlaceInGasPhase = 6, //GIPG GasInPlaceInGasPhase = 6, //GIPG
PoreVolume = 7, //PV PoreVolume = 7, //PV
}; };
static const int numFipValues = PoreVolume + 1 ; static const int numFipTypes = PoreVolume + 1 ;
static std::string EclString(int fip_type) {
switch(static_cast<FipId>(fip_type)) {
case FipDataType::WaterInPlace: return "WIP";
case FipDataType::OilInPlace: return "OIP";
case FipDataType::GasInPlace: return "GIP";
case FipDataType::OilInPlaceInLiquidPhase: return "OIPL";
case FipDataType::OilInPlaceInGasPhase: return "OIPG";
case FipDataType::GasInPlaceInLiquidPhase: return "GIPL";
case FipDataType::GasInPlaceInGasPhase: return "GIPG";
case FipDataType::PoreVolume: return "PV";
}
throw std::logic_error("fip_type: " + std::to_string(fip_type) + " not recognized");
}
}; };
struct WellProdDataType struct WellProdDataType
{ {
@ -181,17 +203,42 @@ class EclOutputBlackOilModule
static const int numWCNames = 3; static const int numWCNames = 3;
}; };
struct RegionSum {
std::size_t ntFip;
std::array<ScalarBuffer, FipDataType::numFipTypes> regFipValues;
ScalarBuffer regPressurePv;
ScalarBuffer regPvHydrocarbon;
ScalarBuffer regPressurePvHydrocarbon;
std::array<Scalar, FipDataType::numFipTypes> fieldFipValues;
Scalar fieldPressurePv;
Scalar fieldPvHydrocarbon;
Scalar fieldPressurePvHydrocarbon;
};
public: public:
template<class CollectDataToIORankType> template<class CollectDataToIORankType>
EclOutputBlackOilModule(const Simulator& simulator, const CollectDataToIORankType& collectToIORank) EclOutputBlackOilModule(const Simulator& simulator, const CollectDataToIORankType& collectToIORank)
: simulator_(simulator) : simulator_(simulator)
{ {
createLocalFipnum_();
// Summary output is for all steps
const Opm::SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig(); const Opm::SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig();
const auto& fp = simulator_.vanguard().eclState().fieldProps();
this->regions_["FIPNUM"] = fp.get_int("FIPNUM");
for (const auto& region : summaryConfig.fip_regions())
this->regions_[region] = fp.get_int(region);
for (auto& region_pair : this->regions_)
createLocalRegion_(region_pair.second);
this->RPRNodes_ = summaryConfig.keywords("RPR*");
this->RPRPNodes_ = summaryConfig.keywords("RPRP*");
for (int fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++) {
std::string key_pattern = "R" + FipDataType::EclString(fip_type) + "*";
this->regionNodes_[fip_type] = summaryConfig.keywords(key_pattern);
}
// Initialize block output
for (const auto& node: summaryConfig) { for (const auto& node: summaryConfig) {
if (node.category() == SummaryConfigNode::Category::Block) { if (node.category() == SummaryConfigNode::Category::Block) {
if (collectToIORank.isCartIdxOnThisRank(node.number() - 1)) { if (collectToIORank.isCartIdxOnThisRank(node.number() - 1)) {
@ -244,8 +291,8 @@ public:
computeFip_ = false; computeFip_ = false;
// Fluid in place // Fluid in place
for (int i = 0; i<FipDataType::numFipValues; i++) { for (int i = 0; i<FipDataType::numFipTypes; i++) {
if (!substep || summaryConfig.require3DField(fipEnumToString_(i))) { if (!substep || summaryConfig.require3DField(FipDataType::EclString(i))) {
if (rstKeywords["FIP"] > 0) { if (rstKeywords["FIP"] > 0) {
rstKeywords["FIP"] = 0; rstKeywords["FIP"] = 0;
outputFipRestart_ = true; outputFipRestart_ = true;
@ -256,7 +303,7 @@ public:
else else
fip_[i].clear(); fip_[i].clear();
} }
if (!substep || summaryConfig.hasKeyword("FPR") || summaryConfig.hasKeyword("FPRP") || summaryConfig.hasKeyword("RPR")) { if (!substep || summaryConfig.hasKeyword("FPR") || summaryConfig.hasKeyword("FPRP") || !this->RPRNodes_.empty()) {
fip_[FipDataType::PoreVolume].resize(bufferSize, 0.0); fip_[FipDataType::PoreVolume].resize(bufferSize, 0.0);
hydrocarbonPoreVolume_.resize(bufferSize, 0.0); hydrocarbonPoreVolume_.resize(bufferSize, 0.0);
pressureTimesPoreVolume_.resize(bufferSize, 0.0); pressureTimesPoreVolume_.resize(bufferSize, 0.0);
@ -1025,9 +1072,9 @@ public:
// Fluid in place // Fluid in place
for (int i = 0; i<FipDataType::numFipValues; i++) { for (int i = 0; i<FipDataType::numFipTypes; i++) {
if (outputFipRestart_ && fip_[i].size() > 0) { if (outputFipRestart_ && fip_[i].size() > 0) {
sol.insert(fipEnumToString_(i), sol.insert(FipDataType::EclString(i),
Opm::UnitSystem::measure::volume, Opm::UnitSystem::measure::volume,
fip_[i], fip_[i],
Opm::data::TargetType::SUMMARY); Opm::data::TargetType::SUMMARY);
@ -1044,105 +1091,203 @@ public:
} }
} }
int regionMax(const std::vector<int>& region) {
const auto max_value = region.empty() ? 0 : *std::max_element(region.begin(), region.end());
return this->simulator_.gridView().comm().max(max_value);
}
RegionSum makeRegionSum(const std::vector<int>& region, bool is_fipnum) {
RegionSum rsum;
rsum.ntFip = this->regionMax(region);
// sum values over each region
rsum.regPressurePv = this->regionSum(this->pressureTimesPoreVolume_, region, rsum.ntFip);
rsum.regPvHydrocarbon = this->regionSum(this->hydrocarbonPoreVolume_, region, rsum.ntFip);
rsum.regPressurePvHydrocarbon = this->regionSum(pressureTimesHydrocarbonVolume_, region, rsum.ntFip);
for (int fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++)
rsum.regFipValues[fip_type] = this->regionSum(this->fip_[fip_type], region, rsum.ntFip);
// sum all region values to compute the field total
rsum.fieldPressurePv = sum(rsum.regPressurePv);
rsum.fieldPvHydrocarbon = sum(rsum.regPvHydrocarbon);
rsum.fieldPressurePvHydrocarbon = sum(rsum.regPressurePvHydrocarbon);
for (int fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++) {
const auto& regionFip = rsum.regFipValues[fip_type];
rsum.fieldFipValues[fip_type] = sum(regionFip);
}
if (is_fipnum) {
// The first time the outputFipLog function is run we store the inplace values in
// the initialInplace_ member. This has at least two problems:
//
// o We really want the *initial* value - now we get the value after
// the first timestep.
//
// o For restarted runs this is obviously wrong.
//
// Finally it is of course not desirable to mutate state in an output
// routine.
if (!this->regionInitialInplace_) {
this->regionInitialInplace_.emplace();
for (int fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++)
this->regionInitialInplace_.value()[fip_type] = rsum.regFipValues[fip_type];
}
if (!this->fieldInitialInplace_)
this->fieldInitialInplace_ = rsum.fieldFipValues;
}
return rsum;
}
std::unordered_map<std::string, RegionSum> accumulateRegionSums() {
std::unordered_map<std::string, RegionSum> rsum_map;
const Opm::SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig();
rsum_map.emplace("FIPNUM", makeRegionSum(this->regions_.at("FIPNUM"), true));
for (const auto& fip_region : summaryConfig.fip_regions()) {
if (fip_region == "FIPNUM")
continue;
const auto& region = this->regions_.at(fip_region);
rsum_map.emplace(fip_region, makeRegionSum(region, false));
}
return rsum_map;
}
Scalar sum(const ScalarBuffer& v) {
return std::accumulate(v.begin(), v.end(), Scalar{0});
}
void updateSummaryRegionValues(const std::unordered_map<std::string, RegionSum>& rsum_map,
std::map<std::string, double>& miscSummaryData,
std::map<std::string, std::vector<double>>& regionData) const {
const Opm::SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig();
// The field summary vectors should only use the FIPNUM based region sum.
{
const auto& rsum = rsum_map.at("FIPNUM");
for (int fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++) {
std::string key = "F" + FipDataType::EclString(fip_type);
if (summaryConfig.hasKeyword(key))
miscSummaryData[key] = rsum.fieldFipValues[fip_type];
}
if (summaryConfig.hasKeyword("FOE") && this->fieldInitialInplace_)
miscSummaryData["FOE"] = rsum.fieldFipValues[FipDataType::OilInPlace]
/ this->fieldInitialInplace_.value()[FipDataType::OilInPlace];
if (summaryConfig.hasKeyword("FPR"))
miscSummaryData["FPR"] = pressureAverage_(rsum.fieldPressurePvHydrocarbon,
rsum.fieldPvHydrocarbon,
rsum.fieldPressurePv,
rsum.fieldFipValues[FipDataType::PoreVolume],
true);
if (summaryConfig.hasKeyword("FPRP"))
miscSummaryData["FPRP"] = pressureAverage_(rsum.fieldPressurePvHydrocarbon,
rsum.fieldPvHydrocarbon,
rsum.fieldPressurePv,
rsum.fieldFipValues[FipDataType::PoreVolume],
false);
}
// The region summary vectors should loop through the FIPxxx regions to
// support the RPR__xxx summary keywords.
{
for (int fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++) {
for (const auto& node : this->regionNodes_[fip_type]) {
const auto& rsum = rsum_map.at(node.fip_region());
regionData[node.keyword()] = rsum.regFipValues[fip_type];
}
}
// The exact same quantity is calculated for RPR and RPRP - is that correct?
for (const auto& node : this->RPRNodes_) {
const auto& rsum = rsum_map.at(node.fip_region());
regionData[node.keyword()] = pressureAverage_(rsum.regPressurePvHydrocarbon,
rsum.regPvHydrocarbon,
rsum.regPressurePv,
rsum.regFipValues[FipDataType::PoreVolume],
true);
}
for (const auto& node : this->RPRPNodes_) {
const auto& rsum = rsum_map.at(node.fip_region());
regionData[node.keyword()] = pressureAverage_(rsum.regPressurePvHydrocarbon,
rsum.regPvHydrocarbon,
rsum.regPressurePv,
rsum.regFipValues[FipDataType::PoreVolume],
false);
}
}
}
void outputFipLogImpl(const RegionSum& rsum) const {
{
Scalar fieldHydroCarbonPoreVolumeAveragedPressure = pressureAverage_(rsum.fieldPressurePvHydrocarbon,
rsum.fieldPvHydrocarbon,
rsum.fieldPressurePv,
rsum.fieldFipValues[FipDataType::PoreVolume],
true);
std::array<Scalar, FipDataType::numFipTypes> initial_values = *this->fieldInitialInplace_;
std::array<Scalar, FipDataType::numFipTypes> current_values = rsum.fieldFipValues;
fipUnitConvert_(initial_values);
fipUnitConvert_(current_values);
pressureUnitConvert_(fieldHydroCarbonPoreVolumeAveragedPressure);
outputRegionFluidInPlace_(initial_values,
current_values,
fieldHydroCarbonPoreVolumeAveragedPressure);
}
for (size_t reg = 0; reg < rsum.ntFip; ++reg) {
std::array<Scalar, FipDataType::numFipTypes> initial_values;
std::array<Scalar, FipDataType::numFipTypes> current_values;
for (std::size_t fip_type = 0; fip_type < FipDataType::numFipTypes; fip_type++) {
initial_values[fip_type] = this->regionInitialInplace_.value()[fip_type][reg];
current_values[fip_type] = rsum.regFipValues[fip_type][reg];
}
fipUnitConvert_(initial_values);
fipUnitConvert_(current_values);
Scalar regHydroCarbonPoreVolumeAveragedPressure
= pressureAverage_(rsum.regPressurePvHydrocarbon[reg],
rsum.regPvHydrocarbon[reg],
rsum.regPressurePv[reg],
rsum.regFipValues[FipDataType::PoreVolume][reg],
true);
pressureUnitConvert_(regHydroCarbonPoreVolumeAveragedPressure);
outputRegionFluidInPlace_(initial_values, current_values, regHydroCarbonPoreVolumeAveragedPressure, reg + 1);
}
}
// write Fluid In Place to output log // write Fluid In Place to output log
void outputFipLog(std::map<std::string, double>& miscSummaryData, std::map<std::string, std::vector<double>>& regionData, const bool substep) void outputFipLog(std::map<std::string, double>& miscSummaryData, std::map<std::string, std::vector<double>>& regionData, const bool substep)
{ {
const auto& comm = simulator_.gridView().comm(); auto rsum_map = this->accumulateRegionSums();
auto maxElement = std::max_element(fipnum_.begin(), fipnum_.end()); if (!isIORank_())
size_t ntFip = 0; return;
if ( maxElement != fipnum_.end() ) {
ntFip = *maxElement;
}
ntFip = comm.max(ntFip);
// sum values over each region updateSummaryRegionValues(rsum_map,
ScalarBuffer regionFipValues[FipDataType::numFipValues]; miscSummaryData,
for (int i = 0; i < FipDataType::numFipValues; i++) { regionData);
regionFipValues[i] = computeFipForRegions_(fip_[i], fipnum_, ntFip);
if (isIORank_() && origRegionValues_[i].empty()) if (!substep)
origRegionValues_[i] = regionFipValues[i]; outputFipLogImpl(rsum_map.at("FIPNUM"));
} }
// sum all region values to compute the field total
std::vector<int> fieldNum(ntFip, 1);
ScalarBuffer fieldFipValues(FipDataType::numFipValues, 0.0);
bool comunicateSum = false; // the regionValues are already summed over all ranks.
for (int i = 0; i<FipDataType::numFipValues; i++) {
const ScalarBuffer& tmp = computeFipForRegions_(regionFipValues[i], fieldNum, 1, comunicateSum);
fieldFipValues[i] = tmp[0];
}
// compute the hydrocarbon averaged pressure over the regions.
ScalarBuffer regPressurePv = computeFipForRegions_(pressureTimesPoreVolume_, fipnum_, ntFip);
ScalarBuffer regPvHydrocarbon = computeFipForRegions_(hydrocarbonPoreVolume_, fipnum_, ntFip);
ScalarBuffer regPressurePvHydrocarbon = computeFipForRegions_(pressureTimesHydrocarbonVolume_, fipnum_, ntFip);
ScalarBuffer fieldPressurePv = computeFipForRegions_(regPressurePv, fieldNum, 1, comunicateSum);
ScalarBuffer fieldPvHydrocarbon = computeFipForRegions_(regPvHydrocarbon, fieldNum, 1, comunicateSum);
ScalarBuffer fieldPressurePvHydrocarbon = computeFipForRegions_(regPressurePvHydrocarbon, fieldNum, 1, comunicateSum);
// output on io rank
// the original Fip values are stored on the first step
// TODO: Store initial Fip in the init file and restore them
// and use them here.
const Opm::SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig();
if (isIORank_()) {
// Field summary output
for (int i = 0; i<FipDataType::numFipValues; i++) {
std::string key = "F" + fipEnumToString_(i);
if (summaryConfig.hasKeyword(key))
miscSummaryData[key] = fieldFipValues[i];
}
if (summaryConfig.hasKeyword("FOE") && !origTotalValues_.empty())
miscSummaryData["FOE"] = fieldFipValues[FipDataType::OilInPlace] / origTotalValues_[FipDataType::OilInPlace];
if (summaryConfig.hasKeyword("FPR"))
miscSummaryData["FPR"] = pressureAverage_(fieldPressurePvHydrocarbon[0], fieldPvHydrocarbon[0], fieldPressurePv[0], fieldFipValues[FipDataType::PoreVolume], true);
if (summaryConfig.hasKeyword("FPRP"))
miscSummaryData["FPRP"] = pressureAverage_(fieldPressurePvHydrocarbon[0], fieldPvHydrocarbon[0], fieldPressurePv[0], fieldFipValues[FipDataType::PoreVolume], false);
// Region summary output
for (int i = 0; i<FipDataType::numFipValues; i++) {
std::string key = "R" + fipEnumToString_(i);
if (summaryConfig.hasKeyword(key))
regionData[key] = regionFipValues[i];
}
if (summaryConfig.hasKeyword("RPR"))
regionData["RPR"] = pressureAverage_(regPressurePvHydrocarbon, regPvHydrocarbon, regPressurePv, regionFipValues[FipDataType::PoreVolume], true);
if (summaryConfig.hasKeyword("RPRP"))
regionData["RPRP"] = pressureAverage_(regPressurePvHydrocarbon, regPvHydrocarbon, regPressurePv, regionFipValues[FipDataType::PoreVolume], false);
// Output to log
if (!substep) {
fipUnitConvert_(fieldFipValues);
if (origTotalValues_.empty())
origTotalValues_ = fieldFipValues;
Scalar fieldHydroCarbonPoreVolumeAveragedPressure = pressureAverage_(fieldPressurePvHydrocarbon[0], fieldPvHydrocarbon[0], fieldPressurePv[0], fieldFipValues[FipDataType::PoreVolume], true);
pressureUnitConvert_(fieldHydroCarbonPoreVolumeAveragedPressure);
outputRegionFluidInPlace_(origTotalValues_, fieldFipValues, fieldHydroCarbonPoreVolumeAveragedPressure, 0);
for (size_t reg = 0; reg < ntFip; ++reg) {
ScalarBuffer tmpO(FipDataType::numFipValues, 0.0);
for (int i = 0; i<FipDataType::numFipValues; i++) {
tmpO[i] = origRegionValues_[i][reg];
}
fipUnitConvert_(tmpO);
ScalarBuffer tmp(FipDataType::numFipValues, 0.0);
for (int i = 0; i<FipDataType::numFipValues; i++) {
tmp[i] = regionFipValues[i][reg];
}
fipUnitConvert_(tmp);
Scalar regHydroCarbonPoreVolumeAveragedPressure = pressureAverage_(regPressurePvHydrocarbon[reg], regPvHydrocarbon[reg], regPressurePv[reg], regionFipValues[FipDataType::PoreVolume][reg], true);
pressureUnitConvert_(regHydroCarbonPoreVolumeAveragedPressure);
outputRegionFluidInPlace_(tmpO, tmp, regHydroCarbonPoreVolumeAveragedPressure, reg + 1);
}
}
}
}
// write production report to output // write production report to output
void outputProdLog(size_t reportStepNum, const bool substep, bool forceDisableProdOutput) void outputProdLog(size_t reportStepNum, const bool substep, bool forceDisableProdOutput)
@ -1772,14 +1917,8 @@ private:
} }
void createLocalFipnum_() void createLocalRegion_(std::vector<int>& region)
{ {
const auto& gridView = simulator_.vanguard().gridView();
if (simulator_.vanguard().eclState().fieldProps().has_int("FIPNUM"))
fipnum_ = simulator_.vanguard().eclState().fieldProps().get_int("FIPNUM");
else
fipnum_.resize(gridView.size(/*codim=*/0), 1);
ElementContext elemCtx(simulator_); ElementContext elemCtx(simulator_);
ElementIterator elemIt = simulator_.gridView().template begin</*codim=*/0>(); ElementIterator elemIt = simulator_.gridView().template begin</*codim=*/0>();
const ElementIterator& elemEndIt = simulator_.gridView().template end</*codim=*/0>(); const ElementIterator& elemEndIt = simulator_.gridView().template end</*codim=*/0>();
@ -1787,19 +1926,19 @@ private:
for (; elemIt != elemEndIt; ++elemIt, ++elemIdx) { for (; elemIt != elemEndIt; ++elemIt, ++elemIdx) {
const Element& elem = *elemIt; const Element& elem = *elemIt;
if (elem.partitionType() != Dune::InteriorEntity) if (elem.partitionType() != Dune::InteriorEntity)
fipnum_[elemIdx] = 0; region[elemIdx] = 0;
} }
} }
// Sum Fip values over regions. // Sum Fip values over regions.
ScalarBuffer computeFipForRegions_(const ScalarBuffer& fip, std::vector<int>& regionId, size_t maxNumberOfRegions, bool commSum = true) ScalarBuffer regionSum(const ScalarBuffer& property, const std::vector<int>& regionId, size_t maxNumberOfRegions) const
{ {
ScalarBuffer totals(maxNumberOfRegions, 0.0); ScalarBuffer totals(maxNumberOfRegions, 0.0);
if (fip.empty()) if (property.empty())
return totals; return totals;
assert(regionId.size() == fip.size()); assert(regionId.size() == property.size());
for (size_t j = 0; j < regionId.size(); ++j) { for (size_t j = 0; j < regionId.size(); ++j) {
const int regionIdx = regionId[j] - 1; const int regionIdx = regionId[j] - 1;
// the cell is not attributed to any region. ignore it! // the cell is not attributed to any region. ignore it!
@ -1807,18 +1946,17 @@ private:
continue; continue;
assert(regionIdx < static_cast<int>(maxNumberOfRegions)); assert(regionIdx < static_cast<int>(maxNumberOfRegions));
totals[regionIdx] += fip[j]; totals[regionIdx] += property[j];
} }
if (commSum) {
const auto& comm = simulator_.gridView().comm(); const auto& comm = simulator_.gridView().comm();
for (size_t i = 0; i < maxNumberOfRegions; ++i) for (size_t i = 0; i < maxNumberOfRegions; ++i)
totals[i] = comm.sum(totals[i]); totals[i] = comm.sum(totals[i]);
}
return totals; return totals;
} }
ScalarBuffer pressureAverage_(const ScalarBuffer& pressurePvHydrocarbon, const ScalarBuffer& pvHydrocarbon, const ScalarBuffer& pressurePv, const ScalarBuffer& pv, bool hydrocarbon) ScalarBuffer pressureAverage_(const ScalarBuffer& pressurePvHydrocarbon, const ScalarBuffer& pvHydrocarbon, const ScalarBuffer& pressurePv, const ScalarBuffer& pv, bool hydrocarbon) const
{ {
size_t size = pressurePvHydrocarbon.size(); size_t size = pressurePvHydrocarbon.size();
assert(pvHydrocarbon.size() == size); assert(pvHydrocarbon.size() == size);
@ -1832,7 +1970,7 @@ private:
return fraction; return fraction;
} }
Scalar pressureAverage_(const Scalar& pressurePvHydrocarbon, const Scalar& pvHydrocarbon, const Scalar& pressurePv, const Scalar& pv, bool hydrocarbon) Scalar pressureAverage_(const Scalar& pressurePvHydrocarbon, const Scalar& pvHydrocarbon, const Scalar& pressurePv, const Scalar& pv, bool hydrocarbon) const
{ {
if (pvHydrocarbon > 1e-10 && hydrocarbon) if (pvHydrocarbon > 1e-10 && hydrocarbon)
return pressurePvHydrocarbon / pvHydrocarbon; return pressurePvHydrocarbon / pvHydrocarbon;
@ -1840,7 +1978,7 @@ private:
return pressurePv / pv; return pressurePv / pv;
} }
void fipUnitConvert_(ScalarBuffer& fip) void fipUnitConvert_(std::array<Scalar, FipDataType::numFipTypes>& fip) const
{ {
const Opm::UnitSystem& units = simulator_.vanguard().eclState().getUnits(); const Opm::UnitSystem& units = simulator_.vanguard().eclState().getUnits();
if (units.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD) { if (units.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD) {
@ -1872,7 +2010,7 @@ private:
} }
} }
void pressureUnitConvert_(Scalar& pav) void pressureUnitConvert_(Scalar& pav) const
{ {
const Opm::UnitSystem& units = simulator_.vanguard().eclState().getUnits(); const Opm::UnitSystem& units = simulator_.vanguard().eclState().getUnits();
if (units.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD) { if (units.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD) {
@ -1890,7 +2028,9 @@ private:
} }
} }
void outputRegionFluidInPlace_(const ScalarBuffer& oip, const ScalarBuffer& cip, const Scalar& pav, const int reg) void outputRegionFluidInPlace_(const std::array<Scalar, FipDataType::numFipTypes>& oip,
const std::array<Scalar, FipDataType::numFipTypes>& cip,
const Scalar& pav, const int reg = 0) const
{ {
if (forceDisableFipOutput_) if (forceDisableFipOutput_)
return; return;
@ -1901,7 +2041,7 @@ private:
const Opm::UnitSystem& units = simulator_.vanguard().eclState().getUnits(); const Opm::UnitSystem& units = simulator_.vanguard().eclState().getUnits();
std::ostringstream ss; std::ostringstream ss;
if (!reg) { if (reg == 0) {
ss << " ===================================================\n" ss << " ===================================================\n"
<< " : Field Totals :\n"; << " : Field Totals :\n";
} }
@ -2043,22 +2183,6 @@ private:
Opm::OpmLog::note(ss.str()); Opm::OpmLog::note(ss.str());
} }
std::string fipEnumToString_(int i)
{
typedef typename FipDataType::FipId FipId;
switch(static_cast<FipId>(i))
{
case FipDataType::WaterInPlace: return "WIP";
case FipDataType::OilInPlace: return "OIP";
case FipDataType::GasInPlace: return "GIP";
case FipDataType::OilInPlaceInLiquidPhase: return "OIPL";
case FipDataType::OilInPlaceInGasPhase: return "OIPG";
case FipDataType::GasInPlaceInLiquidPhase: return "GIPL";
case FipDataType::GasInPlaceInGasPhase: return "GIPG";
case FipDataType::PoreVolume: return "PV";
}
return "ERROR";
}
std::string WPEnumToString_(int i) std::string WPEnumToString_(int i)
{ {
typedef typename WellProdDataType::WPId WPId; typedef typename WellProdDataType::WPId WPId;
@ -2171,10 +2295,17 @@ private:
std::vector<int> failedCellsPb_; std::vector<int> failedCellsPb_;
std::vector<int> failedCellsPd_; std::vector<int> failedCellsPd_;
std::vector<int> fipnum_; std::unordered_map<std::string, std::vector<int>> regions_;
ScalarBuffer fip_[FipDataType::numFipValues]; std::array<ScalarBuffer, FipDataType::numFipTypes> fip_;
ScalarBuffer origTotalValues_; std::optional<std::array<ScalarBuffer, FipDataType::numFipTypes>> regionInitialInplace_;
ScalarBuffer origRegionValues_[FipDataType::numFipValues]; std::optional<std::array<Scalar, FipDataType::numFipTypes>> fieldInitialInplace_;
std::vector<Opm::SummaryConfigNode> RPRNodes_;
std::vector<Opm::SummaryConfigNode> RPRPNodes_;
std::array<std::vector<Opm::SummaryConfigNode>, FipDataType::numFipTypes> regionNodes_;
ScalarBuffer hydrocarbonPoreVolume_; ScalarBuffer hydrocarbonPoreVolume_;
ScalarBuffer pressureTimesPoreVolume_; ScalarBuffer pressureTimesPoreVolume_;
ScalarBuffer pressureTimesHydrocarbonVolume_; ScalarBuffer pressureTimesHydrocarbonVolume_;