FreeCESM
A small, readable Python OOP prototype of the CESM/CAM call graph — not a numerical model, but a structural sketch: every class is named after its Fortran component, every method after what the process does, with the Fortran call-site name kept in the docstring/trace for cross-reference.
It mirrors the PI-atm end-to-end control-flow graph published at coverage.vegavoid.com — a coverage-instrumented trace of the real CESM/CAM Fortran source for a pre-industrial, atmosphere-active case.
Install
pip install -e .
Quick start
from freecesm import Driver
driver = Driver(case="PI-atm", nsteps=10)
trace = driver.execute()
print(f"{len(trace)} call-graph nodes executed")
print(driver.cam.state.summary())
Architecture
Driver— mirrorscesm_driver:pre_init→init→run(thecesm_runcoupling loop, with restart/history gates) →final.Coupler— dispatchescomponent_runon each active component in call-graph order (ice → lnd → rof → ocn → atm) and stands in for thecomponent_exchflux exchange.FreeCAM— the only component with real internal structure. Its entire per-step running order — physics, the coupling exchange, dynamics, output — lives as one explicit, editable list:FreeCAM.workflow.Parameterization— one physics process per subclass (DryAdjustment,DeepConvection,Radiation,Chemistry, ...), each just implementing atendency(state).Dynamics— the spectral-element dycore, collapsed to onerun().CaseConfig/CASES— CESM's real "compset" idea, in miniature: a dataclass naming a factory for every component slot (atmosphere included — nothing is special-cased), so a run can be an atmosphere-only PI case, a fully coupled case, or something built on the fly, e.g. an ocean-only case with a data atmosphere (FreeDATM) instead ofFreeCAM.
Other components — FreeCLM, FreeCICE (prescribed or active), FreeDOCN,
FreePOP, FreeRTM, FreeDATM, StubComponent (GLC/WAV) — are lightweight
stand-ins, each with a one-line run().
Extending the workflow
Adding a new physical process is two steps: subclass Parameterization with a
tendency, then edit FreeCAM.workflow — it's a plain Python list.
from freecesm import Parameterization
class VolcanicAerosol(Parameterization):
name = "volcanic_aerosol (custom)"
def tendency(self, state):
state.T -= 0.15
driver.cam.workflow.insert(3, VolcanicAerosol())
Building a custom case
from freecesm import CaseConfig, Driver, FreeCICE, FreeDOCN
my_case = CaseConfig(
name="PI-dataocean",
description="Coupled atmosphere/land/ice, but a data ocean instead of POP.",
forcing="1850, fixed preindustrial",
make_ice=lambda: FreeCICE(mode="active"),
make_ocn=FreeDOCN,
)
driver = Driver(case=my_case, nsteps=5)
Tests
pip install -e ".[test]"
pytest
Metadata
Release files for freecesm 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| freecesm-0.1.0.tar.gz | 12.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| freecesm-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.6 kB
Release files / freecesm-0.1.0.tar.gz
| Download URL | freecesm-0.1.0.tar.gz |
|---|---|
| Size | 12.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
092ce4fe8277d5c852ce0f79c0282ffe09fdb6722138e131449a2b696c6e9348
|
|
BLAKE2b-256 checksum How to use checksums |
5c3cade64aec7ad4c34452d54920989362493ab47334c11f199f0d76607fd06d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.5
|
Release files / freecesm-0.1.0-py3-none-any.whl
| Download URL | freecesm-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
750e4ec6536a651d870ecd6303ac88da57b5ba6a277381b7bab0d35c1808c37c
|
|
BLAKE2b-256 checksum How to use checksums |
20c784c2bc74420d9436b6e02ae72f9fa11d5c8e6966b45e41d9291a4044dd6d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.5
|