Metadata-Version: 2.3
Name: khimsim
Version: 0.1.0
Summary: Add your description here
Requires-Dist: control>=0.10.2
Requires-Dist: jax>=0.10.2
Requires-Dist: matplotlib>=3.11.0
Requires-Dist: networkx>=3.6.1
Requires-Dist: numpy>=2.5.1
Requires-Dist: scipy>=1.18.0
Requires-Dist: sortedcontainers>=2.4.0
Requires-Dist: sphinx>=9.1.0
Requires-Dist: svgwrite>=1.4.3
Requires-Dist: fmpy>=0.3.20 ; extra == 'fmu'
Requires-Python: >=3.13
Provides-Extra: fmu
Description-Content-Type: text/markdown

# 🎭 Khimsim (Khimaira-Sim)

[![Python Version](https://img.shields.io/badge/python-3.13+-blue.svg)](https://python.org)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

`khimsim` is a high-performance Python library for compiling and simulating hybrid dynamical systems (block diagrams). It supports continuous-time ODE dynamics, multi-rate discrete-time clocks, event-driven state transitions (zero-crossings), and simultaneous resolution of algebraic loops.

## Features

- **Continuous-Time Simulation**: Native support for ODE models integrated using adaptive-step solvers (via SciPy `solve_ivp`).
- **Discrete-Time Simulation**: Clock-bound execution (via `PeriodicClock` and `ListClock`) with Zero-Order Hold (ZOH) semantics.
- **Event-Driven Transitions**: High-precision zero-crossing locator that stops integration to apply discrete updates (e.g., bouncing ball, relays) and handles state jumps.
- **Algebraic Loop Solver**: Detects strongly-connected cycles of direct-feedthrough blocks and solves them simultaneously at runtime using `scipy.optimize.fsolve`.
- **Pythonic & Flexible Block API**: Leverages method signature inspection so blocks only request the parameters they need (`t`, `x`, `xd`, `u`).
- **Comprehensive Blocks Library**:
  - **Continuous**: Integrator, Filtered Derivative, PID, State-Space, Transfer Function, Zero-Pole, Transport Delay.
  - **Discrete**: Delay, ZOH, Discrete PID, Discrete Transfer Function, Filters, Tapped Delay, Variable Delay.
  - **Discontinuities**: Relay (with hysteresis events), Saturation, Dead Zone, PWM, Coulomb & Viscous Friction.
  - **Math**: Abs, Gain (scalar, vector, and matrix), Math Functions, Sign, Sum.
  - **Sources**: Constant, Step, Ramp, Sine, Pulse, Repeating Sequence, File Reader, Random Noise, Equation.

---

## Installation

Ensure you have Python 3.13+ and the dependencies installed. This project uses `uv` for dependency management:

```bash
# Clone the repository
git clone https://github.com/your-repo/khimaira-sim.git
cd khimaira-sim

# Install dependencies and sync virtual environment
uv sync
```

---

## Quick Start Example

Here is a simple example of a closed-loop system containing a continuous-time Plant ($x' = -x + u$) controlled by a proportional controller ($u = K(ref - y)$).

```python
import numpy as np
import matplotlib.pyplot as plt
from khimsim import System, Simulator, Step, Gain, Integrator, Sum

# 1. Instantiate the blocks
ref = Step(step_time=1.0, initial_value=0.0, step_value=2.0, name="reference")
error = Sum(signs="+-", name="error")
ctrl = Gain(K=4.0, name="controller")
plant = Integrator(initial_value=0.0, name="plant")

# 2. Add blocks to the system
sys = System()
sys.add(ref)
sys.add(error)
sys.add(ctrl)
sys.add(plant)

# 3. Connect the diagram
sys.connect(ref, 0, error, 0)    # ref -> positive input of sum
sys.connect(plant, 0, error, 1)  # plant output -> negative input of sum
sys.connect(error, 0, ctrl, 0)   # error -> controller
sys.connect(ctrl, 0, plant, 0)   # controller output -> plant integrator

# 4. Compile and Run the Simulation
sys.compile()
sim = Simulator(sys)
t, y = sim.run(t_start=0.0, t_final=5.0)

# 5. Plot Results
# Extract global output indices of the blocks
ref_idx = sys.blocks_spec[ref].output_index[0]
plant_idx = sys.blocks_spec[plant].output_index[0]

plt.plot(t, y[ref_idx, :], 'r--', label="Reference")
plt.plot(t, y[plant_idx, :], 'b-', label="Plant State")
plt.xlabel("Time (s)")
plt.ylabel("Value")
plt.legend()
plt.title("Proportional Feedback Loop")
plt.show()
```

---

## Running Tests

We use `pytest` for unit testing:

```bash
uv run pytest
```
