Use less allocations on UGGrid intersection geometries
Currently, UGGrid intersection geometries do many allocations for very small objects. In simple simulations I get millions (!) of allocation calls due to this, a few orders of magnitude higher than any other allocation in a simulation. This happens because
- The geometry object is stored as a shared pointer. While this is handy when having several geometries referring to the same intersection, this is barely of any use as we mostly expect people to have one geometry and get it from the entity. An optional type is more appropriate here.
- The coordinates are a
std::vector
of field vectors that need to be created for every geometry. This MR uses the suggestion by @oliver.sander by storing the coordinates wither withstd::array
orDune::ReservedVector
depending on the dimension of the geometry. - Every new intersection stores a
std::vector
of faces. While this is needed for the non-conforming case, it penalizes the common case where there is one or no faces neighboring the intersection. This can be solved by properly using a union type, i.e.std::variant
The current MR mitigates the first issue by using std::optional
, the second by storing coordinates on std::array
or Dune::ReservedVector
, and the third one by using std::variant
. All of them optimized to not allocate anything on the hot-path but still be flexible to allocate if needed.
Edited by Santiago Ospina De Los Ríos