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