oxirs_physics/simulation/
mod.rs

1//! Physics Simulation Orchestration
2
3pub mod parameter_extraction;
4pub mod result_injection;
5pub mod scirs2_thermal;
6pub mod simulation_runner;
7
8pub use parameter_extraction::{ParameterExtractor, SimulationParameters};
9pub use result_injection::{ResultInjector, SimulationResult};
10pub use scirs2_thermal::SciRS2ThermalSimulation;
11pub use simulation_runner::{PhysicsSimulation, SimulationRunner};
12
13use crate::error::{PhysicsError, PhysicsResult};
14use std::collections::HashMap;
15use std::sync::Arc;
16
17/// Simulation Orchestrator - coordinates parameter extraction, simulation, and result injection
18pub struct SimulationOrchestrator {
19    extractor: Arc<ParameterExtractor>,
20    injector: Arc<ResultInjector>,
21    simulations: HashMap<String, Arc<dyn PhysicsSimulation>>,
22}
23
24impl SimulationOrchestrator {
25    /// Create a new orchestrator
26    pub fn new() -> Self {
27        Self {
28            extractor: Arc::new(ParameterExtractor::new()),
29            injector: Arc::new(ResultInjector::new()),
30            simulations: HashMap::new(),
31        }
32    }
33
34    /// Register a simulation type
35    pub fn register(&mut self, name: impl Into<String>, simulation: Arc<dyn PhysicsSimulation>) {
36        self.simulations.insert(name.into(), simulation);
37    }
38
39    /// Extract parameters from RDF graph
40    pub async fn extract_parameters(
41        &self,
42        entity_iri: &str,
43        simulation_type: &str,
44    ) -> PhysicsResult<SimulationParameters> {
45        self.extractor.extract(entity_iri, simulation_type).await
46    }
47
48    /// Run simulation
49    pub async fn run(
50        &self,
51        simulation_type: &str,
52        params: SimulationParameters,
53    ) -> PhysicsResult<SimulationResult> {
54        let simulation = self.simulations.get(simulation_type).ok_or_else(|| {
55            PhysicsError::Simulation(format!("Unknown simulation type: {}", simulation_type))
56        })?;
57
58        simulation.run(&params).await
59    }
60
61    /// Inject results back to RDF
62    pub async fn inject_results(&self, result: &SimulationResult) -> PhysicsResult<()> {
63        self.injector.inject(result).await
64    }
65
66    /// Full simulation workflow: extract → run → inject
67    pub async fn execute_workflow(
68        &self,
69        entity_iri: &str,
70        simulation_type: &str,
71    ) -> PhysicsResult<SimulationResult> {
72        let params = self.extract_parameters(entity_iri, simulation_type).await?;
73        let result = self.run(simulation_type, params).await?;
74        self.inject_results(&result).await?;
75        Ok(result)
76    }
77}
78
79impl Default for SimulationOrchestrator {
80    fn default() -> Self {
81        Self::new()
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_orchestrator_creation() {
91        let orchestrator = SimulationOrchestrator::new();
92        assert!(orchestrator.simulations.is_empty());
93    }
94}