From fa1e54f1718e32028cd4086b466dad291d7600e6 Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Mon, 3 Feb 2025 15:56:52 -0800 Subject: [PATCH 1/3] Normalize deformed assembly by contracting Uniformly contract spatial and curvature components. This preserves the centers of spheres, but alters their curvatures. It should preserve planes entirely. --- app-proto/src/assembly.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index 9b0e065..28afb19 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -371,8 +371,8 @@ impl Assembly { } } - // step each element along the mass shell geodesic that matches its - // velocity in the deformation found above + // step the assembly along the deformation, and then project each + // element back onto its mass shall /* KLUDGE */ // since our test assemblies only include spheres, we assume that every // element is on the 1 mass shell @@ -380,9 +380,25 @@ impl Assembly { elt.representation.update_silent(|rep| { match elt.column_index { Some(column_index) => { + // apply the deformation linearly let rep_next = &*rep + motion_proj.column(column_index); - let normalizer = rep_next.dot(&(&*Q * &rep_next)); - rep.set_column(0, &(rep_next / normalizer)); + + // project back onto the mass shell by contracting + // toward the last coordinate axis + let q_sp = rep_next.fixed_rows::<3>(0).norm_squared(); + let half_q_lt = -2.0 * rep_next[3] * rep_next[4]; + let half_q_lt_sq = half_q_lt * half_q_lt; + let scaling = half_q_lt + (q_sp + half_q_lt_sq).sqrt(); + rep.fixed_rows_mut::<4>(0).copy_from( + &(rep_next.fixed_rows::<4>(0) / scaling) + ); + rep[4] = rep_next[4]; + + /* DEBUG */ + // report self-product before and after projection + console::log_1(&JsValue::from( + format!("Self-product of element representation\n After step: {}\n Scaling: {}\n After scaling: {}", rep_next.dot(&(&*Q * &rep_next)), scaling, rep.dot(&(&*Q * &*rep))) + )); }, None => { console::log_1(&JsValue::from( -- 2.43.0 From 544249ae26d115c724f7719c990f013c842fda6a Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Mon, 3 Feb 2025 18:17:32 -0800 Subject: [PATCH 2/3] Simplify normalization routine We don't need to explicitly allocate scratch space. --- app-proto/src/assembly.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index 28afb19..08914aa 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -381,23 +381,20 @@ impl Assembly { match elt.column_index { Some(column_index) => { // apply the deformation linearly - let rep_next = &*rep + motion_proj.column(column_index); + *rep += motion_proj.column(column_index); // project back onto the mass shell by contracting // toward the last coordinate axis - let q_sp = rep_next.fixed_rows::<3>(0).norm_squared(); - let half_q_lt = -2.0 * rep_next[3] * rep_next[4]; + let q_sp = rep.fixed_rows::<3>(0).norm_squared(); + let half_q_lt = -2.0 * rep[3] * rep[4]; let half_q_lt_sq = half_q_lt * half_q_lt; let scaling = half_q_lt + (q_sp + half_q_lt_sq).sqrt(); - rep.fixed_rows_mut::<4>(0).copy_from( - &(rep_next.fixed_rows::<4>(0) / scaling) - ); - rep[4] = rep_next[4]; + rep.fixed_rows_mut::<4>(0).scale_mut(1.0 / scaling); /* DEBUG */ // report self-product before and after projection console::log_1(&JsValue::from( - format!("Self-product of element representation\n After step: {}\n Scaling: {}\n After scaling: {}", rep_next.dot(&(&*Q * &rep_next)), scaling, rep.dot(&(&*Q * &*rep))) + format!("After scaling by {}, self-product of element representation is {}", scaling, rep.dot(&(&*Q * &*rep))) )); }, None => { -- 2.43.0 From dac96cf1ac47d03e0cc21662fb328d35a7e9e8fa Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Mon, 3 Feb 2025 18:26:36 -0800 Subject: [PATCH 3/3] Improve comments and remove debug output --- app-proto/src/assembly.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index 08914aa..7073c9e 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -5,7 +5,7 @@ use std::{collections::BTreeSet, sync::atomic::{AtomicU64, Ordering}}; use sycamore::prelude::*; use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */ -use crate::engine::{realize_gram, local_unif_to_std, ConfigSubspace, PartialMatrix, Q}; +use crate::engine::{realize_gram, local_unif_to_std, ConfigSubspace, PartialMatrix}; // the types of the keys we use to access an assembly's elements and constraints pub type ElementKey = usize; @@ -371,8 +371,8 @@ impl Assembly { } } - // step the assembly along the deformation, and then project each - // element back onto its mass shall + // step the assembly along the deformation. this changes the elements' + // normalizations, so we restore those afterward /* KLUDGE */ // since our test assemblies only include spheres, we assume that every // element is on the 1 mass shell @@ -380,22 +380,16 @@ impl Assembly { elt.representation.update_silent(|rep| { match elt.column_index { Some(column_index) => { - // apply the deformation linearly + // step the assembly along the deformation *rep += motion_proj.column(column_index); - // project back onto the mass shell by contracting - // toward the last coordinate axis + // restore normalization by contracting toward the last + // coordinate axis let q_sp = rep.fixed_rows::<3>(0).norm_squared(); let half_q_lt = -2.0 * rep[3] * rep[4]; let half_q_lt_sq = half_q_lt * half_q_lt; let scaling = half_q_lt + (q_sp + half_q_lt_sq).sqrt(); rep.fixed_rows_mut::<4>(0).scale_mut(1.0 / scaling); - - /* DEBUG */ - // report self-product before and after projection - console::log_1(&JsValue::from( - format!("After scaling by {}, self-product of element representation is {}", scaling, rep.dot(&(&*Q * &*rep))) - )); }, None => { console::log_1(&JsValue::from( -- 2.43.0