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 TermVector} class}
18
19The {\class TermVector} class carries numerical representation of a linear form and more generally any vector attached to an approximation space:
20\vspace{.1cm}
21\begin{lstlisting}[deletekeywords={[3] map}]
22class TermVector : public Term
23{
24 protected :
25 LinearForm linForm_;
26 map<const Unknown*, SuTermVector*> suTerms_;
27 VectorEntry* entries_p;
28 VectorEntry* scalar_entries_p;
29 vector<DofComponent> cdofs_;
30\end{lstlisting}
31\vspace{.3cm}
32The linear form is a multiple unknowns form, may be reduced to a single unknown form (see {\lib form} library).
33This linear form is void if {\class TermVector} is not explicitly construct from a linear form (linear combination, nodal construction).
34The map \emph{suTerms\_} carries each vector block related to an unknown.
35When there is only one element in map, it means that the {\class TermVector} is actually a single unknown term vector.
36The \emph{scalar\_entries\_p} pointer may be allocated to concatenate the block vectors. When unknowns are vector unknowns,
37the representation may be not suited in certain cases (direct solver), so it is possible to create its scalar representation
38using the \emph{scalar\_entries\_p} ({\class VectorEntry} pointer).
39The {\class VectorEntry} object created has to be of real scalar or complex scalar type. In that case, a non block row numbering consisting in vector of {\class DofComponent} (Unknown pointer, dof number, component number) is also defined (\emph{cdofs\_}).\\
40
41The {\class TermVector} class provides useful constructors and assign operators designed for end users :
42\vspace{.1cm}
43\begin{lstlisting}[]{}
44//default constructor
45TermVector(const String& na = "", bool noass = false);
46
47//from linear form with options and no essential conditions
48TermVector(const LinearForm&, const string_t& na="");
49TermVector(const LinearForm&, TermOption, const string_t& na="");
50TermVector(const LinearForm&, TermOption, TermOption, const string_t& na="");
51TermVector(const LinearForm&, TermOption, TermOption, TermOption,
52           const string_t& na="");
53
54//from linear form with options and one essential condition
55TermVector(const LinearForm&, const EssentialConditions&,
56           const string_t& na="");
57TermVector(const LinearForm&, const EssentialConditions&, TermOption,
58           const string_t& na="");
59TermVector(const LinearForm&, const EssentialConditions&, TermOption,
60           TermOption, const string_t& na="");
61TermVector(const LinearForm&, const EssentialConditions&, TermOption,
62           TermOption, TermOption, const string_t& na="");
63
64void build(const LinearForm &, const EssentialConditions*,
65           const vector<TermOption>&, const string_t&);
66
67//from value or function (interpolation)
68template <typename T>
69  TermVector(const Unknown&, const Domain&, const T&, const String& na = "");
70
71//copy like
72TermVector(const TermVector&, const String& na = "");
73template <typename T>
74  TermVector(const TermVector&, const T&, const String& na);
75TermVector(const SuTermVector &, const String& na="");
76TermVector(SuTermVector *, const String& na="");
77void copy(const TermVector&, const String &);
78
79//constructor from explicit function of TermVector's
80TermVector(const TermVector&, funSR1_t& f, const string_t& na="");
81TermVector(const TermVector&, TermVector&, funSR2_t& f, const string_t& na="");
82TermVector(const TermVector&, funSC1_t& f, const string_t& na="");
83TermVector(const TermVector&, TermVector&, funSC2_t& f, const string_t& na="");  single unknown
84
85//constructor from symbolic function of TermVector's
86TermVector(const TermVector&, const SymbolicFunction& , const string_t& na="");
87TermVector(const TermVector&, const TermVector&, const SymbolicFunction& fs,
88const string_t& na="");
89TermVector(const TermVector&, const TermVector&, const TermVector&,
90const SymbolicFunction& fs, const string_t& na="");
91
92//constructor of a vector TermVector from scalar TermVector's (single unknown, same space)
93TermVector(const Unknown&, const TermVector&, const TermVector&, const string_t& ="");
94TermVector(const Unknown&, const TermVector&, const TermVector&, const TermVector&, const string_t& ="");
95TermVector(const Unknown&, const TermVector&, const TermVector&, const TermVector&, const TermVector&, const string_t& ="");
96
97//from linear combination
98TermVector(const LcTerm&);
99//assignment
100TermVector& operator=(const TermVector&);
101TermVector& operator=(const LcTerm&);
102//insert SuTermVector in TermVector
103void insert(const SuTermVector &);
104void insert(SuTermVector *);
105void insert(const Unknown*, SuTermVector*);
106//destructor, clear
107virtual ~TermVector();
108void clear();
109\end{lstlisting}
110\vspace{.3cm}
111
112When TermVector is constructed from linear form, it is automatically computed except if it has set to be not computed using a the {\class TermOption} \textit{\_notCompute} in its construction.\\ {\class TermOption}s are managed as an enumeration :
113\begin{lstlisting}[]{}
114enum TermOption
115{
116 //general
117 _compute,                 //default behaviour
118 _notCompute,
119 _assembled,               //default behaviour
120 _unassembled,             //not yet available
121 //only for TermMatrix
122 _nonSymmetricMatrix,      //to force symmetry property
123 _symmetricMatrix,
124 _selfAdjointMatrix,
125 _skewSymmetricMatrix,
126 _skewAdjointMatrix,
127 _csRowStorage,            //to force storage
128 _csColStorage,
129 _csDualStorage,
130 _csSymStorage,
131 _denseRowStorage,
132 _denseColStorage,
133 _denseDualStorage,
134 _skylineSymStorage,
135 _skylineDualStorage,
136 _pseudoReduction,         //default behaviour
137 _realReduction,           //not yet available
138 _penalizationReduction    //not yet available
139};
140\end{lstlisting}
141
142Constructors involving {\class SuTermVector} class are reserved to developers. End users should not have to acces to {\class SuTermVector} class, but we decide to let this access free to advanced users. Constructors involving {\class LcTerm} class are implicitly used by users when they write combination of terms in a symbolic way (see {\class LcTerm} class).\\
143The class provides some useful accessors (for users or developers):
144\vspace{.1cm}
145\begin{lstlisting}[]{}
146//user accessors
147const LinearForm& linearForm() const;
148Number nbOfUnknowns() cons;
149bool isSingleUnknown() const;
150set<const Unknown*> unknowns() const;
151ValueType valueType() const;
152Number size() const;
153Number nbDofs() const;
154Number nbDofs(const Unknown&) const;
155const vector<DofComponent>& cdofs() const;
156vector<DofComponent>& cdofs(;
157const Dof& dof(const Unknown&, Number ) const;
158
159//developer accessors
160cit_mustv begin() const;
161it_mustv begin();
162cit_mustv end() const;
163it_mustv end();
164SuTermVector* firstSut() const;
165SuTermVector* firstSut();
166const Unknown* unknown() const;
167VectorEntry*& entries();
168const VectorEntry* entries() const;
169VectorEntry*& scalar_entries();
170const VectorEntry* scalar_entries() const;
171VectorEntry* actual_entries() const;
172\end{lstlisting}
173\vspace{.3cm}
174\emph{it\_mustv} and \emph{cit\_mustv} are iterator aliases:\vspace{.1cm}
175\begin{lstlisting}[deletekeywords={[3] map}]
176typedef map<const Unknown*, SuTermVector*>::iterator it_mustv;
177typedef map<const Unknown*, SuTermVector*>::const_iterator cit_mustv;
178\end{lstlisting}
179\vspace{.3cm}
180Access to a block of {\class TermVector} say a {\class SuTermVector} is proposed in two ways : either using {\cmd subVector} functions returning reference or pointer to {\class SuTermVector} objects or  using {\cmd operator()} returning a new {\class TermVector} object, the {\class SuTermVector} object being copied. This last method is adressed to end users. For particular purpose, is is also possible to reinterpret a {\class TermVector} as a raw vector or a raw vector of vectors (say a {\class Vector<S>} or a {\class Vector<Vector<S> >} with S a Real or a Complex). \\
181\vspace{.1cm}
182\begin{lstlisting}[]{}
183const SuTermVector& subVector() const;
184SuTermVector& subVector(const Unknown*);
185const SuTermVector& subVector(const Unknown*) const;
186SuTermVector& subVector(const Unknown&);
187const SuTermVector& subVector(const Unknown&) const;
188SuTermVector* subVector_p(const Unknown*);
189const SuTermVector* subVector_p(const Unknown*) const;
190TermVector operator()(const Unknown&) const; //user usage
191template<typename T>
192  Vector<T>& asVector(Vector<T>&) const;
193\end{lstlisting}
194\vspace{.3cm}
195The main computing operations are related to the construction of {\class TermVector} from linear form and construction from linear combination {\class TermVector}:
196\vspace{.1cm}
197\begin{lstlisting}[]{}
198void compute();
199void compute(const LcTerm&);   //implicit
200TermVector& operator+=(const TermVector&);
201TermVector& operator-=(const TermVector&);
202template<typename T>
203 TermVector& operator*=(const T&);
204template<typename T>
205 TermVector& operator/=(const T&);
206\end{lstlisting}
207\vspace{.2cm}
208Note that the evaluation of {\class TermVector} defined by a value or a function is done during creation of {\class TermVector}. The algebraic operators +=, -=, *=, /= do the computation, it is not delayed as it is the case for +,-,* and / operators. The linear combination is based on {\class LcTerm} class which manages a list of pairs of {\class Term} and coefficient. Algebraic operators on {\class TermVector}'s produce {\class LcTerm} object carrying the linear combination that will be computed by {\class TermVector} constructor or assignment operator:
209\vspace{.1cm}
210\begin{lstlisting}[]{}
211const TermVector& operator+(const TermVector&);
212LcTerm operator-(const TermVector&);
213LcTerm operator+(const TermVector&, const TermVector&);
214LcTerm operator-(const TermVector&, const TermVector&);
215LcTerm operator+(const LcTerm&, const TermVector&);
216LcTerm operator-(const LcTerm&, const TermVector&);
217LcTerm operator+(const TermVector&, const LcTerm&);
218LcTerm operator-(const TermVector&, const LcTerm&);
219template<typename T>
220 LcTerm operator*(const TermVector&, const T&);
221template<typename T>
222 LcTerm operator*(const T&, const TermVector& )
223template<typename T>
224 LcTerm operator/(const TermVector&, const T&)
225\end{lstlisting}
226\vspace{.3cm}
227
228To manage different representation of {\class TermVector}, the following function are provided :
229\vspace{.1cm}
230\begin{lstlisting}[]{}
231void toScalar(bool keepEntries=false);
232void toVector(bool keepEntries=false);
233void toGlobal(bool keepSuTerms=false);
234void toLocal(bool keepGlobal=false);
235void adjustScalarEntries(const vector<DofComponent>&);
236\end{lstlisting}
237\vspace{.3cm}
238Note the difference between \emph{toScalar} and \emph{toGlobal}. \emph{toScalar} forces the scalar representation of {\class SuTermVector}'s and \emph{toGlobal} go to non block representation, allocating the \emph{scalar\_entries\_p} pointer of {\class TermVector}. \emph{toGlobal} operation induces  \emph{toScalar} operation. \emph{toLocal} reconstructs block representation from global representation (inverse of \emph{toGlobal}) and \emph{toVector} returns to vector representation (inverse of \emph{toScalar}).\\
239
240{ \renewcommand{\arraystretch}{2}
241$$
242 \begin{array}{cccc}
243 \begin{array}{c}
244 \text{\small SuTermVector} \\ [-5mm] \text{\small entries\_p}
245 \end{array}
246 &\begin{array}{|c|}
247   \hline
248   \begin{array}{|c|} \hline \vdots \\ \hline \end{array} \\
249   \begin{array}{c}  \vdots  \end{array} \\
250   \begin{array}{|c|} \hline \vdots \\  \hline \end{array}\\ [2mm]
251  \hline
252 \end{array}
253 &\begin{array}{c}
254      \text{\small SuTermVector} \\ [-5mm] \text{\small scalar\_entries\_p}
255   \end{array}
256 &\begin{array}{|c|}
257          \hline
258          \begin{array}{c} \vdots \\ \end{array} \\
259          \begin{array}{c} \vdots  \end{array} \\
260          \begin{array}{c} \vdots \\  \end{array} \\ [2mm]
261          \hline
262        \end{array}\\
263
264 & & \stackrel{toScalar}{\Longrightarrow} & \\
265
266  \begin{array}{c}
267  \text{\small SuTermVector} \\ [-5mm] \text{\small entries\_p}
268  \end{array}
269   &\begin{array}{|c|}
270     \hline
271     \begin{array}{|c|} \hline \vdots \\ \hline \end{array} \\
272     \begin{array}{c} \vdots  \end{array} \\
273     \begin{array}{|c|} \hline \vdots \\ \hline \end{array} \\ [2mm]
274     \hline
275   \end{array}
276   &\begin{array}{c}
277     \text{\small SuTermVector} \\ [-5mm] \text{\small scalar\_entries\_p}
278   \end{array}
279   &\begin{array}{|c|}
280         \hline
281         \begin{array}{c} \vdots \\ \end{array} \\
282         \begin{array}{c} \vdots  \end{array} \\
283         \begin{array}{c} \vdots \\  \end{array} \\ [2mm]
284         \hline
285       \end{array}\\
286\end{array}
287\ \ \ \ \ \stackrel{toGlobal}{\Longrightarrow} \ \ \ \ \ \ \\
288 \begin{array}{|c|} \hline \vdots \  \\ \vdots \\ \vdots \\ \vdots \\ \vdots \\ \vdots \\ \vdots \\ \vdots \\ \hline \end{array} \\
289 \begin{array}{c}
290  \text{\small TermVector} \\[-5mm] \text{\small scalar\_entries\_p}
291  \end{array}
292$$
293}
294
295In some circonstances, to avoid recomputation, it may be usefull to change the unknowns of a {\class TermVector} without changing its content, with an optional management of components of unknown:
296\vspace{.1cm}
297\begin{lstlisting}[]{}
298void changeUnknown(const Unknown&, const Unknown&,
299                   const Vector<Number>& = Vector<Number>());
300void changeUnknown(const Unknown&,
301                   const Vector<Number>& = Vector<Number>());
302void changeUnknown(const Unknown&, Number);          //shortcut
303void changeUnknown(const Unknown&, Number, Number);  //shortcut
304void changeUnknown(const Unknown&, Number, Number, Number); //shortcut
305\end{lstlisting}
306\vspace{.2cm}
307The principle of {\cmd changeUnknown} functions is the following :
308\begin{itemize}
309\item when two unknows (u,v) are specified, the unknown u is replaced by the unknown v and the reference to unknown u does no longer exists in {\class TermVector}
310\item when a renumbering components vector (rc) is given too, components are re-settled along this vector
311\item when v is not specified, only components are re-settled
312\end{itemize}
313Here are some exemples :
314 \begin{itemize}
315 \item u a scalar unknown, v a scalar unknown, replace unknown u by unknown v
316 \item u a scalar unknown, v a 3-vector unknown, rc=[2] leads to sutv = [0 sutv 0]
317 \item u a 4-vector unknown, v a 2-vector unknown, rc=[2,4] leads to sutv = [0 sutv1 0 sutv2]
318 \item u a 3-vector unknown, rc=[3,0,1], re-settle components as [sutu3 0 sutu1]
319 \end{itemize}
320 \begin{remark}
321 Be cautious that there is no check of the space consistancy! So use it with care.
322 \end{remark}\\
323
324It is possible to adress values of a {\class TermVector} by unknown and index, to get it or to set it:
325\vspace{.1cm}
326\begin{lstlisting}[]{}
327Value getValue(const Unknown&, Number) const;
328void setValue(const Unknown&, Number, const Value&);
329void setValue(const Unknown&, Number, const Real&);
330void setValue(const Unknown&, Number, const Complex&);
331void setValue(const Unknown&, Number, const vector<Real>&);
332void setValue(const Unknown&, Number, const vector<Complex>&);
333\end{lstlisting}
334\vspace{.2cm}
335The {\class Value} class handles different type of values, in particular {\cmd Real} and {\cmd Complex} values.\\
336
337It is also possible to change some values of a {\class TermVector} by specifying the unknown that it is concerned, the geometrical part where values will be changed and the values that can be given either by a constant, a function or a {\class TermVector}:
338\vspace{.1cm}
339\begin{lstlisting}[]{}
340template <typename T>
341void setValue(const Unknown&, const GeomDomain&, const T&);
342void setValue(const Unknown&, const GeomDomain&, const TermVector&;
343void setValue(const Unknown&, const TermVector&);
344\end{lstlisting}
345\vspace{.2cm}
346In all {\cmd setValue} functions, the unknown may be omitted. In that case, the first unknown is assumed.\\
347
348Most powerful functions are functions that can evaluate any function of approximation space ($V_h$) (representing by a {\class TermVector} U) at any point, using space interpolation :
349$$
350u_h(x)=\sum_{i=1,n} U_{u,i}w_i(x)
351$$
352where $U_{u,i}$ is the $i^{th}$ components related to the unknown $u$ of {\class TermVector} $U$ and $(w_i)_{i=1,n}$ the basis functions of approximation space $V_h$.
353\vspace{.1cm}
354\begin{lstlisting}[]{}
355Value evaluate(const Unknown&, const Point&) const;
356template<typename T>
357 T& operator()(const vector<Real>&, T&) const;
358template<typename T>
359 T& operator()(const Unknown&, const vector<Real>&, T&) const;
360\end{lstlisting}
361\vspace{.2cm}
362
363Some additional computational tools are available:
364\vspace{.1cm}
365\begin{lstlisting}[]{}
366TermVector& toAbs();
367TermVector& toReal();
368TermVector& toImag();
369TermVector& toComplex();
370TermVector& toConj();
371TermVector mapTo(const GeomDomain&, const Unknown&) const;
372TermVector onDomain(const GeomDomain&) const;
373Real norm2() const;
374Complex maxValAbs() const;
375\end{lstlisting}
376\vspace{.2cm}
377
378and the class proposes two  basic output functions:
379\vspace{.1cm}
380\begin{lstlisting}[]{}
381void print(ostream&) const;
382void saveToFile(const String&, bool encode=false) const;
383\end{lstlisting}
384\vspace{.2cm}
385
386Besides, some of the functionalities are also provides as extern functions:
387\vspace{.1cm}
388\begin{lstlisting}[]{}
389//linear combination
390const TermVector& operator+(const TermVector&);
391LcTerm operator-(const TermVector&);
392LcTerm operator+(const TermVector&, const TermVector&);
393LcTerm operator-(const TermVector&, const TermVector&);
394LcTerm operator+(const LcTerm&, const TermVector&);
395LcTerm operator-(const LcTerm&, const TermVector&);
396LcTerm operator+(const TermVector&, const LcTerm&);
397LcTerm operator-(const TermVector&, const LcTerm&);
398template<typename T>
399 LcTerm operator*(const TermVector&, const T&);
400template<typename T>
401 LcTerm operator*(const T&, const TermVector&);
402template<typename T>
403 LcTerm operator/(const TermVector&, const T&)
404
405//inner, hermitian product, norm, ...
406TermVector abs(const TermVector&);
407TermVector real(const TermVector&);
408TermVector imag(const TermVector&);
409TermVector conj(const TermVector&);
410Complex innerProduct(const TermVector&, const TermVector&);
411Complex hermitianProduct(const TermVector&, const TermVector&);
412Complex operator|(const TermVector&, const TermVector&);
413Real norm(const TermVector&, Number l=2);
414Real norm1(const TermVector&);
415Real norm2(const TermVector&);
416Real norminfty(const TermVector&);
417
418//output functions
419void print(ostream&) const;
420void saveToFile(const String&, bool encode=false) const;
421void saveToFile(const String&, const list<const TermVector*>&, IOFormat iof=_raw);
422void saveToFile(const String&, const TermVector&, IOFormat iof=_raw);
423void saveToFile(const String&, const TermVector&, const TermVector&,
424                IOFormat iof=_raw);
425void saveToFile(const String&, const TermVector&, const TermVector&,
426                const TermVector&, IOFormat iof=_raw);
427void saveToFile(const String&, const TermVector&, const TermVector&,
428                const TermVector&, const TermVector&, IOFormat iof=_raw);
429\end{lstlisting}
430\vspace{.2cm}
431Available export format are
432\begin{itemize}\addtolength{\itemsep}{-0.5\baselineskip}
433	\item \verb|_raw| : export only the values in a raw format
434	\item \verb|_vtk| : export mesh and values displayable with Paraview
435	\item \verb|_vtu| : export mesh and values displayable with Paraview
436	\item \verb|_matlab| : export mesh and values as an executable Matlab file
437	\item \verb|_xyzv|: export mesh nodes and values as x y z v1 v2 ...
438\end{itemize}
439Integral represention is a particular operation mixing numerical quadrature and interpolation :
440$$
441    u(x_i)=\int_{\Gamma} opk(K)(x_i,y)\, aop\, opu(p)(y)dy\ \ i=1,n.
442$$
443where  $K$ is a kernel, $opk$ an operator on kernel ({\class OperatorOnKernel}), $p$ a layer potential, $opu$ an operator on unknown ({\class OperatorOnUnknown}) and $aop$ an algebraic operator.
444\vspace{.1cm}
445\begin{lstlisting}[]{}
446template<typename T>
447Vector<T>& integralRepresentation(const vector<Point>& xs,
448           const LinearForm& lf, const TermVector& U, Vector<T>& val)
449TermVector integralRepresentation(const Unknown&, const GeomDomain&,
450           const LinearForm&, const TermVector&);
451\end{lstlisting}
452\vspace{.1cm}
453For instance,  the single layer integral representation on a list of points is computed as follows:
454\vspace{.1cm}
455\begin{lstlisting}[]{}
456Vector<Point>Points;
457...
458Vector<Real> val;
459integralRepresentation(Points,intg(gamma,G(_y) * u), U, val);
460\end{lstlisting}
461\vspace{.1cm}
462or if the list of points is the list of nodes of a domain:
463\vspace{.1cm}
464\begin{lstlisting}[]{}
465 TermVector IR=integralRepresentation(Omega,intg(gamma,G(_y) * u), U, val);
466 \end{lstlisting}
467\vspace{.3cm}
468For most of functions of TermVector, the algorithms travel the map of {\class SuTermVector}, calling {\class SuTermVector}'s functions. For instance, the compute function looks like:
469\vspace{.1cm}
470\begin{lstlisting}[]{}
471void TermVector::compute()
472{
473  for(it_mustv it = suTerms_.begin(); it != suTerms_.end(); it++)
474    {
475      if(!it->second->computed()) it->second->compute();
476    }
477  computed() = true;
478}
479\end{lstlisting}
480\vspace{.3cm}
481\displayInfos{
482library=term,
483header=TermVector.hpp,
484implementation=TermVector.cpp,
485test=test\_TermVector.cpp,
486header dep={SuTermVector.hpp, termUtils.hpp, Term.hpp, form.h, config.h, utils.h}
487}
488