mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-21 02:18:56 +00:00
docs: Add AGENTS entrypoint and repository layout guide
Introduce root-level AGENTS.md as the architecture and workflow summary for humans and coding agents. Add docs/src/repository_layout.md as a placement and anti-pattern reference for sources, tests, scripts, and gitignored trees. - AGENTS.md links deep docs and states 2.0 invariants - repository_layout.md includes .cursor/ as gitignored local tooling
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
# AGENTS.md: Quick guide for AI coding agents working on JuliaFEM.jl
|
||||
|
||||
This file is the entry point for any AI agent (Cursor, Copilot, Codex, …)
|
||||
that opens this repository. Read it first; then jump to the linked,
|
||||
authoritative documents for details.
|
||||
|
||||
The package version is **0.x** (see `Project.toml`); the repository is in the
|
||||
middle of a deliberate architectural reset toward a **stable 1.0** (monorepo,
|
||||
type-stable, zero-allocation, GPU-ready). Many older files, README.md sections,
|
||||
and design notes still describe the *previous* API. When in doubt, trust the
|
||||
code and this file over older READMEs.
|
||||
|
||||
---
|
||||
|
||||
## 1. What this project is
|
||||
|
||||
JuliaFEM.jl is an open-source finite element framework written in Julia.
|
||||
It is being rebuilt from first principles around four ideas:
|
||||
|
||||
1. Ciarlet's triple as a type. `Element{K, P, S, N}` encodes the
|
||||
reference domain `K`, polynomial space `P`, DOF specification `S`
|
||||
and total DOF count `N` purely at the type level. The element
|
||||
instance carries only `id` and `dof_indices::NTuple{N, UInt64}`.
|
||||
2. Element as template, not bag of fields. Heavy structural
|
||||
information (which local DOF is which field/entity/component) is
|
||||
produced by `@generated` functions over the element type, so the
|
||||
compiler can fold it into constants. The canonical example is
|
||||
`local_dof_layout(::Type{Element{K,P,S,N}})` returning an
|
||||
`NTuple{N, DOFLayoutEntry}`.
|
||||
3. Microkernels. Assembly is built from small `evaluate`-style
|
||||
functions that compute a single scalar (or block) and are
|
||||
dispatched at compile time. No `Dict`, no `Any`, no boxing.
|
||||
4. Zero-allocation hot paths. Pre-allocated caches plus
|
||||
trait-based material dispatch let the inner loops run with zero GC
|
||||
allocation sites in the optimized LLVM IR.
|
||||
|
||||
The long-term vision (parallelism, GPU, Newton–Krylov, multiphysics,
|
||||
billions of DOF) is documented in [`llm/vision/vision_2.0.md`](llm/vision/vision_2.0.md)
|
||||
(the filename is historical; it is not a shipped “JuliaFEM 2.0” product line).
|
||||
|
||||
---
|
||||
|
||||
## 2. Where things live
|
||||
|
||||
The authoritative file-organization guide is
|
||||
[`docs/src/repository_layout.md`](docs/src/repository_layout.md). Highlights:
|
||||
|
||||
| Folder | What goes there |
|
||||
|---|---|
|
||||
| `src/topology/` | Reference shapes (`Triangle`, `Tetrahedron`, `Hexahedron`, …). |
|
||||
| `src/basis/` | Shape functions (`Lagrange`, `Serendipity`). |
|
||||
| `src/quadrature/` | Integration rules. |
|
||||
| `src/mesh/` | `Mesh{N,Topo}`, structured/unstructured meshes. |
|
||||
| `src/dofs/` | `DOF{Q,E}`, `@DOFSet`, `DOFHandler` (type-stable), DOF connectivity. |
|
||||
| `src/elements/` | `Element{K,P,S,N}` + `local_dof_layout`. |
|
||||
| `src/materials/` | `LinearElastic`, `PerfectPlasticity`, …; trait-based dispatch. |
|
||||
| `src/assemblers/` | `ElementBasedAssembler`, `DOFBasedCOOAssembler`, caches, scatter routines. |
|
||||
| `src/domains/` | Physics kernels per discipline (`continuum/`, `beams/`, `plates/`, …). |
|
||||
| `src/solvers/` | Linear/nonlinear solvers (still minimal). |
|
||||
| `src/physics/` | High-level user API (BCs, problems). |
|
||||
| `src/io/` | Mesh readers (Gmsh by default; Abaqus + Aster live in `Legacy`). |
|
||||
| `src/legacy/` | Older pre-reset API (`Problem`/`Assembly`/`Solver`/`Analysis`, Dict-based fields, Abaqus reader, …) wrapped in `module Legacy`; loaded only when `JULIAFEM_ENABLE_LEGACY=1`. |
|
||||
| `test/<topic>/` | Mirrors `src/<topic>/`. |
|
||||
| `benchmarks/regression/`, `benchmarks/analysis/` | Timestamped reports. |
|
||||
| `docs/src/` | Documenter-built `index.md` and `api.md`. |
|
||||
| `docs/NEWS.md` | Short 0.x changelog (not the Quarto site). |
|
||||
| `docs/tutorials/` | Historical Jupyter notebooks (2015–2016 API; reference only). |
|
||||
| `prototypes/`, `.trash/`, `llm/` | Gitignored: experiments, throwaway, AI session logs. |
|
||||
|
||||
The per-module READMEs under `src/<topic>/` and the user-facing pages
|
||||
under `docs/src/` were rewritten on 2026-05-08 to match the current
|
||||
type-stable API. If you find a document that still references `DOFManager`,
|
||||
`register_fields!`, `count_field_dofs`, `@NamedTuple{u::Tuple{...}}`,
|
||||
the legacy `Physics`/`DirichletBC`/`add_dirichlet!` API or the
|
||||
nonexistent `docs/contributor/` tree, treat it as stale and update or
|
||||
delete it in the same change.
|
||||
|
||||
---
|
||||
|
||||
## 3. Current architecture (0.x)
|
||||
|
||||
### 3.1 DOF specification
|
||||
|
||||
```julia
|
||||
# Single field
|
||||
S = @DOFSet{u::DOF{Displacement{3}, Vertex}}
|
||||
|
||||
# Multi-field (e.g. thermo-mechanical)
|
||||
S = @DOFSet{T::DOF{Temperature, Vertex},
|
||||
u::DOF{Displacement{3}, Vertex}}
|
||||
|
||||
# `S` is a NamedTuple type whose values are `DOF{Quantity, Entity}`.
|
||||
```
|
||||
|
||||
`Quantity` is anything with a defined `dof_size` (`Float64 → 1`, `Vec{3} → 3`,
|
||||
`Tensor{2,3} → 9`, …). `Entity` is one of `Vertex`, `Edge`, `Face`, `Cell`.
|
||||
|
||||
### 3.2 DOF handler
|
||||
|
||||
`DOFHandler{M, S, NF}` (in `src/dofs/dof_handler.jl`) is the type-stable
|
||||
replacement for the legacy `Dict`-based `DOFManager`:
|
||||
|
||||
- One flat `Vector{Int}` per field stores the starting DOF for each
|
||||
entity ID.
|
||||
- `total_dofs` is computed once at element creation.
|
||||
- A `@generated _make_element_dofs(...)` unrolls the
|
||||
field/entity/component loop at compile time, so building
|
||||
`element.dof_indices` is allocation-free.
|
||||
- `DOFManager` is kept as a backward-compat alias.
|
||||
|
||||
```julia
|
||||
elements, handler = create_elements!(mesh, Element{Hex8, Lagrange{1}, S})
|
||||
# handler isa DOFHandler{Mesh{...}, S, NF}
|
||||
# elements::Vector{Element{Hex8, Lagrange{1}, S, 24}}
|
||||
# handler.dof_connectivity::DOFConnectivity already built
|
||||
```
|
||||
|
||||
### 3.3 Element template (compile-time DOF layout)
|
||||
|
||||
`local_dof_layout(::Type{Element{K,P,S,N}})` is a `@generated` function
|
||||
returning `NTuple{N, DOFLayoutEntry}` where each entry describes
|
||||
`(field_idx, entity_local, component)` for one local DOF. The compiler
|
||||
folds this into `Core.Const(...)` at the call site, so DOF decoding
|
||||
becomes a tuple lookup with no runtime arithmetic.
|
||||
|
||||
Use `field_idx`, `entity_local`, `component` accessors (exported).
|
||||
|
||||
### 3.4 Assemblers
|
||||
|
||||
Two production assemblers, both type-stable and zero-allocation after
|
||||
warmup:
|
||||
|
||||
- `ElementBasedAssembler` (`src/assemblers/element_based/element_based_coo.jl`):
|
||||
classical element-by-element assembly, scatter into COO triplets.
|
||||
Gold standard for correctness.
|
||||
- `DOFBasedCOOAssembler` (`src/assemblers/dof_based/dof_based_coo.jl`):
|
||||
walks DOF rows, dispatches into per-element scratch using
|
||||
`local_dof_layout(E)`. Stepping stone toward a GPU/matrix-free
|
||||
pipeline. Currently single-kernel, `ContinuumKernel`-only.
|
||||
|
||||
### 3.5 Materials and caches
|
||||
|
||||
- `AbstractMaterial` → behavior trait (`StatelessConstantTangent`,
|
||||
`StatelessStrainDependent`, `StatefulStrainDependent`).
|
||||
- `compute_stress(material, ε, state, t) → (σ, 𝔻, new_state)`.
|
||||
- Caches:
|
||||
- `GeometryCache`: coords, `∇N`, `detJ·w`.
|
||||
- `ElementCache`: element-level scratch (DOF mapping, IPs).
|
||||
- `AssemblyMaterialWorkspace{FieldType, StateType}`: per-IP
|
||||
NamedTuples of fields and states (type-stable, zero-allocation).
|
||||
- `GlobalMaterialCache`: state across timesteps.
|
||||
|
||||
### 3.6 Distributed matrix-free matvec (MPI)
|
||||
|
||||
`MPI` is a weak dependency; `using MPI` after `JuliaFEM` loads `JuliaFEMMPIExt`.
|
||||
Partition metadata lives in `src/assemblers/partitioning.jl`, `halo_exchange.jl`,
|
||||
and `packed_layout.jl` (`build_partition_packed_layout_for_matvec`,
|
||||
`build_matvec_halo_exchanges`, `RankHaloExchange`, `PartitionPackedLayout`).
|
||||
|
||||
For Krylov solves without a full-length replicated workspace, use
|
||||
`mpi_partitioned_operator_matvec_owned!` with `partitioned_mpi_owned_matvec_workspace`
|
||||
and pass a persistent `mpi_requests` buffer from `allocate_exchange_matvec_halo_mpi_requests`
|
||||
so each matvec does not allocate a fresh `Vector{MPI.Request}`.
|
||||
|
||||
Reference drivers: `test/mpi/partitioned_matvec_smoke.jl`,
|
||||
`test/mpi/partitioned_matvec_cg.jl`. CI runs both under mpiexec (see
|
||||
`.github/workflows/CI.yml`, job `mpi-partitioned-matvec-smoke`).
|
||||
|
||||
---
|
||||
|
||||
## 4. Invariants the agent must preserve
|
||||
|
||||
These are non-negotiable. Tests and code analysis enforce them.
|
||||
|
||||
1. Zero allocations in hot paths.
|
||||
`test/assemblers/test_dof_based_zero_alloc.jl` asserts
|
||||
`@allocated assemble!(...) == 0` and `0` GC allocation sites in the
|
||||
optimized LLVM IR. Don't introduce `Dict`, `Vector{Any}`, untyped
|
||||
closures, or `Vector` literals inside loops.
|
||||
2. Type stability everywhere on the hot path.
|
||||
`Base.promote_op(assemble!, ...) === Nothing` and the inferred
|
||||
types must be concrete. Use `NamedTuple` (typed), `NTuple`, and
|
||||
compile-time helpers, not `Dict`.
|
||||
3. Element template == single source of truth.
|
||||
Anything you'd be tempted to compute as `div`/`mod` over local DOF
|
||||
indices probably belongs in a `@generated` function on
|
||||
`Element{K,P,S,N}` and queried via accessors like
|
||||
`local_dof_layout`.
|
||||
4. Mirror src/ in test/. Tests for `src/foo/bar.jl` go in
|
||||
`test/foo/test_bar.jl`. A topic-level test file should be wired
|
||||
into `test/runtests.jl`.
|
||||
5. Zero stdlib drift. New Julia stdlib deps (`InteractiveUtils`,
|
||||
`Profile`, …) must be added to `[extras]` and the relevant
|
||||
`[targets]` in `Project.toml`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Critical workflow rules
|
||||
|
||||
Contributor-facing workflow text lives in `.github/prompts/commit.prompt.md`
|
||||
and `.github/copilot-instructions.md`. Optional `.githooks/pre-commit`
|
||||
(enabling `core.hooksPath`) caps staged paths at two per commit.
|
||||
Editor-local Cursor rules under `.cursor/` are not part of the git tree.
|
||||
|
||||
- Commits: prefer **small** steps (default one file per commit). Combine
|
||||
multiple files only when they share one logical story (exception—justify
|
||||
why). Never `git add .` or `git add -A` unless the user asks; stage paths
|
||||
deliberately. Read the **full** staged diff (no `head`/`tail`). Message
|
||||
format: Conventional Commits **subject**, blank line, **1–3 sentence**
|
||||
summary, then optional **bullet** details. **Propose** paths + full message
|
||||
and wait for **explicit approval** before each `git commit`. See
|
||||
`.github/prompts/commit.prompt.md` for the full protocol.
|
||||
- Never commit without an explicit user command to start committing. Do not
|
||||
propose or initiate commits unprompted.
|
||||
- Never create files in the root except for `README*` files.
|
||||
Session logs go to `llm/sessions/YYYY-MM-DD-topic.md`. Throwaway
|
||||
scripts go to `.trash/`. Experimental code goes to `prototypes/`.
|
||||
- `prototypes/`, `.trash/`, `llm/` are gitignored. Use freely; do
|
||||
not try to commit them.
|
||||
- Run the full test suite before declaring done.
|
||||
`julia --project=. -e 'using Pkg; Pkg.test()'`. All bundled topic tests must pass
|
||||
with no errors (the exact test count grows with the tree under `test/`).
|
||||
|
||||
---
|
||||
|
||||
## 6. Documentation style
|
||||
|
||||
When writing documentation, session logs, READMEs, guides, comments, or
|
||||
design notes:
|
||||
|
||||
- Avoid emoji.
|
||||
- Avoid markdown bold for emphasis. Do not write `bold` prose unless
|
||||
preserving an existing quoted source that already uses it.
|
||||
- Prefer plain technical writing with clear headings, short paragraphs,
|
||||
and precise code references.
|
||||
- Do not over-emphasize ordinary terms. If every second word needs
|
||||
emphasis, the sentence should be rewritten instead.
|
||||
|
||||
The goal is professional engineering documentation, not marketing copy.
|
||||
|
||||
---
|
||||
|
||||
## 7. Common entry points
|
||||
|
||||
- Build a model and assemble:
|
||||
```julia
|
||||
mesh = create_structured_box_mesh(...)
|
||||
S = @DOFSet{u::DOF{Displacement{3}, Vertex}}
|
||||
ET = Element{Hex8, Lagrange{1}, S}
|
||||
elements, handler = create_elements!(mesh, ET)
|
||||
|
||||
material = LinearElastic(E=210e9, ν=0.3)
|
||||
kernel = ContinuumKernel(ContinuumFormulation{FullThreeD}(),
|
||||
material, Displacement{3}())
|
||||
|
||||
asm = DOFBasedCOOAssembler() # or COOAssembler()
|
||||
cache = create_cache(asm, elements, handler, mesh, kernel)
|
||||
assemble!(cache, asm, kernel, mesh)
|
||||
K, f = extract_system(cache)
|
||||
```
|
||||
- Inspect the compile-time DOF layout:
|
||||
```julia
|
||||
using JuliaFEM
|
||||
S = @DOFSet{u::DOF{Displacement{3}, Vertex}}
|
||||
ET = Element{Hex8, Lagrange{1}, S, 24}
|
||||
local_dof_layout(ET) # NTuple{24, DOFLayoutEntry}
|
||||
```
|
||||
- Regression + code analysis:
|
||||
`test/assemblers/test_dof_based_zero_alloc.jl`
|
||||
- Top-level architecture overview: `src/README.md`. Per-module
|
||||
details: the `README.md` files inside `src/<topic>/`.
|
||||
- Vision and roadmap: `llm/vision/vision_2.0.md`.
|
||||
|
||||
### Documentation doors (which prose to open first)
|
||||
|
||||
| Goal | Start here |
|
||||
|------|------------|
|
||||
| Shortest runnable assembly in the package docs | `docs/src/index.md` and `docs/src/snippets/minimal_elasticity_quickstart.jl` |
|
||||
| Ordered reading on the Quarto site | `juliafem.github.io/learning_path.md` |
|
||||
| Authoritative versus archival site material | `juliafem.github.io/docs/documentation-map.md` |
|
||||
| New domain kernel or assembler hook | `juliafem.github.io/docs/developer-guide/kernel_extension_contract.md` |
|
||||
| Multi-field thermo-mechanical narrative | `docs/src/thermo_elastic_walkthrough.md` |
|
||||
| Quarto site colors / logo / naming | `juliafem.github.io/docs/contributor-guide/design_system.md` |
|
||||
| Where new files go in the repo | `docs/src/repository_layout.md` (pointer: `docs/repository_layout.md`) |
|
||||
|
||||
---
|
||||
|
||||
## 8. When you are unsure
|
||||
|
||||
1. Search the code first (`Grep` / `SemanticSearch`).
|
||||
2. Check the relevant `test/<topic>/` for examples.
|
||||
3. If there's a recent `llm/sessions/YYYY-MM-DD-*.md` log on the topic,
|
||||
read it for context.
|
||||
4. Ask the user. Do not guess silently in a high-impact module.
|
||||
@@ -0,0 +1,273 @@
|
||||
# Repository layout
|
||||
|
||||
Guide for contributors (and editor tooling) on where files belong in the JuliaFEM.jl tree. Read this together with [`AGENTS.md`](https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/AGENTS.md) (architecture and invariants) and [`src/README.md`](https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/src/README.md) (per-module overview).
|
||||
|
||||
Last updated: 2026-05-09.
|
||||
|
||||
---
|
||||
|
||||
## Organisational philosophy
|
||||
|
||||
Prefer subdirectories over flat structures.
|
||||
|
||||
When several files deal with the same topic, group them into a topic subdirectory:
|
||||
|
||||
- The subdirectory has its own `README.md` describing purpose and status.
|
||||
- Related files stay together.
|
||||
- An optional `Project.toml` keeps extra dependencies local instead of growing the main package manifest.
|
||||
|
||||
Examples:
|
||||
|
||||
- `src/materials/` for material models.
|
||||
- `test/materials/` for matching tests.
|
||||
- `benchmarks/regression/` for CI regression benchmarks and reports.
|
||||
- `benchmarks/analysis/` for exploratory or architecture benchmarks.
|
||||
|
||||
Avoid flat directories with dozens of unrelated files.
|
||||
|
||||
---
|
||||
|
||||
## Source code
|
||||
|
||||
```text
|
||||
src/
|
||||
├── topology/ # Reference shapes (Triangle, Tetrahedron, Hexahedron, ...)
|
||||
├── basis/ # Lagrange / Serendipity / DKT shape functions
|
||||
├── quadrature/ # Integration rules
|
||||
├── geometry/ # Jacobians, physical derivatives, strain helpers
|
||||
├── dofs/ # DOF{Quantity, Entity}, @DOFSet, DOFHandler, connectivity
|
||||
├── elements/ # Element{K, P, S, N} template + extraction / interpolation
|
||||
├── materials/ # LinearElastic, NeoHookean, PerfectPlasticity, HeatConductivity, ...
|
||||
├── assemblers/ # caches/, element_based/, dof_based/, matrix_free/, kernel_interface
|
||||
├── domains/ # Per-physics kernels: continuum/, heat/, thermo_elastic/, plates/, ...
|
||||
├── fields/ # AbstractField, Displacement, Temperature, LocalField
|
||||
├── physics/ # Type tags + microkernel hooks (Elasticity, Thermal, ...)
|
||||
├── mesh/ # Mesh{N, Topo}, structured / unstructured / refine / ordering
|
||||
├── io/ # Gmsh-oriented I/O (legacy mesh readers live under legacy/)
|
||||
├── sparse/ # SparseMatrixCOO / SparseVectorCOO scratch helpers
|
||||
├── legacy/ # Pre-2.0 API in `module Legacy`; load with JULIAFEM_ENABLE_LEGACY=1
|
||||
├── exports.jl # Grouped public API exports
|
||||
└── JuliaFEM.jl # Module entry point
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- One concept per directory.
|
||||
- File names: `lowercase_with_underscores.jl`.
|
||||
- Aim for roughly 500 lines per file as a soft limit; split when a file grows far beyond that.
|
||||
- No extra standalone `.md` files inside `src/<topic>/` beyond that topic's `README.md`. Per-symbol documentation lives in docstrings.
|
||||
|
||||
---
|
||||
|
||||
## Tests
|
||||
|
||||
```text
|
||||
test/
|
||||
├── runtests.jl # Topic list and runner
|
||||
├── README.md
|
||||
├── testdata/ # Small meshes and fixtures
|
||||
├── topology/, basis/, mesh/, elements/, fields/, materials/, ...
|
||||
├── domains/ # continuum/, heat/, darcy/, thermo_elastic/, ...
|
||||
├── assemblers/, dofs/, physics/, sparse/, io/, quadrature/, geometry/, ...
|
||||
├── interface/, docs/, mpi/, backend/metal/
|
||||
├── validation/, verification/, reference/
|
||||
└── solvers/ # Reserved; see README there if present
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Mirror `src/` where practical: tests for `src/foo/bar.jl` belong under `test/foo/`.
|
||||
- Topic folders may include a `README.md` for scope and conventions.
|
||||
- Test files: prefer `test_<feature>.jl`.
|
||||
- Long-form comparison or verification methodology can live in topic `README.md` files; timestamp machine-generated reports as `reports/YYYY-MM-DD_HHMMSS_name.txt` under the relevant folder when you add them.
|
||||
- Avoid dropping loose session write-ups under `test/`; use a gitignored notes area or a dated report path as above.
|
||||
|
||||
---
|
||||
|
||||
## Examples, demos, benchmarks
|
||||
|
||||
Some clones use optional top-level folders:
|
||||
|
||||
```text
|
||||
examples/ # Full programs for users (often one subdirectory per example)
|
||||
demos/ # Short API demonstrations for developers
|
||||
benchmarks/
|
||||
├── regression/ # CI-oriented performance checks
|
||||
├── analysis/ # Exploratory benchmarks
|
||||
└── reports/ # Timestamped outputs (YYYY-MM-DD_HHMMSS_*.txt)
|
||||
```
|
||||
|
||||
These directories are not guaranteed to exist in every checkout; add them when you introduce new material.
|
||||
|
||||
Distinction:
|
||||
|
||||
- `examples/`: runnable end-to-end scripts, usually with local `README.md`.
|
||||
- `demos/`: small focused scripts.
|
||||
- `benchmarks/`: timing and allocation measurements; regression versus analysis split by purpose.
|
||||
|
||||
Rules:
|
||||
|
||||
- Timestamp benchmark output files under a `reports/` subdirectory.
|
||||
- Group related benchmarks in the same subtree.
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
```text
|
||||
docs/
|
||||
├── CONTRIBUTING.md
|
||||
├── README.md
|
||||
├── repository_layout.md # Short pointer to docs/src/repository_layout.md
|
||||
├── make.jl
|
||||
├── Project.toml
|
||||
├── logo/
|
||||
├── tutorials/ # Historical notebooks (older API; reference only)
|
||||
└── src/
|
||||
├── index.md
|
||||
├── api.md
|
||||
├── assembler_choice.md
|
||||
├── elements_multiphysics_teaser.md
|
||||
├── thermo_elastic_walkthrough.md
|
||||
├── legacy.md
|
||||
├── repository_layout.md # This guide (built into the manual)
|
||||
├── developer/
|
||||
│ └── architecture_layers.md
|
||||
└── snippets/ # Executable snippets for Documenter pages
|
||||
```
|
||||
|
||||
The high-level architecture narrative lives in the repository root [`AGENTS.md`](https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/AGENTS.md). `docs/src/api.md` is generated from docstrings and exports.
|
||||
|
||||
What belongs in `docs/`:
|
||||
|
||||
- Documenter sources for the published manual (pages listed in `docs/make.jl`).
|
||||
- Logo assets and docs-specific `Project.toml`.
|
||||
- Contributor-facing notes such as `CONTRIBUTING.md`.
|
||||
- This layout guide (`docs/src/repository_layout.md`) plus the short pointer `docs/repository_layout.md`.
|
||||
|
||||
What does not:
|
||||
|
||||
- Per-module developer notes that belong next to code: use `src/<topic>/README.md` instead.
|
||||
- Large generated logs or scratch files: keep them out of `docs/src/` or timestamp under a dedicated reports location.
|
||||
|
||||
---
|
||||
|
||||
## Experimental and disposable paths
|
||||
|
||||
```text
|
||||
prototypes/ # Gitignored in normal setups: experiments by topic
|
||||
.trash/ # Gitignored: pending deletion or scratch outputs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Use `prototypes/` for spike code you might promote into `src/` or delete.
|
||||
- Use `.trash/` for short-lived files; delete once obsolete.
|
||||
|
||||
---
|
||||
|
||||
## Gitignored local notes (`llm/`)
|
||||
|
||||
Many developer setups keep a **local-only**, gitignored `llm/` tree for dated session logs and drafts. Nothing under `llm/` should be committed. If your checkout does not use it, you can ignore this section.
|
||||
|
||||
Naming convention when present: `llm/sessions/YYYY-MM-DD-topic.md` (lowercase, datestamped).
|
||||
|
||||
---
|
||||
|
||||
## Scripts
|
||||
|
||||
```text
|
||||
scripts/
|
||||
├── README.md
|
||||
└── *.jl / *.sh # Dev tooling, CI helpers, mesh utilities (not package code)
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Scripts are not loaded by `using JuliaFEM`; they are run explicitly.
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
```text
|
||||
.github/workflows/ # CI
|
||||
.github/prompts/ # Maintainer prompts (e.g. commit message conventions)
|
||||
Project.toml / Manifest.toml
|
||||
```
|
||||
|
||||
Optional on a developer machine (gitignored): `.cursor/` for editor-specific agent rules—not committed.
|
||||
|
||||
---
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
Avoid:
|
||||
|
||||
1. Session logs or narrative scratch files mixed into `test/` without a clear reports convention.
|
||||
2. Backup suffixes (`.old`, `.bak`) committed next to active sources.
|
||||
3. Log or coverage clutter in the repository root (prefer deletion or `.trash/`).
|
||||
4. Hidden scratch files (`.cleanup_*`, `.temp_*`) under `src/` or `test/`.
|
||||
5. Long-form design documents inside `src/` (keep module READMEs short; larger write-ups belong in `docs/` or local notes).
|
||||
6. Untimestamped benchmark dumps at the top level of `benchmarks/` (use `reports/` with a timestamp prefix).
|
||||
|
||||
---
|
||||
|
||||
## Decision tree
|
||||
|
||||
Executable Julia code?
|
||||
|
||||
- Package implementation: `src/<topic>/<feature>.jl`.
|
||||
- Test: `test/<topic>/test_<feature>.jl`.
|
||||
- Example program: `examples/<name>/` when that tree exists.
|
||||
- Demo script: `demos/` when that tree exists.
|
||||
- Benchmark driver: `benchmarks/<topic>/`.
|
||||
- One-off maintainer script: `scripts/`.
|
||||
- Spike: `prototypes/<topic>/` or `.trash/` if disposable.
|
||||
|
||||
Documentation?
|
||||
|
||||
- Manual page: add `docs/src/...` and wire it in `docs/make.jl`.
|
||||
- API reference: docstrings and exports (see `docs/src/api.md`).
|
||||
- Layering rules: `docs/src/developer/architecture_layers.md`.
|
||||
- Module orientation: `src/<topic>/README.md`.
|
||||
|
||||
Data?
|
||||
|
||||
- Small fixtures: `test/testdata/`.
|
||||
- Large meshes: keep outside the repo or under a clearly marked local path.
|
||||
- Benchmark output: `benchmarks/<topic>/reports/YYYY-MM-DD_HHMMSS_*.txt`.
|
||||
|
||||
Temporary?
|
||||
|
||||
- Spike code: `prototypes/<topic>/`.
|
||||
- Pending cleanup: `.trash/`.
|
||||
|
||||
---
|
||||
|
||||
## Pre-commit checklist
|
||||
|
||||
1. No stray `.old`, `.bak`, `.tmp` in tracked trees.
|
||||
2. Tests mirror `src/` layout where applicable.
|
||||
3. Examples and benchmarks include README or timestamped reports as appropriate.
|
||||
4. Module-facing docs updated in `src/<topic>/README.md` when public behaviour changes.
|
||||
5. `.gitignore` continues to exclude `.trash/`, `prototypes/`, `.cursor/`, and local-only trees such as `llm/` when used.
|
||||
|
||||
---
|
||||
|
||||
## Golden rules
|
||||
|
||||
1. Prefer mirroring `test/` after `src/` for unit tests.
|
||||
2. Keep generated and experimental trees gitignored unless deliberately checked in.
|
||||
3. Treat [`AGENTS.md`](https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/AGENTS.md) as the architecture source of truth.
|
||||
4. Prefer short per-module READMEs in `src/` over growing orphan markdown in random folders.
|
||||
|
||||
---
|
||||
|
||||
When in doubt:
|
||||
|
||||
1. File placement: re-read this page.
|
||||
2. Architecture: read [`AGENTS.md`](https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/AGENTS.md).
|
||||
3. Module conventions: read `src/<topic>/README.md`.
|
||||
4. Maintainer automation: see `.github/copilot-instructions.md` (and local `.cursor/` if you use Cursor; it is gitignored).
|
||||
5. Ask before introducing a new top-level directory.
|
||||
Reference in New Issue
Block a user