FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
Submergence.h
1#ifndef FHSIM_BASE_SUBMERGENCE_H
2#define FHSIM_BASE_SUBMERGENCE_H
3
4#include <algorithm>
5#include <cmath>
6#include <limits>
7
19namespace submergence
20{
21
32template<class Environment>
33double WaveElevationBound(const Environment& environment)
34{
35 if constexpr (requires { environment.MaxWaveElevation(); })
36 return environment.MaxWaveElevation();
37 else
38 return std::numeric_limits<double>::infinity();
39}
40
49template<class Environment>
50double MediumDensity(Environment& environment, double time, const double pos[3], double waterDensity)
51{
52 constexpr double kAirWaterThreshold = 100.0; // kg/m^3, between air and any water
53 double density = 0.0;
54 environment.GetDensity(time, pos, density);
55 return density > kAirWaterThreshold ? waterDensity : density;
56}
57
64inline bool SurelySubmerged(double topDepth, double waveBound)
65{
66 return topDepth > waveBound;
67}
68
78inline double CircleFraction(double x)
79{
80 if (x >= 1.0)
81 return 1.0;
82 if (x <= -1.0)
83 return 0.0;
84 return 0.5 + (x * std::sqrt(1.0 - x * x) + std::asin(x)) / M_PI;
85}
86
92inline double CircleFractionIntegral(double x)
93{
94 if (x >= 1.0)
95 return x;
96 if (x <= -1.0)
97 return 0.0;
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;
100}
101
115inline double CylinderFraction(double s1, double s2, double sectionHeight)
116{
117 const double low = std::min(s1, s2);
118 const double high = std::max(s1, s2);
119 const double half = 0.5 * sectionHeight;
120 if (low >= half)
121 return 1.0;
122 if (high <= -half)
123 return 0.0;
124 if (!(half > 0.0))
125 return high / (high - low); // vertical: the wetted length fraction, here low < 0 < high
126 const double x1 = low / half;
127 const double x2 = high / half;
128 if (x2 - x1 < 1e-6)
129 return CircleFraction(0.5 * (x1 + x2)); // horizontal: one cross-section
130 return (CircleFractionIntegral(x2) - CircleFractionIntegral(x1)) / (x2 - x1);
131}
132
144inline double CylinderFractionGradient(double s1, double s2, double sectionHeight, double& dF_ds1, double& dF_ds2, double& dF_dHeight)
145{
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;
152 double fraction;
153 if (low >= half) {
154 fraction = 1.0;
155 } else if (high <= -half) {
156 fraction = 0.0;
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);
162 } else {
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);
167 fraction = CircleFraction(xm);
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;
171 } else {
172 const double span = x2 - x1;
173 fraction = (CircleFractionIntegral(x2) - CircleFractionIntegral(x1)) / span;
174 const double dx1 = (fraction - CircleFraction(x1)) / span;
175 const double dx2 = (CircleFraction(x2) - fraction) / span;
176 dLow = dx1 / half;
177 dHigh = dx2 / half;
178 dF_dHeight = -0.5 * (dx1 * x1 + dx2 * x2) / half;
179 }
180 }
181 dF_ds1 = firstIsLow ? dLow : dHigh;
182 dF_ds2 = firstIsLow ? dHigh : dLow;
183 return fraction;
184}
185
193inline double CylinderHalfHeight(double axisDz, double diameter, double cosTheta)
194{
195 return 0.5 * (std::abs(axisDz) + diameter * std::sqrt(std::max(0.0, 1.0 - cosTheta * cosTheta)));
196}
197
198} // namespace submergence
199
200#endif
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