1%%%%%%%%%%%%%%%%%%% 2% XLiFE++ is an extended library of finite elements written in C++ 3% Copyright (C) 2014 Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin 4% 5% This program is free software: you can redistribute it and/or modify 6% it under the terms of the GNU General Public License as published by 7% the Free Software Foundation, either version 3 of the License, or 8% (at your option) any later version. 9% This program 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 12% GNU General Public License for more details. 13% You should have received a copy of the GNU General Public License 14% along with this program. If not, see <http://www.gnu.org/licenses/>. 15%%%%%%%%%%%%%%%%%%% 16 17\section{The {\classtitle Function} class}\label{s.function} 18 19The object function aims to encapsulate the user functions with an additional information, 20says parameter data. This encapsulation are concerned with functions of a point or a couple 21of points, required by finite element computations at a low level. These functions are typically 22some physical parameters involved in integrals or source data functions. They may require other 23constant parameters. It is the reason why it is necessary to attach to the function a list 24of parameters (constant values of real type, complex type, ...). This class is designed to 25deal with standard functions involved in a finite element software (24 types): 26\begin{lstlisting}[]{} 27 r function(const Point&, Parameters&) 28 Vector<r> function(const Vector<Point>&, Parameters&) 29 r function(const Point&, const Point&, Parameters&) 30 Vector<r> function(const Vector<Point>&, const Vector<Point>&, Parameters&) 31\end{lstlisting} 32with r of type: 33\begin{lstlisting}[]{} 34real_t, complex_t, Vector<real_t>, Vector<complex_t>, Matrix<real_t>, Matrix<complex_t> 35\end{lstlisting} 36\vspace{.2cm} 37The functions (resp. kernels) taking a point or a couple of points as input argument are called 38"scalar" functions (resp. kernel) whereas those taking a vector of points or a couple of vector 39of points are called "vector" functions (resp. kernels). Do not confuse a "vector" function 40with a function returning a vector and taking a point as input argument. For a such function, 41its vector form returns a vector of vectors. \\ 42 43The object function is based on the non templated class {\class Function}: 44\begin{lstlisting}[deletekeywords={[3] map}] 45template<typename T_> class Function 46{class Function 47 protected: 48 ValueType type_returned_; // type of returned value ( _real, _complex) 49 StrucType struct_returned_; // struct of returned value (_scalar,_vector,_matrix) 50 FunctType type_function_; // type of the function (_function or _kernel} 51 ArgType argType_; // type of the argument (_point,_vector_point) 52 mutable Parameters* params_; // pointer to parameter list 53 dimPair dims_; // dimension of returned values 54 String name_; // name of function and comments 55 void * fun_; // store pointer to function in a void * 56 //flag in OperatorOnUnknown construction (see operator lib) 57 mutable bool check_type_; // to activate a checking of arguments 58 mutable bool conjugate_; // temporary flag for conjugate operation 59 mutable bool transpose_; // temporary flag for transpose operation 60 //to manage data requirements 61 bool requireNx; // true if function requires normal or x-normal vector 62 bool requireNy; // true if function (kernel) requires y-normal vector 63 bool requireElt; // true if function requires element 64 bool requireDom; // true if requires domain 65 bool requireDof; // true if requires dof 66 //special attributes for kernel 67 mutable bool xpar; // true if x is consider as a parameter 68 mutable Point xory; // x or y as parameter of the kernel 69 public: 70 static std::map<String,std::pair<ValueType,StrucType> > returnTypes; 71 static std::map<String,std::pair<ValueType,StrucType> > returnArgs; 72} 73\end{lstlisting} 74 75which manages the user function storing its pointer in the void pointer \emph{fun\_}, its parameters 76list in the Parameters pointer \emph{params\_} and a function name (optional) in the string 77\emph{name\_}. There are also members to store characteristics of the function (type and arguments 78type) allowing to identify quickly the return type of the function. The member \emph{check\_type\_} 79is a flag used in safe evaluation process of the function. The two static maps are used to 80the management of the types.\\ 81 82\begin{remark} 83We choose to use a non templated class for two reasons: to avoid template paradigm to the 84end users and to have a simpler way to transmit such object function in different part of the 85library. The counterpart of this choice is a more complex Function class but the complexity 86is only located in the class. 87\end{remark}\\ 88 89For each type of function is defined a useful alias of the pointer function: 90\begin{lstlisting}[]{} 91typedef r(fun_xx_t)(const Point&, Parameters&); 92typedef Vector<r>(vfun_xx_t)(const Vector<Point>&, Parameters&); 93typedef r(ker_xx_t)(const Point&, const Point&, Parameters&); 94typedef Vector<r>(vker_xx_t)(const Vector<Point>&, const Vector<Point>&, Parameters&); 95\end{lstlisting} 96where \emph{r} is the return type and \emph{xx} a code of the return type (sr,sc,vr,vc,mr,mc); 97s for scalar, v for vector, m for matrix, r for real and c for complex. \\ 98 99The class Function proposes: 100\begin{itemize} 101\item two constructors for each type of function (named and unnamed): 102\begin{lstlisting}[]{} 103 Function(fun_sr_t& f, Parameters& pa = def_parameters); //real scalar type 104 Function(fun_sr_t& f, const String& na, Parameters& pa = def_parameters); 105 Function(fun_sc_t& f, Parameters& pa = def_parameters); //complex scalar type 106 Function(fun_sc_t& f, const String& na, Parameters& pa = def_parameters); 107 ... 108\end{lstlisting} 109which initialize the void pointer and compute the return types using the member function \emph{init()}. 110 111\item evaluation capabilities (unsafe but fast) for each type of function: 112\begin{lstlisting}[deletekeywords={[3] x}] 113real_t fun_sr(const Point &x) 114complex_t fun_sc(const Point &x) 115... 116\end{lstlisting} 117As these functions only recast the void pointer to the required pointer function: 118\begin{lstlisting}[deletekeywords={[3] x, y}] 119real_t fun_sr(const Point &x) 120 {return reinterpret_cast<fun_sr_t*>(fun_)(x,*params_);} 121\end{lstlisting} 122they are unsafe ! 123 124\item templated overloaded operator (), insensitive to the form of function (safe but not as 125fast as previous) 126\begin{lstlisting}[deletekeywords={[3] x}] 127template <typename T_> 128T_& operator()(const Point & x, T_ & res); 129template <typename T_> 130T_& operator()(const Point & x,const Point& y, T_& res); 131template <typename T_> 132Vector<T_>& operator()(const Vector<Point>& x, Vector<T_>& res); 133template <typename T_> 134Vector<T_>& operator()(const Vector<Point>& x, 135 const Vector<Point>& y,Vector<T_> & res); 136\end{lstlisting} 137Note that these functions return a reference, contrary to the direct straight functions which 138return a value. Besides, by testing the input arguments, they are able to deal with single 139point or vector of points independently of the scalar or vector form of the user function 140: 141\begin{lstlisting} 142template<typename T_> 143T_& Function::operator()(const Point & x, T_ & res) 144{ if(check_type_) checkFunctionType(res,Function_t);//check argument types 145 if(type_arg_==Point_t) //case of a function of a point 146 { typedef typename PointerF<T_>::fun_p* funT; 147 funT f=reinterpret_cast<funT>(fun_); 148 res=f(x,*params_); 149 } 150 else //case of a function of a vector of points (construct a vector) 151 { typedef typename PointerF<T_>::vfun_p* vfunT; 152 vfunT f=reinterpret_cast<vfunT>(fun_); 153 Vector<Point> V; 154 V.push_back(x); 155 Vector<T_> R=f(V,*params_); 156 res=R[0]; 157 } 158 return res; 159} 160\end{lstlisting} 161Moreover, using the \emph{checkFunctionType()} they can also perform a control of the type 162of the function. As the checking function uses expensive RTTI capabilities, this possibility 163is conditioned by the \emph{check\_type} state (true or false) which is automatically reset 164to false by the \emph{checkFunctionType()}. 165 166\item accessors to the function characteristics: 167\begin{lstlisting}[]{} 168ValueType typeReturned() const; 169StrucType structReturned() const; 170ValueType valueType() const; 171StrucType strucType() const; 172FunctType typeFunction() const; 173ArgType typeArg() const ; 174bool conjugate() const; 175bool& conjugate(); 176void conjugate(bool v) const; 177bool transpose() const; 178bool& transpose(); 179void transpose(bool v) const; 180bool isVoidFunction() const; 181const void* fun_p() const; 182Parameters& params(); 183Parameters& params() const; 184Parameters*& params_p(); 185const Parameters* params_p() const; 186dimPair dims() const; 187string_t name() const; 188\end{lstlisting} 189\item some functions to manage the function parameters and X/Y parameter in kernel: 190\begin{lstlisting}[]{} 191void addParam(Parameter& pa; 192template<typename K> 193void setParam(K& v, const string_t& name) const; 194Parameter& parameter(const string_t&) const; 195Parameter& parameter(const char* s) const; 196Parameter& parameter(const size_t) const; 197void setX(const Point& P) const; // for kernel 198void setY(const Point& P) const; 199\end{lstlisting} 200\item some functions to manage the function data required during computation: 201\begin{lstlisting}[]{} 202bool normalRequired() const; 203void require(UnitaryVector uv, bool tf=true); 204void require(const string_t& s, bool tf=true); 205\end{lstlisting} 206\item a print utility: 207\begin{lstlisting}[]{} 208void printInfo() const 209\end{lstlisting} 210\end{itemize} 211To deal with some data that are available during FE computation such as normal vectors, current element, current dof or current domain, there is two things to do : tell to \xlifepp that the Function will use such data 212\begin{lstlisting}[]{} 213Function F(fun); //link a C++ function fun to a Function object 214F.require(_n); //tell that function fun will use normal vector 215F.require("element");//tell that function fun will use element 216\end{lstlisting} 217 and get data in the C++ function related to the Function object: 218 \begin{lstlisting}[]{} 219 Real fun(const Point& x, Parameters& pars=theDefaultParameters) 220 {... 221 Vector<Real>& n = getN(); //get the normal vector 222 GeomElement& elt=getElement(); //get element 223 ... 224 } 225 \end{lstlisting} 226 This machinery is based on the {\class ThreadData} class that manages one instance of data by thread. 227 228\displayInfos{library=utils, header=Function.hpp, implementation=Function.cpp, test=test\_Function.cpp, 229header dep={config.h, Parameters.hpp, Point.hpp, String.hpp, Vector.hpp}} 230