feat(surface): major work on implementing surface constraints in a presciption agnostic manner
This commit is contained in:
143
libmeanfield/interface/surface/compiler.cppm
Normal file
143
libmeanfield/interface/surface/compiler.cppm
Normal file
@@ -0,0 +1,143 @@
|
||||
module;
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
export module mean_field:surface.compiler;
|
||||
|
||||
export import :surface.compiled;
|
||||
|
||||
export namespace mean_field::surface {
|
||||
namespace detail {
|
||||
template <typename RelationType, typename Formulation, typename EquationOfState>
|
||||
struct PressureSurfaceRelationMatches : std::false_type { };
|
||||
|
||||
template <typename OutputQuantity, typename... InputQuantities, typename Formulation, typename EquationOfState>
|
||||
struct PressureSurfaceRelationMatches<
|
||||
eos::Relation<OutputQuantity, InputQuantities...>,
|
||||
Formulation,
|
||||
EquationOfState>
|
||||
: std::bool_constant<
|
||||
std::same_as<OutputQuantity, typename Formulation::CarrierQuantity> &&
|
||||
(std::same_as<eos::quantity::Pressure, InputQuantities> || ...) &&
|
||||
((std::same_as<eos::quantity::Pressure, InputQuantities> ||
|
||||
(surfaceBindingCount<typename Formulation::StateBindings, InputQuantities> == 1 &&
|
||||
eos::SupportsPartialDerivative<
|
||||
EquationOfState,
|
||||
eos::Relation<OutputQuantity, InputQuantities...>,
|
||||
InputQuantities>)) &&
|
||||
...)> { };
|
||||
|
||||
template <typename Catalog, typename Formulation, typename EquationOfState>
|
||||
struct MatchingPressureSurfaceRelations;
|
||||
|
||||
template <typename... Relations, typename Formulation, typename EquationOfState>
|
||||
struct MatchingPressureSurfaceRelations<eos::RelationCatalog<Relations...>, Formulation, EquationOfState> {
|
||||
using Tuple = decltype(std::tuple_cat(
|
||||
std::conditional_t<
|
||||
PressureSurfaceRelationMatches<Relations, Formulation, EquationOfState>::value,
|
||||
std::tuple<Relations>,
|
||||
std::tuple<>>{}...
|
||||
));
|
||||
|
||||
static constexpr std::size_t count = std::tuple_size_v<Tuple>;
|
||||
};
|
||||
|
||||
template <std::size_t Count, typename Tuple> struct UniquePressureSurfaceRelation {
|
||||
using Type = void;
|
||||
};
|
||||
|
||||
template <typename Tuple> struct UniquePressureSurfaceRelation<1, Tuple> {
|
||||
using Type = std::tuple_element_t<0, Tuple>;
|
||||
};
|
||||
|
||||
template <typename Dependencies, typename Field> struct AppendSurfaceDependency;
|
||||
|
||||
template <typename RowField, typename... StateFields, typename Field>
|
||||
struct AppendSurfaceDependency<SurfaceConstraintDependencies<RowField, StateFields...>, Field> {
|
||||
using Type = SurfaceConstraintDependencies<RowField, StateFields..., Field>;
|
||||
};
|
||||
|
||||
template <typename Dependencies, typename InputQuantity, typename Bindings>
|
||||
struct AppendPressureSurfaceInputDependency {
|
||||
using Type =
|
||||
typename AppendSurfaceDependency<Dependencies, SurfaceFieldForQuantityT<Bindings, InputQuantity>>::Type;
|
||||
};
|
||||
|
||||
template <typename Dependencies, typename Bindings>
|
||||
struct AppendPressureSurfaceInputDependency<Dependencies, eos::quantity::Pressure, Bindings> {
|
||||
using Type = Dependencies;
|
||||
};
|
||||
|
||||
template <typename Dependencies, typename Bindings, typename... InputQuantities>
|
||||
struct AppendPressureSurfaceInputDependencies;
|
||||
|
||||
template <typename Dependencies, typename Bindings>
|
||||
struct AppendPressureSurfaceInputDependencies<Dependencies, Bindings> {
|
||||
using Type = Dependencies;
|
||||
};
|
||||
|
||||
template <typename Dependencies, typename Bindings, typename FirstInput, typename... RemainingInputs>
|
||||
struct AppendPressureSurfaceInputDependencies<Dependencies, Bindings, FirstInput, RemainingInputs...> {
|
||||
using WithFirst = typename AppendPressureSurfaceInputDependency<Dependencies, FirstInput, Bindings>::Type;
|
||||
using Type = typename AppendPressureSurfaceInputDependencies<WithFirst, Bindings, RemainingInputs...>::Type;
|
||||
};
|
||||
|
||||
template <typename RelationType, typename Formulation> struct PressureSurfaceDependenciesForRelation;
|
||||
|
||||
template <typename OutputQuantity, typename... InputQuantities, typename Formulation>
|
||||
struct PressureSurfaceDependenciesForRelation<eos::Relation<OutputQuantity, InputQuantities...>, Formulation> {
|
||||
using InitialDependencies =
|
||||
SurfaceConstraintDependencies<typename Formulation::CarrierField, typename Formulation::CarrierField>;
|
||||
using Type = typename AppendPressureSurfaceInputDependencies<
|
||||
InitialDependencies,
|
||||
typename Formulation::StateBindings,
|
||||
InputQuantities...>::Type;
|
||||
};
|
||||
|
||||
template <SurfaceConstraintFormulationType Formulation, eos::EquationOfStateModel EquationOfState>
|
||||
struct PressureSurfaceCompilation {
|
||||
using Matches =
|
||||
MatchingPressureSurfaceRelations<typename EquationOfState::Relations, Formulation, EquationOfState>;
|
||||
using Relation = typename UniquePressureSurfaceRelation<Matches::count, typename Matches::Tuple>::Type;
|
||||
};
|
||||
|
||||
template <SurfaceConstraintFormulationType Formulation, eos::EquationOfStateModel EquationOfState>
|
||||
requires(PressureSurfaceCompilation<Formulation, EquationOfState>::Matches::count == 1)
|
||||
struct CompiledPressureSurfaceConstraintType {
|
||||
using Compilation = PressureSurfaceCompilation<Formulation, EquationOfState>;
|
||||
using Relation = typename Compilation::Relation;
|
||||
using Dependencies = typename PressureSurfaceDependenciesForRelation<Relation, Formulation>::Type;
|
||||
using Type = CompiledPressureSurfaceConstraint<EquationOfState, Formulation, Relation, Dependencies>;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename Formulation, typename EquationOfState>
|
||||
concept PressureSurfaceCompilable =
|
||||
SurfaceConstraintFormulationType<Formulation> && eos::EquationOfStateModel<EquationOfState> &&
|
||||
(detail::PressureSurfaceCompilation<std::remove_cvref_t<Formulation>, std::remove_cvref_t<EquationOfState>>::
|
||||
Matches::count == 1);
|
||||
|
||||
template <SurfaceConstraintFormulationType Formulation, eos::EquationOfStateModel EquationOfState>
|
||||
requires PressureSurfaceCompilable<Formulation, EquationOfState>
|
||||
using CompiledPressureSurfaceConstraintT = typename detail::CompiledPressureSurfaceConstraintType<
|
||||
std::remove_cvref_t<Formulation>,
|
||||
std::remove_cvref_t<EquationOfState>>::Type;
|
||||
|
||||
template <
|
||||
SurfaceConstraintFormulationType Formulation,
|
||||
eos::EquationOfStateModel EquationOfState>
|
||||
requires PressureSurfaceCompilable<
|
||||
Formulation,
|
||||
EquationOfState>
|
||||
[[nodiscard]] CompiledPressureSurfaceConstraintT<
|
||||
Formulation,
|
||||
EquationOfState>
|
||||
compilePressureSurfaceConstraint(
|
||||
const ConstantPressureSurface condition,
|
||||
const EquationOfState &equationOfState
|
||||
) noexcept {
|
||||
return CompiledPressureSurfaceConstraintT<Formulation, EquationOfState>{condition, equationOfState};
|
||||
}
|
||||
} // namespace mean_field::surface
|
||||
Reference in New Issue
Block a user