https://mooseframework.inl.gov
PINSFVRhieChowInterpolator.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 #include "Reconstructions.h"
12 #include "NS.h"
13 #include "Assembly.h"
15 
17 
20 {
22  params.addClassDescription("Performs interpolations and reconstructions of porosity and computes "
23  "the Rhie-Chow face velocities.");
24  ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", /*quiet=*/true);
26  params.addRequiredParam<MooseFunctorName>(NS::porosity, "The porosity");
27  params.addParam<unsigned short>(
28  "smoothing_layers",
29  0,
30  "The number of interpolation-reconstruction operations to perform on the porosity");
31  params.addRelationshipManager("ElementSideNeighborLayers",
33  [](const InputParameters & obj_params, InputParameters & rm_params)
34  {
35  rm_params.set<unsigned short>("layers") =
36  obj_params.get<unsigned short>("smoothing_layers");
37  rm_params.set<bool>("use_displaced_mesh") =
38  obj_params.get<bool>("use_displaced_mesh");
39  });
40  return params;
41 }
42 
44  : INSFVRhieChowInterpolator(params),
45  _eps(getFunctor<ADReal>(NS::porosity)),
46  _smoothed_eps(_moose_mesh, NS::smoothed_porosity, /*extrapolated_boundary*/ true),
47  _epss(libMesh::n_threads(), nullptr),
48  _smoothed_epss(libMesh::n_threads(), nullptr),
49  _smoothing_layers(getParam<unsigned short>("smoothing_layers"))
50 {
51  if (_smoothing_layers && _eps.wrapsType<MooseVariableBase>())
52  paramError(
54  "If we are reconstructing porosity, then the input porosity to this user object cannot "
55  "be a Moose variable. There are issues with reconstructing Moose variables: 1) initial "
56  "conditions are run after user objects initial setup 2) reconstructing from a variable "
57  "requires ghosting the solution vectors 3) it's difficult to restrict the face "
58  "informations we evaluate interpolations and reconstructions on such that we never query "
59  "an algebraically remote element due to things like two-term extrapolated boundary faces "
60  "which trigger gradient evaluations which trigger neighbor element evaluation");
61 
62  const auto porosity_name = deduceFunctorName(NS::porosity);
63 
64  for (const auto tid : make_range(libMesh::n_threads()))
65  {
66  _epss[tid] = &UserObject::_subproblem.getFunctor<ADReal>(porosity_name, tid, name(), true);
67 
68  if (_smoothing_layers > 0)
69  {
70  if (!UserObject::_subproblem.hasFunctor(NS::smoothed_porosity, tid))
71  // Smoothed porosity is only an envelope at this point, it will be set during pinsfvSetup()
73 
74  _smoothed_epss[tid] =
76  }
77  }
78 }
79 
80 void
82 {
84  pinsfvSetup();
85 }
86 
87 void
89 {
90  if (!_smoothing_layers)
91  return;
92 
93  if (dynamic_cast<BernoulliPressureVariable *>(_p))
94  paramError(
96  "If 'smoothing_layers' is non-zero, e.g. if the porosity is smooth(ed), "
97  "then the pressure drop should be computed automatically. The "
98  "'BernoulliPressureVariable' class enforces a pressure drop according to the Bernoulli "
99  "equation on any face which has different pressure values on either side. This is "
100  "undesirable when the porosity is varying smoothing and there may be pressure drops "
101  "corresponding to viscous effects. Please just use the 'INSFVPressureVariable' "
102  "class for pressure when the porosity is smooth.");
103 
104  const auto & all_fi = _moose_mesh.allFaceInfo();
105  _geometric_fi.reserve(all_fi.size());
106 
107  for (const auto & fi : all_fi)
109  _geometric_fi.push_back(&fi);
110 
111  _geometric_fi.shrink_to_fit();
112 
113  const auto saved_do_derivatives = ADReal::do_derivatives;
114  ADReal::do_derivatives = true;
117  ADReal::do_derivatives = saved_do_derivatives;
118 
119  // Assign the new functor to all
120  for (const auto tid : make_range((unsigned int)(1), libMesh::n_threads()))
121  {
122  auto & other_smoothed_epss = const_cast<Moose::Functor<ADReal> &>(
124  other_smoothed_epss.assign(_smoothed_eps);
125  }
126 }
127 
128 bool
130 {
131  if (&fi.elem() == libMesh::remote_elem)
132  return false;
133 
134  bool on_us = blockIDs().count(fi.elem().subdomain_id());
135 
136  if (fi.neighborPtr())
137  {
138  if (&fi.neighbor() == libMesh::remote_elem)
139  return false;
140 
141  on_us = on_us || blockIDs().count(fi.neighbor().subdomain_id());
142  }
143 
144  if (!on_us)
145  // Neither the element nor neighbor has a subdomain id on which we are active, so this face is
146  // not relevant
147  return false;
148 
149  //
150  // Ok, we've established that either the element or neighbor is active on our subdomains and
151  // neither of them are remote elements, so this face is still in the running to be considered
152  // relevant. There is one more caveat to be considered. In the case that we are a boundary face,
153  // we will generally need a two term expansion to compute our value, which will require a
154  // cell-gradient evaluation. If that is the case, then all of our surrounding neighbors cannot be
155  // remote. If we are not a boundary face, then at this point we're safe
156  //
157 
158  if (!Moose::FV::onBoundary(blockIDs(), fi))
159  return true;
160 
161  const auto & boundary_elem = (fi.neighborPtr() && blockIDs().count(fi.neighbor().subdomain_id()))
162  ? fi.neighbor()
163  : fi.elem();
164 
165  for (auto * const neighbor : boundary_elem.neighbor_ptr_range())
166  {
167  if (!neighbor)
168  continue;
169 
170  if ((neighbor == libMesh::remote_elem))
171  return false;
172  }
173 
174  // We made it through all the tests!
175  return true;
176 }
177 
178 void
180 {
182  pinsfvSetup();
183  else
184  // Cannot compute Rhie Chow coefficients on initial
186 }
187 
188 void
190 {
191  // Cannot compute Rhie Chow coefficients on initial
194 }
195 
196 void
198 {
199  // Cannot compute Rhie Chow coefficients on initial
202 }
PINSFVRhieChowInterpolator(const InputParameters &params)
INSFVPressureVariable *const _p
The thread 0 copy of the pressure variable.
virtual void initialize() override
unsigned int n_threads()
const Moose::Functor< T > & getFunctor(const std::string &name, const THREAD_ID tid, const std::string &requestor_name, bool requestor_is_ad)
MooseMesh & _moose_mesh
The MooseMesh that this user object operates on.
virtual void meshChanged() override
bool isFaceGeometricallyRelevant(const FaceInfo &fi) const
void setAdditionalValue(const std::string &names)
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
const Elem & elem() const
static const std::string smoothed_porosity
Definition: NS.h:105
Moose::StateArg determineState() const
const ExecFlagType & _current_execute_flag
std::vector< const FaceInfo * > _geometric_fi
All the face information that are "geometrically" accessible on this process.
T & set(const std::string &name, bool quiet_mode=false)
std::vector< const Moose::Functor< ADReal > * > _epss
All the thread copies of the problem&#39;s porosity functor.
virtual const std::set< SubdomainID > & blockIDs() const
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
virtual const std::string & name() const
SubProblem & _subproblem
static const std::string porosity
Definition: NS.h:104
const std::vector< FaceInfo > & allFaceInfo() const
void interpolateReconstruct(CellCenteredMapFunctor< T, Map > &output_functor, const Moose::FunctorBase< T > &input_functor, const unsigned int num_int_recs, const bool weight_with_sf, const std::vector< const FaceInfo *> &faces, const Moose::StateArg &time)
Takes an input functor that can be evaluated at faces, typically by linearly interpolating between ad...
const Elem * neighborPtr() const
std::vector< const Moose::Functor< ADReal > * > _smoothed_epss
All the thread copies of the problem&#39;s smoothed porosity functor.
static InputParameters validParams()
const Elem & neighbor() const
void paramError(const std::string &param, Args... args) const
static InputParameters validParams()
CellCenteredMapFunctor< ADReal, std::unordered_map< dof_id_type, ADReal > > _smoothed_eps
The smoothed porosity functor/field.
bool onBoundary(const SubdomainRestrictable &obj, const FaceInfo &fi)
registerMooseObject("NavierStokesApp", PINSFVRhieChowInterpolator)
virtual void meshChanged() override
static const std::string pressure
Definition: NS.h:56
IntRange< T > make_range(T beg, T end)
This user-object gathers &#39;a&#39; (on-diagonal velocity coefficients) data.
void pinsfvSetup()
called during the first initialize() and upon meshChanged(), this method performs the interpolations ...
const unsigned short _smoothing_layers
The number of interpolations and reconstructions that should be performed on the porosity functor/fie...
const Moose::Functor< ADReal > & _eps
The thread 0 copy of the porosity functor held by the subproblem.
virtual void finalize() override
A class that inherits the free-flow class&#39;s implementation of Rhie-Chow data gathering and adds the a...
static std::string deduceFunctorName(const std::string &name, const InputParameters &params)
const RemoteElem * remote_elem
const ExecFlagType EXEC_INITIAL