PATMO / Documentation

This page documents the current repository state of PATMO. It is written from the code in this repo rather than from an external manual, so the emphasis is on what is actually implemented, how the workflow is currently wired, and which parts should be treated as stable, legacy, or still evolving.

Current Scope

The most complete and up-to-date workflow in this repository is centered on tests/modern_sulfur_cycle/, with tests/archean/ following the same newer pattern. Some older examples are still useful for orientation, but they do not fully match the latest driver interface. This page documents the PATMO core codebase only.

1D atmospheric model Python code generation + Fortran runtime Sparse DLSODES solver Volcano: under development

Overview

PATMO is a one-dimensional planetary atmosphere model for coupled chemistry, transport, and radiative effects. In the current repository, the central idea is not “run one fixed solver with one fixed network,” but instead:

  1. prepare a case with a reaction network, settings, profiles, fluxes, and a Fortran driver
  2. use Python to generate case-specific Fortran modules into build/
  3. compile the generated code with the fixed runtime modules and DLSODES solver
  4. run the resulting executable and inspect the output files written by the driver

In other words, the repository is best understood as a two-stage system: Python performs the preprocessing and code generation, and Fortran performs the time integration.

Architecture overview of PATMO, from case inputs to generated modules, runtime execution, and outputs.
Figure. The current PATMO workflow from case inputs to generated Fortran modules and runtime outputs.

Preprocessing side

Reads options.opt, case input files, chemical networks, thermochemistry data, and photolysis cross-sections.

Generated build

Writes case-specific Fortran modules into build/, along with copied solver files, copied case files, and photochemistry tables.

Runtime side

Uses sparse Jacobians and DLSODES to integrate chemistry, diffusion, optional process terms, and photochemistry.

Quick Start

If a case already has the required plain-text files in place, the shortest current workflow is:

python3 patmo -test=modern_sulfur_cycle
cd build
make
./test

The first command generates the build directory for the selected case. Compilation happens only after that, inside build/.

The repository also contains helper scripts such as compile.sh and the case-specific scripts in tests/modern_sulfur_cycle/ and tests/archean/. In the current code, those scripts can:

  • convert reaction_network.xlsx into reaction_network.ntw
  • convert settings.xlsx into options.opt
  • convert profile.xlsx into profile.dat
  • interpolate solar_flux.xlsx into solar_flux.txt
  • validate patmo_dumpDensityToFile calls in test.f90
  • append default volcano options when a volcano_events.dat file is present
  • invoke python3 patmo -test=<case> and enter build/
chmod +x ./compile.sh
./compile.sh
make
./test

The helper script does not replace compilation; it prepares the case and build directory, then leaves you in build/ so you can run make and then ./test.

Repository Map

Path Role In The Current Workflow
patmo Main Python entry point. Generates case-specific build files for -test=<case>.
src_py/ Python preprocessing, network loading, option parsing, photochemistry preparation, Jacobian and ODE code generation.
src_f90/ Fortran templates and fixed runtime modules that are copied or instantiated into build/.
solvers/ Legacy Fortran solver sources used for the final executable, including DLSODES support.
data/ Reference datasets: KIDA chemistry, thermochemistry, and SWRI photolysis cross-section files.
tests/ Case directories. Each case provides its own driver program and input files.
build/ Generated working directory for the selected case. This is the directory you compile and run.
tools/ Small auxiliary tools, such as helper interpolation scripts.

Case Files

A runnable PATMO case lives under tests/<case>/. The current code does not treat the case directory as passive data only. It treats it as the main scientific setup for the run, including the input files and the driver program that decides what to load, what to set, and what to dump.

