20#include "libmesh/libmesh_common.h"
21#include "libmesh/jump_error_estimator.h"
22#include "libmesh/dof_map.h"
23#include "libmesh/elem.h"
24#include "libmesh/error_vector.h"
25#include "libmesh/fe_base.h"
26#include "libmesh/fe_interface.h"
27#include "libmesh/fem_context.h"
28#include "libmesh/libmesh_logging.h"
29#include "libmesh/mesh_base.h"
30#include "libmesh/quadrature_gauss.h"
31#include "libmesh/system.h"
32#include "libmesh/dense_vector.h"
33#include "libmesh/numeric_vector.h"
34#include "libmesh/int_range.h"
59 bool estimate_parent_error)
61 LOG_SCOPE(
"estimate_error()",
"JumpErrorEstimator");
109#ifdef LIBMESH_ENABLE_AMR
116 error_per_cell.resize (
mesh.max_elem_id());
117 std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);
131 std::vector<float> n_flux_faces;
133 n_flux_faces.resize(error_per_cell.size(), 0);
137 if (solution_vector && solution_vector != system.
solution.get())
142 newsol->
swap(*sys.solution);
148 (system,
nullptr,
false);
150 (system,
nullptr,
false);
168 FEBase * side_fe =
nullptr;
170 const std::set<unsigned char> & elem_dims =
173 for (
const auto &
dim : elem_dims)
187 std::unique_ptr<PointLocatorBase> point_locator;
188 std::unique_ptr<const Elem> side_ptr;
191 point_locator =
mesh.sub_point_locator();
195 for (
const auto & e :
mesh.active_local_element_ptr_range())
199#ifdef LIBMESH_ENABLE_AMR
203 libmesh_warning(
"Warning: Jumps on the border of infinite elements are ignored."
214 bool compute_on_parent =
true;
215 if (!parent || !estimate_parent_error)
216 compute_on_parent =
false;
220 compute_on_parent =
false;
222 if (compute_on_parent &&
223 !error_per_cell[parent->
id()])
228 (*(system.
solution), dof_map, parent, Uparent,
false);
236 std::vector<const Elem *> active_neighbors;
238 active_family_tree_by_neighbor(active_neighbors,
241 for (std::size_t a=0,
242 n_active_neighbors = active_neighbors.size();
243 a != n_active_neighbors; ++a)
245 const Elem * f = active_neighbors[a];
256 libmesh_assert_equal_to
290 libmesh_assert_equal_to
302 bool found_boundary_flux =
false;
312 found_boundary_flux =
true;
327 for (
auto n_e : e->side_index_range())
329 if ((e->neighbor_ptr(n_e) !=
nullptr) ||
337 if (e->neighbor_ptr(n_e) !=
nullptr
338 && !e->neighbor_ptr(n_e) ->infinite())
345 if ((f->
active() && (f->
level() == e->level()) && (e_id < f_id))
346 || (f->
level() < e->level()))
383 side_ptr = e->build_side_ptr(n_e);
384 std::set<const Elem *> candidate_elements;
385 (*point_locator)(side_ptr->vertex_average(), candidate_elements);
394 if (candidate_elements.size() < 2)
405 side_fe->attach_quadrature_rule(side_qrule.get());
406 const std::vector<Point> & qface_point = side_fe->get_xyz();
407 side_fe->reinit(e, n_e);
409 for (
auto qp :
make_range(side_qrule->n_points()))
411 const Point p = qface_point[qp];
412 const std::vector<Point> qp_pointvec(1, p);
413 std::set<const Elem *> side_elements;
414 (*point_locator)(side_ptr->vertex_average(), side_elements);
424 const std::size_t n_neighbors = side_elements.size() - 1;
425 const Real neighbor_frac =
Real(1)/n_neighbors;
427 const std::vector<Real>
428 qp_weightvec(1, neighbor_frac * side_qrule->w(qp));
430 for (
const Elem * f : side_elements)
437 std::vector<Point> qp_coarse, qp_fine;
438 for (
unsigned int v=0; v<
n_vars; v++)
443 if (qp_coarse.empty())
445 coarse_fe->
reinit(f, &qp_coarse, &qp_weightvec);
449 fine_fe->
reinit(e, &qp_fine, &qp_weightvec);
479 libmesh_not_implemented();
481 bool found_boundary_flux =
false;
490 found_boundary_flux =
true;
513 if (error_per_cell[i] != 0.)
514 error_per_cell[i] = std::sqrt(error_per_cell[i]);
525 for (
const auto & val : n_flux_faces)
526 libmesh_assert_equal_to (val,
static_cast<float>(
static_cast<unsigned int>(val)));
532 if (n_flux_faces[i] == 0.0)
541 if (solution_vector && solution_vector != system.
solution.get())
546 newsol->
swap(*sys.solution);
561 FEBase * fe_fine =
nullptr;
565 std::vector<Point> qface_point = fe_fine->
get_xyz();
568 FEBase * fe_coarse =
nullptr;
571 std::vector<Point> qp_coarse;
581 for (
unsigned int v=0; v<
n_vars; v++)
598 const unsigned int divisor =
610 return 1.0f /
static_cast<float>(divisor);
Defines a dense vector for use in Finite Element-type computations.
virtual unsigned int size() const override final
This class handles the numbering of degrees of freedom on a mesh.
This is the base class from which all geometric element types are derived.
const Elem * parent() const
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
unsigned int level() const
const Elem * neighbor_ptr(unsigned int i) const
IntRange< unsigned short > side_index_range() const
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...
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
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.
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
This class forms the foundation from which generic finite elements may be derived.
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's children...
This class provides all data required for a physics package (e.g.
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
std::unique_ptr< QBase > unweighted_quadrature_rule(const unsigned int dim, const int extraorder=0) const
FEFamily family
The type of finite element.
float coarse_n_flux_faces_increment()
A utility function to correctly increase n_flux_faces for the coarse element.
unsigned int var
The variable number currently being evaluated.
bool integrate_slits
A boolean flag, by default false, to be set to true if integrations should be performed on "slits" wh...
bool use_unweighted_quadrature_rules
This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweigh...
Real fine_error
The fine and coarse error values to be set by each side_integration();.
virtual bool boundary_side_integration()
The function, to be implemented by derived classes, which calculates an error term on a boundary side...
virtual void internal_side_integration()=0
The function, to be implemented by derived classes, which calculates an error term on an internal sid...
bool scale_by_n_flux_faces
This boolean flag allows you to scale the error indicator result for each element by the number of "f...
bool integrate_boundary_sides
A boolean flag, by default false, to be set to true if integrations with boundary_side_integration() ...
void reinit_sides()
A utility function to reinit the finite element data on elements sharing a side.
virtual void init_context(FEMContext &c)
An initialization function, to give derived classes a chance to request specific data from the FE obj...
std::unique_ptr< FEMContext > coarse_context
std::unique_ptr< FEMContext > fine_context
Context objects for integrating on the fine and coarse elements sharing a face.
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 derived class's jump error estimate formula to estimate the error on each cell...
This is the MeshBase class.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
const Parallel::Communicator & comm() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
Real weight(unsigned int var) const
Manages consistently variables, degrees of freedom, and coefficient vectors.
int extra_quadrature_order
A member int that can be employed to indicate increased or reduced quadrature order.
const FEType & variable_type(const unsigned int i) const
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
unsigned int n_vars() const
const DofMap & get_dof_map() const
const MeshBase & get_mesh() const
The libMesh namespace provides an interface to certain functionality in the library.
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
void libmesh_ignore(const Args &...)
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...