94 double const vapour_water_density,
95 double const liquid_water_density)
102 constexpr double gravity = 9.81;
108 double const temperature_ratio =
111 double const reduced_temperature =
112 temperature_ratio < 0 ? 0. : temperature_ratio;
113 double const sigma_gl = 0.2358 * std::pow(reduced_temperature, 1.256) *
114 (1 - 0.625 * reduced_temperature);
116 double const buoyancy =
117 gravity * sigma_gl * (liquid_water_density - vapour_water_density);
118 double const drift_buoyancy = buoyancy < 0 ? 0. : buoyancy;
120 return 1.18 * (1 - dryness) * std::sqrt(std::sqrt(drift_buoyancy)) /
121 std::sqrt(liquid_water_density);
142 auto const& [dryness, vapour_water_density, liquid_water_density, v_mix,
170 if (!(liquid_water_density > 0) || !(vapour_water_density > 0))
173 "Non-positive phase density in the vapour void fraction closure: "
174 "liquid density {:g} kg/m^3, vapour density {:g} kg/m^3.",
175 liquid_water_density, vapour_water_density));
177 if (!std::isfinite(dryness) || !std::isfinite(v_mix) ||
178 !std::isfinite(u_gu) || !std::isfinite(C_0))
181 "Non-finite state in the vapour void fraction closure: dryness "
182 "{:g}, mixture velocity {:g} m/s, drift flux velocity {:g} m/s, "
183 "profile parameter {:g}.",
184 dryness, v_mix, u_gu, C_0));
197 double const alpha_max = std::min(1., dryness / S);
210 constexpr double degeneracy_tolerance = 1e-14;
219 constexpr double interval_tolerance = 1e-8;
221 auto const admissible = [&](
double const alpha) -> std::optional<double>
223 double const tolerance = interval_tolerance * std::max(1., alpha_max);
227 if (!(
alpha >= -tolerance) || !(
alpha <= alpha_max + tolerance))
231 return std::clamp(
alpha, 0., alpha_max);
234 if (std::abs(a) <= degeneracy_tolerance * std::abs(b))
249 return admissible(alpha_max);
253 return admissible(-
c / b);
261 double discriminant = b * b - 4 * a *
c;
262 if (discriminant < 0)
266 if (discriminant < -degeneracy_tolerance * b * b)
276 double const q = -0.5 * (b + std::copysign(std::sqrt(discriminant), b));
279 return admissible(0.);
284 double const root_1 = q / a;
285 double const root_2 =
c / q;
287 auto const first = admissible(std::min(root_1, root_2));
288 return first ? first : admissible(std::max(root_1, root_2));