\section{Contributed ``add-ons''}
\label{S:addons}

The \ALBERTA distributions contains a sub-directory
%%
\bv\begin{verbatim}
alberta-VERSION/add_ons/
\end{verbatim}\ev
%%
with contributed extension and code-fragments. The degree of stability
varies between the different packages in the \code{add\_ons/}
sub-directory. We give just a very brief description here. Some of the
``add-ons'' already have been mentioned in the preceeding sections.
The stand-alone programs contained in the \code{add\_ons/} directory
are compiled during the ordinary compilation cycle for the
\ALBERTA-distribution, and install below \code{PREFIX/bin/}, where
prefix is the principal installation prefix for the entire package, as
specified by the \code{--prefix}-argument to the
\code{configure}-script.

\subsection{\code{add\_ons/bamg2alberta/}}
\label{S:bamg2alberta_addon}

Conversion from the output of the \code{bamg} grid-generator
distributed along with the \emph{FreeFem++} toolbox (Christian
Haarhaus).

\subsection{\code{add\_ons/block\_solve/}}
\label{S:blocksolve_addon}

A \code{C}-framework implementing block-matrices consisting of
ordinary \hyperref[T:DOF_MATRIX]{\code{DOF\_MATRIX}} structure (Notger
Noll). The add-on comes in the shape of a library
%%
\bv\begin{verbatim}
PREFIX/lib/liboem_block_solve_Xd[_debug].EXTENSION
PREFIX/include/alberta/oem_block_solve.h
\end{verbatim}\ev
%%

The basic data structures are a
\hyperref[S:BLOCK_DOF_VEC_struct]{\code{BLOCK\_DOF\_VEC}} for storing
finite element functions, a
\hyperref[S:BLOCK_DOF_SCHAR_VEC_struct]{\code{BLOCK\_DOF\_SCHAR\_VEV}}
for storing boundary masks (compare \secref{S:dirichlet_bound}), and,
of course, a
\hyperref[S:BLOCK_DOF_MATRIX_struct]{\code{BLOCK\_DOF\_MATRIX}} for
storing matrices composed from blocks of
\hyperref[T:DOF_MATRIX]{\code{DOF\_MATRIX}} structures. Finally, there
is a \hyperref[S:BLOCK_PRECON_TYPE_struct]{\code{BLOCK\_PRECON\_TYPE}}
structure, for a purpose similar to the
\hyperref[S:PRECON_TYPE_struct]{\code{PRECON\_TYPE}} structure described in
\secref{S:PRECON_TYPE_struct}.

The basic support functions implemented in the library are explained
further below in the Sections
\ref{S:libblocksolve:get_block_dof_vec_fct}-\ref{S:libblocksolve:init_oem_block_precon_fct}, in particular
\begin{itemize}
\item
  \hyperref[S:libblocksolve:get_block_dof_vec_fct]{\code{get\_block\_dof[\_schar]\_vec()}}
  on page \pageref{S:libblocksolve:get_block_dof_vec_fct},
\item \hyperref[S:libblocksolve:free_block_dof_vec_fct]{\code{free\_block\_dof[\_schar]\_vec()}} on page \pageref{S:libblocksolve:free_block_dof_vec_fct}
\item
  \hyperref[S:libblocksolve:get_block_dof_matrix_fct]{\code{get\_block\_dof\_matrix()}}
  on page \pageref{S:libblocksolve:get_block_dof_matrix_fct},
\item
  \hyperref[S:libblocksolve:free_block_dof_matrix_fct]{\code{free\_block\_dof\_matrix()}}
  on page \pageref{S:libblocksolve:free_block_dof_matrix_fct},
\item
  \hyperref[S:libblocksolve:clear_block_dof_matrix_fct]{\code{clear\_block\_dof\_matrix()}}
  on page \pageref{S:libblocksolve:clear_block_dof_matrix_fct},
\item
  \hyperref[S:libblocksolve:oem_block_solve_fct]{\code{oem\_block\_solve()}}
  on page \pageref{S:libblocksolve:oem_block_solve_fct},
\item
  \hyperref[S:libblocksolve:init_oem_block_precon_fct]{\code{init\_oem\_block\_precon()}}
  on page \pageref{S:libblocksolve:init_oem_block_precon_fct}.
\end{itemize}

%%
\begin{datatype}{BLOCK\_DOF[\_SCHAR]\_VEC}
\label{S:BLOCK_DOF_VEC_struct}
\label{S:BLOCK_DOF_SCHAR_VEC_struct}
%%
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!BLOCK_DOF_VEC@{\code{BLOCK\_DOF\_VEC}}}
\ddx{BLOCK_DOF_VEC@{\code{BLOCK\_DOF\_VEC}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!BLOCK_DOF_SCHAR_VEC@{\code{BLOCK\_DOF\_SCHAR\_VEC}}}
\ddx{BLOCK_DOF_SCHAR_VEC@{\code{BLOCK\_DOF\_SCHAR\_VEC}}}
%%
\item[Definition]~\hfill

\begin{lstlisting}
#define N_OEM_BLOCKS_MAX 10

typedef struct block_dof_vec
{
  const char *name;
  int n_components;
  
  DOF_REAL_VEC_D *dof_vec[N_OEM_BLOCKS_MAX];
  
} BLOCK_DOF_VEC;

typedef struct block_dof_schar_vec
{
  const char *name;
  int n_components;
  
  DOF_SCHAR_VEC *schar_vec[N_OEM_BLOCKS_MAX];
  
} BLOCK_DOF_SCHAR_VEC;
\end{lstlisting}

\item[Components]~\hfill

These two structure are quite simple, the meaning of the components
are as follows;
\begin{descr}
\hyperitem{libblocksolve:block_dof_vec:name}{name} A descriptive name,
  used for debugging and pretty-printing.
  %%
\hyperitem{libblocksolve:block_dof_vec:n_components}{n\_components}
  The number of blocks, the restriction \code{n\_components <
    N\_OEM\_BLOCKS\_MAX} applies, of course.
  %%
\hyperitem{libblocksolve:block_dof_vec:dof_vec}{dof\_vec} A flat array
  of at most \code{N\_OEM\_BLOCKS\_MAX} many
  \hyperref[T:DOF_REAL_VEC_D]{\code{DOF\_REAL\_VEC\_D}} components,
  the actual number is stored in \code{n\_components}. Analogously for
  the \code{schar\_vec} component of the
  \code{BLOCK\_DOF\_SCHAR\_VEC}.  \emph{Note:} Though the data-type is
  a \code{DOF\_REAL\_VEC\_D} it is (ab-)used to store also
  \code{DOF\_REAL\_VEC} data, compare the remarks in
  \secref{S:DOF_VEC} concerning the
  \hyperlink{DOF_REAL_VEC_D:stride}{\code{stride}} respectively the
  \hyperlink{DOF_REAL_VEC:reserved}{\code{reserved}} components of a
  \code{DOF\_REAL\_VEC\_D} respectively a \code{DOF\_REAL\_VEC}
  structure.
\end{descr}
\end{datatype}

\begin{datatype}{BLOCK\_DOF\_MATRIX}
\label{S:BLOCK_DOF_MATRIX_struct}
%%
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!BLOCK_DOF_MATRIX@{\code{BLOCK\_DOF\_MATRIX}}}
\ddx{BLOCK_DOF_MATRIX@{\code{BLOCK\_DOF\_MATRIX}}}
%%
\item[Definition]~\hfill

