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 <tuple>
13 :
14 : #include "Limiter.h"
15 : #include "FaceInfo.h"
16 : #include "MooseTypes.h"
17 : #include "libmesh/elem.h"
18 : #include "libmesh/point.h"
19 : #include "libmesh/quadrature.h"
20 :
21 : #include <set>
22 :
23 : namespace Moose
24 : {
25 : /**
26 : * A structure that is used to evaluate Moose functors logically at an element/cell center
27 : */
28 : struct ElemArg
29 : {
30 : const libMesh::Elem * elem;
31 : bool correct_skewness;
32 :
33 : /**
34 : * @returns The conceptual physical location of this data structure
35 : */
36 2984851 : Point getPoint() const { return elem->vertex_average(); }
37 :
38 : /**
39 : * friend function that allows this structure to be used as keys in ordered containers like sets
40 : * and maps
41 : */
42 0 : friend bool operator<(const ElemArg & l, const ElemArg & r)
43 : {
44 0 : return std::make_tuple(l.elem, l.correct_skewness) <
45 0 : std::make_tuple(r.elem, r.correct_skewness);
46 : }
47 : };
48 :
49 : /**
50 : * A structure that is used to evaluate Moose functors at an arbitrary physical point contained
51 : * within an element
52 : */
53 : struct ElemPointArg
54 : {
55 : const libMesh::Elem * elem;
56 : libMesh::Point point;
57 : bool correct_skewness;
58 :
59 : /**
60 : * @returns The conceptual physical location of this data structure
61 : */
62 701 : Point getPoint() const { return point; }
63 :
64 : /**
65 : * friend function that allows this structure to be used as keys in ordered containers like sets
66 : * and maps
67 : */
68 : friend bool operator<(const ElemPointArg & l, const ElemPointArg & r)
69 : {
70 : return std::make_tuple(l.elem, l.point, l.correct_skewness) <
71 : std::make_tuple(r.elem, r.point, r.correct_skewness);
72 : }
73 :
74 : /**
75 : * Make a \p ElemArg from our data
76 : */
77 66476 : ElemArg makeElem() const { return {elem, correct_skewness}; }
78 : };
79 :
80 : /**
81 : * Argument for requesting functor evaluation at quadrature point locations on an element side.
82 : * Data in the argument:
83 : * - The element
84 : * - The element side on which the quadrature points are located
85 : * - The quadrature point index, e.g. if there are \p n quadrature points, we are requesting the\n
86 : * evaluation of the i-th point
87 : * - The quadrature rule that can be used to initialize the functor on the given element and side
88 : */
89 : struct ElemSideQpArg
90 : {
91 : /// The element
92 : const libMesh::Elem * elem;
93 :
94 : /// The local side index
95 : unsigned int side;
96 :
97 : /// The quadrature point index
98 : unsigned int qp;
99 :
100 : /// The quadrature rule
101 : const libMesh::QBase * qrule;
102 :
103 : /// The physical location of the quadrature point
104 : Point point;
105 :
106 : /**
107 : * @returns The conceptual physical location of this data structure
108 : */
109 570339 : Point getPoint() const { return point; }
110 : };
111 :
112 : /**
113 : * State argument for evaluating functors. The iteration type indicates whether you want to evaluate
114 : * a functor based on some iterate state of a transient calculation, nonlinear solve, etc. The state
115 : * indicates which iterate of the iterate type we want to evaluate on. A state of 0 indicates
116 : * "current", e.g. the current time or the current nonlinear iteration (which should actually be
117 : * equivalent); a state of 1 indicates the most-recent "old" time or the most recent previous
118 : * nonlinear iteration, etc.
119 : */
120 :
121 : struct StateArg
122 : {
123 : /**
124 : * Prevent implicit conversions from boolean to avoid users accidentally constructing a time
125 : * argument when they meant to construct a skewness argument, etc.
126 : */
127 : StateArg(bool) = delete;
128 :
129 0 : StateArg(unsigned int state_in) : state(state_in), iteration_type(SolutionIterationType::Time) {}
130 :
131 14302716 : StateArg(unsigned int state_in, SolutionIterationType iteration_type_in)
132 14302716 : : state(state_in), iteration_type(iteration_type_in)
133 : {
134 14302716 : }
135 :
136 : /// The state. Zero represents the most recent state, so for any kind of iteration type, a zero
137 : /// state represents the current state, e.g. current solution
138 : /// One may represent the 'old' value (one before, in the iteration_type specified), and two an 'older' or two steps away state
139 : unsigned int state;
140 :
141 : /// The solution iteration type, e.g. time or nonlinear
142 : SolutionIterationType iteration_type;
143 :
144 : private:
145 76030309 : StateArg() : state(0), iteration_type(SolutionIterationType::Time) {}
146 :
147 : friend StateArg currentState();
148 : };
149 :
150 : inline StateArg
151 76030309 : currentState()
152 : {
153 76030309 : return {};
154 : }
155 :
156 : inline StateArg
157 0 : oldState()
158 : {
159 0 : return {(unsigned int)1};
160 : }
161 :
162 : inline StateArg
163 55500 : previousNonlinearState()
164 : {
165 55500 : return {(unsigned int)1, SolutionIterationType::Nonlinear};
166 : }
167 :
168 : /**
169 : * A structure defining a "face" evaluation calling argument for Moose functors
170 : */
171 : struct FaceArg
172 : {
173 : /// a face information object which defines our location in space
174 : const FaceInfo * fi;
175 :
176 : /// a limiter which defines how the functor evaluated on either side of the face should be
177 : /// interpolated to the face
178 : Moose::FV::LimiterType limiter_type;
179 :
180 : /// a boolean which states whether the face information element is upwind of the face
181 : bool elem_is_upwind;
182 :
183 : /// Whether to perform skew correction
184 : bool correct_skewness;
185 :
186 : /// A member that can be used to indicate whether there is a sidedness to this face. For example,
187 : /// a block restricted diffusion kernel may use this to specify that a diffusion coefficient
188 : /// should be evaluated on the elem side of the face, ignoring possible jumps in the diffusion
189 : /// coefficient between the elem and neighbor sides of the face. If this is null, then a functor
190 : /// that is itself block restricted may modify the value to indicate \emph its sidedness. If there
191 : /// is ever a mismatch between the specified sidedness of a physics object and the sidedness of a
192 : /// functor, then we will error
193 : /// If unspecified (nullptr), the evaluation will be two-sided, unless the functor is not defined
194 : /// on one side of the face.
195 : const libMesh::Elem * face_side;
196 :
197 : /// A member that can be used to define the instance in which the limiters are executed
198 : const Moose::StateArg * state_limiter;
199 :
200 : /**
201 : * @returns The conceptual physical location of this data structure
202 : */
203 1649873 : libMesh::Point getPoint() const { return fi->faceCentroid(); }
204 :
205 : /**
206 : * Make a \p ElemArg from our data using the face information element
207 : */
208 82714966 : ElemArg makeElem() const { return {&fi->elem(), correct_skewness}; }
209 :
210 : /**
211 : * Make a \p ElemArg from our data using the face information neighbor
212 : */
213 82714918 : ElemArg makeNeighbor() const { return {fi->neighborPtr(), correct_skewness}; }
214 :
215 : /**
216 : * friend function that allows this structure to be used as keys in ordered containers like sets
217 : * and maps
218 : */
219 0 : friend bool operator<(const FaceArg & l, const FaceArg & r)
220 : {
221 0 : return std::make_tuple(
222 0 : l.fi, l.limiter_type, l.elem_is_upwind, l.correct_skewness, l.face_side) <
223 0 : std::make_tuple(r.fi, r.limiter_type, r.elem_is_upwind, r.correct_skewness, r.face_side);
224 : }
225 : };
226 :
227 : struct NodeArg
228 : {
229 : /// The node which defines our location in space
230 : const libMesh::Node * node;
231 :
232 : /**
233 : * Indicates what subdomains this argument should be associated with. If a single subdomain is
234 : * given, then there is no ambiguity when this argument is used to evaluate functors at the
235 : * intersection of different blocks. If multiple subdomains are given at such an intersection
236 : * point, it is up to the functor whether it can be evaluated unambiguously, perform an average,
237 : * or error
238 : */
239 : const std::set<SubdomainID> * subdomain_ids;
240 :
241 151321 : libMesh::Point getPoint() const { return *node; }
242 :
243 : /// A static member that can be used when the connection of a node to subdomains is unknown.
244 : /// Functors may still be able to evaluate a NodeArg with this as the provided \p subdomain_ids
245 : /// if the functor has no "sidedness", e.g. like a H1 finite element family variable
246 : static const std::set<SubdomainID> undefined_subdomain_connection;
247 : };
248 :
249 : /**
250 : * Argument for requesting functor evaluation at a quadrature point location in an element. Data
251 : * in the argument:
252 : * - The element containing the quadrature point
253 : * - The quadrature point index, e.g. if there are \p n quadrature points, we are requesting the\n
254 : * evaluation of the i-th point
255 : * - The quadrature rule that can be used to initialize the functor on the given element
256 : */
257 : struct ElemQpArg
258 : {
259 : /// The element
260 : const libMesh::Elem * elem;
261 :
262 : /// The quadrature point index
263 : unsigned int qp;
264 :
265 : /// The quadrature rule
266 : const libMesh::QBase * qrule;
267 :
268 : /// The physical location of the quadrature point
269 : libMesh::Point point;
270 :
271 : /**
272 : * @returns The conceptual physical location of this data structure
273 : */
274 2366643 : libMesh::Point getPoint() const { return point; }
275 : };
276 : }
|