Xmod Co-simulation !!hot!! 〈Easy〉

class XModModel(ABC): """Base class for an xmod co-simulation component."""

def run_with_iteration(self, t_start: float, t_end: float, max_iter: int = 10): """Jacobi-style fixed-point iteration at each time step.""" t = t_start outputs = {name: {} for name in self.models} while t < t_end - 1e-12: converged = False for _iter in range(max_iter): inputs_for = {name: {} for name in self.models} for fm, fp, tm, tp in self.connections: if fm in outputs and fp in outputs[fm]: inputs_for[tm][tp] = outputs[fm][fp] new_outputs = {} for name, model in self.models.items(): step_result = model.step(t, self.dt, inputs_for[name]) new_outputs[name] = step_result.outputs # Check convergence (norm of output change) diff = 0.0 for name in self.models: for port in new_outputs[name]: old_val = outputs[name].get(port, 0) diff += np.linalg.norm(new_outputs[name][port] - old_val) outputs = new_outputs if diff < 1e-8: converged = True break print(f"t={t:.3f}, iter={_iter+1}, converged={converged}") t += self.dt Demo ---------------------------------------------------------------------- if name == " main ": # Build system: controller -> spring-mass-damper plant = SpringMassDamper("mass_spring", m=1.0, k=10.0, c=0.5) ctrl = PController("controller", Kp=20.0, x_ref=1.0) xmod co-simulation

@abstractmethod def get_state(self) -> Dict: """For checkpoint/rollback.""" pass model in self.models.items(): step_result = model.step(t