File: addon-tools.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 (1343 lines) | stat: -rw-r--r-- 52,287 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
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
\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: