Source code for voxcity.simulator.solar.kernels

"""
Numba kernels and low-level computation utilities for solar simulation.
"""

from numba import njit, prange
import numpy as np
from ..common.raytracing import trace_ray_generic


[docs] @njit(parallel=True) def compute_direct_solar_irradiance_map_binary( voxel_data, sun_direction, view_point_height, hit_values, meshsize, tree_k, tree_lad, inclusion_mode, ): """ Return 2D transmittance map (0..1, NaN invalid) for direct beam along sun_direction. """ view_height_voxel = int(view_point_height / meshsize) nx, ny, nz = voxel_data.shape irradiance_map = np.full((nx, ny), np.nan, dtype=np.float64) sd = np.array(sun_direction, dtype=np.float64) sd_len = np.sqrt(sd[0] ** 2 + sd[1] ** 2 + sd[2] ** 2) if sd_len == 0.0: return irradiance_map sd /= sd_len for x in prange(nx): for y in range(ny): found_observer = False for z in range(1, nz): if voxel_data[x, y, z] in (0, -2) and voxel_data[x, y, z - 1] not in (0, -2): if (voxel_data[x, y, z - 1] in (7, 8, 9)) or (voxel_data[x, y, z - 1] < 0): irradiance_map[x, y] = np.nan found_observer = True break else: observer_location = np.array([x, y, z + view_height_voxel], dtype=np.float64) hit, transmittance = trace_ray_generic( voxel_data, observer_location, sd, hit_values, meshsize, tree_k, tree_lad, inclusion_mode, ) irradiance_map[x, y] = transmittance if not hit else 0.0 found_observer = True break if not found_observer: irradiance_map[x, y] = np.nan return irradiance_map