libMesh
exact_error_estimator.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // Local Includes
21 #include "libmesh/libmesh_common.h"
22 #include "libmesh/exact_error_estimator.h"
23 #include "libmesh/dof_map.h"
24 #include "libmesh/equation_systems.h"
25 #include "libmesh/error_vector.h"
26 #include "libmesh/fe_base.h"
27 #include "libmesh/libmesh_logging.h"
28 #include "libmesh/elem.h"
29 #include "libmesh/mesh_base.h"
30 #include "libmesh/mesh_function.h"
31 #include "libmesh/numeric_vector.h"
32 #include "libmesh/quadrature.h"
33 #include "libmesh/system.h"
34 #include "libmesh/tensor_tools.h"
35 #include "libmesh/enum_error_estimator_type.h"
36 #include "libmesh/enum_norm_type.h"
37 
38 // C++ includes
39 #include <algorithm> // for std::fill
40 #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC
41 #include <cmath> // for sqrt
42 #include <memory>
43 
44 namespace libMesh
45 {
46 
47 //-----------------------------------------------------------------
48 // ErrorEstimator implementations
51  _exact_value(nullptr),
52  _exact_deriv(nullptr),
53  _exact_hessian(nullptr),
54  _equation_systems_fine(nullptr),
55  _extra_order(1)
56 {
57  error_norm = H1;
58 }
59 
60 
62 {
63  return EXACT;
64 }
65 
66 
67 void ExactErrorEstimator::attach_exact_value (ValueFunctionPointer fptr)
68 {
71 
72  // We're not using a fine grid solution
73  _equation_systems_fine = nullptr;
74 
75  // We're not using user-provided functors
76  this->clear_functors();
77 }
78 
79 
81 {
82  // Automatically delete any previous _exact_values entries, then add a new
83  // entry for each system.
84  _exact_values.clear();
85 
86  for (auto ptr : f)
87  _exact_values.emplace_back(ptr ? ptr->clone() : nullptr);
88 }
89 
90 
91 void ExactErrorEstimator::attach_exact_value (unsigned int sys_num,
93 {
94  if (_exact_values.size() <= sys_num)
95  _exact_values.resize(sys_num+1);
96 
97  if (f)
98  _exact_values[sys_num] = f->clone();
99 }
100 
101 
102 void ExactErrorEstimator::attach_exact_deriv (GradientFunctionPointer gptr)
103 {
105  _exact_deriv = gptr;
106 
107  // We're not using a fine grid solution
108  _equation_systems_fine = nullptr;
109 
110  // We're not using user-provided functors
111  this->clear_functors();
112 }
113 
114 
116 {
117  // Automatically delete any previous _exact_derivs entries, then add a new
118  // entry for each system.
119  _exact_derivs.clear();
120 
121  for (auto ptr : g)
122  _exact_derivs.emplace_back(ptr ? ptr->clone() : nullptr);
123 }
124 
125 
126 void ExactErrorEstimator::attach_exact_deriv (unsigned int sys_num,
128 {
129  if (_exact_derivs.size() <= sys_num)
130  _exact_derivs.resize(sys_num+1);
131 
132  if (g)
133  _exact_derivs[sys_num] = g->clone();
134 }
135 
136 
137 
138 
139 void ExactErrorEstimator::attach_exact_hessian (HessianFunctionPointer hptr)
140 {
141  libmesh_assert(hptr);
142  _exact_hessian = hptr;
143 
144  // We're not using a fine grid solution
145  _equation_systems_fine = nullptr;
146 
147  // We're not using user-provided functors
148  this->clear_functors();
149 }
150 
151 
153 {
154  // Automatically delete any previous _exact_hessians entries, then add a new
155  // entry for each system.
156  _exact_hessians.clear();
157 
158  for (auto ptr : h)
159  _exact_hessians.emplace_back(ptr ? ptr->clone() : nullptr);
160 }
161 
162 
163 void ExactErrorEstimator::attach_exact_hessian (unsigned int sys_num,
165 {
166  if (_exact_hessians.size() <= sys_num)
167  _exact_hessians.resize(sys_num+1);
168 
169  if (h)
170  _exact_hessians[sys_num] = h->clone();
171 }
172 
173 
175 {
176  libmesh_assert(es_fine);
177  _equation_systems_fine = es_fine;
178 
179  // If we're using a fine grid solution, we're not using exact value
180  // function pointers or functors.
181  _exact_value = nullptr;
182  _exact_deriv = nullptr;
183  _exact_hessian = nullptr;
184 
185  this->clear_functors();
186 }
187 
189  ErrorVector & error_per_cell,
190  const NumericVector<Number> * solution_vector,
191  bool estimate_parent_error)
192 {
193  // Ignore the fact that this variable is unused when !LIBMESH_ENABLE_AMR
194  libmesh_ignore(estimate_parent_error);
195 
196  // The current mesh
197  const MeshBase & mesh = system.get_mesh();
198 
199  // The dimensionality of the mesh
200  const unsigned int dim = mesh.mesh_dimension();
201 
202  // The number of variables in the system
203  const unsigned int n_vars = system.n_vars();
204 
205  // The DofMap for this system
206  const DofMap & dof_map = system.get_dof_map();
207 
208  // Resize the error_per_cell vector to be
209  // the number of elements, initialize it to 0.
210  error_per_cell.resize (mesh.max_elem_id());
211  std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);
212 
213  // Prepare current_local_solution to localize a non-standard
214  // solution vector if necessary
215  if (solution_vector && solution_vector != system.solution.get())
216  {
217  NumericVector<Number> * newsol =
218  const_cast<NumericVector<Number> *>(solution_vector);
219  System & sys = const_cast<System &>(system);
220  newsol->swap(*sys.solution);
221  sys.update();
222  }
223 
224  // Loop over all the variables in the system
225  for (unsigned int var=0; var<n_vars; var++)
226  {
227  // Possibly skip this variable
228  if (error_norm.weight(var) == 0.0) continue;
229 
230  // The (string) name of this variable
231  const std::string & var_name = system.variable_name(var);
232 
233  // The type of finite element to use for this variable
234  const FEType & fe_type = dof_map.variable_type (var);
235 
236  std::unique_ptr<FEBase> fe (FEBase::build (dim, fe_type));
237 
238  // Build an appropriate Gaussian quadrature rule
239  std::unique_ptr<QBase> qrule =
240  fe_type.default_quadrature_rule (dim,
241  _extra_order);
242 
243  fe->attach_quadrature_rule (qrule.get());
244 
245  // Prepare a global solution and a MeshFunction of the fine system if we need one
246  std::unique_ptr<MeshFunction> fine_values;
247  std::unique_ptr<NumericVector<Number>> fine_soln = NumericVector<Number>::build(system.comm());
249  {
250  const System & fine_system = _equation_systems_fine->get_system(system.name());
251 
252  std::vector<Number> global_soln;
253  // FIXME - we're assuming that the fine system solution gets
254  // used even when a different vector is used for the coarse
255  // system
256  fine_system.update_global_solution(global_soln);
257  fine_soln->init
258  (cast_int<numeric_index_type>(global_soln.size()), true,
259  SERIAL);
260  (*fine_soln) = global_soln;
261 
262  fine_values = std::make_unique<MeshFunction>
264  *fine_soln,
265  fine_system.get_dof_map(),
266  fine_system.variable_number(var_name));
267  fine_values->init();
268  } else {
269  // Initialize functors if we're using them
270  for (auto & ev : _exact_values)
271  if (ev)
272  ev->init();
273 
274  for (auto & ed : _exact_derivs)
275  if (ed)
276  ed->init();
277 
278  for (auto & eh : _exact_hessians)
279  if (eh)
280  eh->init();
281  }
282 
283  // Request the data we'll need to compute with
284  fe->get_JxW();
285  fe->get_phi();
286  fe->get_dphi();
287 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
288  fe->get_d2phi();
289 #endif
290  fe->get_xyz();
291 
292 #ifdef LIBMESH_ENABLE_AMR
293  // If we compute on parent elements, we'll want to do so only
294  // once on each, so we need to keep track of which we've done.
295  std::vector<bool> computed_var_on_parent;
296 
297  if (estimate_parent_error)
298  computed_var_on_parent.resize(error_per_cell.size(), false);
299 #endif
300 
301  // TODO: this ought to be threaded (and using subordinate
302  // MeshFunction objects in each thread rather than a single
303  // master)
304 
305  // Iterate over all the active elements in the mesh
306  // that live on this processor.
307  for (const auto & elem : mesh.active_local_element_ptr_range())
308  {
309  const dof_id_type e_id = elem->id();
310 
311 #ifdef LIBMESH_ENABLE_AMR
312  // See if the parent of element e has been examined yet;
313  // if not, we may want to compute the estimator on it
314  const Elem * parent = elem->parent();
315 
316  // We only can compute and only need to compute on
317  // parents with all active children
318  bool compute_on_parent = true;
319  if (!parent || !estimate_parent_error)
320  compute_on_parent = false;
321  else
322  for (auto & child : parent->child_ref_range())
323  if (!child.active())
324  compute_on_parent = false;
325 
326  if (compute_on_parent &&
327  !computed_var_on_parent[parent->id()])
328  {
329  computed_var_on_parent[parent->id()] = true;
330 
331  // Compute a projection onto the parent
332  DenseVector<Number> Uparent;
334  dof_map, parent, Uparent,
335  var, false);
336 
337  error_per_cell[parent->id()] +=
338  static_cast<ErrorVectorReal>
339  (find_squared_element_error(system, var_name,
340  parent, Uparent,
341  fe.get(),
342  fine_values.get()));
343  }
344 #endif
345 
346  // Get the local to global degree of freedom maps
347  std::vector<dof_id_type> dof_indices;
348  dof_map.dof_indices (elem, dof_indices, var);
349  const unsigned int n_dofs =
350  cast_int<unsigned int>(dof_indices.size());
351  DenseVector<Number> Uelem(n_dofs);
352  for (unsigned int i=0; i != n_dofs; ++i)
353  Uelem(i) = system.current_solution(dof_indices[i]);
354 
355  error_per_cell[e_id] +=
356  static_cast<ErrorVectorReal>
357  (find_squared_element_error(system, var_name, elem,
358  Uelem, fe.get(),
359  fine_values.get()));
360 
361  } // End loop over active local elements
362  } // End loop over variables
363 
364 
365 
366  // Each processor has now computed the error contributions
367  // for its local elements. We need to sum the vector
368  // and then take the square-root of each component. Note
369  // that we only need to sum if we are running on multiple
370  // processors, and we only need to take the square-root
371  // if the value is nonzero. There will in general be many
372  // zeros for the inactive elements.
373 
374  // First sum the vector of estimated error values
375  this->reduce_error(error_per_cell, system.comm());
376 
377  // Compute the square-root of each component.
378  {
379  LOG_SCOPE("std::sqrt()", "ExactErrorEstimator");
380  for (auto & val : error_per_cell)
381  if (val != 0.)
382  {
383  libmesh_assert_greater (val, 0.);
384  val = std::sqrt(val);
385  }
386  }
387 
388  // If we used a non-standard solution before, now is the time to fix
389  // the current_local_solution
390  if (solution_vector && solution_vector != system.solution.get())
391  {
392  NumericVector<Number> * newsol =
393  const_cast<NumericVector<Number> *>(solution_vector);
394  System & sys = const_cast<System &>(system);
395  newsol->swap(*sys.solution);
396  sys.update();
397  }
398 }
399 
400 
401 
403  const std::string & var_name,
404  const Elem * elem,
405  const DenseVector<Number> & Uelem,
406  FEBase * fe,
407  MeshFunction * fine_values) const
408 {
409  // The (string) name of this system
410  const std::string & sys_name = system.name();
411  const unsigned int sys_num = system.number();
412 
413  const unsigned int var = system.variable_number(var_name);
414  const unsigned int var_component =
415  system.variable_scalar_number(var, 0);
416 
417  const Parameters & parameters = system.get_equation_systems().parameters;
418 
419  // reinitialize the element-specific data
420  // for the current element
421  fe->reinit (elem);
422 
423  // Get the data we need to compute with
424  const std::vector<Real> & JxW = fe->get_JxW();
425  const std::vector<std::vector<Real>> & phi_values = fe->get_phi();
426  const std::vector<std::vector<RealGradient>> & dphi_values = fe->get_dphi();
427  const std::vector<Point> & q_point = fe->get_xyz();
428 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
429  const std::vector<std::vector<RealTensor>> & d2phi_values = fe->get_d2phi();
430 #endif
431 
432  // The number of shape functions
433  const unsigned int n_sf =
434  cast_int<unsigned int>(Uelem.size());
435 
436  // The number of quadrature points
437  const unsigned int n_qp =
438  cast_int<unsigned int>(JxW.size());
439 
440  Real error_val = 0;
441 
442  // Begin the loop over the Quadrature points.
443  //
444  for (unsigned int qp=0; qp<n_qp; qp++)
445  {
446  // Real u_h = 0.;
447  // RealGradient grad_u_h;
448 
449  Number u_h = 0.;
450 
451  Gradient grad_u_h;
452 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
453  Tensor grad2_u_h;
454 #endif
455 
456  // Compute solution values at the current
457  // quadrature point. This requires a sum
458  // over all the shape functions evaluated
459  // at the quadrature point.
460  for (unsigned int i=0; i<n_sf; i++)
461  {
462  // Values from current solution.
463  u_h += phi_values[i][qp]*Uelem(i);
464  grad_u_h += dphi_values[i][qp]*Uelem(i);
465 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
466  grad2_u_h += d2phi_values[i][qp]*Uelem(i);
467 #endif
468  }
469 
470  // Compute the value of the error at this quadrature point
471  if (error_norm.type(var) == L2 ||
472  error_norm.type(var) == H1 ||
473  error_norm.type(var) == H2)
474  {
475  Number val_error = u_h;
476  if (_exact_value)
477  val_error -= _exact_value(q_point[qp],parameters,sys_name,var_name);
478  else if (_exact_values.size() > sys_num && _exact_values[sys_num])
479  val_error -= _exact_values[sys_num]->
480  component(var_component, q_point[qp], system.time);
481  else if (_equation_systems_fine)
482  val_error -= (*fine_values)(q_point[qp]);
483 
484  // Add the squares of the error to each contribution
485  error_val += JxW[qp]*TensorTools::norm_sq(val_error);
486  }
487 
488  // Compute the value of the error in the gradient at this
489  // quadrature point
490  if (error_norm.type(var) == H1 ||
491  error_norm.type(var) == H1_SEMINORM ||
492  error_norm.type(var) == H2)
493  {
494  Gradient grad_error = grad_u_h;
495  if (_exact_deriv)
496  grad_error -= _exact_deriv(q_point[qp],parameters,sys_name,var_name);
497  else if (_exact_derivs.size() > sys_num && _exact_derivs[sys_num])
498  grad_error -= _exact_derivs[sys_num]->
499  component(var_component, q_point[qp], system.time);
500  else if (_equation_systems_fine)
501  grad_error -= fine_values->gradient(q_point[qp]);
502 
503  error_val += JxW[qp]*grad_error.norm_sq();
504  }
505 
506 
507 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
508  // Compute the value of the error in the hessian at this
509  // quadrature point
510  if ((error_norm.type(var) == H2_SEMINORM ||
511  error_norm.type(var) == H2))
512  {
513  Tensor grad2_error = grad2_u_h;
514  if (_exact_hessian)
515  grad2_error -= _exact_hessian(q_point[qp],parameters,sys_name,var_name);
516  else if (_exact_hessians.size() > sys_num && _exact_hessians[sys_num])
517  grad2_error -= _exact_hessians[sys_num]->
518  component(var_component, q_point[qp], system.time);
519  else if (_equation_systems_fine)
520  grad2_error -= fine_values->hessian(q_point[qp]);
521 
522  error_val += JxW[qp]*grad2_error.norm_sq();
523  }
524 #endif
525 
526  } // end qp loop
527 
528  libmesh_assert_greater_equal (error_val, 0.);
529 
530  return error_val;
531 }
532 
533 
534 
536 {
537  _exact_values.clear();
538  _exact_derivs.clear();
539  _exact_hessians.clear();
540 }
541 
542 
543 
544 } // namespace libMesh
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition: system.h:1615
HessianFunctionPointer _exact_hessian
Function pointer to user-provided function which computes the exact hessian of the solution...
This is the EquationSystems class.
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...
const Elem * parent() const
Definition: elem.h:3030
unsigned int variable_scalar_number(std::string_view var, unsigned int component) const
Definition: system.h:2489
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.
Definition: system.C:745
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:67
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2164
std::vector< std::unique_ptr< FunctionBase< Tensor > > > _exact_hessians
User-provided functors which compute the exact hessians of the solution for each system.
int _extra_order
Extra order to use for quadrature rule.
unsigned int dim
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
ErrorEstimatorType
Defines an enum for the different types of error estimators which are available.
void attach_exact_hessians(std::vector< FunctionBase< Tensor > *> h)
Clone and attach arbitrary functors which compute the exact second derivatives of the EquationSystems...
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2220
const EquationSystems & get_equation_systems() const
Definition: system.h:721
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_tensor.h:1348
MeshBase & mesh
Gradient gradient(const Point &p, const Real time=0.)
const Parallel::Communicator & comm() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
ValueFunctionPointer _exact_value
Function pointer to user-provided function which computes the exact value of the solution.
const T_sys & get_system(std::string_view name) const
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 MeshBase & get_mesh() const
Definition: system.h:2358
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
std::vector< std::unique_ptr< FunctionBase< Gradient > > > _exact_derivs
User-provided functors which compute the exact derivative of the solution for each system...
This is the MeshBase class.
Definition: mesh_base.h:75
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2346
Number current_solution(const dof_id_type global_dof_number) const
Definition: system.C:165
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition: projection.C:80
unsigned int variable_number(std::string_view var) const
Definition: system.C:1609
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the exact solution function to estimate the error on each cell.
static void coarsened_dof_values(const NumericVector< Number > &global_vector, const DofMap &dof_map, const Elem *coarse_elem, DenseVector< Number > &coarse_dofs, const unsigned int var, const bool use_old_dof_indices=false)
Creates a local projection on coarse_elem, based on the DoF values in global_vector for it&#39;s children...
Definition: fe_base.C:1012
virtual ErrorEstimatorType type() const override
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:34
const std::vector< std::vector< OutputGradient > > & get_dphi() const
Definition: fe_base.h:230
void libmesh_ignore(const Args &...)
unsigned int number() const
Definition: system.h:2350
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_vector.h:926
dof_id_type id() const
Definition: dof_object.h:828
unsigned int n_vars
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
FEMNormType type(unsigned int var) const
Definition: system_norm.C:112
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1593
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
This class holds functions that will estimate the error in a finite element solution on a given mesh...
libmesh_assert(ctx)
virtual_for_inffe const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:303
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
Definition: system.h:2478
void reduce_error(std::vector< ErrorVectorReal > &error_per_cell, const Parallel::Communicator &comm) const
This method takes the local error contributions in error_per_cell from each processor and combines th...
virtual_for_inffe const std::vector< Point > & get_xyz() const
Definition: fe_abstract.h:280
const std::vector< std::vector< OutputTensor > > & get_d2phi() const
Definition: fe_base.h:319
void clear_functors()
Helper method for cleanup.
void attach_exact_derivs(std::vector< FunctionBase< Gradient > *> g)
Clone and attach arbitrary functors which compute the exact gradients of the EquationSystems&#39; solutio...
Real weight(unsigned int var) const
Definition: system_norm.C:134
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
GradientFunctionPointer _exact_deriv
Function pointer to user-provided function which computes the exact derivative of the solution...
EquationSystems * _equation_systems_fine
Constant pointer to the EquationSystems object containing a fine grid solution.
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
auto norm_sq(const T &a) -> decltype(std::norm(a))
Definition: tensor_tools.h:104
Gradient gptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition: projection.C:95
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...
Real find_squared_element_error(const System &system, const std::string &var_name, const Elem *elem, const DenseVector< Number > &Uelem, FEBase *fe, MeshFunction *fine_values) const
Helper method for calculating on each element.
Parameters parameters
Data structure holding arbitrary parameters.
virtual unsigned int size() const override final
Definition: dense_vector.h:104
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1605
virtual std::unique_ptr< FunctionBase< Output > > clone() const =0
void attach_exact_values(std::vector< FunctionBase< Number > *> f)
Clone and attach arbitrary functors which compute the exact values of the EquationSystems&#39; solutions ...
const std::string & name() const
Definition: system.h:2342
This class provides function-like objects for data distributed over a mesh.
Definition: mesh_function.h:54
void attach_reference_solution(EquationSystems *es_fine)
Attach function similar to system.h which allows the user to attach a second EquationSystems object w...
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...
unsigned int n_vars() const
Definition: system.h:2430
const DofMap & get_dof_map() const
Definition: system.h:2374
Tensor hessian(const Point &p, const Real time=0.)
std::vector< std::unique_ptr< FunctionBase< Number > > > _exact_values
User-provided functors which compute the exact value of the solution for each system.
This class forms the foundation from which generic finite elements may be derived.
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
uint8_t dof_id_type
Definition: id_types.h:67
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:207