ArchimedLight.jl
ArchimedLight.jl is the Julia reimplementation of the ARCHIMED light model. This model computes the interception and scattering of light by complex 3D scenes, with a focus on performance. It uses a rasterization-based approach for first-order interception and an iterative method for scattering, with flexible options for optical properties and directional response.
It is designed around a simple workflow: build or read a scene, define optical models, create a LightSimulation, then call run_light for one meteo row or a complete meteo table.
<details> <summary>Reproducing the figures</summary>
The animation runs the wheat and agrivoltaic wheat scenes from the archimedlight-benchmark-scenes artifact every 30 minutes over a representative clear-sky day. Each plot has about 2,500 explicit ground tiles, making the moving projected shade visible while the same color scale tracks incident PAR irradiance through the day. The script to reproduce these figures is in docs/make_video.jl. </details>
Scope
- ARCHIMED-style scene/model/meteo ingestion:
.ops,.opf,.gwa, YAML models, and meteo CSV files - File-based and in-memory workflows through the same runtime API
- Directional sky discretization with the standard ARCHIMED turtle sector counts
- First-order interception by CPU rasterization / z-buffer style projection
- Iterative scattering using the same directional visibility information
- Attachment of
Ri_*andRa_*values back onto MTG nodes for inspection and export - Fixture-based parity work against the historical Java implementation
Energy balance, transpiration, and photosynthesis are intentionally out of scope for this package. The historical ARCHIMED documents referenced throughout this site still matter for the model vocabulary and physical assumptions, but the Julia package documented here currently implements the light-only core.
Quick Start
using ArchimedLight
repo_root = normpath(joinpath(dirname(pathof(ArchimedLight)), ".."))
config = joinpath(repo_root, "example_2", "config.yml")
sim, meteo = read_simulation(config)
step = run_light(sim, first(meteo))
step.budget.incident_flux.total.par;
step.budget.absorbed_energy.total.par;Dict{Int64, Float64} with 5968 entries:
4986 => 1298.61
4700 => 1117.87
4576 => 1126.83
6073 => 107.383
2288 => 56.1529
1703 => 81.5081
1956 => 839.459
2350 => 844.308
5975 => 552.69
3406 => 208.614
2841 => 1241.04
2876 => 26.6719
687 => 347.622
185 => 1090.16
1090 => 1240.13
2015 => 438.546
3293 => 396.755
3220 => 7.49491
4888 => 1177.71
⋮ => ⋮The simulation results are grouped by quantity and waveband in LightBudget. When you attach those values back onto the scene, the default attribute names keep the standard ARCHIMED naming convention such as Ri_PAR_f, Ri_PAR_q, and Ra_PAR_q.
Read This Site In Three Passes
- Start with Getting Started if you want one runnable coffee example with the minimum number of moving parts.
- Continue with Beginner Workflows, File-Based Workflow, or Interactive Workflow depending on whether your scene already exists on disk or is being built in Julia.
- Use the reference pages for exact file keys, scene semantics, model structure, meteo columns, and outputs.
Documentation Map
- Getting Started
- Beginner Workflows
- Tutorial: File-Based Workflow
- Tutorial: Interactive Workflow
- Configuration And Options Reference
- Scene Files And Semantics
- Model Files Reference
- Meteo Inputs Reference
- Outputs
- CPU Performance Benchmarks
- Pipeline Overview
- First-Order Interception
- Scattering And Optical Assumptions
- Full Example
- Composable Stages
- API Reference