basis_evaluation.hpp memory mfem/fem/fe/fe_base.hpp mfem/fem/intrules.hpp serif/backend/mfem/discretization/tensor_basis.hpp src/include/serif/backend/mfem/operators/element_data.hpp src/include/serif/backend/mfem/operators/operand_evaluation.hpp src/include/serif/backend/mfem/operators/workspace.hpp src/lib/serif/backend/mfem/discretization/basis_evaluation.cpp serif::discretization::backend::mfem::BasisWorkspace serif::discretization::backend::mfem::BasisEvaluation serif serif::discretization serif::discretization::backend serif::discretization::backend::mfem Basis evaluation, pointwise mapping, and transpose application using dense or tensor-product representations. Emily M. Boudreaux #pragmaonce #include<memory> #include"mfem/fem/fe/fe_base.hpp" #include"mfem/fem/intrules.hpp" #include"serif/backend/mfem/discretization/tensor_basis.hpp" namespaceserif::discretization::backend::mfem{ structBasisWorkspace{ TensorWorkspacetensor; ::mfem::Vectorreference_values; ::mfem::Vectormapping_input; ::mfem::Vectormapping_output; }; classBasisEvaluationfinal{ public: voidsample( const::mfem::FiniteElement&element, const::mfem::IntegrationRule&rule, ReferenceOperationoperation, intcopies, TensorBasisCache&cache, ContractionModemode, constElementReconstruction*reconstruction=nullptr ); voidset_constant( intpoints ); voidreset_from( constBasisEvaluation&reference, intcomponents ); template<typenameMapT> voidmap_point( intpoint, constBasisEvaluation&reference, MapT&&map, BasisWorkspace&workspace ); voidevaluate( const::mfem::Vector&coefficients, ::mfem::Vector&values, BasisWorkspace&workspace )const; voidevaluate_many( const::mfem::Vector&coefficients, ::mfem::Vector&values, intlanes, BasisWorkspace&workspace )const; voidintegrate( const::mfem::Vector&values, ::mfem::Vector&coefficients, BasisWorkspace&workspace )const; [[nodiscard]]intheight()constnoexcept; [[nodiscard]]intwidth()constnoexcept; [[nodiscard]]booluses_tensor()constnoexcept; private: intm_points{0}; intm_components{0}; intm_width{0}; boolm_identity_mapping{false}; std::shared_ptr<constTensorBasis>m_tensor; ::mfem::DenseMatrixm_dense; ::mfem::DenseMatrixm_mapping; }; }//namespaceserif::discretization::backend::mfem template<typenameMapT> voidserif::discretization::backend::mfem::BasisEvaluation::map_point(constintpoint,constBasisEvaluation&reference,MapT&&map,BasisWorkspace&workspace){ constboolcanonical_reference=reference.m_identity_mapping; if(m_identity_mapping){ //Directlymappingacanonicaldestinationmustpreservetheuntouchedpoints. m_mapping.SetSize(m_points*m_components,m_components); m_mapping=0.0; for(intq=0;q<m_points;++q){ for(intcomponent=0;component<m_components;++component){ m_mapping(q*m_components+component,component)=1.0; } } } m_identity_mapping=false; const::mfem::DenseMatrix&source=reference.m_tensor?reference.m_mapping:reference.m_dense; ::mfem::DenseMatrix&destination=m_tensor?m_mapping:m_dense; constintcolumns=canonical_reference?reference.m_components:source.Width(); ::mfem::Vector&input=workspace.mapping_input; ::mfem::Vector&output=workspace.mapping_output; input.SetSize(reference.m_components); output.SetSize(m_components); for(intcolumn=0;column<columns;++column){ for(intaxis=0;axis<reference.m_components;++axis){ input[axis]=canonical_reference?static_cast<double>(axis==column):source(point*reference.m_components+axis,column); } map(input,output); for(intaxis=0;axis<m_components;++axis){ destination(point*m_components+axis,column)=output[axis]; } } }