6#if defined(ENABLE_CATCH)
9# include <catch2/catch_all.hpp>
17 if (!type.compare(
"rational_polynomial")) {
18 this->type = TYPE_RATIONAL_POLYNOMIAL;
30 if (!type.compare(
"rhoLnoexp"))
31 this->type = TYPE_NOT_EXPONENTIAL;
33 this->type = TYPE_EXPONENTIAL;
47 if (type == TYPE_NOT_SET) {
49 }
else if (type == TYPE_RATIONAL_POLYNOMIAL) {
53 double THETA = 1 - T /
T_r;
55 for (std::size_t i = 0; i <
N; ++i) {
56 s[i] = n[i] * pow(THETA, t[i]);
58 double summer = std::accumulate(s.begin(), s.end(), 0.0);
60 if (type == TYPE_NOT_EXPONENTIAL) {
65 tau_r_value =
T_r / T;
83 double call(
double T) {
85 return current_value - value;
88 solver_resid resid(
this, value);
89 std::string errstring;
91 min_bound = Tmin - 0.01;
110 for (std::size_t i = 0; i <
simon.
parts.size(); ++i) {
148 throw ValueError(
"Melting line curve not set");
152 }
else if (OF ==
iP_min) {
154 }
else if (OF ==
iT_max) {
156 }
else if (OF ==
iT_min) {
158 }
else if (OF ==
iP && GIVEN ==
iT) {
162 for (std::size_t i = 0; i <
simon.
parts.size(); ++i) {
165 return part.
p_0 + part.
a * (pow(T / part.
T_0, part.
c) - 1);
168 throw ValueError(
"unable to calculate melting line (p,T) for Simon curve");
177 throw ValueError(
"unable to calculate melting line (p,T) for polynomial_in_Tr curve");
186 throw ValueError(
"unable to calculate melting line (p,T) for polynomial_in_Theta curve");
193 for (std::size_t i = 0; i <
simon.
parts.size(); ++i) {
201 throw ValueError(
format(
"unable to calculate melting line T(p) for Simon curve for p=%Lg; bounds are %Lg,%Lg Pa", value,
pmin,
pmax));
209 double call(
double T) {
214 return given_p - calc_p;
222 solver_resid resid(&part, value);
228 format(
"unable to calculate melting line T(p) for polynomial_in_Theta curve for p=%Lg; bounds are %Lg,%Lg Pa", value,
pmin,
pmax));
237 double call(
double T) {
242 return given_p - calc_p;
250 solver_resid resid(&part, value);
257 format(
"unable to calculate melting line T(p) for polynomial_in_Theta curve for p=%Lg; bounds are %Lg,%Lg Pa", value,
pmin,
pmax));
266#if defined(ENABLE_CATCH)
267TEST_CASE(
"Water melting line",
"[melting]") {
270 SECTION(
"Ice Ih-liquid") {
271 double actual = AS->melting_line(
iT,
iP, 138.268e6);
272 double expected = 260.0;
275 CHECK(std::abs(actual - expected) < 0.01);
277 SECTION(
"Ice III-liquid") {
278 double actual = AS->melting_line(
iT,
iP, 268.685e6);
279 double expected = 254;
282 CHECK(std::abs(actual - expected) < 0.01);
284 SECTION(
"Ice V-liquid") {
285 double actual = AS->melting_line(
iT,
iP, 479.640e6);
286 double expected = 265;
289 CHECK(std::abs(actual - expected) < 0.01);
291 SECTION(
"Ice VI-liquid") {
292 double actual = AS->melting_line(
iT,
iP, 1356.76e6);
293 double expected = 320;
296 CHECK(std::abs(actual - expected) < 1);
300TEST_CASE(
"Tests for values from melting lines",
"[melting]") {
303 for (std::size_t i = 0; i < fluids.size(); ++i) {
307 if (!AS->has_melting_line() || !fluids[i].compare(
"Water")) {
317 std::ostringstream ss0;
318 ss0 <<
"Check melting line limits for fluid " << fluids[i];
319 SECTION(ss0.str(),
"") {
328 for (
double p = 0.1 * (pmax - pmin) + pmin; p < pmax; p += 0.2 * (pmax - pmin)) {
330 std::ostringstream ss1;
331 ss1 <<
"Melting line for " << fluids[i] <<
" at p=" << p;
332 SECTION(ss1.str(),
"") {
333 double actual_T = AS->melting_line(
iT,
iP, p);
337 CHECK(actual_T > Tmin);
338 CHECK(actual_T < Tmax);
342 std::ostringstream ss2;
343 ss2 <<
"Ensure melting line valid for " << fluids[i] <<
" @ EOS pmax";
344 SECTION(ss2.str(),
"") {
345 double actual_T = -_HUGE;
346 double EOS_pmax = AS->pmax();
347 double T_pmax_required = -1;
350 T_pmax_required = AS->melting_line(
iT,
iP, EOS_pmax);
354 CAPTURE(T_pmax_required);
356 CHECK_NOTHROW(actual_T = AS->melting_line(
iT,
iP, EOS_pmax));
362TEST_CASE(
"Test that hs_anchor enthalpy/entropy agrees with EOS",
"[ancillaries]") {
364 for (std::size_t i = 0; i < fluids.size(); ++i) {
370 std::ostringstream ss1;
371 ss1 <<
"Check hs_anchor for " << fluids[i];
372 SECTION(ss1.str(),
"") {
374 "The enthalpy and entropy are hardcoded in the fluid JSON files. They MUST agree with the values calculated by the EOS";
376 double EOS_hmolar = AS->
hmolar();
377 double EOS_smolar = AS->smolar();
378 CAPTURE(hs_anchor.
hmolar);
379 CAPTURE(hs_anchor.
smolar);
382 CHECK(std::abs(EOS_hmolar - hs_anchor.
hmolar) < 1e-3);
383 CHECK(std::abs(EOS_smolar - hs_anchor.
smolar) < 1e-3);
388TEST_CASE(
"Surface tension",
"[surface_tension]") {
389 SECTION(
"from PropsSI") {
392 SECTION(
"from saturation_ancillary") {
395 SECTION(
"from AbstractState") {
398 CHECK_NOTHROW(AS->surface_tension());