13#if defined(ENABLE_CATCH)
14# include <catch2/catch_all.hpp>
24std::vector<double>
linspace(
double a,
double b, std::size_t n) {
25 std::vector<double> v(n);
26 for (std::size_t i = 0; i < n; ++i) {
27 v[i] = (n == 1) ? a : a + (b - a) *
static_cast<double>(i) /
static_cast<double>(n - 1);
39TEST_CASE(
"HS production two-phase round-trip",
"[HS][HS_prod2ph]") {
40 const std::string fluid = GENERATE(as<std::string>{},
"Water",
"Nitrogen",
"R134a",
"MM",
"n-Pentane",
"Methane");
44 const double Tc = ref->T_critical(), Tmin = ref->Ttriple();
45 std::size_t total = 0, ok = 0;
46 for (
double T :
linspace(Tmin + 1.0, Tc - std::max(0.5, 1e-3 * Tc), 25)) {
47 for (
double Q : {0.05, 0.25, 0.5, 0.75, 0.95}) {
53 const double h = ref->hmolar(), s = ref->smolar();
54 if (!std::isfinite(h) || !std::isfinite(s))
continue;
59 }
catch (
const std::exception& e) {
60 FAIL_CHECK(
"two-phase HS threw: " << e.what());
63 const bool good = std::abs(wrk->T() -
T) /
T < 1e-5 && std::abs(wrk->Q() - Q) < 1e-4;
67 CAPTURE(wrk->T(), wrk->Q());
72 std::printf(
"[HS_prod2ph] %s: %zu/%zu two-phase round-trips\n", fluid.c_str(), ok, total);
86TEST_CASE(
"HS production single-phase round-trip (phase-diagram sweep)",
"[HS][HS_prod1ph]") {
87 const std::string fluid = GENERATE(as<std::string>{},
"Water",
"Nitrogen",
"CarbonDioxide",
"R134a",
"MM",
"n-Pentane",
"Methane",
"Hydrogen");
92 const double Tmin = ref->Tmin(), Tmax = ref->Tmax(), pmax = ref->pmax();
95 plo = std::max(ref->p_triple(), pmax * 1e-6);
99 std::size_t total = 0, ok = 0;
102 for (
double T :
linspace(Tmin + 0.5, Tmax, 20)) {
103 for (std::size_t j = 0; j < 20; ++j) {
104 const double p = plo * std::pow(pmax / plo,
static_cast<double>(j) / 19.0);
110 const double h = ref->hmolar(), s = ref->smolar(), rho = ref->rhomolar(), Tt = ref->T();
111 if (!std::isfinite(h) || !std::isfinite(s) || !std::isfinite(rho))
continue;
113 CAPTURE(
T, p, rho, h, s);
116 }
catch (
const std::exception& e) {
117 FAIL_CHECK(
"single-phase HS threw: " << e.what());
120 const bool good = std::abs(wrk->T() - Tt) / Tt < 1e-5 && std::abs(wrk->rhomolar() - rho) / rho < 1e-5;
124 CAPTURE(wrk->T(), wrk->rhomolar());
129 std::printf(
"[HS_prod1ph] %s: %zu/%zu single-phase round-trips\n", fluid.c_str(), ok, total);
149TEST_CASE(
"HS single-phase round-trip (no-superancillary / pseudo-pure fluids)",
"[HS][HS_pseudopure]") {
150 const std::string fluid = GENERATE(as<std::string>{},
"Air",
"R407C",
"R410A",
"R404A",
"R507A",
"SES36");
155 const double Tmin = ref->Tmin(), Tmax = ref->Tmax(), pmax = ref->pmax();
158 plo = std::max(ref->p_triple(), pmax * 1e-6);
162 const double tol = 2e-4;
163 std::size_t total = 0, ok = 0;
164 for (
double T :
linspace(Tmin + 0.5, Tmax, 20)) {
165 for (std::size_t j = 0; j < 20; ++j) {
166 const double p = plo * std::pow(pmax / plo,
static_cast<double>(j) / 19.0);
172 const double h = ref->hmolar(), s = ref->smolar(), rho = ref->rhomolar(), Tt = ref->T();
173 if (!std::isfinite(h) || !std::isfinite(s) || !std::isfinite(rho))
continue;
175 CAPTURE(
T, p, rho, h, s);
178 }
catch (
const std::exception& e) {
179 FAIL_CHECK(
"single-phase HS threw: " << e.what());
182 const bool good = std::abs(wrk->T() - Tt) / Tt < tol && std::abs(wrk->rhomolar() - rho) / rho < tol;
186 CAPTURE(wrk->T(), wrk->rhomolar());
191 std::printf(
"[HS_pseudopure] %s: %zu/%zu single-phase round-trips\n", fluid.c_str(), ok, total);