File: traverse-impl.tex

package info (click to toggle)
alberta 3.1.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 19,176 kB
  • sloc: ansic: 135,836; cpp: 6,601; makefile: 2,801; sh: 333; fortran: 180; lisp: 177; xml: 30
file content (563 lines) | stat: -rw-r--r-- 24,013 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
\subsection{Mesh traversal routines}%
\label{S:traverse}
\idx{mesh traversal|(}

As described before, the mesh is organized in a binary tree, and
most local information is not stored at leaf element level, but is
generated from hierarchical information and macro element data.  The
generation of such local information is done during tree traversal
routines.

When some work has to be done at each tree element or leaf element,
such a tree traversal is most easily done in a recursive way, calling
some special subroutine at each (leaf) element which implements the
operation that currently has to be done. For some other applications,
it is necessary to operate on the (leaf) elements in another fashion,
where a recursive traversal is not possible.
To provide access for both situations, there exist recursive and
non-recursive mesh traversal routines.

For both styles, selection criteria are available to indicate on which
elements the operation should take place. The following constants are
defined:
\cdx{CALL_EVERY_EL_PREORDER@{\code{CALL\_EVERY\_EL\_PREORDER}}}%
\cdx{CALL_EVERY_EL_INORDER@{\code{CALL\_EVERY\_EL\_INORDER}}}%
\cdx{CALL_EVERY_EL_POSTORDER@{\code{CALL\_EVERY\_EL\_POSTORDER}}}%
\cdx{CALL_LEAF_EL@{\code{CALL\_LEAF\_EL}}}%
\cdx{CALL_LEAF_EL_LEVEL@{\code{CALL\_LEAF\_EL\_LEVEL}}}%
\cdx{CALL_EL_LEVEL@{\code{CALL\_EL\_LEVEL}}}%
\cdx{CALL_MG_LEVEL@{\code{CALL\_MG\_LEVEL}}}%
\bv\begin{lstlisting}
CALL_EVERY_EL_PREORDER  
CALL_EVERY_EL_INORDER   
CALL_EVERY_EL_POSTORDER 
CALL_LEAF_EL            
CALL_LEAF_EL_LEVEL
CALL_EL_LEVEL
CALL_MG_LEVEL
\end{lstlisting}\ev
%
  \code{CALL\_EVERY\_EL\_PREORDER}, \code{CALL\_EVERY\_EL\_INORDER},
  and \code{CALL\_EVERY\_EL\_POSTORDER} all three operate on {\em all}
  hierarchical elements of the mesh. These three differ in the
  sequence of operation on elements: \code{CALL\_EVERY\_EL\_PREORDER}
  operates first on a parent element before operating on both
  children, \code{CALL\_EVERY\_EL\_POSTORDER} operates first on both
  children before operating on their parent, and
  \code{CALL\_EVERY\_EL\_INORDER} first operates on \code{child[0]},
  then on the parent element, and last on \code{child[1]}.

\code{CALL\_LEAF\_EL} operates on {\em all\/} leaf elements of the tree,
whereas \code{CALL\_LEAF\_EL\_LEVEL} operates only on leaf elements
which are exactly at a specified tree depth.
\code{CALL\_EL\_LEVEL} operates on all tree elements at a specified tree 
depth. The option \code{CALL\_MG\_LEVEL} is special for multigrid
operations. It provides the operation on all hierarchy elements on a
specified multigrid level (which is usually \code{el->level/DIM}).

Additional flags are defined that specify which local information in
\hyperref[T:EL_INFO]{\code{EL\_INFO}} has to be generated during the
hierarchical mesh traversal. A bitwise \textsf{OR} of some of these
constants is given as a parameter to the traversal routines. These
flags are more or less self explaining (see also \secref{S:EL_INFO}):
\cdx{FILL_NOTHING@{\code{FILL\_NOTHING}}}%
\cdx{FILL_COORDS@{\code{FILL\_COORDS}}}%
\cdx{FILL_BOUND@{\code{FILL\_BOUND}}}%
\cdx{FILL_NEIGH@{\code{FILL\_NEIGH}}}%
\cdx{FILL_OPP_COORDS@{\code{FILL\_OPP\_COORDS}}}%
\cdx{FILL_ORIENTATION@{\code{FILL\_ORIENTATION}}}%
\cdx{FILL_PROJECTION@{\code{FILL\_PROJECTION}}}%
\cdx{FILL_MACRO_WALLS@{\code{FILL\_MACRO\_WALLS}}}%
\cdx{FILL_NON_PERIODIC@{\code{FILL\_NON\_PERIODIC}}}%
\cdx{FILL_MASTER_INFO@{\code{FILL\_MASTER\_INFO}}}%
\cdx{FILL_MASTER_NEIGH@{\code{FILL\_MASTER\_NEIGH}}}%
\cdx{FILL_ANY@{\code{FILL\_ANY}}}
\begin{descr}
  \kitem{FILL\_NOTHING} no information needed at all.
  %% 
  \kitem{FILL\_COORDS} the vertex coordinates \code{EL\_INFO.coord} are
  filled.
  %% 
  \kitem{FILL\_BOUND} the boundary classification
  \code{EL\_INFO.wall\_bound}, \code{EL\_INFO.vertex\_bound} and
  \code{EL\_INFO.edge\_bound} (in 2d and 3d) are filled. If an
  application only needs the boundary classification of the walls of
  an element, then it is probably more efficient to request the
  \code{FILL\_MACRO\_WALLS} fill-flag and call \code{bndry\_type =
    wall\_bound(el\_info, wall)} to obtain this information.
  %% 
  \kitem{FILL\_NEIGH} neighbour element information
  \code{EL\_INFO.neigh} and \code{EL\_INFO.opp\_vertex} is generated.
  %% 
  \kitem{FILL\_OPP\_COORDS} information about opposite vertex coordinates 
  \code{EL\_INFO.opp\_coords} of neighbours is filled;
  the flag \code{FILL\_OPP\_COORDS} can only be selected 
  in combination with \code{FILL\_COORDS|FILL\_NEIGH}.
  %%
  \kitem{FILL\_ORIENTATION} the element orientation info 
  \code{EL\_INFO.orientation} is generated (3d only).
  %%
  \kitem{FILL\_PROJECTION} information about projection routines for
  new vertices is generated using this flag. The entries
  \code{EL\_INFO.active\_projection} are set.
  %%
  \kitem{FILL\_MACRO\_WALLS} the mapping of the local wall-numbers
  (i.e. faces in 3d, edges in 2d, points in 1d) to the numbering of
  the walls on the ambient macro-element is maintained during
  mesh-traversal. The entries \code{EL\_INFO.macro\_wall} are set.
  %%
 \kitem{FILL\_NON\_PERIODIC} for periodic meshes, ignore the periodic
  structure when computing the neighborhood relations and the boundary
  classification.
  %%
  \kitem{FILL\_MASTER\_INFO} for trace-meshes (AKA
  ``slave-meshes''). During mesh-traversal on the trace-mesh generate
  certain information about the ambient ``master''-element. Certain
  fields of \code{EL\_INFO.master} are valid, depending on which other
  traversal flags are set.
  %%
  \kitem{FILL\_MASTER\_NEIGH} for trace-meshes, implies
    \code{FILL\_MASTER\_INFO} explained above. For trace-meshes
    sliding through an ambient bulk-mesh additionally compute
    information about the neighbour of the ambient master-element
    across the wall forming the element on the trace-mesh. Certain
    fields of \code{EL\_INFO.master} are valid, depending on which
    other traversal flags are set.
  %%
 \kitem{FILL\_ANY} macro definition for a bitwise \textsf{OR} of any
  possible fill flags, used for separating the fill flags from the
  \code{CALL\_...} flags.
\end{descr}

During mesh traversal, such information is generated hierarchically
using the two subroutines
\fdx{fill_macro_info()@{\code{fill\_macro\_info()}}}
\fdx{fill_elinfo()@{\code{fill\_elinfo()}}}
\bv\begin{lstlisting}
void fill_macro_info(MESH *, const MACRO_EL *, EL_INFO *);
void fill_elinfo(int, const EL_INFO *, EL_INFO *);
\end{lstlisting}\ev
Description:
\begin{descr}
  \kitem{fill\_macro\_info(mesh, mel, el\_info)} fills \code{el\_info}
  with macro element information of \code{mel} required by
  \code{el\_info->flag} and sets \code{el\_info->mesh} to \code{mesh}; 
\kitem{fill\_elinfo(ichild, parent\_info, el\_info)} fills \code{el\_info} 
  for the child  \code{ichild} using hierarchy information and parent data
  \code{parent\_info} depending on \code{parent\_info->flag}.
\end{descr}

\subsubsection{Sequence of visited elements}

The sequence of elements which are visited during the traversal is
given by the following rules:
\begin{itemize}
\item All elements in the binary mesh tree of one \code{MACRO\_EL mel}
      are visited prior to any element in the tree of the next macro 
      element in the array \code{mesh->macro\_els}.
\item For every \code{EL el}, all elements in the subtree \code{el->child[0]}
      are visited before any element in the subtree \code{el->child[1]}.
\item The traversal order of an element and its two child trees 
      is determined by the flags \code{CALL\_EVERY\_EL\_PREORDER},
      \code{CALL\_EVERY\_EL\_INORDER}, and
      \code{CALL\_EVERY\_EL\_POSTORDER}, as defined above in
      \secref{S:traverse}.
\end{itemize}
This order can only be changed by explicitly calling the 
\code{traverse\_neighbour()} routine during non-recursive traversal, see below.

\subsubsection{Recursive mesh traversal routines}

Recursive traversal of mesh elements is done by the routine
\fdx{mesh_traverse()@{\code{mesh\_traverse()}}}
\bv\begin{lstlisting}
void mesh_traverse(MESH *,int,FLAGS,void (*)(const EL_INFO *,void *),void *);
\end{lstlisting}\ev
Description:
\begin{descr}
\kitem{mesh\_traverse(mesh, level, fill\_flag, el\_fct, data)} traverses
       the mesh \code{mesh}; the argument \code{level} specifies the
       element level if \code{CALL\_EL\_LEVEL} or
       \code{CALL\_LEAF\_EL\_LEVEL}, or the multigrid level if
       \code{CALL\_MG\_LEVEL} is set in the \code{fill\_flag}; 
       otherwise this variable is ignored; 
       by the argument \code{fill\_flag} the elements to be
       traversed and data to be filled into \code{EL\_INFO} is
       selected, using bitwise \textsf{OR} of one \code{CALL\_...} flag
       and several \code{FILL\_...} flags; the argument \code{el\_fct}
       is a pointer to a function which is called on every element
       selected by the \code{CALL\_...} part of \code{fill\_flag}. The pointer 
       \code{data} is used for opaque user data that should be made available 
       to the \code{el\_fct} routine.

       It is possible to use the recursive mesh traversal recursively,
       by calling \code{mesh\_traverse()} from \code{el\_fct}.
\end{descr}

\begin{example}\label{Ex:measure_omega}
An example of a mesh traversal is the computation of the measure
of the computational domain. On each leaf element, the volume
of the element is computed by the library function \code{el\_volume()}
and added to a global variable \code{measure\_omega}, which finally holds
the measure of the domain after the mesh traversal.
%
\bv\begin{lstlisting}
static void measure_el(const EL_INFO *el_info, void *measure_omega)
{
  *((int *)measure_omega) += el_volume(el_info);
  return;
}

...

measure_omega = 0.0;
mesh_traverse(mesh, -1, CALL_LEAF_EL|FILL_COORDS, measure_el, &measure_omega);
MSG("|Omega| = %e\n", measure_omega);
\end{lstlisting}\ev
%
\code{el\_volume()} computes the element volume and thus needs
information about the elements vertex coordinates.
\end{example}

\begin{example}
We give an implementation of the \code{CALL\_EVERY\_EL\_...}
routines to show the simple structure of all recursive
traversal routines. A data structure \code{TRAVERSE\_INFO}, only used by
the traversal routines, holds the traversal flag and a pointer to
the element function \code{el\_fct()}:
%
\bv\begin{lstlisting}
static void recursive_traverse(EL_INFO *el_info, TRAVERSE_INFO *trinfo)
{
  EL      *el = el_info->el;
  EL_INFO el_info_new;

  if (el->child[0]) 
  {
    if (trinfo->flag & CALL_EVERY_EL_PREORDER)  
      trinfo->el_fct(el_info, trinfo->data);

    fill_elinfo(0, el_info, &el_info_new);
    recursive_traverse(&el_info_new, trinfo);

    if (trinfo->flag & CALL_EVERY_EL_INORDER)
      trinfo->el_fct(el_info, trinfo->data);

    fill_elinfo(1, el_info, &el_info_new);
    recursive_traverse(&el_info_new, trinfo);

    if (trinfo->flag & CALL_EVERY_EL_POSTORDER) 
      trinfo->el_fct(el_info, trinfo->data);
  }
  else
  {
    trinfo->el_fct(el_info, trinfo->data);
  }
  return;
}

static void mesh_traverse_every_el(MESH *mesh, FLAGS fill_flag,
                                   void (*el_fct)(const EL_INFO *, void *),
                                   void *data);
{
  EL_INFO       el_info;
  TRAVERSE_INFO traverse_info;
  int           n;

  el_info.fill_flag = (flag & FILL_ANY);
  el_info.mesh = mesh;

  traverse_info.mesh   = mesh;
  traverse_info.el_fct = el_fct;
  traverse_info.flag   = flag;
  traverse_info.data   = data;

  for(n = 0; n < mesh->n_macro_el; n++) {
    fill_macro_info(mesh->macro_els + n, &el_info);
    recursive_traverse(&el_info, &traverse_info);
  }
  return;
}
\end{lstlisting}\ev
\end{example}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{Non--recursive mesh traversal routines}

Some applications may profit from or actually require a non--recursive
form of mesh traversal, where the element routine gets pointers to
visited elements, one after another. For example, mesh refinement and
coarsening routines (see Sections
\ref{S:refinement_routines} and \ref{S:coarsening_routines}), the
gltools and GRAPE graphic interface (see Sections
\ref{S:graph_gltools} and \ref{S:graph_GRAPE}) are functions which
use a non--recursive access to the mesh elements.

Note that currently non-recursive level-based traversal indicated by
the traversal flags \code{CALL\_EL\_LEVEL},
\code{CALL\_LEAF\_EL\_LEVEL} or \code{CALL\_MG\_LEVEL} is not implemented.

The implementation of the non--recursive mesh traversal routines uses
a stack to save the tree path from a macro element to the current
element. A data structure \code{TRAVERSE\_STACK} holds such
information.  Before calling the non--recursive mesh traversal
routines, such a stack must be allocated (and passed to the traversal
routines). 
\ddx{TRAVERSE_STACK@{\code{TRAVERSE\_STACK}}}
\bv\begin{lstlisting}
typedef struct traverse_stack   TRAVERSE_STACK;
\end{lstlisting}\ev
By allocating a new stack, it is even possible to recursively call the
non--recursive mesh traversal during another mesh traversal without
destroying the stack which is already in use.
For the non--recursive mesh traversal no pointer to an element
function \code{el\_fct()} has to be provided, because all operations are 
done by the routines which call the traversal functions.
A mesh traversal is launched by each call to \code{traverse\_first()}
which also initializes the traverse stack. Advancing to the
next element is done by the function \code{traverse\_next()}.
The following non--recursive routines are provided:
\begin{samepage}
\fdx{get_traverse_stack()@{\code{get\_traverse\_stack()}}}
\fdx{free_traverse_stack()@{\code{free\_traverse\_stack()}}}
\fdx{traverse_first()@{\code{traverse\_first()}}}
\fdx{traverse_next()@{\code{traverse\_next()}}}
\fdx{TRAVERSE_FIRST()@{\code{TRAVERSE\_FIRST()}}}
\mdx{TRAVERSE_FIRST()@{\code{TRAVERSE\_FIRST()}}}
\fdx{TRAVERSE_NEXT()@{\code{TRAVERSE\_NEXT()}}}
\mdx{TRAVERSE_NEXT()@{\code{TRAVERSE\_NEXT()}}}
\bv\begin{lstlisting}
TRAVERSE_STACK *get_traverse_stack(void);
void free_traverse_stack(TRAVERSE_STACK *staci);
const EL_INFO *traverse_first(TRAVERSE_STACK *stack, MESH *, int level, FLAGS fill_flags);
const EL_INFO *traverse_next(TRAVERSE_STACK *stack, const EL_INFO *el_info);
TRAVERSE_FIRST(MESH *mesh, int level, FLAGS fill_flags);
TRAVERSE_NEXT();
const EL_INFO *subtree_traverse_first(TRAVERSE_STACK *stack,
                                      const EL_INFO *local_root,
                                      int level, FLAGS flags);
\end{lstlisting}\ev
\end{samepage}
Descriptions:
\begin{descr}
  \kitem{get\_traverse\_stack()} returns a pointer to a 
  data structure \code{TRAVERSE\_STACK}.
  \kitem{free\_traverse\_stack(stack)} frees the traverse stack
  \code{stack} previously accessed by \code{get\_traverse\_stack()}.
  \kitem{traverse\_first(stack, mesh, level, fill\_flag)} launches the
  non--recursive mesh traversal; the return value is a pointer
  to an \code{el\_info} structure of the first element to be visited;

  \code{stack} is a traverse stack previously accessed by
  \code{get\_traverse\_stack()}; 

  \code{mesh} is a pointer to a mesh to
  be traversed, \code{level} specifies the element level if
  \code{CALL\_EL\_LEVEL} or \code{CALL\_LEAF\_EL\_LEVEL}, or the
  multigrid level if \code{CALL\_MG\_LEVEL} is set; otherwise this
  variable is ignored; 

  \code{fill\_flag} specifies the elements to
  be traversed and data to be filled into \code{EL\_INFO} is selected,
  using bitwise \textsf{OR} of one \code{CALL\_...} flag and several
  \code{FILL\_...} flags;

  \kitem{traverse\_next(stack, el\_info)} returns an \code{EL\_INFO}
  structure with data about the next element of the mesh traversal
  or a pointer to \nil, if \code{el\_info->el} is the last 
  element to be visited;

  information which elements are visited and which data has to be 
  filled is accessible via the traverse stack \code{stack}, initialized
  by \code{traverse\_first()}. After
  calling \code{traverse\_next()}, all \code{EL\_INFO} information about
  previous elements is invalid, the structure may be overwritten with
  new data.

  \kitem{TRAVERSE\_FIRST(mesh, level, fill\_flags), TRAVERSE\_NEXT()}
  are convenience macros which internally call the functions
  \code{get\_traverse\_stack()}, \code{traverse\_first()},
  \code{traverse\_next()} and \code{free\_traverse\_stack()}.
  \code{TRAVERSE\_FIRST()} defines a local variable with name
  \code{el\_info} which holds the information about the current element.

  \kitem{subtree\_traverse\_first(stack, local\_root, level, flags)}
  Like \code{traverse\_first()}, but restricts the traversal to the
  sub-tree starting at \code{local\_root}. Note that
  \code{local\_root} is saved on the traverse-\code{stack}, so it is
  possible to initiate a sub-tree traversal from within the recursive
  \code{mesh\_traverse()} routines with this function, or from within
  another non-recursive traversal loop, if that uses another
  \code{TRAVERSE\_STACK}.
\end{descr}

Usually, the interface to a graphical environment
uses the non--recursive mesh traversal, compare the gltools
(\secref{S:graph_gltools})
and GRAPE interfaces (\secref{S:graph_GRAPE}).

\begin{example}
\fdx{get_traverse_stack()@{\code{get\_traverse\_stack()}}}
\fdx{free_traverse_stack()@{\code{free\_traverse\_stack()}}}
\fdx{traverse_first()@{\code{traverse\_first()}}}
\fdx{traverse_next()@{\code{traverse\_next()}}}
  The computation of the measure of the computational domain with the
  non--recursive mesh traversal routines is shown in the following
  code segment.
%
\bv\begin{lstlisting}[label=E:nrtraversal]
REAL measure_omega(MESH *mesh)
{
  TRAVERSE_STACK *stack = get_traverse_stack();
  const EL_INFO  *el_info;
  FLAGS          fill_flag;
  REAL           measure_omega = 0.0;

  el_info = traverse_first(stack, mesh, -1, CALL_LEAF_EL|FILL_COORDS);
  while (el_info)
  {
    measure_omega += el_volume(el_info);
    el_info = traverse_next(stack, el_info);
  }
  free_traverse_stack(stack);

  return(measure_omega);
}
\end{lstlisting}\ev
\end{example}

\begin{example}
\fdx{TRAVERSE_FIRST()@{\code{TRAVERSE\_FIRST()}}}
\mdx{TRAVERSE_FIRST()@{\code{TRAVERSE\_FIRST()}}}
\fdx{TRAVERSE_NEXT()@{\code{TRAVERSE\_NEXT()}}}
\mdx{TRAVERSE_NEXT()@{\code{TRAVERSE\_NEXT()}}}
  The same example as above, but implemented with the convenience
  macros \code{TRAVERSE\_FIRST()}, \code{TRAVERSE\_NEXT()}:
%
  \bv\begin{lstlisting}[label=E:simplenrtraversal]
REAL measure_omega(MESH *mesh)
{
  REAL measure_omega = 0.0;

  TRAVERSE_FIRST(mesh, -1, CALL_LEAF_EL|FILL_COORDS) {
    measure_omega += el_volume(el_info);
  } TRAVERSE_NEXT();
  return measure_omega;
}
\end{lstlisting}\ev
\end{example}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{Neighbour traversal}

Some applications, like the recursive refinement algorithm, need the
possibility to jump from one element to another element using
neighbour relations. Such a traversal can not be performed by the
recursive traversal routines and thus needs the non--recursive mesh
traversal.
The traversal routine for going from one element to a neighbour is
\fdx{traverse_neighbour()@{\code{traverse\_neighbour()}}}%
\bv\begin{lstlisting}
EL_INFO *traverse_neighbour(TRAVERSE_STACK *, EL_INFO *, int);
\end{lstlisting}\ev
Description:
\begin{descr}
\kitem{traverse\_neighbour(stack, el\_info, i)} returns 
a pointer to an \code{EL\_INFO} structure with information about the
\code{i}-th neighbour opposite the \code{i}-th
vertex  of \code{el\_info->el};

The function can be called at any time during the non--recursive 
mesh traversal after initializing the first element by 
\code{traverse\_first()}.

Calling \code{traverse\_neighbour()}, all
\code{EL\_INFO} information about a previous element is invalid, and
can only be regenerated by calling \code{traverse\_neighbour()} again
with the \emph{old\/} \code{OPP\_VERTEX} value. If called at the
boundary, when no adjacent element is available, then the routine
returns \nil; nevertheless, information from the old \code{EL\_INFO}
may be overwritten and lost. To avoid such behavior, one should check
for boundary vertices/edges/faces (1d/2d/3d) before calling 
\code{traverse\_neighbour()}.
\end{descr}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{Access to an element at world coordinates $x$}

Some applications need the access to elements at a special location in
world coordinates. Examples are characteristic methods for convection
problems, or the implementation of a special right hand side like point
evaluations or curve integrals. 
In a characteristic method, the point $x$ is usually given by 
$x = x_0 - \vec{V} \tau$, where $x_0$ is the starting point,
$\vec{V}$ the advection and $\tau$ the time step size. For
points $x_0$ close to the boundary it may happen that
$x$ does not belong to the computational domain. In this situation
it is convenient to know the point on the domain's boundary which lies on
the line segment between the old point $x_0$ and the new point
$x$. This point is uniquely determined by the scalar value
$s$ such that $x_0 + s \, (x - x_0) \in \partial\text{Domain}$.

The following function accesses an element at world coordinates $x$:
\fdx{find_el_at_pt()@{\code{find\_el\_at\_pt()}}}
\bv\begin{lstlisting}
int find_el_at_pt(MESH *, const REAL_D, EL_INFO **, FLAGS, REAL [N_LAMBDA],
                  const MACRO_EL *, const REAL_D, REAL *);
\end{lstlisting}\ev
Description:
\begin{descr}
\kitem{find\_el\_at\_pt(mesh, x, el\_info\_p, fill\_flag, bary, start\_mel, x0, sp)}
fills element information in an \code{EL\_INFO} structure and 
corresponding barycentric coordinates
of the element where the point \code{x} is located; the return value is 
\code{true} if \code{x} is inside the domain, or \code{false} otherwise.
Arguments of the function are:

\code{mesh} is the mesh to be traversed;

\code{x} are the world coordinates of the point (should be in the domain
         occupied by \code{mesh});

\code{el\_info\_p} is the return address for a pointer to the
             \code{EL\_INFO} for the element at \code{x} (or when \code{x} is
             outside the domain but \code{x0} was given, of the element
             containing the point
             $x_0 + s \, (x - x_0) \in \partial\text{Domain}$);

\code{fill\_flag} are the flags which specify which information should be
             filled in the \code{EL\_INFO} structure,
             coordinates are included in any case as they are needed
             by the routine itself;

\code{bary} pointer where to return the barycentric coordinates of \code{x} on 
            \code{*el\_info\_p->el} (or, when \code{x} is
             outside the domain but \code{x0} was given, of the point
             $x_0 + s \, (x - x_0) \in \partial\text{Domain}$);

\code{start\_mel} an initial guess for the macro element containing \code{x},
             or \nil;

\code{x0}   starting point of a characteristic method, see above, or \nil;

\code{sp}   return address for the relative distance to domain boundary in a 
             characteristic method if \code{x0 != nil}, see above, or \nil.
\end{descr}

The implementation of \code{find\_el\_at\_pt()} is based on the
transformation from world to local coordinates, available via the
routine \code{world\_to\_coord()}, compare Section
\ref{S:bary_routines}.  At the moment, \code{find\_el\_at\_pt()} works
correctly only for domains with non--curved boundary. This is due to
the fact that the implementation first looks for the macro--element
containing \code{x} and then finds its path through the corresponding
element tree based on the macro barycentric coordinates. For domains
with curved boundary, it is possible that in some cases a point inside
the domain is considered as external.
\idx{mesh traversal|)}

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