Skip to content

Commit 14c7eed

Browse files
committed
WIP Y fields
pre-switch to type space should work fix broken tests bugfix fix implicit tensor rep tests WIPP1 working state Improve readability at cost of concise code update docs further cleanup
1 parent 13633ca commit 14c7eed

File tree

6 files changed

+397
-447
lines changed

6 files changed

+397
-447
lines changed

docs/src/matrix_fields.md

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ check_preconditioner
9090
lazy_or_concrete_preconditioner
9191
apply_preconditioner
9292
get_scalar_keys
93-
get_field_first_index_offset
94-
broadcasted_get_field_type
95-
inner_type_ignore_adjoint
93+
field_offset_and_type
9694
```
9795

9896
## Utilities
@@ -155,27 +153,44 @@ and
155153
nt_fieldmatrix[(@name(a.bar), @name(b))]
156154
```
157155

158-
If the key `(@name(name1), @name(name2))` corresponds to an entry, then
159-
`(@name(foo.bar.buz), @name(biz.bop.fud))` would be the internal key for the key
160-
`(@name(name1.foo.bar.buz), @name(name2.biz.bop.fud))`.
156+
### Further Indexing Details
161157

162-
Currently, internal values cannot be extracted in all situations. Extracting interal values
163-
works when:
158+
Let key `(@name(name1), @name(name2))` correspond to entry `sample_entry` in `FieldMatrix` `A`.
159+
An example of this is:
164160

165-
- The second name in the internal key is empty, and the first name in the internal key accesses internal values for the type of element contained in each row of the entry. This does not work when the element type of each row is a 2d tensor.
166-
167-
- The first name in the internal key is empty, and the type of element contained in each row of the entry is an `AxisVector` or the adjoint of an `AxisVector`. In this case, the second name must access inernal values for the type of `AxisVector` contained in each row.
168-
169-
- The element type of each row in the entry is a 2d tensor, and the internal key is of the form `(@name(components.data.:(1)), @name(components.data.:(2)))`, but possibly with different numbers to index into the 2d tensor
170-
171-
- The element type of each row in the entry is some number of nested `Tuple`s and `NamedTuple`s, and the first name in the internal key accesses an `AxisVector` or the adjoint of an `AxisVector` from the outer `Tuple`/`NamedTuple`, and the second name in the inernal key accesses a component of the `AxisVector`
172-
173-
If the `FieldMatrix` represents a Jacobian, then extracting internal values works when an entry represents:
174-
175-
- The partial derrivative of an `AxisVector`, `Tuple`, or `NamedTuple` with respect to a scalar.
176-
177-
- The partial derrivative of a scalar with respect to an `AxisVector`.
178-
179-
- The partial derrivative of a `Tuple`, or `NamedTuple` with respect to an `AxisVector`. In this case, the first name of the internal key must index into the tuple and result in a scalar.
161+
```julia
162+
A = MatrixFields.FieldMatrix((@name(name1), @name(name2)) => sample_entry)
163+
```
180164

