Unexpected behaviour of BCRSMatrix implict buildmode
The behaviour of the implicit build mode is in several ways unexpected and does not fit its documentation:
- (a) In contrast to the documentation, the allocated overflow area is not used while filling the matrix in favour of a separate
- (b) The allocated overflow area does always contain
4*avgmore entries than expected.
- (c) The given
avgvalue is not really related to average row sizes. If you give the exact average,
compres()may fail if the overflow size is zero.
- (d) The allocated overflow area is in fact used to balance the mismatch between the given
avgvalue and rows having more entries than this.
compress()may fail depending on the row order: The following will fail for
row=0but succeed for
using M = Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1>>; M m(6, 6, 1, 0.0, M::implicit); for(std::size_t i=0; i<6; ++i) m.entry(row,i) = i; m.compress();
Explanation for this behaviour: When allocating storage, this is partitioned into the overflow area followed by
avg reserved entries per row.
When more than
avg entries are used in a row, they are stored in an additional
compress() all entries are shifted forward towards the first
free position, inserting intermediate entries from the overflow map when necessary. This explains, why early rows cannot have more than
entries, while later ones may consume remaining space left by preceding less populated rows.
Due to (a) there is a possible fix for several of those problems. Before compressing forward with insertion of overflow entries, one can compress backwards without this insertion. This would solve (c)-(e) at the price of an additional shifting operation. Even more, this would allow to compute the number of non-zeros in the first sweep and than allocate new storage if the overflow was to small instead of throwing an exception and letting the user assemble all entries again with a hopefully better guess.