File Status What It Does
copylist.pcp Required Lists which case files are copied into build/ before generation and compilation.
options.opt Required Stores grid, photochemistry, and process switches that the Python side reads before code generation.
reaction_network.ntw Usually required Explicit reaction network in PATMO text format. Often generated from reaction_network.xlsx.
test.f90 Required Case-specific driver. Calls the public PATMO routines, sets the experiment, and decides which outputs to write.
profile.dat Case dependent Initial atmospheric profile loaded by patmo_loadInitialProfile().
solar_flux.txt Required when photochemistry is used Top-of-atmosphere photon flux sampled on the active wavelength grid.
Auxiliary text tables Optional Case-specific files for rainout, aerosol, condensation, deposition, or other custom source/sink logic used by test.f90.
volcano_events.dat Optional Current experimental event file for volcanic gas and ash forcing. This feature should be treated as under development.

The explicit network file is a structured comma-separated text format. The current parser in src_py/patmo_network.py recognizes:

  • #@var:T=Tgas style variable aliases
  • @format: lines that define how each reaction row is parsed
  • @ghost: lines for additional ghost species
  • reaction rows containing indexed reactants, products, and one rate expression
#@var:T=Tgas
@format:idx,R,R,R,P,P,P,rate
1,COS,OH,,CO2,SH,,1.1E-13*exp(-1200/T)
2,COS,O,,CO,SO,,2.1E-11*exp(-2200/T)

If options.network is left empty and options.species is provided, the Python side can also construct a reduced network directly from the KIDA database.

Options Reference

The current option parser lives in src_py/patmo_options.py. It supports integers, floats, booleans, comma-separated lists, and key:value dictionaries. Boolean flags are read from T and F.

Key Meaning Current Behavior
network Path to the explicit reaction network file. If set, loadNetwork() reads that file directly.
species Comma-separated species list. If used with an empty network, KIDA reactions are filtered to this species set.
cellsNumber Number of vertical layers. Copied into generated Fortran commons and used throughout the grid arrays.
cellThickness Nominal cell thickness. Used in generated dry deposition terms and related source/sink scaling.
photoBinsNumber Number of photochemistry bins. Defines the size of photoMetric.dat and photolysis-related arrays.
wavelengMin, wavelengMax Wavelength range in nm. The current photochemistry pipeline uses these values to derive the active energy grid.
energyMin, energyMax Legacy energy-range fields. Still parsed, but the current photochemistry builder is driven primarily by wavelength limits when photochemistry is enabled.
zenith_angle Solar zenith angle in degrees. Converted to mu = cos(theta) inside generated photo-rate code.
TOA_para Top-of-atmosphere scaling coefficient. Written into the generated photo-rate module as a multiplicative factor.
plotRates Whether rate plotting should be enabled. Currently used as a light build-time flag; plotting support depends on matplotlib.
useEntropyProduction Entropy-production control flag. Affects reverse-reaction handling and whether entropy production is part of the intended workflow.
Key Meaning Current Behavior
usePhotochemistry Enable the photolysis preprocessing and runtime photo-rate path. Controls cross-section loading, photo metric creation, and photolysis rate evaluation.
useHescape Enable hydrogen escape terms. Turns on conditional blocks in the generated ODE and main runtime module.
useWaterRemoval Enable water condensation/removal logic. Activates conditional removal terms in patmo_ode.
useAerosolformation Enable aerosol conversion terms. Activates the current sulfuric-acid-to-aerosol conversion block in the generated ODE.
constant_species Comma-separated list of species that should remain fixed. Generated as dn = 0 constraints for those species.
gravity_species Dictionary of species to settling expressions. Injected into generated ODE code as gravity-settling source/sink terms.
drydep_species Dictionary of surface dry deposition rates. Applied in the bottom layer through generated dry-deposition code.
emission_species Dictionary of lower-boundary emission terms. Added as explicit source terms in the first atmospheric layer.
useVolcano Enable volcanic forcing. Turns on the experimental patmo_volcano integration path.
volcanoFile Volcanic event file name. Passed directly into patmo_volcano_init().
volcanoAshSettling Ash settling coefficient. Used in the ash transport/settling update inside patmo_volcano.
volcanoAshDecay Ash decay coefficient. Used in the ash opacity decay update inside patmo_volcano.

