Skip to main content

SOLWEIG-GPU: GPU-Accelerated Thermal Comfort Modeling Framework

SOLWEIG Logo

Project Status: Active PyPI version Documentation Status DOI License: GPL v3 PyPI Downloads EMD Tests

SOLWEIG-GPU is a Python package and command-line interface for running the standalone 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).

What is new in Version 2

  • Modular code to calculate wall and aspect, sky-view factor, and TMRT/UTCI
  • Ability to compute wet bulb globe temperature (WBGT)
  • Bug fixes
  • Implements GLIDE-SOL (Zonato et al., 2026) features:
    • Download and process the required input datasets
    • Wind direction based wind-extension coefficient calculation (requires ERA5 data)
    • Compute diagnostic urban heat island intensity (UHII) when ERA5 forcing data is used

Cite this work as

  1. Kamath, H. G., Sudharsan, N., Singh, M., Wallenberg, N., Lindberg, F., & Niyogi, D. (2026). SOLWEIG-GPU: GPU-Accelerated Thermal Comfort Modeling Framework for Urban Digital Twins. Journal of Open Source Software, 11(118), 9535. https://doi.org/10.21105/joss.09535

  2. Zonato, A., Kamath, H.G., Sudharsan, N., Monaco, L., Kittner, J., Wolf, L., Demuzere, M.A., Middel, A., Bechtel, B. and Milelli, M., 2026. GLIDE-SOL: A GPU-accelerated Global Lightweight Infrastructure for Diagnostic Environmental Modeling with SOLWEIG. EGUsphere, 2026, pp.1-30. https://doi.org/10.5194/egusphere-2026-776

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

SOLWEIG GPU code is an extension of the original SOLWEIG Python model that is part of the Urban Multi-scale Environmental Predictor (UMEP). GitHub code: 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


For detailed documentation, see Solweig-GPU Documentation

Features

  • CPU and GPU support (automatically uses GPU if available)
  • Divides larger areas into tiles based on the selected tile size
  • CPU-based computations of wall height and aspect are parallelized across multiple CPUs
  • GPU-based computation of SVF, shortwave/longwave radiation, shadows, Tmrt, and UTCI
  • Compatible with meteorological data from UMEP, ERA5, and WRF (wrfout)
  • Pipeline can be run in stages (preprocess, run_walls_aspect, run_utci_tiles) for subset-of-tiles or reuse; see documentation (Developer Guide and API Reference)

SOLWEIG-GPU workflow
Flowchart of the SOLWEIG-GPU modeling framework


Required Input Data

  • Building DSM: Includes both buildings and terrain elevation (e.g., Building_DSM.tif)
  • DEM: Digital Elevation Model excluding buildings (e.g., DEM.tif)
  • Tree DSM: Vegetation height data only (e.g., Trees.tif)

Currently tested only for hourly data

  • Meteorological forcing:
    • Custom .txt file (from UMEP)
    • ERA5 (both instantaneous and accumulated)
    • WRF output NetCDF (wrfout)

ERA5 Variables Required

  • 2-meter air temperature
  • 2-meter dew point temperature
  • Surface pressure
  • 10-meter U and V wind components
  • Downwelling shortwave radiation (accumulated)
  • Forecasted surface roughness (if wind extinction coefficients are to be calculated)

Output Details

  • Output directory: output_folder/ (under the directory you pass as base_path)
  • Structure: One folder per tile (e.g., 0_0/, 1000_0/)
  • SVF: Single-band raster
  • Other outputs: Multi-band raster (e.g., 24 bands for hourly results)

If you need outputs in a different folder, set base_path to that directory and pass complete paths for the rasters: building_dsm_filename, dem_filename, trees_filename, and landcover_filename (optional).

UTCI for New Delhi
UTCI for New Delhi, India, generated using SOLWEIG-GPU and visualized with ArcGIS Online.


Installation

We recommend using conda environment (please see documentation)

conda create -n solweig python=3.10
conda activate solweig
conda install -c conda-forge gdal cudnn pytorch timezonefinder matplotlib #cudnn is required only if you are using nvidia GPU
pip install solweig-gpu
#if you have older versions installed
pip install --upgrade solweig-gpu

Testing

Run the test suite with:

pytest -q

With coverage:

pytest --cov=solweig_gpu --cov-report=term-missing

CI runs tests on Linux and macOS across Python 3.10–3.12.


Sample Data

