Xmod Co-simulation -

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)

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 )

@abstractmethod def step(self, t: float, dt: float, inputs: Dict[str, np.ndarray]) -> XModStep: """Advance model by dt from t with given inputs.""" pass xmod co-simulation

def __init__(self, name: str, Kp: float, x_ref: float = 0.0): super().__init__(name) self.Kp = Kp self.x_ref = x_ref self.input_ports = [XModPort("x_measured")] self.output_ports = [XModPort("F_cmd")]

def get_state(self): return {"x": self.x, "v": self.v} model in self.models.items(): step_result = model.step(t

def set_state(self, state: Dict): pass xmod co-simulation master ---------------------------------------------------------------------- class XModCoSimulation: """Orchestrates coupled xmod models."""

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)) 1e-8: converged = True break print(f"t={t:.3f}

@abstractmethod def get_state(self) -> Dict: """For checkpoint/rollback.""" pass

To make sure you have the best possible experience on our site, we use cookies. By continuing to use this website, you consent to the use of cookies.
Learn more
To top