libMesh
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | List of all members
libMesh::DiscontinuityMeasure Class Reference

This class measures discontinuities between elements for debugging purposes. More...

#include <discontinuity_measure.h>

Inheritance diagram for libMesh::DiscontinuityMeasure:
[legend]

Public Types

typedef std::map< std::pair< const System *, unsigned int >, std::unique_ptr< ErrorVector > > ErrorMap
 When calculating many error vectors at once, we need a data structure to hold them all.
 

Public Member Functions

 DiscontinuityMeasure ()
 Constructor.
 
 DiscontinuityMeasure (const DiscontinuityMeasure &)=delete
 This class cannot be (default) copy constructed/assigned because its base class has unique_ptr members.
 
DiscontinuityMeasureoperator= (const DiscontinuityMeasure &)=delete
 
 DiscontinuityMeasure (DiscontinuityMeasure &&)=default
 Defaulted move ctor, move assignment operator, and destructor.
 
DiscontinuityMeasureoperator= (DiscontinuityMeasure &&)=default
 
virtual ~DiscontinuityMeasure ()=default
 
void attach_essential_bc_function (std::pair< bool, Real > fptr(const System &system, const Point &p, const std::string &var_name))
 Register a user function to use in computing the essential BCs.
 
virtual ErrorEstimatorType type () const override
 
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.
 
virtual void estimate_errors (const EquationSystems &equation_systems, ErrorVector &error_per_cell, const std::map< const System *, SystemNorm > &error_norms, const std::map< const System *, const NumericVector< Number > * > *solution_vectors=nullptr, bool estimate_parent_error=false)
 This virtual function can be redefined in derived classes, but by default computes the sum of the error_per_cell for each system in the equation_systems.
 
virtual void estimate_errors (const EquationSystems &equation_systems, ErrorMap &errors_per_cell, const std::map< const System *, const NumericVector< Number > * > *solution_vectors=nullptr, bool estimate_parent_error=false)
 This virtual function can be redefined in derived classes, but by default it calls estimate_error repeatedly to calculate the requested error vectors.
 

Public Attributes

bool scale_by_n_flux_faces
 This boolean flag allows you to scale the error indicator result for each element by the number of "flux faces" the element actually has.
 
bool use_unweighted_quadrature_rules
 This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweighted shape functions in master element space) rather than "default" quadrature rules (sized to exactly integrate polynomials of one higher degree than mass matrix terms).
 
bool integrate_slits
 A boolean flag, by default false, to be set to true if integrations should be performed on "slits" where two elements' faces overlap even if those elements are not connected by neighbor links.
 
SystemNorm error_norm
 When estimating the error in a single system, the error_norm is used to control the scaling and norm choice for each variable.
 

Protected Member Functions

virtual void init_context (FEMContext &c) override
 An initialization function, for requesting specific data from the FE objects.
 
virtual void internal_side_integration () override
 The function which calculates a normal derivative jump based error term on an internal side.
 
virtual bool boundary_side_integration () override
 The function which calculates a normal derivative jump based error term on a boundary side.
 
void reinit_sides ()
 A utility function to reinit the finite element data on elements sharing a side.
 
float coarse_n_flux_faces_increment ()
 A utility function to correctly increase n_flux_faces for the coarse element.
 
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 them to get the global error vector.
 

Protected Attributes

std::pair< bool, Real >(* _bc_function )(const System &system, const Point &p, const std::string &var_name)
 Pointer to function that provides BC information.
 
bool integrate_boundary_sides
 A boolean flag, by default false, to be set to true if integrations with boundary_side_integration() should be performed.
 
std::unique_ptr< FEMContextfine_context
 Context objects for integrating on the fine and coarse elements sharing a face.
 
std::unique_ptr< FEMContextcoarse_context
 
Real fine_error
 The fine and coarse error values to be set by each side_integration();.
 
Real coarse_error
 
unsigned int var
 The variable number currently being evaluated.
 

Detailed Description

This class measures discontinuities between elements for debugging purposes.

It derives from ErrorEstimator just in case someone finds it useful in a DG framework.

Author
Roy H. Stogner
Date
2006

Definition at line 49 of file discontinuity_measure.h.

Member Typedef Documentation

◆ ErrorMap

typedef std::map<std::pair<const System *, unsigned int>, std::unique_ptr<ErrorVector> > libMesh::ErrorEstimator::ErrorMap
inherited

When calculating many error vectors at once, we need a data structure to hold them all.

Definition at line 121 of file error_estimator.h.

Constructor & Destructor Documentation

◆ DiscontinuityMeasure() [1/3]

libMesh::DiscontinuityMeasure::DiscontinuityMeasure ( )

Constructor.

Responsible for initializing the _bc_function function pointer to nullptr. Defaults to L2 norm; changes to system norm are ignored.

Definition at line 41 of file discontinuity_measure.C.

41 :
43 _bc_function(nullptr)
44{
45 error_norm = L2;
46}
std::pair< bool, Real >(* _bc_function)(const System &system, const Point &p, const std::string &var_name)
Pointer to function that provides BC information.
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...

References libMesh::ErrorEstimator::error_norm, and libMesh::L2.

◆ DiscontinuityMeasure() [2/3]

libMesh::DiscontinuityMeasure::DiscontinuityMeasure ( const DiscontinuityMeasure )
delete

This class cannot be (default) copy constructed/assigned because its base class has unique_ptr members.

◆ DiscontinuityMeasure() [3/3]

libMesh::DiscontinuityMeasure::DiscontinuityMeasure ( DiscontinuityMeasure &&  )
default

Defaulted move ctor, move assignment operator, and destructor.

◆ ~DiscontinuityMeasure()

virtual libMesh::DiscontinuityMeasure::~DiscontinuityMeasure ( )
virtualdefault

Member Function Documentation

◆ attach_essential_bc_function()

