module; #include #include export module mean_field:eos.pressure_surface; export import :eos.evaluation; export namespace mean_field::eos { namespace detail { template < ThermodynamicQuantityType InputQuantity, typename SurfaceState> [[nodiscard]] constexpr auto pressureSurfaceRelationInput( const dimensions::PressureValue targetPressure, const SurfaceState &state ) { if constexpr (std::same_as) { return targetPressure; } else { return state.value(InputQuantity{}); } } template struct PressureSurfaceRelationOperations; template struct PressureSurfaceRelationOperations> { template < typename EquationOfState, typename SurfaceState> [[nodiscard]] static dimensions::QuantityValue requiredCarrierValue( const EquationOfState &equationOfState, const dimensions::PressureValue targetPressure, const SurfaceState &state ) { return evaluate( equationOfState, pressureSurfaceRelationInput(targetPressure, state)... ); } template < typename InputQuantity, typename EquationOfState, typename SurfaceState, typename SurfaceVariation> [[nodiscard]] static double inputJacobianContribution( const EquationOfState &equationOfState, const dimensions::PressureValue targetPressure, const SurfaceState &state, const SurfaceVariation &variation ) { if constexpr (std::same_as) { return 0.0; } else { const auto derivative = partialDerivative( equationOfState, pressureSurfaceRelationInput(targetPressure, state)... ); return derivative.value() * variation.value(InputQuantity{}).value(); } } template < typename EquationOfState, typename SurfaceState, typename SurfaceVariation> [[nodiscard]] static double carrierCorrectionJacobianAction( const EquationOfState &equationOfState, const dimensions::PressureValue targetPressure, const SurfaceState &state, const SurfaceVariation &variation ) { return ( 0.0 + ... + inputJacobianContribution(equationOfState, targetPressure, state, variation) ); } }; } // namespace detail /* * EOS-owned resolution of a constant-pressure condition into the carrier * quantity used by an equation formulation. No field or solver concepts * enter this type. */ template class ResolvedPressureSurfaceRelation final { public: using RelationType = SelectedRelation; using CarrierQuantity = RelationOutputT; ResolvedPressureSurfaceRelation( const EquationOfState &equationOfState, const dimensions::PressureValue targetPressure ) noexcept : m_equationOfState(std::addressof(equationOfState)), m_targetPressure(targetPressure) { } [[nodiscard]] dimensions::PressureValue targetPressure() const noexcept { return m_targetPressure; } template [[nodiscard]] dimensions::QuantityValue requiredCarrierValue(const SurfaceState &state) const { return detail::PressureSurfaceRelationOperations::requiredCarrierValue( *m_equationOfState, m_targetPressure, state ); } template < typename SurfaceState, typename SurfaceVariation> [[nodiscard]] double carrierCorrectionJacobianAction( const SurfaceState &state, const SurfaceVariation &variation ) const { return detail::PressureSurfaceRelationOperations::carrierCorrectionJacobianAction( *m_equationOfState, m_targetPressure, state, variation ); } private: const EquationOfState *m_equationOfState; dimensions::PressureValue m_targetPressure; }; } // namespace mean_field::eos