wrapped_function.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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"
26 #include "libmesh/function_base.h"
27 #include "libmesh/libmesh_common.h"
28 #include "libmesh/point.h"
29 #include "libmesh/system.h"
30 
31 // C++ includes
32 #include <cstddef>
33 
34 namespace libMesh
35 {
36 
49 template <typename Output=Number>
50 class WrappedFunction : public FunctionBase<Output>
51 {
52 public:
53 
57  WrappedFunction (const System & sys,
58  Output fptr(const Point & p,
59  const Parameters & parameters,
60  const std::string & sys_name,
61  const std::string & unknown_name) = nullptr,
62  const Parameters * parameters = nullptr,
63  unsigned int varnum=0)
64  : _sys(sys),
65  _fptr(fptr),
66  _parameters(parameters),
67  _varnum(varnum)
68  {
69  this->_initialized = true;
70  if (!parameters)
72  }
73 
77  WrappedFunction (WrappedFunction &&) = default;
78  WrappedFunction (const WrappedFunction &) = default;
79  virtual ~WrappedFunction () = default;
80 
84  WrappedFunction & operator= (const WrappedFunction &) = delete;
86 
87  virtual std::unique_ptr<FunctionBase<Output>> clone () const override;
88 
89  virtual Output operator() (const Point & p,
90  const Real time = 0.) override;
91 
92  virtual void operator() (const Point & p,
93  const Real time,
94  DenseVector<Output> & output) override;
95 
96  virtual Output component (unsigned int i,
97  const Point & p,
98  Real time=0.) override;
99 
100 protected:
101 
102  const System & _sys;
103 
104  Output (*_fptr)(const Point & p,
105  const Parameters & parameters,
106  const std::string & sys_name,
107  const std::string & unknown_name);
108 
110 
111  unsigned int _varnum;
112 };
113 
114 
115 // ------------------------------------------------------------
116 // WrappedFunction inline methods
117 
118 
119 template <typename Output>
120 inline
122  const Real /*time*/)
123 {
124  libmesh_assert(_fptr);
125  libmesh_assert(_parameters);
126  return _fptr(p,
127  *_parameters,
128  _sys.name(),
129  _sys.variable_name(_varnum));
130 }
131 
132 
133 template <typename Output>
134 inline
135 std::unique_ptr<FunctionBase<Output>>
137 {
138  return std::unique_ptr<FunctionBase<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
virtual unsigned int size() const override
Definition: dense_vector.h:92
Wrap a libMesh-style function pointer into a FunctionBase object.
virtual Output component(unsigned int i, const Point &p, Real time=0.) override
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:712
const unsigned int n_vars
Definition: tecplot_io.C:69
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:92
virtual std::unique_ptr< FunctionBase< Output > > clone() const override
WrappedFunction & operator=(const WrappedFunction &)=delete
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual ~WrappedFunction()=default
const Parameters * _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)
Base class for functors that can be evaluated at a point and (optionally) time.
A geometric point in (x,y,z) space.
Definition: point.h:38