void libMesh::DiscontinuityMeasure::attach_essential_bc_function ( std::pair< bool, Real >   fptrconst System &system, const Point &p, const std::string &var_name)

Register a user function to use in computing the essential BCs.

Definition at line 202 of file discontinuity_measure.C.

205{
207
208 // We may be turning boundary side integration on or off
209 if (fptr)
211 else
213}
bool integrate_boundary_sides
A boolean flag, by default false, to be set to true if integrations with boundary_side_integration() ...
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition projection.C:81

References _bc_function, fptr(), and libMesh::JumpErrorEstimator::integrate_boundary_sides.

◆ boundary_side_integration()

bool libMesh::DiscontinuityMeasure::boundary_side_integration ( )
overrideprotectedvirtual

The function which calculates a normal derivative jump based error term on a boundary side.

Returns
true if the flux bc function is in fact defined on the current side.

Reimplemented from libMesh::JumpErrorEstimator.

Definition at line 132 of file discontinuity_measure.C.

133{
134 const Elem & fine_elem = fine_context->get_elem();
135
136 FEBase * fe_fine = nullptr;
137 fine_context->get_side_fe( var, fe_fine, fine_elem.dim() );
138
139 const std::string & var_name =
140 fine_context->get_system().variable_name(var);
141
142 const std::vector<Real> & JxW_face = fe_fine->get_JxW();
143 const std::vector<Point> & qface_point = fe_fine->get_xyz();
144
145 // The reinitialization also recomputes the locations of
146 // the quadrature points on the side. By checking if the
147 // first quadrature point on the side is on an essential boundary
148 // for a particular variable, we will determine if the whole
149 // element is on an essential boundary (assuming quadrature points
150 // are strictly contained in the side).
151 if (this->_bc_function(fine_context->get_system(),
152 qface_point[0], var_name).first)
153 {
154 const Real h = fine_elem.hmax();
155
156 // The number of quadrature points
157 const unsigned int n_qp = fe_fine->n_quadrature_points();
158
159 // The error contribution from this face
160 Real error = 1.e-30;
161
162 // loop over the integration points on the face.
163 for (unsigned int qp=0; qp<n_qp; qp++)
164 {
165 // Value of the imposed essential BC at this quadrature point.
166 const std::pair<bool,Real> essential_bc =
167 this->_bc_function(fine_context->get_system(), qface_point[qp],
168 var_name);
169
170 // Be sure the BC function still thinks we're on the
171 // essential boundary.
172 libmesh_assert_equal_to (essential_bc.first, true);
173
174 // The solution value on each point
175 Number u_fine = fine_context->side_value(var, qp);
176
177 // The difference between the desired BC and the approximate solution.
178 const Number jump = essential_bc.second - u_fine;
179
180 // The flux jump squared. If using complex numbers,
181 // norm_sq(z) returns |z|^2, where |z| is the modulus of z.
182 const Real jump2 = TensorTools::norm_sq(jump);
183
184 // Integrate the error on the face. The error is
185 // scaled by an additional power of h, where h is
186 // the maximum side length for the element. This
187 // arises in the definition of the indicator.
188 error += JxW_face[qp]*jump2;
189
190 } // End quadrature point loop
191
192 fine_error = error*h*error_norm.weight(var);
193
194 return true;
195 } // end if side on flux boundary
196 return false;
197}
unsigned int var
The variable number currently being evaluated.
Real fine_error
The fine and coarse error values to be set by each side_integration();.
std::unique_ptr< FEMContext > fine_context
Context objects for integrating on the fine and coarse elements sharing a face.
Real weight(unsigned int var) const
auto norm_sq(const T &a)
FEGenericBase< Real > FEBase
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References _bc_function, libMesh::Elem::dim(), libMesh::ErrorEstimator::error_norm, libMesh::JumpErrorEstimator::fine_context, libMesh::JumpErrorEstimator::fine_error, libMesh::FEAbstract::get_JxW(), libMesh::FEAbstract::get_xyz(), libMesh::Elem::hmax(), libMesh::FEAbstract::n_quadrature_points(), libMesh::TensorTools::norm_sq(), libMesh::Real, libMesh::JumpErrorEstimator::var, and libMesh::SystemNorm::weight().

◆ coarse_n_flux_faces_increment()

float libMesh::JumpErrorEstimator::coarse_n_flux_faces_increment ( )
protectedinherited

A utility function to correctly increase n_flux_faces for the coarse element.

Definition at line 592 of file jump_error_estimator.C.

593{
594 // Keep track of the number of internal flux sides found on each
595 // element
596 unsigned short dim = coarse_context->get_elem().dim();
597
598 const unsigned int divisor =
599 1 << (dim-1)*(fine_context->get_elem().level() -
600 coarse_context->get_elem().level());
601
602 // With a difference of n levels between fine and coarse elements,
603 // we compute a fractional flux face for the coarse element by adding:
604 // 1/2^n in 2D
605 // 1/4^n in 3D
606 // each time. This code will get hit 2^n times in 2D and 4^n
607 // times in 3D so that the final flux face count for the coarse
608 // element will be an integer value.
609
610 return 1.0f / static_cast<float>(divisor);
611}
unsigned int dim
std::unique_ptr< FEMContext > coarse_context

References libMesh::JumpErrorEstimator::coarse_context, dim, and libMesh::JumpErrorEstimator::fine_context.

Referenced by libMesh::JumpErrorEstimator::estimate_error().

◆ estimate_error()

void libMesh::JumpErrorEstimator::estimate_error ( const System system,
ErrorVector error_per_cell,
const NumericVector< Number > *  solution_vector = nullptr,
bool  estimate_parent_error = false 
)
overridevirtualinherited

This function uses the derived class's jump error estimate formula to estimate the error on each cell.

The estimated error is output in the vector error_per_cell

Conventions for assigning the direction of the normal:

  • e & f are global element ids

Case (1.) Elements are at the same level, e<f Compute the flux jump on the face and add it as a contribution to error_per_cell[e] and error_per_cell[f]


