Simulator Group Data: Chase Upstream API Update

This commit makes the 'groupData()' function return a

    map<string, Opm::data::GroupData>

object instead of a

    map<string, Opm::data::GroupConstraints>

object.  The 'GroupData' structure adds a level of indirection to
the current per-group summary quantities that are directly assigned
by the simulator.  While here, also move the assignment of the
current group constraints/control values out to a separate helper
to reduce the body of the per-group loop in 'groupData()'.

This is in preparation of adding support for reporting group-level
production/injection guiderates (Gx[IP]GR) to the summary file.
This commit is contained in:
Bård Skaflestad 2020-07-01 13:52:02 +02:00
parent 6a6f55b099
commit 5bb4321824
4 changed files with 100 additions and 67 deletions

View File

@ -549,41 +549,43 @@ public:
class PackUnPackGroupData : public P2PCommunicatorType::DataHandleInterface
{
const Opm::data::Group& localGroupData_;
Opm::data::Group& globalGroupData_;
const Opm::data::GroupValues& localGroupData_;
Opm::data::GroupValues& globalGroupData_;
public:
PackUnPackGroupData(const Opm::data::Group& localGroupData,
Opm::data::Group& globalGroupData,
bool isIORank)
: localGroupData_(localGroupData)
PackUnPackGroupData(const Opm::data::GroupValues& localGroupData,
Opm::data::GroupValues& globalGroupData,
const bool isIORank)
: localGroupData_ (localGroupData)
, globalGroupData_(globalGroupData)
{
if (isIORank) {
MessageBufferType buffer;
pack(0, buffer);
if (! isIORank) { return; }
// pass a dummy_link to satisfy virtual class
int dummyLink = -1;
unpack(dummyLink, buffer);
}
MessageBufferType buffer;
this->pack(0, buffer);
// pass a dummy_link to satisfy virtual class
const int dummyLink = -1;
this->unpack(dummyLink, buffer);
}
// pack all data associated with link
void pack(int link, MessageBufferType& buffer)
{
// we should only get one link
if (link != 0)
throw std::logic_error("link in method pack is not 0 as expected");
if (link != 0) {
throw std::logic_error {
"link in method pack is not 0 as expected"
};
}
// write all group data
localGroupData_.write(buffer);
this->localGroupData_.write(buffer);
}
// unpack all data associated with link
void unpack(int /*link*/, MessageBufferType& buffer)
{ globalGroupData_.read(buffer); }
{ this->globalGroupData_.read(buffer); }
};
@ -649,7 +651,7 @@ public:
void collect(const Opm::data::Solution& localCellData,
const std::map<std::pair<std::string, int>, double>& localBlockData,
const Opm::data::Wells& localWellData,
const Opm::data::Group& localGroupData)
const Opm::data::GroupValues& localGroupData)
{
globalCellData_ = {};
globalBlockData_.clear();
@ -660,34 +662,39 @@ public:
if(!needsReordering && !isParallel())
return;
// this also packs and unpacks the local buffers one ioRank
PackUnPackCellData
packUnpackCellData(localCellData,
globalCellData_,
localIndexMap_,
indexMaps_,
numCells(),
isIORank());
if (!isParallel())
// this also linearises the local buffers on ioRank
PackUnPackCellData packUnpackCellData {
localCellData,
this->globalCellData_,
this->localIndexMap_,
this->indexMaps_,
this->numCells(),
this->isIORank()
};
if (! isParallel()) {
// no need to collect anything.
return;
}
PackUnPackWellData
packUnpackWellData(localWellData,
globalWellData_,
isIORank());
PackUnPackWellData packUnpackWellData {
localWellData,
this->globalWellData_,
this->isIORank()
};
PackUnPackGroupData
packUnpackGroupData(localGroupData,
globalGroupData_,
isIORank());
PackUnPackGroupData packUnpackGroupData {
localGroupData,
this->globalGroupData_,
this->isIORank()
};
PackUnPackBlockData
packUnpackBlockData(localBlockData,
globalBlockData_,
isIORank());
PackUnPackBlockData packUnpackBlockData {
localBlockData,
this->globalBlockData_,
this->isIORank()
};
toIORankComm_.exchange(packUnpackCellData);
toIORankComm_.exchange(packUnpackWellData);
@ -711,7 +718,7 @@ public:
const Opm::data::Wells& globalWellData() const
{ return globalWellData_; }
const Opm::data::Group& globalGroupData() const
const Opm::data::GroupValues& globalGroupData() const
{ return globalGroupData_; }
bool isIORank() const
@ -760,7 +767,7 @@ protected:
Opm::data::Solution globalCellData_;
std::map<std::pair<std::string, int>, double> globalBlockData_;
Opm::data::Wells globalWellData_;
Opm::data::Group globalGroupData_;
Opm::data::GroupValues globalGroupData_;
std::vector<int> localIdxToGlobalIdx_;
};

