volume_inputs.hpp serif/backend/mfem/operators/volume_data.hpp serif/backend/mfem/discretization/coefficient_tracking.hpp src/include/serif/backend/mfem/model/inputs.hpp src/include/serif/backend/mfem/model/volume_displacement.hpp src/include/serif/backend/mfem/operators/volume_application.hpp src/include/serif/backend/mfem/operators/volume_computations.hpp serif::operators::backend::mfem::MetadataTracking serif::operators::backend::mfem::DisplacementCoefficients serif::operators::backend::mfem::CompactificationCoefficients serif::operators::backend::mfem::CoefficientTracking serif serif::operators serif::operators::backend serif::operators::backend::mfem #pragmaonce #include"serif/backend/mfem/operators/volume_data.hpp" #include"serif/backend/mfem/discretization/coefficient_tracking.hpp" namespaceserif::operators::backend::mfem { usingdiscretization::backend::mfem::CoefficientTracking; structMetadataTracking{ template<std::size_tColumnCount> [[nodiscard]]BasisBindings<ColumnCount>capture(constBasisBindings<ColumnCount>&input)const{ usingnamespaceutils::errors; input.residual_binding->validate(); input.displacement_binding->validate(); for(constauto*column:input.columns){ column->validate(); } serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR>( input.residual_binding->mesh().GetNodesSequence()==input.nodes_sequence, "Thevolumeinputcontextdescribesanearliermeshrevision;rebuildtheinputsbeforepreparingthegraph."); returninput; } template<std::size_tColumnCount> [[nodiscard]]boolmatches(constBasisBindings<ColumnCount>&captured,constBasisBindings<ColumnCount>&input)const{ returncaptured==capture(input); } template<typenameT> [[nodiscard]]constvoid*identity(constT&)const{ returnnullptr; } }; usingMeshAndCoefficientBindings=volume_keys::Scoped<void>::Bindings; structDisplacementCoefficients { }; structCompactificationCoefficients { }; template<typenameTestT,typenameSchemaT> voidvalidate_volume_discretization(constVolumeDiscretization<TestT, SchemaT>&discretization) { usingnamespaceutils::errors; discretization.residual_binding.validate(); discretization.displacement_binding.validate(); constauto*space=discretization.compactification_space; serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR>(space!=nullptr&&discretization.compactification.FESpace()==space&& space->GetSequence()==discretization.compactification_sequence&& discretization.compactification.Size()==space->GetVSize(), "Compactificationbindingchangedunexpectedly."); serif_ensure<SERiFErrorCode::MISMATCHED_MESHING_MAPS,std::invalid_argument>( space->GetMesh()==&discretization.residual_binding.mesh()&&discretization.displacement_binding.space().GetMesh()==&discretization.residual_binding.mesh(), "Termbindingsmustshareamesh."); serif_ensure<SERiFErrorCode::INVALID_DIMENSION,std::invalid_argument>(discretization.mapper.get_dimension()==3&&discretization.compactification.VectorDim()==1, "Equationmappingrequiresathree-dimensionalmapperandscalarcompactification."); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT,typename...Columns> [[nodiscard]]automake_volume_binding_input(constVolumeDiscretization<typenameEquationT::Test,SchemaT>&discretization,constCoefficientsT&term_coefficients, utils::types::TypeList<Columns...>) { usingnamespaceutils::dependencies; usingnamespaceutils::errors; validate_volume_discretization(discretization); constautovalidate_term=[&]<typenameOperandT>(OperandT) { constauto&input=term_coefficients.templateget<typenameOperandT::term_type>(); static_assert(std::same_as<typenamestd::remove_cvref_t<decltype(input.binding)>::Schema,SchemaT>,"Termbindingsmustusethesamedomainschema."); input.binding.validate_values(input.values); serif_ensure<SERiFErrorCode::MISMATCHED_MESHING_MAPS,std::invalid_argument>(&input.binding.mesh()==&discretization.residual_binding.mesh(), "Operatorinputsmustsharetheresidualmesh."); }; (validate_term(Columns{}),...); constBasisBindings<sizeof...(Columns)>bindings{.residual_binding=&discretization.residual_binding, .displacement_binding=&discretization.displacement_binding, .compactification_space=discretization.compactification_space, .mapper=&discretization.mapper, .nodes_sequence=discretization.residual_binding.mesh().GetNodesSequence(), .columns={&term_coefficients.templateget<typenameColumns::term_type>().binding...}}; returnown<typenamevolume_keys::Scoped<Scope>::Bindings>(bindings,MetadataTracking{}); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT> [[nodiscard]]automake_volume_binding_input(constVolumeDiscretization<typename EquationT::Test, SchemaT>&discretization,constCoefficientsT&term_coefficients) { returnmake_volume_binding_input<EquationT, Scope>(discretization,term_coefficients,typenameEquationPlan<EquationT>::Columns{}); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT,typename...Columns> [[nodiscard]]automake_volume_inputs(constVolumeDiscretization<typename EquationT::Test, SchemaT>&discretization,constCoefficientsT&term_coefficients,utils::types::TypeList<Columns...>columns) { usingnamespaceutils::dependencies; constautobindings=make_volume_binding_input<EquationT, Scope>(discretization,term_coefficients,columns); returnmake_dependency_context( bindings, own<CompactificationCoefficients>(MappingCoefficients{.binding=*discretization.compactification_space,.values=discretization.compactification}, CoefficientTracking{}), own<typenameColumns::term_type>(term_coefficients.templateget<typenameColumns::term_type>(),CoefficientTracking{})...); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT> [[nodiscard]]automake_volume_inputs(constVolumeDiscretization<typename EquationT::Test, SchemaT>&discretization,constCoefficientsT&term_coefficients) { returnmake_volume_inputs<EquationT, Scope>(discretization,term_coefficients,typenameEquationPlan<EquationT>::Columns{}); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT,typename...Columns> [[nodiscard]]automake_volume_inputs(constVolumeDiscretization<typename EquationT::Test, SchemaT>&discretization,constCoefficientsT&term_coefficients, const::mfem::Vector&displacement_coefficients,utils::types::TypeList<Columns...>columns) { usingnamespaceutils::dependencies; constautoinputs=make_volume_inputs<EquationT, Scope>(discretization,term_coefficients,columns); discretization.displacement_binding.validate_values(displacement_coefficients); returnmake_dependency_context(inputs.templateresource<typenamevolume_keys::Scoped<Scope>::Bindings>(), own<DisplacementCoefficients>(bind(discretization.displacement_binding,displacement_coefficients),CoefficientTracking{}), inputs.templateresource<CompactificationCoefficients>(),inputs.templateresource<typenameColumns::term_type>()...); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT> [[nodiscard]]automake_volume_inputs(constVolumeDiscretization<typename EquationT::Test, SchemaT>&discretization,constCoefficientsT&term_coefficients, const::mfem::Vector&displacement_coefficients) { returnmake_volume_inputs<EquationT, Scope>(discretization,term_coefficients,displacement_coefficients,typenameEquationPlan<EquationT>::Columns{}); } template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT> voidmake_volume_inputs(constVolumeDiscretization<typename EquationT::Test, SchemaT>&,constCoefficientsT&,::mfem::Vector&&)=delete; template<VolumeEquationEquationT,typenameScope=void,typenameSchemaT,typenameCoefficientsT> voidmake_volume_inputs(constVolumeDiscretization<typename EquationT::Test, SchemaT>&,constCoefficientsT&,const::mfem::Vector&&)=delete; }//namespaceserif::operators::backend::mfem