Line data Source code
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 : #pragma once
11 :
12 : #include "RhieChowFaceFluxProvider.h"
13 : #include "TaggingInterface.h"
14 : #include "INSFVPressureVariable.h"
15 : #include "ADReal.h"
16 : #include "ADFunctorInterface.h"
17 : #include "INSFVPressureVariable.h"
18 : #include "libmesh/vector_value.h"
19 : #include "libmesh/id_types.h"
20 : #include "libmesh/stored_range.h"
21 :
22 : class MooseMesh;
23 : class INSFVVelocityVariable;
24 : class INSFVPressureVariable;
25 : namespace libMesh
26 : {
27 : class Elem;
28 : class MeshBase;
29 : }
30 :
31 : class RhieChowInterpolatorBase : public RhieChowFaceFluxProvider,
32 : public TaggingInterface,
33 : public ADFunctorInterface
34 : {
35 : public:
36 : static InputParameters validParams();
37 : RhieChowInterpolatorBase(const InputParameters & params);
38 :
39 : /**
40 : * API for momentum residual objects that have on-diagonals for velocity call.
41 : * This is only supposed to be called if we are using an implicit pressure-velocity
42 : * coupling in a monolithic solve.
43 : * @param The element we are adding 'a' coefficient data for
44 : * @param component The velocity component we are adding 'a' coefficient data for
45 : * @param value The value of 'a' that we are adding
46 : */
47 : virtual void addToA(const libMesh::Elem * elem, unsigned int component, const ADReal & value) = 0;
48 :
49 : /**
50 : * Retrieve a face velocity
51 : * @param m The velocity interpolation method. This is either Rhie-Chow or Average. Rhie-Chow is
52 : * recommended as it avoids checkerboards in the pressure field
53 : * @param fi The face that we wish to retrieve the velocity for
54 : * @param tid The thread ID
55 : * @return The face velocity
56 : */
57 : virtual VectorValue<ADReal> getVelocity(const Moose::FV::InterpMethod m,
58 : const FaceInfo & fi,
59 : const Moose::StateArg & time,
60 : const THREAD_ID tid,
61 : bool subtract_mesh_velocity) const = 0;
62 :
63 : virtual Real getVolumetricFaceFlux(const Moose::FV::InterpMethod m,
64 : const FaceInfo & fi,
65 : const Moose::StateArg & time,
66 : const THREAD_ID tid,
67 : bool subtract_mesh_velocity) const override;
68 :
69 : /// Return the interpolation method used for velocity
70 4097 : Moose::FV::InterpMethod velocityInterpolationMethod() const { return _velocity_interp_method; }
71 :
72 : /**
73 : * makes sure coefficient data gets communicated on both sides of a given boundary. This
74 : * is a virtual function, mostly used for monolithic approaches.
75 : */
76 0 : virtual void ghostADataOnBoundary(const BoundaryID /*boundary_id*/) {}
77 :
78 : /**
79 : * @return The pressure variable corresponding to the provided thread ID
80 : */
81 : const INSFVPressureVariable & pressure(THREAD_ID tid) const;
82 :
83 : const INSFVVelocityVariable * vel() const { return _u; }
84 :
85 : /// Bool of the Rhie Chow user object is used in monolithic/segregated approaches
86 : virtual bool segregated() const = 0;
87 :
88 : protected:
89 : /**
90 : * A virtual method that allows us to only implement getVelocity once for free and porous flows
91 : */
92 : virtual const Moose::FunctorBase<ADReal> & epsilon(THREAD_ID tid) const;
93 :
94 : /**
95 : * Fill the passed-in variable container with the thread copies of \p var_name
96 : */
97 : template <typename Container>
98 : void fillContainer(const std::string & var_name, Container & container);
99 :
100 : /**
101 : * Check the block consistency between the passed in \p var and us
102 : */
103 : template <typename VarType>
104 : void checkBlocks(const VarType & var) const;
105 :
106 : /// The \p MooseMesh that this user object operates on
107 : MooseMesh & _moose_mesh;
108 :
109 : /// The \p libMesh mesh that this object acts on
110 : const libMesh::MeshBase & _mesh;
111 :
112 : /// The dimension of the mesh, e.g. 3 for hexes and tets, 2 for quads and tris
113 : const unsigned int _dim;
114 :
115 : /// The thread 0 copy of the pressure variable
116 : INSFVPressureVariable * const _p;
117 :
118 : /// The thread 0 copy of the x-velocity variable
119 : INSFVVelocityVariable * const _u;
120 :
121 : /// The thread 0 copy of the y-velocity variable (null if the problem is 1D)
122 : INSFVVelocityVariable * const _v;
123 :
124 : /// The thread 0 copy of the z-velocity variable (null if the problem is not 3D)
125 : INSFVVelocityVariable * const _w;
126 :
127 : /// All the thread copies of the pressure variable
128 : std::vector<MooseVariableFVReal *> _ps;
129 :
130 : /// All the thread copies of the x-velocity variable
131 : std::vector<MooseVariableFVReal *> _us;
132 :
133 : /// All the thread copies of the y-velocity variable
134 : std::vector<MooseVariableFVReal *> _vs;
135 :
136 : /// All the thread copies of the z-velocity variable
137 : std::vector<MooseVariableFVReal *> _ws;
138 :
139 : /// The velocity variable numbers
140 : std::vector<unsigned int> _var_numbers;
141 :
142 : /// The nonlinear system
143 : SystemBase & _sys;
144 :
145 : /// The interpolation method to use for the velocity
146 : Moose::FV::InterpMethod _velocity_interp_method;
147 :
148 : /// Whether this object is operating on the displaced mesh
149 : const bool _displaced;
150 :
151 : private:
152 : /// A unity functor used in the epsilon virtual method
153 : const Moose::ConstantFunctor<ADReal> _unity_functor{1};
154 : };
155 :
156 : inline const Moose::FunctorBase<ADReal> &
157 183532948 : RhieChowInterpolatorBase::epsilon(THREAD_ID) const
158 : {
159 183532948 : return _unity_functor;
160 : }
161 :
162 : inline const INSFVPressureVariable &
163 : RhieChowInterpolatorBase::pressure(const THREAD_ID tid) const
164 : {
165 : mooseAssert(tid < _ps.size(), "Attempt to access out-of-bounds in pressure variable container");
166 : return *static_cast<INSFVPressureVariable *>(_ps[tid]);
167 : }
168 :
169 : template <typename Container>
170 : void
171 23521 : RhieChowInterpolatorBase::fillContainer(const std::string & name, Container & container)
172 : {
173 : typedef typename Container::value_type ContainedType;
174 49617 : for (const auto tid : make_range(libMesh::n_threads()))
175 : {
176 : auto * const var = static_cast<ContainedType>(
177 26096 : &UserObject::_subproblem.getVariable(tid, getParam<VariableName>(name)));
178 26096 : container[tid] = var;
179 : }
180 23521 : }
181 :
182 : template <typename VarType>
183 : void
184 23527 : RhieChowInterpolatorBase::checkBlocks(const VarType & var) const
185 : {
186 23527 : const auto & var_blocks = var.blockIDs();
187 23527 : const auto & uo_blocks = blockIDs();
188 :
189 : // Error if this UO has any blocks that the variable does not
190 : std::set<SubdomainID> uo_blocks_minus_var_blocks;
191 23527 : std::set_difference(uo_blocks.begin(),
192 : uo_blocks.end(),
193 : var_blocks.begin(),
194 : var_blocks.end(),
195 : std::inserter(uo_blocks_minus_var_blocks, uo_blocks_minus_var_blocks.end()));
196 23527 : if (uo_blocks_minus_var_blocks.size() > 0)
197 6 : mooseError("Block restriction of interpolator user object '",
198 2 : this->name(),
199 : "' (",
200 : Moose::stringify(blocks()),
201 : ") includes blocks not in the block restriction of variable '",
202 2 : var.name(),
203 : "' (",
204 : Moose::stringify(var.blocks()),
205 : ")");
206 :
207 : // Get the blocks in the variable but not this UO
208 : std::set<SubdomainID> var_blocks_minus_uo_blocks;
209 23525 : std::set_difference(var_blocks.begin(),
210 : var_blocks.end(),
211 : uo_blocks.begin(),
212 : uo_blocks.end(),
213 : std::inserter(var_blocks_minus_uo_blocks, var_blocks_minus_uo_blocks.end()));
214 :
215 : // For each block in the variable but not this UO, error if there is connection
216 : // to any blocks on the UO.
217 23525 : for (auto & block_id : var_blocks_minus_uo_blocks)
218 : {
219 2 : const auto connected_blocks = _moose_mesh.getBlockConnectedBlocks(block_id);
220 : std::set<SubdomainID> connected_blocks_on_uo;
221 2 : std::set_intersection(connected_blocks.begin(),
222 : connected_blocks.end(),
223 : uo_blocks.begin(),
224 : uo_blocks.end(),
225 : std::inserter(connected_blocks_on_uo, connected_blocks_on_uo.end()));
226 2 : if (connected_blocks_on_uo.size() > 0)
227 6 : mooseError("Block restriction of interpolator user object '",
228 2 : this->name(),
229 : "' (",
230 : Moose::stringify(uo_blocks),
231 : ") doesn't match the block restriction of variable '",
232 2 : var.name(),
233 : "' (",
234 : Moose::stringify(var_blocks),
235 : ")");
236 : }
237 23523 : }
|