| | |

f
e —> n

Case (2.) The neighbor is at a higher level. Compute the flux jump on e's face and add it as a contribution to error_per_cell[e] and error_per_cell[f]


| | | | | | e |—> n | | | | | |--------—| f |


Implements libMesh::ErrorEstimator.

Definition at line 56 of file jump_error_estimator.C.

60{
61 LOG_SCOPE("estimate_error()", "JumpErrorEstimator");
62
99 // This parameter is not used when !LIBMESH_ENABLE_AMR.
100 libmesh_ignore(estimate_parent_error);
101
102 // The current mesh
103 const MeshBase & mesh = system.get_mesh();
104
105 // The number of variables in the system
106 const unsigned int n_vars = system.n_vars();
107
108 // The DofMap for this system
109#ifdef LIBMESH_ENABLE_AMR
110 const DofMap & dof_map = system.get_dof_map();
111#endif
112
113 // Resize the error_per_cell vector according to the
114 // maximum element ID because we will be indexing it with IDs.
115 // Initialize to 0.
116 error_per_cell.resize (mesh.max_elem_id());
117 std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);
118
119 // Declare a vector of floats which is as long as
120 // error_per_cell above, and fill with zeros. This vector will be
121 // used to keep track of the number of edges (faces) on each active
122 // element which are either:
123 // 1) an internal edge
124 // 2) an edge on a Neumann boundary for which a boundary condition
125 // function has been specified.
126 // The error estimator can be scaled by the number of flux edges (faces)
127 // which the element actually has to obtain a more uniform measure
128 // of the error. Use floats instead of ints since in case 2 (above)
129 // f gets 1/2 of a flux face contribution from each of his
130 // neighbors
131 std::vector<float> n_flux_faces;
133 n_flux_faces.resize(error_per_cell.size(), 0);
134
135 // Prepare current_local_solution to localize a non-standard
136 // solution vector if necessary
137 if (solution_vector && solution_vector != system.solution.get())
138 {
139 NumericVector<Number> * newsol =
140 const_cast<NumericVector<Number> *>(solution_vector);
141 System & sys = const_cast<System &>(system);
142 newsol->swap(*sys.solution);
143 sys.update();
144 }
145
146 // We don't use full elem_jacobian or subjacobians here.
147 fine_context = std::make_unique<FEMContext>
148 (system, nullptr, /* allocate_local_matrices = */ false);
149 coarse_context = std::make_unique<FEMContext>
150 (system, nullptr, /* allocate_local_matrices = */ false);
151
152 // Don't overintegrate - we're evaluating differences of FE values,
153 // not products of them.
155 fine_context->use_unweighted_quadrature_rules(system.extra_quadrature_order);
156
157 // Loop over all the variables we've been requested to find jumps in, to
158 // pre-request
159 for (var=0; var<n_vars; var++)
160 {
161 // Skip variables which aren't part of our norm,
162 // as well as SCALAR variables, which have no jumps
163 if (error_norm.weight(var) == 0.0 ||
164 system.variable_type(var).family == SCALAR)
165 continue;
166
167 // FIXME: Need to generalize this to vector-valued elements. [PB]
168 FEBase * side_fe = nullptr;
169
170 const std::set<unsigned char> & elem_dims =
171 fine_context->elem_dimensions();
172
173 for (const auto & dim : elem_dims)
174 {
175 fine_context->get_side_fe( var, side_fe, dim );
176
177 side_fe->get_xyz();
178 }
179 }
180
183
184 // If we're integrating jumps across mesh slits, then we'll need a
185 // point locator to find slits, and we'll need to integrate point by
186 // point on sides.
187 std::unique_ptr<PointLocatorBase> point_locator;
188 std::unique_ptr<const Elem> side_ptr;
189
190 if (integrate_slits)
191 point_locator = mesh.sub_point_locator();
192
193 // Iterate over all the active elements in the mesh
194 // that live on this processor.
195 for (const auto & e : mesh.active_local_element_ptr_range())
196 {
197 const dof_id_type e_id = e->id();
198
199#ifdef LIBMESH_ENABLE_AMR
200
201 if (e->infinite())
202 {
203 libmesh_warning("Warning: Jumps on the border of infinite elements are ignored."
204 << std::endl);
205 continue;
206 }
207
208 // See if the parent of element e has been examined yet;
209 // if not, we may want to compute the estimator on it
210 const Elem * parent = e->parent();
211
212 // We only can compute and only need to compute on
213 // parents with all active children
214 bool compute_on_parent = true;
215 if (!parent || !estimate_parent_error)
216 compute_on_parent = false;
217 else
218 for (auto & child : parent->child_ref_range())
219 if (!child.active())
220 compute_on_parent = false;
221
222 if (compute_on_parent &&
223 !error_per_cell[parent->id()])
224 {
225 // Compute a projection onto the parent
226 DenseVector<Number> Uparent;
228 (*(system.solution), dof_map, parent, Uparent, false);
229
230 // Loop over the neighbors of the parent
231 for (auto n_p : parent->side_index_range())
232 {
233 if (parent->neighbor_ptr(n_p) != nullptr) // parent has a neighbor here
234 {
235 // Find the active neighbors in this direction
236 std::vector<const Elem *> active_neighbors;
237 parent->neighbor_ptr(n_p)->
238 active_family_tree_by_neighbor(active_neighbors,
239 parent);
240 // Compute the flux to each active neighbor
241 for (std::size_t a=0,
242 n_active_neighbors = active_neighbors.size();
243 a != n_active_neighbors; ++a)
244 {
245 const Elem * f = active_neighbors[a];
246
247 if (f ->infinite()) // don't take infinite elements into account
248 continue;
249
250 // FIXME - what about when f->level <
251 // parent->level()??
252 if (f->level() >= parent->level())
253 {
254 fine_context->pre_fe_reinit(system, f);
255 coarse_context->pre_fe_reinit(system, parent);
256 libmesh_assert_equal_to
257 (coarse_context->get_elem_solution().size(),
258 Uparent.size());
259 coarse_context->get_elem_solution() = Uparent;
260
261 this->reinit_sides();
262
263 // Loop over all significant variables in the system
264 for (var=0; var<n_vars; var++)
265 if (error_norm.weight(var) != 0.0 &&
266 system.variable_type(var).family != SCALAR)
267 {
269
270 error_per_cell[fine_context->get_elem().id()] +=
271 static_cast<ErrorVectorReal>(fine_error);
272 error_per_cell[coarse_context->get_elem().id()] +=
273 static_cast<ErrorVectorReal>(coarse_error);
274 }
275
276 // Keep track of the number of internal flux
277 // sides found on each element
279 {
280 n_flux_faces[fine_context->get_elem().id()]++;
281 n_flux_faces[coarse_context->get_elem().id()] +=
283 }
284 }
285 }
286 }
288 {
289 fine_context->pre_fe_reinit(system, parent);
290 libmesh_assert_equal_to
291 (fine_context->get_elem_solution().size(),
292 Uparent.size());
293 fine_context->get_elem_solution() = Uparent;
294 fine_context->side = cast_int<unsigned char>(n_p);
295 fine_context->side_fe_reinit();
296
297 // If we find a boundary flux for any variable,
298 // let's just count it as a flux face for all
299 // variables. Otherwise we'd need to keep track of
300 // a separate n_flux_faces and error_per_cell for
301 // every single var.
302 bool found_boundary_flux = false;
303
304 for (var=0; var<n_vars; var++)
305 if (error_norm.weight(var) != 0.0 &&
306 system.variable_type(var).family != SCALAR)
307 {
308 if (this->boundary_side_integration())
309 {
310 error_per_cell[fine_context->get_elem().id()] +=
311 static_cast<ErrorVectorReal>(fine_error);
312 found_boundary_flux = true;
313 }
314 }
315
316 if (scale_by_n_flux_faces && found_boundary_flux)
317 n_flux_faces[fine_context->get_elem().id()]++;
318 }
319 }
320 }
321#endif // #ifdef LIBMESH_ENABLE_AMR
322
323 // If we do any more flux integration, e will be the fine element
324 fine_context->pre_fe_reinit(system, e);
325
326 // Loop over the neighbors of element e
327 for (auto n_e : e->side_index_range())
328 {
329 if ((e->neighbor_ptr(n_e) != nullptr) ||
331 {
332 fine_context->side = cast_int<unsigned char>(n_e);
333 fine_context->side_fe_reinit();
334 }
335
336 // e is not on the boundary (infinite elements are treated as boundary)
337 if (e->neighbor_ptr(n_e) != nullptr
338 && !e->neighbor_ptr(n_e) ->infinite())
339 {
340
341 const Elem * f = e->neighbor_ptr(n_e);
342 const dof_id_type f_id = f->id();
343
344 // Compute flux jumps if we are in case 1 or case 2.
345 if ((f->active() && (f->level() == e->level()) && (e_id < f_id))
346 || (f->level() < e->level()))
347 {
348 // f is now the coarse element
349 coarse_context->pre_fe_reinit(system, f);
350
351 this->reinit_sides();
352
353 // Loop over all significant variables in the system
354 for (var=0; var<n_vars; var++)
355 if (error_norm.weight(var) != 0.0 &&
356 system.variable_type(var).family != SCALAR)
357 {
359
360 error_per_cell[fine_context->get_elem().id()] +=
361 static_cast<ErrorVectorReal>(fine_error);
362 error_per_cell[coarse_context->get_elem().id()] +=
363 static_cast<ErrorVectorReal>(coarse_error);
364 }
365
366 // Keep track of the number of internal flux
367 // sides found on each element
369 {
370 n_flux_faces[fine_context->get_elem().id()]++;
371 n_flux_faces[coarse_context->get_elem().id()] +=
373 }
374 } // end if (case1 || case2)
375 } // if (e->neighbor(n_e) != nullptr)
376
377 // e might not have a neighbor_ptr, but might still have
378 // another element sharing its side. This can happen in a
379 // mesh where solution continuity is maintained via nodal
380 // constraint rows.
381 else if (integrate_slits)
382 {
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);
386
387 // We should have at least found ourselves...
388 libmesh_assert(candidate_elements.count(e));
389
390 // If we only found ourselves, this probably isn't a
391 // slit; we don't yet support meshes so non-conforming
392 // as to have overlap of part of an element side without
393 // overlap of its center.
394 if (candidate_elements.size() < 2)
395 continue;
396
397 FEType hardest_fe_type = fine_context->find_hardest_fe_type();
398
399 auto dim = e->dim();
400
401 auto side_qrule =
402 hardest_fe_type.unweighted_quadrature_rule
403 (dim-1, system.extra_quadrature_order);
404 auto side_fe = FEAbstract::build(dim, hardest_fe_type);
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);
408
409 for (auto qp : make_range(side_qrule->n_points()))
410 {
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);
415
416 // If we have multiple neighbors meeting here we'll just
417 // take weighted jumps from all of them.
418 //
419 // We'll also do integrations from both sides of slits,
420 // rather than try to figure out a disambiguation rule
421 // that makes sense for non-conforming slits in general.
422 // This means we want an extra factor of 0.5 on the
423 // integrals to compensate for doubling them.
424 const std::size_t n_neighbors = side_elements.size() - 1;
425 const Real neighbor_frac = Real(1)/n_neighbors;
426
427 const std::vector<Real>
428 qp_weightvec(1, neighbor_frac * side_qrule->w(qp));
429
430 for (const Elem * f : side_elements)
431 {
432 if (f == e)
433 continue;
434
435 coarse_context->pre_fe_reinit(system, f);
436 fine_context->pre_fe_reinit(system, e);
437 std::vector<Point> qp_coarse, qp_fine;
438 for (unsigned int v=0; v<n_vars; v++)
439 if (error_norm.weight(v) != 0.0 &&
440 fine_context->get_system().variable_type(v).family != SCALAR)
441 {
442 FEBase * coarse_fe = coarse_context->get_side_fe(v, dim);
443 if (qp_coarse.empty())
444 FEMap::inverse_map (dim, f, qp_pointvec, qp_coarse);
445 coarse_fe->reinit(f, &qp_coarse, &qp_weightvec);
446 FEBase * fine_fe = fine_context->get_side_fe(v, dim);
447 if (qp_fine.empty())
448 FEMap::inverse_map (dim, e, qp_pointvec, qp_fine);
449 fine_fe->reinit(e, &qp_fine, &qp_weightvec);
450 }
451
452 // Loop over all significant variables in the system
453 for (var=0; var<n_vars; var++)
454 if (error_norm.weight(var) != 0.0 &&
455 system.variable_type(var).family != SCALAR)
456 {
458
459 error_per_cell[fine_context->get_elem().id()] +=
460 static_cast<ErrorVectorReal>(fine_error);
461 error_per_cell[coarse_context->get_elem().id()] +=
462 static_cast<ErrorVectorReal>(coarse_error);
463 }
464 }
465 }
466 }
467
468 // Otherwise, e is on the boundary. If it happens to
469 // be on a Dirichlet boundary, we need not do anything.
470 // On the other hand, if e is on a Neumann (flux) boundary
471 // with grad(u).n = g, we need to compute the additional residual
472 // (h * \int |g - grad(u_h).n|^2 dS)^(1/2).
473 // We can only do this with some knowledge of the boundary
474 // conditions, i.e. the user must have attached an appropriate
475 // BC function.
477 {
478 if (integrate_slits)
479 libmesh_not_implemented();
480
481 bool found_boundary_flux = false;
482
483 for (var=0; var<n_vars; var++)
484 if (error_norm.weight(var) != 0.0 &&
485 system.variable_type(var).family != SCALAR)
486 if (this->boundary_side_integration())
487 {
488 error_per_cell[fine_context->get_elem().id()] +=
489 static_cast<ErrorVectorReal>(fine_error);
490 found_boundary_flux = true;
491 }
492
493 if (scale_by_n_flux_faces && found_boundary_flux)
494 n_flux_faces[fine_context->get_elem().id()]++;
495 } // end if (e->neighbor_ptr(n_e) == nullptr)
496 } // end loop over neighbors
497 } // End loop over active local elements
498
499
500 // Each processor has now computed the error contributions
501 // for its local elements. We need to sum the vector
502 // and then take the square-root of each component. Note
503 // that we only need to sum if we are running on multiple
504 // processors, and we only need to take the square-root
505 // if the value is nonzero. There will in general be many
506 // zeros for the inactive elements.
507
508 // First sum the vector of estimated error values
509 this->reduce_error(error_per_cell, system.comm());
510
511 // Compute the square-root of each component.
512 for (auto i : index_range(error_per_cell))
513 if (error_per_cell[i] != 0.)
514 error_per_cell[i] = std::sqrt(error_per_cell[i]);
515
516
517 if (this->scale_by_n_flux_faces)
518 {
519 // Sum the vector of flux face counts
520 this->reduce_error(n_flux_faces, system.comm());
521
522 // Sanity check: Make sure the number of flux faces is
523 // always an integer value
524#ifdef DEBUG
525 for (const auto & val : n_flux_faces)
526 libmesh_assert_equal_to (val, static_cast<float>(static_cast<unsigned int>(val)));
527#endif
528
529 // Scale the error by the number of flux faces for each element
530 for (auto i : index_range(n_flux_faces))
531 {
532 if (n_flux_faces[i] == 0.0) // inactive or non-local element
533 continue;
534
535 error_per_cell[i] /= static_cast<ErrorVectorReal>(n_flux_faces[i]);
536 }
537 }
538
539 // If we used a non-standard solution before, now is the time to fix
540 // the current_local_solution
541 if (solution_vector && solution_vector != system.solution.get())
542 {
543 NumericVector<Number> * newsol =
544 const_cast<NumericVector<Number> *>(solution_vector);
545 System & sys = const_cast<System &>(system);
546 newsol->swap(*sys.solution);
547 sys.update();
548 }
549}
unsigned int n_vars
void ErrorVector unsigned int
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...
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
Definition fe_abstract.C:78
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...
Definition fe_base.C:976
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)
Definition fe_map.C:1512
float coarse_n_flux_faces_increment()
A utility function to correctly increase n_flux_faces for the coarse element.
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...
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...
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...
MeshBase & mesh
void active_family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
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...
Definition int_range.h:153
void libmesh_ignore(const Args &...)
libmesh_assert(ctx)
uint8_t dof_id_type
Definition id_types.h:67
template class LIBMESH_EXPORT NumericVector< Number >
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...
Definition int_range.h:176

