libMesh
mesh_refinement_flagging.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_config.h"
22 
23 // only compile these functions if the user requests AMR support
24 #ifdef LIBMESH_ENABLE_AMR
25 
26 // C++ includes
27 #include <algorithm> // for std::sort
28 
29 // Local includes
30 #include "libmesh/elem.h"
31 #include "libmesh/error_vector.h"
32 #include "libmesh/mesh_refinement.h"
33 #include "libmesh/mesh_base.h"
34 #include "libmesh/parallel.h"
35 #include "libmesh/remote_elem.h"
36 
37 namespace libMesh
38 {
39 
40 
41 
42 //-----------------------------------------------------------------
43 // Mesh refinement methods
45  const Real refine_frac,
46  const Real coarsen_frac,
47  const unsigned int max_l)
48 {
49  parallel_object_only();
50 
51  // Verify that our error vector is consistent, using std::vector to
52  // avoid confusing this->comm().verify
53  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
54 
55  // The function arguments are currently just there for
56  // backwards_compatibility
58  {
59  // If the user used non-default parameters, lets warn
60  // that they're deprecated
61  if (refine_frac != 0.3 ||
62  coarsen_frac != 0.0 ||
63  max_l != libMesh::invalid_uint)
64  libmesh_deprecated();
65 
66  _refine_fraction = refine_frac;
67  _coarsen_fraction = coarsen_frac;
68  _max_h_level = max_l;
69  }
70 
71  // Check for valid fractions..
72  // The fraction values must be in [0,1]
73  libmesh_assert_greater_equal (_refine_fraction, 0);
74  libmesh_assert_less_equal (_refine_fraction, 1);
75  libmesh_assert_greater_equal (_coarsen_fraction, 0);
76  libmesh_assert_less_equal (_coarsen_fraction, 1);
77 
78  // Clean up the refinement flags. These could be left
79  // over from previous refinement steps.
80  this->clean_refinement_flags();
81 
82  // We're getting the minimum and maximum error values
83  // for the ACTIVE elements
84  Real error_min = 1.e30;
85  Real error_max = 0.;
86 
87  // And, if necessary, for their parents
88  Real parent_error_min = 1.e30;
89  Real parent_error_max = 0.;
90 
91  // Prepare another error vector if we need to sum parent errors
92  ErrorVector error_per_parent;
94  {
95  create_parent_error_vector(error_per_cell,
96  error_per_parent,
97  parent_error_min,
98  parent_error_max);
99  }
100 
101  // We need to loop over all active elements to find the minimum
102  for (auto & elem : _mesh.active_local_element_ptr_range())
103  {
104  const dof_id_type id = elem->id();
105  libmesh_assert_less (id, error_per_cell.size());
106 
107  error_max = std::max (error_max, error_per_cell[id]);
108  error_min = std::min (error_min, error_per_cell[id]);
109  }
110  this->comm().max(error_max);
111  this->comm().min(error_min);
112 
113  // Compute the cutoff values for coarsening and refinement
114  const Real error_delta = (error_max - error_min);
115  const Real parent_error_delta = parent_error_max - parent_error_min;
116 
117  const Real refine_cutoff = (1.- _refine_fraction)*error_max;
118  const Real coarsen_cutoff = _coarsen_fraction*error_delta + error_min;
119  const Real parent_cutoff = _coarsen_fraction*parent_error_delta + error_min;
120 
121  // // Print information about the error
122  // libMesh::out << " Error Information:" << std::endl
123  // << " ------------------" << std::endl
124  // << " min: " << error_min << std::endl
125  // << " max: " << error_max << std::endl
126  // << " delta: " << error_delta << std::endl
127  // << " refine_cutoff: " << refine_cutoff << std::endl
128  // << " coarsen_cutoff: " << coarsen_cutoff << std::endl;
129 
130 
131 
132  // Loop over the elements and flag them for coarsening or
133  // refinement based on the element error
134  for (auto & elem : _mesh.active_element_ptr_range())
135  {
136  const dof_id_type id = elem->id();
137 
138  libmesh_assert_less (id, error_per_cell.size());
139 
140  const ErrorVectorReal elem_error = error_per_cell[id];
141 
143  {
144  Elem * parent = elem->parent();
145  if (parent)
146  {
147  const dof_id_type parentid = parent->id();
148  if (error_per_parent[parentid] >= 0. &&
149  error_per_parent[parentid] <= parent_cutoff)
150  elem->set_refinement_flag(Elem::COARSEN);
151  }
152  }
153  // Flag the element for coarsening if its error
154  // is <= coarsen_fraction*delta + error_min
155  else if (elem_error <= coarsen_cutoff)
156  {
157  elem->set_refinement_flag(Elem::COARSEN);
158  }
159 
160  // Flag the element for refinement if its error
161  // is >= refinement_cutoff.
162  if (elem_error >= refine_cutoff)
163  if (elem->level() < _max_h_level)
164  elem->set_refinement_flag(Elem::REFINE);
165  }
166 }
167 
168 
169 
171 {
172  parallel_object_only();
173 
174  // Verify that our error vector is consistent, using std::vector to
175  // avoid confusing this->comm().verify
176  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell_in)));
177 
178  libmesh_assert_greater (_coarsen_threshold, 0);
179 
180  // Check for valid fractions..
181  // The fraction values must be in [0,1]
182  libmesh_assert_greater_equal (_refine_fraction, 0);
183  libmesh_assert_less_equal (_refine_fraction, 1);
184  libmesh_assert_greater_equal (_coarsen_fraction, 0);
185  libmesh_assert_less_equal (_coarsen_fraction, 1);
186 
187  // How much error per cell will we tolerate?
188  const Real local_refinement_tolerance =
189  _absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem()));
190  const Real local_coarsening_tolerance =
191  local_refinement_tolerance * _coarsen_threshold;
192 
193  // Prepare another error vector if we need to sum parent errors
194  ErrorVector error_per_parent;
196  {
197  Real parent_error_min, parent_error_max;
198 
199  create_parent_error_vector(error_per_cell_in,
200  error_per_parent,
201  parent_error_min,
202  parent_error_max);
203  }
204 
205  for (auto & elem : _mesh.active_element_ptr_range())
206  {
207  Elem * parent = elem->parent();
208  const dof_id_type elem_number = elem->id();
209  const ErrorVectorReal elem_error = error_per_cell_in[elem_number];
210 
211  if (elem_error > local_refinement_tolerance &&
212  elem->level() < _max_h_level)
213  elem->set_refinement_flag(Elem::REFINE);
214 
215  if (!_coarsen_by_parents && elem_error <
216  local_coarsening_tolerance)
217  elem->set_refinement_flag(Elem::COARSEN);
218 
219  if (_coarsen_by_parents && parent)
220  {
221  ErrorVectorReal parent_error = error_per_parent[parent->id()];
222  if (parent_error >= 0.)
223  {
224  const Real parent_coarsening_tolerance =
225  std::sqrt(parent->n_children() *
226  local_coarsening_tolerance *
227  local_coarsening_tolerance);
228  if (parent_error < parent_coarsening_tolerance)
229  elem->set_refinement_flag(Elem::COARSEN);
230  }
231  }
232  }
233 }
234 
235 
236 
238 {
239  parallel_object_only();
240 
241  // Verify that our error vector is consistent, using std::vector to
242  // avoid confusing this->comm().verify
243  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
244 
245  // Check for valid fractions..
246  // The fraction values must be in [0,1]
247  libmesh_assert_greater_equal (_refine_fraction, 0);
248  libmesh_assert_less_equal (_refine_fraction, 1);
249  libmesh_assert_greater_equal (_coarsen_fraction, 0);
250  libmesh_assert_less_equal (_coarsen_fraction, 1);
251 
252  // This function is currently only coded to work when coarsening by
253  // parents - it's too hard to guess how many coarsenings will be
254  // performed otherwise.
256 
257  // The number of active elements in the mesh - hopefully less than
258  // 2 billion on 32 bit machines
259  const dof_id_type n_active_elem = _mesh.n_active_elem();
260 
261  // The maximum number of active elements to flag for coarsening
262  const dof_id_type max_elem_coarsen =
263  static_cast<dof_id_type>(_coarsen_fraction * n_active_elem) + 1;
264 
265  // The maximum number of elements to flag for refinement
266  const dof_id_type max_elem_refine =
267  static_cast<dof_id_type>(_refine_fraction * n_active_elem) + 1;
268 
269  // Clean up the refinement flags. These could be left
270  // over from previous refinement steps.
271  this->clean_refinement_flags();
272 
273  // The target number of elements to add or remove
274  const std::ptrdiff_t n_elem_new =
275  std::ptrdiff_t(_nelem_target) - std::ptrdiff_t(n_active_elem);
276 
277  // Create an vector with active element errors and ids,
278  // sorted by highest errors first
279  const dof_id_type max_elem_id = _mesh.max_elem_id();
280  std::vector<std::pair<ErrorVectorReal, dof_id_type>> sorted_error;
281 
282  sorted_error.reserve (n_active_elem);
283 
284  // On a DistributedMesh, we need to communicate to know which remote ids
285  // correspond to active elements.
286  {
287  std::vector<bool> is_active(max_elem_id, false);
288 
289  for (auto & elem : _mesh.active_local_element_ptr_range())
290  {
291  const dof_id_type eid = elem->id();
292  is_active[eid] = true;
293  libmesh_assert_less (eid, error_per_cell.size());
294  sorted_error.emplace_back(error_per_cell[eid], eid);
295  }
296 
297  this->comm().max(is_active);
298 
299  this->comm().allgather(sorted_error);
300  }
301 
302  // Default sort works since pairs are sorted lexicographically
303  std::sort (sorted_error.begin(), sorted_error.end());
304  std::reverse (sorted_error.begin(), sorted_error.end());
305 
306  // Create a sorted error vector with coarsenable parent elements
307  // only, sorted by lowest errors first
308  ErrorVector error_per_parent;
309  std::vector<std::pair<ErrorVectorReal, dof_id_type>> sorted_parent_error;
310  Real parent_error_min, parent_error_max;
311 
312  create_parent_error_vector(error_per_cell,
313  error_per_parent,
314  parent_error_min,
315  parent_error_max);
316 
317  // create_parent_error_vector sets values for non-parents and
318  // non-coarsenable parents to -1. Get rid of them.
319  for (auto i : index_range(error_per_parent))
320  if (error_per_parent[i] != -1)
321  sorted_parent_error.emplace_back(error_per_parent[i], i);
322 
323  std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
324 
325  // Keep track of how many elements we plan to coarsen & refine
326  dof_id_type coarsen_count = 0;
327  dof_id_type refine_count = 0;
328 
329  const unsigned int dim = _mesh.mesh_dimension();
330  unsigned int twotodim = 1;
331  for (unsigned int i=0; i!=dim; ++i)
332  twotodim *= 2;
333 
334  // First, let's try to get our element count to target_nelem
335  if (n_elem_new >= 0)
336  {
337  // Every element refinement creates at least
338  // 2^dim-1 new elements
339  refine_count =
340  std::min(cast_int<dof_id_type>(n_elem_new / (twotodim-1)),
341  max_elem_refine);
342  }
343  else
344  {
345  // Every successful element coarsening is likely to destroy
346  // 2^dim-1 net elements.
347  coarsen_count =
348  std::min(cast_int<dof_id_type>(-n_elem_new / (twotodim-1)),
349  max_elem_coarsen);
350  }
351 
352  // Next, let's see if we can trade any refinement for coarsening
353  while (coarsen_count < max_elem_coarsen &&
354  refine_count < max_elem_refine &&
355  coarsen_count < sorted_parent_error.size() &&
356  refine_count < sorted_error.size() &&
357  sorted_error[refine_count].first >
358  sorted_parent_error[coarsen_count].first * _coarsen_threshold)
359  {
360  coarsen_count++;
361  refine_count++;
362  }
363 
364  // On a DistributedMesh, we need to communicate to know which remote ids
365  // correspond to refinable elements
366  dof_id_type successful_refine_count = 0;
367  {
368  std::vector<bool> is_refinable(max_elem_id, false);
369 
370  for (const auto & pr : sorted_error)
371  {
372  dof_id_type eid = pr.second;
373  Elem * elem = _mesh.query_elem_ptr(eid);
374  if (elem && elem->level() < _max_h_level)
375  is_refinable[eid] = true;
376  }
377  this->comm().max(is_refinable);
378 
379  if (refine_count > max_elem_refine)
380  refine_count = max_elem_refine;
381  for (const auto & pr : sorted_error)
382  {
383  if (successful_refine_count >= refine_count)
384  break;
385 
386  dof_id_type eid = pr.second;
387  Elem * elem = _mesh.query_elem_ptr(eid);
388  if (is_refinable[eid])
389  {
390  if (elem)
392  successful_refine_count++;
393  }
394  }
395  }
396 
397  // If we couldn't refine enough elements, don't coarsen too many
398  // either
399  if (coarsen_count < (refine_count - successful_refine_count))
400  coarsen_count = 0;
401  else
402  coarsen_count -= (refine_count - successful_refine_count);
403 
404  if (coarsen_count > max_elem_coarsen)
405  coarsen_count = max_elem_coarsen;
406 
407  dof_id_type successful_coarsen_count = 0;
408  if (coarsen_count)
409  {
410  for (const auto & pr : sorted_parent_error)
411  {
412  if (successful_coarsen_count >= coarsen_count * twotodim)
413  break;
414 
415  dof_id_type parent_id = pr.second;
416  Elem * parent = _mesh.query_elem_ptr(parent_id);
417 
418  // On a DistributedMesh we skip remote elements
419  if (!parent)
420  continue;
421 
422  libmesh_assert(parent->has_children());
423  for (auto & elem : parent->child_ref_range())
424  {
425  if (&elem != remote_elem)
426  {
427  libmesh_assert(elem.active());
428  elem.set_refinement_flag(Elem::COARSEN);
429  successful_coarsen_count++;
430  }
431  }
432  }
433  }
434 
435  // Return true if we've done all the AMR/C we can
436  if (!successful_coarsen_count &&
437  !successful_refine_count)
438  return true;
439  // And false if there may still be more to do.
440  return false;
441 }
442 
443 
444 
446  const Real refine_frac,
447  const Real coarsen_frac,
448  const unsigned int max_l)
449 {
450  parallel_object_only();
451 
452  // Verify that our error vector is consistent, using std::vector to
453  // avoid confusing this->comm().verify
454  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
455 
456  // The function arguments are currently just there for
457  // backwards_compatibility
459  {
460  // If the user used non-default parameters, lets warn
461  // that they're deprecated
462  if (refine_frac != 0.3 ||
463  coarsen_frac != 0.0 ||
464  max_l != libMesh::invalid_uint)
465  libmesh_deprecated();
466 
467  _refine_fraction = refine_frac;
468  _coarsen_fraction = coarsen_frac;
469  _max_h_level = max_l;
470  }
471 
472  // Check for valid fractions..
473  // The fraction values must be in [0,1]
474  libmesh_assert_greater_equal (_refine_fraction, 0);
475  libmesh_assert_less_equal (_refine_fraction, 1);
476  libmesh_assert_greater_equal (_coarsen_fraction, 0);
477  libmesh_assert_less_equal (_coarsen_fraction, 1);
478 
479  // The number of active elements in the mesh
480  const dof_id_type n_active_elem = _mesh.n_active_elem();
481 
482  // The number of elements to flag for coarsening
483  const dof_id_type n_elem_coarsen =
484  static_cast<dof_id_type>(_coarsen_fraction * n_active_elem);
485 
486  // The number of elements to flag for refinement
487  const dof_id_type n_elem_refine =
488  static_cast<dof_id_type>(_refine_fraction * n_active_elem);
489 
490 
491 
492  // Clean up the refinement flags. These could be left
493  // over from previous refinement steps.
494  this->clean_refinement_flags();
495 
496 
497  // This vector stores the error and element number for all the
498  // active elements. It will be sorted and the top & bottom
499  // elements will then be flagged for coarsening & refinement
500  std::vector<ErrorVectorReal> sorted_error;
501 
502  sorted_error.reserve (n_active_elem);
503 
504  // Loop over the active elements and create the entry
505  // in the sorted_error vector
506  for (auto & elem : _mesh.active_local_element_ptr_range())
507  sorted_error.push_back (error_per_cell[elem->id()]);
508 
509  this->comm().allgather(sorted_error);
510 
511  // Now sort the sorted_error vector
512  std::sort (sorted_error.begin(), sorted_error.end());
513 
514  // If we're coarsening by parents:
515  // Create a sorted error vector with coarsenable parent elements
516  // only, sorted by lowest errors first
517  ErrorVector error_per_parent, sorted_parent_error;
519  {
520  Real parent_error_min, parent_error_max;
521 
522  create_parent_error_vector(error_per_cell,
523  error_per_parent,
524  parent_error_min,
525  parent_error_max);
526 
527  sorted_parent_error = error_per_parent;
528  std::sort (sorted_parent_error.begin(), sorted_parent_error.end());
529 
530  // All the other error values will be 0., so get rid of them.
531  sorted_parent_error.erase (std::remove(sorted_parent_error.begin(),
532  sorted_parent_error.end(), 0.),
533  sorted_parent_error.end());
534  }
535 
536 
537  ErrorVectorReal top_error= 0., bottom_error = 0.;
538 
539  // Get the maximum error value corresponding to the
540  // bottom n_elem_coarsen elements
541  if (_coarsen_by_parents && n_elem_coarsen)
542  {
543  const unsigned int dim = _mesh.mesh_dimension();
544  unsigned int twotodim = 1;
545  for (unsigned int i=0; i!=dim; ++i)
546  twotodim *= 2;
547 
548  dof_id_type n_parent_coarsen = n_elem_coarsen / (twotodim - 1);
549 
550  if (n_parent_coarsen)
551  bottom_error = sorted_parent_error[n_parent_coarsen - 1];
552  }
553  else if (n_elem_coarsen)
554  {
555  bottom_error = sorted_error[n_elem_coarsen - 1];
556  }
557 
558  if (n_elem_refine)
559  top_error = sorted_error[sorted_error.size() - n_elem_refine];
560 
561  // Finally, let's do the element flagging
562  for (auto & elem : _mesh.active_element_ptr_range())
563  {
564  Elem * parent = elem->parent();
565 
566  if (_coarsen_by_parents && parent && n_elem_coarsen &&
567  error_per_parent[parent->id()] <= bottom_error)
569 
570  if (!_coarsen_by_parents && n_elem_coarsen &&
571  error_per_cell[elem->id()] <= bottom_error)
572  elem->set_refinement_flag(Elem::COARSEN);
573 
574  if (n_elem_refine &&
575  elem->level() < _max_h_level &&
576  error_per_cell[elem->id()] >= top_error)
577  elem->set_refinement_flag(Elem::REFINE);
578  }
579 }
580 
581 
582 
584  const Real refine_frac,
585  const Real coarsen_frac,
586  const unsigned int max_l)
587 {
588  // Verify that our error vector is consistent, using std::vector to
589  // avoid confusing this->comm().verify
590  libmesh_assert(this->comm().verify(dynamic_cast<const std::vector<ErrorVectorReal> &>(error_per_cell)));
591 
592  // The function arguments are currently just there for
593  // backwards_compatibility
595  {
596  // If the user used non-default parameters, lets warn
597  // that they're deprecated
598  if (refine_frac != 0.3 ||
599  coarsen_frac != 0.0 ||
600  max_l != libMesh::invalid_uint)
601  libmesh_deprecated();
602 
603  _refine_fraction = refine_frac;
604  _coarsen_fraction = coarsen_frac;
605  _max_h_level = max_l;
606  }
607 
608  // Get the mean value from the error vector
609  const Real mean = error_per_cell.mean();
610 
611  // Get the standard deviation. This equals the
612  // square-root of the variance
613  const Real stddev = std::sqrt (error_per_cell.variance());
614 
615  // Check for valid fractions
616  libmesh_assert_greater_equal (_refine_fraction, 0);
617  libmesh_assert_less_equal (_refine_fraction, 1);
618  libmesh_assert_greater_equal (_coarsen_fraction, 0);
619  libmesh_assert_less_equal (_coarsen_fraction, 1);
620 
621  // The refine and coarsen cutoff
622  const Real refine_cutoff = mean + _refine_fraction * stddev;
623  const Real coarsen_cutoff = std::max(mean - _coarsen_fraction * stddev, 0.);
624 
625  // Loop over the elements and flag them for coarsening or
626  // refinement based on the element error
627  for (auto & elem : _mesh.active_element_ptr_range())
628  {
629  const dof_id_type id = elem->id();
630 
631  libmesh_assert_less (id, error_per_cell.size());
632 
633  const ErrorVectorReal elem_error = error_per_cell[id];
634 
635  // Possibly flag the element for coarsening ...
636  if (elem_error <= coarsen_cutoff)
637  elem->set_refinement_flag(Elem::COARSEN);
638 
639  // ... or refinement
640  if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
641  elem->set_refinement_flag(Elem::REFINE);
642  }
643 }
644 
645 
646 
648 {
649  element_flagging.flag_elements();
650 }
651 
652 
653 
655 {
656  for (auto & elem : _mesh.element_ptr_range())
657  {
658  if (elem->active())
659  {
660  elem->set_p_refinement_flag(elem->refinement_flag());
661  elem->set_refinement_flag(Elem::DO_NOTHING);
662  }
663  else
664  {
665  elem->set_p_refinement_flag(elem->refinement_flag());
666  elem->set_refinement_flag(Elem::INACTIVE);
667  }
668  }
669 }
670 
671 
672 
674 {
675  for (auto & elem : _mesh.element_ptr_range())
676  elem->set_p_refinement_flag(elem->refinement_flag());
677 }
678 
679 
680 
682 {
683  // Possibly clean up the refinement flags from
684  // a previous step
685  for (auto & elem : _mesh.element_ptr_range())
686  {
687  if (elem->active())
688  {
689  elem->set_refinement_flag(Elem::DO_NOTHING);
690  elem->set_p_refinement_flag(Elem::DO_NOTHING);
691  }
692  else
693  {
694  elem->set_refinement_flag(Elem::INACTIVE);
695  elem->set_p_refinement_flag(Elem::INACTIVE);
696  }
697  }
698 }
699 
700 } // namespace libMesh
701 
702 #endif
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
const Elem * parent() const
Definition: elem.h:3030
virtual dof_id_type n_active_elem() const =0
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
void flag_elements_by_error_tolerance(const ErrorVector &error_per_cell)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell...
MeshBase & _mesh
Reference to the mesh.
unsigned int dim
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
bool flag_elements_by_nelem_target(const ErrorVector &error_per_cell)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell...
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
const Parallel::Communicator & comm() const
virtual Real variance() const override
Definition: error_vector.h:115
virtual unsigned int n_children() const =0
void clean_refinement_flags()
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
void create_parent_error_vector(const ErrorVector &error_per_cell, ErrorVector &error_per_parent, Real &parent_error_min, Real &parent_error_max)
Calculates the error on all coarsenable parents.
The libMesh namespace provides an interface to certain functionality in the library.
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
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
void switch_h_to_p_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to ...
void flag_elements_by_mean_stddev(const ErrorVector &error_per_cell, const Real refine_fraction=1.0, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell...
dof_id_type id() const
Definition: dof_object.h:828
void min(const T &r, T &o, Request &req) const
Abstract base class to be used for user-specified element flagging.
bool _use_member_parameters
For backwards compatibility, we initialize this as false and then set it to true if the user uses any...
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
void flag_elements_by(ElementFlagging &element_flagging)
Flag elements based on a function object.
void flag_elements_by_elem_fraction(const ErrorVector &error_per_cell, const Real refine_fraction=0.3, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell...
unsigned int level() const
Definition: elem.h:3074
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
unsigned int mesh_dimension() const
Definition: mesh_base.C:372
void flag_elements_by_error_fraction(const ErrorVector &error_per_cell, const Real refine_fraction=0.3, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell...
void add_p_to_h_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p ...
bool has_children() const
Definition: elem.h:2979
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:117
bool _coarsen_by_parents
Refinement parameter values.
uint8_t dof_id_type
Definition: id_types.h:67
virtual Real mean() const override
Definition: error_vector.C:69
const RemoteElem * remote_elem
Definition: remote_elem.C:57
virtual void flag_elements()=0
Callback function to be used for marking elements for refinement.