Gyredocs
Depth Practice
API

Gyre/Reference

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.

Written at L2 Practice goes to L4 Theorycontributorsdevelopers 5505 words Markdown

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:

yamldocs/content/guide/quickstart.md
---
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.

Sections and their display names are fixed in gyre.docsite.build.SECTIONS; a page that names another section fails the build. Within a section the landing page comes first, then pages by (order, title). The same linear order drives the previous/next links at the bottom of each page. The sidebar shows, next to each page, the deepest level that page reaches, measured from the rendered content rather than declared.

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:

markdown
::: 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 y0y_0. 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 y1y_1 and scrolls by y1−y0y_1 - y_0. 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.

markdown
::: 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 a2+b2=c2a^2 + b^2 = c^2; a display equation goes between double dollars:

markdown
$$
\pd{u}{t} + \nabla \cdot f(u) = 0
\label{eq:conservation}
$$
∂u∂t+∇⋅f(u)=0(1)\pd{u}{t} + \nabla \cdot f(u) = 0 \tag{1}

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, pmatrix and the other KaTeX environments work.
{ ⁣{u} ⁣}=12 (u−+u+),⟦u⟧=u+−u−,∥u∥M2=uTMu,∣J∣=det⁡∂x∂ξ.\begin{aligned} \avg{u} &= \tfrac12\,(u^- + u^+), &\qquad \jump{u} &= u^+ - u^-, \\ \norm{u}_M^2 &= u\T M u, &\qquad \abs{J} &= \det \pd{x}{\xi}. \end{aligned}

The site defines a few macros for recurring notation:

Macro Renders as Meaning
\R R\R the real numbers
\dd dx\dd x upright differential, \dd x
\pd{u}{x} ∂u∂x\pd{u}{x} partial derivative
\jump{u} ⟦u⟧\jump{u} jump across an interface
\avg{u} { ⁣{u} ⁣}\avg{u} average across an interface
\norm{u} ∥u∥\norm{u} norm
\abs{J} ∣J∣\abs{J} absolute value
u\T uTu\T transpose

A worked example at four depths#

This section shows how one topic reads at each level. The mathematics is standard12; it is here to exercise long-form math, numbering and nested levels.

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 N+1N + 1 Gauss–Lobatto nodes of an element, with quadrature weights wiw_i and Lagrange polynomials ℓj\ell_j, the collocation derivative matrix and the mass matrix are

Dij=ℓj′(ξi),M=diag⁡(w0,…,wN).(2)D_{ij} = \ell_j'(\xi_i), \qquad M = \operatorname{diag}(w_0, \dots, w_N). \tag{2}

In practice the volume term of a conservation law is evaluated with a symmetric two-point flux f#f^{\#} instead of the nodal flux, which is called flux differencing:

∂f∂ξ∣i  ≈  2∑j=0NDij f#(ui,uj).(3)\left.\pd{f}{\xi}\right|_i \;\approx\; 2 \sum_{j=0}^{N} D_{ij}\, f^{\#}(u_i, u_j). \tag{3}

The two-point flux must be symmetric, f#(ui,uj)=f#(uj,ui)f^{\#}(u_i, u_j) = f^{\#}(u_j, u_i), and consistent, f#(u,u)=f(u)f^{\#}(u, u) = f(u). With the central choice f#(ui,uj)=12(fi+fj)f^{\#}(u_i, u_j) = \tfrac12 (f_i + f_j), formula (3) reduces to the standard collocation derivative, because the rows of DD sum to zero:

2∑jDij 12(fi+fj)  =  fi∑jDij+∑jDijfj  =  (Df)i.2 \sum_j D_{ij}\, \tfrac12 (f_i + f_j) \;=\; f_i \sum_j D_{ij} + \sum_j D_{ij} f_j \;=\; (D f)_i .

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, O(N2)O(N^2) per line instead of O(N)O(N).

Claim. With (2), the matrix Q=MDQ = MD satisfies

Q+QT=B,B=diag⁡(−1,0,…,0,1).(4)Q + Q\T = B, \qquad B = \operatorname{diag}(-1, 0, \dots, 0, 1). \tag{4}

Proof. Gauss–Lobatto quadrature with N+1N + 1 nodes is exact for polynomials of degree at most 2N−12N - 1. The product ℓi ℓj′\ell_i\, \ell_j' has degree 2N−12N - 1, so, using ℓi(ξk)=δik\ell_i(\xi_k) = \delta_{ik},

