www.mooseframework.org
ElementQualityChecker.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
20 {
21  return MooseEnum("ASPECT_RATIO SKEW SHEAR SHAPE MAX_ANGLE MIN_ANGLE CONDITION DISTORTION TAPER "
22  "WARP STRETCH DIAGONAL ASPECT_RATIO_BETA ASPECT_RATIO_GAMMA SIZE JACOBIAN");
23 }
24 
27 {
28  return MooseEnum("WARNING ERROR", "WARNING");
29 }
30 
32 
33 template <>
36 {
38  params.addClassDescription("Class to check the quality of each element using different metrics "
39  "from libmesh.");
40 
41  params.addRequiredParam<MooseEnum>("metric_type",
43  "Type of quality metric to be checked");
44  params.addParam<Real>("upper_bound", "the upper bound for provided metric type");
45  params.addParam<Real>("lower_bound", "The lower bound for provided metric type");
46  params.addParam<MooseEnum>("failure_type",
48  "The way how the failure of quality metric check should respond");
49  params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL;
50 
51  return params;
52 }
53 
55  : ElementUserObject(parameters),
56  _m_type(getParam<MooseEnum>("metric_type").getEnum<ElemQuality>()),
57  _has_upper_bound(isParamValid("upper_bound")),
58  _has_lower_bound(isParamValid("lower_bound")),
59  _upper_bound(_has_upper_bound ? getParam<Real>("upper_bound") : 0.0),
60  _lower_bound(_has_lower_bound ? getParam<Real>("lower_bound") : 0.0),
61  _m_min(0),
62  _m_max(0),
63  _m_sum(0),
64  _failure_type(getParam<MooseEnum>("failure_type").getEnum<FailureType>())
65 {
66 }
67 
68 void
70 {
71  _m_min = 0;
72  _m_max = 0;
73  _m_sum = 0;
75  _elem_ids.clear();
76  _bypassed = false;
77  _bypassed_elem_type.clear();
78 }
79 
80 void
82 {
83  // obtain the available quality metric for current ElemType
84  std::vector<ElemQuality> metrics_avail = libMesh::Quality::valid(_current_elem->type());
85 
86  // check whether the provided quality metric is applicable to current ElemType
87  if (!checkMetricApplicability(_m_type, metrics_avail))
88  {
89  _bypassed = true;
90  _bypassed_elem_type.insert(Utility::enum_to_string(_current_elem->type()));
91 
92  return;
93  }
94 
95  std::pair<Real, Real> default_bounds = _current_elem->qual_bounds(_m_type);
96  std::pair<Real, Real> actual_bounds;
98  {
100  mooseError("Provided lower bound should be less than provided upper bound!");
101 
102  actual_bounds = std::make_pair(_lower_bound, _upper_bound);
103  }
104  else if (_has_lower_bound)
105  {
106  if (_lower_bound >= default_bounds.second)
107  mooseError("Provided lower bound should less than the default upper bound: ",
108  default_bounds.second);
109 
110  actual_bounds = std::make_pair(_lower_bound, default_bounds.second);
111  }
112  else if (_has_upper_bound)
113  {
114  if (_upper_bound <= default_bounds.first)
115  mooseError("Provided upper bound should larger than the default lower bound: ",
116  default_bounds.first);
117 
118  actual_bounds = std::make_pair(default_bounds.first, _upper_bound);
119  }
120  else
121  actual_bounds = default_bounds;
122 
123  // calculate and save quality metric value for current element
124  Real mv = _current_elem->quality(_m_type);
125 
126  _checked_elem_num += 1;
127  _m_sum += mv;
128  if (mv > _m_max)
129  _m_max = mv;
130  else if (mv < _m_min)
131  _m_min = mv;
132 
133  // check element quality metric, save ids of elements whose quality metrics exceeds the preset
134  // bounds
135  if (mv < actual_bounds.first || mv > actual_bounds.second)
136  _elem_ids.insert(_current_elem->id());
137 }
138 
139 void
141 {
142  const ElementQualityChecker & eqc = static_cast<const ElementQualityChecker &>(uo);
143  _elem_ids.insert(eqc._elem_ids.begin(), eqc._elem_ids.end());
144  _bypassed_elem_type.insert(eqc._bypassed_elem_type.begin(), eqc._bypassed_elem_type.end());
145  _bypassed |= eqc._bypassed;
146  _m_sum += eqc._m_sum;
148 
149  if (_m_min > eqc._m_min)
150  _m_min = eqc._m_min;
151  if (_m_max < eqc._m_max)
152  _m_max = eqc._m_max;
153 }
154 
155 void
157 {
158  _communicator.min(_m_min);
159  _communicator.max(_m_max);
160  _communicator.sum(_m_sum);
161  _communicator.sum(_checked_elem_num);
162  _communicator.set_union(_elem_ids);
163  _communicator.max(_bypassed);
164  _communicator.set_union(_bypassed_elem_type);
165 
166  if (_bypassed)
167  mooseWarning("Provided quality metric doesn't apply to following element type: " +
169 
170  _console << libMesh::Quality::name(_m_type) << " Metric values:"
171  << "\n";
172  _console << " Minimum: " << _m_min << "\n";
173  _console << " Maximum: " << _m_max << "\n";
174  _console << " Average: " << _m_sum / _checked_elem_num << "\n";
175 
176  if (!_elem_ids.empty())
177  {
178  switch (_failure_type)
179  {
181  {
182  mooseWarning("List of failed element IDs: ", Moose::stringify(_elem_ids));
183  break;
184  }
185 
186  case FailureType::ERROR:
187  {
188  mooseError("List of failed element IDs: ", Moose::stringify(_elem_ids));
189  break;
190  }
191 
192  default:
193  mooseError("Unknown failure type!");
194  }
195  }
196 }
197 
198 bool
199 ElementQualityChecker::checkMetricApplicability(const ElemQuality & elem_metric,
200  const std::vector<ElemQuality> & elem_metrics)
201 {
202  bool has_metric = false;
203 
204  for (unsigned int i = 0; i < elem_metrics.size(); ++i)
205  if (elem_metric == elem_metrics[i])
206  has_metric = true;
207 
208  return has_metric;
209 }
InputParameters validParams< ElementUserObject >()
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:24
const FailureType _failure_type
void execute() override
Execute method.
void mooseWarning(Args &&... args) const
Definition: MooseObject.h:155
std::set< dof_id_type > _elem_ids
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.
bool checkMetricApplicability(const ElemQuality &elem_metric, const std::vector< ElemQuality > &elem_metrics)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
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...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
static MooseEnum FailureMessageType()
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:60
void threadJoin(const UserObject &uo) override
Must override.
InputParameters validParams< ElementQualityChecker >()
ElementQualityChecker(const InputParameters &parameters)
const Elem *const & _current_elem
The current element pointer (available during execute())
static MooseEnum QualityMetricType()
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 option parameter and a documentation string to the InputParameters object...
std::set< std::string > _bypassed_elem_type
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
Base class for user-specific data.
Definition: UserObject.h:37
const ExecFlagType EXEC_INITIAL