Check tangent space sync when deforming

Only give elements column indices once they've actually been through a
realization. Ignore motions of elements that haven't been through a
realization. Get the dimensions of the projected motion matrix from the
saved tangent space, not the current number of elements.
This commit is contained in:
Aaron Fenyes 2024-12-17 21:24:38 -08:00
parent 4fd79b9e47
commit 971a7ca7e2
2 changed files with 59 additions and 25 deletions

View file

@ -88,11 +88,17 @@ impl PartialMatrix {
// --- configuration subspaces ---
#[derive(Clone)]
pub struct ConfigSubspace(Vec<DMatrix<f64>>);
pub struct ConfigSubspace {
assembly_dim: usize,
basis: Vec<DMatrix<f64>>
}
impl ConfigSubspace {
pub fn zero() -> ConfigSubspace {
ConfigSubspace(Vec::new())
pub fn zero(assembly_dim: usize) -> ConfigSubspace {
ConfigSubspace {
assembly_dim: assembly_dim,
basis: Vec::new()
}
}
// approximate the kernel of a symmetric endomorphism of the configuration
@ -119,12 +125,18 @@ impl ConfigSubspace {
format!("Eigenvalues used to find kernel: {}", eig.eigenvalues)
));
ConfigSubspace(basis.collect())
ConfigSubspace {
assembly_dim: assembly_dim,
basis: basis.collect()
}
}
pub fn dim(&self) -> usize {
let ConfigSubspace(basis) = self;
basis.len()
self.basis.len()
}
pub fn assembly_dim(&self) -> usize {
self.assembly_dim
}
// find the projection onto this subspace of the motion where the element
@ -133,8 +145,7 @@ impl ConfigSubspace {
// for the zero subspace, this method's behavior doesn't match its name: it
// panics rather than returning zero
pub fn proj(&self, v: &DVectorView<f64>, column_index: usize) -> DMatrix<f64> {
let ConfigSubspace(basis) = self;
basis.into_iter().map(
self.basis.iter().map(
|b| b.column(column_index).dot(&v) * b
).sum()
}
@ -325,14 +336,14 @@ pub fn realize_gram(
state = better_state;
history.backoff_steps.push(backoff_steps);
},
None => return (state.config, ConfigSubspace::zero(), false, history)
None => return (state.config, ConfigSubspace::zero(assembly_dim), false, history)
};
}
let success = state.loss < tol;
let tangent = if success {
ConfigSubspace::symmetric_kernel(hess, assembly_dim)
} else {
ConfigSubspace::zero()
ConfigSubspace::zero(assembly_dim)
};
(state.config, tangent, success, history)
}