Skip to content

Developer Guide

LiranSc edited this page Apr 10, 2026 · 9 revisions

👨‍💻 Developer Guide

GRANITE v0.6.5 | ← CHANGELOG Summary | Documentation Index & Master Reference →

Condensed developer reference. For the full 52 KB guide see docs/DEVELOPER_GUIDE.md.


1. Coding Standards

Language

  • C++17 exclusively. No C++20 until v1.0 (HPC cluster compiler compatibility).
  • No exceptions in library code. Use GRANITE_ASSERT(cond, msg) and return codes.
  • No std::cout in library code. Use the Logger class (MPI rank-aware).

Naming Conventions

Category Convention Examples
Namespaces snake_case granite::, granite::spacetime, granite::grmhd
Classes PascalCase GridBlock, GRMetric3, CCZ4Solver
Functions camelCase computeRHS(), fillGhostZones()
Variables snake_case conformal_factor, dt_local
Constants UPPER_SNAKE MAX_AMR_LEVELS, NGHOST

Physical Units

Always document units in comments: // [M, G=c=1]
Physical constants must be in include/granite/constants.hpp — never magic numbers.

Formatting

python3 scripts/run_granite.py format  # LLVM clang-format, 100-char limit

2. Pre-PR Checklist

[ ] Full test suite passes: python3 scripts/run_granite.py build --tests
[ ] health_check.py passes
[ ] dev_benchmark.py passes in < 5 minutes
[ ] CHANGELOG.md updated under ## [Unreleased]
[ ] New physics: paper citation in comment (Author Year, Journal Vol, Page)
[ ] No ko_sigma > 0.1 in any YAML or code
[ ] Known Fixed Bugs (C1, C3, H1, H2, H3, TOV, KO-σ, Sommerfeld+BL) verified intact
[ ] No regression in constraint norm growth rate vs. baseline

3. Adding a New Physics Module

Step 1: RFC
  Open GitHub Discussion: "[RFC] New Feature: <name>"
  Include: governing equations, paper references, impact estimate

Step 2: Branch
  git checkout -b feature/<descriptive-name>

Step 3: Implement
  src/<subsystem>/<feature>.cpp
  Follow existing patterns: no exceptions, Logger not cout, units documented

Step 4: Public Interface
  include/granite/<subsystem>/<feature>.hpp
  Only expose what users of the module need

Step 5: Tests
  tests/<subsystem>/test_<feature>.cpp
  Minimum: one unit test + one convergence order test

Step 6: YAML Support
  Add parameters to YAML parser + document in Parameter-Reference wiki

Step 7: Update CHANGELOG.md
  Under ## [Unreleased]

Step 8: PR
  Use the PR template. Include benchmark results showing no regression.

Test Template

TEST(NewFeatureSuite, PhysicsCorrectness) {
    GridBlock state = createTestBlock(32, 32, 32, /*dx=*/0.1);
    initializeMinkowski(state);
    double result = computeNewObservable(state);
    EXPECT_NEAR(result, expected_analytic_value, 1e-10)
        << "Must match analytic value to roundoff";
}

TEST(NewFeatureSuite, ConvergenceOrder) {
    double err_coarse = runAndMeasureError(/*dx=*/0.2);
    double err_fine   = runAndMeasureError(/*dx=*/0.1);
    double order = std::log2(err_coarse / err_fine);
    EXPECT_NEAR(order, 4.0, 0.1) << "Should converge at 4th order";
}

4. Test Suite Structure

tests/
├── core/
│   ├── test_grid.cpp         # GridBlock memory, buffer, MPI neighbor (22 tests)
│   └── test_types.cpp        # Type sizes, NUM_VARS constants (3 tests)
├── spacetime/
│   ├── test_ccz4_flat.cpp    # Flat spacetime RHS=0, KO, selective advection (7 tests)
│   └── test_gauge_wave.cpp   # CCZ4 gauge wave convergence (5 tests)
├── initial_data/
│   ├── test_brill_lindquist.cpp  # BL conformal factor (7 tests)
│   └── test_polytrope.cpp        # TOV solver: M≈1.4M☉, R≈10km (3 tests)
└── grmhd/
    ├── test_grmhd_gr.cpp    # GR-aware HLLE, MP5 accuracy (7 tests)
    ├── test_hlld_ct.cpp     # HLLD + CT ∇·B preservation (7 tests)
    ├── test_ppm.cpp         # PPM reconstruction (5 tests)
    └── test_tabulated_eos.cpp # Nuclear EOS full suite (20 tests)

Total: 92 tests, 100% pass rate (GoogleTest)

5. Build System Reference

# Development cycle
python3 scripts/run_granite.py build --release   # Production build
python3 scripts/run_granite.py build --debug     # Debug + ASan/UBSan
python3 scripts/run_granite.py build --tests     # Build + run all 92 tests
python3 scripts/run_granite.py format            # clang-format all C++
python3 scripts/run_granite.py clean             # Remove build/

# Direct CMake
cmake -B build -DCMAKE_BUILD_TYPE=Release \
    -DGRANITE_ENABLE_MPI=ON \
    -DGRANITE_ENABLE_OMP=ON \
    -DGRANITE_ENABLE_HDF5=ON
cmake --build build -j$(nproc)
ctest --test-dir build --output-on-failure

CMake Options:

Option Default Purpose
GRANITE_ENABLE_MPI ON MPI parallelism
GRANITE_ENABLE_OMP ON OpenMP threading
GRANITE_ENABLE_HDF5 ON HDF5 I/O + checkpoints
GRANITE_ENABLE_CUDA OFF GPU kernels (v0.7 roadmap)
GRANITE_ENABLE_SANITIZERS OFF ASan + UBSan (Debug only)

6. CI/CD Pipeline

GitHub Actions (.github/workflows/ci.yml) runs on every push and PR to main:

  1. Install: gcc-12, openmpi-dev, hdf5-parallel, libomp-dev, yaml-cpp
  2. CMake configure with -DGRANITE_ENABLE_OPENMP=ON
  3. Build Release target
  4. ctest --output-on-failure — must show 92/92 passing
  5. cppcheck static analysis — must return exit code 0

All PRs block on CI failure. No exceptions.


See also: Architecture Overview | Parameter Reference | Known Fixed Bugs

Clone this wiki locally