libMesh
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 
37 namespace libMesh
38 {
39 
52 template <typename Output=Number>
53 class WrappedFunction : public FunctionBase<Output>
54 {
55 public:
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 
80  WrappedFunction (WrappedFunction &&) = default;
81  WrappedFunction (const WrappedFunction &) = default;
82  virtual ~WrappedFunction () = default;
83 
87  WrappedFunction & operator= (const WrappedFunction &) = delete;
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 
103 protected:
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 
122 template <typename Output>
123 inline
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 
136 template <typename Output>
137 inline
138 std::unique_ptr<FunctionBase<Output>>
140 {
141  return std::make_unique<WrappedFunction<Output>>
142  (_sys, _fptr, _parameters, _varnum);
143 }
144 
145 
146 template <typename Output>
147 inline
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 
187 template <typename Output>
188 inline
189 Output WrappedFunction<Output>::component (unsigned int i,
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
Wrap a libMesh-style function pointer into a FunctionBase object.
virtual Output component(unsigned int i, const Point &p, Real time=0.) override
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:74
virtual Output operator()(const Point &p, const Real time=0.) override
Output(* _fptr)(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name)
const EquationSystems & get_equation_systems() const
Definition: system.h:767
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
The libMesh namespace provides an interface to certain functionality in the library.
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition: projection.C:81
unsigned int n_vars
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:98
virtual std::unique_ptr< FunctionBase< Output > > clone() const override
libmesh_assert(ctx)
WrappedFunction & operator=(const WrappedFunction &)=delete
This class contains a const reference so it can&#39;t be assigned.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual ~WrappedFunction()=default
const Parameters * _parameters
Parameters parameters
Data structure holding arbitrary parameters.
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.
virtual unsigned int size() const override final
Definition: dense_vector.h:104
Base class for functors that can be evaluated at a point and (optionally) time.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39