template<class Scalar>
ScatterMap class
Cached map from polytope-local matrix entries into the value array of an assembled Math::SparseMatrix.
The sparsity pattern of a named form is fixed by the mesh, the DOF maps of the two spaces and the polytopes the form integrates over, so it is computed once, on the first assembly, out of the triplet list that assembly produces anyway. Every subsequent assembly zeroes the value array and scatters the local matrices straight into it through the cached indices, skipping both the triplet list and Eigen's symbolic pass.
The pattern is purely topological: it holds every entry the DOF maps connect, including those whose value happens to vanish. Reassembling a form therefore never changes the sparsity of its operator, which is what makes the value array reusable.
Regions
The map iterates whatever the iteration object selects. Of its candidates, a polytope is visited when filter accepts it and, if an attribute set is given, when its attribute belongs to that set; this is the same selection the triplet assembly of an integrator makes. A candidate that is not visited owns an empty range of the index array, so the offsets stay indexed by candidate and need no remapping.
Validity
The cached indices are only valid for the DOF maps and the selection they were built from, and the shape of the operator identifies neither: an edge flip or a renumbering can leave the row count, the column count, the nonzero count and the candidate count all unchanged while moving every entry, and so can a change of attribute set. The cache is therefore keyed on a fingerprint of the visited polytopes and their maps.
The fingerprint is accumulated inside the scatter loop rather than in a pass of its own: the loop already reads both DOF arrays, so folding the hash into it costs one mix per degree of freedom instead of a second traversal, which measured 2-3x on the reassembly benchmarks. It is compared once the loop is done, and a mismatch discards the values and rebuilds the pattern from triplets, so nothing assembled against a stale pattern is ever observable. Before a polytope scatters, its local size is checked against the range the cache reserved for it, so that a polytope the cache never visited cannot write past its range before the fingerprint gets a chance to reject the pattern. The per-polytope hashes are combined by addition, which keeps the fingerprint independent of the order the threads happen to visit the polytopes in.
Public types
- using ScalarType = Scalar
- Scalar value type.
-
using MatrixType = Math::
SparseMatrix<ScalarType> - Assembled operator type.
Public functions
-
template<class KernelType, class IterationType, class TrialFES, class TestFES>void assemble(MatrixType& out, const KernelType& prototype, const TrialFES& trialFES, const TestFES& testFES, const IterationType& seq, const FlatSet<Geometry::
Attribute>& attributes) - Assembles
outsequentially.
Function documentation
template<class Scalar>
template<class KernelType, class IterationType, class TrialFES, class TestFES>
void Rodin:: Assembly:: ScatterMap<Scalar>:: assemble(MatrixType& out,
const KernelType& prototype,
const TrialFES& trialFES,
const TestFES& testFES,
const IterationType& seq,
const FlatSet<Geometry:: Attribute>& attributes)
Assembles out sequentially.
| Template parameters | |
|---|---|
| KernelType | Local kernel, providing compute(Math::Matrix<ScalarType>&, const Geometry::Polytope&). |
| Parameters | |
| out in/out | Operator receiving the assembly. |
| prototype in | Local kernel, copied once for the assembly. |
| trialFES in | Trial space. |
| testFES in | Test space. |
| seq in | Iteration over the region to integrate. |
| attributes in | Attributes to restrict to, or empty for all. |