References libMesh::Elem::active(), libMesh::JumpErrorEstimator::boundary_side_integration(), libMesh::FEAbstract::build(), libMesh::Elem::child_ref_range(), libMesh::JumpErrorEstimator::coarse_context, libMesh::JumpErrorEstimator::coarse_error, libMesh::JumpErrorEstimator::coarse_n_flux_faces_increment(), libMesh::FEGenericBase< OutputType >::coarsened_dof_values(), libMesh::ParallelObject::comm(), dim, libMesh::ErrorEstimator::error_norm, libMesh::ErrorVectorReal, libMesh::System::extra_quadrature_order, libMesh::FEType::family, libMesh::JumpErrorEstimator::fine_context, libMesh::JumpErrorEstimator::fine_error, libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::FEAbstract::get_xyz(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::JumpErrorEstimator::init_context(), libMesh::JumpErrorEstimator::integrate_boundary_sides, libMesh::JumpErrorEstimator::integrate_slits, libMesh::JumpErrorEstimator::internal_side_integration(), libMesh::FEMap::inverse_map(), libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::libmesh_ignore(), libMesh::make_range(), mesh, n_vars, libMesh::System::n_vars(), libMesh::Elem::neighbor_ptr(), libMesh::Elem::parent(), libMesh::Real, libMesh::ErrorEstimator::reduce_error(), libMesh::FEAbstract::reinit(), libMesh::JumpErrorEstimator::reinit_sides(), libMesh::SCALAR, libMesh::JumpErrorEstimator::scale_by_n_flux_faces, libMesh::Elem::side_index_range(), libMesh::DenseVector< T >::size(), libMesh::System::solution, libMesh::NumericVector< T >::swap(), libMesh::FEType::unweighted_quadrature_rule(), libMesh::JumpErrorEstimator::use_unweighted_quadrature_rules, libMesh::JumpErrorEstimator::var, libMesh::System::variable_type(), and libMesh::SystemNorm::weight().

Referenced by assemble_and_solve(), main(), and SlitMeshRefinedSystemTest::testSystem().

◆ estimate_errors() [1/2]

void libMesh::ErrorEstimator::estimate_errors ( const EquationSystems equation_systems,
ErrorMap errors_per_cell,
const std::map< const System *, const NumericVector< Number > * > *  solution_vectors = nullptr,
bool  estimate_parent_error = false 
)
virtualinherited

This virtual function can be redefined in derived classes, but by default it calls estimate_error repeatedly to calculate the requested error vectors.

FIXME: This is a default implementation - derived classes should reimplement it for efficiency.

Currently this function ignores the error_norm.weight() values because it calculates each variable's error individually, unscaled.

The user selects which errors get computed by filling a map with error vectors: If errors_per_cell[&system][v] exists, it will be filled with the error values in variable v of system

Reimplemented in libMesh::UniformRefinementEstimator.

Definition at line 94 of file error_estimator.C.

98{
99 SystemNorm old_error_norm = this->error_norm;
100
101 // Find the requested error values from each system
102 for (auto s : make_range(equation_systems.n_systems()))
103 {
104 const System & sys = equation_systems.get_system(s);
105
106 unsigned int n_vars = sys.n_vars();
107
108 for (unsigned int v = 0; v != n_vars; ++v)
109 {
110 // Only fill in ErrorVectors the user asks for
111 if (!errors_per_cell.count(std::make_pair(&sys, v)))
112 continue;
113
114 // Calculate error in only one variable
115 std::vector<Real> weights(n_vars, 0.0);
116 weights[v] = 1.0;
117 this->error_norm =
118 SystemNorm(std::vector<FEMNormType>(n_vars, old_error_norm.type(v)),
119 weights);
120
121 const NumericVector<Number> * solution_vector = nullptr;
122 if (solution_vectors &&
123 solution_vectors->find(&sys) != solution_vectors->end())
124 solution_vector = solution_vectors->find(&sys)->second;
125
126 this->estimate_error
127 (sys, *errors_per_cell[std::make_pair(&sys, v)],
128 solution_vector, estimate_parent_error);
129 }
130 }
131
132 // Restore our old state before returning
133 this->error_norm = old_error_norm;
134}
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false)=0
This pure virtual function must be redefined in derived classes to compute the error for each active ...

