|
| 1 | +<!-- |
| 2 | +Project-specific Copilot instructions for the schism-esmf repository. |
| 3 | +Keep this short and actionable: what an automated coding agent needs to know to be |
| 4 | +productive here (architecture, build/test/dev flows, conventions, and integration points). |
| 5 | +--> |
| 6 | +# schism-esmf — Copilot / automated agent instructions |
| 7 | + |
| 8 | +Quick orientation (big picture) |
| 9 | +- This repository provides ESMF/NUOPC "caps" that wrap a pre-built SCHISM hydrodynamics |
| 10 | + library so it can be used as an ESMF/NUOPC component. Key outputs are libraries |
| 11 | + (eg. `libesmf_schism.a`, `libschism_nuopc.a`) and executables `main_esmf` / `main_nuopc`. |
| 12 | +- Major directories: `src/` (Fortran sources and subcomponents), `example/` (setups/tests), |
| 13 | + `scripts/` (helpers to create setups), and `cmake/` (custom CMake helpers, notably ESMF discovery). |
| 14 | + |
| 15 | +What to assume when editing/building |
| 16 | +- SCHISM is expected to be pre-built. The build system requires `SCHISM_BUILD_DIR` to point |
| 17 | + to a SCHISM build (contains `include/` and `lib/` with SCHISM libraries). See `CMakeLists.txt`. |
| 18 | + Required SCHISM libraries: `libcore.a`, `libhydro.a`, `libturbulence.a`, `libyaml.a`, `libparmetis.a`, `libmetis.a` |
| 19 | +- ESMF is discovered via an `esmf.mk` file; provide it via the environment variable `ESMFMKFILE` |
| 20 | + (or let `cmake/FindESMF.cmake` locate it). The CMake helper `cmake/FindESMF.cmake` parses the |
| 21 | + ESMF makefile and exposes include/lib variables and an `ESMF::ESMF` target. |
| 22 | +- **CRITICAL**: ESMF must be built with real MPI support (`ESMF_COMM=mpich` or `openmpi`), NOT `mpiuni` (MPI stub). |
| 23 | + Check with: `grep ESMF_COMM $ESMFMKFILE` |
| 24 | + |
| 25 | +Build and test commands (concrete) |
| 26 | +- Fast: set env vars, configure, build |
| 27 | + ```bash |
| 28 | + export ESMFMKFILE=/path/to/esmf.mk |
| 29 | + export SCHISM_BUILD_DIR=/path/to/schism/build |
| 30 | + mkdir -p build && cd build |
| 31 | + cmake .. |
| 32 | + cmake --build . -- -j$(nproc) |
| 33 | + ``` |
| 34 | +- **macOS-specific**: Install ESMF with MPI support, use Homebrew/conda gfortran |
| 35 | + ```bash |
| 36 | + # Install ESMF with MPI (choose one MPI implementation) |
| 37 | + mamba install -c conda-forge "esmf=8.9.0=mpi_mpich*" |
| 38 | + # or |
| 39 | + mamba install -c conda-forge "esmf=8.9.0=mpi_openmpi*" |
| 40 | + |
| 41 | + export ESMFMKFILE=/path/to/esmf.mk |
| 42 | + export SCHISM_BUILD_DIR=/path/to/schism/build |
| 43 | + mkdir -p build && cd build |
| 44 | + cmake .. \ |
| 45 | + -DCMAKE_Fortran_COMPILER=$(which gfortran) \ |
| 46 | + -DCMAKE_C_COMPILER=$(which gcc) |
| 47 | + cmake --build . -- -j$(sysctl -n hw.ncpu) |
| 48 | + ``` |
| 49 | +- Legacy Make: The repo also supports its historical top-level `Makefile` workflow; some docs/examples |
| 50 | + mention using `make all` in the repository root or `make` inside `example/` to exercise runs. |
| 51 | +- To run example setups: go to `example/` and run `make` as described by `scripts/ReadMe.md` and `example/Makefile`. |
| 52 | + |
| 53 | +CI-ready checklist (for automated builds) |
| 54 | +1. Ensure `ESMFMKFILE` points to a valid `esmf.mk` (check existence: `test -f "$ESMFMKFILE"`). |
| 55 | +2. **Verify ESMF has MPI support**: `grep ESMF_COMM "$ESMFMKFILE" | grep -v mpiuni` (must show `mpich` or `openmpi`). |
| 56 | +3. Ensure `SCHISM_BUILD_DIR` points to a pre-built SCHISM with all required libraries: |
| 57 | + ```bash |
| 58 | + test -f "$SCHISM_BUILD_DIR/lib/libhydro.a" && \ |
| 59 | + test -f "$SCHISM_BUILD_DIR/lib/libcore.a" && \ |
| 60 | + test -f "$SCHISM_BUILD_DIR/lib/libturbulence.a" && \ |
| 61 | + test -f "$SCHISM_BUILD_DIR/lib/libyaml.a" |
| 62 | + ``` |
| 63 | +4. Set `CMAKE_Fortran_COMPILER` to an MPI-aware wrapper (e.g., `mpif90`, `esmpifort`) — CMake will warn if you use a bare compiler. |
| 64 | +5. Run CMake configure with explicit compiler flags and capture stderr for "FATAL_ERROR" or "WARNING" messages. |
| 65 | +6. Run `cmake --build . -- VERBOSE=1` to see full compile/link commands and catch missing symbols early. |
| 66 | +6. Optional: run a quick smoke test by executing `./main_esmf --help` or similar (if applicable) to verify linkage. |
| 67 | + |
| 68 | +**Automated validation**: Run `.github/test-cmake-instructions.sh` to validate your environment against this checklist. |
| 69 | +See `.github/TEST_README.md` for details. |
| 70 | + |
| 71 | +**Build troubleshooting**: If build fails, see `.github/BUILD_TROUBLESHOOTING.md` for detailed solutions to common issues: |
| 72 | +- MPI/ParMETIS symbol mismatches |
| 73 | +- Missing module files |
| 74 | +- MOSSCO dependencies |
| 75 | +- Compile option parsing errors |
| 76 | + |
| 77 | +Important patterns & conventions |
| 78 | +- Fortran modules are written in `.F90` files and CMake emits them into a centralized |
| 79 | + modules directory (`CMAKE_Fortran_MODULE_DIRECTORY` configured to `build/modules`). When adding |
| 80 | + new modules, ensure consumers see the `target_include_directories(...)` or that targets are linked |
| 81 | + in the correct CMake subdirectory (see `src/CMakeLists.txt`). |
| 82 | +- **Shared source pattern**: Common Fortran sources used by multiple targets (e.g., `schism_bmi.F90`, |
| 83 | + `schism_esmf_util.F90`) are compiled once in a separate library (`schism_interface_common`) to avoid |
| 84 | + parallel build race conditions. See `src/schism/CMakeLists.txt` for the pattern. |
| 85 | +- SCHISM dependency chain: CMake discovers and links in this order: |
| 86 | + 1. SCHISM core libraries: `libcore.a`, `libhydro.a` |
| 87 | + 2. SCHISM dependencies: `libturbulence.a`, `libyaml.a`, `libparmetis.a`, `libmetis.a` |
| 88 | + 3. MPI libraries: `find_package(MPI REQUIRED)` provides `${MPI_Fortran_LIBRARIES}` |
| 89 | +- Optional integrations: PDAF (data assimilation) and MOSSCO are optional — guard changes so they compile |
| 90 | + when absent. See `scripts/Readme.md` and `src/` subdirs referencing PDAF and MOSSCO. |
| 91 | + |
| 92 | +Where to make changes |
| 93 | +- High-level code: `src/` (subdirs `driver/`, `model/`, `schism/`). Add tests or example inputs under `example/`. |
| 94 | +- Build logic and ESMF wiring: `cmake/` and top-level `CMakeLists.txt`. Small edits to linking are usually |
| 95 | + localized in `src/CMakeLists.txt` or `src/schism/CMakeLists.txt`. |
| 96 | + |
| 97 | +Debugging and verification tips |
| 98 | +- Build with verbose output: `cmake --build . -- VERBOSE=1` or `make VERBOSE=1` to see compiler/linker commands. |
| 99 | +- If ESMF or SCHISM symbols are missing at link time, verify `ESMFMKFILE` and `SCHISM_BUILD_DIR` and inspect |
| 100 | + `cmake/FindESMF.cmake` behavior (it exports `ESMF_INCLUDE_DIRS` and `ESMF_LIBRARIES`). |
| 101 | +- Module (.mod) problems: ensure `CMAKE_Fortran_MODULE_DIRECTORY` is consistent and that targets depend on the target |
| 102 | + that creates the module (use `target_link_libraries` and `target_include_directories` instead of global include hacks). |
| 103 | + |
| 104 | +Examples from the codebase |
| 105 | +- See `ReadMe.md` at project root for env var examples (ESMFMKFILE and SCHISM_BUILD_DIR). |
| 106 | +- See `cmake/FindESMF.cmake` for how ESMF variables and the `ESMF::ESMF` target are produced. |
| 107 | +- See `src/CMakeLists.txt` for how `main_esmf` and `main_nuopc` are declared and linked. |
| 108 | + |
| 109 | +Do not assume |
| 110 | +- That SCHISM or ESMF will be built by this repository — they are external prerequisites. |
| 111 | +- That all example workflows are unit-tested; many are manual and exercised via `example/` and `scripts/`. |
| 112 | + |
| 113 | +When in doubt |
| 114 | +- Prefer minimal, scoped changes: update or add a CMake target in the specific `src/` subdirectory rather than global edits. |
| 115 | +- Add small runnable examples under `example/` when introducing behavior changes so CI or local runs can validate them. |
| 116 | + |
| 117 | +If anything here is unclear or you'd like me to expand a section (build matrix, tests, or common failure modes), tell me which part and I'll iterate. |
| 118 | + |
| 119 | +### Style to consider |
| 120 | + |
| 121 | +Always use camelcase for naming the ReadMe.md files in each directory. Same with BuildTroubleshooting.md and TestReadMe.md and other markdown files. |
0 commit comments