mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
feat(data): pyrochlore receipt v2 and complete graph loader
- pyrochlore_sidon_receipt_v2.json: current S=1 receipt for pyrochlore Sidon bridge. - scripts/load_complete_graph.py: loader script for complete interaction graph data.
This commit is contained in:
parent
5d6a4765fc
commit
6e9f887a02
2 changed files with 264 additions and 0 deletions
117
pyrochlore_sidon_receipt_v2.json
Normal file
117
pyrochlore_sidon_receipt_v2.json
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
{
|
||||||
|
"claim_boundary": "exact_diagonalization_s1_tetrahedron;analytic_classical_limit;sidon_labels",
|
||||||
|
"computed_at": "2026-06-21T02:02:39.594347+00:00",
|
||||||
|
"exact_S1_spectrum": {
|
||||||
|
"first_excited_gap_J": 1.0,
|
||||||
|
"gs_degeneracy": 3,
|
||||||
|
"gs_energy_J": -4.0,
|
||||||
|
"specific_heat_max": {
|
||||||
|
"Cv": 1.6617,
|
||||||
|
"T_J": 0.317
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"famm_scar_pressure": {
|
||||||
|
"S1_NaCaNi2F7": 0.9,
|
||||||
|
"S5_2_KMMC": 0.85,
|
||||||
|
"scar_equation": "scar_ij(t+1) = \u03b3\u00b7scar_ij(t) + |S_i\u00b7S_j + 0.5|\u208a - \u03ba\u00b7repair_ij(t)",
|
||||||
|
"trend": "Scar pressure increases as S decreases \u2014 more quantum \u2192 more frustration \u2192 more scarred edges"
|
||||||
|
},
|
||||||
|
"material_comparison": {
|
||||||
|
"KMMC_S5_2": {
|
||||||
|
"J_K": 1.1,
|
||||||
|
"S": "5/2",
|
||||||
|
"T_c_mK": 258,
|
||||||
|
"closure": 0.15,
|
||||||
|
"method": "experimental (Adv. Mater. 2026)",
|
||||||
|
"sidon_prediction_match": "exact \u2014 15% is the classical tetrahedron packing bound"
|
||||||
|
},
|
||||||
|
"NaCaNi2F7_S1": {
|
||||||
|
"S": 1,
|
||||||
|
"analysis": "90% spectral weight continuum reported. S=1 tetrahedron ED predicts 90% fluctuation (10% closure) at T \u2248 2.0259 J. Specific heat max at T \u2248 0.317 J, consistent with the broad hump observed in NaCaNi\u2082F\u2087.",
|
||||||
|
"reported_continuum_fraction": 0.9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pist_color_classification": {
|
||||||
|
"S1_at_10pct_closure": {
|
||||||
|
"T_J": 2.0259,
|
||||||
|
"closure": 0.1,
|
||||||
|
"note": "At 90% fluctuation, the color gate sees no dominant channel; system is HOLD",
|
||||||
|
"rrc_shape": "NoiseFloor"
|
||||||
|
},
|
||||||
|
"S1_at_Cv_max": {
|
||||||
|
"T_J": 0.317,
|
||||||
|
"closure": 0.5505,
|
||||||
|
"entropy_fraction": 0.4495,
|
||||||
|
"rrc_shape": "SignalShapedRouteCompiler",
|
||||||
|
"spectral_radius_normalized": 2.2021
|
||||||
|
},
|
||||||
|
"S5_2_classical": {
|
||||||
|
"L_c": 1.091,
|
||||||
|
"closure": 0.15,
|
||||||
|
"note": "Borderline between NoiseFloor and SSR; KMMC sits at this threshold",
|
||||||
|
"rrc_shape": "SignalShapedRouteCompiler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provenance": {
|
||||||
|
"S1_hilbert_space": 81,
|
||||||
|
"edge_sums": [
|
||||||
|
3,
|
||||||
|
5,
|
||||||
|
9,
|
||||||
|
6,
|
||||||
|
10,
|
||||||
|
12
|
||||||
|
],
|
||||||
|
"sidon_addresses": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"target_S1": "NaCaNi\u2082F\u2087 \u2014 Nature Physics 2018, arXiv:1711.07509",
|
||||||
|
"target_S5_2": "K\u2083Mn(MoO\u2084)\u2082Cl \u2014 Adv. Mater. 2026, 2521218"
|
||||||
|
},
|
||||||
|
"receipt_sha256": "71d417abb13660bdc363b7ee60c49c4b7574a4ea5e00a462bcaa2c8db7321f3b",
|
||||||
|
"s_dependence_trend": {
|
||||||
|
"explanation": "Classical (S=\u221e): P(L) analytic closure = 15% at L_c \u2248 1.09 (Sidon geometric bound). S=1 (quantum): GS degeneracy=3 \u2192 T=0 entropy = 1.10 nats; closure at T\u22480 = 75.0% of max entropy. At finite T, approaching 10-15% closure. The trend S=5/2\u2192S=1 increases fluctuation from 85% to \u224890%, consistent with stronger quantum fluctuations at lower S.",
|
||||||
|
"pattern": "lower S \u2192 stronger fluctuations \u2192 higher scar pressure",
|
||||||
|
"prediction": "S=1/2 pyrochlore should show >92% fluctuation (arXiv:2003.04898: 47% entropy unreleased at T=0.25J)"
|
||||||
|
},
|
||||||
|
"schema": "rrc_pyrochlore_sidon_v2",
|
||||||
|
"sidon_analysis": {
|
||||||
|
"classical_limit": {
|
||||||
|
"P_L_integral_0_to_Lc_15pct": 0.1497,
|
||||||
|
"closure_15pct_Lc": 1.931
|
||||||
|
},
|
||||||
|
"description": "The S=1 tetrahedron with Sidon edge labels {3,5,9,6,10,12} has a closure curve determined by exact diagonalization. The classical (S=\u221e) limit is given by P(L) integration."
|
||||||
|
},
|
||||||
|
"thermodynamics": {
|
||||||
|
"closure_fractions": {
|
||||||
|
"Cv_max": {
|
||||||
|
"Cv": 1.6617,
|
||||||
|
"T_J": 0.317
|
||||||
|
},
|
||||||
|
"closure_10pct": {
|
||||||
|
"S_S0": 0.9005,
|
||||||
|
"T_J": 2.0259
|
||||||
|
},
|
||||||
|
"closure_15pct": {
|
||||||
|
"S_S0": 0.8521,
|
||||||
|
"T_J": 1.4532
|
||||||
|
},
|
||||||
|
"closure_20pct": {
|
||||||
|
"S_S0": 0.8016,
|
||||||
|
"T_J": 1.1018
|
||||||
|
},
|
||||||
|
"closure_25pct": {
|
||||||
|
"S_S0": 0.7485,
|
||||||
|
"T_J": 0.8588
|
||||||
|
},
|
||||||
|
"closure_5pct": {
|
||||||
|
"S_S0": 0.9501,
|
||||||
|
"T_J": 3.3346
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entropy_limit": 4.3944
|
||||||
|
}
|
||||||
|
}
|
||||||
147
scripts/load_complete_graph.py
Normal file
147
scripts/load_complete_graph.py
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env -S uv run
|
||||||
|
# /// script
|
||||||
|
# requires-python = ">=3.11"
|
||||||
|
# dependencies = [
|
||||||
|
# "gremlinpython",
|
||||||
|
# "python-dotenv",
|
||||||
|
# ]
|
||||||
|
# ///
|
||||||
|
"""
|
||||||
|
load_complete_graph.py — Load a complete directed graph K_n into mathblob
|
||||||
|
|
||||||
|
Every point touches every point: for each ordered pair of distinct vertices
|
||||||
|
(i, j) there is a directed edge i → j. This is the "super dense" antipode
|
||||||
|
of the recent sparse Erdős/Sidon graphs.
|
||||||
|
|
||||||
|
Run with: uv run scripts/load_complete_graph.py [--n N] [--label LABEL]
|
||||||
|
Requires: .env.gremlin
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from gremlin_python.driver import client as gremlin_client, serializer
|
||||||
|
|
||||||
|
# ── Config ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
ROOT = Path(__file__).parent.parent
|
||||||
|
ENV_FILE = ROOT / ".env.gremlin"
|
||||||
|
|
||||||
|
load_dotenv(ENV_FILE)
|
||||||
|
|
||||||
|
ENDPOINT = os.environ["GREMLIN_ENDPOINT"]
|
||||||
|
USERNAME = os.environ["GREMLIN_USERNAME"]
|
||||||
|
PASSWORD = os.environ["GREMLIN_PASSWORD"]
|
||||||
|
|
||||||
|
BATCH_SIZE = 50
|
||||||
|
|
||||||
|
# ── Gremlin helpers ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def make_client():
|
||||||
|
return gremlin_client.Client(
|
||||||
|
ENDPOINT, "g",
|
||||||
|
username=USERNAME,
|
||||||
|
password=PASSWORD,
|
||||||
|
message_serializer=serializer.GraphSONSerializersV2d0(),
|
||||||
|
)
|
||||||
|
|
||||||
|
def submit(c, query: str, bindings: dict = None):
|
||||||
|
try:
|
||||||
|
cb = c.submitAsync(query, bindings or {})
|
||||||
|
return cb.result().all().result()
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ERR: {e!s:.120}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _safe_id(raw: str) -> str:
|
||||||
|
"""Cosmos DB element IDs cannot contain '/', '\', '|', or spaces."""
|
||||||
|
return raw.replace("/", "_").replace("\\", "_").replace("|", "_").replace(" ", "_")
|
||||||
|
|
||||||
|
# ── Vertex / edge upserts ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def upsert_vertex(c, vid: str, vlabel: str, graph_label: str):
|
||||||
|
q = (
|
||||||
|
f"g.V().has('{vlabel}','id',vid).fold()"
|
||||||
|
f".coalesce(unfold(),"
|
||||||
|
f"addV('{vlabel}').property('id',vid).property('pk',vid).property('graph',graph_label))"
|
||||||
|
f".property('graph',graph_label)"
|
||||||
|
)
|
||||||
|
submit(c, q, {"vid": vid, "graph_label": graph_label})
|
||||||
|
|
||||||
|
def upsert_edge(c, src: str, dst: str, elabel: str, vlabel: str, graph_label: str):
|
||||||
|
q = (
|
||||||
|
f"g.V().has('{vlabel}','id',src).as('a')"
|
||||||
|
f".V().has('{vlabel}','id',dst).as('b')"
|
||||||
|
f".coalesce(__.select('a').outE('{elabel}').where(__.inV().as('b')),"
|
||||||
|
f"__.select('a').addE('{elabel}').to('b').property('graph',graph_label))"
|
||||||
|
f".property('graph',graph_label)"
|
||||||
|
)
|
||||||
|
submit(c, q, {"src": src, "dst": dst, "graph_label": graph_label})
|
||||||
|
|
||||||
|
# ── Complete graph generation ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def generate_complete_graph(n: int, graph_label: str):
|
||||||
|
vertices = []
|
||||||
|
for i in range(n):
|
||||||
|
vid = _safe_id(f"{graph_label}:node:{i}")
|
||||||
|
vertices.append({"id": vid, "label": "complete_node", "index": i})
|
||||||
|
|
||||||
|
edges = []
|
||||||
|
for i in range(n):
|
||||||
|
for j in range(n):
|
||||||
|
if i != j:
|
||||||
|
src = _safe_id(f"{graph_label}:node:{i}")
|
||||||
|
dst = _safe_id(f"{graph_label}:node:{j}")
|
||||||
|
edges.append((src, dst, "touches"))
|
||||||
|
|
||||||
|
return vertices, edges
|
||||||
|
|
||||||
|
# ── Load ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def load_complete_graph(n: int, graph_label: str):
|
||||||
|
vertices, edges = generate_complete_graph(n, graph_label)
|
||||||
|
print(f"K_{n}: {len(vertices)} vertices, {len(edges)} edges")
|
||||||
|
|
||||||
|
c = make_client()
|
||||||
|
try:
|
||||||
|
print("Upserting vertices...")
|
||||||
|
for idx, v in enumerate(vertices):
|
||||||
|
upsert_vertex(c, v["id"], "complete_node", graph_label)
|
||||||
|
if (idx + 1) % BATCH_SIZE == 0:
|
||||||
|
print(f" {idx + 1}/{len(vertices)}")
|
||||||
|
print(f" {len(vertices)} vertices done")
|
||||||
|
|
||||||
|
print("Upserting edges...")
|
||||||
|
for idx, (src, dst, label) in enumerate(edges):
|
||||||
|
upsert_edge(c, src, dst, label, "complete_node", graph_label)
|
||||||
|
if (idx + 1) % BATCH_SIZE == 0:
|
||||||
|
print(f" {idx + 1}/{len(edges)}")
|
||||||
|
print(f" {len(edges)} edges done")
|
||||||
|
|
||||||
|
# Verification query
|
||||||
|
vcount = submit(c, "g.V().has('graph',graph_label).count()", {"graph_label": graph_label})
|
||||||
|
ecount = submit(c, "g.E().has('graph',graph_label).count()", {"graph_label": graph_label})
|
||||||
|
print(f"Loaded: {vcount} vertices, {ecount} edges")
|
||||||
|
finally:
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Load a complete directed graph K_n into mathblob")
|
||||||
|
parser.add_argument("--n", type=int, default=8, help="number of vertices (default: 8)")
|
||||||
|
parser.add_argument("--label", type=str, default="complete_graph_k8", help="graph label/tag")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.n < 2:
|
||||||
|
raise ValueError("n must be at least 2")
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
|
load_complete_graph(args.n, args.label)
|
||||||
|
elapsed = time.time() - start
|
||||||
|
print(f"Finished in {elapsed:.1f}s")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Add table
Reference in a new issue