Skip to content

Commit 137c386

Browse files
committed
Merge master
2 parents 049fd80 + ffcf565 commit 137c386

24 files changed

Lines changed: 3159 additions & 233 deletions

.github/pull_request_template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Explain how you addressed the bug/feature request, what choices you made and why
1010
- [ ] Tests & pre-commit hooks pass
1111
- [ ] Updated documentation if needed
1212
- [ ] Updated changelog.qmd if needed
13+
- [ ] A review by Copilot was done to ensure the requirements in `AGENTS.md` are satisfied
1314

1415
## Additional Notes (optional)
1516
Add any additional notes or information that may be helpful.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Parameter & variable metadata JSON generation
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches: [ master ]
6+
paths: [ "Wflow/src/standard_name/**" ]
7+
pull_request:
8+
paths: [ "Wflow/src/standard_name/**" ]
9+
jobs:
10+
json_gen:
11+
name: JSON generation
12+
runs-on: ubuntu-latest
13+
continue-on-error: true
14+
steps:
15+
- uses: actions/checkout@v6
16+
- uses: julia-actions/cache@v3
17+
- uses: prefix-dev/setup-pixi@v0.9.5
18+
- name: prepare pixi
19+
run: pixi run install-julia
20+
- name: Test parameter metadata JSON generation
21+
run: pixi run parameter_metadata_json_gen
22+
- name: Ensure that there was no change in the metadata
23+
run: git diff --exit-code

