https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
29template <bool is_ad>
31{
32public:
34
45 static const std::map<std::string, ESlopeReconstructionType> _slope_reconstruction_type_to_enum;
46
53 static MooseEnum getSlopeReconstructionMooseEnum(const std::string & name = "");
54
55protected:
63 virtual void
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
127
130
131public:
133
134protected:
136 static const unsigned int _n_side;
138 static const unsigned int _n_sten;
139};
140
141namespace THM
142{
143template <>
145stringToEnum<SlopeReconstruction1DInterface<true>::ESlopeReconstructionType>(const std::string & s);
146
147template <>
149stringToEnum<SlopeReconstruction1DInterface<false>::ESlopeReconstructionType>(
150 const std::string & s);
151}
152
153template <bool is_ad>
154const std::map<std::string,
157 {"NONE", None}, {"FULL", Full}, {"MINMOD", Minmod}, {"MC", MC}, {"SUPERBEE", Superbee}};
158
159template <bool is_ad>
162{
163 return THM::getMooseEnum<SlopeReconstruction1DInterface<is_ad>::ESlopeReconstructionType>(
164 name, _slope_reconstruction_type_to_enum);
165}
166
167template <bool is_ad>
169
170template <bool is_ad>
172
173template <bool is_ad>
176{
178
180 "scheme",
182 "Slope reconstruction scheme");
183
184 return params;
185}
186
187template <bool is_ad>
189 const MooseObject * moose_object)
190 : _moose_object(moose_object),
191 _scheme(THM::stringToEnum<ESlopeReconstructionType>(
192 moose_object->parameters().get<MooseEnum>("scheme")))
193{
194}
195
196template <bool is_ad>
197void
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
216template <bool is_ad>
217std::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
233template <bool is_ad>
234std::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
256template <bool is_ad>
257std::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 using std::abs, std::min, std::max;
269
270 // get the number of slopes to be stored
271 const unsigned int n_slopes = W_elem.size();
272
273 // compute one-sided slope(s)
274 std::vector<std::vector<GenericReal<is_ad>>> slopes_one_sided;
275 for (unsigned int i = 0; i < W_neighbor.size(); i++)
276 {
277 const Real dx = (x_elem - x_neighbor[i]) * dir;
278
279 std::vector<GenericReal<is_ad>> slopes(n_slopes, 0.0);
280 for (unsigned int m = 0; m < n_slopes; m++)
281 slopes[m] = (W_elem[m] - W_neighbor[i][m]) / dx;
282
283 slopes_one_sided.push_back(slopes);
284 }
285
286 // Fill in any missing one-sided slopes and compute central slope
287 std::vector<GenericReal<is_ad>> slopes_central(n_slopes, 0.0);
288 if (W_neighbor.size() == 2)
289 {
290 const Real dx = (x_neighbor[0] - x_neighbor[1]) * dir;
291 for (unsigned int m = 0; m < n_slopes; m++)
292 slopes_central[m] = (W_neighbor[0][m] - W_neighbor[1][m]) / dx;
293 }
294 else if (W_neighbor.size() == 1)
295 {
296 slopes_one_sided.push_back(slopes_one_sided[0]);
297 slopes_central = slopes_one_sided[0];
298 }
299 else // only one element; use zero slopes
300 {
301 slopes_one_sided.push_back(slopes_central);
302 slopes_one_sided.push_back(slopes_central);
303 }
304
305 // vector for the (possibly limited) slopes
306 std::vector<GenericReal<is_ad>> slopes_limited(n_slopes, 0.0);
307
308 // limit the slopes
309 switch (_scheme)
310 {
311 // first-order, zero slope
312 case None:
313 break;
314
315 // full reconstruction; no limitation
316 case Full:
317
318 slopes_limited = slopes_central;
319 break;
320
321 // minmod limiter
322 case Minmod:
323
324 for (unsigned int m = 0; m < n_slopes; m++)
325 {
326 if ((slopes_one_sided[0][m] * slopes_one_sided[1][m]) > 0.0)
327 {
328 if (abs(slopes_one_sided[0][m]) < abs(slopes_one_sided[1][m]))
329 slopes_limited[m] = slopes_one_sided[0][m];
330 else
331 slopes_limited[m] = slopes_one_sided[1][m];
332 }
333 }
334 break;
335
336 // MC (monotonized central-difference) limiter
337 case MC:
338
339 for (unsigned int m = 0; m < n_slopes; m++)
340 {
341 if (slopes_central[m] > 0.0 && slopes_one_sided[0][m] > 0.0 && slopes_one_sided[1][m] > 0.0)
342 slopes_limited[m] =
343 min(slopes_central[m], 2.0 * min(slopes_one_sided[0][m], slopes_one_sided[1][m]));
344 else if (slopes_central[m] < 0.0 && slopes_one_sided[0][m] < 0.0 &&
345 slopes_one_sided[1][m] < 0.0)
346 slopes_limited[m] =
347 max(slopes_central[m], 2.0 * max(slopes_one_sided[0][m], slopes_one_sided[1][m]));
348 }
349 break;
350
351 // superbee limiter
352 case Superbee:
353
354 for (unsigned int m = 0; m < n_slopes; m++)
355 {
356 GenericReal<is_ad> slope1 = 0.0;
357 GenericReal<is_ad> slope2 = 0.0;
358
359 // calculate slope1 with minmod
360 if (slopes_one_sided[1][m] > 0.0 && slopes_one_sided[0][m] > 0.0)
361 slope1 = min(slopes_one_sided[1][m], 2.0 * slopes_one_sided[0][m]);
362 else if (slopes_one_sided[1][m] < 0.0 && slopes_one_sided[0][m] < 0.0)
363 slope1 = max(slopes_one_sided[1][m], 2.0 * slopes_one_sided[0][m]);
364
365 // calculate slope2 with minmod
366 if (slopes_one_sided[1][m] > 0.0 && slopes_one_sided[0][m] > 0.0)
367 slope2 = min(2.0 * slopes_one_sided[1][m], slopes_one_sided[0][m]);
368 else if (slopes_one_sided[1][m] < 0.0 && slopes_one_sided[0][m] < 0.0)
369 slope2 = max(2.0 * slopes_one_sided[1][m], slopes_one_sided[0][m]);
370
371 // calculate slope with maxmod
372 if (slope1 > 0.0 && slope2 > 0.0)
373 slopes_limited[m] = max(slope1, slope2);
374 else if (slope1 < 0.0 && slope2 < 0.0)
375 slopes_limited[m] = min(slope1, slope2);
376 }
377 break;
378
379 default:
380 mooseError("Unknown slope reconstruction scheme");
381 break;
382 }
383 return slopes_limited;
384}
InputParameters emptyInputParameters()
void mooseError(Args &&... args)
Moose::GenericType< Real, is_ad > GenericReal
const std::string name
Definition Setup.h:21
void addRequiredParam(const std::string &name, const std::string &doc_string)
Interface class for 1-D slope reconstruction.
const ESlopeReconstructionType _scheme
Slope reconstruction scheme.
std::vector< GenericReal< is_ad > > getElementSlopes(const std::vector< GenericReal< is_ad > > &W_elem, const Point &x_elem, const RealVectorValue &dir, const std::vector< std::vector< GenericReal< is_ad > > > &W_neighbor, const std::vector< Point > &x_neighbor) const
Gets limited slopes for the primitive variables in the 1-D direction.
virtual std::vector< GenericReal< is_ad > > computeElementPrimitiveVariables(const Elem *elem) const =0
Computes the cell-average primitive variable values for an element.
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)
static const unsigned int _n_sten
Number of elemental values in stencil for computing slopes.
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.
ESlopeReconstructionType
Slope reconstruction type.
@ None
No reconstruction; Godunov scheme.
@ Full
Full reconstruction; no limitation.
@ MC
Monotonized Central-Difference slope limiter.
static const unsigned int _n_side
Number of sides.
static const std::map< std::string, ESlopeReconstructionType > _slope_reconstruction_type_to_enum
Map of slope reconstruction type string to enum.
const MooseObject *const _moose_object
MooseObject this interface is extending.
static MooseEnum getSlopeReconstructionMooseEnum(const std::string &name="")
Gets a MooseEnum for slope reconstruction type.
SlopeReconstruction1DInterface(const MooseObject *moose_object)
std::vector< GenericReal< is_ad > > getElementSlopes(const Elem *elem) const
Gets limited slopes for the primitive variables in the 1-D direction.