field_values.hpp concepts serif/backend/mfem/discretization/term_coefficients.hpp serif/backend/mfem/operators/operand_evaluation.hpp src/lib/serif/backend/mfem/serialize/top.cpp serif::discretization::backend::mfem::FieldValues serif serif::discretization serif::discretization::backend serif::discretization::backend::mfem #pragmaonce #include<concepts> #include"serif/backend/mfem/discretization/term_coefficients.hpp" #include"serif/backend/mfem/operators/operand_evaluation.hpp" namespaceserif::discretization::backend::mfem{ template<blocks::SpatialTermTerm> classFieldValuesfinal{ public: usingValueOperand=forms::Operand<Term>; usingValue=forms::OperandValue<ValueOperand>; FieldValues(constDofMap&binding,const::mfem::Vector&coefficients): m_binding(binding),m_coefficients(coefficients),m_elements(binding.validated_elements()),m_rule(1){ usingnamespaceutils::errors; usingTraits=blocks::SpatialTermTraits<Term>; binding.validate_values(coefficients); constexprintcopies=Traits::rank==0?1:3; constexprintcontinuity=Traits::family==functional_space::Family::h1?::mfem::FiniteElementCollection::CONTINUOUS:::mfem::FiniteElementCollection::DISCONTINUOUS; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(Traits::rank<=1&& (Traits::family==functional_space::Family::h1||Traits::family==functional_space::Family::l2), "FieldValuessupportsscalar/vectorH1andL2fields."); serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(binding.space().GetVDim()==copies&& binding.space().FEColl()->GetContType()==continuity, "FieldValuestermfamilyorrankdisagreeswiththesuppliedbinding;passthematchingtypedcoefficientview."); for(intelement=0;element<binding.space().GetNE();++element){ constauto&finite_element=*binding.space().GetFE(element); serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(finite_element.GetOrder()==Traits::order&& finite_element.GetRangeType()==::mfem::FiniteElement::SCALAR&& finite_element.GetMapType()==::mfem::FiniteElement::VALUE, "FieldValuestermorderormappingdisagreeswiththesuppliedbinding;passthematchingtypedcoefficientview."); } } template<typenameBinding>requiresstd::same_as<typenameBinding::Term,Term> explicitFieldValues(constoperators::backend::mfem::CoefficientView<Binding>&field): FieldValues(field.binding,field.values){} FieldValues(constDofMap&,::mfem::Vector&&)=delete; FieldValues(constDofMap&,const::mfem::Vector&&)=delete; [[nodiscard]]Valuevalue(intelement,const::mfem::IntegrationPoint&point){ returnsample<forms::Operation::Value>(element,point); } voidvalues(intelement,const::mfem::IntegrationRule&points,::mfem::Vector&result){ usingEvaluator=operators::backend::mfem::OperandEvaluator<ValueOperand>; m_elements.element_values(element,m_coefficients,m_local); auto&transformation=*m_binding.mesh().GetElementTransformation(element); Evaluator::sample_basis(m_binding,element,points,m_basis,m_cache, ContractionMode::automatic,transformation,m_workspace); Evaluator::evaluate(m_basis,m_local,result,m_workspace); } [[nodiscard]]Valuevalue(intelement,const::mfem::IntegrationPoint&point,constmapping::MappingPointContext&context){ usingEvaluator=operators::backend::mfem::OperandEvaluator<ValueOperand>; returnEvaluator::physical_value(sample<forms::Operation::Value>(element,point),context); } [[nodiscard]]std::array<double,3>gradient(intelement,const::mfem::IntegrationPoint&point) requires(blocks::SpatialTermTraits<Term>::rank==0&&blocks::SpatialTermTraits<Term>::family==functional_space::Family::h1){ returnsample<forms::Operation::Gradient>(element,point); } [[nodiscard]]std::array<double,3>gradient(intelement,const::mfem::IntegrationPoint&point,constmapping::MappingPointContext&context) requires(blocks::SpatialTermTraits<Term>::rank==0&&blocks::SpatialTermTraits<Term>::family==functional_space::Family::h1){ usingOperand=forms::Operand<Term, forms::Operation::Gradient>; usingEvaluator=operators::backend::mfem::OperandEvaluator<Operand>; returnEvaluator::physical_value(sample<forms::Operation::Gradient>(element,point),context); } private: template<typenameOperation> [[nodiscard]]autosample(intelement,const::mfem::IntegrationPoint&point){ usingOperand=forms::Operand<Term, Operation>; usingEvaluator=operators::backend::mfem::OperandEvaluator<Operand>; m_elements.element_values(element,m_coefficients,m_local); m_rule.IntPoint(0)=point; auto&transformation=*m_binding.mesh().GetElementTransformation(element); //Arbitraryone-pointqueriesmustnotretainaseparatetensorplanforeveryquery. Evaluator::sample_basis(m_binding,element,m_rule,m_basis,m_cache, ContractionMode::dense,transformation,m_workspace); Evaluator::evaluate(m_basis,m_local,m_values,m_workspace); returnEvaluator::reference_value(m_values,0); } constDofMap&m_binding; const::mfem::Vector&m_coefficients; DofMap::Elementsm_elements; ::mfem::IntegrationRulem_rule; ::mfem::Vectorm_local,m_values; BasisEvaluationm_basis; TensorBasisCachem_cache; BasisWorkspacem_workspace; }; }