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(