module; #include #include #include #include export module mean_field:eos.quantities; export namespace mean_field::eos { struct ThermodynamicQuantity { }; template concept ThermodynamicQuantityType = std::same_as> && std::derived_from; 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 concept Numeric = std::integral || std::floating_point; template 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 operator+( const QuantityValue &lhs, const QuantityValue &rhs ) noexcept { return QuantityValue{lhs.m_value + rhs.m_value}; } friend constexpr QuantityValue operator-( const QuantityValue &lhs, const QuantityValue &rhs ) noexcept { return QuantityValue{lhs.m_value - rhs.m_value}; } template friend constexpr QuantityValue operator*( const QuantityValue &lhs, rhsT rhs ) noexcept { return QuantityValue{lhs.m_value * static_cast(rhs)}; } template friend constexpr QuantityValue operator*( lhsT lhs, const QuantityValue &rhs ) noexcept { return QuantityValue{static_cast(lhs) * rhs.m_value}; } template friend constexpr QuantityValue operator/( const QuantityValue &lhs, rhsT rhs ) noexcept { return QuantityValue{lhs.m_value / static_cast(rhs)}; } template friend constexpr std::partial_ordering operator<=>( const QuantityValue &lhs, compT rhs ) noexcept { return lhs.m_value <=> static_cast(rhs); } template friend constexpr std::partial_ordering operator<=>( compT lhs, const QuantityValue &rhs ) noexcept { return static_cast(lhs) <=> rhs.m_value; } friend constexpr std::partial_ordering operator<=>( const QuantityValue &lhs, const QuantityValue &rhs ) noexcept { return lhs.m_value <=> rhs.m_value; } private: double m_value; }; using DensityValue = QuantityValue; using PressureValue = QuantityValue; using SpecificEnthalpyValue = QuantityValue; template struct IsQuantityValue : std::false_type { }; template struct IsQuantityValue> : std::true_type { }; template concept QuantityValueType = IsQuantityValue>::value; template struct QuantityOf; template struct QuantityOf> { using Type = Quantity; }; template using QuantityOfT = typename QuantityOf>::Type; template 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 friend constexpr PartialDerivative< OutputQuantity, InputQuantity> operator*( const PartialDerivative< OutputQuantity, InputQuantity> &, rhsT ) noexcept; template friend constexpr PartialDerivative< OutputQuantity, InputQuantity> operator*( lhsT, const PartialDerivative< OutputQuantity, InputQuantity> & ) noexcept; template friend constexpr PartialDerivative< OutputQuantity, InputQuantity> operator/( const PartialDerivative< OutputQuantity, InputQuantity> &, rhsT ) noexcept; template friend constexpr std::partial_ordering operator<=>( const PartialDerivative< OutputQuantity, InputQuantity> &lhs, cmpT rhs ) noexcept { return lhs.m_value <=> static_cast(rhs); } template friend constexpr std::partial_ordering operator<=>( cmpT lhs, const PartialDerivative< OutputQuantity, InputQuantity> &rhs ) noexcept { return static_cast(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 struct WithRespectTo final { }; } // namespace mean_field::eos