physics-lint / app.py
nickh007's picture
Initial release: Gradio Lite in-browser build, three tabs, wheels bundled
b12e74d verified
Raw
History Blame Contribute Delete
7.77 kB
"""physics-lint — try the physical-admissibility checkers in a browser.
All computation happens in `demo_logic`, which imports no UI framework, so the
numbers shown here are produced by exactly the code the test suite exercises.
Run locally:
pip install -r requirements.txt
python app.py
"""
from __future__ import annotations
import gradio as gr
import demo_logic as dl
CSS = """
.verdict-pass textarea, .verdict-pass { border-left: 4px solid #16a34a; }
.verdict-fail textarea, .verdict-fail { border-left: 4px solid #dc2626; }
footer { visibility: hidden; }
"""
INTRO = """
# physics-lint
**Is this model physically possible?**
Three checks that answer that question in three different places — an
S-parameter file, a coupling extractor, and a certified bound on what screening
can do. Each one can tell you something is *wrong*; none can tell you something
is *right*. That distinction is the point, and it is repeated on every tab.
Everything here runs in-process from open-source packages. Nothing is uploaded
anywhere.
"""
def _tab_sparam() -> None:
gr.Markdown(
"### Five laws every passive linear network must obey\n\n"
"Vendor models, simulator exports and measurements all end up as "
"Touchstone files, and some of them describe networks that cannot "
"exist: they produce power from nothing, respond before they are "
"excited, or present negative resistance. Simulators believe them "
"anyway."
)
examples = dl.list_examples()
with gr.Row():
with gr.Column(scale=1):
picker = gr.Dropdown(
choices=examples,
value=next((e for e in examples if "passive_line" in e), None),
label="Example network",
)
upload = gr.File(label="…or upload your own .sNp",
file_types=[".s1p", ".s2p", ".s3p", ".s4p"])
run = gr.Button("Check", variant="primary")
gr.Markdown(
"**Try `active_gain`** — the same line with 3× gain bolted onto "
"the through path.\n\n"
"**Try `ferrite_isolator`** — physically real *and* fails "
"reciprocity, because its medium is non-reciprocal. A tool that "
"treats every law failure as a defect rejects legitimate hardware."
)
with gr.Column(scale=2):
out = gr.Markdown()
def _go(sel, up):
path = up.name if up is not None else sel
md, _ = dl.check_touchstone(path)
return md
run.click(_go, [picker, upload], out)
picker.change(_go, [picker, upload], out)
upload.change(_go, [picker, upload], out)
gr.Markdown("### Does the checker still discriminate?")
ctrl_btn = gr.Button("Run the negative control")
ctrl_out = gr.Markdown()
ctrl_btn.click(lambda: dl.negative_control_report(), None, ctrl_out)
gr.Markdown(f"> **Scope.** {dl.SCOPE_SPARAM}")
def _tab_ceiling() -> None:
gr.Markdown(
"### The screening ceiling\n\n"
"Pack conductors together and every other conductor screens the field "
"between any two, so a pair's mutual capacitance inside an array is at "
"most its isolated-pair value:\n\n"
"$$k = |C_\\text{full}| / |C_\\text{iso}| \\le 1$$\n\n"
"A predicted `k > 1` is **anti-screening** — it says adding a grounded "
"conductor between two others *increases* their coupling. No passive "
"arrangement of conductors in a linear medium can do that."
)
with gr.Row():
with gr.Column(scale=1):
model = gr.Dropdown(choices=list(dl.EXTRACTORS),
value=list(dl.EXTRACTORS)[1], label="Extractor")
n = gr.Slider(4, 16, value=8, step=1, label="Conductors")
pitch = gr.Slider(40, 150, value=80, step=5, label="Nominal pitch (µm)")
seed = gr.Slider(0, 20, value=1, step=1, label="Layout seed")
one = gr.Button("Check this extractor", variant="primary")
allb = gr.Button("Compare all four")
with gr.Column(scale=2):
out = gr.Markdown()
one.click(dl.check_extractor, [model, n, pitch, seed], out)
allb.click(dl.sweep_all_extractors, [n, pitch, seed], out)
gr.Markdown(
"`born_second_order` is a truncated perturbation series — the thing a "
"competent engineer reaches for when a full solve is too slow. It is "
"not a strawman. Truncating an alternating series overshoots, and the "
"overshoot drives the prediction into the impossible region."
)
gr.Markdown(f"> **Scope.** {dl.SCOPE_CEILING}")
def _tab_theorem() -> None:
b = dl.family_bounds()
gr.Markdown(
"### Try to break a machine-certified bound\n\n"
"For a four-conductor family — two tight pairs, four free parameters — "
"interval branch-and-bound has certified that **every** layout satisfies "
f"`k ≤ {dl.K_BAR:.12f}`. 237,490 certified leaves, zero failure regions, "
"full volume coverage.\n\n"
"The consequence: a pairwise-superposition extractor assumes `k ≡ 1`, so "
"it over-predicts the worst coupling by **at least 10%** on every member "
"of the family. Not on average. Always.\n\n"
"Move the sliders. If you find a point above the bound, the theorem is "
"wrong and we want to know."
)
with gr.Row():
with gr.Column(scale=1):
d0 = gr.Slider(*b["d0_um"], value=40.0, step=0.1,
label="d₀ — conductor diameter (µm)")
ptm = gr.Slider(*b["pt_mult"], value=1.1, step=0.001,
label="pt_mult — pitch multiplier")
sepm = gr.Slider(*b["sep_mult"], value=3.5, step=0.01,
label="sep_mult — pair separation")
jogm = gr.Slider(*b["jog_mult"], value=0.0, step=0.001,
label="jog_mult — vertical offset")
go = gr.Button("Evaluate", variant="primary")
with gr.Column(scale=2):
out = gr.Markdown()
for c in (d0, ptm, sepm, jogm):
c.change(dl.probe_family, [d0, ptm, sepm, jogm], out)
go.click(dl.probe_family, [d0, ptm, sepm, jogm], out)
gr.Markdown(
"The certified bound is 0.909090909091; the worst layout adversarial "
"search has found is ≈0.9053. That gap is the price of a first-order "
"interval relaxation, not a claim about physics."
)
gr.Markdown(f"> **Scope.** {dl.SCOPE_FAMILY}")
def build() -> gr.Blocks:
with gr.Blocks(title="physics-lint", css=CSS,
theme=gr.themes.Soft()) as demo:
gr.Markdown(INTRO)
with gr.Tabs():
with gr.Tab("S-parameters"):
_tab_sparam()
with gr.Tab("Coupling extractors"):
_tab_ceiling()
with gr.Tab("The certified bound"):
_tab_theorem()
gr.Markdown(
"---\n"
"Built from [`sparam-lint`](https://github.com/nickharris808/sparam-lint) "
"and [`maxwell-lint`](https://github.com/nickharris808/maxwell-lint) "
"(Apache-2.0). The certified bound is published as the "
"[`screening-ceiling`](https://huggingface.co/datasets/nickh007/screening-ceiling) "
"dataset with a zero-dependency verifier.\n\n"
"These tools **grade** a model. Producing one that is passive by "
"construction and accurate at speed in the many-body regime is the "
"[ChipletOS](https://chipletos.com) closed core."
)
return demo
if __name__ == "__main__":
build().launch()