solweig-gpu 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Harsh Kamath and Naveen Sudharsan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ include LICENSE
3
+
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: solweig-gpu
3
+ Version: 0.1.0
4
+ Summary: GPU-accelerated SOLWEIG model for urban thermal comfort simulation
5
+ Home-page: https://github.com/nvnsudharsan/utci-pipeline
6
+ Author: Harsh Kamath, Naveen Sudharsan
7
+ Author-email: harsh.kamath@utexas.edu, naveens@utexas.edu
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: POSIX :: Linux
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
12
+ Requires-Python: >=3.8
13
+ License-File: LICENSE
14
+ Requires-Dist: torch
15
+ Requires-Dist: numpy
16
+ Requires-Dist: scipy
17
+ Requires-Dist: pandas
18
+ Requires-Dist: netCDF4
19
+ Requires-Dist: pytz
20
+ Requires-Dist: shapely
21
+ Requires-Dist: timezonefinder
22
+ Requires-Dist: gdal
23
+ Requires-Dist: xarray
24
+ Requires-Dist: tqdm
25
+ Requires-Dist: PyQt5
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: home-page
30
+ Dynamic: license-file
31
+ Dynamic: requires-dist
32
+ Dynamic: requires-python
33
+ Dynamic: summary
@@ -0,0 +1,147 @@
1
+ # SOLWEIG-GPU: GPU-Accelerated Thermal Comfort Modeling Framework
2
+
3
+ **SOLWEIG-GPU** is a Python package and command-line interface for running the SOLWEIG (Solar and LongWave Environmental Irradiance Geometry) model on CPU or GPU (if available). It enables high-resolution urban microclimate modeling by computing key variables such as Sky View Factor (SVF), Mean Radiant Temperature (Tmrt), and the Universal Thermal Climate Index (UTCI).
4
+
5
+ **SOLWEIG** was originally developed by Dr. Fredrik Lindberg's group. Journal reference: Lindberg, F., Holmer, B. & Thorsson, S. SOLWEIG 1.0 – Modelling spatial variations of 3D radiant fluxes and mean radiant temperature in complex urban settings. Int J Biometeorol 52, 697–713 (2008). https://doi.org/10.1007/s00484-008-0162-7
6
+
7
+ **SOLWEIG GPU** code is an extention of the original **SOLWEIG** python model that is the part of the Urban Multi-scale Environmental Predictor (UMEP) (GitHub code reference: https://github.com/UMEP-dev/UMEP). UMEP journal reference: Lindberg, F., Grimmond, C.S.B., Gabey, A., Huang, B., Kent, C.W., Sun, T., Theeuwes, N.E., Järvi, L., Ward, H.C., Capel-Timms, I. and Chang, Y., 2018. Urban Multi-scale Environmental Predictor (UMEP): An integrated tool for city-based climate services. Environmental modelling & software, 99, pp.70-87. https://doi.org/10.1016/j.envsoft.2017.09.020
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ - CPU and GPU support (automatically uses GPU if available)
14
+ - Divides larger areas into tiles based on the selected tile size
15
+ - CPU-based computations of wall height and aspect parallelized across multiple CPUs
16
+ - GPU-based computation of SVF, shortwave/longwave radiation, shadows, Tmrt, and UTCI
17
+ - Compatible with meteorological data from UMEP, ERA5, and WRF (`wrfout`)
18
+
19
+ ![SOLWEIG-GPU workflow ](/solweig_diagram.png)
20
+ *Flowchart of the SOLWEIG-GPU modeling framework*
21
+
22
+ ---
23
+
24
+ ## Required Input Data
25
+
26
+ - `Building DSM`: Includes both buildings and terrain elevation (e.g., `Building_DSM.tif`)
27
+ - `DEM`: Digital Elevation Model excluding buildings (e.g., `DEM.tif`)
28
+ - `Tree DSM`: Vegetation height data only (e.g., `Trees.tif`)
29
+ - Meteorological forcing:
30
+ - Custom `.txt` file (from UMEP)
31
+ - ERA5 (both instantaneous and accumulated)
32
+ - WRF output NetCDF (`wrfout`)
33
+
34
+ > Please refer to the sample dataset to familiarize yourself with the expected inputs. Sample data can be found at https://utexas.box.com/s/8fctqicidr5cup8kj3tk53jd444pow6z
35
+
36
+ ### ERA5 Variables Required
37
+ - 2-meter air temperature
38
+ - 2-meter dew point temperature
39
+ - Surface pressure
40
+ - 10-meter U and V wind components
41
+ - Downwelling shortwave radiation (accumulated)
42
+ - Downwelling longwave radiation (accumulated)
43
+
44
+ ---
45
+
46
+ ## Output Details
47
+
48
+ - Output directory: `Outputs/`
49
+ - Structure: One folder per tile (e.g., `tile_0_0/`, `tile_0_600/`)
50
+ - SVF: Single-band raster
51
+ - Other outputs: Multi-band raster (e.g., 24 bands for hourly results)
52
+
53
+ ![UTCI for New Delhi](/UTCI_New_Delhi.jpeg)
54
+ *UTCI for New Delhi, India, generated using SOLWEIG-GPU and visualized with ArcGIS Online.*
55
+
56
+ ---
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ conda create -n solweig python=3.10
62
+ conda activate solweig
63
+ conda install -c conda-forge gdal pytorch
64
+ git clone https://github.com/nvnsudharsan/solweig-gpu.git
65
+ cd solweig-gpu
66
+ pip install .
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Python Usage
72
+
73
+ ```python
74
+ from solweig_gpu import thermal_comfort
75
+
76
+ thermal_comfort(
77
+ base_path='/path/to/input',
78
+ selected_date_str='2020-08-13',
79
+ building_dsm_filename='Building_DSM.tif',
80
+ dem_filename='DEM.tif',
81
+ trees_filename='Trees.tif',
82
+ tile_size=3600,
83
+ use_own_met=True,
84
+ own_met_file='/path/to/met.txt',
85
+ start_time='2020-08-13 00:00:00',
86
+ end_time='2020-08-13 23:00:00',
87
+ data_source_type='ERA5', # or 'WRFOUT'
88
+ data_folder='/path/to/era5_or_wrfout',
89
+ save_tmrt=True,
90
+ save_svf=False,
91
+ save_kup=False,
92
+ save_kdown=False,
93
+ save_lup=False,
94
+ save_ldown=False,
95
+ save_shadow=False
96
+ )
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Command-Line Interface (CLI)
102
+
103
+ ```bash
104
+ conda activate solweig
105
+ thermal_comfort --base_path /path/to/input \
106
+ --selected_date_str 2020-08-13 \
107
+ --building_dsm_filename Building_DSM.tif \
108
+ --dem_filename DEM.tif \
109
+ --trees_filename Trees.tif \
110
+ --tile_size 3600 \
111
+ --use_own_met True \
112
+ --own_met_file /path/to/met.txt \
113
+ --start_time "2020-08-13 00:00:00" \
114
+ --end_time "2020-08-13 23:00:00" \
115
+ --data_source_type ERA5 \
116
+ --data_folder /path/to/era5_or_wrfout \
117
+ --save_tmrt True \
118
+ --save_svf False
119
+ ```
120
+
121
+ > Tip: Use `--help` to list all CLI options.
122
+
123
+ ---
124
+
125
+ ## GUI Usage
126
+
127
+ To launch the GUI:
128
+ ```bash
129
+ conda activate solweig
130
+ solweig_gpu
131
+ ```
132
+
133
+ ![GUI](/GUI.png)
134
+
135
+ ### GUI Workflow
136
+ 1. Select the **base path** containing input datasets.
137
+ 2. Choose the **Building DSM**, **DEM**, and **Tree DSM** raster files.
138
+ 3. Set the **tile size** (e.g., 600 or 1200 pixels).
139
+ 4. Select a **meteorological source** (`metfile`, `ERA5`, or `wrfout`):
140
+ - If `metfile`: Provide a `.txt` file.
141
+ - If `ERA5`: Provide a folder with both instantaneous and accumulated files.
142
+ - If `wrfout`: Provide a folder with WRF output NetCDF files.
143
+ 5. Set the **start** and **end times** in UTC (`YYYY-MM-DD HH:MM:SS`).
144
+ 6. Choose which outputs to generate (e.g., Tmrt, UTCI, radiation fluxes).
145
+ 7. Output will be saved in `Outputs/`, with subfolders for each tile.
146
+
147
+ ---
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="solweig-gpu",
5
+ version="0.1.0",
6
+ description="GPU-accelerated SOLWEIG model for urban thermal comfort simulation",
7
+ author="Harsh Kamath, Naveen Sudharsan",
8
+ author_email="harsh.kamath@utexas.edu, naveens@utexas.edu",
9
+ url="https://github.com/nvnsudharsan/utci-pipeline",
10
+ packages=find_packages(), # Automatically finds `solweig_gpu`
11
+ install_requires=[
12
+ "torch",
13
+ "numpy",
14
+ "scipy",
15
+ "pandas",
16
+ "netCDF4",
17
+ "pytz",
18
+ "shapely",
19
+ "timezonefinder",
20
+ "gdal",
21
+ "xarray",
22
+ "tqdm",
23
+ "PyQt5",
24
+ ],
25
+ classifiers=[
26
+ "Programming Language :: Python :: 3",
27
+ "Operating System :: POSIX :: Linux",
28
+ "Intended Audience :: Science/Research",
29
+ "Topic :: Scientific/Engineering :: Atmospheric Science",
30
+ ],
31
+ python_requires=">=3.8",
32
+ entry_points={
33
+ 'console_scripts': [
34
+ 'thermal_comfort=solweig_gpu.cli:main',
35
+ 'solweig_gpu=solweig_gpu.solweig_gpu_gui:main',
36
+ ],
37
+ },
38
+ )
@@ -0,0 +1 @@
1
+ from .solweig_gpu import thermal_comfort
@@ -0,0 +1,257 @@
1
+ import torch
2
+
3
+ # Function to computed UTCI using 6th order polynomial approximation.
4
+ # Inputs:
5
+ # - Mean radiant temperature
6
+ # - Air temperature
7
+ # - Wind speed
8
+ # - Air vapor pressure
9
+
10
+
11
+ def utci_polynomial(D_Tmrt, Ta, va, Pa):
12
+ UTCI_approx = Ta + \
13
+ (6.07562052E-01) + \
14
+ (-2.27712343E-02) * Ta + \
15
+ (8.06470249E-04) * Ta**2 + \
16
+ (-1.54271372E-04) * Ta**3 + \
17
+ (-3.24651735E-06) * Ta**4 + \
18
+ (7.32602852E-08) * Ta**5 + \
19
+ (1.35959073E-09) * Ta**6 + \
20
+ (-2.25836520E+00) * va + \
21
+ (8.80326035E-02) * Ta * va + \
22
+ (2.16844454E-03) * Ta**2 * va + \
23
+ (-1.53347087E-05) * Ta**3 * va + \
24
+ (-5.72983704E-07) * Ta**4 * va + \
25
+ (-2.55090145E-09) * Ta**5 * va + \
26
+ (-7.51269505E-01) * va**2 + \
27
+ (-4.08350271E-03) * Ta * va**2 + \
28
+ (-5.21670675E-05) * Ta**2 * va**2 + \
29
+ (1.94544667E-06) * Ta**3 * va**2 + \
30
+ (1.14099531E-08) * Ta**4 * va**2 + \
31
+ (1.58137256E-01) * va**3 + \
32
+ (-6.57263143E-05) * Ta * va**3 + \
33
+ (2.22697524E-07) * Ta**2 * va**3 + \
34
+ (-4.16117031E-08) * Ta**3 * va**3 + \
35
+ (-1.27762753E-02) * va**4 + \
36
+ (9.66891875E-06) * Ta * va**4 + \
37
+ (2.52785852E-09) * Ta**2 * va**4 + \
38
+ (4.56306672E-04) * va**5 + \
39
+ (-1.74202546E-07) * Ta * va**5 + \
40
+ (-5.91491269E-06) * va**6 + \
41
+ (3.98374029E-01) * D_Tmrt + \
42
+ (1.83945314E-04) * Ta * D_Tmrt + \
43
+ (-1.73754510E-04) * Ta**2 * D_Tmrt + \
44
+ (-7.60781159E-07) * Ta**3 * D_Tmrt + \
45
+ (3.77830287E-08) * Ta**4 * D_Tmrt + \
46
+ (5.43079673E-10) * Ta**5 * D_Tmrt + \
47
+ (-2.00518269E-02) * va * D_Tmrt + \
48
+ (8.92859837E-04) * Ta * va * D_Tmrt + \
49
+ (3.45433048E-06) * Ta**2 * va * D_Tmrt + \
50
+ (-3.77925774E-07) * Ta**3 * va * D_Tmrt + \
51
+ (-1.69699377E-09) * Ta**4 * va * D_Tmrt + \
52
+ (1.69992415E-04) * va**2 * D_Tmrt + \
53
+ (-4.99204314E-05) * Ta * va**2 * D_Tmrt + \
54
+ (2.47417178E-07) * Ta**2 * va**2 * D_Tmrt + \
55
+ (1.07596466E-08) * Ta**3 * va**2 * D_Tmrt + \
56
+ (8.49242932E-05) * va**3 * D_Tmrt + \
57
+ (1.35191328E-06) * Ta * va**3 * D_Tmrt + \
58
+ (-6.21531254E-09) * Ta**2 * va**3 * D_Tmrt + \
59
+ (-4.99410301E-06) * va**4 * D_Tmrt + \
60
+ (-1.89489258E-08) * Ta * va**4 * D_Tmrt + \
61
+ (8.15300114E-08) * va**5 * D_Tmrt + \
62
+ (7.55043090E-04) * D_Tmrt**2 + \
63
+ (-5.65095215E-05) * Ta * D_Tmrt**2 + \
64
+ (-4.52166564E-07) * Ta**2 * D_Tmrt**2 + \
65
+ (2.46688878E-08) * Ta**3 * D_Tmrt**2 + \
66
+ (2.42674348E-10) * Ta**4 * D_Tmrt**2 + \
67
+ (1.54547250E-04) * va * D_Tmrt**2 + \
68
+ (5.24110970E-06) * Ta * va * D_Tmrt**2 + \
69
+ (-8.75874982E-08) * Ta**2 * va * D_Tmrt**2 + \
70
+ (-1.50743064E-09) * Ta**3 * va * D_Tmrt**2 + \
71
+ (-1.56236307E-05) * va**2 * D_Tmrt**2 + \
72
+ (-1.33895614E-07) * Ta * va**2 * D_Tmrt**2 + \
73
+ (2.49709824E-09) * Ta**2 * va**2 * D_Tmrt**2 + \
74
+ (6.51711721E-07) * va**3 * D_Tmrt**2 + \
75
+ (1.94960053E-09) * Ta * va**3 * D_Tmrt**2 + \
76
+ (-1.00361113E-08) * va**4 * D_Tmrt**2 + \
77
+ (-1.21206673E-05) * D_Tmrt**3 + \
78
+ (-2.18203660E-07) * Ta * D_Tmrt**3 + \
79
+ (7.51269482E-09) * Ta**2 * D_Tmrt**3 + \
80
+ (9.79063848E-11) * Ta**3 * D_Tmrt**3 + \
81
+ (1.25006734E-06) * va * D_Tmrt**3 + \
82
+ (-1.81584736E-09) * Ta * va * D_Tmrt**3 + \
83
+ (-3.52197671E-10) * Ta**2 * va * D_Tmrt**3 + \
84
+ (-3.36514630E-08) * va**2 * D_Tmrt**3 + \
85
+ (1.35908359E-10) * Ta * va**2 * D_Tmrt**3 + \
86
+ (4.17032620E-10) * va**3 * D_Tmrt**3 + \
87
+ (-1.30369025E-09) * D_Tmrt**4 + \
88
+ (4.13908461E-10) * Ta * D_Tmrt**4 + \
89
+ (9.22652254E-12) * Ta**2 * D_Tmrt**4 + \
90
+ (-5.08220384E-09) * va * D_Tmrt**4 + \
91
+ (-2.24730961E-11) * Ta * va * D_Tmrt**4 + \
92
+ (1.17139133E-10) * va**2 * D_Tmrt**4 + \
93
+ (6.62154879E-10) * D_Tmrt**5 + \
94
+ (4.03863260E-13) * Ta * D_Tmrt**5 + \
95
+ (1.95087203E-12) * va * D_Tmrt**5 + \
96
+ (-4.73602469E-12) * D_Tmrt**6 + \
97
+ (5.12733497E+00) * Pa + \
98
+ (-3.12788561E-01) * Ta * Pa + \
99
+ (-1.96701861E-02) * Ta**2 * Pa + \
100
+ (9.99690870E-04) * Ta**3 * Pa + \
101
+ (9.51738512E-06) * Ta**4 * Pa + \
102
+ (-4.66426341E-07) * Ta**5 * Pa + \
103
+ (5.48050612E-01) * va * Pa + \
104
+ (-3.30552823E-03) * Ta * va * Pa + \
105
+ (-1.64119440E-03) * Ta**2 * va * Pa + \
106
+ (-5.16670694E-06) * Ta**3 * va * Pa + \
107
+ (9.52692432E-07) * Ta**4 * va * Pa + \
108
+ (-4.29223622E-02) * va**2 * Pa + \
109
+ (5.00845667E-03) * Ta * va**2 * Pa + \
110
+ (1.00601257E-06) * Ta**2 * va**2 * Pa + \
111
+ (-1.81748644E-06) * Ta**3 * va**2 * Pa + \
112
+ (-1.25813502E-03) * va**3 * Pa + \
113
+ (-1.79330391E-04) * Ta * va**3 * Pa + \
114
+ (2.34994441E-06) * Ta**2 * va**3 * Pa + \
115
+ (1.29735808E-04) * va**4 * Pa + \
116
+ (1.29064870E-06) * Ta * va**4 * Pa + \
117
+ (-2.28558686E-06) * va**5 * Pa + \
118
+ (-3.69476348E-02) * D_Tmrt * Pa + \
119
+ (1.62325322E-03) * Ta * D_Tmrt * Pa + \
120
+ (-3.14279680E-05) * Ta**2 * D_Tmrt * Pa + \
121
+ (2.59835559E-06) * Ta**3 * D_Tmrt * Pa + \
122
+ (-4.77136523E-08) * Ta**4 * D_Tmrt * Pa + \
123
+ (8.64203390E-03) * va * D_Tmrt * Pa + \
124
+ (-6.87405181E-04) * Ta * va * D_Tmrt * Pa + \
125
+ (-9.13863872E-06) * Ta**2 * va * D_Tmrt * Pa + \
126
+ (5.15916806E-07) * Ta**3 * va * D_Tmrt * Pa + \
127
+ (-3.59217476E-05) * va**2 * D_Tmrt * Pa + \
128
+ (3.28696511E-05) * Ta * va**2 * D_Tmrt * Pa + \
129
+ (-7.10542454E-07) * Ta**2 * va**2 * D_Tmrt * Pa + \
130
+ (-1.24382300E-05) * va**3 * D_Tmrt * Pa + \
131
+ (-7.38584400E-09) * Ta * va**3 * D_Tmrt * Pa + \
132
+ (2.20609296E-07) * va**4 * D_Tmrt * Pa + \
133
+ (-7.32469180E-04) * D_Tmrt**2 * Pa + \
134
+ (-1.87381964E-05) * Ta * D_Tmrt**2 * Pa + \
135
+ (4.80925239E-06) * Ta**2 * D_Tmrt**2 * Pa + \
136
+ (-8.75492040E-08) * Ta**3 * D_Tmrt**2 * Pa + \
137
+ (2.77862930E-05) * va * D_Tmrt**2 * Pa + \
138
+ (-5.06004592E-06) * Ta * va * D_Tmrt**2 * Pa + \
139
+ (1.14325367E-07) * Ta**2 * va * D_Tmrt**2 * Pa + \
140
+ (2.53016723E-06) * va**2 * D_Tmrt**2 * Pa + \
141
+ (-1.72857035E-08) * Ta * va**2 * D_Tmrt**2 * Pa + \
142
+ (-3.95079398E-08) * va**3 * D_Tmrt**2 * Pa + \
143
+ (-3.59413173E-07) * D_Tmrt**3 * Pa + \
144
+ (7.04388046E-07) * Ta * D_Tmrt**3 * Pa + \
145
+ (-1.89309167E-08) * Ta**2 * D_Tmrt**3 * Pa + \
146
+ (-4.79768731E-07) * va * D_Tmrt**3 * Pa + \
147
+ (7.96079978E-09) * Ta * va * D_Tmrt**3 * Pa + \
148
+ (1.62897058E-09) * va**2 * D_Tmrt**3 * Pa + \
149
+ (3.94367674E-08) * D_Tmrt**4 * Pa + \
150
+ (-1.18566247E-09) * Ta * D_Tmrt**4 * Pa + \
151
+ (3.34678041E-10) * va * D_Tmrt**4 * Pa + \
152
+ (-1.15606447E-10) * D_Tmrt**5 * Pa + \
153
+ (-2.80626406E+00) * Pa**2 + \
154
+ (5.48712484E-01) * Ta * Pa**2 + \
155
+ (-3.99428410E-03) * Ta**2 * Pa + \
156
+ (-9.54009191E-04) * Ta**3 * Pa**2 + \
157
+ (1.93090978E-05) * Ta**4 * Pa**2 + \
158
+ (-3.08806365E-01) * va * Pa**2 + \
159
+ (1.16952364E-02) * Ta * va * Pa**2 + \
160
+ (4.95271903E-04) * Ta**2 * va * Pa**2 + \
161
+ (-1.90710882E-05) * Ta**3 * va * Pa**2 + \
162
+ (2.10787756E-03) * va**2 * Pa + \
163
+ (-6.98445738E-04) * Ta * va**2 * Pa + \
164
+ (2.30109073E-05) * Ta**2 * va**2 * Pa + \
165
+ (4.17856590E-04) * va**3 * Pa + \
166
+ (-1.27043871E-05) * Ta * va**3 * Pa + \
167
+ (-3.04620472E-06) * va**4 * Pa + \
168
+ (5.14507424E-02) * D_Tmrt * Pa**2 + \
169
+ (-4.32510997E-03) * Ta * D_Tmrt * Pa**2 + \
170
+ (8.99281156E-05) * Ta**2 * D_Tmrt * Pa**2 + \
171
+ (-7.14663943E-07) * Ta**3 * D_Tmrt * Pa**2 + \
172
+ (-2.66016305E-04) * va * D_Tmrt * Pa**2 + \
173
+ (2.63789586E-04) * Ta * va * D_Tmrt * Pa**2 + \
174
+ (-7.01199003E-06) * Ta**2 * va * D_Tmrt * Pa**2 + \
175
+ (-1.06823306E-04) * va**2 * D_Tmrt * Pa**2 + \
176
+ (3.61341136E-06) * Ta * va**2 * D_Tmrt * Pa**2 + \
177
+ (2.29748967E-07) * va**3 * D_Tmrt * Pa**2 + \
178
+ (3.04788893E-04) * D_Tmrt**2 * Pa**2 + \
179
+ (-6.42070836E-05) * Ta * D_Tmrt**2 * Pa**2 + \
180
+ (1.16257971E-06) * Ta**2 * D_Tmrt**2 * Pa**2 + \
181
+ (7.68023384E-06) * va * D_Tmrt**2 * Pa**2 + \
182
+ (-5.47446896E-07) * Ta * va * D_Tmrt**2 * Pa**2 + \
183
+ (-3.59937910E-08) * va**2 * D_Tmrt**2 * Pa**2 + \
184
+ (-4.36497725E-06) * D_Tmrt**3 * Pa**2 + \
185
+ (1.68737969E-07) * Ta * D_Tmrt**3 * Pa**2 + \
186
+ (2.67489271E-08) * va * D_Tmrt**3 * Pa**2 + \
187
+ (3.23926897E-09) * D_Tmrt**4 * Pa**2 + \
188
+ (-3.53874123E-02) * Pa**3 + \
189
+ (-2.21201190E-01) * Ta * Pa**3 + \
190
+ (1.55126038E-02) * Ta**2 * Pa**3 + \
191
+ (-2.63917279E-04) * Ta**3 * Pa**3 + \
192
+ (4.53433455E-02) * va * Pa**3 + \
193
+ (-4.32943862E-03) * Ta * va * Pa**3 + \
194
+ (1.45389826E-04) * Ta**2 * va * Pa**3 + \
195
+ (2.17508610E-04) * va**2 * Pa**3 + \
196
+ (-6.66724702E-05) * Ta * va**2 * Pa**3 + \
197
+ (3.33217140E-05) * va**3 * Pa**3 + \
198
+ (-2.26921615E-03) * D_Tmrt * Pa**3 + \
199
+ (3.80261982E-04) * Ta * D_Tmrt * Pa**3 + \
200
+ (-5.45314314E-09) * Ta**2 * D_Tmrt * Pa**3 + \
201
+ (-7.96355448E-04) * va * D_Tmrt * Pa**3 + \
202
+ (2.53458034E-05) * Ta * va * D_Tmrt * Pa**3 + \
203
+ (-6.31223658E-06) * va**2 * D_Tmrt * Pa**3 + \
204
+ (3.02122035E-04) * D_Tmrt**2 * Pa**3 + \
205
+ (-4.77403547E-06) * Ta * D_Tmrt**2 * Pa**3 + \
206
+ (1.73825715E-06) * va * D_Tmrt**2 * Pa**3 + \
207
+ (-4.09087898E-07) * D_Tmrt**3 * Pa**3 + \
208
+ (6.14155345E-01) * Pa**4 + \
209
+ (-6.16755931E-02) * Ta * Pa**4 + \
210
+ (1.33374846E-03) * Ta**2 * Pa**4 + \
211
+ (3.55375387E-03) * va * Pa**4 + \
212
+ (-5.13027851E-04) * Ta * va * Pa**4 + \
213
+ (1.02449757E-04) * va**2 * Pa**4 + \
214
+ (-1.48526421E-03) * D_Tmrt * Pa**4 + \
215
+ (-4.11469183E-05) * Ta * D_Tmrt * Pa**4 + \
216
+ (-6.80434415E-06) * va * D_Tmrt * Pa**4 + \
217
+ (-9.77675906E-06) * D_Tmrt**2 * Pa**4 + \
218
+ (8.82773108E-02) * Pa**5 + \
219
+ (-3.01859306E-03) * Ta * Pa**5 + \
220
+ (1.04452989E-03) * va * Pa**5 + \
221
+ (2.47090539E-04) * D_Tmrt * Pa**5 + \
222
+ (1.48348065E-03) * Pa**6
223
+
224
+ return UTCI_approx
225
+
226
+ def utci_calculator(Ta, RH, Tmrt, va10m):
227
+ # Ta = torch.tensor(Ta, dtype=torch.float32)
228
+ # RH = torch.tensor(RH, dtype=torch.float32)
229
+ # Tmrt = torch.tensor(Tmrt, dtype=torch.float32)
230
+ # va10m = torch.tensor(va10m, dtype=torch.float32)
231
+
232
+ invalid_mask = (Ta <= -999) | (RH <= -999) | (va10m <= -999) | (Tmrt <= -999)
233
+ valid_mask = ~invalid_mask
234
+
235
+ tk = Ta[valid_mask] + 273.15 # air temp in K
236
+
237
+ # saturation vapour pressure (es)
238
+ g = torch.tensor([-2.8365744E3, -6.028076559E3, 1.954263612E1, -2.737830188E-2,
239
+ 1.6261698E-5, 7.0229056E-10, -1.8680009E-13, 2.7150305], dtype=torch.float32)
240
+
241
+ es = g[7] * torch.log(tk)
242
+ for i in range(0, 7):
243
+ es = es + g[i] * tk ** (i + 1 - 3.)
244
+
245
+ es = torch.exp(es) * 0.01
246
+
247
+ ehPa = es * RH[valid_mask] / 100.
248
+
249
+ D_Tmrt = Tmrt[valid_mask] - Ta[valid_mask]
250
+ Pa = ehPa / 10.0 # use vapour pressure in kPa
251
+ va = va10m[valid_mask]
252
+
253
+ # Calculate 6th order polynomial as approximation
254
+ UTCI_approx = torch.full_like(Ta, -999, dtype=torch.float32)
255
+ UTCI_approx[valid_mask] = utci_polynomial(D_Tmrt, Ta[valid_mask], va, Pa)
256
+
257
+ return UTCI_approx
@@ -0,0 +1,58 @@
1
+ import argparse
2
+ from .solweig_gpu import thermal_comfort
3
+
4
+ def main():
5
+ parser = argparse.ArgumentParser(description="Run SOLWEIG with GPU acceleration.")
6
+ parser.add_argument('--base_path', required=True, help='Base directory containing input data')
7
+ parser.add_argument('--date', required=True, help='Date for which thermal comfort is computed (e.g., 2021-07-01)')
8
+ parser.add_argument('--building_dsm', default='Building_DSM.tif', help='Filename of the building DSM raster')
9
+ parser.add_argument('--dem', default='DEM.tif', help='Filename of the DEM raster')
10
+ parser.add_argument('--trees', default='Trees.tif', help='Filename of the trees raster')
11
+ parser.add_argument('--tile_size', type=int, default=3600, help='Tile size for GPU processing (e.g., 100 to 4000)')
12
+ parser.add_argument('--use_own_met', type=bool, default=True, help='Set to True if using your own meteorological file')
13
+ parser.add_argument('--own_metfile', default = None, help='Path to your own meteorological file')
14
+ parser.add_argument('--data_source_type', default=None, help='Specify source of meteorological data (e.g., ERA5 or WRF), if not providing met file')
15
+ parser.add_argument('--data_folder', default = None,help='folder for meteorological data source, if it is ERA5 to WRF')
16
+ parser.add_argument(
17
+ '--start',
18
+ default=None,
19
+ help="""Start time of the input file ('2020-08-12 00:00:00')""")
20
+ parser.add_argument(
21
+ '--end',
22
+ default=None,
23
+ help="""Start time of the input file ('2020-08-12 00:00:00')""")
24
+ parser.add_argument('--save_tmrt', action='store_true', help='Flag to save mean radiant temperature')
25
+ parser.add_argument('--save_svf', action='store_true', help='Flag to save sky view factor')
26
+ parser.add_argument('--save_kup', action='store_true', help='Flag to save upward shortwave radiation')
27
+ parser.add_argument('--save_kdown', action='store_true', help='Flag to save downward shortwave radiation')
28
+ parser.add_argument('--save_lup', action='store_true', help='Flag to save upward longwave radiation')
29
+ parser.add_argument('--save_ldown', action='store_true', help='Flag to save downward longwave radiation')
30
+ parser.add_argument('--save_shadow', action='store_true', help='Flag to save shadow map')
31
+
32
+ args = parser.parse_args()
33
+
34
+ thermal_comfort(
35
+ base_path=args.base_path,
36
+ selected_date_str=args.date,
37
+ building_dsm_filename=args.building_dsm,
38
+ dem_filename=args.dem,
39
+ trees_filename=args.trees,
40
+ tile_size=args.tile_size,
41
+ use_own_met=args.use_own_met,
42
+ own_met_file=args.own_metfile,
43
+ start_time=args.start,
44
+ end_time=args.end,
45
+ data_source_type=args.data_source_type,
46
+ data_folder=args.data_folder,
47
+ save_tmrt=args.save_tmrt,
48
+ save_svf=args.save_svf,
49
+ save_kup=args.save_kup,
50
+ save_kdown=args.save_kdown,
51
+ save_lup=args.save_lup,
52
+ save_ldown=args.save_ldown,
53
+ save_shadow=args.save_shadow
54
+ )
55
+
56
+ if __name__ == '__main__':
57
+ main()
58
+