Preprocessing side
Reads options.opt, case input files, chemical networks, thermochemistry data,
and photolysis cross-sections.
PROFILE NODE
A code-based reference guide to the current PATMO repository and runtime workflow.
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.
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:
build/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.
Reads options.opt, case input files, chemical networks, thermochemistry data,
and photolysis cross-sections.
Writes case-specific Fortran modules into build/, along with copied solver files,
copied case files, and photochemistry tables.
Uses sparse Jacobians and DLSODES to integrate chemistry, diffusion,
optional process terms, and photochemistry.
Manual Case Run
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/.
Spreadsheet-Assisted Workflow
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:
reaction_network.xlsx into reaction_network.ntwsettings.xlsx into options.optprofile.xlsx into profile.datsolar_flux.xlsx into solar_flux.txtpatmo_dumpDensityToFile calls in test.f90volcano_events.dat file is presentpython3 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.
| 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. |
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. |
Network File Format
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#@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.
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.
Core Setup
| 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. |
Process Switches And Boundary Terms
| 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. |
The current main orchestration logic is in the repository root file patmo.
That script performs the following build sequence for -test=<case>:
patmo_test.buildTest() reads copylist.pcp and copies the selected case files into build/.
patmo_options.options() parses the run configuration and process flags.
patmo_network loads the explicit network file and any KIDA-derived chemistry selected by the options.
patmo_photochemistry loads cross-sections, defines the logarithmic metric, and writes interpolated files.
Utility, rate, reverse-rate, ODE, commons, sparsity, Jacobian, and main modules are generated into build/.
Generated And Copied Build Files
| 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. |
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:fexBuilds the right-hand side from chemistry, diffusion, eddy transport, wet deposition, and any enabled optional source/sink terms.
The generated patmo_jacobian and patmo_sparsity modules provide the sparse structure
required by the solver.
Photochemistry Path
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 metricbuild/xsecs/build/xsecs/photoMetric.dat and build/xsecs/*.dat are written for the runtime sidepatmo_photo loads those files at initialization timepatmo_photoRates integrates cross-sections against the current optical depth field and flux scalingProcess Terms In The Current ODE
The generated ODE system contains the reaction network terms and then layers additional process terms on top. In the current source, those include:
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.
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. |
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. |
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.
What The Current Code Already Does
volcano_events.dat at initialization time when useVolcano = TGAS and ASH event rowsCurrent Event File Shape
# 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.
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.