5
5
Interpolation
6
6
=============
7
7
8
- Firedrake offers various ways to interpolate expressions onto fields
9
- (:py:class: `~.Function `\s ). Interpolation is often used to set up
10
- initial conditions and/or boundary conditions. The basic syntax for
11
- interpolation is:
8
+ Firedrake offers highly flexible capabilities for interpolating expressions
9
+ (functions of space) into finite element :py:class: `~.Function `\s .
10
+ Interpolation is often used to set up initial conditions and/or boundary
11
+ conditions. Mathematically, if :math: `e(x)` is a function of space and
12
+ :math: `V` is a finite element functionspace then
13
+ :math: `\operatorname {interpolate}(e, V)` is the :py:class: `~.Function `
14
+ :math: `v_i \phi _i\in V` such that:
12
15
13
- .. code-block :: python3
14
-
15
- # create new function f on function space V
16
- f = interpolate(expression, V)
16
+ .. math ::
17
17
18
- # alternatively:
19
- f = Function(V).interpolate(expression)
18
+ v_i = \bar {\phi }^*_i(e)
20
19
21
- # setting the values of an existing function
22
- f.interpolate(expression)
20
+ where :math: ` \bar { \phi }^*_i` is the :math: `i`-th dual basis function to
21
+ :math: `V` suitably extended such that its domain encompasses :math: `e`.
23
22
24
23
.. note ::
25
24
26
- Interpolation is supported for most, but not all, of the elements
27
- that Firedrake provides. In particular, higher-continuity elements
28
- such as Argyris and Hermite do not presently support interpolation.
25
+ The extension of dual basis functions to :math: `e` usually follows from the
26
+ definition of the dual basis. For example, point evaluation and integral
27
+ nodes can naturally be extended to any expression which is evaluatable at
28
+ the relevant points, or integrable over that domain.
29
+
30
+ Firedrake will not impose any constraints on the expression to be
31
+ interpolated beyond that its value shape matches that of the space into
32
+ which it is interpolated. If the user interpolates an expression for which
33
+ the nodes are not well defined (for example point evaluation at a
34
+ discontinuity), the result is implementation-dependent.
35
+
36
+ The interpolate operator
37
+ ------------------------
38
+
39
+ .. note ::
40
+ The semantics for interpolation in Firedrake are in the course of changing.
41
+ The documentation provided here is for the new behaviour, in which the
42
+ `interpolate ` operator is symbolic. In order to access the behaviour
43
+ documented here (which is recommended), users need to use the following
44
+ import line:
45
+
46
+ .. code-block :: python3
47
+
48
+ from firedrake.__future__ import interpolate
49
+
50
+
51
+ The basic syntax for interpolation is:
52
+
53
+ .. literalinclude :: ../../tests/regression/test_interpolation_manual.py
54
+ :language: python3
55
+ :dedent:
56
+ :start-after: [test_interpolate_operator 1]
57
+ :end-before: [test_interpolate_operator 2]
58
+
59
+ It is also possible to interpolate an expression directly into an existing
60
+ :py:class: `~.Function `:
61
+
62
+ .. literalinclude :: ../../tests/regression/test_interpolation_manual.py
63
+ :language: python3
64
+ :dedent:
65
+ :start-after: [test_interpolate_operator 3]
66
+ :end-before: [test_interpolate_operator 4]
67
+
68
+ This is a numerical operation, equivalent to:
69
+
70
+ .. literalinclude :: ../../tests/regression/test_interpolation_manual.py
71
+ :language: python3
72
+ :dedent:
73
+ :start-after: [test_interpolate_operator 5]
74
+ :end-before: [test_interpolate_operator 6]
75
+
29
76
30
- The recommended way to specify the source expression is UFL. UFL _
31
- produces clear error messages in case of syntax or type errors, yet
77
+ The source expression can be any UFL _ expression with the correct shape.
78
+ UFL produces clear error messages in case of syntax or type errors, yet
32
79
UFL expressions have good run-time performance, since they are
33
80
translated to C interpolation kernels using TSFC _ technology.
34
81
Moreover, UFL offers a rich language for describing expressions,
@@ -46,67 +93,27 @@ including:
46
93
47
94
Here is an example demonstrating some of these features:
48
95
49
- .. code-block :: python3
50
-
51
- # g is a vector-valued Function, e.g. on an H(div) function space
52
- f = interpolate(sqrt(3.2 * div(g)), V)
96
+ .. literalinclude :: ../../tests/regression/test_interpolation_manual.py
97
+ :language: python3
98
+ :dedent:
99
+ :start-after: [test_interpolate_operator 7]
100
+ :end-before: [test_interpolate_operator 8]
53
101
54
102
This also works as expected when interpolating into a a space defined on the facets
55
103
of the mesh:
56
104
57
- .. code-block :: python3
58
-
59
- # where trace is a trace space on the current mesh:
60
- f = interpolate(expression, trace)
61
-
62
-
63
- Interpolator objects
64
- --------------------
65
-
66
- Firedrake is also able to generate reusable :py:class: `~.Interpolator `
67
- objects which provide caching of the interpolation operation. The
68
- following line creates an interpolator which will interpolate the
69
- current value of `expression ` into the space `V `:
70
-
71
- .. code-block :: python3
72
-
73
- interpolator = Interpolator(expression, V)
74
-
75
- If `expression ` does not contain a :py:func: `~ufl.TestFunction ` then
76
- the interpolation can be performed with:
77
-
78
- .. code-block :: python3
79
-
80
- f = interpolator.interpolate()
81
-
82
- Alternatively, one can use the interpolator to set the value of an existing :py:class: `~.Function `:
83
-
84
- .. code-block :: python3
85
-
86
- f = Function(V)
87
- interpolator.interpolate(output=f)
88
-
89
- If `expression ` contains a :py:func: `~ufl.TestFunction ` then
90
- the interpolator acts to interpolate :py:class: `~.Function `\s in the
91
- test space to those in the target space. For example:
92
-
93
- .. code-block :: python3
94
-
95
- w = TestFunction(W)
96
- interpolator = Interpolator(w, V)
105
+ .. literalinclude :: ../../tests/regression/test_interpolation_manual.py
106
+ :language: python3
107
+ :dedent:
108
+ :start-after: [test_interpolate_operator 9]
109
+ :end-before: [test_interpolate_operator 10]
97
110
98
- Here, `interpolator ` acts as the interpolation matrix from the
99
- :py:func: `~.FunctionSpace ` W into the
100
- :py:func: `~.FunctionSpace ` V. Such that if `f ` is a
101
- :py:class: `~.Function ` in `W ` then `g = interpolator.interpolate(f) ` is its
102
- interpolation into a function `g ` in `V `. As before, the `output ` parameter can
103
- be used to write into an existing :py:class: `~.Function `. Passing the
104
- `transpose=True ` option to :py:meth: `~.Interpolator.interpolate ` will
105
- cause the transpose interpolation to occur. This is equivalent to the
106
- multigrid restriction operation which interpolates assembled 1-forms
107
- in the dual space to `V ` to assembled 1-forms in the dual space to
108
- `W `.
111
+ .. note ::
109
112
113
+ Interpolation is supported into most, but not all, of the elements that
114
+ Firedrake provides. In particular it is not currently possible to
115
+ interpolate into spaces defined by higher-continuity elements such as
116
+ Argyris and Hermite.
110
117
111
118
Interpolation across meshes
112
119
---------------------------
@@ -286,22 +293,12 @@ the external data source, but the precise details are not relevant
286
293
now. In this case, interpolation into a target function space ``V ``
287
294
proceeds as follows:
288
295
289
- .. code-block :: python3
290
296
291
- # First, grab the mesh.
292
- m = V.mesh()
293
-
294
- # Now make the VectorFunctionSpace corresponding to V.
295
- W = VectorFunctionSpace(m, V.ufl_element())
296
-
297
- # Next, interpolate the coordinates onto the nodes of W.
298
- X = interpolate(m.coordinates, W)
299
-
300
- # Make an output function.
301
- f = Function(V)
302
-
303
- # Use the external data function to interpolate the values of f.
304
- f.dat.data[:] = mydata(X.dat.data_ro)
297
+ .. literalinclude :: ../../tests/regression/test_interpolation_manual.py
298
+ :language: python3
299
+ :dedent:
300
+ :start-after: [test_interpolate_external 1]
301
+ :end-before: [test_interpolate_external 2]
305
302
306
303
This will also work in parallel, as the interpolation will occur on
307
304
each process, and Firedrake will take care of the halo updates before
@@ -310,65 +307,6 @@ the next operation using ``f``.
310
307
For interaction with external point data, see the
311
308
:ref: `corresponding manual section <external-point-data >`.
312
309
313
-
314
- C string expressions
315
- --------------------
316
-
317
- .. warning ::
318
-
319
- C string expressions were a FEniCS compatibility feature which has
320
- now been removed. Users should use UFL expressions instead. This
321
- section only remains to assist in the transition of existing code.
322
-
323
- Here are a couple of old-style C string expressions, and their modern replacements.
324
-
325
- .. code-block :: python3
326
-
327
- # Expression:
328
- f = interpolate(Expression("sin(x[0]*pi)"), V)
329
-
330
- # UFL equivalent:
331
- x = SpatialCoordinate(V.mesh())
332
- f = interpolate(sin(x[0] * math.pi), V)
333
-
334
- # Expression with a Constant parameter:
335
- f = interpolate(Expression('sin(x[0]*t)', t=t), V)
336
-
337
- # UFL equivalent:
338
- x = SpatialCoordinate(V.mesh())
339
- f = interpolate(sin(x[0] * t), V)
340
-
341
-
342
- Python expression classes
343
- -------------------------
344
-
345
- .. warning ::
346
-
347
- Python expression classes were a FEniCS compatibility feature which has
348
- now been removed. Users should use UFL expressions instead. This
349
- section only remains to assist in the transition of existing code.
350
-
351
- Since Python ``Expression `` classes expressions are
352
- deprecated, below are a few examples on how to replace them with UFL
353
- expressions:
354
-
355
- .. code-block :: python3
356
-
357
- # Python expression:
358
- class MyExpression(Expression):
359
- def eval(self, value, x):
360
- value[:] = numpy.dot(x, x)
361
-
362
- def value_shape(self):
363
- return ()
364
-
365
- f.interpolate(MyExpression())
366
-
367
- # UFL equivalent:
368
- x = SpatialCoordinate(f.function_space().mesh())
369
- f.interpolate(dot(x, x))
370
-
371
-
372
310
Generating Functions with randomised values
373
311
-------------------------------------------
374
312
0 commit comments