Xmod Co-simulation May 2026
# Log results history = [] def log(t, outputs): x = outputs["mass_spring"].get("x", [0])[0] history.append((t, x)) print(f"t={t:.3f}, x={x:.4f}")
def connect(self, from_model: str, from_port: str, to_model: str, to_port: str): self.connections.append((from_model, from_port, to_model, to_port))
sim.run(0.0, 2.0, log_callback=log)
@abstractmethod def get_state(self) -> Dict: """For checkpoint/rollback.""" pass
def get_state(self): return {} # stateless xmod co-simulation
def __init__(self, name: str, m: float, k: float, c: float): super().__init__(name) self.m = m self.k = k self.c = c self.x = 0.0 self.v = 0.0 # Define ports self.input_ports = [XModPort("F_ext")] self.output_ports = [XModPort("x"), XModPort("v")]
def __init__(self, name: str): self.name = name self.input_ports: List[XModPort] = [] self.output_ports: List[XModPort] = [] # Log results history = [] def log(t,
def step(self, t: float, dt: float, inputs: Dict[str, np.ndarray]) -> XModStep: F_ext = inputs.get("F_ext", np.array([0.0]))[0] # Simple semi-implicit Euler a = (F_ext - self.k * self.x - self.c * self.v) / self.m self.v += a * dt self.x += self.v * dt return XModStep( outputs={"x": np.array([self.x]), "v": np.array([self.v])}, new_time=t + dt )