sim_lib_numbers_numeric/
registry.rs1use std::{
5 collections::BTreeMap,
6 sync::{Arc, OnceLock, RwLock},
7};
8
9use sim_kernel::{Error, Result, Symbol};
10
11use super::traits::{Differentiator, NumericKind, OdeSolver, Quadrature};
12
13#[derive(Default)]
14pub struct NumericRegistry {
15 differentiators: BTreeMap<Symbol, Arc<dyn Differentiator>>,
16 quadrature_fixed: BTreeMap<Symbol, Arc<dyn Quadrature>>,
17 quadrature_adaptive: BTreeMap<Symbol, Arc<dyn Quadrature>>,
18 ode_fixed: BTreeMap<Symbol, Arc<dyn OdeSolver>>,
19 ode_adaptive: BTreeMap<Symbol, Arc<dyn OdeSolver>>,
20}
21
22impl NumericRegistry {
23 pub fn register_differentiator(&mut self, plugin: Arc<dyn Differentiator>) {
24 self.differentiators.insert(plugin.name(), plugin);
25 }
26
27 pub fn register_quadrature(&mut self, plugin: Arc<dyn Quadrature>) {
28 match plugin.kind() {
29 NumericKind::QuadratureFixed => {
30 self.quadrature_fixed.insert(plugin.name(), plugin);
31 }
32 NumericKind::QuadratureAdaptive => {
33 self.quadrature_adaptive.insert(plugin.name(), plugin);
34 }
35 _ => {}
36 }
37 }
38
39 pub fn register_ode_solver(&mut self, plugin: Arc<dyn OdeSolver>) {
40 match plugin.kind() {
41 NumericKind::OdeFixed => {
42 self.ode_fixed.insert(plugin.name(), plugin);
43 }
44 NumericKind::OdeAdaptive => {
45 self.ode_adaptive.insert(plugin.name(), plugin);
46 }
47 _ => {}
48 }
49 }
50
51 pub fn differentiator(&self, method: &Symbol) -> Option<Arc<dyn Differentiator>> {
52 self.differentiators.get(method).cloned()
53 }
54
55 pub fn quadrature_fixed(&self, method: &Symbol) -> Option<Arc<dyn Quadrature>> {
56 self.quadrature_fixed.get(method).cloned()
57 }
58
59 pub fn quadrature_adaptive(&self, method: &Symbol) -> Option<Arc<dyn Quadrature>> {
60 self.quadrature_adaptive.get(method).cloned()
61 }
62
63 pub fn ode_fixed(&self, method: &Symbol) -> Option<Arc<dyn OdeSolver>> {
64 self.ode_fixed.get(method).cloned()
65 }
66
67 pub fn ode_adaptive(&self, method: &Symbol) -> Option<Arc<dyn OdeSolver>> {
68 self.ode_adaptive.get(method).cloned()
69 }
70}
71
72static GLOBAL_NUMERIC_REGISTRY: OnceLock<RwLock<NumericRegistry>> = OnceLock::new();
73
74pub fn global_numeric_registry() -> &'static RwLock<NumericRegistry> {
76 GLOBAL_NUMERIC_REGISTRY.get_or_init(|| RwLock::new(NumericRegistry::default()))
77}
78
79pub fn register_differentiator(plugin: Arc<dyn Differentiator>) -> Result<()> {
85 global_numeric_registry()
86 .write()
87 .map_err(|_| Error::PoisonedLock("numeric registry"))?
88 .register_differentiator(plugin);
89 Ok(())
90}
91
92pub fn register_quadrature(plugin: Arc<dyn Quadrature>) -> Result<()> {
101 global_numeric_registry()
102 .write()
103 .map_err(|_| Error::PoisonedLock("numeric registry"))?
104 .register_quadrature(plugin);
105 Ok(())
106}
107
108pub fn register_ode_solver(plugin: Arc<dyn OdeSolver>) -> Result<()> {
117 global_numeric_registry()
118 .write()
119 .map_err(|_| Error::PoisonedLock("numeric registry"))?
120 .register_ode_solver(plugin);
121 Ok(())
122}