Set out invariants for column indices

This should make it safe to use the elements' column indices outside the
realization method—for unpacking tangent vectors, at least.
This commit is contained in:
Aaron Fenyes 2024-12-18 09:49:14 -08:00
parent 967daa595d
commit e2c5ba0fc7

View File

@ -134,7 +134,16 @@ pub struct Assembly {
pub elements: Signal<Slab<Element>>,
pub constraints: Signal<Slab<Constraint>>,
// solution variety tangent space
// solution variety tangent space. the basis vectors are stored in
// configuration matrix format, ordered according to the elements' column
// indices. when you realize the assembly, every element that's present
// during realization gets a column index and is reflected in the tangent
// space. since the methods in this module never assign column indices
// without later realizing the assembly, we get the following invariant:
//
// (1) if an element has a column index, its tangent motions can be found
// in that column of the tangent space basis matrices
//
pub tangent: Signal<ConfigSubspace>,
// indexing
@ -291,6 +300,14 @@ impl Assembly {
// --- deformation ---
// project the given motion to the tangent space of the solution variety and
// move the assembly along it. the implementation is based on invariant (1)
// from above and the following additional invariant:
//
// (2) if an element is affected by a constraint, it has a column index
//
// we have this invariant because the assembly gets realized each time you
// add a constraint
pub fn deform(&self, motion: AssemblyMotion) {
/* KLUDGE */
// when the tangent space is zero, deformation won't do anything, but
@ -319,11 +336,9 @@ impl Assembly {
None => {
// give the element a column index, even though it's never
// been through a realization, and add its motion to that
// column of the projected motion. this puts the element
// column indices out of sync with the saved tangent space,
// but that's okay: the realization we do to get back onto
// the solution variety will re-index the elements and
// recompute the tangent space
// column of the projected motion. this temporarily breaks
// invariant (1), but the invariant will be restored when we
// realize the assembly at the end of the deformation
let mut target_column = motion_proj.column_mut(next_column_index);
target_column += elt_motion.velocity;
self.elements.update_silent(