File: periodic-impl.tex

package info (click to toggle)
alberta 3.1.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 19,176 kB
  • sloc: ansic: 135,836; cpp: 6,601; makefile: 2,801; sh: 333; fortran: 180; lisp: 177; xml: 30
file content (386 lines) | stat: -rw-r--r-- 13,860 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
\newpage

\section{Periodic finite element spaces}
%
\label{S:periodic}

In \ALBERTA, a periodic mesh is thought of (part of) the fundamental
domain of crystallographic group. The periodic structure is induced by
a set of face-transformation. Given a fundamental domain of a
crystallographic group, the face-transformations are the special set
of generators of that group which map the given fundamental domain to
its neighbour across on of the walls separating it from its neighbour.

\subsection{Definition of periodic meshes}
\noindent
\begin{minipage}{0.50\textwidth}

  The most convenient way to define a periodic structure for a mesh is
  to specify geometric face-transformations through the file which
  defines the macro-triangulation; this has already been explained in
  \secref{S:macro_tria}. An 2d-example, defining a periodic torus,
  would look like follows. A corresponding example for 3d can be found
  in the suite of demo-programs which is shipped with the
  \ALBERTA-package.

  One thing which might be striking in \exampleref{E:periodic_torus}
  on the right is that the triangulation seems to be unnecessarily
  complicated: it is possible to triangulate a square with just two
  triangles, instead of the $8$ elements which are used in this
  example. The reason is the following: \ALBERTA uses the global
  numbering of the vertex-nodes to compute the relative orientation of
  neighboring elements. This is needed, e.g., during mesh refinement
  and coarsening, or when computing integrals over the walls of the
  elements, assembling jump terms. Now, if the mesh is periodic then
  the vertex nodes used to orient neighboring elements are actually
  identified. Therefore, the simplest macro triangulation with only
  two triangles would have just one vertex-\code{DOF}, all vertices
  would have been identified, making it impossible to orient
  neighboring elements.

  \begin{quote}
    \emph{Therefore \ALBERTA imposes the restriction a
      face-transformation must not map any vertex to a vertex on the
      same element.}
  \end{quote}
\end{minipage}
\hfill
\begin{minipage}{0.45\textwidth}
\begin{example}
A macro triangulation for a topological torus.
\label{E:periodic_torus}
\bv\begin{lstlisting}
DIM: 2
DIM_OF_WORLD: 2

number of elements: 8
number of vertices: 9

element vertices:
 4 0 1
 2 4 1
 4 2 5
 8 4 5
 4 8 7
 6 4 7
 4 6 3
 0 4 3

vertex coordinates:
 -1.0 -1.0  
  0.0 -1.0
  1.0 -1.0
 -1.0  0.0  
  0.0  0.0
  1.0  0.0
 -1.0  1.0  
  0.0  1.0
  1.0  1.0

number of wall transformations: 2

wall transformations:
# generator #1
 1 0 2
 0 1 0
 0 0 1
# generator #2
 1 0 0
 0 1 2
 0 0 1  
\end{lstlisting}\ev
\end{example}
\end{minipage}

There is, however, some limited support to cope with coarse
macro-triangulations: if it encounters a periodic macro-triangulations
which violates this restriction then it tries to resolve the issue by
running some steps of global refinement over the mesh in the hope that
the refined meshes fulfill the restriction. It then converts the
refined meshes into a macro triangulation and starts over with the
refine macro-mesh. Thus, the following macro-triangulation could be
used by an application:
\begin{example}
  \label{E:coarse_periodic_macro}
  Coarse periodic macro triangulation.
  \bv\begin{lstlisting}
DIM: 2
DIM_OF_WORLD: 2

number of elements: 2
number of vertices: 4

element vertices:
 2 0 1   0 2 3

vertex coordinates:
 -1.0 -1.0    1.0 -1.0    1.0  1.0    -1.0 1.0

number of wall transformations: 2

wall transformations:
# generator #1
 1 0 2
 0 1 0
 0 0 1
# generator #2
 1 0 0
 0 1 2
 0 0 1  
  \end{lstlisting}\ev
\end{example}
%%
However, the application program will end up with a mesh which is
based on a refined mesh which probably looks very similar to the
triangulation defined by \exampleref{E:periodic_torus}.

There are two other methods to define a periodic structure on a mesh:
by specifying combinatoric face-transformations in the macro
triangulation, this is explained in \secref{S:macro_tria}, or by
passing geometric face-transformation to the \code{GET\_MESH()} call,
see \secref{S:mesh_initialization}. Similar to the mechanism of
initializing node-projections (see \exampleref{Ex:unit_ball}) it is
possible to pass a second routine to the \code{GET\_MESH()} call to
initialize face-transformations:

