Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 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 6996 : Variable (System * sys,
60 : std::string var_name,
61 : const unsigned int var_number,
62 : const unsigned int first_scalar_num,
63 245196 : const FEType & var_type) :
64 231204 : _sys(sys),
65 238200 : _name(std::move(var_name)),
66 : _active_subdomains(),
67 231204 : _number(var_number),
68 231204 : _first_scalar_number(first_scalar_num),
69 245230 : _type(var_type)
70 6996 : {}
71 :
72 : /**
73 : * Constructor. Takes a set which contains the subdomain
74 : * indices for which this variable is active.
75 : */
76 14734238 : 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 14734238 : const std::set<subdomain_id_type> & var_active_subdomains) :
82 13903806 : _sys(sys),
83 14319022 : _name(std::move(var_name)),
84 : _active_subdomains(var_active_subdomains),
85 13903806 : _number(var_number),
86 13903806 : _first_scalar_number(first_scalar_num),
87 14734238 : _type(var_type)
88 14734238 : {}
89 :
90 : /**
91 : * Standard constructors.
92 : */
93 487374 : Variable (const Variable &) = default;
94 : Variable & operator= (const Variable &) = default;
95 33943188 : 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 16117 : bool operator== ( const Variable & other) const
103 : {
104 31310 : return (_sys == other._sys) &&
105 16117 : (_name == other._name) &&
106 13915 : (_active_subdomains == other._active_subdomains) &&
107 30044 : (_first_scalar_number == other._first_scalar_number) &&
108 15984 : (_type == other._type);
109 : }
110 :
111 : /**
112 : * \returns A pointer to the System this Variable is part of.
113 : */
114 416989 : System * system() const
115 : {
116 14352889 : return _sys;
117 : }
118 :
119 : /**
120 : * \returns The user-specified name of the variable.
121 : */
122 1074269 : const std::string & name() const
123 14853837 : { return _name; }
124 :
125 : /**
126 : * \returns The rank of this variable in the system.
127 : */
128 10961637 : unsigned int number() const
129 118319643 : { 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 424310 : unsigned int first_scalar_number() const
139 3935782 : { return _first_scalar_number; }
140 :
141 : /**
142 : * \returns The \p FEType for this variable.
143 : */
144 52157023 : const FEType & type() const
145 315977467 : { 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 344741678 : bool active_on_subdomain (subdomain_id_type sid) const
168 351997709 : { 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 1134 : bool implicitly_active () const
176 1134 : { return _active_subdomains.empty(); }
177 :
178 : /**
179 : * \returns The set of subdomain ids this variable lives on.
180 : */
181 423644 : const std::set<subdomain_id_type> & active_subdomains() const
182 14710709 : { 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 :
193 :
194 :
195 : /**
196 : * This class defines a logically grouped set of variables in
197 : * the system. \p VariableGroup is appropriate for representing
198 : * several unknowns in the problem that are all approximated
199 : * with the same finite element approximation family and
200 : * (optionally) a list of subdomains to which the
201 : * variables are restricted.
202 : */
203 981988 : class VariableGroup : public Variable
204 : {
205 : public:
206 : /**
207 : * Constructor. Omits the subdomain mapping, hence this
208 : * constructor creates a variable which is active on
209 : * all subdomains.
210 : */
211 244006 : VariableGroup (System * sys,
212 : std::vector<std::string> var_names,
213 : const unsigned int var_number,
214 : const unsigned int first_scalar_num,
215 244006 : const FEType & var_type) :
216 : Variable (sys,
217 : "var_group",
218 : var_number,
219 : first_scalar_num,
220 : var_type),
221 244006 : _names(std::move(var_names))
222 244006 : {}
223 :
224 :
225 : /**
226 : * Constructor. Takes a set which contains the subdomain
227 : * indices for which this variable is active.
228 : */
229 3396 : VariableGroup (System * sys,
230 : std::vector<std::string> var_names,
231 : const unsigned int var_number,
232 : const unsigned int first_scalar_num,
233 : const FEType & var_type,
234 3396 : const std::set<subdomain_id_type> & var_active_subdomains) :
235 :
236 : Variable (sys,
237 : "var_group",
238 : var_number,
239 : first_scalar_num,
240 : var_type,
241 : var_active_subdomains),
242 6696 : _names(std::move(var_names))
243 3396 : {}
244 :
245 : /**
246 : * Standard constructors.
247 : */
248 247214 : VariableGroup (const VariableGroup &) = default;
249 : VariableGroup & operator= (const VariableGroup &) = default;
250 523466 : VariableGroup (VariableGroup &&) = default;
251 : VariableGroup & operator= (VariableGroup &&) = default;
252 :
253 : /**
254 : * \returns true iff the \p other VariableGroup has exactly the same
255 : * Variable members as this one.
256 : */
257 16117 : bool operator== ( const VariableGroup & other) const
258 : {
259 16129 : return (this->Variable::operator==(other)) &&
260 480 : (_names == other._names);
261 : }
262 :
263 : /**
264 : * \returns The number of variables in this \p VariableGroup
265 : */
266 28001513 : unsigned int n_variables () const
267 40201287 : { return cast_int<unsigned int>(_names.size()); }
268 :
269 : /**
270 : * \returns A \p Variable object constructed for an individual member
271 : * of our group.
272 : */
273 14730842 : Variable variable (unsigned int v) const
274 : {
275 415120 : libmesh_assert_less (v, this->n_variables());
276 : return Variable (this->system(),
277 830240 : this->name(v),
278 : this->number(v),
279 : this->first_scalar_number(v),
280 : this->type(),
281 29046564 : this->active_subdomains());
282 : }
283 :
284 : /**
285 : * Support vg(v).
286 : *
287 : * \returns A \p Variable for v.
288 : */
289 415120 : Variable operator() (unsigned int v) const
290 14730842 : { return this->variable(v); }
291 :
292 : /**
293 : * \returns The user-specified name of the variable.
294 : */
295 416080 : const std::string & name(unsigned int v) const
296 : {
297 416080 : libmesh_assert_less (v, this->n_variables());
298 14453202 : return _names[v];
299 : }
300 :
301 : /**
302 : * \returns The rank of this variable in the system.
303 : */
304 14345985 : unsigned int number(unsigned int v) const
305 : {
306 14345985 : libmesh_assert_less (v, this->n_variables());
307 179333054 : return _number + v;
308 : }
309 :
310 : // Don't let number(uint) hide number()
311 : using Variable::number;
312 :
313 : /**
314 : * \returns The index of the first scalar component of this variable in the
315 : * system.
316 : */
317 415120 : unsigned int first_scalar_number(unsigned int v) const
318 : {
319 415120 : libmesh_assert_less (v, this->n_variables());
320 14730842 : return _first_scalar_number+v;
321 : }
322 :
323 : /**
324 : * Appends a variable to the group. Really only can be used by \p System in
325 : * a very limited window of opportunity - after the user specifies variables
326 : * but before the system is initialized.
327 : */
328 506 : void append (std::string var_name)
329 18184 : { _names.push_back (std::move(var_name)); }
330 :
331 : protected:
332 : std::vector<std::string> _names;
333 : };
334 :
335 : } // namespace libMesh
336 :
337 : #endif // LIBMESH_VARIABLE_H
|