inject failure according to exponential distribution
[charm.git] / doc / fem / mesh.tex
1 \section{Mesh Nodes and Elements}
2 \label{sec:entities}
3
4 These routines describe and retreive the finite element mesh for this
5 computation.  A \term{mesh}, from the framework's perspective, is a list of
6 elements, nodes, and other data that describes the computational domain.
7 The FEM framework provides extensive support for creating, manipulating,
8 and partitioning meshes. 
9
10 A \term{serial mesh} consists of a single large piece.  It's usually
11 easiest to read and write serial meshes to existing, non-parallel file formats,
12 and it can be easier to manipulate serial meshes.  By contrast, a 
13 \term{parallel mesh} consists
14 of several pieces, called \term{chunks} or partitions.  Different processors
15 can work on different pieces of a parallel mesh, so most of the computation
16 is done using parallel meshes.  A simple program might create or read in a
17 single serial mesh in init, get a local chunk of the 
18 partitioned\footnote{The framework uses the excellent graph partitioning
19 package Metis.}
20 mesh in driver, and work on that chunk for the rest of the program.  
21 A more complex program might set an initial mesh in init; then get, 
22 work on, reassemble and repartition the mesh several times in driver 
23 via \kw{FEM\_Update\_mesh}.
24
25 \subsection{Mesh Entity Types}
26 A mesh consists of \term{entities}, such as nodes and elements.
27 Entities always have a \term{local number}, which is just the entities'
28 current index in its array.  Entites may also have a \term{global number}, 
29 which is the entity's index in the unpartitioned serial mesh.
30 Entities have data values called \term{attributes}.
31 For example, the location of each node might be called the 
32 ``location'' attribute of the ``node'' entity type.  Attributes are
33 always stored in regular arrays indexed by the entity's local number.
34 This table lists the different attributes that can be read or
35 written for each type of entity.
36
37 A \term{shared entity} is a boundary entitity that two or more chunks 
38 can both update---currently, only nodes can be shared.  Shared nodes
39 are mixed in with regular nodes, and the framework currently provides
40 no way to identify which nodes are shared.
41
42 A \term{ghost entity} is a boundary entity that is asymmetrically shared---one
43 side provides values for the ghost from one of its real entities, 
44 and the other sides accept read-only copies of these values.
45 Ghosts are described in more detail in Section~\ref{sec:ghost},
46 and can be accessed by adding the constant \kw{FEM\_GHOST} to 
47 the corresponding real entity's type.
48
49 The different kinds of entities are described in the following sections.
50
51 \begin{center}
52 \begin{tabular}{|l|l|}\hline
53 Real Entity & Ghost Entity \\ \hline
54 \kw{FEM\_NODE} & \kw{FEM\_GHOST}+\kw{FEM\_NODE} \\ \hline
55 \kw{FEM\_ELEM}+$elType$ & \kw{FEM\_GHOST}+\kw{FEM\_ELEM}+$elType$ \\ \hline
56 \kw{FEM\_SPARSE}+$sparseType$ & \kw{FEM\_GHOST}+\kw{FEM\_SPARSE}+$sparseType$ \\ \hline
57 \end{tabular}
58 \end{center}
59
60
61
62 \subsubsection{Nodes}
63 \kw{FEM\_NODE} is the entity code for nodes, the simplest kind of entity.  
64 A node is a single point in the domain, and elements are defined by their nodes.
65 Nodes can have the following attributes:
66
67 \begin{itemize}
68 \item \kw{FEM\_DATA}+$tag$  Uninterpreted user data, which might
69     include material properties, boundary conditions, flags, etc.
70     User data can have any data type and width.
71     $tag$ can be any number from 0 to one billion---it allows you
72     to register several data fields with a single entity.
73
74 \item \kw{FEM\_GLOBALNO}  Global node numbers. Always a 1-wide index type.
75
76 \item \kw{FEM\_SYMMETRIES} Symmetries that apply to this node.  
77     Always a 1-wide \kw{FEM\_BYTE}.
78
79 \item \kw{FEM\_NODE\_PRIMARY}  Marker indicating that this chunk is responsible 
80     for this node.  Every node is primary in exactly one chunk.
81     This attribute is always a 1-wide \kw{FEM\_BYTE} containing 0 or 1.
82
83 % \item \kw{FEM\_COORD}  Optional coordinates for this node.
84 \end{itemize}
85
86
87 \subsubsection{Elements}
88 \kw{FEM\_ELEM}+$elType$ is the entity code for one kind of element.
89 $elType$ is a small, user-defined value that uniquely identifies 
90 this element type.  Like nodes, elements can have the attributes
91 \kw{FEM\_DATA}+$tag$, \kw{FEM\_GLOBALNO}, or \kw{FEM\_SYMMETRIES};
92 but every element type must have this attribute:
93
94 \begin{itemize}
95 \item \kw{FEM\_CONN} Lists the numbers of the nodes around this element. 
96     See the description in the ghost section for special ghost connectivity.
97     Always an index type--\kw{FEM\_INDEX\_0} for C-style 0-based node indexing,
98     or \kw{FEM\_INDEX\_1} for Fortran-style 1-based node indexing.
99 \end{itemize}
100
101
102 \subsubsection{Sparse Elements}
103 \kw{FEM\_SPARSE}+$sparseType$ is the entity code for one kind of sparse element.
104 Again, $sparseType$ is a small, user-defined unique value.
105 The only difference between ordinary elements and sparse elements 
106 regards partitioning.  Ignoring ghosts, ordinary elements are never duplicated---each
107 element is sent to its own chunk.  Sparse elements may be duplicated,
108 and are always dependent on some other entity for their partitioning.
109 Sparse elements have all the attributes of ordinary elements:
110 \kw{FEM\_DATA}+$tag$, \kw{FEM\_GLOBALNO}, \kw{FEM\_SYMMETRIES},
111 and \kw{FEM\_CONN}, as well as the special attribute \kw{FEM\_SPARSE\_ELEM}.
112
113 Without the \kw{FEM\_SPARSE\_ELEM} attribute, a sparse element will 
114 be copied to every chunk that contains all the sparse element's nodes.  
115 This is useful for things like node-associated boundary conditions, 
116 where the sparse element connectivity might list the nodes with boundary
117 conditions, and the sparse element data might list the boundary condition values.
118
119 The \kw{FEM\_SPARSE\_ELEM} attribute lists the ordinary element each 
120 sparse element should be partitioned with.  This attribute consists of 
121 pairs ($elType$,$elNum$), indicating that this sparse element
122 should be sent to wherever the $elNum$'th \kw{FEM\_ELEM}+$elType$ 
123 is partitioned.
124
125
126 \begin{itemize}
127 \item \kw{FEM\_SPARSE\_ELEM} Lists the element we should be partitioned with.
128     The width of this attribute is always 2, and the data type must
129     be an index type--\kw{FEM\_INDEX\_0} or \kw{FEM\_INDEX\_1}.
130 % & \kw{FEM\_COORD} & Optional coordinates for this node.
131 \end{itemize}
132
133
134
135 \subsection{Mesh Entity Manipulation}
136
137
138 \prototype{FEM\_Mesh\_default\_read}
139 \function{int FEM\_Mesh\_default\_read(void);}
140 \function{INTEGER function :: FEM\_Mesh\_default\_read()}
141
142 Return the default reading mesh.  This routine is valid:
143
144 \begin{itemize}
145 \item From \kw{driver()}, to return the partitioned mesh.
146 \item During your FEM\_Update\_mesh routine, to return the assembled mesh.
147 \item Anytime after a call to FEM\_Mesh\_set\_default\_read.
148 \end{itemize}
149
150 \prototype{FEM\_Mesh\_default\_write}
151 \function{int FEM\_Mesh\_default\_write(void);}
152 \function{INTEGER function :: FEM\_Mesh\_default\_write()}
153
154 Return the default writing mesh.  This routine is valid:
155
156 \begin{itemize}
157 \item From \kw{init()}, to change the new serial mesh.
158 \item From \kw{driver()}, to change the new partitioned mesh.
159 \item During your FEM\_Update\_mesh routine, to change the new serial mesh.
160 \item Anytime after a call to FEM\_Mesh\_set\_default\_write.
161 \end{itemize}
162
163
164 \prototype{FEM\_Mesh\_get\_length}  
165 \function{int FEM\_Mesh\_get\_length(int mesh,int entity);}
166 \function{INTEGER function :: FEM\_Mesh\_get\_length(mesh,entity)}
167   \args{INTEGER, INTENT(IN) :: mesh,entity }
168
169 Return the number of \uw{entity}s that exist in this \uw{mesh}.
170
171 This call can be used with any entity.
172 For example, to get the number of nodes,
173   \begin{alltt}
174       nNodes=FEM\_Mesh\_get\_length(\uw{mesh},\kw{FEM\_NODE})
175   \end{alltt}
176 To get the number of ghost nodes, 
177   \begin{alltt}
178       nGhostNodes=FEM\_Mesh\_get\_length(\uw{mesh},\kw{FEM\_GHOST}+\kw{FEM\_NODE})
179   \end{alltt}
180 To get the number of real elements of type 2,
181   \begin{alltt}
182         nElem=FEM\_Mesh\_get\_length(\uw{mesh},\kw{FEM\_ELEM}+2)
183   \end{alltt}
184
185
186 \prototype{FEM\_Mesh\_data}  
187 \function{void FEM\_Mesh\_data(int mesh,int entity,int attr,
188         void *data, int first, int length, int datatype,int width);}
189 \function{SUBROUTINE FEM\_Mesh\_data(mesh,entity,attr,data,first,length,datatype,width)}
190   \args{INTEGER, INTENT(IN) :: mesh,entity,attr,first,length,datatype,width}
191   \args{datatype, intent(inout) :: data(width,length) }
192
193 This is the one routine for getting or setting entity's attributes 
194 on the mesh.  
195
196 \begin{itemize}
197 \item \uw{mesh} A FEM mesh object.  Depending on whether this is
198    a reading or writing mesh, this routine reads from or writes to
199    the data array you pass in.
200
201 \item \uw{entity} A FEM entity code, for example \kw{FEM\_NODE} or
202    \kw{FEM\_GHOST}+\kw{FEM\_ELEM}+1.
203
204 \item \uw{attr} A FEM attribute code, for example \kw{FEM\_DATA}+$tag$
205    or \kw{FEM\_CONN}.  
206  
207 \item \uw{data} The user data to get or set.  Each row of this array consists
208   of \uw{width} values, and contains the data values of the attribute for the
209   corresponding entity.  This data must be formatted as one of:
210   \begin{alltt}
211       datatype :: data(width,length)
212       datatype :: data(width*length)
213   \end{alltt}
214
215 \item \uw{first} The first entity to affect.  In C, this is normally 0;
216   in Fortran, this is normally 1.
217
218 \item \uw{length} The number of entities to affect.  The entities
219   affected are thus those numbered from \uw{first} to \uw{first}+\uw{length}-1.
220   For now, \uw{length} must be either 1, to touch a single entity; or
221   else the total number of entities--that is, FEM\_Mesh\_get\_length(mesh,entity).
222
223 \item \uw{datatype} The data type stored in this attribute.  This
224   is one of the standard FEM data types \kw{FEM\_BYTE}, \kw{FEM\_INT}, 
225   \kw{FEM\_FLOAT}, or \kw{FEM\_DOUBLE}; or else the C-style 0-based
226   index type \kw{FEM\_INDEX\_0} or the Fortran-style 1-based index type
227   \kw{FEM\_INDEX\_1}. Alternatively, the equivalent types \kw{IDXL\_BYTE}, \kw{IDXL\_INT},
228 \kw{IDXL\_FLOAT}, \kw{IDXL\_DOUBLE}, \kw{IDXL\_INDEX\_0}, or \kw{IDXL\_INDEX\_1} may be used.
229
230 \item \uw{width} The number of data items per entity. 
231
232 \end{itemize}
233
234 For example, to set the element connectivity, which is stored as 
235 3 integer node indices in \uw{nodes}, you would:
236
237   \begin{alltt}
238 /* C version */
239    int *nodes=new int[3*nElems];
240    ... fill out nodes ...
241    FEM\_Mesh\_data(mesh,FEM\_ELEM+1,FEM\_CONN, nodes, 0,nElems, FEM\_INDEX\_0, 3);
242    ... continue to use or delete nodes ...
243    
244 ! F90 version
245    ALLOCATE(nodes(3,nElems))
246    ... fill out nodes ...
247    CALL FEM\_Mesh\_data(mesh,FEM\_ELEM+1,FEM\_CONN, nodes, 1,nElems, FEM\_INDEX\_1, 3)
248    ... continue to use or delete nodes ...
249   \end{alltt}
250
251 To add a new node property with 2 double-precision numbers 
252 from an array \uw{mat} (containing, for example,
253 material properties), you would first pick an unused
254 user data "tag", for example 13, and:
255
256   \begin{alltt}
257 /* C version */
258    double *mat=new double[2*nNodes];
259    ...
260    FEM\_Mesh\_data(mesh,FEM\_NODE, FEM\_DATA+13, mat, 0,nNodes, FEM\_DOUBLE, 2);
261    
262 ! F90 version
263    ALLOCATE(mat(2,nNodes))
264    CALL FEM\_Mesh\_data(mesh,FEM\_NODE,FEM\_DATA+13, mat, 1,nNodes, FEM\_DOUBLE, 2)
265   \end{alltt}
266
267
268 \subsection{Entity Inquiry}
269
270 \prototype{FEM\_Mesh\_get\_width}  
271 \function{int FEM\_Mesh\_get\_width(int mesh,int entity,int attr);}
272 \function{INTEGER function :: FEM\_Mesh\_get\_width(mesh,entity,attr)}
273   \args{INTEGER, INTENT(IN) :: mesh,entity,attr }
274
275 Return the width of the attribute \uw{attr} of \uw{entity} of \uw{mesh}.
276 This is the value previously passed as ``width'' to FEM\_Mesh\_data.
277
278
279 \prototype{FEM\_Mesh\_get\_datatype}  
280 \function{int FEM\_Mesh\_get\_datatype(int mesh,int entity,int attr);}
281 \function{INTEGER function :: FEM\_Mesh\_get\_datatype(mesh,entity,attr)}
282   \args{INTEGER, INTENT(IN) :: mesh,entity,attr }
283
284 Return the FEM data type of the attribute \uw{attr} of \uw{entity} of \uw{mesh}.
285 This is the value previously passed as ``datatype'' to FEM\_Mesh\_data.
286
287
288 \prototype{FEM\_Mesh\_get\_entities}  
289 \function{int FEM\_Mesh\_get\_entities(int mesh,int *entities);}
290 \function{INTEGER function :: FEM\_Mesh\_get\_entities(mesh,entities)}
291   \args{INTEGER, INTENT(IN) :: mesh}
292   \args{INTEGER, INTENT(OUT) :: entities(:) }
293
294 Extract an array of the different entities present in this mesh.
295 Returns the number of entity types present.  The \uw{entities}
296 array must be big enough to hold all the different entities in
297 the mesh.
298
299 For example, a simple mesh might have two entity types:
300 FEM\_NODE and FEM\_ELEM+1.
301
302
303 \prototype{FEM\_Mesh\_get\_attributes}  
304 \function{int FEM\_Mesh\_get\_attributes(int mesh,int entity,int *attributes);}
305 \function{INTEGER function :: FEM\_Mesh\_get\_attributes(mesh,entity,attributes)}
306   \args{INTEGER, INTENT(IN) :: mesh, entity}
307   \args{INTEGER, INTENT(OUT) :: attributes(:) }
308
309 Extract an array of the different attributes of this entity.
310 Returns the number of attribute types present.  The \uw{attributes}
311 array must be big enough to hold all the attributes.
312
313 For example, a simple element might have three attributes:
314 FEM\_CONN for node connectivity, FEM\_GLOBALNO for global element
315 numbers, and FEM\_DATA+7 for a material type.
316
317 \prototype{FEM\_Get\_*\_name}  
318 \function{const char *FEM\_Get\_entity\_name(int entity,char *storage);}
319 \function{const char *FEM\_Get\_attr\_name(int attr,char *storage);}
320 \function{const char *FEM\_Get\_datatype\_name(int datatype,char *storage);}
321
322 Return a human-readable name for this FEM entity, attribute, or datatype.
323 The \uw{storage} array must point to a buffer of at least 100 characters;
324 this array might be used as temporary space to store the returned string.
325
326 These routines are only available in C.
327
328
329 \subsection{Advanced Entity Manipulation}
330
331 \prototype{FEM\_Mesh\_data\_offset}  
332 \function{void FEM\_Mesh\_data\_offset(int mesh,int entity,int attr,
333         void *data, int first, int length, int datatype,int width,
334         int offsetBytes,int distanceBytes,int skewBytes);}
335 \function{SUBROUTINE FEM\_Mesh\_data\_offset(mesh,entity,attr,data,first,length,datatype,width,
336         offsetBytes,distanceBytes,skewBytes)}
337   \args{INTEGER, INTENT(IN) :: mesh,entity,attr,first,length,datatype,width}
338   \args{INTEGER, INTENT(IN) :: offsetBytes,distanceBytes,skewBytes }
339   \args{datatype, intent(inout) :: data(width,length) }
340
341 This routine is a more complicated version of FEM\_Mesh\_data.
342 It allows you to get or set a mesh field directly
343 from a user-defined structure.  See the documentation of
344 IDXL\_Layout\_offset in Section~\ref{sec:IDXLLayoutoffset}
345 for details on how to set offsetBytes, distanceBytes, and skewBytes.
346
347 \prototype{FEM\_Mesh\_data\_layout}
348 \function{
349 void FEM\_Mesh\_data\_layout(int mesh,int entity,int attr,
350       void *data, int firstItem, int length, IDXL\_Layout\_t layout);
351 }
352 \function{SUBROUTINE FEM\_Mesh\_data\_layout(mesh,entity,attr,data,first,length,layout)}
353   \args{INTEGER, INTENT(IN) :: mesh,entity,attr,first,length,layout}
354   \args{INTEGER, INTENT(IN) :: layout}
355
356 This routine is a more complicated version of FEM\_Mesh\_data.
357 Like FEM\_Mesh\_data\_offset, it allows you to get or set a mesh
358 field directly from a user-defined structure; but this routine
359 expects the structure to be described by an IDXL\_Layout object.
360
361 %%%%%%%%%%%%%%%%%%%%%% Mesh Creation %%%%%%%%%%%%%%%%%%%%%%%%%%
362 \section{Meshes}
363 \label{sec:mesh}
364
365 A "mesh" is a collection of nodes and elements 
366 knit together in memory, as described in Section~\ref{sec:terminology}.
367 Meshes are always referred to by an integer that 
368 serves as a handle to the local mesh.
369
370 This section describes routines to manipulate entire meshes
371 at once: this includes calls to create and delete meshes,
372 read and write meshes,
373 partition and reassemble meshes, and send meshes between
374 processors.
375
376 Only a few of the mesh routines are collective; 
377 most of them only describe local data and hence 
378 operate independently on each chunk.
379
380
381 \subsection{Mesh Routines}
382
383 \prototype{FEM\_Mesh\_allocate}
384 \function{int FEM\_Mesh\_allocate(void);}
385 \function{INTEGER FUNCTION :: FEM\_Mesh\_allocate()}
386
387 Create a new local mesh object.  The mesh is initially empty,
388 but it is a setting mesh, so call FEM\_Mesh\_data 
389 to fill the mesh with data.
390
391
392 \prototype{FEM\_Mesh\_deallocate}
393 \function{int FEM\_Mesh\_deallocate(int mesh);}
394 \function{SUBROUTINE FEM\_Mesh\_deallocate(mesh)}
395   \args{INTEGER, INTENT(IN) :: mesh}
396
397 Destroy this local mesh object, and its associated
398 data.
399
400
401 \prototype{FEM\_Mesh\_copy}
402 \function{int FEM\_Mesh\_copy(int mesh);}
403 \function{INTEGER FUNCTION FEM\_Mesh\_copy(mesh)}
404   \args{INTEGER, INTENT(IN) :: mesh}
405
406 Create a new mesh object with a separate copy of the data 
407 stored in this old mesh object.
408
409
410 \prototype{FEM\_Mesh\_write}
411 \function{void FEM\_Mesh\_write(int mesh,const char *prefix,int partNo,int nParts);}
412 \function{SUBROUTINE FEM\_Mesh\_write(mesh,prefix,partNo,nParts)}
413   \args{INTEGER, INTENT(IN) :: mesh}
414   \args{INTEGER, INTENT(IN) :: partNo,nParts}
415   \args{character (LEN=*), INTENT(IN) :: prefix}
416
417 Write this mesh to the file ``\uw{prefix}\_vp\uw{partNo}\_\uw{nParts}.dat''.
418
419 By convention, \uw{partNo} begins at 0; but no index conversion is
420 performed so you can assign any meaning to \uw{partNo} and \uw{nParts}.
421 In particular, this routine is not collective--you can read any
422 mesh from any processor.
423 For example, if \uw{prefix} is ``foo/bar'', the data for the 
424 first of 7 chunks would be stored in ``foo/bar\_vp0\_7.dat''
425 and could be read using FEM\_Mesh\_read('foo/bar',0,7).
426
427 Meshes are stored in a machine-portable format internal to FEM.
428 The format is currently ASCII based, but it is subject to change.
429 We strongly recommend using the FEM routines to read and write 
430 these files rather than trying to prepare or parse them yourself.
431
432
433 \prototype{FEM\_Mesh\_read}
434 \function{int FEM\_Mesh\_read(const char *prefix,int partNo,int nParts);}
435 \function{INTEGER FUNCTION :: FEM\_Mesh\_read(prefix,partNo,nParts)}
436   \args{INTEGER, INTENT(IN) :: partNo,nParts}
437   \args{character (LEN=*), INTENT(IN) :: prefix}
438
439 Read a new mesh from the file ``\uw{prefix}\_vp\uw{partNo}\_\uw{nParts}.dat''.
440 The new mesh begins in getting mode, so you can read the 
441 data out of the mesh using calls to FEM\_Mesh\_data.
442
443
444
445 \prototype{FEM\_Mesh\_broadcast}
446   \function{int FEM\_Mesh\_broadcast(int mesh,int fromRank,FEM\_Comm\_t comm\_context);}
447   \function{INTEGER FUNCTION :: FEM\_Mesh\_broadcast(mesh,fromRank,comm\_context)}
448      \args{INTEGER, INTENT(IN) :: mesh,fromRank,comm\_context}
449
450 Take the mesh \uw{mesh} on processor \uw{fromRank} (normally 0), 
451 partition the mesh into one piece per processor (in the MPI communicator
452 \uw{comm\_context}, and return each processor its own piece 
453 of the partitioned mesh.  This call is collective, but only 
454 processor \uw{fromRank} needs to pass in a \uw{mesh}; the 
455 \uw{mesh} value is ignored on other processors.
456
457 For example, if rank 0 has a mesh named ``src'', we can 
458 partition src for all the processors by executing:
459 \begin{alltt}
460   m=FEM_Mesh_broadcast(src,0,MPI_COMM_WORLD);
461 \end{alltt}
462
463 The new, partitioned mesh is in getting mode, so 
464 you can read the partitioned data using calls to FEM\_Mesh\_data.
465 This call does not affect \uw{mesh} in any way.
466
467   
468 \prototype{FEM\_Mesh\_reduce}
469   \function{int FEM\_Mesh\_reduce(int mesh,int toRank,FEM\_Comm\_t comm\_context);}
470   \function{INTEGER FUNCTION :: FEM\_Mesh\_reduce(mesh,toRank,comm\_context);}
471      \args{INTEGER, INTENT(IN) :: mesh,toRank,comm\_context}
472
473 This call is the reverse operation of FEM\_Mesh\_broadcast:
474 each processor passes in a mesh in \uw{mesh}, the mesh is 
475 assembled, and the function returns the assembled mesh
476 to processor \uw{toRank}.  This call is collective, but 
477 only processor \uw{toRank} is returned a mesh; all other
478 processors are returned the non-mesh value 0.
479
480 The new, reassembled mesh is in getting mode.
481 This call does not affect \uw{mesh}.
482
483
484 \subsection{Mesh Utility}
485
486 \prototype{FEM\_Mesh\_is\_get}
487 \function{int FEM\_Mesh\_is\_get(int mesh)}
488 \function{INTEGER FUNCTION :: FEM\_Mesh\_is\_get(mesh)}
489   \args{INTEGER, INTENT(IN) :: mesh }
490
491 Return true if this mesh is in getting mode.
492 A getting mesh returns values to FEM\_Mesh\_data.
493
494 \prototype{FEM\_Mesh\_is\_set}
495 \function{int FEM\_Mesh\_is\_set(int mesh)}
496 \function{INTEGER FUNCTION :: FEM\_Mesh\_is\_set(mesh)}
497   \args{INTEGER, INTENT(IN) :: mesh }
498
499 Return true if this mesh is in setting mode.
500 A setting mesh extracts values from FEM\_Mesh\_data.
501
502
503 \prototype{FEM\_Mesh\_become\_get}
504 \function{void FEM\_Mesh\_become\_get(int mesh)}
505 \function{SUBROUTINE :: FEM\_Mesh\_become\_get(mesh)}
506   \args{INTEGER, INTENT(IN) :: mesh }
507
508 Put this mesh in getting mode, so you can read back
509 its values.
510
511 \prototype{FEM\_Mesh\_become\_set}
512 \function{void FEM\_Mesh\_become\_set(int mesh)}
513 \function{SUBROUTINE :: FEM\_Mesh\_become\_set(mesh)}
514   \args{INTEGER, INTENT(IN) :: mesh }
515
516 Put this mesh in setting mode, so you can set its values.
517
518 \prototype{FEM\_Mesh\_print}
519 \function{void FEM\_Mesh\_print(int mesh);}
520 \function{SUBROUTINE FEM\_Mesh\_print(mesh)}
521     \args{INTEGER, INTENT(IN) :: mesh}
522
523 Print out a text description of the nodes and elements 
524 of this mesh.
525
526
527 \subsection{Advanced Mesh Manipulation}
528
529 \prototype{FEM\_Mesh\_pup}
530 \function{typedef void (*FEM\_Userdata\_fn)(pup\_er p,void *data);}
531 \function{void FEM\_Mesh\_pup(int mesh,int pupTag,FEM\_Userdata\_fn fn,void *data);}
532 \function{SUBROUTINE myPupFn(p,data);}
533    \args{INTEGER, INTENT(IN) :: p}
534    \args{TYPE(myType) :: data}
535 \function{SUBROUTINE FEM\_Mesh\_pup(mesh,pupTag,myPupFn,data);}
536    \args{INTEGER, INTENT(IN) :: mesh,pupTag}
537    \args{SUBROUTINE :: myPupFn}
538    \args{TYPE(myType) :: data}
539
540 Store \uw{data} with this \uw{mesh}.  \uw{data} is a struct or TYPE
541 with a pup function \uw{myPupFn}---see the TCharm manual for details 
542 on writing a pup function.
543 \uw{pupTag} is an integer used to distinguish different pieces of data
544 associated with this mesh.
545
546 When called on a setting mesh, this routine stores \uw{data};
547 when called on a getting mesh, this routine reads out \uw{data}.
548
549 \uw{data} will be associated with the mesh itself, not any 
550 entity in the mesh.  This makes it useful for storing shared
551 data, often simulation constants such as the timestep or material 
552 properties.  \uw{data} is made a part of the mesh, and it will be 
553 read and written, sent and received, partitioned and assembled
554 with the mesh.
555
556
557 \prototype{FEM\_Mesh\_send}
558   \function{void FEM\_Mesh\_send(int mesh,int toRank,int tag,FEM\_Comm\_t comm\_context);}
559   \function{SUBROUTINE FEM\_Mesh\_send(mesh,toRank,tag,comm)}
560     \args{INTEGER, INTENT(IN) :: mesh,toRank,tag,comm}
561   
562   Send the mesh \uw{mesh} to the processor \uw{toRank}, using
563   the MPI tag \uw{tag} and communicator \uw{comm\_context}.
564   Tags are normally only needed if you plan to mix direct MPI
565   calls with your FEM calls.
566   
567   This call does not affect \uw{mesh}.
568   
569
570 \prototype{FEM\_Mesh\_recv}
571   \function{int FEM\_Mesh\_recv(int fromRank,int tag,FEM\_Comm\_t comm\_context);}
572   \function{INTEGER FUNCTION FEM\_Mesh\_recv(fromRank,tag,comm)}
573     \args{INTEGER, INTENT(IN) :: fromRank,tag,comm}
574   
575   Receive a new mesh from the processor \uw{fromRank}, using
576   the MPI tag \uw{tag} and communicator \uw{comm\_context}.
577   You can also use the special values MPI\_ANY\_SOURCE as \uw{fromRank}
578   to receive a mesh from any processor, or use
579   MPI\_ANY\_TAG for \uw{tag} to match any tag.
580
581   The new mesh is returned in getting mode.
582
583 \prototype{FEM\_Mesh\_partition}
584   \function{void FEM\_Mesh\_partition(int mesh,int nParts,int *destMeshes);}
585   \function{SUBROUTINE FEM\_Mesh\_partition(mesh,nParts,destMeshes)}
586     \args{INTEGER, INTENT(IN) :: mesh,nParts}
587     \args{INTEGER, INTENT(OUT) :: destMeshes(nParts)}
588
589 Divide \uw{mesh} into \uw{nParts} pieces, and store the pieces
590 into the array \uw{destMeshes}. 
591
592 The partitioned mesh is returned in getting mode.
593 This is a local call; FEM\_Mesh\_broadcast is the collective version.
594 This call does not affect the source mesh \uw{mesh}.
595
596   
597 \prototype{FEM\_Mesh\_assemble}
598   \function{int FEM\_Mesh\_assemble(int nParts,const int *srcMeshes);}
599   \function{INTEGER FUNCTION FEM\_Mesh\_assemble(nParts,srcMeshes)}
600     \args{INTEGER, INTENT(IN) :: nParts, srcMeshes(nParts)}
601
602 Assemble the \uw{nParts} meshes listed in \uw{srcMeshes} into
603 a single mesh.  Corresponding mesh pieces are matched using 
604 the attribute FEM\_GLOBALNO.  Specifically, if the value of 
605 the integer index attribute FEM\_GLOBALNO for an entity is $i$,
606 the entity will be given the number $i$ in the reassembled mesh.
607 If you do not set FEM\_GLOBALNO, the different pieces of the 
608 mesh will remain separate---even ``matching'' nodes will not be merged.
609
610 The assembled mesh is returned in getting mode.
611 This is a local call; FEM\_Mesh\_reduce is the collective version.
612 This call does not affect the source meshes.
613
614
615 \prototype{FEM\_Mesh\_copy\_globalno}
616   \function{void FEM\_Mesh\_copy\_globalno(int src\_mesh,int dest\_mesh);}
617   \function{SUBROUTINE FEM\_Mesh\_copy\_globalno(src\_mesh,dest\_mesh)}
618     \args{INTEGER, INTENT(IN) :: src\_mesh,dest\_mesh}
619
620 Copy the FEM\_GLOBALNO attribute for all the entity types in 
621 \uw{src\_mesh} into all the matching types in \uw{dest\_mesh},
622 where the matching types exist.  This call is often used 
623 before an FEM\_Mesh\_assemble or FEM\_Mesh\_reduce to synchronize
624 global numbers before reassembly.
625
626
627 %%%%%%%%%%%%%%%%%%%%%% Ghosts %%%%%%%%%%%%%%%%%%%%%%%%%%
628
629 \section{Mesh Ghosts}
630 \label{sec:ghost}
631
632 A \term{ghost entity} is a local, read-only copy of a real entity
633 on another chunk. Ghosts are typically added to the boundary of a chunk to allow the real (non-ghost) elements at the boundary to access values across the processor boundary.  This makes a chunk ``feel'' as if it was part of a complete unpartitioned mesh; and can be useful with cell-centered methods, and in mesh modification.
634
635 \begin{figure}
636 \begin{center}
637 \includegraphics[width=1.5in]{fig/ghost_pre}
638 \end{center}
639 \caption{A small mesh partitioned into two pieces.}
640 \label{fig:ghostpre}
641
642 % \end{figure} \begin{figure} % Make sure these two figures don't get separated
643
644 \begin{center}
645 \includegraphics[width=1.5in]{fig/ghost_edge}
646 \end{center}
647 \caption{The same mesh with one layer of edge-adjacent ghosts.}
648 \label{fig:ghostedge}
649
650 % \end{figure} \begin{figure}
651
652 \begin{center}
653 \includegraphics[width=1.5in]{fig/ghost_node}
654 \end{center}
655 \caption{The same mesh with one layer of node-adjacent ghosts.}
656 \label{fig:ghostnode}
657 \end{figure}
658
659
660 In Figure~\ref{fig:ghostpre}, we begin with a small mesh partitioned
661 into pieces on the left and right.  In Figure~\ref{fig:ghostedge},
662 we have added ghost elements (dark hashing) that share an edge with
663 adjacent real elements (light hatching).  In Figure~\ref{fig:ghostnode},
664 we add ghost elements that share at least one node with adjacent 
665 real elements.
666
667
668
669 \subsection{Ghost Numbering}
670 \label{sec:ghostnum}
671 Ghosts and real entities are stored by the framework
672 in separate lists---to access the ghost entity type, add \kw{FEM\_GHOST}
673 to the real entity's type.  For example, \kw{FEM\_GHOST}+\kw{FEM\_ELEM}+1 
674 lists the ghost elements for \uw{elType} 1.  To get the number 
675 of ghost nodes, you would call 
676 \kw{FEM\_Mesh\_get\_length}(\uw{mesh},\kw{FEM\_GHOST}+\kw{FEM\_NODE}).
677
678 \begin{figure}[h]
679 \begin{center}
680 \includegraphics[width=4in]{fig/conn_indexing}
681 \end{center}
682 \caption{Node indices used in the element connectivity array.
683 There are $n$ real nodes and $m$ ghosts.}
684 \label{fig:connindexing}
685 \end{figure}
686
687 For real elements, the element connectivity always consists of real nodes.
688 But for ghost elements, the adjacent nodes may be missing, or may themselves
689 be ghosts.
690 Thus ghost element connectivity lists may include the invalid 
691 value -1 (in C) or 0 (in Fortran) to indicate that the corresponding 
692 node is not present; or may include values
693 less than this, which indicate the corresponding node is a ghost.
694 In C, ghost node $i$ is indicated by the value $-2-i$, while
695 in Fortran, ghost node $i$ is indicated by the value $-i$.  
696 This node indexing system is illustrated in Figure~\ref{fig:connindexing}, 
697 This indexing system is bizarre, but it allows us to keep
698 the real and ghost nodes clearly separate, while still
699 allowing real and ghost nodes to be added in increasing order
700 at both ends.
701
702 Since the C tests are complicated, in C we recommend using these macros:
703
704 \begin{itemize}
705 \item \kw{FEM\_Is\_ghost\_index}(i) returns true if $i$ represents a ghost node.
706 In Fortran, use the test $i$ .lt. $0$
707
708 \item \kw{FEM\_From\_ghost\_index}(i) returns the ghost node's index given its connectivity entry.
709 In Fortran, use the expression $-i$.
710
711 \item \kw{FEM\_To\_ghost\_index}(i) returns the connectivity entry for a given ghost node index.
712 In Fortran, again use the expression $-i$.
713 \end{itemize}
714
715 For example, a quadrilateral ghost element that is adjacent to, respectively, two real 
716 nodes 23 and 17, the tenth local ghost node, and one not-present node might have a 
717 connectivity entry of {23,17,-11,-1} (in C) or {23,17,-10,0} (in Fortran).
718
719 Applications may wish to use some other numbering,
720 such as by storing all the ghost nodes after all the real nodes.
721 The code to extract and renumber the connectivity of some 3-node triangles 
722 stored in FEM\_ELEM+2 would be:
723
724 \begin{alltt}
725 /* C version */
726   int nReal=FEM\_Mesh\_get\_length(mesh,FEM\_ELEM+2);
727   int nGhost=FEM\_Mesh\_get\_length(mesh,FEM\_GHOST+FEM\_ELEM+2);
728   typedef int intTriplet[3];
729   intTriplet *conn=new intTriplet[nReal+nGhost];
730   /* Extract real triangles into conn[0..nReal-1] */
731   FEM\_Mesh\_data(mesh,FEM\_ELEM+2,FEM\_CONN, &conn[0][0], 0,nReal, 3,FEM\_INDEX\_0);
732   /* Extract ghost triangles into conn[nReal..nReal+nGhost-1] */
733   FEM\_Mesh\_data(mesh,FEM\_GHOST+FEM\_ELEM+2,FEM\_CONN, &conn[nReal][0], 0,nGhost, 3,FEM\_INDEX\_0);
734   
735   /* Renumber the ghost triangle connectivity */
736   for (int t=nReal;t<nReal+nGhost;t++)
737     for (int i=0;i<3;i++) \{
738       int in=conn[t][i]; /* uses FEM ghost node numbering */
739       int out; /* uses application's ghost numbering */
740       if (in==-1) \{ 
741         out=some\_value\_for\_missing\_nodes; 
742       \} else if (FEM\_Is\_ghost\_index(in)) \{
743         out=first\_application\_ghost+FEM\_From\_ghost\_index(in);
744       \} else /*regular real node*/ \{
745         out=in;
746       \}
747       conn[t][i]=out;
748     \}
749
750 ! F90 version
751   INTEGER, ALLOCATABLE :: conn(3,:)
752   INTEGER :: nReal,nGhost,t,i,in,out
753   nReal=FEM\_Mesh\_get\_length(mesh,FEM\_ELEM+2)
754   nGhost=FEM\_Mesh\_get\_length(mesh,FEM\_GHOST+FEM\_ELEM+2)
755   ALLOCATE(conn(3,nReal+nGhost))
756   ! Extract real triangles into conn[1..nReal] 
757   CALL FEM\_Mesh\_data(mesh,FEM\_ELEM+2,FEM\_CONN, conn, 1,nReal, 3,FEM\_INDEX\_1)
758   ! Extract ghost triangles into conn[nReal+1..nReal+nGhost] 
759   CALL FEM\_Mesh\_data(mesh,FEM\_GHOST+FEM\_ELEM+2,FEM\_CONN, conn(1,nReal+1), 1,nGhost, 3,FEM\_INDEX\_1)
760   
761   ! Renumber the ghost triangle connectivity 
762   DO t=nReal+1,nReal+nGhost
763     DO i=1,3
764       in=conn(i,t) 
765       IF (in .EQ. 0) out=some\_value\_for\_missing\_nodes
766       IF (in .LT. 0) out=first\_application\_ghost-1+(-in)
767       IF (in .GT. 0) out=in
768       conn(i,t)=out
769     END DO
770   END DO
771   
772   
773 \end{alltt}
774
775
776
777 \subsection{Setting up the ghost layer}
778 The framework's ghost handling is element-centric. You specify which kinds of elements should be ghosts and how they connect by listing their faces before partitioning.  
779
780 \begin{itemize}
781 \item
782
783 \prototype{FEM\_Add\_ghost\_layer}
784 \function{void FEM\_Add\_ghost\_layer(int nodesPerFace,int doAddNodes);}
785 \function{SUBROUTINE FEM\_Add\_ghost\_layer(nodesPerFace,doAddNodes)}
786   \args{INTEGER, INTENT(IN) :: nodesPerFace,doAddNodes}
787 This routine creates a new layer of ghosts around each FEM chunk. \kw{nodesPerFace} is the number of shared nodes that together form a ``face''. \kw{doAddNodes} specifies that you want ghost nodes around your ghost elements.  If \kw{doAddNodes} is 0, ghost elements will have invalid -1 (in C) or 0 (in Fortran) connectivity entries where there is no corresponding local node.
788
789 A face is an unordered ``tuple'' of nodes, and is an abstract way to describe which ghosts
790 your application needs---an element will be added to your chunk if it connects to at 
791 least one of your elements' faces.  For example, if you have a 3D, tetrahedral element that require ghosts 
792 on all 4 of its sides, this is equivalent to requiring ghosts of every element that shares all 3
793 nodes of one of your triangular faces, so for you a face is a 3-node triangle.  If you have a 2D shape
794 and want edge-adjacency, for you a face is a 2-node edge.  If you want node-adjacent ghosts,
795 a face is a single node.
796
797 Calling this routine several times creates several layers of ghost elements, and the different layers need not have the same parameters.
798
799 \item
800 \prototype{FEM\_Add\_ghost\_elem}
801 \function{void FEM\_Add\_ghost\_elem(int elType,int facesPerElem,const int *elem2face);}
802 \function{SUBROUTINE FEM\_Add\_ghost\_elem(elType,facesPerElem,elem2face)}
803   \args{INTEGER, INTENT(IN) :: elType,facesPerElem}
804   \args{INTEGER, INTENT(IN) :: elem2face(nodesPerFace,facesPerElem)}
805
806 This call is used to specify which type of element is to be added to the current ghost layer. \kw{facesPerElem} and \kw{elem2face} specify a mapping between each element and the surrounding faces.  The \kw{elem2face} table lists, for each face, the nodes of this element which form the face, specified as element-local numbers---indices into this element's connectivity entry. The \kw{elem2face} table should have nodesPerFace*facesPerElem entries, and no entry should be greater than nodePerEl for that element type.
807
808 Because all faces must take up the same space in the array,
809 \kw{elem2face} can include special indices--- -1 for C, 0 for Fortran---that indicate the
810 corresponding face is actually shorter than usual.  For example, if \kw{nodesPerFace} for this layer
811 is 4, for 4-node quadrilateral faces, you could set one entry in \kw{elem2face} to -1 to specify
812 this is a 3-node triangular face.  Faces of different lengths will never match, so this is just
813 a simple way to add ghosts from two kinds of faces at once.
814
815 \end{itemize}
816
817 The above two routines are always used together. For example, if your elements are 3-node triangles and you only require one shared node for inclusion in a single ghost layer, you would use:
818 \begin{alltt}
819    FEM\_Add\_ghost\_layer(1,1); /* 1 node per face: node adjacency */
820    const static int tri2node[]=\{0,1,2\};
821    FEM\_Add\_ghost\_elem(0,3,tri2node); /* triangles are surrounded by 3 nodes */
822 \end{alltt}
823
824 If you require two shared nodes (a shared edge), the code will look like:
825 \begin{alltt}    
826    FEM\_Add\_ghost\_layer(2,1); /* 2 nodes per face: edge adjacency */
827    const static int tri2edge[]=\{0,1,  1,2,  2,0\};
828    FEM\_Add\_ghost\_elem(0,3,tri2edge); /*triangles are surrounded by 3 edges */
829 \end{alltt}
830
831
832 \subsection{Symmetries and Ghosts--Geometric Layer}
833
834 The FEM framework can create ghosts not only of things that are on other 
835 processors, but also for various problem symmetries, like mirror reflection,
836 and various types of periodicities.  The interface for these ghosts is 
837 simple---you ask for the symmetries to be created, then you will get 
838 extra ghosts along each symmetry boundary.  The symmetry ghosts are
839 updated properly during any communication, even if the symmetry ghosts
840 are ghosts of real local elements from the same chunk.
841
842
843 \begin{figure}[h]
844 \begin{center}
845 \includegraphics[width=3in]{fig/sym_ghost}
846 \end{center}
847 \caption{Illustrating symmetry ghost elements.}
848 \label{fig:symghost}
849 \end{figure}
850
851 Figure~\ref{fig:symghost} shows a chunk of a mesh for a 
852 rectangular domain with horizontal linear translational periodicity---that 
853 is, the domain repeats horizontally.
854 Symmetry ghosts lie along the left and right sides; ordinary cross-processor
855 parallel ghosts lie along the top edge where this chunk joins up with the
856 rest of the domain; and the external boundary along the bottom of the chunk
857 has no ghosts.
858
859
860
861 \prototype{FEM\_Add\_linear\_periodicity}
862 \function{void FEM\_Add\_linear\_periodicity(
863         int nFaces,int nPer,
864         const int *facesA,const int *facesB,
865         int nNodes,const double *nodeLocs
866         );}
867 \function{
868 SUBROUTINE FEM\_Add\_linear\_periodicity(nFaces,nPer,facesA,facesB,
869                                 nNodes,nodeLocs)}
870   \args{INTEGER, INTENT(IN) :: nFaces, nPer, nNodes}
871   \args{INTEGER, INTENT(IN) :: facesA(nPer,nFaces), facesB(nPer,nFaces)}
872   \args{double precision, INTENT(IN) :: nodeLocs(3,nNodes)}
873
874 Make facesA and facesB match up under linear translation.
875 Each face of facesA must match up with exactly one face of
876 facesB, but both the faces and the nodes within a face can be
877 permuted in any order---the order is recovered by matching 3d locations
878 in the nodeLocs array.
879
880 This call can be repeated, for example if the domain is periodic along several
881 directions.  This call can only be issued from \kw{init()}.
882
883
884
885 \prototype{FEM\_Sym\_coordinates}
886 \function{void FEM\_Sym\_coordinates(int elTypeOrMinusOne,double *locs);}
887 \function{SUBROUTINE FEM\_Sym\_coordinates(elTypeOrZero,locs)}
888   \args{INTEGER, INTENT(IN) :: elTypeOrZero}
889   \args{double precision, intent(inout) :: locs(3,<number of items>)}
890
891 This call adjusts the 3d locations listed in \kw{locs} so they respect the symmetries
892 of their corresponding item.  If elTypeOrZero is an element type,
893 the locations are adjusted to match with the corresponding element;
894 if elTypeOrZero is zero, the locations are adjusted to match up with
895 the corresponding node.
896
897 This call is needed because symmetry ghost nodes and elements
898 initially have their original locations, which must be adjusted
899 to respect the symmetry boundaries.  Thus this call is needed
900 both for initial location data (e.g., from \kw{FEM\_Get\_node\_data})
901 as well as any communicated location data (e.g., from
902 \kw{FEM\_Update\_ghost\_field}).
903
904 This call can only be issued from \kw{driver()}.
905
906
907
908 \subsection{Advanced Symmetries and Ghosts--Lower Layer}
909
910 The geometric symmetry layer in the preceeding section is actually
911 a thin wrapper around this lower, more difficult to use layer.
912
913 \prototype{FEM\_Set\_sym\_nodes}
914 \function{void FEM\_Set\_sym\_nodes(const int *canon,const int *sym);}
915 \function{SUBROUTINE FEM\_Set\_sym\_nodes(canon,sym)}
916   \args{INTEGER, INTENT(IN) :: canon(nNodes)}
917   \args{INTEGER, INTENT(IN) :: sym(nNodes)}
918
919 This call describes all possible symmetries in an extremely terse format.
920 It can only be called from \kw{init()}.
921 The ``canonicalization array'' canon maps nodes to their canonical 
922 representative---if canon($i$)=canon($j$), nodes $i$ and $j$ are 
923 images of each other under some symmetry.  The sym array has bits set
924 for each symmetry boundary passing through a node.
925
926 For example, a 2d domain with 6 elements A, B, C, D, E, and F and 12 
927 nodes numbered 1-12 that is 
928 mirror-symmetric on the horizontal boundaries but periodic in the 
929 vertical boundaries would look like:
930
931 \begin{alltt}
932    D^'|  D^ |  E^ |  F^ |  F^`
933    -  1  -  2  -  3  -  4  -
934    A' |  A  |  B  |  C  |  C`
935    -  5  -  6  -  7  -  8  -
936    D' |  D  |  E  |  F  |  F`
937    -  9  - 10  -  11 -  12 -
938    Av'|  Av |  Bv |  Cv |  Cv`
939
940   v indicates the value has been shifted down (bottom boundary),
941   ^ indicates the value has been shifted up (top boundary),
942   ' indicates the value has been copied from the left (right boundary),
943   ` indicates the value has been copied from the right (left boundary).
944 \end{alltt}
945
946 If we mark the left border with 1, the top with 2, the right with 4,
947 and the bottom with 8, this situation is indicated by topologically pasting the 
948 top row to the bottom row by setting their \kw{canon} entries equal, and 
949 marking each node with its symmetries.
950
951 \begin{center}
952 \begin{tabular}{|l|l|l|}\hline
953   Node & \kw{canon} &  \kw{sym}              \\\hline
954     1  &    1  &      3 (left + top)   \\
955     2  &    2  &      2 (top)   \\
956     3  &    3  &      2 (top)   \\
957     4  &    4  &      6 (top + right)   \\
958     5  &    5  &      1 (left)   \\
959     6  &    6  &      0 (none)   \\
960     7  &    7  &      0 (none)   \\
961     8  &    8  &      4 (right)   \\
962     9  &    1  &      9 (left+bottom)    \\
963     10 &    2  &      8 (bottom)   \\
964     11 &    3  &      8 (bottom)   \\
965     12 &    4  &      12 (bottom+right)   \\
966 \hline
967 \end{tabular}
968 \end{center}
969
970
971 \prototype{FEM\_Get\_sym}
972 \function{void FEM\_Get\_sym(int elTypeOrMinusOne,int *destSym);}
973 \function{void FEM\_Get\_sym(elTypeOrZero,destSym);}
974   \args{INTEGER, INTENT(IN) :: elTypeOrMinusOne }
975   \args{INTEGER, INTENT(OUT) :: destSym(nItems)}
976
977 This call extracts the list of symmetry conditions that apply to 
978 an item type.  If elType is an element type, it returns the
979 symmetry conditions that apply to that element type; if elType is
980 -1 (zero for Fortran), it returns the symmetry conditions that apply
981 to the nodes.  Symmetry conditions are normally only nonzero
982 for ghost nodes and elements.
983
984
985 Mirror symmetry conditions are not yet supported, nor are
986 multiple layers of symmetry ghosts, but both should be easy to add
987 without changing this interface.
988
989 % FIXME: document these
990 % void FEM\_Set\_partition(int *elem2chunk)
991 % int FTN\_NAME(FEM\_GET\_COMM\_PARTNERS,fem\_get\_comm\_partners)(void)
992 % int FTN\_NAME(FEM\_GET\_COMM\_PARTNER,fem\_get\_comm\_partner)(int *partnerNo)
993 % int FTN\_NAME(FEM\_GET\_COMM\_COUNT,fem\_get\_comm\_count)(int *partnerNo)
994 % void FTN\_NAME(FEM\_GET\_COMM\_NODES,fem\_get\_comm\_nodes)(int *pNo,int *nodeNos)
995 % void FTN\_NAME(FEM\_GET\_ELEM\_NUMBERS,fem\_get\_elem\_numbers)(int *gNo)
996 % void fem\_get\_node\_numbers(int *gNo)
997
998
999
1000
1001
1002 %%%%%%%%%%%%%%%%%%%%%% Old Mesh %%%%%%%%%%%%%%%%%%%%%%%%%%
1003
1004 \section{Older Mesh Routines}
1005 These routines have a simpler, but less flexible interface
1006 than the general routines described in Section~\ref{sec:entities}.  Because they are 
1007 easy to implement in terms of the new routines, they will remain
1008 part of the framework indefinitely.
1009 These routines always use the default mesh, as returned by 
1010 \kw{FEM\_Mesh\_default\_read} and \kw{FEM\_Mesh\_default\_write}.
1011
1012
1013 \prototype{FEM\_Get/Set\_elem}
1014 \function{void FEM\_Set\_elem(int elType,int  nEl,int  doublePerEl,int  nodePerEl);}
1015 \function{void FEM\_Get\_elem(int elType,int *nEl,int *doublePerEl,int *nodePerEl);}
1016 \function{SUBROUTINE FEM\_Set\_elem(elType,nEl,doublePerEl,nodePerEl)}
1017   \args{INTEGER, INTENT(IN)  :: elType,nEl,doublePerEl,nodePerEl}
1018 \function{SUBROUTINE FEM\_Get\_elem(elType,nEl,doublePerEl,nodePerEl)}
1019   \args{INTEGER, INTENT(IN)  :: elType}
1020   \args{INTEGER, INTENT(OUT) :: nEl,doublePerEl,nodePerEl}
1021
1022      Describe/retreive the number and type of elements.  \kw{ElType} is a
1023 user-defined small, unique element type tag.  \kw{nEl} is the number of elements 
1024 being registered.  \kw{doublesPerEl} and \kw{nodePerEl} are the number of doubles of user data, and nodes (respectively) associated with each element.
1025
1026      \kw{doublePerEl} or \kw{nodePerEl} may be zero, indicating that no user
1027 data or connectivity data (respectively) is associated with the element.
1028
1029      You can make this and any other mesh setup calls in any order---there is no need 
1030 to make them in linearly increasing order.  However, for a given type of element
1031 \kw{FEM\_Set\_elem} must be called before setting that element's connectivity or data.
1032
1033
1034 \prototype{FEM\_Get/Set\_elem\_conn}
1035 \function{void FEM\_Set\_elem\_conn(int elType,const int *conn);}
1036 \function{void FEM\_Get\_elem\_conn(int elType,int *conn);}
1037 \function{SUBROUTINE FEM\_Set\_elem\_conn\_r(elType,conn)}
1038   \args{INTEGER, INTENT(IN)  :: elType}
1039   \args{INTEGER, INTENT(IN),  dimension(nodePerEl,nEl) :: conn}
1040 \function{SUBROUTINE FEM\_Get\_elem\_conn\_r(elType,conn)}
1041   \args{INTEGER, INTENT(IN)  :: elType}
1042   \args{INTEGER, INTENT(OUT), dimension(nodePerEl,nEl) :: conn}
1043 \function{SUBROUTINE FEM\_Set\_elem\_conn\_c(elType,conn)}
1044   \args{INTEGER, INTENT(IN)  :: elType}
1045   \args{INTEGER, INTENT(IN),  dimension(nEl,nodePerEl) :: conn}
1046 \function{SUBROUTINE FEM\_Get\_elem\_conn\_c(elType,conn)}
1047   \args{INTEGER, INTENT(IN)  :: elType}
1048   \args{INTEGER, INTENT(OUT), dimension(nEl,nodePerEl) :: conn}
1049
1050      Describe/retreive the element connectivity array for this element
1051      type.  The connectivity array is indexed by the element number,
1052      and gives the indices of the nodes surrounding the element.  It is
1053      hence \kw{nodePerEl*nEl} integers long.
1054
1055      The C version array indices are zero-based, and must be stored in
1056      row-major order (a given element's surrounding nodes are stored
1057      contiguously in the conn array).  The Fortran version indices are
1058      one-based, and are available in row-major (named \_r) and
1059      column-major (named \_c) versions.  We recommend row-major storage
1060      because it results in better cache utilization (because the nodes
1061      around an element are stored contiguously).
1062      
1063      In this older interface, ghost nodes are indicated by invalid, 
1064
1065 \prototype{FEM\_Get/Set\_node}
1066 \function{void FEM\_Set\_node(int  nNode,int  doublePerNode);}
1067 \function{void FEM\_Get\_node(int *nNode,int *doublePerNode);}
1068 \function{SUBROUTINE FEM\_Set\_node(nNode,doublePerNode)}
1069   \args{INTEGER, INTENT(IN)  :: nNode,doublePerNode}
1070 \function{SUBROUTINE FEM\_Get\_node(nNode,doublePerNode)}
1071   \args{INTEGER, INTENT(OUT) :: nNode,doublePerNode}
1072
1073      Describe/retreive the number of nodes and doubles of user data
1074      associated with each node.  There is only one type of node, so no
1075      \kw{nodeType} identifier is needed.
1076
1077      \kw{doublePerNode} may be zero, indicating that no user data is
1078      associated with each node.
1079      
1080
1081 \subsection{Old Mesh Data}
1082 \prototype{FEM\_Get/Set\_data}
1083 \function{void FEM\_Set\_node\_data(const double *data);}
1084 \function{void FEM\_Get\_node\_data(double *data);}
1085 \function{void FEM\_Set\_elem\_data(int elType,const double *data);}
1086 \function{void FEM\_Get\_elem\_data(int elType,double *data);}
1087 \function{SUBROUTINE FEM\_Set\_node\_data\_r(data)}
1088   \args{REAL*8, INTENT(IN),  dimension(doublePerNode,nNode)  :: data}
1089 \function{SUBROUTINE FEM\_Get\_node\_data\_r(data)}
1090   \args{REAL*8, INTENT(OUT), dimension(doublePerNode,nNode)  :: data}
1091 \function{SUBROUTINE FEM\_Set\_node\_data\_c(data)}
1092   \args{REAL*8, INTENT(IN),  dimension(nNode,doublePerNode)  :: data}
1093 \function{SUBROUTINE FEM\_Get\_node\_data\_c(data)}
1094   \args{REAL*8, INTENT(OUT), dimension(nNode,doublePerNode)  :: data}
1095
1096 \function{SUBROUTINE FEM\_Set\_elem\_data\_r(elType,data)}
1097   \args{INTEGER, INTENT(IN)  :: elType}
1098   \args{REAL*8, INTENT(IN),  dimension(doublePerElem,nElem)  :: data}
1099 \function{SUBROUTINE FEM\_Get\_elem\_data\_r(elType,data)}
1100   \args{INTEGER, INTENT(IN)  :: elType}
1101   \args{REAL*8, INTENT(OUT), dimension(doublePerElem,nElem)  :: data}
1102 \function{SUBROUTINE FEM\_Set\_elem\_data\_c(elType,data)}
1103   \args{INTEGER, INTENT(IN)  :: elType}
1104   \args{REAL*8, INTENT(IN),  dimension(nElem,doublePerElem)  :: data}
1105 \function{SUBROUTINE FEM\_Get\_elem\_data\_c(elType,data)}
1106   \args{INTEGER, INTENT(IN)  :: elType}
1107   \args{REAL*8, INTENT(OUT), dimension(nElem,doublePerElem)  :: data}
1108
1109      Describe/retrieve the optional, uninterpreted user data associated with
1110 each node and element.  This user data is partitioned and reassembled along
1111 with the connectivity matrix, and may include initial conditions, node locations,
1112 material types, or any other data needed or produced by the program.   The Fortran
1113 arrays can be row- or column- major (see \kw{FEM\_Set\_elem\_conn} for
1114 details).  The row-major form is preferred.
1115
1116
1117
1118 \subsection{Old Ghost Numbering}
1119
1120
1121
1122 In this older version of the framework, FEM\_Get\_node and FEM\_Get\_elem return the 
1123 \textbf{total} number of nodes and elements, including ghosts. The routines below
1124 return the index of the first ghost node or element, where ghosts are numbered
1125 after all the real elements.  This old ghost numbering scheme does not work
1126 well when adding new ghosts, which is why the new ghost numbering scheme
1127 describes in Section~\ref{sec:ghostnum} is used in the new API.
1128
1129
1130 \begin{figure}[h]
1131 \begin{center}
1132 \includegraphics[width=4in]{fig/conn_indexing_old}
1133 \end{center}
1134 \caption{Old ghost element and node numbering.  \kw{FEM\_Get\_ghost\_*} returns $g$,
1135 \kw{FEM\_Get\_*} returns $n$.}
1136 \label{fig:connold}
1137 \end{figure}
1138
1139
1140
1141 \prototype{FEM\_Get\_ghost}
1142 \function{int FEM\_Get\_node\_ghost(void);}
1143 \function{int FEM\_Get\_elem\_ghost(int elemType);}
1144
1145 The examples below iterate over the real and ghost elements using the old numbering:
1146 \begin{alltt}
1147 C version:
1148         int firstGhost,max;
1149         FEM\_Get\_node(\&max, \&ignored);
1150         firstGhost=FEM\_Get\_node\_ghost();
1151         for (i=0;i<firstGhost;i++)
1152                 ... i is a real node...
1153         for (i=firstGhost;i<max;i++)
1154                 ... i is a ghost node ...
1155
1156 Fortran version:
1157         call FEM\_Get\_node(max,ignored);
1158         firstGhost=FEM\_Get\_node\_ghost();
1159         do i=1,firstGhost-1
1160                 ... i is a real node...
1161         end do
1162         do i=firstGhost,max
1163                 ... i is a ghost node...
1164         end do
1165 \end{alltt}
1166
1167
1168
1169 \subsection{Old Backward Compatability}
1170 \prototype{FEM\_Set\_mesh}
1171 \function{void FEM\_Set\_mesh(int nElem, int nNodes, int nodePerEl,const int* conn);}
1172
1173      This is a convenience routine equivalent to:
1174 \begin{alltt}
1175           FEM\_Set\_node(nNodes,0);
1176           FEM\_Set\_elem(0,nElem,0,nodePerEl);
1177           FEM\_Set\_elem\_Conn(0,conn);
1178 \end{alltt}
1179
1180 \function{SUBROUTINE FEM\_Set\_mesh(nElem,nNodes,nodePerEl,conn)}
1181     \args{INTEGER, INTENT(IN) :: nElem, nNodes, nodePerEl}
1182     \args{INTEGER, INTENT(IN), dimension(nElem,nodePerEl) :: conn;}
1183
1184      This is a convenience routine equivalent to:
1185 \begin{alltt}
1186           CALL FEM\_Set\_node(nNodes,0)
1187           CALL FEM\_Set\_elem(1,nElem,0,nodePerEl)
1188           CALL FEM\_Set\_elem\_Conn\_c(1,conn)
1189 \end{alltt}
1190
1191
1192 \subsection{Old Sparse Data}
1193
1194 Sparse data is typically used to represent boundary conditions.  For
1195 example, in a structural dynamics program typically some nodes have 
1196 an imposed force or position.  The routines in this section are 
1197 used to describe this kind of mesh-associated data---data that only 
1198 applies to some ``sparse'' subset of the nodes or elements.  
1199
1200
1201 \prototype{FEM\_Set\_sparse}
1202 \function{void FEM\_Set\_sparse(int S\_id,int nRec,
1203          const int *nodes,int nodesPerRec,
1204          const void *data,int dataPerRec,int dataType);}
1205 \function{SUBROUTINE FEM\_Set\_sparse(S\_id,nRec,nodes,nodesPerRec,data,dataPerRec,dataType)}
1206   \args{INTEGER, INTENT(IN) :: S\_id,nRec,nodesPerRec,dataPerRec,dataType}
1207   \args{INTEGER, INTENT(IN) :: nodes(nodesPerRec,nRec)}
1208   \args{varies,  INTENT(IN) :: data(dataPerRec,nRec)}
1209
1210 Register \kw{nRec} sparse data records with the framework under the number \kw{S\_id}. 
1211 The first call to \kw{FEM\_Set\_sparse} must give a \kw{S\_id} of zero in C (1 in fortran);
1212 and subsequent calls to \kw{FEM\_Set\_sparse} must give increasing consecutive \kw{S\_id}s.
1213
1214 One sparse data record consists of some number of nodes, listed in the
1215 \kw{nodes} array, and some amount of user data, listed in the data array.
1216 Sparse data records are copied into the chunks that contains all that record's listed 
1217 nodes.  Sparse data records are normally used to describe mesh boundary conditions--
1218 for node-associated boundary conditions, \kw{nodesPerRec} is 1; for triangle-associated
1219 boundary conditions, \kw{nodesPerRec} is 3.
1220
1221 In general, \kw{nodePerRec} gives the number of nodes associated with each
1222 sparse data record, and \kw{nodes} gives the actual node numbers.
1223 \kw{dataPerRec} gives the number of data items associated with each sparse 
1224 data record, and \kw{dataType}, one of \kw{FEM\_BYTE}, \kw{FEM\_INT},
1225 \kw{FEM\_REAL}, or \kw{FEM\_DOUBLE}, gives the type of each data item.
1226 As usual, you may change or delete the \kw{nodes} and \kw{data} arrays after 
1227 this call returns.
1228
1229 For example, if the first set of sparse data is 17 sparse data records, each 
1230 containing 2 nodes stored in \kw{bNodes} and 3 integers stored in \kw{bDesc}, 
1231 we would make the call:
1232 \begin{alltt}
1233 /*C version*/
1234   FEM\_Set\_sparse(0,17, bNodes,2, bDesc,3,FEM\_INT);
1235 ! Fortran version
1236   CALL FEM\_Set\_sparse(1,17, bNodes,2, bDesc,3,FEM\_INT)
1237 \end{alltt}
1238
1239 \prototype{FEM\_Set\_sparse\_elem}
1240 \function{void FEM\_Set\_sparse\_elem(int S\_id,const int *rec2elem);}
1241 \function{SUBROUTINE FEM\_Set\_sparse\_elem(S\_id,rec2elem)}
1242   \args{INTEGER, INTENT(IN) :: S\_id}
1243   \args{INTEGER, INTENT(IN) :: rec2elem(2,nRec)}
1244
1245 Attach the previously-set sparse records \kw{S\_id} to the given elements.
1246 \kw{rec2elem} consists of pairs of integers---one for each sparse data record.
1247 The first integer in the pair is the
1248 element type to attach the sparse record to, and the second integer
1249 gives the element number within that type.  For example, to attach
1250 the 3 sparse records at \kw{S\_id} to the elements numbered 10, 11, and 12
1251 of the element type \kw{elType}, use:
1252
1253 \begin{alltt}
1254 /*C version*/
1255   int rec2elem[]={elType,10, elType,11, elType,12};
1256   FEM\_Set\_sparse\_elem(S\_id,rec2elem);
1257 ! Fortran version
1258   integer :: rec2elem(2,3);
1259   rec2elem(1,:)=elType
1260   rec2elem(2,1)=10; rec2elem(2,2)=11; rec2elem(2,3)=12;
1261   CALL FEM\_Set\_sparse\_elem(S\_id,rec2elem)
1262 \end{alltt}
1263
1264
1265 \prototype{FEM\_Get\_sparse}
1266 \function{int  FEM\_Get\_sparse\_length(int S\_id);}
1267 \function{void FEM\_Get\_sparse(int S\_id,int *nodes,void *data);}
1268 \function{function FEM\_Get\_sparse\_length(S\_id);}
1269   \args{INTEGER, INTENT(IN) :: S\_id}
1270   \args{INTEGER, INTENT(OUT) :: FEM\_Get\_sparse\_Length}
1271 \function{SUBROUTINE FEM\_Get\_sparse(S\_id,nodes,data);}
1272   \args{INTEGER, INTENT(IN) :: S\_id}
1273   \args{INTEGER, INTENT(OUT) :: nodes(nodesPerRec,FEM\_Get\_sparse\_Length(S\_id))}
1274   \args{varies,  INTENT(OUT) :: data(dataPerRec,FEM\_Get\_sparse\_Length(S\_id))}
1275
1276 Retrieve the previously registered sparse data from the framework.
1277 \kw{FEM\_Get\_sparse\_length} returns the number of records of sparse
1278 data registered under the given \kw{S\_id}; zero indicates no records
1279 are available.  \kw{FEM\_Get\_sparse} returns you the actual nodes
1280 (translated to local node numbers) and unchanged user data for
1281 these sparse records.
1282
1283 In this old interface, there is no way to access sparse ghosts.
1284
1285
1286
1287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288 \newpage
1289 \section{Mesh Modification}
1290
1291
1292 \prototype{FEM\_Update\_mesh}
1293 \function{void FEM\_Update\_mesh(FEM\_Update\_mesh\_fn routine, int callMeshUpdated,int doWhat);}
1294 \function{SUBROUTINE FEM\_Update\_mesh(routine,callMeshUpdated,doWhat)}
1295     \args{external, INTENT(IN) :: routine}
1296     \args{INTEGER, INTENT(IN) :: callMeshUpdated,doWhat}
1297
1298 Reassemble the mesh chunks from each partition into a single serial mesh,
1299 and call the given \kw{routine} on the assembled mesh.
1300 In this \kw{routine}, which runs on processor 0, the \kw{FEM\_Get} and \kw{FEM\_Set} routines
1301 can manipulate the serial mesh.  The parameter \kw{callMeshUpdated}, which must
1302 be non-zero, is passed down to \kw{routine} as \kw{routine(callMeshUpdated)}.
1303
1304 \kw{FEM\_Get} calls from
1305 \kw{driver()} will only return the new mesh after a \kw{FEM\_Update\_mesh} call
1306 where \kw{doWhat} is \kw{FEM\_MESH\_UPDATE}; otherwise \kw{FEM\_Get} from \kw{driver()} will still
1307 return the old mesh.
1308 \kw{FEM\_Update\_mesh} can only be called from driver; and must be called by the driver routine for
1309 every chunk. 
1310
1311 %     If \kw{doRepartition} is 0, the mesh is not repartitioned, and \kw{FEM\_Update\_mesh}
1312 %returns immediately.  If \kw{doRepartition} is 1, \kw{FEM\_Update\_mesh} blocks
1313 %until the reassembled serial mesh is repartitioned back into chunks and redistributed.
1314 %If \kw{doRepartition} is 2, 
1315
1316 \begin{center}
1317 \begin{tabular}{|l|l|l|l|}\hline
1318 \kw{doWhat} & Numeric & Repartition? & \kw{FEM\_Update\_mesh} \\\hline
1319 \kw{FEM\_MESH\_OUTPUT} & 0 & No & \kw{driver()} continues alongside \kw{routine} \\
1320 \kw{FEM\_MESH\_FINALIZE} & 2 & No & \kw{driver()} blocks until \kw{routine} finishes\\
1321 \kw{FEM\_MESH\_UPDATE} & 1 & Yes & \kw{driver()} blocks for the new partition \\
1322 \hline
1323 \end{tabular}
1324 \end{center}
1325
1326 For example, \kw{FEM\_Update\_mesh}(\uw{my\_output\_routine}, \uw{k}, \kw{FEM\_MESH\_OUTPUT}) 
1327 reassembles the mesh and calls a routine named
1328 \uw{my\_output\_routine(k)} while the driver routines continue with the computation.
1329 This might be useful, for example, for writing out intermediate solutions as a 
1330 single file; writing outputs from \kw{driver()} is more efficient but often results 
1331 in a separate file for each mesh chunk.
1332
1333    To block the driver routines during a call to a routine named
1334 \uw{my\_finalize\_routine(k)}, such as 
1335 at the end of the computation when the drivers have no other work to do, 
1336 use \kw{FEM\_Update\_mesh}(\uw{my\_finalize\_routine}, \uw{k}, \kw{FEM\_MESH\_FINALIZE}).
1337
1338      To reassemble, modify, and repartition the mesh, use
1339 \kw{FEM\_Update\_mesh}(\uw{my\_update\_routine}, \uw{k}, \kw{FEM\_MESH\_UPDATE}).
1340 It may be easier to perform major mesh modifications from \uw{my\_update\_routine(k)} than
1341 the drivers, since the entire serial mesh is available to \uw{my\_update\_routine(k)}.
1342
1343      \kw{FEM\_Update\_mesh} reassembles the serial mesh with an attempt to
1344      preserve the element and node global numbering.  If the new mesh
1345      has the same number and type of elements and nodes, the global
1346      numbers (and hence serial mesh) will be unchanged.  If new
1347      elements or nodes are added at each chunk, they will be assigned
1348      new unique global numbers.  If elements or nodes are removed,
1349      their global numbers are not re-used-- you can detect the
1350      resulting holes in the serial mesh since the user data associated
1351      with the deleted elements will be all zero.  Generally, however, it
1352      is less error-prone to perform mesh modifications only in \kw{driver()}
1353      or only in an update routine, rather than some in both.
1354
1355