surface_boundary.cpp concepts type_traits utility serif/discretization/domain/schema/schemas.hpp serif/backend/mfem/geometry/surface/boundary_computations.hpp serif/geometry/surface/automatic.hpp serif/eos/models/polytropic.hpp serif/utils/dependencies/computation_cache.hpp serif::compile_time_checks::surface_boundary::ScalarTerm serif::compile_time_checks::surface_boundary::ScalarTerm::value serif::compile_time_checks::surface_boundary::ScalarTerm::residual serif::compile_time_checks::surface_boundary::UniformTemperature serif::compile_time_checks::surface_boundary::Gas serif::compile_time_checks::surface_boundary::CentralMultiplier serif::compile_time_checks::surface_boundary::ForwardOnly serif::compile_time_checks::surface_boundary::MissingPartials serif::compile_time_checks::surface_boundary::MissingInversePartial serif::compile_time_checks::surface_boundary::OtherTemperature serif::compile_time_checks::surface_boundary::OtherDensity serif::compile_time_checks::surface_boundary::TwoInverseRelations serif::compile_time_checks::surface_boundary::ReversedInverseRelations serif::compile_time_checks::surface_boundary::SymbolicEOS serif serif::compile_time_checks serif::compile_time_checks::surface_boundary #include<concepts> #include<type_traits> #include<utility> #include"serif/discretization/domain/schema/schemas.hpp" #include"serif/backend/mfem/geometry/surface/boundary_computations.hpp" #include"serif/geometry/surface/automatic.hpp" #include"serif/eos/models/polytropic.hpp" #include"serif/utils/dependencies/computation_cache.hpp" namespaceserif::compile_time_checks::surface_boundary { namespacesurface=serif::geometry::surface; namespacebackend=surface::backend::mfem; namespacediscretization=serif::discretization; namespacefinite_elements=discretization::backend::mfem; namespacecoefficients=serif::operators::backend::mfem; namespaceblocks=discretization::blocks; namespacespaces=discretization::functional_space; namespacequantities=serif::dimensions; namespacedependencies=serif::utils::dependencies; namespaceeos=serif::eos; template<typenameQuantityT,typenameSpace> structScalarTerm:blocks::term<blocks::density> { usingFunctionalSpace=Space; usingSupport=discretization::domain::StellarDomains; usingQuantity=QuantityT; structvalue:blocks::value_block_base { }; structresidual:blocks::residual_block_base { }; }; structUniformTemperature:blocks::term<blocks::density>,blocks::global_scalar { usingSupport=discretization::domain::StellarDomains; usingQuantity=quantities::Temperature; staticconstexprboolthermodynamic_state=true; }; usingDensity=ScalarTerm<quantities::MassDensity, spaces::DiscreteFunctionalSpace<spaces::H1, 1, 0>>; usingDiscontinuousDensity=ScalarTerm<quantities::MassDensity, spaces::DiscreteFunctionalSpace<spaces::L2, 2, 0>>; usingTemperature=ScalarTerm<quantities::Temperature, spaces::DiscreteFunctionalSpace<spaces::H1, 2, 0>>; usingDiscontinuousTemperature=ScalarTerm<quantities::Temperature, spaces::DiscreteFunctionalSpace<spaces::L2, 2, 0>>; usingDensityRelation=eos::relations::Relation<quantities::MassDensity, quantities::Pressure, quantities::Temperature>; usingPressureRelation=eos::relations::Relation<quantities::Pressure, quantities::MassDensity, quantities::Temperature>; structGas { usingRelations=eos::relations::RelationCatalog<DensityRelation, PressureRelation>; quantities::DensityValueevaluate(DensityRelation,quantities::PressureValue,quantities::TemperatureValue)const; quantities::PressureValueevaluate(PressureRelation,quantities::DensityValue,quantities::TemperatureValue)const; quantities::PartialDerivative<quantities::MassDensity,quantities::Temperature>partial_derivative(DensityRelation,quantities::WithRespectTo<quantities::Temperature>,quantities::PressureValue,quantities::TemperatureValue)const; quantities::PartialDerivative<quantities::Pressure,quantities::MassDensity>partial_derivative(PressureRelation,quantities::WithRespectTo<quantities::MassDensity>,quantities::DensityValue,quantities::TemperatureValue)const; quantities::PartialDerivative<quantities::Pressure,quantities::Temperature>partial_derivative(PressureRelation,quantities::WithRespectTo<quantities::Temperature>,quantities::DensityValue,quantities::TemperatureValue)const; booloperator==(constGas&)const=default; }; template<typenameDensityTerm=Density,typenameTemperatureTerm=Temperature> usingState=dependencies::Bindings<dependencies::Binding<quantities::MassDensity,DensityTerm>,dependencies::Binding<quantities::Temperature,TemperatureTerm>>; usingFormulation=surface::PressureSurfaceFormulation<Gas,State<>>; usingGlobalInput=surface::PressureSurfaceFormulation<Gas,State<Density,UniformTemperature>>; usingDiscontinuousInput=surface::PressureSurfaceFormulation<Gas,State<Density,DiscontinuousTemperature>>; usingDiscontinuousRow=surface::PressureSurfaceFormulation<Gas,State<DiscontinuousDensity>>; usingDirect=surface::DirectPressureSurfaceFormulation<Gas,State<>,quantities::Temperature,PressureRelation>; usingGlobalRow=surface::DirectPressureSurfaceFormulation<Gas,State<Density,UniformTemperature>,quantities::Temperature,PressureRelation>; static_assert(finite_elements::BoundaryTraceTerm<Density>); static_assert(finite_elements::BoundaryTraceTerm<Temperature>); static_assert(finite_elements::BoundaryTraceTerm<UniformTemperature>); static_assert(!finite_elements::BoundaryTraceTerm<DiscontinuousTemperature>); static_assert(!finite_elements::BoundaryTraceTerm<blocks::displacement::vector>); static_assert(!finite_elements::BoundaryTraceTerm<int>); static_assert(backend::PressureBoundaryFormulation<Formulation>); static_assert(backend::PressureBoundaryFormulation<GlobalInput>); static_assert(backend::PressureBoundaryFormulation<Direct>); static_assert(std::same_as<Direct::Test,Temperature>); static_assert(std::same_as<Direct::ResidualQuantity,quantities::Pressure>); static_assert(!backend::PressureBoundaryFormulation<DiscontinuousInput>); static_assert(!backend::PressureBoundaryFormulation<DiscontinuousRow>); static_assert(!backend::PressureBoundaryFormulation<GlobalRow>); static_assert(!backend::PressureBoundaryFormulation<int>); usingSchema=discretization::domain::schema::CoreEnvelopeVacuumDomainSchema; template<typenameTerm> usingView=coefficients::CoefficientView<finite_elements::TermBinding<Term,Schema>>; template<typenameTerm> conceptBuildsTrace=requires(std::shared_ptr<constfinite_elements::DofSelection>rows,constfinite_elements::TermBinding<Term,Schema>&binding) { finite_elements::make_boundary_trace(rows,binding); }; static_assert(BuildsTrace<Density>); static_assert(BuildsTrace<Temperature>); static_assert(BuildsTrace<UniformTemperature>); static_assert(!BuildsTrace<DiscontinuousTemperature>); static_assert(!BuildsTrace<blocks::displacement::vector>); template<typenameBinding> conceptBuildsTemporaryTrace=requires(std::shared_ptr<constfinite_elements::DofSelection>rows) { finite_elements::make_boundary_trace(rows,std::declval<Binding>()); }; static_assert(!BuildsTemporaryTrace<finite_elements::TermBinding<Density, Schema>>); static_assert(!BuildsTemporaryTrace<const finite_elements::TermBinding<Density, Schema>>); static_assert(!BuildsTemporaryTrace<finite_elements::TermBinding<UniformTemperature, Schema>>); usingCoefficients=decltype(coefficients::make_term_coefficients(std::declval<View<Density>>(),std::declval<View<Temperature>>())); usingMissingColumn=decltype(coefficients::make_term_coefficients(std::declval<View<Density>>())); template<typenameContext> conceptBuildsBoundary=requires(constContext&context) { backend::make_pressure_boundary<Formulation>(context); }; static_assert(BuildsBoundary<Coefficients>); static_assert(!BuildsBoundary<MissingColumn>); usingBoundary=decltype(backend::make_pressure_boundary<Formulation>(std::declval<constCoefficients&>())); usingEOSResource=decltype(dependencies::own<surface::keys::EquationOfState>(Gas{})); usingWrongEOS=decltype(dependencies::own<surface::keys::EquationOfState>(0)); usingWrongEOSKey=decltype(dependencies::own<Gas>(Gas{})); template<typenameResource,typenameContext> conceptBuildsInputs=requires(Boundaryboundary,Resourceequation_of_state,surface::IsobaricSurfacecondition,constContext&context) { backend::make_pressure_boundary_inputs(boundary,equation_of_state,condition,context); }; static_assert(BuildsInputs<EOSResource, Coefficients>); static_assert(!BuildsInputs<WrongEOS, Coefficients>); static_assert(!BuildsInputs<WrongEOSKey, Coefficients>); static_assert(!BuildsInputs<EOSResource, MissingColumn>); usingInputs=decltype(backend::make_pressure_boundary_inputs(std::declval<Boundary>(),std::declval<EOSResource>(),std::declval<surface::IsobaricSurface>(),std::declval<constCoefficients&>())); usingGraph=decltype(backend::make_pressure_boundary_graph<Formulation>()); usingMissingEOS=decltype(std::declval<constInputs&>().select(dependencies::KeyList<backend::keys::BoundaryDiscretization,surface::keys::PressureCondition,Density,Temperature>{})); usingMissingState=decltype(std::declval<constInputs&>().select(dependencies::KeyList<backend::keys::BoundaryDiscretization,surface::keys::EquationOfState,surface::keys::PressureCondition,Density>{})); static_assert(dependencies::CanPrepare<Graph,Inputs,surface::SurfaceFailure>); static_assert(!dependencies::CanPrepare<Graph,MissingEOS,surface::SurfaceFailure>); static_assert(!dependencies::CanPrepare<Graph,MissingState,surface::SurfaceFailure>); static_assert(!dependencies::CanPrepare<Graph,Inputs,int>); static_assert(std::same_as<dependencies::bound_type_t<typenameInputs::Bindings,Density>,View<Density>>); static_assert(std::same_as<dependencies::bound_type_t<typenameInputs::Bindings,Temperature>,View<Temperature>>); usingGlobalCoefficients=decltype(coefficients::make_term_coefficients(std::declval<View<Density>>(),std::declval<View<UniformTemperature>>())); usingGlobalBoundary=decltype(backend::make_pressure_boundary<GlobalInput>(std::declval<constGlobalCoefficients&>())); usingGlobalInputs=decltype(backend::make_pressure_boundary_inputs(std::declval<GlobalBoundary>(),std::declval<EOSResource>(),std::declval<surface::IsobaricSurface>(),std::declval<constGlobalCoefficients&>())); usingDirectBoundary=decltype(backend::make_pressure_boundary<Direct>(std::declval<constCoefficients&>())); usingDirectInputs=decltype(backend::make_pressure_boundary_inputs(std::declval<DirectBoundary>(),std::declval<EOSResource>(),std::declval<surface::IsobaricSurface>(),std::declval<constCoefficients&>())); static_assert(dependencies::CanPrepare<decltype(backend::make_pressure_boundary_graph<GlobalInput>()),GlobalInputs,surface::SurfaceFailure>); static_assert(dependencies::CanPrepare<decltype(backend::make_pressure_boundary_graph<Direct>()),DirectInputs,surface::SurfaceFailure>); usingDensitySampling=Graph::ComputationAt<Graph::index<backend::keys::BoundarySamples<Density>>()>; usingTemperatureSampling=Graph::ComputationAt<Graph::index<backend::keys::BoundarySamples<Temperature>>()>; static_assert(std::same_as<typenameDensitySampling::Inputs,dependencies::InputList<backend::keys::BoundaryDiscretization,Density>>); static_assert(std::same_as<typenameTemperatureSampling::Inputs,dependencies::InputList<backend::keys::BoundaryDiscretization,Temperature>>); static_assert(!std::same_as<backend::keys::BoundarySamples<Density>,Density>); static_assert(Graph::size==4); structCentralMultiplier:blocks::term<blocks::density>,blocks::global_scalar { usingSupport=discretization::domain::StellarDomains; usingQuantity=quantities::SpecificEnthalpy; }; usingEnthalpy=ScalarTerm<quantities::SpecificEnthalpy, spaces::DiscreteFunctionalSpace<spaces::H1, 3, 0>>; usingPressure=ScalarTerm<quantities::Pressure, spaces::DiscreteFunctionalSpace<spaces::H1, 1, 0>>; usingBernoulliConstant=blocks::barotropic_constant::mass_normalization; usingGasFields=dependencies::KeyList<Density,Temperature>; usingGasRows=dependencies::KeyList<Density>; usingGasSelection=surface::AutomaticPressureSurface<Gas,GasFields,GasRows>; static_assert(GasSelection::status==surface::PressureSurfaceSelection::supported); static_assert(GasSelection::Formulation::resolves_carrier); static_assert(std::same_as<typenameGasSelection::Formulation::Test,Density>); static_assert(!surface::AutomaticPressureSurfaceCompilable<Gas,GasFields,dependencies::KeyList<>>); static_assert(!surface::AutomaticPressureSurfaceCompilable<Gas,GasFields,GasRows,dependencies::KeyList<Temperature>>); static_assert(!surface::AutomaticPressureSurfaceCompilable<Gas,dependencies::KeyList<Density>,GasRows>); static_assert(!surface::AutomaticPressureSurfaceCompilable<Gas,dependencies::KeyList<Density,DiscontinuousTemperature>,GasRows>); static_assert(surface::AutomaticPressureSurfaceCompilable<Gas,dependencies::KeyList<Density,UniformTemperature>,GasRows>); structForwardOnly:Gas { usingRelations=eos::relations::RelationCatalog<PressureRelation>; }; structMissingPartials { usingRelations=eos::relations::RelationCatalog<PressureRelation>; quantities::PressureValueevaluate(PressureRelation,quantities::DensityValue,quantities::TemperatureValue)const; }; structMissingInversePartial:Gas { usingGas::partial_derivative; quantities::PartialDerivative<quantities::MassDensity,quantities::Temperature>partial_derivative(DensityRelation,quantities::WithRespectTo<quantities::Temperature>,quantities::PressureValue,quantities::TemperatureValue)const=delete; }; usingForwardFallback=surface::AutomaticPressureSurface<MissingInversePartial,GasFields,GasRows>; static_assert(ForwardFallback::status==surface::PressureSurfaceSelection::supported); static_assert(!ForwardFallback::Formulation::resolves_carrier); structOtherTemperature:Temperature { }; structOtherDensity:Density { }; usingDensityFromPressure=eos::relations::Relation<quantities::MassDensity, quantities::Pressure>; structTwoInverseRelations:Gas { usingRelations=eos::relations::RelationCatalog<DensityFromPressure, DensityRelation, PressureRelation>; usingGas::evaluate; quantities::DensityValueevaluate(DensityFromPressure,quantities::PressureValue)const; }; structReversedInverseRelations:TwoInverseRelations { usingRelations=eos::relations::RelationCatalog<PressureRelation, DensityRelation, DensityFromPressure>; }; usingDirectSelection=surface::AutomaticPressureSurface<ForwardOnly,GasFields,GasRows>; static_assert(!DirectSelection::Formulation::resolves_carrier); static_assert(!surface::AutomaticPressureSurfaceCompilable<MissingPartials,GasFields,GasRows>); static_assert(surface::AutomaticPressureSurface<ForwardOnly,GasFields,GasFields>::status==surface::PressureSurfaceSelection::ambiguous); static_assert(surface::AutomaticPressureSurfaceCompilable<ForwardOnly,GasFields,GasFields,GasFields,Temperature>); static_assert(surface::AutomaticPressureSurface<TwoInverseRelations,GasFields,GasRows>::status==surface::PressureSurfaceSelection::ambiguous); static_assert(surface::AutomaticPressureSurface<ReversedInverseRelations,GasFields,GasRows>::status==surface::PressureSurfaceSelection::ambiguous); static_assert(!surface::AutomaticPressureSurfaceCompilable<Gas,dependencies::KeyList<Density,Temperature,OtherTemperature>,GasRows>); static_assert(surface::AutomaticPressureSurface<Gas,dependencies::KeyList<Density,OtherDensity,Temperature>,dependencies::KeyList<Density,OtherDensity>>::status==surface::PressureSurfaceSelection::ambiguous); usingPolytropicFields=dependencies::KeyList<Enthalpy,blocks::density::mass,BernoulliConstant,CentralMultiplier>; usingPolytropicSelection=surface::AutomaticPressureSurface<eos::models::Polytrope,PolytropicFields,dependencies::KeyList<Enthalpy,BernoulliConstant>>; static_assert(std::same_as<typenamePolytropicSelection::Formulation::CarrierTerm,Enthalpy>); static_assert(!surface::AutomaticPressureSurfaceCompilable<eos::models::Polytrope,dependencies::KeyList<BernoulliConstant,CentralMultiplier>,dependencies::KeyList<BernoulliConstant>>); static_assert(surface::AutomaticPressureSurfaceCompilable<eos::models::Polytrope,dependencies::KeyList<blocks::density::mass>,dependencies::KeyList<blocks::density::mass>>); structSymbolicEOS { }; usingPressureFields=dependencies::KeyList<Pressure,Density,Temperature>; usingPressureSelection=surface::AutomaticPressureSurface<SymbolicEOS,PressureFields,dependencies::KeyList<Pressure>>; static_assert(!PressureSelection::Formulation::uses_eos); static_assert(std::same_as<typenamesurface::AutomaticPressureSurface<Gas,PressureFields,PressureFields>::Formulation::CarrierTerm,Pressure>); static_assert(backend::PressureBoundaryFormulation<typenamePressureSelection::Formulation>); }