30#ifndef OPM_EQUIL_PRESSURE_FUNCTION_HPP
31#define OPM_EQUIL_PRESSURE_FUNCTION_HPP
45template <
class Scalar,
class RHS>
50 const std::array<Scalar,2>& span,
61 const Scalar h = stepsize();
62 const Scalar h2 = h / 2;
63 const Scalar h6 = h / 6;
69 f_.push_back(f(span_[0], y0));
71 for (
int i = 0; i < N; ++i) {
72 const Scalar x = span_[0] + i*h;
73 const Scalar y = y_.back();
75 const Scalar k1 = f_[i];
76 const Scalar k2 = f(x + h2, y + h2*k1);
77 const Scalar k3 = f(x + h2, y + h2*k2);
78 const Scalar k4 = f(x + h, y + h*k3);
80 y_.push_back(y + h6*(k1 + 2*(k2 + k3) + k4));
81 f_.push_back(f(x + h, y_.back()));
84 assert (y_.size() ==
typename std::vector<Scalar>::size_type(N + 1));
91 const Scalar h = stepsize();
92 int i = (x - span_[0]) / h;
95 if (N_ <= i) { i = N_ - 1; }
99 const Scalar t = (x - (span_[0] + i*h)) / h;
101 const Scalar y0 = y_[i], y1 = y_[i + 1];
102 const Scalar f0 = f_[i], f1 = f_[i + 1];
104 Scalar u = (1 - 2*t) * (y1 - y0);
105 u += h * ((t - 1)*f0 + t*f1);
107 u += (1 - t)*y0 + t*y1;
114 std::array<Scalar,2> span_;
115 std::vector<Scalar> y_;
116 std::vector<Scalar> f_;
118 Scalar stepsize()
const
119 {
return (span_[1] - span_[0]) / N_; }
126template <
class Scalar,
class ODE>
130 using VSpan = std::array<Scalar, 2>;
143 this->value_[Direction::Up] = std::make_unique<Distribution>
146 this->value_[Direction::Down] = std::make_unique<Distribution>
151 : initial_(rhs.initial_)
153 this->value_[Direction::Up] =
154 std::make_unique<Distribution>(*rhs.value_[Direction::Up]);
156 this->value_[Direction::Down] =
157 std::make_unique<Distribution>(*rhs.value_[Direction::Down]);
164 this->initial_ = rhs.initial_;
166 this->value_[Direction::Up] =
167 std::make_unique<Distribution>(*rhs.value_[Direction::Up]);
169 this->value_[Direction::Down] =
170 std::make_unique<Distribution>(*rhs.value_[Direction::Down]);
177 this->initial_ = rhs.initial_;
178 this->value_ = std::move(rhs.value_);
183 Scalar
value(
const Scalar depth)
const
185 if (depth < this->initial_.
depth) {
187 return (*this->value_[Direction::Up])(depth);
189 else if (depth > this->initial_.
depth) {
191 return (*this->value_[Direction::Down])(depth);
200 enum Direction : std::size_t { Up, Down, NumDir };
202 using Distribution = RK4IVP<Scalar, ODE>;
203 using DistrPtr = std::unique_ptr<Distribution>;
206 std::array<DistrPtr, Direction::NumDir> value_;
Definition: PressureFunction.hpp:128
PressureFunction(const PressureFunction &rhs)
Definition: PressureFunction.hpp:150
std::array< Scalar, 2 > VSpan
Definition: PressureFunction.hpp:130
PressureFunction(const ODE &ode, const InitCond &ic, const int nsample, const VSpan &span)
Definition: PressureFunction.hpp:137
PressureFunction(PressureFunction &&rhs)=default
PressureFunction & operator=(PressureFunction &&rhs)
Definition: PressureFunction.hpp:175
Scalar value(const Scalar depth) const
Definition: PressureFunction.hpp:183
PressureFunction & operator=(const PressureFunction &rhs)
Definition: PressureFunction.hpp:162
Definition: PressureFunction.hpp:47
Scalar operator()(const Scalar x) const
Definition: PressureFunction.hpp:87
RK4IVP(const RHS &f, const std::array< Scalar, 2 > &span, const Scalar y0, const int N)
Definition: PressureFunction.hpp:49
Definition: InitStateEquil.hpp:78
Definition: PressureFunction.hpp:132
Scalar pressure
Definition: PressureFunction.hpp:134
Scalar depth
Definition: PressureFunction.hpp:133