Skip to content

Commit df22a69

Browse files
sbryngelsonclaude
andauthored
Add simulation gallery entries and computer links (#1160)
* Add 6 new simulations to docs gallery with computer links New entries: burstwave lithotripsy, kidney stone stress waves, pitching airfoil, Mach 10 triple jet, Mach 12 Starship, whale bubble nets. Grouped cards by topic. Computer names now link to their respective HPC center pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add gallery cards, SEO improvements, and per-page dates - Add 3 new simulation gallery cards (earplug, orifice, particle cloud) - Add JSON-LD structured data to landing page for rich search results - Add per-page meta description to Doxygen header template - Switch sitemap from txt to xml format for better SEO - Add inject-dates.py build step for per-page last-updated dates - Use full git history in docs CI for accurate file dates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add YouTube icon and target_blank to gallery card links Cards linking to YouTube show the YouTube brand icon instead of a generic external-link icon. DOI links keep the original icon. All card links now open in a new tab. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix JSON-LD schema type and walltime format consistency - Change @type from SoftwareApplication to SoftwareSourceCode so programmingLanguage and codeRepository are conformant properties - Normalize "30 min" to "30m" to match other gallery entries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Link scaling plot to performance page, harden lychee CI config - Make weak scaling card clickable (links to expectedPerformance.html) - Fix lychee exclude_path: glob to regex syntax for CLI compatibility - Add URL exclude for sitemap referenced in robots.txt - Move publish step before lychee so deploys are not blocked by link errors - Set lychee fail: true so broken links fail CI - Add VERBATIM to inject-dates CMake custom command Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove invalid SoftwareSourceCode properties (applicationCategory, operatingSystem) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Exclude HPE Cray docs from lychee (broken SSL cert) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9b1e64f commit df22a69

16 files changed

Lines changed: 118 additions & 25 deletions

File tree

.github/workflows/docs.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ jobs:
1515

1616
steps:
1717
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # Full history for per-page last-updated dates
1820

1921
# We build doxygen from source because of
2022
# https://github.com/doxygen/doxygen/issues/9016
@@ -51,20 +53,14 @@ jobs:
5153
base-url-path: https://mflowcode.github.io/
5254
path-to-root: build/install/docs/mfc
5355
include-pdf: false
54-
sitemap-format: txt
56+
sitemap-format: xml
5557

5658
- name: Output stats
5759
run: |
5860
echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}"
5961
echo "url-count = ${{ steps.sitemap.outputs.url-count }}"
6062
echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}"
6163
62-
- name: Linkcheck - Lychee
63-
uses: lycheeverse/lychee-action@v2
64-
with:
65-
args: -c .lychee.toml build/install/docs/mfc/
66-
fail: false
67-
6864
- name: Publish Documentation
6965
if: github.repository == 'MFlowCode/MFC' && github.ref == 'refs/heads/master' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' )
7066
run: |
@@ -81,5 +77,11 @@ jobs:
8177
git -C ../www commit -m "Docs @ ${GITHUB_SHA::7}" || true
8278
git -C ../www push
8379
80+
- name: Linkcheck - Lychee
81+
uses: lycheeverse/lychee-action@v2
82+
with:
83+
args: -c .lychee.toml build/install/docs/mfc/
84+
fail: true
85+
8486
# DOC_PUSH_URL should be of the format:
8587
# --> https://<username>:<token>@github.com/<username>/<repository>

.lychee.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ accept = ["200", "429"]
1616

1717
verbose = "error"
1818

19-
# Exclude sitemap from link checking (it contains pre-publish production URLs)
20-
exclude_path = ["**/sitemap.txt"]
19+
# Exclude sitemap file from scanning (it contains pre-publish production URLs)
20+
exclude_path = ["sitemap\\.xml"]
21+
22+
# Exclude URLs that fail due to external issues (broken SSL, pre-deploy only, etc.)
23+
exclude = [
24+
"https://mflowcode\\.github\\.io/sitemap\\.xml", # Only exists after deployment
25+
"https://cpe\\.ext\\.hpe\\.com", # HPE Cray docs have broken SSL cert
26+
]

CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,25 @@ if (MFC_DOCUMENTATION)
806806
GEN_DOCS(post_process "MFC: Post-Process")
807807
GEN_DOCS(documentation "MFC")
808808

