236 lines
7.3 KiB
C++
236 lines
7.3 KiB
C++
module;
|
|
|
|
#include <compare>
|
|
#include <concepts>
|
|
#include <string_view>
|
|
#include <type_traits>
|
|
|
|
export module mean_field:eos.quantities;
|
|
|
|
export namespace mean_field::eos {
|
|
struct ThermodynamicQuantity { };
|
|
|
|
template <typename Candidate>
|
|
concept ThermodynamicQuantityType =
|
|
std::same_as<Candidate, std::remove_cv_t<Candidate>> && std::derived_from<Candidate, ThermodynamicQuantity>;
|
|
|
|
namespace quantity {
|
|
struct Density final : ThermodynamicQuantity {
|
|
static constexpr std::string_view identifier = "density";
|
|
};
|
|
|
|
struct Pressure final : ThermodynamicQuantity {
|
|
static constexpr std::string_view identifier = "pressure";
|
|
};
|
|
|
|
struct SpecificEnthalpy final : ThermodynamicQuantity {
|
|
static constexpr std::string_view identifier = "specific_enthalpy";
|
|
};
|
|
} // namespace quantity
|
|
|
|
template <typename T>
|
|
concept Numeric = std::integral<T> || std::floating_point<T>;
|
|
|
|
template <ThermodynamicQuantityType Quantity> class QuantityValue final {
|
|
public:
|
|
explicit constexpr QuantityValue(const double value) noexcept : m_value(value) {
|
|
}
|
|
|
|
[[nodiscard]] constexpr double value() const noexcept {
|
|
return m_value;
|
|
}
|
|
|
|
[[nodiscard]] friend constexpr bool operator==(
|
|
const QuantityValue &,
|
|
const QuantityValue &
|
|
) noexcept = default;
|
|
|
|
friend constexpr QuantityValue<Quantity> operator+(
|
|
const QuantityValue<Quantity> &lhs,
|
|
const QuantityValue<Quantity> &rhs
|
|
) noexcept {
|
|
return QuantityValue<Quantity>{lhs.m_value + rhs.m_value};
|
|
}
|
|
|
|
friend constexpr QuantityValue<Quantity> operator-(
|
|
const QuantityValue<Quantity> &lhs,
|
|
const QuantityValue<Quantity> &rhs
|
|
) noexcept {
|
|
return QuantityValue<Quantity>{lhs.m_value - rhs.m_value};
|
|
}
|
|
|
|
template <Numeric rhsT>
|
|
friend constexpr QuantityValue<Quantity> operator*(
|
|
const QuantityValue<Quantity> &lhs,
|
|
rhsT rhs
|
|
) noexcept {
|
|
return QuantityValue<Quantity>{lhs.m_value * static_cast<double>(rhs)};
|
|
}
|
|
|
|
template <Numeric lhsT>
|
|
friend constexpr QuantityValue<Quantity> operator*(
|
|
lhsT lhs,
|
|
const QuantityValue<Quantity> &rhs
|
|
) noexcept {
|
|
return QuantityValue<Quantity>{static_cast<double>(lhs) * rhs.m_value};
|
|
}
|
|
|
|
template <Numeric rhsT>
|
|
friend constexpr QuantityValue<Quantity> operator/(
|
|
const QuantityValue<Quantity> &lhs,
|
|
rhsT rhs
|
|
) noexcept {
|
|
return QuantityValue<Quantity>{lhs.m_value / static_cast<double>(rhs)};
|
|
}
|
|
|
|
template <Numeric compT>
|
|
friend constexpr std::partial_ordering operator<=>(
|
|
const QuantityValue<Quantity> &lhs,
|
|
compT rhs
|
|
) noexcept {
|
|
return lhs.m_value <=> static_cast<double>(rhs);
|
|
}
|
|
|
|
template <Numeric compT>
|
|
friend constexpr std::partial_ordering operator<=>(
|
|
compT lhs,
|
|
const QuantityValue<Quantity> &rhs
|
|
) noexcept {
|
|
return static_cast<double>(lhs) <=> rhs.m_value;
|
|
}
|
|
|
|
friend constexpr std::partial_ordering operator<=>(
|
|
const QuantityValue<Quantity> &lhs,
|
|
const QuantityValue<Quantity> &rhs
|
|
) noexcept {
|
|
return lhs.m_value <=> rhs.m_value;
|
|
}
|
|
|
|
private:
|
|
double m_value;
|
|
};
|
|
|
|
using DensityValue = QuantityValue<quantity::Density>;
|
|
using PressureValue = QuantityValue<quantity::Pressure>;
|
|
using SpecificEnthalpyValue = QuantityValue<quantity::SpecificEnthalpy>;
|
|
|
|
template <typename Candidate> struct IsQuantityValue : std::false_type { };
|
|
|
|
template <ThermodynamicQuantityType Quantity> struct IsQuantityValue<QuantityValue<Quantity>> : std::true_type { };
|
|
|
|
template <typename Candidate>
|
|
concept QuantityValueType = IsQuantityValue<std::remove_cvref_t<Candidate>>::value;
|
|
|
|
template <typename Candidate> struct QuantityOf;
|
|
|
|
template <ThermodynamicQuantityType Quantity> struct QuantityOf<QuantityValue<Quantity>> {
|
|
using Type = Quantity;
|
|
};
|
|
|
|
template <QuantityValueType Value> using QuantityOfT = typename QuantityOf<std::remove_cvref_t<Value>>::Type;
|
|
|
|
template <ThermodynamicQuantityType OutputQuantity, ThermodynamicQuantityType InputQuantity>
|
|
class PartialDerivative final {
|
|
public:
|
|
explicit constexpr PartialDerivative(const double value) noexcept : m_value(value) {
|
|
}
|
|
|
|
[[nodiscard]] constexpr double value() const noexcept {
|
|
return m_value;
|
|
}
|
|
|
|
friend constexpr PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity>
|
|
operator+(
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &lhs,
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &rhs
|
|
) noexcept;
|
|
|
|
friend constexpr PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity>
|
|
operator-(
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &lhs,
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &rhs
|
|
) noexcept;
|
|
|
|
template <Numeric rhsT>
|
|
friend constexpr PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity>
|
|
operator*(
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &,
|
|
rhsT
|
|
) noexcept;
|
|
|
|
template <Numeric lhsT>
|
|
friend constexpr PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity>
|
|
operator*(
|
|
lhsT,
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &
|
|
) noexcept;
|
|
|
|
template <Numeric rhsT>
|
|
friend constexpr PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity>
|
|
operator/(
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &,
|
|
rhsT
|
|
) noexcept;
|
|
|
|
template <Numeric cmpT>
|
|
friend constexpr std::partial_ordering operator<=>(
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &lhs,
|
|
cmpT rhs
|
|
) noexcept {
|
|
return lhs.m_value <=> static_cast<double>(rhs);
|
|
}
|
|
|
|
template <Numeric cmpT>
|
|
friend constexpr std::partial_ordering operator<=>(
|
|
cmpT lhs,
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &rhs
|
|
) noexcept {
|
|
return static_cast<double>(lhs) <=> rhs.m_value;
|
|
}
|
|
|
|
friend constexpr std::partial_ordering operator<=>(
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &lhs,
|
|
const PartialDerivative<
|
|
OutputQuantity,
|
|
InputQuantity> &rhs
|
|
) noexcept {
|
|
return lhs.m_value <=> rhs.m_value;
|
|
}
|
|
|
|
private:
|
|
double m_value;
|
|
};
|
|
|
|
template <ThermodynamicQuantityType Quantity> struct WithRespectTo final { };
|
|
} // namespace mean_field::eos
|