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 :
19 :
20 : #ifndef LIBMESH_DIRICHLET_BOUNDARIES_H
21 : #define LIBMESH_DIRICHLET_BOUNDARIES_H
22 :
23 : #include "libmesh/libmesh_config.h"
24 :
25 : #ifdef LIBMESH_ENABLE_DIRICHLET
26 :
27 : // Local Includes
28 : #include "libmesh/id_types.h"
29 : #include "libmesh/vector_value.h"
30 :
31 : // C++ Includes
32 : #include <cstddef>
33 : #include <set>
34 : #include <vector>
35 : #include <memory>
36 :
37 : namespace libMesh
38 : {
39 :
40 : // Forward declarations
41 : class System;
42 :
43 : template <typename Output> class FEMFunctionBase;
44 : template <typename Output> class FunctionBase;
45 :
46 : /**
47 : * Dirichlet functions may be indexed either by "system variable
48 : * order" or "local variable order", depending on how the
49 : * DirichletBoundary object is constructed. For example, suppose a
50 : * system has variables {a, b, c, d}, and a DirichletBoundary is set
51 : * for variables {b, d} (i.e. variables_in is {1, 3}). If the
52 : * boundary is constructed to use "system variable order", input
53 : * function(s) will be queried for components 1 and 3; this is useful
54 : * for reusing input functions as both exact solutions and Dirichlet
55 : * boundaries in benchmark problems. If the boundary is constructed
56 : * to use "local variable order", input function(s) will be queried
57 : * for components 0 and 1; this is useful for flexibly constructing
58 : * Dirichlet boundaries in multiphysics codes or from user input
59 : * files.
60 : */
61 : enum VariableIndexing { SYSTEM_VARIABLE_ORDER = 0,
62 : LOCAL_VARIABLE_ORDER };
63 :
64 : /**
65 : * This class allows one to associate Dirichlet boundary values with
66 : * a given set of mesh boundary ids and system variable ids.
67 : *
68 : * Dirichlet values must be supplied as the input function "f"; when
69 : * using some specialized elements, gradient values must be supplied
70 : * via the input function "g".
71 : *
72 : * Dirichlet functions may be subclasses of FunctionBase or
73 : * FEMFunctionBase; in the latter case the user must also supply a
74 : * reference to the System on which the FEMFunctionBase will be
75 : * evaluated.
76 : *
77 : * Dirichlet functions are allowed to return NaN; if this is
78 : * encountered, then the degree of freedom values in a patch around
79 : * the location of the returned NaN will be left unconstrained. E.g.
80 : * a NaN on a boundary edge in 3D would leave that edge and the two
81 : * adjoining face interiors unconstrained, but would still permit the
82 : * other edge and node DoFs around those faces to be constrained.
83 : *
84 : * \author Roy Stogner
85 : * \date 2012
86 : * \brief Class for specifying Dirichlet boundary conditions as constraints.
87 : */
88 1496 : class DirichletBoundary
89 : {
90 : public:
91 :
92 : /**
93 : * Constructor for a system-variable-order boundary using
94 : * pointers-to-functors.
95 : */
96 : DirichletBoundary(std::set<boundary_id_type> b_in,
97 : std::vector<unsigned int> variables_in,
98 : const FunctionBase<Number> * f_in,
99 : const FunctionBase<Gradient> * g_in = nullptr);
100 :
101 : /**
102 : * Constructor for a boundary from reference-to-functor.
103 : *
104 : * Defaults to system variable indexing for backwards compatibility,
105 : * but most users will prefer local indexing.
106 : */
107 : DirichletBoundary(std::set<boundary_id_type> b_in,
108 : std::vector<unsigned int> variables_in,
109 : const FunctionBase<Number> & f_in,
110 : VariableIndexing type = SYSTEM_VARIABLE_ORDER);
111 :
112 : /**
113 : * Constructor for a system-variable-order boundary from
114 : * references-to-functors.
115 : *
116 : * Defaults to system variable indexing for backwards compatibility,
117 : * but most users will prefer local indexing.
118 : */
119 : DirichletBoundary(std::set<boundary_id_type> b_in,
120 : std::vector<unsigned int> variables_in,
121 : const FunctionBase<Number> & f_in,
122 : const FunctionBase<Gradient> & g_in,
123 : VariableIndexing type = SYSTEM_VARIABLE_ORDER);
124 :
125 : /**
126 : * Constructor for a system-variable-order boundary from
127 : * pointers-to-fem-functors.
128 : */
129 : DirichletBoundary(std::set<boundary_id_type> b_in,
130 : std::vector<unsigned int> variables_in,
131 : const System & f_sys_in,
132 : const FEMFunctionBase<Number> * f_in,
133 : const FEMFunctionBase<Gradient> * g_in = nullptr);
134 :
135 : /**
136 : * Constructor for a system-variable-order boundary from
137 : * reference-to-fem-functor.
138 : *
139 : * Defaults to system variable indexing for backwards compatibility,
140 : * but most users will prefer local indexing.
141 : */
142 : DirichletBoundary(std::set<boundary_id_type> b_in,
143 : std::vector<unsigned int> variables_in,
144 : const System & f_sys_in,
145 : const FEMFunctionBase<Number> & f_in,
146 : VariableIndexing type = SYSTEM_VARIABLE_ORDER);
147 :
148 : /**
149 : * Constructor for a system-variable-order boundary from
150 : * references-to-fem-functors.
151 : *
152 : * Defaults to system variable indexing for backwards compatibility,
153 : * but most users will prefer local indexing.
154 : */
155 : DirichletBoundary(std::set<boundary_id_type> b_in,
156 : std::vector<unsigned int> variables_in,
157 : const System & f_sys_in,
158 : const FEMFunctionBase<Number> & f_in,
159 : const FEMFunctionBase<Gradient> & g_in,
160 : VariableIndexing type = SYSTEM_VARIABLE_ORDER);
161 :
162 : /**
163 : * Copy assignment/constructor. Deep copies (clones) functors;
164 : * shallow copies any System reference
165 : */
166 : DirichletBoundary (const DirichletBoundary & dirichlet_in);
167 : DirichletBoundary & operator= (const DirichletBoundary &);
168 :
169 : /**
170 : * This class is default move-assignable and move-constructible.
171 : */
172 284 : DirichletBoundary (DirichletBoundary &&) = default;
173 0 : DirichletBoundary & operator= (DirichletBoundary &&) = default;
174 :
175 : /**
176 : * Standard destructor
177 : */
178 : ~DirichletBoundary ();
179 :
180 : std::set<boundary_id_type> b;
181 : std::vector<unsigned int> variables;
182 :
183 : std::unique_ptr<FunctionBase<Number>> f;
184 : std::unique_ptr<FunctionBase<Gradient>> g;
185 :
186 : std::unique_ptr<FEMFunctionBase<Number>> f_fem;
187 : std::unique_ptr<FEMFunctionBase<Gradient>> g_fem;
188 :
189 : const System * f_system;
190 :
191 : /**
192 : * Defaults to zero, but can be set to a custom small negative value
193 : * to try and avoid spurious zero (or negative) Jacobian values when
194 : * applying Dirichlet constraints. This can be useful in various
195 : * different situations, for example:
196 : * 1.) When specifying DirichletBCs on poorly-shaped elements.
197 : * 2.) When degenerate Hexahedra are used in place of Prisms for convenience.
198 : * 3.) On elements (e.g. Pyramids) which always have a zero Jacobian at the "apex" node.
199 : * In theory there's nothing preventing someone from specifying
200 : * DirichletBCs in such cases; setting this tolerance to a small
201 : * negative value makes this possible in practice.
202 : */
203 : Real jacobian_tolerance;
204 : };
205 :
206 :
207 : /**
208 : * We're using a class instead of a typedef to allow forward
209 : * declarations and future flexibility.
210 : *
211 : * \note \p std::map has no virtual destructor, so downcasting here
212 : * would be dangerous.
213 : */
214 : class DirichletBoundaries : public std::vector<std::unique_ptr<DirichletBoundary>>
215 : {
216 : public:
217 6808 : DirichletBoundaries() = default;
218 231738 : ~DirichletBoundaries() = default;
219 : };
220 :
221 : } // namespace libMesh
222 :
223 : #endif // LIBMESH_ENABLE_DIRICHLET
224 :
225 : #endif // LIBMESH_DIRICHLET_BOUNDARIES_H
|