mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #5231 from bska/phase-pv-region-average
Add Utility for Region-Based Phase-Filled Averages
This commit is contained in:
@@ -476,6 +476,51 @@ opm_add_test(test_parallel_wbp_calculation_well_openconns
|
||||
2
|
||||
)
|
||||
|
||||
opm_add_test(test_parallel_region_phase_pvaverage_np2
|
||||
EXE_NAME
|
||||
test_region_phase_pvaverage
|
||||
CONDITION
|
||||
MPI_FOUND AND Boost_UNIT_TEST_FRAMEWORK_FOUND
|
||||
DRIVER_ARGS
|
||||
-n 2
|
||||
-b ${PROJECT_BINARY_DIR}
|
||||
TEST_ARGS
|
||||
--run_test=Parallel/*
|
||||
NO_COMPILE
|
||||
PROCESSORS
|
||||
2
|
||||
)
|
||||
|
||||
opm_add_test(test_parallel_region_phase_pvaverage_np3
|
||||
EXE_NAME
|
||||
test_region_phase_pvaverage
|
||||
CONDITION
|
||||
MPI_FOUND AND Boost_UNIT_TEST_FRAMEWORK_FOUND
|
||||
DRIVER_ARGS
|
||||
-n 3
|
||||
-b ${PROJECT_BINARY_DIR}
|
||||
TEST_ARGS
|
||||
--run_test=Parallel/*
|
||||
NO_COMPILE
|
||||
PROCESSORS
|
||||
3
|
||||
)
|
||||
|
||||
opm_add_test(test_parallel_region_phase_pvaverage_np4
|
||||
EXE_NAME
|
||||
test_region_phase_pvaverage
|
||||
CONDITION
|
||||
MPI_FOUND AND Boost_UNIT_TEST_FRAMEWORK_FOUND
|
||||
DRIVER_ARGS
|
||||
-n 4
|
||||
-b ${PROJECT_BINARY_DIR}
|
||||
TEST_ARGS
|
||||
--run_test=Parallel/*
|
||||
NO_COMPILE
|
||||
PROCESSORS
|
||||
4
|
||||
)
|
||||
|
||||
opm_add_test(test_broadcast
|
||||
DEPENDS "opmsimulators"
|
||||
LIBRARIES opmsimulators ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
|
||||
@@ -51,6 +51,7 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
opm/simulators/flow/Main.cpp
|
||||
opm/simulators/flow/NonlinearSolver.cpp
|
||||
opm/simulators/flow/RSTConv.cpp
|
||||
opm/simulators/flow/RegionPhasePVAverage.cpp
|
||||
opm/simulators/flow/SimulatorReportBanners.cpp
|
||||
opm/simulators/flow/SimulatorSerializer.cpp
|
||||
opm/simulators/flow/ValidationFunctions.cpp
|
||||
@@ -284,6 +285,7 @@ list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_partitionCells.cpp
|
||||
tests/test_preconditionerfactory.cpp
|
||||
tests/test_privarspacking.cpp
|
||||
tests/test_region_phase_pvaverage.cpp
|
||||
tests/test_relpermdiagnostics.cpp
|
||||
tests/test_RestartSerialization.cpp
|
||||
tests/test_rstconv.cpp
|
||||
@@ -460,6 +462,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/simulators/flow/partitionCells.hpp
|
||||
opm/simulators/flow/priVarsPacking.hpp
|
||||
opm/simulators/flow/RSTConv.hpp
|
||||
opm/simulators/flow/RegionPhasePVAverage.hpp
|
||||
opm/simulators/flow/SimulatorFullyImplicitBlackoil.hpp
|
||||
opm/simulators/flow/SimulatorReportBanners.hpp
|
||||
opm/simulators/flow/SimulatorSerializer.hpp
|
||||
|
||||
216
opm/simulators/flow/RegionPhasePVAverage.cpp
Normal file
216
opm/simulators/flow/RegionPhasePVAverage.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <opm/simulators/flow/RegionPhasePVAverage.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldProps.hpp>
|
||||
|
||||
#include <opm/simulators/utils/ParallelCommunication.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
std::vector<std::string> fipRegionNames(const std::vector<std::string>& regionNames)
|
||||
{
|
||||
auto regs = regionNames;
|
||||
|
||||
std::sort(regs.begin(), regs.end());
|
||||
|
||||
return { regs.begin(), std::unique(regs.begin(), regs.end()) };
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>::size_type>
|
||||
regionStartPointers(const std::vector<std::string>& regionNames,
|
||||
const Opm::RegionPhasePoreVolAverage::RegionArrayAccessor& getRegionArray,
|
||||
const Opm::Parallel::Communication& comm)
|
||||
{
|
||||
// All elements get an initial value of 1 to account for the maximum
|
||||
// region ID. There should be "max ID + 1" elements for each region
|
||||
// set. Unused IDs--e.g., 0 if IDs start at 1--will effectively be
|
||||
// wasted in this scheme. If that becomes a problem we might
|
||||
// consider some kind of renumbering approach.
|
||||
auto start = std::vector<std::vector<double>::size_type>(regionNames.size() + 1, 1);
|
||||
|
||||
const auto nset = regionNames.size();
|
||||
for (auto rset = 0*nset; rset < nset; ++rset) {
|
||||
const auto& reg = getRegionArray(regionNames[rset]);
|
||||
|
||||
auto m = std::max_element(reg.begin(), reg.end());
|
||||
if (m == reg.end()) { // reg.empty()
|
||||
continue;
|
||||
}
|
||||
|
||||
start[rset + 1] += *m;
|
||||
}
|
||||
|
||||
comm.max(start.data(), start.size());
|
||||
|
||||
std::partial_sum(start.begin(), start.end(), start.begin());
|
||||
|
||||
return start;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
Opm::RegionPhasePoreVolAverage::
|
||||
RegionPhasePoreVolAverage(const Parallel::Communication& comm,
|
||||
const std::size_t numPhases,
|
||||
const std::vector<std::string>& regionNames,
|
||||
RegionArrayAccessor getRegionArray)
|
||||
: comm_ { std::cref(comm) }
|
||||
, np_ { numPhases }
|
||||
, rsetNames_ { fipRegionNames(regionNames) }
|
||||
, getRegionArray_ { std::move(getRegionArray) }
|
||||
, rsStart_ { regionStartPointers(rsetNames_, getRegionArray_, comm_) }
|
||||
, x_ (rsStart_.back() * numPhases * AvgType::NumTypes * Element::NumElem)
|
||||
{}
|
||||
|
||||
double Opm::RegionPhasePoreVolAverage::fieldValue(const Phase& p) const
|
||||
{
|
||||
return this->averageValueWithFallback(this->fieldStartIx(p.ix));
|
||||
}
|
||||
|
||||
double
|
||||
Opm::RegionPhasePoreVolAverage::
|
||||
value(std::string_view rset, const Phase& p, const Region& r) const
|
||||
{
|
||||
auto rsetPos = std::lower_bound(this->rsetNames_.begin(),
|
||||
this->rsetNames_.end(), rset);
|
||||
|
||||
if ((rsetPos == this->rsetNames_.end()) || (*rsetPos != rset)) {
|
||||
// rset is not a known region set name.
|
||||
return 0.0; // Maybe nullopt or throw here...
|
||||
}
|
||||
|
||||
const auto rsetIx = std::distance(this->rsetNames_.begin(), rsetPos);
|
||||
return this->averageValueWithFallback(this->rsetStartIx(rsetIx, r.ix, p.ix));
|
||||
}
|
||||
|
||||
void Opm::RegionPhasePoreVolAverage::prepareAccumulation()
|
||||
{
|
||||
std::fill(this->x_.begin(), this->x_.end(), 0.0);
|
||||
}
|
||||
|
||||
void Opm::RegionPhasePoreVolAverage::
|
||||
addCell(const std::size_t activeCell,
|
||||
const Phase& p,
|
||||
const CellValue& cv)
|
||||
{
|
||||
this->add(this->fieldStartIx(p.ix), cv);
|
||||
|
||||
for (auto rset = 0*this->rsetNames_.size(); rset < this->rsetNames_.size(); ++rset) {
|
||||
this->add(this->rsetStartIx(rset, this->regionIndex(rset, activeCell), p.ix), cv);
|
||||
}
|
||||
}
|
||||
|
||||
void Opm::RegionPhasePoreVolAverage::accumulateParallel()
|
||||
{
|
||||
this->comm_.get().sum(this->x_.data(), this->x_.size());
|
||||
}
|
||||
|
||||
double Opm::RegionPhasePoreVolAverage::averageValueWithFallback(const Ix start) const
|
||||
{
|
||||
const auto spv_w = this->weight(start, AvgType::SatPV);
|
||||
|
||||
return (spv_w > 0.0)
|
||||
? this->averageValue(start, AvgType::SatPV)
|
||||
: this->averageValue(start, AvgType::PV);
|
||||
}
|
||||
|
||||
double Opm::RegionPhasePoreVolAverage::averageValue(const Ix start,
|
||||
const AvgType type) const
|
||||
{
|
||||
return this->value(start, type) / this->weight(start, type);
|
||||
}
|
||||
|
||||
Opm::RegionPhasePoreVolAverage::Ix
|
||||
Opm::RegionPhasePoreVolAverage::fieldStartIx(const unsigned int phase) const
|
||||
{
|
||||
return this->startIx(0, phase);
|
||||
}
|
||||
|
||||
Opm::RegionPhasePoreVolAverage::Ix
|
||||
Opm::RegionPhasePoreVolAverage::rsetStartIx(const std::size_t rset,
|
||||
const int region,
|
||||
const unsigned int phase) const
|
||||
{
|
||||
return this->startIx(this->rsStart_[rset] + region, phase);
|
||||
}
|
||||
|
||||
Opm::RegionPhasePoreVolAverage::Ix
|
||||
Opm::RegionPhasePoreVolAverage::startIx(const std::size_t offset,
|
||||
const unsigned int phase) const
|
||||
{
|
||||
return (offset*this->np_ + phase) * AvgType::NumTypes * Element::NumElem;
|
||||
}
|
||||
|
||||
int Opm::RegionPhasePoreVolAverage::regionIndex(const std::size_t rset,
|
||||
const std::size_t activeCell) const
|
||||
{
|
||||
return this->getRegionArray_(this->rsetNames_[rset])[activeCell];
|
||||
}
|
||||
|
||||
void Opm::RegionPhasePoreVolAverage::add(const Ix start, const CellValue& cv)
|
||||
{
|
||||
this->add(start, AvgType::SatPV, cv.value, cv.sat * cv.porv);
|
||||
this->add(start, AvgType::PV , cv.value, cv.porv);
|
||||
}
|
||||
|
||||
void Opm::RegionPhasePoreVolAverage::add(const Ix start,
|
||||
const AvgType type,
|
||||
const double x,
|
||||
const double w)
|
||||
{
|
||||
this->value (start, type) += w * x;
|
||||
this->weight(start, type) += w;
|
||||
}
|
||||
|
||||
double& Opm::RegionPhasePoreVolAverage::value(const Ix start, const AvgType type)
|
||||
{
|
||||
return this->x_[ this->valueArrayIndex(start, type, Element::Value) ];
|
||||
}
|
||||
|
||||
double& Opm::RegionPhasePoreVolAverage::weight(const Ix start, const AvgType type)
|
||||
{
|
||||
return this->x_[ this->valueArrayIndex(start, type, Element::Weight) ];
|
||||
}
|
||||
|
||||
double Opm::RegionPhasePoreVolAverage::value(const Ix start, const AvgType type) const
|
||||
{
|
||||
return this->x_[ this->valueArrayIndex(start, type, Element::Value) ];
|
||||
}
|
||||
|
||||
double Opm::RegionPhasePoreVolAverage::weight(const Ix start, const AvgType type) const
|
||||
{
|
||||
return this->x_[ this->valueArrayIndex(start, type, Element::Weight) ];
|
||||
}
|
||||
|
||||
Opm::RegionPhasePoreVolAverage::Ix
|
||||
Opm::RegionPhasePoreVolAverage::valueArrayIndex(const Ix start,
|
||||
const AvgType type,
|
||||
const Element element) const
|
||||
{
|
||||
return start + type*Element::NumElem + element;
|
||||
}
|
||||
353
opm/simulators/flow/RegionPhasePVAverage.hpp
Normal file
353
opm/simulators/flow/RegionPhasePVAverage.hpp
Normal file
@@ -0,0 +1,353 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*
|
||||
Copyright 2024 Equinor AS
|
||||
|
||||
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 OPM_REGION_PHASE_POREVOL_AVERAGE_MODULE_HPP
|
||||
#define OPM_REGION_PHASE_POREVOL_AVERAGE_MODULE_HPP
|
||||
|
||||
#include <opm/simulators/utils/ParallelCommunication.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
/// Facility for calculating volume-weighted average function values
|
||||
/// over user-defined regions in parallel. Defaults to phase-filled
|
||||
/// pore-volume averages, but falls back to simple pore-volume averages
|
||||
/// if the saturation is identically zero in a region--i.e., calculates
|
||||
/// what the average value would be if the phase fully occupied the
|
||||
/// available pore-volume in this case.
|
||||
class RegionPhasePoreVolAverage
|
||||
{
|
||||
public:
|
||||
/// Minimal characteristics of a cell from a simulation grid.
|
||||
struct CellValue
|
||||
{
|
||||
/// Function value
|
||||
double value { 0.0 };
|
||||
|
||||
/// Phase saturation
|
||||
double sat { 0.0 };
|
||||
|
||||
/// Reservoir condition pore-volume
|
||||
double porv { 0.0 };
|
||||
};
|
||||
|
||||
/// Compile-time disambiguation type for phases.
|
||||
struct Phase
|
||||
{
|
||||
/// Phase index
|
||||
unsigned int ix;
|
||||
};
|
||||
|
||||
/// Compile-time disambiguation type for regions.
|
||||
struct Region
|
||||
{
|
||||
/// Region index
|
||||
unsigned int ix;
|
||||
};
|
||||
|
||||
/// Call-back function type for accessing region arrays--typically the FIP* arrays.
|
||||
using RegionArrayAccessor = std::function<const std::vector<int>&(const std::string&)>;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param[in] comm Grid level global communicator.
|
||||
///
|
||||
/// \param[in] numPhases Number of phases for which to calculate
|
||||
/// average values.
|
||||
///
|
||||
/// \param[in] regionNames List of region sets. Typically contains
|
||||
/// one or more of the FIP* array names and, possibly, the PVTNUM
|
||||
/// region set as well.
|
||||
///
|
||||
/// \param[in] getRegionArray Call-back function for accessing
|
||||
/// region definition from region set names.
|
||||
explicit RegionPhasePoreVolAverage(const Parallel::Communication& comm,
|
||||
std::size_t numPhases,
|
||||
const std::vector<std::string>& regionNames,
|
||||
RegionArrayAccessor getRegionArray);
|
||||
|
||||
/// Retrieve field-level average function value for specific phase.
|
||||
///
|
||||
/// \param[in] p Phase for which to retrieve the field-level average
|
||||
/// function value.
|
||||
///
|
||||
/// \return Field-level average function value for phase \p p.
|
||||
double fieldValue(const Phase& p) const;
|
||||
|
||||
/// Retrieve region-level average function value for specific phase
|
||||
/// in specific region of named region set.
|
||||
///
|
||||
/// \param[in] rset Named region set--e.g., "FIPNUM".
|
||||
///
|
||||
/// \param[in] p Phase for which to retrieve the region-level average
|
||||
/// function value.
|
||||
///
|
||||
/// \param[in] r Region ID for which to retrieve the region-level
|
||||
/// average function value.
|
||||
///
|
||||
/// \return Region-level average function value.
|
||||
double value(std::string_view rset, const Phase& p, const Region& r) const;
|
||||
|
||||
/// Clear internal arrays in preparation of accumulating
|
||||
/// region-level averages from per-cell contributions.
|
||||
void prepareAccumulation();
|
||||
|
||||
/// Incorporate contributions from a single cell.
|
||||
///
|
||||
/// \param[in] activeCell Per-rank active cell ID--typically one of
|
||||
/// the rank's interior cells.
|
||||
///
|
||||
/// \param[in] p Phase for which to incorporate the per-cell contribution.
|
||||
///
|
||||
/// \param[in] cv Single cell function value contribution.
|
||||
void addCell(std::size_t activeCell, const Phase& p, const CellValue& cv);
|
||||
|
||||
/// Accumulate region-level average values across MPI ranks.
|
||||
///
|
||||
/// Typically the last step in calculating the region-level average
|
||||
/// values. It is typically an error to call this function multiple
|
||||
/// times without an intervening call to \c prepareAccumulation().
|
||||
void accumulateParallel();
|
||||
|
||||
private:
|
||||
/// Index type for value array.
|
||||
using Ix = std::vector<double>::size_type;
|
||||
|
||||
/// Kinds of weighting functions.
|
||||
enum AvgType {
|
||||
SatPV, //< Weighted by phase-filled pore-volume.
|
||||
PV, //< Weighted by total pore-volume (s=1).
|
||||
|
||||
// ---- Must be last enumerator ----
|
||||
NumTypes, //< Number of averge types.
|
||||
};
|
||||
|
||||
/// Elements/items collected per average type.
|
||||
enum Element {
|
||||
Value, //< Running sum of weighted function values.
|
||||
Weight, //< Running sum of weights.
|
||||
|
||||
// ---- Must be last enumerator ----
|
||||
NumElem, //< Number of items/elements per average type.
|
||||
};
|
||||
|
||||
/// MPI communication object.
|
||||
std::reference_wrapper<const Parallel::Communication> comm_;
|
||||
|
||||
/// Number of phases for which to accumulate function value averages.
|
||||
std::size_t np_{};
|
||||
|
||||
/// Named region sets.
|
||||
std::vector<std::string> rsetNames_{};
|
||||
|
||||
/// Call-back function for accessing region set arrays.
|
||||
RegionArrayAccessor getRegionArray_;
|
||||
|
||||
/// Start pointers for average values of each named region set. In
|
||||
/// particular, \code rsStart_[i] \endcode identifies the offset
|
||||
/// into \c x_ of the first average type of the first phase of the
|
||||
/// first region in region set \code rsetNames_[i] \endcode.
|
||||
std::vector<Ix> rsStart_{};
|
||||
|
||||
/// All elements--i.e., running sums--that go into calculating the
|
||||
/// field- and region-level weighted function averages per phase.
|
||||
/// We store all elements in a single linear array, and track
|
||||
/// numerators and denominators in separate elements, in order to
|
||||
/// simplify cross-rank reduction in parallel simulation runs. See
|
||||
/// accumulateParallel() for details on this reduction process.
|
||||
///
|
||||
/// There are \c np_ base entries for each region in each region set
|
||||
/// (+ FIELD). Each base entry has \code AvgType::NumTypes \endcode
|
||||
/// different average types, and each average type comprises \code
|
||||
/// Element::NumElem \endcode separate elements in \c x_.
|
||||
///
|
||||
/// You should typically access this array through the value() and
|
||||
/// weight() member functions, and the start index to both of those
|
||||
/// should be the return value from fieldStartIx() or rsetStartIx().
|
||||
std::vector<double> x_{};
|
||||
|
||||
/// Compute final average value for a single region and phase.
|
||||
///
|
||||
/// Prefers the average value weighted by phase-filled pore-volume,
|
||||
/// but falls back to average value weighted by total pore-volume if
|
||||
/// saturation is identically zero throughout the region.
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \return Weighted average function value.
|
||||
double averageValueWithFallback(Ix start) const;
|
||||
|
||||
/// Compute average function value for a single region and phase.
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to compute.
|
||||
///
|
||||
/// \return Weighted average function value.
|
||||
double averageValue(Ix start, AvgType type) const;
|
||||
|
||||
/// Compute linearised value array offset for field-level average
|
||||
/// function values of a single phase.
|
||||
///
|
||||
/// \param[in] phase Phase index for which to compute array offset.
|
||||
///
|
||||
/// \return Value array offset for field-level averages of \p phase.
|
||||
Ix fieldStartIx(unsigned int phase) const;
|
||||
|
||||
/// Compute linearised value array offset for region-level average
|
||||
/// function values of a single phase.
|
||||
///
|
||||
/// \param[in] rset Enumerated region set.
|
||||
///
|
||||
/// \param[in] region Region index within \p rset.
|
||||
///
|
||||
/// \param[in] phase Phase index for which to compute array offset.
|
||||
///
|
||||
/// \return Value array offset for region-level averages of \p phase.
|
||||
Ix rsetStartIx(std::size_t rset, int region, unsigned int phase) const;
|
||||
|
||||
/// Compute linearised value array offset for average function
|
||||
/// values of a single phase.
|
||||
///
|
||||
/// \param[in] offset Field or region base offset.
|
||||
///
|
||||
/// \param[in] phase Phase index for which to compute array offset.
|
||||
///
|
||||
/// \return Value array offset for weighted averages of \p phase.
|
||||
Ix startIx(std::size_t offset, unsigned int phase) const;
|
||||
|
||||
/// Compute region ID of single active cell within particular region
|
||||
/// set.
|
||||
///
|
||||
/// \param[in] rset Enumerated region set.
|
||||
///
|
||||
/// \param[in] activeCell Per-rank active cell ID--typically one of
|
||||
/// the rank's interior cells.
|
||||
///
|
||||
/// \return Region ID of \p activeCell within \p rset.
|
||||
int regionIndex(std::size_t rset, std::size_t activeCell) const;
|
||||
|
||||
/// Incorporate per-cell contribution into all average function types.
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] cv Single cell function value contribution.
|
||||
void add(Ix start, const CellValue& cv);
|
||||
|
||||
/// Incorporate per-cell contribution into specific function type.
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to accumulate.
|
||||
///
|
||||
/// \param[in] x Function value.
|
||||
///
|
||||
/// \param[in] w Function weight.
|
||||
void add(Ix start, AvgType type, double x, double w);
|
||||
|
||||
/// Mutable access to value item of specific average value type
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to accumulate.
|
||||
///
|
||||
/// \return Reference to mutable element of linearised value array
|
||||
/// corresponding to the running sum of function values.
|
||||
double& value(Ix start, AvgType type);
|
||||
|
||||
/// Mutable access to weight item of specific average value type
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to accumulate.
|
||||
///
|
||||
/// \return Reference to mutable element of linearised value array
|
||||
/// corresponding to the running sum of function weights.
|
||||
double& weight(Ix start, AvgType type);
|
||||
|
||||
/// Read-only access to value item of specific average value type
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to accumulate.
|
||||
///
|
||||
/// \return Running sum of function value.
|
||||
double value(Ix start, AvgType type) const;
|
||||
|
||||
/// Read-only access to weight item of specific average value type
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to accumulate.
|
||||
///
|
||||
/// \return Running sum of function weights.
|
||||
double weight(Ix start, AvgType type) const;
|
||||
|
||||
/// Compute value array index of particular item of particular
|
||||
/// average value
|
||||
///
|
||||
/// \param[in] start Offset into linearised value array (\c x_)
|
||||
/// corresponding to the first average value type of a particular
|
||||
/// phase in a particular region. Usually calculated by
|
||||
/// fieldStartIx() or rsetStartIx().
|
||||
///
|
||||
/// \param[in] type Which kind of average value to reference.
|
||||
///
|
||||
/// \param[in] element Which running sum element to reference for
|
||||
/// this particular average value.
|
||||
///
|
||||
/// \return Index into linearised value array \c x_ corresponding to
|
||||
/// this particular element of this particular average function
|
||||
/// type.
|
||||
Ix valueArrayIndex(Ix start, AvgType type, Element element) const;
|
||||
};
|
||||
} // namespace Opm
|
||||
|
||||
#endif // OPM_REGION_PHASE_POREVOL_AVERAGE_MODULE_HPP
|
||||
1068
tests/test_region_phase_pvaverage.cpp
Normal file
1068
tests/test_region_phase_pvaverage.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user