Bug in ISTL container index depth calculation
Summary
The MultiIndex<std::size_t,depth>
which serves to find vector values in a nested vector container (a.k.a. ContainerIndex
), is calculated using the typetree algorithm for accumulating values. That is, the accummulate_value<...>
, which is a meta-algorithm that statically traverses and accumulates a value on the tree with a depth-first traversal with post-order accesses to apply functors (follow blue dots #2A7FFF
). See https://en.wikipedia.org/wiki/Tree_traversal#Post-order
The calculation looks like this:
static const std::size_t ci_depth =
TypeTree::AccumulateValue<RootGFS,
extract_max_container_depth,
TypeTree::max<std::size_t>,
0,
TypeTree::plus<std::size_t>
>::result + 1;
where the value is initialized at 0, a max
functor is used for sibling-to-sibling* reduction and a plus
functor is used for child-to-parent. Finally, the extract_max_container_depth
returns 1
or 0
depending on whether the node uses blocking or not. Here the idea is to find the maximum depth of the blocked nodes so that the ContainerIndex
is able to represent all possible multi-indices in the nested vector structure.
The problem is that these functors and algorithm do not accumulate the desired depth of the blocking.
To see this, let's make an example: assume that we are working with the tree shown above. Nodes B
, G
, and I
return 1
meaning that these nodes are blocked, otherwise 0
. Looking at the tree, it is clear that the CointainerIndex
depth should be 2
. However, when the tree traversal makes the sibling-to-sibling reduction between nodes B
and H
, the algorithm accumulates 1
instead of 0
, then and the overall depth accumulates 3
instead of the expected 2
.
*Note: I said "sibling-to-sibling" because this is what the documentation says, but this is indeed "sibling-to-next-leaf".
Proposed ways to solve this
Two possible ways:
- Add a parent-to-child reduction in
dune-typetree
(copasi/dune-typetree@d5f7e62a) and add a add a first value functor for that reduction in this call in pdelab (copasi/dune-pdelab@72f0a14e) - Change the accumulation algorithm in
dune-typetree
that is able to perform a complete depth-first traversal at compile time (staging/dune-typetree!93 (merged)) and change to use it here.
In either case, to my understanding, this requires a change in dune-typetree
...