| 
 | 1 | +######################################################################  | 
 | 2 | +#  .cursorrules  –  project-level instructions for Cursor AI         #  | 
 | 3 | +#  Target repo: github.com/mflowcode/mfc                             #  | 
 | 4 | +#  Format: plain-text "rules for the Agent". One idea per line.      #  | 
 | 5 | +######################################################################  | 
 | 6 | + | 
 | 7 | +### ───────────────────────────────────────────────────────────────────  | 
 | 8 | +###  1. Global project context (ALWAYS applied)  | 
 | 9 | +### ───────────────────────────────────────────────────────────────────  | 
 | 10 | + | 
 | 11 | +- You are interacting with **MFC** – an exascale, many-physics, multi-component  | 
 | 12 | +  flow solver written in modern Fortran and generated with the Fypp  | 
 | 13 | +  pre-processor. Most source files use the `.fpp` extension (Fypp templates)  | 
 | 14 | +  and are transpiled to `.f90` during the CMake build. A minority of modules  | 
 | 15 | +  remain as plain `.f90`. The code lives in `src/`, tests in `tests/`,  | 
 | 16 | +  and example input cases in `examples/`.  | 
 | 17 | + | 
 | 18 | +- Fypp helper macros live in files under any `include/` directory within  | 
 | 19 | +  `src/` (e.g., `src/<module>/include/`). **Scan these macro files first** so  | 
 | 20 | +  that template expansions resolve correctly.  | 
 | 21 | + | 
 | 22 | +- Always assume free-form Fortran 2008+ (`.fpp` and `.f90`) with `implicit none`,  | 
 | 23 | +  explicit `intent(in|out|inout)`, and modern constructs (`allocate`,  | 
 | 24 | +  `move_alloc`, `iso_fortran_env`, etc.).  | 
 | 25 | + | 
 | 26 | +- Prefer `module` + `contains` → `subroutine foo()` patterns; avoid COMMON  | 
 | 27 | +  blocks and `include` files.  | 
 | 28 | + | 
 | 29 | +- **Simulation kernels are accelerated exclusively with OpenACC.** Always  | 
 | 30 | +  include the appropriate `!$acc` pragmas when generating or modifying  | 
 | 31 | +  performance-critical loops.  | 
 | 32 | + | 
 | 33 | +- **The codebase is written in Fortran 2008+ with the Fypp pre-processor.**  | 
 | 34 | +  Always use the appropriate Fypp macros when generating or modifying  | 
 | 35 | +  performance-critical loops.  | 
 | 36 | + | 
 | 37 | +- **Before suggesting or applying any source-code changes, first read/parse the  | 
 | 38 | +  full codebase *and* the documentation sources listed below, then produce a  | 
 | 39 | +  concise description of how the codebase is structured and functions.**  | 
 | 40 | + | 
 | 41 | +- Documentation sources:  | 
 | 42 | +  - Primary online docs: <https://mflowcode.github.io/documentation/md_readme.html>  | 
 | 43 | +  - Root-level `README.md` in the repository.  | 
 | 44 | + | 
 | 45 | +### ───────────────────────────────────────────────────────────────────  | 
 | 46 | +###  2. Style & naming conventions  (AUTO-ATTACH for *.fpp and *.f90 files)  | 
 | 47 | +### ───────────────────────────────────────────────────────────────────  | 
 | 48 | + | 
 | 49 | +- Indent 2 spaces; continuation lines line up under “&”.  | 
 | 50 | +- No maximum line length is enforced.  | 
 | 51 | +- Prefer shorter, streamlined code—avoid needless verbosity while keeping clarity.  | 
 | 52 | +- Lower-case keywords (`do`, `end subroutine`, etc.).  | 
 | 53 | +- Module names: `m_<feature>` (e.g., `m_transport`).  | 
 | 54 | +- Public procedures: `<verb>_<noun>` (e.g., `compute_flux`) with prefixe `s_` or `f_` for subroutines and functions, respectively.  | 
 | 55 | +- Avoid private helper functions within a subroutine or function, and instead make them private to the module (if appropriate)  | 
 | 56 | +- Helper functions or subroutines start with with f_[name here] or s_[name here], respectively  | 
 | 57 | +- Avoid passing arguments to subroutines and functions that need to be reshaped in the subroutine or function, such that the compiler can optimize the code.  | 
 | 58 | +- Avoid common Fortran code smells, such as:  | 
 | 59 | +  - Use of `goto` statements (except in legacy interop situations).  | 
 | 60 | +  - Omission of `intent(...)` declarations.  | 
 | 61 | +  - Use of global state via `COMMON` blocks or `save` variables.  | 
 | 62 | +  - Shadowing of variable names (especially loop indices).  | 
 | 63 | +  - Non-descriptive or single-letter variable names outside small scopes.  | 
 | 64 | +  - Excessively long helper procedures (>200 lines); prefer decomposition.  | 
 | 65 | +  - Excessively long subroutines (>500 lines); prefer decomposition.  | 
 | 66 | +  - Excessively long functions (>100 lines); prefer decomposition.  | 
 | 67 | +  - Excessively long modules (>1000 lines); prefer decomposition.  | 
 | 68 | +  - Excessively long files (>1000 lines); prefer decomposition.  | 
 | 69 | +  - Subroutines and functions that are too long to be understood at a glance.  | 
 | 70 | +  - Use of `!$acc routine seq` to mark subroutines and functions that are called from OpenACC parallel loops.  | 
 | 71 | +  - Mixing I/O logic with computation (separate concerns).  | 
 | 72 | +  - Missing implicit none statements.  | 
 | 73 | +  - Missing `intent(in|out|inout)` declarations.  | 
 | 74 | +  - Missing `dimension` or `allocatable`/`pointer` attributes.  | 
 | 75 | +  - Missing `private` declarations.  | 
 | 76 | +  - Missing `public` declarations.  | 
 | 77 | +  - Missing `module procedure` declarations.  | 
 | 78 | +  - Missing `use` statements.  | 
 | 79 | +  - Declaring arrays without `dimension` or `allocatable`/`pointer` attributes.  | 
 | 80 | +  - Use of `stop` for error handling (prefer use of the subroutine `s_mpi_abort` with an appropriate string message argument).  | 
 | 81 | + | 
 | 82 | +### ───────────────────────────────────────────────────────────────────  | 
 | 83 | +###  3. Test workflow  (AUTOMATICALLY applied when the code is significantly changed and should be tested)  | 
 | 84 | +### ───────────────────────────────────────────────────────────────────  | 
 | 85 | + | 
 | 86 | +- Run the test suite after any meaningful code change to verify correctness.  | 
 | 87 | +- Ask the user to alter the test suite command so that only the relevant tests are run.  | 
 | 88 | +- When you think you are done with the code changes, run ./mfc.sh test -j $(nproc) -f EA8FA07E -t 9E2CA336  | 
 | 89 | +- Otherwise, only run specific tests that are relevant to the code changes.  | 
 | 90 | +- Do not run ./mfc.sh test -j $(nproc) without any other arguments (it takes too long to run all tests).  | 
 | 91 | + | 
 | 92 | +### ───────────────────────────────────────────────────────────────────  | 
 | 93 | +###  4. OpenACC programming guidelines  (AUTOMATICALLY applied to *.fpp/*.f90)  | 
 | 94 | +### ───────────────────────────────────────────────────────────────────  | 
 | 95 | + | 
 | 96 | +- **Prefer:**  | 
 | 97 | + | 
 | 98 | +  !$acc parallel loop gang vector default(present)  | 
 | 99 | + | 
 | 100 | +  around tight loops over cells or particles; fall back to `!$acc kernels`  | 
 | 101 | +  only when loop dependencies prevent direct parallelization. Always add  | 
 | 102 | +  `reduction` clauses where needed.  | 
 | 103 | + | 
 | 104 | +- Use `collapse(n)` in `!$acc parallel loop` pragmas to combine nested loops  | 
 | 105 | +  when it improves parallelism and the iterations are independent.  | 
 | 106 | + | 
 | 107 | +- Use `private(var1, var2, ...)` clauses for all variables that are local  | 
 | 108 | +  to a parallel region or loop, especially scalar temporaries and loop counters.  | 
 | 109 | + | 
 | 110 | +- Use `!$acc routine seq` to mark subroutines and functions that are called from OpenACC parallel loops.   | 
 | 111 | + | 
 | 112 | +- When adding `!$acc routine seq` put it on the first line after the declaration of the subroutine or function.  | 
 | 113 | + | 
 | 114 | +- Allocate large arrays with the `managed` attribute or move them to the device  | 
 | 115 | +  at program start using a persistent `!$acc enter data` region.  | 
 | 116 | + | 
 | 117 | +- Do **not** place `stop` or `error stop` statements inside OpenACC parallel regions or loops, as they are unsupported in device code and will cause runtime failures.  | 
 | 118 | + | 
 | 119 | +- Ensure the code compiles with Cray Fortran (`ftn`) and NVIDIA HPC SDK  | 
 | 120 | +  (`nvfortran`) for OpenACC GPU offloading, and with GNU (`gfortran`) and Intel  | 
 | 121 | +  (`ifx`/`ifort`) for CPU-only builds where OpenACC directives are ignored.  | 
 | 122 | + | 
 | 123 | +######################################################################  | 
 | 124 | +# End of file  | 
 | 125 | +######################################################################  | 
0 commit comments