From 3bdbde3326c4c29dd0f425f8e2057b58dc39db5f Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sat, 9 May 2026 16:21:06 +0300 Subject: [PATCH] docs: Refresh README and contributing guide for post-reset API Replace outdated badges and roadmap prose with the current 2.0 focus areas, installation notes, and pointers to AGENTS.md. Rewrite CONTRIBUTING as a concise fork/test/layer-contract checklist aligned with the repo layout. - README: drop stale Travis/Gitter stack; document legacy module caveat - CONTRIBUTING: remove Quarto front matter; link architecture_layers checker --- README.md | 180 ++++++++++++++++++-------------------- docs/CONTRIBUTING.md | 204 ++++++++++++++++++++++++++----------------- 2 files changed, 211 insertions(+), 173 deletions(-) diff --git a/README.md b/README.md index 55d799f..46a4b4f 100644 --- a/README.md +++ b/README.md @@ -1,128 +1,118 @@ -# JuliaFEM.jl - an open source solver for both industrial and academia usage +# JuliaFEM.jl [![logo](https://raw.githubusercontent.com/JuliaFEM/JuliaFEM.jl/master/docs/logo/JuliaFEMLogo_256x256.png)](https://github.com/JuliaFEM/JuliaFEM.jl) [![DOI](https://zenodo.org/badge/35573493.svg)](https://zenodo.org/badge/latestdoi/35573493) [![License](https://img.shields.io/github/license/JuliaFEM/JuliaFEM.jl.svg)](https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md) -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JuliaFEM/JuliaFEM.jl) -[![Build Status](https://travis-ci.org/JuliaFEM/JuliaFEM.jl.svg?branch=master)](https://travis-ci.org/JuliaFEM/JuliaFEM.jl) -[![Coverage Status](https://coveralls.io/repos/github/JuliaFEM/JuliaFEM.jl/badge.svg?branch=master)](https://coveralls.io/github/JuliaFEM/JuliaFEM.jl?branch=master) -[![Stable documentation](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliafem.github.io/JuliaFEM.jl/stable) -[![Latest documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://juliafem.github.io/JuliaFEM.jl/latest) -[![Issues](https://img.shields.io/github/issues/JuliaFEM/JuliaFEM.jl.svg)](https://github.com/JuliaFEM/JuliaFEM.jl/issues) -The JuliaFEM project develops open-source software for reliable, scalable, -distributed Finite Element Method. +JuliaFEM.jl is an open-source finite element framework written in Julia. +The package is still **0.x**; the repository is in the middle of a deliberate +architectural reset toward a **stable 1.0** with a type-stable, zero-allocation, +GPU-friendly assembly pipeline. Many older READMEs and tutorials still describe +the previous API; when in doubt, trust the code and [`AGENTS.md`](AGENTS.md). +Contributions (bug reports, docs, tests, and features) are welcome. -The JuliaFEM software library is a framework that allows for the distributed -processing of large Finite Element Models across clusters of computers using -simple programming models. It is designed to scale up from single servers to -thousands of machines, each offering local computation and storage. The basic -design principle is: everything is nonlinear. All physics models are nonlinear -from which the linearization are made as a special cases. +## Status -At the moment, users can perform the following analyses with JuliaFEM: elasticity, -thermal, eigenvalue, contact mechanics, and quasi-static solutions. Typical examples -in industrial applications include non-linear solid mechanics, contact mechanics, -finite strains, and fluid structure interaction problems. For visualization, -JuliaFEM uses ParaView which prefers XDMF file format using XML to store light -data and HDF to store large data-sets, which is more or less the open-source standard. +Current focus areas: -## Vision +- `Element{K, P, S, N}` template with compile-time DOF layout. +- `DOFHandler` and `DOFBasedCOOAssembler` (zero-allocation hot paths). +- Microkernel-style physics in `src/domains/{continuum, heat, thermo_elastic}/`. +- Matrix-free `apply_K!`, `apply_M!`, Dirichlet, multipoint constraints, + IC(0) / Jacobi / block-Jacobi preconditioners and a generalized + eigensolver in `src/assemblers/`. +- A KernelAbstractions backend for the matrix-free path with a Float32 + Metal smoke test in `test/backend/metal/`. -On one hand, the vision of the JuliaFEM includes the opportunity for massive -parallelization using multiple computers with MPI and threading as well as cloud -computing resources in Amazon, Azure and Google Cloud services together with a -company internal server. And on the other hand, the real application complexity -including the simulation model complexity as well as geometric complexity. Not -to forget that the reuse of the existing material models as well as the whole -simulation models are considered crucial features of the JuliaFEM package. +The legacy element-based API (`Problem`, `update!`, `Analysis`, …) is +still present under `src/legacy/` for backward compatibility but is not +the recommended entry point. -Recreating the wheel again is definitely not anybody's goal, and thus we try -to use and embrace good practices and formats as much as possible. We have -implemented Abaqus / CalculiX input-file format support and maybe will in the -future extend to other FEM solver formats. Using modern development environments -encourages the user towards fast development time and high productivity. For -developing and creating new ideas and tutorials, we have used Jupyter notebooks -to make easy-to-use handouts. - -The user interface for JuliaFEM is Jupyter Notebook, and Julia language itself -is a real programming language. This makes it possible to use JuliaFEM as a part -of a bigger solution cycle, including for example data mining, automatic geometry -modifications, mesh generation, solution, and post-processing and enabling -efficient optimization loops. - -## Installing JuliaFEM - -Inside Julia REPL, type: +## Installing ```julia +using Pkg Pkg.add("JuliaFEM") ``` -## Initial road map +## A modern minimal example -JuliaFEM current status: **project planning** +```julia +using JuliaFEM -| Version | Number of degree of freedom | Number of cores | -| ------: | --------------------------: | --------------: | -| 0.1.0 | 1 000 000 | 10 | -| 0.2.0 | 10 000 000 | 100 | -| 1.0.0 | 100 000 000 | 1 000 | -| 2.0.0 | 1 000 000 000 | 10 000 | -| 3.0.0 | 10 000 000 000 | 100 000 | +mesh = create_structured_box_mesh(Hex8; + xmin = 0.0, xmax = 1.0, nx = 4, + ymin = 0.0, ymax = 1.0, ny = 4, + zmin = 0.0, zmax = 1.0, nz = 4, +) -We strongly believe in the test driven development as well as building on top -of previous work. Thus all the new code in this project should be 100% tested. -Also other people have wisdom in style as well: +S = @DOFSet{u::DOF{Displacement{3}, Vertex}} +ET = Element{Hex8, Lagrange{1}, S} +elements, handler = create_elements!(mesh, ET) -[The Zen of Python](https://www.python.org/dev/peps/pep-0020/): +material = LinearElastic(E = 210e9, ν = 0.3) +kernel = ContinuumKernel(ContinuumFormulation{FullThreeD}(), + material, Displacement{3}()) -```text -Beautiful is better than ugly. -Explicit is better than implicit. -Simple is better than complex. -Complex is better than complicated. -Flat is better than nested. -Sparse is better than dense. -Readability counts. -Errors should never pass silently. +asm = DOFBasedCOOAssembler() +cache = create_cache(asm, elements, handler, mesh, kernel) +assemble!(cache, asm, kernel, mesh) +K, f = extract_system(cache) ``` -## Citing +The same block is parsed from this file in `test/docs/readme_example.jl`, so it stays +copy-pasteable as the API evolves. -If you like using our package, please consider citing our [article](https://rakenteidenmekaniikka.journal.fi/article/view/64224/26397) +For a matrix-free Krylov solve, see +`test/assemblers/test_dof_based_apply_K.jl` and +`test/assemblers/test_eigensolve.jl`. -```text -@article{frondelius2017juliafem, - title={Julia{FEM} - open source solver for both industrial and academia usage}, - volume={50}, - url={https://rakenteidenmekaniikka.journal.fi/article/view/64224}, - DOI={10.23998/rm.64224}, - number={3}, - journal={Rakenteiden Mekaniikka}, - author={Frondelius, Tero and Aho, Jukka}, - year={2017}, - pages={229-233} -} -``` +## Documentation + +- [`docs/repository_layout.md`](docs/repository_layout.md): where to put new files + (full text under [`docs/src/repository_layout.md`](docs/src/repository_layout.md)). +- [`docs/`](docs/): Documenter-built API reference and user-facing index. + Historical Jupyter tutorials under [`docs/tutorials/`](docs/tutorials/) + (2015-2016 API; reference only). +- `src//README.md`: short module notes (topology, mesh, materials, ...). ## Contributing -We welcome contributions! JuliaFEM encourages good practices, starting from unit -testing and continuing to full integration testing across platforms. +Please read [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md) before opening a pull +request: fork and branch, keep changes review-sized, run tests, and describe +what you changed. -**Interested in contributing?** Please read: +**Git commits.** Keep history easy to read: small commits, usually one file; +**two files** in one commit is fine when they are inseparable (e.g. a helper and +its only caller). An optional hook (`.githooks/`, set `core.hooksPath`) caps +staged paths at two. If that workflow feels unfamiliar, open your PR with tests +passing and ask for help splitting history in review. -- **[Contributing Guide](docs/CONTRIBUTING.md)** - Quick start for contributors -- **[Coding Standards](docs/contributor/coding_standards.md)** - Required reading (includes important rules like "no Greek letters in code") -- **[Contributor Manual](docs/contributor/README.md)** - Technical details and architecture +**Code expectations.** Assembly hot paths must stay type-stable and allocation-free +after warmup; CI and [`test/assemblers/test_dof_based_zero_alloc.jl`](test/assemblers/test_dof_based_zero_alloc.jl) +guard that. The full suite: -Key requirements: +```bash +julia --project=. -e 'using Pkg; Pkg.test()' +``` -- ✅ Type-stable code (performance critical) -- ✅ Tests included with all changes -- ✅ Follow coding standards (use `u, v, w` not ξ, η, ζ) -- ✅ Clean commit messages +Use that locally before opening a PR; CI runs the same tests. -**Questions?** Open a GitHub Discussion or issue - we're happy to help! +## Citing + +If you use JuliaFEM.jl in academic work, please cite + +```text +@article{frondelius2017juliafem, + title = {Julia{FEM} - open source solver for both industrial and academia usage}, + volume = {50}, + url = {https://rakenteidenmekaniikka.journal.fi/article/view/64224}, + doi = {10.23998/rm.64224}, + number = {3}, + journal = {Rakenteiden Mekaniikka}, + author = {Frondelius, Tero and Aho, Jukka}, + year = {2017}, + pages = {229-233} +} +``` diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index d2c3d80..0cf6b13 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,99 +1,147 @@ ---- -title: "Contributing to JuliaFEM" -description: "Quick start guide for new contributors" -date: 2025-11-09 -author: "Jukka Aho" -categories: ["development", "contributing", "getting started"] -keywords: ["juliafem", "contributing", "pull requests", "development"] -audience: "contributors" -level: "beginner" -type: "guide" ---- +# Contributing to JuliaFEM.jl -Thank you for considering contributing to JuliaFEM! 🎉 +Thank you for considering a contribution. Please read `AGENTS.md` in the +repository root before opening a pull request; it describes the current +architecture, the non-negotiable invariants (zero-allocation hot paths, +type stability, mirrored test/src layout) and the documentation style. -## Quick Links +## Quick start -- **[Contributor Manual](contributor/README.md)** - Start here for technical details -- **[Coding Standards](contributor/coding_standards.md)** - **REQUIRED** reading for all contributors -- **[Testing Philosophy](contributor/testing_philosophy.md)** - How we test and why - -## Quick Start - -1. **Fork the repository** on GitHub - -2. **Clone your fork:** - - ```bash - git clone https://github.com/YOUR_USERNAME/JuliaFEM.jl.git - cd JuliaFEM.jl - ``` - -3. **Create a branch:** - - ```bash - git checkout -b fix-issue-123 - ``` - -4. **Read the [Coding Standards](contributor/coding_standards.md)** - Critical rules like: - - ✅ Use `u, v, w` for reference coordinates - - ❌ Never use Greek letters (ξ, η, ζ) in code - - ✅ Type-stable code required - - ✅ Zero allocations in hot paths - -5. **Make your changes** following the standards - -6. **Run tests:** +1. Fork and clone the repository. +2. Create a topic branch from `main`. +3. Make your change, keeping it small enough to review. +4. Run the full test suite from the repository root: ```bash julia --project=. -e 'using Pkg; Pkg.test()' ``` -7. **Commit with good messages:** +5. Respect the layer dependency contract in + `docs/src/developer/architecture_layers.md`. CI runs + `julia scripts/check_layer_contract.jl`; run it locally before pushing if + you touch `src/domains/` or foundation directories (`topology`, + `quadrature`, `geometry`, `basis`, `sparse`). - ```text - feat(topology): Add Pyr5 pyramid element - - - Implement 5-node pyramid reference element - - Zero-allocation tuple interface - - Tests for reference coordinates - - Closes #123 - ``` +6. Open a pull request with a clear description of the change and any + relevant benchmark or test output. -8. **Push and create Pull Request** +## Time to first success -## Code of Conduct +From a clean clone of JuliaFEM.jl, expect roughly this order: -- Be respectful and constructive -- Focus on the code, not the person -- Welcome newcomers and help them learn -- Ask questions before making assumptions +1. `julia --project=. -e 'using Pkg; Pkg.instantiate()'` — resolve dependencies. +2. `julia --project=. -e 'using Pkg; Pkg.test()'` — full bundled suite (same + command CI uses for the package tests). +3. Optional checks from the repository root: + - `julia scripts/check_layer_contract.jl` — static layer dependency audit + (same as CI). +4. Optional documentation smoke tests from the repository root: + - `julia --project=. scripts/verify_docs_quickstart.jl` — keeps the + Documenter minimal elasticity snippet aligned with the mesh in + `docs/src/snippets/minimal_elasticity_quickstart.jl`. + - `cd juliafem.github.io && julia scripts/check_website_docs.jl` — curated + site Markdown links and patterns. +5. Package API HTML (when editing `docs/src/`): + `julia --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'` + then `julia --project=docs docs/make.jl` from the repository root. -## What We Look For +If any of these fail before you touch application code, fix the environment +(Julia version versus `[compat]`, stale `Manifest.toml`, or missing Quarto +when rendering the website) rather than chasing false positives in the library. -✅ **Type-stable code** - Performance depends on it -✅ **Tests included** - New features need tests -✅ **Documentation** - Docstrings for exported functions -✅ **Clean commits** - Logical, well-described changes -✅ **Follows standards** - Read [coding_standards.md](contributor/coding_standards.md) +## Coding rules worth highlighting -❌ **Type-unstable code** - Will be rejected -❌ **No tests** - Cannot merge without tests -❌ **Greek letters in code** - Use u, v, w instead -❌ **Breaking changes** - Discuss in issue first +- Use ASCII identifiers in code (`u`, `v`, `w` for reference coordinates, + not `xi`, `eta`, `zeta` or Greek letters). Greek may appear in + comments and docstrings where it aids reading. +- Hot paths must remain zero-allocation. The regression for this lives + in `test/assemblers/test_dof_based_zero_alloc.jl`. New code that + touches the assembly path should not add `Dict`, `Vector{Any}`, + untyped closures or growable buffers inside loops. +- Tests for `src//.jl` go to + `test//test_.jl`. +- Prefer one file per commit; two paths is fine when they are one story + (e.g. implementation + its test). Never `git add .` or `git add -A` + unless you mean it. The full protocol is in + `.github/prompts/commit.prompt.md`. With + `git config core.hooksPath .githooks`, the pre-commit hook allows at + most **two** staged files per commit. -## Getting Help +## Documentation pull requests -- **Questions?** Open a GitHub Discussion -- **Bug report?** Open an issue with reproducible example -- **Feature idea?** Open an issue to discuss before implementing -- **Stuck?** Ask in the issue or PR - we're happy to help! +When you change **user-facing prose** (Quarto `juliafem.github.io/docs/`, examples +index, book landing pages) or **docstrings** that feed the site API page: -## License +1. From `juliafem.github.io/`, run + `julia scripts/check_website_docs.jl` + (denylist + relative Markdown / `book/index.qmd` chapter targets). +2. If you edited **JuliaFEM docstrings** or `docs/api/` sources used by the site + builder, run + `julia --project=. scripts/build_docs.jl api` + from `juliafem.github.io/` and commit the regenerated `api/` output if your + project tracks it. +3. Add or adjust **`juliafem.github.io/docs/documentation-map.md`** when you + introduce a new top-level guide readers should trust. +4. For package-only Documenter (`docs/make.jl`), use the **`docs/`** environment: + `julia --project=docs -e 'using Pkg; Pkg.instantiate()'` then + `julia --project=docs docs/make.jl` from the repository root (see `docs/README.md`). -By contributing, you agree that your contributions will be licensed under the MIT License. +## Documentation style ---- +When writing READMEs, docstrings, design notes or session logs: -**Ready to contribute?** → Start with [Contributor Manual](contributor/README.md) and [Coding Standards](contributor/coding_standards.md) +- No emoji. +- No markdown bold for emphasis. Plain prose carries enough weight. +- Prefer short, technical sentences and precise code references over + marketing copy. + +## Where things go + +[`src/repository_layout.md`](src/repository_layout.md) is the +authoritative file organisation guide and contains a decision tree for +any new file. A short pointer lives at [`repository_layout.md`](repository_layout.md). +In particular, local session logs and scratch notes often live under a +gitignored `llm/` tree, not under `docs/` or `test/`. + +## Website and Quarto CI + +The **`juliafem.github.io/`** tree is a Quarto site checked by +**`.github/workflows/SiteDocs.yml`**. Visual tokens and navbar/logo rules live in +**`juliafem.github.io/docs/contributor-guide/design_system.md`**. After changing +site Markdown or book landing links, run from `juliafem.github.io`: + +```bash +julia --project=. scripts/build_docs.jl api +julia scripts/check_website_docs.jl +``` + +A full local site build is `quarto render` from `juliafem.github.io/`. It fails +if two inputs share the same HTML stem (for example paired Literate `*.md` and +`*.qmd`, or Documenter `api/index.md` next to `api/index.qmd`); `build_docs.jl` +removes those duplicates after regenerating API and examples. + +If you change `default_quadrature` or quadrature tables under `src/quadrature/`, +regenerate the user-guide table snippet from the **repository root** and commit +the updated file: + +```bash +julia --project=. juliafem.github.io/scripts/generate_quadrature_defaults_snippet.jl +git diff juliafem.github.io/docs/user-guide/_quadrature_defaults_snippet.md +``` + +**`SiteDocs.yml`** runs that generator and fails the job when the snippet is out +of date (`git diff --exit-code` on the snippet path). The same workflow runs +**`scripts/check_curated_doc_vocabulary.jl`**, which fails if obsolete API +strings appear under **`juliafem.github.io/docs/user-guide/`** (for example +`register_fields!`). + +`check_website_docs.jl` enforces a small denylist of obsolete example patterns, +scans relative `*.md` / `*.qmd` links under `docs/`, `examples/`, `showcase/`, and +`articles/`, and verifies that **chapter links in `book/index.qmd`** resolve to +real `.qmd` files. + +## Getting help + +- Open a GitHub issue with a minimal reproducible example for bugs. +- Open a GitHub discussion or issue for design questions before doing + large pieces of work.