Design Principles

The core design philosophy behind WiTwin Channel

The Public Contract#

Every WiTwin Channel workflow is built around one stable pattern:

scene = wc.Scene(...)
result = wc.deterministic.solve(scene=scene, transmitter="tx", receiver="rm", config=config)

The full contract is Scene + solver.solve(scene, config) + Result. There is no shared tracer object. Solvers are independent entry points.

Package Layering#

The package is organized in strict layers. Each layer may only depend on the layer below it:

witwin.channel.core          # shared numerics, geometry, physics, runtime, results
witwin.channel.core.scene    # declarative Scene, endpoints, arrays, edge policy
witwin.channel.deterministic # deterministic radiomap solver
witwin.channel.montecarlo    # Monte Carlo radiomap solver
witwin.channel.path          # path-level solver

Note

Solver packages must not import from each other. Any behavior shared across solvers belongs in witwin.channel.core.

Scene Owns the State#

Scene is the single source of truth for all simulation state:

  • Geometry and materials via Structure objects
  • Transmitters and receivers by name
  • Frequency, device, and antenna array settings

Solver Config objects describe only algorithm controls — sample budgets, bounce limits, diffraction order, edge policy, and integrator settings. They do not own scene state.

Differentiability First#

WiTwin Channel is designed for gradient-based workflows. Geometric differentiability flows through scene geometry, material parameters, endpoints, and solver outputs. This enables:

  • Inverse rendering — infer scene properties from signal measurements
  • Optimization — tune antenna placement, material parameters, or geometry
  • RF digital twin workflows — fit a scene model to real-world measurements

Shared Results#

All radiomap solvers return a shared RadioMapResult from witwin.channel.core. This contains:

  • path_gain — signal strength at every grid point
  • rss — received signal strength
  • sinr — signal-to-interference-plus-noise ratio
  • RadioMapCoordinates — grid coordinates and transmitter-axis helpers
  • RadioMapFieldPayload and RadioMapPowerPayload — field and power components

The path solver returns a separate PathResult with per-path coefficients, delays, angles of departure and arrival, interaction types, and torch-backed .cir(), .cfr(), and .taps() helpers.