Please refer to the sample dataset to familiarize yourself with the expected inputs. Sample data can be found at: DOI


Python Usage

Notes on sample data and forcing options

  • The Input_raster folder in the sample contains the raster files required by SOLWEIG-GPU:

    1. Building_DSM.tif
    2. DEM.tif
    3. Trees.tif
    4. Landcover.tif (optional)
  • SOLWEIG-GPU can be meteorologically forced in three ways:

    1. Using your own meteorological .txt file
    2. ERA5 reanalysis
    3. Weather Research and Forecasting (WRF) output files. Make sure filenames follow one of:
      • wrfout_d0x_yyyy-mm-dd_hh_mm_ss (preferred; works across operating systems)
      • wrfout_d0x_yyyy-mm-dd_hh:mm:ss
      • wrfout_d0x_yyyy-mm-dd_hh
  • The Forcing_data folder in the sample data contains example data for all forcing methods.


Examples

Data download (optional)

Download the required data for SOLWEIG-GPU from near-globally available urban datasets. Google Earth Engine must be authenticated before this process.

import os
from solweig_gpu import build_inputs

os.environ["EE_PROJECT"] = "your-gee-project-id"  # Your own GEE/GCP project ID

base_path = build_inputs(
    lat=latitude,
    lon=longitude,
    city="City name",
    km_buffer=2,        # Kilometers from the central lat-lon to set the download extent
    km_reduced_lat=1,
    km_reduced_lon=1,
    base_folder="/path/to/save/inputs",
    resolution=2,       # Spatial resolution of the generated rasters in meters
)

print("SOLWEIG input folder:", base_path)

Compute direction-based wind coefficients (optional)

This requires ERA5 data with the variable Forecasted surface roughness.

from solweig_gpu import build_wind_ext_coeff

build_wind_ext_coeff(
    "/path/to/solweig/input",                            # Base path where input rasters are present
    "/path/to/era5/data_stream-oper_stepType-instant.nc"  # ERA5 instantaneous file
)

Example 1: Modular way of running the model with ERA5

Step 1: Preprocess and create inputs in the required format
  • The model simulation date is 2020-08-13.
  • The start and end dates provided to the model are 2020-08-13 06:00:00 UTC and 2020-08-14 05:00:00 UTC, respectively. UTC to local time conversion is handled internally. For Austin, TX, this corresponds to 2020-08-13 01:00:00 to 2020-08-13 23:00:00 local time.
  • The tile_size depends on the RAM available on the GPU. A smaller value is safer for lower-memory GPUs, while larger tiles can improve throughput on high-memory GPUs.
  • The overlap controls the additional pixels used for shadow transfer between neighboring tiles. For example, with tile_size=1000 and overlap=100, the processed tile size becomes 1100 × 1100 pixels.
from solweig_gpu import preprocess

preprocess(
    base_path="/path/to/solweig/input",
    selected_date_str="2020-08-13",
    building_dsm_filename="Building_DSM.tif",
    dem_filename="DEM.tif",
    trees_filename="Trees.tif",
    landcover_filename="Landuse.tif",        # Use None if land cover is not used
    windcoeff_folder="/path/to/solweig/input", # Use None if wind coefficients are not used
    tile_size=400,
    overlap=0,
    use_own_met=False,
    start_time="2020-08-13 06:00:00",
    end_time="2020-08-14 05:00:00",
    data_source_type="ERA5",
    data_folder="/path/to/era5",
    own_met_file=None,
    preprocess_dir="/path/to/solweig/input",
    use_uhi=True,  # Use only with ERA5. Calculates diagnostic urban heat island intensity.
)
Step 2: Calculate wall height and aspect
from solweig_gpu import run_walls_aspect

run_walls_aspect("/path/to/solweig/input")
Step 3: Calculate the sky-view factor
from solweig_gpu import calculate_svf

calculate_svf(
    base_path="/path/to/solweig/input",
    patch_option=2,
    overwrite=False,
)
Step 4: Run the SOLWEIG-GPU model
from solweig_gpu import run_utci_tiles

run_utci_tiles(
    base_path="/path/to/solweig/input",
    preprocess_dir="/path/to/solweig/input",
    selected_date_str="2020-08-13",
    save_tmrt=True,
    save_svf=False,
    save_kup=False,
    save_kdown=False,
    save_lup=False,
    save_ldown=False,
    save_shadow=False,
    save_wbgt=False,
)

Example 2: Run the model end-to-end with ERA5

