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