Deform fresh elements too
Implement deformation of elements that haven't gone through realization.
This commit is contained in:
parent
dc067976eb
commit
967daa595d
@ -33,8 +33,8 @@ pub struct Element {
|
|||||||
pub serial: u64,
|
pub serial: u64,
|
||||||
|
|
||||||
// the configuration matrix column index that was assigned to this element
|
// the configuration matrix column index that was assigned to this element
|
||||||
// last time the assembly was realized, or `None` if the assembly has never
|
// last time the assembly was realized, or `None` if the element has never
|
||||||
// been realized with this element in it
|
// been through a realization
|
||||||
column_index: Option<usize>
|
column_index: Option<usize>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,13 +160,6 @@ impl Assembly {
|
|||||||
let id = elt.id.clone();
|
let id = elt.id.clone();
|
||||||
let key = self.elements.update(|elts| elts.insert(elt));
|
let key = self.elements.update(|elts| elts.insert(elt));
|
||||||
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
||||||
|
|
||||||
// realize to update the tangent space
|
|
||||||
/* KLUDGE */
|
|
||||||
// since the newly inserted element is unconstrained, we should be able
|
|
||||||
// to update the tangent space without recomputing the Hessian and its
|
|
||||||
// eigendecomposition
|
|
||||||
self.realize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_insert_element(&self, elt: Element) -> bool {
|
pub fn try_insert_element(&self, elt: Element) -> bool {
|
||||||
@ -300,35 +293,43 @@ impl Assembly {
|
|||||||
|
|
||||||
pub fn deform(&self, motion: AssemblyMotion) {
|
pub fn deform(&self, motion: AssemblyMotion) {
|
||||||
/* KLUDGE */
|
/* KLUDGE */
|
||||||
// when the tangent space is zero, we currently need to avoid calling
|
// when the tangent space is zero, deformation won't do anything, but
|
||||||
// its `proj` method, because it will panic rather than returning zero.
|
// the attempt to deform should be registered in the UI. this console
|
||||||
// in the future, we'll want a more intentionally designed system for
|
// message will do for now
|
||||||
// handling this case
|
if self.tangent.with(|tan| tan.dim() <= 0 && tan.assembly_dim() > 0) {
|
||||||
if self.tangent.with(|tan| tan.dim() <= 0) {
|
|
||||||
console::log_1(&JsValue::from("The assembly is rigid"));
|
console::log_1(&JsValue::from("The assembly is rigid"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ELEMENT_DIM: usize = 5;
|
const ELEMENT_DIM: usize = 5;
|
||||||
let assembly_dim = self.tangent.with(|tan| tan.assembly_dim());
|
let assembly_dim = self.elements.with(|elts| elts.len());
|
||||||
let mut motion_proj = DMatrix::zeros(ELEMENT_DIM, assembly_dim);
|
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
|
// project the element motions onto the tangent space of the solution
|
||||||
// variety, and sum them to get a deformation of the whole assembly
|
// 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 {
|
for elt_motion in motion {
|
||||||
match self.elements.with_untracked(|elts| elts[elt_motion.key].column_index) {
|
match self.elements.with_untracked(|elts| elts[elt_motion.key].column_index) {
|
||||||
Some(column_index) => {
|
Some(column_index) => {
|
||||||
motion_proj += self.tangent.with(
|
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)
|
|tan| tan.proj(&elt_motion.velocity, column_index)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
console::log_1(&JsValue::from(
|
// give the element a column index, even though it's never
|
||||||
format!(
|
// been through a realization, and add its motion to that
|
||||||
"Ignoring motion of fresh element \"{}\"",
|
// column of the projected motion. this puts the element
|
||||||
self.elements.with_untracked(|elts| elts[elt_motion.key].id.clone())
|
// 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
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,7 +356,9 @@ impl Assembly {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// bring the configuration back onto the solution variety
|
// bring the configuration back onto the solution variety. this also
|
||||||
|
// gets the elements' column indices and the saved tangent space back in
|
||||||
|
// sync
|
||||||
self.realize();
|
self.realize();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user