https://mooseframework.inl.gov
ElementQualityChecker.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "ElementQualityChecker.h"
11 #include "MooseError.h"
12 #include "Conversion.h"
13 
14 #include "libmesh/elem_quality.h"
15 #include "libmesh/enum_elem_quality.h"
16 #include "libmesh/string_to_enum.h"
17 
18 #include <limits>
19 
22 {
23  return MooseEnum("ASPECT_RATIO SKEW SHEAR SHAPE MAX_ANGLE MIN_ANGLE CONDITION DISTORTION TAPER "
24  "WARP STRETCH DIAGONAL ASPECT_RATIO_BETA ASPECT_RATIO_GAMMA SIZE JACOBIAN");
25 }
26 
29 {
30  return MooseEnum("WARNING ERROR", "WARNING");
31 }
32 
34 
37 {
39  params.addClassDescription("Class to check the quality of each element using different metrics "
40  "from libmesh.");
41 
42  params.addRequiredParam<MooseEnum>("metric_type",
44  "Type of quality metric to be checked");
45  params.addParam<Real>("upper_bound", "The upper bound for provided metric type");
46  params.addParam<Real>("lower_bound", "The lower bound for provided metric type");
47  params.addParam<bool>("suppress_invalid_metric_warning",
48  false,
49  "Whether to print the warning related to the quality metric type not being "
50  "applicable to a given element type.");
51  params.addParam<MooseEnum>("failure_type",
53  "The way how the failure of quality metric check should respond");
54  params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL;
55 
56  return params;
57 }
58 
60  : ElementUserObject(parameters),
61  _m_type(getParam<MooseEnum>("metric_type").getEnum<libMesh::ElemQuality>()),
62  _has_upper_bound(isParamValid("upper_bound")),
63  _has_lower_bound(isParamValid("lower_bound")),
64  _upper_bound(_has_upper_bound ? getParam<Real>("upper_bound") : 0.0),
65  _lower_bound(_has_lower_bound ? getParam<Real>("lower_bound") : 0.0),
66  _m_min(std::numeric_limits<Real>::max()),
67  _m_max(std::numeric_limits<Real>::lowest()),
68  _m_sum(0),
69  _suppress_invalid_metric_warning(getParam<bool>("suppress_invalid_metric_warning")),
70  _failure_type(getParam<MooseEnum>("failure_type").getEnum<FailureType>())
71 {
72 }
73 
74 void
76 {
78  _m_max = std::numeric_limits<Real>::lowest();
79  _m_sum = 0;
81  _elem_ids.clear();
82  _bypassed = false;
83  _bypassed_elem_type.clear();
84 }
85 
86 void
88 {
89  // obtain the available quality metric for current ElemType
90  std::vector<libMesh::ElemQuality> metrics_avail = libMesh::Quality::valid(_current_elem->type());
91 
92  // check whether the provided quality metric is applicable to current ElemType
93  if (!checkMetricApplicability(_m_type, metrics_avail))
94  {
95  _bypassed = true;
96  _bypassed_elem_type.insert(Utility::enum_to_string(_current_elem->type()));
97 
98  return;
99  }
100 
101  std::pair<Real, Real> default_bounds = _current_elem->qual_bounds(_m_type);
102  std::pair<Real, Real> actual_bounds;
104  {
105  if (_lower_bound >= _upper_bound)
106  mooseError("Provided lower bound should be less than provided upper bound!");
107 
108  actual_bounds = std::make_pair(_lower_bound, _upper_bound);
109  }
110  else if (_has_lower_bound)
111  {
112  if (_lower_bound >= default_bounds.second)
113  mooseError("Provided lower bound should less than the default upper bound: ",
114  default_bounds.second);
115 
116  actual_bounds = std::make_pair(_lower_bound, default_bounds.second);
117  }
118  else if (_has_upper_bound)
119  {
120  if (_upper_bound <= default_bounds.first)
121  mooseError("Provided upper bound should larger than the default lower bound: ",
122  default_bounds.first);
123 
124  actual_bounds = std::make_pair(default_bounds.first, _upper_bound);
125  }
126  else
127  actual_bounds = default_bounds;
128 
129  // calculate and save quality metric value for current element
130  Real mv = _current_elem->quality(_m_type);
131 
132  _checked_elem_num += 1;
133  _m_sum += mv;
134  if (mv < _m_min)
135  _m_min = mv;
136  if (mv > _m_max)
137  _m_max = mv;
138 
139  // check element quality metric, save ids of elements whose quality metrics exceeds the preset
140  // bounds
141  if (mv < actual_bounds.first || mv > actual_bounds.second)
142  _elem_ids.insert(_current_elem->id());
143 }
144 
145 void
147 {
148  const auto & eqc = static_cast<const ElementQualityChecker &>(uo);
149  _elem_ids.insert(eqc._elem_ids.begin(), eqc._elem_ids.end());
150  _bypassed_elem_type.insert(eqc._bypassed_elem_type.begin(), eqc._bypassed_elem_type.end());
151  _bypassed |= eqc._bypassed;
152  _m_sum += eqc._m_sum;
153  _checked_elem_num += eqc._checked_elem_num;
154 
155  if (_m_min > eqc._m_min)
156  _m_min = eqc._m_min;
157  if (_m_max < eqc._m_max)
158  _m_max = eqc._m_max;
159 }
160 
161 void
163 {
171 
172  if (_bypassed)
174  mooseWarning("Provided quality metric doesn't apply to following element type: " +
176 
177  _console << libMesh::Quality::name(_m_type) << " Metric values:\n";
178  if (_checked_elem_num)
179  {
180  _console << " Minimum: " << _m_min << "\n";
181  _console << " Maximum: " << _m_max << "\n";
182  _console << " Average: " << _m_sum / _checked_elem_num << "\n";
183  }
184  else
185  _console << " No elements were checked.\n";
186 
187  if (!_elem_ids.empty())
188  {
189  switch (_failure_type)
190  {
192  {
193  mooseWarning("List of failed element IDs: ", Moose::stringify(_elem_ids));
194  break;
195  }
196 
197  case FailureType::ERROR:
198  {
199  mooseError("List of failed element IDs: ", Moose::stringify(_elem_ids));
200  break;
201  }
202 
203  default:
204  mooseError("Unknown failure type!");
205  }
206  }
207 
208  _console << std::flush;
209 }
210 
211 bool
213  const libMesh::ElemQuality & elem_metric,
214  const std::vector<libMesh::ElemQuality> & elem_metrics)
215 {
216  bool has_metric = false;
217 
218  for (unsigned int i = 0; i < elem_metrics.size(); ++i)
219  if (elem_metric == elem_metrics[i])
220  has_metric = true;
221 
222  return has_metric;
223 }
std::string name(const ElemQuality q)
void initialize() override
Called before execute() is ever called so that data can be cleared.
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
const FailureType _failure_type
void execute() override
Execute method.
std::set< dof_id_type > _elem_ids
set to save ids for all failed elements
static InputParameters validParams()
unsigned int _checked_elem_num
number of checked elements
bool checkMetricApplicability(const libMesh::ElemQuality &elem_metric, const std::vector< libMesh::ElemQuality > &elem_metrics)
void finalize() override
Finalize.
registerMooseObject("MooseApp", ElementQualityChecker)
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & _communicator
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
auto max(const L &left, const R &right)
static InputParameters validParams()
void mooseWarning(Args &&... args) const
bool _bypassed
whether the element quality check is bypassed or not
void min(const T &r, T &o, Request &req) const
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:54
static MooseEnum FailureMessageType()
ElemQuality
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
void threadJoin(const UserObject &uo) override
Must override.
Real _m_min
minimum, maximum and summation of quality metric values of all checked elements
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
ElementQualityChecker(const InputParameters &parameters)
const Elem *const & _current_elem
The current element pointer (available during execute())
void max(const T &r, T &o, Request &req) const
static MooseEnum QualityMetricType()
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:271
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
std::set< std::string > _bypassed_elem_type
set to save bypassed element type
libMesh::ElemQuality _m_type
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
const bool _suppress_invalid_metric_warning
Whether to print element applicability warning for bypassed elements.
std::vector< ElemQuality > valid(const ElemType t)
Base class for user-specific data.
Definition: UserObject.h:19
void set_union(T &data, const unsigned int root_id) const
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:30