\begin{lstlisting}
#define N_OEM_BLOCKS_MAX 10

typedef enum { Full, Empty, Diag, Triag, Symm } MatType;

typedef struct block_dof_matrix 
{
  const char      *name;
  int             n_row_components;
  int             n_col_components;
  
  const FE_SPACE  *row_fe_spaces[N_OEM_BLOCKS_MAX];
  const FE_SPACE  *col_fe_spaces[N_OEM_BLOCKS_MAX];
  
  MatType         block_type;
  
  DOF_MATRIX      *dof_mat[N_OEM_BLOCKS_MAX][N_OEM_BLOCKS_MAX];
  MatrixTranspose transpose[N_OEM_BLOCKS_MAX][N_OEM_BLOCKS_MAX];
} BLOCK_DOF_MATRIX;
\end{lstlisting}

\item[Components]~\hfill

Slightly more complicated than the
\hyperref[S:BLOCK_DOF_VEC_struct]{\code{BLOCK\_DOF\_VEC}} structure,
but still straight forward, maybe with the exception of the
\code{block\_type} component.

\begin{descr}
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:name}{name} A descriptive
  name, for pretty-printing an debugging purposes.
  %% 
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:n_row_components}{n\_row\_components}
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:n_col_components}{n\_col\_components}
  The number of row- and column-blocks.
  %%
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:row_fe_spaces}{row\_fe\_spaces}
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:col_fe_spaces}{col\_fe\_spaces}
  The finite element spaces, for each row and column.
  %%
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:block_type}{block\_type}
  An enumeration value, describing the block-structure:
  \begin{descr}
  \kitem{Full} An ordinary, fully filled block-matrix.
      %%
  \kitem{Empty} The empty, i.e. zero-matrix. This implies that all
    pointers in the \code{dof\_mat[][]} component (see below) are
    \nil-pointers.
    %% 
  \kitem{Diag} A diagonal matrix. Only the diagonal blocks in
    \code{dof\_mat[][]} are non-\nil.
      %%
  \kitem{Triag} An upper triangular matrix. Only the upper-triangular
    blocks in \code{dof\_mat[][]} are non-\nil.
    %% 
  \kitem{Symm} A symmetric matrix, it holds \code{dof\_mat[i][j] ==
      dof\_mat[j][i]}. The \code{transpose[][]} component is
    initialized to \hyperref[enum:MatrixTranspose]{\code{Transpose}}
    by
    \hyperref[S:libblocksolve:get_block_dof_matrix_fct]{\code{get\_block\_dof\_matrix()}}.
    %% 
  \end{descr}
  %%
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:dof_mat}{dof\_mat[][]} The
  data of the matrix. Not all pointers need to be non-\nil, see the
  documentation for \code{block\_type} above.
  %%
\hyperitem{libblocksolve:BLOCK_DOF_MATRIX:transpose}{transpose[][]}
  For each component of \code{dof\_mat} a
  \hyperref[enum:MatrixTranspose]{\code{MatrixTranspose}} flag specifying
  whether the matrix pointed to should operate as transposed matrix.
\end{descr}
\end{datatype}

\begin{datatype}{BLOCK\_PRECON\_TYPE}
\label{S:BLOCK_PRECON_TYPE_struct}
%%
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!BLOCK_PRECON@{\code{BLOCK\_PRECON}}}
\ddx{BLOCK_PRECON@{\code{BLOCK\_PRECON}}}
%%
\item[Definition]~\hfill

\begin{lstlisting}
#define N_OEM_BLOCKS_MAX 10

typedef struct block_precon_type
{ 
  /* Block-Precon-Type */
  OEM_PRECON block_type;
  
  REAL block_omega;      /* for BlkSSORPrecon */
  int  block_n_iter;     /* for BlkSSORPrecon */
  
  PRECON_TYPE precon_type[N_OEM_BLOCKS_MAX];
} BLOCK_PRECON_TYPE;
\end{lstlisting}

\item[Description]~\hfill

  This is a ``parameter-transport'' structure understood by
  \hyperref[S:libblocksolve:init_oem_block_precon_fct]{\code{init\_oem\_block\_precon()}},
  see below \secref{S:libblocksolve:init_oem_block_precon_fct}.
  Compare also \secref{S:init_precon_from_type_fct}.

\item[Components]~\hfill
\begin{descr}
\hyperitem{libblocksolve:block_precon_type:block_type}{block\_type}
  The block-type of the preconditioner. Only
  \hyperref[S:OEM_PRECON_enum]{\code{BlkDiagPrecon}} and --
  experimentally -- \hyperref[S:OEM_PRECON_enum]{\code{BlkSSORPrecon}}
    are supported.
  %% 
\hyperitem{libblocksolve:block_precon_type:block_omega}{block\_omega}
\hyperitem{libblocksolve:block_precon_type:block_n_iter}{block\_n\_iter}
  The respective parameters when unsing \code{block\_type ==
    BlkSSORPrecon}.
  %% 
\hyperitem{libblocksolve:block_precon_type:precon_type}{precon\_type}
  For each row the \hyperref[S:PRECON_TYPE_struct]{type of the
    preconditioner}, see \secref{S:PRECON_TYPE_struct}.
  %% 
\end{descr}
\end{datatype}

\begin{function}{\dots\_print\_block\_\dots()}
\label{S:libblocksolve_pretty_printing}
%%
\item[Description]~\hfill

Not all functions implemented in the library are explained in detail
below, in particular, we just notice without detailed description that
the following routines exist for pretty-printing:
%%

\item[Prototypes]~\hfill

\begin{lstlisting}
void print_block_dof_vec(BLOCK_DOF_VEC *block_vec);
void print_block_dof_matrix(BLOCK_DOF_MATRIX *block_mat);
void print_block_dof_vec_maple(BLOCK_DOF_VEC *block_vec,
                               const char *block_name);
void print_block_dof_matrix_maple(BLOCK_DOF_MATRIX *block_mat,
                                  const char *block_name);
void fprint_block_dof_vec_maple(FILE *fp, BLOCK_DOF_VEC *block_vec,
                                const char *block_name);
void fprint_block_dof_matrix_maple(FILE *fp, BLOCK_DOF_MATRIX *block_mat,
                                   const char *block_name);
void file_print_block_dof_vec_maple(const char *file_name,
                                    const char fopen_options[],
                                    BLOCK_DOF_VEC *block_vec,
                                    const char *block_name);
void file_print_block_dof_matrix_maple(const char *file_name,
                                       const char fopen_options[],
                                       BLOCK_DOF_MATRIX *block_mat,
                                       const char *block_name);
\end{lstlisting}
\end{function}