References libMesh::ErrorEstimator::error_norm, libMesh::ErrorEstimator::estimate_error(), libMesh::EquationSystems::get_system(), libMesh::make_range(), libMesh::EquationSystems::n_systems(), n_vars, libMesh::System::n_vars(), and libMesh::SystemNorm::type().

◆ estimate_errors() [2/2]

void libMesh::ErrorEstimator::estimate_errors ( const EquationSystems equation_systems,
ErrorVector error_per_cell,
const std::map< const System *, SystemNorm > &  error_norms,
const std::map< const System *, const NumericVector< Number > * > *  solution_vectors = nullptr,
bool  estimate_parent_error = false 
)
virtualinherited

This virtual function can be redefined in derived classes, but by default computes the sum of the error_per_cell for each system in the equation_systems.

Currently this function ignores the error_norm member variable, and uses the function argument error_norms instead.

This function is named estimate_errors instead of estimate_error because otherwise C++ can get confused.

Reimplemented in libMesh::UniformRefinementEstimator.

Definition at line 47 of file error_estimator.C.

52{
53 SystemNorm old_error_norm = this->error_norm;
54
55 // Sum the error values from each system
56 for (auto s : make_range(equation_systems.n_systems()))
57 {
58 ErrorVector system_error_per_cell;
59 const System & sys = equation_systems.get_system(s);
60 if (const auto it = error_norms.find(&sys);
61 it == error_norms.end())
62 this->error_norm = old_error_norm;
63 else
64 this->error_norm = it->second;
65
66 const NumericVector<Number> * solution_vector = nullptr;
67 if (solution_vectors &&
68 solution_vectors->find(&sys) != solution_vectors->end())
69 solution_vector = solution_vectors->find(&sys)->second;
70
71 this->estimate_error(sys, system_error_per_cell,
72 solution_vector, estimate_parent_error);
73
74 if (s)
75 {
76 libmesh_assert_equal_to (error_per_cell.size(), system_error_per_cell.size());
77 for (auto i : index_range(error_per_cell))
78 error_per_cell[i] += system_error_per_cell[i];
79 }
80 else
81 error_per_cell = system_error_per_cell;
82 }
83
84 // Restore our old state before returning
85 this->error_norm = old_error_norm;
86}

