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);
155 fine_context->use_unweighted_quadrature_rules(system.extra_quadrature_order);
164 system.variable_type(
var).family ==
SCALAR)
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;
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
266 system.variable_type(
var).family !=
SCALAR)
290 libmesh_assert_equal_to
302 bool found_boundary_flux =
false;
306 system.variable_type(
var).family !=
SCALAR)
312 found_boundary_flux =
true;
321 #endif // #ifdef LIBMESH_ENABLE_AMR 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()))
356 system.variable_type(
var).family !=
SCALAR)
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)
403 (
dim-1, system.extra_quadrature_order);
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);
455 system.variable_type(
var).family !=
SCALAR)
479 libmesh_not_implemented();
481 bool found_boundary_flux =
false;
485 system.variable_type(
var).family !=
SCALAR)
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);
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.