From 1893bde7a8a942b706884f03001547c1ad5383f7 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Tue, 17 Mar 2026 19:06:39 +0000 Subject: [PATCH 1/2] copy from Breeze --- AGENTS.md | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 159 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..e74ee9319 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,158 @@ +# Breeze.jl — Agent Rules + +## Project Overview + +Breeze.jl is Julia software for simulating atmospheric flows. +It relies on [Oceananigans.jl](https://github.com/CliMA/Oceananigans.jl) for grids, fields, solvers, and advection schemes, +with extensions to CloudMicrophysics for microphysical schemes, RRTMGP for radiative transfer solvers, +and interfaces with ClimaOcean for coupled atmosphere-ocean simulations. + +## Language & Environment + +- **Julia 1.10+** | CPU and GPU (CUDA) +- **Key packages**: Oceananigans.jl, CloudMicrophysics.jl, RRTMGP.jl, ClimaOcean.jl, + KernelAbstractions.jl, CUDA.jl, Enzyme.jl, Reactant.jl +- **Style**: ExplicitImports.jl for source code; `using Oceananigans` and `using Breeze` for examples +- **Testing**: ParallelTestRunner.jl for distributed testing + +## Critical Rules + +### Kernel Functions (GPU compatibility) + +- Use `@kernel` / `@index` (KernelAbstractions.jl) +- Kernels must be **type-stable** and **allocation-free** +- Use `ifelse` — never short-circuiting `if`/`else` or ternary `?`/`:` in kernels +- No error messages, no Models inside kernels +- Mark functions called inside kernels with `@inline` +- **Never loop over grid points outside kernels** — use `launch!` +- **Use literal zeros**: `max(0, a)` not `max(zero(FT), a)`. Julia handles type promotion. + +### Type Stability & Memory + +- All structs must be concretely typed. **Never use `Any` as a type parameter or field type.** +- Use the **materialization pattern**: user-facing constructor creates a "skeleton" struct with + placeholder types (like `Nothing`), then `materialize_*` creates the fully-typed version. +- For mutable state within an immutable struct, use a `mutable struct` as the field type. +- Type annotations are for **dispatch**, not documentation +- Minimize allocation; favor inline computation + +### Imports + +- Source code: explicit imports (checked by tests). Never use `import` to extend functions; + always use `Module.function_name(...) = ...` or `function Module.function_name() ... end` +- Exports at the top of module files, before other code +- Import Oceananigans/Breeze names first, then external packages +- Internal Breeze imports use absolute paths, not relative +- Examples/docs: rely on `using Oceananigans` and `using Breeze` + +### Docstrings + +- Use `$(TYPEDSIGNATURES)` from DocStringExtensions.jl (never write explicit signatures) +- **ALWAYS `jldoctest` blocks, NEVER plain `julia` blocks** — doctests are tested; plain blocks rot +- Include expected output after `# output`; prefer `show` methods over boolean comparisons +- **Citations**: Use inline `[Author (year)](@cite Key)` syntax woven into prose +- Use unicode for math (`θ`, `ρ`, `Π`), not LaTeX + +### Software Design + +- Minimize code duplication (allow only for trivial one-liners) +- When something would be better in Oceananigans, add a detailed TODO note +- Almost always extend functions in source code, not in examples +- Coding style: consult `docs/src/appendix/notation.md` for variable names +- Use math or English consistently in expressions; don't mix +- Keyword arguments: no-space for inline `f(x=1)`, single-space for multiline `f(a = 1, b = 2)` + +## Naming Conventions + +- **Files**: snake_case — `atmosphere_model.jl` +- **Types/Constructors**: PascalCase — `AtmosphereModel` +- **Functions**: snake_case — `compute_pressure!` +- **Kernels**: may prefix with underscore — `_kernel_function` +- **Variables**: English long name or unicode from `notation.md`. Add new variables to that table. +- **Avoid abbreviations**: `latitude` not `lat`, `temperature` not `temp` + +## Module Structure + +``` +src/ +├── Breeze.jl # Main module, exports +├── Thermodynamics/ # Thermodynamic states & equations +├── AtmosphereModels/ # Core atmosphere model logic +├── Microphysics/ # Cloud microphysics +├── TurbulenceClosures/ # Including those ported from Oceananigans +├── Advection.jl # Advection operators for anelastic models +├── CompressibleEquations/ # Compressible dynamics +├── AnelasticEquations/ # Anelastic dynamics +├── ParcelModels/ # Parcel model dynamics +└── MoistAirBuoyancies.jl # Legacy buoyancy for Oceananigans.NonhydrostaticModel +``` + +## Breeze Formulations + +Breeze uses "formulations" for different equation sets. Currently `AnelasticDynamics` in conservation +form (all prognostics are densities) with two thermodynamic formulations: + - `LiquidIcePotentialTemperatureThermodynamics` — prognostic `ρθ` + - `StaticEnergyThermodynamics` — prognostic `ρe` + +Planned: fully compressible formulation, `EntropyThermodynamics` (prognostic `ρη`). + +## Common Pitfalls + +1. **Type instability** in kernels — ruins GPU performance +2. **Overconstraining types**: use annotations for dispatch, not documentation +3. **Missing imports**: tests will catch this — add explicit imports +4. **Plain `julia` blocks in docstrings**: always use `jldoctest` +5. **Subtle bugs from missing method imports**, especially in extensions +6. **Never extend `getproperty`** to fix undefined property bugs — fix the caller instead +7. **"Type is not callable"**: variable name shadows a function — rename or qualify +8. **Quick fixes that break correctness**: if a test fails after a change, revisit the original edit +9. **Scope creep in PRs**: keep changes focused on a single concern +10. **Modifying Project.toml dependencies**: never add, remove, or change `[deps]` or `[weakdeps]` + in the root `Project.toml` unless the task absolutely requires it. Dependency changes have + wide-reaching consequences — they affect CI, load time, and downstream compatibility. + Only touch `[compat]` bounds when explicitly asked. + +## Git Workflow & Whitespace + +Follow [ColPrac](https://github.com/SciML/ColPrac). Feature branches, descriptive commits, +update tests and docs with code changes, check CI before merging. + +**PRs fail CI with trailing whitespace or trailing blank lines.** Before committing: +remove trailing whitespace, remove trailing blank lines, ensure file ends with exactly one newline. + +## Agent Behavior + +- Prioritize type stability and GPU compatibility +- Follow established patterns in existing code +- Add tests for new functionality; update exports when adding public API +- Reference physics equations in comments when implementing dynamics +- When unsure: study working examples first (BOMEX, RICO, etc.), look at similar + Oceananigans implementations, review tests for usage patterns + +## Further Reading + +Detailed reference docs are in `.agents/` — read on demand: + +| Document | Content | +|----------|---------| +| `.agents/testing.md` | Running tests, writing tests, debugging, QA | +| `.agents/documentation.md` | Building docs, fast builds, Literate.jl examples, doctest details | +| `.agents/validation.md` | Reproducing paper results, common issues, TC genesis | +| `.agents/physics-debugging.md` | Thermodynamic variables, diagnose-before-fix, model architecture | + +### Auto-loading Rules + +Rules in `.claude/rules/` load automatically when you touch matching files: +- `kernel-rules.md` — GPU kernel requirements (src/) +- `docstring-rules.md` — docstring and jldoctest conventions (src/) +- `testing-rules.md` — test writing and running (test/) +- `docs-rules.md` — documentation building and style (docs/) +- `examples-rules.md` — Literate.jl example conventions (examples/) + +### Skills (slash commands) + +- `/run-tests` — run targeted tests, prioritized by what's likely to break +- `/build-docs` — build documentation locally +- `/add-feature` — checklist for adding new physics/features +- `/new-simulation` — set up, run, and visualize a new simulation +- `/babysit-ci` — monitor CI, auto-fix small issues, retrigger flaky runs diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..43c994c2d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md From 3239ec11f5bfb52ed62f9d3775b852b2f65e9efc Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Tue, 17 Mar 2026 19:14:38 +0000 Subject: [PATCH 2/2] modify agents --- AGENTS.md | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e74ee9319..285469a8c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,18 +1,15 @@ -# Breeze.jl — Agent Rules +# NumericalEarth.jl — Agent Rules ## Project Overview -Breeze.jl is Julia software for simulating atmospheric flows. -It relies on [Oceananigans.jl](https://github.com/CliMA/Oceananigans.jl) for grids, fields, solvers, and advection schemes, -with extensions to CloudMicrophysics for microphysical schemes, RRTMGP for radiative transfer solvers, -and interfaces with ClimaOcean for coupled atmosphere-ocean simulations. +NumericalEarth.jl provides infrastructure for running Earth system model components—ocean, atmosphere, sea ice, and others—coupled together or driven by prescribed datasets. The coupling interface is generic: plug in [Oceananigans.jl](https://github.com/CliMA/Oceananigans.jl) for ocean dynamics, [ClimaSeaIce.jl](https://github.com/CliMA/ClimaSeaIce.jl) for sea ice, SpeedyWeather or other atmospheric models, or use reanalysis products like JRA55 and ERA5 as prescribed forcing. ## Language & Environment - **Julia 1.10+** | CPU and GPU (CUDA) -- **Key packages**: Oceananigans.jl, CloudMicrophysics.jl, RRTMGP.jl, ClimaOcean.jl, +- **Key packages**: Oceananigans.jl, ClimaSeaIce.jl, SpeedyWeather.jl, KernelAbstractions.jl, CUDA.jl, Enzyme.jl, Reactant.jl -- **Style**: ExplicitImports.jl for source code; `using Oceananigans` and `using Breeze` for examples +- **Style**: ExplicitImports.jl for source code; `using NumericalEarth` for examples - **Testing**: ParallelTestRunner.jl for distributed testing ## Critical Rules @@ -41,9 +38,9 @@ and interfaces with ClimaOcean for coupled atmosphere-ocean simulations. - Source code: explicit imports (checked by tests). Never use `import` to extend functions; always use `Module.function_name(...) = ...` or `function Module.function_name() ... end` - Exports at the top of module files, before other code -- Import Oceananigans/Breeze names first, then external packages -- Internal Breeze imports use absolute paths, not relative -- Examples/docs: rely on `using Oceananigans` and `using Breeze` +- Import Oceananigans/NumericalEarth names first, then external packages +- Internal NumericalEarth imports use absolute paths, not relative +- Examples/docs: rely on `using Oceananigans` and `using NumericalEarth` ### Docstrings @@ -75,27 +72,17 @@ and interfaces with ClimaOcean for coupled atmosphere-ocean simulations. ``` src/ -├── Breeze.jl # Main module, exports -├── Thermodynamics/ # Thermodynamic states & equations -├── AtmosphereModels/ # Core atmosphere model logic -├── Microphysics/ # Cloud microphysics -├── TurbulenceClosures/ # Including those ported from Oceananigans -├── Advection.jl # Advection operators for anelastic models -├── CompressibleEquations/ # Compressible dynamics -├── AnelasticEquations/ # Anelastic dynamics -├── ParcelModels/ # Parcel model dynamics -└── MoistAirBuoyancies.jl # Legacy buoyancy for Oceananigans.NonhydrostaticModel +├── NumericalEarth.jl # Main module, exports +├── Atmospheres/ # Interfaces for atmospheres (prescribed or diagnostic) +├── Bathymetry/ # Module for downloading and modifying bathymetry and topography +├── DataWrangling/ # Interfaces for atmospheres (prescribed or diagnostic) +├── Diagnostics/ # Various diagnostics from all model components +├── EarthSystemModels/ # Module that brings all Earth system model components together +├── InitialConditions/ # Module for initial conditions +├── Oceans/ # Interfaces for oceans (prescribed or diagnostic) +└── SeaIces/ # Interfaces for sea ices (prescribed or diagnostic) ``` -## Breeze Formulations - -Breeze uses "formulations" for different equation sets. Currently `AnelasticDynamics` in conservation -form (all prognostics are densities) with two thermodynamic formulations: - - `LiquidIcePotentialTemperatureThermodynamics` — prognostic `ρθ` - - `StaticEnergyThermodynamics` — prognostic `ρe` - -Planned: fully compressible formulation, `EntropyThermodynamics` (prognostic `ρη`). - ## Common Pitfalls 1. **Type instability** in kernels — ruins GPU performance