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