forked from StudioInfinity/dyna3
Deform the assembly
This seems like a good starting point, even though the code is messy and the deformation routine has some numerical quirks. Note that the translation direction is mixed up: the keys are for x, but the velocity field is for z.
This commit is contained in:
parent
7aa69bdfcd
commit
58e7587131
3 changed files with 111 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
|||
use nalgebra::{DMatrix, DVector, Vector3};
|
||||
use nalgebra::{DMatrix, DVector, DVectorView, Vector3};
|
||||
use rustc_hash::FxHashMap;
|
||||
use slab::Slab;
|
||||
use std::{collections::BTreeSet, sync::atomic::{AtomicU64, Ordering}};
|
||||
|
@ -152,6 +152,13 @@ impl Assembly {
|
|||
let id = elt.id.clone();
|
||||
let key = self.elements.update(|elts| elts.insert(elt));
|
||||
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 {
|
||||
|
@ -266,6 +273,7 @@ impl Assembly {
|
|||
));
|
||||
console::log_2(&JsValue::from("Steps:"), &JsValue::from(history.scaled_loss.len() - 1));
|
||||
console::log_2(&JsValue::from("Loss:"), &JsValue::from(*history.scaled_loss.last().unwrap()));
|
||||
console::log_2(&JsValue::from("Tangent dimension:"), &JsValue::from(tangent.dim()));
|
||||
|
||||
if success {
|
||||
// read out the solution
|
||||
|
@ -279,4 +287,41 @@ impl Assembly {
|
|||
self.tangent.set_silent(tangent);
|
||||
}
|
||||
}
|
||||
|
||||
// --- deformation ---
|
||||
|
||||
pub fn deform(&self, element_motions: Vec<(ElementKey, DVectorView<f64>)>) {
|
||||
/* KLUDGE */
|
||||
// when the tangent space is zero, we currently need to avoid calling
|
||||
// its `proj` method, because it will panic rather than returning zero.
|
||||
// in the future, we'll want a more intentionally designed system for
|
||||
// handling this case
|
||||
if self.tangent.with(|tan| tan.dim() <= 0) {
|
||||
console::log_1(&JsValue::from("The assembly is rigid"));
|
||||
return;
|
||||
}
|
||||
|
||||
const ELEMENT_DIM: usize = 5;
|
||||
let assembly_dim = self.elements.with(|elts| elts.len());
|
||||
let mut motion_proj = DMatrix::zeros(ELEMENT_DIM, 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
|
||||
for (elt_key, elt_motion) in element_motions {
|
||||
let column_index = self.elements.with(|elts| elts[elt_key].column_index);
|
||||
motion_proj += self.tangent.with(|tan| tan.proj(&elt_motion, column_index));
|
||||
}
|
||||
|
||||
// step the configuration linearly along the tangent space of the
|
||||
// solution variety
|
||||
for (_, elt) in self.elements.get_clone_untracked() {
|
||||
elt.representation.update_silent(|rep| {
|
||||
let rep_next = &*rep + motion_proj.column(elt.column_index);
|
||||
rep.set_column(0, &rep_next);
|
||||
});
|
||||
}
|
||||
|
||||
// bring the configuration back onto the solution variety
|
||||
self.realize();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue