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 115 error_per_cell.resize (
mesh.max_elem_id());
116 std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);
130 std::vector<float> n_flux_faces;
132 n_flux_faces.resize(error_per_cell.size(), 0);
136 if (solution_vector && solution_vector != system.
solution.get())
141 newsol->
swap(*sys.solution);
147 (system,
nullptr,
false);
149 (system,
nullptr,
false);
154 fine_context->use_unweighted_quadrature_rules(system.extra_quadrature_order);
163 system.variable_type(
var).family ==
SCALAR)
167 FEBase * side_fe =
nullptr;
169 const std::set<unsigned char> & elem_dims =
172 for (
const auto &
dim : elem_dims)
186 std::unique_ptr<PointLocatorBase> point_locator;
187 std::unique_ptr<const Elem> side_ptr;
190 point_locator =
mesh.sub_point_locator();
194 for (
const auto & e :
mesh.active_local_element_ptr_range())
198 #ifdef LIBMESH_ENABLE_AMR 202 libmesh_warning(
"Warning: Jumps on the border of infinite elements are ignored." 213 bool compute_on_parent =
true;
214 if (!parent || !estimate_parent_error)
215 compute_on_parent =
false;
219 compute_on_parent =
false;
221 if (compute_on_parent &&
222 !error_per_cell[parent->
id()])
227 (*(system.solution), dof_map, parent, Uparent,
false);
235 std::vector<const Elem *> active_neighbors;
240 for (std::size_t a=0,
241 n_active_neighbors = active_neighbors.size();
242 a != n_active_neighbors; ++a)
244 const Elem * f = active_neighbors[a];
255 libmesh_assert_equal_to
265 system.variable_type(
var).family !=
SCALAR)
289 libmesh_assert_equal_to
301 bool found_boundary_flux =
false;
305 system.variable_type(
var).family !=
SCALAR)
311 found_boundary_flux =
true;
320 #endif // #ifdef LIBMESH_ENABLE_AMR 326 for (
auto n_e : e->side_index_range())
328 if ((e->neighbor_ptr(n_e) !=
nullptr) ||
336 if (e->neighbor_ptr(n_e) !=
nullptr 337 && !e->neighbor_ptr(n_e) ->infinite())
344 if ((f->
active() && (f->
level() == e->level()) && (e_id < f_id))
345 || (f->
level() < e->level()))
355 system.variable_type(
var).family !=
SCALAR)
382 side_ptr = e->build_side_ptr(n_e);
383 std::set<const Elem *> candidate_elements;
384 (*point_locator)(side_ptr->vertex_average(), candidate_elements);
393 if (candidate_elements.size() < 2)
402 (
dim-1, system.extra_quadrature_order);
404 side_fe->attach_quadrature_rule(side_qrule.get());
405 const std::vector<Point> & qface_point = side_fe->get_xyz();
406 side_fe->reinit(e, n_e);
408 for (
auto qp :
make_range(side_qrule->n_points()))
410 const Point p = qface_point[qp];
411 const std::vector<Point> qp_pointvec(1, p);
412 std::set<const Elem *> side_elements;
413 (*point_locator)(side_ptr->vertex_average(), side_elements);
423 const std::size_t n_neighbors = side_elements.size() - 1;
424 const Real neighbor_frac =
Real(1)/n_neighbors;
426 const std::vector<Real>
427 qp_weightvec(1, neighbor_frac * side_qrule->w(qp));
429 for (
const Elem * f : side_elements)
436 std::vector<Point> qp_coarse, qp_fine;
437 for (
unsigned int v=0; v<
n_vars; v++)
442 if (qp_coarse.empty())
444 coarse_fe->
reinit(f, &qp_coarse, &qp_weightvec);
448 fine_fe->
reinit(e, &qp_fine, &qp_weightvec);
454 system.variable_type(
var).family !=
SCALAR)
478 libmesh_not_implemented();
480 bool found_boundary_flux =
false;
484 system.variable_type(
var).family !=
SCALAR)
489 found_boundary_flux =
true;
512 if (error_per_cell[i] != 0.)
513 error_per_cell[i] = std::sqrt(error_per_cell[i]);
524 for (
const auto & val : n_flux_faces)
525 libmesh_assert_equal_to (val, static_cast<float>(static_cast<unsigned int>(val)));
531 if (n_flux_faces[i] == 0.0)
540 if (solution_vector && solution_vector != system.solution.
get())
545 newsol->
swap(*sys.solution);
560 FEBase * fe_fine =
nullptr;
564 std::vector<Point> qface_point = fe_fine->get_xyz();
567 FEBase * fe_coarse =
nullptr;
570 std::vector<Point> qp_coarse;
580 for (
unsigned int v=0; v<
n_vars; v++)
597 const unsigned int divisor =
609 return 1.0f /
static_cast<float>(divisor);
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
const Elem * parent() const
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
Access multiple components at once.
IntRange< unsigned short > side_index_range() const
void active_family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
std::unique_ptr< FEMContext > fine_context
Context objects for integrating on the fine and coarse elements sharing a face.
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)
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
This is the base class from which all geometric element types are derived.
virtual void internal_side_integration()=0
The function, to be implemented by derived classes, which calculates an error term on an internal sid...
bool integrate_slits
A boolean flag, by default false, to be set to true if integrations should be performed on "slits" wh...
The libMesh namespace provides an interface to certain functionality in the library.
const MeshBase & get_mesh() const
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
This is the MeshBase class.
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
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 handles the numbering of degrees of freedom on a mesh.
void reinit_sides()
A utility function to reinit the finite element data on elements sharing a side.
void libmesh_ignore(const Args &...)
virtual bool boundary_side_integration()
The function, to be implemented by derived classes, which calculates an error term on a boundary side...
Manages consistently variables, degrees of freedom, and coefficient vectors.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
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.
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
std::unique_ptr< FEMContext > coarse_context
Real fine_error
The fine and coarse error values to be set by each side_integration();.
const Elem * neighbor_ptr(unsigned int i) const
Real weight(unsigned int var) const
unsigned int level() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< QBase > unweighted_quadrature_rule(const unsigned int dim, const int extraorder=0) const
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
float coarse_n_flux_faces_increment()
A utility function to correctly increase n_flux_faces for the coarse element.
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...
bool use_unweighted_quadrature_rules
This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweigh...
unsigned int var
The variable number currently being evaluated.
virtual unsigned int size() const override final
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...
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...
unsigned int n_vars() const
bool integrate_boundary_sides
A boolean flag, by default false, to be set to true if integrations with boundary_side_integration() ...
const DofMap & get_dof_map() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual void init_context(FEMContext &c)
An initialization function, to give derived classes a chance to request specific data from the FE obj...
This class forms the foundation from which generic finite elements may be derived.