Generation Pipeline

The current main orchestration logic is in the repository root file patmo. That script performs the following build sequence for -test=<case>:

Python Build Steps

1. Copy case files

patmo_test.buildTest() reads copylist.pcp and copies the selected case files into build/.

2. Read options

patmo_options.options() parses the run configuration and process flags.

3. Build the network

patmo_network loads the explicit network file and any KIDA-derived chemistry selected by the options.

4. Prepare photochemistry

patmo_photochemistry loads cross-sections, defines the logarithmic metric, and writes interpolated files.

5. Generate Fortran

Utility, rate, reverse-rate, ODE, commons, sparsity, Jacobian, and main modules are generated into build/.

Category Files
Generated Fortran modules patmo.f90, patmo_ode.f90, patmo_commons.f90, patmo_rates.f90, patmo_photo.f90, patmo_photoRates.f90, patmo_reverseRates.f90, patmo_jacobian.f90, patmo_sparsity.f90, patmo_utils.f90
Copied fixed runtime files Makefile, patmo_constants.f90, patmo_parameters.f90, patmo_volcano.f90
Copied solver files opkda1.f, opkda2.f, opkdmain.f
Generated chemistry diagnostics reactionsVerbatim.dat, xsecs/photoMetric.dat, xsecs/*.dat
Copied case data The files listed in copylist.pcp, including the case-specific test.f90.

Runtime Model

After compilation, the runtime behavior is centered on the generated patmo module and the case-specific test.f90 driver.

patmo_init()

Loads photochemistry metrics and cross-sections when enabled, zeroes rates and cumulative arrays, loads verbatim reaction names, and initializes volcanic state when the volcano path is active.

patmo_run(dt, convergence)

Computes optical depth, rates, reverse rates, and sparse structure if needed, then advances the full 1D state using DLSODES.

patmo_ode:fex

Builds the right-hand side from chemistry, diffusion, eddy transport, wet deposition, and any enabled optional source/sink terms.

Jacobian path

The generated patmo_jacobian and patmo_sparsity modules provide the sparse structure required by the solver.

The current photolysis workflow is split across Python preprocessing and Fortran runtime:

  • src_py/patmo_photochemistry.py finds SWRI cross-sections and interpolates them onto the active log-energy metric
  • the interpolated cross-section tables needed by the runtime are written into build/xsecs/
  • build/xsecs/photoMetric.dat and build/xsecs/*.dat are written for the runtime side
  • patmo_photo loads those files at initialization time
  • patmo_photoRates integrates cross-sections against the current optical depth field and flux scaling

The generated ODE system contains the reaction network terms and then layers additional process terms on top. In the current source, those include:

  • molecular and eddy diffusion between neighboring cells
  • constant-species constraints
  • gravity settling for configured species
  • dry deposition in the bottom layer
  • lower-boundary emissions
  • wet deposition
  • optional water removal
  • optional aerosol formation
  • optional hydrogen escape
  • optional volcanic gas and ash forcing

Driver Routines

The public routines currently exposed by src_f90/patmo.f90 are the routines a case driver usually calls. The table below focuses on the ones that appear most often in the bundled cases.

Routine Typical Use
patmo_init() Initialize the generated runtime, photochemistry tables, and reaction metadata.
patmo_loadInitialProfile() Load the initial vertical profile from profile.dat with unit conversion.
patmo_setFluxBB() Set a blackbody stellar flux field. Used by several bundled examples.
patmo_setGravity() Set the gravitational acceleration used by transport terms.
patmo_hydrostaticEquilibrium() Construct or update the hydrostatic structure from a chosen ground pressure.
patmo_setDiffusionDzzAll(), patmo_setEddyKzzAll() Set layer-wide transport coefficients.
patmo_setChemistryAll(), patmo_setTgasAll() Directly set species abundances or temperatures for every cell.
patmo_run(dt, convergence) Advance the model by one time step and return the current convergence estimate.
patmo_dumpHydrostaticProfile(), patmo_dumpOpacity(), patmo_dumpJValue(), patmo_dumpAllRates() Write standard diagnostic files after or during a run.
patmo_dumpDensityToFile(), patmo_dumpMixingRatioToFile(), patmo_dumpAllMixingRatioToFile() Write species-specific or full-column output files.
patmo_getTotalMass(), patmo_getEntropyProduction() Return scalar diagnostics that can be used inside a custom driver loop.

Important current-state note: the main source file now defines patmo_run(dt, convergence). The hello, benchmark, and entropy examples still call an older one-argument form, so they should be read as legacy examples rather than as the most current driver template.

Outputs

Output behavior is split between fixed PATMO dump routines and whatever the case-specific driver writes. The most common current output files are:

File Where It Comes From Meaning
hydrostat.out Driver call Hydrostatic structure near the start of the run.
hydrostatEnd.out Driver call Hydrostatic structure at the end of the run.
allNDs.dat patmo_dumpAllMixingRatioToFile() All-species column output written at the end of a run.
opacity.dat patmo_dumpOpacity() Current wavelength- or energy-resolved opacity diagnostic.
jvalue.dat patmo_dumpJValue() Photolysis rate diagnostic for the active photo reactions.
rates.dat patmo_dumpAllRates() All reaction rates for the generated forward, photochemical, and reverse network.
Species-specific dump files patmo_dumpDensityToFile() or patmo_dumpMixingRatioToFile() Case-selected diagnostic outputs for individual species.
build/reactionsVerbatim.dat Python preprocessing Human-readable reaction list corresponding to the generated network.

Bundled Cases

The repository currently contains five bundled case folders. They are not all at the same maturity level.

Case Role Current Status In This Repo
tests/modern_sulfur_cycle/ Main teaching and reference case. Most complete current workflow. Matches the newer helper-script and two-argument driver style.
tests/archean/ Extended sulfur/archean scenario. Also uses the newer workflow structure and the current patmo_run(dt, convergence) signature.
tests/hello/ Minimal orientation example. Useful for reading, but it still uses the older one-argument patmo_run(dt) form and energy-range options.
tests/benchmark/ Longer legacy benchmark case. Legacy-style driver; use it carefully as a reference, not as the primary current template.
tests/entropy/ Entropy-production example. Legacy-style driver; still useful conceptually, but not the cleanest match to the current runtime interface.

Volcano

Under Development

Volcano-related functionality exists in the current codebase, but it should be treated as an under-development path rather than as a fully settled public workflow. The repository currently exposes a patmo_volcano.f90 module, option flags, and example event files, but this documentation intentionally presents them as experimental.

  • reads volcano_events.dat at initialization time when useVolcano = T
  • supports GAS and ASH event rows
  • maps event altitude ranges from km to the existing model grid
  • adds volcanic gas source terms inside the ODE right-hand side
  • adds gray ash opacity to the optical-depth field
  • updates ash by source input, decay, and simple settling after each step
# kind species t_start_s t_end_s zmin_km zmax_km source_rate
GAS SO2 0.0 5.1840e6 12.0 25.0 2.50e3
GAS H2S 0.0 5.1840e6 10.0 22.0 3.00e2
ASH ASH 0.0 1.2960e7 14.0 30.0 2.00e-8

This format reflects the current source code and the example file shipped in tests/modern_sulfur_cycle/volcano_events.dat. It should not yet be treated as a frozen interface.

Notes

  • build/ is a generated workspace. It is not the source of truth; the source of truth is the case directory plus the Python and Fortran templates.
  • The repository mixes current workflows with older examples. This page prioritizes the currently consistent path rather than flattening those differences away.
  • When photochemistry is enabled, wavelength-based configuration is the more current path in this repository.
  • The external wiki can still be useful, but this page is meant to describe the code snapshot currently present in this repo.