\begin{example}
  2d. Initialization of face-transformations through an
  \code{init\_wall\_trafos()}-hook passed to \code{GET\_MESH()}. For
  this to work the macro-data file has assigned different boundary
  ``street-numbers'' to the different periodic boundary segments: type
  $1$ corresponds to a translation in $x_1$-direction and type $2$ to
  a translation in $x_2$-direction. The \code{init\_wall\_trafos()}
  function is called with fully-features macro-elements (except for
  the missing periodic structure, of course). The convention is to
  return \nil if no face-transformation applies, and a pointer to the
  face-transformation if the boundary-wall with local number
  \code{wall} in \code{mel} belongs to a periodic boundary segment.
  %%
  \bv\begin{lstlisting}
static AFF_TRAFO *init_wall_trafos(MESH *mesh, MACRO_EL *mel, int wall)
{
  static AFF_TRAFO wall_trafos[DIM_OF_WORLD] = {
    { {{1.0, 0.0},
        {0.0, 1.0}}, {2.0, 0.0} },
    { {{1.0, 0.0},
        {0.0, 1.0}}, {0.0, 2.0} }
  };
  static AFF_TRAFO inverse_wall_trafos[DIM_OF_WORLD] = {
    { {{1.0, 0.0},
        {0.0, 1.0}}, {-2.0, 0.0} },
    { {{1.0, 0.0},
        {0.0, 1.0}}, {0.0, -2.0} }
  };

  switch (mel->wall_bound[wall]) {
  case 1: /* translation in x[0] direction */
    if (mel->coord[(wall+1) % N_VERTICES(mesh->dim)][0] > 0.0) {
      return &wall_trafos[0];
    } else {
      return &inverse_wall_trafos[0];
    }
  case 2: /* translation in x[1] direction */
    if (mel->coord[(wall+1) % N_VERTICES(mesh->dim)][1] > 0.0) {
      return &wall_trafos[1];
    } else {
      return &inverse_wall_trafos[1];
    }
  }
  return NULL;
}
  \end{lstlisting}\ev
\end{example}

\subsection{Periodic meshes and  finite element spaces}
Defining a periodic structure on a mesh only generates a mesh
\emph{could} carry periodic finite element spaces. \code{GET\_MESH()}
indicates this by setting \code{MESH.is\_periodic} to \code{true}.
Additionally, the following components of the \code{MESH}-structure
are maintained by \ALBERTA and are automatically updated during mesh
adaptation.
%%
\begin{descr}
  \kitem{is\_periodic} Set to \code{true} by \code{GET\_MESH()} if the
  mesh admits periodic finite element spaces.
  %%
  \kitem{per\_n\_vertices, per\_n\_edges, per\_n\_faces} Number of
  vertices, edges and faces taking the identification of those
  sub-simplices on periodic boundary segments into account, i.e.
  \code{MESH.n\_faces} counts periodic faces twice,
  \code{MESH.per\_n\_faces} counts them only once.
  %%
  \kitem{wall\_trafos} If specified by the application this list
  contains the geometric face-transformations and their inverses. This
  can be helpful, sometimes an application may have the need to
  compute the orbit of geometric objects under the action of the
  underlying crystallographic group. Internally, \ALBERTA has the need
  to compute orbits of vertices and edges when adding new periodic
  finite element spaces to the mesh.
  %%
  \kitem{n\_wall\_trafos} Self-explanatory.
  %%
\end{descr}
%%
Having defined a periodic structure on a mesh, an application must do
more to actually define periodic function spaces: it must pass the
flag \code{ADM\_PERIODIC} to \code{get\_fe\_space()} respectively
\code{get\_dof\_space()}. Otherwise the returned space will be
\emph{non}-periodic. Periodic finite element spaces are implemented by
actually identifying degrees of freedom, so -- at least for scalar
problems or in the context of mere translations -- nothing more has to
be done to implement periodic boundary conditions. This is exercised
by the example \code{src/Common/ellipt-periodic.c} which can be found
in the demo-package.
%%
\begin{example}
  \label{E:peridic_non_periodic_space}
  Allocating periodic and non-periodic finite element space on the
  same mesh.
  \label{E:get_periodic_fe_space}
  \bv\begin{lstlisting}
    const BAS_FCTS *bfcts = get_lagrange(dim, degree)
    const FE_SPACE *per_fe_space =
      get_fe_space(mesh, "periodic space", bfcts, 1 /* range dimension */,
                   ADM_PERIODIC);
    const FE_SPACE *std_fe_space =
      get_fe_space(mesh, "periodic space", bfcts, 1 /* range dimension */,
                   ADM_FLAGS_DFLT);
  \end{lstlisting}\ev
\end{example}
%%
There are many good reasons to allow non-periodic finite element
spaces on a periodic-admissible mesh, some of them are:
\begin{itemize}
\item Parts of a specific problem may require periodic boundary
  conditions, others not.
\item In the context of parametric meshes the coordinate functions
  defining the geometry of the mesh are -- of course -- non-periodic.
