https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AEFVSlopeLimitingOneD.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
11
13
16{
18 params.addClassDescription("One-dimensional slope limiting to get the limited slope of cell "
19 "average variable for the advection equation using a cell-centered "
20 "finite volume method.");
21 params.addRequiredCoupledVar("u", "constant monomial variable");
22 MooseEnum scheme("none minmod mc superbee", "none");
23 params.addParam<MooseEnum>("scheme", scheme, "TVD-type slope limiting scheme");
24 return params;
25}
26
28 : SlopeLimitingBase(parameters), _u(getVar("u", 0)), _scheme(getParam<MooseEnum>("scheme"))
29{
30}
31
32std::vector<RealGradient>
34{
35 // you should know how many equations you are solving and assign this number
36 // e.g. = 1 (for the advection equation)
37 unsigned int nvars = 1;
38
39 const Elem * elem = _current_elem;
40
41 // index of conserved variable
42 unsigned int iv;
43
44 // index of sides around an element
45 unsigned int is;
46
47 // index of the neighbor element
48 unsigned int in;
49
50 // number of sides surrounding an element = 2 in 1D
51 unsigned int nside = elem->n_sides();
52
53 // number of reconstruction stencils = 3 in 1D
54 unsigned int nsten = nside + 1;
55
56 // vector for the gradients of primitive variables
57 std::vector<RealGradient> ugrad(nvars, RealGradient(0., 0., 0.));
58
59 // array to store center coordinates of this cell and its neighbor cells
60 std::vector<Real> xc(nsten, 0.);
61
62 // the first always stores the current cell
63 xc[0] = elem->vertex_average()(0);
64
65 // array for the cell-average values in the current cell and its neighbors
66 std::vector<std::vector<Real>> ucell(nsten, std::vector<Real>(nvars, 0.));
67
68 // central slope:
69 // u_{i+1} - u {i-1}
70 // -----------------
71 // x_{i+1} - x_{i-1}
72
73 // left-side slope:
74 // u_{i} - u {i-1}
75 // ---------------
76 // x_{i} - x_{i-1}
77
78 // right-side slope:
79 // u_{i+1} - u {i}
80 // ---------------
81 // x_{i+1} - x_{i}
82
83 // array to store the central and one-sided slopes, where the first should be central slope
84 std::vector<std::vector<Real>> sigma(nsten, std::vector<Real>(nvars, 0.));
85
86 // get the cell-average variable in the central cell
87 if (_is_implicit)
88 ucell[0][0] = _u->getElementalValue(elem);
89 else
90 ucell[0][0] = _u->getElementalValueOld(elem);
91
92 // a flag to indicate the boundary side of the current cell
93
94 unsigned int bflag = 0;
95
96 // loop over the sides to compute the one-sided slopes
97
98 for (is = 0; is < nside; is++)
99 {
100 in = is + 1;
101
102 // when the current element is an internal cell
103 if (elem->neighbor_ptr(is) != NULL)
104 {
105 const Elem * neig = elem->neighbor_ptr(is);
106 if (this->hasBlocks(neig->subdomain_id()))
107 {
108 xc[in] = neig->vertex_average()(0);
109
110 // get the cell-average variable in this neighbor cell
111 if (_is_implicit)
112 ucell[in][0] = _u->getElementalValue(neig);
113 else
114 ucell[in][0] = _u->getElementalValueOld(neig);
115
116 // calculate the one-sided slopes of primitive variables
117
118 for (iv = 0; iv < nvars; iv++)
119 sigma[in][iv] = (ucell[0][iv] - ucell[in][iv]) / (xc[0] - xc[in]);
120 }
121 else
122 bflag = in;
123 }
124 // when the current element is at the boundary,
125 // we choose not to construct the slope in 1D just for convenience.
126 else
127 {
128 bflag = in;
129 }
130 }
131
132 // calculate the slope of the current element
133 // according to the choice of the slope limiter algorithm
134
135 switch (_scheme)
136 {
137 // first-order, zero slope
138 case 0:
139 break;
140
141 // ==============
142 // minmod limiter
143 // ==============
144 case 1:
145
146 if (bflag == 0)
147 {
148 for (iv = 0; iv < nvars; iv++)
149 {
150 if ((sigma[1][iv] * sigma[2][iv]) > 0.)
151 {
152 if (std::abs(sigma[1][iv]) < std::abs(sigma[2][iv]))
153 ugrad[iv](0) = sigma[1][iv];
154 else
155 ugrad[iv](0) = sigma[2][iv];
156 }
157 }
158 }
159 break;
160
161 // ===========================================
162 // MC (monotonized central-difference limiter)
163 // ===========================================
164 case 2:
165
166 if (bflag == 0)
167 {
168 for (iv = 0; iv < nvars; iv++)
169 sigma[0][iv] = (ucell[1][iv] - ucell[2][iv]) / (xc[1] - xc[2]);
170
171 for (iv = 0; iv < nvars; iv++)
172 {
173 if (sigma[0][iv] > 0. && sigma[1][iv] > 0. && sigma[2][iv] > 0.)
174 ugrad[iv](0) = std::min(sigma[0][iv], 2. * std::min(sigma[1][iv], sigma[2][iv]));
175 else if (sigma[0][iv] < 0. && sigma[1][iv] < 0. && sigma[2][iv] < 0.)
176 ugrad[iv](0) = std::max(sigma[0][iv], 2. * std::max(sigma[1][iv], sigma[2][iv]));
177 }
178 }
179 break;
180
181 // ================
182 // Superbee limiter
183 // ================
184 case 3:
185
186 if (bflag == 0)
187 {
188 for (iv = 0; iv < nvars; iv++)
189 {
190 Real sigma1 = 0.;
191 Real sigma2 = 0.;
192
193 // calculate sigma1 with minmod
194 if (sigma[2][iv] > 0. && sigma[1][iv] > 0.)
195 sigma1 = std::min(sigma[2][iv], 2. * sigma[1][iv]);
196 else if (sigma[2][iv] < 0. && sigma[1][iv] < 0.)
197 sigma1 = std::max(sigma[2][iv], 2. * sigma[1][iv]);
198
199 // calculate sigma2 with minmod
200 if (sigma[2][iv] > 0. && sigma[1][iv] > 0.)
201 sigma2 = std::min(2. * sigma[2][iv], sigma[1][iv]);
202 else if (sigma[2][iv] < 0. && sigma[1][iv] < 0.)
203 sigma2 = std::max(2. * sigma[2][iv], sigma[1][iv]);
204
205 // calculate sigma with maxmod
206 if (sigma1 > 0. && sigma2 > 0.)
207 ugrad[iv](0) = std::max(sigma1, sigma2);
208 else if (sigma1 < 0. && sigma2 < 0.)
209 ugrad[iv](0) = std::min(sigma1, sigma2);
210 }
211 }
212 break;
213
214 default:
215 mooseError("Unknown 1D TVD-type slope limiter scheme");
216 break;
217 }
218
219 return ugrad;
220}
registerMooseObject("RdgApp", AEFVSlopeLimitingOneD)
PetscInt nvars
One-dimensional slope limiting to get the limited slope of cell average variable for the advection eq...
MooseVariable * _u
the input variable
virtual std::vector< RealGradient > limitElementSlope() const override
compute the limited slope of the cell
MooseEnum _scheme
One-D slope limiting scheme.
static InputParameters validParams()
AEFVSlopeLimitingOneD(const InputParameters &parameters)
bool hasBlocks(const SubdomainName &name) const
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
DofValue getElementalValue(const Elem *elem, unsigned int idx=0) const
DofValue getElementalValueOld(const Elem *elem, unsigned int idx=0) const
Base class for slope limiting to limit the slopes of cell average variables.
static InputParameters validParams()