# nhm-usgs/prms architecture

> Architecture diagram of the GitHub repository nhm-usgs/prms, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nhm-usgs/prms
- Repository: https://github.com/nhm-usgs/prms

## Overview

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: [`mmf/call_modules.c`](https://github.com/nhm-usgs/prms/blob/master/mmf/call_modules.c) (Module call), [`prms/snowcomp.f90`](https://github.com/nhm-usgs/prms/blob/master/prms/snowcomp.f90) (Hydro processes), [`mmf/mmf.c`](https://github.com/nhm-usgs/prms/blob/master/mmf/mmf.c) (MMF core), [`prms/obs.f90`](https://github.com/nhm-usgs/prms/blob/master/prms/obs.f90) (Forcing)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_build["Build"]
  node_makefile["Top build<br/>build script"]
  node_mmf_makefile["MMF build<br/>build script"]
  node_prms_makefile["PRMS build<br/>build script"]
end

subgraph group_mmf["MMF runtime"]
  node_mmf_core["MMF core<br/>runtime core<br/>[mmf.c]"]
  node_arg_parse["Args<br/>startup parsing<br/>[parse_args.c]"]
  node_control_io["Control I/O<br/>control reader<br/>[read_control.c]"]
  node_param_load["Metadata load<br/>[read_params.c]"]
  node_var_registry[("Var registry<br/>shared state<br/>[declvar.c]")]
  node_module_orch["Module call<br/>orchestrator<br/>[call_modules.c]"]
  node_time_base["Time base<br/>calendar/time<br/>[timing.c]"]
end

subgraph group_prms["PRMS science"]
  node_prms_init["Domain init<br/>model setup<br/>[basin.f90]"]
  node_forcing["Forcing<br/>climate input<br/>[obs.f90]"]
  node_climate_dist["Climate dist<br/>distribution<br/>[precip_dist2.f90]"]
  node_hydro["Hydro processes<br/>process kernels<br/>[snowcomp.f90]"]
  node_et["ET<br/>evapotranspiration<br/>[potet_pm.f90]"]
  node_routing["Routing<br/>[routing.f90]"]
end

subgraph group_outputs["Outputs"]
  node_outputs_main["Summaries<br/>reporting<br/>[prms_summary.f90]"]
  node_outputs_grid["Exports<br/>output export<br/>[nhru_ncf.f90]"]
end

node_makefile -->|"builds"| node_mmf_makefile
node_makefile -->|"builds"| node_prms_makefile
node_mmf_makefile -->|"compiles"| node_mmf_core
node_prms_makefile -->|"compiles"| node_prms_init
node_arg_parse -->|"feeds"| node_control_io
node_control_io -->|"drives"| node_param_load
node_param_load -->|"registers"| node_var_registry
node_var_registry -->|"shares state"| node_module_orch
node_time_base -->|"ticks"| node_module_orch
node_mmf_core -->|"starts"| node_arg_parse
node_mmf_core -->|"orchestrates"| node_module_orch
node_module_orch -->|"calls"| node_prms_init
node_prms_init -->|"requests"| node_forcing
node_forcing -->|"distributes"| node_climate_dist
node_climate_dist -->|"drives"| node_hydro
node_forcing -->|"drives"| node_et
node_et -->|"contributes"| node_hydro
node_hydro -->|"passes flow"| node_routing
node_routing -->|"summarizes"| node_outputs_main
node_hydro -->|"exports"| node_outputs_grid
node_module_orch -.->|"finalizes"| node_outputs_main

click node_makefile "https://github.com/nhm-usgs/prms/tree/master/Makefile"
click node_mmf_makefile "https://github.com/nhm-usgs/prms/tree/master/mmf/Makefile"
click node_prms_makefile "https://github.com/nhm-usgs/prms/tree/master/prms/Makefile"
click node_mmf_core "https://github.com/nhm-usgs/prms/blob/master/mmf/mmf.c"
click node_arg_parse "https://github.com/nhm-usgs/prms/blob/master/mmf/parse_args.c"
click node_control_io "https://github.com/nhm-usgs/prms/blob/master/mmf/read_control.c"
click node_param_load "https://github.com/nhm-usgs/prms/blob/master/mmf/read_params.c"
click node_var_registry "https://github.com/nhm-usgs/prms/blob/master/mmf/declvar.c"
click node_module_orch "https://github.com/nhm-usgs/prms/blob/master/mmf/call_modules.c"
click node_time_base "https://github.com/nhm-usgs/prms/blob/master/mmf/timing.c"
click node_prms_init "https://github.com/nhm-usgs/prms/blob/master/prms/basin.f90"
click node_forcing "https://github.com/nhm-usgs/prms/blob/master/prms/obs.f90"
click node_climate_dist "https://github.com/nhm-usgs/prms/blob/master/prms/precip_dist2.f90"
click node_hydro "https://github.com/nhm-usgs/prms/blob/master/prms/snowcomp.f90"
click node_et "https://github.com/nhm-usgs/prms/blob/master/prms/potet_pm.f90"
click node_routing "https://github.com/nhm-usgs/prms/blob/master/prms/routing.f90"
click node_outputs_main "https://github.com/nhm-usgs/prms/blob/master/prms/prms_summary.f90"
click node_outputs_grid "https://github.com/nhm-usgs/prms/blob/master/prms/nhru_ncf.f90"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_makefile,node_mmf_makefile,node_prms_makefile toneBlue
class node_mmf_core,node_arg_parse,node_control_io,node_param_load,node_var_registry,node_module_orch,node_time_base toneAmber
class node_prms_init,node_forcing,node_climate_dist,node_hydro,node_et,node_routing toneMint
class node_outputs_main,node_outputs_grid toneRose
```

## Components

### Build

Top-level and per-component build entry points.

- [Top build](https://github.com/nhm-usgs/prms/tree/master/Makefile): build script · Repository-level build entry point. · `Makefile`
- [MMF build](https://github.com/nhm-usgs/prms/tree/master/mmf/Makefile): build script · Builds the C runtime layer. · `mmf/Makefile`
- [PRMS build](https://github.com/nhm-usgs/prms/tree/master/prms/Makefile): build script · Builds the Fortran model layer and final executable. · `prms/Makefile`

### MMF runtime

C framework for control parsing, shared state, and module orchestration.

- [MMF core](https://github.com/nhm-usgs/prms/blob/master/mmf/mmf.c): runtime core · Main lifecycle entry for the model framework. · `mmf/mmf.c`
- [Args](https://github.com/nhm-usgs/prms/blob/master/mmf/parse_args.c): startup parsing · Command-line and run-mode parsing. · `mmf/parse_args.c`
- [Control I/O](https://github.com/nhm-usgs/prms/blob/master/mmf/read_control.c): control reader · Reads control files and run metadata. · `mmf/read_control.c`
- [Metadata load](https://github.com/nhm-usgs/prms/blob/master/mmf/read_params.c): metadata loader · Reads parameter and variable definitions before execution. · `mmf/read_params.c`
- [Var registry](https://github.com/nhm-usgs/prms/blob/master/mmf/declvar.c): shared state · Named variable and dimension registration plus access helpers. · `mmf/declvar.c`
- [Module call](https://github.com/nhm-usgs/prms/blob/master/mmf/call_modules.c): orchestrator · Invokes setup and process modules during the simulation loop. · `mmf/call_modules.c`
- [Time base](https://github.com/nhm-usgs/prms/blob/master/mmf/timing.c): calendar/time · Handles dates, steps, and simulation timing. · `mmf/timing.c`

### PRMS science

Fortran process modules, domain setup, forcing, and routing.

- [Domain init](https://github.com/nhm-usgs/prms/blob/master/prms/basin.f90): model setup · Defines basin, subbasin, and time structure plus parameter setup. · `prms/basin.f90`
- [Forcing](https://github.com/nhm-usgs/prms/blob/master/prms/obs.f90): climate input · Reads and distributes precipitation, temperature, and solar forcing. · `prms/obs.f90`
- [Climate dist](https://github.com/nhm-usgs/prms/blob/master/prms/precip_dist2.f90): distribution · Spatially distributes climate inputs to HRUs. · `prms/precip_dist2.f90`
- [Hydro processes](https://github.com/nhm-usgs/prms/blob/master/prms/snowcomp.f90): process kernels · Core snow, soil, groundwater, and runoff calculations. · `prms/snowcomp.f90`
- [ET](https://github.com/nhm-usgs/prms/blob/master/prms/potet_pm.f90): evapotranspiration · Potential evapotranspiration formulations. · `prms/potet_pm.f90`
- [Routing](https://github.com/nhm-usgs/prms/blob/master/prms/routing.f90): stream routing · Channel routing and streamflow propagation. · `prms/routing.f90`

### Outputs

Summary and export nodes for model results.

- [Summaries](https://github.com/nhm-usgs/prms/blob/master/prms/prms_summary.f90): reporting · Aggregated model summaries and diagnostics. · `prms/prms_summary.f90`
- [Exports](https://github.com/nhm-usgs/prms/blob/master/prms/nhru_ncf.f90): output export · HRU/segment outputs and gridded or NetCDF products. · `prms/nhru_ncf.f90`

## Connections

- 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.
