Skip to content

Add restart capability to the fire behavior model - #39

Open
masih-e wants to merge 1 commit into
NCAR:developfrom
masih-e:restart-pr
Open

masih-e wants to merge 1 commit into
NCAR:developfrom
masih-e:restart-pr

Conversation

@masih-e

@masih-e masih-e commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Description of changes:

The CFBM has had no way to stop a simulation and resume it.
This feature adds a restart capability. A run can write its dynamic fire state to a
NetCDF file at a fixed interval, and a later run can be initialized from one of
those files instead of a cold start. It covers standalone runs, serial and MPI,
and runs coupled to WRF.

Two options are added to the &time namelist block:

Option Type Default Meaning
restart logical .false. Resume from fire_restart_<start datetime>.nc
restart_interval integer -1 Restart write interval in seconds; -1 disables writes

Both default to the previous behavior, so existing namelists are unaffected.

Changes by file:

  • state/state_mod.F90 carries the Read_restart and Write_restart
    type-bound methods, Build_restart_file_name, and the MPI helpers they need.
    A restart read validates the grid metadata stored in the file against the
    current configuration before touching any state, so a mismatched restart file
    fails early with a message instead of producing a silently wrong run.
  • io/netcdf_mod.F90 adds attribute writers (Add_netcdf_att) and
    MPI-aware readers and writers for distributed 2D and 3D fields.
  • driver/initialize_mod.F90 routes the real-case restart path through a
    new Init_fire_state_from_restart, leaving the existing geogrid
    initialization untouched. The WRF-coupled path reads the restart after the
    fire components are initialized.
  • driver/fire_behavior.F90 reads the restart state at startup in place of
    Save_state, and writes a restart every restart_interval seconds.
    restart_interval must map to a whole number of time steps or the run stops
    with a message.
  • io/namelist_mod.F90 adds the two options, their broadcast, and a range
    check.
  • physics/fmc_wrffire_mod.F90 drops its unused state_mod and
    namelist_mod imports. This one is load-bearing rather than cosmetic:
    state_mod now uses fmc_wrffire_mod for the moisture restart fields, so
    leaving those imports in place would create a circular module dependency.

Type of change

  • New feature (non-breaking change which adds functionality)

Tests conducted:

All testing on Derecho (NCAR) using the repository environment
env/derecho/gnu-12.2.0: GCC 12.2.0, cray-mpich 8.1.25, NetCDF-Fortran 4.9.2,
HDF5 1.12.2, ESMF 8.5.0, CMake 3.26.3.

Builds. Three configurations, all clean with no errors or new warnings:
serial (--mpi-off), MPI (default), and --esmx (which includes NUOPC).

Registered ctest suite, run on the --esmx build so every registered case
is reachable:

test7 test8 test7esmf test8esmf test7esmx test8esmx testx
pass pass pass pass pass pass pass

7 of 7. The NUOPC cases matter here because the cap uses both initialize_mod
and state_mod, and this PR touches both.

Restart regressions. These run a case straight through, then run it again
stopping and restarting partway, and compare the two. Restart test scripts are
not included in this PR (see below), but the results are:

Serial build, 20 of 20 checks:

test7_restart test8_restart test9 test9_restart
5/5 5/5 5/5 5/5

MPI build on a compute node, 30 of 30 checks:

ranks test7_restart test8_restart
1 5/5 5/5
2 5/5 5/5
4 5/5 5/5

The multi-rank runs are the ones that exercise the distributed restart read and
write and the halo exchange following a restart read. Restarting at 2 and 4
ranks reproduces the continuous run, so the domain decomposition is handled
correctly on the restart path.

57 passing checks in total across the three build configurations.

Not covered. Two gaps, stated explicitly:

  1. The WRF-coupled restart path (Init_fire_state_within_wrf calling
    Read_restart) is exercised by a separate WRF harness, and not tested here.
  2. Rank counts above 4 have not been tried.

On the test scripts. The restart test scripts (test7_restart.s,
test8_restart.s, test9.s, test9_restart.s, the test9 case directory, and
the tests/CMakeLists.txt registration) are deliberately held out of this PR
pending the separate discussion about how tests should be organized. They are
ready and can be added here or in a follow-up PR, whichever is preferred.

Documentation:

  • Documentation has been updated for these changes
  • No documentation update needed

Documentation was left out to keep the diff focused on
the code. Happy to add it to this PR if preferred, otherwise it will follow
separately.

Contributors:

@masih-e (Masih Eghdami:masih@ucar.edu)
@mefrediani (Maria Frediani:frediani@ucar.edu)

LLM/coding assistant technology used: the restart implementation was developed
with assistance from Codex GPT-5.5 and Claude Opus 4.7. Claude Opus 5 assisted
with the pre-review cleanup of this branch.

Further information:

state/state_mod.F90 grows from 1063 to 1965 lines in this PR, which is more
than that file should carry. A restart-specific module is worth doing as a follow-up. This
change is not possible with the current code because the restart calls depend on the fire
state type.

Lets a simulation write its dynamic fire state to a NetCDF restart file
at a fixed interval and resume from one of those files, for standalone
runs (serial and MPI) and for runs coupled to WRF.

Namelist (time block):
  restart          - resume from fire_restart_<start datetime>.nc
  restart_interval - restart write interval in seconds, -1 disables

state_mod:
  Read_restart and Write_restart type-bound methods, plus
  Build_restart_file_name and the MPI helpers they need. A restart read
  validates the grid metadata stored in the file against the current
  configuration before touching any state, so a mismatched restart file
  fails early instead of producing a silently wrong run.

netcdf_mod:
  Attribute writers (Add_netcdf_att) and MPI-aware readers and writers
  for distributed 2D and 3D fields.

initialize_mod:
  Init_fire_state_from_restart takes the real-case restart path, so the
  existing geogrid initialization is left as is. The WRF-coupled path
  reads the restart after the fire components are initialized.

fire_behavior:
  Reads the restart state at startup instead of Save_state, and writes a
  restart every restart_interval seconds. restart_interval must map to a
  whole number of time steps or the run stops with a message.

fmc_wrffire_mod:
  Drops the unused state_mod and namelist_mod imports. state_mod now uses
  fmc_wrffire_mod for the moisture restart fields, so these imports would
  otherwise form a circular module dependency.

The code was created with assistance from Codex GPT-5.5 and Claude Opus 4.7.

Co-authored-by: mefrediani <frediani@ucar.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant