Closed g-bauer closed 1 year ago
Sounds excellent! Do we need separate Second
and SecondMixed
entries for the cache specifically? Feels like we could just use the SecondMixed
variant for that.
The cache stores derivatives as HashMap<PartialDerivative, f64>
, so the Second
variant is a possible key. But we could ignore that when filling the map, i.e. we can write
fn get_or_insert_with_d2_64<F: FnOnce() -> Dual2_64>(
&mut self,
derivative: Derivative,
f: F,
) -> f64 {
if let Some(&value) = self.map.get(&PartialDerivative::SecondMixed(derivative, derivative)) {
self.hit += 1;
value
} else {
self.miss += 1;
let value = f();
self.map.insert(PartialDerivative::Zeroth, value.re);
self.map
.insert(PartialDerivative::First(derivative), value.v1[0]);
self.map
.insert(PartialDerivative::SecondMixed(derivative, derivative), value.v2[0]);
value.v2[0]
}
}
This just uses SecondMixed
and would lead to a cache hit in case one computes the second derivative using the less efficient HyperDual64
.
At the moment, we calculate all properties of a
State
that use second derivatives viaHyperDual64
. Second derivatives w.r.t a single property, i.e. non-mixed derivatives, can be calculated usingDual2_64
which are a bit more efficient.Should we add
Dual2_64
to thePartialDerivative
enum and to the cache? E.g. we could doBackground: This will speed up algorithms that use those non-mixed, second derivatives, e.g. the density iteration. First implementation shows speedup of ~9 % for density iteration and 6 % for
tp_flash
.