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{Bilinear forms}
18
19Bilinear forms are managed using
20\begin{itemize}
21\item {\class BasicBilinearForm} abstract class of basic linear form,
22\item {\class IntgBilinearForm} class inheriting from {\class BasicBilinearForm} and dealing
23with integral form,
24\item {\class DoubleIntgBilinearForm} class inheriting from {\class BasicBilinearForm} and
25dealing with double integral forms,
26\item {\class SuBilinearForm} class storing linear combination of {\class  BasicBilinearForm}
27objects having the same unknown,
28\item {\class BilinearForm} class storing a list of {\class SuBilinearForm} objects using a
29map indexed by unknowns.
30\end{itemize}
31
32\subsection{{The \classtitle BasicBilinearForm} class}
33
34The {\class BasicBilinearForm} class is an abstract class having only the unknowns as attribute
35and their associated accessors:
36\vspace{.1cm}
37\begin{lstlisting}[deletekeywords={[3] up, vp}]
38class BasicBilinearForm
39{protected:
40   const Unknown* u_p;             //pointer to unknown u
41   const Unknown* v_p;             //pointer to unknown v (test function)
42 public :
43   const Unknown& up() const;
44   const Unknown& vp() const;
45   ...
46\end{lstlisting}
47\vspace{.1cm}
48The 'u' letter refers always to the left unknown of the bilinear form and the 'v' letter to
49the right unknown (test function) of the bilinear form. In matrix representation 'u' stands
50for columns and 'v' for rows.\\
51
52The child classes inheriting from {\class BasicBilinearForm} have to provide the following
53member functions:
54\vspace{.1cm}
55\begin{lstlisting}[]
56virtual ~BasicBilinearForm(){};
57virtual BasicBilinearForm* clone() const =0;
58virtual LinearFormType type() const =0;
59virtual ValueType valueType() const=0;
60virtual void print(std::ostream&) const =0;
61\end{lstlisting}
62\vspace{.1cm}
63The \verb?virtual clone()? function is used to construct a copy of the child objects from parent.
64
65\subsection{{The \classtitle IntgBilinearForm} class}
66
67The {\class IntgBilinearForm} class handles linear forms defined by a (single) integral over
68a geometric domain:
69$$\int_{D} {\cal L}_1(u) op {\cal L}_2(v)$$
70where $D$ is a geometric domain ({\class Domain} class) and ${\cal L}_1$, ${\cal L}_2$  are
71linear operators ({\class OperatorOnUnknown} class) acting on unknowns $u$ and $v$ ({\class
72Unknown} class) and $op$ is an algebraic product operator.  In case of mesh domain, it handles also the quadrature rules, one rule by shape of elements.\\
73This class is defined as follows:
74\vspace{.1cm}
75\begin{lstlisting}
76class IntgBilinearForm : public BasicBilinearForm
77{protected :
78 const GeomDomain* domain_p; //geometric domain of the integral (pointer)
79 const OperatorOnUnknown* opu_p; //operator on unknown u (pointer)
80 const OperatorOnUnknown* opv_p; //operator on unknown v (pointer)
81 AlgebraicOperator aop_;         //algebraic operation between operators
82 map<Number, Quadrature*> quadratures_; //!< pointers to quadrature rules
83 ...
84\end{lstlisting}
85\vspace{.1cm}
86Note that the \verb?quadratures_? map may be empty. This, is the case when the domain is not of type mesh domain. Generally, the elements of a mesh domain have the same shape but it may not.
87 It is the reason why a map is used to store the quadratures .\\
88
89It has one basic constructor, some public accessors and utilities:
90\vspace{.1cm}
91\begin{lstlisting}[]
92IntgBilinearForm(const GeomDomain&,const OperatorOnUnknown&, AlgebraicOperator,
93                 const OperatorOnUnknown&, QuadRule = _defaultRule, Number =0)
94const OperatorOnUnknown* opu() const;
95const OperatorOnUnknown* opv() const;
96const GeomDomain* domain() const;
97virtual BasicBilinearForm* clone() const;
98virtual LinearFormType type() const
99virtual ValueType valueType() const
100void setQuadrature(QuadRule , Number);
101virtual void print(std::ostream&) const;
102\end{lstlisting}
103\vspace{.1cm}
104The {\cmd setQuadrature} function set the quadrature pointers from a {\class QuadRule} (enumeration of type of quadrature rule) and a quadrature number (degree or order of quadrature rule).
105For a full description of quadrature rules see section \ref{quadrature_section}. When {\class QuadRule} is set to \verb?_defaultRule? in constructor, the 'best' rule is chosen regarding the
106shape element and the degree of integrand (see {\cmd Quadrature::bestQuadRule} function).
107
108\subsection{{The \classtitle DoubleIntgBilinearForm} class}
109
110The {\class DoubleIntgBilinearForm} class handles linear forms defined by a double integral
111over a product of geometric domains:
112$$\int_{D_x}\int_{D_y} {\cal L}(u)$$
113where $D_x$, $D_y$ are geometric domain ({\class GeomDomain} class) and ${\cal L}$ a linear operator
114({\class OperatorOnUnknown} class) acting on unknown $u$ ({\class Unknownn} class).\\
115Except, there are two geometric domains, this class is very similar to the {\class IntgBilinearForm}
116class:
117\vspace{.1cm}
118\begin{lstlisting}
119class DoubleIntgBilinearForm : public BasicBilinearForm
120{protected :
121 const GeomDomain* domainx_p;     //first geometric domain (say x variable)
122 const GeomDomain* domainy_p;     //second geometric domain (say y variable)
123 const OperatorOnUnknown* opu_p; //operator on unknown u (pointer)
124 const OperatorOnUnknown* opv_p; //operator on unknown v (pointer)
125 ...
126\end{lstlisting}
127\vspace{.2cm}It provides a basic constructor and some public accessors:
128\vspace{.1cm}
129\begin{lstlisting}[]
130DoubleIntgBilinearForm(const GeomDomain&,const GeomDomain&,const OperatorOnUnknown&,
131                       AlgebraicOperator,const OperatorOnUnknown&);
132const OperatorOnUnknown* opu() const;
133const OperatorOnUnknown* opv() const;
134const GeomDomain* domainx() const;
135const GeomDomain* domainy() const;
136virtual BasicBilinearForm* clone() const;
137virtual LinearFormType type() const;
138virtual ValueType valueType() const;
139virtual void print(std::ostream&)const;
140\end{lstlisting}
141\vspace{.1cm}
142
143\begin{remark}
144Be cautious in the definition of double integral. The syntax
145\begin{lstlisting}[]
146BilinearForm a=intg(Sigma, Gamma ,u*G*v);
147\end{lstlisting}
148has to be interpreted as
149$$
150\int_{\Sigma_x}\int_{\Gamma_y}u(y)G(x,y)v(x)dy\,dx
151$$
152where $u$ (the right unknown) stands for the unknown, $v$ (the left unknown) being the test function. In matrix representation, it means that $u$ stands for columns and $v$ for rows.
153\end{remark}
154
155\subsection{{The \classtitle SuBilinearForm} class}
156
157{\class BasicBilinearForm} objects may be lineary combined to produce a linear combination
158of {\class BasicBilinearForm} objects stored as a list of pair of {\class BasicBilinearForm}
159object and a complex scalar in the {\class SuBilinearForm} class.
160\vspace{.1cm}
161\begin{lstlisting}
162typedef std::pair<BasicBilinearForm*,complex_t> blfPair;
163class SuBilinearForm
164{protected:
165   std::vector<blfPair> blfs_; //list of pairs of basic bilinear form and coefficient
166   ...
167\end{lstlisting}
168\vspace{.1cm}
169All the {\class BasicBilinearForm} objects must have the same pair of unknowns ! It is the
170reason why this class has no pointer to unknowns; it refers to the first basic bilinear form
171to get its unknowns.\\
172
173Because {\class BasicBilinearForm} objects are copied for safety reason, this class provides
174default and basic constructors but also a copy constructor, a destructor and the overload assignment
175operator:
176\vspace{.1cm}
177\begin{lstlisting}[]
178SuBilinearForm(){};
179SuBilinearForm(const SuBilinearForm&);
180~SuBilinearForm();
181SuBilinearForm& operator=(const SuBilinearForm&);
182\end{lstlisting}
183\vspace{.2cm}
184It provides few accessors (some being const and no const):
185\vspace{.1cm}
186\begin{lstlisting}[]
187number_t size() const;
188std::vector<blfPair>& blfs();
189const std::vector<blfPair>& blfs() const;
190blfPair& operator()(number_t n);
191const blfPair& operator()(number_t n) const;
192const Unknown* up() const;
193const Unknown* vp() const;
194const Space* uSpace() const;
195const Space* vSpace() const;
196LinearFormType type() const;
197ValueType valueType() const;
198\end{lstlisting}
199\vspace{.2cm}
200It is possible to perform linear combination of linear combinations using the following overloaded
201operators:
202\vspace{.1cm}
203\begin{lstlisting}[]
204SuBilinearForm& SuBilinearForm::operator +=(const SuBilinearForm&);
205SuBilinearForm& SuBilinearForm::operator -=(const SuBilinearForm&);
206SuBilinearForm& SuBilinearForm::operator *=(const complex_t&);
207SuBilinearForm& SuBilinearForm::operator /=(const complex_t&);
208SuBilinearForm operator-(const SuBilinearForm&);
209SuBilinearForm operator+(const SuBilinearForm&,const SuBilinearForm&);
210SuBilinearForm operator-(const SuBilinearForm&,const SuBilinearForm&);
211SuBilinearForm operator*(const complex_t&,const SuBilinearForm&);
212SuBilinearForm operator*(const SuBilinearForm&,const complex_t&);
213SuBilinearForm operator/(const SuBilinearForm&,const complex_t&);
214bool SuBilinearForm::checkConsistancy(const SuBilinearForm&) const;
215\end{lstlisting}
216\vspace{.1cm}
217The member function {\cmd checkConsistancy} performs a test to insure that pair of unknowns
218is always the same.\\
219
220Finally, there are some print facilities:
221\vspace{.1cm}
222\begin{lstlisting}[]
223void SuBilinearForm::print(std::ostream&)const;
224std::ostream& operator<<(std::ostream&,const SuBilinearForm&);
225\end{lstlisting}
226
227\subsection{{The \classtitle BilinearForm} class}
228
229The {\class BilinearForm} class is the end user class dealing with general bilinear form, either
230a single unknown bilinear form (a {\class SuBilinearForm} object) or a multiple unknown bilinear
231form (a list of {\class SuBilinearForm} objects). In this class, a single unknown bilinear
232form is a multiple unknown blinear form with one pair of unknowns! The list of {\class SuBilinearForm}
233objects is stored in a map of {\class SuBilinearForm}, indexed by a pair of pointers to unknown
234:
235\vspace{.1cm}
236\begin{lstlisting}[deletekeywords={[3] map}]
237typedef std::pair<const Unknown *,const Unknown *> uvPair;
238
239class BilinearForm
240{protected :
241 std::map<uvPair,SuBilinearForm> mlcblf_;;  //list of linear combinations of basic forms
242 ...
243\end{lstlisting}
244\vspace{.2cm}
245To manage the map, the following aliases are defined:
246\vspace{.1cm}
247\begin{lstlisting}[deletekeywords={[3] map}]
248typedef std::map<uvPair,SuBilinearForm>::iterator it_mublc;
249typedef std::map<uvPair,SuBilinearForm>::const_iterator cit_mublc;
250\end{lstlisting}
251\vspace{.1cm}
252\begin{remark}
253When the {\class SuBilinearForm} unknowns owns an unknown component, the {\class SuBilinearForm}
254object is attached to its parent item! In other words, component unknowns are not indexed in
255the map.
256\end{remark}
257
258This class provides only one constructor from a linear combination of forms:
259\vspace{.1cm}
260\begin{lstlisting}[]
261BilinearForm(const SuBilinearForm&);
262\end{lstlisting}
263\vspace{.2cm}
264and proposes some accessors and facilities:
265\vspace{.1cm}
266\begin{lstlisting}[]
267bool singleUnknown() const;
268bool isEmpty() const;
269SuBilinearForm& operator[](const uvPair&);             //protected
270const SuBilinearForm& operator[](const uvPair&) const; //protected
271const SuBilinearForm& first() const;
272BilinearForm operator()(const Unknown&,const Unknown&) const;
273BasicBilinearForm& operator()(const Unknown&,const Unknown&,number_t);
274const BasicBilinearForm& operator()(const Unknown&,const Unknown&,number_t) const;
275\end{lstlisting}
276\vspace{.2cm}
277Besides, there are two fundamental external enduser's function (\verb?intg? and \verb?intg_intg?)
278which constructs {\class BilinearForm} object:
279\vspace{.1cm}
280\begin{lstlisting}
281BilinearForm intg(const GeomDomain&,const OperatorOnUnknown&,
282                  AlgebraicOperator,const OperatorOnUnknown&);
283BilinearForm intg(const GeomDomain&,const OperatorOnUnknowns&);
284BilinearForm intg(const GeomDomain&,const GeomDomain&,
285                       const OperatorOnUnknown&,AlgebraicOperator,
286                       const OperatorOnUnknown&);
287BilinearForm intg(const GeomDomain&,const GeomDomain&,const OperatorOnUnknowns&);
288\end{lstlisting}
289\vspace{.1cm}
290{\class OperatorUnknows} is a simple class used to store the two operators and the algebraic
291operation.\\
292
293In order to construct any linear forms, the algebraic operators (\verb?+= -= *= /= + - * /?)
294are oveloaded for different objects:
295\vspace{.1cm}
296\begin{lstlisting}[]
297BilinearForm& BilinearForm::operator +=(const BilinearForm&);
298BilinearForm& BilinearForm::operator -=(const BilinearForm&);
299BilinearForm& BilinearForm::operator *=(const complex_t&);
300BilinearForm& BilinearForm::operator /=(const complex_t&);
301BilinearForm operator+(const BilinearForm&,const BilinearForm&);
302BilinearForm operator-(const BilinearForm&,const BilinearForm&);
303BilinearForm operator*(const complex_t&,const BilinearForm&);
304BilinearForm operator*(const BilinearForm&,const complex_t&);
305BilinearForm operator/(const BilinearForm&,const complex_t&);
306\end{lstlisting}
307\vspace{.2cm}
308Finally, the class provides usual print facilities:
309\vspace{.1cm}
310\begin{lstlisting}[]
311void BilinearForm::print(std::ostream&)const;
312std::ostream& operator<<(std::ostream&,const BilinearForm&);
313\end{lstlisting}
314\vspace{.2cm}
315
316\subsection*{Example}
317
318To end we show some characteristic examples. In these examples, \verb?u?,\verb?v?  are scalar
319unknowns, \verb?p?, \verb?q?  are vector unknowns, \verb?f? either a scalar or a scalar function,
320\verb?h? either a vector or a vector  function, \verb?g? a scalar or a scalar kernel and \verb?Omega?,\verb?Gamma?
321\verb?Sigma? some geometric domains.
322\vspace{.1cm}
323\begin{lstlisting}[]
324BilinearForm a1=intg(Omega,grad(u)|grad(v));
325a1-=k2*intg(Omega,f*u*v);
326a1=intg(Omega,grad(u)|grad(v))-intg(Omega,f*u*v);   //same result
327BilinearForm a2=intg(Omega,div(p)*q)+eps*intg(Omega,p*q);
328BilinearForm a3=a1+a2;
329a3=intg(Omega,grad(u)|grad(v))+intg(Omega,div(p)*q) //same result
330  -intg(Omega,f*u*v)+eps*intg(Gamma,p*q);
331\end{lstlisting}
332\vspace{.2cm}
333
334\displayInfos{library=form, header=BilinearForm.hpp, implementation=BilinearForm.cpp, test=test\_form.cpp,
335header dep={config.h, utils.h}}
336
337