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 Projector} class} 18The {\class Projector} class is intended to handle projection from one FE space, say $V$ to an other FE space, say $W$. The projection $w\in W$ of a $v \in V$ is based on a bilinear form, say $a(.,.)$, defined on both spaces : 19$$a(w,\tilde{w}) =a(v,\tilde{w})\, \ \forall \tilde{w}\in W.$$ 20Let $(w_i)_{i=1,n}$ a basis of $W$ and $(v_i)_{i=1,m}$ a basis of $V$, the above problem is equivalent to the matrix problem: 21$$\mathbb{A}\,W=\mathbb{B}\,V$$ 22where $\mathbb{A}_{ij}=a(w_j,w_i)$, $\mathbb{B}_{ij}=a(v_j,w_i)$, $v=\sum_{i=1,m}V_i\,v_i$ and $w=\sum_{i=1,n}W_i\,w_i$. 23The bilinear form should be symmetric and positive on the space $W$ in order to the matrix $\mathbb{A}$ be invertible. The most simple example is the $L^2$ projection related to the bilinear form: 24$$a(w,\tilde{w})=\int_{\Omega }w\,\tilde{w}\,d\Omega.$$ 25 26As a consequence, the {\class Projector} class manages the following data: 27\vspace{.1cm} 28\begin{lstlisting}[]{} 29class Projector 30{ 31public: 32ProjectorType projectorType; //!< type of projection 33string_t name; //!< name of projection 34protected: 35Space* V_, *W_; //!< spaces involved 36Unknown* u_V, *u_W; //!< internal unknowns 37const GeomDomain* domain_; //!< domain involved in bilinear forms 38BilinearForm* a_V, *a_W; //!< bilinear forms used by projector 39mutable TermMatrix* A_, *B_; //!< matrix a(W,W) and a(W,V) 40mutable TermMatrix* invA_B; //!< matrix inv(A)*B if allocated 41} 42\end{lstlisting} 43\vspace{.1cm} 44where the projector type is one of the following: 45\vspace{.1cm} 46\begin{lstlisting}[]{} 47enum ProjectorType {_noProjectorType=0, _userProjector, _L2Projector, _H1Projector, _H10Projector}; 48\end{lstlisting} 49\vspace{.1cm} 50Because, bilinear forms in \xlifepp are linked to unknowns/spaces, the class manages two bilinear forms and their matrix representation. The unknowns used by the {\class Projector} are not some user unknowns but are specific to the class. Finally, it can allocate a {\class TermMatrix} object representing the matrix $\mathbb{A}^{-1}\,\mathbb{B}$.\\ 51 52Besides, in order to save time and memory, all the projectors that have been handled (explicitely or implicitely) are listed in a static vector: 53\vspace{.1cm} 54\begin{lstlisting}[]{} 55static std::vector<Projector*> theProjectors; 56\end{lstlisting} 57\vspace{.1cm} 58Projector are constructed from spaces, a projector type or a bilinear form and an optional name. When dealing with the restriction of a space to a domain, the domain has to be given. When dealing with projection of vector unknown, the sizes have to be specified. 59\vspace{.1cm} 60\begin{lstlisting}[]{} 61Projector(Space& V, Space& W, ProjectorType pt=_L2Projector, 62 const string_t& na=""); 63Projector(Space& V, Space& W, const GeomDomain&, ProjectorType pt=_L2Projector, 64 const string_t& na=""); 65Projector(Space& V, Space& W, BilinearForm& a, const string_t& na=""); 66Projector(Space& V, dimen_t nbcV, Space& W, dimen_t nbcW, 67 ProjectorType pt=_L2Projector, const string_t& na=""); 68Projector(Space& V, dimen_t nbcV, Space& W, dimen_t nbcW, const GeomDomain&, 69 ProjectorType pt=_L2Projector, const string_t& na=""); 70Projector(Space& V, dimen_t nbcV, Space& W, dimen_t nbcW, BilinearForm& a, 71 const string_t& na=""); 72~Projector(); 73void init(dimen_t nbc_V, dimen_t nbc_W); 74\end{lstlisting} 75\vspace{.1cm} 76The {\var init()} function do really the job of construction. In particular, it computes the matrix {\var A\_} and {\var B\_} and do a factorization of {\var A\_}.\\ 77 78Note that the {\class TermMatrix} is not allocated at the construction. To allocate it, one has to call the member function: 79\vspace{.1cm} 80\begin{lstlisting}[]{} 81TermMatrix& asTermMatrix(const Unknown&, const Unknown&, 82 const string_t& = "invA_B"); 83\end{lstlisting} 84\vspace{.1cm} 85that returns a reference to the {\class TermMatrix} {\var invA\_B} and deletes the {\class TermMatrix} {\var A\_} and {\var B\_}.\\ 86 87Once constructed, projectors can process {\class TermVector}'s by using one of the three operator functions: 88\vspace{.1cm} 89\begin{lstlisting}[]{} 90TermVector operator()(TermVector& V,const Unknown& u) const; 91TermVector operator()(const TermVector& V) const; 92TermVector& operator()(TermVector& V, TermVector& PV) const; 93\end{lstlisting} 94\vspace{.1cm} 95Because an unknown is always linked to any {\class TermVector}, the user can pass the unknown either in a explicit way or in a implicit way when the {\class TermVector} result is passed to the operator. When no unknown is passed to, the unknown of the projection will be the first unknown linked to the space $W$. If the {\class TermMatrix} {\var invA\_B} is allocated, the projection does the product {\var invA\_B * V}, if not the projection does the product {\var B\_ * V} and solve the linear system {\var A\_ * X = B\_ * V} using the {\var factSolve} functions. \\ 96 97Projection can also be processed by using the operator *: 98\vspace{.1cm} 99\begin{lstlisting}[]{} 100friend TermVector operator*(const Projector& P, const TermVector& V); 101\end{lstlisting} 102\vspace{.1cm} 103that only calls {\var P(V)}.\\ 104 105Users can compute the projection of a {\class TermVector} without instanciating a {\class Projector} object: 106\vspace{.1cm} 107\begin{lstlisting}[]{} 108TermVector projection(const TermVector& V, Space& W, ProjectorType pt=_L2Projector); 109\end{lstlisting} 110\vspace{.1cm} 111In that case, a {\class Projector} object is created in the back.\\ 112 113Two functions deal with the list of all projectors: 114\vspace{.1cm} 115\begin{lstlisting}[]{} 116friend Projector& findProjector(Space& V, Space& W, 117 ProjectorType pt=_L2Projector); 118static void clearGlobalVector(); 119\end{lstlisting} 120\vspace{.1cm} 121The {\var findProjector} creates a new projector if projector has not been found.\\ 122 123Finally, there are some print stuff: 124\vspace{.1cm} 125\begin{lstlisting}[]{} 126void print(ostream&) const; 127friend ostream& operator<<(ostream&, const Projector&); 128\end{lstlisting} 129\vspace{.1cm} 130 131\displayInfos{ 132 library=term, 133 header=Projector.hpp, 134 implementation=Projector.cpp, 135 test=unit\_Projector.cpp, 136 header dep={Term.hpp, config.h, utils.h} 137} 138 139 140 141