References libMesh::ErrorEstimator::error_norm, libMesh::ErrorEstimator::estimate_error(), libMesh::EquationSystems::get_system(), libMesh::index_range(), libMesh::make_range(), and libMesh::EquationSystems::n_systems().

◆ init_context()

void libMesh::DiscontinuityMeasure::init_context ( FEMContext c)
overrideprotectedvirtual

An initialization function, for requesting specific data from the FE objects.

Reimplemented from libMesh::JumpErrorEstimator.

Definition at line 59 of file discontinuity_measure.C.

60{
61 const unsigned int n_vars = c.n_vars();
62 for (unsigned int v=0; v<n_vars; v++)
63 {
64 // Possibly skip this variable
65 if (error_norm.weight(v) == 0.0) continue;
66
67 // FIXME: Need to generalize this to vector-valued elements. [PB]
68 FEBase * side_fe = nullptr;
69
70 const std::set<unsigned char> & elem_dims =
71 c.elem_dimensions();
72
73 for (const auto & dim : elem_dims)
74 {
75 c.get_side_fe( v, side_fe, dim );
76
77 // We'll need values and mapping Jacobians on both sides for
78 // discontinuity computation
79 side_fe->get_phi();
80
81 // But we only need mapping Jacobians from one side
82 if (&c != coarse_context.get())
83 side_fe->get_JxW();
84 }
85 }
86}

