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{Linear forms}
18
19Linear forms are managed using
20\begin{itemize}
21\item {\class BasicLinearForm} abstract class of basic linear form,
22\item {\class IntgLinearForm} class inheriting from {\class BasicLinearForm} and dealing with
23integral form,
24\item {\class DoubleIntgLinearForm} class inheriting from {\class BasicLinearForm} and dealing
25with double integral forms,
26\item {\class SuLinearForm} class storing linear combination of {\class  BasicLinearForm} objects
27having the same unknown,
28\item {\class LinearForm} class storing a list of {\class SuLinearForm} objects using a map
29indexed by unknown.
30\end{itemize}
31
32\subsection{{The \classtitle BasicLinearForm} class}
33
34The {\class BasicLinearForm} class is an abstract class having only an unknown as attribute
35and its associated accessor:
36\vspace{.1cm}
37\begin{lstlisting}
38class BasicLinearForm
39{protected:
40   const Unknown* u_p;           //pointer to unknown
41 public :
42   const Unknown& up() const     //return the unknown
43\end{lstlisting}
44\vspace{.2cm}
45The child classes inheriting from {\class BasicLinearForm} have to provide the following member
46functions:
47\vspace{.1cm}
48\begin{lstlisting}[]
49virtual ~BasicLinearForm(){};              //virtual destructor
50virtual BasicLinearForm* clone() const =0; //clone of the linear form
51virtual LinearFormType type() const =0;    //return the type of the linear form
52virtual ValueType valueType() const=0;     //return the value type of the linear form
53virtual void print(std::ostream&) const =0;//print utility
54\end{lstlisting}
55\vspace{.1cm}
56The virtual {\cmd clone} function is used to construct a copy of the child objects from parent.
57
58\subsection{{The \classtitle IntgLinearForm} class}
59
60The {\class IntgLinearForm} class handles linear forms defined by a (single) integral over
61a geometric domain:
62$$\int_{D} {\cal L}(u)$$
63where $D$ is a geometric domain ({\class Domain} class) and ${\cal L}$ a linear operator ({\class
64OperatorOnUnknown} class) acting on unknown $u$ ({\class Unknownn} class).\\
65This class is defined as follows:
66\vspace{.1cm}
67\begin{lstlisting}
68class IntgLinearForm : public BasicLinearForm
69{protected :
70 const GeomDomain* domain_p; //geometric domain of the integral (pointer)
71 const OperatorOnUnknown* opu_p; //operator on unknown (pointer)
72\end{lstlisting}
73\vspace{.2cm}
74It has some public constructors and some public accessors:
75\vspace{.1cm}
76\begin{lstlisting}[]
77IntgLinearForm(const GeomDomain&,const OperatorOnUnknown&);
78const OperatorOnUnknown* opu() const;
79const GeomDomain* domain() const;
80virtual BasicLinearForm* clone() const;
81virtual LinearFormType type() const
82virtual ValueType valueType() const
83virtual void print(std::ostream&) const;
84\end{lstlisting}
85\vspace{.2cm}
86
87\subsection{{The \classtitle DoubleIntgLinearForm} class}
88
89The {\class DoubleIntgLinearForm} class handles linear forms defined by a double integral over
90a product of geometric domains:
91$$\int_{D_x}\int_{D_y} {\cal L}(u)$$
92where $D_x$, $D_y$ are geometric domain ({\class GeomDomain} class) and ${\cal L}$ a linear operator
93({\class OperatorOnUnknown} class) acting on unknown $u$ ({\class Unknown} class).\\
94Except, there are two geometric domains, this class is very similar to the {\class IntgLinearForm}
95class:
96\vspace{.1cm}
97\begin{lstlisting}
98class DoubleIntgLinearForm : public BasicLinearForm
99{protected :
100 const OperatorOnUnknown* opu_p;  // operator on unknown (pointer)
101 const GeomDomain* domainx_p; // first geometric domain (say x variable)
102 const GeomDomain* domainy_p; // second geometric domain (say y variable)
103\end{lstlisting}
104\vspace{.2cm}
105It provides some public constructors and some public accessors:
106\vspace{.1cm}
107\begin{lstlisting}[]
108DoubleIntgLinearForm(const GeomDomain&, const GeomDomain&,const OperatorOnUnknown&);
109const OperatorOnUnknown* opu() const;
110const GeomDomain* domainx() const;
111const GeomDomain* domainy() const;
112virtual BasicLinearForm* clone() const;
113virtual LinearFormType type() const;
114virtual ValueType valueType() const;
115virtual void print(std::ostream&)const;
116\end{lstlisting}
117\vspace{.2cm}
118
119\subsection{{The \classtitle SuLinearForm} class}
120
121{\class BasicLinearForm} objects may be lineary combined to produce a linear combination of
122{\class BasicLinearForm} objects stored as a list of pair of {\class BasicLinearForm} object
123and a complex scalar in the {\class SuLinearForm} class.
124\vspace{.1cm}
125\begin{lstlisting}
126typedef std::pair<BasicLinearForm*,complex_t> lfPair;
127class SuLinearForm
128{protected:
129   std::vector<lfPair> lfs_; //list of pairs of basic linear form and coefficient
130   ...
131\end{lstlisting}
132\vspace{.1cm}
133All the{\class BasicLinearForm} objects must have the same unknown ! It is the reason why this
134class has no pointer to an unknown; it refers to the first basic linear form to get its unknown.\\
135
136Because {\class BasicLinearForm} objects are copied for safety reason, this class provides
137default and basic constructors but also a copy constructor, a destructor and the overload assignment
138operator:
139\vspace{.1cm}
140\begin{lstlisting}
141SuLinearForm(){};
142SuLinearForm(const SuLinearForm&);
143~SuLinearForm();
144SuLinearForm& operator=(const SuLinearForm&);
145\end{lstlisting}
146\vspace{.2cm}
147It provides few accessors (some being const and no const):
148\vspace{.1cm}
149\begin{lstlisting}[]
150number_t size() const;
151std::vector<lfPair>& lfs();
152const std::vector<lfPair>& lfs() const;
153lfPair& operator()(number_t n);
154const lfPair& operator()(number_t n) const;
155const Unknown* unknown() const;
156const Space* space() const;
157LinearFormType type() const;
158ValueType valueType() const;
159\end{lstlisting}
160\vspace{.2cm}
161It is possible to perform linear combination of linear combinations using the following overloaded
162operators:
163\vspace{.1cm}
164\begin{lstlisting}[]
165SuLinearForm& SuLinearForm::operator +=(const SuLinearForm&);
166SuLinearForm& SuLinearForm::operator -=(const SuLinearForm&);
167SuLinearForm& SuLinearForm::operator *=(const complex_t&);
168SuLinearForm& SuLinearForm::operator /=(const complex_t&);
169SuLinearForm operator-(const SuLinearForm&);
170SuLinearForm operator+(const SuLinearForm&,const SuLinearForm&);
171SuLinearForm operator-(const SuLinearForm&,const SuLinearForm&);
172SuLinearForm operator*(const complex_t&,const SuLinearForm&);
173SuLinearForm operator*(const SuLinearForm&,const complex_t&);
174SuLinearForm operator/(const SuLinearForm&,const complex_t&);
175bool SuLinearForm::checkConsistancy(const SuLinearForm&) const;
176\end{lstlisting}
177\vspace{.1cm}
178The member function {\cmd checkConsistancy} performs a test to insure that unknown is always
179the same.\\
180
181Finally, there are some print facilities:
182\vspace{.1cm}
183\begin{lstlisting}[]
184void SuLinearForm::print(std::ostream&)const;
185std::ostream& operator<<(std::ostream&,const SuLinearForm&);
186\end{lstlisting}
187
188\subsection{{The \classtitle LinearForm} class}
189
190The {\class LinearForm} class is the end user class dealing with general linear form, either
191a single unknown linear form (a {\class SuLinearForm} object) or a multiple unknown linear
192form (a list of {\class SuLinearForm} objects). In this class, a single unknown linear form
193is a multiple unknown linear form with one unknown! The list of {\class SuLinearForm} objects
194is stored in a map of {\class SuLinearForm}, indexed by the pointer to {\class SuLinearForm}
195unknown:
196\vspace{.1cm}
197\begin{lstlisting}[deletekeywords={[3] map}]
198class LinearForm
199{protected :
200 std::map<const Unknown *,SuLinearForm> mlclf_;  //list of linear combinations of basic forms
201 ...
202\end{lstlisting}
203\vspace{.2cm}
204To manage the map, the following aliases are defined:
205\vspace{.1cm}
206\begin{lstlisting}[deletekeywords={[3] map}]
207typedef std::map<const Unknown *,SuLinearForm>::iterator it_mulc;
208typedef std::map<const Unknown *,SuLinearForm>::const_iterator cit_mulc;
209\end{lstlisting}
210\vspace{.1cm}
211\begin{remark}
212When the {\class SuLinearForm} unknown is an unknown component, the {\class SuLinearForm} object
213is attached to its parent item! In other words, a component unknown is not indexed in the map.
214\end{remark}
215
216This class provides only one constructor from a linear combination of forms:
217\vspace{.1cm}
218\begin{lstlisting}[]
219LinearForm(const SuLinearForm&);
220\end{lstlisting}
221\vspace{.2cm}
222and proposes some accessors and facilities:
223\vspace{.1cm}
224\begin{lstlisting}[]
225bool isEmpty() const;
226bool singleUnknown() const;
227SuLinearForm& operator[](const Unknown*);            //protected
228const SuLinearForm& operator[](const Unknown*) const;//protected
229const SuLinearForm& first() const;
230LinearForm operator()(const Unknown&) const;
231BasicLinearForm& operator()(const Unknown&,number_t);
232const BasicLinearForm& operator()(const Unknown&,number_t) const;
233\end{lstlisting}
234\vspace{.2cm}
235Besides, there are two fundamental external end user's function ({\cmd intg})
236which constructs {\class LinearForm} object:
237\vspace{.1cm}
238\begin{lstlisting}[]
239LinearForm intg(const GeomDomain&,const OperatorOnUnknown&);
240LinearForm intg(const GeomDomain&,const Unknown&);
241LinearForm intg(const GeomDomain&,const GeomDomain&,const OperatorOnUnknown&);
242LinearForm intg(const GeomDomain&,const GeomDomain&,const Unknown&);
243\end{lstlisting}
244\vspace{.2cm}
245In order to construct any linear forms, the algebraic operators (\verb?+= -= *= /= + - * /?)
246are oveloaded for different objects:
247\vspace{.1cm}
248\begin{lstlisting}[]
249LinearForm& LinearForm::operator +=(const LinearForm&);
250LinearForm& LinearForm::operator -=(const LinearForm&);
251LinearForm& LinearForm::operator *=(const complex_t&);
252LinearForm& LinearForm::operator /=(const complex_t&);
253LinearForm operator+(const LinearForm&,const LinearForm&);
254LinearForm operator-(const LinearForm&,const LinearForm&);
255LinearForm operator*(const complex_t&,const LinearForm&);
256LinearForm operator*(const LinearForm&,const complex_t&);
257LinearForm operator/(const LinearForm&,const complex_t&);
258\end{lstlisting}
259\vspace{.2cm}
260Finally, the class provides usual print facilities:
261\vspace{.1cm}
262\begin{lstlisting}[]
263void LinearForm::print(std::ostream&)const;
264std::ostream& operator<<(std::ostream&,const LinearForm&);
265\end{lstlisting}
266\vspace{.2cm}
267
268\subsection*{Example}
269
270To end we show some characteristic examples. In these examples, \verb?u? is a scalar unknown,
271\verb?w? is a vector unknown, \verb?f? either a scalar or a scalar function, \verb?h? either
272a vector or a vector  function, \verb?g? a scalar or a scalar kernel and \verb?Omega?,\verb?Gamma?
273\verb?Sigma? some geometric domains.
274\vspace{.1cm}
275\begin{lstlisting}[]
276LinearForm l1=intg(Omega,f*u);
277l1+=intg(Omega,h|grad(u));
278l1=intg(Omega,f*u)+intg(Omega,h|grad(u));  //equivalent
279l1=l1-2*intg(Gamma,Sigma,g*u);
280LinearForm l2=intg(Omega,f*div(w))+intg(Gamma,h|(w^n));
281LinearForm l3=l1+l2;     //multiple unknowns
282l3=intg(Omega,f*u)+intg(Omega,f*div(w))+intg(Omega,h|grad(u))
283  +2*intg(Gamma,Sigma,g*u)+intg(Gamma,h|(w^n));  //same result
284\end{lstlisting}
285\vspace{.2cm}
286
287\displayInfos{library=form, header=LinearForm.hpp, implementation=LinearForm.cpp, test=test\_form.cpp,
288header dep={config.h, utils.h}}
289
290