809+
# Inject per-page last-updated dates into documentation markdown files.
810+
# Runs after auto-generated .md files exist, before Doxygen processes them.
811+
# Uses a stamp file so it only runs once per build.
812+
add_custom_command(
813+
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp"
814+
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/examples.md"
815+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/case_constraints.md"
816+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/physics_constraints.md"
817+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/cli-reference.md"
818+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/parameters.md"
819+
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/docs/inject-dates.py"
820+
"${CMAKE_CURRENT_SOURCE_DIR}"
821+
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp"
822+
COMMENT "Injecting page dates into documentation"
823+
VERBATIM
824+
)
825+
add_custom_target(inject_page_dates DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/inject-dates.stamp")
826+
add_dependencies(documentation_doxygen inject_page_dates)
827+
809828
# > Copy Resources (main landing page & assets)
810829
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/docs/res"
811830
DESTINATION "docs/mfc")

docs/header.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
<meta name="viewport" content="width=device-width, initial-scale=1"/>
1919
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
2020
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
21-
<meta name=”keywords” content="exascale, fluid dynamics, cfd, computational fluid dynamics, compressible, hpc, bryngelson, colonius, subgrid, multiphase, frontier, summit, el capitan, aurora, amd gpu, gpu, nvidia"/>
21+
<meta name="description" content="$title — MFC documentation. Open-source exascale multiphase flow solver." />
22+
<meta name="keywords" content="exascale, fluid dynamics, cfd, computational fluid dynamics, compressible, hpc, bryngelson, colonius, subgrid, multiphase, frontier, summit, el capitan, aurora, amd gpu, gpu, nvidia"/>
2223
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
2324
<script type="text/javascript" src="$relpath^jquery.js"></script>
2425
<script type="text/javascript" src="$relpath^dynsections.js"></script>

