libMesh
wrapped_function.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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 
32 // C++ includes
33 #include <cstddef>
34 #include <memory>
35 
36 namespace libMesh
37 {
38 
51 template <typename Output=Number>
52 class WrappedFunction : public FunctionBase<Output>
53 {
54 public:
55 
59  WrappedFunction (const System & sys,
60  Output fptr(const Point & p,
61  const Parameters & parameters,
62  const std::string & sys_name,
63  const std::string & unknown_name) = nullptr,
64  const Parameters * parameters = nullptr,
65  unsigned int varnum=0)
66  : _sys(sys),
67  _fptr(fptr),
68  _parameters(parameters),
69  _varnum(varnum)
70  {
71  this->_initialized = true;
72  if (!parameters)
74  }
75 
79  WrappedFunction (WrappedFunction &&) = default;
80  WrappedFunction (const WrappedFunction &) = default;
81  virtual ~WrappedFunction () = default;
82 
86  WrappedFunction & operator= (const WrappedFunction &) = delete;
88 
89  virtual std::unique_ptr<FunctionBase<Output>> clone () const override;
90 
91  virtual Output operator() (const Point & p,
92  const Real time = 0.) override;
93 
94  virtual void operator() (const Point & p,
95  const Real time,
96  DenseVector<Output> & output) override;
97 
98  virtual Output component (unsigned int i,
99  const Point & p,
100  Real time=0.) override;
101 
102 protected:
103 
104  const System & _sys;
105 
106  Output (*_fptr)(const Point & p,
107  const Parameters & parameters,
108  const std::string & sys_name,
109  const std::string & unknown_name);
110 
112 
113  unsigned int _varnum;
114 };
115 
116 
117 // ------------------------------------------------------------
118 // WrappedFunction inline methods
119 
120 
121 template <typename Output>
122 inline
124  const Real /*time*/)
125 {
126  libmesh_assert(_fptr);
127  libmesh_assert(_parameters);
128  return _fptr(p,
129  *_parameters,
130  _sys.name(),
131  _sys.variable_name(_varnum));
132 }
133 
134 
135 template <typename Output>
136 inline
137 std::unique_ptr<FunctionBase<Output>>
139 {
140  return std::make_unique<WrappedFunction<Output>>
141  (_sys, _fptr, _parameters, _varnum);
142 }
143 
144 
145 template <typename Output>
146 inline
148  const Real /*time*/,
149  DenseVector<Output> & output)
150 {
151  libmesh_assert(_fptr);
152  libmesh_assert(_parameters);
153 
154  // We fill each entry of output with a single scalar component of
155  // the data in our System
156  libmesh_assert_equal_to (output.size(), _sys.n_components());
157 
158  // Loop over variables, then over each component in
159  // vector-valued variables, evaluating each.
160  const unsigned int n_vars = _sys.n_vars();
161  for (unsigned int v = 0; v != n_vars; ++v)
162  {
163  const unsigned int n_components =
164  _sys.variable(v).n_components();
165  if (n_components == 1)
166  output(_sys.variable_scalar_number(v,0)) =
167  _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v));
168  else
169  {
170  // Right now our only non-scalar variable type is the
171  // SCALAR variables. The irony is priceless.
172  libmesh_assert_equal_to (_sys.variable(v).type().family, SCALAR);
173 
174  // We pass the point (j,0,0) to an old-style fptr function
175  // pointer to distinguish the different scalars within the
176  // SCALAR variable.
177  for (unsigned int j=0; j != n_components; ++j)
178  output(_sys.variable_scalar_number(v,j)) =
179  _fptr(Point(j,0,0), *_parameters,
180  _sys.name(), _sys.variable_name(v));
181  }
182  }
183 }
184 
185 
186 template <typename Output>
187 inline
188 Output WrappedFunction<Output>::component (unsigned int i,
189  const Point & p,
190  Real /*time*/)
191 {
192  libmesh_assert(_fptr);
193  libmesh_assert(_parameters);
194 
195  // Loop over variables, then over each component in
196  // FEFamily SCALAR variables.
197  unsigned int vc = 0;
198  const unsigned int n_vars = _sys.n_vars();
199  for (unsigned int v = 0; v != n_vars; ++v)
200  {
201  const auto & var_fe_type = _sys.variable_type(v);
202  const unsigned int n_components = [&var_fe_type, v, this](){
203  if (var_fe_type.family == SCALAR)
204  return _sys.variable(v).n_components();
205  else
206  return FEInterface::n_vec_dim(_sys.get_mesh(), var_fe_type);
207  }();
208  if (i >= vc + n_components)
209  {
210  vc += n_components;
211  continue;
212  }
213 
214  if (n_components > 1 && var_fe_type.family != SCALAR)
215  libmesh_error_msg(
216  "WrappedFunction::component cannot currently evaluate vector finite element families");
217 
218  if (n_components == 1)
219  return _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v));
220  else
221  {
222  libmesh_assert_equal_to (_sys.variable(i).type().family, SCALAR);
223 
224  // We pass the point (j,0,0) to an old-style fptr function
225  // pointer to distinguish the different scalars within the
226  // SCALAR variable.
227  for (unsigned int j=0; j != n_components; ++j)
228  if (i == vc + j)
229  return _fptr(Point(j,0,0), *_parameters,
230  _sys.name(), _sys.variable_name(v));
231  }
232  }
233 
234  libmesh_error_msg("Component index " << i << " not found in system " << _sys.name());
235  return Output();
236 }
237 
238 
239 
240 } // namespace libMesh
241 
242 #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:67
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:730
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:80
unsigned int n_vars
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
virtual std::unique_ptr< FunctionBase< Output > > clone() const override
libmesh_assert(ctx)
static unsigned int n_vec_dim(const MeshBase &mesh, const FEType &fe_type)
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