Quick Start

Build your first scene and run a simulation with WiTwin Channel

Overview#

Every WiTwin Channel workflow follows the same pattern:

  1. Build a Scene with geometry, materials, transmitters, and receivers
  2. Pick a solver and configure it
  3. Call solve() and read the result

Your First Simulation#

The example below places a concrete wall between a transmitter and a receiver grid, then computes a 32×32 coverage map using the deterministic solver.

import numpy as np
import witwin.channel as wc
 
scene = wc.Scene(
    structures=[
        wc.Structure(
            name="wall",
            geometry=wc.Box(
                position=(0.0, 0.0, 1.5),
                size=(0.25, 4.0, 3.0),
                device="cuda",
            ),
            material=wc.Material(eps_r=4.0, sigma_e=0.0),
        ),
    ],
    transmitters=[
        wc.Transmitter("tx", (-2.0, 0.0, 1.5)),
    ],
    receivers=[
        wc.ReceiverGrid(
            "rm",
            axis="z",
            position=1.5,
            bounds=((-3.0, 3.0), (-3.0, 3.0)),
            grid_shape=(32, 32),
        ),
    ],
    frequency=3.5e9,
    device="cuda",
)
 
result = wc.deterministic.solve(
    scene=scene,
    transmitter="tx",
    receiver="rm",
    config=wc.deterministic.Config(
        num_samples=256,
        max_bounces=1,
        max_diffraction_order=0,
        edge_policy=wc.EdgePolicy(edge_selection_mode="all_edges"),
    ),
)
 
path_gain = np.asarray(result.path_gain, dtype=np.float32)
print(path_gain.shape, float(path_gain.max()))

What Just Happened#

  • Scene holds all geometry, materials, and endpoints
  • wc.Structure pairs a Box shape with a Material
  • wc.Transmitter places a radio source at a position
  • wc.ReceiverGrid defines a 2D measurement grid at height z=1.5
  • wc.deterministic.solve() runs the simulation and returns a RadioMapResult
  • result.path_gain contains the signal strength at every grid point

Choosing a Solver#

Note

Not sure which solver to use? Start with deterministic — it is the fastest and most predictable. Switch to montecarlo for more complex environments or path when you need per-path CIR/CFR data.

SolverUse when
deterministicYou need a fast, repeatable coverage map
montecarloYou need sampling-based integration over complex scenes
pathYou need discrete paths, CIR, CFR, or per-path channel data

Path Solver Result#

When using the path solver, the returned PathResult gives you access to:

  • .cir() — channel impulse response, returns (coefficients, delays)
  • .cfr(frequencies) — channel frequency response over a set of subcarrier frequencies
  • .taps(bandwidth, num_taps) — discrete channel taps at a given bandwidth
  • .filter_by_type(*interaction_types) — filter paths by interaction type (REFLECTION, DIFFRACTION, TRANSMISSION, SCATTERING)

Next Steps#

  • Scene API — learn what goes inside a Scene
  • Solvers — full solver configuration reference
  • Tutorials — end-to-end worked examples