$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 #ifndef LIBMESH_WRAPPED_FUNCTION_H 00021 #define LIBMESH_WRAPPED_FUNCTION_H 00022 00023 // Local Includes 00024 #include "libmesh/dense_vector.h" 00025 #include "libmesh/equation_systems.h" 00026 #include "libmesh/function_base.h" 00027 #include "libmesh/libmesh_common.h" 00028 #include "libmesh/point.h" 00029 #include "libmesh/system.h" 00030 00031 // C++ includes 00032 #include <cstddef> 00033 00034 namespace libMesh 00035 { 00036 00037 00041 // ------------------------------------------------------------ 00042 // WrappedFunction class definition 00043 template <typename Output=Number> 00044 class WrappedFunction : public FunctionBase<Output> 00045 { 00046 public: 00047 00051 WrappedFunction (const System &sys, 00052 Output fptr(const Point& p, 00053 const Parameters& parameters, 00054 const std::string& sys_name, 00055 const std::string& unknown_name) = NULL, 00056 const Parameters* parameters = NULL, 00057 unsigned int varnum=0) 00058 : _sys(sys), 00059 _fptr(fptr), 00060 _parameters(parameters), 00061 _varnum(varnum) 00062 { 00063 this->_initialized = true; 00064 if (!parameters) 00065 _parameters = &sys.get_equation_systems().parameters; 00066 } 00067 00068 virtual UniquePtr<FunctionBase<Output> > clone () const; 00069 00074 virtual Output operator() (const Point& p, 00075 const Real time = 0.); 00076 00082 virtual void operator() (const Point& p, 00083 const Real time, 00084 DenseVector<Output>& output); 00085 00090 virtual Output component (unsigned int i, 00091 const Point& p, 00092 Real time=0.); 00093 00094 protected: 00095 00096 const System& _sys; 00097 00098 Output (*_fptr)(const Point& p, 00099 const Parameters& parameters, 00100 const std::string& sys_name, 00101 const std::string& unknown_name); 00102 00103 const Parameters* _parameters; 00104 00105 unsigned int _varnum; 00106 }; 00107 00108 00109 // ------------------------------------------------------------ 00110 // WrappedFunction inline methods 00111 00112 00113 template <typename Output> 00114 inline 00115 Output WrappedFunction<Output>::operator() (const Point& p, 00116 const Real /*time*/) 00117 { 00118 libmesh_assert(_fptr); 00119 libmesh_assert(_parameters); 00120 return _fptr(p, 00121 *_parameters, 00122 _sys.name(), 00123 _sys.variable_name(_varnum)); 00124 } 00125 00126 00127 template <typename Output> 00128 inline 00129 UniquePtr<FunctionBase<Output> > 00130 WrappedFunction<Output>::clone () const 00131 { 00132 return UniquePtr<FunctionBase<Output> > 00133 (new WrappedFunction<Output> 00134 (_sys, _fptr, _parameters, _varnum)); 00135 } 00136 00137 00143 template <typename Output> 00144 inline 00145 void WrappedFunction<Output>::operator() (const Point& p, 00146 const Real /*time*/, 00147 DenseVector<Output>& output) 00148 { 00149 libmesh_assert(_fptr); 00150 libmesh_assert(_parameters); 00151 00152 // We fill each entry of output with a single scalar component of 00153 // the data in our System 00154 libmesh_assert_equal_to (output.size(), _sys.n_components()); 00155 00156 // Loop over variables, then over each component in 00157 // vector-valued variables, evaluating each. 00158 const unsigned int n_vars = _sys.n_vars(); 00159 for (unsigned int v = 0; v != n_vars; ++v) 00160 { 00161 const unsigned int n_components = 00162 _sys.variable(v).n_components(); 00163 if (n_components == 1) 00164 output(_sys.variable_scalar_number(v,0)) = 00165 _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v)); 00166 else 00167 { 00168 // Right now our only non-scalar variable type is the 00169 // SCALAR variables. The irony is priceless. 00170 libmesh_assert_equal_to (_sys.variable(v).type().family, SCALAR); 00171 00172 // We pass the point (j,0,0) to an old-style fptr function 00173 // pointer to distinguish the different scalars within the 00174 // SCALAR variable. 00175 for (unsigned int j=0; j != n_components; ++j) 00176 output(_sys.variable_scalar_number(v,j)) = 00177 _fptr(Point(j,0,0), *_parameters, 00178 _sys.name(), _sys.variable_name(v)); 00179 } 00180 } 00181 } 00182 00183 00188 template <typename Output> 00189 inline 00190 Output WrappedFunction<Output>::component (unsigned int i, 00191 const Point& p, 00192 Real /*time*/) 00193 { 00194 libmesh_assert(_fptr); 00195 libmesh_assert(_parameters); 00196 00197 // Loop over variables, then over each component in 00198 // vector-valued variables. 00199 const unsigned int n_vars = _sys.n_vars(); 00200 for (unsigned int v = 0; v != n_vars; ++v) 00201 { 00202 const unsigned int n_components = 00203 _sys.variable(v).n_components(); 00204 if (n_components == 1 && 00205 i == _sys.variable_scalar_number(v,0)) 00206 return _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v)); 00207 else if (i >= _sys.variable_scalar_number(v,0) && 00208 i <= _sys.variable_scalar_number(v,n_components-1)) 00209 { 00210 // Right now our only non-scalar variable type is the 00211 // SCALAR variables. The irony is priceless. 00212 libmesh_assert_equal_to (_sys.variable(i).type().family, SCALAR); 00213 00214 // We pass the point (j,0,0) to an old-style fptr function 00215 // pointer to distinguish the different scalars within the 00216 // SCALAR variable. 00217 for (unsigned int j=0; j != n_components; ++j) 00218 if (i == _sys.variable_scalar_number(v,j)) 00219 return _fptr(Point(j,0,0), *_parameters, 00220 _sys.name(), _sys.variable_name(v)); 00221 } 00222 } 00223 00224 libmesh_error_msg("Component index " << i << " not found in system " << _sys.name()); 00225 return Output(); 00226 } 00227 00228 00229 00230 } // namespace libMesh 00231 00232 #endif // LIBMESH_WRAPPED_FUNCTION_H