View File

@ -562,7 +562,10 @@ public:
return wellDat;
}
Opm::data::Group groupData(const int /* reportStepIdx */, Opm::Schedule& /* sched */) const {
Opm::data::GroupValues
groupData(const int /* reportStepIdx */,
const Opm::Schedule& /* sched */) const
{
return {};
}

View File

@ -187,30 +187,19 @@ namespace Opm {
void initFromRestartFile(const RestartValue& restartValues);
Opm::data::Group groupData(const int reportStepIdx, Opm::Schedule& sched) const
Opm::data::GroupValues
groupData(const int reportStepIdx, const Opm::Schedule& sched) const
{
Opm::data::Group dw;
for (const std::string gname : sched.groupNames(reportStepIdx)) {
auto gvalues = ::Opm::data::GroupValues{};
for (const auto& gname : sched.groupNames(reportStepIdx)) {
const auto& grup = sched.getGroup(gname, reportStepIdx);
const auto& grup_type = grup.getGroupType();
Opm::data::currentGroupConstraints cgc;
cgc.currentProdConstraint = Opm::Group::ProductionCMode::NONE;
cgc.currentGasInjectionConstraint = Opm::Group::InjectionCMode::NONE;
cgc.currentWaterInjectionConstraint = Opm::Group::InjectionCMode::NONE;
if (this->well_state_.hasProductionGroupControl(gname)) {
cgc.currentProdConstraint = this->well_state_.currentProductionGroupControl(gname);
}
if ((grup_type == Opm::Group::GroupType::INJECTION) || (grup_type == Opm::Group::GroupType::MIXED)) {
if (this->well_state_.hasInjectionGroupControl(Opm::Phase::WATER, gname)) {
cgc.currentWaterInjectionConstraint = this->well_state_.currentInjectionGroupControl(Opm::Phase::WATER, gname);
}
if (this->well_state_.hasInjectionGroupControl(Opm::Phase::GAS, gname)) {
cgc.currentGasInjectionConstraint = this->well_state_.currentInjectionGroupControl(Opm::Phase::GAS, gname);
}
}
dw.emplace(gname, cgc);
auto& gdata = gvalues[gname];
this->assignGroupControl(grup, gdata);
}
return dw;
return gvalues;
}
Opm::data::Wells wellData() const
@ -443,8 +432,7 @@ namespace Opm {
void setWsolvent(const Group& group, const Schedule& schedule, const int reportStepIdx, double wsolvent);
void assignGroupControl(const Group& group, data::GroupData& gdata) const;
};

View File

@ -2430,5 +2430,40 @@ namespace Opm {
}
}
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
assignGroupControl(const Group& group, data::GroupData& gdata) const
{
const auto& gname = group.name();
const auto grup_type = group.getGroupType();
auto& cgc = gdata.currentControl;
cgc.currentProdConstraint =
::Opm::Group::ProductionCMode::NONE;
cgc.currentGasInjectionConstraint =
cgc.currentWaterInjectionConstraint =
::Opm::Group::InjectionCMode::NONE;
if (this->well_state_.hasProductionGroupControl(gname)) {
cgc.currentProdConstraint = this->well_state_
.currentProductionGroupControl(gname);
}
if ((grup_type == ::Opm::Group::GroupType::INJECTION) ||
(grup_type == ::Opm::Group::GroupType::MIXED))
{
if (this->well_state_.hasInjectionGroupControl(::Opm::Phase::WATER, gname)) {
cgc.currentWaterInjectionConstraint = this->well_state_
.currentInjectionGroupControl(::Opm::Phase::WATER, gname);
}
if (this->well_state_.hasInjectionGroupControl(::Opm::Phase::GAS, gname)) {
cgc.currentGasInjectionConstraint = this->well_state_
.currentInjectionGroupControl(::Opm::Phase::GAS, gname);
}
}
}
} // namespace Opm