From 27a8cbfd6989dc6b6318d0b1660e2b37b7e8ddf6 Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Thu, 3 Jul 2025 16:27:28 -0700 Subject: [PATCH] Add a balanced test assembly This test assembly reveals one way that the engine can stall, indicated by a long plateau in the loss history. You can make the plateau even longer by shrinking the inner spheres. --- app-proto/src/add_remove.rs | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/app-proto/src/add_remove.rs b/app-proto/src/add_remove.rs index b95eec2..d23a849 100644 --- a/app-proto/src/add_remove.rs +++ b/app-proto/src/add_remove.rs @@ -238,6 +238,68 @@ fn load_pointed_assemb(assembly: &Assembly) { } } +/* DEBUG */ +// the initial configuration of this test assembly deliberately violates the +// constraints, so loading the assembly will trigger a non-trivial realization +fn load_balanced_assemb(assembly: &Assembly) { + // create the spheres + const R_OUTER: f64 = 10.0; + const R_INNER: f64 = 4.0; + let spheres = [ + Sphere::new( + "outer".to_string(), + "Outer".to_string(), + [0.75_f32, 0.75_f32, 0.75_f32], + engine::sphere(0.0, 0.0, 0.0, R_OUTER) + ), + Sphere::new( + "a".to_string(), + "A".to_string(), + [1.00_f32, 0.00_f32, 0.25_f32], + engine::sphere(0.0, 4.0, 0.0, R_INNER) + ), + Sphere::new( + "b".to_string(), + "B".to_string(), + [0.00_f32, 0.25_f32, 1.00_f32], + engine::sphere(0.0, -4.0, 0.0, R_INNER) + ), + ]; + for sphere in spheres { + let _ = assembly.try_insert_element(sphere); + } + + // get references to the spheres + let [outer, a, b] = ["outer", "a", "b"].map( + |id| assembly.elements_by_id.with_untracked( + |elts_by_id| elts_by_id[id].clone() + ) + ); + + // fix the diameters of the outer, sun, and moon spheres + for (sphere, radius) in [ + (outer.clone(), R_OUTER), + (a.clone(), R_INNER), + (b.clone(), R_INNER) + ] { + let curvature_regulator = sphere.regulators().with_untracked( + |regs| regs.first().unwrap().clone() + ); + let curvature = 0.5 / radius; + curvature_regulator.set_point().set( + SpecifiedValue::try_from(curvature.to_string()).unwrap() + ); + } + + // set the inversive distances between the spheres. as described above, the + // initial configuration deliberately violates these constraints + for inner in [a, b] { + let tangency = InversiveDistanceRegulator::new([outer.clone(), inner]); + tangency.set_point.set(SpecifiedValue::try_from("1".to_string()).unwrap()); + assembly.insert_regulator(Rc::new(tangency)); + } +} + // setting the inversive distances between the vertices to -2 gives a regular // tetrahedron with side length 1, whose insphere and circumsphere have radii // sqrt(1/6) and sqrt(3/2), respectively. to measure those radii, set an @@ -507,6 +569,7 @@ pub fn AddRemove() -> View { "general" => load_gen_assemb(assembly), "low-curv" => load_low_curv_assemb(assembly), "pointed" => load_pointed_assemb(assembly), + "balanced" => load_balanced_assemb(assembly), "radius-ratio" => load_radius_ratio_assemb(assembly), "irisawa-hexlet" => load_irisawa_hexlet_assemb(assembly), _ => () @@ -560,6 +623,7 @@ pub fn AddRemove() -> View { option(value="general") { "General" } option(value="low-curv") { "Low-curvature" } option(value="pointed") { "Pointed" } + option(value="balanced") { "Balanced" } option(value="radius-ratio") { "Radius ratio" } option(value="irisawa-hexlet") { "Irisawa hexlet" } option(value="empty") { "Empty" }