Field Simulation

Compute electric field distributions on a plane using the deterministic solver

Overview#

The solve_field() function computes the full electromagnetic field on an axis-aligned plane. Unlike the radiomap solvers which return signal strength over a grid, solve_field() returns the complex field broken down into components: line-of-sight, reflection, and diffraction.

Basic Example#

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)),
    ],
    frequency=3.5e9,
    device="cuda",
)
 
field_spec = wc.deterministic.FieldSpec(
    axis="z",
    position=1.5,
    bounds=((-5.0, 5.0), (-5.0, 5.0)),
    resolution=0.1,
    ray_sampling="full_sphere",
)
 
result = wc.deterministic.solve_field(
    scene=scene,
    frequency=3.5e9,
    tx_pos=(-2.0, 0.0, 1.5),
    field=field_spec,
    config=wc.deterministic.Config(
        num_samples=512,
        max_bounces=2,
        max_diffraction_order=1,
    ),
)

FieldSpec Parameters#

FieldSpec defines the receiver plane where the field is computed:

ParameterDefaultDescription
axis"z"Normal axis of the measurement plane
position0.0Position along the normal axis
bounds((-8.0, 8.0), (-8.0, 8.0))Extent of the plane in the two tangential directions
grid_shapeNoneFixed grid resolution as (nx, ny)
resolutionNoneGrid resolution in wavelengths. Use instead of grid_shape
ray_sampling"full_sphere"Ray sampling strategy. One of "auto", "circle", "full_sphere", "hemisphere", "hemisphere_facing_monitor"
max_diffractionsNoneOverride max_diffraction_order from Config for this plane

Note

Either grid_shape or resolution must be provided. If both are given, grid_shape takes precedence.

Reading the Result#

FieldResult contains the field broken down by propagation mechanism:

total_field = result.field.total
los = result.field.los
reflection = result.field.reflection
diffraction = result.field.diffraction
total_power = result.total_power
x = result.coords.x
y = result.coords.y

The field attribute is a FieldComponents object with these components:

ComponentDescription
losLine-of-sight field
reflectionReflected field
diffractionTotal diffracted field
diffraction_directDirect diffraction only
diffraction_mixedMixed reflection-diffraction
totalSum of all components

Config Parameters#

solve_field() uses the same Config as the deterministic radiomap solver:

ParameterDefaultDescription
num_samples10000Number of rays
max_bounces2Maximum reflection bounces
max_diffraction_order1Maximum diffraction order
edge_policyNoneEdge selection policy

Next Steps#