#include #include #include #include #include "serif/eos/evaluation.hpp" #include "serif/eos/exceptions.hpp" #include "serif/eos/models/polytropic.hpp" namespace eos = serif::eos; namespace dimensions = serif::dimensions; TEST_CASE("Polytropic pressure potential obeys its mechanical derivative contract", "[eos][barotropic_density][unit]") { for (const double index : {1.0, 1.5, 2.0, 2.5, 3.0}) { const eos::models::Polytrope model{index, 0.73}; for (const double density : {1.0e-6, 0.2, 2.0}) { CAPTURE(index, density); const dimensions::DensityValue state{density}; const double potential = eos::evaluate(model, state).value(); CHECK_THAT(potential, Catch::Matchers::WithinRel((index + 1.0) * 0.73 * std::pow(density, 1.0 / index), 2.0e-15)); const double step = density * 1.0e-4; const double positive = eos::evaluate(model, dimensions::DensityValue{density + step}).value(); const double negative = eos::evaluate(model, dimensions::DensityValue{density - step}).value(); const double expected_slope = eos::partial_derivative(model, state).value() / density; CHECK_THAT((positive - negative) / (2.0 * step), Catch::Matchers::WithinRel(expected_slope, 3.0e-9)); } CHECK(eos::evaluate(model, dimensions::DensityValue{0.0}).value() == 0.0); for (const double invalid : {-0.1, std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()}) { CHECK_THROWS_AS(eos::evaluate(model, dimensions::DensityValue{invalid}), eos::EOSEvaluationError); } } }