mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-11-02 20:30:55 -06:00
Populate satellite data for RC summary output
Add updateScheduleSatelliteData() to ReservoirCouplingMaster and ReservoirCouplingMasterReportStep. Called from EclWriter::evalSummaryState() before summary evaluation. This populates the Schedule's GSatProd and GroupSatelliteInjection with slave production/injection rates received via MPI. The existing satellite_rate machinery in opm-common's Summary.cpp then automatically computes all rate-based summary vectors (FOPR, GOPR, FGOR, FWCT, etc.) correctly for the master model. Requires the companion opm-common PR that adds Schedule::updateSatelliteProduction/Injection().
This commit is contained in:
1 parent
d01d75ce09
commit
b292f39a0c
5 files changed
+110
-1
No files matched your search
@@ -53,6 +53,11 @@
|
||||
#include <opm/simulators/utils/ParallelRestart.hpp>
|
||||
#include <opm/simulators/utils/ParallelSerialization.hpp>
|
||||
|
||||
#include <opm/simulators/flow/rescoup/ReservoirCouplingEnabled.hpp>
|
||||
#ifdef RESERVOIR_COUPLING_ENABLED
|
||||
#include <opm/simulators/flow/rescoup/ReservoirCouplingMaster.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
#include <limits>
|
||||
@@ -128,7 +133,7 @@ class EclWriter : public EclGenericWriter<GetPropType<TypeTag, Properties::Grid>
|
||||
|
||||
typedef Dune::MultipleCodimMultipleGeomTypeMapper< GridView > VertexMapper;
|
||||
|
||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal ||
|
||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal ||
|
||||
getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::SequentialImplicitThermal };
|
||||
enum { enableMech = getPropValue<TypeTag, Properties::EnableMech>() };
|
||||
enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
|
||||
@@ -320,6 +325,13 @@ public:
|
||||
miscSummaryData["MSUMNEWT"] = this->simulation_report_.success.total_newton_iterations;
|
||||
}
|
||||
|
||||
// For reservoir coupling master: populate satellite production/injection
|
||||
// data from slave groups so that summary.eval() picks up the rates through
|
||||
// the existing GSatProd / satellite_rate machinery in opm-common's Summary.cpp.
|
||||
// This must be done before evalSummary() so the rates are available when
|
||||
// summary vectors are evaluated.
|
||||
this->updateReservoirCouplingSatelliteData_();
|
||||
|
||||
{
|
||||
OPM_TIMEBLOCK(evalSummary);
|
||||
|
||||
@@ -752,6 +764,29 @@ private:
|
||||
const Schedule& schedule() const
|
||||
{ return simulator_.vanguard().schedule(); }
|
||||
|
||||
/// Populate satellite production/injection data from reservoir coupling
|
||||
/// slave groups into the Schedule's GSatProd / GroupSatelliteInjection
|
||||
/// structures. Delegates to ReservoirCouplingMaster::updateScheduleSatelliteData().
|
||||
void updateReservoirCouplingSatelliteData_()
|
||||
{
|
||||
#ifdef RESERVOIR_COUPLING_ENABLED
|
||||
// Guard: only BlackoilWellModel has reservoir coupling support.
|
||||
// CompWellModel (compositional) does not, so we use if constexpr
|
||||
// to avoid compilation errors when EclWriter is instantiated with
|
||||
// a compositional TypeTag.
|
||||
using WellModelType = std::remove_cvref_t<
|
||||
decltype(simulator_.problem().wellModel())>;
|
||||
if constexpr (requires(WellModelType& wm) { wm.isReservoirCouplingMaster(); }) {
|
||||
auto& wellModel = simulator_.problem().wellModel();
|
||||
if (!wellModel.isReservoirCouplingMaster()) {
|
||||
return;
|
||||
}
|
||||
wellModel.reservoirCouplingMaster().updateScheduleSatelliteData(
|
||||
simulator_.vanguard().schedule(), simulator_.episodeIndex());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void prepareLocalCellData(const bool isSubStep,
|
||||
const int reportStepNum)
|
||||
{
|
||||
|
||||
@@ -497,6 +497,15 @@ updateMasterGroupNameOrderMap(
|
||||
this->master_group_name_order_[slave_name] = master_group_name_map;
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
ReservoirCouplingMaster<Scalar>::
|
||||
updateScheduleSatelliteData(Schedule& schedule, const int report_step_idx)
|
||||
{
|
||||
assert(this->report_step_data_);
|
||||
this->report_step_data_->updateScheduleSatelliteData(schedule, report_step_idx);
|
||||
}
|
||||
|
||||
// ------------------
|
||||
// Private methods
|
||||
// ------------------
|
||||
|
||||
@@ -154,6 +154,13 @@ public:
|
||||
this->logger_.setDeferredLogger(deferred_logger);
|
||||
}
|
||||
void setFirstSubstepOfSyncTimestep(bool value);
|
||||
|
||||
/// @brief Update the Schedule's satellite production/injection data from
|
||||
/// slave group rates.
|
||||
/// @details Called from EclWriter::evalSummaryState() at the end of each
|
||||
/// sync step. Delegates to ReservoirCouplingMasterReportStep. See its
|
||||
/// updateScheduleSatelliteData() for details.
|
||||
void updateScheduleSatelliteData(Schedule& schedule, int report_step_idx);
|
||||
// These are currently only used for unit testing
|
||||
void setSlaveActivationDate(int index, double date) { this->slave_activation_dates_[index] = date; }
|
||||
void setSlaveNextReportTimeOffset(int index, double offset);
|
||||
|
||||
@@ -320,6 +320,53 @@ setReportStepIdx(int report_step_idx)
|
||||
this->report_step_idx_ = report_step_idx;
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
ReservoirCouplingMasterReportStep<Scalar>::
|
||||
updateScheduleSatelliteData(Schedule& schedule, const int report_step_idx)
|
||||
{
|
||||
using RcPhase = ReservoirCoupling::Phase;
|
||||
using RateKind = ReservoirCoupling::RateKind;
|
||||
|
||||
const auto numSlaves = this->numSlaves();
|
||||
for (unsigned int i = 0; i < numSlaves; ++i) {
|
||||
const auto& masterGroupNames = this->getMasterGroupNamesForSlave(i);
|
||||
for (const auto& groupName : masterGroupNames) {
|
||||
// GSatProd expects positive production rates. The rates from
|
||||
// getMasterGroupRate_(ProductionSurface) originate from the slave's
|
||||
// GuideRate::RateVector which stores positive values for production
|
||||
// (guide rate convention, not the well-state sign convention).
|
||||
const double oilRate = this->getMasterGroupRate_(
|
||||
groupName, RcPhase::Oil, RateKind::ProductionSurface);
|
||||
const double gasRate = this->getMasterGroupRate_(
|
||||
groupName, RcPhase::Gas, RateKind::ProductionSurface);
|
||||
const double waterRate = this->getMasterGroupRate_(
|
||||
groupName, RcPhase::Water, RateKind::ProductionSurface);
|
||||
const double resvRate =
|
||||
this->getMasterGroupRate_(groupName, RcPhase::Oil, RateKind::ProductionReservoir)
|
||||
+ this->getMasterGroupRate_(groupName, RcPhase::Gas, RateKind::ProductionReservoir)
|
||||
+ this->getMasterGroupRate_(groupName, RcPhase::Water, RateKind::ProductionReservoir);
|
||||
|
||||
schedule.updateSatelliteProduction(
|
||||
report_step_idx, groupName, oilRate, gasRate, waterRate, resvRate);
|
||||
|
||||
// Injection rates: positive values match what GSatInje expects.
|
||||
for (const auto phase : {RcPhase::Oil, RcPhase::Gas, RcPhase::Water}) {
|
||||
const double surfRate = this->getMasterGroupRate_(
|
||||
groupName, phase, RateKind::InjectionSurface);
|
||||
const double resRate = this->getMasterGroupRate_(
|
||||
groupName, phase, RateKind::InjectionReservoir);
|
||||
|
||||
if (surfRate != 0.0 || resRate != 0.0) {
|
||||
const auto opmPhase = convertToOpmPhase(phase);
|
||||
schedule.updateSatelliteInjection(
|
||||
report_step_idx, groupName, opmPhase, surfRate, resRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------
|
||||
// Private methods
|
||||
|
||||
@@ -221,6 +221,17 @@ public:
|
||||
/// being processed.
|
||||
void setReportStepIdx(int report_step_idx);
|
||||
|
||||
/// @brief Update the Schedule's satellite production/injection data from
|
||||
/// slave group rates received via MPI.
|
||||
/// @details Populates the Schedule's GSatProd and GroupSatelliteInjection
|
||||
/// for each master group so that opm-common's Summary.cpp satellite_rate
|
||||
/// machinery computes all rate-based summary vectors correctly for all
|
||||
/// master groups.
|
||||
/// @param schedule Non-const reference to the Schedule (needed for
|
||||
/// updateSatelliteProduction/Injection)
|
||||
/// @param report_step_idx 0-based report step index
|
||||
void updateScheduleSatelliteData(Schedule& schedule, int report_step_idx);
|
||||
|
||||
/// @brief Check if a specific slave process has been activated
|
||||
/// @param index Index of the slave process
|
||||
/// @return true if the slave is activated, false otherwise
|
||||
|
||||
Reference in new issue
Block a user