You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/matrix_fields.md
+22-40Lines changed: 22 additions & 40 deletions
Original file line number
Diff line number
Diff line change
@@ -107,7 +107,7 @@ scalar_field_matrix
107
107
108
108
A FieldMatrix entry can be:
109
109
110
-
-An`UniformScaling`, which contains a `Number`
110
+
-A`UniformScaling`, which contains a `Number`
111
111
- A `DiagonalMatrixRow`, which can contain either a `Number` or a tensor (represented as a `Geometry.Axis2Tensor`)
112
112
- A `ColumnwiseBandMatrixField`, where each value is a [`BandMatrixRow`](@ref) with entries of any type that can be represented using the field's base number type.
113
113
@@ -162,29 +162,22 @@ An example of this is:
162
162
A = MatrixFields.FieldMatrix((@name(name1), @name(name2)) => sample_entry)
163
163
```
164
164
165
-
Now consider what happens indexing `A` with the key `(@name(name1.foo.bar.buz), @name(name2.biz.bop.fud))`.
165
+
Now consider what happens when indexing `A` with the key `(@name(name1.foo.bar.buz), @name(name2.biz.bop.fud))`.
166
166
167
167
First, `getindex` finds a key in `A` that contains the key being indexed. In this example, `(@name(name1.foo.bar.buz), @name(name2.biz.bop.fud))` is contained within `(@name(name1), @name(name2))`, so `(@name(name1), @name(name2))` is called the "parent key" and `(@name(foo.bar.buz), @name(biz.bop.fud))` is referred to as the "internal key".
168
168
169
169
Next, the entry that `(@name(name1), @name(name2))` is paired with is recursively indexed
170
170
by the internal key.
171
171
172
-
The recursive indexing of an internal entry given some entry `entry` and internal_key`internal_name_pair`
172
+
The recursive indexing of an internal entry given some entry `entry` and internal key`internal_name_pair`
173
173
works as follows:
174
174
175
175
1. If the `internal_name_pair` is blank, return `entry`
176
-
2. If the element type of each band of `entry` is an `Axis2Tensor`, and `internal_name_pair` is of the form
177
-
`(@name(components.data.1...), @name(components.data.2...))` (potentially with different numbers),
178
-
then extract the specified component, and recurse on it with the remaining `internal_name_pair`.
176
+
2. If the element type of each band of `entry` is an `Axis2Tensor`, and `internal_name_pair` is of the form `(@name(components.data.1...), @name(components.data.2...))` (potentially with different numbers), then extract the specified component, and recurse on it with the remaining `internal_name_pair`.
179
177
3. If the element type of each band of `entry` is a `Geometry.AdjointAxisVector`, then recurse on the parent of the adjoint.
180
-
4. If `internal_name_pair[1]` is not empty, and the first name in it is a field of the element type of each band of `entry`,
181
-
extract that field from `entry`, and recurse into it with the remaining names of `internal_name_pair[1]` and all of `internal_name_pair[2]`
182
-
5. If `internal_name_pair[2]` is not empty, and the first name in it is a field of the element type of each band of `entry`,
183
-
extract that field from `entry`, and recurse into it with all of `internal_name_pair[1]` and the remaining names of `internal_name_pair[2]`
184
-
6. At this point, if none of the previous cases are true, both `internal_name_pair[1]` and `internal_name_pair[2]` should be
185
-
non-empty, and it is assumed that `entry` is being used to implicitly represent some tensor structure. If the first name in
186
-
`internal_name_pair[1]` is equivalent to `internal_name_pair[2]`, then both the first names are dropped, and entry is recursed onto.
187
-
If the first names are different, both the first names are dropped, and the zero of entry is recursed onto.
178
+
4. If `internal_name_pair[1]` is not empty, and the first name in it is a field of the element type of each band of `entry`, extract that field from `entry`, and recurse into it with the remaining names of `internal_name_pair[1]` and all of `internal_name_pair[2]`
179
+
5. If `internal_name_pair[2]` is not empty, and the first name in it is a field of the element type of each band of `entry`, extract that field from `entry`, and recurse into it with all of `internal_name_pair[1]` and the remaining names of `internal_name_pair[2]`
180
+
6. At this point, if none of the previous cases are true, both `internal_name_pair[1]` and `internal_name_pair[2]` should be non-empty, and it is assumed that `entry` is being used to implicitly represent some tensor structure. If the first name in `internal_name_pair[1]` is equivalent to `internal_name_pair[2]`, then both the first names are dropped, and entry is recursed onto. If the first names are different, both the first names are dropped, and the zero of entry is recursed onto.
188
181
189
182
When the entry is a `ColumnWiseBandMatrixField`, indexing it will return a broadcasted object in
190
183
the following situations:
@@ -224,7 +217,7 @@ A `ColumnwiseBandMatrixField` is a `Field` with a `BandMatrixRow` at each point.
224
217
to represent a collection of banded matrices, where there is one band matrix for each column
225
218
of the space the `Field` is on. Beyond only storing the diagonals of the band matrix, an `entry`
226
219
can be optimized to use less memory. Each optimized representation can be indexed equivalently to
227
-
non optimized representation, and used in addition, subtraction, Matrix-vector multiplication,
220
+
non optimized representations, and used in addition, subtraction, matrix-vector multiplication,
228
221
Matrix-matrix multiplication, `RecursiveApply`, and `FieldMatrixSolver`.
229
222
230
223
For the following sections, `space` is a column space with $N_v$ levels. A column space is
Consider the case where $b_1 = 0$ and $b_2 = 0$, i.e $M$ is a diagonal matrix, and
242
235
where $M = k * I$, and $k$ is of type `T_k`. This would happen if
243
-
$\frac{\partial f_i}{\partial g_j} = [i=j] * k$. Instead of storing
244
-
each element on the diagonal, less memory can be used by storing a single value that represents a scaling of the identity. This reduces memory usage by a factor of $N_v$.
236
+
$\frac{\partial f_i}{\partial g_j} = \delta_{ij} * k$. Instead of storing
237
+
each element on the diagonal, the `FieldMatrix` can store a single value that represents a scaling of the identity matrix, reducing memory usage by a factor of $N_v$:
245
238
246
239
```julia
247
240
entry =fill(DiagonalMatrixRow(k), space)
@@ -265,21 +258,20 @@ The functions that index an entry with an internal key assume the implicit tenso
265
258
when all of the following are true for `entry` where `T_k` is the element type of each band, and
266
259
`(internal_key_1, internal_key_2)` is the internal key indexing `entry`.
267
260
268
-
- the first key in the `internal_key_1` name chain is not a fieldname of `T_k`
269
-
- the first key in the `internal_key_2` name chain is not a fieldname of `T_k`
270
-
-`internal_key_1` and `internal_key_2` are both not empty
261
+
- the `internal_key_1` name chain is not empty and its first name is not a field of `T_k`
262
+
- the `internal_key_2` name chain is not empty and its first name is not a field of `T_k`
271
263
272
264
For most use cases, `T_k` is a scalar.
273
265
274
266
If the above conditions are met, the optimization assumes that the user intends the
275
267
entry to have an implicit tensor structure, with the values of type `T_k` representing a scaling of the
276
-
tensor identity. If both the first and second name in the name pair are equivalent, then they index onto the diagonal,
277
-
and the value is returned. Otherwise, they index off the diagonal, and a zero value
268
+
identity tensor. If both the first and second names in the name pair are equivalent, then they index onto the diagonal,
269
+
and the scalar value of `k` is returned. Otherwise, they index off the diagonal, and a zero value
278
270
is returned.
279
271
280
-
This optimization is intended to be used when `T_f = T_g`, and they are both `AxisVectors`
281
-
The notation $f_{n}[i]$ where $0 < n \leq N_v$ refers to the $i$ component of the element
282
-
at the $n$ vertical level of $f$. In the following example, `T_f=T_g=Covariant12Vector`, and
272
+
This optimization is intended to be used when `T_f = T_g`.
273
+
The notation $f_{n}[i]$ where $0 < n \leq N_v$ refers to the $i$-th component of the element
274
+
at the $n$-th vertical level of $f$. In the following example, `T_f` and `T_g` are both `Covariant12Vector`s, and
0 commit comments