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::transform(this->begin(),
188 template <
typename OtherRandIt>
190 !std::is_same_v<RandIt, OtherRandIt> &&
191 std::is_convertible_v<typename InterRegFlow<OtherRandIt>::ElmT, ElmT>,
192 InterRegFlow&> operator=(
const InterRegFlow<OtherRandIt>& rhs)
194 this->copyIn(rhs.begin(), rhs.end());
205 void addFlow(
const ElmT sign,
const FlowRates& q)
207 assert (this->isValid());
209 const auto numComp =
static_cast<std::size_t
>(Component::NumComponents);
211 for (
auto component = 0*numComp; component < numComp; ++component) {
212 this->add(sign * q.rate_[component], component);
220 constexpr static std::size_t bufferSize() noexcept
222 return InterRegFlow::index(Component::NumComponents, Direction::Positive);
231 constexpr ElmT flow(
const Component component)
const noexcept
236 return this->flow(component, Direction::Positive)
237 + this->flow(component, Direction::Negative);
253 constexpr ElmT flow(
const Component component,
254 const Direction direction)
const noexcept
256 return *(this->elements_.first + InterRegFlow::index(component, direction));
261 constexpr bool empty() const noexcept
263 return this->begin() == this->end();
269 constexpr bool isValid() const noexcept
271 using sz_t =
decltype(InterRegFlow::bufferSize());
273 const auto& [begin, end] = this->elements_;
275 return static_cast<sz_t
>(std::distance(begin, end))
276 == InterRegFlow::bufferSize();
280 RandIt begin() const noexcept
282 return this->elements_.first;
286 RandIt end() const noexcept
288 return this->elements_.second;
293 std::pair<RandIt, RandIt> elements_;
304 constexpr static std::size_t
305 index(
const std::size_t component,
const Direction direction)
307 return 2*component + (direction == Direction::Negative);
317 constexpr static std::size_t
318 index(
const Component component,
const Direction direction)
320 return InterRegFlow::index(
static_cast<std::size_t
>(component), direction);
327 void add(
const ElmT rate,
const std::size_t component)
329 const auto direction = std::signbit(rate)
330 ? Direction::Negative : Direction::Positive;
332 auto* rateVec = &*this->elements_.first;
333 rateVec[InterRegFlow::index(component, direction)] += rate;
339 void copyIn(
const InterRegFlow& rhs)
341 if (this->elements_ != rhs.elements_) {
342 this->copyIn(rhs.elements_.first, rhs.elements_.second);
352 template <
typename OtherRandIt>
353 void copyIn(OtherRandIt begin, OtherRandIt end)
355 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