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"));
|
||||
}
|
||||
|
||||
const ELEMENT_DIM: usize = 5;
|
||||
let assembly_dim = self.elements.with(|elts| elts.len());
|
||||
let mut motion_proj = DMatrix::zeros(ELEMENT_DIM, assembly_dim);
|
||||
let tan_assembly_dim = self.tangent.with(|tan| tan.assembly_dim());
|
||||
|
||||
// project the element motions onto the tangent space of the solution
|
||||
// variety, and sum them to get a deformation of the whole assembly
|
||||
let mut next_column_index = tan_assembly_dim;
|
||||
for elt_motion in motion {
|
||||
match self.elements.with_untracked(|elts| elts[elt_motion.key].column_index) {
|
||||
Some(column_index) => {
|
||||
let mut target_columns = motion_proj.columns_mut(0, tan_assembly_dim);
|
||||
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)
|
||||
);
|
||||
// give a column index to each moving element that doesn't have one yet.
|
||||
// this temporarily breaks invariant (1), but the invariant will be
|
||||
// restored when we realize the assembly at the end of the deformation.
|
||||
// in the process, we find out how many matrix columns we'll need to
|
||||
// hold the deformation
|
||||
let realized_dim = self.tangent.with(|tan| tan.assembly_dim());
|
||||
let motion_dim = self.elements.update_silent(|elts| {
|
||||
let mut next_column_index = realized_dim;
|
||||
for elt_motion in motion.iter() {
|
||||
let moving_elt = &mut elts[elt_motion.key];
|
||||
if moving_elt.column_index.is_none() {
|
||||
moving_elt.column_index = Some(next_column_index);
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user