nodal_evaluation.hpp cmath expected serif/operators/backend/mfem/nodal_data.hpp serif/operators/backend/mfem/rejection.hpp src/include/serif/operators/backend/mfem/nodal_computations.hpp serif serif::operators serif::operators::backend serif::operators::backend::mfem #pragmaonce #include<cmath> #include<expected> #include"serif/operators/backend/mfem/nodal_data.hpp" #include"serif/operators/backend/mfem/rejection.hpp" namespaceserif::operators::backend::mfem{ template<NodalValueEquationEquationT> [[nodiscard]]equations::EquationPoint<typenameEquationT::Operands>make_nodal_equation_point( const::mfem::Vector&values,constintfirst ){ usingValue=discretization::forms::OperandValue<equations::TestOperandOf<EquationT>>; equations::EquationPoint<typenameEquationT::Operands>point; for(intaxis=0;axis<discretization::forms::component_count<Value>;++axis){ discretization::forms::component(point.fields.templateget<typenameEquationT::Test>(),axis)=values[first+axis]; } returnpoint; } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]std::expected<void,PreparationRejection>store_nodal_linearization( constequations::PointLinearization<typenameEquationT::Operands, discretization::forms::OperandValue<equations::TestOperandOf<EquationT>>>&physics, constintfirst,NodalData<EquationT, SchemaT>&data ){ usingnamespaceutils::errors; usingValue=discretization::forms::OperandValue<equations::TestOperandOf<EquationT>>; constexprintcomponents=discretization::forms::component_count<Value>; for(intoutput=0;output<components;++output){ for(intaxis=0;axis<3;++axis){ serif_ensure<SERiFErrorCode::INVALID_ARGUMENT,std::logic_error>( (discretization::forms::derivative_component<Value, discretization::forms::VectorValue>(physics.position_derivative,output,axis)==0.0), "Anodalequationdeclaredposition-independentmusthavezeropositionderivative."); } data.residual[first+output]=discretization::forms::component(physics.residual,output); boolfinite=std::isfinite(data.residual[first+output]); for(intinput=0;input<components;++input){ constdoublepartial=discretization::forms::derivative_component<Value, Value>( physics.field_derivatives.templateget<typenameEquationT::Test>(),output,input); data.derivative(first+output,input)=partial; finite=finite&&std::isfinite(partial); } if(!finite){ returnstd::unexpected(PreparationRejection{ .reason=PreparationRejectionReason::NON_FINITE,.message="Non-finitenodalresidualorderivative."}); } } return{}; } template<NodalValueEquationEquationT,discretization::domain::schema::IsSchemaSchemaT> [[nodiscard]]std::expected<NodalData<EquationT,SchemaT>,PreparationRejection>evaluate_nodal_values( constEquationT&equation,constNodalDiscretization<EquationT, SchemaT>&discretization,const::mfem::Vector&values ){ usingValue=discretization::forms::OperandValue<equations::TestOperandOf<EquationT>>; constexprintcomponents=discretization::forms::component_count<Value>; NodalData<EquationT, SchemaT>data{ .discretization=discretization, .residual=::mfem::Vector(values.Size()), .derivative=::mfem::DenseMatrix(values.Size(),components) }; for(intfirst=0;first<values.Size();first+=components){ constautopoint=make_nodal_equation_point<EquationT>(values,first); equations::PointLinearization<typenameEquationT::Operands,Value>physics; try{ physics=equation.evaluate(point); }catch(conststd::domain_error&error){ returnstd::unexpected(PreparationRejection{.reason=PreparationRejectionReason::EQUATION,.message=error.what()}); } constautoaccepted=store_nodal_linearization<EquationT>(physics,first,data); if(!accepted){ returnstd::unexpected(accepted.error()); } } returndata; } }