\item Vector-valued problems: e.g. for the simulation of fluids the
  velocity field can in general not be chosen as a vector field
  consisting of component-wise periodic functions. This is actually
  only possible in the most simple case were the face-transformations
  are mere translations. Otherwise the identification of the velocity
  field across a periodic boundary segment requires first the
  transformation of the components of the vector field by the
  face-transformation.

  This implies that in this context the linear systems have to be
  actively modified, a mere identification of \code{DOF}s does not
  suffice.
\end{itemize}
%%
Above reasoning implies that it is desirable to be able to loop over
the mesh ignoring its periodic structure altogether. This can be
achieved like demonstrated below:
\begin{example}
  Non-periodic mesh-traversal on a periodic mesh. The resulting
  \code{EL\_INFO}-structures are completely unaware of the periodic
  structure, in particular the periodic neighbors are \emph{not}
  filled in. This is easily achieved by setting the
  \code{FILL\_NON\_PERIODIC} fill-flag.
  %%
  \bv\begin{lstlisting}
    TRAVERSE_FIRST(mesh, -1,
                   CALL_LEAF_EL|FILL_NON_PERIODIC|
                   FILL_NEIGH|FILL_MACRO_WALLS) {
      int w;

      for (w = 0; w < N_WALLS(mesh->dim); w++) {
        int mwall = el_info->macro_wall[w];
        if (el_info->neigh[w] == NULL &&
            el_info->macro_el->neigh_vertices[mwall][0] >= 0) {
          MSG("I'm a non-periodic element,
               but my macro-element has periodic boundaries!\n");
        }
      }
      
    } TRAVERSE_NEXT();    
  \end{lstlisting}\ev
\end{example}
%%
\subsection{Element-wise access to periodic data}

Data like the face-transformations is stored only on the macro-element
level, not in the \code{EL\_INFO}-structure. However, requesting the
\code{FILL\_MACRO\_WALLS} fill-flag gives an application the link
between the wall numbering of the current element and the numbering of
walls of the macro-element it is contained in, see also
\secref{S:EL_INFO} and \exampleref{E:access_to_periodic_data}. The
following additional information is available through the
\code{MACRO\_EL}-structure when the mesh carries a periodic structure:
%%
\begin{descr}
\kitem{np\_vertex\_bound} The \emph{non}-periodic boundary
  classification of the vertices, i.e. in ignorance of the periodicity
  of the mesh.
  %% 
\kitem{np\_edge\_bound} Same, but for edges.
  %%
\kitem{neigh\_vertices} As
  \hyperlink{MACRO_EL:neigh_vertices}{explained} in
  \secref{S:macro_element}
  %% 
\kitem{wall\_trafo} The geometric face-transformations for each
  wall. \code{wall\_trafo[wall]} is \nil if the corresponding boundary
  segment is non-periodic, or is an interior wall.
\end{descr}
%%
\begin{example}
  \label{E:access_to_periodic_data}
  A demonstration of how to access information about periodic boundary
  conditions during mesh-traversal. Long version:
  %%
  \bv\begin{lstlisting}
    TRAVERSE_FIRST(mesh, -1, CALL_LEAF_EL|FILL_MACRO_WALLS) {
      int w, mwall;

      for (w = 0; w < N_WALLS(mesh->dim); w++) {
        if ((mwall = el_info->macro_wall[w]) < 0) {
          continue; /* interior  wall */
        }
        if (el_info->macro_el->wall_trafo[mwall] != NULL) {
          MSG("Hurray, a face transformation!\n");
        }
      }
    } TRAVERSE_NEXT();
  \end{lstlisting}\ev
  %%
  Slightly shorter, using the \code{wall\_trafo()} call:
  %%
  \bv\begin{lstlisting}
    TRAVERSE_FIRST(mesh, -1, CALL_LEAF_EL|FILL_MACRO_WALLS) {
      int w;
      const AFF_TRAFO *face_trafo;

      for (w = 0; w < N_WALLS(mesh->dim); w++) {
        if ((face_trafo = wall_trafo(el_info, w)) != NULL) {
          MSG("Hurray, a face transformation @%p!\n", face_trafo);
        }
      }
    } TRAVERSE_NEXT();
  \end{lstlisting}\ev
\end{example}

\subsection{Periodicity and trace-meshes}

In principle, the periodic structure of a mesh is inherited by its
trace-meshes. However, this may not make sense in all cases. For
instance, if the master-mesh is a topological torus then the attempt
to define a trace mesh consisting of all periodic boundaries will fail
-- or at least that trace-mesh will have no consistent periodic
structure. The reason is simple: periodicity is induced by mapping
walls to walls with face-transformations. In general this implies that
the orbits of co-dimension $2$ and co-dimension $3$ face-simplices
under the group spanned by the face-transformations contain more than
two elements. So if the intersection of the trace-mesh with those
orbits also contains more than $2$ elements, then the periodic
structure on the trace-mesh cannot be well-defined.

So in general a trace-mesh of a periodic master mesh must be
perpendicular to the periodic boundary segments of the ambient
master-mesh.

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "alberta-man"
%%% End: