19 #include "libmesh/dof_map.h" 20 #include "libmesh/elem.h" 21 #include "libmesh/exact_solution.h" 22 #include "libmesh/equation_systems.h" 23 #include "libmesh/fe_base.h" 24 #include "libmesh/function_base.h" 25 #include "libmesh/mesh_base.h" 26 #include "libmesh/mesh_function.h" 27 #include "libmesh/mesh_serializer.h" 28 #include "libmesh/numeric_vector.h" 29 #include "libmesh/parallel.h" 30 #include "libmesh/quadrature.h" 31 #include "libmesh/wrapped_function.h" 32 #include "libmesh/wrapped_functor.h" 33 #include "libmesh/fe_interface.h" 34 #include "libmesh/raw_accessor.h" 35 #include "libmesh/tensor_tools.h" 36 #include "libmesh/enum_norm_type.h" 37 #include "libmesh/utility.h" 47 _equation_systems(es),
48 _equation_systems_fine(nullptr),
59 const std::string & sys_name = system.
name();
68 sem[var_name] = std::vector<Real>(5, 0.);
146 _exact_values[sys_num] = std::make_unique<WrappedFunctor<Number>>(*f);
209 _exact_derivs[sys_num] = std::make_unique<WrappedFunctor<Gradient>>(*g);
272 _exact_hessians[sys_num] = std::make_unique<WrappedFunctor<Tensor>>(*h);
288 std::string_view unknown_name)
292 auto & system_error_map = libmesh_map_find(
_errors, sys_name);
293 return libmesh_map_find(system_error_map, unknown_name);
299 std::string_view unknown_name)
303 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
314 this->_compute_error<Real>(sys_name,
321 this->_compute_error<RealGradient>(sys_name,
327 libmesh_error_msg(
"Invalid variable type!");
336 std::string_view unknown_name,
341 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
351 return std::sqrt(error_vals[0]);
353 return std::sqrt(error_vals[0] + error_vals[1]);
355 return std::sqrt(error_vals[0] + error_vals[1] + error_vals[2]);
359 "Cannot compute HCurl error norm of scalar-valued variables!");
361 return std::sqrt(error_vals[0] + error_vals[5]);
366 "Cannot compute HDiv error norm of scalar-valued variables!");
368 return std::sqrt(error_vals[0] + error_vals[6]);
371 return std::sqrt(error_vals[1]);
373 return std::sqrt(error_vals[2]);
377 "Cannot compute HCurl error seminorm of scalar-valued variables!");
379 return std::sqrt(error_vals[5]);
384 "Cannot compute HDiv error seminorm of scalar-valued variables!");
386 return std::sqrt(error_vals[6]);
389 return error_vals[3];
391 return error_vals[4];
394 libmesh_error_msg(
"Currently only Sobolev norms/seminorms are supported!");
405 std::string_view unknown_name)
410 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
415 return std::sqrt(error_vals[0]);
425 std::string_view unknown_name)
430 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
435 return error_vals[3];
445 std::string_view unknown_name)
450 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
455 return error_vals[4];
465 std::string_view unknown_name)
473 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
477 return std::sqrt(error_vals[0] + error_vals[1]);
482 std::string_view unknown_name)
489 std::string_view unknown_name)
497 std::string_view unknown_name)
505 std::vector<Real> & error_vals = this->
_check_inputs(sys_name,
509 return std::sqrt(error_vals[0] + error_vals[1] + error_vals[2]);
518 template<
typename OutputShape>
520 std::string_view unknown_name,
521 std::vector<Real> & error_vals)
545 const unsigned int sys_num = computed_system.
number();
546 const unsigned int var = computed_system.
variable_number(unknown_name);
547 unsigned int var_component = 0;
550 const auto & var_fe_type = computed_system.
variable_type(var_num);
552 var_component += var_vec_dim;
557 std::unique_ptr<MeshFunction> coarse_values;
558 std::unique_ptr<NumericVector<Number>> comparison_soln =
565 const System & comparison_system
568 std::vector<Number> global_soln;
570 comparison_soln->init(comparison_system.
solution->size(),
true,
SERIAL);
571 (*comparison_soln) = global_soln;
573 coarse_values = std::make_unique<MeshFunction>
578 coarse_values->init();
582 const std::set<unsigned char> & elem_dims =
mesh.elem_dimensions();
589 ev->init_context(context);
596 ed->init_context(context);
603 eh->init_context(context);
614 for (
auto dim : elem_dims)
633 error_vals = std::vector<Real>(7, 0.);
645 libMesh::err <<
"Error calculation using reference solution not yet\n" 646 <<
"supported for vector-valued elements." 648 libmesh_not_implemented();
653 std::vector<std::unique_ptr<FEGenericBase<OutputShape>>> fe_ptrs(4);
654 std::vector<std::unique_ptr<QBase>> q_rules(4);
657 for (
const auto dim : elem_dims)
665 q_rules[
dim]->allow_rules_with_negative_weights =
false;
671 fe_ptrs[
dim]->attach_quadrature_rule (q_rules[
dim].
get());
676 std::vector<dof_id_type> dof_indices;
685 for (
const auto & elem :
mesh.active_local_element_ptr_range())
694 const unsigned int dim = elem->dim();
704 std::set<subdomain_id_type> subdomain_id;
705 subdomain_id.insert(elem_subid);
713 const std::vector<Real> & JxW = fe->
get_JxW();
717 const std::vector<std::vector<OutputShape>> & phi_values = fe->
get_phi();
720 const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputGradient>> &
725 const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputShape>> * curl_values =
nullptr;
729 const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputDivergence>> * div_values =
nullptr;
737 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 740 const std::vector<std::vector<typename FEGenericBase<OutputShape>::OutputTensor>> *
741 d2phi_values =
nullptr;
748 const std::vector<Point> & q_point = fe->
get_xyz();
758 computed_dof_map.
dof_indices (elem, dof_indices, var);
761 const unsigned int n_qp = qrule->
n_points();
764 const unsigned int n_sf =
765 cast_int<unsigned int>(dof_indices.size());
770 for (
unsigned int qp=0; qp<n_qp; qp++)
778 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 788 for (
unsigned int i=0; i<n_sf; i++)
792 grad_u_h += dphi_values[i][qp]*computed_system.
current_solution (dof_indices[i]);
795 curl_u_h += (*curl_values)[i][qp]*computed_system.
current_solution (dof_indices[i]);
796 div_u_h += (*div_values)[i][qp]*computed_system.
current_solution (dof_indices[i]);
800 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 801 grad2_u_h += (*d2phi_values)[i][qp]*computed_system.
current_solution (dof_indices[i]);
811 for (
unsigned int c = 0; c < n_vec_dim; c++)
812 exact_val_accessor(c) =
814 component(context, var_component+c, q_point[qp], time);
820 (*coarse_values)(q_point[qp],time,output,&subdomain_id);
821 exact_val = output(0);
827 error_vals[0] += JxW[qp]*error_sq;
830 error_vals[3] += JxW[qp]*
norm;
832 if (error_vals[4]<
norm) { error_vals[4] =
norm; }
840 for (
unsigned int c = 0; c < n_vec_dim; c++)
841 for (
unsigned int d = 0; d < LIBMESH_DIM; d++)
842 exact_grad_accessor(d + c*LIBMESH_DIM) =
844 component(context, var_component+c, q_point[qp], time)(d);
849 std::vector<Gradient> output(1);
850 coarse_values->gradient(q_point[qp],time,output,&subdomain_id);
856 error_vals[1] += JxW[qp]*grad_error.
norm_sq();
896 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 907 libmesh_not_implemented();
909 for (
unsigned int c = 0; c < n_vec_dim; c++)
910 for (
unsigned int d = 0; d <
dim; d++)
911 for (
unsigned int e =0; e <
dim; e++)
912 exact_hess_accessor(d + e*
dim + c*
dim*
dim) =
914 component(context, var_component+c, q_point[qp], time)(d,e);
918 error_vals[2] += JxW[qp]*grad2_error.
norm_sq();
923 std::vector<Tensor> output(1);
924 coarse_values->hessian(q_point[qp],time,output,&subdomain_id);
925 exact_hess = output[0];
929 error_vals[2] += JxW[qp]*grad2_error.
norm_sq();
938 Real l_infty_norm = error_vals[4];
941 error_vals[4] = l_infty_norm;
945 template LIBMESH_EXPORT
void ExactSolution::_compute_error<Real>(std::string_view, std::string_view, std::vector<Real> &);
946 template LIBMESH_EXPORT
void ExactSolution::_compute_error<RealGradient>(std::string_view, std::string_view, std::vector<Real> &);
std::map< std::string, std::vector< Real >, std::less<> > SystemErrorMap
Data structure which stores the errors: ||e|| = ||u - u_h|| ||grad(e)|| = ||grad(u) - grad(u_h)|| for...
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
This class handles the computation of the L2 and/or H1 error for the Systems in the EquationSystems o...
Real l_inf_error(std::string_view sys_name, std::string_view unknown_name)
This is the EquationSystems class.
virtual_for_inffe const std::vector< std::vector< OutputDivergence > > & get_div_phi() const
void update_global_solution(std::vector< Number > &global_soln) const
Fill the input vector global_soln so that it contains the global solution on all processors.
unsigned int n_systems() const
Real h2_error(std::string_view sys_name, std::string_view unknown_name)
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
TensorTools::DecrementRank< OutputNumber >::type OutputNumberDivergence
Real l1_error(std::string_view sys_name, std::string_view unknown_name)
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Real hdiv_error(std::string_view sys_name, std::string_view unknown_name)
const EquationSystems & _equation_systems
Constant reference to the EquationSystems object used for the simulation.
bool has_system(std::string_view name) const
std::map< std::string, SystemErrorMap, std::less<> > _errors
A map of SystemErrorMaps, which contains entries for each system in the EquationSystems object...
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
ExactSolution(const EquationSystems &es)
Constructor.
void attach_exact_values(const std::vector< FunctionBase< Number > *> &f)
Clone and attach arbitrary functors which compute the exact values of the EquationSystems' solutions ...
int _extra_order
Extra order to use for quadrature rule.
const FEType & variable_type(const unsigned int c) const
static FEFieldType field_type(const FEType &fe_type)
FEMNormType
defines an enum for norms defined on vectors of finite element coefficients
Real hcurl_error(std::string_view sys_name, std::string_view unknown_name)
const Parallel::Communicator & comm() const
std::vector< Real > & _check_inputs(std::string_view sys_name, std::string_view unknown_name)
This function is responsible for checking the validity of the sys_name and unknown_name inputs...
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
std::vector< std::unique_ptr< FEMFunctionBase< Number > > > _exact_values
User-provided functors which compute the exact value of the solution for each system.
The libMesh namespace provides an interface to certain functionality in the library.
void attach_exact_derivs(const std::vector< FunctionBase< Gradient > *> &g)
Clone and attach arbitrary functors which compute the exact gradients of the EquationSystems' solutio...
const T_sys & get_system(std::string_view name) const
const MeshBase & get_mesh() const
const EquationSystems * _equation_systems_fine
Constant pointer to the EquationSystems object containing the fine grid solution. ...
std::vector< std::unique_ptr< FEMFunctionBase< Gradient > > > _exact_derivs
User-provided functors which compute the exact derivative of the solution for each system...
This is the MeshBase class.
Gradient exact_grad(const Point &, const Parameters &, const std::string &, const std::string &)
virtual void elem_fe_reinit(const std::vector< Point > *const pts=nullptr)
Reinitializes interior FE objects on the current geometric element.
Number current_solution(const dof_id_type global_dof_number) const
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
unsigned int variable_number(std::string_view var) const
This class provides a wrapper with which to evaluate a (libMesh-style) function pointer in a Function...
This class handles the numbering of degrees of freedom on a mesh.
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
const std::vector< std::vector< OutputGradient > > & get_dphi() const
std::set< subdomain_id_type > _excluded_subdomains
Elements in a subdomain from this set are skipped during the error computation.
unsigned int number() const
auto norm_sq() const -> decltype(std::norm(T()))
void attach_exact_hessians(std::vector< FunctionBase< Tensor > *> h)
Clone and attach arbitrary functors which compute the exact second derivatives of the EquationSystems...
Manages consistently variables, degrees of freedom, and coefficient vectors.
void compute_error(std::string_view sys_name, std::string_view unknown_name)
Computes and stores the error in the solution value e = u-u_h, the gradient grad(e) = grad(u) - grad(...
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
virtual_for_inffe const std::vector< Real > & get_JxW() const
This class provides all data required for a physics package (e.g.
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)=0
This is at the core of this class.
const std::string & variable_name(const unsigned int i) const
unsigned int n_points() const
virtual_for_inffe const std::vector< Point > & get_xyz() const
const std::vector< std::vector< OutputTensor > > & get_d2phi() const
bool active_on_subdomain(subdomain_id_type sid) const
Real l2_error(std::string_view sys_name, std::string_view unknown_name)
TensorTools::MakeNumber< OutputShape >::type OutputNumber
void attach_exact_hessian(unsigned int sys_num, FunctionBase< Tensor > *h)
Clone and attach an arbitrary functor which computes the exact second derivatives of the system sys_n...
static unsigned int n_vec_dim(const MeshBase &mesh, const FEType &fe_type)
void attach_exact_deriv(unsigned int sys_num, FunctionBase< Gradient > *g)
Clone and attach an arbitrary functor which computes the exact gradient of the system sys_num solutio...
void _compute_error(std::string_view sys_name, std::string_view unknown_name, std::vector< Real > &error_vals)
This function computes the error (in the solution and its first derivative) for a single unknown in a...
const FEType & variable_type(const unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
void set_excluded_subdomains(const std::set< subdomain_id_type > &excluded)
The user can indicate that elements in certain subdomains should be excluded from the error calculati...
const MeshBase & get_mesh() const
Gradient gptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Parameters parameters
Data structure holding arbitrary parameters.
void get_element_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for interior finite element object for variable var for the largest dimension in the mesh...
void attach_exact_value(unsigned int sys_num, FunctionBase< Number > *f)
Clone and attach an arbitrary functor which computes the exact value of the system sys_num solution a...
const std::string & name() const
void attach_reference_solution(const EquationSystems *es_fine)
Attach function similar to system.h which allows the user to attach a second EquationSystems object w...
unsigned int n_vars() const
This class forms the foundation from which generic finite elements may be derived.
Real h1_error(std::string_view sys_name, std::string_view unknown_name)
virtual std::unique_ptr< FEMFunctionBase< Output > > clone() const =0
const DofMap & get_dof_map() const
std::vector< std::unique_ptr< FEMFunctionBase< Tensor > > > _exact_hessians
User-provided functors which compute the exact hessians of the solution for each system.
The QBase class provides the basic functionality from which various quadrature rules can be derived...
This class forms the foundation from which generic finite elements may be derived.
This class provides single index access to FieldType (i.e.
virtual_for_inffe const std::vector< std::vector< OutputShape > > & get_curl_phi() const
const std::vector< std::vector< OutputShape > > & get_phi() const
Real error_norm(std::string_view sys_name, std::string_view unknown_name, const FEMNormType &norm)