docs/index.html

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,54 @@
2323
<meta property="og:url" content="https://mflowcode.github.io" />
2424
<meta property="og:type" content="website" />
2525
<meta name="twitter:card" content="summary_large_image" />
26+
<script type="application/ld+json">
27+
{
28+
"@context": "https://schema.org",
29+
"@type": "SoftwareSourceCode",
30+
"name": "MFC",
31+
"alternateName": "Multi-Component Flow Code",
32+
"description": "Open-source exascale multiphase flow solver. 2025 Gordon Bell Prize Finalist. Scales to 200+ trillion grid points on 43,000+ GPUs.",
33+
"url": "https://mflowcode.github.io",
34+
"license": "https://opensource.org/licenses/MIT",
35+
"programmingLanguage": ["Fortran", "Python"],
36+
"codeRepository": "https://github.com/MFlowCode/MFC",
37+
"author": {
38+
"@type": "Organization",
39+
"name": "MFlowCode",
40+
"url": "https://github.com/MFlowCode"
41+
},
42+
"award": "2025 ACM Gordon Bell Prize Finalist"
43+
}
44+
</script>
2645
<script src="https://cdn.tailwindcss.com"></script>
2746
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
2847
<link rel="icon" type="image/x-icon" href="res/icon.ico">
2948
<script>
3049
const sims = [
31-
{ name: "Viscous Taylor-Green vortex", image: "res/simulations/h.png", computer: "Delta", accelerators: "128 A100s", walltime: "17h", source: "https://www.youtube.com/watch?v=7i2h08dlDQw" },
32-
{ name: "Shedding water droplet", image: "res/simulations/a.png", computer: "Summit", accelerators: "960 V100s", walltime: "4h", source: "https://www.youtube.com/watch?v=Gjj-qZkXcrg" },
33-
{ name: "Flow over an airfoil (vorticity)", image: "res/simulations/g.png", computer: "Delta", accelerators: "128 A100s", walltime: "19h", source: "https://www.youtube.com/watch?v=FvAgnBW59cY" },
34-
{ name: "Cavitation fragments kidney stone", image: "res/simulations/d.png", computer: "Summit", accelerators: "576 V100s", walltime: "30 min", source: "https://doi.org/10.48550/arXiv.2305.09163" },
35-
{ name: "Breakup of vibrated interface", image: "res/simulations/f.png", computer: "Summit", accelerators: "128 V100s", walltime: "4h", source: "https://www.youtube.com/watch?v=XQ3g1oSg8mc" },
36-
{ name: "Mach 2 flow over a sphere", image: "res/simulations/i.png", computer: "Phoenix", accelerators: "36 V100s", walltime: "30m", source: "https://www.youtube.com/watch?v=HQGSUvYEGqM" },
37-
{ name: "Mach 2 shear layer", image: "res/simulations/j.png", computer: "Phoenix", accelerators: "32 V100s", walltime: "15m", source: "https://www.youtube.com/watch?v=GtcdCHLmJO8" },
38-
{ name: "Collapsing bubbles (pressure)", image: "res/simulations/b.png", computer: "Summit", accelerators: "216 V100s", walltime: "3h", source: "https://doi.org/10.48550/arXiv.2305.09163" },
39-
{ name: "Collapsing bubbles (streamlines)", image: "res/simulations/c.png", computer: "Summit", accelerators: "216 V100s", walltime: "3h", source: "https://doi.org/10.48550/arXiv.2305.09163" },
50+
// Rockets & jets
51+
{ name: "Mach 12 Starship Super Heavy", image: "res/simulations/o.png", computer: "Alps", computerUrl: "https://www.cscs.ch/computers/alps/", accelerators: "5K GH200s", walltime: "18h", source: "https://www.youtube.com/watch?v=NSn3OVF8N4I" },
52+
{ name: "Mach 10 triple jet booster", image: "res/simulations/n.png", computer: "Frontier", computerUrl: "https://www.olcf.ornl.gov/frontier/", accelerators: "10K GCDs", walltime: "12h", source: "https://www.youtube.com/watch?v=pMUl55xqGgM" },
53+
{ name: "Mach 2 flow over a sphere", image: "res/simulations/i.png", computer: "Phoenix", computerUrl: "https://www.pace.gatech.edu/", accelerators: "36 V100s", walltime: "30m", source: "https://www.youtube.com/watch?v=HQGSUvYEGqM" },
54+
{ name: "Mach 2 shear layer", image: "res/simulations/j.png", computer: "Phoenix", computerUrl: "https://www.pace.gatech.edu/", accelerators: "32 V100s", walltime: "15m", source: "https://www.youtube.com/watch?v=GtcdCHLmJO8" },
55+
// Aerodynamics
56+
{ name: "Flow over an airfoil (vorticity)", image: "res/simulations/g.png", computer: "Delta", computerUrl: "https://www.ncsa.illinois.edu/research/project-highlights/delta/", accelerators: "128 A100s", walltime: "19h", source: "https://www.youtube.com/watch?v=FvAgnBW59cY" },
57+
{ name: "Pitching airfoil (3D)", image: "res/simulations/m.png", computer: "Phoenix", computerUrl: "https://www.pace.gatech.edu/", accelerators: "1 A100", walltime: "5h", source: "https://www.youtube.com/watch?v=2XH-9MumDHU" },
58+
// Shock-droplet
59+
{ name: "Shedding water droplet", image: "res/simulations/a.png", computer: "Summit", computerUrl: "https://www.olcf.ornl.gov/summit/", accelerators: "960 V100s", walltime: "4h", source: "https://www.youtube.com/watch?v=Gjj-qZkXcrg" },
60+
// Biomedical & acoustics
61+
{ name: "Burstwave lithotripsy", image: "res/simulations/k.png", computer: "Delta", computerUrl: "https://www.ncsa.illinois.edu/research/project-highlights/delta/", accelerators: "128 A100s", walltime: "30m", source: "https://www.youtube.com/watch?v=XWsUTaJXGF8" },
62+
{ name: "Cavitation fragments kidney stone", image: "res/simulations/d.png", computer: "Summit", computerUrl: "https://www.olcf.ornl.gov/summit/", accelerators: "576 V100s", walltime: "30m", source: "https://doi.org/10.48550/arXiv.2305.09163" },
63+
{ name: "Kidney stone stress waves", image: "res/simulations/l.png", computer: "Bridges2", computerUrl: "https://www.psc.edu/resources/bridges-2/", accelerators: "8 V100s", walltime: "20m", source: "https://www.youtube.com/watch?v=Q2L0J68qnRw" },
64+
{ name: "Whale bubble net feeding", image: "res/simulations/p.png", computer: "Delta", computerUrl: "https://www.ncsa.illinois.edu/research/project-highlights/delta/", accelerators: "128 A100s", walltime: "30m", source: "https://www.youtube.com/watch?v=6EpP6tdCZSA" },
65+
{ name: "Earplug acoustics (kinetic energy)", image: "res/simulations/q.png", computer: "Delta", computerUrl: "https://www.ncsa.illinois.edu/research/project-highlights/delta/", accelerators: "8 A100s", walltime: "5h", source: "https://www.youtube.com/watch?v=xSW5wZkdbrc" },
66+
{ name: "Circular orifice (1 kHz)", image: "res/simulations/r.png", computer: "Delta", computerUrl: "https://www.ncsa.illinois.edu/research/project-highlights/delta/", accelerators: "16 A100s", walltime: "5h", source: "https://www.youtube.com/watch?v=jOhJ_c7eco4" },
67+
// Bubble dynamics
68+
{ name: "Collapsing bubbles (pressure)", image: "res/simulations/b.png", computer: "Summit", computerUrl: "https://www.olcf.ornl.gov/summit/", accelerators: "216 V100s", walltime: "3h", source: "https://doi.org/10.48550/arXiv.2305.09163" },
69+
{ name: "Collapsing bubbles (streamlines)", image: "res/simulations/c.png", computer: "Summit", computerUrl: "https://www.olcf.ornl.gov/summit/", accelerators: "216 V100s", walltime: "3h", source: "https://doi.org/10.48550/arXiv.2305.09163" },
70+
{ name: "Euler-Lagrange particle cloud", image: "res/simulations/s.png", computer: "Phoenix", computerUrl: "https://www.pace.gatech.edu/", accelerators: "8 A100s", walltime: "<1h", source: "https://www.youtube.com/watch?v=RoT-yC5Lxmg" },
71+
// Fundamentals
72+
{ name: "Breakup of vibrated interface", image: "res/simulations/f.png", computer: "Summit", computerUrl: "https://www.olcf.ornl.gov/summit/", accelerators: "128 V100s", walltime: "4h", source: "https://www.youtube.com/watch?v=XQ3g1oSg8mc" },
73+
{ name: "Viscous Taylor-Green vortex", image: "res/simulations/h.png", computer: "Delta", computerUrl: "https://www.ncsa.illinois.edu/research/project-highlights/delta/", accelerators: "128 A100s", walltime: "17h", source: "https://www.youtube.com/watch?v=7i2h08dlDQw" },
4074
];
4175