References libMesh::JumpErrorEstimator::coarse_context, dim, libMesh::FEMContext::elem_dimensions(), libMesh::ErrorEstimator::error_norm, libMesh::FEAbstract::get_JxW(), libMesh::FEGenericBase< OutputType >::get_phi(), libMesh::FEMContext::get_side_fe(), n_vars, libMesh::DiffContext::n_vars(), and libMesh::SystemNorm::weight().

◆ internal_side_integration()

void libMesh::DiscontinuityMeasure::internal_side_integration ( )
overrideprotectedvirtual

The function which calculates a normal derivative jump based error term on an internal side.

Implements libMesh::JumpErrorEstimator.

Definition at line 91 of file discontinuity_measure.C.

92{
93 const Elem & coarse_elem = coarse_context->get_elem();
94 const Elem & fine_elem = fine_context->get_elem();
95
96 FEBase * fe_fine = nullptr;
97 fine_context->get_side_fe( var, fe_fine, fine_elem.dim() );
98
99 FEBase * fe_coarse = nullptr;
100 coarse_context->get_side_fe( var, fe_coarse, fine_elem.dim() );
101
102 Real error = 1.e-30;
103 unsigned int n_qp = fe_fine->n_quadrature_points();
104
105 const std::vector<Real> & JxW_face = fe_fine->get_JxW();
106
107 for (unsigned int qp=0; qp != n_qp; ++qp)
108 {
109 // Calculate solution values on fine and coarse elements
110 // at this quadrature point
111 Number
112 u_fine = fine_context->side_value(var, qp),
113 u_coarse = coarse_context->side_value(var, qp);
114
115 // Find the jump in the value
116 // at this quadrature point
117 const Number jump = u_fine - u_coarse;
118 const Real jump2 = TensorTools::norm_sq(jump);
119 // Accumulate the jump integral
120 error += JxW_face[qp] * jump2;
121 }
122
123 // Add the h-weighted jump integral to each error term
124 fine_error =
125 error * fine_elem.hmax() * error_norm.weight(var);
127 error * coarse_elem.hmax() * error_norm.weight(var);
128}

References libMesh::JumpErrorEstimator::coarse_context, libMesh::JumpErrorEstimator::coarse_error, libMesh::Elem::dim(), libMesh::ErrorEstimator::error_norm, libMesh::JumpErrorEstimator::fine_context, libMesh::JumpErrorEstimator::fine_error, libMesh::FEAbstract::get_JxW(), libMesh::Elem::hmax(), libMesh::FEAbstract::n_quadrature_points(), libMesh::TensorTools::norm_sq(), libMesh::Real, libMesh::JumpErrorEstimator::var, and libMesh::SystemNorm::weight().

◆ operator=() [1/2]

DiscontinuityMeasure & libMesh::DiscontinuityMeasure::operator= ( const DiscontinuityMeasure )
delete

◆ operator=() [2/2]

DiscontinuityMeasure & libMesh::DiscontinuityMeasure::operator= ( DiscontinuityMeasure &&  )
default

◆ reduce_error()

void libMesh::ErrorEstimator::reduce_error ( std::vector< ErrorVectorReal > &  error_per_cell,
const Parallel::Communicator comm 
) const
protectedinherited

This method takes the local error contributions in error_per_cell from each processor and combines them to get the global error vector.

Definition at line 32 of file error_estimator.C.

34{
35 // This function must be run on all processors at once
36 // parallel_object_only();
37
38 // Each processor has now computed the error contributions
39 // for its local elements. We may need to sum the vector to
40 // recover the error for each element.
41
42 comm.sum(error_per_cell);
43}

References libMesh::Parallel::Communicator::sum().

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), and libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error().

◆ reinit_sides()

void libMesh::JumpErrorEstimator::reinit_sides ( )
protectedinherited

A utility function to reinit the finite element data on elements sharing a side.

Definition at line 554 of file jump_error_estimator.C.

555{
556 fine_context->side_fe_reinit();
557
558 unsigned short dim = fine_context->get_elem().dim();
559 libmesh_assert_equal_to(dim, coarse_context->get_elem().dim());
560
561 FEBase * fe_fine = nullptr;
562 fine_context->get_side_fe( 0, fe_fine, dim );
563
564 // Get the physical locations of the fine element quadrature points
565 std::vector<Point> qface_point = fe_fine->get_xyz();
566
567 // Find the master quadrature point locations on the coarse element
568 FEBase * fe_coarse = nullptr;
569 coarse_context->get_side_fe( 0, fe_coarse, dim );
570
571 std::vector<Point> qp_coarse;
572
573 FEMap::inverse_map (coarse_context->get_elem().dim(),
574 &coarse_context->get_elem(), qface_point,
575 qp_coarse);
576
577 // The number of variables in the system
578 const unsigned int n_vars = fine_context->n_vars();
579
580 // Calculate all coarse element shape functions at those locations
581 for (unsigned int v=0; v<n_vars; v++)
582 if (error_norm.weight(v) != 0.0 &&
583 fine_context->get_system().variable_type(v).family != SCALAR)
584 {
585 coarse_context->get_side_fe( v, fe_coarse, dim );
586 fe_coarse->reinit (&coarse_context->get_elem(), &qp_coarse);
587 }
588}

