\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: 
