element_coordinates.cpp serif/backend/mfem/discretization/element_coordinates.hpp serif serif::discretization serif::discretization::backend serif::discretization::backend::mfem #include"serif/backend/mfem/discretization/element_coordinates.hpp" namespaceserif::discretization::backend::mfem{ ElementCoordinates::ElementCoordinates(constDofMap::Elements&elements,constintelement):m_binding(elements.m_binding){ usingnamespaceutils::errors; m_binding.validate_structure(); m_supported=m_binding.supports(element); serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR>(m_binding.mesh().GetAttribute(element)==m_binding.m_attributes[element],"Termbindingdomainattributeschangedunexpectedly."); if(m_binding.m_space==nullptr){ m_dofs.Append(0); }else{ m_binding.m_space->GetElementVDofs(element,m_dofs,m_transformation); } } intElementCoordinates::reduced_dof(constintlocal)const{ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::out_of_range>(local>=0&&local<size(),"Elementcoordinateindexisoutofrange."); if(m_binding.m_space==nullptr&&!m_supported){ return-1; } constintencoded=m_dofs[local]; returnm_binding.m_full_to_reduced[encoded<0?-1-encoded:encoded]; } intElementCoordinates::local_dof(constintreduced)const{ for(intlocal=0;local<size();++local){ if(reduced_dof(local)==reduced){ returnlocal; } } return-1; } voidElementCoordinates::orient_primal(::mfem::Vector&values)const{ if(m_transformation.GetDofTransformation()!=nullptr){ m_transformation.InvTransformPrimal(values); } } voidElementCoordinates::unit_direction(constintcolumn,::mfem::Vector&direction)const{ constintreduced=reduced_dof(column); direction.SetSize(size()); direction=0.0; if(reduced>=0||m_binding.constrained()){ direction[column]=m_dofs[column]<0?-1.0:1.0; } orient_primal(direction); } voidElementCoordinates::element_values(const::mfem::Vector&reduced,::mfem::Vector&values)const{ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::invalid_argument>(reduced.Size()==m_binding.size(),"Elementextractionrequiresasupportedcoefficientvector."); values.SetSize(size()); for(intlocal=0;local<size();++local){ if(m_binding.constrained()){ doublevalue=0.0; m_binding.for_each_coefficient(::mfem::FiniteElementSpace::DecodeDof(m_dofs[local]), [&](constintindex,constdoubleweight){value+=weight*reduced[index];}); values[local]=m_dofs[local]<0?-value:value; }else{ constintindex=reduced_dof(local); values[local]=index<0?0.0:(m_dofs[local]<0?-reduced[index]:reduced[index]); } } orient_primal(values); } voidElementCoordinates::orient_dual(::mfem::Vector&values)const{ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::invalid_argument>(values.Size()==size(),"Elementdualvectordoesnotmatchthelocalcoordinates."); if(m_transformation.GetDofTransformation()!=nullptr){ m_transformation.TransformDual(values); } for(intlocal=0;local<size();++local){ if(m_dofs[local]<0){ values[local]=-values[local]; } } } voidElementCoordinates::add_element(::mfem::Vector&values,::mfem::Vector&full)const{ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::invalid_argument>(full.Size()==m_binding.full_size(),"Elementassemblyvectordoesnotmatchthefullspace."); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::invalid_argument>(values.Size()==size(),"Elementassemblyvectordoesnotmatchthelocalcoordinates."); if(m_transformation.GetDofTransformation()!=nullptr){ m_transformation.TransformDual(values); } if(m_binding.m_space==nullptr&&!m_supported){ return; } full.AddElementVector(m_dofs,values); } ElementCoordinatesDofMap::Elements::coordinates(constintelement)const{ returnElementCoordinates(*this,element); } voidDofMap::Elements::element_values(constintelement,const::mfem::Vector&reduced,::mfem::Vector&values)const{ coordinates(element).element_values(reduced,values); } voidDofMap::Elements::add_element(constintelement,::mfem::Vector&values,::mfem::Vector&full)const{ coordinates(element).add_element(values,full); } voidDofMap::element_values(constintelement,const::mfem::Vector&reduced,::mfem::Vector&values)const{ validated_elements().element_values(element,reduced,values); } voidDofMap::add_element(constintelement,::mfem::Vector&values,::mfem::Vector&full)const{ validated_elements().add_element(element,values,full); } }//namespaceserif::discretization::backend::mfem