https://mooseframework.inl.gov
FVAdvectedVanLeerWeightBased.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 
12 #include "MathFVUtils.h"
13 
14 #include <algorithm>
15 #include <limits>
16 
18 
21 {
23  params.addClassDescription(
24  "Van Leer interpolation for advected quantities implemented as limited blending weights "
25  "(no MUSCL reconstruction, no deferred correction).");
26  params.addParam<bool>(
27  "limit_to_linear",
28  true,
29  "Whether to limit the scheme to be no more downwind-biased than linear interpolation "
30  "(blends between upwind and linear; avoids 'compressive' weights that can lead to "
31  "downwind weighting and poor linear solver behavior).");
32  params.addRangeCheckedParam<Real>(
33  "blending_factor",
34  1.0,
35  "blending_factor>=0 & blending_factor<=1",
36  "Scales the high-order blending strength; 0 gives pure upwind, 1 gives the full limited "
37  "blending. Values < 1 can improve linear solver robustness for fully implicit assembly.");
38  return params;
39 }
40 
42  : FVInterpolationMethod(params),
43  _limit_to_linear(getParam<bool>("limit_to_linear")),
44  _blending_factor(getParam<Real>("blending_factor"))
45 {
46 }
47 
50  Real elem_value,
51  Real neighbor_value,
52  const VectorValue<Real> * elem_grad,
53  const VectorValue<Real> * neighbor_grad,
54  Real mass_flux) const
55 {
56  mooseAssert(elem_grad && neighbor_grad,
57  "Van Leer advected interpolation requires both element and neighbor gradients.");
58 
59  const bool upwind_is_elem = mass_flux >= 0.0;
60 
61  const Real phi_upwind = upwind_is_elem ? elem_value : neighbor_value;
62  const Real phi_downwind = upwind_is_elem ? neighbor_value : elem_value;
63 
64  const VectorValue<Real> grad_upwind = upwind_is_elem ? *elem_grad : *neighbor_grad;
65  const Point upwind_to_downwind = upwind_is_elem ? face.dCN() : Point(-face.dCN());
66 
67  const auto r_f = Moose::FV::rF(phi_upwind, phi_downwind, grad_upwind, upwind_to_downwind);
68  const Real beta = (r_f + std::abs(r_f)) / (1.0 + std::abs(r_f));
69 
70  // Geometric weight associated with the upwind cell for this face.
71  const Real w_f = upwind_is_elem ? face.gC() : (1.0 - face.gC());
72 
73  // Following the Greenshields blending form:
74  // phi_f = (1-g)*phi_upwind + g*phi_downwind, with g = beta*(1-w_f)
75  const Real g_unclamped = _blending_factor * beta * (1.0 - w_f);
76  const Real g_clamped = std::min(std::max(g_unclamped, 0.0), 1.0 - w_f);
77  // Clamp to [0, 1-w_f] so the weights do not become more downwind-biased than linear.
78  const Real g = _limit_to_linear ? g_clamped : g_unclamped;
79 
80  const Real w_upwind = 1.0 - g;
81  const Real w_downwind = g;
82 
83  // Map (upwind, downwind) weights back to (elem, neighbor) ordering.
84  const Real w_elem = upwind_is_elem ? w_upwind : w_downwind;
85  const Real w_neighbor = upwind_is_elem ? w_downwind : w_upwind;
86 
88  result.weights_matrix = std::make_pair(w_elem, w_neighbor);
89 
90  return result;
91 }
92 
93 Real
95  Real elem_value,
96  Real neighbor_value,
97  const VectorValue<Real> * elem_grad,
98  const VectorValue<Real> * neighbor_grad,
99  Real mass_flux) const
100 {
101  const auto result =
102  advectedInterpolate(face, elem_value, neighbor_value, elem_grad, neighbor_grad, mass_flux);
103  return result.weights_matrix.first * elem_value + result.weights_matrix.second * neighbor_value;
104 }
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:50
registerMooseObject("MooseApp", FVAdvectedVanLeerWeightBased)
Scalar rF(const Scalar &phiC, const Scalar &phiD, const Vector &gradC, const RealVectorValue &dCD)
From Moukalled 12.30.
Definition: MathFVUtils.h:448
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Registered base class for linear FV interpolation objects.
Van Leer interpolation for advected quantities that blends between upwind and the higher-order limite...
auto max(const L &left, const R &right)
This data structure is used to store geometric and variable related metadata about each cell face in ...
Definition: FaceInfo.h:37
AdvectedSystemContribution advectedInterpolate(const FaceInfo &face, Real elem_value, Real neighbor_value, const VectorValue< Real > *elem_grad, const VectorValue< Real > *neighbor_grad, Real mass_flux) const override
Compute the matrix weights for the advected face value.
Real gC() const
Return the geometric weighting factor.
Definition: FaceInfo.h:136
static InputParameters validParams()
const bool _limit_to_linear
Whether to clamp the blending to be no more downwind-biased than linear.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
FVAdvectedVanLeerWeightBased(const InputParameters &params)
Matrix/RHS contribution for an advected face interpolation.
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 optional parameter and a documentation string to the InputParameters object...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Real advectedInterpolateValue(const FaceInfo &face, Real elem_value, Real neighbor_value, const VectorValue< Real > *elem_grad, const VectorValue< Real > *neighbor_grad, Real mass_flux) const override
Compute the advected face value.
const Real _blending_factor
Scales the high-order blending strength (0 = upwind, 1 = full limited blending).
auto min(const L &left, const R &right)
const Point & dCN() const
Definition: FaceInfo.h:142