Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 : #ifndef LIBMESH_VARIABLE_H
19 : #define LIBMESH_VARIABLE_H
20 :
21 : // Local Includes
22 : #include "libmesh/libmesh_common.h"
23 : #include "libmesh/fe_type.h"
24 : #include "libmesh/id_types.h"
25 :
26 : // C++ includes
27 : #include <set>
28 : #include <string>
29 : #include <vector>
30 :
31 : namespace libMesh
32 : {
33 :
34 : // Forward Declaration
35 : class System;
36 : class MeshBase;
37 :
38 : /**
39 : * This class defines the notion of a variable in the system.
40 : * A variable is one of potentially several unknowns in the
41 : * problem at hand. A variable is described by a unique
42 : * name, a finite element approximation family, and
43 : * (optionally) a list of subdomains to which the
44 : * variable is restricted.
45 : *
46 : * \author Roy Stogner
47 : * \date 2010
48 : * \brief A variable which is solved for in a System of equations.
49 : */
50 : class Variable
51 : {
52 : public:
53 :
54 : /**
55 : * Constructor. Omits the subdomain mapping, hence this
56 : * constructor creates a variable which is active on
57 : * all subdomains.
58 : */
59 7218 : Variable (System * sys,
60 : std::string var_name,
61 : const unsigned int var_number,
62 : const unsigned int first_scalar_num,
63 254227 : const FEType & var_type) :
64 239791 : _sys(sys),
65 247009 : _name(std::move(var_name)),
66 : _active_subdomains(),
67 239791 : _number(var_number),
68 239791 : _first_scalar_number(first_scalar_num),
69 254365 : _type(var_type)
70 7218 : {}
71 :
72 : /**
73 : * Constructor. Takes a set which contains the subdomain
74 : * indices for which this variable is active.
75 : */
76 7377710 : Variable (System * sys,
77 : std::string var_name,
78 : const unsigned int var_number,
79 : const unsigned int first_scalar_num,
80 : const FEType & var_type,
81 7377710 : const std::set<subdomain_id_type> & var_active_subdomains) :
82 6961966 : _sys(sys),
83 7169838 : _name(std::move(var_name)),
84 : _active_subdomains(var_active_subdomains),
85 6961966 : _number(var_number),
86 6961966 : _first_scalar_number(first_scalar_num),
87 7377710 : _type(var_type)
88 7377710 : {}
89 :
90 : /**
91 : * Standard constructors.
92 : */
93 : Variable (const Variable &) = default;
94 : Variable & operator= (const Variable &) = default;
95 16995532 : Variable (Variable &&) = default;
96 : Variable & operator= (Variable &&) = default;
97 :
98 : /**
99 : * \returns true iff the \p other Variable has the same
100 : * characteristics and system numbering as this one.
101 : */
102 : bool operator== ( const Variable & other) const
103 : {
104 : return (_sys == other._sys) &&
105 : (_name == other._name) &&
106 : (_active_subdomains == other._active_subdomains) &&
107 : (_first_scalar_number == other._first_scalar_number) &&
108 : (_type == other._type);
109 : }
110 :
111 : /**
112 : * \returns A pointer to the System this Variable is part of.
113 : */
114 3093 : System * system() const
115 : {
116 6997425 : return _sys;
117 : }
118 :
119 : /**
120 : * \returns The user-specified name of the variable.
121 : */
122 2385408 : const std::string & name() const
123 30537772 : { return _name; }
124 :
125 : /**
126 : * \returns The rank of this variable in the system.
127 : */
128 10722532 : unsigned int number() const
129 114899602 : { return _number; }
130 :
131 : /**
132 : * \returns The index of the first scalar component of this variable in the system. Say you've
133 : * got a flow problem that's (u,v,w,p,T) - p will be at first_scalar_number 3 regardless of
134 : * whether p is variable number 1 in the case that u,v,w is represented by a single vector-valued
135 : * variable at number 0, or p is variable number 3 in the case that u,v,w are three scalar-valued
136 : * variables with variable numbers 0,1,2
137 : */
138 482031 : unsigned int first_scalar_number() const
139 641006 : { return _first_scalar_number; }
140 :
141 : /**
142 : * \returns The \p FEType for this variable.
143 : */
144 72739778 : const FEType & type() const
145 344702555 : { return _type; }
146 :
147 : /**
148 : * \returns The number of components of this variable if the \p FEFamily is \p SCALAR or if the
149 : * associated \p FEFieldType is \p TYPE_SCALAR. Otherwise this will error because determination of
150 : * the number of components for a \p TYPE_VECTOR requires the mesh
151 : */
152 : unsigned int n_components() const;
153 :
154 : /**
155 : * \returns The number of components of this variable
156 : */
157 : unsigned int n_components(const MeshBase & mesh) const;
158 :
159 : /**
160 : * \returns \p true if this variable is active on subdomain \p sid,
161 : * \p false otherwise.
162 : *
163 : * \note We interpret the special case of an empty \p
164 : * _active_subdomains container as active everywhere, i.e. for all
165 : * subdomains.
166 : */
167 361069496 : bool active_on_subdomain (subdomain_id_type sid) const
168 368723404 : { return (_active_subdomains.empty() || _active_subdomains.count(sid)); }
169 :
170 : /**
171 : * \returns \p true if this variable is active on all subdomains
172 : * because it has no specified activity map. This can be used
173 : * to perform more efficient computations in some places.
174 : */
175 1230 : bool implicitly_active () const
176 1230 : { return _active_subdomains.empty(); }
177 :
178 : /**
179 : * \returns The set of subdomain ids this variable lives on.
180 : */
181 217821 : const std::set<subdomain_id_type> & active_subdomains() const
182 552740 : { return _active_subdomains; }
183 :
184 : protected:
185 : System * _sys;
186 : std::string _name;
187 : std::set<subdomain_id_type> _active_subdomains;
188 : unsigned int _number;
189 : unsigned int _first_scalar_number;
190 : FEType _type;
191 :
192 : private:
193 : /**
194 : * \returns The \p FEType for this variable. Altering this while
195 : * this Variable is already in use may be dangerous!
196 : */
197 746 : FEType & type()
198 2468 : { return _type; }
199 :
200 : // DofMap can change a VariableGroup type() to disable/enable
201 : // p-refinement post-variable-addition.
202 : friend class DofMap;
203 : };
204 :
205 :
206 :
207 : /**
208 : * This class defines a logically grouped set of variables in
209 : * the system. \p VariableGroup is appropriate for representing
210 : * several unknowns in the problem that are all approximated
211 : * with the same finite element approximation family and
212 : * (optionally) a list of subdomains to which the
213 : * variables are restricted.
214 : */
215 498420 : class VariableGroup : public Variable
216 : {
217 : public:
218 : /**
219 : * Constructor. Omits the subdomain mapping, hence this
220 : * constructor creates a variable which is active on
221 : * all subdomains.
222 : */
223 249397 : VariableGroup (System * sys,
224 : std::vector<std::string> var_names,
225 : const unsigned int var_number,
226 : const unsigned int first_scalar_num,
227 249397 : const FEType & var_type) :
228 : Variable (sys,
229 : "var_group",
230 : var_number,
231 : first_scalar_num,
232 : var_type),
233 249397 : _names(std::move(var_names))
234 249397 : {}
235 :
236 :
237 : /**
238 : * Constructor. Takes a set which contains the subdomain
239 : * indices for which this variable is active.
240 : */
241 3396 : VariableGroup (System * sys,
242 : std::vector<std::string> var_names,
243 : const unsigned int var_number,
244 : const unsigned int first_scalar_num,
245 : const FEType & var_type,
246 3396 : const std::set<subdomain_id_type> & var_active_subdomains) :
247 :
248 : Variable (sys,
249 : "var_group",
250 : var_number,
251 : first_scalar_num,
252 : var_type,
253 : var_active_subdomains),
254 6696 : _names(std::move(var_names))
255 3396 : {}
256 :
257 : /**
258 : * Standard constructors.
259 : */
260 : VariableGroup (const VariableGroup &) = default;
261 : VariableGroup & operator= (const VariableGroup &) = default;
262 267573 : VariableGroup (VariableGroup &&) = default;
263 : VariableGroup & operator= (VariableGroup &&) = default;
264 :
265 : /**
266 : * \returns true iff the \p other VariableGroup has exactly the same
267 : * Variable members as this one.
268 : */
269 : bool operator== ( const VariableGroup & other) const
270 : {
271 : return (this->Variable::operator==(other)) &&
272 : (_names == other._names);
273 : }
274 :
275 : /**
276 : * \returns The number of variables in this \p VariableGroup
277 : */
278 25814559 : unsigned int n_variables () const
279 38340540 : { return cast_int<unsigned int>(_names.size()); }
280 :
281 : /**
282 : * \returns A \p Variable object constructed for an individual member
283 : * of our group.
284 : */
285 7374314 : Variable variable (unsigned int v) const
286 : {
287 207776 : libmesh_assert_less (v, this->n_variables());
288 : return Variable (this->system(),
289 415552 : this->name(v),
290 : this->number(v),
291 : this->first_scalar_number(v),
292 : this->type(),
293 14540852 : this->active_subdomains());
294 : }
295 :
296 : /**
297 : * Support vg(v).
298 : *
299 : * \returns A \p Variable for v.
300 : */
301 207776 : Variable operator() (unsigned int v) const
302 7374314 : { return this->variable(v); }
303 :
304 : /**
305 : * \returns The user-specified name of the variable.
306 : */
307 208740 : const std::string & name(unsigned int v) const
308 : {
309 208740 : libmesh_assert_less (v, this->n_variables());
310 7408737 : return _names[v];
311 : }
312 :
313 : /**
314 : * \returns The rank of this variable in the system.
315 : */
316 14590739 : unsigned int number(unsigned int v) const
317 : {
318 14590739 : libmesh_assert_less (v, this->n_variables());
319 185770169 : return _number + v;
320 : }
321 :
322 : // Don't let number(uint) hide number()
323 : using Variable::number;
324 :
325 : /**
326 : * \returns The index of the first scalar component of this variable in the
327 : * system.
328 : */
329 1374 : unsigned int first_scalar_number(unsigned int v) const
330 : {
331 1374 : libmesh_assert_less (v, this->n_variables());
332 7167912 : return _first_scalar_number+v;
333 : }
334 :
335 : /**
336 : * Appends a variable to the group. Really only can be used by \p System in
337 : * a very limited window of opportunity - after the user specifies variables
338 : * but before the system is initialized.
339 : */
340 586 : void append (std::string var_name)
341 21024 : { _names.push_back (std::move(var_name)); }
342 :
343 : protected:
344 : std::vector<std::string> _names;
345 : };
346 :
347 : } // namespace libMesh
348 :
349 : #endif // LIBMESH_VARIABLE_H
|