libMesh
wrapped_function.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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/auto_ptr.h" // libmesh_make_unique
31 
32 // C++ includes
33 #include <cstddef>
34 
35 namespace libMesh
36 {
37 
50 template <typename Output=Number>
51 class WrappedFunction : public FunctionBase<Output>
52 {
53 public:
54 
58  WrappedFunction (const System & sys,
59  Output fptr(const Point & p,
60  const Parameters & parameters,
61  const std::string & sys_name,
62  const std::string & unknown_name) = nullptr,
63  const Parameters * parameters = nullptr,
64  unsigned int varnum=0)
65  : _sys(sys),
66  _fptr(fptr),
67  _parameters(parameters),
68  _varnum(varnum)
69  {
70  this->_initialized = true;
71  if (!parameters)
73  }
74 
78  WrappedFunction (WrappedFunction &&) = default;
79  WrappedFunction (const WrappedFunction &) = default;
80  virtual ~WrappedFunction () = default;
81 
85  WrappedFunction & operator= (const WrappedFunction &) = delete;
87 
88  virtual std::unique_ptr<FunctionBase<Output>> clone () const override;
89 
90  virtual Output operator() (const Point & p,
91  const Real time = 0.) override;
92 
93  virtual void operator() (const Point & p,
94  const Real time,
95  DenseVector<Output> & output) override;
96 
97  virtual Output component (unsigned int i,
98  const Point & p,
99  Real time=0.) override;
100 
101 protected:
102 
103  const System & _sys;
104 
105  Output (*_fptr)(const Point & p,
106  const Parameters & parameters,
107  const std::string & sys_name,
108  const std::string & unknown_name);
109 
111 
112  unsigned int _varnum;
113 };
114 
115 
116 // ------------------------------------------------------------
117 // WrappedFunction inline methods
118 
119 
120 template <typename Output>
121 inline
123  const Real /*time*/)
124 {
125  libmesh_assert(_fptr);
126  libmesh_assert(_parameters);
127  return _fptr(p,
128  *_parameters,
129  _sys.name(),
130  _sys.variable_name(_varnum));
131 }
132 
133 
134 template <typename Output>
135 inline
136 std::unique_ptr<FunctionBase<Output>>
138 {
139  return libmesh_make_unique<WrappedFunction<Output>>
140  (_sys, _fptr, _parameters, _varnum);
141 }
142 
143 
144 template <typename Output>
145 inline
147  const Real /*time*/,
148  DenseVector<Output> & output)
149 {
150  libmesh_assert(_fptr);
151  libmesh_assert(_parameters);
152 
153  // We fill each entry of output with a single scalar component of
154  // the data in our System
155  libmesh_assert_equal_to (output.size(), _sys.n_components());
156 
157  // Loop over variables, then over each component in
158  // vector-valued variables, evaluating each.
159  const unsigned int n_vars = _sys.n_vars();
160  for (unsigned int v = 0; v != n_vars; ++v)
161  {
162  const unsigned int n_components =
163  _sys.variable(v).n_components();
164  if (n_components == 1)
165  output(_sys.variable_scalar_number(v,0)) =
166  _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v));
167  else
168  {
169  // Right now our only non-scalar variable type is the
170  // SCALAR variables. The irony is priceless.
171  libmesh_assert_equal_to (_sys.variable(v).type().family, SCALAR);
172 
173  // We pass the point (j,0,0) to an old-style fptr function
174  // pointer to distinguish the different scalars within the
175  // SCALAR variable.
176  for (unsigned int j=0; j != n_components; ++j)
177  output(_sys.variable_scalar_number(v,j)) =
178  _fptr(Point(j,0,0), *_parameters,
179  _sys.name(), _sys.variable_name(v));
180  }
181  }
182 }
183 
184 
185 template <typename Output>
186 inline
187 Output WrappedFunction<Output>::component (unsigned int i,
188  const Point & p,
189  Real /*time*/)
190 {
191  libmesh_assert(_fptr);
192  libmesh_assert(_parameters);
193 
194  // Loop over variables, then over each component in
195  // vector-valued variables.
196  const unsigned int n_vars = _sys.n_vars();
197  for (unsigned int v = 0; v != n_vars; ++v)
198  {
199  const unsigned int n_components =
200  _sys.variable(v).n_components();
201  if (n_components == 1 &&
202  i == _sys.variable_scalar_number(v,0))
203  return _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v));
204  else if (i >= _sys.variable_scalar_number(v,0) &&
205  i <= _sys.variable_scalar_number(v,n_components-1))
206  {
207  // Right now our only non-scalar variable type is the
208  // SCALAR variables. The irony is priceless.
209  libmesh_assert_equal_to (_sys.variable(i).type().family, SCALAR);
210 
211  // We pass the point (j,0,0) to an old-style fptr function
212  // pointer to distinguish the different scalars within the
213  // SCALAR variable.
214  for (unsigned int j=0; j != n_components; ++j)
215  if (i == _sys.variable_scalar_number(v,j))
216  return _fptr(Point(j,0,0), *_parameters,
217  _sys.name(), _sys.variable_name(v));
218  }
219  }
220 
221  libmesh_error_msg("Component index " << i << " not found in system " << _sys.name());
222  return Output();
223 }
224 
225 
226 
227 } // namespace libMesh
228 
229 #endif // LIBMESH_WRAPPED_FUNCTION_H
libMesh::System
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:100
libMesh::FunctionBase
Base class for functors that can be evaluated at a point and (optionally) time.
Definition: dirichlet_boundaries.h:44
libMesh::System::get_equation_systems
const EquationSystems & get_equation_systems() const
Definition: system.h:720
n_vars
unsigned int n_vars
Definition: adaptivity_ex3.C:116
libMesh::WrappedFunction::operator=
WrappedFunction & operator=(const WrappedFunction &)=delete
This class contains a const reference so it can't be assigned.
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::WrappedFunction::_varnum
unsigned int _varnum
Definition: wrapped_function.h:112
libMesh::WrappedFunction::component
virtual Output component(unsigned int i, const Point &p, Real time=0.) override
Definition: wrapped_function.h:187
libMesh::WrappedFunction::clone
virtual std::unique_ptr< FunctionBase< Output > > clone() const override
Definition: wrapped_function.h:137
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::WrappedFunction
Wrap a libMesh-style function pointer into a FunctionBase object.
Definition: wrapped_function.h:51
libMesh::FunctionBase::_initialized
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
Definition: function_base.h:179
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::DenseVector::size
virtual unsigned int size() const override
Definition: dense_vector.h:92
libMesh::WrappedFunction::_parameters
const Parameters * _parameters
Definition: wrapped_function.h:110
libMesh::WrappedFunction::WrappedFunction
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.
Definition: wrapped_function.h:58
libMesh::WrappedFunction::_sys
const System & _sys
Definition: wrapped_function.h:103
libMesh::WrappedFunction::_fptr
Output(* _fptr)(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name)
Definition: wrapped_function.h:105
libMesh::SCALAR
Definition: enum_fe_family.h:58
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::WrappedFunction::~WrappedFunction
virtual ~WrappedFunction()=default
fptr
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition: projection.C:80
libMesh::WrappedFunction::operator()
virtual Output operator()(const Point &p, const Real time=0.) override
Definition: wrapped_function.h:122
libMesh::Parameters
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:59
libMesh::DenseVector< Output >
libMesh::EquationSystems::parameters
Parameters parameters
Data structure holding arbitrary parameters.
Definition: equation_systems.h:557