https://mooseframework.inl.gov
SlopeReconstruction1DInterface.h
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 #pragma once
11 
12 #include "MooseObject.h"
13 #include "MooseEnum.h"
14 #include "MooseTypes.h"
15 #include "InputParameters.h"
16 #include "THMEnums.h"
17 
18 #include "libmesh/elem.h"
19 #include "libmesh/vector_value.h"
20 #include "libmesh/point.h"
21 
29 template <bool is_ad>
31 {
32 public:
33  SlopeReconstruction1DInterface(const MooseObject * moose_object);
34 
37  {
38  None,
39  Full,
41  MC,
43  };
45  static const std::map<std::string, ESlopeReconstructionType> _slope_reconstruction_type_to_enum;
46 
53  static MooseEnum getSlopeReconstructionMooseEnum(const std::string & name = "");
54 
55 protected:
63  virtual void
64  getNeighborPrimitiveVariables(const Elem * elem,
65  std::vector<std::vector<GenericReal<is_ad>>> & W_neighbor,
66  std::vector<Point> & x_neighbor) const;
67 
75  std::vector<GenericReal<is_ad>> getElementSlopes(const Elem * elem) const;
76 
89  std::vector<GenericReal<is_ad>>
90  getBoundaryElementSlopes(const std::vector<GenericReal<is_ad>> & W_elem,
91  const Point & x_elem,
92  const RealVectorValue & dir,
93  std::vector<std::vector<GenericReal<is_ad>>> W_neighbor,
94  std::vector<Point> x_neighbor,
95  const std::vector<GenericReal<is_ad>> & W_boundary) const;
96 
108  std::vector<GenericReal<is_ad>>
109  getElementSlopes(const std::vector<GenericReal<is_ad>> & W_elem,
110  const Point & x_elem,
111  const RealVectorValue & dir,
112  const std::vector<std::vector<GenericReal<is_ad>>> & W_neighbor,
113  const std::vector<Point> & x_neighbor) const;
114 
122  virtual std::vector<GenericReal<is_ad>>
123  computeElementPrimitiveVariables(const Elem * elem) const = 0;
124 
126  const MooseObject * const _moose_object;
127 
130 
131 public:
132  static InputParameters validParams();
133 
134 protected:
136  static const unsigned int _n_side;
138  static const unsigned int _n_sten;
139 };
140 
141 namespace THM
142 {
143 template <>
145 stringToEnum<SlopeReconstruction1DInterface<true>::ESlopeReconstructionType>(const std::string & s);
146 
147 template <>
149 stringToEnum<SlopeReconstruction1DInterface<false>::ESlopeReconstructionType>(
150  const std::string & s);
151 }
152 
153 template <bool is_ad>
154 const std::map<std::string,
157  {"NONE", None}, {"FULL", Full}, {"MINMOD", Minmod}, {"MC", MC}, {"SUPERBEE", Superbee}};
158 
159 template <bool is_ad>
160 MooseEnum
162 {
163  return THM::getMooseEnum<SlopeReconstruction1DInterface<is_ad>::ESlopeReconstructionType>(
164  name, _slope_reconstruction_type_to_enum);
165 }
166 
167 template <bool is_ad>
169 
170 template <bool is_ad>
172 
173 template <bool is_ad>
176 {
178 
179  params.addRequiredParam<MooseEnum>(
180  "scheme",
182  "Slope reconstruction scheme");
183 
184  return params;
185 }
186 
187 template <bool is_ad>
189  const MooseObject * moose_object)
190  : _moose_object(moose_object),
192  moose_object->parameters().get<MooseEnum>("scheme")))
193 {
194 }
195 
196 template <bool is_ad>
197 void
199  const Elem * elem,
200  std::vector<std::vector<GenericReal<is_ad>>> & W_neighbor,
201  std::vector<Point> & x_neighbor) const
202 {
203  W_neighbor.clear();
204  x_neighbor.clear();
205  for (unsigned int i_side = 0; i_side < _n_side; i_side++)
206  {
207  auto neighbor = elem->neighbor_ptr(i_side);
208  if (neighbor && (neighbor->processor_id() == _moose_object->processor_id()))
209  {
210  x_neighbor.push_back(neighbor->vertex_average());
211  W_neighbor.push_back(computeElementPrimitiveVariables(neighbor));
212  }
213  }
214 }
215 
216 template <bool is_ad>
217 std::vector<GenericReal<is_ad>>
219 {
220  mooseAssert(elem, "The supplied element is a nullptr.");
221 
222  const auto W_elem = computeElementPrimitiveVariables(elem);
223  const Point x_elem = elem->vertex_average();
224  const RealVectorValue dir = (elem->node_ref(1) - elem->node_ref(0)).unit();
225 
226  std::vector<Point> x_neighbor;
227  std::vector<std::vector<GenericReal<is_ad>>> W_neighbor;
228  getNeighborPrimitiveVariables(elem, W_neighbor, x_neighbor);
229 
230  return getElementSlopes(W_elem, x_elem, dir, W_neighbor, x_neighbor);
231 }
232 
233 template <bool is_ad>
234 std::vector<GenericReal<is_ad>>
236  const std::vector<GenericReal<is_ad>> & W_elem,
237  const Point & x_elem,
238  const RealVectorValue & dir,
239  std::vector<std::vector<GenericReal<is_ad>>> W_neighbor,
240  std::vector<Point> x_neighbor,
241  const std::vector<GenericReal<is_ad>> & W_boundary) const
242 {
243  if (W_neighbor.size() == 1)
244  {
245  W_neighbor.push_back(W_boundary);
246 
247  // The boundary point will be assumed to be the same distance away as neighbor
248  const Point dx = x_elem - x_neighbor[0];
249  const Point x_boundary = x_elem + dx;
250  x_neighbor.push_back(x_boundary);
251  }
252 
253  return getElementSlopes(W_elem, x_elem, dir, W_neighbor, x_neighbor);
254 }
255 
256 template <bool is_ad>
257 std::vector<GenericReal<is_ad>>
259  const std::vector<GenericReal<is_ad>> & W_elem,
260  const Point & x_elem,
261  const RealVectorValue & dir,
262  const std::vector<std::vector<GenericReal<is_ad>>> & W_neighbor,
263  const std::vector<Point> & x_neighbor) const
264 {
265  mooseAssert(x_neighbor.size() == W_neighbor.size(),
266  "Neighbor positions size must equal neighbor solutions size.");
267 
268  // get the number of slopes to be stored
269  const unsigned int n_slopes = W_elem.size();
270 
271  // compute one-sided slope(s)
272  std::vector<std::vector<GenericReal<is_ad>>> slopes_one_sided;
273  for (unsigned int i = 0; i < W_neighbor.size(); i++)
274  {
275  const Real dx = (x_elem - x_neighbor[i]) * dir;
276 
277  std::vector<GenericReal<is_ad>> slopes(n_slopes, 0.0);
278  for (unsigned int m = 0; m < n_slopes; m++)
279  slopes[m] = (W_elem[m] - W_neighbor[i][m]) / dx;
280 
281  slopes_one_sided.push_back(slopes);
282  }
283 
284  // Fill in any missing one-sided slopes and compute central slope
285  std::vector<GenericReal<is_ad>> slopes_central(n_slopes, 0.0);
286  if (W_neighbor.size() == 2)
287  {
288  const Real dx = (x_neighbor[0] - x_neighbor[1]) * dir;
289  for (unsigned int m = 0; m < n_slopes; m++)
290  slopes_central[m] = (W_neighbor[0][m] - W_neighbor[1][m]) / dx;
291  }
292  else if (W_neighbor.size() == 1)
293  {
294  slopes_one_sided.push_back(slopes_one_sided[0]);
295  slopes_central = slopes_one_sided[0];
296  }
297  else // only one element; use zero slopes
298  {
299  slopes_one_sided.push_back(slopes_central);
300  slopes_one_sided.push_back(slopes_central);
301  }
302 
303  // vector for the (possibly limited) slopes
304  std::vector<GenericReal<is_ad>> slopes_limited(n_slopes, 0.0);
305 
306  // limit the slopes
307  switch (_scheme)
308  {
309  // first-order, zero slope
310  case None:
311  break;
312 
313  // full reconstruction; no limitation
314  case Full:
315 
316  slopes_limited = slopes_central;
317  break;
318 
319  // minmod limiter
320  case Minmod:
321 
322  for (unsigned int m = 0; m < n_slopes; m++)
323  {
324  if ((slopes_one_sided[0][m] * slopes_one_sided[1][m]) > 0.0)
325  {
326  if (std::abs(slopes_one_sided[0][m]) < std::abs(slopes_one_sided[1][m]))
327  slopes_limited[m] = slopes_one_sided[0][m];
328  else
329  slopes_limited[m] = slopes_one_sided[1][m];
330  }
331  }
332  break;
333 
334  // MC (monotonized central-difference) limiter
335  case MC:
336 
337  for (unsigned int m = 0; m < n_slopes; m++)
338  {
339  if (slopes_central[m] > 0.0 && slopes_one_sided[0][m] > 0.0 && slopes_one_sided[1][m] > 0.0)
340  slopes_limited[m] = std::min(
341  slopes_central[m], 2.0 * std::min(slopes_one_sided[0][m], slopes_one_sided[1][m]));
342  else if (slopes_central[m] < 0.0 && slopes_one_sided[0][m] < 0.0 &&
343  slopes_one_sided[1][m] < 0.0)
344  slopes_limited[m] = std::max(
345  slopes_central[m], 2.0 * std::max(slopes_one_sided[0][m], slopes_one_sided[1][m]));
346  }
347  break;
348 
349  // superbee limiter
350  case Superbee:
351 
352  for (unsigned int m = 0; m < n_slopes; m++)
353  {
354  GenericReal<is_ad> slope1 = 0.0;
355  GenericReal<is_ad> slope2 = 0.0;
356 
357  // calculate slope1 with minmod
358  if (slopes_one_sided[1][m] > 0.0 && slopes_one_sided[0][m] > 0.0)
359  slope1 = std::min(slopes_one_sided[1][m], 2.0 * slopes_one_sided[0][m]);
360  else if (slopes_one_sided[1][m] < 0.0 && slopes_one_sided[0][m] < 0.0)
361  slope1 = std::max(slopes_one_sided[1][m], 2.0 * slopes_one_sided[0][m]);
362 
363  // calculate slope2 with minmod
364  if (slopes_one_sided[1][m] > 0.0 && slopes_one_sided[0][m] > 0.0)
365  slope2 = std::min(2.0 * slopes_one_sided[1][m], slopes_one_sided[0][m]);
366  else if (slopes_one_sided[1][m] < 0.0 && slopes_one_sided[0][m] < 0.0)
367  slope2 = std::max(2.0 * slopes_one_sided[1][m], slopes_one_sided[0][m]);
368 
369  // calculate slope with maxmod
370  if (slope1 > 0.0 && slope2 > 0.0)
371  slopes_limited[m] = std::max(slope1, slope2);
372  else if (slope1 < 0.0 && slope2 < 0.0)
373  slopes_limited[m] = std::min(slope1, slope2);
374  }
375  break;
376 
377  default:
378  mooseError("Unknown slope reconstruction scheme");
379  break;
380  }
381  return slopes_limited;
382 }
SlopeReconstruction1DInterface(const MooseObject *moose_object)
Moose::GenericType< Real, is_ad > GenericReal
const MooseObject *const _moose_object
MooseObject this interface is extending.
virtual void getNeighborPrimitiveVariables(const Elem *elem, std::vector< std::vector< GenericReal< is_ad >>> &W_neighbor, std::vector< Point > &x_neighbor) const
Gets the primitive solution vector and position of neighbor(s)
Monotonized Central-Difference slope limiter.
static const unsigned int _n_sten
Number of elemental values in stencil for computing slopes.
void mooseError(Args &&... args)
Full reconstruction; no limitation.
T stringToEnum(const std::string &s)
Converts a string to an enum.
void addRequiredParam(const std::string &name, const std::string &doc_string)
InputParameters emptyInputParameters()
static const std::map< std::string, ESlopeReconstructionType > _slope_reconstruction_type_to_enum
Map of slope reconstruction type string to enum.
const ESlopeReconstructionType _scheme
Slope reconstruction scheme.
const std::string name
Definition: Setup.h:20
std::vector< GenericReal< is_ad > > getBoundaryElementSlopes(const std::vector< GenericReal< is_ad >> &W_elem, const Point &x_elem, const RealVectorValue &dir, std::vector< std::vector< GenericReal< is_ad >>> W_neighbor, std::vector< Point > x_neighbor, const std::vector< GenericReal< is_ad >> &W_boundary) const
Gets limited slopes for the primitive variables in the 1-D direction for boundary element...
static const unsigned int _n_side
Number of sides.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Interface class for 1-D slope reconstruction.
virtual std::vector< GenericReal< is_ad > > computeElementPrimitiveVariables(const Elem *elem) const =0
Computes the cell-average primitive variable values for an element.
std::vector< GenericReal< is_ad > > getElementSlopes(const Elem *elem) const
Gets limited slopes for the primitive variables in the 1-D direction.
const Elem & get(const ElemType type_in)
static MooseEnum getSlopeReconstructionMooseEnum(const std::string &name="")
Gets a MooseEnum for slope reconstruction type.