voxcity.simulator.solar¶
Solar Irradiance Simulation Package
Public API exports for the refactored solar simulator. The implementation is decomposed into focused stages: 1) kernels.py - Low-level kernels for visibility/irradiance 2) radiation.py - Physics: convert geometry to irradiance 3) temporal.py - Time-series integration and solar position 4) integration.py- High-level workflows and I/O 5) sky.py - Sky hemisphere discretization methods
Submodules¶
Attributes¶
Functions¶
|
Return 2D transmittance map (0..1, NaN invalid) for direct beam along sun_direction. |
|
Compute solar azimuth and elevation for given times and location using Astral. |
Generate the 145 Tregenza sky patch center directions. |
|
|
Get the Tregenza patch index for a given sun position. |
|
Numba-accelerated version of get_tregenza_patch_index. |
Generate Reinhart sky patches (subdivided Tregenza). |
|
|
Generate uniform grid sky patches. |
|
Generate quasi-uniform sky patches using Fibonacci spiral. |
|
Bin hourly sun positions into sky patches and aggregate DNI. |
|
Numba-accelerated binning of sun positions to Tregenza patches. |
|
Get information about a sky discretization method. |
|
Visualize sky patches on a polar plot. |
|
Compute horizontal direct irradiance map (W/m²) with tree transmittance. |
|
Compute diffuse horizontal irradiance map (W/m²) using SVF. |
|
Combine direct and diffuse horizontal irradiance (W/m²). |
|
Numba kernel: compute per-face direct/diffuse/global (W/m²) using generic ray tracer. |
|
Compute per-face direct/diffuse/global (W/m²) on a building mesh with SVF. |
|
Integrate global horizontal irradiance over a period using EPW data. |
|
Cumulative Wh/m² on building faces over a period from weather dataframe. |
|
Compute global irradiance from EPW, either instantaneous or cumulative. |
|
Compute building-surface irradiance using EPW (instantaneous or cumulative). |
|
Persist irradiance mesh to pickle file. |
|
Load irradiance mesh from pickle file. |
Package Contents¶
- voxcity.simulator.solar.compute_direct_solar_irradiance_map_binary(voxel_data, sun_direction, view_point_height, hit_values, meshsize, tree_k, tree_lad, inclusion_mode)[source]¶
Return 2D transmittance map (0..1, NaN invalid) for direct beam along sun_direction.
- voxcity.simulator.solar.get_solar_positions_astral(times, lon, lat)[source]¶
Compute solar azimuth and elevation for given times and location using Astral. Returns a DataFrame indexed by times with columns [‘azimuth’, ‘elevation’] (degrees).
- voxcity.simulator.solar.generate_tregenza_patches()[source]¶
Generate the 145 Tregenza sky patch center directions.
The Tregenza subdivision divides the sky hemisphere into 145 patches arranged in 8 altitude bands. This is the standard sky discretization used in Radiance (genskyvec), EnergyPlus, DAYSIM, and Ladybug Tools.
- Returns:
patches (np.ndarray, shape (145, 2)) – Array of (azimuth_degrees, elevation_degrees) for each patch center.
directions (np.ndarray, shape (145, 3)) – Unit direction vectors (dx, dy, dz) pointing to each patch center.
solid_angles (np.ndarray, shape (145,)) – Solid angle (steradians) of each patch.
References
Tregenza, P.R. (1987). “Subdivision of the sky hemisphere for luminance measurements.” Lighting Research & Technology, 19(1), 13-14.
- voxcity.simulator.solar.get_tregenza_patch_index(azimuth_deg, elevation_deg)[source]¶
Get the Tregenza patch index for a given sun position.
- Parameters:
azimuth_deg (float) – Solar azimuth in degrees (0-360, measured clockwise from north).
elevation_deg (float) – Solar elevation in degrees (0-90).
- Returns:
Patch index (0-144), or -1 if below horizon.
- Return type:
int
- voxcity.simulator.solar.get_tregenza_patch_index_fast(azimuth_deg, elevation_deg)[source]¶
Numba-accelerated version of get_tregenza_patch_index.
- Parameters:
azimuth_deg (float) – Solar azimuth in degrees (0-360).
elevation_deg (float) – Solar elevation in degrees (0-90).
- Returns:
Patch index (0-144), or -1 if below horizon.
- Return type:
int
- voxcity.simulator.solar.TREGENZA_BANDS = [(6.0, 30), (18.0, 30), (30.0, 24), (42.0, 24), (54.0, 18), (66.0, 12), (78.0, 6), (90.0, 1)]¶
- voxcity.simulator.solar.TREGENZA_BAND_BOUNDARIES = [0.0, 12.0, 24.0, 36.0, 48.0, 60.0, 72.0, 84.0, 90.0]¶
- voxcity.simulator.solar.generate_reinhart_patches(mf=4)[source]¶
Generate Reinhart sky patches (subdivided Tregenza).
The Reinhart subdivision increases resolution by subdividing each Tregenza patch by a multiplication factor (MF). With MF=4, this yields 2305 patches.
- Parameters:
mf (int) – Multiplication factor. Common values: - MF=1: 145 patches (same as Tregenza) - MF=2: 577 patches - MF=4: 2305 patches (common for annual daylight simulation) - MF=6: 5185 patches
- Returns:
patches (np.ndarray, shape (N, 2)) – Array of (azimuth_degrees, elevation_degrees) for each patch center.
directions (np.ndarray, shape (N, 3)) – Unit direction vectors (dx, dy, dz) for each patch center.
solid_angles (np.ndarray, shape (N,)) – Solid angle (steradians) of each patch.
References
Reinhart, C.F. & Walkenhorst, O. (2001). “Validation of dynamic RADIANCE-based daylight simulations for a test office with external blinds.” Energy and Buildings, 33(7), 683-697.
- voxcity.simulator.solar.generate_uniform_grid_patches(n_azimuth=36, n_elevation=9)[source]¶
Generate uniform grid sky patches.
Simple subdivision with equal azimuth and elevation spacing. Note: This creates non-equal solid angle patches (smaller near zenith).
- Parameters:
n_azimuth (int) – Number of azimuth divisions (default: 36 = 10° spacing).
n_elevation (int) – Number of elevation divisions (default: 9 = 10° spacing).
- Returns:
patches (np.ndarray, shape (N, 2)) – Array of (azimuth_degrees, elevation_degrees) for each patch center.
directions (np.ndarray, shape (N, 3)) – Unit direction vectors for each patch center.
solid_angles (np.ndarray, shape (N,)) – Solid angle (steradians) of each patch.
- voxcity.simulator.solar.generate_fibonacci_patches(n_patches=145)[source]¶
Generate quasi-uniform sky patches using Fibonacci spiral.
Uses the golden angle spiral to distribute points nearly uniformly on the hemisphere. This provides more uniform patch areas than regular grids with fewer total patches.
- Parameters:
n_patches (int) – Number of patches to generate (default: 145 to match Tregenza).
- Returns:
patches (np.ndarray, shape (N, 2)) – Array of (azimuth_degrees, elevation_degrees) for each patch center.
directions (np.ndarray, shape (N, 3)) – Unit direction vectors for each patch center.
solid_angles (np.ndarray, shape (N,)) – Approximate solid angle per patch (uniform for Fibonacci).
- voxcity.simulator.solar.bin_sun_positions_to_patches(azimuth_arr, elevation_arr, dni_arr, method='tregenza', **kwargs)[source]¶
Bin hourly sun positions into sky patches and aggregate DNI.
This is the key optimization for cumulative solar irradiance: instead of tracing rays for every hourly sun position, aggregate DNI values for each sky patch and trace rays once per patch.
- Parameters:
azimuth_arr (np.ndarray) – Array of solar azimuth values in degrees.
elevation_arr (np.ndarray) – Array of solar elevation values in degrees.
dni_arr (np.ndarray) – Array of Direct Normal Irradiance values (W/m²).
method (str) – Sky discretization method: “tregenza”, “reinhart”, “uniform”, “fibonacci”.
**kwargs (dict) – Additional parameters for patch generation (e.g., mf for Reinhart).
- Returns:
patch_directions (np.ndarray, shape (N, 3)) – Unit direction vectors for each patch.
patch_cumulative_dni (np.ndarray, shape (N,)) – Cumulative DNI (W·h/m²) for each patch.
patch_solid_angles (np.ndarray, shape (N,)) – Solid angle of each patch.
patch_hours (np.ndarray, shape (N,)) – Number of hours with sun in each patch.
- voxcity.simulator.solar.bin_sun_positions_to_tregenza_fast(azimuth_arr, elevation_arr, dni_arr)[source]¶
Numba-accelerated binning of sun positions to Tregenza patches.
- Parameters:
azimuth_arr (np.ndarray) – Array of solar azimuth values in degrees.
elevation_arr (np.ndarray) – Array of solar elevation values in degrees.
dni_arr (np.ndarray) – Array of Direct Normal Irradiance values (W/m²).
- Returns:
cumulative_dni (np.ndarray, shape (145,)) – Cumulative DNI (W·h/m²) for each Tregenza patch.
hours_count (np.ndarray, shape (145,)) – Number of hours with sun in each patch.
- voxcity.simulator.solar.get_patch_info(method='tregenza', **kwargs)[source]¶
Get information about a sky discretization method.
- Parameters:
method (str) – Sky discretization method.
**kwargs (dict) – Additional parameters for the method.
- Returns:
Dictionary with patch count, method name, and parameters.
- Return type:
dict
- voxcity.simulator.solar.visualize_sky_patches(method='tregenza', ax=None, show=True, **kwargs)[source]¶
Visualize sky patches on a polar plot.
- Parameters:
method (str) – Sky discretization method.
ax (matplotlib axis, optional) – Existing polar axis to plot on.
show (bool) – Whether to call plt.show().
**kwargs (dict) – Additional parameters for patch generation.
- Returns:
ax – The plot axis.
- Return type:
matplotlib axis
- voxcity.simulator.solar.get_direct_solar_irradiance_map(voxcity: voxcity.models.VoxCity, azimuth_degrees_ori, elevation_degrees, direct_normal_irradiance, show_plot=False, **kwargs)[source]¶
Compute horizontal direct irradiance map (W/m²) with tree transmittance.
- voxcity.simulator.solar.get_diffuse_solar_irradiance_map(voxcity: voxcity.models.VoxCity, diffuse_irradiance=1.0, show_plot=False, **kwargs)[source]¶
Compute diffuse horizontal irradiance map (W/m²) using SVF.
- voxcity.simulator.solar.get_global_solar_irradiance_map(voxcity: voxcity.models.VoxCity, azimuth_degrees_ori, elevation_degrees, direct_normal_irradiance, diffuse_irradiance, show_plot=False, **kwargs)[source]¶
Combine direct and diffuse horizontal irradiance (W/m²).
- voxcity.simulator.solar.compute_solar_irradiance_for_all_faces(face_centers, face_normals, face_svf, sun_direction, direct_normal_irradiance, diffuse_irradiance, voxel_data, meshsize, tree_k, tree_lad, hit_values, inclusion_mode, grid_bounds_real, boundary_epsilon)[source]¶
Numba kernel: compute per-face direct/diffuse/global (W/m²) using generic ray tracer.
- voxcity.simulator.solar.get_building_solar_irradiance(voxcity: voxcity.models.VoxCity, building_svf_mesh, azimuth_degrees, elevation_degrees, direct_normal_irradiance, diffuse_irradiance, **kwargs)[source]¶
Compute per-face direct/diffuse/global (W/m²) on a building mesh with SVF.
- voxcity.simulator.solar.get_cumulative_global_solar_irradiance(voxcity: voxcity.models.VoxCity, df, lon, lat, tz, direct_normal_irradiance_scaling=1.0, diffuse_irradiance_scaling=1.0, **kwargs)[source]¶
Integrate global horizontal irradiance over a period using EPW data. Returns W/m²·hour accumulation on the ground plane.
- Parameters:
voxcity (VoxCity) – The VoxCity model.
df (pd.DataFrame) – Weather data with ‘DNI’ and ‘DHI’ columns.
lon (float) – Longitude and latitude for solar position calculation.
lat (float) – Longitude and latitude for solar position calculation.
tz (float) – Timezone offset in hours.
direct_normal_irradiance_scaling (float) – Scaling factor for DNI.
diffuse_irradiance_scaling (float) – Scaling factor for DHI.
**kwargs (dict) –
Additional options: - use_sky_patches : bool (default False)
If True, use sky patch aggregation for efficiency. DNI is aggregated into sky patches and ray tracing is done once per patch instead of per timestep.
- sky_discretizationstr (default “tregenza”)
Sky discretization method: “tregenza”, “reinhart”, “uniform”, “fibonacci”
- reinhart_mfint (default 4)
Multiplication factor for Reinhart subdivision.
- sky_n_patchesint (default 145)
Number of patches for Fibonacci method.
- progress_reportbool
Print progress information.
- Returns:
Cumulative global solar irradiance map (Wh/m²).
- Return type:
np.ndarray
- voxcity.simulator.solar.get_cumulative_building_solar_irradiance(voxcity: voxcity.models.VoxCity, building_svf_mesh, weather_df, lon, lat, tz, **kwargs)[source]¶
Cumulative Wh/m² on building faces over a period from weather dataframe.
- Parameters:
voxcity (VoxCity) – The VoxCity model.
building_svf_mesh (trimesh.Trimesh) – Building mesh with SVF in metadata.
weather_df (pd.DataFrame) – Weather data with ‘DNI’ and ‘DHI’ columns.
lon (float) – Longitude and latitude.
lat (float) – Longitude and latitude.
tz (float) – Timezone offset in hours.
**kwargs (dict) –
Additional options: - use_sky_patches : bool (default False)
If True, use sky patch aggregation for efficiency. Reduces computation from N timesteps to M patches (M << N).
- sky_discretizationstr (default “tregenza”)
Method: “tregenza”, “reinhart”, “uniform”, “fibonacci”
- reinhart_mfint (default 4)
Multiplication factor for Reinhart subdivision.
- fast_pathbool (default True)
Use optimized Numba kernels.
- progress_reportbool
Print progress information.
- Returns:
Mesh with cumulative irradiance in metadata (direct, diffuse, global in Wh/m²).
- Return type:
trimesh.Trimesh
- voxcity.simulator.solar.get_global_solar_irradiance_using_epw(voxcity: voxcity.models.VoxCity, calc_type: str = 'instantaneous', direct_normal_irradiance_scaling: float = 1.0, diffuse_irradiance_scaling: float = 1.0, **kwargs)[source]¶
Compute global irradiance from EPW, either instantaneous or cumulative.
- voxcity.simulator.solar.get_building_global_solar_irradiance_using_epw(*args, **kwargs)[source]¶
Compute building-surface irradiance using EPW (instantaneous or cumulative).