Qij=wi ℓj′(ξi)=∑k=0Nwk ℓi(ξk) ℓj′(ξk)=∫−11ℓi ℓj′ dξ.Q_{ij} = w_i\, \ell_j'(\xi_i) = \sum_{k=0}^{N} w_k\, \ell_i(\xi_k)\, \ell_j'(\xi_k) = \int_{-1}^{1} \ell_i\, \ell_j' \,\dd\xi .

Therefore

Qij+Qji=∫−11(ℓi ℓj)′ dξ=ℓi(1) ℓj(1)−ℓi(−1) ℓj(−1)=Bij,Q_{ij} + Q_{ji} = \int_{-1}^{1} (\ell_i\, \ell_j)' \,\dd\xi = \ell_i(1)\,\ell_j(1) - \ell_i(-1)\,\ell_j(-1) = B_{ij},

since the end points are nodes. ■\blacksquare

Let s(u)s(u) be the entropy function, v=∂s/∂uv = \partial s / \partial u the entropy variables, ψ\psi the entropy potential and F=vTf−ψF = v\T f - \psi the entropy flux. Suppose the two-point flux satisfies Tadmor’s condition3

(vj−vi)Tf#(ui,uj)=ψj−ψi.(5)(v_j - v_i)\T f^{\#}(u_i, u_j) = \psi_j - \psi_i . \tag{5}

Contract the volume term (3) with wi viTw_i\, v_i\T and sum over the nodes. Writing 2Q=(Q−QT)+B2Q = (Q - Q\T) + B from (4) and using the symmetry of f#f^{\#},

∑i,j2 Qij viTfij#=∑i,jQij (vi−vj)Tfij#  +  ∑iBii viTfi=−∑i,jQij (ψj−ψi)  +  [vTf]0N=−[ψ]0N+[vTf]0N  =  FN−F0.\begin{aligned} \sum_{i,j} 2\, Q_{ij}\, v_i\T f^{\#}_{ij} &= \sum_{i,j} Q_{ij}\, (v_i - v_j)\T f^{\#}_{ij} \;+\; \sum_{i} B_{ii}\, v_i\T f_i \\ &= -\sum_{i,j} Q_{ij}\, (\psi_j - \psi_i) \;+\; \bigl[v\T f\bigr]_0^N \\ &= -\bigl[\psi\bigr]_0^N + \bigl[v\T f\bigr]_0^N \;=\; F_N - F_0 . \end{aligned}

The third line uses ∑jQij=0\sum_j Q_{ij} = 0 (rows of DD sum to zero) and ∑iQij=Bjj\sum_i Q_{ij} = B_{jj} (from (4)). The volume term therefore changes the discrete entropy ∑iwi si\sum_i w_i\, s_i 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).

markdown
```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}")
```
pythonbuild_docs.py
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.

console
$ gyre docs build -o site --verification var/verification
documentation written to site
http
GET /api/v1/info HTTP/1.1
Accept: application/json
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":

markdown
::: tabs
=== "Command line"
```bash
gyre docs build -o site
```
=== "Python"
```python
from gyre.docsite import build_site
build_site("site")
```
:::
bash
gyre docs build -o site
python
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.

Link to other pages by the relative path of their Markdown file, optionally with an anchor:

markdown
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:

markdown
{{ 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:

Error against mesh sizeDemonstration studySynthetic illustration

Convergence chart: log-log axes, ticks at the mesh sizes, reference-slope triangles.

Data table
hp = 1p = 2p = 3
0.50.2344670.05488690.0125882
0.250.05412150.006247857.7034e-04
0.1250.01452448.6089e-044.9834e-05
0.06250.003429.7412e-052.9699e-06

Synthetic illustration — made-up numbers that demonstrate the component; not solver output.

A history chart draws dense series without markers:

Residual historyDemonstration studySynthetic illustration

History chart: dense lines without markers.

Data table
nonlinear iterationp = 1p = 2p = 3
0111
11.152011.298881.42121
20.2380640.3026380.362324
30.08469560.1213970.159025
40.1030060.1664660.2386
50.05826510.1061660.166501
60.01990540.04089430.0701749
70.01141030.02643040.049626
80.008025570.02096040.0430617
90.003964250.01167340.0262408
100.001841790.006114970.0150404
110.001079280.004040190.0108731
126.2289e-040.002629020.00774163
133.1433e-040.001495850.00481962
141.6402e-048.8005e-040.00310256
159.2353e-055.5870e-040.00215516
165.0136e-053.4198e-040.00144338
172.6192e-052.0143e-049.3026e-04
181.4094e-051.2221e-046.1756e-04
197.7178e-067.5454e-054.1718e-04
204.1362e-064.5594e-052.7583e-04
212.2029e-062.7379e-051.8123e-04
221.1901e-061.6678e-051.2079e-04
236.4357e-071.0168e-058.0582e-05
243.4495e-076.1450e-065.3284e-05
251.8511e-073.7181e-063.5276e-05
269.9849e-082.2612e-062.3474e-05
275.3763e-081.3728e-061.5593e-05
282.8869e-088.3111e-071.0330e-05
291.5527e-085.0399e-076.8538e-06
308.3621e-093.0604e-074.5538e-06
314.4979e-091.8560e-073.0218e-06
322.4180e-091.1250e-072.0041e-06
331.3010e-096.8247e-081.3303e-06
347.0012e-104.1409e-088.8315e-07
353.7655e-102.5111e-085.8599e-07
362.0253e-101.5228e-083.8882e-07
371.0896e-109.2375e-092.5808e-07
385.8622e-115.6033e-091.7129e-07
393.1532e-113.3982e-091.1366e-07
401.6962e-112.0611e-097.5431e-08
419.1252e-121.2502e-095.0063e-08
424.9089e-127.5827e-103.3225e-08
432.6406e-124.5990e-102.2049e-08
441.4205e-122.7894e-101.4633e-08
457.6417e-131.6919e-109.7112e-09
464.1108e-131.0262e-106.4448e-09
472.2113e-136.2241e-114.2770e-09
481.2318e-133.7751e-112.8385e-09
491.0462e-132.2898e-111.8838e-09
501.7376e-131.3888e-111.2502e-09
512.6702e-138.4234e-128.2966e-10
522.9866e-135.1091e-125.5061e-10
532.3959e-133.0988e-123.6541e-10
541.4412e-131.8795e-122.4250e-10
551.0002e-131.1400e-121.6094e-10
561.4784e-136.9144e-131.0681e-10
572.4362e-134.8723e-137.0882e-11
582.9929e-135.9858e-134.7041e-11
592.6367e-135.2735e-133.1219e-11
601.6952e-133.3904e-132.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:

Relative cost per degree of freedomDemonstration studySynthetic illustration

Bar chart: grouped, thin bars from a zero baseline.

Data table
polynomial orderresidualJacobian-vector product
p = 112.1
p = 22.65.3
p = 35.912.4

Synthetic illustration — made-up numbers that demonstrate the component; not solver output.

A single smooth curveDemonstration studySynthetic illustration

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
00
0.50.0548875
10.1091
1.50.161963
20.2128
2.50.260938
30.3057
3.50.346413
40.3824
4.50.412988
50.4375
5.50.455263
60.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.

Errors and observed ordersDemonstration studySynthetic illustration
pNhL2 errororder
120.50.234467—
140.250.05412152.115
180.1250.01452441.898
1160.06250.003422.086
220.50.0548869—
240.250.006247853.135
280.1258.6089e-042.859
2160.06259.7412e-053.144
320.50.0125882—
340.257.7034e-044.03
380.1254.9834e-053.95
3160.06252.9699e-064.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.

PassedDemonstration study3 of 3 checks passed · 0 sSynthetic illustration

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.

FailedDemonstration of a failing study2 of 3 checks passed · 0 sSynthetic illustration

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

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:

Data not available — study 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.

Analytic vortex on an invented grid100 elements · 6×6 points eachSynthetic illustration

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:

Data not available — the field sample 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:

json
{"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.

How the documentation site is built Markdown pages, verification records, field samples and the theme flow through markup.py, shortcodes.py and build.py into the static site. docs/content/**/*.md pages with front matter var/verification/*.json study records (gyre verify) var/runs/**/field.json field samples (gyre run) docs/theme/ templates, CSS, JS, KaTeX markup.py level blocks, callouts, tabs, math, code shortcodes.py charts, tables, status, fields, generators build.py navigation, link check, templates site/ <page>.html <page>.md search-index.json llms.txt site-manifest.json assets/ data/fields/ static, offline, byte-reproducible

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.

pythonsrc/gyre/docsite/generators.py
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#

console
$ 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#

  1. Front matter has title, summary, order and the right level.
  2. The summary can be read alone and says what the page delivers.
  3. The page reads well with the dial at its base level; deeper passages are in titled level blocks.
  4. Numbers come from verification output through shortcodes, not typed by hand.
  5. gyre docs build succeeds: no broken links, and no unexpected warnings in site-manifest.json.

Notes

  1. 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).

    ↩
  2. 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).

    ↩
  3. E. Tadmor, “The numerical viscosity of entropy stable schemes for systems of conservation laws. I”, Mathematics of Computation 49 (1987).

    ↩

    ↑ ↓ moveEnter open[ ] change depthResults show section and depth level