feat(mean_field): added dimensions, discritization, and start of eos
The full rewrite of mean_field into something maintainable is progressing. dimensions is mostly done, discritization (domain, blocks, and fields) is done, and eos is progressing quickly
This commit is contained in:
146
src/lib/serif/eos/models/polytropic.cpp
Normal file
146
src/lib/serif/eos/models/polytropic.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "serif/eos/models/polytropic.hpp"
|
||||
#include "serif/utils/misc/finite.hpp"
|
||||
#include "serif/eos/exceptions.hpp"
|
||||
|
||||
namespace serif::eos::models {
|
||||
using utils::misc::validate_finite;
|
||||
using utils::misc::validate_greater_than;
|
||||
using utils::misc::validate_less_than;
|
||||
using utils::misc::validate_nonnegativity;
|
||||
|
||||
using namespace dimensions;
|
||||
using namespace relations;
|
||||
|
||||
Polytrope::Polytrope(const PolytropeParameters& parameters) : Polytrope(parameters.n, parameters.K) {}
|
||||
|
||||
Polytrope::Polytrope(const double n, const double K):
|
||||
m_polytropic_index(n),
|
||||
m_polytropic_constant(K),
|
||||
m_enthalpy_scale((n + 1.0) * K) {
|
||||
validate_finite<EOSEvaluationError>(m_polytropic_index, EOSEvaluationErrorCode::outside_domain);
|
||||
validate_greater_than<EOSEvaluationError>(m_polytropic_index, 1.0, EOSEvaluationErrorCode::outside_domain);
|
||||
validate_finite<EOSEvaluationError>(m_polytropic_constant, EOSEvaluationErrorCode::outside_domain);
|
||||
validate_greater_than<EOSEvaluationError>(m_polytropic_constant, 0.0, EOSEvaluationErrorCode::outside_domain);
|
||||
}
|
||||
|
||||
[[nodiscard]] double Polytrope::polytropic_index() const noexcept {
|
||||
return m_polytropic_index;
|
||||
}
|
||||
|
||||
[[nodiscard]] double Polytrope::polytropic_constant() const noexcept {
|
||||
return m_polytropic_constant;
|
||||
}
|
||||
|
||||
[[nodiscard]] double Polytrope::enthalpy_scale() const noexcept {
|
||||
return m_enthalpy_scale;
|
||||
}
|
||||
|
||||
[[nodiscard]] PressureValue Polytrope::evaluate(PressureFromDensity, const DensityValue density) const {
|
||||
validate_nonnegativity<EOSEvaluationError>(density.value(), EOSEvaluationErrorCode::invalid_thermodynamic_input);
|
||||
|
||||
if (density.value() == 0.0) {
|
||||
// P = 0
|
||||
return PressureValue{0.0};
|
||||
}
|
||||
|
||||
// P = K * (ρ)^(1 + 1/n)
|
||||
return PressureValue{
|
||||
m_polytropic_constant * std::pow(density.value(), 1.0 + 1.0 / m_polytropic_index)
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] SpecificEnthalpyValue Polytrope::evaluate(SpecificEnthalpyFromDensity, const DensityValue density) const {
|
||||
validate_nonnegativity<EOSEvaluationError>(density.value(), EOSEvaluationErrorCode::invalid_thermodynamic_input);
|
||||
if (density.value() == 0.0) {
|
||||
// h = 0
|
||||
return SpecificEnthalpyValue{0.0};
|
||||
}
|
||||
|
||||
// h = hs * (ρ)^(1/n)
|
||||
return SpecificEnthalpyValue{
|
||||
m_enthalpy_scale * std::pow(density.value(), 1.0 / m_polytropic_index)
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] DensityValue Polytrope::evaluate(DensityFromSpecificEnthalpy, SpecificEnthalpyValue specific_enthalpy) const {
|
||||
validate_finite<EOSEvaluationError>(specific_enthalpy.value(), EOSEvaluationErrorCode::invalid_thermodynamic_input);
|
||||
|
||||
if (specific_enthalpy.value() <= 0.0) {
|
||||
// ρ = 0
|
||||
return DensityValue{0.0};
|
||||
}
|
||||
|
||||
// ρ = (h/hs)^n
|
||||
return DensityValue{std::pow(specific_enthalpy.value() / m_enthalpy_scale, m_polytropic_index)};
|
||||
}
|
||||
|
||||
[[nodiscard]] PressureValue Polytrope::evaluate(PressureFromSpecificEnthalpy, SpecificEnthalpyValue specific_enthalpy) const {
|
||||
const DensityValue density = evaluate(DensityFromSpecificEnthalpy{}, specific_enthalpy);
|
||||
if (specific_enthalpy.value() <= 0.0) {
|
||||
// P = 0
|
||||
return PressureValue{0.0};
|
||||
}
|
||||
|
||||
// P = ρ * h / (n + 1)
|
||||
return PressureValue{density.value() * specific_enthalpy.value()/ (m_polytropic_index + 1.0)};
|
||||
}
|
||||
|
||||
[[nodiscard]] SpecificEnthalpyValue Polytrope::evaluate(SpecificEnthalpyFromPressure, PressureValue pressure) const {
|
||||
validate_nonnegativity<EOSEvaluationError>(pressure.value(), EOSEvaluationErrorCode::invalid_thermodynamic_input);
|
||||
if (pressure.value() == 0.0) {
|
||||
// h = 0
|
||||
return SpecificEnthalpyValue{0.0};
|
||||
}
|
||||
|
||||
const double indexPlusOne = m_polytropic_index + 1.0;
|
||||
|
||||
// h = (n+1) * (K^(n/(n+1))) * (P^(1/(n+1)))
|
||||
return SpecificEnthalpyValue{
|
||||
indexPlusOne * std::pow(m_polytropic_constant, m_polytropic_index / indexPlusOne) *
|
||||
std::pow(pressure.value(), 1.0 / indexPlusOne)
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] PartialDerivative<Density, SpecificEnthalpy> Polytrope::partial_derivative(DensityFromSpecificEnthalpy, WithRespectTo<SpecificEnthalpy>, const SpecificEnthalpyValue specific_enthalpy) const {
|
||||
validate_finite<EOSEvaluationError>(specific_enthalpy.value(), EOSEvaluationErrorCode::invalid_thermodynamic_input);
|
||||
|
||||
if (specific_enthalpy.value() < 0.0) {
|
||||
// dρ/dh = 0
|
||||
return PartialDerivative<Density, SpecificEnthalpy>{0.0};
|
||||
}
|
||||
|
||||
if (specific_enthalpy.value() == 0.0) {
|
||||
// dρ/dh = n == 1 -> 1/hs
|
||||
// dρ/dh = else -> 0
|
||||
return PartialDerivative<Density, SpecificEnthalpy>{
|
||||
m_polytropic_index == 1.0 ? 1.0 / m_enthalpy_scale : 0.0
|
||||
};
|
||||
}
|
||||
|
||||
// dρ/dh = (n/hs) * (h/hs)^(n-1)
|
||||
return PartialDerivative<Density, SpecificEnthalpy>{
|
||||
m_polytropic_index / m_enthalpy_scale * std::pow(specific_enthalpy.value() / m_enthalpy_scale, m_polytropic_index - 1.0)
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] PartialDerivative<Pressure, SpecificEnthalpy> Polytrope::partial_derivative(PressureFromSpecificEnthalpy, WithRespectTo<SpecificEnthalpy>, const SpecificEnthalpyValue specific_enthalpy) const {
|
||||
const DensityValue density = evaluate(DensityFromSpecificEnthalpy{}, specific_enthalpy);
|
||||
|
||||
// dP/dh = ρ
|
||||
return PartialDerivative<Pressure, SpecificEnthalpy>{density.value()};
|
||||
}
|
||||
|
||||
[[nodiscard]] PartialDerivative<Pressure, Density> Polytrope::partial_derivative(PressureFromDensity, WithRespectTo<Density>, const DensityValue density) const {
|
||||
validate_nonnegativity<EOSEvaluationError>(density.value(), EOSEvaluationErrorCode::invalid_thermodynamic_input);
|
||||
|
||||
if (density.value() == 0.0) {
|
||||
// dP/dρ = 0
|
||||
return PartialDerivative<Pressure, Density>{0.0};
|
||||
}
|
||||
|
||||
// dP/dρ = K * (1 + 1/n) * (ρ)^(1/n)
|
||||
return PartialDerivative<Pressure, Density>{
|
||||
m_polytropic_constant * (1.0 + 1.0 / m_polytropic_index) * std::pow(density.value(), 1.0 / m_polytropic_index)
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user