Skip to main content

A 3D monte carlo simulation of Atmospheric Radiative Transfer

Project description

AtmoRad

A vectorized Monte Carlo simulation of atmospheric radiative transfer.

Python 3.10+ License: MIT

2D Surface absorption map Sample photon paths
map paths
Vertical flux profile Vertical absorption profile
profile hist

Overview:

This project simulates the propagation of light through a plane-parallel atmosphere over a horizontally mixed surface and its interactions with the ground boundary. Developed as a student project, created to learn computational physics and software development.

Physical model

  • Analog Monte Carlo Approach: Light is simulated using discrete photon packets. Final flux is calculated as a fraction of the total detected packets.
  • Plane-parallel approximation: The atmosphere consists of horizontally uniform layers.
  • Multi-material atmospheric layers: Layers can consist of multiple atmospheric materials simultaneously. A photon is assigned a material randomly when it is initialized and again when it crosses into a new layer. Each material has its own extinction coefficient, SSA and phase function.
  • Custom Phase Functions: Henyey-Greenstein and Rayleigh phase functions are already implemented in the simulation, but any custom user-defined function can be constructed using the Scattering class.
  • Surface Reflections: The surface consists of materials, each with its own albedo, a predefined BRDF reflection model (Lambertian, Mirror), and a ProceduralMap that outputs material ID based on spatial coordinates.
  • Photon Properties: Light is treated as monochromatic, non-polarized particles. During the simulation they can be scattered, reflected, or absorbed.
  • Incident Irradiance & Adjacency Effect: Custom detectors allow measuring downward/upward incident flux at any arbitrary altitude - helpful for visualizing the adjacency effect.

Technical implementation:

  • The simulation uses numpy to simulate photons simultaneously in large batches.
  • The results are plotted using matplotlib and seaborn (e.g., photon paths, flux profile, 2D ground flux maps)
  • The code uses multiprocessing to run batches in parallel.

Installation:

uv tool install atmorad-py
  • Using pip:
pip install atmorad-py
  • Run the simulation:
atmorad --init
atmorad simulation.toml
  • Check results/ directory for simulation artifacts.

Project Structure

  • engine/: Divides photons into batches and runs the simulation.
  • physics/: Contains a rotation function, scattering phase functions, reflection functions.
  • environment/: Keeps track of the environment. Contains Scene, Atmosphere and Surface classes.
  • detectors/: Provides functionality for tracking photons during the simulation and generates results.
  • output/: Handles results and figure generation.
  • config/ and builder.py: Parses .toml configuration file and generates simulation context.
  • cli.py: Provides CLI for atmorad.

Customization

You can define your own surface reflection algorithms and scattering phase functions using decorators as shown below:

import numpy as np
from atmorad import build_context, MCRadiationRunner, DataIO, ResultAnalyzer
from atmorad import SurfaceReflection, register_reflection, orientation
from atmorad import Scattering, register_scattering

# 1. Register a custom surface reflection
@register_reflection("custom-reflection")
class CustomReflection(SurfaceReflection):
    # Specify arbitrary custom parameters
    def __init__(self, param_1, param_2):
        self.param_1 = param_1
        self.param_2 = param_2
    def reflect(self, direction, rand_1, rand_2):
        # Your custom reflection physics here
        cos_theta = np.sqrt(rand_1)
        sin_theta = np.sqrt(1.0 - rand_1)

        # you can also use specified parameters
        # self.param_1, self.param_2

        phi = rand_2 * 2 * np.pi
        cos_phi, sin_phi = np.cos(phi), np.sin(phi)
        
        return orientation(cos_theta, sin_theta, cos_phi, sin_phi)
    
# 2. Register a custom scattering phase function
@register_scattering("custom-scattering")
class CustomScattering(Scattering):
    # Specify arbitrary custom parameters
    def __init__(self, g, resolution=1000):
        # Define a pdf array
        self.g = g
        cos_grid = np.linspace(-1, 1, resolution)

        pdf = (1 - g**2) / (2 * (1 + g**2 - 2 * g * cos_grid) ** 1.5)

        super().__init__(pdf_array=pdf, resolution=resolution)

# 3. Run the simulation using custom names in your config
if __name__ == "__main__":
    context = build_context("simulation.toml")
    runner = MCRadiationRunner(context)
    runner.run()

    # 4. Save and analyze results
    results = runner.get_results()
    outputs = DataIO(context.config)
    analyzer = ResultAnalyzer(results, context.config)
    
    outputs.save_all_artifacts(analyzer, results)
    outputs.save_metadata(context.config, results)
    outputs.save_results(results)

In simulation.toml you can specify your defined scatterings and reflections:

[atmosphere_materials.custom-atm-material]
ssa = 0.9
scattering = {type = "custom-scattering", g=0.8} 

[surface_materials.custom-surf-material]
albedo = 0.5
reflection = {type = "custom-reflection", param_1=2, param_2=1.3} # match param names defined in python

Then you can use your defined materials for atmospheric layers and surface maps:

[[layer]]
z_range_km = [0, 2]
materials = [{type = "custom-atm-material", weight = 1.0}]

# ...

[surface]
name = "uniform"
material = "custom-surf-material"

References and Literature

Acknowledgments

  • This project was inspired by the lectures on Radiative Processes in the Atmosphere by Prof. K. Markowicz, Faculty of Physics, University of Warsaw.
  • Large Language Models were used for code debugging and learning best Python practices (e.g. dataclasses, __init__.py import interfaces, class responsibilities, config parsing).

Contributing

Feel free to open an Issue or submit a Pull Request if you'd like to contribute or report a bug.

Project details


Download files

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

Source Distribution

atmorad_py-0.1.1.tar.gz (105.2 kB view details)

Uploaded Source

Built Distribution

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

atmorad_py-0.1.1-py3-none-any.whl (35.7 kB view details)

Uploaded Python 3

File details

Details for the file atmorad_py-0.1.1.tar.gz.

File metadata

  • Download URL: atmorad_py-0.1.1.tar.gz
  • Upload date:
  • Size: 105.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for atmorad_py-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3fadecfec3386911c8a4e3b2dddace255168dfb5f1331801edb01fbff18e3fcf
MD5 59516aa3fa50fc8f0d1c8215dd337efb
BLAKE2b-256 242b708e9aa2e5adc28797f45ec8c91d0177ebc8d591911bf7279c2d2e8a1fdd

See more details on using hashes here.

File details

Details for the file atmorad_py-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: atmorad_py-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 35.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for atmorad_py-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 700a3782d82dab47109b738e4c702fc895fe89e74870dd9d38e8c58b1312ec18
MD5 5f7ab232929135221999ad7c0ce7571a
BLAKE2b-256 eb15c6c485e84a00c4fddc61bbe855439c6fe96a88eedbb26063c75862480202

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page