voxcity.simulator_gpu.solar.volumetric.VolumetricFluxCalculator

class voxcity.simulator_gpu.solar.volumetric.VolumetricFluxCalculator(domain, n_azimuth: int = 36, min_opaque_lad: float = 0.5, periodic_xy: bool = False)

GPU-accelerated volumetric radiative flux calculator.

Computes 3D radiation fields throughout the domain volume, not just at surface elements. This is useful for: - Mean Radiant Temperature (MRT) calculations - Photolysis rate estimation - Plant canopy light availability - Pedestrian thermal comfort

Modes: - DIRECT_DIFFUSE: Only direct solar + diffuse sky radiation (faster) - WITH_REFLECTIONS: Includes reflected radiation from buildings/ground/trees

domain
nx
ny
nz
dx
dy
dz
n_azimuth = 36
min_opaque_lad = 0.5
periodic_xy = 1
mode
max_dist
skyvf_vol
swflux_vol
swflux_reflected_vol
swflux_direct_vol
swflux_diffuse_vol
opaque_top
shadow_top
azim_dir_x
azim_dir_y
compute_opaque_top()

Compute opaque top levels considering buildings and vegetation.

compute_skyvf_vol(n_zenith: int = 9)

Compute volumetric sky view factors for all grid cells.

This is computationally expensive - call once per domain setup or when geometry changes.

Parameters:

n_zenith – Number of zenith angle divisions for hemisphere integration. Higher values give more accurate results but slower computation. Default 9 gives ~10° resolution.

compute_shadow_top(sun_direction: Tuple[float, float, float])

Compute shadow top for a given solar direction.

Parameters:

sun_direction – Unit vector pointing toward sun (x, y, z)

compute_swflux_vol(sw_direct: float, sw_diffuse: float, cos_zenith: float, sun_direction: Tuple[float, float, float], lad: taichi.template | None = None)

Compute volumetric shortwave flux for all grid cells.

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

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

  • cos_zenith – Cosine of solar zenith angle

  • sun_direction – Unit vector toward sun (x, y, z)

  • lad – Optional LAD field for canopy attenuation

get_skyvf_vol() numpy.ndarray

Get volumetric sky view factor as numpy array.

get_swflux_vol() numpy.ndarray

Get volumetric SW flux as numpy array (W/m²).

get_shadow_top() numpy.ndarray

Get shadow top indices as numpy array.

get_opaque_top() numpy.ndarray

Get opaque top indices as numpy array.

get_shadow_mask_3d() numpy.ndarray

Get 3D shadow mask (1=shadowed, 0=sunlit).

Returns:

3D boolean array where True indicates shadowed cells

get_horizontal_slice(k: int, field: str = 'swflux') numpy.ndarray

Get horizontal slice of a volumetric field.

Parameters:
  • k – Vertical level index

  • field – ‘swflux’ or ‘skyvf’

Returns:

2D array at level k

get_vertical_slice(axis: str, index: int, field: str = 'swflux') numpy.ndarray

Get vertical slice of a volumetric field.

Parameters:
  • axis – ‘x’ or ‘y’

  • index – Index along the axis

  • field – ‘swflux’ or ‘skyvf’

Returns:

2D array (horizontal_coord, z)

set_mode(mode: VolumetricFluxMode | str)

Set the volumetric flux computation mode.

Parameters:

mode – Either a VolumetricFluxMode enum or string: ‘direct_diffuse’ - Only direct + diffuse sky radiation ‘with_reflections’ - Include reflected radiation from surfaces

compute_reflected_flux_vol(surfaces, surf_outgoing: numpy.ndarray)

Compute volumetric reflected flux from surface outgoing radiation.

This propagates reflected radiation from surfaces into the 3D volume. Should be called after surface reflection calculations are complete.

NOTE: This is O(N_cells * N_surfaces) and can be slow for large domains. For repeated calls, use compute_c2s_matrix() once followed by compute_reflected_flux_vol_cached() for O(nnz) computation.

Parameters:
  • surfaces – Surfaces object with geometry (center, normal, area)

  • surf_outgoing – Array of surface outgoing radiation (W/m²) Shape: (n_surfaces,)

compute_reflected_flux_terrain_following(surfaces, surf_outgoing: numpy.ndarray)

Compute reflected flux only at terrain-following extraction level.

This is ~61x faster than compute_reflected_flux_vol() because it only computes for O(nx*ny) cells instead of O(nx*ny*nz) cells.

Requires init_cumulative_accumulation() to be called first.

Parameters:
  • surfaces – Surfaces object with geometry (center, normal, area)

  • surf_outgoing – Array of surface outgoing radiation (W/m²)

compute_swflux_vol_with_reflections(sw_direct: float, sw_diffuse: float, cos_zenith: float, sun_direction: Tuple[float, float, float], surfaces, surf_outgoing: numpy.ndarray, lad: taichi.template | None = None)

Compute volumetric shortwave flux including reflected radiation.

This is a convenience method that combines direct/diffuse computation with reflected radiation from surfaces.

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

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

  • cos_zenith – Cosine of solar zenith angle

  • sun_direction – Unit vector toward sun (x, y, z)

  • surfaces – Surfaces object with geometry

  • surf_outgoing – Surface outgoing radiation array (W/m²)

  • lad – Optional LAD field for canopy attenuation

get_swflux_reflected_vol() numpy.ndarray

Get volumetric reflected SW flux as numpy array (W/m²).

get_swflux_direct_vol() numpy.ndarray

Get volumetric direct SW flux as numpy array (W/m²).

get_swflux_diffuse_vol() numpy.ndarray

