|
DNDSR 0.2.1
Distributed Numeric Data Structure for CFV
|
This page collects the detailed coding conventions for DNDSR. It complements the short guardrails in AGENTS.md.
#pragma once in headers; no #ifndef guards.The clang-format configuration lives at src/.clang-format.
"DNDS/Macros.hpp", "DNDS/Defines.hpp")src/): "DNDS/Array.hpp", "Geom/Mesh.hpp"| Element | Convention | Example |
|---|---|---|
| Namespace | PascalCase | DNDS, DNDS::Geom, DNDS::CFV |
| Class / Struct | PascalCase | MPIInfo, VariationalReconstruction |
| Public method | PascalCase | Resize(), ConstructMetrics() |
| Private/protected member | _ prefix | _size, _data, _pRowStart |
| Type alias | t_ prefix or using | t_IndexVec, tDiFj |
| Template parameter | T-prefix or PascalCase | T, TOut, _row_size |
| Constant | PascalCase | UnInitReal, DynamicSize |
| Macro | DNDS_ALL_CAPS | DNDS_INDEX_MAX, DNDS_MPI_REAL |
| Enum value | PascalCase | UnknownElem, Line2, Roe |
From Defines.hpp:
Use the project's assert/check macros from DNDS/Errors.hpp:
Avoid raw assert(). Use DNDS_assert for debug checks and DNDS_check_throw for runtime validation that must remain in release builds.
Eigen::Matrix<real, ...> with the project's real type.if constexpr for compile-time branching on template parameters._explicit_instantiation/ subdirectories.Configuration lives at the project root:
/.clang-tidy — enabled check groups: modernize-*, readability-*, bugprone-*, performance-*, cppcoreguidelines-*, google-build-using-namespace, mpi-*, openmp-* (with a curated list of disabled checks). Used by both command-line clang-tidy and clangd in editors./.clang-tidy-fix — narrow subset intended to be run with --fix./.clang-format — formatting rules./.clangd — editor-only flag tweaks (CUDA/OpenMP handling); intentionally does not duplicate the tidy check list.Run the checkers via the scripts in scripts/:
Both scripts use concurrent.futures internally to parallelize across cores; no external run-clang-tidy helper is needed. The legacy scripts/run-clang-tidy.sh, run-clang-tidy-fix.sh, and run-clang-format.sh still work — they are thin shims that forward to the Python drivers.
Column-aligned macro blocks. Some DNDS_FIELD(...) blocks inside DNDS_DECLARE_CONFIG bodies are hand-aligned for readability. These blocks must be wrapped in // clang-format off / // clang-format on so that automated formatting does not destroy the alignment.
CUDA note. clang-tidy cannot parse nvcc-driven .cu compile commands (nvcc-only flags break clang's CUDA frontend). The runner excludes .cu files by default; headers included from CUDA TUs are still tidied transitively via their .cpp includers. Pass --include-cu to opt in anyway.
NOLINT placement. NOLINTNEXTLINE(check) applies to the immediately following line. Put any rationale comment before the NOLINT directive, not between it and the offending code. When --fix can rewrite the flagged line, use block-form NOLINTBEGIN(check) ... NOLINTEND(check) so the directive survives the rewrite. Every NOLINT marker in the tree is paired with a rationale comment explaining why the check is wrong or inapplicable at that site.
Per-module sanitation status.
| Module | Status | Diagnostics |
|---|---|---|
src/DNDS/ | Clean (2026-04-29) | 1 (unrelated Eigen PCH omp.h) |
src/Solver/ | Not started | — |
src/Geom/ | Not started | — |
src/CFV/ | Not started | — |
src/Euler/ | Not started | — |
src/EulerP/ | Not started | — |
The full cleanup history for DNDS — 26 passes, 24 597 → 1 diagnostics — is recorded in `docs/dev/clang_tidy_plan.md`. That document is the reference for the per-pass recipe, the .clang-tidy disable rationales, and the NOLINT placement gotchas. Use the same recipe for the other modules in the order Solver → Geom → CFV → Euler → EulerP. The existing .clang-tidy disables carry forward unchanged; any new module-specific disables go in the file-header table, not inside the Checks: folded scalar.
Source comments are processed by Doxygen (for the standalone C++ API docs) and by Breathe (to embed them in the Sphinx site). Both systems read the same /// and /** */ comment blocks. The rules below ensure cross-references work in both outputs.
Use /// for single-line doc comments and /** */ for multi-line blocks. Always document the why, not just the what.
Use @ref DNDS::ClassName "ClassName" for fully-qualified references. Doxygen resolves these as hyperlinks in its HTML output. Breathe (Sphinx) also resolves them when the qualified name matches a documented symbol.
Why the "DisplayText" part? Without it, Doxygen renders the full qualified name DNDS::MPIInfo as the link text, which is verbose. @ref DNDS::MPIInfo "MPIInfo" shows just MPIInfo as the link label.
For members of the same class or symbols in the same namespace, use unqualified @ref Name:
Doxygen resolves unqualified names contextually (within the enclosing class/namespace). Breathe cannot resolve these, so they render as plain text in Sphinx — but the Doxygen HTML (served at /doxygen/) has working links.
For macros, use @ref DNDS_assert (macros live in the global scope):
Keep these as backtick inline code (no @ref):
`MPI_Allreduce`, `Eigen::Matrix`, `std::vector``TABLE_Fixed`, `CSR`, `TABLE_StaticMax``_row_size`, `T``Resize(100)`, `operator()`| Command | Purpose | Example |
|---|---|---|
@brief | One-line summary | @brief Resize the array. |
@details | Extended description | Multi-paragraph explanation |
@param name | Document a parameter | @param mpi The MPI context. |
@tparam T | Document a template param | @tparam T Element type. |
@return | Document the return value | @return Number of rows. |
@pre / @post | Pre/post conditions | @pre Array is compressed. |
@sa | "See also" links | @sa Compress, Decompress |
@ref DNDS::Foo "Foo" | Cross-ref to class/struct | See above |
@ref Bar | Cross-ref to local symbol | See above |
@note | Highlighted note | @note Thread-safe. |
@warning | Highlighted warning | @warning Not MPI-safe. |
@code{.cpp} ... @endcode | Code block | Fenced example |
snake_case (test_all_reduce_scalar, meshFile).MPIInfo, VariationalReconstruction_2)._ prefix (_pre_import, _init_mpi).@pytest.fixture for MPI setup.assert statements (not unittest-style).if __name__ == "__main__": blocks.assert np.all(...), assert (arr == val).all().When writing new C++ tests with using namespace DNDS;, qualify DNDS::index, DNDS::real, and DNDS::rowsize in declarations to avoid ambiguity with POSIX index() from <strings.h> (pulled in by doctest).