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