https://mooseframework.inl.gov
PressureDrop.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 
10 #include "PressureDrop.h"
11 #include "MathFVUtils.h"
12 #include "NSFVUtils.h"
13 #include "NS.h"
14 
15 #include <cmath>
16 
17 registerMooseObject("NavierStokesApp", PressureDrop);
18 
21 {
23  params.addClassDescription(
24  "Computes the pressure drop between an upstream and a downstream boundary.");
25 
26  params.addRequiredParam<MooseFunctorName>("pressure", "The pressure functor");
27  params.addParam<MooseFunctorName>("weighting_functor",
28  "A vector functor to compute a flux to weigh the pressure for "
29  "the pressure average computations");
30  params.addRequiredParam<std::vector<BoundaryName>>(
31  "upstream_boundary", "The upstream surface (must also be specified in 'boundary' parameter");
32  params.addRequiredParam<std::vector<BoundaryName>>(
33  "downstream_boundary",
34  "The downstream surface (must also be specified in 'boundary' parameter");
35 
36  params.addParam<MooseEnum>("weighting_interp_method",
38  "The interpolation to use for the weighting functor.");
39  return params;
40 }
41 
43  : SideIntegralPostprocessor(parameters),
44  _pressure(getFunctor<Real>("pressure")),
45  _weighting_functor(isParamValid("weighting_functor")
46  ? &getFunctor<RealVectorValue>("weighting_functor")
47  : nullptr)
48 {
49  // Examine the variable type of pressure to determine the type of integration
50  const auto pressure_name = getParam<MooseFunctorName>("pressure");
51  if (!_subproblem.hasVariable(pressure_name))
52  paramError("pressure", "Pressure must be a variable");
53  const auto * const pressure_var = &_subproblem.getVariable(_tid, pressure_name);
54  _qp_integration = dynamic_cast<const MooseVariableFE<Real> *>(pressure_var);
55 
56  checkFunctorSupportsSideIntegration<Real>("pressure", _qp_integration);
58  checkFunctorSupportsSideIntegration<RealVectorValue>("weighting_functor", _qp_integration);
59 
60  if (!_qp_integration)
61  Moose::FV::setInterpolationMethod(*this, _weight_interp_method, "weighting_interp_method");
62 
63  else if (parameters.isParamSetByUser("weighting_interp_method"))
64  paramError("weighting_interp_method", "Face interpolation only specified for finite volume");
65 
66  // Only keep the ids
67  auto upstream_bdies = getParam<std::vector<BoundaryName>>("upstream_boundary");
68  auto downstream_bdies = getParam<std::vector<BoundaryName>>("downstream_boundary");
69  _upstream_boundaries.resize(upstream_bdies.size());
70  _downstream_boundaries.resize(downstream_bdies.size());
71  for (auto i : make_range(upstream_bdies.size()))
72  _upstream_boundaries[i] = _mesh.getBoundaryID(upstream_bdies[i]);
73  for (auto i : make_range(downstream_bdies.size()))
74  _downstream_boundaries[i] = _mesh.getBoundaryID(downstream_bdies[i]);
75 
76  // Check that boundary restriction makes sense
77  for (auto bdy : _upstream_boundaries)
78  if (!hasBoundary(bdy))
79  paramError("boundary",
80  "Upstream boundary '" + _mesh.getBoundaryName(bdy) +
81  "' is not included in boundary restriction");
82  for (auto bdy : _downstream_boundaries)
83  if (!hasBoundary(bdy))
84  paramError("boundary",
85  "Downstream boundary '" + _mesh.getBoundaryName(bdy) +
86  "' is not included in boundary restriction");
87  for (auto bdy : boundaryIDs())
88  if (std::find(_upstream_boundaries.begin(), _upstream_boundaries.end(), bdy) ==
89  _upstream_boundaries.end() &&
90  std::find(_downstream_boundaries.begin(), _downstream_boundaries.end(), bdy) ==
92  paramError("boundary",
93  "Boundary restriction on boundary '" + _mesh.getBoundaryName(bdy) +
94  "' is not part of upstream or downstream boundaries");
95  for (auto bdy : _upstream_boundaries)
96  if (std::find(_downstream_boundaries.begin(), _downstream_boundaries.end(), bdy) !=
98  paramError("upstream_boundary",
99  "Upstream boundary '" + _mesh.getBoundaryName(bdy) +
100  "' is also a downstream boundary");
101 }
102 
103 void
105 {
108  _weight_upstream = 0;
109  _weight_downstream = 0;
110 
111  // Build the face infos in all cases, needed to detect upstream/downstream status
114 }
115 
116 void
118 {
119  initialize();
120 }
121 
122 void
124 {
125  // Determine if upstream or downstream boundary
126  bool upstream = false;
127  bool status_known = false;
128  getFaceInfos();
129 
130  for (auto & fi : _face_infos)
131  {
132  for (const auto bdy : fi->boundaryIDs())
133  {
134  if (std::find(_upstream_boundaries.begin(), _upstream_boundaries.end(), bdy) !=
135  _upstream_boundaries.end())
136  {
137  upstream = true;
138  status_known = true;
139 #ifdef NDEBUG
140  break;
141 #else
142  if (std::find(_downstream_boundaries.begin(), _downstream_boundaries.end(), bdy) !=
144  mooseError("Boundary '", _mesh.getBoundaryName(bdy), "' is both upstream and downstream");
145 #endif
146  }
147 #ifndef NDEBUG
148  if (upstream &&
149  std::find(_downstream_boundaries.begin(), _downstream_boundaries.end(), bdy) !=
151  mooseError("Face info is part of both upstream and downstream boundaries");
152 #endif
153  if (!upstream &&
154  std::find(_downstream_boundaries.begin(), _downstream_boundaries.end(), bdy) !=
156  status_known = true;
157 
158  // in debug mode we will check all boundaries the face info is a part of
159  // to make sure they are consistently upstream or downstream
160 #ifdef NDEBUG
161  if (status_known)
162  break;
163 #endif
164  }
165  // we ll assume all face infos for a given element and side have the same upstream status
166  // it seems very unlikely that upstream and downstream boundaries would be touching
167  // and the delimitation would be within a refined element's face
168  if (status_known)
169  break;
170  }
171 
172  if (upstream)
173  {
174  // Integration loops are different for FE and FV at this point
175  if (_qp_integration)
176  {
177  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
178  {
182  }
183  }
184  else
185  {
186  for (auto & fi : _face_infos)
187  {
189  fi->faceArea() * fi->faceCoord() * computeFaceInfoWeightedPressureIntegral(fi);
190  _weight_upstream += fi->faceArea() * fi->faceCoord() * computeFaceInfoWeightIntegral(fi);
191  }
192  }
193  }
194  // Downstream contributions
195  else
196  {
197  if (_qp_integration)
198  {
199  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
200  {
204  }
205  }
206  else
207  {
208  for (auto & fi : _face_infos)
209  {
211  fi->faceArea() * fi->faceCoord() * computeFaceInfoWeightedPressureIntegral(fi);
212  _weight_downstream += fi->faceArea() * fi->faceCoord() * computeFaceInfoWeightIntegral(fi);
213  }
214  }
215  }
216 }
217 
218 Real
220 {
221  mooseAssert(fi, "We should have a face info in " + name());
222 
223  const bool correct_skewness =
225  const Moose::ElemQpArg elem_arg = {_current_elem, _qp, _qrule, _q_point[_qp]};
226  const auto state = determineState();
227  mooseAssert(_qp == 0, "Only one quadrature point");
228  mooseAssert(_pressure.hasFaceSide(*fi, true) || _pressure.hasFaceSide(*fi, true),
229  "Pressure must be defined at least on one side of the face!");
230  const auto * elem = _pressure.hasFaceSide(*fi, true) ? fi->elemPtr() : fi->neighborPtr();
231 
232  if (_weighting_functor)
233  {
234  mooseAssert(_pressure.hasFaceSide(*fi, true) == _weighting_functor->hasFaceSide(*fi, true),
235  "Pressure and weighting functor have to be defined on the same side of the face!");
236  auto ssf = Moose::FaceArg(
237  {fi,
239  MetaPhysicL::raw_value((*_weighting_functor)(elem_arg, state)) * fi->normal() > 0,
240  correct_skewness,
241  elem,
242  nullptr});
243  const auto face_weighting = MetaPhysicL::raw_value((*_weighting_functor)(ssf, state));
244  // Dont use upwinding or an advection limiter for pressure
246  return fi->normal() * face_weighting * _pressure(ssf, state);
247  }
248  else
249  {
250  const auto ssf = Moose::FaceArg(
251  {fi, Moose::FV::LimiterType::CentralDifference, true, correct_skewness, elem, nullptr});
252  return _pressure(ssf, state);
253  }
254 }
255 
256 Real
258 {
259  mooseAssert(fi, "We should have a face info in " + name());
260  const Moose::ElemQpArg elem_arg = {_current_elem, _qp, _qrule, _q_point[_qp]};
261  mooseAssert(_qp == 0, "Only one quadrature point");
262  const auto state = determineState();
263 
264  const bool correct_skewness =
266 
267  if (_weighting_functor)
268  {
269  const auto ssf = Moose::FaceArg(
270  {fi,
272  MetaPhysicL::raw_value((*_weighting_functor)(elem_arg, state)) * fi->normal() > 0,
273  correct_skewness,
274  _weighting_functor->hasFaceSide(*fi, true) ? fi->elemPtr() : fi->neighborPtr(),
275  nullptr});
276  return fi->normal() * MetaPhysicL::raw_value((*_weighting_functor)(ssf, state));
277  }
278  else
279  return 1;
280 }
281 
282 Real
284 {
285  const Moose::ElemSideQpArg elem_side_arg = {
287  const auto state = determineState();
288  if (_weighting_functor)
289  return (*_weighting_functor)(elem_side_arg, state) * _normals[_qp] *
290  _pressure(elem_side_arg, state);
291  else
292  return _pressure(elem_side_arg, state);
293 }
294 
295 Real
297 {
298  const Moose::ElemSideQpArg elem_side_arg = {
300  const auto state = determineState();
301  if (_weighting_functor)
302  return (*_weighting_functor)(elem_side_arg, state) * _normals[_qp];
303  else
304  return 1;
305 }
306 
307 void
309 {
310  const auto & pps = static_cast<const PressureDrop &>(y);
311  _weighted_pressure_upstream += pps._weighted_pressure_upstream;
312  _weighted_pressure_downstream += pps._weighted_pressure_downstream;
313  _weight_upstream += pps._weight_upstream;
314  _weight_downstream += pps._weight_downstream;
315 }
316 
317 void
319 {
324 }
325 
326 Real
328 {
331  {
332  mooseWarning("Weight integral is 0 (downstream or upstream), either :\n"
333  "- pressure drop value is queried before being computed\n"
334  "- the weight flux integral is simply 0, the weighting is not appropriate");
335  return 0;
336  }
339 }
bool isFiniteVolumeInfoDirty() const
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
virtual void meshChanged() override
Definition: PressureDrop.C:117
const Moose::Functor< Real > & _pressure
The pressure functor.
Definition: PressureDrop.h:47
const unsigned int & _current_side
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual void finalize() override
Definition: PressureDrop.C:318
static InputParameters validParams()
Real computeQpWeightedPressureIntegral() const
Computes the contribution on a Qp to the weighted pressure integral.
Definition: PressureDrop.C:283
Moose::StateArg determineState() const
const std::string & getBoundaryName(BoundaryID boundary_id)
Moose::FV::InterpMethod _weight_interp_method
The interpolation method to use for the weighting functor quantity.
Definition: PressureDrop.h:51
Real computeFaceInfoWeightIntegral(const FaceInfo *fi) const
Computes the contribution on a face to the integral of the weight.
Definition: PressureDrop.C:257
auto raw_value(const Eigen::Map< T > &in)
const MooseArray< Point > & _q_point
const std::vector< double > y
MooseEnum interpolationMethods()
virtual const std::string & name() const
static InputParameters validParams()
Definition: PressureDrop.C:20
void mooseWarning(Args &&... args) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
Real _weighted_pressure_upstream
The weighted integral of the upstream pressure.
Definition: PressureDrop.h:57
virtual void execute() override
Definition: PressureDrop.C:123
std::vector< const FaceInfo *> _face_infos
const MooseArray< Real > & _JxW
LimiterType limiterType(InterpMethod interp_method)
const Elem * neighborPtr() const
void gatherSum(T &value)
registerMooseObject("NavierStokesApp", PressureDrop)
This postprocessor computes the pressure drop between an upstream and a downstream boundary...
Definition: PressureDrop.h:19
const Moose::Functor< RealVectorValue > *const _weighting_functor
A weighting functor if the pressure profile is not uniform.
Definition: PressureDrop.h:49
Real _weighted_pressure_downstream
The weighted integral of the downstream pressure.
Definition: PressureDrop.h:59
Real _weight_downstream
The integral of the weights on the downstream boundary, for normalization.
Definition: PressureDrop.h:63
PressureDrop(const InputParameters &parameters)
Definition: PressureDrop.C:42
const Point & normal() const
void paramError(const std::string &param, Args... args) const
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const=0
Real computeQpWeightIntegral() const
Computes the contribution on a Qp to the integral of the weight.
Definition: PressureDrop.C:296
virtual void initialize() override
Definition: PressureDrop.C:104
const MooseArray< Real > & _coord
virtual bool hasVariable(const std::string &var_name) const=0
const Elem * elemPtr() const
bool hasBoundary(const BoundaryName &name) const
bool isParamSetByUser(const std::string &name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real _weight_upstream
The integral of the weights on the upstream boundary, for normalization.
Definition: PressureDrop.h:61
std::vector< BoundaryID > _upstream_boundaries
Vector of the ids of the upstream boundaries.
Definition: PressureDrop.h:53
const QBase *const & _qrule
const MooseArray< Point > & _normals
IntRange< T > make_range(T beg, T end)
virtual Real getValue() const override
Definition: PressureDrop.C:327
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
const InputParameters & parameters() const
std::vector< BoundaryID > _downstream_boundaries
Vector of the ids of the downstream boundaries.
Definition: PressureDrop.h:55
Real computeFaceInfoWeightedPressureIntegral(const FaceInfo *fi) const
Computes the contribution on a face to the weighted pressure integral.
Definition: PressureDrop.C:219
const Elem *const & _current_elem
virtual const std::set< BoundaryID > & boundaryIDs() const
bool setInterpolationMethod(const MooseObject &obj, Moose::FV::InterpMethod &interp_method, const std::string &param_name)
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
void setupFiniteVolumeMeshData() const
virtual void threadJoin(const UserObject &y) override
Definition: PressureDrop.C:308