How nhm-usgs/prms works
1. Repository purpose and shape
- This repo is the source tree for PRMS (Precipitation Runoff Modeling System).
- It is split into two major layers: a C-based modeling framework/runtime in mmf/ and the Fortran PRMS process modules and driver code in prms/.
2. Build and packaging boundary
- The top-level make builds the system from source; the resulting executable is placed under prms/prms.
- mmf/Makefile and prms/Makefile suggest the framework and model code are built separately and then linked into the final model executable.
3. MMF runtime/framework layer
- The mmf/ directory contains the infrastructure that manages model execution, configuration, and shared state.
- Key responsibilities include parsing control files and arguments, reading parameter/variable metadata, allocating memory, setting dimensions, and orchestrating module calls.
4. Shared-variable and dimension management
- Files such as declvar.c, getvar.c, putvar.c, var_addr.c, control_var.c, control_array.c, decldim.c, getdim.c, and setdims-related code show that MMF acts as a registry for model variables and dimensions.
- This is the main integration boundary: modules do not directly own all state; they exchange data through the framework’s named variable/dimension system.
5. Model initialization and configuration flow
- Startup appears to flow through parse_args.c, read_control.c, read_params.c, read_vars.c, and read_datainfo.c.
- Supporting code such as sort_params.c, sort_vars.c, build_lists.c, and check_vars.c indicates validation and ordering of model metadata before simulation begins.
6. Execution orchestration
- mmf.c, call_modules.c, call_setdims.c, batch_run.c, and graph_single_run.c indicate the framework can run a model in different modes, including batch-style execution.
- timing.c, get_times.c, and julday.c/julconvert.c suggest calendar/time-step handling is centralized in the runtime layer.
7. PRMS scientific/process modules
- The prms/ directory contains the hydrologic and climatic process modules that do the actual simulation work.
- Major subsystems include precipitation and temperature distribution (precip_*, temp_*), solar/radiation (ccsolrad, ddsolrad, soltab), evapotranspiration (potet_*), snow (snowcomp), soil water and runoff (soilzone, srunoff, water_balance), groundwater (gwflow), and channel routing/streamflow (routing, muskingum, strmflow, stream_temp).
8. Temporal and spatial domain structure
- Modules such as subbasin, basin, basin_sum, prms_time, nhru_*, nsegment_*, and nsub_summary show that the model is organized around hydrologic response units, subbasins, and stream segments.
- This is the core spatial hierarchy that a diagram should show: basin → subbasin → HRU/segment, with time stepping across the entire domain.
9. Parameter and input handling inside PRMS
- Files like setup_param.f90, convert_params.f90, dynamic_param_read.f90, and water_use_read.f90 handle parameter setup and runtime parameter ingestion.
- obs.f90 and the various climate distribution modules indicate external forcing data are read and spatially distributed before process modules consume them.
10. Outputs and reporting
- Output/reporting is split across summary and export modules such as *_summary.f90, *_ncf.f90, map_results.f90, and write_climate_hru.f90.
- This suggests the model produces both aggregated diagnostic summaries and gridded/per-entity outputs, likely including NetCDF-based products where the *_ncf modules are used.
11. Cross-language architecture boundary
- The repo’s most important architectural boundary is C framework vs. Fortran science kernels.
- The C side manages lifecycle, metadata, memory, and orchestration; the Fortran side computes the hydrologic state transitions and outputs.
12. Practical diagram takeaway
- A good architecture diagram should show: control/input files and arguments feeding the MMF runtime, which initializes shared dimensions/variables, then repeatedly invokes PRMS process modules on each time step, and finally writes summaries and output datasets.
Main entry points: call_modules.c Module call · snowcomp.f90 Hydro processes · mmf.c MMF core · obs.f90 Forcing
Components 18
Build
Top-level and per-component build entry points.
- Top build · Repository-level build entry point.
Makefile - MMF build · Builds the C runtime layer.
mmf/Makefile - PRMS build · Builds the Fortran model layer and final executable.
prms/Makefile
MMF runtime
C framework for control parsing, shared state, and module orchestration.
- MMF core · Main lifecycle entry for the model framework.
mmf/mmf.c - Args · Command-line and run-mode parsing.
mmf/parse_args.c - Control I/O · Reads control files and run metadata.
mmf/read_control.c - Metadata load · Reads parameter and variable definitions before execution.
mmf/read_params.c - Var registry · Named variable and dimension registration plus access helpers.
mmf/declvar.c - Module call · Invokes setup and process modules during the simulation loop.
mmf/call_modules.c - Time base · Handles dates, steps, and simulation timing.
mmf/timing.c
PRMS science
Fortran process modules, domain setup, forcing, and routing.
- Domain init · Defines basin, subbasin, and time structure plus parameter setup.
prms/basin.f90 - Forcing · Reads and distributes precipitation, temperature, and solar forcing.
prms/obs.f90 - Climate dist · Spatially distributes climate inputs to HRUs.
prms/precip_dist2.f90 - Hydro processes · Core snow, soil, groundwater, and runoff calculations.
prms/snowcomp.f90 - ET · Potential evapotranspiration formulations.
prms/potet_pm.f90 - Routing · Channel routing and streamflow propagation.
prms/routing.f90
Connections 21
- Top build → MMF build: builds · Top-level build drives the runtime build.
- Top build → PRMS build: builds · Top-level build drives the model build.
- MMF build → MMF core: compiles · Builds the C runtime executable layer.
- PRMS build → Domain init: compiles · Builds the Fortran model kernel layer.
- Args → Control I/O: feeds · Command-line options select the control/configuration path.
- Control I/O → Metadata load: drives · Control data determines which model metadata are loaded.
- Metadata load → Var registry: registers · Parameter and variable definitions populate the shared registry.
- Var registry → Module call: shares state · Modules exchange data through named variables and dimensions.
- Time base → Module call: ticks · Simulation time advances the execution loop.
- MMF core → Args: starts · Runtime entry begins with argument parsing.
- MMF core → Module call: orchestrates · Core runtime manages module invocation.
- Module call → Domain init: calls · Framework invokes setup and process kernels.
- Domain init → Forcing: requests · Domain setup prepares forcing inputs.
- Forcing → Climate dist: distributes · Observed climate is mapped to HRUs or other spatial units.
- Climate dist → Hydro processes: drives · Distributed forcing feeds the hydrologic kernels.
- Forcing → ET: drives · Forcing data also feeds evapotranspiration calculations.
- ET → Hydro processes: contributes · ET estimates are consumed by the water-balance kernels.
- Hydro processes → Routing: passes flow · Runoff and stream inflow move into routing.
- Routing → Summaries: summarizes · Routing results feed aggregated reporting.
- Hydro processes → Exports: exports · Process state is written to HRU/segment output products.
- Module call → Summaries: finalizes · Framework coordinates end-of-run reporting.