AGENTS.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Copilot instructions
2+
3+
Wflow — Julia hydrological modeling framework (Julia ≥ 1.10). Installation via `pixi.toml`.
4+
5+
## Repository layout
6+
- `Wflow/src/` — core package source
7+
- `Wflow/test/` — tests (`TestItemRunner.jl`, `@testitem` macros)
8+
- `build/` — binary compilation scripts
9+
- `server/` — ZMQ-based BMI server
10+
- `docs/` — Quarto documentation (targets hydrologists); Julia code blocks execute using `docs/docs_utils.jl`
11+
- `data/`, `utils/` — test data and utility scripts
12+
13+
## Key dependencies
14+
NCDatasets, BasicModelInterface, Graphs, Polyester, StaticArrays, CFTime, Accessors, Parameters, EnumX, OrderedCollections
15+
16+
## Internal systems (do not reimplement)
17+
- **Unit system** (`units.jl`): `Unit` struct for dimensional analysis, `to_SI`/`from_SI`, timestep-dependent `dt` units
18+
- **Standard name metadata** (`standard_name/`): `OrderedDict` mapping standard names → `ParameterMetadata` (lens, unit, default, type, flags). Used for NetCDF I/O, TOML binding, docs
19+
- **Config system** (`config_structure.jl`, `config_init.jl`, `config_utils.jl`): `Config` wraps TOML as typed `AbstractConfigSection` structs. `InputEntry` handles netCDF ref / uniform value / external name
20+
- **NetCDF I/O** (`io.jl`): `NCReader`/`Writer`; `ncread` combines config lookup + reading + defaults + unit conversion
21+
- **Network/graph** (`network.jl`, `routing/utils.jl`, `subdomains.jl`): `flowgraph` converts LDD → DiGraph; `NetworkLand`/`NetworkRiver` store 1D↔2D index maps, edge connectivity, subdomain decomposition
22+
- **Threading** (`utils.jl`): `threaded_foreach``Threads.@spawn` (≤8 threads) or `Polyester.@batch`
23+
- **Numeric helpers** (`utils.jl`): `scurve`, `pow`, `tosecond`, `bounded_divide`, `lattometres`, `svectorscopy`, etc.
24+
25+
## Architecture
26+
- Central type: `Model{R, L, M, T}` — routing, land model, mass balance, model type tag
27+
- **Land models** (`AbstractLandModel`): vertical per-cell fluxes. `LandHydrologySBM` (hydrology), `SoilLossModel` (sediment)
28+
- **Routing** (`Routing{O,R,S}`): `overland_flow`, `river_flow`, `subsurface_flow` — each concrete or null (`No*` type)
29+
- **Model type tags** (dispatch singletons): `SbmModel`, `SbmGwfModel`, `SedimentModel`
30+
- **Immutable struct updates**: use `@reset` from Accessors.jl
31+
32+
## Simulation loop (`run_timestep!`)
33+
1. `advance!(clock)`
34+
2. `load_dynamic_input!`
35+
3. `storage_prev!`
36+
4. `update_model!`
37+
5. `compute_mass_balance!`
38+
6. `write_output`
39+
40+
## Model types (`config.model.type`)
41+
- `sbm`: SBM soil + kinematic wave subsurface + surface routing (snow, glaciers, reservoirs, demand)
42+
- `sbm_gwf`: like `sbm` but 2D groundwater flow replaces lateral subsurface
43+
- `sediment`: soil erosion/sediment transport, `NoMassBalance`
44+
45+
## Routing (`config.model.land_routing`, `config.model.river_routing`)
46+
- `kinematic_wave` (default): parallel via subdomains
47+
- `local_inertial`: shallow water equations, staggered grid; combined 2D when both land+river use it
48+
49+
## Domain & indexing
50+
- `Domain` has `land`, `river`, `reservoir`, `drain` sub-domains (each: Network + Parameters)
51+
- Internal 1D arrays over active cells only; `indices` (1D→2D), `reverse_indices` (2D→1D, 0=inactive)
52+
53+
## BMI (`bmi.jl`)
54+
- `BMI.initialize`, `update`, `update_until`, `finalize`
55+
- `get_value_ptr` uses standard name lens system; CSDMS-style names
56+
- 6 grid IDs: 0=reservoir, 1=drain, 2=river, 3–5=land
57+
- `API` TOML section lists exposed variables
58+
- Layered soil: name pattern `"soil_layer_N_..."` → SVector index
59+
60+
## States
61+
- Cold/warm start: `config.model.cold_start__flag`; warm reads from `config.state.path_input`
62+
- `extract_required_states(config)`, `check_states(config)`, `set_states!(path, model)`
63+
- 3D (x,y,time) and 4D (x,y,layer,time) NetCDF variables; layered → SVector
64+
65+
## Forcing
66+
- `AtmosphericForcing`: precipitation, potential_evaporation, temperature
67+
- Right-labeling: timestamp marks end of accumulation period
68+
- `load_dynamic_input!` = `update_forcing!` + `update_cyclic!`
69+
- Reservoir: precip/evap averaged over coverage cells, zeroed in land model
70+
71+
## Testing
72+
- To run a subset of test items filtered by name use e.g. for unit tests
73+
74+
```
75+
pixi run julia --project=Wflow --eval='using Pkg; Pkg.test(test_args=[\"unit\"])'
76+
```
77+
78+
- `TestItemRunner.jl` with `@testitem` (not `@testset`); unit tests prefixed `"unit: "`
79+
- Test data: `utils/download_test_data.jl` → Moselle/Piave datasets
80+
- Integration: init model → run 1–2 steps → assert values with ``
81+
- State restart test: continuous run == cold-start + warm-start split
82+
- `Aqua.jl` for code quality checks
83+
84+
## Code style (mandatory)
85+
- Multiple dispatch; prefer immutable structs; `@kwdef` for defaults
86+
- Precise argument types in signatures
87+
- Docstrings on all computational code specifying units of all variables
88+
- No single-symbol iteration variables — use descriptive `*_idx` names
89+
- Minimize function arguments; pass structs, unpack only at lowest level; no `NamedTuple` wrappers
90+
- Code must be clear from hydrological, mathematical, and CS perspectives
91+
92+
## Performance (mandatory)
93+
- Zero allocations during simulation loops
94+
- No type instabilities (`@code_warntype`)
95+
- Target static compatibility
96+
- PrecompileTools.jl for startup
97+
98+
## Documentation
99+
- Quarto-based; Julia code blocks execute during render using `docs/docs_utils.jl`
100+
- Keep non-executed example code in sync with actual source files

0 commit comments

Comments
 (0)