28 lines
1.1 KiB
C++
28 lines
1.1 KiB
C++
#pragma once
|
|
#include <cmath>
|
|
|
|
namespace fluidsim::port {
|
|
// Causal unflanged circular-pipe reflection fit, Silva et al. (2009), Eq. 16.
|
|
// R(s)=-(1+n*a/c*s)/(1+d*a/c*s+e*(a/c*s)^2).
|
|
// Trapezoidal state integration supports the solver's variable CFL timestep.
|
|
class OpenEndRadiation {
|
|
public:
|
|
double process(double incident, double scaled_dt) {
|
|
if (!initialized_) { position_ = incident; previous_ = incident; initialized_ = true; }
|
|
constexpr double n = .167, d = n + 2*.6133;
|
|
constexpr double e = (d*d-n*n-1)/2;
|
|
const double h = scaled_dt*.5;
|
|
const double rhs = velocity_ + h/e*(previous_ + incident - position_ - d*velocity_);
|
|
const double next_velocity = (rhs - h/e*(position_ + h*velocity_)) /
|
|
(1 + h*d/e + h*h/e);
|
|
position_ += h*(velocity_ + next_velocity);
|
|
velocity_ = next_velocity;
|
|
previous_ = incident;
|
|
return -(position_ + n*velocity_);
|
|
}
|
|
private:
|
|
double position_{}, velocity_{}, previous_{};
|
|
bool initialized_{};
|
|
};
|
|
} // namespace fluidsim::port
|