181-
- The partial derrivative of an `AxisVector` with respect to an `AxisVector`. In this case, the partial derrivative of a component of the first `AxisVector` with respect to a component of the second `AxisVector` can be extracted, but not an entire `AxisVector` with respect to a component, or a component with respect to an entire `AxisVector`
165+
Now consider what happens indexing `A` with the key `(@name(name1.foo.bar.buz), @name(name2.biz.bop.fud))`.
166+
167+
First, a function searches the keys of `A` for a key that `(@name(foo.bar.buz), @name(biz.bop.fud))`
168+
is a child of. In this example, `(@name(foo.bar.buz), @name(biz.bop.fud))` is a child of
169+
the key `(@name(name1), @name(name2))`, and
170+
`(@name(foo.bar.buz), @name(biz.bop.fud))` is referred to as the internal key.
171+
172+
Next, the entry that `(@name(name1), @name(name2))` is paired with is recursively indexed
173+
by the internal key.
174+
175+
The recursive indexing of an internal entry given some entry `entry` and internal_key `internal_name_pair`
176+
works as follows:
177+
178+
1. If the `internal_name_pair` is blank, return `entry`
179+
2. If the element type of each band of `entry` is an `Axis2Tensor`, and `internal_name_pair` is of the form
180+
`(@name(components.data.1...), @name(components.data.2...))` (potentially with different numbers),
181+
then extract the specified component, and recurse on it with the remaining `internal_name_pair`.
182+
3. If the element type of each band of `entry` is a `Geometry.AdjointAxisVector`, then recurse on the parent of the adjoint.
183+
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`,
184+
extract that field from `entry`, and recurse on the it with the remaining names of `internal_name_pair[1]` and all of `internal_name_pair[2]`
185+
5. If `internal_name_pair[2]` is not empty, and the first name in it is a field of the element type of each row of `entry`,
186+
extract that field from `entry`, and recurse on the it with all of `internal_name_pair[1]` and the remaining names of `internal_name_pair[2]`
187+
6. At this point, if none of the previous cases are true, both `internal_name_pair[1]` and `internal_name_pair[2]` should be
188+
non-empty, and it is assumed that `entry` is being used to implicitly represent some tensor structure. If the first name in
189+
`internal_name_pair[1]` is equivalent to `internal_name_pair[2]`, then both the first names are dropped, and entry is recursed onto.
190+
If the first names are different, both the first names are dropped, and the zero of entry is recursed onto.
191+
192+
When the entry is a `ColumnWiseBandMatrixField`, indexing it will return a broadcasted object in
193+
the following situations:
194+
195+
1. The internal key indexes to a type different than the basetype of the entry
196+
2. The internal key indexes to a zero-ed value

src/Geometry/axistensors.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ coordinate_axis(::Type{<:LatLongPoint}) = (1, 2)
6161

6262
coordinate_axis(coord::AbstractPoint) = coordinate_axis(typeof(coord))
6363

64-
@inline idxin(I::Tuple{Int}, i::Int) = 1
64+
@inline idxin(I::Tuple{Int}, i::Int) = I[1] == i ? 1 : nothing
6565

6666
@inline function idxin(I::Tuple{Int, Int}, i::Int)
6767
@inbounds begin

src/MatrixFields/field_name.jl

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ extract_first(::FieldName{name_chain}) where {name_chain} = first(name_chain)
5050
drop_first(::FieldName{name_chain}) where {name_chain} =
5151
FieldName(Base.tail(name_chain)...)
5252

53-
extract_last(::FieldName{name_chain}) where {name_chain} =
54-
name_chain[length(name_chain)]
55-
5653
has_field(x, ::FieldName{()}) = true
5754
has_field(x, name::FieldName) =
5855
extract_first(name) in propertynames(x) &&
@@ -62,18 +59,6 @@ get_field(x, ::FieldName{()}) = x
6259
get_field(x, name::FieldName) =
6360
get_field(getproperty(x, extract_first(name)), drop_first(name))
6461

65-
"""
66-
broadcasted_get_field_type(::Type{X}, name::FieldName)
67-
68-
Returns the type of the field accessed by `name` in the type `X`.
69-
"""
70-
broadcasted_get_field_type(::Type{X}, ::FieldName{()}) where {X} = X
71-
broadcasted_get_field_type(::Type{X}, name::FieldName) where {X} =
72-
broadcasted_get_field_type(
73-
fieldtype(X, extract_first(name)),
74-
drop_first(name),
75-
)
76-
7762
broadcasted_has_field(::Type{X}, ::FieldName{()}) where {X} = true
7863
broadcasted_has_field(::Type{X}, name::FieldName) where {X} =
7964
extract_first(name) in fieldnames(X) &&
@@ -214,7 +199,4 @@ if hasfield(Method, :recursion_relation)
214199
for m in methods(get_subtree_at_name)
215200
m.recursion_relation = dont_limit
216201
end
217-
for m in methods(broadcasted_get_field_type)
218-
m.recursion_relation = dont_limit
219-
end
220202
end

0 commit comments

Comments
 (0)