Get volumetric diffuse SW flux as numpy array (W/m²).

get_flux_components() dict

Get all volumetric flux components as a dictionary.

Returns:

  • ‘total’: Total SW flux (direct + diffuse + reflected if enabled)

  • ’direct’: Direct solar component

  • ’diffuse’: Diffuse sky component

  • ’reflected’: Reflected from surfaces (if computed)

  • ’skyvf’: Sky view factor

Return type:

Dictionary with keys

compute_c2s_matrix(surfaces, is_solid, lad=None, min_vf_threshold: float = 1e-06, progress_report: bool = False)

Pre-compute Cell-to-Surface View Factor matrix for fast reflections.

This is O(N_cells * N_surfaces) but only needs to be done once for fixed geometry. Subsequent calls to compute_reflected_flux_vol_cached() become O(nnz) instead of O(N*M).

Call this before running multi-timestep simulations with reflections.

Parameters:
  • surfaces – Surfaces object with center, normal, area fields

  • is_solid – 3D solid obstacle field

  • lad – Optional LAD field for vegetation attenuation

  • min_vf_threshold – Minimum view factor to store (sparsity threshold)

  • progress_report – Print progress messages

compute_reflected_flux_vol_cached(surf_outgoing: numpy.ndarray, progress_report: bool = False)

Compute volumetric reflected flux using cached C2S-VF matrix.

This is O(nnz) instead of O(N_cells * N_surfaces), providing massive speedup for repeated calls with different surface radiation.

Must call compute_c2s_matrix() first.

Parameters:
  • surf_outgoing – Array of surface outgoing radiation (W/m²)

  • progress_report – Print progress messages

invalidate_c2s_cache()

Invalidate the cached C2S-VF matrix.

Call this if geometry (buildings, terrain, vegetation) changes.

property c2s_matrix_cached: bool

Check if C2S-VF matrix is currently cached.

property c2s_matrix_entries: int

Get number of non-zero entries in cached C2S-VF matrix.

compute_swflux_vol_with_reflections_cached(sw_direct: float, sw_diffuse: float, cos_zenith: float, sun_direction: Tuple[float, float, float], surf_outgoing: numpy.ndarray, lad=None)

Compute volumetric shortwave flux with reflections using cached matrix.

This is the fast path for multi-timestep simulations. Must call compute_c2s_matrix() once before using this method.

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

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

  • cos_zenith – Cosine of solar zenith angle

  • sun_direction – Unit vector toward sun (x, y, z)

  • surf_outgoing – Surface outgoing radiation array (W/m²)

  • lad – Optional LAD field for canopy attenuation

compute_t2s_matrix(surfaces, min_vf_threshold: float = 1e-06, progress_report: bool = False)

Pre-compute Terrain-to-Surface View Factor matrix for fast reflections.

This computes view factors only for cells at the terrain-following extraction height (O(nx*ny) cells), not the full 3D volume.

Requires init_cumulative_accumulation() to be called first to set ground_k and height_offset_k.

Parameters:
  • surfaces – Surfaces object with center, normal, area fields

  • min_vf_threshold – Minimum view factor to store (sparsity threshold)

  • progress_report – Print progress messages

compute_reflected_flux_terrain_cached(surf_outgoing: numpy.ndarray)

Compute reflected flux at terrain-following level using cached T2S matrix.

This is O(nnz) instead of O(N_cells * N_surfaces), providing massive speedup for cumulative simulations with multiple sky patches.

Requires: 1. init_cumulative_accumulation() called first 2. compute_t2s_matrix() called to pre-compute view factors

Parameters:

surf_outgoing – Array of surface outgoing radiation (W/m²)

invalidate_t2s_cache()

Invalidate the cached T2S-VF matrix.

Call this if geometry or volumetric_height changes.

property t2s_matrix_cached: bool

Check if T2S-VF matrix is currently cached.

property t2s_matrix_entries: int

Get number of non-zero entries in cached T2S-VF matrix.

init_cumulative_accumulation(ground_k: numpy.ndarray, height_offset_k: int, is_solid: numpy.ndarray)

Initialize GPU-side cumulative terrain-following accumulation.

Must be called before using accumulate_terrain_following_slice_gpu().

Parameters:
  • ground_k – 2D array (nx, ny) of ground k-levels. -1 means no valid ground.

  • height_offset_k – Number of cells above ground for extraction.

  • is_solid – 3D array (nx, ny, nz) of solid flags.

accumulate_terrain_following_slice_gpu(weight: float = 1.0)

Accumulate current swflux_vol terrain-following slice to cumulative map on GPU.

This is the fast path for cumulative simulations. Must call init_cumulative_accumulation() first.

Parameters:

weight – Multiplier for values (e.g., time_step_hours for Wh conversion).

accumulate_svf_diffuse_gpu(total_dhi: float)

Accumulate diffuse contribution using SVF field directly on GPU.

Parameters:

total_dhi – Total cumulative diffuse horizontal irradiance (Wh/m²).

get_cumulative_map() numpy.ndarray

Get the accumulated terrain-following cumulative map.

Returns:

2D numpy array (nx, ny) of cumulative irradiance values.

finalize_cumulative_map(apply_nan_mask: bool = True) numpy.ndarray

Get final cumulative map with optional NaN masking for invalid cells.

Parameters:

apply_nan_mask – If True, set cells with no valid ground or inside solid to NaN.

Returns:

2D numpy array (nx, ny) of cumulative irradiance values.

reset_cumulative_accumulation()

Reset the cumulative map to zero without reinitializing ground_k.