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_FUNCTION_BASE_H
21 : #define LIBMESH_FUNCTION_BASE_H
22 :
23 : // Local Includes
24 : #include "libmesh/libmesh_common.h"
25 : #include "libmesh/dense_vector.h" // required to instantiate a DenseVector<> below
26 :
27 : // C++ includes
28 : #include <cstddef>
29 : #include <memory>
30 :
31 : namespace libMesh
32 : {
33 :
34 : // Forward Declarations
35 : class Point;
36 :
37 : /**
38 : * \brief Base class for functors that can be evaluated at a point and
39 : * (optionally) time.
40 : *
41 : * Instances of FunctionBase represent functions (in the mathematical sense)
42 : * of time and space, \f$ f(\mathbf{x},t) = \mbox{\texttt{v}} \f$, where \p v
43 : * may be either a \p Number or a \p DenseVector<Number>. Children of this
44 : * base class implement different styles of data retrieval for these
45 : * functions. Use the constructors of the derived classes for creating new
46 : * objects. The required input of each derived class thwarts the effective use
47 : * of the commonly used \p build() member. But afterward the virtual members
48 : * allow the convenient and libMesh-common usage through a \p FunctionBase *.
49 : *
50 : * \note For functor objects for vector-valued variables, it is
51 : * assumed each component is indexed contiguously; e.g. if u_var is a
52 : * 3d vector-valued variable at index 3, following some scalar-valued variables
53 : * at indices 0, 1, and 2, then libMesh expects the x-component of u_var to be
54 : * at index 3, the y-component at index 4, and the z-component at index 5.
55 : *
56 : * \note For 2-D elements in 3 spatial dimensions, libMesh is expecting
57 : * 2 components (i.e. mesh_dimension() number of components).
58 : *
59 : * \author Daniel Dreyer
60 : * \date 2003
61 : */
62 : template <typename Output=Number>
63 : class FunctionBase
64 : {
65 : protected:
66 :
67 : /**
68 : * Constructor. Optionally takes a master.
69 : */
70 : explicit
71 : FunctionBase (const FunctionBase * master = nullptr);
72 :
73 : public:
74 :
75 : /**
76 : * The 5 special functions can be defaulted for this class.
77 : */
78 : FunctionBase (FunctionBase &&) = default;
79 0 : FunctionBase (const FunctionBase &) = default;
80 : FunctionBase & operator= (const FunctionBase &) = default;
81 : FunctionBase & operator= (FunctionBase &&) = default;
82 17604 : virtual ~FunctionBase () = default;
83 :
84 : /**
85 : * The actual initialization process.
86 : */
87 55499 : virtual void init () {}
88 :
89 : /**
90 : * Clears the function.
91 : */
92 0 : virtual void clear () {}
93 :
94 : /**
95 : * \returns A new copy of the function.
96 : *
97 : * The new copy should be as "deep" as necessary to allow
98 : * independent destruction and simultaneous evaluations of the
99 : * copies in different threads.
100 : */
101 : virtual std::unique_ptr<FunctionBase<Output>> clone () const = 0;
102 :
103 : /**
104 : * \returns The scalar function value at coordinate \p p and time \p
105 : * time, which defaults to zero.
106 : *
107 : * Pure virtual, so you have to override it.
108 : */
109 : virtual Output operator() (const Point & p,
110 : const Real time = 0.) = 0;
111 :
112 : /**
113 : * Evaluation function for time-independent vector-valued functions.
114 : * Sets output values in the passed-in \p output DenseVector.
115 : */
116 : void operator() (const Point & p,
117 : DenseVector<Output> & output);
118 :
119 : /**
120 : * Evaluation function for time-dependent vector-valued functions.
121 : * Sets output values in the passed-in \p output DenseVector.
122 : *
123 : * Pure virtual, so you have to override it.
124 : */
125 : virtual void operator() (const Point & p,
126 : const Real time,
127 : DenseVector<Output> & output) = 0;
128 :
129 : /**
130 : * \returns The vector component \p i at coordinate \p p and time \p
131 : * time.
132 : *
133 : * \note Subclasses aren't required to override this, since the default
134 : * implementation is based on the full vector evaluation, which is
135 : * often correct.
136 : *
137 : * \note Subclasses are recommended to override this, since the default
138 : * implementation is based on a vector evaluation, which is usually
139 : * unnecessarily inefficient.
140 : *
141 : * \note The default implementation calls operator() with a DenseVector of
142 : * size \p i+1 which will result in unexpected behaviour if operator()
143 : * makes any access beyond that limit.
144 : */
145 : virtual Output component(unsigned int i,
146 : const Point & p,
147 : Real time=0.);
148 :
149 :
150 : /**
151 : * \returns \p true when this object is properly initialized
152 : * and ready for use, \p false otherwise.
153 : */
154 : bool initialized () const;
155 :
156 : /**
157 : * Function to set whether this is a time-dependent function or not.
158 : * This is intended to be only used by subclasses who cannot natively
159 : * determine time-dependence. In such a case, this function should
160 : * be used immediately following construction.
161 : */
162 : void set_is_time_dependent( bool is_time_dependent);
163 :
164 : /**
165 : * \returns \p true when the function this object represents
166 : * is actually time-dependent, \p false otherwise.
167 : */
168 : bool is_time_dependent() const;
169 :
170 : protected:
171 :
172 : /**
173 : * Const pointer to our master, initialized to \p nullptr.
174 : * There may be cases where multiple functions are required,
175 : * but to save memory, one master handles some centralized
176 : * data.
177 : */
178 : const FunctionBase * _master;
179 :
180 : /**
181 : * When \p init() was called so that everything is ready
182 : * for calls to \p operator() (...), then this \p bool is true.
183 : */
184 : bool _initialized;
185 :
186 : /**
187 : * Cache whether or not this function is actually time-dependent.
188 : */
189 : bool _is_time_dependent;
190 :
191 : };
192 :
193 :
194 : // ------------------------------------------------------------
195 : // FunctionBase inline methods
196 :
197 : template<typename Output>
198 : inline
199 823753 : FunctionBase<Output>::FunctionBase (const FunctionBase * master) :
200 793481 : _master (master),
201 10093 : _initialized (false),
202 821175 : _is_time_dependent (true) // Assume we are time-dependent until the user says otherwise
203 : {
204 17664 : }
205 :
206 :
207 :
208 : template <typename Output>
209 : inline
210 281880 : bool FunctionBase<Output>::initialized() const
211 : {
212 282426 : return (this->_initialized);
213 : }
214 :
215 : template <typename Output>
216 : inline
217 : void FunctionBase<Output>::set_is_time_dependent( bool is_time_dependent )
218 : {
219 : this->_is_time_dependent = is_time_dependent;
220 : }
221 :
222 : template <typename Output>
223 : inline
224 260 : bool FunctionBase<Output>::is_time_dependent() const
225 : {
226 8932 : return (this->_is_time_dependent);
227 : }
228 :
229 :
230 : template <typename Output>
231 : inline
232 325538 : Output FunctionBase<Output>::component (unsigned int i,
233 : const Point & p,
234 : Real time)
235 : {
236 325538 : DenseVector<Output> outvec(i+1);
237 325538 : (*this)(p, time, outvec);
238 357103 : return outvec(i);
239 : }
240 :
241 :
242 :
243 : template <typename Output>
244 : inline
245 174354 : void FunctionBase<Output>::operator() (const Point & p,
246 : DenseVector<Output> & output)
247 : {
248 : // Call the time-dependent function with t=0.
249 4027188 : this->operator()(p, 0., output);
250 3852834 : }
251 :
252 : } // namespace libMesh
253 :
254 : #endif // LIBMESH_FUNCTION_BASE_H
|