4055b3f20c123dbeafd53f701602c778ddcfcf4d
[charm.git] / doc / netfem / manual.rst
1 =====================
2 Charm++ NetFEM Manual
3 =====================
4
5 .. contents::
6    :depth: 3
7
8 Introduction
9 ============
10
11 NetFEM was built to provide an easy way to visualize the current state
12 of a finite-element simulation, or any parallel program that computes on
13 an unstructured mesh. NetFEM is designed to require very little effort
14 to add to a program, and connects to the running program over the
15 network via the network protocol CCS (Converse Client/Server).
16
17 Compiling and Installing
18 ========================
19
20 NetFEM is part of Charm++, so it can be downloaded as part of charm. To
21 build NetFEM, just build FEM normally, or else do a make in
22 charm/netlrts-linux/tmp/libs/ck-libs/netfem/.
23
24 To link with NetFEM, add -module netfem to your program’s link line.
25 Note that you do *not* need to use the FEM framework to use NetFEM.
26
27 The netfem header file for C is called “netfem.h”, the header for
28 fortran is called ‘netfemf.h’. A simple example NetFEM program is in
29 charm/pgms/charm++/fem/simple2D/. A more complicated example is in
30 charm/pgms/charm++/fem/crack2D/.
31
32 Running NetFEM Online
33 =====================
34
35 Once you have a NetFEM program, you can run it and view the results
36 online by starting the program with CCS enabled:
37
38 .. code-block:: bash
39
40       foo.bar.edu>  ./charmrun ./myprogram +p2 ++server ++server-port 1234
41
42 “++server-port” controls the TCP port number to use for CCS—here, we use
43 1234. Currently, NetFEM only works with one chunk per processor—that is,
44 the -vp option cannot be used.
45
46 To view the results online, you then start the NetFEM client, which can
47 be downloaded for Linux or Windows from http://charm.cs.illinois.edu/research/fem/netfem/.
48
49 Enter the name of the machine running charmrun and the TCP port number
50 into the NetFEM client—for example, you might run:
51
52 .. code-block:: bash
53
54      netfem foo.bar.edu:1234
55
56 The NetFEM client will then connect to the program, download the most
57 recent mesh registered with NetFEM_POINTAT, and display it. At any time,
58 you can press the “update” button to reload the latest mesh.
59
60 Running NetFEM Offline
61 ======================
62
63 Rather than using CCS as above, you can register your meshes using
64 NetFEM_WRITE, which makes the server write out binary output dump files.
65 For example, to view timestep 10, which is written to the “NetFEM/10/“
66 directory, you’d run the client program as:
67
68 .. code-block:: bash
69
70      netfem NetFEM/10
71
72 In offline mode, the “update” button fetches the next extant timestep
73 directory.
74
75 NetFEM with other Visualization Tools
76 =====================================
77
78 You can use a provided converter program to convert the offline NetFEM
79 files into an XML format compatible with the powerful offline
80 visualization tool ParaView (http://paraview.org). The converter is
81 located in .../charm/src/libs/ck-libs/netfem/ParaviewConverter/. Build
82 the converter by simply issuing a “make” command in that
83 directory(assuming NetFEM already has been built).
84
85 Run the converter from the parent directory of the "NetFEM" directory to
86 be converted. The converter will generate a directory called
87 “ParaViewData”, which contains subdirectories for each timestep, along
88 with a “timestep”directory for index files for each timestep. All files
89 in the ParaViewData directory can be opened by ParaView. To open all
90 chunks for a given timestep, open the desired timestep file in
91 “ParaViewData/timesteps”. Also, individual partition files can also be
92 opened from “ParaViewData / :math:`<`\ timestep\ :math:`>` /
93 :math:`<`\ partition_num\ :math:`>`”.
94
95 Interface Basics
96 ================
97
98 You publish your data via NetFEM by making a series of calls to describe
99 the current state of your data. There are only 6 possible calls you can
100 make.
101
102 NetFEM_Begin is the first routine you call. NetFEM_End is the last
103 routine to call. These two calls bracket all the other NetFEM calls.
104
105 NetFEM_Nodes describes the properties of the nodes, or vertices of the
106 domain. NetFEM_Elements describes the properties of your elements
107 (triangles, tetrahedra, etc.). After making one of these calls, you list
108 the different data arrays associated with your nodes or elements by
109 making calls to NetFEM_Scalar or NetFEM_Vector.
110
111 For example, a typical finite element simulation might have a scalar
112 mass and vector position, velocity, and net force associated with each
113 node; and have a scalar stress value associated with each element. The
114 sequence of NetFEM calls this application would make would be:
115
116 .. code-block:: none
117
118      NetFEM_Begin
119        NetFEM_Nodes -- lists position of each node
120          NetFEM_Vector -- lists velocity of each node
121          NetFEM_Vector -- lists net force on each node
122          NetFEM_Scalar -- lists mass of each node
123
124        NetFEM_Elements -- lists the nodes of each element
125          NetFEM_Scalar -- lists the stress of each element
126
127      NetFEM_End
128
129 .. figure:: fig/example.pdf
130    :name: fig:example
131    :width: 5in
132
133    These arrays, typical of a finite element analysis program, might be
134    passed into NetFEM.
135
136 Simple Interface
137 ================
138
139 The details of how to make each call are:
140
141 | NetFEM NetFEM_Begin(int source, int step, int dim, int flavor);
142   integer function NetFEM_Begin(source,step,dim,flavor)
143 | Begins describing a single piece of a mesh. Returns a handle that is
144   used for each subsequent call until NetFEM_End. This call, like all
145   NetFEM calls, is collective—every processor should make the same calls
146   in the same order.
147
148 source identifies the piece of the mesh—use FEM_My_partition or CkMyPe.
149
150 step identifies which version of the mesh this is—for example, you might
151 use the timestep number. This is only used to identify the mesh in the
152 client.
153
154 dim is the number of spatial dimensions. For example, in a 2D
155 computation, you’d pass dim==2; in a 3D computation, dim==3. The client
156 currently only supports 2D or 3D computations.
157
158 flavor specifies what to do with the data. This can take the value
159 NetFEM_POINTAT, which is used in online visualization, and specifies
160 that NetFEM should only keep a pointer to your data rather than copy it
161 out of your arrays. Or it can take the value NetFEM_WRITE, which writes
162 out the data to files named “NetFEM/step/source.dat” for offline
163 visualization.
164
165 | void NetFEM_End(NetFEM n); subroutine NetFEM_End(n)
166 | Finishes describing a single piece of a mesh, which then makes the
167   mesh available for display.
168
169 | void NetFEM_Nodes(NetFEM n,int nNodes,const double \*loc,const char
170   \*name); subroutine NetFEM_Nodes(n,nNodes,loc,name)
171 | Describes the nodes in this piece of the mesh.
172
173 n is the NetFEM handle obtained from NetFEM_Begin.
174
175 nNodes is the number of nodes listed here.
176
177 loc is the location of each node. This must be double-precision array,
178 laid out with the same number of dimensions as passed to NetFEM_Begin.
179 For example, in C the location of a 2D node :math:`n` is stored in
180 loc[2*n+0] (x coordinate) and loc[2*n+1] (y coordinate). In Fortran,
181 location of a node :math:`n` is stored in loc(:,n).
182
183 name is a human-readable name for the node locations to display in the
184 client. We recommend also including the location units here, for example
185 "Position (m)".
186
187 | void NetFEM_Elements(NetFEM n,int nElements,int nodePerEl,const int
188   \*conn,const char \*name); subroutine
189   NetFEM_Elements(n,nElements,nodePerEl,conn,name)
190 | Describes the elements in this piece of the mesh. Unlike NetFEM_Nodes,
191   this call can be repeated if there are different types of elements
192   (For example, some meshes contain a mix of triangles and
193   quadrilaterals).
194
195 n is the NetFEM handle obtained from NetFEM_Begin.
196
197 nElements is the number of elements listed here.
198
199 nodePerEl is the number of nodes for each element. For example, a
200 triangle has 3 nodes per element; while tetrahedra have 4.
201
202 conn gives the index of each element’s nodes. Note that when called from
203 C, the first node is listed in conn as 0 (0-based node indexing), and
204 element :math:`e`\ ’s first node is stored in conn[e*nodePerEl+0]. When
205 called from Fortran, the first node is listed as 1 (1-based node
206 indexing), and element :math:`e`\ ’s first node is stored in conn(1,e)
207 or conn((e-1)*nodePerEl+1).
208
209 name is a human-readable name for the elements to display in the client.
210 For example, this might be "Linear-Strain Triangles".
211
212 | void NetFEM_Vector(NetFEM n,const double \*data,const char \*name);
213   subroutine NetFEM_Vector(n,data,name)
214 | Describes a spatial vector associated with each node or element in the
215   mesh. Attaches the vector to the most recently listed node or element.
216   You can repeat this call several times to describe different vectors.
217
218 n is the NetFEM handle obtained from NetFEM_Begin.
219
220 data is the double-precision array of vector values. The dimensions of
221 the array have to match up with the node or element the data is
222 associated with-in C, a 2D element :math:`e`\ ’s vector starts at
223 data[2*e]; in Fortran, element :math:`e`\ ’s vector is data(:,e).
224
225 name is a human-readable name for this vector data. For example, this
226 might be "Velocity (m/s)".
227
228 | void NetFEM_Scalar(NetFEM n,const double \*data,int dataPer,const char
229   \*name); subroutine NetFEM_Scalar(n,data,dataPer,name)
230 | Describes some scalar data associated with each node or element in the
231   mesh. Like NetFEM_Vector, this data is attached to the most recently
232   listed node or element and this call can be repeated. For a node or
233   element, you can make the calls to NetFEM_Vector and NetFEM_Scalar in
234   any order.
235
236 n is the NetFEM handle obtained from NetFEM_Begin.
237
238 data is the double-precision array of values. In C, an element
239 :math:`e`\ ’s scalar values start at data[dataPer*e]; in Fortran,
240 element :math:`e`\ ’s values are in data(:,e).
241
242 dataPer is the number of values associated with each node or element.
243 For true scalar data, this is 1; but can be any value. Even if dataPer
244 happens to equal the number of dimensions, the client knows that this
245 data does not represent a spatial vector.
246
247 name is a human-readable name for this scalar data. For example, this
248 might be "Mass (Kg)" or "Stresses (pure)".
249
250 Advanced “Field” Interface
251 ==========================
252
253 This more advanced interface can be used if you store your node or
254 element data in arrays of C structs or Fortran TYPEs. To use this
255 interface, you’ll have to provide the name of your struct and field.
256 Each “field” routine is just an extended version of a regular NetFEM
257 call described above, and can be used in place of the regular NetFEM
258 call. In each case, you pass a description of your field in addition to
259 the usual NetFEM parameters.
260
261 In C, use the macro “NetFEM_Field(theStruct,theField)” to describe the
262 FIELD. For example, to describe the field “loc” of your structure named
263 “node_t”,
264
265 ::
266
267       node_t *myNodes=...;
268       ..., NetFEM_Field(node_t,loc), ...
269
270 In Fortran, you must pass as FIELD the byte offset from the start of the
271 structure to the start of the field, then the size of the structure. The
272 FEM "foffsetof" routine, which returns the number of bytes between its
273 arguments, can be used for this. For example, to describe the field
274 “loc” of your named type “NODE”,
275
276 .. code-block:: fortran
277
278       TYPE(NODE), ALLOCATABLE :: n(:)
279       ..., foffsetof(n(1),n(1)%loc),foffsetof(n(1),n(2)), ...
280
281 | void NetFEM_Nodes_field(NetFEM n,int nNodes,FIELD,const void \*loc,const
282   char \*name);
283 | subroutine NetFEM_Nodes_field(n,nNodes,FIELD,loc,name)
284 | A FIELD version of NetFEM_Nodes.
285
286 | void NetFEM_Elements_field(NetFEM n,int nElements,int
287   nodePerEl,FIELD,int idxBase,const int \*conn,const char \*name);
288 | subroutine NetFEM_Elements_field(n,nElements,nodePerEl,FIELD,idxBase,conn,name)
289 | A FIELD version of NetFEM_Elements. This version also allows you to
290   control the starting node index of the connectivity array—in C, this is
291   normally 0; in Fortran, this is normally 1.
292
293 | void NetFEM_Vector_field(NetFEM n,const double \*data,FIELD,const char
294   \*name);
295 | subroutine NetFEM_Vector_field(n,data,FIELD,name)
296 | A FIELD version of NetFEM_Vector.
297
298 | void NetFEM_Scalar_field(NetFEM n,const double \*data,int
299   dataPer,FIELD,const char \*name); subroutine
300   NetFEM_Scalar(n,data,dataPer,FIELD,name)
301 | A FIELD version of NetFEM_Scalar.