Before this PR, serac::Functional eagerly initialized its member variables. Some of those member variables required for the sparse matrix assembly are expensive (both in compute and memory) to initialize. In many analyses, users never create sparse matrices for some of the trial space derivatives (like the parameter fields) which means that some of those member variables were never needed after all.
This PR changes the behavior so that the expensive bits are initialized just-in-time, rather than when a serac::Functional is created, to be more consistent with the mantra "don't pay for what you don't use". The end result is a much smaller memory footprint (about ~50-75% smaller, depending on number of parameter fields) and shorter time to initialize.
The implementation is crude, but we're planning to remove much of this code in the coming months anyway.
Before this PR,
serac::Functional
eagerly initialized its member variables. Some of those member variables required for the sparse matrix assembly are expensive (both in compute and memory) to initialize. In many analyses, users never create sparse matrices for some of the trial space derivatives (like the parameter fields) which means that some of those member variables were never needed after all.This PR changes the behavior so that the expensive bits are initialized just-in-time, rather than when a
serac::Functional
is created, to be more consistent with the mantra "don't pay for what you don't use". The end result is a much smaller memory footprint (about ~50-75% smaller, depending on number of parameter fields) and shorter time to initialize.The implementation is crude, but we're planning to remove much of this code in the coming months anyway.