nodal_computations.hpp expected utility tuple serif/operators/backend/mfem/nodal_evaluation.hpp serif/operators/backend/mfem/nodal_inputs.hpp serif/operators/backend/mfem/preparation.hpp serif/utils/dependencies/dependencies.hpp src/compile_time_checks/serif/operators/computation_owners.cpp src/compile_time_checks/serif/operators/serial_backend.cpp src/include/serif/model/computations/point_constraints.hpp serif serif::operators serif::operators::backend serif::operators::backend::mfem #pragmaonce #include<expected> #include<utility> #include<tuple> #include"serif/operators/backend/mfem/nodal_evaluation.hpp" #include"serif/operators/backend/mfem/nodal_inputs.hpp" #include"serif/operators/backend/mfem/preparation.hpp" #include"serif/utils/dependencies/dependencies.hpp" namespaceserif::operators::backend::mfem { template<typenameScope,typenameInputKey,NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]automake_nodal_evaluation_computation(EquationTequation,NodalDiscretization<EquationT, SchemaT>discretization) { usingnamespaceutils::dependencies; validate_nodal_discretization(discretization); returnmake_computation<typenamenodal_keys::Scoped<Scope>::Linearization,InputList<InputKey>>( [equation=std::move(equation),discretization](constSelectedNodalValues&input) { usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::invalid_argument>(input.selected_rows==discretization.selected_rows, "Preparethisnodalgraphwiththeselectionusedtoconstructit."); returnevaluate_nodal_values(equation,discretization,input.values); }); } template<typenameScope=void,NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]automake_nodal_equation_computation(EquationTequation,NodalDiscretization<EquationT, SchemaT>discretization) { returnmake_nodal_evaluation_computation<Scope, nodal_keys::SelectedInput<Scope, typename EquationT::Test>>(std::move(equation),discretization); } template<typenameScope=void,NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]automake_nodal_sampling_computation(NodalDiscretization<EquationT, SchemaT>discretization) { usingnamespaceutils::dependencies; usingBinding=discretization::backend::mfem::TermBinding<typenameEquationT::Test,SchemaT>; validate_nodal_discretization(discretization); returnmake_computation<typenamenodal_keys::Scoped<Scope>::Samples,InputList<typenamenodal_keys::Scoped<Scope>::Bindings,typenameEquationT::Test>>( [discretization](constNodalBindings&bindings,constCoefficientView<Binding>&input) { usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::invalid_argument>(bindings.selection==discretization.selected_rows, "Preparenodalcomputationswiththeiroriginalequationselection."); returnselect_nodal_values(discretization,make_term_coefficients(input)); }); } template<typenameScope=void,NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]automake_nodal_equation_computations(EquationTequation,NodalDiscretization<EquationT, SchemaT>discretization) { returnstd::tuple{make_nodal_sampling_computation<Scope>(discretization), make_nodal_evaluation_computation<Scope, typename nodal_keys::Scoped<Scope>::Samples>(std::move(equation),discretization)}; } template<typenameScope=void,AffinePointEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]automake_point_border_computation(constPointBorderDiscretization<EquationT, SchemaT>&discretization) { usingnamespaceutils::dependencies; returnmake_computation<typenamenodal_keys::Scoped<Scope>::BorderLinearization,InputList<typenamenodal_keys::Scoped<Scope>::Linearization,typenameEquationT::Border>>( [discretization](constNodalData<EquationT, SchemaT>&nodal,constauto&border) { usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::invalid_argument>(&border.binding==&discretization.border_binding, "Pointbordercoefficientsmustusetheequation'sscalarbinding."); discretization.border_binding.validate_values(border.values); returnPointBorderData<EquationT, SchemaT>{.nodal=nodal,.border_binding=discretization.border_binding,.border_coefficient=border.values[0]}; }); } template<typenameScope=void,AffinePointEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]automake_point_border_computations(EquationTequation,constPointBorderDiscretization<EquationT, SchemaT>&discretization) { returnstd::tuple_cat(make_nodal_equation_computations<Scope>(std::move(equation),discretization.nodal),std::tuple{make_point_border_computation<Scope>(discretization)}); } template<typenameScope=void,NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT,typenameCoefficientsT> [[nodiscard]]automake_nodal_equation_cache(EquationTequation,constNodalDiscretization<EquationT, SchemaT>&discretization,constCoefficientsT&term_coefficients) { usingnamespaceutils::dependencies; constautocontext=make_nodal_dependency_context<Scope>(discretization,term_coefficients); autonodal_equation=make_nodal_equation_computation<Scope>(std::move(equation),discretization); returnmake_computation_cache<PreparationRejection>(context,std::move(nodal_equation)); } template<typenameScope=void,AffinePointEquationEquationT,discretization::domain::schema::IsSchemaSchemaT,typenameCoefficientsT> [[nodiscard]]automake_point_border_cache(EquationTequation,constPointBorderDiscretization<EquationT, SchemaT>&discretization,constCoefficientsT&term_coefficients) { usingnamespaceutils::dependencies; constautocontext=make_point_border_dependency_context<Scope>(discretization,term_coefficients); autonodal_equation=make_nodal_equation_computation<Scope>(std::move(equation),discretization.nodal); constautopoint_border=make_point_border_computation<Scope>(discretization); returnmake_computation_cache<PreparationRejection>(context,std::move(nodal_equation),point_border); } template<typenameScope=void,typenameCacheT,NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT,typenameCoefficientsT> [[nodiscard]]std::expected<void,PreparationRejection>try_prepare_nodal(CacheT&cache,constNodalDiscretization<EquationT, SchemaT>&discretization, constCoefficientsT&term_coefficients,constPreparationModemode=PreparationMode::reuse_unchanged) { returntry_prepare_validated(cache, [&]() { constautocontext=make_nodal_dependency_context<Scope>(discretization,term_coefficients); returncache.try_prepare(context,{},mode); }); } template<typenameScope=void,typenameCacheT,AffinePointEquationEquationT,discretization::domain::schema::IsSchemaSchemaT,typenameCoefficientsT> [[nodiscard]]std::expected<void,PreparationRejection>try_prepare_point_border(CacheT&cache,constPointBorderDiscretization<EquationT, SchemaT>&discretization, constCoefficientsT&term_coefficients, constPreparationModemode=PreparationMode::reuse_unchanged) { returntry_prepare_validated(cache, [&]() { constautocontext=make_point_border_dependency_context<Scope>(discretization,term_coefficients); returncache.try_prepare(context,{},mode); }); } template<typenameScope=void,typenameCacheT,typenameDiscretizationT,typenameCoefficientsT> voidprepare_nodal(CacheT&cache,constDiscretizationT&discretization,constCoefficientsT&term_coefficients,constPreparationModemode=PreparationMode::reuse_unchanged) { usingnamespaceutils::errors; constautoaccepted=try_prepare_nodal<Scope>(cache,discretization,term_coefficients,mode); if(!accepted) { serif_error<std::domain_error,SERiFErrorCode::INVALID_ARGUMENT>("{}preparationrejected:{}",DiscretizationT::Equation::name,accepted.error().message); } } template<typenameScope=void,typenameCacheT,typenameDiscretizationT,typenameCoefficientsT> voidprepare_point_border(CacheT&cache,constDiscretizationT&discretization,constCoefficientsT&term_coefficients, constPreparationModemode=PreparationMode::reuse_unchanged) { usingnamespaceutils::errors; constautoaccepted=try_prepare_point_border<Scope>(cache,discretization,term_coefficients,mode); if(!accepted) { serif_error<std::domain_error,SERiFErrorCode::INVALID_ARGUMENT>("{}preparationrejected:{}",DiscretizationT::Equation::name,accepted.error().message); } } template<typenameScope=void,typenameCacheT> [[nodiscard]]NumericalWorknodal_work_report(constCacheT&cache) { NumericalWorkwork; if(!cache.ready()) { returnwork; } if(cache.report().templatestatus<typenamenodal_keys::Scoped<Scope>::Linearization>()==utils::dependencies::PreparationStatus::computed) { constauto&nodal=cache.templateget<typenamenodal_keys::Scoped<Scope>::Linearization>(); work.physics_points=nodal.residual.Size()/nodal.derivative.Width(); } ifconstexpr(requires{cache.templateget<typenamenodal_keys::Scoped<Scope>::BorderLinearization>();}) { usingBorderData=std::remove_cvref_t<decltype(cache.templateget<typenamenodal_keys::Scoped<Scope>::BorderLinearization>())>; work.refreshed_scalars=cache.report().templatesource_changed<typenameBorderData::Border>(); } returnwork; } }//namespaceserif::operators::backend::mfem