binding.hpp cstddef memory tuple type_traits utility serif/model/equilibrium_plan.hpp serif/backend/mfem/model/inputs.hpp serif/backend/mfem/geometry/surface/pressure_boundary.hpp serif/backend/mfem/geometry/deformation/inputs.hpp src/include/serif/backend/mfem/model/equilibrium_evaluator.hpp src/include/serif/backend/mfem/solver/seed/state.hpp serif::model::backend::mfem::BoundModel serif serif::model serif::model::backend serif::model::backend::mfem serif::model::backend::mfem::detail #pragmaonce #include<cstddef> #include<memory> #include<tuple> #include<type_traits> #include<utility> #include"serif/model/equilibrium_plan.hpp" #include"serif/backend/mfem/model/inputs.hpp" #include"serif/backend/mfem/geometry/surface/pressure_boundary.hpp" #include"serif/backend/mfem/geometry/deformation/inputs.hpp" namespaceserif::model::backend::mfem { template<typenameModel,typenameDescriptionT,typenameDiscretization,typenameBoundary,typenamePlanT> structBoundModel { usingDescription=DescriptionT; usingPlan=PlanT; std::shared_ptr<constModel>model; Descriptiondefinition; std::shared_ptr<constDiscretization>discretization; Boundaryboundary; template<typenameRow> [[nodiscard]]autoequation_discretization()const { returndiscretization->templateequation_discretization<Row>(); } }; template<utils::dependencies::IsKeyListPrescribed=utils::dependencies::KeyList<>,typenameModel,typenameDiscretization,typenameCoefficients> [[nodiscard]]autobind_model_definition(std::shared_ptr<constModel>model,std::shared_ptr<constDiscretization>discretization, constCoefficients&coefficients) { usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(model!=nullptr&&discretization!=nullptr,"Bindingastellarmodelrequiresbothanowningphysicaldescriptionandanowningdiscretization."); autodefinition=resolve_equilibrium_equations(*model); usingDescription=decltype(definition); usingAvailableFields=typenameCoefficients::Keys; usingPlan=EquilibriumPlan<typename Model::EquationOfState, Description, Prescribed, AvailableFields>; static_assert(Plan::Surface::supported, "Theisobaricconditionhasnouniquesupportedequation.ChecktheEOSrelations,availableboundaryfields,derivativesandsolvedequationrows.ForgenuinelyambiguousrowsanequationmaynameitsIsobaricSurfaceField."); detail::validate_coefficient_owners(*discretization,coefficients,typenamePlan::Coefficients{}); constautoboundary=[&]() { ifconstexpr(Plan::has_surface&&Plan::Surface::supported) { usingFormulation=typenamePlan::Surface::Formulation; returngeometry::surface::backend::mfem::make_pressure_boundary<Formulation>(coefficients); } else { returnNoSurfaceCondition{}; } }(); usingBinding=BoundModel<Model,Description,Discretization,decltype(boundary),Plan>; returnstd::make_shared<constBinding>(Binding{.model=std::move(model),.definition=std::move(definition), .discretization=std::move(discretization),.boundary=boundary}); } namespacedetail { template<typenameEOS> [[nodiscard]]autoequation_of_state_input(constEOS&eos){ usingnamespaceutils::dependencies; returnborrow<geometry::surface::keys::EquationOfState>(eos,track_by([](constEOS&value){ returnstd::addressof(value); })); } template<typenameGeometry> [[nodiscard]]std::size_tgeometry_size(constGeometry&coefficients) { ifconstexpr(requires{coefficients.Size();}) { returnstatic_cast<std::size_t>(coefficients.Size()); } else { returncoefficients.size(); } } } template<typenameBound,typenameCoefficients,typenameGeometry> [[nodiscard]]autoequilibrium_inputs(constBound&bound,constCoefficients&coefficients,constGeometry&geometry_coefficients) { namespaceexecution=operators::backend::mfem; usingDescription=typenameBound::Description; usingPlan=typenameBound::Plan; constauto&discretization=*bound.discretization; detail::validate_coefficient_owners(discretization,coefficients,typenamePlan::Coefficients{}); constautocommon=detail::model_inputs(discretization,coefficients,typenameDescription::InteriorEquations::Equations{},typenamePlan::Coefficients{}); constautodeformation=[&]() { ifconstexpr(Plan::has_shape) { returngeometry::deformation::backend::mfem::make_deformation_inputs(discretization.deformation.model,discretization.deformation.reference,geometry_coefficients); } else { returnutils::dependencies::make_dependency_context(utils::dependencies::own<execution::DisplacementCoefficients>( execution::bind(discretization.templatebinding<discretization::blocks::displacement::vector>(),geometry_coefficients),discretization::backend::mfem::CoefficientTracking{})); } }(); constautoboundary=[&]() { usingnamespaceutils::dependencies; ifconstexpr(Plan::has_surface) { constautoeos=detail::equation_of_state_input(bound.model->equation_of_state()); returngeometry::surface::backend::mfem::make_pressure_boundary_metadata(bound.boundary,eos,bound.definition.surface_condition); } else { returnmake_dependency_context(); } }(); returnutils::dependencies::combine_dependency_contexts(common,deformation,boundary); } template<typenamePlan,typenameDiscretization,typenameGeometry> [[nodiscard]]typenamePlan::Layoutequilibrium_layout(constDiscretization&discretization,constGeometry&geometry_coefficients){ returndiscretization::blocks::make_system_layout<typename Plan::Layout>([&]<typenameTerm>()->std::size_t{ ifconstexpr(std::same_as<Term,discretization::blocks::surface_deformation::coefficients>||std::same_as<Term,discretization::blocks::surface_deformation::shape_equilibrium>){ returndetail::geometry_size(geometry_coefficients); }else{ returnstatic_cast<std::size_t>(discretization.templatebinding<Term>().size()); } }); } }