\begin{function}{get\_block\_dof[\_schar]\_vec()}
\label{S:libblocksolve:get_block_dof_vec_fct}
\label{S:libblocksolve:get_block_dof_schar_vec_fct}
%%
\fdx{get_block_dof_vec()@{\code{get\_block\_dof\_vec()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!get_block_dof_vec@{\code{get\_block\_dof\_vec()}}}
\fdx{get_block_dof_schar_vec()@{\code{get\_block\_dof\_schar\_vec()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!get_block_dof_schar_vec@{\code{get\_block\_dof\_schar\_vec()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
BLOCK_DOF_VEC *get_block_dof_vec(const char *name, int n_components,
                                 const FE_SPACE *fe_space, ...);
BLOCK_DOF_SCHAR_VEC *
get_block_dof_schar_vec(const char *name, int n_components,
                        const FE_SPACE *fe_space, ...);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
block_vec = get_block_dof[_schar]_vec(name, n_components,
                                      first_fe_space, ...);
\end{lstlisting}\ev
\item[Description] ~\hfill

  Allocate and initialize a new
  \hyperref[S:BLOCK_DOF_VEC_struct]{\code{BLOCK\_DOF[\_SCHAR]\_VEC}}
  structure. The routine will internally place calls to
  \hyperref[S:DOF_VEC]{\code{get\_dof\_real[\_d]\_vec[\_d]()}}.

\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:get_block_dof_vec:name}{name} A descriptive
    name, useful for debugging purposes and pretty-printing. The name
    is duplicated by calling \code{strdup(3)}.
    %%
  \hyperitem{libblocksolve:get_block_dof_vec:n_components}{n\_components}
    The number of blocks the vector shall consist of.
    %%
  \hyperitem{libblocksolve:get_block_dof_vec:first_fe_space}{first\_fe\_space}
    The \hyperref[T:FE_SPACE]{finite element space} for the first
    component.
    %% 
  \hyperitem{libblocksolve:get_block_dof_vec:va_arg}{\dots} In
    generalk, \code{n\_components-1} further finite element spaces. If
    a \nil-pointer is encountered in the list, then the preceding
    finite element space will be used for all following components of
    the block-vector.
    %% 
  \end{descr}
\item[Return Value] ~\hfill

  A pointer to a newly allocated
  \hyperref[S:BLOCK_DOF_VEC_struct]{\code{DOF\_BLOCK[\_SCHAR]\_VEC}}
  structure, use
  \hyperref[S:libblocksolve:free_block_dof_vec_fct]{\code{free\_block\_dof\_vec()}}
  to release the associated resources and delete the vector.
\item[Examples] ~\hfill

  Have a look at the test program
%%
  \bv\begin{verbatim}
alberta-VERSION/add_ons/block_solver/demo/Common/quasi-stokes.c
\end{verbatim}\ev
\end{function}

\begin{function}{free\_block\_dof[\_schar]\_vec()}
\label{S:libblocksolve:free_block_dof_vec_fct}
\label{S:libblocksolve:free_block_dof_schar_vec_fct}
%%
\fdx{free_block_dof_vec()@{\code{free\_block\_dof\_vec()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!free_block_dof_vec@{\code{free\_block\_dof\_vec()}}}
\fdx{free_block_dof_schar_vec()@{\code{free\_block\_dof\_schar\_vec()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!free_block_dof_schar_vec@{\code{free\_block\_dof\_schar\_vec()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
void free_block_dof_vec(BLOCK_DOF_VEC *bvec);
void free_block_dof_schar_vec(BLOCK_DOF_VEC *bvec);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
free_block_dof[_schar]_vec(block_vec);
\end{lstlisting}\ev
\item[Description] ~\hfill

  Release a vector previously allocated by a call to
  \hyperref[S:libblocksolve:get_block_dof_vec_fct]{\code{get\_block\_dof\_vec()}}.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:free_block_dof_vec:block_vec}{block\_vec}
    The vector to destroy.
    %% 
  \end{descr}
\end{function}

\begin{function}{get\_block\_dof\_matrix()}
\label{S:libblocksolve:get_block_dof_matrix_fct}
%%
\fdx{get_block_dof_matrix()@{\code{get\_block\_dof\_matrix()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!get_block_dof_matrix@{\code{get\_block\_dof\_matrix()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
BLOCK_DOF_MATRIX *get_block_dof_matrix(const char *name,
                                       int n_row_components,
                                       int n_col_components,
                                       MatType block_type,
                                       const FE_SPACE *fe_space, ...);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
block_matrix = get_block_dof_matrix(name, n_row, n_col,
                                    block_type,
                                    first_fe_space, ...);  
\end{lstlisting}\ev
\item[Description] ~\hfill

  Allocate a new
  \hyperref[S:BLOCK_DOF_MATRIX_struct]{\code{BLOCK\_DOF\_MATRIX}}
  structure. Call
  \hyperref[S:libblocksolve:free_block_dof_matrix_fct]{\code{free\_block\_dof\_matrix()}} to release the associated memory.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:get_block_dof_matrix:name}{name} A
    descriptive name, useful for debugging purposes and
    pretty-printing. \code{name} is duplicating by a call to
    \code{strdup(3)}.
    %% 
  \hyperitem{libblocksolve:get_block_dof_matrix:n_row}{n\_row}
  \hyperitem{libblocksolve:get_block_dof_matrix:n_col}{n\_col}
    The number of row- and column-blocks.
    %% 
  \hyperitem{libblocksolve:get_block_dof_matrix:block_type}{block\_type}
    The
    \hyperlink{libblocksolve:BLOCK_DOF_MATRIX:block_type}{block-type},
    as explained in \secref{S:BLOCK_DOF_MATRIX_struct}.
    %% 
  \hyperitem{libblocksolve:get_block_dof_matrix:first_fe_space}{first\_fe\_space}
    The finite element spaces defining the blocks. The function
    expects them to be ordered alternating: first row space, first
    column space, second row space, second column space. If
    \code{n\_cols != n\_rows}, then the trailing ``excess'' spaces are
    specified one after another. If a \nil-pointer is encountered,
    then the preceding finite element space is used for all remaining
    rows and columns.
    %% 
  \end{descr}
\item[Return Value] ~\hfill

  A pointer to a newly allocated
  \hyperref[S:BLOCK_DOF_MATRIX_struct]{\code{DOF\_DOF\_BLOCK\_MATRIX}}
  structure, use
  \hyperref[S:libblocksolve:free_block_dof_matrix_fct]{\code{free\_block\_dof\_matrix()}}
  to release the associated resources and delete the matrix.
\item[Examples] ~\hfill

  The interested reader is referred to the test program
%%
  \bv\begin{verbatim}
alberta-VERSION/add_ons/block_solver/demo/Common/quasi-stokes.c
\end{verbatim}\ev
\end{function}

\begin{function}{free\_block\_dof\_matrix()}
\label{S:libblocksolve:free_block_dof_matrix_fct}
%%
\fdx{free_block_dof_matrix()@{\code{free\_block\_dof\_matrix()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!free_block_dof_matrix@{\code{free\_block\_dof\_matrix()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
void free_block_dof_matrix(BLOCK_DOF_MATRIX *bmatrix);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
free_block_dof_matrix(block_matrix);
\end{lstlisting}\ev
\item[Description] ~\hfill

  Release a matrix previously allocated by a call to
  \hyperref[S:libblocksolve:get_block_dof_matrix_fct]{\code{get\_block\_dof\_matrix()}}.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:free_block_dof_matrix:block_matrix}{block\_matrix}
    The matrix to destroy.
    %% 
  \end{descr}
\end{function}

\begin{function}{clear\_block\_dof\_matrix()}
\label{S:libblocksolve:clear_block_dof_matrix_fct}
\label{S:libblocksolve:clear_block_dof_schar_matrix_fct}
%%
\fdx{clear_block_dof_matrix()@{\code{clear\_block\_dof\_matrix()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!clear_block_dof_matrix@{\code{clear\_block\_dof\_matrix()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
void clear_block_dof_matrix(BLOCK_DOF_MATRIX *bmatrix);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
clear_block_dof_matrix(block_matrix);
\end{lstlisting}\ev
\item[Description] ~\hfill

  Clear the entries of a
  \hyperref[S:BLOCK_DOF_MATRIX_struct]{\code{BLOCK\_DOF\_MATRIX}}.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:clear_block_dof_matrix:block_matrix}{block\_matrix}
    The matrix to clear to $0$.
    %% 
  \end{descr}
\end{function}

\begin{function}{oem\_block\_solve()}
\label{S:libblocksolve:oem_block_solve_fct}
%%
\fdx{oem_block_solve()@{\code{oem\_block\_solve()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!oem_block_solve()@{\code{oem\_block\_solve()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
int oem_block_solve(const BLOCK_DOF_MATRIX *A,
                    const BLOCK_DOF_SCHAR_VEC *bound,
                    const BLOCK_DOF_VEC *f, BLOCK_DOF_VEC *u,
                    OEM_SOLVER solver,
                    REAL tol,
                    const PRECON *precon,
                    int restart, int max_iter, int info);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
iterations =
  oem_block_solve(A, bound, f, u, solver,
                  tol, precon, restart, max_iter, info);
\end{lstlisting}\ev
\item[Description] ~\hfill

  The reader is referred to
  \hyperref[S:oem_solve_fct]{\code{oem\_solver()}} for further
  explanations. \code{oem\_solve()} and \code{oem\_block\_solver()}
  differ only in that the latter accepts block-vectors and -matrices,
  and the former accepts ordinary DOF-vectors and -matrices as arguments.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:oem_block_solve:A}{A} The system matrix.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:bound}{bound} A flag-vector
    to mask-out certain DOFs, e.g. to implement Dirichlet boundary
    conditions.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:f}{f} The load vector.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:u}{u} Storage for the
    solution and initial guess for the iterative solver.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:solver}{solver} Use the
    respective OEM-solver; see \hyperref[enum:OEM_SOLVER]{above} for
    the available keywords.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:tol}{tol} Tolerance for the
    residual; if the norm of the residual is less or equal \code{tol},
    \code{oem\_solve\_[s|d|dow]()} returns the actual iterate as the
    approximative solution of the system.
    %%  
  \hyperitem{libblocksolve:oem_block_solve:tol}{tol} A pointer to a
    structure describing the preconditioner to use, see further below
    in \secref{S:libblocksolve:init_oem_block_precon_fct}.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:restart}{restart} Only used
    by \code{gmres}: the maximum dimension of the Krylov-space.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:max_iter}{max\_iter}
    Maximal number of iterations to be performed by the linear solver.
    This can be compared with the return value -- which gives the
    number of iterations actually performed -- to determine whether
    the solver has achieved its goal.
    %% 
  \hyperitem{libblocksolve:oem_block_solve:info}{info} This is the
    level of information of the linear solver; \code{0} is the lowest
    level of information (no information is printed) and \code{10} the
    highest level.
  \end{descr}
\item[Return Value] ~\hfill
  
  The number of iterations the solver needed until the norm of the
  residual was below \code{tol}, or \code{max\_iter} if the solver was
  not able to reach its goal before the prescribed maximum iteration
  count was exhausted.
\item[Examples] ~\hfill

  The interested reader is referred to the test program
%%
  \bv\begin{verbatim}
alberta-VERSION/add_ons/block_solver/demo/Common/quasi-stokes.c
\end{verbatim}\ev
\end{function}

\begin{function}{init\_oem\_block\_precon()}
\label{S:libblocksolve:init_oem_block_precon_fct}
%%
\fdx{init_oem_block_precon()@{\code{init\_oem\_block\_precon()}}}
\idx{add_ons@{\code{add\_ons}}!liboem_block_solve@{\code{liboem\_block\_solve}}!init_oem_block_precon()@{\code{init\_oem\_block\_precon()}}}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
const PRECON *
init_oem_block_precon(const BLOCK_DOF_MATRIX *A,
                      const BLOCK_DOF_SCHAR_VEC *bound,
                      int info,
                      const BLOCK_PRECON_TYPE *prec_type);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
precon = init_oem_block_precon(A, bound, info, prec_type);
\end{lstlisting}\ev
\item[Description] ~\hfill

  The reader should compare this functions with
  \hyperref[S:init_precon_from_type_fct]{\code{init\_precon\_from\_type()}}
  on page \pageref{S:init_precon_from_type_fct}.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libblocksolve:init_oem_block_precon:A}{A} The matrix to
    compute the preconditioner for.
    %% 
  \hyperitem{libblocksolve:init_oem_block_precon:bound}{bound} A
    flag-vector, masking out specific DOFs, compare the explanations
    for the \hyperlink{oem_solve:mask}{\code{mask}} parameter to
    \hyperref[S:oem_solve_fct]{\code{oem\_solve()}}, see
    \secref{S:oem_solve_fct}. \code{bound} may be \nil.
    %%
  \hyperitem{libblocksolve:init_oem_block_precon:info}{info} An
    integer controlling the amount of information printed to the
    terminal the application is running in (larger values mean more
    ``noise'').
    %%
  \hyperitem{libblocksolve:init_oem_block_precon:prec_type}{prec\_type}
    A pointer to a structure of type
    \hyperref[S:BLOCK_PRECON_TYPE_struct]{\code{BLOCK\_PRECON\_TYPE}},
    as described in \secref{S:BLOCK_PRECON_TYPE_struct} above,
    describing the preconditioner to generate.
  \end{descr}
\item[Return Value] ~\hfill
  
  A pointer to an initialized
  \hyperref[S:PRECON_struct]{\code{PRECON}} structure implementing the
  preconditioner, see \secref{S:PRECON_struct}.
\item[Examples] ~\hfill

  The interested reader is referred to the test program
%%
  \bv\begin{verbatim}
alberta-VERSION/add_ons/block_solver/demo/Common/quasi-stokes.c
\end{verbatim}\ev
\end{function}

\begin{function}{[\dots]()}
\label{S:libblocksolve:undocumented}

\item[Description]~\hfill

The remaining functions are also implemented, the reader is referred
to the \secref{S:dof_vec_skel} for similar functions for ordinary
\hyperref[T:DOF_REAL_VEC]{\code{DOF\_REAL\_VEC}} structures.

\item[Prototypes]~\hfill
\bv\begin{lstlisting}
void block_dof_copy(const BLOCK_DOF_VEC *x, BLOCK_DOF_VEC *y);
void block_dof_set(REAL stotz, BLOCK_DOF_VEC *bvec);
int copy_from_block_dof_vec(REAL *x, BLOCK_DOF_VEC *bdof);
int copy_to_block_dof_vec(BLOCK_DOF_VEC *bdof, REAL *x);
int block_dof_vec_length(BLOCK_DOF_VEC *bdof);
\end{lstlisting}\ev
\end{function}

\subsection{\code{add\_ons/geomview/}}
\label{S:geomview_addon}

A stand-alone viewer to convert simulation data as produced by
\ALBERTA's \hyperref[S:file_formats]{IO-routines} (see
\secref{S:file_formats}) to OOGL-format, which is the data format
understood by Geomview. See also \secref{S:graph_Geomview}.
(Claus-Justus Heine, Carsten Eilks)

\subsection{\code{add\_ons/gmv/}}
\label{S:gmv_addon}

A stand-alone program to convert \ALBERTA data-files (see
\secref{S:file_formats}) to GMV format, see also \secref{S:graph_GMV}.
The program in the \code{add\_ons/} directory is just a wrapper,
calling the library functions described in \secref{S:graph_GMV}
(courtesy to Daniel K\"oster).

\subsection{\code{add\_ons/grape/}}
\label{S:grape_addon}

The Grape interface, see also \secref{S:graph_GRAPE} (Alfred Schmidt,
Kunibert G. Siebert, Robert Kl\"ofkorn, Claus-Justus Heine and
probably others).

\subsection{\code{add\_ons/libalbas/}}
\label{S:libalbas_addon}

A basis-function add-on, with the focus on stable discretisations of
the Stokes problem (Claus-Justus Heine). The additional basis function
sets are on the one hand available through \ALBERTA basis-function
plugin-mechanism (see \secref{S:fancy_bas_fcts}), and otherwise
through the following functions:
%%
\fdx{get_bubble()@{\code{get\_bubble()}}}
\idx{add_ons@{\code{add\_ons}}!libalbas!get_bubble()@{\code{get\_bubble()}}}
%%
\fdx{get_wall_bubbles()@{\code{get\_wall\_bubbles()}}}
\idx{add_ons@{\code{add\_ons}}!libalbas!get_wall_bubbles()@{\code{get\_wall\_bubbles()}}}
%%
\fdx{get_trace_bubble()@{\code{get\_trace\_bubble()}}}
\idx{add_ons@{\code{add\_ons}}!libalbas!get_trace_bubble()@{\code{get\_trace\_bubble()}}}
%%
\fdx{get_raviart_thomas()@{\code{get\_raviart\_thomas()}}}
\idx{add_ons@{\code{add\_ons}}!libalbas!get_raviart_thomas()@{\code{get\_raviart\_thomas()}}}
%%
\bv\begin{lstlisting}
const BAS_FCTS *bas_fcts_init(int dim, int dow, const char *name);

const BAS_FCTS *get_null_bfcts(unsigned dim);
const BAS_FCTS *get_bubble(unsigned dim, unsigned inter_deg);
const BAS_FCTS *get_wall_bubbles(unsigned dim, unsigned inter_deg);
const BAS_FCTS *get_trace_bubble(unsigned dim, unsigned inter_deg);
const BAS_FCTS *get_raviart_thomas(unsigned dim, unsigned inter_deg);
const BAS_FCTS *get_old_mini_element(unsigned dim);

typedef struct stokes_pair STOKES_PAIR;
struct stokes_pair 
{
  const BAS_FCTS *velocity;
  const BAS_FCTS *pressure;
  /* const BAS_FCTS *slip_stress; */
};
STOKES_PAIR stokes_pair(const char *name, unsigned dim, unsigned degree);
\end{lstlisting}\ev

We document only
\hyperref[S:bas_fcts_init_fct]{\code{bas\_fcts\_init()}} and
\hyperref[S:stokes_pair_fct]{\code{stokes\_pair()}}, the other
functions are self-explanatory after reading the documentation for 
\hyperref[S:bas_fcts_init_fct]{\code{bas\_fcts\_init()}} below.
%%
\begin{function}{bas\_fcts\_init()}
\label{S:bas_fcts_init_fct}
%% 
\fdx{bas_fcts_init()@{\code{bas\_fcts\_init()}}|(}
\idx{add_ons@{\code{add\_ons}}!libalbas!bas_fcts_init()@{\code{bas\_fcts\_init()}}|(}
%%
\item[Prototype] ~\hfill
  %% 
  \bv\begin{lstlisting}
const BAS_FCTS *bas_fcts_init(int dim, int dow, const char *name);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
bas_fcts = bas_fcts_init(dim, DIM_OF_WORLD, name);
\end{lstlisting}\ev
\item[Description] ~\hfill

  The entry point when using \code{libalbas} as
  \hyperref[S:fancy_bas_fcts]{plugin-module} (see
  \secref{S:fancy_bas_fcts}), but also an ordinary library function
  which can be called by functions linked against \code{libalbas}.

\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libalbas:bas_fcts_init:dim}{dim} The desired dimension of
    the basis functions.
    %% 
  \hyperitem{libalbas:bas_fcts_init:dow}{dow} This should equal \DOW.
    As \code{libalbas} can be used as a plugin which is loaded
    according to the value of an environment variable (see
    \secref{S:fancy_bas_fcts}), the parameter \code{dow} can be used
    by the library for sanity checks.
    %% 
  \hyperitem{libalbas:bas_fcts_init:name}{name} In \ALBERTA basis
    functions are identified by a unique name.
    \code{bas\_fcts\_init()} currently implements the following basis
    function sets:
    \begin{descr}
    \hyperitem{libalbas:bas_fcts_init:P1Bubble}{"P1+bubble"} An older
      implementation of the velocity component of the Mini-element.
      This implementation does \emph{not} use the
      \hyperref[S:chain_impl]{direct sum} framework (see
      \secref{S:chain_impl}).
      %%
    \hyperitem{libalbas:bas_fcts_init:Bubble}{"Bubble[\_IX][\_Nd]"} A
      single element bubble $b_T$,
      \[
      b_T(\lambda)=w(\code{dim})\,\prod_{i=0}^{\code{dim}}\lambda_i,
      \]
      where the scaling factor $w(\code{dim})$ is chosen such that the
      bubble has mean-value $1$ on the reference element. The
      ``\code{\_Nd}'' suffix is optional, if present, it is compared
      against the parameter \code{dim} as sanity check. The
      ``\code{\_IX}'' part is optional, too. If present, it specifies
      the degree of a quadrature rule used for the interpolation
      operator. The interpolation operator uses the mean-value of the
      non-interpolated function as value for the single DOF per
      element. If the bubble-function belongs to a
      \hyperref[S:chain_impl]{chain} of basis functions, then the
      interpolation operator take the mean value of the other
      components of the corresponding direct sum into account, so the
      resulting interpolant will have the same mean-value as the
      non-interpolated function on each element. The default
      interpolation degree is $0$ (respectively $1$, using the
      standard $1$-point formula).
      %%
    \hyperitem{libalbas:bas_fcts_init:WallBubbles}{"WallBubbles[\_IX][\_Nd]"}
      A \DOW-valued basis function set which consists the
      face-bubbles. This basis function set comes with an
      \hyperref[S:init_element]{per-element initializer} (see
      \secref{S:init_element}) as it depends on the geometry of the
      element: the bubbles point in normal direction with respect to
      the faces of each element. Using a formula:
      \[
      b^e_i=
      \pm\,w(\code{dim})\,
      \big(\prod_{\atop{j=0,\,\dots\,\code{dim}}{j \neq i}}\lambda_j\big)
      \,\nu_i,
      \]
      where $\nu_i$ denotes the normal to the $i$-the face of the
      element. The scaling factor is chosen such that the mean-value
      over the faces of the reference simplex is $1$ for each bubble.
      The sign is chosen such that the resulting finite element space
      consists of globally continuous functions. The current
      implementation does not take curved boundaries into account. The
      ``\code{\_IX}'' and ``\code{\_Nd}'' parts are optional. The
      \code{X} denotes the quadrature degree of a quadrature formula
      used for interpolation. The interpolation operator determines
      the local DOFs such that the flux of the interpolated function
      across the boundaries of each element is the same as the flux of
      the non-interpolated function, up to quadrature errors. The
      default quadrature degree is again $0$ (respectively $1$, see
      above in the explanations for the element bubble).
      %%
    \hyperitem{libalbas:bas_fcts_init:TraceBubbles}{"TraceBubbles[\_IX][\_Nd]"}
      This is the trace-space of the face-bubbles (compare with the
      \hyperlink{BAS_FCTS:trace_bas_fcts}{\code{trace\_bas\_fcts}}
      component in the \hyperref[T:BAS_FCTS]{\code{BAS\_FCTS}}
      structure, see \secref{S:BAS_FCTS}).
      %%
    \hyperitem{libalbas:bas_fcts_init:RaviartThomas}{"RaviartThomas"}
      This is the lowest-order Raviart-Thomas element. However, the
      code is untested and was primarily meant as a sketch.
      %%
    \hyperitem{libalbas:bas_fcts_init:directsum}{"\dots\#\dots"} Any
      string containing a ``\code{\#}'' letter is first decomposed
      into separate tokens, separated by the ``\code{\#}'' signs. The
      individual components are then generated by calls to \ALBERTA's
      \hyperref[F:get_bas_fcts_fct]{\code{get\_bas\_fcts()}} routine,
      and then chained together by calls to
      \hyperref[S:bfcts_chains]{\code{chain\_bas\_fcts()}}, see
      \secref{S:bfcts_chains}.
    \end{descr}
    %% 
  \end{descr}
\item[Return Value] ~\hfill
  
A pointer to new \hyperref[T:BAS_FCTS]{\code{BAS\_FCTS}} structure, as
requested by the parameter \code{name}, or \nil in case that the request
could not be serviced.
\item[Examples] ~\hfill

The interested reader is referred to the source-code for the
\hyperref[S:stokes_pair_fct]{\code{stokes\_pair()}} function in
\code{alberta-VERSION/add\_ons/libalbas/src/basfcts.c}
\end{function}
%% 
\fdx{bas_fcts_init()@{\code{bas\_fcts\_init()}}|)}
\idx{add_ons@{\code{add\_ons}}!libalbas!bas_fcts_init()@{\code{bas\_fcts\_init()}}|)}
%% 

\begin{function}{stokes\_pair()}
\label{S:stokes_pair_fct}
\label{S:STOKES_PAIR_struct}
%% 
\fdx{stokes_pair()@{\code{stokes\_pair()}}|(}
\idx{add_ons@{\code{add\_ons}}!libalbas!stokes_pair()@{\code{stokes\_pair()}}|(}
%% 

\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
typedef struct stokes_pair 
{
  const BAS_FCTS *velocity;
  const BAS_FCTS *pressure;
  /* const BAS_FCTS *slip_stress; */
} STOKES_PAIR;

STOKES_PAIR stokes_pair(const char *name, unsigned dim, unsigned degree);
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
stokes_pair_struct = stokes_pair(name, dim, degree);
\end{lstlisting}\ev
\item[Description] ~\hfill

  Generate some of the known stable mixed discretizations for the
  Stokes-problem, the explanations for the parameter \code{name}
  below.
\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{libalbas:stokes_pair:name}{name} The name of the
    Stokes-pair. The function understands the following names:
    \begin{descr}
    \kitem{"Mini"} Generate the so-called ``Mini element'': the
      velocity space consists of the direct sum of a linear Lagrange
      element and an \hyperlink{libalbas:bas_fcts_init:Bubble}{element
        bubble}, and the pressure space is a linear Lagrange space.
      The parameter \code{degree} to \code{stokes\_pair()} controls
      the quadrature degree for the interpolation operator, see the
      explanations for
      \hyperref[S:bas_fcts_init_fct]{\code{bas\_fcts\_init()}} above
      in \secref{S:bas_fcts_init_fct}.
      %%
    \kitem{"TaylorHood"} The classical Taylor-Hood element. The
      parameter \code{degree} controls the degree of the velocity
      space in this case.
      %%
    \kitem{"BernardiRaugel"} Generate the ``Bernardi-Raugel'' element:
      the velocity space is constructed as the direct sum of a linear
      Lagrange space and the space of
      \hyperlink{libalbas:bas_fcts_init:WallBubbles}{face bubbles}
      described in \secref{S:bas_fcts_init_fct} above.  The parameter
      \code{degree} to \code{stokes\_pair()} controls the quadrature
      degree for the interpolation operator, see the explanations for
      \hyperref[S:bas_fcts_init_fct]{\code{bas\_fcts\_init()}} above
      in \secref{S:bas_fcts_init_fct}.

      The pressure space for the ``Bernardi-Raugel'' element consists
      of the space of discontinuous, element-wise constant functions.
      %%
    \kitem{CrouzeixRaviart} Generate the quadratic
      ``Crouzeix-Raviart-Mansfield'' element: the velocity space
      consists of the direct sum of a quadratic Lagrange space with an
      %%
      \hyperlink{libalbas:bas_fcts_init:Bubble}{element bubble} in 2d,
      %%
      and of a three-component direct sum in 3d, where additionally
      \hyperlink{libalbas:bas_fcts_init:WallBubbles}{face bubbles}
      have to be added. The pressure space is piece-wise linear and
      discontinuous.

      The parameter \code{degree} controls the degree of the
      quadrature formula used for the interpolation operator, see see
      the explanations for
      \hyperref[S:bas_fcts_init_fct]{\code{bas\_fcts\_init()}} above
      in \secref{S:bas_fcts_init_fct}.
    \end{descr}
    %% 
  \hyperitem{libalbas:stokes_pair:dim}{dim} The (mesh-)dimension of
    the requested set of basis functions.
    %% 
  \hyperitem{libalbas:stokes_pair:degree}{degree} As explained above,
    the meaning of this parameter changes, depending on which
;    Stokes-pair is requested.
    %% 
  \end{descr}
\item[Return Value] ~\hfill

  An instance of a \code{STOKES\_PAIR} structure. Note that this is
  not a pointer, but a real instance of that structure.
\end{function}
%% 
\fdx{stokes_pair()@{\code{stokes\_pair()}}|)}
\idx{add_ons@{\code{add\_ons}}!libalbas!stokes_pair()@{\code{stokes\_pair()}}|)}
%% 

\subsection{\code{add\_ons/meshtv/}}
\label{S:meshtv_addon}

A stand-alone program to convert \ALBERTA data-files (see
\secref{S:file_formats}) to SILO/MeshTV format.
(Daniel K\"oster).

\subsection{\code{add\_ons/paraview/}}
\label{S:paraview_addon}

A stand-alone program to convert \ALBERTA data-files (see
\secref{S:file_formats}) to Paraview format, see
\secref{S:graph_paraview}.  (Rebecca Stotz).

\subsection{\code{add\_ons/static\_condensation/}}
\label{S:static_condensation_addon}

Static-condensation for Stokes-discretizations with the Mini-element,
thus reducing the dimension of the velocity space by
$\#\text{elements}\times\DOW$. (Rebecca Stotz)

There are versions for the ``gradient'' formulation as well as for the
deformation-tensor formulation, including some timings, comparing time
needed to solve the condensed equations (with the
\hyperref[S:blocksolve_addon]{block-solve add-on}, see
\secref{S:blocksolve_addon} above and the \hyperref[S:OEM]{SYMMLQ}
solver) against the time needed to solve the uncondensed equations
with the \hyperref[S:OEM_SPCG]{CG-method for Schur's complement}.

The add-on comes in the shape of a library
%%
\bv\begin{verbatim}
PREFIX/lib/libstatic_condensation_Xd[_debug].EXTENSION
PREFIX/include/alberta/static-condensation.h
\end{verbatim}\ev
%%
The library defines the following functions:
%%
%% LaTeX code fragment, a template for documenting a function
%%
\begin{function}{condense\_mini\_spp[\_dd]()}
\label{S:condense_mini_spp_fct}
%%
\fdx{condense_mini_spp()@{\code{condense\_mini\_spp()}}|(}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!condense_mini_spp()@{\code{condense\_mini\_spp()}}|(}
%%
\fdx{condense_mini_spp_dd()@{\code{condense\_mini\_spp\_dd()}}|(}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!condense_mini_spp_dd()@{\code{condense\_mini\_spp\_dd()}}|(}
%%
\item[Prototype] ~\hfill
%%
\bv\begin{lstlisting}
void condense_mini_spp(const DOF_REAL_VEC_D *u_h,
                       const DOF_REAL_VEC_D *f_h,
                       const DOF_REAL_VEC *g_h,
                       BNDRY_FLAGS dirichlet_mask,
                       EL_MATRIX_INFO *A_minfo, 
                       EL_MATRIX_INFO *B_minfo,
                       BLOCK_DOF_MATRIX *system_matrix, 
                       BLOCK_DOF_VEC *up_h,
                       BLOCK_DOF_VEC *load_vector) 

void condense_mini_spp_dd(const DOF_REAL_VEC_D *u_h, 
                          const DOF_REAL_VEC_D *f_h,
                          const DOF_REAL_VEC *g_h, 
                          BNDRY_FLAGS dirichlet_mask,
                          EL_MATRIX_INFO *A_minfo, 
                          EL_MATRIX_INFO *B_minfo,
                          BLOCK_DOF_MATRIX *system_matrix, 
                          BLOCK_DOF_VEC *up_h,
                          BLOCK_DOF_VEC *load_vector) 

\end{lstlisting}\ev

\item[Synopsis] ~\hfill

\bv\begin{lstlisting}[basicstyle=\normalsize]
condense_mini_spp(u_h, f_h, g_h, dirichlet_mask, 
                  A_minfo, B_minfo, 
                  system_matrix, up_h, load_vector);

condense_mini_spp_dd(u_h, f_h, g_h, dirichlet_mask, 
                     A_minfo, B_minfo, 
                     system_matrix, up_h, load_vector);
\end{lstlisting}\ev
\item[Description] ~\hfill

  We consider the saddle point problem, with
  \hyperref[S:get_lagrange]{Lagrange}
  and
  \hyperlink{libalbas:bas_fcts_init:Bubble}{bubble}
  basis-functions:
  \[
  \left[
    \begin{matrix}
      A_{11} &  A_{12} & B_1 \\
      A_{21} &  A_{22} & B_2 \\
      B_1^t  &  B_2^t  & 0 
    \end{matrix}\right]\cdot\left[
    \begin{matrix}
      u_{h,1} \\ u_{h,2} \\ p_h
    \end{matrix}\right]
  =\left[
    \begin{matrix}
      f_{h,1} \\ f_{h,2} \\ g_h
    \end{matrix}\right],
  \]
  where, e.g. $u_{h,1}$ and $f_{h,1}$ are the Lagrange-components of
  the velocity field and the load-vector for the velocity and
  $u_{h,2}$ and $f_{h,2}$ are the bubble-components.  This problem
  will be converted into an new system:
  \[
  \left[
    \begin{matrix}
      A_{single} & B_{single} \\
      B^t_{single} &  C_{single} 
    \end{matrix}\right]\cdot\left[
    \begin{matrix}
      u_{h,single} \\ p_{h,single}
    \end{matrix}\right]
  =\left[
    \begin{matrix}
      f_{h,single} \\ g_{h,single}
    \end{matrix}\right],
  \]
  which is equivalent to
  \[
  \code{system\_matrix} \cdot \code{up\_h} = \code{load\_vector}.
  \]
  The function \code{condense\_mini\_spp()} converts the saddle point problem as follows
  \begin{equation}\label{eq:static-condensation-01}
    \begin{split}
      u_{h,single}  &= u_1 = \code{up\_h->dof\_vec[0]},\\ 
      p_{h,single} &= p = \code{up\_h->dof\_vec[1]},\\
      f_{h,single} &= f_{h,1} - A_{12}\ A_{22}^{-1}\  f_{h,2}
      = \code{load\_vector->dof\_vec[0]},\\
      g_{h,single} &= g - B^t_2\  A_{22}^{-1}\  f_2 
      = \code{load\_vector->dof\_vec[1]},\\ 
      A_{single}  &= A_{11} - A_{12}\  A_{22}^{-1}\  A_{21}
      = \code{system\_matrix->dof\_mat[0][0]},\\ 
      B_{single}  &= B_1 - A_{12}\  A_{22}^{-1}\  B_2  
      = \code{system\_matrix->dof\_mat[0][1]}, \\
      B^t_{single} &= (B_{single})^{tr}  
      = \code{system\_matrix->dof\_mat[1][0]},\\
      C_{single}  &= - B^t_2\  A_{22}^{-1}\  B_2     
      = \code{system\_matrix->dof\_mat[1][1]}.
    \end{split}
  \end{equation}

\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{condense_mini_spp:u_h}{u\_h} Storage of the principal
    unknown, and start-value for an iterative solver. In the context
    of \hyperref[S:dirichlet_bound]{Dirichlet boundary conditions}
    (see \secref{S:dirichlet_bound}) the application has to make sure
    that \code{u\_h} already incorporates (interpolated) Dirichlet
    boundary conditions.
    %% 
  \hyperitem{condense_mini_spp:f_h}{f\_h} Load-vector for the
    principal equations.
    %% 
  \hyperitem{condense_mini_spp:g_h}{g\_h} Load-vector for the
    constraint equation.
    %% 
  \hyperitem{condense_mini_spp:dirichlet_mask}{dirichlet\_mask} A
    bit-mask describing which parts of the boundary should be treated
    as Dirichlet-boundary, see \secref{S:dirichlet_bound}.
    \emph{Note:} \code{dirichlet\_mask} must not be \nil.
    %% 
  \hyperitem{condense_mini_spp:A_minfo}{A\_minfo} Element matrix
    information to assemble matrix $A = \begin{pmatrix} A_{11} &
      A_{12}\\ A_{21} & A_{22} \end{pmatrix}$. The static condensation
    only works if $A_{22}$ is diagonal, which is the case for the
    \hyperlink{libalbas:get_bas_fcts:Bubble}{bubble} basis-functions
    because they ``live'' only on one element.
    %% 
  \hyperitem{condense_mini_spp:B_minfo}{B\_minfo} Element matrix
    information to assemble the matrix $B = \begin{pmatrix} B_1 \\
      B_2\end{pmatrix}$.
    %% 
  \hyperitem{condense_mini_spp:system_matrix}{system\_matrix} Storage
    for the new matrices of the condensed system. It is a pointer to a
    \code{BLOCK\_DOF\_MATRIX} structure, in which the matrices
    $A_{single}$, $B_{single}$, $B^t_{single}$ and $C_{single}$ are
    stored, as shown in equation \eqref{eq:static-condensation-01}.
    %% 
  \hyperitem{condense_mini_spp:up_h}{up\_h} Storage for the condensed
    solution. It is a pointer to a \code{BLOCK\_DOF\_VEC} structure,
    \code{up\_h->dof\_vec[0]} is the storage for the lagrange
    components of the velocity and \code{up\_h->dof\_vec[1]} is the
    storage for the pressure.
    %% 
  \hyperitem{condense_mini_spp:load_vector}{load\_vector} Load-vector
    of the condensed system, as shown in
    \eqref{eq:static-condensation-01}.
    %% 
  \end{descr}

\item[Examples] ~\hfill

  In subdirectory \code{static\_condensation/demo}, there are two demo
  programs, \code{mini-stokes.c} and \code{mini-quasi-stokes.c} as an
  example how to use the functions \code{condense\_mini\_spp()},
  \code{condense\_mini\_spp\_dd()} and \code{expand\_mini\_spp()},
  \code{expand\_mini\_spp\_dd()}.

\end{function}
%%
\fdx{condense_mini_spp()@{\code{condense\_mini\_spp()}}|)}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!condense_mini_spp()@{\code{condense\_mini\_spp()}}|)}
%%
\fdx{condense_mini_spp_dd()@{\code{condense\_mini\_spp\_dd()}}|)}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!condense_mini_spp_dd()@{\code{condense\_mini\_spp\_dd()}}|)}
%%

\begin{function}{expand\_mini\_spp[\_dd]()}
\label{S:expand_mini_spp}
%% 
\fdx{expand_mini_spp()@{\code{expand\_mini\_spp()}}|(}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!expand_mini_spp()@{\code{expand\_mini\_spp()}}|(}
%%
\fdx{expand_mini_spp_dd()@{\code{expand\_mini\_spp\_dd()}}|(}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!expand_mini_spp_dd()@{\code{expand\_mini\_spp\_dd()}}|(}
%%
\item[Prototype] ~\hfill
  %% 
  \bv\begin{lstlisting}
void expand_mini_spp(const BLOCK_DOF_VEC *up_h, 
                     const DOF_REAL_VEC_D *f_h,
                     DOF_REAL_VEC_D *uh, 
                     BNDRY_FLAGS dirichlet_mask,
                     EL_MATRIX_INFO *A_minfo, 
                     EL_MATRIX_INFO *B_minfo)

void expand_mini_spp_dd(const BLOCK_DOF_VEC *up_h, 
                        const DOF_REAL_VEC_D *f_h,
                        DOF_REAL_VEC_D *uh, 
                        BNDRY_FLAGS dirichlet_mask,
                        EL_MATRIX_INFO *A_minfo, 
                        EL_MATRIX_INFO *B_minfo)
\end{lstlisting}\ev

\item[Synopsis] ~\hfill

  \bv\begin{lstlisting}[basicstyle=\normalsize]
expand_mini_spp(up_h, f_h, uh, dirichlet_mask,
                A_minfo, B_minfo);

expand_mini_spp_dd(up_h, f_h, uh, dirichlet_mask,
                   A_minfo, B_minfo);
\end{lstlisting}\ev
\item[Description] ~\hfill

  The functions \code{expand\_mini\_spp()} and
  \code{expand\_mini\_spp\_dd()} reconstruct the bubble-components
  which were eliminated by the function
  \hyperref[S:condense_mini_spp_fct]{\code{condense\_mini\_spp()}} or
  \hyperref[S:condense_mini_spp_fct]{\code{condense\_mini\_spp\_dd()}}
  or (see \secref{S:condense_mini_spp_fct}). The functions recompose
  the Lagrange-components and the bubble-components and store them in
  \code{uh}.

  The bubble-component of $u$ is reconstructed as follows
  \[
  u_{h,2} = A_{22}^{-1}\ (f_{h,2} - A_{21}\ u_{h,1} - B_2\ p_h).
  \]
  Note that $A_{22}$ is a diagonal matrix, so this operation is
  comparatively cheap.

\item[Parameters]~\hfill
  \begin{descr}
  \hyperitem{expand_mini_spp:up_h}{up\_h} The principal unknown, after
    solving the condensed system.
    %% 
  \hyperitem{expand_mini_spp:f_h}{f\_h} Load-vector for the principal
    equations.
    %% 
  \hyperitem{expand_mini_spp:uh}{uh} Storage for the recomposed solution
    of the principal equations.
    %% 
  \hyperitem{expand_mini_spp:dirichlet_mask}{dirichlet\_mask} A
    bit-mask describing which parts of the boundary should be treated
    as Dirichlet-boundary. \emph{Note:} \code{dirichlet\_mask} must
    not be \nil.
    %% 
  \hyperitem{expand_mini_spp:A_minfo}{A\_minfo}
    \hyperref[T:EL_MATRIX_INFO]{Element matrix information} for
    assembling the matrix $A = \begin{pmatrix} A_{11} & A_{12}\\
      A_{21} & A_{22} \end{pmatrix}$.  The static condensation only
    works if $A_{22}$ is diagonal, which is the case for the
    \hyperlink{libalbas:get_bas_fcts:Bubble}{bubble} basis-functions
    because they ``live'' only on one element.
    %% 
  \hyperitem{expand_mini_spp:B_minfo}{B\_minfo}
    \hyperref[T:EL_MATRIX_INFO]{Element matrix information}
    to assemble the matrix $B = \begin{pmatrix} B_1 \\ B_2\end{pmatrix}$.
    %% 
  \end{descr}

\item[Examples] ~\hfill

  In subdirectory \code{static\_condensation/demo}, there are two demo
  programs, \code{mini-stokes.c} and \code{mini-quasi-stokes.c} as an
  example how to use the functions \code{condense\_mini\_spp()},
  \code{condense\_mini\_spp\_dd()} and \code{expand\_mini\_spp()},
  \code{expand\_mini\_spp\_dd()}. One for
\end{function}
%% 
%% 
\fdx{expand_mini_spp()@{\code{expand\_mini\_spp()}}|)}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!expand_mini_spp()@{\code{expand\_mini\_spp()}}|)}
%%
\fdx{expand_mini_spp_dd()@{\code{expand\_mini\_spp\_dd()}}|)}
\idx{add_ons@{\code{add\_ons}}!static_condensation@{\code{static\_condensation}}!expand_mini_spp_dd()@{\code{expand\_mini\_spp\_dd()}}|)}
%%

\subsection{\code{add\_ons/triangle2alberta/}}
\label{S:triangle2alberta_addon}

A converter from the mesh-generator \emph{Triangle} to \ALBERTA
macro-file format (Daniel K\"oster).

\subsection{\code{add\_ons/write\_mesh\_fig/}}
\label{S:write_mesh_fig_addon}

Contains a function to dump an \ALBERTA-mesh in the
\code{fig}-file-format as understood by the \code{xfig} CAD-tool.
Daniel K\"oster).

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