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 interpolation method to use for the velocity
143 : Moose::FV::InterpMethod _velocity_interp_method;
144 :
145 : /// Whether this object is operating on the displaced mesh
146 : const bool _displaced;
147 :
148 : private:
149 : /// A unity functor used in the epsilon virtual method
150 : const Moose::ConstantFunctor<ADReal> _unity_functor{1};
151 : };
152 :
153 : inline const Moose::FunctorBase<ADReal> &
154 183319892 : RhieChowInterpolatorBase::epsilon(THREAD_ID) const
155 : {
156 183319892 : return _unity_functor;
157 : }
158 :
159 : inline const INSFVPressureVariable &
160 : RhieChowInterpolatorBase::pressure(const THREAD_ID tid) const
161 : {
162 : mooseAssert(tid < _ps.size(), "Attempt to access out-of-bounds in pressure variable container");
163 : return *static_cast<INSFVPressureVariable *>(_ps[tid]);
164 : }
165 :
166 : template <typename Container>
167 : void
168 23521 : RhieChowInterpolatorBase::fillContainer(const std::string & name, Container & container)
169 : {
170 : typedef typename Container::value_type ContainedType;
171 49617 : for (const auto tid : make_range(libMesh::n_threads()))
172 : {
173 : auto * const var = static_cast<ContainedType>(
174 26096 : &UserObject::_subproblem.getVariable(tid, getParam<VariableName>(name)));
175 26096 : container[tid] = var;
176 : }
177 23521 : }
178 :
179 : template <typename VarType>
180 : void
181 23527 : RhieChowInterpolatorBase::checkBlocks(const VarType & var) const
182 : {
183 23527 : const auto & var_blocks = var.blockIDs();
184 23527 : const auto & uo_blocks = blockIDs();
185 :
186 : // Error if this UO has any blocks that the variable does not
187 : std::set<SubdomainID> uo_blocks_minus_var_blocks;
188 23527 : std::set_difference(uo_blocks.begin(),
189 : uo_blocks.end(),
190 : var_blocks.begin(),
191 : var_blocks.end(),
192 : std::inserter(uo_blocks_minus_var_blocks, uo_blocks_minus_var_blocks.end()));
193 23527 : if (uo_blocks_minus_var_blocks.size() > 0)
194 2 : mooseError("Block restriction of interpolator user object '",
195 : this->name(),
196 : "' (",
197 : Moose::stringify(blocks()),
198 : ") includes blocks not in the block restriction of variable '",
199 : var.name(),
200 : "' (",
201 : Moose::stringify(var.blocks()),
202 : ")");
203 :
204 : // Get the blocks in the variable but not this UO
205 : std::set<SubdomainID> var_blocks_minus_uo_blocks;
206 23525 : std::set_difference(var_blocks.begin(),
207 : var_blocks.end(),
208 : uo_blocks.begin(),
209 : uo_blocks.end(),
210 : std::inserter(var_blocks_minus_uo_blocks, var_blocks_minus_uo_blocks.end()));
211 :
212 : // For each block in the variable but not this UO, error if there is connection
213 : // to any blocks on the UO.
214 23525 : for (auto & block_id : var_blocks_minus_uo_blocks)
215 : {
216 2 : const auto connected_blocks = _moose_mesh.getBlockConnectedBlocks(block_id);
217 : std::set<SubdomainID> connected_blocks_on_uo;
218 2 : std::set_intersection(connected_blocks.begin(),
219 : connected_blocks.end(),
220 : uo_blocks.begin(),
221 : uo_blocks.end(),
222 : std::inserter(connected_blocks_on_uo, connected_blocks_on_uo.end()));
223 2 : if (connected_blocks_on_uo.size() > 0)
224 2 : mooseError("Block restriction of interpolator user object '",
225 : this->name(),
226 : "' (",
227 : Moose::stringify(uo_blocks),
228 : ") doesn't match the block restriction of variable '",
229 : var.name(),
230 : "' (",
231 : Moose::stringify(var_blocks),
232 : ")");
233 : }
234 23523 : }
|