20#ifndef OPM_OUTPUT_DATA_INTERREGFLOW_HPP
21#define OPM_OUTPUT_DATA_INTERREGFLOW_HPP
33namespace Opm {
namespace data {
38 template <
typename RandIt>
45 using ElmT = std::remove_cv_t<
46 std::remove_reference_t<
47 typename std::iterator_traits<RandIt>::value_type
51 enum class Component :
char {
52 Oil, Gas, Water, Disgas, Vapoil,
59 enum class Direction :
char {
70 this->rate_.fill(ElmT{});
78 ElmT& operator[](
const Component i)
80 return this->rate_[this->index(i)];
83 friend class InterRegFlow;
87 std::array<ElmT, static_cast<std::size_t>(Component::NumComponents)> rate_{};
94 std::size_t index(
const Component i)
const
96 return static_cast<std::size_t
>(i);
104 explicit InterRegFlow(RandIt begin, RandIt end)
105 : elements_(begin, end)
109 InterRegFlow(
const InterRegFlow&) =
delete;
116 InterRegFlow(InterRegFlow&& rhs)
117 : elements_(rhs.elements_.first, rhs.elements_.second)
119 rhs.elements_.second = rhs.elements_.first;
127 InterRegFlow& operator=(
const InterRegFlow& rhs)
141 InterRegFlow& operator=(InterRegFlow&& rhs)
143 if (! this->isValid()) {
144 this->elements_ = rhs.elements_;
150 rhs.elements_.second = rhs.elements_.first;
163 template <
typename OtherRandIt>
165 std::is_convertible_v<typename InterRegFlow<OtherRandIt>::ElmT, ElmT>,
166 InterRegFlow&> operator+=(
const InterRegFlow<OtherRandIt>& rhs)
168 std::ranges::transform(*
this, rhs, this->begin(), std::plus<>{});
184 template <
typename OtherRandIt>
186 !std::is_same_v<RandIt, OtherRandIt> &&
187 std::is_convertible_v<typename InterRegFlow<OtherRandIt>::ElmT, ElmT>,
188 InterRegFlow&> operator=(
const InterRegFlow<OtherRandIt>& rhs)
190 this->copyIn(rhs.begin(), rhs.end());
201 void addFlow(
const ElmT sign,
const FlowRates& q)
203 assert (this->isValid());
205 const auto numComp =
static_cast<std::size_t
>(Component::NumComponents);
207 for (
auto component = 0*numComp; component < numComp; ++component) {
208 this->add(sign * q.rate_[component], component);
216 constexpr static std::size_t bufferSize() noexcept
218 return InterRegFlow::index(Component::NumComponents, Direction::Positive);
227 constexpr ElmT flow(
const Component component)
const noexcept
232 return this->flow(component, Direction::Positive)
233 + this->flow(component, Direction::Negative);
249 constexpr ElmT flow(
const Component component,
250 const Direction direction)
const noexcept
252 return *(this->elements_.first + InterRegFlow::index(component, direction));
257 constexpr bool empty() const noexcept
259 return this->begin() == this->end();
265 constexpr bool isValid() const noexcept
267 using sz_t =
decltype(InterRegFlow::bufferSize());
269 const auto& [begin, end] = this->elements_;
271 return static_cast<sz_t
>(std::distance(begin, end))
272 == InterRegFlow::bufferSize();
276 RandIt begin() const noexcept
278 return this->elements_.first;
282 RandIt end() const noexcept
284 return this->elements_.second;
289 std::pair<RandIt, RandIt> elements_;
300 constexpr static std::size_t
301 index(
const std::size_t component,
const Direction direction)
303 return 2*component + (direction == Direction::Negative);
313 constexpr static std::size_t
314 index(
const Component component,
const Direction direction)
316 return InterRegFlow::index(
static_cast<std::size_t
>(component), direction);
323 void add(
const ElmT rate,
const std::size_t component)
325 const auto direction = std::signbit(rate)
326 ? Direction::Negative : Direction::Positive;
328 auto* rateVec = &*this->elements_.first;
329 rateVec[InterRegFlow::index(component, direction)] += rate;
335 void copyIn(
const InterRegFlow& rhs)
337 if (this->elements_ != rhs.elements_) {
338 this->copyIn(rhs.elements_.first, rhs.elements_.second);
348 template <
typename OtherRandIt>
349 void copyIn(OtherRandIt begin, OtherRandIt end)
351 std::copy(begin, end, this->elements_.first);
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30