libMesh
Loading...
Searching...
No Matches
wrapped_function.h
Go to the documentation of this file.
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
19
20#ifndef LIBMESH_WRAPPED_FUNCTION_H
21#define LIBMESH_WRAPPED_FUNCTION_H
22
23// Local Includes
24#include "libmesh/dense_vector.h"
25#include "libmesh/equation_systems.h"
26#include "libmesh/function_base.h"
27#include "libmesh/libmesh_common.h"
28#include "libmesh/point.h"
29#include "libmesh/system.h"
30#include "libmesh/fe_interface.h"
31#include "libmesh/variable.h"
32
33// C++ includes
34#include <cstddef>
35#include <memory>
36
37namespace libMesh
38{
39
52template <typename Output=Number>
53class WrappedFunction : public FunctionBase<Output>
54{
55public:
56
60 WrappedFunction (const System & sys,
61 Output fptr(const Point & p,
62 const Parameters & parameters,
63 const std::string & sys_name,
64 const std::string & unknown_name) = nullptr,
65 const Parameters * parameters = nullptr,
66 unsigned int varnum=0)
67 : _sys(sys),
68 _fptr(fptr),
69 _parameters(parameters),
70 _varnum(varnum)
71 {
72 this->_initialized = true;
73 if (!parameters)
75 }
76
81 WrappedFunction (const WrappedFunction &) = default;
82 virtual ~WrappedFunction () = default;
83
89
90 virtual std::unique_ptr<FunctionBase<Output>> clone () const override;
91
92 virtual Output operator() (const Point & p,
93 const Real time = 0.) override;
94
95 virtual void operator() (const Point & p,
96 const Real time,
97 DenseVector<Output> & output) override;
98
99 virtual Output component (unsigned int i,
100 const Point & p,
101 Real time=0.) override;
102
103protected:
104
105 const System & _sys;
106
107 Output (*_fptr)(const Point & p,
108 const Parameters & parameters,
109 const std::string & sys_name,
110 const std::string & unknown_name);
111
113
114 unsigned int _varnum;
115};
116
117
118// ------------------------------------------------------------
119// WrappedFunction inline methods
120
121
122template <typename Output>
123inline
125 const Real /*time*/)
126{
127 libmesh_assert(_fptr);
128 libmesh_assert(_parameters);
129 return _fptr(p,
130 *_parameters,
131 _sys.name(),
132 _sys.variable_name(_varnum));
133}
134
135
136template <typename Output>
137inline
138std::unique_ptr<FunctionBase<Output>>
140{
141 return std::make_unique<WrappedFunction<Output>>
142 (_sys, _fptr, _parameters, _varnum);
143}
144
145
146template <typename Output>
147inline
149 const Real /*time*/,
150 DenseVector<Output> & output)
151{
152 libmesh_assert(_fptr);
153 libmesh_assert(_parameters);
154
155 // We fill each entry of output with a single scalar component of
156 // the data in our System
157 libmesh_assert_equal_to (output.size(), _sys.n_components());
158
159 // Loop over variables, then over each component in
160 // vector-valued variables, evaluating each.
161 const unsigned int n_vars = _sys.n_vars();
162 for (unsigned int v = 0; v != n_vars; ++v)
163 {
164 const auto n_components =
165 _sys.variable(v).n_components(_sys.get_mesh());
166 if (n_components == 1)
167 output(_sys.variable_scalar_number(v,0)) =
168 _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v));
169 else
170 {
171 // Right now our only non-scalar variable type is the
172 // SCALAR variables. The irony is priceless.
173 libmesh_assert_equal_to (_sys.variable(v).type().family, SCALAR);
174
175 // We pass the point (j,0,0) to an old-style fptr function
176 // pointer to distinguish the different scalars within the
177 // SCALAR variable.
178 for (unsigned int j=0; j != n_components; ++j)
179 output(_sys.variable_scalar_number(v,j)) =
180 _fptr(Point(j,0,0), *_parameters,
181 _sys.name(), _sys.variable_name(v));
182 }
183 }
184}
185
186
187template <typename Output>
188inline
190 const Point & p,
191 Real /*time*/)
192{
193 libmesh_assert(_fptr);
194 libmesh_assert(_parameters);
195
196 // Loop over variables, then over each component in
197 // FEFamily SCALAR variables.
198 unsigned int vc = 0;
199 const unsigned int n_vars = _sys.n_vars();
200 for (unsigned int v = 0; v != n_vars; ++v)
201 {
202 const auto & var_fe_type = _sys.variable_type(v);
203 const auto n_components = _sys.variable(v).n_components(_sys.get_mesh());
204 if (i >= vc + n_components)
205 {
206 vc += n_components;
207 continue;
208 }
209
210 if (n_components > 1 && var_fe_type.family != SCALAR)
211 libmesh_error_msg(
212 "WrappedFunction::component cannot currently evaluate vector finite element families");
213
214 if (n_components == 1)
215 return _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v));
216 else
217 {
218 libmesh_assert_equal_to (_sys.variable(i).type().family, SCALAR);
219
220 // We pass the point (j,0,0) to an old-style fptr function
221 // pointer to distinguish the different scalars within the
222 // SCALAR variable.
223 for (unsigned int j=0; j != n_components; ++j)
224 if (i == vc + j)
225 return _fptr(Point(j,0,0), *_parameters,
226 _sys.name(), _sys.variable_name(v));
227 }
228 }
229
230 libmesh_error_msg("Component index " << i << " not found in system " << _sys.name());
231 return Output();
232}
233
234
235
236} // namespace libMesh
237
238#endif // LIBMESH_WRAPPED_FUNCTION_H
unsigned int n_vars
Defines a dense vector for use in Finite Element-type computations.
virtual unsigned int size() const override final
Parameters parameters
Data structure holding arbitrary parameters.
Base class for functors that can be evaluated at a point and (optionally) time.
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition parameters.h:75
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
const EquationSystems & get_equation_systems() const
Definition system.h:767
Wrap a libMesh-style function pointer into a FunctionBase object.
WrappedFunction & operator=(const WrappedFunction &)=delete
This class contains a const reference so it can't be assigned.
const Parameters * _parameters
virtual Output operator()(const Point &p, const Real time=0.) override
virtual Output component(unsigned int i, const Point &p, Real time=0.) override
virtual ~WrappedFunction()=default
WrappedFunction(const System &sys, Output fptr(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name)=nullptr, const Parameters *parameters=nullptr, unsigned int varnum=0)
Constructor to wrap scalar-valued function pointers.
WrappedFunction(WrappedFunction &&)=default
The move/copy ctor and destructor are defaulted for this class.
Output(* _fptr)(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name)
WrappedFunction(const WrappedFunction &)=default
virtual std::unique_ptr< FunctionBase< Output > > clone() const override
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition projection.C:81