Make the deformation matrix just the right size
Also, correct the check for whether an element had a column index when we started. The previous revision would've gotten the wrong answer for an element without a column index that appeared more than once in the motion.
This commit is contained in:
parent
e2c5ba0fc7
commit
6df0e855cf
@ -317,36 +317,50 @@ impl Assembly {
|
|||||||
console::log_1(&JsValue::from("The assembly is rigid"));
|
console::log_1(&JsValue::from("The assembly is rigid"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ELEMENT_DIM: usize = 5;
|
// give a column index to each moving element that doesn't have one yet.
|
||||||
let assembly_dim = self.elements.with(|elts| elts.len());
|
// this temporarily breaks invariant (1), but the invariant will be
|
||||||
let mut motion_proj = DMatrix::zeros(ELEMENT_DIM, assembly_dim);
|
// restored when we realize the assembly at the end of the deformation.
|
||||||
let tan_assembly_dim = self.tangent.with(|tan| tan.assembly_dim());
|
// in the process, we find out how many matrix columns we'll need to
|
||||||
|
// hold the deformation
|
||||||
// project the element motions onto the tangent space of the solution
|
let realized_dim = self.tangent.with(|tan| tan.assembly_dim());
|
||||||
// variety, and sum them to get a deformation of the whole assembly
|
let motion_dim = self.elements.update_silent(|elts| {
|
||||||
let mut next_column_index = tan_assembly_dim;
|
let mut next_column_index = realized_dim;
|
||||||
for elt_motion in motion {
|
for elt_motion in motion.iter() {
|
||||||
match self.elements.with_untracked(|elts| elts[elt_motion.key].column_index) {
|
let moving_elt = &mut elts[elt_motion.key];
|
||||||
Some(column_index) => {
|
if moving_elt.column_index.is_none() {
|
||||||
let mut target_columns = motion_proj.columns_mut(0, tan_assembly_dim);
|
moving_elt.column_index = Some(next_column_index);
|
||||||
target_columns += self.tangent.with(
|
|
||||||
|tan| tan.proj(&elt_motion.velocity, column_index)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
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 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(
|
|
||||||
|elts| elts[elt_motion.key].column_index = Some(next_column_index)
|
|
||||||
);
|
|
||||||
next_column_index += 1;
|
next_column_index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next_column_index
|
||||||
|
});
|
||||||
|
|
||||||
|
// project the element motions onto the tangent space of the solution
|
||||||
|
// variety and sum them to get a deformation of the whole assembly. the
|
||||||
|
// matrix `motion_proj` that holds the deformation has extra columns for
|
||||||
|
// any moving elements that aren't reflected in the saved tangent space
|
||||||
|
const ELEMENT_DIM: usize = 5;
|
||||||
|
let mut motion_proj = DMatrix::zeros(ELEMENT_DIM, motion_dim);
|
||||||
|
for elt_motion in motion {
|
||||||
|
// we can unwrap the column index because we know that every moving
|
||||||
|
// element has one at this point
|
||||||
|
let column_index = self.elements.with_untracked(
|
||||||
|
|elts| elts[elt_motion.key].column_index.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
if column_index < realized_dim {
|
||||||
|
// this element had a column index when we started, so by
|
||||||
|
// invariant (1), it's reflected in the tangent space
|
||||||
|
let mut target_columns = motion_proj.columns_mut(0, realized_dim);
|
||||||
|
target_columns += self.tangent.with(
|
||||||
|
|tan| tan.proj(&elt_motion.velocity, column_index)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// this element didn't have a column index when we started, so
|
||||||
|
// by invariant (2), it's unconstrained
|
||||||
|
let mut target_column = motion_proj.column_mut(column_index);
|
||||||
|
target_column += elt_motion.velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// step each element along the mass shell geodesic that matches its
|
// step each element along the mass shell geodesic that matches its
|
||||||
|
Loading…
Reference in New Issue
Block a user