Merge pull request #6830 from daavid00/bvels

BVEL[G|O|W][I|J|K][|-] summary keywords
This commit is contained in:
David Landa-Marbán authored and GitHub committed 2026-02-19 13:58:08 +01:00
commit 0eace1f172
5 files changed
+375 -33

No files matched your search

@@ -333,6 +333,15 @@ public:
const auto& getFloresInfo() const
{ return floresInfo_; }
/*!
* \brief Return constant reference to the velocityInfo.
*
* (This object is only non-empty if dispersion, bioeffects, or block
* velocities are active.)
*/
const auto& getVelocityInfo() const
{ return velocityInfo_; }
template <class SubDomainType>
void resetSystem_(const SubDomainType& domain)
{
@@ -684,6 +693,13 @@ private:
SparseTable<FlowInfo> flowsInfo_;
SparseTable<FlowInfo> floresInfo_;
struct VelocityInfo
{
int faceId;
VectorBlock velocity;
};
SparseTable<VelocityInfo> velocityInfo_;
// the jacobian matrix
std::unique_ptr<SparseMatrixAdapter> jacobian_;
@@ -462,7 +462,8 @@ public:
/*!
* \brief Return constant reference to the velocityInfo.
*
* (This object is only non-empty if the DISPERC keyword is true.)
* (This object is only non-empty if dispersion, bioeffects, or block
* velocities are active.)
*/
const auto& getVelocityInfo() const
{ return velocityInfo_; }
@@ -675,15 +676,17 @@ private:
void createFlows_()
{
OPM_TIMEBLOCK(createFlows);
// If FLOWS/FLORES is set in any RPTRST in the schedule, then we initializate the sparse tables
// For now, do the same also if any block flows are requested (TODO: only save requested cells...)
// If FLOWS/FLORES is set in any RPTRST in the schedule, then we initializate the sparse tables.
// If DISPERC is in the deck, we initialize the sparse table here as well.
const bool anyFlows = simulator_().problem().eclWriter().outputModule().getFlows().anyFlows();
const auto& blockFlows = simulator_().problem().eclWriter().outputModule().getFlows().blockFlows();
const auto& blockVelocity = simulator_().problem().eclWriter().outputModule().getFlows().blockVelocity();
const bool isTemp = simulator_().vanguard().eclState().getSimulationConfig().isTemp();
const bool anyFlores = simulator_().problem().eclWriter().outputModule().getFlows().anyFlores() || isTemp;
const bool dispersionActive = simulator_().vanguard().eclState().getSimulationConfig().rock_config().dispersion();
if (((!(anyFlows || !blockFlows.empty()) || !flowsInfo_.empty()) && (!anyFlores || !floresInfo_.empty())) && (!dispersionActive && !enableBioeffects)) {
if (!dispersionActive && !enableBioeffects && blockVelocity.empty()
&& !((anyFlows || !blockFlows.empty()) && flowsInfo_.empty())
&& !(anyFlores && floresInfo_.empty())) {
return;
}
const auto& model = model_();
@@ -715,12 +718,16 @@ private:
if (dispersionActive || enableBioeffects) {
velocityInfo_.reserve(numCells, 6 * numCells);
}
else if (!blockVelocity.empty()) {
velocityInfo_.reserve(numCells, 6 * blockVelocity.size());
}
for (const auto& elem : elements(gridView_())) {
stencil.update(elem);
for (unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
const unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
bool blockFlowFound = false;
bool blockVelocityFound = false;
if (!blockFlows.empty()) {
if (std::binary_search(blockFlows.begin(), blockFlows.end(),
simulator_().vanguard().cartesianIndex(myIdx))) {
@@ -728,7 +735,19 @@ private:
}
else {
flowsInfo_.appendRow(loc_flinfo.begin(), loc_flinfo.begin());
if (!dispersionActive && !enableBioeffects && !anyFlores) {
if (!dispersionActive && !enableBioeffects && !anyFlores && blockVelocity.empty()) {
continue;
}
}
}
if (!blockVelocity.empty() && !(dispersionActive || enableBioeffects)) {
if (std::binary_search(blockVelocity.begin(), blockVelocity.end(),
simulator_().vanguard().cartesianIndex(myIdx))) {
blockVelocityFound = true;
}
else {
velocityInfo_.appendRow(loc_vlinfo.begin(), loc_vlinfo.begin());
if (!anyFlows && blockFlows.empty() && !anyFlores) {
continue;
}
}
@@ -755,7 +774,7 @@ private:
}
}
loc_flinfo[dofIdx - 1] = FlowInfo{faceId, flow, nncId};
loc_vlinfo[dofIdx - 1] = VelocityInfo{flow};
loc_vlinfo[dofIdx - 1] = VelocityInfo{faceId, flow};
}
}
@@ -771,7 +790,7 @@ private:
if (anyFlores) {
floresInfo_.appendRow(loc_flinfo.begin(), loc_flinfo.end());
}
if (dispersionActive || enableBioeffects) {
if (dispersionActive || enableBioeffects || blockVelocityFound) {
velocityInfo_.appendRow(loc_vlinfo.begin(), loc_vlinfo.end());
}
}
@@ -895,6 +914,7 @@ private:
// the full system to zero, not just our part.
// Instead, that must be called before starting the linearization.
const bool dispersionActive = simulator_().vanguard().eclState().getSimulationConfig().rock_config().dispersion();
const auto& blockVelocity = simulator_().problem().eclWriter().outputModule().getFlows().blockVelocity();
const unsigned int numCells = domain.cells.size();
// Fetch timestepsize used later in accumulation term.
@@ -935,6 +955,15 @@ private:
darcyFlux[phaseIdx].value() / nbInfo.res_nbinfo.faceArea;
}
}
else if (!blockVelocity.empty()) {
if (std::binary_search(blockVelocity.begin(), blockVelocity.end(),
simulator_().vanguard().cartesianIndex(globI))) {
for (unsigned phaseIdx = 0; phaseIdx < numEq; ++phaseIdx) {
velocityInfo_[globI][loc].velocity[phaseIdx] =
darcyFlux[phaseIdx].value() / nbInfo.res_nbinfo.faceArea;
}
}
}
setResAndJacobi(res, bMat, adres);
residual_[globI] += res;
//SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat);
@@ -1089,6 +1118,7 @@ private:
struct VelocityInfo
{
int faceId;
VectorBlock velocity;
};
SparseTable<VelocityInfo> velocityInfo_;
+64 -20
View File
@@ -89,7 +89,18 @@ FlowsContainer(const Schedule& schedule,
const SummaryConfig& summaryConfig,
std::function<bool(const int)> isInterior)
{
using namespace std::string_literals;
using Dir = FaceDir::DirEnum;
const std::array<int, 3> phaseIdxs = {gasPhaseIdx, oilPhaseIdx, waterPhaseIdx};
const std::array<int, 3> compIdxs = {gasCompIdx, oilCompIdx, waterCompIdx};
const auto nameIdxs = std::array{ "G"s, "O"s, "W"s };
const auto ijkIdxs = std::array{ "I-"s, "I"s, "J-"s, "J"s, "K-"s, "K"s };
const auto dirIdxs = std::array{ FaceDir::ToIntersectionIndex(Dir::XMinus),
FaceDir::ToIntersectionIndex(Dir::XPlus),
FaceDir::ToIntersectionIndex(Dir::YMinus),
FaceDir::ToIntersectionIndex(Dir::YPlus),
FaceDir::ToIntersectionIndex(Dir::ZMinus),
FaceDir::ToIntersectionIndex(Dir::ZPlus) };
// Check if FLORES/FLOWS is set in any RPTRST in the schedule
enableFlores_ = false; // Used for the output of i+, j+, k+
@@ -110,18 +121,31 @@ FlowsContainer(const Schedule& schedule,
return rstkw.find("FLOWS") != rstkw.end();
});
// Check for any BVEL[G|O|W][I|J|K][|-] summary keys
if (summaryConfig.keywords("BVEL*").size() > 0) {
for (unsigned ii = 0; ii < phaseIdxs.size(); ++ii) {
if (FluidSystem::phaseIsActive(phaseIdxs[ii])) {
for (unsigned jj = 0; jj < dirIdxs.size(); ++jj) {
std::string blockid = "BVEL" + nameIdxs[ii] + ijkIdxs[jj];
if (summaryConfig.keywords(blockid).size() == 0) {
continue;
}
for (const auto& node : summaryConfig.keywords(blockid)) {
if (isInterior(node.number() - 1)) {
blockVelocityIds_[compIdxs[ii]][dirIdxs[jj]].push_back(node.number() - 1);
blockVelocityAllIds_.push_back(node.number() - 1);
}
}
}
}
}
std::sort(blockVelocityAllIds_.begin(), blockVelocityAllIds_.end());
auto last = std::unique(blockVelocityAllIds_.begin(), blockVelocityAllIds_.end());
blockVelocityAllIds_.erase(last, blockVelocityAllIds_.end());
}
// Check for any BFLO[G|O|W][I|J|K][|-] summary keys
if (summaryConfig.keywords("BFLO*").size() > 0 && !anyFlows_) {
const std::array<int, 3> phaseIdxs { gasPhaseIdx, oilPhaseIdx, waterPhaseIdx };
const std::array<int, 3> compIdxs { gasCompIdx, oilCompIdx, waterCompIdx };
const std::string nameIdxs[3] { "G", "O", "W" };
const std::string ijkIdxs[6] { "I-", "I", "J-", "J", "K-", "K" };
const std::array<int, 6> dirIdxs { FaceDir::ToIntersectionIndex(Dir::XMinus),
FaceDir::ToIntersectionIndex(Dir::XPlus),
FaceDir::ToIntersectionIndex(Dir::YMinus),
FaceDir::ToIntersectionIndex(Dir::YPlus),
FaceDir::ToIntersectionIndex(Dir::ZMinus),
FaceDir::ToIntersectionIndex(Dir::ZPlus) };
for (unsigned ii = 0; ii < phaseIdxs.size(); ++ii) {
if (FluidSystem::phaseIsActive(phaseIdxs[ii])) {
for (unsigned jj = 0; jj < dirIdxs.size(); ++jj) {
@@ -152,17 +176,29 @@ allocate(const std::size_t bufferSize,
const bool allocRestart,
std::map<std::string, int>& rstKeywords)
{
using namespace std::string_literals;
using Dir = FaceDir::DirEnum;
const std::array<int, 3> phaseIdxs { gasPhaseIdx, oilPhaseIdx, waterPhaseIdx };
const std::array<int, 3> compIdxs { gasCompIdx, oilCompIdx, waterCompIdx };
const std::string nameIdxs[3] { "G", "O", "W" };
const std::string ijkIdxs[6] { "I-", "I", "J-", "J", "K-", "K" };
const std::array<int, 6> dirIdxs { FaceDir::ToIntersectionIndex(Dir::XMinus),
FaceDir::ToIntersectionIndex(Dir::XPlus),
FaceDir::ToIntersectionIndex(Dir::YMinus),
FaceDir::ToIntersectionIndex(Dir::YPlus),
FaceDir::ToIntersectionIndex(Dir::ZMinus),
FaceDir::ToIntersectionIndex(Dir::ZPlus) };
const std::array<int, 3> phaseIdxs = {gasPhaseIdx, oilPhaseIdx, waterPhaseIdx};
const std::array<int, 3> compIdxs = {gasCompIdx, oilCompIdx, waterCompIdx};
const auto nameIdxs = std::array{ "G"s, "O"s, "W"s };
const auto ijkIdxs = std::array{ "I-"s, "I"s, "J-"s, "J"s, "K-"s, "K"s };
const auto dirIdxs = std::array{ FaceDir::ToIntersectionIndex(Dir::XMinus),
FaceDir::ToIntersectionIndex(Dir::XPlus),
FaceDir::ToIntersectionIndex(Dir::YMinus),
FaceDir::ToIntersectionIndex(Dir::YPlus),
FaceDir::ToIntersectionIndex(Dir::ZMinus),
FaceDir::ToIntersectionIndex(Dir::ZPlus) };
// Allocate vels for BVEL[G|O|W][I|J|K][|-] summary keywords
if (!blockVelocityAllIds_.empty()) {
for (unsigned ii = 0; ii < phaseIdxs.size(); ++ii) {
if (FluidSystem::phaseIsActive(phaseIdxs[ii])) {
for (unsigned jj = 0; jj < dirIdxs.size(); ++jj) {
velocity_[compIdxs[ii]][dirIdxs[jj]].resize(blockVelocityIds_[compIdxs[ii]][dirIdxs[jj]].size(), 0.0);
}
}
}
}
// Allocate flows for BFLO[G|O|W][I|J|K][|-] summary keywords
if (!blockFlowsAllIds_.empty()) {
@@ -304,6 +340,14 @@ assignFlows(const unsigned globalDofIdx,
}
}
template<class FluidSystem>
void FlowsContainer<FluidSystem>::
assignBlockVelocity(const unsigned index,
const int faceId,
const int comp_idx,
const Scalar velocity)
{ velocity_[comp_idx][faceId][index] = velocity; }
template<class FluidSystem>
void FlowsContainer<FluidSystem>::
assignBlockFlows(const unsigned index,
+36 -3
View File
@@ -72,6 +72,11 @@ public:
const Scalar oil,
const Scalar water);
void assignBlockVelocity(const unsigned globalDofIdx,
const int faceId,
const int comp_idx,
const Scalar velocity);
void assignBlockFlows(const unsigned globalDofIdx,
const int faceId,
const int comp_idx,
@@ -95,6 +100,9 @@ public:
bool hasFlows() const
{ return enableFlows_; }
const std::vector<int> blockVelocity() const
{ return blockVelocityAllIds_; }
const std::vector<int> blockFlows() const
{ return blockFlowsAllIds_; }
@@ -107,6 +115,15 @@ public:
return std::distance(blockIdxs.begin(), it);
}
unsigned blockVelocityIds(const unsigned globalDofIdx,
const int dir,
const int comp_idx) const
{
const auto& blockIdxs = blockVelocityIds_[comp_idx][dir];
auto it = std::lower_bound(blockIdxs.begin(), blockIdxs.end(), globalDofIdx);
return std::distance(blockIdxs.begin(), it);
}
bool anyFlows() const
{ return anyFlows_; }
@@ -122,14 +139,27 @@ public:
bool anyFlores() const
{ return anyFlores_; }
bool hasBlockValue(const unsigned globalDofIdx,
const int dir,
const int comp_idx) const
bool hasBlockVelocityValue(const unsigned globalDofIdx,
const int dir,
const int comp_idx) const
{
const auto& blockIdxs = blockVelocityIds_[comp_idx][dir];
return std::binary_search(blockIdxs.begin(), blockIdxs.end(), globalDofIdx);
}
bool hasBlockFlowValue(const unsigned globalDofIdx,
const int dir,
const int comp_idx) const
{
const auto& blockIdxs = blockFlowsIds_[comp_idx][dir];
return std::binary_search(blockIdxs.begin(), blockIdxs.end(), globalDofIdx);
}
Scalar getVelocity(const unsigned globalDofIdx,
const FaceDir::DirEnum dir,
const int comp_idx) const
{ return velocity_[comp_idx][FaceDir::ToIntersectionIndex(dir)][globalDofIdx]; }
Scalar getFlow(const unsigned globalDofIdx,
const FaceDir::DirEnum dir,
const int comp_idx) const
@@ -145,12 +175,15 @@ private:
std::array<std::array<ScalarBuffer, 6>, numPhases> flows_;
std::array<std::array<ScalarBuffer, 6>, numPhases> flores_;
std::array<std::array<ScalarBuffer, 6>, numPhases> velocity_;
std::array<FlowsData<double>, 3> floresn_;
std::array<FlowsData<double>, 3> flowsn_;
std::vector<int> blockFlowsAllIds_;
std::vector<int> blockVelocityAllIds_;
std::array<std::array<std::vector<int>, 6>, numPhases> blockFlowsIds_;
std::array<std::array<std::vector<int>, 6>, numPhases> blockVelocityIds_;
};
} // namespace Opm
+222 -3
View File
@@ -1652,14 +1652,22 @@ private:
const std::vector<int>& blockIdxs = flowsC.blockFlows();
const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
if (std::binary_search(blockIdxs.begin(), blockIdxs.end(), cartesianIdx)) {
const std::array<int, 3> compIdxs { gasCompIdx, oilCompIdx, waterCompIdx };
const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
for (const auto& flowsInfo : flowsInfos) {
if (flowsInfo.faceId < 0) {
continue;
}
for (unsigned ii = 0; ii < compIdxs.size(); ++ii) {
if (flowsC.hasBlockValue(cartesianIdx, flowsInfo.faceId, compIdxs[ii])) {;
if (!compEnabled[ii]) {
continue;
}
if (flowsC.hasBlockFlowValue(cartesianIdx, flowsInfo.faceId, compIdxs[ii])) {
flowsC.assignBlockFlows(flowsC.blockFlowsIds(cartesianIdx, flowsInfo.faceId, compIdxs[ii]),
flowsInfo.faceId,
compIdxs[ii],
flowsInfo.flow[compIdxs[ii]]);
flowsInfo.flow[conti0EqIdx
+ FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
}
}
}
@@ -1697,6 +1705,37 @@ private:
}
}, !this->simulator_.problem().model().linearizer().getFloresInfo().empty()
},
Entry{[&velocityInf = this->simulator_.problem().model().linearizer().getVelocityInfo(),
&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const auto& velocityInfos = velocityInf[ectx.globalDofIdx];
const std::vector<int>& blockIdxs = flowsC.blockVelocity();
const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
if (std::binary_search(blockIdxs.begin(), blockIdxs.end(), cartesianIdx)) {
const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
for (const auto& velocityInfo : velocityInfos) {
if (velocityInfo.faceId < 0) {
continue;
}
for (unsigned ii = 0; ii < compIdxs.size(); ++ii) {
if (!compEnabled[ii]) {
continue;
}
if (flowsC.hasBlockVelocityValue(cartesianIdx, velocityInfo.faceId, compIdxs[ii])) {
flowsC.assignBlockVelocity(flowsC.blockVelocityIds(cartesianIdx, velocityInfo.faceId, compIdxs[ii]),
velocityInfo.faceId,
compIdxs[ii],
velocityInfo.velocity[conti0EqIdx
+ FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
}
}
}
}
}, !this->flowsC_.blockVelocity().empty() &&
!this->simulator_.problem().model().linearizer().getVelocityInfo().empty()
},
// hack to make the intial output of rs and rv Ecl compatible.
// For cells with swat == 1 Ecl outputs; rs = rsSat and rv=rvSat, in all but the initial step
// where it outputs rs and rv values calculated by the initialization. To be compatible we overwrite
@@ -2164,6 +2203,186 @@ private:
}
}
},
Entry{ScalarEntry{"BVELGI",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx);
return flowsC.getVelocity(index, Dir::XPlus, gasCompIdx);
}
}
},
Entry{ScalarEntry{"BVELGI-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx);
return flowsC.getVelocity(index, Dir::XMinus, gasCompIdx);
}
}
},
Entry{ScalarEntry{"BVELGJ",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx);
return flowsC.getVelocity(index, Dir::YPlus, gasCompIdx);
}
}
},
Entry{ScalarEntry{"BVELGJ-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx);
return flowsC.getVelocity(index, Dir::YMinus, gasCompIdx);
}
}
},
Entry{ScalarEntry{"BVELGK",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx);
return flowsC.getVelocity(index, Dir::ZPlus, gasCompIdx);
}
}
},
Entry{ScalarEntry{"BVELGK-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx);
return flowsC.getVelocity(index, Dir::ZMinus, gasCompIdx);
}
}
},
Entry{ScalarEntry{"BVELOI",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx);
return flowsC.getVelocity(index, Dir::XPlus, oilCompIdx);
}
}
},
Entry{ScalarEntry{"BVELOI-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx);
return flowsC.getVelocity(index, Dir::XMinus, oilCompIdx);
}
}
},
Entry{ScalarEntry{"BVELOJ",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx);
return flowsC.getVelocity(index, Dir::YPlus, oilCompIdx);
}
}
},
Entry{ScalarEntry{"BVELOJ-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx);
return flowsC.getVelocity(index, Dir::YMinus, oilCompIdx);
}
}
},
Entry{ScalarEntry{"BVELOK",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx);
return flowsC.getVelocity(index, Dir::ZPlus, oilCompIdx);
}
}
},
Entry{ScalarEntry{"BVELOK-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx);
return flowsC.getVelocity(index, Dir::ZMinus, oilCompIdx);
}
}
},
Entry{ScalarEntry{"BVELWI",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx);
return flowsC.getVelocity(index, Dir::XPlus, waterCompIdx);
}
}
},
Entry{ScalarEntry{"BVELWI-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx);
return flowsC.getVelocity(index, Dir::XMinus, waterCompIdx);
}
}
},
Entry{ScalarEntry{"BVELWJ",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx);
return flowsC.getVelocity(index, Dir::YPlus, waterCompIdx);
}
}
},
Entry{ScalarEntry{"BVELWJ-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx);
return flowsC.getVelocity(index, Dir::YMinus, waterCompIdx);
}
}
},
Entry{ScalarEntry{"BVELWK",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx);
return flowsC.getVelocity(index, Dir::ZPlus, waterCompIdx);
}
}
},
Entry{ScalarEntry{"BVELWK-",
[&flowsC = this->flowsC_,
&vanguard = this->simulator_.vanguard()](const Context& ectx)
{
const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx);
return flowsC.getVelocity(index, Dir::ZMinus, waterCompIdx);
}
}
},
Entry{ScalarEntry{"BRPV",
[&model = this->simulator_.model()](const Context& ectx)
{