References libMesh::JumpErrorEstimator::coarse_context, dim, libMesh::ErrorEstimator::error_norm, libMesh::JumpErrorEstimator::fine_context, libMesh::FEAbstract::get_xyz(), libMesh::FEMap::inverse_map(), n_vars, libMesh::FEAbstract::reinit(), libMesh::SCALAR, and libMesh::SystemNorm::weight().

Referenced by libMesh::JumpErrorEstimator::estimate_error().

◆ type()

ErrorEstimatorType libMesh::DiscontinuityMeasure::type ( ) const
overridevirtual
Returns
The type for the ErrorEstimator subclass.

Implements libMesh::ErrorEstimator.

Definition at line 51 of file discontinuity_measure.C.

52{
54}

References libMesh::DISCONTINUITY_MEASURE.

Member Data Documentation

◆ _bc_function

std::pair< bool, Real >(* libMesh::DiscontinuityMeasure::_bc_function) (const System &system, const Point &p, const std::string &var_name)
protected

Pointer to function that provides BC information.

Definition at line 103 of file discontinuity_measure.h.

Referenced by attach_essential_bc_function(), and boundary_side_integration().

◆ coarse_context

std::unique_ptr<FEMContext> libMesh::JumpErrorEstimator::coarse_context
protectedinherited

◆ coarse_error

Real libMesh::JumpErrorEstimator::coarse_error
protectedinherited

◆ error_norm

SystemNorm libMesh::ErrorEstimator::error_norm
inherited

When estimating the error in a single system, the error_norm is used to control the scaling and norm choice for each variable.

Not all estimators will support all norm choices. The default scaling is for all variables to be weighted equally. The default norm choice depends on the error estimator.

Part of this functionality was supported via component_scale and sobolev_order in older libMesh versions, and a small part was supported via component_mask in even older versions. Hopefully the encapsulation here will allow us to avoid changing this API again.

Definition at line 158 of file error_estimator.h.

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::AdjointRefinementEstimator::AdjointRefinementEstimator(), boundary_side_integration(), libMesh::KellyErrorEstimator::boundary_side_integration(), DiscontinuityMeasure(), libMesh::AdjointResidualErrorEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::ErrorEstimator::estimate_errors(), libMesh::ErrorEstimator::estimate_errors(), libMesh::ExactErrorEstimator::ExactErrorEstimator(), libMesh::ExactErrorEstimator::find_squared_element_error(), init_context(), libMesh::LaplacianErrorEstimator::init_context(), libMesh::KellyErrorEstimator::init_context(), internal_side_integration(), libMesh::LaplacianErrorEstimator::internal_side_integration(), libMesh::KellyErrorEstimator::internal_side_integration(), libMesh::KellyErrorEstimator::KellyErrorEstimator(), libMesh::LaplacianErrorEstimator::LaplacianErrorEstimator(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::PatchRecoveryErrorEstimator::PatchRecoveryErrorEstimator(), libMesh::JumpErrorEstimator::reinit_sides(), and libMesh::UniformRefinementEstimator::UniformRefinementEstimator().

◆ fine_context

std::unique_ptr<FEMContext> libMesh::JumpErrorEstimator::fine_context
protectedinherited

◆ fine_error

Real libMesh::JumpErrorEstimator::fine_error
protectedinherited

◆ integrate_boundary_sides

bool libMesh::JumpErrorEstimator::integrate_boundary_sides
protectedinherited

A boolean flag, by default false, to be set to true if integrations with boundary_side_integration() should be performed.

Definition at line 169 of file jump_error_estimator.h.

Referenced by attach_essential_bc_function(), libMesh::KellyErrorEstimator::attach_flux_bc_function(), and libMesh::JumpErrorEstimator::estimate_error().

◆ integrate_slits

bool libMesh::JumpErrorEstimator::integrate_slits
inherited

A boolean flag, by default false, to be set to true if integrations should be performed on "slits" where two elements' faces overlap even if those elements are not connected by neighbor links.

This may only be useful for flex-IGA meshes, where highly-nonconforming meshes are given pseudo-conforming solutions via nodal constraints.

Note that, to safely use this option in parallel, it is also necessary to expand the default algebraic ghosting requirements to include elements on the opposite sides of slits from local elements.

Definition at line 130 of file jump_error_estimator.h.

Referenced by libMesh::JumpErrorEstimator::estimate_error(), and SlitMeshRefinedSystemTest::testSystem().

◆ scale_by_n_flux_faces

bool libMesh::JumpErrorEstimator::scale_by_n_flux_faces
inherited

This boolean flag allows you to scale the error indicator result for each element by the number of "flux faces" the element actually has.

This tends to weight more evenly cells which are on the boundaries and thus have fewer contributions to their flux. The value is initialized to false, simply set it to true if you want to use the feature.

Definition at line 100 of file jump_error_estimator.h.

Referenced by libMesh::JumpErrorEstimator::estimate_error().

◆ use_unweighted_quadrature_rules

bool libMesh::JumpErrorEstimator::use_unweighted_quadrature_rules
inherited

This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweighted shape functions in master element space) rather than "default" quadrature rules (sized to exactly integrate polynomials of one higher degree than mass matrix terms).

The results with the former, lower-order rules will be somewhat less accurate in many cases but will be much cheaper to compute.

The value is initialized to false, simply set it to true if you want to use the feature.

Definition at line 114 of file jump_error_estimator.h.

Referenced by libMesh::JumpErrorEstimator::estimate_error(), and main().

◆ var

unsigned int libMesh::JumpErrorEstimator::var
protectedinherited

The documentation for this class was generated from the following files: