{"id":"layer2-supercell-evaluation","title":"Layer 2 Supercell Scaling Evaluation","subtitle":"Technical memo: elastic constants are converged at the 1×1×1 conventional cell; 3×3×3 adds runtime without accuracy gain.","category":"validation","tags":["mlip","matpes","supercell","convergence","projection-law"],"source":"articles/docs/layer2_supercell_evaluation.md","lang":"en","words":2165,"readMinutes":10,"toc":[{"depth":2,"text":"TL;DR","id":"tl-dr"},{"depth":2,"text":"1. Convergence of elastic constants with supercell size","id":"1-convergence-of-elastic-constants-with-supercell-size"},{"depth":3,"text":"1.1 Aggregate picture","id":"1-1-aggregate-picture"},{"depth":3,"text":"1.2 Case-by-case |ΔCᵢⱼ| between sizes (matched cases, all three constants)","id":"1-2-case-by-case-c-between-sizes-matched-cases-all-three-constants"},{"depth":3,"text":"1.3 Lattice parameter is invariant to size","id":"1-3-lattice-parameter-is-invariant-to-size"},{"depth":3,"text":"1.4 Conclusion of §1","id":"1-4-conclusion-of-1"},{"depth":2,"text":"2. Runtime / cost trade-offs","id":"2-runtime-cost-trade-offs"},{"depth":3,"text":"2.1 Per-model mean runtime (seconds/case)","id":"2-1-per-model-mean-runtime-seconds-case"},{"depth":3,"text":"2.2 The 1×1×1 total-runtime anomaly","id":"2-2-the-1-1-1-total-runtime-anomaly"},{"depth":3,"text":"2.3 CHGNet is the runtime outlier at 4×4×4","id":"2-3-chgnet-is-the-runtime-outlier-at-4-4-4"},{"depth":3,"text":"2.4 Cost recommendation","id":"2-4-cost-recommendation"},{"depth":2,"text":"3. Best-performing model / functional combinations","id":"3-best-performing-model-functional-combinations"},{"depth":3,"text":"3.1 MAE by model × functional (averaged over Cu+Ni, all available supercells)","id":"3-1-mae-by-model-functional-averaged-over-cu-ni-all-available-supercells"},{"depth":3,"text":"3.2 Findings","id":"3-2-findings"},{"depth":3,"text":"3.3 The QET ≡ TensorNet alias (data-integrity note)","id":"3-3-the-qet-tensornet-alias-data-integrity-note"},{"depth":2,"text":"4. Caveats and data-quality issues","id":"4-caveats-and-data-quality-issues"},{"depth":2,"text":"5. Recommendations","id":"5-recommendations"},{"depth":2,"text":"Appendix — per-case MAE (GPa) / runtime (s) across supercells","id":"appendix-per-case-mae-gpa-runtime-s-across-supercells"}],"html":"<h1 id=\"layer-2-supercell-scaling-technical-evaluation\">Layer 2 Supercell Scaling — Technical Evaluation</h1><blockquote>\n<p><strong>Task:</strong> t_22ae2ad9 · <strong>Author:</strong> synthesizer · <strong>Date:</strong> 2026-06-26</p>\n<p><strong>Sources:</strong> <code>data/benchmark_layer2_results.json</code> (schema <code>lupine.benchmark.layer2.v1</code>, 16 cases, 1×1×1),\n<code>data/supercell_scaling_comparison.json</code> (1×1×1 + 3×3×3, 32 rows),\n<code>data/layer2_outputs_3x3x3/</code> (16 per-case JSON + <code>_summary.json</code>),\n<code>data/layer2_outputs_4x4x4/</code> (15 per-case JSON + <code>_summary.json</code> + <code>run.log</code>),\n<code>data/targets_0K.json</code> (schema <code>lupine.targets_0K.v3</code>, reference tensors).\nMethod driver: <code>data/layer2_benchmark_task.py</code>; grid runner: <code>data/run_layer2_supercell_grid.py</code>;\ncomparator: <code>data/compare_supercell_scaling.py</code>.</p>\n</blockquote>\n<hr>\n<h2 id=\"tl-dr\">TL;DR</h2><p>Supercell size is <strong>not</strong> the limiting factor for MatPES-potential elastic constants of bulk FCC metals.\nThe mean absolute error (MAE) on the three independent cubic constants (C₁₁, C₁₂, C₄₄) is flat across cell\nsizes — <strong>13.26 → 13.29 → 13.41 GPa</strong> for 1×1×1 (4 atoms) → 3×3×3 (108) → 4×4×4 (256) — while the per-atom\nruntime rises steeply. The residual ~13 GPa gap to DFT is <strong>model-form error</strong> (weights + training pool),\nnot finite-size error, and is dominated by the functional-mismatch and a few stiff/target-shift cases.\nThe cost-optimal cell is the <strong>3×3×3 supercell</strong>: it is <em>faster than</em> the 1×1×1 run in aggregate (cache\nwarm-up artifact), matches it in accuracy to &lt;0.05 GPa, and avoids the 4×4×4 blow-up. The 1×1×1\nconventional cell remains valid for screening. Going to 4×4×4 buys nothing in accuracy and ~4× the runtime.</p>\n<hr>\n<h2 id=\"1-convergence-of-elastic-constants-with-supercell-size\">1. Convergence of elastic constants with supercell size</h2><h3 id=\"1-1-aggregate-picture\">1.1 Aggregate picture</h3><div class=\"table-wrap\"><table><thead><tr>\n<th>Supercell</th>\n<th align=\"right\">Atoms/cell</th>\n<th align=\"right\">Cases</th>\n<th align=\"right\">Mean MAE on Cᵢⱼ (GPa)</th>\n<th align=\"right\">Total runtime (s)</th>\n<th align=\"right\">Mean runtime/case (s)</th>\n</tr>\n</thead><tbody><tr>\n<td data-label=\"Supercell\">1×1×1</td>\n<td align=\"right\" data-label=\"Atoms/cell\">4</td>\n<td align=\"right\" data-label=\"Cases\">16</td>\n<td align=\"right\" data-label=\"Mean MAE on Cᵢⱼ (GPa)\"><strong>13.26</strong></td>\n<td align=\"right\" data-label=\"Total runtime (s)\">1217.76</td>\n<td align=\"right\" data-label=\"Mean runtime/case (s)\">76.11</td>\n</tr>\n<tr>\n<td data-label=\"Supercell\">3×3×3</td>\n<td align=\"right\" data-label=\"Atoms/cell\">108</td>\n<td align=\"right\" data-label=\"Cases\">16</td>\n<td align=\"right\" data-label=\"Mean MAE on Cᵢⱼ (GPa)\"><strong>13.29</strong></td>\n<td align=\"right\" data-label=\"Total runtime (s)\">519.50</td>\n<td align=\"right\" data-label=\"Mean runtime/case (s)\">32.47</td>\n</tr>\n<tr>\n<td data-label=\"Supercell\">4×4×4</td>\n<td align=\"right\" data-label=\"Atoms/cell\">256</td>\n<td align=\"right\" data-label=\"Cases\">15 †</td>\n<td align=\"right\" data-label=\"Mean MAE on Cᵢⱼ (GPa)\"><strong>13.41</strong></td>\n<td align=\"right\" data-label=\"Total runtime (s)\">2161.91</td>\n<td align=\"right\" data-label=\"Mean runtime/case (s)\">144.13</td>\n</tr>\n</tbody></table></div><p>† The 4×4×4 grid is missing <code>Cu_CHGNet_PBE</code> (15/16); the runner logged the case as started but no output\nfile and no error were produced — a <strong>silent failure</strong> (see §4). All three MAE figures use only the cases\npresent at each size; the 4×4×4 figure is therefore computed over 15 cases but is within rounding of the\n16-case number (the missing case contributes ~12.8 GPa at SC1/SC3, near the mean, so its absence is benign).</p>\n<p>A 64× increase in atom count (4 → 256) moves the ensemble MAE by <strong>+0.15 GPa</strong> — less than the rounding on\nany single constant. This is the signature of an <strong>accuracy floor set by the model, not the box</strong>.</p>\n<h3 id=\"1-2-case-by-case-c-between-sizes-matched-cases-all-three-constants\">1.2 Case-by-case |ΔCᵢⱼ| between sizes (matched cases, all three constants)</h3><div class=\"table-wrap\"><table><thead><tr>\n<th>Transition</th>\n<th align=\"right\">Matched cases</th>\n<th align=\"right\">max |ΔCᵢⱼ| (GPa)</th>\n<th align=\"right\">mean |ΔCᵢⱼ| (GPa)</th>\n<th align=\"right\">RMS |ΔCᵢⱼ| (GPa)</th>\n</tr>\n</thead><tbody><tr>\n<td data-label=\"Transition\">1 → 3</td>\n<td align=\"right\" data-label=\"Matched cases\">16</td>\n<td align=\"right\" data-label=\"max |ΔCᵢⱼ| (GPa)\">0.68</td>\n<td align=\"right\" data-label=\"mean |ΔCᵢⱼ| (GPa)\">0.249</td>\n<td align=\"right\" data-label=\"RMS |ΔCᵢⱼ| (GPa)\">0.304</td>\n</tr>\n<tr>\n<td data-label=\"Transition\">3 → 4</td>\n<td align=\"right\" data-label=\"Matched cases\">15</td>\n<td align=\"right\" data-label=\"max |ΔCᵢⱼ| (GPa)\">3.31</td>\n<td align=\"right\" data-label=\"mean |ΔCᵢⱼ| (GPa)\">0.264</td>\n<td align=\"right\" data-label=\"RMS |ΔCᵢⱼ| (GPa)\">0.605</td>\n</tr>\n</tbody></table></div><p>Interpretation:</p>\n<ul>\n<li><strong>1 → 3:</strong> essentially converged. The largest single-constant swing in the entire grid (0.68 GPa) is\nbelow the typical experimental/DFT target uncertainty (~1–3 GPa). Finite-size effects at the\nconventional cell are already negligible for bulk FCC elasticity, as expected: an MLIP with a local\ncutoff sees a perfectly periodic environment in either cell.</li>\n<li><strong>3 → 4:</strong> the <em>mean</em> change (0.26 GPa) is comparable to 1→3, but the <em>tail</em> widens (max 3.31 GPa,\nRMS 0.61). The single outlier is <strong>Ni / M3GNet / PBE</strong> (3.43 → 5.01 GPa MAE; C₁₁ drift 272.09 → 268.78).\nThis is not a systematic divergence — it is one case where the relaxation landscape of the larger cell\nsettles on a slightly different configuration. It does not change the ensemble conclusion but is the\none place the 4×4×4 result is <em>less</em> accurate than the smaller cells, not more.</li>\n</ul>\n<h3 id=\"1-3-lattice-parameter-is-invariant-to-size\">1.3 Lattice parameter is invariant to size</h3><p>Predicted equilibrium lattice parameters <code>a</code> are stable to <strong>±0.0008 Å</strong> across all three supercell sizes\nfor every case. The relaxer (<code>RelaxCalc</code>, <code>fmax=0.005</code>) converges to the same bulk geometry regardless of\ncell padding, which is why the elastic constants are so nearly size-independent: the elastic fit is taken\nat the same minimum in every case.</p>\n<h3 id=\"1-4-conclusion-of-1\">1.4 Conclusion of §1</h3><p>Elastic constants are <strong>converged at the conventional cell</strong> for this system class. The remaining ~13 GPa\nMAE cannot be closed by supercell expansion. It is model-form error and concentrates in specific\nmodel/functional combinations (§3).</p>\n<hr>\n<h2 id=\"2-runtime-cost-trade-offs\">2. Runtime / cost trade-offs</h2><h3 id=\"2-1-per-model-mean-runtime-seconds-case\">2.1 Per-model mean runtime (seconds/case)</h3><div class=\"table-wrap\"><table><thead><tr>\n<th>Model</th>\n<th align=\"right\">1×1×1</th>\n<th align=\"right\">3×3×3</th>\n<th align=\"right\">4×4×4</th>\n<th>Scaling 1→4</th>\n</tr>\n</thead><tbody><tr>\n<td data-label=\"Model\">M3GNet</td>\n<td align=\"right\" data-label=\"1×1×1\">39.2</td>\n<td align=\"right\" data-label=\"3×3×3\">9.7</td>\n<td align=\"right\" data-label=\"4×4×4\">22.9</td>\n<td data-label=\"Scaling 1→4\">0.6×</td>\n</tr>\n<tr>\n<td data-label=\"Model\">CHGNet</td>\n<td align=\"right\" data-label=\"1×1×1\">252.8</td>\n<td align=\"right\" data-label=\"3×3×3\">71.1</td>\n<td align=\"right\" data-label=\"4×4×4\">489.8</td>\n<td data-label=\"Scaling 1→4\">1.9×</td>\n</tr>\n<tr>\n<td data-label=\"Model\">TensorNet</td>\n<td align=\"right\" data-label=\"1×1×1\">9.7</td>\n<td align=\"right\" data-label=\"3×3×3\">24.0</td>\n<td align=\"right\" data-label=\"4×4×4\">74.7</td>\n<td data-label=\"Scaling 1→4\">7.7×</td>\n</tr>\n<tr>\n<td data-label=\"Model\">QET ‡</td>\n<td align=\"right\" data-label=\"1×1×1\">2.7</td>\n<td align=\"right\" data-label=\"3×3×3\">25.1</td>\n<td align=\"right\" data-label=\"4×4×4\">75.5</td>\n<td data-label=\"Scaling 1→4\">28×</td>\n</tr>\n</tbody></table></div><p>‡ QET and TensorNet resolve to the <em>same</em> <code>TensorNet-MatPES</code> checkpoint (see §3.3); the runtime\ndifferences between them at a given size reflect machine load / one-off cache states, not architecture.</p>\n<h3 id=\"2-2-the-1-1-1-total-runtime-anomaly\">2.2 The 1×1×1 total-runtime anomaly</h3><p>The 1×1×1 grid (1217.76 s) is <strong>slower in aggregate than the 3×3×3 grid (519.50 s)</strong>, which is physically\nimpossible for a pure size-scaling test. This is a <strong>cache-warm / model-download confound</strong>: the 1×1×1 runs\nwere the first invocation and paid the one-time HuggingFace download + TorchScript-trace cost for each\ncheckpoint; the 3×3×3 grid reused the cached models. The per-case <em>steady-state</em> cost is therefore better\nread from the 3×3×3 and 4×4×4 columns. The CHGNet column still shows the genuine size trend (71 → 490 s,\nroughly linear-ish in atoms), because CHGNet is the heaviest per-atom architecture.</p>\n<h3 id=\"2-3-chgnet-is-the-runtime-outlier-at-4-4-4\">2.3 CHGNet is the runtime outlier at 4×4×4</h3><p>Two CHGNet cases at 4×4×4 dominate the wall-clock:</p>\n<ul>\n<li><strong>Ni / CHGNet / r2SCAN: 1003.16 s</strong> (vs 88.7 s at 3×3×3 — an 11× blow-up for a 2.4× atom increase).</li>\n<li><strong>Ni / CHGNet / PBE: 148.0 s</strong>; <strong>Cu / CHGNet / r2SCAN: 318.3 s</strong>.</li>\n</ul>\n<p>This is super-linear scaling in the relaxation loop (CHGNet&#39;s iterative ionic relaxation at 256 atoms with\n<code>fmax=0.005</code> does many more force evaluations than at 108). For production grids, CHGNet at 4×4×4 should be\ntreated as ~10–20× the 3×3×3 cost, and budgeted accordingly.</p>\n<h3 id=\"2-4-cost-recommendation\">2.4 Cost recommendation</h3><ul>\n<li><strong>Screening / bulk benchmarks:</strong> use <strong>3×3×3</strong>. It matches the 1×1×1 accuracy, is the fastest in\nsteady-state (520 s for the full 16-case grid), and removes any residual concern about the conventional\ncell&#39;s representativeness. The 1×1×1 conventional cell is an acceptable <em>faster</em> alternative when the\nmodel cache is already warm.</li>\n<li><strong>Do not use 4×4×4 for bulk FCC elasticity.</strong> It buys ≤0.15 GPa in ensemble MAE and costs ~4× the\n3×3×3 runtime, with a pathological CHGNet tail. Reserve ≥4×4×4 for defect, surface, or\nphonon-dispersion work where the larger cell is physically motivated.</li>\n<li><strong>Memory:</strong> no OOM events were recorded in any grid. The 4×4×4 runs (256 atoms) completed on the\nsame host as the smaller cells; memory was not the binding constraint — wall-clock was.</li>\n</ul>\n<hr>\n<h2 id=\"3-best-performing-model-functional-combinations\">3. Best-performing model / functional combinations</h2><h3 id=\"3-1-mae-by-model-functional-averaged-over-cu-ni-all-available-supercells\">3.1 MAE by model × functional (averaged over Cu+Ni, all available supercells)</h3><div class=\"table-wrap\"><table><thead><tr>\n<th>Model</th>\n<th>Functional</th>\n<th align=\"right\">SC1 MAE</th>\n<th align=\"right\">SC3 MAE</th>\n<th align=\"right\">SC4 MAE</th>\n<th align=\"right\">Mean (all)</th>\n</tr>\n</thead><tbody><tr>\n<td data-label=\"Model\"><strong>M3GNet</strong></td>\n<td data-label=\"Functional\"><strong>PBE</strong></td>\n<td align=\"right\" data-label=\"SC1 MAE\"><strong>8.50</strong></td>\n<td align=\"right\" data-label=\"SC3 MAE\"><strong>8.36</strong></td>\n<td align=\"right\" data-label=\"SC4 MAE\">9.16</td>\n<td align=\"right\" data-label=\"Mean (all)\"><strong>8.67</strong></td>\n</tr>\n<tr>\n<td data-label=\"Model\">M3GNet</td>\n<td data-label=\"Functional\">r2SCAN</td>\n<td align=\"right\" data-label=\"SC1 MAE\">11.14</td>\n<td align=\"right\" data-label=\"SC3 MAE\">11.07</td>\n<td align=\"right\" data-label=\"SC4 MAE\">11.14</td>\n<td align=\"right\" data-label=\"Mean (all)\">11.12</td>\n</tr>\n<tr>\n<td data-label=\"Model\">TensorNet</td>\n<td data-label=\"Functional\">PBE</td>\n<td align=\"right\" data-label=\"SC1 MAE\">9.44</td>\n<td align=\"right\" data-label=\"SC3 MAE\">9.70</td>\n<td align=\"right\" data-label=\"SC4 MAE\">9.75</td>\n<td align=\"right\" data-label=\"Mean (all)\">9.63</td>\n</tr>\n<tr>\n<td data-label=\"Model\">QET ‡</td>\n<td data-label=\"Functional\">PBE</td>\n<td align=\"right\" data-label=\"SC1 MAE\">9.44</td>\n<td align=\"right\" data-label=\"SC3 MAE\">9.70</td>\n<td align=\"right\" data-label=\"SC4 MAE\">9.75</td>\n<td align=\"right\" data-label=\"Mean (all)\">9.63</td>\n</tr>\n<tr>\n<td data-label=\"Model\">TensorNet</td>\n<td data-label=\"Functional\">r2SCAN</td>\n<td align=\"right\" data-label=\"SC1 MAE\">15.59</td>\n<td align=\"right\" data-label=\"SC3 MAE\">15.56</td>\n<td align=\"right\" data-label=\"SC4 MAE\">15.52</td>\n<td align=\"right\" data-label=\"Mean (all)\">15.56</td>\n</tr>\n<tr>\n<td data-label=\"Model\">QET ‡</td>\n<td data-label=\"Functional\">r2SCAN</td>\n<td align=\"right\" data-label=\"SC1 MAE\">15.59</td>\n<td align=\"right\" data-label=\"SC3 MAE\">15.56</td>\n<td align=\"right\" data-label=\"SC4 MAE\">15.52</td>\n<td align=\"right\" data-label=\"Mean (all)\">15.56</td>\n</tr>\n<tr>\n<td data-label=\"Model\">CHGNet</td>\n<td data-label=\"Functional\">PBE</td>\n<td align=\"right\" data-label=\"SC1 MAE\">14.84</td>\n<td align=\"right\" data-label=\"SC3 MAE\">14.72</td>\n<td align=\"right\" data-label=\"SC4 MAE\">16.65</td>\n<td align=\"right\" data-label=\"Mean (all)\">15.40</td>\n</tr>\n<tr>\n<td data-label=\"Model\">CHGNet</td>\n<td data-label=\"Functional\">r2SCAN</td>\n<td align=\"right\" data-label=\"SC1 MAE\">21.58</td>\n<td align=\"right\" data-label=\"SC3 MAE\">21.64</td>\n<td align=\"right\" data-label=\"SC4 MAE\">21.40</td>\n<td align=\"right\" data-label=\"Mean (all)\"><strong>21.54</strong> (worst)</td>\n</tr>\n</tbody></table></div><p>‡ QET and TensorNet share the same checkpoint and return <strong>byte-identical</strong> Cᵢⱼ in all 12 matched\n(case × supercell) pairs — verified directly. They are not independent models in this release (§3.3).</p>\n<h3 id=\"3-2-findings\">3.2 Findings</h3><ol>\n<li><strong>M3GNet/PBE is the clear winner</strong> at 8.67 GPa mean, and is the only combination that stays below\n10 GPa at <em>every</em> supercell size. Its best single case is Ni/PBE at <strong>3.43 GPa</strong> (SC3).</li>\n<li><strong>PBE-trained models beat r2SCAN-trained models</strong> for elasticity, across all architectures (8.67 vs\n11.12 for M3GNet; 9.63 vs 15.56 for TensorNet/QET; 15.40 vs 21.54 for CHGNet). This is\ncounterintuitive — r2SCAN is the more accurate functional — and most plausibly reflects the relative\nmaturity / coverage of the two MatPES training pools rather than a ceiling of the architectures.</li>\n<li><strong>CHGNet/r2SCAN is the worst combination (21.54 GPa mean)</strong> and is the dominant contributor to the\nensemble MAE. Its bulk-modulus error on Ni is +11.2 % (B_pred 251.76 vs B_tgt 226.40 GPa) — the\nlargest single relative error in the grid.</li>\n<li><strong>Errors scale with the magnitude of the target.</strong> Nickel (C₁₁ ≈ 276 GPa PBE / 315 GPa r2SCAN-shifted)\nand the r2SCAN bulk-shifted targets (which are uniformly stiffer) concentrate the largest absolute\nerrors. A 21 GPa miss on a ~315 GPa C₁₁ is ~7 % relative — the same architectures hit 3–5 % on copper.</li>\n</ol>\n<h3 id=\"3-3-the-qet-tensornet-alias-data-integrity-note\">3.3 The QET ≡ TensorNet alias (data-integrity note)</h3><p>In the MatPES 2025.2 release the <code>QET</code> and <code>TensorNet</code> labels in <code>MODEL_MAP</code> (<code>data/layer2_benchmark_task.py:30</code>)\nboth resolve to a <code>TensorNet-MatPES-*</code> checkpoint:</p>\n<pre><code>(&quot;QET&quot;, &quot;PBE&quot;):       &quot;TensorNet-MatPES-PBE-2025.2&quot;\n(&quot;TensorNet&quot;, &quot;PBE&quot;): &quot;TensorNet-PES-MatPES-PBE-2025.2&quot;\n</code></pre>\n<p>The resulting Cᵢⱼ are <strong>identical to floating-point precision</strong> in every matched case (e.g. Cu/PBE:\nc11=162.35, c12=118.18, c44=71.77 at 4×4×4 for both &quot;QET&quot; and &quot;TensorNet&quot;). The 16-case grid therefore\ncontains only <strong>3 distinct architectures</strong> (M3GNet, CHGNet, TensorNet), with TensorNet counted twice.\nAny ensemble statistic that treats QET and TensorNet as independent models double-weights TensorNet.\nThe MAE tables above average per (model,label), so the alias does not inflate the headline numbers, but\n<strong>the effective N for &quot;model-form error&quot; is 3, not 4.</strong></p>\n<hr>\n<h2 id=\"4-caveats-and-data-quality-issues\">4. Caveats and data-quality issues</h2><ol>\n<li><strong>Missing 4×4×4 case.</strong> <code>data/layer2_outputs_4x4x4/Cu_CHGNet_PBE.json</code> does not exist. The runner\n(<code>run.log</code>) shows <code>=== Running Cu CHGNet PBE 4x4x4 ===</code> followed immediately by the next case with no\nerror/traceback — a silent process exit (likely OOM-kill or a torch crash inside the relaxer that the\n<code>try/except</code> in <code>layer2_benchmark_task.py</code> did not surface because no output file was written). The\n<code>_summary.json</code> reports 15 cases and the runner exited 0, so the loss went unflagged. <strong>The\n<code>supercell_scaling_comparison.json</code> predates the 4×4×4 run and therefore omits this size entirely</strong>;\nthe 4×4×4 numbers in §1.1–§1.2 were recomputed here from the raw per-case JSON.</li>\n<li><strong>QET ≡ TensorNet alias.</strong> See §3.3. The &quot;four model families&quot; framing over-counts TensorNet.</li>\n<li><strong>r2SCAN targets are synthesized, not measured.</strong> Per <code>targets_0K.json</code> (schema <code>v3</code>), the r2SCAN\nreference tensors are constructed by scaling the de Jong 2015 PBE tensors by a bulk-modulus ratio\n<code>B_r2SCAN/B_PBE</code> from Liu et al. 2024 (e.g. Cu ratio 1.1952, Ni ratio 1.1430). This is an\n<strong>approximation</strong> — it assumes the shear constants scale identically to the bulk modulus, which is not\ngenerally true. Some of the r2SCAN MAE is therefore target-construction error, not pure model error.\nFor elements with no published r2SCAN bulk modulus (Al, Ca, Sr in the full 15-metal table), the\nunshifted PBE tensor is used as the r2SCAN target (<code>r2scan_shift_ratio = 1.0</code>), which makes the\nr2SCAN/PBE comparison meaningless for those elements. Cu and Ni (the two tested here) both <em>do</em> have\nshifts, so this caveat does not affect the present grid but limits generalization.</li>\n<li><strong>Two-element scope.</strong> Only Cu and Ni (both FCC) are tested. The convergence-on-conventional-cell\nconclusion is expected to hold for other clean bulk FCC/BCC metals but is <strong>not demonstrated</strong> for\nlow-symmetry, defect-laden, or anisotropic systems, where supercell effects can be genuine.</li>\n<li><strong>Target provenance is mixed.</strong> Cu/Ni PBE tensors are from de Jong 2015 (VASP, stress-strain). The\nwider 15-metal table mixes sources (Ag: Pandit &amp; Bongiorno 2023; Au: Wang &amp; Li 2008 PW91, used because\nthe MP PBE tensor is unphysical). Cross-source comparisons at ~1–3 GPa level require care.</li>\n<li><strong>Single random seed / single relax.</strong> Each case is one relax + one elastic fit; there is no estimate\nof run-to-run variance. The 3×3→4×4 Ni/M3GNet/PBE outlier (§1.2) shows this variance is non-zero at\nthe larger cell.</li>\n</ol>\n<hr>\n<h2 id=\"5-recommendations\">5. Recommendations</h2><ol>\n<li><strong>Adopt 3×3×3 as the default bulk-elasticity cell</strong> for the Layer 2 MatPES benchmark, with 1×1×1\nretained as the fast-screening option when the model cache is warm. Retire 4×4×4 from the bulk-FCC\npipeline; it is not cost-justified.</li>\n<li><strong>Re-run the missing <code>Cu_CHGNet_PBE</code> at 4×4×4</strong> (or formally drop 4×4×4 per recommendation 1) so the\n<code>layer2_outputs_4x4x4/_summary.json</code> is either complete or explicitly marked partial. The silent\nfailure should also be hardened: <code>run_layer2_supercell_grid.py:44</code> should treat a missing output file\nas a failure even when the subprocess returns 0.</li>\n<li><strong>Regenerate <code>supercell_scaling_comparison.json</code></strong> with <code>compare_supercell_scaling.py</code> extended to all\nthree sizes so the published comparison artifact matches the raw data on disk.</li>\n<li><strong>Resolve the QET/TensorNet alias</strong> in the model roster before publishing model-vs-model rankings:\neither drop the <code>QET</code> label or replace it with a genuinely distinct checkpoint. Until then, report\n&quot;3 architectures&quot; and de-duplicate when ensembling.</li>\n<li><strong>Investigate the PBE-better-than-r2SCAN result.</strong> It likely indicates the r2SCAN MatPES training pool\nis thinner for elastic response than the PBE pool. A targeted stress/strain fine-tune on r2SCAN\nreference data (de Jong 2015 + the Liu 2024 bulk shifts) is the highest-leverage accuracy improvement\navailable — it would attack the dominant error source, whereas supercell scaling does not.</li>\n<li><strong>Expand scope before generalizing.</strong> If the &quot;conventional cell is sufficient&quot; claim is to be made\nbroadly, add 2–3 BCC metals (e.g. W, Mo) and one lower-symmetry system to the convergence study. The\npresent evidence is FCC-only.</li>\n</ol>\n<hr>\n<h2 id=\"appendix-per-case-mae-gpa-runtime-s-across-supercells\">Appendix — per-case MAE (GPa) / runtime (s) across supercells</h2><div class=\"table-wrap\"><table><thead><tr>\n<th>Element</th>\n<th>Model</th>\n<th>Func</th>\n<th align=\"right\">1×1×1</th>\n<th align=\"right\">3×3×3</th>\n<th align=\"right\">4×4×4</th>\n</tr>\n</thead><tbody><tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">CHGNet</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">12.84/308.4</td>\n<td align=\"right\" data-label=\"3×3×3\">12.79/75.4</td>\n<td align=\"right\" data-label=\"4×4×4\">— (missing)</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">CHGNet</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">23.15/58.4</td>\n<td align=\"right\" data-label=\"3×3×3\">23.05/58.6</td>\n<td align=\"right\" data-label=\"4×4×4\">23.06/318.3</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">M3GNet</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">13.37/19.2</td>\n<td align=\"right\" data-label=\"3×3×3\">13.30/10.6</td>\n<td align=\"right\" data-label=\"4×4×4\">13.31/20.6</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">M3GNet</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">12.08/90.6</td>\n<td align=\"right\" data-label=\"3×3×3\">12.14/10.8</td>\n<td align=\"right\" data-label=\"4×4×4\">12.21/24.8</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">QET</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">9.72/2.9</td>\n<td align=\"right\" data-label=\"3×3×3\">9.73/23.6</td>\n<td align=\"right\" data-label=\"4×4×4\">9.81/62.2</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">QET</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">12.56/3.1</td>\n<td align=\"right\" data-label=\"3×3×3\">12.65/24.8</td>\n<td align=\"right\" data-label=\"4×4×4\">12.60/64.5</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">TensorNet</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">9.72/2.7</td>\n<td align=\"right\" data-label=\"3×3×3\">9.73/23.4</td>\n<td align=\"right\" data-label=\"4×4×4\">9.81/62.8</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Cu</td>\n<td data-label=\"Model\">TensorNet</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">12.56/2.8</td>\n<td align=\"right\" data-label=\"3×3×3\">12.65/22.4</td>\n<td align=\"right\" data-label=\"4×4×4\">12.60/63.1</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">CHGNet</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">16.84/310.2</td>\n<td align=\"right\" data-label=\"3×3×3\">16.64/61.7</td>\n<td align=\"right\" data-label=\"4×4×4\">16.65/148.0</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">CHGNet</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">20.00/334.2</td>\n<td align=\"right\" data-label=\"3×3×3\">20.22/88.7</td>\n<td align=\"right\" data-label=\"4×4×4\">19.74/1003.2</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">M3GNet</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">3.63/1.8</td>\n<td align=\"right\" data-label=\"3×3×3\">3.43/8.5</td>\n<td align=\"right\" data-label=\"4×4×4\">5.01/20.6</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">M3GNet</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">10.19/45.3</td>\n<td align=\"right\" data-label=\"3×3×3\">9.99/9.1</td>\n<td align=\"right\" data-label=\"4×4×4\">10.08/25.4</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">QET</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">9.16/2.4</td>\n<td align=\"right\" data-label=\"3×3×3\">9.68/22.3</td>\n<td align=\"right\" data-label=\"4×4×4\">9.69/66.7</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">QET</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">18.62/2.6</td>\n<td align=\"right\" data-label=\"3×3×3\">18.46/29.6</td>\n<td align=\"right\" data-label=\"4×4×4\">18.43/108.7</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">TensorNet</td>\n<td data-label=\"Func\">PBE</td>\n<td align=\"right\" data-label=\"1×1×1\">9.16/30.5</td>\n<td align=\"right\" data-label=\"3×3×3\">9.68/21.7</td>\n<td align=\"right\" data-label=\"4×4×4\">9.69/63.1</td>\n</tr>\n<tr>\n<td data-label=\"Element\">Ni</td>\n<td data-label=\"Model\">TensorNet</td>\n<td data-label=\"Func\">r2SCAN</td>\n<td align=\"right\" data-label=\"1×1×1\">18.62/2.7</td>\n<td align=\"right\" data-label=\"3×3×3\">18.46/28.3</td>\n<td align=\"right\" data-label=\"4×4×4\">18.43/109.9</td>\n</tr>\n</tbody></table></div><p>MAE is mean absolute error over {C₁₁, C₁₂, C₄₄} vs the <code>targets_0K.json</code> reference tensor; runtime is\nwall-clock for relax + elastic fit, in seconds. Source: recomputed from per-case JSON in\n<code>data/layer2_outputs{,_3x3x3,_4x4x4}/</code> with <code>data/targets_0K.json</code> targets.</p>\n"}