voxcity.simulator_gpu.solar.radiation.RadiationModel

class voxcity.simulator_gpu.solar.radiation.RadiationModel(domain: voxcity.simulator_gpu.solar.domain.Domain, config: RadiationConfig | None = None)

GPU-accelerated solar radiation transfer model.

Computes shortwave (direct and diffuse) radiation for all surface elements in the domain.

domain
config
surfaces
n_surfaces
solar_calc
ray_tracer
svf_calc
csf_calc
volumetric_calc = None
compute_svf()

Compute Sky View Factors for all surfaces.

This is computationally expensive, call once per domain setup.

update_solar_position(day_of_year: int, second_of_day: float)

Update solar position.

Parameters:
  • day_of_year – Day number (1-365)

  • second_of_day – Seconds since midnight UTC

compute_shortwave_radiation(sw_direct: float, sw_diffuse: float)

Compute shortwave (solar) radiation for all surfaces.

Parameters:
  • sw_direct – Direct normal irradiance (W/m²)

  • sw_diffuse – Diffuse horizontal irradiance (W/m²)

compute_svf_matrix()

Pre-compute surface-to-surface view factor matrix (PALM-like approach).

This is expensive O(n²) but only needs to be done once for fixed geometry. Subsequent reflection iterations become O(nnz) instead of O(n²).

Call this before running multi-timestep simulations for efficiency.

compute_csf_matrix()

Pre-compute Canopy-Surface Factor matrix.

Stores geometric factors for Surface <-> Canopy interactions. This allows O(nnz) computation for canopy absorption and scattering instead of O(N_cells * N_surfaces).

invalidate_svf_cache()

Invalidate the cached SVF matrix.

Call this if geometry (buildings, terrain, vegetation) changes. The matrix will be recomputed on the next compute_svf() call.

property svf_matrix_cached: bool

Check if SVF matrix is currently cached.

property svf_matrix_entries: int

Get number of non-zero entries in cached SVF matrix.

compute_radiation(day_of_year: int, second_of_day: float, sw_direct: float, sw_diffuse: float)

Compute shortwave radiation components.

Parameters:
  • day_of_year – Day number (1-365)

  • second_of_day – Seconds since midnight UTC

  • sw_direct – Direct normal irradiance (W/m²)

  • sw_diffuse – Diffuse horizontal irradiance (W/m²)

get_surface_fluxes() dict

Get radiation fluxes as numpy arrays.

Returns:

  • position: Grid indices (i, j, k)

  • direction: Surface direction index

  • area: Surface area (m²)

  • svf: Sky view factor

  • shadow_factor: Shadow factor (0=sunlit, 1=shaded)

  • sw_in_direct: Direct SW radiation (W/m²)

  • sw_in_diffuse: Diffuse SW radiation including reflections (W/m²)

  • sw_out: Outgoing (reflected) SW radiation (W/m²)

  • sw_in_total: Total incoming SW (W/m²)

  • sw_net: Net absorbed SW (W/m²)

Return type:

Dictionary with flux arrays including

get_total_absorbed_sw() float

Get total absorbed shortwave radiation (W).

get_domain_shadow_map() numpy.ndarray

Get 2D shadow map at ground/terrain level.

Only includes ground surfaces (k=0), not building rooftops. Building footprints are marked with NaN.

Returns:

2D array of shadow factors (0=shadowed, 1=sunlit, NaN=building)

get_irradiance_map() numpy.ndarray

Get 2D map of total incoming shortwave irradiance at ground level.

Returns:

2D array of irradiance values (W/m²), NaN for building footprints

get_net_sw_radiation_map() numpy.ndarray

Get 2D map of net shortwave radiation at ground level.

Returns:

2D array of net SW radiation values (W/m²), NaN for building footprints

compute_volumetric_svf()

Compute volumetric sky view factors.

This must be called before computing volumetric SW fluxes. Only needed once unless domain geometry changes.

Raises:

RuntimeError – If volumetric_flux is not enabled in config

get_volumetric_skyvf() numpy.ndarray

Get volumetric sky view factor as 3D numpy array.

Returns:

3D array of shape (nx, ny, nz) with SVF values [0, 1]

Raises:

RuntimeError – If volumetric_flux is not enabled

get_volumetric_swflux() numpy.ndarray

Get volumetric shortwave flux as 3D numpy array.

This is the omnidirectional SW flux at each grid cell, representing average irradiance onto an imaginary sphere (W/m²).

Returns:

3D array of shape (nx, ny, nz) with SW flux values

Raises:

RuntimeError – If volumetric_flux is not enabled

get_volumetric_shadow_top() numpy.ndarray

Get shadow top level as 2D numpy array.

Shadow top is the highest grid level that is in shadow for the current solar position.

Returns:

2D array of shape (nx, ny) with vertical indices

Raises:

RuntimeError – If volumetric_flux is not enabled

get_volumetric_shadow_mask() numpy.ndarray

Get 3D shadow mask.

Returns:

3D boolean array where True indicates shadowed cells

Raises:

RuntimeError – If volumetric_flux is not enabled

get_volumetric_swflux_slice(level: int | None = None, axis: str | None = None, index: int | None = None) numpy.ndarray

Get a 2D slice of volumetric SW flux.

Parameters:
  • level – Vertical level for horizontal slice (k index)

  • axis – ‘x’ or ‘y’ for vertical slices

  • index – Index along the axis for vertical slices

Returns:

2D array of SW flux values (W/m²)

Raises:
  • RuntimeError – If volumetric_flux is not enabled

  • ValueError – If invalid slice parameters

get_canopy_absorbed_sw() numpy.ndarray

Get total absorbed SW radiation in plant canopy.

Returns:

3D array of absorbed SW radiation (W/m³)

get_canopy_absorbed_sw_direct() numpy.ndarray

Get direct SW radiation absorbed in plant canopy.

Returns:

3D array of absorbed direct SW radiation (W/m³)

get_canopy_absorbed_sw_diffuse() numpy.ndarray

Get diffuse SW radiation absorbed in plant canopy.

Returns:

3D array of absorbed diffuse SW radiation (W/m³)

get_canopy_received_sw() numpy.ndarray

Get total received SW radiation at plant canopy (before absorption).

Returns:

3D array of received SW radiation (W/m²)

get_total_canopy_absorption() float

Get total SW radiation absorbed by all plant canopy (W).

Returns:

Total absorbed power in Watts

get_canopy_absorption_profile() numpy.ndarray

Get vertical profile of canopy-averaged SW absorption.

Returns:

1D array of mean absorbed SW per level (W/m³)

get_canopy_scattered_sw() numpy.ndarray

Get scattered (reflected) SW radiation from canopy cells.

Returns:

3D array of scattered SW flux (W/m³) indexed by (i, j, k)

get_canopy_to_canopy_sw() numpy.ndarray

Get SW radiation received from other canopy cells (canopy-to-canopy scattering).

This is radiation scattered by one canopy cell and absorbed by another. Only non-zero if canopy_to_canopy=True in config.

Returns:

3D array of canopy-to-canopy SW flux (W/m³) indexed by (i, j, k)

get_surface_sw_from_canopy() numpy.ndarray

Get SW radiation received by surfaces from canopy scattering.

Returns:

1D array of SW from canopy (W/m²) per surface element