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{Space management}
18
19\subsection{The {\classtitle Space} and {\classtitle SpaceInfo} classes}
20
21The {\class Space} class manages different kind of spaces using inherited classes: finite element
22space ({\class FeSpace}), spectral space ({\class SpSpace}), sub space (({\class SubSpace})
23and product space ({\class ProdSpace}). To avoid the user to deal explicitly with this space
24hierarchy, we use the following programming paradigm: {\class Space} class has a pointer
25to a Space as attribute, which contains either its own address or the address of a child. In
26a sense, the {\class Space} class is not an abstract class but has a the behaviour of an abstract
27one. When an end user declares a Space object, he induces the construction of a child Space.
28With this trick, an end user instantiates only {\class Space} object, never the child spaces.
29As a consequence, it requires a little more memory because member attributes are duplicated.
30In order to limit this effect, the common characteristics of a space are collected in the {\class
31SpaceInfo} class:
32\vspace{.1cm}
33\begin{lstlisting}[deletekeywords={[3] dimCom}]
34class SpaceInfo
35 {public :
36  String name_;                 // name of space
37  Domain * domain_p;            // geometric domain supporting the space
38  SobolevType spaceConforming_; // conforming space (L2,H1,Hdiv,Hcurl,H2,Hinf)
39  dimen_t dimFun_;              // number of components of the basis functions
40  Dimen dimCom;                 // number of components of the unknowns
41  SpaceType spaceType_;         // space type (FESpace,SPSpace,SubSpace,ProductSpace)
42  SpaceInfo(){};
43  SpaceInfo(const String &,SobolevType,Domain *,dimen_t , SpaceType)
44 };
45\end{lstlisting}
46\vspace{.2cm}
47The general characteristics of a space are the geometric domain supporting the basis functions,
48the space conformity which "tells" the regularity of the basis functions and the dimension
49of the basis functions. The space conformity property is a way to distinguish discontinuous
50finite element approximation from continuous one. The space conformity is given by the SobolevType
51enumeration declared in the \textit{config.hpp} header file:
52\vspace{.1cm}
53\begin{lstlisting}[]
54enum SobolevType {L2=0, L2=_L2,H1, H1=_H1,_Hdiv, Hdiv=_Hdiv,_Hcurl, Hcurl=_Hcurl,
55                  _Hrot=_Hcurl, Hrot=_Hrot,_H2, H2=_H2,_Hinf, Hinf=_Hinf}
56\end{lstlisting}
57\vspace{.1cm}
58To be user friendly, several names are available for the same space.\\
59
60The parent class {\class Space} has only two pointers and a static vector managing the list
61of all defined spaces:
62\vspace{.1cm}
63\begin{lstlisting}
64class Space
65{protected :
66  Space * space_p;                       //pointer to the "true" space (child)
67  SpaceInfo * spaceInfo_p;               //pointer to the space information structure
68public :
69  static std::vector<Space*> theSpaces;  //unique list of defined spaces
70\end{lstlisting}
71\vspace{.2cm}
72Regarding the type of spaces, the {\class Space} provides several constructors to construct child spaces:
73\vspace{.1cm}
74\begin{lstlisting}
75//constructors of trivial space of dim n, say Rn
76Space(number_t, const string_t& ="Rn");
77Space(const GeomDomain&, number_t, const string_t& ="Rn");
78
79//constructors addressing spectral space
80Space(const SpectralBasis&, const string_t&);  //from spectral basis
81Space(const GeomDomain&, const Function&, number_t, dimen_t, const string_t&);
82Space(const GeomDomain&, const Function&, number_t, dimen_t);
83Space(const GeomDomain&, const Function&, number_t, const string_t&);
84Space(const TermVectors&, const string_t&);   //from interpolated functions
85
86//constructors addressing FeSpace type from Interpolation or FE types
87Space(const GeomDomain&, const Interpolation&, const string_t&, bool opt = true);
88Space(const GeomDomain&, PolynomType, const string_t&, bool opt = true);
89Space(const GeomDomain&, QolynomType, const string_t&, bool opt = true);
90Space(const GeomDomain&, FeFaceType, const string_t&, bool opt = true);
91Space(const GeomDomain&, FeEdgeType, const string_t&, bool opt = true);
92
93//constructors addressing SubSpace type
94Space(const GeomDomain&, Space&, const string_t& na = "");
95Space(const GeomDomain&, const vector<number_t>&, Space&, const string_t& na = "");
96Space(const std::vector<number_t>&, Space&, const string_t& na = "");
97
98//tools related to construtors
99void buildSpFun(const GeomDomain&, const Function&, number_t,
100                dimen_t, const string_t&);
101SubSpace* createSubSpace(const GeomDomain&, Space&, const string_t& na);
102void createSubSpaces(const vector<const GeomDomain*>&,vector<Space*>&);
103Space* buildSubspaces(const vector<const GeomDomain*>&, vector<Space*>&);
104\end{lstlisting}
105\vspace{.1cm}
106These constructors work as follows (\textit{(child)Space} denotes any inherited space class):
107\vspace{.1cm}
108\begin{lstlisting}[]
109 (child)Space* csp_p=new (child)Space(...); //create the (child)Space
110 space_p=static_cast<Space *>(csp_p);       //cast (child)Space* to Space*
111 spaceInfo_p=csp_p->spaceInfo_p;            //copy the SpaceInfo pointer
112 theSpaces.push_back(this);                 //store space in list of spaces
113\end{lstlisting}
114\vspace{.1cm}
115Note that it is the child constructors that set all the attributes (general ones and specific
116ones).\\
117
118The {\class Space} class provides some accessors, some being virtual:
119\vspace{.1cm}
120\begin{lstlisting}[]
121string_t name() const;                //space name
122SobolevType conformingSpace() const;  //space conformity
123const GeomDomain* domain();           //related domain
124dimen_t dimDomain() const;            //dimension of related domain
125dimen_t dimPoint() const ;            //dimension of points
126dimen_t dimFun() const;               //dimension of basis functions
127SpaceType typeOfSpace() const;        //type of space
128SpaceType typeOfSubSpace() const;     //type of sub-space
129virtual bool isSpectral() const;      //true if spectral space
130virtual bool isFE() const;            //true if FE space or FeSubspace
131const Space* space() const;           //pointer to true space object
132virtual number_t dimSpace() const;    //space dimension
133virtual number_t nbDofs()const;       //number of dofs
134virtual const FeSpace* feSpace() const;      //pointer to child fespace
135virtual FeSpace* feSpace();                  //pointer to child fespace
136virtual const FeSubSpace* feSubSpace() const;//pointer to child fesubspace
137virtual const SpSpace* spSpace() const;      //pointer to child fesubspace
138virtual const SubSpace* subSpace() const;    //pointer to child subspace
139virtual SubSpace* subSpace();                //pointer to child subspace
140virtual const Space* rootSpace() const;      //pointer to root space
141virtual Space* rootSpace();                  //pointer to root space
142virtual ValueType valueType() const;         //value type of basis function
143virtual StrucType strucType() const;         //structure type of basis function
144virtual bool include(const Space*) const;    //inclusion test
145\end{lstlisting}
146\vspace{.1cm}
147To understand how works the non abstract/abstract class paradigm, here is the implementation
148of the access function \textit{feSpace}:
149\vspace{.1cm}
150\begin{lstlisting}[]
151FeSpace* Space::feSpace() const
152{if(space_p!=this) return space_p->feSpace();    //call the true feSpace
153 error("is_not_fespace",name());
154 return 0;
155}
156FeSpace* FeSpace::feSpace() const {return *this;}
157\end{lstlisting}
158\vspace{.1cm}
159The test \verb?space_p!=this? means that the current space is a user space (it has a child),
160the {\cmd fespace()} function is called by its child. By polymorphic behaviour, if \verb?space_p?
161is a {\class FeSpace} the {\cmd FeSpace::fespace()} is called else {\cmd Space::fespace()} is
162again called, but with \verb?space_p=this? and an error is thrown because the current space
163is not a {\class FeSpace}. \\
164
165As you will see in section \ref{s.dof}, the dof number is relative to the parent space. To get the global number of a dof or the dof itself and to manage dofs, Space provides the following functions :
166\vspace{0.1cm}
167\begin{lstlisting}[]
168virtual number_t dofId(number_t) const;        //n-th DoF id of space
169virtual std::vector<number_t> dofIds() const;  //DoF ids on space
170virtual const Dof& dof(number_t) const;        //n-th dof (n=1,...)
171virtual std::pair<number_t, number_t> renumberDofs();//optimize dofs numbering
172virtual void shiftDofs(number_t n);     //shift dofs numbering from n (SpSpace)
173\end{lstlisting}
174\vspace{0.2cm}
175When space is a FE space or a FE subspace, tools to access to finite element informations are provided:
176\vspace{0.1cm}
177\begin{lstlisting}[]
178virtual const Interpolation* interpolation() const;
179virtual number_t nbOfElements() const;
180virtual const Element* element_p(number_t k) const:
181virtual const Element* element_p(GeomElement* gelt) const;
182virtual number_t numElement(GeomElement* gelt) const;
183virtual vector<number_t> elementDofs(number_t k) const;
184virtual vector<number_t> elementParentDofs(number_t k) const;
185virtual const set<RefElement*>& refElements() const;
186virtual void buildgelt2elt() const;
187\end{lstlisting}
188\vspace{0.2cm}
189Finally, the {\class Space} provides some printing facilities:
190\vspace{.1cm}
191\begin{lstlisting}[]
192void printSpaceInfo(std::ostream &) const;
193virtual void print(std::ostream &) const;
194friend std::ostream& operator<<(std::ostream&,const Space &);
195\end{lstlisting}
196\vspace{.2cm}
197Some functions managing subspaces (comparison, merging) are also available:
198\begin{lstlisting}[]
199bool compareSpaceUsingSize(const Space*, const Space*);
200vector<number_t> renumber(const Space*, const Space*);
201Space& subSpace(Space&, const GeomDomain&);
202inline Space& operator |(Space&, const GeomDomain&);
203Space* mergeSubspaces(Space*&, Space*&, bool newSubspaces=false);
204Space* mergeSubspaces(std::vector<Space*>&, bool newSubspaces=false);
205Space* unionOf(std::vector<Space*>&);
206vector<Point> dofCoords(Space&, const GeomDomain&);
207\end{lstlisting}
208\vspace{.2cm}
209Linked to the {\class Space} class, the {\class DoF} class stores characteristics of degree
210of freedom. Degree of freedom is like a key index of components of element of space. Generally,
211it  handles a numeric index and carries some additionnal informations. From {\class DoF} class
212inherit the classes {\class FeDoF} and {\class SpDoF} (see section DoF).\\
213\displayInfos{library=space, header=Space.hpp, implementation=Space.cpp, test=test\_Space.cpp,
214header dep={config.h, geometry.h, Df.hpp}}
215
216Now, let's have a look at the child space classes.
217
218\subsection{The {\classtitle FeSpace} class}
219
220A finite elements space is defined is by a finite set of functions given by interpolated form on a mesh.
221The inherited {\class FeSpace} class is defined as follows :
222\vspace{.1cm}
223\begin{lstlisting}[deletekeywords={[3] elements}]
224class FeSpace : public Space
225{
226  protected :
227    const Interpolation* interpolation_p;    //!< pointer to finite element interpolation description
228    bool optimizedNumbering_;                //!< true if dof numbering is bandwidth optimized
229
230  public:
231    std::vector<Element> elements;           //!< list of finite elements
232    std::vector<FeDof> dofs;                 //!< list of global degrees of freedom
233
234    static Number lastEltIndex;              //!< to manage a unique index for elements
235};
236\end{lstlisting}
237\vspace{.1cm}
238This class provides one constructor, using two member functions:
239\vspace{.1cm}
240\begin{lstlisting}[]
241FeSpace(const Domain&, const Interpolation&, Dimen, const String&, bool opt=true);
242void buildElements();   //!< construct the list of elements
243void buildFeDofs();     //!< construct the list of FeDofs
244\end{lstlisting}
245\vspace{.1cm}
246The {\cmd buildElements()} member functions create the list of elements ({\class Element} objects) from the list of geometric elements belonging to the domain supporting the space. The {\cmd buildFeDofs()} function is the most important one. It constructs from reference dofs the list of global dofs using a general algorithm. It works as follows:
247\vspace{.1cm}
248$$
249\left|
250\begin{array}{l}
251\bullet \ \text{case of no shared dof (L2 conforming space), concatenate all local dofs and exit}\\
252\bullet \ \text{case of shared dofs  }\\
253 \ \ \ \ \bullet \ \text{construct a string index of dofs by traveling elements with the convention }\\
254  \ \ \ \ \ \ \  \text{"V i" for a dof on vertex i}\\
255  \ \ \ \ \ \ \  \text{"E i j l" for the l-th dof on edge [Vi, Vj], i<j, not a vertex dof}\\
256  \ \ \ \ \ \ \  \text{"F i j k l" for the l-th dof on face [Vi, Vj, Vk], i<j<k, not an edge dof}\\
257  \ \ \ \ \ \ \  \text{"N i l" for the l-th dof on element i (non shared dof)}\\
258 \ \ \ \ \bullet \ \text{construct the list of global dofs from this index and update elements}
259\end{array}
260\right.
261$$
262To insure the right matching between shared dofs on edge or face, this algorithm uses the {\cmd sideDofsMap} and {\cmd sideOfSideDofsMap} member functions of finite element classes. These functions relates dof numbering to one edge/face to an other edge/face.\\
263\vspace{.2cm}
264The {\class FeSpace} class provides also some specific accessors:
265\vspace{.1cm}
266\begin{lstlisting}[]
267virtual Number nbDofs() const; //!< number of dofs (a dof may be a vector dof)
268Dimen dimElements() const; //!< return the dimension of FE elements
269const Interpolation* interpolation() const; //!< return pointer to interpolation
270Number nbOfElements() const; //!< number of elements
271\end{lstlisting}
272\vspace{.1cm}
273The {\class FeSpace} class provides also some specific renumbering functions:
274\vspace{.1cm}
275\begin{lstlisting}[]
276Graph graphOfDofs(); //!< create dof connection graph
277const Element* element_p(Number k) const; //!< access to k-th (k>=0) element (pointer)
278std::vector<Number> elementDofs(Number k) const; //!< access to dofs ranks (local numbering) of k-th (>=0) element
279std::vector<Number> elementParentDofs(Number k) const; //!< access to dofs ranks (parent numbering, same as local) of k-th (>=0) element
280\end{lstlisting}
281\vspace{.1cm}
282\displayInfos{library=space, header=FeSpace.hpp, implementation=FeSpace.cpp, test=test\_Space.cpp,
283header dep={config.h, Elements.hpp, Space.hpp, dof.hpp, finiteElement.h}}
284
285
286\subsection{The {\classtitle SpSpace} class}
287
288A spectral space is defined by a finite set of functions given by analytic expression or by
289interpolated form. These global basis functions defined over a geometric domain are collected
290in the {\class SpectralBasis} class declared in the \textit{SpectralBasis.hpp} header file
291(see the section SpectralBasis). The inherited {\class SpSpace} class is defined as follows:
292\vspace{.1cm}
293\begin{lstlisting}
294class SpSpace : public Space
295{
296  protected :
297    SpectralBasis* spectralBasis_; //! object function encapsulating the spectral functions
298    //either defined in an analytical form or by interpolated functions (TermVector)
299  public :
300    std::vector<SpDof> dofs;       //! list of global degrees of freedom
301};
302\end{lstlisting}
303\vspace{.1cm}
304This class provides one constructor, a destructor, several accessors and a printing function:
305\vspace{.1cm}
306\begin{lstlisting}[]
307SpSpace(const String&, Domain&, number_t, dimen_t, SpectralBasis*);
308~SpSpace();
309SpectralBasis* spectralBasis() const;
310virtual Number nbDofs() const;     //!< number of dofs (a dof may be a vector dof)
311\end{lstlisting}
312\vspace{.1cm}
313
314\displayInfos{library=space, header=SpSpace.hpp, implementation=SpSpace.cpp, test=test\_Space.cpp,
315header dep={config.h, Elements.hpp, Space.hpp, dof.hpp}}
316
317
318\subsection{The {\classtitle SubSpace} and {\classtitle FeSubSpace} classes}
319
320A subspace is part of a space. Its dofs are a subset of the parent dofs. The inherited {\class SubSpace} class is defined as follows:
321\vspace{.1cm}
322\begin{lstlisting}
323class SubSpace : public Space
324{
325  protected :
326    Space* parent_p;                     //!< the parent space
327    std::vector<Number> dofNumbers_; //!< global numbers of D.o.Fs in parent D.o.Fs numbering
328};
329\end{lstlisting}
330\vspace{.1cm}
331This class provides two constructor, a destructor, and several specific accessors about the {\tt dofNumbers\_} attribute or about the type of subspace :
332\vspace{.1cm}
333\begin{lstlisting}[]
334SubSpace()                                                //!< default constructor
335SubSpace(const Domain&, Space&, const String& na = ""); //!< constructor specifying geom domain, parent space and name
336~SubSpace();                                              //! destructor
337
338std::vector<Number>& dofNumbers()                         //!< access to dofNumbers list
339const std::vector<Number>& dofNumbers() const             //!< access to dofNumbers list (const)
340std::vector<Number> dofRootNumbers() const;               //!< access to dofNumbers list in root space numbering
341Number dofRootNumber(Number k) const;                     //!< access to dof number in root space numbering
342virtual Number nbDofs() const                             //! number of dofs (a dof may be a vector dof)
343virtual bool isFeSubspace();
344virtual const FeSubSpace* fesubspace() const;
345\end{lstlisting}
346\vspace{.1cm}
347It also provides functions for numbering management:
348\vspace{.1cm}
349\begin{lstlisting}[]
350void createNumbering();   //!< create numbering of subspace DoFs
351void dofsOfFeSubspace();  //!< build dofs numbering of Fe SubSpace
352void dofsOfSpSubspace();  //!< build dofs numbering of Sp SubSpace
353void dofsOfSubSubspace(); //!< build dofs numbering of Subspace of SubSpace
354\end{lstlisting}
355\vspace{.1cm}
356\displayInfos{library=space, header=SubSpace.hpp, implementation=SubSpace.cpp, test=test\_Space.cpp,
357header dep={config.h, Elements.hpp, Space.hpp, Dof.hpp}}
358
359
360The {\class FeSubSpace} class concerns subspaces of finite element spaces. It is defined as follows:
361\vspace{.1cm}
362\begin{lstlisting}[deletekeywords={[3] elements}]
363class FeSubSpace : public SubSpace
364{
365  public :
366    std::vector<Element*> elements;                //!< list of finite elements (or subelements)
367    std::vector<std::vector<Number> > dofRanks;    //!< numbering of D.o.Fs of domain elements in domain D.o.Fs
368};
369\end{lstlisting}
370\vspace{.1cm}
371This class provides one constructor, a destructor, and several specific functions, also provided by the {\class FeSpace} class :
372\vspace{.1cm}
373\begin{lstlisting}
374FeSubSpace(const Domain&, Space&, const String& na = ""); //!< constructor specifying geom domain, parent space and name
375~FeSubSpace();                                         //!< destructor
376Number nbOfElements() const;                           //!< number of elements
377const Element* element_p(Number k) const;              //!< access to k-th (k>=0) element (pointer)
378std::vector<Number> elementDofs(Number k) const;       //!< access to dofs ranks (local numbering) of k-th (>=0) element
379std::vector<Number> elementParentDofs(Number k) const; //!< access to dofs ranks (parent numbering) of k-th (>=0) element
380\end{lstlisting}
381\vspace{.1cm}
382\displayInfos{library=space, header=FeSubSpace.hpp, implementation=FeSubSpace.cpp, test=test\_Space.cpp,
383header dep={config.h, Elements.hpp, SubSpace.hpp, dof.hpp}}
384
385\subsection{The {\classtitle ProdSpace} class}
386
387The {\class ProdSpace} class manages product of spaces using a vector of space pointers :
388\vspace{.1cm}
389\begin{lstlisting}
390class ProdSpace : public Space
391{
392  protected :
393    std::vector<Space*> spaces_;
394  public :
395    virtual Number dimSpace()const;
396    virtual Number nbdofs() const;
397    virtual const Space* rootSpace() const
398    {return static_cast<const Space*>(this);}
399    virtual Space* rootSpace()
400    {return static_cast<Space*>(this);}
401    virtual Number dofId(Number n) const
402    {error("no_dof_numbering", name());
403     return 0;}
404};
405\end{lstlisting}
406\vspace{.1cm}
407It is currently not used.
408\subsection{The {\classtitle Spaces} class}
409{\class Spaces} is an alias of {\class PCollection<Space>} class that manages a collection of {\class Space} objects, in fact a {\var std::vector<Space*>}. Be cautious when using it because the Space pointers are shared; in particular when using temporary instance of Space! It is the reason why the {\class PCollectionItem} class is overloaded to protect pointer in assign syntax {\cmd sp(i)=Space(...)}:
410\vspace{.1cm}
411\begin{lstlisting}[]
412template<> class PCollectionItem<Space>
413{public:
414 typename std::vector<Space*>::iterator itp;
415 PCollectionItem(typename std::vector<Space*>::iterator it) : itp(it){}
416 Space& operator = (const Space& sp); //protected assignment
417 operator Space&(){return **itp;}     //autocast PCollectionItem->Space&
418};
419\end{lstlisting}
420\vspace{.2cm}
421Main usages of this class are the following:
422\vspace{.1cm}
423\begin{lstlisting}[]
424Space V1(omega,_P1,"V1"), V2(omega,_P2,"V2"), V3(omega,_P3,"V3");
425Spaces Vs2(V1,V2);
426Spaces Vs3(V1,V2,V3);
427Spaces Vs4; Vs4<<V1<<V2<<V3<<V1;
428Spaces Vs5(5);
429for(Number i=1;i<=5;i++)
430   Vs5(i)=Space(omega,interpolation(Lagrange,_standard,i,H1),"V_"+tostring(i));
431\end{lstlisting}
432\vspace{.2cm}
433\begin{cpp11}
434If C++11 is available (the library has to be compiled in C++11), the following syntax is also working:
435\vspace{.1cm}
436\begin{lstlisting}[]
437Spaces vs={V1,V2,V3};
438\end{lstlisting}
439\end{cpp11}
440
441\vspace{.2cm}
442Collection of spaces can also be set by the following functions  from one or several domains and one or several interpolations:
443\vspace{.1cm}
444\begin{lstlisting}[]
445Spaces spaces(const Domains&,const Interpolations&,bool=true);
446Spaces spaces(const Domains&,const Interpolation&,bool=true);
447Spaces spaces(const GeomDomain&,const Interpolations&,bool=true);
448\end{lstlisting}
449\vspace{.2cm}
450
451\displayInfos{library=space, header=ProdSpace.hpp, implementation=ProdSpace.cpp, test=test\_space.cpp,
452header dep={config.h, Space.hpp}}
453