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 OperatorOnUnknown} class}
18
19The {\class OperatorOnUnknow} class is intended to store the description of an expression involving
20a differential operator acting on an unknown (or a test function) with possibly operations
21at the left and the right. More precisely, the general form of the operator on unknown is:
22\begin{center}
23\textbf{tr(data) op dif( tr(u) ) op tr(data)}
24\end{center}
25where
26\begin{itemize}
27\item \textbf{u} is an unknown,
28\item \textbf{dif} a differential operator,
29\item \textbf{data} is a user data (value or function),
30\item \textbf{op} an algebraic operation among \verb?*? (product), \verb?|? (inner product),
31\verb?^? (cross product), \verb?:? (contracted product),
32\item \textbf{tr} a transformation among conj (conjugate), tran (transpose) and adj (adjoint).
33\end{itemize}
34All is optional except the unknown u. \\
35
36The simplest form is \textbf{u} and a more complex one is for instance, something like this
37($f$ a matrix and $g$ a vector):
38\begin{center}
39\textbf{adj}(\textbf{f})* \textbf{grad}(\textbf{conj}(\textbf{u}[2])) | \textbf{conj}(\textbf{g})
40\end{center}
41which mathematically reads:
42$$f^*\,\nabla \overline{u}_2\,.\,\overline{g}$$
43The class has the following attributes:
44\vspace{.1cm}
45\begin{lstlisting}
46class OperatorOnUnknown
47{protected :
48   const Unknown * u_p;            //unknown involved in operator
49   bool conjugateUnknown_;         //true if the unknown has to be conjugated
50   DifferentialOperator * difOp_p; //differential operator involved in operator
51   Operand * leftOperand_p;        //object before the diff operator
52   Operand * rightOperand_p;       //object after the diff operator
53   bool leftPriority_;             //priority order flag, true if left operand is prior
54   Vector<complex_t> coefs_;       //coefficients for operator (gradG, divG, curlG)
55   ValueType type_;                //returned value (_real,_complex)
56   StrucType struct_;              //returned structure (_scalar,_vector,_matrix)
57\end{lstlisting}
58\vspace{.2cm}
59{\class Operand} is a class storing a user data (value or function) and an algebraic operation
60(\verb?* | ^ %?).\\
61
62The class provides some basic constructors (from unknown and differential operator type), some
63useful constructors (from unknown and function or value),  a copy constructor, the assignment
64operator and a destructor:
65\vspace{.1cm}
66\begin{lstlisting}[]
67OperatorOnUnknown(const Unknown* un=0,DiffOpType=_id);
68OperatorOnUnknown(const Unknown& un,DiffOpType=_id);
69OperatorOnUnknown(const Unknown&,const Function&,AlgebraicOperator,bool);
70OperatorOnUnknown(const Unknown&,const Value&,AlgebraicOperator,bool);
71OperatorOnUnknown(const OperatorOnUnknown &);
72~OperatorOnUnknown();
73OperatorOnUnknown& operator=(const OperatorOnUnknown &);
74\end{lstlisting}
75\vspace{.2cm}
76Note that the {\class DifferentialOperator} object are created on the fly when creating {\class OperatorOnUnknown} from {\class Unknown} and {\class DiffOpType}. \\
77
78The class provides some accessors (read or write):
79\vspace{.1cm}
80\begin{lstlisting}[]
81DiffOpType difOpType() const ;
82DifferentialOperator*& difOp() ;
83ValueType& type();
84Operand*& leftOperand();
85Operand*& rightOperand();
86Vector<complex_t>& coefs();
87const Vector<complex_t>& coefs() const;
88bool leftPriority() const;
89bool& leftPriority();
90\end{lstlisting}
91\vspace{.2cm}
92and  some utilities to update class attributes and print them:
93\vspace{.1cm}
94\begin{lstlisting}[]
95void setReturnedType(const Unknown*,DiffOpType);
96void updateReturnedType(AlgebraicOperator,ValueType,StrucType,bool);
97void print(std::ostream&) const;
98std::ostream& operator<<(std::ostream&,const OperatorOnUnknown &);  //extern
99\end{lstlisting}
100\vspace{.2cm}
101The two first one manage the returned types and check consistency of operations and the two
102last functions output on stream the {\class OperatorOnUnknown} characteristics.\\
103
104To deal with the general syntax of {\class OperatorOnUnknown}, a lot of external functions are required,
105in particular some overloaded operators. The first family of functions concerns the creation
106of simple {\class OperatorOfUnknown} object from a differential operator and an unknown. Their names
107are the names of differential operator type ({\class DiffOpType} enumeration) without the leading underscore.
108We give only a few examples here (see OperatorOnUnknown.hpp header file for the complete list):
109\vspace{.1cm}
110\begin{lstlisting}[]
111OperatorOnUnknown& id(const Unknown&);
112OperatorOnUnknown& d0(const Unknown&);
113...
114OperatorOnUnknown& grad(const Unknown&);
115OperatorOnUnknown& nabla(const Unknown&);
116...
117OperatorOnUnknown& nx(const Unknown&);
118...
119OperatorOnUnknown& gradG (const Unknown&,const complex_t&,const complex_t&,
120                                         const complex_t&,const complex_t&);
121...
122OperatorOnUnknown& mean(const Unknown&);
123OperatorOnUnknown& jump(const Unknown&);
124\end{lstlisting}
125\vspace{.2cm}
126These functions constructs an {\class OperatorOnUnknown} in the heap memory and return a reference in
127order to be used in an chained expression. In this context, it may be occur a memory leak if
128nobody delete explicitly the {\class OperatorOnUnknown} object created on the fly.\\
129
130To manage general syntax, the following c++ operators have been overloaded:\\
131\hspace*{5mm} \verb?*? : usual consistent product between scalars, vectors and matrices \\
132\hspace*{5mm} \verb?|? : inner product of vectors, for complex objects it is an hermitian product\\
133\hspace*{5mm} \verb?^? : cross product of vectors\\
134\hspace*{5mm} \verb?%? : contracted product (the second term is transposed)
135
136These operators are enumerated in the {\class AlgebraicOperator} enumeration.\\
137
138They are overloaded for {\class Unknown} or {\class OperatorOnUnknown} and unitaryVector ({\class UnitaryVector} enumerates the normal vector \_ n and the tangential vector \_ t). When differential operators involve operation with normal, you can use the previous function (for instance \textit{ndot}) or use their mathematical syntax (for instance \textit{n*u}):
139\vspace{.1cm}
140\begin{lstlisting}[]
141OperatorOnUnknown& operator*(UnitaryVector,const Unknown &);    // n*u
142OperatorOnUnknown& operator*(const Unknown &,UnitaryVector);    // u*n
143OperatorOnUnknown& operator|(UnitaryVector,const Unknown &);    // n|u
144OperatorOnUnknown& operator^(UnitaryVector,const Unknown &);    // n^u
145OperatorOnUnknown& operator|(const Unknown &,UnitaryVector);    // u|n
146OperatorOnUnknown& operator|(UnitaryVector,OperatorOnUnknown&); // n|grad(u)
147OperatorOnUnknown& operator^(UnitaryVector,OperatorOnUnknown&); // n^(n^u) or n^curl(u)
148OperatorOnUnknown& operator*(UnitaryVector,OperatorOnUnknown&); // n*div
149OperatorOnUnknown& operator|(OperatorOnUnknown&,UnitaryVector); // grad(u)|n
150OperatorOnUnknown& operator*(OperatorOnUnknown&,UnitaryVector); // div*n
151\end{lstlisting}
152\vspace{.1cm}
153Note that all cases are not considered. It should be !?\\
154
155To deal with left and right-hand side operations, these algebraic operators have been also overloaded
156for different types of objects ({\class Unknown}, {\class OperatorOnUnknown}, {\class Function}, {\class Value}, user c++ function
157or user value). The operator overloading with c++ function or user value avoids the user to
158explicitly encapsulate its own data (c++ function or scalar, vector, matrix) in Function object
159or Value object. There are shortcuts. In the following, only prototypes of * operator are presented.
160
161\subsection{Operations between {\classtitle Unknown} and {\classtitle Function}}
162\vspace{.1cm}
163\begin{lstlisting}[]
164OperatorOnUnknown&  operator*(const Unknown &,const Function&);    // u*F
165OperatorOnUnknown&  operator*(const Function&,const Unknown &);    // F*u
166template <typename T>
167  OperatorOnUnknown& operator*(const Unknown &,T( )(const Point&,Parameters&));
168  OperatorOnUnknown& operator*(T( )(const Point&,Parameters&),const Unknown &);
169  OperatorOnUnknown& operator*(const Unknown &,
170                               T( )(const Vector<Point>&,Parameters&));
171  OperatorOnUnknown& operator*(T( )(const Vector<Point>&,Parameters&),
172                               const Unknown &);
173...
174\end{lstlisting}
175\vspace{.1cm}
176The two first one declarations concern Function object encapsulating c++ user functions whereas
177 the templated forms concerns c++ user functions. As mentioned before, it avoids the user to
178encapsulate his c++ functions. Note that only c++ functions that can be encapsulated in Function
179object are working in templated forms. Other functions may be accepted in compilation process,
180but the result during execution may be hazardous!\\
181\begin{remark}
182Kernel type functions can not be use straightforward in operator. Contrary to the ordinary
183functions, they have to be encapsulated in {\class Function} objects!
184\end{remark}
185
186\subsection{Operations between {\classtitle Unknown} and {\classtitle Value}}
187
188\vspace{.1cm}
189\begin{lstlisting}[]
190OperatorOnUnknown&  operator*(const Unknown&,const Value&);       // u*V
191OperatorOnUnknown&  operator*(const Value&,const Unknown&);       // V*u
192template<typename T>
193  OperatorOnUnknown&  operator*(const Unknown& ,const T& )        // u*T
194  OperatorOnUnknown&  operator*(const T& ,const Unknown&)         // T*u
195...
196\end{lstlisting}
197\vspace{.1cm}
198The two first one declarations concern Value object encapsulating c++ user data and the templated
199forms concerns c++ user data. Only c++ user data that can be encapsulated in Value object are
200working in templated forms. \\
201
202\subsection{Operations between {\classtitle OperatorOnUnknown} and {\classtitle Function}}
203
204The principle is the same as in previous cases.
205\vspace{.1cm}
206\begin{lstlisting}[]
207OperatorOnUnknown& operator*(OperatorOnUnknown&,const Function &); // op(u)*F
208OperatorOnUnknown& operator*(const Function &,OperatorOnUnknown&); // F*op(u)
209template<typename T>
210  OperatorOnUnknown& operator*(OperatorOnUnknown&, T( )(const Point&,Parameters&))
211  OperatorOnUnknown& operator*(T( )(const Point&,Parameters&), OperatorOnUnknown&)
212  OperatorOnUnknown& operator*(OperatorOnUnknown&,
213                               T( )(const Vector<Point>&,Parameters&))
214  OperatorOnUnknown& operator*(T( )(const Vector<Point>&,Parameters&),
215                               OperatorOnUnknown&)
216...
217\end{lstlisting}
218\vspace{.1cm}
219
220\subsection{Operations between {\classtitle OperatorOnUnknown} and {\classtitle Value}}
221
222\vspace{.1cm}
223\begin{lstlisting}[]
224OperatorOnUnknown& operator*(OperatorOnUnknown&,const Value &);   // op(u)*V
225OperatorOnUnknown& operator*(const Value &,OperatorOnUnknown&);   // V*op(u)
226template<typename T>
227  OperatorOnUnknown& operator*(OperatorOnUnknown&,const T&);      // op(u)*T
228  OperatorOnUnknown& operator*(const T&,OperatorOnUnknown&);      // T*op(u)
229...
230\end{lstlisting}
231\vspace{.2cm}
232Most of the previous overloaded operators use the following update functions:
233\vspace{.1cm}
234\begin{lstlisting}[]
235OperatorOnUnknown& updateRight(OperatorOnUnknown&,const Function&,AlgebraicOperator);
236OperatorOnUnknown& updateLeft (OperatorOnUnknown&,const Function&,AlgebraicOperator);
237OperatorOnUnknown& updateRight(OperatorOnUnknown&,const Value&,AlgebraicOperator);
238OperatorOnUnknown& updateLeft (OperatorOnUnknown&,const Value&,AlgebraicOperator);
239template<typename T>
240  OperatorOnUnknown& updateRight(OperatorOnUnknown&,const T&,AlgebraicOperator);
241  OperatorOnUnknown& updateLeft(OperatorOnUnknown&,const T&,AlgebraicOperator);
242\end{lstlisting}
243\vspace{.2cm}
244
245Note that it is possible to use the transformations \textit{conj}, \textit{tran} and \textit{adj}
246on Unknown, Value or Function. These functions are defined in the files related to these classes.
247For simplicity, it is not possible to apply such transformations to an {\class OperatorOnUnknown} object
248or a part of the expression. For instance, the syntax \textit{conj(grad(u))} is not supported.
249\\
250Finally, we give some examples to show how this machinery works:
251\vspace{.1cm}
252\begin{lstlisting}[deletekeywords={[3] opu}]
253//define some C++ functions
254real_t F(const Point &P,Parameters& pa = defaultParameters) {...}
255Vector<real_t> vecF(const Point &P,Parameters& pa = defaultParameters) {...}
256Matrix<real_t> matF(const Point &P,Parameters& pa = defaultParameters) {...}
257//define some constant values
258real_t pi=3.14159; complex_t i(0,1);vector<real_t> v(3,1); matrix<complex_t> A(3,3,i);
259//assume u is an Unknown (a vector of dimension 3)
260OperatorOnUnknown opu=u;    //the simplest one
261opu=grad(u);                //involve only differential operator
262opu=_n^curl(u);              //equivalent to ncrosscurl(u)
263opu=v^u;                    //cross product with vector
264opu=vecF^u;                 //cross product with vector function
265opu=A*grad(u);              //left product with a matrix
266opu=grad(u)*matF;           //right product with a matrix function
267opu=(matF*grad(u))%A;       //product and contracted product
268opu=curl(conj(u))|conj(v);  //use conj transformation
269\end{lstlisting}
270\vspace{.2cm}
271Be careful with operator priority. The C++ priority rules are applied and not the mathematical
272ones. In doubt, use parenthesis.
273The code performs some constancy checking on operand and operator but only on structure (scalar,
274vector, matrix) not on the dimension (see \textit{upadateReturnedType} and \textit{setReturnedType}
275functions).
276\displayInfos{library=operator, header=OperatorOnUnknown.hpp, implementation=OperatorOnUnknown.cpp,
277test=test\_operator.cpp, header dep={config.h, utils.h}}
278
279