wrapped_function.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 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 AutoPtr<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 AutoPtr<FunctionBase<Output> > 00130 WrappedFunction<Output>::clone () const 00131 { 00132 return AutoPtr<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 const unsigned int size = output.size(); 00155 libmesh_assert_equal_to (size, _sys.n_components()); 00156 00157 // Loop over variables, then over each component in 00158 // vector-valued variables, evaluating each. 00159 const unsigned int n_vars = _sys.n_vars(); 00160 for (unsigned int v = 0; v != n_vars; ++v) 00161 { 00162 const unsigned int n_components = 00163 _sys.variable(v).n_components(); 00164 if (n_components == 1) 00165 output(_sys.variable_scalar_number(v,0)) = 00166 _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v)); 00167 else 00168 { 00169 // Right now our only non-scalar variable type is the 00170 // SCALAR variables. The irony is priceless. 00171 libmesh_assert_equal_to (_sys.variable(v).type().family, SCALAR); 00172 00173 // We pass the point (j,0,0) to an old-style fptr function 00174 // pointer to distinguish the different scalars within the 00175 // SCALAR variable. 00176 for (unsigned int j=0; j != n_components; ++j) 00177 output(_sys.variable_scalar_number(v,j)) = 00178 _fptr(Point(j,0,0), *_parameters, 00179 _sys.name(), _sys.variable_name(v)); 00180 } 00181 } 00182 } 00183 00184 00189 template <typename Output> 00190 inline 00191 Output WrappedFunction<Output>::component (unsigned int i, 00192 const Point& p, 00193 Real /*time*/) 00194 { 00195 libmesh_assert(_fptr); 00196 libmesh_assert(_parameters); 00197 00198 // Loop over variables, then over each component in 00199 // vector-valued variables. 00200 const unsigned int n_vars = _sys.n_vars(); 00201 for (unsigned int v = 0; v != n_vars; ++v) 00202 { 00203 const unsigned int n_components = 00204 _sys.variable(v).n_components(); 00205 if (n_components == 1 && 00206 i == _sys.variable_scalar_number(v,0)) 00207 return _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v)); 00208 else if (i >= _sys.variable_scalar_number(v,0) && 00209 i <= _sys.variable_scalar_number(v,n_components-1)) 00210 { 00211 // Right now our only non-scalar variable type is the 00212 // SCALAR variables. The irony is priceless. 00213 libmesh_assert_equal_to (_sys.variable(i).type().family, SCALAR); 00214 00215 // We pass the point (j,0,0) to an old-style fptr function 00216 // pointer to distinguish the different scalars within the 00217 // SCALAR variable. 00218 for (unsigned int j=0; j != n_components; ++j) 00219 if (i == _sys.variable_scalar_number(v,j)) 00220 return _fptr(Point(j,0,0), *_parameters, 00221 _sys.name(), _sys.variable_name(v)); 00222 } 00223 } 00224 libMesh::err << "Component index " << i << 00225 " not found in system " << _sys.name() << std::endl; 00226 libmesh_error(); 00227 return Output(); 00228 } 00229 00230 00231 00232 } // namespace libMesh 00233 00234 #endif // LIBMESH_WRAPPED_FUNCTION_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:49 UTC
Hosted By: