Loading...
Searching...
No Matches
PAvgCalculator.hpp
/*
Copyright 2020, 2023 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PAVG_CALCULATOR_HPP
#define PAVG_CALCULATOR_HPP
#include <array>
#include <cstddef>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
namespace Opm {
class Connection;
class GridDims;
class PAvg;
template<class Scalar> class PAvgDynamicSourceData;
class WellConnections;
} // namespace Opm
namespace Opm {
template<class Scalar> class PAvgCalculator;
template<class Scalar>
typename PAvgCalculator<Scalar>::Result
linearCombination(const Scalar alpha, typename PAvgCalculator<Scalar>::Result x,
const Scalar beta , const typename PAvgCalculator<Scalar>::Result& y);
template<class Scalar>
class PAvgCalculator
{
protected:
class Accumulator;
public:
class Result
{
private:
friend class Accumulator;
friend Result
linearCombination<Scalar>(const Scalar alpha, Result x,
const Scalar beta , const Result& y);
public:
enum class WBPMode
{
WBP, //< Connecting cells
WBP4, //< Immediate neighbours
WBP5, //< Connecting cells and immediate neighbours
WBP9, //< Connecting cells, immediate, and diagonal neighbours
};
Scalar value(const WBPMode type) const
{
return this->wbp_[this->index(type)];
}
private:
static constexpr auto NumModes =
static_cast<std::size_t>(WBPMode::WBP9) + 1;
using WBPStore = std::array<Scalar, NumModes>;
WBPStore wbp_{};
Result& set(const WBPMode type, const Scalar wbp)
{
this->wbp_[this->index(type)] = wbp;
return *this;
}
constexpr typename WBPStore::size_type index(const WBPMode mode) const
{
return static_cast<typename WBPStore::size_type>(mode);
}
};
class Sources
{
public:
Sources& wellBlocks(const PAvgDynamicSourceData<Scalar>& wbSrc)
{
this->wb_ = &wbSrc;
return *this;
}
Sources& wellConns(const PAvgDynamicSourceData<Scalar>& wcSrc)
{
this->wc_ = &wcSrc;
return *this;
}
const PAvgDynamicSourceData<Scalar>& wellBlocks() const
{
return *this->wb_;
}
const PAvgDynamicSourceData<Scalar>& wellConns() const
{
return *this->wc_;
}
private:
const PAvgDynamicSourceData<Scalar>* wb_{nullptr};
const PAvgDynamicSourceData<Scalar>* wc_{nullptr};
};
PAvgCalculator(const GridDims& cellIndexMap,
const WellConnections& connections);
virtual ~PAvgCalculator();
void pruneInactiveWBPCells(const std::vector<bool>& isActive);
void inferBlockAveragePressures(const Sources& sources,
const PAvg& controls,
const Scalar gravity,
const Scalar refDepth);
const std::vector<std::size_t>& allWBPCells() const
{
return this->contributingCells_;
}
std::vector<std::size_t> allWellConnections() const;
const Result& averagePressures() const
{
return this->averagePressures_;
}
protected:
class Accumulator
{
public:
using LocalRunningAverages = std::array<Scalar, 8>;
Accumulator();
~Accumulator();
Accumulator(const Accumulator& rhs);
Accumulator(Accumulator&& rhs);
Accumulator& operator=(const Accumulator& rhs);
Accumulator& operator=(Accumulator&& rhs);
Accumulator& addCentre(const Scalar weight,
const Scalar press);
Accumulator& addRectangular(const Scalar weight,
const Scalar press);
Accumulator& addDiagonal(const Scalar weight,
const Scalar press);
Accumulator& add(const Scalar weight,
const Accumulator& other);
void prepareAccumulation();
void prepareContribution();
void commitContribution(const Scalar innerWeight = -1.0);
// Please note that member functions \c getRunningAverages() and \c
// assignRunningAverages() are concessions to parallel/MPI runs, and
// especially for simulation runs with distributed wells. In this
// situation we need a way to access, communicate/collect/sum, and
// assign partial results. Moreover, the \c LocalRunningAverages
// should be treated opaquely apart from applying a global reduction
// operation. In other words, the intended/expected use case is
//
// Accumulator a{}
// ...
// auto avg = a.getRunningAverages()
// MPI_Allreduce(avg, MPI_SUM)
// a.assignRunningAverages(avg)
//
// Any other use is probably a bug and the above is the canonical
// implementation of member function collectGlobalContributions() in
// MPI aware sub classes of PAvgCalculator.
LocalRunningAverages getRunningAverages() const;
void assignRunningAverages(const LocalRunningAverages& avg);
Result getFinalResult() const;
private:
class Impl;
std::unique_ptr<Impl> pImpl_;
};
Accumulator accumCTF_{};
Accumulator accumPV_{};
private:
using ContrIndexType = std::vector<std::size_t>::size_type;
using SetupMap = std::unordered_map<std::size_t, ContrIndexType>;
enum class NeighbourKind
{
Rectangular,
Diagonal,
};
struct PAvgConnection
{
PAvgConnection(const Scalar ctf_arg,
const Scalar depth_arg,
const ContrIndexType cell_arg)
: ctf (ctf_arg)
, depth(depth_arg)
, cell (cell_arg)
{}
Scalar ctf{};
Scalar depth{};
ContrIndexType cell{};
std::vector<ContrIndexType> rectNeighbours{};
std::vector<ContrIndexType> diagNeighbours{};
};
typename std::vector<PAvgConnection>::size_type numInputConns_{};
std::vector<PAvgConnection> connections_{};
std::vector<typename std::vector<PAvgConnection>::size_type> openConns_{};
std::vector<typename std::vector<PAvgConnection>::size_type> inputConn_{};
std::vector<std::size_t> contributingCells_{};
Result averagePressures_{};
void addConnection(const GridDims& cellIndexMap,
const Connection& conn,
SetupMap& setupHelperMap);
void pruneInactiveConnections(const std::vector<bool>& isActive);
void accumulateLocalContributions(const Sources& sources,
const PAvg& controls,
const Scalar gravity,
const Scalar refDepth);
virtual void collectGlobalContributions();
void assignResults(const PAvg& controls);
void addNeighbour(std::optional<std::size_t> neighbour,
NeighbourKind neighbourKind,
SetupMap& setupHelperMap);
std::size_t lastConnsCell() const;
void addNeighbours_X(const GridDims& grid, SetupMap& setupHelperMap);
void addNeighbours_Y(const GridDims& grid, SetupMap& setupHelperMap);
void addNeighbours_Z(const GridDims& grid, SetupMap& setupHelperMap);
template <typename ConnIndexMap, typename CTFPressureWeightFunction>
void accumulateLocalContributions(const Sources& sources,
const PAvg& controls,
const std::vector<Scalar>& connDP,
ConnIndexMap connIndex,
CTFPressureWeightFunction ctfPressWeight);
template <typename ConnIndexMap>
void accumulateLocalContributions(const Sources& sources,
const PAvg& controls,
const std::vector<Scalar>& connDP,
ConnIndexMap&& connIndex);
void accumulateLocalContribOpen(const Sources& sources,
const PAvg& controls,
const std::vector<Scalar>& connDP);
void accumulateLocalContribAll(const Sources& sources,
const PAvg& controls,
const std::vector<Scalar>& connDP);
template <typename ConnIndexMap>
std::vector<Scalar>
connectionPressureOffsetWell(const std::size_t nconn,
const Sources& sources,
const Scalar gravity,
const Scalar refDepth,
ConnIndexMap connIndex) const;
template <typename ConnIndexMap>
std::vector<Scalar>
connectionPressureOffsetRes(const std::size_t nconn,
const Sources& sources,
const Scalar gravity,
const Scalar refDepth,
ConnIndexMap connIndex) const;
std::vector<Scalar>
connectionPressureOffset(const Sources& sources,
const PAvg& controls,
const Scalar gravity,
const Scalar refDepth) const;
};
} // namespace Opm
#endif // PAVG_CALCULATOR_HPP
Opm::PAvgCalculator::Accumulator
Accumulate weighted running averages of cell contributions to WBP.
Definition PAvgCalculator.hpp:263
Opm::PAvgCalculator::Accumulator::Accumulator
Accumulator()
Constructor.
Definition PAvgCalculator.cpp:495
Opm::PAvgCalculator::Accumulator::prepareAccumulation
void prepareAccumulation()
Zero out/clear WBP result buffer.
Definition PAvgCalculator.cpp:565
Opm::PAvgCalculator::Accumulator::addCentre
Accumulator & addCentre(const Scalar weight, const Scalar press)
Add contribution from centre/connecting cell.
Definition PAvgCalculator.cpp:530
Opm::PAvgCalculator::Accumulator::addDiagonal
Accumulator & addDiagonal(const Scalar weight, const Scalar press)
Add contribution from diagonal, level 2 neighbouring cell.
Definition PAvgCalculator.cpp:548
Opm::PAvgCalculator::Accumulator::getFinalResult
Result getFinalResult() const
Calculate final WBP results from individual contributions.
Definition PAvgCalculator.cpp:598
Opm::PAvgCalculator::Accumulator::prepareContribution
void prepareContribution()
Zero out/clear WBP term buffer.
Definition PAvgCalculator.cpp:571
Opm::PAvgCalculator::Accumulator::~Accumulator
~Accumulator()
Destructor.
Opm::PAvgCalculator::Accumulator::assignRunningAverages
void assignRunningAverages(const LocalRunningAverages &avg)
Assign coalesced/global contributions.
Definition PAvgCalculator.cpp:591
Opm::PAvgCalculator::Accumulator::getRunningAverages
LocalRunningAverages getRunningAverages() const
Get buffer of intermediate, local results.
Definition PAvgCalculator.cpp:584
Opm::PAvgCalculator::Accumulator::addRectangular
Accumulator & addRectangular(const Scalar weight, const Scalar press)
Add contribution from direct, rectangular, level 1 neighbouring cell.
Definition PAvgCalculator.cpp:539
Opm::PAvgCalculator::Accumulator::add
Accumulator & add(const Scalar weight, const Accumulator &other)
Add contribution from other accumulator.
Definition PAvgCalculator.cpp:557
Opm::PAvgCalculator::Accumulator::LocalRunningAverages
std::array< Scalar, 8 > LocalRunningAverages
Collection of running averages and their associate weights.
Definition PAvgCalculator.hpp:269
Opm::PAvgCalculator::Accumulator::commitContribution
void commitContribution(const Scalar innerWeight=-1.0)
Accumulate current source term into result buffer whilst applying any user-prescribed term weighting.
Definition PAvgCalculator.cpp:577
Opm::PAvgCalculator::Accumulator::operator=
Accumulator & operator=(const Accumulator &rhs)
Assignment operator.
Definition PAvgCalculator.cpp:514
Opm::PAvgCalculator::Result
Result of block-averaging well pressure procedure.
Definition PAvgCalculator.hpp:81
Opm::PAvgCalculator::Result::value
Scalar value(const WBPMode type) const
Retrieve numerical value of specific block-averaged well pressure.
Definition PAvgCalculator.hpp:106
Opm::PAvgCalculator::Result::WBPMode
WBPMode
Kind of block-averaged well pressure.
Definition PAvgCalculator.hpp:95
Opm::PAvgCalculator::Sources
References to source contributions owned by other party.
Definition PAvgCalculator.hpp:146
Opm::PAvgCalculator::Sources::wellConns
const PAvgDynamicSourceData< Scalar > & wellConns() const
Get read-only access to connection-level contributions.
Definition PAvgCalculator.hpp:177
Opm::PAvgCalculator::Sources::wellConns
Sources & wellConns(const PAvgDynamicSourceData< Scalar > &wcSrc)
Provide reference to connection-level contributions (pressure, pore-volume, mixture density) owned by...
Definition PAvgCalculator.hpp:164
Opm::PAvgCalculator::Sources::wellBlocks
Sources & wellBlocks(const PAvgDynamicSourceData< Scalar > &wbSrc)
Provide reference to cell-level contributions (pressure, pore-volume, mixture density) owned by other...
Definition PAvgCalculator.hpp:153
Opm::PAvgCalculator::Sources::wellBlocks
const PAvgDynamicSourceData< Scalar > & wellBlocks() const
Get read-only access to cell-level contributions.
Definition PAvgCalculator.hpp:171
Opm::PAvgCalculator
Facility for deriving well-level pressure values from selected block-averaging procedures.
Definition PAvgCalculator.hpp:74
Opm::PAvgCalculator::~PAvgCalculator
virtual ~PAvgCalculator()
Destructor.
Opm::PAvgCalculator::pruneInactiveWBPCells
void pruneInactiveWBPCells(const std::vector< bool > &isActive)
Finish construction by pruning inactive cells.
Definition PAvgCalculator.cpp:636
Opm::PAvgCalculator::allWellConnections
std::vector< std::size_t > allWellConnections() const
List all reservoir connections that potentially contribute to this block-averaging pressure calculati...
Definition PAvgCalculator.cpp:721
Opm::PAvgCalculator::accumPV_
Accumulator accumPV_
Average pressures weighted by pore-volume.
Definition PAvgCalculator.hpp:393
Opm::PAvgCalculator::accumCTF_
Accumulator accumCTF_
Average pressures weighted by connection transmissibility factor.
Definition PAvgCalculator.hpp:390
Opm::PAvgCalculator::averagePressures
const Result & averagePressures() const
Block-average pressure derived from selection of source cells.
Definition PAvgCalculator.hpp:255
Opm::PAvgCalculator::PAvgCalculator
PAvgCalculator(const GridDims &cellIndexMap, const WellConnections &connections)
Constructor.
Definition PAvgCalculator.cpp:618
Opm::PAvgCalculator::allWBPCells
const std::vector< std::size_t > & allWBPCells() const
List of all cells, global indices in natural ordering, that contribute to the block-average pressures...
Definition PAvgCalculator.hpp:233
Opm::PAvgCalculator::inferBlockAveragePressures
void inferBlockAveragePressures(const Sources &sources, const PAvg &controls, const Scalar gravity, const Scalar refDepth)
Compute block-average well-level pressure values from collection of source contributions and user-def...
Definition PAvgCalculator.cpp:707
Opm::PAvgDynamicSourceData
Dynamic source data for block-average pressure calculations.
Definition PAvgDynamicSourceData.hpp:36
Opm::PAvg
Definition PAvg.hpp:30
Opm
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30