Introduce a regulator trait
This will provide a common interface for Lorentz product regulators, curvature regulators, and hopefully all the other regulators too.
This commit is contained in:
parent
00f60b0e90
commit
126d4c0cce
3 changed files with 75 additions and 35 deletions
|
@ -1,7 +1,7 @@
|
|||
use nalgebra::{DMatrix, DVector, DVectorView, Vector3};
|
||||
use rustc_hash::FxHashMap;
|
||||
use slab::Slab;
|
||||
use std::{collections::BTreeSet, sync::atomic::{AtomicU64, Ordering}};
|
||||
use std::{collections::BTreeSet, rc::Rc, sync::atomic::{AtomicU64, Ordering}};
|
||||
use sycamore::prelude::*;
|
||||
use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
||||
|
||||
|
@ -132,14 +132,35 @@ impl Element {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub trait Regulator {
|
||||
// get information
|
||||
fn subjects(&self) -> Vec<ElementKey>;
|
||||
fn measurement(&self) -> ReadSignal<f64>;
|
||||
fn set_point(&self) -> Signal<SpecifiedValue>;
|
||||
|
||||
// write problem data
|
||||
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>);
|
||||
}
|
||||
|
||||
pub struct ProductRegulator {
|
||||
pub subjects: [ElementKey; 2],
|
||||
pub measurement: ReadSignal<f64>,
|
||||
pub set_point: Signal<SpecifiedValue>
|
||||
}
|
||||
|
||||
impl ProductRegulator {
|
||||
impl Regulator for ProductRegulator {
|
||||
fn subjects(&self) -> Vec<ElementKey> {
|
||||
self.subjects.into()
|
||||
}
|
||||
|
||||
fn measurement(&self) -> ReadSignal<f64> {
|
||||
self.measurement
|
||||
}
|
||||
|
||||
fn set_point(&self) -> Signal<SpecifiedValue> {
|
||||
self.set_point
|
||||
}
|
||||
|
||||
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
|
||||
self.set_point.with_untracked(|set_pt| {
|
||||
if let Some(val) = set_pt.value {
|
||||
|
@ -169,7 +190,7 @@ type AssemblyMotion<'a> = Vec<ElementMotion<'a>>;
|
|||
pub struct Assembly {
|
||||
// elements and regulators
|
||||
pub elements: Signal<Slab<Element>>,
|
||||
pub regulators: Signal<Slab<ProductRegulator>>,
|
||||
pub regulators: Signal<Slab<Rc<dyn Regulator>>>,
|
||||
|
||||
// solution variety tangent space. the basis vectors are stored in
|
||||
// configuration matrix format, ordered according to the elements' column
|
||||
|
@ -240,19 +261,23 @@ impl Assembly {
|
|||
);
|
||||
}
|
||||
|
||||
fn insert_regulator(&self, regulator: ProductRegulator) {
|
||||
let subjects = regulator.subjects;
|
||||
let key = self.regulators.update(|regs| regs.insert(regulator));
|
||||
let subject_regulators = self.elements.with(
|
||||
|elts| subjects.map(|subj| elts[subj].regulators)
|
||||
fn insert_regulator(&self, regulator: Rc<dyn Regulator>) {
|
||||
let subjects = regulator.subjects();
|
||||
let key = self.regulators.update(
|
||||
|regs| regs.insert(regulator)
|
||||
);
|
||||
let subject_regulators: Vec<_> = self.elements.with(
|
||||
|elts| subjects.into_iter().map(
|
||||
|subj| elts[subj].regulators
|
||||
).collect()
|
||||
);
|
||||
for regulators in subject_regulators {
|
||||
regulators.update(|regs| regs.insert(key));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_new_regulator(self, subjects: [ElementKey; 2]) {
|
||||
// create and insert a new regulator
|
||||
pub fn insert_new_product_regulator(self, subjects: [ElementKey; 2]) {
|
||||
// create and insert a new product regulator
|
||||
let measurement = self.elements.map(
|
||||
move |elts| {
|
||||
let representations = subjects.map(|subj| elts[subj].representation);
|
||||
|
@ -264,26 +289,31 @@ impl Assembly {
|
|||
}
|
||||
);
|
||||
let set_point = create_signal(SpecifiedValue::from_empty_spec());
|
||||
self.insert_regulator(ProductRegulator {
|
||||
self.insert_regulator(Rc::new(ProductRegulator {
|
||||
subjects: subjects,
|
||||
measurement: measurement,
|
||||
set_point: set_point
|
||||
});
|
||||
}));
|
||||
|
||||
/* DEBUG */
|
||||
// print an updated list of regulators
|
||||
console::log_1(&JsValue::from("Regulators:"));
|
||||
self.regulators.with(|regs| {
|
||||
for (_, reg) in regs.into_iter() {
|
||||
console::log_5(
|
||||
&JsValue::from(" "),
|
||||
&JsValue::from(reg.subjects[0]),
|
||||
&JsValue::from(reg.subjects[1]),
|
||||
&JsValue::from(":"),
|
||||
®.set_point.with_untracked(
|
||||
|set_pt| JsValue::from(set_pt.spec.as_str())
|
||||
console::log_1(&JsValue::from(format!(
|
||||
" {:?}: {}",
|
||||
reg.subjects(),
|
||||
reg.set_point().with_untracked(
|
||||
|set_pt| {
|
||||
let spec = &set_pt.spec;
|
||||
if spec.is_empty() {
|
||||
"__".to_string()
|
||||
} else {
|
||||
spec.clone()
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
)));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue