Authoring guide
In one minuteHow to write pages for this site: front matter, the four depth levels, callouts, mathematics, code, tabs, charts, tables, status badges, the field viewer and diagrams. Every feature is shown live on this page.
Pages are Markdown files under docs/content/. A small pre-processor adds depth levels, callouts, tabs, mathematics and data-driven components to standard Markdown; gyre docs build turns the files into this site. This page is both the reference and the test card: each feature is described and then used.
- L1Essentialswhat it is and why it mattersanyone
- L2Practicehow to use itusers and MDO integrators
- L3Mechanicshow it works: algorithms and architecturedevelopers
- L4Theoryderivations, proofs and numerical analysisnumerical analysts
Move the depth dial in the top bar (or press [ and ]) while you read this page to see how passages fold and unfold.
Pages and front matter#
A page is one file. docs/content/guide/quickstart.md becomes guide/quickstart.html, and the Markdown source is published next to it as guide/quickstart.md for agents and tools. Files and directories whose name starts with _ or . are ignored; any other non-Markdown file under docs/content/ is copied to the site unchanged, so images can sit next to the page that uses them.
Every page starts with YAML front matter:
---
title: Quickstart
summary: The shortest path from an installed package to a converged flow solution.
section: guide
order: 20
level: 2
audience: [users]
keywords: [first run, preset]
---
| Field | Required | Meaning |
|---|---|---|
title |
yes | Page title, shown as the top heading. Do not repeat it as a # heading in the body. |
summary |
yes | One or two plain-text sentences. Shown as the “in one minute” lead of the page, in navigation cards, in search results and in llms.txt. No Markdown. |
section |
no | One of overview, guide, examples, verification, engineering, theory, reference. Defaults to the top-level directory of the file. |
order |
no | Integer position within the section (default 100; index.md defaults to 0). Ties are broken by title. |
level |
no | Base depth level of the page, 1 to 4 (default 1). See Depth levels. |
audience |
no | List of intended readers, shown as chips under the title. |
keywords |
no | List of search keywords. |
study |
no | Id of the verification study this page reports. Links the study card on the verification overview to this page, and lets status and study shortcodes omit the id. |
studies |
no | List of further study ids reported on this page. Their cards on the verification overview link here too; shortcodes for them name the id. |
The file index.md of a section is that section’s landing page: the section title in the sidebar links to it. docs/content/index.md is the home page; its front matter also carries hero, paths (the persona reading paths) and highlights, which the home template lays out.
Depth levels#
Every passage of the documentation belongs to one of four levels. The reader’s dial decides which passages are open; a passage deeper than the dial is not removed but folded into a one-line stub that shows its level, title and length, and opens in place.
Text outside any block belongs to the page’s base level (level in the front matter). A block assigns a different level to a passage:
::: level 3 "Why flux differencing conserves entropy"
Any Markdown: paragraphs, lists, tables, math, shortcodes,
```python
fenced_code = "also works"
```
and callouts.
:::
The level may be written as a number (3), as L3, or by name (mechanics). The quoted title is optional but strongly recommended: it is what the reader sees on the folded stub and in the table of contents. A block without a title shows its opening words instead.
Three blocks follow, one per level other than this page’s base level 2.
Write the short, plain answer first, then let readers who want more open the deeper passages.
The pre-processor parses the page into a tree before Markdown runs. Each block is rendered on its own and wrapped in a <section class="lv" data-level="3"> with a toggle button; whether it is folded is decided in the browser by two attributes, data-depth on the document (the dial) and data-user on the block (the reader’s choice for that one block), using CSS only. The builder also counts the words at each level for the depth map in the right-hand column.
Before the dial changes, the script records the first content element at the top of the viewport and its offset . After the change it measures the same element again (or, if that element is now inside a folded passage, the stub that replaced it) at offset and scrolls by . Content above the reading position may grow or shrink by any amount; the element being read does not move on screen.
Rules worth knowing:
- Folding follows the dial. A block is open when its level is at or below the dial. Opening or closing a single block by hand is remembered until the dial crosses that block’s level.
- Pages deeper than level 1 fold too. On a page whose base level is 2 or more, the text under each
##heading is treated as a passage at the base level and folds when the dial is shallower. The lead-in before the first##heading, the headings themselves, and any explicit block shallower than the base level always stay visible. This page has base level 2: set the dial to 1 to see its outline. - Do not nest a shallower block inside a deeper one. It would be hidden whenever its parent is folded. Deeper inside shallower is fine.
- Blocks start at the left margin. The
:::lines must not be indented. - Links unfold their target. Following a link, a search result or a table-of-contents entry into a folded passage opens it.
Readers can pin a depth in a link with ?depth=3, and the dial position is remembered between visits.
Callouts#
Five kinds of callout share one syntax. The title is optional.
::: warning "Check the units"
The angle of attack is given in degrees.
:::
Callouts may sit inside level blocks, and level blocks inside callouts.
Mathematics#
TeX mathematics is written between dollar signs and rendered in the browser by a vendored copy of KaTeX, so it works offline. Inline math such as $a^2 + b^2 = c^2$ gives ; a display equation goes between double dollars:
$$
\pd{u}{t} + \nabla \cdot f(u) = 0
\label{eq:conservation}
$$
A display equation that carries \label{eq:name} is numbered and can be cited from the text with \eqref{eq:name}, as in: the conservation law (1). References may come before the equation. Equation numbers are per page.
Things to know:
- Math is protected from Markdown: underscores, asterisks, backslashes and vertical bars inside it are left alone, including in tables and headings.
- A literal dollar sign is written
\$. A$followed by a space, or a closing$followed by a digit, is not treated as math, so prices such as $5 and $10 are safe. \(…\)and\[…\]are accepted as alternative delimiters.- Code spans and fenced code are never searched for math.
- Use multi-line environments inside a display:
aligned,cases,pmatrixand the other KaTeX environments work.
The site defines a few macros for recurring notation:
| Macro | Renders as | Meaning |
|---|---|---|
\R |
the real numbers | |
\dd |
upright differential, \dd x |
|
\pd{u}{x} |
partial derivative | |
\jump{u} |
jump across an interface | |
\avg{u} |
average across an interface | |
\norm{u} |
norm | |
\abs{J} |
absolute value | |
u\T |
transpose |
A worked example at four depths#
High-order methods can be made robust by arranging the discrete derivative so that it obeys the same integration-by-parts rule as the exact derivative. Whatever the exact equations conserve, the discrete equations then conserve too.
On the Gauss–Lobatto nodes of an element, with quadrature weights and Lagrange polynomials , the collocation derivative matrix and the mass matrix are
In practice the volume term of a conservation law is evaluated with a symmetric two-point flux instead of the nodal flux, which is called flux differencing:
The two-point flux must be symmetric, , and consistent, . With the central choice , formula (3) reduces to the standard collocation derivative, because the rows of sum to zero:
Other two-point fluxes change the aliasing behaviour of the scheme without changing its order of accuracy. The cost is one flux evaluation per pair of nodes along each grid line, per line instead of .
Claim. With (2), the matrix satisfies
Proof. Gauss–Lobatto quadrature with nodes is exact for polynomials of degree at most . The product has degree , so, using ,
Therefore
since the end points are nodes.
Let be the entropy function, the entropy variables, the entropy potential and the entropy flux. Suppose the two-point flux satisfies Tadmor’s condition3
Contract the volume term (3) with and sum over the nodes. Writing from (4) and using the symmetry of ,
The third line uses (rows of sum to zero) and (from (4)). The volume term therefore changes the discrete entropy only through the entropy flux at the two end points, exactly as in the continuous equation: no entropy is produced or destroyed inside the element.
At dial level 2 this section shows the two definitions and three stubs; at level 4 it is a complete derivation. The depth map in the right-hand column shows how much of the page sits at each level.
Code#
Fenced code is highlighted at build time. The info string after the opening fence takes the language and two optional attributes: title="..." labels the block and hl="..." highlights lines (numbers and ranges).
```python title="build_docs.py" hl="3-4"
from gyre.docsite import build_site
site = build_site("site", verification_dir="var/verification")
print(f"documentation written to {site}")
```
from gyre.docsite import build_site
site = build_site("site", verification_dir="var/verification")
print(f"documentation written to {site}")
Any language known to Pygments works; the ones used most here are python, bash, json, yaml and http. Use console for a terminal session: the copy button then copies the commands without the prompts and the output.
$ gyre docs build -o site --verification var/verification
documentation written to site
GET /api/v1/info HTTP/1.1
Accept: application/json
{"name": "gyre", "version": "0.1.0", "describe": "abc123+dirty",
"deployment": {"name": "dev", "host": "workstation"}}
Inline code uses single backticks: build_site(output_dir="site").
Tabs#
Alternatives that a reader chooses between go into tabs. A tab group is a ::: tabs block whose panels start with === "Label":
::: tabs
=== "Command line"
```bash
gyre docs build -o site
```
=== "Python"
```python
from gyre.docsite import build_site
build_site("site")
```
:::
gyre docs build -o site
from gyre.docsite import build_site
build_site("site")
Choosing a label selects the tab with the same label in every group on the page and is remembered between pages, so a reader who prefers Python sees Python everywhere. A panel may hold any Markdown, not only code. Without JavaScript, and in print, all panels are shown one after the other with their labels.
Tables, lists and other Markdown#
Standard Markdown tables are supported, with alignment given by colons in the separator row. Wide tables scroll sideways instead of breaking the layout.
| Level | Name | Typical content | Words per page (guide) |
|---|---|---|---|
| 1 | Essentials | what and why | 100 to 300 |
| 2 | Practice | commands, options, examples | 300 to 1200 |
| 3 | Mechanics | algorithms, architecture | as needed |
| 4 | Theory | derivations, proofs | as needed |
Also available: definition lists, abbreviations, attribute lists ({#custom-id} after a heading sets its anchor), footnotes ([^key] in the text and [^key]: note anywhere on the page), and raw HTML. Straight quotes become typographic quotes in prose; dashes are left as typed, so write --flag in code and an en dash or em dash as the character itself.
- Term
- A definition list pairs a term with its explanation.
Links#
Link to other pages by the relative path of their Markdown file, optionally with an anchor:
See the [verification overview](../verification/index.md) and
[how levels work](authoring.md#depth-levels).
The builder rewrites .md links to the built pages and checks every internal link and anchor. A link to a page or anchor that does not exist fails the build with a list of all broken links. Because sources and built pages mirror each other, the same relative links also work for agents that read the .md files. Links that start with / (such as /api/docs, the interactive API explorer served by the Gyre service) and links with a scheme (https://…) are left untouched.
Data components#
Shortcodes embed data-driven components. A shortcode sits alone on a line:
{{ chart: isentropic_vortex/error_vs_h }}
Verification numbers on this site come only from the files written by gyre verify, one <study-id>.json per study, and every chart and table shows the revision, time and device recorded in that file. The examples on this page use synthetic sample data from docs/theme/samples/ instead, referenced with the prefix sample:. Anything rendered from a sample is labelled “Synthetic illustration”; never use the prefix on a page that reports results.
Charts#
{{ chart: <study-id>/<chart-id> }} draws one chart of a study. Charts are plain SVG and need no network; hover or use the arrow keys to read values, click a legend entry to hide a series, open the data table, or download the chart as a standalone SVG.
A convergence chart has logarithmic axes, ticks at the mesh sizes and a slope triangle for each reference slope:
Convergence chart: log-log axes, ticks at the mesh sizes, reference-slope triangles.
Data table
| h | p = 1 | p = 2 | p = 3 |
|---|---|---|---|
| 0.5 | 0.234467 | 0.0548869 | 0.0125882 |
| 0.25 | 0.0541215 | 0.00624785 | 7.7034e-04 |
| 0.125 | 0.0145244 | 8.6089e-04 | 4.9834e-05 |
| 0.0625 | 0.00342 | 9.7412e-05 | 2.9699e-06 |
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
A history chart draws dense series without markers:
History chart: dense lines without markers.
Data table
| nonlinear iteration | p = 1 | p = 2 | p = 3 |
|---|---|---|---|
| 0 | 1 | 1 | 1 |
| 1 | 1.15201 | 1.29888 | 1.42121 |
| 2 | 0.238064 | 0.302638 | 0.362324 |
| 3 | 0.0846956 | 0.121397 | 0.159025 |
| 4 | 0.103006 | 0.166466 | 0.2386 |
| 5 | 0.0582651 | 0.106166 | 0.166501 |
| 6 | 0.0199054 | 0.0408943 | 0.0701749 |
| 7 | 0.0114103 | 0.0264304 | 0.049626 |
| 8 | 0.00802557 | 0.0209604 | 0.0430617 |
| 9 | 0.00396425 | 0.0116734 | 0.0262408 |
| 10 | 0.00184179 | 0.00611497 | 0.0150404 |
| 11 | 0.00107928 | 0.00404019 | 0.0108731 |
| 12 | 6.2289e-04 | 0.00262902 | 0.00774163 |
| 13 | 3.1433e-04 | 0.00149585 | 0.00481962 |
| 14 | 1.6402e-04 | 8.8005e-04 | 0.00310256 |
| 15 | 9.2353e-05 | 5.5870e-04 | 0.00215516 |
| 16 | 5.0136e-05 | 3.4198e-04 | 0.00144338 |
| 17 | 2.6192e-05 | 2.0143e-04 | 9.3026e-04 |
| 18 | 1.4094e-05 | 1.2221e-04 | 6.1756e-04 |
| 19 | 7.7178e-06 | 7.5454e-05 | 4.1718e-04 |
| 20 | 4.1362e-06 | 4.5594e-05 | 2.7583e-04 |
| 21 | 2.2029e-06 | 2.7379e-05 | 1.8123e-04 |
| 22 | 1.1901e-06 | 1.6678e-05 | 1.2079e-04 |
| 23 | 6.4357e-07 | 1.0168e-05 | 8.0582e-05 |
| 24 | 3.4495e-07 | 6.1450e-06 | 5.3284e-05 |
| 25 | 1.8511e-07 | 3.7181e-06 | 3.5276e-05 |
| 26 | 9.9849e-08 | 2.2612e-06 | 2.3474e-05 |
| 27 | 5.3763e-08 | 1.3728e-06 | 1.5593e-05 |
| 28 | 2.8869e-08 | 8.3111e-07 | 1.0330e-05 |
| 29 | 1.5527e-08 | 5.0399e-07 | 6.8538e-06 |
| 30 | 8.3621e-09 | 3.0604e-07 | 4.5538e-06 |
| 31 | 4.4979e-09 | 1.8560e-07 | 3.0218e-06 |
| 32 | 2.4180e-09 | 1.1250e-07 | 2.0041e-06 |
| 33 | 1.3010e-09 | 6.8247e-08 | 1.3303e-06 |
| 34 | 7.0012e-10 | 4.1409e-08 | 8.8315e-07 |
| 35 | 3.7655e-10 | 2.5111e-08 | 5.8599e-07 |
| 36 | 2.0253e-10 | 1.5228e-08 | 3.8882e-07 |
| 37 | 1.0896e-10 | 9.2375e-09 | 2.5808e-07 |
| 38 | 5.8622e-11 | 5.6033e-09 | 1.7129e-07 |
| 39 | 3.1532e-11 | 3.3982e-09 | 1.1366e-07 |
| 40 | 1.6962e-11 | 2.0611e-09 | 7.5431e-08 |
| 41 | 9.1252e-12 | 1.2502e-09 | 5.0063e-08 |
| 42 | 4.9089e-12 | 7.5827e-10 | 3.3225e-08 |
| 43 | 2.6406e-12 | 4.5990e-10 | 2.2049e-08 |
| 44 | 1.4205e-12 | 2.7894e-10 | 1.4633e-08 |
| 45 | 7.6417e-13 | 1.6919e-10 | 9.7112e-09 |
| 46 | 4.1108e-13 | 1.0262e-10 | 6.4448e-09 |
| 47 | 2.2113e-13 | 6.2241e-11 | 4.2770e-09 |
| 48 | 1.2318e-13 | 3.7751e-11 | 2.8385e-09 |
| 49 | 1.0462e-13 | 2.2898e-11 | 1.8838e-09 |
| 50 | 1.7376e-13 | 1.3888e-11 | 1.2502e-09 |
| 51 | 2.6702e-13 | 8.4234e-12 | 8.2966e-10 |
| 52 | 2.9866e-13 | 5.1091e-12 | 5.5061e-10 |
| 53 | 2.3959e-13 | 3.0988e-12 | 3.6541e-10 |
| 54 | 1.4412e-13 | 1.8795e-12 | 2.4250e-10 |
| 55 | 1.0002e-13 | 1.1400e-12 | 1.6094e-10 |
| 56 | 1.4784e-13 | 6.9144e-13 | 1.0681e-10 |
| 57 | 2.4362e-13 | 4.8723e-13 | 7.0882e-11 |
| 58 | 2.9929e-13 | 5.9858e-13 | 4.7041e-11 |
| 59 | 2.6367e-13 | 5.2735e-13 | 3.1219e-11 |
| 60 | 1.6952e-13 | 3.3904e-13 | 2.0718e-11 |
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
A bar chart compares categories. It draws thin vertical bars on a zero baseline; when the category labels are long or numerous it switches to horizontal bars, and when the value axis is logarithmic it becomes a dot plot, because a bar has no honest length on a log scale. A line chart with a single series needs no legend:
Bar chart: grouped, thin bars from a zero baseline.
Data table
| polynomial order | residual | Jacobian-vector product |
|---|---|---|
| p = 1 | 1 | 2.1 |
| p = 2 | 2.6 | 5.3 |
| p = 3 | 5.9 | 12.4 |
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
Line chart with one series: no legend is needed.
Data table
| angle of attack (degrees) | lift coefficient |
|---|---|
| -2 | -0.2128 |
| -1.5 | -0.161963 |
| -1 | -0.1091 |
| -0.5 | -0.0548875 |
| 0 | 0 |
| 0.5 | 0.0548875 |
| 1 | 0.1091 |
| 1.5 | 0.161963 |
| 2 | 0.2128 |
| 2.5 | 0.260938 |
| 3 | 0.3057 |
| 3.5 | 0.346413 |
| 4 | 0.3824 |
| 4.5 | 0.412988 |
| 5 | 0.4375 |
| 5.5 | 0.455263 |
| 6 | 0.4656 |
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
Charts are forgiving about data, and say so:
- A
null(or non-finite) value breaks a line: the series is drawn as separate segments, with no markers. Use this to draw several short pieces, such as tangents, as one series. - Zero and negative values cannot be drawn on a logarithmic axis. They are left out and counted in a note under the chart; the data table keeps them.
- Series that lie on top of each other are drawn dashed with small markers, so both stay visible, and share one direct label.
- A reference slope is drawn as a triangle next to the part of a series it explains, on any chart with two logarithmic axes.
Tables from a study#
{{ table: <study-id>/<table-id> }} renders one table of a study. Numbers are right-aligned in tabular figures with six significant digits, in scientific notation below 0.001 and from a million up; booleans read yes or no and missing values are shown as a dash. A table wider than the text column scrolls sideways inside its frame.
| p | N | h | L2 error | order |
|---|---|---|---|---|
| 1 | 2 | 0.5 | 0.234467 | — |
| 1 | 4 | 0.25 | 0.0541215 | 2.115 |
| 1 | 8 | 0.125 | 0.0145244 | 1.898 |
| 1 | 16 | 0.0625 | 0.00342 | 2.086 |
| 2 | 2 | 0.5 | 0.0548869 | — |
| 2 | 4 | 0.25 | 0.00624785 | 3.135 |
| 2 | 8 | 0.125 | 8.6089e-04 | 2.859 |
| 2 | 16 | 0.0625 | 9.7412e-05 | 3.144 |
| 3 | 2 | 0.5 | 0.0125882 | — |
| 3 | 4 | 0.25 | 7.7034e-04 | 4.03 |
| 3 | 8 | 0.125 | 4.9834e-05 | 3.95 |
| 3 | 16 | 0.0625 | 2.9699e-06 | 4.069 |
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
Status badges and whole studies#
{{ status: <study-id> }} shows whether a study passed, and each of its checks with the measured value and the expectation. Pass and fail are marked by an icon and a word, never by colour alone.
Synthetic illustration: numbers generated by a formula to demonstrate the component. The numbers imitate a convergence study with design order p + 1.
- observed order, p = 12.086expected >= 1.8pass
- observed order, p = 23.144expected >= 2.8pass
- observed order, p = 34.069expected >= 3.8pass
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
Synthetic illustration: numbers generated by a formula to demonstrate the component. One check is made to fail so that the failure styling can be seen.
- free-stream residual3.10e-15expected <= 1e-12pass
- observed order, p = 33.12expected >= 3.8fail
- entropy production-2.40e-16expected <= 1e-13pass
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
{{ study: <study-id> }} renders everything a study recorded: the status, then every chart and every table. On a page that sets study: in its front matter the id can be omitted, so a verification page can consist of an explanation followed by {{ study }}.
{{ studies }} renders a summary grid of all studies found in the verification directory, each linked to the page that declares it. The grid below is the real one for this build:
39 of 39 studies passed
- Passed
operators1/1 checks · 0.29 s
39979fcf90Same code as this build - Passed
Free-stream preservation on curved meshes
free_stream1/1 checks · 18.67 s
39979fcf90Same code as this build - Passed
Entropy conservation and stability
entropy_conservation41/41 checks · 15.77 s
39979fcf90Same code as this build - Passed
Structure of the BR2 viscous operator
viscous_operator17/17 checks · 116.9 s
39979fcf90Same code as this build - Passed
Independent 1-D model of the BR2 formulation
diffusion_1d17/17 checks · 4.93 s
39979fcf90Same code as this build - Passed
Exact linearization by automatic differentiation
linearization40/40 checks · 198.1 s
39979fcf90Same code as this build - Passed
Differentiable mesh deformation
mesh_deformation9/9 checks · 2.45 s
39979fcf90Same code as this build - Passed
density_wave4/4 checks · 40.98 s
39979fcf90Same code as this build - Passed
isentropic_vortex10/10 checks · 65.18 s
39979fcf90Same code as this build - Passed
mms_euler6/6 checks · 212.5 s
39979fcf90Same code as this build - Passed
Manufactured solutions: Navier–Stokes
mms_navier_stokes14/14 checks · 1225 s
39979fcf90Same code as this build - Passed
Nonlinear and linear solver convergence
solver_convergence16/16 checks · 890.1 s
39979fcf90Same code as this build - Passed
Line-implicit smoothing on a wall-resolved mesh
line_smoother7/7 checks · 2160 s
39979fcf90Same code as this build - Passed
Line-implicit smoothing in three dimensions
line_smoother_3d6/6 checks · 620.4 s
39979fcf90Same code as this build - Passed
Single-precision blocks in the preconditioner
mixed_precision6/6 checks · 2649 s
39979fcf90Same code as this build - Passed
Adjoint gradients versus finite differences
adjoint_gradients18/18 checks · 1176 s
39979fcf90Same code as this build - Passed
output_error5/5 checks · 367.7 s
39979fcf90Same code as this build - Passed
cylinder_re407/7 checks · 417.2 s
39979fcf90Same code as this build - Passed
extruded_3d8/8 checks · 300.8 s
39979fcf90Same code as this build - Passed
Inviscid flow past a sphere (3-D)
sphere_inviscid9/9 checks · 424.7 s
39979fcf90Same code as this build - Passed
Laminar flow past a sphere, Re = 100 (3-D)
sphere_re1005/5 checks · 187.8 s
39979fcf90Same code as this build - Passed
Adjoint derivatives of 3-D outputs
adjoint_3d6/6 checks · 297.7 s
39979fcf90Same code as this build - Passed
Largest 3-D solve on one device
scale_3d7/7 checks · 452 s
39979fcf90Same code as this build - Passed
Manufactured solutions: RANS with the Spalart-Allmaras model
rans_mms9/9 checks · 455.8 s
39979fcf90Same code as this build - Passed
Exact linearization with the Spalart-Allmaras model
rans_linearization20/20 checks · 158.6 s
39979fcf90Same code as this build - Passed
Turbulent flat plate (NASA TMR) with the Spalart-Allmaras model
rans_flat_plate8/8 checks · 162.1 s
39979fcf90Same code as this build - Passed
Three-dimensional consistency with the Spalart-Allmaras model
rans_extruded_3d10/10 checks · 675.1 s
39979fcf90Same code as this build - Passed
Adjoint gradients with the Spalart-Allmaras model
rans_adjoint6/6 checks · 119 s
39979fcf90Same code as this build - Passed
Discipline contract for MDO integration
discipline_contract15/15 checks · 249.9 s
39979fcf90Same code as this build - Passed
imported_mesh29/29 checks · 184.5 s
39979fcf90Same code as this build - Passed
order_selection13/13 checks · 364.4 s
39979fcf90Same code as this build - Passed
example_airfoil4/4 checks · 104.5 s
39979fcf90Same code as this build - Passed
Example: laminar cylinder, Re = 40
example_cylinder4/4 checks · 51.5 s
39979fcf90Same code as this build - Passed
Example: turbulent flat plate (Spalart-Allmaras)
example_flat_plate5/5 checks · 119.9 s
39979fcf90Same code as this build - Passed
Example: lift polar with adjoint slopes
example_polar5/5 checks · 686.1 s
39979fcf90Same code as this build - Passed
Example: coupled aero-structural adjoint
example_coupling2/2 checks · 823 s
39979fcf90Same code as this build - Passed
Example: transonic aerofoil with shock capturing
example_transonic9/9 checks · 151.8 s
39979fcf90Same code as this build - Passed
performance_cpu2/2 checks · 123.8 s
39979fcf90Same code as this build - Passed
Kernel throughput (NVIDIA GeForce RTX 3060 Ti)
performance_gpu2/2 checks · 103.5 s
39979fcf90Same code as this build
When data is missing#
A missing study, chart, table or field never fails the build. The reader sees a placeholder that says what to run, like this one for a study that does not exist:
no_such_study has no verification results yet (no_such_study.json not found). Run gyre verify and rebuild the documentation.Field viewer#
{{ field: <path> | field=mach | title=… | height=420 }} embeds an interactive viewer for a two-dimensional solution sample written by gyre.io.field_payload (the file field.json in a run directory). The path is relative to the runs directory, var/runs by default.
Drag to pan. Click the view, then scroll to zoom (or hold Ctrl while scrolling); pinch on a touch screen. The value under the pointer is read out in the corner. The tool bar selects the field and the colour map and toggles element edges and isolines.
Fields: mach [0.02333, 1.235], pressure [0.3756, 1], density [0.4969, 1]. Raw sample (JSON)
Synthetic illustration — made-up numbers that demonstrate the component; not solver output.
The next viewer asks for a real sample, smoke/field.json. It appears if that run exists in the runs directory when the site is built, and is replaced by a placeholder otherwise:
smoke/field.json is not found (looked in var/runs). Run gyre run <case> -o <dir> and rebuild the documentation.| Option | Default | Meaning |
|---|---|---|
field |
first field | Field shown initially. |
title |
case name | Caption above the viewer. |
height |
420 |
Height of the view in pixels. |
view |
the sample’s own view, else everything |
Initial window as xmin,xmax,ymin,ymax; also what the reset button returns to. The window is fitted inside the view at equal scale in both directions. |
cmap |
viridis |
Colour map: viridis or magma (both perceptually uniform). |
edges |
off |
on to start with element edges drawn. |
A study record is a JSON object:
{"id": "isentropic_vortex", "title": "Isentropic vortex", "description": "...",
"passed": true, "wall_time": 12.3,
"checks": [{"name": "observed order p=3", "value": 3.6, "expected": ">= 3.4", "passed": true}],
"charts": [{"id": "error_vs_h", "type": "convergence", "title": "...",
"xlabel": "h", "ylabel": "L2 error", "xscale": "log", "yscale": "log",
"series": [{"name": "p=2", "x": [0.5, 0.25], "y": [1e-2, 1.3e-3]}],
"reference_slopes": [{"slope": 3, "label": "h^3"}], "note": "optional caption"}],
"tables": [{"id": "orders", "title": "...", "columns": ["N", "error", "order"],
"rows": [[16, 1e-3, null]]}],
"provenance": {"version": "0.1.0", "commit": "...", "describe": "abc123+dirty",
"timestamp": "...", "device": {"platform": "gpu", "device_kind": "..."}}}
Chart type is convergence, history, line or bar; xscale and yscale are log or linear, and xscale may be category for bar charts, which take category names in x. Entries of x and y may be null; non-finite numbers are treated as null. A reference slope may name the series it belongs to with "series": "p=2"; otherwise the slopes are matched to the series in order of steepness when there are as many of one as of the other, and to the series with the closest fitted slope if not. A chart series may also hold null where a study deliberately omits a point. A study may also carry level (the suite it ran in), notes (a paragraph the study generates from the numbers of its own run, shown under the status) and error (the traceback of a study that raised, shown in the status block); a timing study also carries device and host_load. Files in the verification directory that are not study records (such as index.json) are ignored, except that index.json sets the order of the overview grid.
index.json is written by gyre verify. Its studies list has one entry per result file in the directory, each with id, title, passed, checks, failed_checks, wall_time and the level, commit, device and timestamp of the run that produced it, plus stale (true if that run was not the last invocation). suite, generated, wall_time, provenance, requested (the study ids of the last invocation), skipped (studies not run, each with id and reason) and summary (ran, passed, failed, stale, stale_failed) describe the last invocation.
A field sample is {"m", "elements", "x", "y", "fields": {name: {"data", "min", "max"}}}, where x, y and each data are base64-encoded little-endian float32 arrays of shape (elements, m, m): every element is a structured m × m patch. An optional key "view": [xmin, xmax, ymin, ymax] gives the window to show first; without it the viewer fits the whole sample. The builder copies the sample to data/fields/ in the site. If a result.json lies next to the sample, its provenance is shown under the viewer.
Diagrams#
{{ diagram: <file.svg> | caption=… | width=… }} inlines an SVG file into the page, so that it can use the theme’s colours and follow the light and dark themes. The file is looked up next to the page, then relative to docs/content/, then in docs/theme/diagrams/ (where the one below lives). Keep diagram sources that belong to the content in a directory whose name starts with _ (for example docs/content/_diagrams/) so that they are not also copied to the site as loose files.
The build: inputs on the left, the three modules of gyre.docsite in the middle, the static site on the right.
Do not put colours in the SVG. Use these classes instead:
| Class | Use |
|---|---|
dg-line, dg-accent, dg-faint |
strokes: normal, emphasised, background |
dg-box, dg-box-accent |
filled rectangles and shapes |
dg-fill, dg-fill-accent |
solid fills, such as arrow heads |
dg-text, dg-small, dg-mono |
labels: normal, secondary, code |
dg-l1 … dg-l4 |
fills in the colours of the four depth levels |
Give the <svg> a viewBox, a <title> and, when it carries information, a <desc>. Ids inside the file (markers, gradients) must be unique on the page, so prefix them.
Generated content and page lists#
{{ generated: <name> }} calls a registered Python function that returns Markdown and renders the result in place. This is how reference material that lives in the code, such as tables of presets or a schema, stays in step with the code. The build information below is produced this way:
| Build | |
|---|---|
| Package | gyre |
| Version | 0.4.0 |
| Revision | ceb1f4b0be |
| Commit | ceb1f4b0bed41de53e586df10858079f5a2bcdd8 |
| Working tree | clean |
Generators are registered in src/gyre/docsite/generators.py, which the builder imports before rendering. A generator takes no arguments and returns Markdown; anything the Markdown dialect supports may be used in it, including level blocks and other shortcodes.
from .shortcodes import register_generator
@register_generator("presets")
def presets_table() -> str:
from ..cases import PRESETS # import heavy modules lazily
rows = [f"| `{name}` | {spec.description} |" for name, spec in PRESETS.items()]
return "\n".join(["| Preset | Description |", "|---|---|", *rows])
A generator that is not registered, or that raises, does not fail the build: the page shows a “Shortcode problem” box and the problem is recorded in the warnings of site-manifest.json.
Two more shortcodes help with navigation: {{ pages }} lists the pages of the current section as cards ({{ pages: guide }} lists another section), and {{ levels }} prints the legend of the four levels shown at the top of this page.
Building and checking#
$ gyre docs build -o site --verification var/verification
documentation written to site
The build is fast, has no network access and needs no tool chain beyond Python. Opening site/index.html from the file system works; the live deployment stamp in the footer then falls back to the build-time stamp.
build_site(output_dir="site", verification_dir="var/verification", content_dir=None, runs_dir="var/runs") returns the output path. content_dir defaults to docs/content and the theme to docs/theme of the source checkout that contains the package (falling back to the working directory); the environment variables GYRE_DOCS_CONTENT and GYRE_DOCS_THEME override them. The other paths are relative to the working directory.
| Output | Purpose |
|---|---|
<page>.html, <page>.md |
every page, and its Markdown source next to it |
search-index.json, search-index.js |
full-text index (the .js copy lets search work from the file system) |
llms.txt, llms-full.txt |
index of all pages for AI agents, and all pages in one file |
site-manifest.json |
pages, sections, levels, build stamp, warnings and the list of files written |
site-data.js |
build stamp and reading paths for the scripts |
assets/ |
the theme’s CSS, JavaScript and vendored KaTeX |
data/fields/ |
field samples used by field shortcodes |
The output is deterministic: the same inputs give the same bytes, and no wall-clock time is written unless SOURCE_DATE_EPOCH is set. Files are rewritten only when their content changes, and files that a previous build wrote but this one does not are removed; nothing else in the output directory is touched.
Authoring errors (unknown section, unclosed block, broken internal link or anchor) raise gyre.docsite.DocsBuildError listing every problem. Missing data, unknown shortcodes and failing generators do not; they are shown on the page and recorded as warnings.
Checklist for a new page#
- Front matter has
title,summary,orderand the rightlevel. - The summary can be read alone and says what the page delivers.
- The page reads well with the dial at its base level; deeper passages are in titled level blocks.
- Numbers come from verification output through shortcodes, not typed by hand.
gyre docs buildsucceeds: no broken links, and no unexpected warnings insite-manifest.json.
Notes
T. C. Fisher and M. H. Carpenter, “High-order entropy stable finite difference schemes for nonlinear conservation laws: finite domains”, Journal of Computational Physics 252 (2013).
↩G. J. Gassner, A. R. Winters and D. A. Kopriva, “Split form nodal discontinuous Galerkin schemes with summation-by-parts property for the compressible Euler equations”, Journal of Computational Physics 327 (2016).
↩E. Tadmor, “The numerical viscosity of entropy stable schemes for systems of conservation laws. I”, Mathematics of Computation 49 (1987).
↩