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{Domain management}
18
19Main objects in variational formulation are integrals over a geometrical domain. Geometrical
20domains can be any subset of any dimension of the computational geometrical domain, usually
21given by a mesh. But they can also be defined from analytical parametrisations. Besides, it
22me bay useful to consider unions of domains and sometimes, intersections of domains. Such "composite"
23domains are involved when evaluating linear combination of integrals over different domains.
24To deal with all this kind of geometrical domains, the following classes are provided:
25\begin{itemize}
26\item {\class MeshDomain} class to deal with domain defined from a list of mesh elements,
27\item {\class CompositeDomain} class to deal with domain defined as an union or an intersection
28of MeshDomains,
29\item {\class AnalyticalDomain} class to deal with domain defined from parametrisations (not yet implemented).
30\item {\class PointsDomain} class to deal with domain managing only a list of Points (cloud)
31\end{itemize}
32
33These classes inherit from the {\class GeomDomain} base class.
34
35In order for the end user to deal with only a single class ({\class GeomDomain}), we use the "abstract/non
36abstract" pattern:  {\class GeomDomain} has a {\class GeomDomain*} member attribute that points either
37to a child (end user object) or to itself (child object). Constructors of {\class GeomDomain} class
38construct child objects and member functions (either virtual or not) are interfaces with children.
39
40\subsection{The {\classtitle GeomDomain} base class}
41
42The {\class GeomDomain} base class has only two pointers as member attributes, one for general
43information and the other for child
44\vspace{.1cm}
45\begin{lstlisting}
46class GeomDomain
47{protected :
48   DomainInfo* domainInfo_p;    // pointer to domain information class
49   GeomDomain* domain_p;        // pointer to its child or itself if a child
50   static std::vector<const GeomDomain*> theDomains; // list of all domains
51   ...
52\end{lstlisting}
53\vspace{.1cm}
54where {\class DomainInfo} is the simple class:
55\vspace{.1cm}
56\begin{lstlisting}[deletekeywords={[3] name, dim, domType, description}]
57class DomainInfo
58{public :
59   String name;        // name of domain
60   Dimen dim;          // dimension of domain (the max when compositeDomain)
61   DomainType domType; // type of domain
62   const Mesh* mesh_p; // pointer to mesh
63   String description; // additionnal information
64  DomainInfo(const String&, Dimen, DomainType, const Mesh*, const String& = "");
65};
66\end{lstlisting}
67\vspace{.2cm}
68The type of domain is defined by the enumeration:
69\vspace{.1cm}
70\begin{lstlisting}[]
71enum DomainType {_undefDomain = 0, _analyticDomain, _meshDomain,
72                 _compositeDomain, _pointsDomain}
73\end{lstlisting}
74\vspace{.2cm}
75In order to not have clones of domains, created domains are listed in the static vector
76\verb?theDomains?.
77
78\begin{remark}
79There is no reason to instantiate child objects without using base class constructors like.
80Thus, only base class objects are collected in the static vector \verb?theDomains? and not child
81objects!
82\end{remark}
83
84The {\class GeomDomain} base class provides a basic constructor and child constructors like that
85construct a child object in memory and store its pointer in the \verb?domain_p? attribute:
86\vspace{.1cm}
87\begin{lstlisting}[]
88GeomDomain(const String & na="",dimen_t d=0, const Mesh* m=0);
89GeomDomain(const Mesh&, const String&, Dimen, const String& =""); //build meshdomain
90GeomDomain(SetOperationType sot,
91           const GeomDomain&,const GeomDomain&,
92           const String & na="");   //build composite domain with two domains
93GeomDomain(SetOperationType sot,
94           const std::vector<const GeomDomain*>&,
95           const String & na="");  //build composite domain with n domains
96~GeomDomain();                     //destructor
97\end{lstlisting}
98\vspace{.2cm}
99The set operations available are listed in the \verb?SetOperationType? enumeration:
100\vspace{.1cm}
101\begin{lstlisting}[]
102enum SetOperationType{_union, _intersection};
103\end{lstlisting}
104\vspace{.2cm}
105The class has the following accessors, some to access to {\class DomainInfo} attributes, the others to access to child attributes through polymorphism behaviour:
106\vspace{.1cm}
107\begin{lstlisting}[]
108const String& name() const;
109Dimen dim() const;
110const DomainType domType() const;
111const Mesh* mesh() const;
112const String& description() const;
113virtual const MeshDomain* meshDomain() const;             // non const also
114virtual const CompositeDomain* compositeDomain() const;   // non const also
115virtual const AnalyticalDomain* analyticalDomain() const; // non const also
116\end{lstlisting}
117\vspace{.2cm}
118For instance, the virtual accessor \verb?meshDomain()? has the following implementation in
119the base class:
120\vspace{.1cm}
121\begin{lstlisting}[]
122const MeshDomain* GeomDomain::meshDomain() const
123{if(domain_p!=this) return domain_p->meshDomain();
124 error("domain_notmesh");
125 return 0;
126}
127\end{lstlisting}
128\vspace{.1cm}
129and the \verb?meshDomain()? function in the  \verb?MeshDomain()? child class is:
130\vspace{.1cm}
131\begin{lstlisting}[]
132const MeshDomain* MeshDomain::meshDomain() const {return this;}
133\end{lstlisting}
134\vspace{.2cm}
135Besides, some useful member functions are provided
136\vspace{.1cm}
137\begin{lstlisting}[]
138void rename(const String&) ;         //rename domain
139void addSuffix(const String&);       //add a suffix to domain name
140Dimen spaceDim() const;              //return the space dimension
141const String domTypeName() const;    //return domain type name
142virtual bool isUnion() const;        //true if union
143virtual bool isIntersection() const; //true if intersection
144virtual bool include(const GeomDomain&) const; //true if includes a domain
145virtual Number numberOfElements() const;  // number of geometric elements
146virtual GeomElement* element(Number); //access to k-th element (k>=1)
147virtual void setMaterialId(Number);   //set material id (>0) for all elements
148virtual void setDomainId(Number);     //set a domain id for all elements
149virtual void clearGeomMapData();      //clear geometric data
150virtual const GeomDomain* largestDomain(std::vector<const GeomDomain*>) const;
151\end{lstlisting}
152\vspace{.2cm}
153There are some static member functions to search domains in the domain list and  to print
154the domain list:
155\vspace{.1cm}
156\begin{lstlisting}[]
157static const GeomDomain* findDomain(const GeomDomain*);
158static const GeomDomain* findDomain(SetOperationType,
159                                    const std::vector<const Domain*>&);
160static void printTheDomains(std::ostream&);
161\end{lstlisting}
162\vspace{.2cm}
163To manage the union of domains, the following functions are proposed:
164\vspace{.1cm}
165\begin{lstlisting}[]
166const GeomDomain* geomUnionOf(std::vector<const GeomDomain*>&);
167GeomDomain& merge(const std::vector<GeomDomain*>&, const String& name); //merge n domains
168GeomDomain& merge(GeomDomain&, GeomDomain&, const String& name);   //merge 2 domains
169...
170\end{lstlisting}
171The {\cmd geomUnionOf} function constructs (or identifies) the symbolic union of domains, say in the meaning of composite domains, whereas {\cmd merge} functions create a true union of domains by merging list of elements.
172\vspace{.2cm}
173Finally, the class provides print facilities:
174\vspace{.1cm}
175\begin{lstlisting}[]
176virtual void GeomDomain::print(std::ostream&) const;
177std::ostream& operator<<(std::ostream&,const GeomDomain&);
178\end{lstlisting}
179
180\subsection{The {\classtitle MeshDomain} child class}
181
182The {\class MeshDomain} child class handles a domain defined as a list of mesh elements, say a lis tof {\class GeomElement} objects that is a basic stone of a mesh.
183\vspace{.1cm}
184\begin{lstlisting}[deletekeywords={[3] set}]
185class MeshDomain : public GeomDomain
186{ public :
187    vector<GeomElement*> geomElements;//list of geometric elements
188  ...
189\end{lstlisting}
190\vspace{.1cm}
191It manages other important informations :
192\begin{lstlisting}[deletekeywords={[3] set}]
193protected :
194  MeshDomain* parent_p;            //parent mesh domain if submesh domain
195public :
196  set<ShapeType> shapeTypes;       //list of element shape types in mesh domain
197  const MeshDomain* extensionof_p; //side domain pointer extension pointer
198  mutable pair<OrientationType, const GeomDomain*> normalOrientationRule;  //orientation rule
199\end{lstlisting}
200\vspace{.1cm}
201 \verb?shapeTypes? is the list of element shape types contains at least one item and more than one if the mesh domain is a mixture of different elements. For instance if there are some triangles and quadrangles, the \verb?shapeTypes? list has two items (\verb?_triangle?,\verb?_quadrangle?). \\
202 The {\class MeshDomain} pointer  \verb?parent_p? gives a link to its parent domain when it is a side domain.\\
203 The {\class MeshDomain} pointer  \verb?extensionof_p? gives a link to its "child" when domain is an extension of a side domain. The extension of a side domain is the set of elements having a side (edge/face) located on the side domain. Such domains are required to compute boundary terms that involves non tangential derivative, for instance:
204 $$\int_\Gamma \partial_xu\,v.$$
205 \verb?normalOrientationRule? stores informations about the way the normals of a manifold domain are oriented :
206\begin{itemize}
207\item an orientation type from the enumeration
208\begin{lstlisting}[deletekeywords={[3] map, list}]
209enum OrientationType{_undefOrientationType, _towardsInfinite,
210                     _outwardsInfinite, _towardsDomain, _outwardsDomain};
211\end{lstlisting}
212\item a {\class GeomDomain} pointer providing the domain involved when  \verb?_towardsDomain? or \verb?_outwardsDomain? is selected
213\end{itemize}
214\begin{remark}
215When not specified, \verb?_towardsInfinite? is chosen for an immersed manifold and \verb?_outwardsDomain? for a boundary (may be hazardous when the boundary is an interface).
216\end{remark}
217
218Two structures useful to locate element from point, may be also constructed if they are required:
219\vspace{.1cm}
220\begin{lstlisting}[deletekeywords={[3] map, list}]
221mutable std::map<Point,std::list<GeomElement*> > vertexElements;
222mutable KdTree<Point> kdtree;
223\end{lstlisting}
224\vspace{.1cm}
225The first one gives for any vertex of the domain, the list of elements having this vertex and the second is a kdtree structure (tree of points) allowing to get in a short time the vertex closest to a given point. These structures are built on the fly by interpolation tools.\\
226
227The class manages also some flags to know what quantities are already computed :
228\vspace{.1cm}
229\begin{lstlisting}[]
230mutable bool orientationComputed;
231mutable bool jacobianComputed;
232mutable bool diffEltComputed;
233mutable bool normalComputed;
234mutable bool inverseJacobianComputed;
235\end{lstlisting}
236\vspace{.1cm}
237
238This class provides a single basic constructor and the member functions related to virtual
239member functions of the {\class GeomDomain} base class:
240\vspace{.1cm}
241\begin{lstlisting}[]
242MeshDomain(const Mesh&,const String&,Dimen);
243MeshDomain* meshDomain();
244const MeshDomain* meshDomain() const;
245\end{lstlisting}
246\vspace{.2cm}
247
248Some accessors and basic tools are provided:
249\vspace{.1cm}
250\begin{lstlisting}[]
251MeshDomain* parent() const {return parent_p;};
252void setShapeTypes();
253virtual MeshDomain* meshDomain();
254virtual const MeshDomain* meshDomain() const;
255virtual bool isUnion() const;
256virtual bool isIntersection() const;
257bool isSideDomain() const;
258virtual Number numberOfElements() const;
259virtual GeomElement* element(Number);
260virtual void setMaterialId(Number);
261virtual void setDomainId(Number);
262\end{lstlisting}
263\vspace{.1cm}
264The {\cmd setMaterialId} and {\cmd setDomainlId} end user functions propagates Ids to all geometric elements of the domain. It is the way to get some physical information in FE computation at a low level.\\
265
266There are more specific tools related to mesh domains:
267\vspace{.1cm}
268\begin{lstlisting}[deletekeywords={[3] set}]
269//node access
270std::set<Number> nodeNumbers() const;
271std::vector<Point> nodes() const;
272//set functions
273virtual bool include(const GeomDomain&) const;
274bool include(const MeshDomain& d) const;
275bool isUnionOf(const std::vector<const GeomDomain*>&)const;
276const GeomDomain* largestDomain(std::vector<const GeomDomain*>)const;
277//Geometric tool
278void setNormalOrientation(OrientationType, const GeomDomain& ) const;
279void setNormalOrientation(OrientationType = _undefOrientationType,
280                          const GeomDomain* gp=0) const;
281void setOrientationForManifold(OrientationType = _towardsInfinite) const;
282void setOrientationForBoundary(OrientationType ort =_outwardsDomain,
283                               const GeomDomain*  =0) const;
284void reverseOrientations() const;
285void buildGeomData() const;
286void clearGeomMapData();
287//create domain extension
288const GeomDomain* extendDomain() const;
289//tools to locate element
290void buildVertexElements() const;
291void buildKdTree() const;
292GeomElement* locate(const Point&) const;
293\end{lstlisting}
294\vspace{.1cm}
295
296The {\cmd buildGeomData} function constructs measure and orientation of the elements of the domain. \\
297
298The orientation of an element is the sign $s$ such that the normal computed times $s$ is the desired normal. When domain is a side domain, the orientations are either constructed using a tracking algorithm ({\cmd setOrientationForManifold}) or using a "volumic" algorithm ({\cmd setOrientationForBoundary}) when the side domain is the boundary of a "volumic" domain. Contrary to most FE softwares, \xlifepp does not assume that the numbering of nodes provided by meshing tools gives the outward normals! So the normal are always oriented by \xlifepp.\\
299
300\begin{remark}
301The computation of normal vector orientations is not done when mesh is generated or loaded but it is done during the construction of a space involving a manifold or during the computation of a Term involving normal vectors.
302\end{remark}
303
304The {\cmd locate} function is a powerful tool that returns one of the elements including a given point (null pointer if no element). It is used in all interpolation operations. It is wellknown that this operation is time expansive. This is the reason why additional structures {\cmd  vertexElements} and {\cmd  kdtree} may be constructed if point location is required. This structures are constructed only once by  {\cmd buildVertexElements} and {\cmd buildKdTree} functions at the first call of {\cmd locate}. The time to locate a point is generally (may be worth) in $log(n)$ ($n$ the number of vertices).\\
305
306Some print/export stuff is available:
307\vspace{.1cm}
308\begin{lstlisting}[]
309virtual void print(std::ostream&) const;
310friend std::ostream& operator<<(std::ostream&, const MeshDomain&);
311void saveNormalsToFile(const string_t&, IOFormat iof=_vtk) const;
312\end{lstlisting}
313
314
315\subsection{The {\classtitle CompositeDomain} child class}
316
317The {\class CompositeDomain} child class describes set operations (union and intersection)
318of geometrical domains ({\class Domain} objects). It is an abstact description that it means
319that elements lists of {\class MeshDomain} objects are not merged or intersected!
320\vspace{.1cm}
321\begin{lstlisting}
322class CompositeDomain : public GeomDomain
323{protected :
324  SetOperationType setOpType_;            //type of the set operation
325  std::vector<const Domain*> domains_;    //list of domains
326	...
327\end{lstlisting}
328\vspace{.1cm}
329{\cmd SetOperationType} enumerates \verb?_union? and \verb?_intersection? values. \\
330
331This class provides a single basic constructor, an accessor to the set operation and the member
332functions related to virtual member functions of the {\class GeomDomain} base class:
333\vspace{.1cm}
334\begin{lstlisting}[]
335CompositeDomain(SetOperationType, const std::vector<const GeomDomain*>&,const String&);
336SetOperationType setOpType() const;
337const std::vector<const GeomDomain*>& domains() const;
338CompositeDomain* compositeDomain();
339const CompositeDomain* compositeDomain();
340bool isUnion() const;
341bool isIntersection() const;
342std::vector<const GeomDomain *> basicDomains() const;   //recursive
343virtual Number numberOfElements() const;
344void print(std::ostream&) const;
345\end{lstlisting}
346\vspace{.1cm}
347The {\cmd basicDomains()} function is recursive and provides the list of all basic domains, that are domains which are not composite domains.
348
349\subsection{The {\classtitle PointsDomain} child class}
350
351This class deals with domain only defined by a list of points (cloud):
352\vspace{.1cm}
353\begin{lstlisting}[]
354class PointsDomain : public GeomDomain
355{
356public :
357 std::vector<Point> points;
358 PointsDomain(const std::vector<Point>&, const String& = "");
359 PointsDomain* pointsDomain();
360 const PointsDomain* pointsDomain() const;
361 const Point& point(Number n) const;
362 Point& point(Number n);
363 virtual bool include(const GeomDomain&) const;
364 virtual void print(std::ostream&) const;
365};
366\end{lstlisting}
367\vspace{.1cm}
368It may be useful but it is not used in core of the library!
369
370
371\subsection{The {\classtitle AnalyticalDomain} child class}
372
373This class has not be yet implemented (here for future usage).
374
375\subsection{The {\classtitle Domains} class}
376{\class Domains} is an alias of {\class PCollection<GeomDomain>} class that manages a collection of {\class GeomDomain}, in fact a {\var std::vector<GeomDomain*>} (see the definition of {\class PCollection}). It may be used as following:
377\vspace{.1cm}
378\begin{lstlisting}[]
379Strings sn("Gamma1","Gamma2","Gamma3","Gamma4");
380Mesh mesh2d(Rectangle(_xmin=0,_xmax=0.5,_ymin=0,_ymax=1,_nnodes=Numbers(3,6),
381           _domain_name="Omega",_side_names=sn),_triangle,1,_structured);
382Domain omega=mesh2d.domain("Omega"),
383       gamma1=mesh2d.domain("Gamma1"), gamma2=mesh2d.domain("Gamma2"),
384       gamma3=mesh2d.domain("Gamma3"),gamma4=mesh2d.domain("Gamma4");
385Domains ds3(gamma1,gamma2,gamma3);
386Domains ds4;
387for(Number i=0;i<4;i++) ds4<<mesh2d.domain(i+1);
388Domains ds5(5);
389for(Number i=1;i<=5;i++) ds5(i)=mesh2d.domain(i-1);
390\end{lstlisting}
391\vspace{.2cm}
392\begin{cpp11}
393If C++11 is available (the library has to be compiled in C++11), the following syntax is also working:
394\vspace{.1cm}
395\begin{lstlisting}[]
396Domains dsi={gamma1,gamma2,gamma3};
397\end{lstlisting}
398\end{cpp11}
399
400\displayInfos{library=geometry, header=GeomDomain.hpp, implementation=GeomDomain.cpp, test=test\_Domain.cpp,
401header dep={config.h, utils.h}}
402
403