from solweig_gpu import thermal_comfort

thermal_comfort(
    base_path="/path/to/solweig/input",
    selected_date_str="2020-08-13",
    building_dsm_filename="Building_DSM.tif",
    dem_filename="DEM.tif",
    trees_filename="Trees.tif",
    landcover_filename="Landuse.tif",  # Use None if land cover is not used
    ERA_5_z0_find=True,  # If True, expects data_stream-oper_stepType-instant.nc in data_folder
    tile_size=400,
    overlap=0,
    use_own_met=False,
    start_time="2020-08-13 06:00:00",
    end_time="2020-08-14 05:00:00",
    data_source_type="ERA5",
    data_folder="/path/to/era5",
    use_uhi=True,
    save_wbgt=True,
)

Example 3: Run the model end-to-end with WRF

This can also be run in the modular way by following Example 1 and replacing data_source_type with wrfout.

from solweig_gpu import thermal_comfort

thermal_comfort(
    base_path="/path/to/solweig/input",
    selected_date_str="2020-08-13",
    building_dsm_filename="Building_DSM.tif",
    dem_filename="DEM.tif",
    trees_filename="Trees.tif",
    landcover_filename=None,
    ERA_5_z0_find=False,  # Set True only if data_folder contains ERA5 data_stream-oper_stepType-instant.nc
    tile_size=3600,
    overlap=20,
    use_own_met=False,
    start_time="2020-08-13 06:00:00",
    end_time="2020-08-14 05:00:00",
    data_source_type="wrfout",
    data_folder="/path/to/wrfout/files",
    own_met_file=None,
    use_uhi=False,  # Always keep False when using WRF forcing
    save_tmrt=True,
    save_svf=False,
    save_kup=False,
    save_kdown=False,
    save_lup=False,
    save_ldown=False,
    save_shadow=False,
    save_wbgt=False,
)
  • The model simulation date is 2020-08-13.
  • The start and end dates provided to the model are 2020-08-13 06:00:00 UTC and 2020-08-14 05:00:00 UTC, respectively. These are the start and end times of the WRF output in UTC. In local time, this corresponds to 2020-08-13 01:00:00 to 2020-08-13 23:00:00 for Austin, TX. UTC to local time conversion is handled internally.
  • The tile_size depends on the RAM available on the GPU. The value can be reduced for lower-memory GPUs.
  • The overlap controls the additional pixels used for shadow transfer between neighboring tiles. For example, with tile_size=3600 and overlap=20, the processed tile size becomes 3620 × 3620 pixels.
  • If ERA_5_z0_find=True, SOLWEIG-GPU calculates wind-extension coefficients and expects the ERA5 file data_stream-oper_stepType-instant.nc to be available in data_folder. If data_folder points to WRF output files, keep data_stream-oper_stepType-instant.nc in that folder.

Example 4: Own File

from solweig_gpu import thermal_comfort

thermal_comfort(
    base_path="/path/to/solweig/input",
    selected_date_str="2020-08-13",
    building_dsm_filename="Building_DSM.tif",
    dem_filename="DEM.tif",
    trees_filename="Trees.tif",
    landcover_filename=None,
    ERA_5_z0_find=False,  # Set True only if data_folder contains ERA5 data_stream-oper_stepType-instant.nc
    tile_size=3600,
    overlap=20,
    use_own_met=True,
    start_time=None,
    end_time=None,
    data_source_type=None,
    data_folder=None,
    own_met_file="/path/to/met.txt",
    use_uhi=False,  # Not recommended with user-provided meteorological files
    save_tmrt=True,
    save_svf=False,
    save_kup=False,
    save_kdown=False,
    save_lup=False,
    save_ldown=False,
    save_shadow=False,
    save_wbgt=False,
)
  • Use this option when forcing SOLWEIG-GPU with a user-provided meteorological .txt file.
  • Keep use_own_met=True and provide the meteorological file through own_met_file.
  • Keep use_uhi=False for user-provided meteorological files.
  • If ERA_5_z0_find=True, SOLWEIG-GPU expects the ERA5 file data_stream-oper_stepType-instant.nc in data_folder. Because this example does not use ERA5 forcing, the safer default is ERA_5_z0_find=False.
  • If ERA_5_z0_find=True, wind directions should be available for each time step in the meteorological .txt file.

Note for Windows Users

