nodal_rows.hpp array cmath serif/operators/backend/mfem/nodal_data.hpp src/include/serif/operators/backend/mfem/point_border.hpp serif serif::operators serif::operators::backend serif::operators::backend::mfem #pragmaonce #include<array> #include<cmath> #include"serif/operators/backend/mfem/nodal_data.hpp" namespaceserif::operators::backend::mfem{ template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> voidvalidate_nodal_output(constNodalData<EquationT, SchemaT>&data,const::mfem::Vector&result){ usingnamespaceutils::errors; data.discretization.selected_rows->validate(); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::invalid_argument>( result.Size()==data.discretization.residual_binding.size(),"Nodaloutputmustmatchitsresidualbinding."); } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> voidapply_residual_rows(constNodalData<EquationT, SchemaT>&data,::mfem::Vector&result){ validate_nodal_output(data,result); constauto&rows=*data.discretization.selected_rows; for(intindex=0;index<rows.size();++index){ result[rows.reduced_dofs()[index]]=data.residual[index]; } } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> voidapply_jacobian_rows( constNodalData<EquationT, SchemaT>&data, const::mfem::Vector&direction, ::mfem::Vector&result ){ usingnamespaceutils::errors; constexprintcomponents=NodalDiscretization<EquationT, SchemaT>::components; validate_nodal_output(data,result); data.discretization.residual_binding.validate_values(direction); constauto&rows=*data.discretization.selected_rows; for(intfirst=0;first<rows.size();first+=components){ std::array<double,components>input_values; for(intinput=0;input<components;++input){ input_values[input]=direction[rows.reduced_dofs()[first+input]]; } for(intoutput=0;output<components;++output){ doublevalue=0.0; for(intinput=0;input<components;++input){ value+=data.derivative(first+output,input)*input_values[input]; } serif_ensure<SERiFErrorCode::NON_FINITE_VALUE_ERROR,std::domain_error>( std::isfinite(value),"Non-finitenodalJacobianaction."); result[rows.reduced_dofs()[first+output]]=value; } } } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT,typenameCoefficientsT> requiresrequires(constCoefficientsT&direction){direction.templateget<typenameEquationT::Test>();} voidapply_jacobian_rows( constNodalData<EquationT, SchemaT>&data, constCoefficientsT&direction, ::mfem::Vector&result ){ usingnamespaceutils::errors; constauto&input=direction.templateget<typenameEquationT::Test>(); serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::invalid_argument>( &input.binding==&data.discretization.residual_binding,"Nodaldirectionmustusetheequation'sresidualbinding."); apply_jacobian_rows(data,input.values,result); } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> voidmask_residual_dual( constNodalData<EquationT, SchemaT>&data, const::mfem::Vector&dual, ::mfem::Vector&volume_dual ){ validate_nodal_output(data,dual); data.discretization.residual_binding.validate_values(dual); volume_dual=dual; for(constintrow:data.discretization.selected_rows->reduced_dofs()){ volume_dual[row]=0.0; } } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> voidadd_jacobian_transpose_rows( constNodalData<EquationT, SchemaT>&data, const::mfem::Vector&dual, ::mfem::Vector&result ){ constexprintcomponents=NodalDiscretization<EquationT, SchemaT>::components; validate_nodal_output(data,result); data.discretization.residual_binding.validate_values(dual); constauto&rows=*data.discretization.selected_rows; for(intfirst=0;first<rows.size();first+=components){ std::array<double,components>dual_values; for(intoutput=0;output<components;++output){ dual_values[output]=dual[rows.reduced_dofs()[first+output]]; } for(intinput=0;input<components;++input){ for(intoutput=0;output<components;++output){ result[rows.reduced_dofs()[first+input]]+=data.derivative(first+output,input)*dual_values[output]; } } } data.discretization.residual_binding.validate_values(result); } }