from devito import Grid, TimeFunction
= TimeFunction(name='u', grid=Grid((3,)), save=1)
u print(u)
u(time, x)
The first compilation pass is named lowering, and three main tasks are carried out: indexification, substitution, and domain-alignment. In this notebook, we will explore the Indexification step.
The indexification consists of converting Functions into Indexeds, that is actual array accesses. An Indexed
always keeps a reference to its originating Function
. For instance, all accesses to u
such as u[t, x + 1]
and u[t + 1, x − 2]
would store a pointer to the same, user-defined Function
u(t, x). This metadata is exploited throughout the various compilation passes.
To see this, let’s create a TimeFunction
named u
.
u(time, x)
Note that u
has one temporal dimension and one spatial dimension, that we will call time
and x
here, respectively.
Functions (of type Function
, TimeFunction
and SparseFunction
) can be indexified in two equivalent ways, either via the .indexify() method, as illustrated below, or via explicit indexing, as typically done in user code.
u_i = u.indexify() # For more details about the method `indexify`, see `devito/symbolics/manipulation.py`
print(u_i)
u[time, x]
Now, dimensions are interpreted as indices.
The explicit indexing mode is when you write
and you get exactly (representation shown below)
ie, this is totally equivalent to indexify. Another example, you can write
and you get
Clearly, we now have that
Thus
However, we can verify that these accesses still point to the very same TimeFunction
object.
Note also that there is no data
associated with Indexed
objects.
The data
representing the grid is accessed through the Function
that the indices point to.