4276
const scalings = [
@@ -54,14 +88,14 @@
5488
<img class="h-10" src="res/logo.png" alt="">
5589
</div>
5690
<div class="flex-1 p-2 font-semibold text-center">${s.name}</div>
57-
<a class="w-10 text-center" href="${s.source}">
58-
<i class="fa-solid fa-arrow-up-right-from-square"></i>
91+
<a class="w-10 text-center text-xl" href="${s.source}" target="_blank">
92+
<i class="${s.source.includes('youtube.com') ? 'fa-brands fa-youtube' : 'fa-solid fa-arrow-up-right-from-square'}"></i>
5993
</a>
6094
</div>
6195
<div class="grid grid-cols-3 gap-4 px-4 py-2">
6296
<div class="flex flex-row items-center">
6397
<div class="pr-2"><i class="fa-solid fa-server"></i></div>
64-
<div class="flex-1 text-center">${s.computer}</div>
98+
<div class="flex-1 text-center">${s.computerUrl ? `<a href="${s.computerUrl}" class="underline hover:text-amber-400" target="_blank">${s.computer}</a>` : s.computer}</div>
6599
</div>
66100
<div class="flex flex-row items-center">
67101
<div class="pr-2"><i class="fa-solid fa-microchip"></i></div>
@@ -76,12 +110,12 @@
76110
`).join("");
77111

78112
document.getElementById("ft-scaling").innerHTML = scalings.map(s => `
79-
<div class="flex md:w-2/6 mx-auto flex-col text-white rounded bg-slate-900 rounded-b-lg">
113+
<a href="documentation/expectedPerformance.html" class="flex md:w-2/6 mx-auto flex-col text-white rounded bg-slate-900 rounded-b-lg hover:ring-2 hover:ring-amber-400 transition-shadow no-underline">
80114
<div class="flex-1 grid bg-white pb-2">
81115
<img class="place-self-center" src="${s.image}" alt="${s.label}">
82116
</div>
83117
<div class="flex-1 p-2 font-semibold text-center">${s.label}</div>
84-
</div>
118+
</a>
85119
`).join("");
86120

87121
fetch("https://api.github.com/repos/MFlowCode/MFC/releases/latest")

docs/inject-dates.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
"""Inject last-updated dates into docs before Doxygen runs.
3+
4+
Usage: python3 inject-dates.py [source_dir]
5+
source_dir defaults to current directory.
6+
"""
7+
import subprocess
8+
import sys
9+
from pathlib import Path
10+
from datetime import date
11+
12+
src_dir = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(".")
13+
docs_dir = src_dir / "docs" / "documentation"
14+
15+
for md_file in sorted(docs_dir.glob("*.md")):
16+
if "Page last updated:" in md_file.read_text():
17+
continue
18+
19+
result = subprocess.run(
20+
["git", "log", "-1", "--format=%as", "--", str(md_file)],
21+
capture_output=True, text=True,
22+
cwd=str(src_dir),
23+
)
24+
page_date = result.stdout.strip() or str(date.today())
25+
26+
with open(md_file, "a") as f:
27+
f.write(
28+
f"\n\n<div style='text-align:center; font-size:0.75rem; "
29+
f"color:#888; padding:16px 0 0;'>"
30+
f"Page last updated: {page_date}</div>\n"
31+
)

docs/res/simulations/k.png

295 KB
Loading

docs/res/simulations/l.png

150 KB
Loading

docs/res/simulations/m.png

51.9 KB
Loading

docs/res/simulations/n.png

294 KB
Loading

0 commit comments

Comments
 (0)