Handle dynamic memory managment in functions
Issue
Functions with dynamic number of components induce data structures that need memory to be managed dynamically. For example, a discrete global basis of a DynamicPowerBasis
proposed in !285 (merged) would possibly be Dune::DynamicVector
or an std::vector
. However, the function signature of functions requires the return type to be created inside of the function operator (see !285 (comment 91091)). A naive implementation is tremendously far from optimal because it would lead to memory allocations for every function call (e.g., every quadrature point evaluation). So this issue is to discuss possible alternatives to tackle this issue.
Alternatives
- Encourage the use of vectors with custom allocators that reuse the same memory over and over again if some conditions are given.
- Return vectors with small object optimization to avoid allocation on small sizes.
- Hand in the responsibility of allocation to the user by adding a factory to the
makeDiscreteGlobbalBasis
signature (see !285 (comment 91101)). - Discourage its use in favor of scalar functions e.g., by using the sub-space facilities.
- Extend the function signature to have an optional storage argument with an empty default (e.g.
Range Function::operator()(const Domain& domain, std::optional<Range> storage = {})
).