/[escript]/trunk/doc/user/escript.tex
ViewVC logotype

Contents of /trunk/doc/user/escript.tex

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2647 - (show annotations)
Fri Sep 4 05:25:25 2009 UTC (9 years, 7 months ago) by gross
File MIME type: application/x-tex
File size: 62396 byte(s)
fault system add. There is still an example for the usage missing.
1
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % Copyright (c) 2003-2009 by University of Queensland
5 % Earth Systems Science Computational Center (ESSCC)
6 % http://www.uq.edu.au/esscc
7 %
8 % Primary Business: Queensland, Australia
9 % Licensed under the Open Software License version 3.0
10 % http://www.opensource.org/licenses/osl-3.0.php
11 %
12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13
14
15 \chapter{The Module \escript}
16 \label{ESCRIPT CHAP}
17
18
19 \begin{figure}
20 \includegraphics[width=\textwidth]{figures/EscriptDiagram1}
21 \caption{\label{ESCRIPT DEP}Dependency of Function Spaces in Finley. An arrow indicates that a function in the
22 function space at the starting point can be interpolated to the function space of the arrow target.
23 All functionspaces on the left side can be interpolated to any of the functionspaces on the right.}
24 \end{figure}
25
26 \escript is a Python module that allows you to represent the values of
27 a function at points in a \Domain in such a way that the function will
28 be useful for the Finite Element Method (FEM) simulation. It also
29 provides what we call a function space that describes how the data is
30 used in the simulation. Stored along with the data is information
31 about the elements and nodes which will be used by \finley.
32
33 In order to understand what we mean by the term 'function space',
34 consider that the solution of a partial differential equation
35 \index{partial differential equation} (PDE) is a function on a domain
36 $\Omega$. When solving a PDE using FEM, the solution is
37 piecewise-differentiable but, in general, its gradient is
38 discontinuous. To reflect these different degrees of smoothness,
39 different function spaces are used. For instance, in FEM, the
40 displacement field is represented by its values at the nodes of the
41 mesh, and so is continuous. The strain, which is the symmetric
42 part of the gradient of the displacement field, is stored on the
43 element centers, and so is considered to be discontinuous.
44
45 A function space is described by a \FunctionSpace object. The
46 following statement generates the object \var{solution_space} which is
47 a \FunctionSpace object and provides access to the function space of
48 PDE solutions on the \Domain \var{mydomain}:
49
50 \begin{python}
51 solution_space=Solution(mydomain)
52 \end{python}
53 The following generators for function spaces on a \Domain \var{mydomain} are commonly used:
54 \begin{itemize}
55 \item \var{Solution(mydomain)}: solutions of a PDE.
56 \item \var{ReducedSolution(mydomain)}: solutions of a PDE with a reduced smoothness requirement.
57 \item \var{ContinuousFunction(mydomain)}: continuous functions, eg. a temperature distribution.
58 \item \var{Function(mydomain)}: general functions which are not necessarily continuous, eg. a stress field.
59 \item \var{FunctionOnBoundary(mydomain)}: functions on the boundary of the domain, eg. a surface pressure.
60 \item \var{FunctionOnContact0(mydomain)}: functions on side $0$ of the discontinuity.
61 \item \var{FunctionOnContact1(mydomain)}: functions on side $1$ of the discontinuity.
62 \end{itemize}
63 In some cases under-integration is used. For these cases the user may use a
64 \FunctionSpace from the floowing list:
65 \begin{itemize}
66 \item \var{ReducedFunction(mydomain)}
67 \item \var{ReducedFunctionOnBoundary(mydomain)}
68 \item \var{ReducedFunctionOnContact0(mydomain)}
69 \item \var{ReducedFunctionOnContact1(mydomain)}
70 \end{itemize}
71 In comparison to the full teh corresponding full version
72 they use a reduced number of integration nodes (typically one only) to represent values.
73
74
75 The reduced smoothness for PDE solution is often used to fulfill the Ladyzhenskaya–-Babuska–-Brezzi condition \cite{LBB} when
76 solving saddle point problems \index{saddle point problems}, eg. the Stokes equation.
77 A discontinuity \index{discontinuity} is a region within the domain across which functions may be discontinuous.
78 The location of discontinuity is defined in the \Domain object.
79 \fig{ESCRIPT DEP} shows the dependency between the types of function spaces in Finley (other libraries may have different relationships).
80
81 The solution of a PDE is a continuous function. Any continuous function can be seen as a general function
82 on the domain and can be restricted to the boundary as well as to one side of
83 discontinuity (the result will be different depending on
84 which side is chosen). Functions on any side of the
85 discontinuity can be seen as a function on the corresponding other side.
86
87 A function on the boundary or on one side of
88 the discontinuity cannot be seen as a general function on the domain as there are no values
89 defined for the interior. For most PDE solver libraries
90 the space of the solution and continuous functions is identical, however in some cases, eg.
91 when periodic boundary conditions are used in \finley, a solution
92 fulfills periodic boundary conditions while a continuous function does not have to be periodic.
93
94 The concept of function spaces describes the properties of
95 functions and allows abstraction from the actual representation
96 of the function in the context of a particular application. For instance,
97 in the FEM context a
98 function of the \Function type (written as \emph{Function()} in Figure~\ref{ESCRIPT DEP})
99 is usually represented by its values at the element center,
100 but in a finite difference scheme the edge midpoint of cells is preferred.
101 By changing its function space you can use the same function in a Finite Difference
102 scheme instead of Finite Element scheme.
103 Changing the function space of a particular function
104 will typically lead to a change of its representation.
105 So, when seen as a general function,
106 a continuous function which is typically represented by its values
107 on the node of the FEM mesh or finite difference grid
108 must be interpolated to the element centers or the cell edges,
109 respectively. Interpolation happens automatically in \escript
110 whenever it is required.
111
112 In \escript the class that stores these functions is called \Data.
113 The function is represented through its values on \DataSamplePoints where
114 the \DataSamplePoints are chosen according to the function space
115 of the function.
116 \Data class objects are used to define the coefficients
117 of the PDEs to be solved by a PDE solver library
118 and also to store the solutions of the PDE.
119
120 The values of the function have a rank which gives the
121 number of indices, and a \Shape defining the range of each index.
122 The rank in \escript is limited to the range $0$ through $4$ and
123 it is assumed that the rank and \Shape is the same for all \DataSamplePoints.
124 The \Shape of a \Data object is a tuple (list) \var{s} of integers. The length
125 of \var{s} is the rank of the \Data object and the \var{i}-th index ranges between $0$ and $\var{s[i]}-1$.
126 For instance, a stress field has rank $2$ and
127 \Shape $(d,d)$ where $d$ is the spatial dimension.
128 The following statement creates the \Data object
129 \var{mydat} representing a
130 continuous function with values
131 of \Shape $(2,3)$ and rank $2$:
132 \begin{python}
133 mydat=Data(value=1,what=ContinuousFunction(myDomain),shape=(2,3))
134 \end{python}
135 The initial value is the constant $1$ for all \DataSamplePoints and
136 all components.
137
138 \Data objects can also be created from any \numpy
139 array or any object, such as a list of floating point numbers,
140 that can be converted into a \numpyNDA \cite{NUMPY}.
141 The following two statements
142 create objects which are equivalent to \var{mydat}:
143 \begin{python}
144 mydat1=Data(value=numpy.ones((2,3)),what=ContinuousFunction(myDomain))
145 mydat2=Data(value=[[1,1],[1,1],[1,1]],what=ContinuousFunction(myDomain))
146 \end{python}
147 In the first case the initial value is \var{numpy.ones((2,3))}
148 which generates a $2 \times 3$ matrix as a \numpyNDA
149 filled with ones. The \Shape of the created \Data object
150 it taken from the \Shape of the array. In the second
151 case, the creator converts the initial value, which is a list of lists,
152 and converts it into a \numpyNDA before creating the actual
153 \Data object.
154
155 For convenience \escript provides creators for the most common types
156 of \Data objects in the following forms (\var{d} defines the
157 spatial dimension):
158 \begin{itemize}
159 \item \var{Scalar(0,Function(mydomain))} is the same as \var{Data(0,Function(myDomain),(,))} (each value is a scalar),
160 e.g a temperature field.
161 \item \var{Vector(0,Function(mydomain))} is the same as \var{Data(0,Function(myDomain),(d))} (each value is a vector), e.g
162 a velocity field.
163 \item \var{Tensor(0,Function(mydomain))} is the same as \var{Data(0,Function(myDomain),(d,d))},
164 eg. a stress field.
165 \item \var{Tensor4(0,Function(mydomain))} is the same as \var{Data(0,Function(myDomain),(d,d,d,d))}
166 eg. a Hook tensor field.
167 \end{itemize}
168 Here the initial value is $0$ but any object that can be converted into a \numpyNDA and whose \Shape
169 is consistent with \Shape of the \Data object to be created can be used as the initial value.
170
171 \Data objects can be manipulated by applying unary operations (eg. cos, sin, log) point
172 and can be combined point-wise by applying arithmetic operations (eg. +, - ,* , /).
173 It is to be emphasized that \escript itself does not handle any spatial dependencies as
174 it does not know how values are interpreted by the processing PDE solver library.
175 However \escript invokes interpolation if this is needed during data manipulations.
176 Typically, this occurs in binary operation when both arguments belong to different
177 function spaces or when data are handed over to a PDE solver library
178 which requires functions to be represented in a particular way.
179
180 The following example shows the usage of {\tt Data} objects: Assume we have a
181 displacement field $u$ and we want to calculate the corresponding stress field
182 $\sigma$ using the linear--elastic isotropic material model
183 \begin{eqnarray}\label{eq: linear elastic stress}
184 \sigma\hackscore {ij}=\lambda u\hackscore {k,k} \delta\hackscore {ij} + \mu ( u\hackscore {i,j} + u\hackscore {j,i})
185 \end{eqnarray}
186 where $\delta\hackscore {ij}$ is the Kronecker symbol and
187 $\lambda$ and $\mu$ are the Lame coefficients. The following function
188 takes the displacement {\tt u} and the Lame coefficients
189 \var{lam} and \var{mu} as arguments and returns the corresponding stress:
190 \begin{python}
191 from esys.escript import *
192 def getStress(u,lam,mu):
193 d=u.getDomain().getDim()
194 g=grad(u)
195 stress=lam*trace(g)*kronecker(d)+mu*(g+transpose(g))
196 return stress
197 \end{python}
198 The variable
199 \var{d} gives the spatial dimension of the
200 domain on which the displacements are defined.
201 \var{kronecker} returns the Kronecker symbol with indexes
202 $i$ and $j$ running from $0$ to \var{d}-1. The call \var{grad(u)} requires
203 the displacement field \var{u} to be in the \var{Solution} or \ContinuousFunction
204 function space. The result \var{g} as well as the returned stress will be in the \Function function space.
205 If, for example, \var{u} is the solution of a PDE then \var{getStress} might be called
206 in the following way:
207 \begin{python}
208 s=getStress(u,1.,2.)
209 \end{python}
210 However \var{getStress} can also be called with \Data objects as values for
211 \var{lam} and \var{mu} which,
212 for instance in the case of a temperature dependency, are calculated by an expression.
213 The following call is equivalent to the previous example:
214 \begin{python}
215 lam=Scalar(1.,ContinuousFunction(mydomain))
216 mu=Scalar(2.,Function(mydomain))
217 s=getStress(u,lam,mu)
218 \end{python}
219
220 The function \var{lam} belongs to the \ContinuousFunction function space
221 but with \var{g} the function \var{trace(g)} is in the \Function function space.
222 In the evaluation of the product \var{lam*trace(g)} we have different function
223 spaces (on the nodes versus in the centers) and at first glance we have incompatible data.
224 \escript converts the arguments in an appropriate function space according to
225 Table~\ref{ESCRIPT DEP}. In this example that means
226 \escript sees \var{lam} as a function of the \Function function space.
227 In the context of FEM this means the nodal values of
228 \var{lam} are interpolated to the element centers.
229 The interpolation is automatic and requires no special handling.
230
231 \begin{figure}
232 \includegraphics[width=\textwidth]{figures/EscriptDiagram2}
233 \caption{\label{Figure: tag}Element Tagging. A rectangular mesh over a region with two rock types {\it white} and {\it gray}.
234 The number in each cell refers to the major rock type present in the cell ($1$ for {\it white} and $2$ for {\it gray}).
235 }
236 \end{figure}
237
238 Material parameters such as the Lame coefficients are typically dependent on rock types present in the
239 area of interest. A common technique to handle these kinds of material parameters is "tagging", which
240 uses storage efficiently. \fig{Figure: tag}
241 shows an example. In this case two rock types {\it white} and {\it gray} can be found in the domain. The domain
242 is subdivided into triangular shaped cells. Each
243 cell has a tag indicating the rock type predominately found in this cell. Here $1$ is used to indicate
244 rock type {\it white} and $2$ for rock type {\it gray}. The tags are assigned at the time when the cells are generated
245 and stored in the \Domain class object. To allow easier usage of tags, names can be used instead of numbers. These names are typically defined
246 at the time when the geometry is generated.
247
248 The following statements show how, for the
249 example of \fig{Figure: tag}, the stress calculation discussed above and tagged values are used for
250 \var{lam}:
251 \begin{python}
252 lam=Scalar(value=2.,what=Function(mydomain))
253 insertTaggedValue(lam,white=30.,gray=5000.)
254 s=getStress(u,lam,2.)
255 \end{python}
256 In this example \var{lam} is set to $30$ for those cells with tag {\it white} (=$1$) and to $5000.$ for those cells
257 with tag {\it gray} (=$2$_. The initial value $2$ of \var{lam} is used as a default value for the case when a tag
258 is encountered which has not been linked with a value. The \var{getStress} method
259 does not need to be changed now that we are using tags.
260 \escript resolves the tags when \var{lam*trace(g)} is calculated.
261
262 This brings us to a very important point about \escript.
263 You can develop a simulation with constant Lame coefficients, and then later switch to tagged
264 Lame coefficients without otherwise changing your python script.
265 In short, you can use the same script to model with different domains and different types of input data.
266
267 There are three main ways in which \Data objects are represented internally: constant, tagged, and expanded.
268 In the constant case, the same value is used at each sample point and only a single value is stored to save memory.
269 In the expanded case, each sample point has an individual value (such as for the solution of a PDE).
270 This is where your largest data sets will be created because the values are stored as a complete array.
271 The tagged case has already been discussed above.
272
273 Expanded data is created when you create a \Data object with expanded=True.
274 Tagged data sets are created when you use the insertTaggedValue() method as shown above.
275
276 Values are accessed through a sample reference number. Operations on expanded \Data
277 objects have to be performed for each sample point individually. When tagged values are used, the values are
278 held in a dictionary. Operations on tagged data require processing the set of tagged values only, rather than
279 processing the value for each individual sample point.
280 \escript allows any mixture of constant, tagged and expanded data in a single expression.
281
282 \Data objects can be written to disk files and read with \var{dump} and \var{load}, both of which use \netCDF\cite{NETCDF}.
283 Use these to save data for visualization, checkpoint/restart or simply to save and reuse data that was expensive to compute.
284
285 For instance to save the coordinates of the data points of the
286 \ContinuousFunction to the file {\tt x.nc} use
287 \begin{python}
288 x=ContinuousFunction(mydomain).getX()
289 x.dump("x.nc")
290 mydomain.dump(`dom.nc`)
291 \end{python}
292 To recover the object \var{x} and \var{mydomain} was a \finley mesh use
293 \begin{python}
294 from esys.finley import LoadMesh
295 mydomain=LoadMesh('dom.nc')
296 x=load("x.nc", mydomain)
297 \end{python}
298 It possible to rerun the mechanism that was originally used to generates
299 \var{mydomain} to recreate \var{mydomain}. However in most cases using \var{dump} and
300 load is faster in particular if optimization has been applied. In case that
301 \escript is running on more than one \MPI processor the \var{dump} will create an individual file for each processor containing the local data. In order to avoid conflicts the file name is extended by the \MPI processor rank.
302
303 The function space of the \Data is stored in {\tt x.nc}, though.
304 If the \Data object
305 is expanded, the number of data points in the file and of the \Domain for the particular \FunctionSpace must match.
306 Moreover, the ordering of the values is checked using the reference identifiers provided by
307 \FunctionSpace on the \Domain. In some cases, data points will be re-ordered. Take care to be sure you get what you want!
308
309
310 \section{\escript Classes}
311 \declaremodule{extension}{esys.escript}
312 \modulesynopsis{Data manipulation}
313
314 \subsection{\Domain class}
315 \begin{classdesc}{Domain}{}
316 A \Domain object is used to describe a geometric region together with
317 a way of representing functions over this region.
318 The \Domain class provides an abstract interface to the domain of \FunctionSpace and \Data objects.
319 \Domain needs to be subclassed in order to provide a complete implementation.
320 \end{classdesc}
321 The following methods are available:
322 \begin{methoddesc}[Domain]{getDim}{}
323 returns the spatial dimension of the \Domain.
324 \end{methoddesc}
325 \begin{methoddesc}[Domain]{dump}{filename}
326 dumps the \Domain into the file \var{filename}.
327 \end{methoddesc}
328 \begin{methoddesc}[Domain]{getX}{}
329 returns the locations in the \Domain. The \FunctionSpace of the returned
330 \Data object is chosen by the \Domain implementation. Typically it will be
331 in the \Function.
332 \end{methoddesc}
333
334 \begin{methoddesc}[Domain]{setX}{newX}
335 assigns a new location to the \Domain. \var{newX} has to have \Shape $(d,)$
336 where $d$ is the spatial dimension of the domain. Typically \var{newX} must be
337 in the \ContinuousFunction but the space actually to be used depends on the \Domain implementation.
338 \end{methoddesc}
339
340 \begin{methoddesc}[Domain]{getNormal}{}
341 returns the surface normals on the boundary of the \Domain as \Data object.
342 \end{methoddesc}
343
344 \begin{methoddesc}[Domain]{getSize}{}
345 returns the local sample size, e.g. the element diameter, as \Data object.
346 \end{methoddesc}
347
348 \begin{methoddesc}[Domain]{setTagMap}{tag_name, tag}
349 defines a mapping of the tag name \var{tag_name} to the \var{tag}.
350 \end{methoddesc}
351 \begin{methoddesc}[Domain]{getTag}{tag_name}
352 returns the tag associated with the tag name \var{tag_name}.
353 \end{methoddesc}
354 \begin{methoddesc}[Domain]{isValidTagName}{tag_name}
355 return \True if \var{tag_name} is a valid tag name.
356 \end{methoddesc}
357
358 \begin{methoddesc}[Domain]{__eq__}{arg}
359 (python == operator) returns \True if the \Domain \var{arg} describes the same domain. Otherwise
360 \False is returned.
361 \end{methoddesc}
362
363 \begin{methoddesc}[Domain]{__ne__}{arg}
364 (python != operator) returns \True if the \Domain \var{arg} does not describe the same domain.
365 Otherwise \False is returned.
366 \end{methoddesc}
367
368 \begin{methoddesc}[Domain]{__str__}{arg}
369 (python str() function) returns string representation of the \Domain.
370 \end{methoddesc}
371
372 \begin{methoddesc}[Domain]{onMasterProcessor)}{}
373 returns \True if the processor is the master processor within
374 the \MPI processor group used by the \Domain. This is the processor with rank 0.
375 If \MPI support is not enabled the return value is always \True.
376 \end{methoddesc}
377
378 \begin{methoddesc}[Domain]{getMPISize}{}
379 returns the number of \MPI processors used for this \Domain. If \MPI support is not enabled
380 1 is returned.
381 \end{methoddesc}
382
383 \begin{methoddesc}[Domain]{getMPIRank}{}
384 returns the rank of the processor executing the statement
385 within the \MPI processor group used by the \Domain.
386 If \MPI support is not enabled 0 is returned.
387 \end{methoddesc}
388
389 \begin{methoddesc}[Domain]{MPIBarrier}{}
390 executes barrier synchronization within
391 the \MPI processor group used by the \Domain.
392 If \MPI support is not enabled, this command does nothing.
393 \end{methoddesc}
394
395 \subsection{\FunctionSpace class}
396 \begin{classdesc}{FunctionSpace}{}
397 \FunctionSpace objects are used to define properties of \Data objects, such as continuity. \FunctionSpace objects
398 are instantiated by generator functions. A \Data object in a particular \FunctionSpace is
399 represented by its values at \DataSamplePoints which are defined by the type and the \Domain of the
400 \FunctionSpace.
401 \end{classdesc}
402 The following methods are available:
403 \begin{methoddesc}[FunctionSpace]{getDim}{}
404 returns the spatial dimension of the \Domain of the \FunctionSpace.
405 \end{methoddesc}
406
407
408
409 \begin{methoddesc}[FunctionSpace]{getX}{}
410 returns the location of the \DataSamplePoints.
411 \end{methoddesc}
412
413 \begin{methoddesc}[FunctionSpace]{getNormal}{}
414 If the domain of functions in the \FunctionSpace
415 is a hyper-manifold (e.g. the boundary of a domain)
416 the method returns the outer normal at each of the
417 \DataSamplePoints. Otherwise an exception is raised.
418 \end{methoddesc}
419
420 \begin{methoddesc}[FunctionSpace]{getSize}{}
421 returns a \Data objects measuring the spacing of the \DataSamplePoints.
422 The size may be zero.
423 \end{methoddesc}
424
425 \begin{methoddesc}[FunctionSpace]{getDomain}{}
426 returns the \Domain of the \FunctionSpace.
427 \end{methoddesc}
428
429 \begin{methoddesc}[FunctionSpace]{setTags}{new_tag, mask}
430 assigns a new tag \var{new_tag} to all data sample
431 where \var{mask} is positive for a least one data point.
432 \var{mask} must be defined on the this \FunctionSpace.
433 Use the \var{setTagMap} to assign a tag name to \var{new_tag}.
434 \end{methoddesc}
435
436 \begin{methoddesc}[FunctionSpace]{__eq__}{arg}
437 (python == operator) returns \True if the \Domain \var{arg} describes the same domain. Otherwise
438 \False is returned.
439 \end{methoddesc}
440
441 \begin{methoddesc}[FunctionSpace]{__ne__}{arg}
442 (python != operator) returns \True if the \Domain \var{arg} do not describe the same domain.
443 Otherwise \False is returned.
444 \end{methoddesc}
445
446 \begin{methoddesc}[Domain]{__str__}{g}
447 (python str() function) returns string representation of the \Domain.
448 \end{methoddesc}
449
450 The following function provide generators for \FunctionSpace objects:
451 \begin{funcdesc}{Function}{domain}
452 returns the \Function on the \Domain \var{domain}. \Data objects in this type of \Function
453 are defined over the whole geometric region defined by \var{domain}.
454 \end{funcdesc}
455
456 \begin{funcdesc}{ContinuousFunction}{domain}
457 returns the \ContinuousFunction on the \Domain domain. \Data objects in this type of \Function
458 are defined over the whole geometric region defined by \var{domain} and assumed to represent
459 a continuous function.
460 \end{funcdesc}
461
462 \begin{funcdesc}{FunctionOnBoundary}{domain}
463 returns the \ContinuousFunction on the \Domain domain. \Data objects in this type of \Function
464 are defined on the boundary of the geometric region defined by \var{domain}.
465 \end{funcdesc}
466
467 \begin{funcdesc}{FunctionOnContactZero}{domain}
468 returns the \FunctionOnContactZero the \Domain domain. \Data objects in this type of \Function
469 are defined on side 0 of a discontinuity within the geometric region defined by \var{domain}.
470 The discontinuity is defined when \var{domain} is instantiated.
471 \end{funcdesc}
472
473 \begin{funcdesc}{FunctionOnContactOne}{domain}
474 returns the \FunctionOnContactOne on the \Domain domain.
475 \Data objects in this type of \Function
476 are defined on side 1 of a discontinuity within the geometric region defined by \var{domain}.
477 The discontinuity is defined when \var{domain} is instantiated.
478 \end{funcdesc}
479
480 \begin{funcdesc}{Solution}{domain}
481 returns the \SolutionFS on the \Domain domain. \Data objects in this type of \Function
482 are defined on geometric region defined by \var{domain} and are solutions of
483 partial differential equations \index{partial differential equation}.
484 \end{funcdesc}
485
486 \begin{funcdesc}{ReducedSolution}{domain}
487 returns the \ReducedSolutionFS on the \Domain domain. \Data objects in this type of \Function
488 are defined on geometric region defined by \var{domain} and are solutions of
489 partial differential equations \index{partial differential equation} with a reduced smoothness
490 for the solution approximation.
491 \end{funcdesc}
492
493 \subsection{\Data Class}
494 \label{SEC ESCRIPT DATA}
495
496 The following table shows arithmetic operations that can be performed point-wise on
497 \Data objects.
498 \begin{tableii}{l|l}{textrm}{expression}{Description}
499 \lineii{+\var{arg0}} {identical to \var{arg} \index{+}}
500 \lineii{-\var{arg0}} {negation\index{-}}
501 \lineii{\var{arg0}+\var{arg1}} {adds \var{arg0} and \var{arg1} \index{+}}
502 \lineii{\var{arg0}*\var{arg1}} {multiplies \var{arg0} and \var{arg1} \index{*}}
503 \lineii{\var{arg0}-\var{arg1}} {difference \var{arg1} from\var{arg1} \index{-}}
504 \lineii{\var{arg0}/\var{arg1}} {divide \var{arg0} by \var{arg1} \index{/}}
505 \lineii{\var{arg0}**\var{arg1}} {raises \var{arg0} to the power of \var{arg1} \index{**}}
506 \end{tableii}
507 At least one of the arguments \var{arg0} or \var{arg1} must be a
508 \Data object.
509 Either of the arguments may be a \Data object, a python number or a \numpy object.
510
511 If \var{arg0} or \var{arg1} are
512 not defined on the same \FunctionSpace, then an attempt is made to convert \var{arg0}
513 to the \FunctionSpace of \var{arg1} or to convert \var{arg1} to
514 the \FunctionSpace of \var{arg0}. Both arguments must have the same
515 \Shape or one of the arguments may be of rank 0 (a constant).
516
517 The returned \Data object has the same \Shape and is defined on
518 the \DataSamplePoints as \var{arg0} or \var{arg1}.
519
520 The following table shows the update operations that can be applied to
521 \Data objects:
522 \begin{tableii}{l|l}{textrm}{expression}{Description}
523 \lineii{\var{arg0}+=\var{arg2}} {adds \var{arg0} to \var{arg2} \index{+}}
524 \lineii{\var{arg0}*=\var{arg2}} {multiplies \var{arg0} with \var{arg2} \index{*}}
525 \lineii{\var{arg0}-=\var{arg2}} {subtracts \var{arg2} from\var{arg2} \index{-}}
526 \lineii{\var{arg0}/=\var{arg2}} {divides \var{arg0} by \var{arg2} \index{/}}
527 \lineii{\var{arg0}**=\var{arg2}} {raises \var{arg0} by \var{arg2} \index{**}}
528 \end{tableii}
529 \var{arg0} must be a \Data object. \var{arg1} must be a
530 \Data object or an object that can be converted into a
531 \Data object. \var{arg1} must have the same \Shape as
532 \var{arg0} or have rank 0. In the latter case it is
533 assumed that the values of \var{arg1} are constant for all
534 components. \var{arg1} must be defined in the same \FunctionSpace as
535 \var{arg0} or it must be possible to interpolate \var{arg1} onto the
536 \FunctionSpace of \var{arg0}.
537
538 The \Data class supports taking slices from a \Data object as well as assigning new values to a slice of an existing
539 \Data object. \index{slicing}
540 The following expressions for taking and setting slices are valid:
541 \begin{tableiii}{l|ll}{textrm}{rank of \var{arg}}{slicing expression}{\Shape of returned and assigned object}
542 \lineiii{0}{ no slicing } {-}
543 \lineiii{1}{\var{arg[l0:u0]}} {(\var{u0}-\var{l0},)}
544 \lineiii{2}{\var{arg[l0:u0,l1:u1]}} {(\var{u0}-\var{l0},\var{u1}-\var{l1})}
545 \lineiii{3}{\var{arg[l0:u0,l1:u1,l2:u2]} } {(\var{u0}-\var{l0},\var{u1}-\var{l1},\var{u2}-\var{l2})}
546 \lineiii{4}{\var{arg[l0:u0,l1:u1,l2:u2,l3:u3]}} {(\var{u0}-\var{l0},\var{u1}-\var{l1},\var{u2}-\var{l2},\var{u3}-\var{l3})}
547 \end{tableiii}
548 where \var{s} is the \Shape of \var{arg} and
549 \[0 \le \var{l0} \le \var{u0} \le \var{s[0]},\]
550 \[0 \le \var{l1} \le \var{u1} \le \var{s[1]},\]
551 \[0 \le \var{l2} \le \var{u2} \le \var{s[2]},\]
552 \[0 \le \var{l3} \le \var{u3} \le \var{s[3]}.\]
553 Any of the lower indexes \var{l0}, \var{l1}, \var{l2} and \var{l3} may not be present in which case
554 $0$ is assumed.
555 Any of the upper indexes \var{u0}, \var{u1}, \var{u2} and \var{u3} may be omitted, in which case, the upper limit for that dimension is assumed.
556 The lower and upper index may be identical, in which case the column and the lower or upper
557 index may be dropped. In the returned or in the object assigned to a slice, the corresponding component is dropped,
558 i.e. the rank is reduced by one in comparison to \var{arg}.
559 The following examples show slicing in action:
560 \begin{python}
561 t=Data(1.,(4,4,6,6),Function(mydomain))
562 t[1,1,1,0]=9.
563 s=t[:2,:,2:6,5] # s has rank 3
564 s[:,:,1]=1.
565 t[:2,:2,5,5]=s[2:4,1,:2]
566 \end{python}
567
568 \subsection{Generation of \Data objects}
569 \begin{classdesc}{Data}{value=0,shape=(,),what=FunctionSpace(),expand=\False}
570 creates a \Data object with \Shape \var{shape} in the \FunctionSpace \var{what}.
571 The values at all \DataSamplePoints are set to the double value \var{value}. If \var{expanded} is \True
572 the \Data object is represented in expanded from.
573 \end{classdesc}
574
575 \begin{classdesc}{Data}{value,what=FunctionSpace(),expand=\False}
576 creates a \Data object in the \FunctionSpace \var{what}.
577 The value for each \DataSamplePoints is set to \var{value}, which could be a \numpy, \Data object \var{value} or a dictionary of
578 \numpy or floating point numbers. In the latter case the keys must be integers and are used
579 as tags.
580 The \Shape of the returned object is equal to the \Shape of \var{value}. If \var{expanded} is \True
581 the \Data object is represented in expanded form.
582 \end{classdesc}
583
584 \begin{classdesc}{Data}{}
585 creates an \EmptyData object. The \EmptyData object is used to indicate that an argument is not present
586 where a \Data object is required.
587 \end{classdesc}
588
589 \begin{funcdesc}{Scalar}{value=0.,what=FunctionSpace(),expand=\False}
590 returns a \Data object of rank 0 (a constant) in the \FunctionSpace \var{what}.
591 Values are initialized with \var{value}, a double precision quantity. If \var{expanded} is \True
592 the \Data object is represented in expanded from.
593 \end{funcdesc}
594
595 \begin{funcdesc}{Vector}{value=0.,what=FunctionSpace(),expand=\False}
596 returns a \Data object of \Shape \var{(d,)} in the \FunctionSpace \var{what},
597 where \var{d} is the spatial dimension of the \Domain of \var{what}.
598 Values are initialed with \var{value}, a double precision quantity. If \var{expanded} is \True
599 the \Data object is represented in expanded from.
600 \end{funcdesc}
601
602 \begin{funcdesc}{Tensor}{value=0.,what=FunctionSpace(),expand=\False}
603 returns a \Data object of \Shape \var{(d,d)} in the \FunctionSpace \var{what},
604 where \var{d} is the spatial dimension of the \Domain of \var{what}.
605 Values are initialed with \var{value}, a double precision quantity. If \var{expanded} is \True
606 the \Data object is represented in expanded from.
607 \end{funcdesc}
608
609 \begin{funcdesc}{Tensor3}{value=0.,what=FunctionSpace(),expand=\False}
610 returns a \Data object of \Shape \var{(d,d,d)} in the \FunctionSpace \var{what},
611 where \var{d} is the spatial dimension of the \Domain of \var{what}.
612 Values are initialed with \var{value}, a double precision quantity. If \var{expanded} is \True
613 the \Data object is re\var{arg}presented in expanded from.
614 \end{funcdesc}
615
616 \begin{funcdesc}{Tensor4}{value=0.,what=FunctionSpace(),expand=\False}
617 returns a \Data object of \Shape \var{(d,d,d,d)} in the \FunctionSpace \var{what},
618 where \var{d} is the spatial dimension of the \Domain of \var{what}.
619 Values are initialized with \var{value}, a double precision quantity. If \var{expanded} is \True
620 the \Data object is represented in expanded from.
621 \end{funcdesc}
622
623 \begin{funcdesc}{load}{filename,domain}
624 recovers a \Data object on \Domain \var{domain} from the file \var{filename}, which was created by \function{dump}.
625 \end{funcdesc}
626
627 \subsection{\Data methods}
628 These are the most frequently-used methods of the
629 \Data class. A complete list of methods can be found on \ReferenceGuide.
630 \begin{methoddesc}[Data]{getFunctionSpace}{}
631 returns the \FunctionSpace of the object.
632 \end{methoddesc}
633
634 \begin{methoddesc}[Data]{getDomain}{}
635 returns the \Domain of the object.
636 \end{methoddesc}
637
638 \begin{methoddesc}[Data]{getShape}{}
639 returns the \Shape of the object as a \class{tuple} of
640 integers.
641 \end{methoddesc}
642
643 \begin{methoddesc}[Data]{getRank}{}
644 returns the rank of the data on each data point. \index{rank}
645 \end{methoddesc}
646
647 \begin{methoddesc}[Data]{isEmpty}{}
648 returns \True id the \Data object is the \EmptyData object.
649 Otherwise \False is returned.
650 Note that this is not the same as asking if the object contains no \DataSamplePoints.
651 \end{methoddesc}
652
653 \begin{methoddesc}[Data]{setTaggedValue}{tag_name,value}
654 assigns the \var{value} to all \DataSamplePoints which have the tag
655 assigned to \var{tag_name}. \var{value} must be an object of class
656 \class{numpy.ndarray} or must be convertible into a
657 \class{numpy.ndarray} object. \var{value} (or the corresponding
658 \class{numpy.ndarray} object) must be of rank $0$ or must have the
659 same rank like the object.
660 If a value has already be defined for tag \var{tag_name} within the object
661 it is overwritten by the new \var{value}. If the object is expanded,
662 the value assigned to \DataSamplePoints with tag \var{tag_name} is replaced by
663 \var{value}. If no tag is assigned tag name \var{tag_name}, no value is set.
664 \end{methoddesc}
665
666 \begin{methoddesc}[Data]{dump}{filename}
667 dumps the \Data object to the file \var{filename}. The file stores the
668 function space but not the \Domain. It is in the responsibility of the user to
669 save the \Domain.
670 \end{methoddesc}
671
672 \begin{methoddesc}[Data]{__str__}{}
673 returns a string representation of the object.
674 \end{methoddesc}
675
676 \subsection{Functions of \Data objects}
677 This section lists the most important functions for \Data class objects \var{a}.
678 A complete list and a more detailed description of the functionality can be found on \ReferenceGuide.
679 \begin{funcdesc}{saveVTK}{filename,**kwdata}
680 writes \Data defined by keywords in the file with \var{filename} using the
681 vtk file format \VTK file format. The key word is used as an identifier. The statement
682 \begin{python}
683 saveVTK("out.xml",temperature=T,velocity=v)
684 \end{python}
685 will write the scalar \var{T} as \var{temperature} and the vector \var{v} as \var{velocity} into the
686 file \file{out.xml}. Restrictions on the allowed combinations of \FunctionSpace apply.
687 \end{funcdesc}
688 \begin{funcdesc}{saveDX}{filename,**kwdata}
689 writes \Data defined by keywords in the file with \var{filename} using the
690 vtk file format \OpenDX file format. The key word is used as an identifier. The statement
691 \begin{python}
692 saveDX("out.dx",temperature=T,velocity=v)
693 \end{python}
694 will write the scalar \var{T} as \var{temperature} and the vector \var{v} as \var{velocity} into the
695 file \file{out.dx}. Restrictions on the allowed combinations of \FunctionSpace apply.
696 \end{funcdesc}
697 \begin{funcdesc}{kronecker}{d}
698 returns a \RankTwo \Data object in \FunctionSpace \var{d} such that
699 \begin{equation}
700 \code{kronecker(d)}\left[ i,j\right] = \left\{
701 \begin{array}{cc}
702 1 & \mbox{ if } i=j \\
703 0 & \mbox{ otherwise }
704 \end{array}
705 \right.
706 \end{equation}
707 If \var{d} is an integer a $(d,d)$ \numpy array is returned.
708 \end{funcdesc}
709 \begin{funcdesc}{identityTensor}{d}
710 is a synonym for \code{kronecker} (see above).
711 % returns a \RankTwo \Data object in \FunctionSpace \var{d} such that
712 % \begin{equation}
713 % \code{identityTensor(d)}\left[ i,j\right] = \left\{
714 % \begin{array}{cc}
715 % 1 & \mbox{ if } i=j \\
716 % 0 & \mbox{ otherwise }
717 % \end{array}
718 % \right.
719 % \end{equation}
720 % If \var{d} is an integer a $(d,d)$ \numpy array is returned.
721 \end{funcdesc}
722 \begin{funcdesc}{identityTensor4}{d}
723 returns a \RankFour \Data object in \FunctionSpace \var{d} such that
724 \begin{equation}
725 \code{identityTensor(d)}\left[ i,j,k,l\right] = \left\{
726 \begin{array}{cc}
727 1 & \mbox{ if } i=k \mbox{ and } j=l\\
728 0 & \mbox{ otherwise }
729 \end{array}
730 \right.
731 \end{equation}
732 If \var{d} is an integer a $(d,d,d,d)$ \numpy array is returned.
733 \end{funcdesc}
734 \begin{funcdesc}{unitVector}{i,d}
735 returns a \RankOne \Data object in \FunctionSpace \var{d} such that
736 \begin{equation}
737 \code{identityTensor(d)}\left[ j \right] = \left\{
738 \begin{array}{cc}
739 1 & \mbox{ if } j=i\\
740 0 & \mbox{ otherwise }
741 \end{array}
742 \right.
743 \end{equation}
744 If \var{d} is an integer a $(d,)$ \numpy array is returned.
745
746 \end{funcdesc}
747
748 \begin{funcdesc}{Lsup}{a}
749 returns the $L^{sup}$ norm of \var{arg}. This is the maximum of the absolute values
750 over all components and all \DataSamplePoints of \var{a}.
751 \end{funcdesc}
752
753 \begin{funcdesc}{sup}{a}
754 returns the maximum value over all components and all \DataSamplePoints of \var{a}.
755 \end{funcdesc}
756
757 \begin{funcdesc}{inf}{a}
758 returns the minimum value over all components and all \DataSamplePoints of \var{a}
759 \end{funcdesc}
760
761
762
763 \begin{funcdesc}{minval}{a}
764 returns at each \DataSamplePoints the minimum value over all components.
765 \end{funcdesc}
766
767 \begin{funcdesc}{maxval}{a}
768 returns at each \DataSamplePoints the maximum value over all components.
769 \end{funcdesc}
770
771 \begin{funcdesc}{length}{a}
772 returns at Euclidean norm at each \DataSamplePoints. For a \RankFour \var{a} this is
773 \begin{equation}
774 \code{length(a)}=\sqrt{\sum\hackscore{ijkl} \var{a} \left[i,j,k,l\right]^2}
775 \end{equation}
776 \end{funcdesc}
777 \begin{funcdesc}{trace}{a\optional{,axis_offset=0}}
778 returns the trace of \var{a}. This is the sum over components \var{axis_offset} and \var{axis_offset+1} with the same index. For instance in the
779 case of a \RankTwo function and this is
780 \begin{equation}
781 \code{trace(a)}=\sum\hackscore{i} \var{a} \left[i,i\right]
782 \end{equation}
783 and for a \RankFour function and \code{axis_offset=1} this is
784 \begin{equation}
785 \code{trace(a,1)}\left[i,j\right]=\sum\hackscore{k} \var{a} \left[i,k,k,j\right]
786 \end{equation}
787 \end{funcdesc}
788
789 \begin{funcdesc}{transpose}{a\optional{, axis_offset=None}}
790 returns the transpose of \var{a}. This swaps the first \var{axis_offset} components of \var{a} with the rest. If \var{axis_offset} is not
791 present \code{int(r/2)} is used where \var{r} is the rank of \var{a}.
792 the sum over components \var{axis_offset} and \var{axis_offset+1} with the same index. For instance in the
793 case of a \RankTwo function and this is
794 \begin{equation}
795 \code{transpose(a)}\left[i,j\right]=\var{a} \left[j,i\right]
796 \end{equation}
797 and for a \RankFour function and \code{axis_offset=1} this is
798 \begin{equation}
799 \code{transpose(a,1)}\left[i,j,k,l\right]=\var{a} \left[j,k,l,i\right]
800 \end{equation}
801 \end{funcdesc}
802
803 \begin{funcdesc}{swap_axes}{a\optional{, axis0=0 \optional{, axis1=1 }}}
804 returns \var{a} but with swapped components \var{axis0} and \var{axis1}. The argument \var{a} must be
805 at least of \RankTwo. For instance in the
806 for a \RankFour argument, \code{axis0=1} and \code{axis1=2} this is
807 \begin{equation}
808 \code{swap_axes(a,1,2)}\left[i,j,k,l\right]=\var{a} \left[i,k,j,l\right]
809 \end{equation}
810 \end{funcdesc}
811
812 \begin{funcdesc}{symmetric}{a}
813 returns the symmetric part of \var{a}. This is \code{(a+transpose(a))/2}.
814 \end{funcdesc}
815 \begin{funcdesc}{nonsymmetric}{a}
816 returns the non--symmetric part of \var{a}. This is \code{(a-transpose(a))/2}.
817 \end{funcdesc}
818 \begin{funcdesc}{inverse}{a}
819 return the inverse of \var{a}. This is
820 \begin{equation}
821 \code{matrix_mult(inverse(a),a)=kronecker(d)}
822 \end{equation}
823 if \var{a} has shape \code{(d,d)}. The current implementation is restricted to arguments of shape
824 \code{(2,2)} and \code{(3,3)}.
825 \end{funcdesc}
826 \begin{funcdesc}{eigenvalues}{a}
827 return the eigenvalues of \var{a}. This is
828 \begin{equation}
829 \code{matrix_mult(a,V)=e[i]*V}
830 \end{equation}
831 where \code{e=eigenvalues(a)} and \var{V} is suitable non--zero vector \var{V}.
832 The eigenvalues are ordered in increasing size.
833 The argument \var{a} has to be the symmetric, ie. \code{a=symmetric(a)}.
834 The current implementation is restricted to arguments of shape
835 \code{(2,2)} and \code{(3,3)}.
836 \end{funcdesc}
837 \begin{funcdesc}{eigenvalues_and_eigenvectors}{a}
838 return the eigenvalues and eigenvectors of \var{a}. This is
839 \begin{equation}
840 \code{matrix_mult(a,V[:,i])=e[i]*V[:,i]}
841 \end{equation}
842 where \code{e,V=eigenvalues_and_eigenvectors(a)}. The eigenvectors \var{V} are orthogonal and normalized, ie.
843 \begin{equation}
844 \code{matrix_mult(transpose(V),V)=kronecker(d)}
845 \end{equation}
846 if \var{a} has shape \code{(d,d)}. The eigenvalues are ordered in increasing size.
847 The argument \var{a} has to be the symmetric, ie. \code{a=symmetric(a)}.
848 The current implementation is restricted to arguments of shape
849 \code{(2,2)} and \code{(3,3)}.
850 \end{funcdesc}
851 \begin{funcdesc}{maximum}{*a}
852 returns the maximum value over all arguments at all \DataSamplePoints and for each component.
853 For instance
854 \begin{equation}
855 \code{maximum(a0,a1)}\left[i,j\right]=max(\var{a0} \left[i,j\right],\var{a1} \left[i,j\right])
856 \end{equation}
857 at all \DataSamplePoints.
858 \end{funcdesc}
859 \begin{funcdesc}{minimum}{*a}
860 returns the minimum value over all arguments at all \DataSamplePoints and for each component.
861 For instance
862 \begin{equation}
863 \code{minimum(a0,a1)}\left[i,j\right]=min(\var{a0} \left[i,j\right],\var{a1} \left[i,j\right])
864 \end{equation}
865 at all \DataSamplePoints.
866 \end{funcdesc}
867
868 \begin{funcdesc}{clip}{a\optional{, minval=0.}\optional{, maxval=1.}}
869 cuts back \var{a} into the range between \var{minval} and \var{maxval}. A value in the returned object equals
870 \var{minval} if the corresponding value of \var{a} is less than \var{minval}, equals \var{maxval} if the
871 corresponding value of \var{a} is greater than \var{maxval}
872 or corresponding value of \var{a} otherwise.
873 \end{funcdesc}
874 \begin{funcdesc}{inner}{a0,a1}
875 returns the inner product of \var{a0} and \var{a1}. For instance in the
876 case of \RankTwo arguments and this is
877 \begin{equation}
878 \code{inner(a)}=\sum\hackscore{ij}\var{a0} \left[j,i\right] \cdot \var{a1} \left[j,i\right]
879 \end{equation}
880 and for a \RankFour arguments this is
881 \begin{equation}
882 \code{inner(a)}=\sum\hackscore{ijkl}\var{a0} \left[i,j,k,l\right] \cdot \var{a1} \left[j,i,k,l\right]
883 \end{equation}
884 \end{funcdesc}
885
886 \begin{funcdesc}{matrix_mult}{a0,a1}
887 returns the matrix product of \var{a0} and \var{a1}. If \var{a1} is \RankOne this is
888 \begin{equation}
889 \code{matrix_mult(a)}\left[i\right]=\sum\hackscore{k}\var{a0} \cdot \left[i,k\right]\var{a1} \left[k\right]
890 \end{equation}
891 and if \var{a1} is \RankTwo this is
892 \begin{equation}
893 \code{matrix_mult(a)}\left[i,j\right]=\sum\hackscore{k}\var{a0} \cdot \left[i,k\right]\var{a1} \left[k,j\right]
894 \end{equation}
895 \end{funcdesc}
896
897 \begin{funcdesc}{transposed_matrix_mult}{a0,a1}
898 returns the matrix product of the transposed of \var{a0} and \var{a1}. The function is equivalent to
899 \code{matrix_mult(transpose(a0),a1)}.
900 If \var{a1} is \RankOne this is
901 \begin{equation}
902 \code{transposed_matrix_mult(a)}\left[i\right]=\sum\hackscore{k}\var{a0} \cdot \left[k,i\right]\var{a1} \left[k\right]
903 \end{equation}
904 and if \var{a1} is \RankTwo this is
905 \begin{equation}
906 \code{transposed_matrix_mult(a)}\left[i,j\right]=\sum\hackscore{k}\var{a0} \cdot \left[k,i\right]\var{a1} \left[k,j\right]
907 \end{equation}
908 \end{funcdesc}
909
910 \begin{funcdesc}{matrix_transposed_mult}{a0,a1}
911 returns the matrix product of \var{a0} and the transposed of \var{a1}.
912 The function is equivalent to
913 \code{matrix_mult(a0,transpose(a1))}.
914 If \var{a1} is \RankTwo this is
915 \begin{equation}
916 \code{matrix_transposed_mult(a)}\left[i,j\right]=\sum\hackscore{k}\var{a0} \cdot \left[i,k\right]\var{a1} \left[j,k\right]
917 \end{equation}
918 \end{funcdesc}
919
920 \begin{funcdesc}{outer}{a0,a1}
921 returns the outer product of \var{a0} and \var{a1}. For instance if \var{a0} and \var{a1} both are \RankOne then
922 \begin{equation}
923 \code{outer(a)}\left[i,j\right]=\var{a0} \left[i\right] \cdot \var{a1}\left[j\right]
924 \end{equation}
925 and if \var{a0} is \RankOne and \var{a1} is \RankThree
926 \begin{equation}
927 \code{outer(a)}\left[i,j,k\right]=\var{a0} \left[i\right] \cdot \var{a1}\left[j,k\right]
928 \end{equation}
929 \end{funcdesc}
930
931 \begin{funcdesc}{tensor_mult}{a0,a1}
932 returns the tensor product of \var{a0} and \var{a1}. If \var{a1} is \RankTwo this is
933 \begin{equation}
934 \code{tensor_mult(a)}\left[i,j\right]=\sum\hackscore{kl}\var{a0}\left[i,j,k,l\right] \cdot \var{a1} \left[k,l\right]
935 \end{equation}
936 and if \var{a1} is \RankFour this is
937 \begin{equation}
938 \code{tensor_mult(a)}\left[i,j,k,l\right]=\sum\hackscore{mn}\var{a0} \left[i,j,m,n\right] \cdot \var{a1} \left[m,n,k,l\right]
939 \end{equation}
940 \end{funcdesc}
941
942 \begin{funcdesc}{transposed_tensor_mult}{a0,a1}
943 returns the tensor product of the transposed of \var{a0} and \var{a1}. The function is equivalent to
944 \code{tensor_mult(transpose(a0),a1)}.
945 If \var{a1} is \RankTwo this is
946 \begin{equation}
947 \code{transposed_tensor_mult(a)}\left[i,j\right]=\sum\hackscore{kl}\var{a0}\left[k,l,i,j\right] \cdot \var{a1} \left[k,l\right]
948 \end{equation}
949 and if \var{a1} is \RankFour this is
950 \begin{equation}
951 \code{transposed_tensor_mult(a)}\left[i,j,k,l\right]=\sum\hackscore{mn}\var{a0} \left[m,n,i,j\right] \cdot \var{a1} \left[m,n,k,l\right]
952 \end{equation}
953 \end{funcdesc}
954
955 \begin{funcdesc}{tensor_transposed_mult}{a0,a1}
956 returns the tensor product of \var{a0} and the transposed of \var{a1}.
957 The function is equivalent to
958 \code{tensor_mult(a0,transpose(a1))}.
959 If \var{a1} is \RankTwo this is
960 \begin{equation}
961 \code{tensor_transposed_mult(a)}\left[i,j\right]=\sum\hackscore{kl}\var{a0}\left[i,j,k,l\right] \cdot \var{a1} \left[l,k\right]
962 \end{equation}
963 and if \var{a1} is \RankFour this is
964 \begin{equation}
965 \code{tensor_transposed_mult(a)}\left[i,j,k,l\right]=\sum\hackscore{mn}\var{a0} \left[i,j,m,n\right] \cdot \var{a1} \left[k,l,m,n\right]
966 \end{equation}
967 \end{funcdesc}
968
969 \begin{funcdesc}{grad}{a\optional{, where=None}}
970 returns the gradient of \var{a}. If \var{where} is present the gradient will be calculated in \FunctionSpace \var{where} otherwise a
971 default \FunctionSpace is used. In case that \var{a} has \RankTwo one has
972 \begin{equation}
973 \code{grad(a)}\left[i,j,k\right]=\frac{\partial \var{a} \left[i,j\right]}{\partial x\hackscore{k}}
974 \end{equation}
975 \end{funcdesc}
976 \begin{funcdesc}{integrate}{a\optional{ ,where=None}}
977 returns the integral of \var{a} where the domain of integration is defined by the \FunctionSpace of \var{a}. If \var{where} is
978 present the argument is interpolated into \FunctionSpace \var{where} before integration. For instance in the case of
979 a \RankTwo argument in \ContinuousFunction it is
980 \begin{equation}
981 \code{integrate(a)}\left[i,j\right]=\int\hackscore{\Omega}\var{a} \left[i,j\right] \; d\Omega
982 \end{equation}
983 where $\Omega$ is the spatial domain and $d\Omega$ volume integration. To integrate over the boundary of the domain one uses
984 \begin{equation}
985 \code{integrate(a,where=FunctionOnBoundary(a.getDomain))}\left[i,j\right]=\int\hackscore{\partial \Omega} a\left[i,j\right] \; ds
986 \end{equation}
987 where $\partial \Omega$ is the surface of the spatial domain and $ds$ area or line integration.
988 \end{funcdesc}
989 \begin{funcdesc}{interpolate}{a,where}
990 interpolates argument \var{a} into the \FunctionSpace \var{where}.
991 \end{funcdesc}
992 \begin{funcdesc}{div}{a\optional{ ,where=None}}
993 returns the divergence of \var{a}. This
994 \begin{equation}
995 \code{div(a)}=trace(grad(a),where)
996 \end{equation}
997 \end{funcdesc}
998 \begin{funcdesc}{jump}{a\optional{ ,domain=None}}
999 returns the jump of \var{a} over the discontinuity in its domain or if \Domain \var{domain} is present
1000 in \var{domain}.
1001 \begin{equation}
1002 \begin{array}{rcl}
1003 \code{jump(a)}& = &\code{interpolate(a,FunctionOnContactOne(domain))} \\
1004 & & \hfill - \code{interpolate(a,FunctionOnContactZero(domain))}
1005 \end{array}
1006 \end{equation}
1007 \end{funcdesc}
1008 \begin{funcdesc}{L2}{a}
1009 returns the $L^2$-norm of \var{a} in its function space. This is
1010 \begin{equation}
1011 \code{L2(a)=integrate(length(a)}^2\code{)} \; .
1012 \end{equation}
1013 \end{funcdesc}
1014
1015 The following functions operate ``point-wise''. That is, the operation is applied to each component of each point
1016 individually.
1017
1018 \begin{funcdesc}{sin}{a}
1019 applies sine function to \var{a}.
1020 \end{funcdesc}
1021
1022 \begin{funcdesc}{cos}{a}
1023 applies cosine function to \var{a}.
1024 \end{funcdesc}
1025
1026 \begin{funcdesc}{tan}{a}
1027 applies tangent function to \var{a}.
1028 \end{funcdesc}
1029
1030 \begin{funcdesc}{asin}{a}
1031 applies arc (inverse) sine function to \var{a}.
1032 \end{funcdesc}
1033
1034 \begin{funcdesc}{acos}{a}
1035 applies arc (inverse) cosine function to \var{a}.
1036 \end{funcdesc}
1037
1038 \begin{funcdesc}{atan}{a}
1039 applies arc (inverse) tangent function to \var{a}.
1040 \end{funcdesc}
1041
1042 \begin{funcdesc}{sinh}{a}
1043 applies hyperbolic sine function to \var{a}.
1044 \end{funcdesc}
1045
1046 \begin{funcdesc}{cosh}{a}
1047 applies hyperbolic cosine function to \var{a}.
1048 \end{funcdesc}
1049
1050 \begin{funcdesc}{tanh}{a}
1051 applies hyperbolic tangent function to \var{a}.
1052 \end{funcdesc}
1053
1054 \begin{funcdesc}{asinh}{a}
1055 applies arc (inverse) hyperbolic sine function to \var{a}.
1056 \end{funcdesc}
1057
1058 \begin{funcdesc}{acosh}{a}
1059 applies arc (inverse) hyperbolic cosine function to \var{a}.
1060 \end{funcdesc}
1061
1062 \begin{funcdesc}{atanh}{a}
1063 applies arc (inverse) hyperbolic tangent function to \var{a}.
1064 \end{funcdesc}
1065
1066 \begin{funcdesc}{exp}{a}
1067 applies exponential function to \var{a}.
1068 \end{funcdesc}
1069
1070 \begin{funcdesc}{sqrt}{a}
1071 applies square root function to \var{a}.
1072 \end{funcdesc}
1073
1074 \begin{funcdesc}{log}{a}
1075 applies the natural logarithm to \var{a}.
1076 \end{funcdesc}
1077
1078 \begin{funcdesc}{log10}{a}
1079 applies the base-$10$ logarithm to \var{a}.
1080 \end{funcdesc}
1081
1082 \begin{funcdesc}{sign}{a}
1083 applies the sign function to \var{a}, that is $1$ where \var{a} is positive,
1084 $-1$ where \var{a} is negative and $0$ otherwise.
1085 \end{funcdesc}
1086
1087 \begin{funcdesc}{wherePositive}{a}
1088 returns a function which is $1$ where \var{a} is positive and $0$ otherwise.
1089 \end{funcdesc}
1090
1091 \begin{funcdesc}{whereNegative}{a}
1092 returns a function which is $1$ where \var{a} is negative and $0$ otherwise.
1093 \end{funcdesc}
1094
1095 \begin{funcdesc}{whereNonNegative}{a}
1096 returns a function which is $1$ where \var{a} is non--negative and $0$ otherwise.
1097 \end{funcdesc}
1098
1099 \begin{funcdesc}{whereNonPositive}{a}
1100 returns a function which is $1$ where \var{a} is non--positive and $0$ otherwise.
1101 \end{funcdesc}
1102
1103 \begin{funcdesc}{whereZero}{a\optional{, tol=None, \optional{, rtol=1.e-8}}}
1104 returns a function which is $1$ where \var{a} equals zero with tolerance \var{tol} and $0$ otherwise. If \var{tol} is not present, the absolute maximum value of C{a} times C{rtol} is used.
1105 \end{funcdesc}
1106
1107 \begin{funcdesc}{whereNonZero}{a, \optional{, tol=None, \optional{, rtol=1.e-8}}}
1108 returns a function which is $1$ where \var{a} different from zero with tolerance \var{tol} and $0$ otherwise. If \var{tol} is not present, the absolute maximum value of C{a} times C{rtol} is used.
1109 \end{funcdesc}
1110
1111 \subsection{Interpolating Data}
1112 \index{interpolateTable}
1113 In some cases, it may be useful to produce Data objects which fit some user defined function.
1114 Manually modifying each value in the Data object is not a good idea since it depends on
1115 knowing the location and order of each datapoint in the domain.
1116 Instead \escript can use an interpolation table to produce a Data object.
1117
1118 The following example is available as `int_save.py` in the examples directory.
1119 We will produce a \Data object which aproximates a sine curve.
1120
1121 \begin{python}
1122 from esys.escript import saveDataCSV, sup
1123 import numpy
1124 from esys.finley import Rectangle
1125
1126 n=4
1127 r=Rectangle(n,n)
1128 x=r.getX()
1129 x0=x[0]
1130 x1=x[1] #we'll use this later
1131 toobig=100
1132 \end{python}
1133
1134 First we produce an interpolation table.
1135 \begin{python}
1136 sine_table=[0, 0.70710678118654746, 1, 0.70710678118654746, 0,
1137 -0.70710678118654746, -1, -0.70710678118654746, 0,
1138 0.70710678118654746]
1139 \end{python}
1140
1141 We wish to identify $0$ and $1$ with the ends of the curve.
1142 That is, with the first and eighth values in the table.
1143 But \var{x0} contains values between $0$ and $1$ inclusive so we need to continue the table to the ninth entry.
1144
1145 \begin{python}
1146 numslices=len(sine_table)-1
1147
1148 minval=0
1149 maxval=1.125 # The extra 0.25 is to account for the extra entry in the table
1150
1151 step=sup(maxval-minval)/numslices
1152 \end{python}
1153
1154 So the values $v$ from the input lie in the interval minval$\leq v < $maxval.
1155 \var{step} represents the gap (in the input range) between entries in the table.
1156 Now we produce our new \Data object.
1157
1158 \begin{python}
1159 result=x0.interpolateTable(sine_table, minval, step, toobig)
1160 \end{python}
1161 Any values which interpolate to larger than \var{toobig} will raise an exception.
1162
1163 Now for a 2D example.
1164 We will interpolate a surface such that the bottom edge is the sine curve described above.
1165 The amplitude of the curve decreases as we move towards the top edge.
1166
1167 Our interpolation table will have three rows.
1168 \begin{python}
1169 st=numpy.array(sine_table)
1170
1171 table=[st, 0.5*st, 0*st ]
1172 \end{python}
1173
1174 The use of numpy and multiplication here is just to save typing.
1175
1176 \begin{python}
1177 result2=x1.interpolateTable(table, 0, 0.55, x0, minval, step, toobig)
1178 \end{python}
1179
1180 In the 2D case, the params for the x1 direction (min=0, step=0.55) come first followed by the x0 data object and
1181 its params.
1182 In this case, the upper bound in the x1 direction is $1.10$ not $1$ so we don't need to add an extra row to the table.
1183
1184 \subsection{Saving Data as CSV}
1185 \index{saveDataCSV}
1186 \index{CSV}
1187 For simple post-processing, \Data objects can be saved in comma separated value format.
1188
1189 If \var{mydata1} and \var{mydata2} are scalar data, the following command:
1190 \begin{python}
1191 saveDataCSV('output.csv',U=mydata1, V=mydata2)
1192 \end{python}
1193 will record the values of mydata in \texttt{output.csv} in the following format:
1194 \begin{verbatim}
1195 U, V
1196 1.0000000e+0, 2.0000000e-1
1197 5.0000000e-0, 1.0000000e+1
1198 ...
1199 \end{verbatim}
1200
1201 The names of the keyword parameters form the names of columns in the ouput.
1202 If the data objects are over different function spaces, then saveDataCSV will attempt to
1203 interpolate to a common function space.
1204 If this is not possible, then an exception will be raised.
1205
1206 Output can be restricted using a scalar mask.
1207 \begin{python}
1208 saveDataCSV('outfile.csv', U=mydata1, V=mydata2, mask=myscalar)
1209 \end{python}
1210 Will only output those rows which correspond to to positive values of \var{myscalar}.
1211 Some aspects of the output can be tuned using additional params.
1212 \begin{python}
1213 saveDataCSV('data.csv', append=True, sep=' ', csep='/', mask=mymask, e=mat1)
1214 \end{python}
1215
1216 \begin{itemize}
1217 \item \var{append} - specifies that the output should be written to the end of an existing file.
1218 \item \var{sep} - defines the separator between fields.
1219 \item \var{csep} - defines the separator between components in the header line. For example between the components of a matrix.
1220 \end{itemize}
1221
1222 The above command would produce output like this:
1223 \begin{verbatim}
1224 e/0/0 e/1/0 e/0/1 e/1/1
1225 1.0000000000e+00 2.0000000000e+00 3.0000000000e+00 4.0000000000e+00
1226 ...
1227 \end{verbatim}
1228
1229
1230
1231 \subsection{\Operator Class}
1232 The \Operator class provides an abstract access to operators build
1233 within the \LinearPDE class. \Operator objects are created
1234 when a PDE is handed over to a PDE solver library and handled
1235 by the \LinearPDE object defining the PDE. The user can gain access
1236 to the \Operator of a \LinearPDE object through the \var{getOperator}
1237 method.
1238
1239 \begin{classdesc}{Operator}{}
1240 creates an empty \Operator object.
1241 \end{classdesc}
1242
1243 \begin{methoddesc}[Operator]{isEmpty}{fileName}
1244 returns \True is the object is empty. Otherwise \True is returned.
1245 \end{methoddesc}
1246
1247 \begin{methoddesc}[Operator]{setValue}{value}
1248 resets all entries in the object representation to \var{value}
1249 \end{methoddesc}
1250
1251 \begin{methoddesc}[Operator]{solves}{rhs}
1252 solves the operator equation with right hand side \var{rhs}
1253 \end{methoddesc}
1254
1255 \begin{methoddesc}[Operator]{of}{u}
1256 applies the operator to the \Data object \var{u}
1257 \end{methoddesc}
1258
1259 \begin{methoddesc}[Operator]{saveMM}{fileName}
1260 saves the object to a matrix market format file of name
1261 \var{fileName}, see
1262 \url{http://maths.nist.gov/MatrixMarket}
1263 % \ulink{maths.nist.gov/MatrixMarket}{\url{http://maths.nist.gov/MatrixMarket}}.
1264 \index{Matrix Market}
1265 \end{methoddesc}
1266
1267 \section{Physical Units}
1268 \escript provides support for physical units in the SI system \index{SI units} including unit conversion. So the
1269 user can define variables in the form
1270 \begin{python}
1271 from esys.escript.unitsSI import *
1272 l=20*m
1273 w=30*kg
1274 w2=40*lb
1275 T=100*Celsius
1276 \end{python}
1277 In the two latter cases an conversion from pounds\index{pounds} and degree Celsius\index{Celsius} is performed into the appropriate SI units kg and Kelvin is performed. In addition
1278 composed units can be used, for instance
1279 \begin{python}
1280 from esys.escript.unitsSI import *
1281 rho=40*lb/cm**3
1282 \end{python}
1283 to define the density in the units of pounds per cubic centimeter. The value $40$ will be converted
1284 into SI units, in this case kg per cubic meter.
1285 Moreover unit prefixes are supported:
1286 \begin{python}
1287 from esys.escript.unitsSI import *
1288 p=40*Mega*Pa
1289 \end{python}
1290 to the the pressure to 40 Mega Pascal. Units can also be converted back from the SI system into
1291 a desired unit, e.g
1292 \begin{python}
1293 from esys.escript.unitsSI import *
1294 print p/atm
1295 \end{python}
1296 can be used print the pressure in units of atmosphere\index{atmosphere}.
1297
1298 This is an incomplete list of supported physical units:
1299
1300 \begin{datadesc}{km}
1301 unit of kilo meter
1302 \end{datadesc}
1303
1304 \begin{datadesc}{m}
1305 unit of meter
1306 \end{datadesc}
1307
1308 \begin{datadesc}{cm}
1309 unit of centi meter
1310 \end{datadesc}
1311
1312 \begin{datadesc}{mm}
1313 unit of milli meter
1314 \end{datadesc}
1315
1316 \begin{datadesc}{sec}
1317 unit of second
1318 \end{datadesc}
1319
1320 \begin{datadesc}{minute}
1321 unit of minute
1322 \end{datadesc}
1323
1324 \begin{datadesc}{h}
1325 unit of hour
1326 \end{datadesc}
1327 \begin{datadesc}{day}
1328 unit of day
1329 \end{datadesc}
1330 \begin{datadesc}{yr}
1331 unit of year
1332 \end{datadesc}
1333
1334 \begin{datadesc}{gram}
1335 unit of gram
1336 \end{datadesc}
1337 \begin{datadesc}{kg}
1338 unit of kilo gram
1339 \end{datadesc}
1340 \begin{datadesc}{lb}
1341 unit of pound
1342 \end{datadesc}
1343 \begin{datadesc}{ton}
1344 metric ton
1345 \end{datadesc}
1346
1347 \begin{datadesc}{A}
1348 unit of Ampere
1349 \end{datadesc}
1350
1351 \begin{datadesc}{Hz}
1352 unit of Hertz
1353 \end{datadesc}
1354
1355 \begin{datadesc}{N}
1356 unit of Newton
1357 \end{datadesc}
1358 \begin{datadesc}{Pa}
1359 unit of Pascal
1360 \end{datadesc}
1361 \begin{datadesc}{atm}
1362 unit of atmosphere
1363 \end{datadesc}
1364 \begin{datadesc}{J}
1365 unit of Joule
1366 \end{datadesc}
1367
1368 \begin{datadesc}{W}
1369 unit of Watt
1370 \end{datadesc}
1371
1372 \begin{datadesc}{C}
1373 unit of Coulomb
1374 \end{datadesc}
1375 \begin{datadesc}{V}
1376 unit of Volt
1377 \end{datadesc}
1378 \begin{datadesc}{F}
1379 unit of Farad
1380 \end{datadesc}
1381
1382 \begin{datadesc}{Ohm}
1383 unit of Ohm
1384 \end{datadesc}
1385 \begin{datadesc}{K}
1386 unit of Kelvin
1387 \end{datadesc}
1388 \begin{datadesc}{Celsius}
1389 unit of Celsius
1390 \end{datadesc}
1391
1392 \begin{datadesc}{Fahrenheit}
1393 unit of Fahrenheit
1394 \end{datadesc}
1395
1396 Moreover unit prefixes are supported:
1397
1398 \begin{datadesc}{Yotta}
1399 prefix yotta = $10^{24}$.
1400
1401 \end{datadesc}
1402
1403 \begin{datadesc}{Zetta}
1404 prefix zetta= $10^{21}$.
1405 \end{datadesc}
1406
1407 \begin{datadesc}{Exa}
1408 prefix exa= $10^{18}$.
1409 \end{datadesc}
1410
1411 \begin{datadesc}{Peta}
1412 prefix peta= $10^{15}$.
1413 \end{datadesc}
1414
1415 \begin{datadesc}{Tera}
1416 prefix tera= $10^{12}$.
1417 \end{datadesc}
1418
1419 \begin{datadesc}{Giga}
1420 prefix giga= $10^9$.
1421 \end{datadesc}
1422
1423 \begin{datadesc}{Mega}
1424 prefix mega= $10^6$.
1425 \end{datadesc}
1426
1427 \begin{datadesc}{Kilo}
1428 prefix kilo= $10^3$.
1429 \end{datadesc}
1430
1431 \begin{datadesc}{Hecto}
1432 prefix hecto= $10^2$.
1433 \end{datadesc}
1434
1435 \begin{datadesc}{Deca}
1436 prefix deca= $10^1$.
1437 \end{datadesc}
1438
1439 \begin{datadesc}{Deci}
1440 prefix deci= $10^{-1}$.
1441 \end{datadesc}
1442
1443 \begin{datadesc}{Centi}
1444 prefix centi= $10^{-2}$.
1445 \end{datadesc}
1446
1447 \begin{datadesc}{Milli}
1448 prefix milli= $10^{-3}$.
1449 \end{datadesc}
1450
1451 \begin{datadesc}{Micro}
1452 prefix micro= $10^{-6}$.
1453 \end{datadesc}
1454
1455 \begin{datadesc}{Nano}
1456 prefix nano= $10^{-9}$.
1457 \end{datadesc}
1458
1459 \begin{datadesc}{Pico}
1460 prefix pico= $10^{-12}$.
1461 \end{datadesc}
1462
1463 \begin{datadesc}{Femto}
1464 prefix femto= $10^{-15}$.
1465 \end{datadesc}
1466
1467 \begin{datadesc}{Atto}
1468 prefix atto= $10^{-18}$.
1469 \end{datadesc}
1470
1471 \begin{datadesc}{Zepto}
1472 prefix zepto= $10^{-21}$.
1473 \end{datadesc}
1474
1475 \begin{datadesc}{Yocto}
1476 prefix yocto= $10^{-24}$.
1477 \end{datadesc}
1478
1479
1480 \section{Utilities}
1481
1482 The \class{FileWriter} provides a mechanism to write data to a file.
1483 In essence, this class wraps the standard \class{file} class to write data
1484 that are global in MPI to a file. In fact, data are written on the processor
1485 with \MPI rank 0 only. It is recommended to use \class{FileWriter}
1486 rather than \class{open} in order to write code that is running
1487 with and without \MPI. It is save to use \class{open} under MPI to read data which are global under \MPI.
1488
1489 \begin{classdesc}{FileWriter}{fn\optional{,append=\False, \optional{createLocalFiles=\False}})}
1490 Opens a file of name \var{fn} for writing. If \var{append} is set to \True
1491 written data are append at the end of the file.
1492 If running under \MPI only the first processor with rank==0
1493 will open the file and write to it.
1494 If \var{createLocalFiles} is set each individual processor will create a file
1495 where for any processor with rank>0 the file name is extended by its rank. This option is normally used for debug purposes only.
1496 \end{classdesc}
1497
1498 The following methods are available:
1499 \begin{methoddesc}[FileWriter]{close}{}
1500 closes the file.
1501 \end{methoddesc}
1502 \begin{methoddesc}[FileWriter]{flush}{}
1503 flushes the internal buffer to disk.
1504 \end{methoddesc}
1505 \begin{methoddesc}[FileWriter]{write}{txt}
1506 Write string \var{txt} to file.
1507 Note that newline is not added.
1508 \end{methoddesc}
1509 \begin{methoddesc}[FileWriter]{writelines}{txts}
1510 Write the list \var{txts} of strings to the file..
1511 Note that newlines are not added.
1512 This method is equivalent to call write() for each string.
1513 \end{methoddesc}
1514 \begin{memberdesc}[FileWriter]{closed}
1515 \True if file is closed.
1516 \end{memberdesc}
1517 \begin{memberdesc}[FileWriter]{mode}
1518 access mode.
1519 \end{memberdesc}
1520 \begin{memberdesc}[FileWriter]{name}
1521 file name.
1522 \end{memberdesc}
1523 \begin{memberdesc}[FileWriter]{newlines}
1524 line separator
1525 \end{memberdesc}
1526
1527
1528 \begin{funcdesc}{setEscriptParamInt}{name,value}
1529 assigns the integer value \var{value} to the parameter \var{name}.
1530 If \var{name}="TOO_MANY_LINES" conversion of any \Data object to a string switches to a
1531 condensed format if more than \var{value} lines would be created.
1532 \end{funcdesc}
1533
1534 \begin{funcdesc}{getEscriptParamInt}{name}
1535 returns the current value of integer parameter \var{name}.
1536 \end{funcdesc}
1537
1538 \begin{funcdesc}{listEscriptParams}{a}
1539 returns a list of valid parameters and their description.
1540 \end{funcdesc}
1541
1542 \begin{funcdesc}{getMPISizeWorld}{}
1543 returns the number of \MPI processors in use in the \env{MPI_COMM_WORLD} processor group.
1544 If \MPI is not used 1 is returned.
1545 \end{funcdesc}
1546 \begin{funcdesc}{getMPIRankWorld}{}
1547 returns the rank of the process within the \env{MPI_COMM_WORLD} processor group.
1548 If \MPI is not used 0 is returned.
1549 \end{funcdesc}
1550 \begin{funcdesc}{MPIBarrierWorld}{}
1551 performs a barrier synchronization across all processors within \env{MPI_COMM_WORLD}
1552 processor group.
1553 \end{funcdesc}
1554 \begin{funcdesc}{getMPIWorldMax}{a}
1555 returns the maximum value of the integer \var{a} across all
1556 processors within \env{MPI_COMM_WORLD}.
1557 \end{funcdesc}
1558

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26