boundary_computations.hpp serif/backend/mfem/geometry/surface/boundary_inputs.hpp serif/geometry/surface/computations.hpp serif/backend/mfem/shared/finite.hpp src/compile_time_checks/serif/geometry/surface_boundary.cpp src/include/serif/backend/mfem/geometry/surface/pressure_boundary.hpp src/include/serif/backend/mfem/model/graph.hpp serif serif::geometry serif::geometry::surface serif::geometry::surface::backend serif::geometry::surface::backend::mfem serif::geometry::surface::backend::mfem::detail #pragmaonce #include"serif/backend/mfem/geometry/surface/boundary_inputs.hpp" #include"serif/geometry/surface/computations.hpp" #include"serif/backend/mfem/shared/finite.hpp" namespaceserif::geometry::surface::backend::mfem { namespacedetail { template<typenameTerm,typenameBoundary,typenameInput> [[nodiscard]]std::expected<BoundaryValues<Term>,SurfaceFailure>sample_boundary_values(constBoundary&boundary,constInput&input) { usingnamespaceutils::errors; constauto&trace=boundary.traces.templateget<Term>(); serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR, std::invalid_argument>(&trace.binding()==&input.binding,"Pressure-boundarycoefficientsmustusethebindingthatcompiledtheirtrace."); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT, std::invalid_argument>(input.values.Size()==trace.binding().size(),"Pressure-boundarycoefficientsmustmatchthesupportedfieldsize."); if(!utils::checks::is_finite(input.values)) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::non_finite_state,.message="Apressure-boundaryfieldcontainsanon-finitecoefficient."}); } BoundaryValues<Term>result{.values=std::vector<double>(boundary.selected_rows->size())}; ::mfem::Vectorvalues(result.values.data(),static_cast<int>(result.values.size())); trace.interpolation().Mult(input.values,values); if(!utils::checks::is_finite(values)) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::non_finite_state,.message="Afinite-elementboundarytraceproducedanon-finitevalue."}); } returnresult; } template<PressureBoundaryFormulationFormulation,typename...Terms> [[nodiscard]]autopressure_boundary_computations(utils::dependencies::KeyList<Terms...>) { usingnamespaceutils::dependencies; constautosample=[]<typenameTerm>() { returnmake_computation<keys::BoundarySamples<Term>,InputList<keys::BoundaryDiscretization,Term>>( [](constauto&boundary,constauto&input) { static_assert(std::same_as<typenamestd::remove_cvref_t<decltype(*boundary)>::Formulation,Formulation>,"Theboundarygraphmustusetheformulationthatcompileditstraces."); returnsample_boundary_values<Term>(*boundary,input); }); }; returnstd::tuple_cat(std::tuple{sample.templateoperator()<Terms>()...},make_pressure_surface_computations<Formulation, keys::BoundarySamples>()); } } template<PressureBoundaryFormulationFormulation> [[nodiscard]]automake_pressure_boundary_computations() { returndetail::pressure_boundary_computations<Formulation>(typenameFormulation::StateTerms{}); } template<PressureBoundaryFormulationFormulation> [[nodiscard]]automake_pressure_boundary_graph() { returnstd::apply([](auto...computations) { returnutils::dependencies::make_computation_graph(std::move(computations)...); },make_pressure_boundary_computations<Formulation>()); } }