https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
18
21{
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) ==
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
103void
105{
110
111 // Build the face infos in all cases, needed to detect upstream/downstream status
114}
115
116void
121
122void
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) !=
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
218Real
220{
221 mooseAssert(fi, "We should have a face info in " + name());
222
223 const bool correct_skewness =
224 _weight_interp_method == Moose::FV::InterpMethod::SkewCorrectedAverage;
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
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
245 ssf.limiter_type = Moose::FV::LimiterType::CentralDifference;
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
256Real
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 =
265 _weight_interp_method == Moose::FV::InterpMethod::SkewCorrectedAverage;
266
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
282Real
284{
285 const Moose::ElemSideQpArg elem_side_arg = {
287 const auto state = determineState();
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
295Real
297{
298 const Moose::ElemSideQpArg elem_side_arg = {
300 const auto state = determineState();
302 return (*_weighting_functor)(elem_side_arg, state) * _normals[_qp];
303 else
304 return 1;
305}
306
307void
309{
310 const auto & pps = static_cast<const PressureDrop &>(y);
312 _weighted_pressure_downstream += pps._weighted_pressure_downstream;
313 _weight_upstream += pps._weight_upstream;
314 _weight_downstream += pps._weight_downstream;
315}
316
317void
325
326Real
328{
329 if (MooseUtils::absoluteFuzzyEqual(_weight_upstream, 0) ||
330 MooseUtils::absoluteFuzzyEqual(_weight_downstream, 0))
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}
const std::vector< double > y
registerMooseObject("NavierStokesApp", PressureDrop)
bool hasBoundary(const BoundaryName &name) const
virtual const std::set< BoundaryID > & boundaryIDs() const
const Point & normal() const
const Elem * neighborPtr() const
const Elem * elemPtr() const
bool isParamSetByUser(const std::string &name) const
void addRequiredParam(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)
const InputParameters & parameters() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
void setupFiniteVolumeMeshData() const
const std::string & getBoundaryName(const BoundaryID boundary_id) const
bool isFiniteVolumeInfoDirty() const
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
This postprocessor computes the pressure drop between an upstream and a downstream boundary.
Real computeFaceInfoWeightedPressureIntegral(const FaceInfo *fi) const
Computes the contribution on a face to the weighted pressure integral.
Real computeFaceInfoWeightIntegral(const FaceInfo *fi) const
Computes the contribution on a face to the integral of the weight.
Real _weighted_pressure_upstream
The weighted integral of the upstream pressure.
const Moose::Functor< Real > & _pressure
The pressure functor.
PressureDrop(const InputParameters &parameters)
static InputParameters validParams()
std::vector< BoundaryID > _upstream_boundaries
Vector of the ids of the upstream boundaries.
Moose::FV::InterpMethod _weight_interp_method
The interpolation method to use for the weighting functor quantity.
virtual void finalize() override
virtual void execute() override
Real _weight_downstream
The integral of the weights on the downstream boundary, for normalization.
virtual void meshChanged() override
const Moose::Functor< RealVectorValue > *const _weighting_functor
A weighting functor if the pressure profile is not uniform.
virtual Real getValue() const override
Real computeQpWeightedPressureIntegral() const
Computes the contribution on a Qp to the weighted pressure integral.
virtual void initialize() override
virtual void threadJoin(const UserObject &y) override
Real _weighted_pressure_downstream
The weighted integral of the downstream pressure.
Real _weight_upstream
The integral of the weights on the upstream boundary, for normalization.
Real computeQpWeightIntegral() const
Computes the contribution on a Qp to the integral of the weight.
std::vector< BoundaryID > _downstream_boundaries
Vector of the ids of the downstream boundaries.
static InputParameters validParams()
const unsigned int & _current_side
const MooseArray< Real > & _coord
const QBase *const & _qrule
const MooseArray< Real > & _JxW
const MooseArray< Point > & _q_point
const MooseArray< Point > & _normals
const Elem *const & _current_elem
std::vector< const FaceInfo * > _face_infos
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
virtual bool hasVariable(const std::string &var_name) const=0
Moose::StateArg determineState() const
void gatherSum(T &value)
auto raw_value(const Eigen::Map< T > &in)
LimiterType limiterType(InterpMethod interp_method)
bool setInterpolationMethod(const MooseObject &obj, Moose::FV::InterpMethod &interp_method, const std::string &param_name)
MooseEnum interpolationMethods()