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 solverNote
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
Structureobjects - 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 pointrss— received signal strengthsinr— signal-to-interference-plus-noise ratioRadioMapCoordinates— grid coordinates and transmitter-axis helpersRadioMapFieldPayloadandRadioMapPowerPayload— 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.