Understand case.toml¶
A case is one WRF experiment. wrfkit keeps the scientific configuration in:
Think of the three files this way:
| File | Purpose |
|---|---|
case.toml |
common scientific settings + wrfkit workflow settings |
namelist.wps |
full native WPS configuration |
namelist.input |
full native WRF configuration |
For most work, start with case.toml. The native namelists remain visible and
are still the files that WPS and WRF actually read.
What wrfkit does not decide
wrfkit can check syntax and some relationships between fields. It cannot decide whether a domain, physics scheme, time step, or other scientific choice is appropriate for your study.
The short version¶
A beginner usually needs to understand these sections first:
[time] # when the simulation runs
[domain] # where the WRF grid is and how large/fine it is
[geography] # static WPS geography
[forcing] # which weather data drives the model
[forcing.subset] # which part of that weather data to download
[model] # numerical integration settings
[physics] # physics preset
[output] # how often WRF writes output
When those are not enough, use [advanced.wrf.*] or [advanced.wps.*]
to write lower-level native namelist options directly. The normal sections are
ordered as experiment definition → domain → inputs → model → output; native
[advanced.*] overrides belong at the end so the abstraction boundary stays
visible.
A minimal example¶
The bundled Athens minimal validation case looks like this:
schema_version = 1
[case]
description = "Athens, Georgia minimal single-domain validation case"
[namelist]
managed = true
[time]
start = 2026-09-30T00:00:00Z
end = 2026-09-30T06:00:00Z
forcing_interval_seconds = 10800
[domain]
max_dom = 1
parent_id = [1]
parent_grid_ratio = [1]
i_parent_start = [1]
j_parent_start = [1]
e_we = [61]
e_sn = [61]
e_vert = [45]
dx = 12000
dy = 12000
map_proj = "lambert"
ref_lat = 33.95
ref_lon = -83.38
truelat1 = 30.0
truelat2 = 60.0
stand_lon = -84.0
[geography]
dataset = "wps-lowres-mandatory"
resolution = "lowres"
[forcing]
provider = "gfs"
product = "0p25"
cycle = 2026-09-30T00:00:00Z
forecast_hours = [0, 3, 6]
[forcing.subset]
west = 265
east = 288
south = 25
north = 42
[model]
time_step = 72
[physics]
suite = "CONUS"
[output]
history_interval_minutes = 180
frames_per_outfile = 1
restart = false
Before changing anything, remember two useful read-only checks:
The first checks the configuration. The second shows the resolved experiment that wrfkit intends to run.
TOML syntax and wrfkit schema¶
A case.toml file uses standard TOML syntax. The important distinction is
between TOML syntax and the wrfkit schema:
- TOML decides whether the text is a valid TOML document.
- wrfkit decides whether a top-level section or convenience field belongs to the supported case schema.
- WRF/WPS decide whether a native
[advanced.*]namelist group/key/value is actually valid for the model version.
Values¶
Strings use quotes:
Integers and floating-point values are unquoted:
TOML Booleans are lowercase:
True and False are not TOML Boolean literals.
Arrays use square brackets:
WRF settings that vary by domain often use one array element per domain. Follow the upstream WRF/WPS documentation for the expected number and meaning of values.
TOML also supports date/time values. wrfkit requires an explicit UTC offset for case times:
A trailing Z means UTC.
Comments begin with #:
Tables¶
A section such as:
creates the model table.
A nested section:
creates subset inside forcing.
Native passthrough tables use the same TOML nesting:
Here wrf identifies the native model family and physics maps to
&physics in namelist.input.
The supported top-level schema¶
The current schema accepts these top-level sections/keys:
Unknown top-level sections and unknown fields inside the convenience tables are rejected. This is deliberate: a typo such as:
should fail rather than silently do nothing.
For a setting taken directly from the WRF/WPS manual, use the native passthrough layer instead of inventing another wrfkit top-level table.
For example, this is not the intended interface:
If the upstream WRF manual really defines a namelist group named
&some_good_stuff, write:
wrfkit intentionally does not hard-code every possible native group/key under
advanced.wrf or advanced.wps. That lets newer or uncommon WRF/WPS
options be used without waiting for a new wrfkit convenience field.
Passthrough does not certify the upstream option
wrfkit can render an arbitrary native group/key, but it cannot guarantee that the name, type, range, or scientific value is valid for your WRF/WPS version. Check the upstream manual. A made-up group can still be rejected later by the native program.
Three levels of configuration¶
A useful mental model is:
1. wrfkit convenience layer
[time], [domain], [geography], [forcing], [model], [physics], [output]
↓
common settings + wrfkit validation
2. native passthrough layer
[advanced.wrf.<group>]
[advanced.wps.<group>]
↓
arbitrary native namelist groups/keys
3. raw native layer
[advanced.wrf_raw.<group>]
[advanced.wps_raw.<group>]
↓
verbatim Fortran namelist values when ordinary TOML conversion is not enough
Prefer level 1 when wrfkit provides the field. Use level 2 for valid manual options that are not convenience fields. Use level 3 only for syntax that cannot be represented normally.
Settings you will use most often¶
Experiment identity and namelist control¶
| Field | Meaning |
|---|---|
schema_version |
wrfkit TOML format version; keep 1 for the current format |
case.description |
free-text description for humans and provenance |
namelist.managed |
whether wrfkit may update TOML-owned native namelist fields |
With:
wrfkit updates only the fields represented by TOML and preserves other native namelist settings.
With managed = false, wrfkit does not modify namelist.wps or
namelist.input. TOML can still control wrfkit-specific workflow settings,
such as forcing acquisition.
Time¶
| Field | Meaning |
|---|---|
start |
simulation start time |
end |
simulation end time |
forcing_interval_seconds |
spacing between external meteorological input times |
Times must include a UTC offset. A trailing Z means UTC.
10800 seconds is 3 hours. A six-hour simulation using three-hour forcing
therefore needs forcing at 0, 3, and 6 hours.
Domain¶
The [domain] section answers three basic questions:
- How many WRF domains are there?
- Where are they?
- How large and how fine are their grids?
Grid size and spacing¶
| Field | Meaning |
|---|---|
max_dom |
number of WRF domains |
e_we |
west-east staggered grid dimension |
e_sn |
south-north staggered grid dimension |
e_vert |
number of full vertical levels |
dx |
horizontal grid spacing in the x direction |
dy |
horizontal grid spacing in the y direction |
For projected grids, dx and dy are in meters. Thus 12000 means
12 km.
A smaller grid spacing gives finer spatial resolution, but usually increases the computational cost substantially.
Projection and location¶
map_proj = "lambert"
ref_lat = 33.95
ref_lon = -83.38
truelat1 = 30.0
truelat2 = 60.0
stand_lon = -84.0
| Field | Meaning |
|---|---|
map_proj |
WPS map projection |
ref_lat |
reference latitude |
ref_lon |
reference longitude |
truelat1 |
first true latitude |
truelat2 |
second true latitude when used |
stand_lon |
standard longitude / central meridian |
The current parser also accepts pole_lat and pole_lon when needed.
Nesting¶
For nested domains:
| Field | Meaning |
|---|---|
parent_id |
parent domain for each grid |
parent_grid_ratio |
how much finer a nest is than its parent |
i_parent_start |
nest start in the parent's west-east direction |
j_parent_start |
nest start in the parent's south-north direction |
For a single-domain case, these remain the simple d01 values shown above.
Other domain fields
The convenience layer also accepts lower-level domain fields such as:
These map to WRF domain settings. Use the upstream WRF documentation when choosing scientific values.
Static geography¶
For the built-in minimal validation case:
The two fields have different jobs:
| Field | Meaning |
|---|---|
dataset |
where the WPS static geography comes from |
resolution |
native WPS geog_data_res selector |
For ordinary research cases, wrfkit recognizes the official high-resolution mandatory-data profile:
The tracked athens-highres case now uses the same general Athens region and
validation forcing window but a 3 km, 241 x 241 WRF grid with high-resolution
mandatory geography. It is no longer a controlled geography-only pair with the
12 km athens-minimal case.
wrfkit can automatically acquire this managed package. The official archive is
stored alongside the geography data so a shared data_root can reuse it across
repository clones. The downloader validates the tar/gzip archive, checks the
expected mandatory-field directories, records the archive SHA-256 for
provenance, and installs the extracted tree atomically.
The official high-resolution package has now been exercised in the current validation workflow. The downloader also remains covered in CI with a local archive fixture. See Supported and validated for the current environment-specific boundary.
resolution is not forced to "default". A researcher may keep WPS's native
selector freedom, for example:
The small low-resolution validation package is different: because it only contains the
low-resolution teaching/test data expected by wrfkit, its selector remains
restricted to "lowres".
Use geography you already have¶
If a lab or HPC system already provides WPS geography, use the external profile:
wrfkit does not download, copy, or modify an external geography directory. It
checks that the directory exists during prep and links the case workspace's
geog path to it.
An absolute path may point to another filesystem, which is useful on HPC
systems. A relative path is resolved under the machine's reusable data root:
With:
that resolves to:
This keeps the scientific choice (resolution) in the case while allowing the
physical storage location to follow the machine.
Use ./wrfctl plan --case NAME to see the resolved dataset, selector,
management mode, and path before running anything.
Weather forcing¶
| Field | Meaning | Current automatic support |
|---|---|---|
provider |
weather-data provider | "gfs" |
product |
provider product | "0p25" |
cycle |
forecast initialization time | GFS 00/06/12/18 UTC cycle |
forecast_hours |
lead times to acquire | non-negative hour values |
The forecast hours must cover every WPS input time required by the simulation.
Forcing download area¶
| Field | Meaning |
|---|---|
west |
western longitude |
east |
eastern longitude |
south |
southern latitude |
north |
northern latitude |
The current GFS downloader uses longitudes from 0 to 360° east. For example, 275°E is the same longitude as 85°W.
The subset must be large enough to cover the WRF domain and the surrounding area needed for boundary input.
Model time step¶
This is WRF's integration time step in seconds.
The annotated template records the common WRF real-data rule of thumb of no
more than about 6 × dx(km). For a 12 km grid, 72 s is therefore an upper
rule-of-thumb value, not a guarantee of numerical stability.
If WRF reports CFL-related instability, a smaller time step may be needed.
Physics suite¶
This maps to WRF's physics_suite.
A physics suite is a coordinated preset. It is not automatically the best choice for every region, resolution, season, or research question.
If you need to choose individual schemes, use the advanced WRF interface below.
Output¶
| Field | Meaning |
|---|---|
history_interval_minutes |
how often WRF writes history output |
frames_per_outfile |
number of output times stored in each history file |
restart |
native WRF restart switch |
restart_interval_minutes |
restart-output interval when configured |
Smaller history intervals create more frequent output and normally require more storage.
Warning
The TOML restart fields can map into the native namelist, but wrfkit's complete restart/recovery workflow is not currently claimed as validated.
Native options beyond the convenience layer¶
The convenience fields above are intentionally limited. wrfkit does not try to re-create every WRF/WPS namelist option as a custom TOML field.
For a valid option documented by WRF/WPS, use:
Example:
Unknown native group/key names are intentionally allowed under these advanced families, while unknown wrfkit convenience sections/fields are rejected.
If a convenience field and an advanced field target the same native key, the advanced value wins. Keep advanced tables at the end of the file so that override boundary is visible.
For the complete guide—including manual-to-TOML translation, type conversion, raw Fortran values, future/unknown native options, WRF/WPS examples, and the validation sequence—continue to Native WRF/WPS namelist options.
A safe editing routine¶
The documentation's default interactive workflow is to enter the pinned shell
once, then work with wrfctl directly:
Inside the (wrfkit) shell:
# 1. edit
$EDITOR cases/my-case/case.toml
# 2. validate without writing native namelists
wrfctl config --case my-case --check
# 3. inspect the resolved experiment
wrfctl plan --case my-case
# 4. render + prepare inputs
wrfctl prep --case my-case
# 5. run WRF
wrfctl run --case my-case
If the scientific configuration changes after preparation, the freshness guard
normally stops run until you prepare again. See
High-level and low-level workflows for the
exact stage mapping and the explicit stale-prep override boundary.
Complete annotated template¶
The repository also contains a copyable template:
It includes additional advanced examples and comments.
For native WRF/WPS options beyond wrfkit's convenience layer, use the official
WRF documentation together with the [advanced.*] interface.
Related pages¶
- Machine setup and shell: Bootstrap and enter the wrfkit shell
- Build a real experiment: Make a research case
- Inspect every WPS/WRF stage: High-level and low-level workflows
- Change the software environment: Customize flake.nix
- Command syntax: wrfctl command reference