Documentation 6b54b78464
Loading...
Searching...
No Matches
scalar_edge_flux.hpp
Go to the documentation of this file.
1/*!
2 * \file scalar_edge_flux.hpp
3 * \brief Model-agnostic convection and diffusion of a transported scalar, shared by every
4 * scalar solver (turbulence, transition, species, flamelet, heat).
5 * \author P. Gomes
6 * \version 8.5.0 "Harrier"
7 *
8 * SU2 Project Website: https://su2code.github.io
9 *
10 * The SU2 Project is maintained by the SU2 Foundation
11 * (http://su2foundation.org)
12 *
13 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
14 *
15 * SU2 is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * SU2 is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
27 */
28
29#pragma once
30
31#include "../../../../Common/include/CConfig.hpp"
32#include "../../../../Common/include/containers/container_decorators.hpp"
33#include "../util.hpp"
34#include "../../variables/CFlowVariable.hpp"
35
36/*!
37 * \brief Locates the data of one endpoint of an edge.
38 * \note The j side of a boundary flux indexes per-marker ghost containers, which have the
39 * same types as the solver's own, so the kernels read both through one code path.
40 */
41template <class VariableType>
42struct EdgeSide {
43 const VariableType& scalarNodes; /*!< \brief Scalar solver variables. */
44 const CFlowVariable* flowNodes; /*!< \brief Flow variables, null for solid heat transfer. */
45 CMatrixView<const su2double> coord; /*!< \brief Point coordinates. */
46 CMatrixView<const su2double> gridVel; /*!< \brief Empty when the grid is static. */
47};
48
49/*!
50 * \brief Loop invariant flags for a scalar edge flux, built once outside the edge loop so the
51 * compiler can unswitch the branches they guard.
52 * \note Built through the named constructors below: the flags are too many and too alike to be
53 * given positionally, where one transposed pair would change the discretization silently.
54 */
56 bool dynamicGrid = false;
57 bool boundedScalar = false;
58 bool correctGradient = false;
59 bool accurateJacobians = false;
60 bool implicit = false; /*!< \brief Whether the Jacobians are assembled, and so computed. */
61 bool convective = true; /*!< \brief Whether the convective scheme contributes. */
62 bool viscous = false; /*!< \brief Whether the diffusion term contributes. */
63 bool oneSided = false; /*!< \brief Whether only the row of i is assembled. */
64 bool muscl = false; /*!< \brief Whether the convective scheme reconstructs. */
65
66 /*!
67 * \brief Options of the interior edge loop: both terms, both rows, and reconstruction and
68 * gradient correction as the configuration asks for them.
69 */
70 static ScalarFluxOptions Interior(const CConfig& config, bool bounded, bool accurateJacobians = false) {
71 auto opt = common(config);
72 opt.boundedScalar = bounded;
73 opt.accurateJacobians = accurateJacobians;
74 opt.correctGradient = true;
75 opt.viscous = true;
76 opt.muscl = config.GetMUSCL();
77 return opt;
78 }
79
80 /*!
81 * \brief Options of a boundary that imposes a convective flux alone, which is most of them:
82 * the diffusive term at an inlet or an outlet causes serious convergence problems.
83 */
84 static ScalarFluxOptions BoundaryConvective(const CConfig& config, bool bounded) {
85 auto opt = common(config);
86 opt.boundedScalar = bounded;
87 opt.oneSided = true;
88 return opt;
89 }
90
91 /*!
92 * \brief Options of a boundary that imposes both terms, which is the turbomachinery sites.
93 * \note They impose no mass flux, so the bounded scheme contributes nothing here whatever the
94 * configuration says.
95 */
96 static ScalarFluxOptions BoundaryFull(const CConfig& config) {
97 auto opt = common(config);
98 opt.correctGradient = true;
99 opt.viscous = true;
100 opt.oneSided = true;
101 return opt;
102 }
103
104 /*!
105 * \brief Options of the diffusive pass of a fluid interface, which follows a convective pass
106 * over the donor vertices.
107 * \param[in] correctGrad - Whether the projected gradient is corrected for skewness, which the
108 * models do not agree on at this boundary.
109 */
110 static ScalarFluxOptions BoundaryDiffusive(const CConfig& config, bool correctGrad) {
111 auto opt = common(config);
112 opt.correctGradient = correctGrad;
113 opt.convective = false;
114 opt.viscous = true;
115 opt.oneSided = true;
116 return opt;
117 }
118
119 private:
120 static ScalarFluxOptions common(const CConfig& config) {
122 opt.dynamicGrid = config.GetDynamic_Grid();
124 return opt;
125 }
126};
127
128/*!
129 * \brief Thin wrapper giving a Vector the all(iVar) accessor the MUSCL reconstruction helpers
130 * expect (see CCompressiblePrimitives in numerics_simd/flow/variables.hpp).
131 */
132template <class Double, size_t Size>
134 static constexpr size_t nVar = Size; /*!< \brief Only used as VarType::nVar when reconstruct's own nVarGrad_ default
135 applies; every call site here passes an explicit nVarGrad_ instead. */
137};
138
139/*!
140 * \brief Diffusion of a transported scalar, driven by model-supplied coefficients.
141 * \note The derived class returns the coefficients of both orientations of the edge, as one
142 * object, so that whatever the two share is computed once. A model whose coefficients
143 * are the same in both orientations returns the same value twice. A model whose matrix
144 * is diagonal declares DiagonalDiffusion and returns a vector instead of a matrix.
145 */
146template <class Double, class Derived, class FlowIndices, int nDim, size_t nVar>
148 protected:
150
151 /*!
152 * \param[in] rho - Density of both endpoints, read once by ComputeFlux.
153 */
154 template <class VariableType>
155 FORCEINLINE void diffusionTerms(const FlowIndices& idx, const ScalarFluxOptions& opt, Int iPoint,
156 const EdgeSide<VariableType>& side_i, Int jPoint,
157 const EdgeSide<VariableType>& side_j, const CPair<Double>& rho,
158 const Vector<Double, nDim>& normal, const Vector<Double, nDim>& vector_ij,
159 EdgeResidual<Double, nVar>& res) const {
160 if (!opt.viscous) return;
161
162 constexpr size_t Size = EdgeResidual<Double, nVar>::Size;
163
164 const Double dist2_ij = fmax(squaredNorm(vector_ij), EPS);
165 const Double proj_vector_ij = dot(vector_ij, normal) / dist2_ij;
166
167 /*--- Average gradient, corrected for skewness when asked.
168 * \note Gathered one variable at a time, bounded by res.nVar rather than Size: a static
169 * model with nVar 1 has Size 2 (the Matrix<Double,1,*> degeneracy floor), and a
170 * dynamic one has Size MaxScalarVar, so a single Size-wide read would run past the
171 * actual width of the gradient container in either case. ---*/
173 for (size_t iVar = 0; iVar < res.nVar; ++iVar) {
174 const auto grad_i = gatherVariables<nDim>(iPoint, side_i.scalarNodes.GetGradient(), iVar);
175 const auto grad_j = gatherVariables<nDim>(jPoint, side_j.scalarNodes.GetGradient(), iVar);
176 for (int iDim = 0; iDim < nDim; ++iDim) avgGrad(iVar, iDim) = 0.5 * (grad_i(iDim) + grad_j(iDim));
177 }
178
179 if (opt.correctGradient) {
180 for (size_t iVar = 0; iVar < res.nVar; ++iVar) {
181 const Double phi_i = gatherVariables(iPoint, side_i.scalarNodes.GetSolution(), iVar);
182 const Double phi_j = gatherVariables(jPoint, side_j.scalarNodes.GetSolution(), iVar);
183 const Double corr = (dot(avgGrad[iVar], vector_ij) - phi_j + phi_i) / dist2_ij;
184 for (int iDim = 0; iDim < nDim; ++iDim) avgGrad(iVar, iDim) -= corr * vector_ij(iDim);
185 }
186 }
187
188 Vector<Double, Size> projGrad;
189 for (size_t iVar = 0; iVar < res.nVar; ++iVar) projGrad(iVar) = dot(avgGrad[iVar], normal);
190
191 /*--- The Jacobians of a conservative model are w.r.t. the conserved (density-weighted)
192 * variable, which divides the geometric projection by the density of the row being written. ---*/
193 Double proj_on_w_i = proj_vector_ij, proj_on_w_j = proj_vector_ij;
194 if constexpr (Derived::Conservative) {
195 proj_on_w_i = proj_vector_ij / rho.i;
196 proj_on_w_j = proj_vector_ij / rho.j;
197 }
198
199 const auto* self = static_cast<const Derived*>(this);
200 const auto D = self->coefficients(idx, iPoint, side_i, jPoint, side_j, rho);
201
202 for (size_t iVar = 0; iVar < res.nVar; ++iVar) {
203 if constexpr (Derived::DiagonalDiffusion) {
204 res.flux_i(iVar) -= D.i(iVar) * projGrad(iVar);
205 if (opt.implicit) {
206 res.jac_ii(iVar, iVar) += D.i(iVar) * proj_on_w_i;
207 if (!opt.oneSided) res.jac_ij(iVar, iVar) -= D.i(iVar) * proj_on_w_j;
208 }
209 if (!opt.oneSided) {
210 res.flux_j(iVar) += D.j(iVar) * projGrad(iVar);
211 if (opt.implicit) {
212 res.jac_ji(iVar, iVar) -= D.j(iVar) * proj_on_w_i;
213 res.jac_jj(iVar, iVar) += D.j(iVar) * proj_on_w_j;
214 }
215 }
216 } else {
217 for (size_t jVar = 0; jVar < res.nVar; ++jVar) {
218 res.flux_i(iVar) -= D.i(iVar, jVar) * projGrad(jVar);
219 if (opt.implicit) {
220 res.jac_ii(iVar, jVar) += D.i(iVar, jVar) * proj_on_w_i;
221 if (!opt.oneSided) res.jac_ij(iVar, jVar) -= D.i(iVar, jVar) * proj_on_w_j;
222 }
223 if (!opt.oneSided) {
224 res.flux_j(iVar) += D.j(iVar, jVar) * projGrad(jVar);
225 if (opt.implicit) {
226 res.jac_ji(iVar, jVar) -= D.j(iVar, jVar) * proj_on_w_i;
227 res.jac_jj(iVar, jVar) += D.j(iVar, jVar) * proj_on_w_j;
228 }
229 }
230 }
231 }
232 }
233
234 if (opt.implicit && opt.accurateJacobians) {
235 /*--- Coefficients that depend on the transported variables contribute here, from whatever
236 * the model chose to carry in the object it returned from coefficients. ---*/
237 self->coefficientJacobians(opt, D, projGrad, res);
238 }
239
240 self->extraDiffusionTerms(idx, opt, iPoint, side_i, jPoint, side_j, rho, normal, vector_ij, res);
241 }
242
243 /*!
244 * \brief Contribution of the derivatives of the coefficients themselves.
245 */
246 template <class... Ts>
247 FORCEINLINE void coefficientJacobians(Ts&&...) const {}
248
249 /*!
250 * \brief Diffusion of a model that transports more than one gradient, of states it
251 * synthesises from its own containers.
252 */
253 template <class... Ts>
254 FORCEINLINE void extraDiffusionTerms(Ts&&...) const {}
255};
256
257/*!
258 * \brief Convective flux shared by every model whose transport equation has the shape
259 * flux(iVar) = a0 * w_i * phi_i(iVar) + a1 * w_j * phi_j(iVar), which is every
260 * model except SA and stochastic backscatter (see CScalarFlux_SA).
261 * \note The weight w is 1 for a non-conservative model, the density for a conservative one.
262 */
263template <class Double, class Derived, class FlowIndices, int nDim, size_t nVar>
264class CUpwScalarFlux : public CAvgGradScalarBase<Double, Derived, FlowIndices, nDim, nVar> {
265 protected:
267
268 explicit CUpwScalarFlux(const CConfig&) {}
269
270 /*!
271 * \brief Upwind convection of the transported variable, weighted by the density for a
272 * conservative model.
273 * \param[in] phi - Transported variable of both endpoints, reconstructed if opt.muscl is set;
274 * read from here rather than side_i/side_j.scalarNodes directly so a model needs
275 * no reconstruction logic of its own.
276 * \param[in] rho - Density of both endpoints, reconstructed alongside the velocity when the
277 * convective scheme reconstructs, so it weights the flux as the velocity does.
278 * \note The flux is written in terms of the transported variable but the Jacobians are w.r.t.
279 * the conserved one, which for a conservative model is the density-weighted variable;
280 * the density therefore multiplies the flux and not the Jacobian.
281 */
282 template <class VariableType, size_t Size>
283 FORCEINLINE void finalizeFlux(const FlowIndices&, const ScalarFluxOptions& opt, Int, const EdgeSide<VariableType>&,
284 Int, const EdgeSide<VariableType>&, const Double& a0, const Double& a1,
285 const CPair<Double>& rho, const CPair<CScalarValues<Double, Size>>& phi,
286 EdgeResidual<Double, nVar>& res) const {
287 Double w0 = a0, w1 = a1;
288 if constexpr (Derived::Conservative) {
289 w0 *= rho.i;
290 w1 *= rho.j;
291 }
292
293 for (size_t iVar = 0; iVar < res.nVar; ++iVar) {
294 const Double flux = w0 * phi.i.all(iVar) + w1 * phi.j.all(iVar);
295
296 res.flux_i(iVar) += flux;
297 if (!opt.oneSided) res.flux_j(iVar) -= flux;
298
299 if (opt.implicit) {
300 res.jac_ii(iVar, iVar) += a0;
301 if (!opt.oneSided) {
302 res.jac_ij(iVar, iVar) += a1;
303 res.jac_ji(iVar, iVar) -= a0;
304 res.jac_jj(iVar, iVar) -= a1;
305 }
306 }
307 }
308 }
309};
310
311/*!
312 * \brief Upwind convection and diffusion of a transported scalar, accumulated into one
313 * residual, each term contributing or not according to the options.
314 */
315template <class Double_, class Derived, class FlowIndices, int nDim_, size_t nVar_>
316class CUpwScalarBase : public CUpwScalarFlux<Double_, Derived, FlowIndices, nDim_, nVar_> {
317 public:
318 using Double = Double_;
320 static constexpr int nDim = nDim_;
321 static constexpr size_t nVar = nVar_;
322
323 /*!
324 * \brief Backing size, for the model to size the containers its coefficients() returns;
325 * nVar itself is Dynamic for a runtime model and never usable as a container size.
326 */
327 static constexpr size_t Size = EdgeResidual<Double_, nVar_>::Size;
328
329 /*!
330 * \brief Whether the model's diffusion coefficients read the density, beyond the reading that
331 * Conservative already implies. A model that declares neither never gathers it.
332 */
333 static constexpr bool DiffusionReadsDensity = false;
334
335 protected:
337
338 const FlowIndices idx;
339 const size_t nEqn; /*!< \brief Equations of the model, which a dynamic one gives to its base. */
340
341 /*!
342 * \brief MUSCL reconstruction parameters, read from CConfig once per construction (i.e. once
343 * per nonlinear iteration, see CScalarSolver::EdgeFluxResidual) instead of per edge;
344 * this is also where the scalar limiter's freezing (GetLimiterIter) is resolved, by
345 * collapsing its type to NONE once frozen. The flow limiter is not frozen this way: once
346 * the flow solver stops recomputing it, it keeps applying the last values it has.
347 */
350 const bool musclFlow;
351
352 public:
353 /*!
354 * \brief Constructor, inherited by the model with `using Base::Base`.
355 * \note Public, not protected: a using-declaration that inherits a constructor keeps the
356 * base's own access, so the solver that builds the concrete model needs this public
357 * to build it at all.
358 */
359 explicit CUpwScalarBase(const CConfig& config, size_t nEqn_ = nVar_)
360 : Base(config),
361 idx(nDim, config.GetnSpecies()),
362 nEqn(nEqn_),
363 kappa(config.GetMUSCL_Kappa()),
364 umusclRamp(config.GetMUSCLRampValue()),
365 kappaFlow(config.GetMUSCL_Kappa_Flow()),
366 limiterType(config.GetInnerIter() <= config.GetLimiterIter() ? config.GetKind_SlopeLimit() : LIMITER::NONE),
367 limiterTypeFlow(config.GetKind_SlopeLimit_Flow() != LIMITER::VAN_ALBADA_EDGE ? config.GetKind_SlopeLimit_Flow()
368 : LIMITER::NONE),
369 musclFlow(config.GetMUSCL_Flow() && config.GetKind_ConvNumScheme_Flow() == SPACE_UPWIND) {
370 if (nEqn > Size) {
371 SU2_MPI::Error("Static arrays are too small for the requested equation count.", CURRENT_FUNCTION);
372 }
373 }
374
375 template <class VariableType>
377 const EdgeSide<VariableType>& side_i, Int jPoint,
378 const EdgeSide<VariableType>& side_j,
379 const Vector<Double, nDim>& normal, const Double& massFlux) const {
380 /*--- Inputs are registered as they are read, by each of the two terms. ---*/
382 AD::SetPreaccIn(normal, nDim);
383
385
386 /*--- Read once by the reconstruction and by the diffusion. ---*/
387 Vector<Double, nDim> vector_ij;
388 if (opt.muscl || opt.viscous) {
389 vector_ij = distanceVector<nDim>(iPoint, side_i.coord, jPoint, side_j.coord);
390 }
391
392 /*--- Density of both endpoints, gathered once: the conservative weighting of the convective
393 * term, the bounded scheme's division of the mass flux, and some models' diffusion
394 * coefficients all want it, and in reverse mode every gather is a preaccumulation input. ---*/
395 CPair<Double> rho{Double(1.0), Double(1.0)};
396 if (Derived::Conservative || Derived::DiffusionReadsDensity || opt.boundedScalar) {
397 rho.i = gatherVariables(iPoint, side_i.flowNodes->GetPrimitive(), idx.Density());
398 rho.j = gatherVariables(jPoint, side_j.flowNodes->GetPrimitive(), idx.Density());
399 }
400
401 if (opt.convective) {
402 /*--- Upwinding weights of the face normal mass or volume flux, and the density that weights
403 * a conservative flux, which follows the velocity in being reconstructed or not. ---*/
404 Double a0, a1;
405 CPair<Double> rhoConv = rho;
406
407 if (opt.boundedScalar) {
408 AD::SetPreaccIn(massFlux);
409 a0 = fmax(0.0, massFlux) / rho.i;
410 a1 = fmin(0.0, massFlux) / rho.j;
411 } else {
413 u.i.all = gatherVariables<nDim>(iPoint, side_i.flowNodes->GetPrimitive(), idx.Velocity());
414 u.j.all = gatherVariables<nDim>(jPoint, side_j.flowNodes->GetPrimitive(), idx.Velocity());
415
416 if (opt.muscl && musclFlow) {
417 reconstruct<nDim>(iPoint, jPoint, vector_ij, side_i.flowNodes->GetGradient_Reconstruction(),
419 umusclRamp);
420
421 if constexpr (Derived::Conservative) {
422 /*--- Density is not adjacent to the velocity in the primitive row, so it is a second
423 * reconstruction of one variable rather than a wider slice of the first. Some upwind
424 * schemes (see EulerNPrimVarGrad) size the flow's gradient/limiter columns smaller
425 * than the full primitive count and leave density out of it entirely, so fall back to
426 * the cell-centered density instead. ---*/
427 if (idx.Density() < side_i.flowNodes->GetnPrimVarGrad()) {
429 r.i.all(0) = rho.i;
430 r.j.all(0) = rho.j;
431 reconstruct<1>(iPoint, jPoint, vector_ij, side_i.flowNodes->GetGradient_Reconstruction(),
433 umusclRamp);
434 rhoConv.i = r.i.all(0);
435 rhoConv.j = r.j.all(0);
436 }
437 }
438 }
439
440 /*--- Face normal velocity of the mean of the two points, relative to the grid. ---*/
442 for (int iDim = 0; iDim < nDim; ++iDim) vel_ij(iDim) = 0.5 * (u.i.all(iDim) + u.j.all(iDim));
443
444 if (opt.dynamicGrid) {
445 const auto ug_i = gatherVariables<nDim>(iPoint, side_i.gridVel);
446 /*--- A boundary's ghost point has no grid velocity of its own: it is spatially
447 * coincident with i, so it moves with it. ---*/
448 const auto ug_j = opt.oneSided ? ug_i : gatherVariables<nDim>(jPoint, side_j.gridVel);
449 for (int iDim = 0; iDim < nDim; ++iDim) vel_ij(iDim) -= 0.5 * (ug_i(iDim) + ug_j(iDim));
450 }
451
452 const Double q_ij = dot(vel_ij, normal);
453 a0 = fmax(0.0, q_ij);
454 a1 = fmin(0.0, q_ij);
455 }
456
457 /*--- Transported variable of both endpoints, reconstructed if opt.muscl is set.
458 * Gathered one variable at a time (like the diffusion gradients above) so a static model
459 * with nVar 1 never reads past the single column its solution container actually has. ---*/
461 for (size_t iVar = 0; iVar < res.nVar; ++iVar) {
462 phi.i.all(iVar) = gatherVariables(iPoint, side_i.scalarNodes.GetSolution(), iVar);
463 phi.j.all(iVar) = gatherVariables(jPoint, side_j.scalarNodes.GetSolution(), iVar);
464 }
465
466 if (opt.muscl) {
467 if constexpr (nVar != Dynamic) {
468 reconstruct<nVar>(iPoint, jPoint, vector_ij, side_i.scalarNodes.GetGradient_Reconstruction(),
469 side_i.scalarNodes.GetLimiter(), limiterType, 0, phi, kappa, umusclRamp);
470 } else {
471 /*--- A dynamic model's equation count is only known at runtime, so the reconstructed
472 * width is passed as an argument instead of a template parameter. ---*/
473 reconstruct(iPoint, jPoint, vector_ij, side_i.scalarNodes.GetGradient_Reconstruction(),
474 side_i.scalarNodes.GetLimiter(), limiterType, 0, phi, kappa, umusclRamp, res.nVar);
475 }
476 }
477
478 static_cast<const Derived*>(this)->finalizeFlux(idx, opt, iPoint, side_i, jPoint, side_j, a0, a1, rhoConv, phi,
479 res);
480 }
481
482 Base::diffusionTerms(idx, opt, iPoint, side_i, jPoint, side_j, rho, normal, vector_ij, res);
483
484 setPreaccOut(res.flux_i, res.nVar);
485 if (!opt.oneSided) setPreaccOut(res.flux_j, res.nVar);
487
488 return res;
489 }
490
491 /*!
492 * \brief Compute the flux of an edge and write it to the linear system.
493 */
494 template <class VariableType>
495 FORCEINLINE void ComputeFlux(const ScalarFluxOptions& opt, Int iEdge, Int iPoint,
496 const EdgeSide<VariableType>& side_i, Int jPoint, const EdgeSide<VariableType>& side_j,
497 const Vector<Double, nDim>& normal, const Double& massFlux, UpdateType updateType,
498 Double updateMask, CSysVector<su2double>& vector, CSysVector<su2double>& vectorDiff,
499 SparseMatrixType& matrix) const {
500 const auto res = ComputeFlux(opt, iPoint, side_i, jPoint, side_j, normal, massFlux);
501
502 updateLinearSystem(iEdge, iPoint, jPoint, opt.implicit, updateType, updateMask, res, vector, vectorDiff, matrix);
503 }
504};
A templated matrix/vector-like object.
Definition C2DContainer.hpp:374
Diffusion of a transported scalar, driven by model-supplied coefficients.
Definition scalar_edge_flux.hpp:147
void diffusionTerms(const FlowIndices &idx, const ScalarFluxOptions &opt, Int iPoint, const EdgeSide< VariableType > &side_i, Int jPoint, const EdgeSide< VariableType > &side_j, const CPair< Double > &rho, const Vector< Double, nDim > &normal, const Vector< Double, nDim > &vector_ij, EdgeResidual< Double, nVar > &res) const
Definition scalar_edge_flux.hpp:155
void coefficientJacobians(Ts &&...) const
Contribution of the derivatives of the coefficients themselves.
Definition scalar_edge_flux.hpp:247
void extraDiffusionTerms(Ts &&...) const
Diffusion of a model that transports more than one gradient, of states it synthesises from its own co...
Definition scalar_edge_flux.hpp:254
typename CLaneTraits< Double >::Int Int
Definition scalar_edge_flux.hpp:149
static void Error(const std::string &ErrorMsg, const std::string &FunctionName)
Definition mpi_structure.cpp:131
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
bool GetDynamic_Grid(void) const
Get information about dynamic grids.
Definition CConfig.hpp:6276
bool GetMUSCL(void) const
Get if the upwind scheme used MUSCL or not.
Definition CConfig.hpp:4768
unsigned short GetKind_TimeIntScheme(void) const
Get the kind of time integration method.
Definition CConfig.hpp:4732
Class for defining the common variables of flow solvers.
Definition CFlowVariable.hpp:38
unsigned long GetnPrimVarGrad() const
Number of primitive variables that have a gradient/limiter column, from the start of the primitive ro...
Definition CFlowVariable.hpp:213
su2double GetPrimitive(unsigned long iPoint, unsigned long iVar) const final
Get a primitive variable.
Definition CFlowVariable.hpp:95
CMatrixView< su2double > GetGradient_Reconstruction(unsigned long iPoint) final
Get the array of the reconstruction variables gradient at a node.
Definition CFlowVariable.hpp:173
su2double GetLimiter_Primitive(unsigned long iPoint, unsigned long iVar) const final
Get the value of the primitive variables gradient.
Definition CFlowVariable.hpp:190
Class to represent a matrix (without owning the data, this just wraps a pointer).
Definition container_decorators.hpp:40
Class for holding and manipulating vectors needed by linear solvers.
Definition CSysVector.hpp:195
Upwind convection and diffusion of a transported scalar, accumulated into one residual,...
Definition scalar_edge_flux.hpp:316
EdgeResidual< Double, nVar > ComputeFlux(const ScalarFluxOptions &opt, Int iPoint, const EdgeSide< VariableType > &side_i, Int jPoint, const EdgeSide< VariableType > &side_j, const Vector< Double, nDim > &normal, const Double &massFlux) const
Definition scalar_edge_flux.hpp:376
CUpwScalarBase(const CConfig &config, size_t nEqn_=nVar_)
Constructor, inherited by the model with using Base::Base.
Definition scalar_edge_flux.hpp:359
static constexpr bool DiffusionReadsDensity
Whether the model's diffusion coefficients read the density, beyond the reading that Conservative alr...
Definition scalar_edge_flux.hpp:333
typename CLaneTraits< Double_ >::Int Int
Definition scalar_edge_flux.hpp:319
const bool musclFlow
Definition scalar_edge_flux.hpp:350
const su2double kappa
MUSCL reconstruction parameters, read from CConfig once per construction (i.e. once per nonlinear ite...
Definition scalar_edge_flux.hpp:348
const LIMITER limiterTypeFlow
Definition scalar_edge_flux.hpp:349
const size_t nEqn
Equations of the model, which a dynamic one gives to its base.
Definition scalar_edge_flux.hpp:339
const LIMITER limiterType
Definition scalar_edge_flux.hpp:349
Double_ Double
Definition scalar_edge_flux.hpp:318
const FlowIndices idx
Definition scalar_edge_flux.hpp:338
void ComputeFlux(const ScalarFluxOptions &opt, Int iEdge, Int iPoint, const EdgeSide< VariableType > &side_i, Int jPoint, const EdgeSide< VariableType > &side_j, const Vector< Double, nDim > &normal, const Double &massFlux, UpdateType updateType, Double updateMask, CSysVector< su2double > &vector, CSysVector< su2double > &vectorDiff, SparseMatrixType &matrix) const
Compute the flux of an edge and write it to the linear system.
Definition scalar_edge_flux.hpp:495
static constexpr size_t Size
Backing size, for the model to size the containers its coefficients() returns; nVar itself is Dynamic...
Definition scalar_edge_flux.hpp:327
const su2double umusclRamp
Definition scalar_edge_flux.hpp:348
const su2double kappaFlow
Definition scalar_edge_flux.hpp:348
static constexpr int nDim
Definition scalar_edge_flux.hpp:320
static constexpr size_t nVar
Definition scalar_edge_flux.hpp:321
Convective flux shared by every model whose transport equation has the shape flux(iVar) = a0 * w_i * ...
Definition scalar_edge_flux.hpp:264
void finalizeFlux(const FlowIndices &, const ScalarFluxOptions &opt, Int, const EdgeSide< VariableType > &, Int, const EdgeSide< VariableType > &, const Double &a0, const Double &a1, const CPair< Double > &rho, const CPair< CScalarValues< Double, Size > > &phi, EdgeResidual< Double, nVar > &res) const
Upwind convection of the transported variable, weighted by the density for a conservative model.
Definition scalar_edge_flux.hpp:283
typename CLaneTraits< Double >::Int Int
Definition scalar_edge_flux.hpp:266
CUpwScalarFlux(const CConfig &)
Definition scalar_edge_flux.hpp:268
#define FORCEINLINE
Definition code_config.hpp:44
passivedouble su2double
Definition code_config.hpp:181
#define CURRENT_FUNCTION
Definition mpi_structure.hpp:59
void StartPreacc()
Starts a new preaccumulation section and sets the input variables.
Definition ad_structure.hpp:215
void EndPreacc()
Ends a preaccumulation section and computes the local Jacobi matrix of a code section using the varia...
Definition ad_structure.hpp:243
void SetPreaccIn(Ts &&... data)
Sets the scalar inputs of a preaccumulation section.
Definition ad_structure.hpp:186
UpdateType
Ways to update vectors and system matrices. COLORING is the typical i/j update, whereas for REDUCTION...
Definition util.hpp:44
constexpr size_t Dynamic
Equation count of a model whose value is only known at runtime.
Definition util.hpp:152
auto squaredNorm(ForwardIterator iterator) -> typename std::decay< decltype(*iterator)>::type
Squared norm.
Definition util.hpp:231
void reconstruct(typename CLaneTraits< Double >::Int iPoint, typename CLaneTraits< Double >::Int jPoint, const Vector< Double, nDim > &vector_ij, const Gradient_t &gradient, const Limiter_t &limiter, LIMITER limiterType, size_t iRow, CPair< VarType > &V, const CNonDeduced< Double > &kappa, const CNonDeduced< Double > &umusclRamp, size_t nVarGradRuntime=0)
Reconstruct a slice of nVarGrad variables starting at column iRow, dispatching on the limiter type; s...
Definition util.hpp:546
void updateLinearSystem(Int iEdge, Int iPoint, Int jPoint, bool implicit, UpdateType updateType, Double updateMask, const Vector< Double, nVar > &flux, const Matrix< Double, nVar, nVar > &jac_i, const Matrix< Double, nVar, nVar > &jac_j, CSysVector< su2double > &vector, SparseMatrixType &matrix)
Update the matrix and right-hand-side of a linear system with one conservative flux.
Definition util.hpp:571
void setPreaccOut(Vector< Double, Size > &x, size_t nVar)
Register the leading nVar entries of a static vector as preaccumulation outputs.
Definition util.hpp:380
auto dot(ForwardIterator iterator, const T *ptr) -> typename std::decay< decltype(*ptr)>::type
Dot product.
Definition util.hpp:203
Double gatherVariables(Int iPoint, const Container &vars, size_t iVar=0)
Gather a single variable, from column iVar (0 by default) of row iPoint of a 2D container,...
Definition util.hpp:277
@ NONE
Definition option_structure.hpp:282
@ EULER_IMPLICIT
Implicit Euler time integration definition.
Definition option_structure.hpp:1711
@ SPACE_UPWIND
Upwind convective numerical method.
Definition option_structure.hpp:633
LIMITER
Types of slope limiters.
Definition option_structure.hpp:1038
@ VAN_ALBADA_EDGE
Slope limiter using Van Albada method (edge formulation).
constexpr passivedouble EPS
Error scale.
Definition option_structure.hpp:100
Index type and lane count that go with a flux value type, the converse of CValueTraits,...
Definition util.hpp:107
Simple pair type for i/j variables.
Definition util.hpp:130
T i
Definition util.hpp:131
T j
Definition util.hpp:131
Thin wrapper giving a Vector the all(iVar) accessor the MUSCL reconstruction helpers expect (see CCom...
Definition scalar_edge_flux.hpp:133
Vector< Double, Size > all
Definition scalar_edge_flux.hpp:136
static constexpr size_t nVar
Only used as VarType::nVar when reconstruct's own nVarGrad_ default applies; every call site here pas...
Definition scalar_edge_flux.hpp:134
Residual of one edge, accumulated by the convective and the diffusive terms.
Definition util.hpp:169
Vector< Double, Size > flux_j
Definition util.hpp:176
Matrix< Double, Size, Size > jac_jj
Definition util.hpp:177
Matrix< Double, Size, Size > jac_ji
Definition util.hpp:177
const size_t nVar
Definition util.hpp:178
Vector< Double, Size > flux_i
Definition util.hpp:176
Matrix< Double, Size, Size > jac_ii
Definition util.hpp:177
Matrix< Double, Size, Size > jac_ij
Definition util.hpp:177
Locates the data of one endpoint of an edge.
Definition scalar_edge_flux.hpp:42
CMatrixView< const su2double > gridVel
Empty when the grid is static.
Definition scalar_edge_flux.hpp:46
CMatrixView< const su2double > coord
Point coordinates.
Definition scalar_edge_flux.hpp:45
const CFlowVariable * flowNodes
Flow variables, null for solid heat transfer.
Definition scalar_edge_flux.hpp:44
const VariableType & scalarNodes
Scalar solver variables.
Definition scalar_edge_flux.hpp:43
Loop invariant flags for a scalar edge flux, built once outside the edge loop so the compiler can uns...
Definition scalar_edge_flux.hpp:55
bool viscous
Whether the diffusion term contributes.
Definition scalar_edge_flux.hpp:62
bool implicit
Whether the Jacobians are assembled, and so computed.
Definition scalar_edge_flux.hpp:60
bool accurateJacobians
Definition scalar_edge_flux.hpp:59
bool muscl
Whether the convective scheme reconstructs.
Definition scalar_edge_flux.hpp:64
bool boundedScalar
Definition scalar_edge_flux.hpp:57
bool oneSided
Whether only the row of i is assembled.
Definition scalar_edge_flux.hpp:63
static ScalarFluxOptions BoundaryDiffusive(const CConfig &config, bool correctGrad)
Options of the diffusive pass of a fluid interface, which follows a convective pass over the donor ve...
Definition scalar_edge_flux.hpp:110
static ScalarFluxOptions BoundaryFull(const CConfig &config)
Options of a boundary that imposes both terms, which is the turbomachinery sites.
Definition scalar_edge_flux.hpp:96
bool dynamicGrid
Definition scalar_edge_flux.hpp:56
bool correctGradient
Definition scalar_edge_flux.hpp:58
static ScalarFluxOptions Interior(const CConfig &config, bool bounded, bool accurateJacobians=false)
Options of the interior edge loop: both terms, both rows, and reconstruction and gradient correction ...
Definition scalar_edge_flux.hpp:70
bool convective
Whether the convective scheme contributes.
Definition scalar_edge_flux.hpp:61
static ScalarFluxOptions BoundaryConvective(const CConfig &config, bool bounded)
Options of a boundary that imposes a convective flux alone, which is most of them: the diffusive term...
Definition scalar_edge_flux.hpp:84