On Windows, Python uses the spawn start method for new processes: each worker re-imports your script. Without guarding the entry point, a top-level call to thermal_comfort() would run again in every child process, causing repeated execution and failures (e.g. BrokenProcessPool). Always call thermal_comfort() inside a main() function and use if __name__ == "__main__": (see example below).

from solweig_gpu import thermal_comfort
import multiprocessing as mp

def main():
    thermal_comfort(
    base_path="/path/to/solweig/input",
    selected_date_str="2020-08-13",
    building_dsm_filename="Building_DSM.tif",
    dem_filename="DEM.tif",
    trees_filename="Trees.tif",
    landcover_filename="Landuse.tif",  # Use None if land cover is not used
    ERA_5_z0_find=True,  # If True, expects data_stream-oper_stepType-instant.nc in data_folder
    tile_size=400,
    overlap=0,
    use_own_met=False,
    start_time="2020-08-13 06:00:00",
    end_time="2020-08-14 05:00:00",
    data_source_type="ERA5",
    data_folder="/path/to/era5",
    use_uhi=True,
    save_wbgt=True,
)

if __name__ == "__main__":
    mp.freeze_support()
    main()

Command-Line Interface (CLI)

Example using sample ERA5 data on Windows

conda activate solweig
thermal_comfort --base_path '/path/to/input' ^
                --date '2020-08-13' ^
                --building_dsm 'Building_DSM.tif' ^
                --dem 'DEM.tif' ^
                --trees 'Trees.tif' ^
                --tile_size 1000 ^
                --landcover  'Landcover.tif' ^
                --overlap 100 ^
                --use_own_met False ^
                --data_source_type 'ERA5' ^
                --data_folder '/path/to/era5' ^
                --start '2020-08-13 06:00:00' ^
                --end '2020-08-13 23:00:00' ^
                --era5_z0_find True ^
                --use_uhi True ^
                --save_tmrt True ^
                --save_svf False ^
                --save_kup False ^
                --save_kdown False ^
                --save_lup False ^
                --save_ldown False ^
                --save_shadow False ^
                --save_wbgt True ^
                --save_ta False ^
                --save_wind False
  • --era5_z0_find computes directional wind-extension coefficients and requires data_stream-oper_stepType-instant.nc in --data_folder. It defaults to True when --data_folder is provided and False otherwise.
  • --use_uhi computes the diagnostic urban heat island intensity; use it only with ERA5 forcing (set False for WRF or your own meteorological file).

Tip: Use --help to list all CLI options.


Contributing

Please refer to the documentation

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solweig_gpu-2.0.0.tar.gz (4.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

solweig_gpu-2.0.0-py3-none-any.whl (157.6 kB view details)

Uploaded Python 3

File details

Details for the file solweig_gpu-2.0.0.tar.gz.

File metadata

  • Download URL: solweig_gpu-2.0.0.tar.gz
  • Upload date:
  • Size: 4.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for solweig_gpu-2.0.0.tar.gz
Algorithm Hash digest
SHA256 7e94ec391913310e600c8c2e7046ea3ce56b9d6ab30cf18d354aef040a762b0e
MD5 f078001b3f6c316c9f4c4dce0fde93e1
BLAKE2b-256 4bec1f55e4af1d36785153436e32c52dfffb13c1004633922a595543927c9f82

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig_gpu-2.0.0.tar.gz:

Publisher: publish.yml on nvnsudharsan/SOLWEIG-GPU

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solweig_gpu-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: solweig_gpu-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 157.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for solweig_gpu-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 60e61c6167b5bcb35d91e629375922940df28f3ded89b8b609482bbb45e1a0da
MD5 b883fd3b5840e3caa119b3079b365b41
BLAKE2b-256 f30189a4c6c067ffb88113ea65b71e349b579a689f32e55727d7fb687d0ad085

See more details on using hashes here.

Provenance

The following attestation bundles were made for solweig_gpu-2.0.0-py3-none-any.whl:

Publisher: publish.yml on nvnsudharsan/SOLWEIG-GPU

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 files

1.2.22

2 files

1.2.21

2 files

1.2.20

2 files

1.2.19

2 files

1.2.18

2 files

1.2.15

2 files

1.2.14

2 files

1.2.13

2 files

1.2.12

2 files

1.2.11

2 files

1.2.10

2 files

1.2.9

2 files

1.2.8

2 files

1.2.7

2 files

1.2.5

2 files

1.2.4

2 files

1.2.2

2 files

1.2.1

2 files

1.0.1

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page