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]);
518template<
typename OutputShape>
520 std::string_view unknown_name,
521 std::vector<Real> & error_vals)
530 libmesh_parallel_only(communicator);
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;
829 Real norm = sqrt(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];
939 communicator.max(l_infty_norm);
940 communicator.sum(error_vals);
941 error_vals[4] = l_infty_norm;
945template LIBMESH_EXPORT
void ExactSolution::_compute_error<Real>(std::string_view, std::string_view, std::vector<Real> &);
946template LIBMESH_EXPORT
void ExactSolution::_compute_error<RealGradient>(std::string_view, std::string_view, std::vector<Real> &);
Defines a dense vector for use in Finite Element-type computations.
This class handles the numbering of degrees of freedom on a mesh.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
const FEType & variable_type(const unsigned int i) const
This is the EquationSystems class.
unsigned int n_systems() const
const MeshBase & get_mesh() const
Parameters parameters
Data structure holding arbitrary parameters.
bool has_system(std::string_view name) const
virtual void clear()
Restores the data structure to a pristine state.
const T_sys & get_system(std::string_view name) const
This class handles the computation of the L2 and/or H1 error for the Systems in the EquationSystems o...
std::set< subdomain_id_type > _excluded_subdomains
Elements in a subdomain from this set are skipped during the error computation.
Real l2_error(std::string_view sys_name, std::string_view unknown_name)
Real h1_error(std::string_view sys_name, std::string_view unknown_name)
Real hcurl_error(std::string_view sys_name, std::string_view unknown_name)
Real h2_error(std::string_view sys_name, std::string_view unknown_name)
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...
Real error_norm(std::string_view sys_name, std::string_view unknown_name, const FEMNormType &norm)
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 attach_exact_values(const std::vector< FunctionBase< Number > * > &f)
Clone and attach arbitrary functors which compute the exact values of the EquationSystems' solutions ...
void attach_exact_hessians(std::vector< FunctionBase< Tensor > * > h)
Clone and attach arbitrary functors which compute the exact second derivatives of the EquationSystems...
std::map< std::string, SystemErrorMap, std::less<> > _errors
A map of SystemErrorMaps, which contains entries for each system in the EquationSystems object.
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...
std::vector< std::unique_ptr< FEMFunctionBase< Number > > > _exact_values
User-provided functors which compute the exact value of the solution for each system.
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...
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...
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...
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...
const EquationSystems & _equation_systems
Constant reference to the EquationSystems object used for the simulation.
std::vector< std::unique_ptr< FEMFunctionBase< Gradient > > > _exact_derivs
User-provided functors which compute the exact derivative of the solution for each system.
Real hdiv_error(std::string_view sys_name, std::string_view unknown_name)
Real l1_error(std::string_view sys_name, std::string_view unknown_name)
std::vector< std::unique_ptr< FEMFunctionBase< Tensor > > > _exact_hessians
User-provided functors which compute the exact hessians of the solution for each system.
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(...
Real l_inf_error(std::string_view sys_name, std::string_view unknown_name)
ExactSolution(const EquationSystems &es)
Constructor.
void attach_exact_derivs(const std::vector< FunctionBase< Gradient > * > &g)
Clone and attach arbitrary functors which compute the exact gradients of the EquationSystems' solutio...
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.
int _extra_order
Extra order to use for quadrature rule.
const EquationSystems * _equation_systems_fine
Constant pointer to the EquationSystems object containing the fine grid solution.
This class forms the foundation from which generic finite elements may be derived.
virtual_for_inffe const std::vector< Real > & get_JxW() const
virtual_for_inffe const std::vector< Point > & get_xyz() const
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.
This class forms the foundation from which generic finite elements may be derived.
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< std::vector< OutputDivergence > > & get_div_phi() const
const std::vector< std::vector< OutputShape > > & get_phi() const
const std::vector< std::vector< OutputGradient > > & get_dphi() const
TensorTools::MakeNumber< OutputShape >::type OutputNumber
const std::vector< std::vector< OutputTensor > > & get_d2phi() const
virtual_for_inffe const std::vector< std::vector< OutputShape > > & get_curl_phi() const
TensorTools::DecrementRank< OutputNumber >::type OutputNumberDivergence
static unsigned int n_vec_dim(const MeshBase &mesh, const FEType &fe_type)
static FEFieldType field_type(const FEType &fe_type)
This class provides all data required for a physics package (e.g.
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
virtual void elem_fe_reinit(const std::vector< Point > *const pts=nullptr)
Reinitializes interior FE objects on the current geometric element.
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.
FEMFunctionBase is a base class from which users can derive in order to define "function-like" object...
virtual std::unique_ptr< FEMFunctionBase< Output > > clone() const =0
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Base class for functors that can be evaluated at a point and (optionally) time.
This is the MeshBase class.
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
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...
const Parallel::Communicator & comm() const
The QBase class provides the basic functionality from which various quadrature rules can be derived.
unsigned int n_points() const
This class provides single index access to FieldType (i.e.
Manages consistently variables, degrees of freedom, and coefficient vectors.
const std::string & name() const
Number current_solution(const dof_id_type global_dof_number) const
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
const FEType & variable_type(const unsigned int i) const
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
const std::string & variable_name(const unsigned int i) const
unsigned int variable_number(std::string_view var) const
bool has_variable(std::string_view var) 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_vars() const
const DofMap & get_dof_map() const
unsigned int number() const
const MeshBase & get_mesh() const
bool active_on_subdomain(subdomain_id_type sid) const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
This class provides a wrapper with which to evaluate a (libMesh-style) function pointer in a Function...
Gradient exact_grad(const Point &, const Parameters &, const std::string &, const std::string &)
The libMesh namespace provides an interface to certain functionality in the library.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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...
Gradient gptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)