Closed jockyuiz closed 1 year ago
Hi, this is currently the main limitation of TinyAD. It is only fast because elements have a small and constant size.
Here are two workarounds:
Workaround A
Statically choose a maximum allowed vertex valence and use func.add_elements<max_valence>(..)
. You can then dynamically query the subset of variables that you actually want to use per vertex via element.variables(..)
. This means that per-element derivatives will just carry around a bunch of zeros when not all variables are used.
Run time performance will slow down a lot depending on max_valence
. Another trick would then be to create element types for a number of common valences, like func.add_elements<5>(..)
, func.add_elements<6>(..)
, func.add_elements<7>(..)
, and use func.add_elements<max_valence>(..)
only for all other vertices. This compiles slower but runs faster. I'd recommend this workaround.
Workaround B
Use dynamic mode via TinyAD::Double<Eigen::Dynamic>
for each element (not supported in the scalar_function
interface) and assemble the global derivatives manually. But I don't really recommend that, because dynamic mode is much more limited, see #6.
Hi, I'm trying to define an objective that involves the shape operator, which evaluates the data on one-ring around each vertex. However, I only find objectives connected with constant variables in all the examples. I can't do something like
func::add_element <valence>
in a loop since it requires a const value inside<>. Is there any solution to this kind of objective? Thank you so much in advance!