1#ifndef FHSIM_BASE_SUBMERGENCE_H
2#define FHSIM_BASE_SUBMERGENCE_H
32template<
class Environment>
35 if constexpr (
requires { environment.MaxWaveElevation(); })
36 return environment.MaxWaveElevation();
38 return std::numeric_limits<double>::infinity();
49template<
class Environment>
50double MediumDensity(Environment& environment,
double time,
const double pos[3],
double waterDensity)
52 constexpr double kAirWaterThreshold = 100.0;
54 environment.GetDensity(time, pos, density);
55 return density > kAirWaterThreshold ? waterDensity : density;
66 return topDepth > waveBound;
84 return 0.5 + (x * std::sqrt(1.0 - x * x) + std::asin(x)) / M_PI;
98 const double c = 1.0 - x * x;
99 return 0.5 * x + (x * std::asin(x) + std::sqrt(c) - c * std::sqrt(c) / 3.0) / M_PI;
117 const double low = std::min(s1, s2);
118 const double high = std::max(s1, s2);
119 const double half = 0.5 * sectionHeight;
125 return high / (high - low);
126 const double x1 = low / half;
127 const double x2 = high / half;
144inline double CylinderFractionGradient(
double s1,
double s2,
double sectionHeight,
double& dF_ds1,
double& dF_ds2,
double& dF_dHeight)
146 dF_ds1 = dF_ds2 = dF_dHeight = 0.0;
147 const bool firstIsLow = s1 <= s2;
148 const double low = firstIsLow ? s1 : s2;
149 const double high = firstIsLow ? s2 : s1;
150 const double half = 0.5 * sectionHeight;
151 double dLow = 0.0, dHigh = 0.0;
155 }
else if (high <= -half) {
157 }
else if (!(half > 0.0)) {
158 const double span = high - low;
159 fraction = high / span;
160 dHigh = -low / (span * span);
161 dLow = high / (span * span);
163 const double x1 = low / half;
164 const double x2 = high / half;
165 if (x2 - x1 < 1e-6) {
166 const double xm = 0.5 * (x1 + x2);
168 const double slope = (std::abs(xm) < 1.0) ? 2.0 * std::sqrt(1.0 - xm * xm) / M_PI : 0.0;
169 dLow = dHigh = 0.5 * slope / half;
170 dF_dHeight = -0.5 * slope * xm / half;
172 const double span = x2 - x1;
178 dF_dHeight = -0.5 * (dx1 * x1 + dx2 * x2) / half;
181 dF_ds1 = firstIsLow ? dLow : dHigh;
182 dF_ds2 = firstIsLow ? dHigh : dLow;
195 return 0.5 * (std::abs(axisDz) + diameter * std::sqrt(std::max(0.0, 1.0 - cosTheta * cosTheta)));
Definition Submergence.h:20
bool SurelySubmerged(double topDepth, double waveBound)
Definition Submergence.h:64
double CircleFractionIntegral(double x)
Definition Submergence.h:92
double WaveElevationBound(const Environment &environment)
Definition Submergence.h:33
double CylinderFraction(double s1, double s2, double sectionHeight)
Definition Submergence.h:115
double CylinderFractionGradient(double s1, double s2, double sectionHeight, double &dF_ds1, double &dF_ds2, double &dF_dHeight)
Definition Submergence.h:144
double MediumDensity(Environment &environment, double time, const double pos[3], double waterDensity)
Definition Submergence.h:50
double CylinderHalfHeight(double axisDz, double diameter, double cosTheta)
Definition Submergence.h:193
double CircleFraction(double x)
Definition Submergence.h:78