voxcity 1.0.2__py3-none-any.whl → 1.0.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. voxcity/downloader/ocean.py +559 -0
  2. voxcity/generator/api.py +6 -0
  3. voxcity/generator/grids.py +45 -32
  4. voxcity/generator/pipeline.py +327 -27
  5. voxcity/geoprocessor/draw.py +14 -8
  6. voxcity/geoprocessor/raster/__init__.py +2 -0
  7. voxcity/geoprocessor/raster/core.py +31 -0
  8. voxcity/geoprocessor/raster/landcover.py +173 -49
  9. voxcity/geoprocessor/raster/raster.py +1 -1
  10. voxcity/models.py +2 -0
  11. voxcity/simulator_gpu/__init__.py +115 -0
  12. voxcity/simulator_gpu/common/__init__.py +9 -0
  13. voxcity/simulator_gpu/common/geometry.py +11 -0
  14. voxcity/simulator_gpu/core.py +322 -0
  15. voxcity/simulator_gpu/domain.py +262 -0
  16. voxcity/simulator_gpu/environment.yml +11 -0
  17. voxcity/simulator_gpu/init_taichi.py +154 -0
  18. voxcity/simulator_gpu/integration.py +15 -0
  19. voxcity/simulator_gpu/kernels.py +56 -0
  20. voxcity/simulator_gpu/radiation.py +28 -0
  21. voxcity/simulator_gpu/raytracing.py +623 -0
  22. voxcity/simulator_gpu/sky.py +9 -0
  23. voxcity/simulator_gpu/solar/__init__.py +178 -0
  24. voxcity/simulator_gpu/solar/core.py +66 -0
  25. voxcity/simulator_gpu/solar/csf.py +1249 -0
  26. voxcity/simulator_gpu/solar/domain.py +561 -0
  27. voxcity/simulator_gpu/solar/epw.py +421 -0
  28. voxcity/simulator_gpu/solar/integration.py +2953 -0
  29. voxcity/simulator_gpu/solar/radiation.py +3019 -0
  30. voxcity/simulator_gpu/solar/raytracing.py +686 -0
  31. voxcity/simulator_gpu/solar/reflection.py +533 -0
  32. voxcity/simulator_gpu/solar/sky.py +907 -0
  33. voxcity/simulator_gpu/solar/solar.py +337 -0
  34. voxcity/simulator_gpu/solar/svf.py +446 -0
  35. voxcity/simulator_gpu/solar/volumetric.py +1151 -0
  36. voxcity/simulator_gpu/solar/voxcity.py +2953 -0
  37. voxcity/simulator_gpu/temporal.py +13 -0
  38. voxcity/simulator_gpu/utils.py +25 -0
  39. voxcity/simulator_gpu/view.py +32 -0
  40. voxcity/simulator_gpu/visibility/__init__.py +109 -0
  41. voxcity/simulator_gpu/visibility/geometry.py +278 -0
  42. voxcity/simulator_gpu/visibility/integration.py +808 -0
  43. voxcity/simulator_gpu/visibility/landmark.py +753 -0
  44. voxcity/simulator_gpu/visibility/view.py +944 -0
  45. voxcity/visualizer/renderer.py +2 -1
  46. {voxcity-1.0.2.dist-info → voxcity-1.0.13.dist-info}/METADATA +16 -53
  47. {voxcity-1.0.2.dist-info → voxcity-1.0.13.dist-info}/RECORD +50 -15
  48. {voxcity-1.0.2.dist-info → voxcity-1.0.13.dist-info}/WHEEL +0 -0
  49. {voxcity-1.0.2.dist-info → voxcity-1.0.13.dist-info}/licenses/AUTHORS.rst +0 -0
  50. {voxcity-1.0.2.dist-info → voxcity-1.0.13.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,154 @@
1
+ """
2
+ Taichi initialization for simulator_gpu.
3
+
4
+ This module provides centralized Taichi initialization to ensure ti.init()
5
+ is called before any Taichi fields or kernels are used.
6
+ """
7
+
8
+ import taichi as ti
9
+ import os
10
+ import warnings
11
+ from typing import Optional
12
+
13
+ # Track initialization state
14
+ _TAICHI_INITIALIZED = False
15
+
16
+
17
+ def init_taichi(
18
+ arch: Optional[str] = None,
19
+ default_fp: type = ti.f32,
20
+ default_ip: type = ti.i32,
21
+ debug: bool = False,
22
+ suppress_fp16_warnings: bool = True,
23
+ **kwargs
24
+ ) -> bool:
25
+ """
26
+ Initialize Taichi runtime if not already initialized.
27
+
28
+ This function is idempotent - calling it multiple times is safe.
29
+ The first call will initialize Taichi, subsequent calls will be no-ops.
30
+
31
+ Args:
32
+ arch: Architecture to use. Options:
33
+ - None (default): Auto-detect best available (GPU preferred)
34
+ - 'gpu': Use GPU (CUDA, Vulkan, Metal, etc.)
35
+ - 'cuda': Use CUDA specifically
36
+ - 'vulkan': Use Vulkan
37
+ - 'metal': Use Metal (macOS)
38
+ - 'cpu': Use CPU
39
+ default_fp: Default floating point type (ti.f32 or ti.f64)
40
+ default_ip: Default integer type (ti.i32 or ti.i64)
41
+ debug: Enable debug mode for better error messages
42
+ suppress_fp16_warnings: Suppress Taichi's fp16 precision loss warnings
43
+ (default: True). These warnings occur when using fp16 intermediate
44
+ buffers for memory bandwidth optimization.
45
+ **kwargs: Additional arguments passed to ti.init()
46
+
47
+ Returns:
48
+ True if initialization was performed, False if already initialized.
49
+ """
50
+ global _TAICHI_INITIALIZED
51
+
52
+ if _TAICHI_INITIALIZED:
53
+ return False
54
+
55
+ # Suppress fp16 precision warnings if requested
56
+ # These occur when assigning f32 values to f16 fields, which is intentional
57
+ # for memory bandwidth optimization in intermediate buffers
58
+ if suppress_fp16_warnings:
59
+ # Filter Taichi's precision loss warnings via Python warnings module
60
+ warnings.filterwarnings(
61
+ 'ignore',
62
+ message='.*Assign a value with precision.*',
63
+ category=UserWarning
64
+ )
65
+ warnings.filterwarnings(
66
+ 'ignore',
67
+ message='.*Atomic add may lose precision.*',
68
+ category=UserWarning
69
+ )
70
+ # Also set Taichi log level to ERROR to suppress warnings from Taichi's internal logging
71
+ # This is needed because Taichi uses its own logging system for some warnings
72
+ if 'log_level' not in kwargs:
73
+ kwargs['log_level'] = ti.ERROR
74
+
75
+ # Determine architecture
76
+ if arch is None:
77
+ # Auto-detect: prefer GPU, fall back to CPU
78
+ ti_arch = ti.gpu
79
+ elif arch == 'gpu':
80
+ ti_arch = ti.gpu
81
+ elif arch == 'cuda':
82
+ ti_arch = ti.cuda
83
+ elif arch == 'vulkan':
84
+ ti_arch = ti.vulkan
85
+ elif arch == 'metal':
86
+ ti_arch = ti.metal
87
+ elif arch == 'cpu':
88
+ ti_arch = ti.cpu
89
+ else:
90
+ raise ValueError(f"Unknown architecture: {arch}")
91
+
92
+ # Check environment variable for override
93
+ env_arch = os.environ.get('TAICHI_ARCH', '').lower()
94
+ if env_arch == 'cpu':
95
+ ti_arch = ti.cpu
96
+ elif env_arch == 'cuda':
97
+ ti_arch = ti.cuda
98
+ elif env_arch == 'vulkan':
99
+ ti_arch = ti.vulkan
100
+ elif env_arch == 'gpu':
101
+ ti_arch = ti.gpu
102
+
103
+ # Initialize Taichi
104
+ ti.init(
105
+ arch=ti_arch,
106
+ default_fp=default_fp,
107
+ default_ip=default_ip,
108
+ debug=debug,
109
+ **kwargs
110
+ )
111
+
112
+ _TAICHI_INITIALIZED = True
113
+ return True
114
+
115
+
116
+ def ensure_initialized():
117
+ """
118
+ Ensure Taichi is initialized with default settings.
119
+
120
+ This is a convenience function for lazy initialization.
121
+ Call this before any Taichi operations if you're not sure
122
+ whether init_taichi() has been called.
123
+ """
124
+ if not _TAICHI_INITIALIZED:
125
+ init_taichi()
126
+
127
+
128
+ def is_initialized() -> bool:
129
+ """Check if Taichi has been initialized."""
130
+ return _TAICHI_INITIALIZED
131
+
132
+
133
+ def reset():
134
+ """
135
+ Reset initialization state.
136
+
137
+ Note: This does NOT reset Taichi itself (which cannot be reset once initialized).
138
+ This only resets the tracking flag for testing purposes.
139
+ """
140
+ global _TAICHI_INITIALIZED
141
+ _TAICHI_INITIALIZED = False
142
+
143
+
144
+ # Convenience: expose ti for direct access
145
+ taichi = ti
146
+
147
+ __all__ = [
148
+ 'init_taichi',
149
+ 'ensure_initialized',
150
+ 'is_initialized',
151
+ 'reset',
152
+ 'taichi',
153
+ 'ti',
154
+ ]
@@ -0,0 +1,15 @@
1
+ """VoxCity-style `integration` module (toplevel) for compatibility."""
2
+
3
+ from .solar.integration import (
4
+ get_global_solar_irradiance_using_epw,
5
+ get_building_global_solar_irradiance_using_epw,
6
+ save_irradiance_mesh,
7
+ load_irradiance_mesh,
8
+ )
9
+
10
+ __all__ = [
11
+ "get_global_solar_irradiance_using_epw",
12
+ "get_building_global_solar_irradiance_using_epw",
13
+ "save_irradiance_mesh",
14
+ "load_irradiance_mesh",
15
+ ]
@@ -0,0 +1,56 @@
1
+ """VoxCity-style `kernels` module (toplevel) for compatibility.
2
+
3
+ Implements a minimal subset of `voxcity.simulator.solar.kernels` so code that
4
+ imports these symbols continues to run when using:
5
+
6
+ import simulator_gpu as simulator
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Tuple
12
+
13
+ import numpy as np
14
+
15
+
16
+ def compute_direct_solar_irradiance_map_binary(
17
+ voxel_data,
18
+ sun_direction,
19
+ view_point_height,
20
+ hit_values,
21
+ meshsize,
22
+ tree_k,
23
+ tree_lad,
24
+ inclusion_mode,
25
+ ):
26
+ """Approximate VoxCity kernel: return direct-beam transmittance map (0..1).
27
+
28
+ Signature matches `voxcity.simulator.solar.kernels.compute_direct_solar_irradiance_map_binary`.
29
+
30
+ Notes:
31
+ - `hit_values` and `inclusion_mode` are accepted for compatibility but
32
+ are not currently used in the GPU path.
33
+ - Output is flipped with `np.flipud`, matching VoxCity.
34
+ """
35
+ from .solar.integration import _compute_direct_transmittance_map_gpu
36
+
37
+ sd = np.array(sun_direction, dtype=np.float64)
38
+ L = float(np.sqrt((sd * sd).sum()))
39
+ if L == 0.0:
40
+ nx, ny = voxel_data.shape[0], voxel_data.shape[1]
41
+ return np.flipud(np.full((nx, ny), np.nan, dtype=np.float64))
42
+ sd /= L
43
+
44
+ trans = _compute_direct_transmittance_map_gpu(
45
+ voxel_data=np.asarray(voxel_data),
46
+ sun_direction=(float(sd[0]), float(sd[1]), float(sd[2])),
47
+ view_point_height=float(view_point_height),
48
+ meshsize=float(meshsize),
49
+ tree_k=float(tree_k),
50
+ tree_lad=float(tree_lad),
51
+ )
52
+
53
+ return np.flipud(trans)
54
+
55
+
56
+ __all__ = ["compute_direct_solar_irradiance_map_binary"]
@@ -0,0 +1,28 @@
1
+ """VoxCity-style `radiation` module (toplevel) for compatibility."""
2
+
3
+ from .solar.integration import (
4
+ get_direct_solar_irradiance_map,
5
+ get_diffuse_solar_irradiance_map,
6
+ get_global_solar_irradiance_map,
7
+ )
8
+
9
+
10
+ def compute_solar_irradiance_for_all_faces(*args, **kwargs):
11
+ """Compatibility stub.
12
+
13
+ VoxCity's public API sometimes re-exports this symbol; if your workflow
14
+ depends on it, we can map it to a GPU equivalent (or implement it) once the
15
+ expected inputs/outputs are confirmed.
16
+ """
17
+ raise NotImplementedError(
18
+ "compute_solar_irradiance_for_all_faces is not implemented in simulator_gpu yet. "
19
+ "Use get_*_solar_irradiance_map functions or open an issue with the expected signature."
20
+ )
21
+
22
+
23
+ __all__ = [
24
+ "get_direct_solar_irradiance_map",
25
+ "get_diffuse_solar_irradiance_map",
26
+ "get_global_solar_irradiance_map",
27
+ "compute_solar_irradiance_for_all_faces",
28
+ ]