#!/usr/bin/env python3 """ B.6.8 DIMENSIONAL OVERFLOW TEST ================================== Date: 2026-03-19 Purpose: Test whether curvature overflow at the r=0.5 ceiling spontaneously produces 3D structure (out-of-plane displacement) from a 2D hexagonal template, and whether that structure shows phi-related geometry (pentagonal frustration). THEORETICAL BASIS: 1. C_potential deepens with energy coalescence (B.6.7 confirmed) 2. Maximum curvature is self-limiting: r=0.5 ceiling (B.6.7 confirmed) 3. Anti-particles = dimensional overflow (theory.txt line 32) 4. When r(x) exceeds 0.5 locally, the excess energy CANNOT be accommodated in the 2D geometry — it must express in a new dimension 5. This overflow IS the 2D→3D transition MECHANISM: Instead of clipping r at 0.49 (which discards the overflow information), we let excess curvature generate an OUT-OF-PLANE displacement z(x). The z-displacement represents the 3rd dimension emerging from curvature saturation. Below ceiling (r < 0.5): standard 2D pulsed interference At ceiling (r = 0.5): 2D pattern collapses locally Above ceiling (r > 0.5): excess → z-displacement → 3D structure The z(x) field modifies effective distances between neighbors: points displaced out-of-plane see different path lengths, changing the interference conditions and potentially creating new symmetries. WHAT WE MEASURE: - Whether z(x) is UNIFORM (no structure) or PATTERNED (structured overflow) - The symmetry of the z-pattern (2,3,4,5,6-fold) - Whether z-pattern angles approach phi-related values (72°, 108°) - The spatial relationship between 2D peaks and z-displacement - Whether the combined (x,y,z) structure has higher order than (x,y) alone DESIGNED FOR LOCAL + HETZNER: Progress output, intermediate saves. CRITICAL DESIGN RULE: OUTCOME-AGNOSTIC. No pass/fail. The data shows what it shows. The z-displacement is a DIRECT consequence of curvature overflow. No tuning of the z-generation mechanism — overflow is proportional. """ import numpy as np from scipy import ndimage from scipy.spatial import cKDTree from collections import defaultdict import json import time import os def log(msg): print(msg, flush=True) # ====================================================================== # SECTION 1: FDTD WITH DIMENSIONAL OVERFLOW # ====================================================================== def run_dimensional_overflow(grid_size=256, n_wavelengths=10, r_base=0.3, feedback_alpha=0.05, n_cycles=300, snapshot_interval=20, k=2*np.pi): """ 2D pulsed FDTD where curvature overflow generates z-displacement. When V(x) pushes r(x) past 0.5, the excess is NOT clipped — it is redirected into z(x), a scalar field representing out-of-plane displacement. The z-field accumulates over cycles. The z-displacement then feeds back into the 2D simulation by modifying the effective distance between neighboring grid points: d_eff(i,j) = sqrt(dx² + (z_i - z_j)²) This changes the Laplacian's coupling strength, creating a 2D+z coupled system. """ L = n_wavelengths dx = L / grid_size c = 1.0 dt = 0.4 * dx / c wavelength = 1.0 f0 = c / wavelength T = 1.0 / f0 steps_per_cycle = int(T / dt) x = np.linspace(-L/2, L/2, grid_size) y = np.linspace(-L/2, L/2, grid_size) X, Y = np.meshgrid(x, y) angles = np.array([0, 2*np.pi/3, 4*np.pi/3]) kx = k * np.cos(angles) ky = k * np.sin(angles) # Fields psi = np.zeros((grid_size, grid_size)) psi_prev = np.zeros((grid_size, grid_size)) # Accumulated intensity and z-displacement I_accumulated = np.zeros((grid_size, grid_size)) z_field = np.zeros((grid_size, grid_size)) # out-of-plane displacement courant2 = (c * dt / dx) ** 2 snapshots = [] r_threshold = 0.5 # the curvature ceiling for cycle in range(n_cycles): I_this_cycle = np.zeros((grid_size, grid_size)) # Compute current potential and decoherence I_norm = I_accumulated / (cycle + 1) if cycle > 0 else np.zeros_like(I_accumulated) V_field = feedback_alpha * I_norm # Compute r(x) WITHOUT clipping — track where it exceeds 0.5 r_raw = r_base + V_field # Split into 2D component (capped at threshold) and overflow (z-component) r_2d = np.minimum(r_raw, r_threshold - 0.01) # effective 2D decoherence r_2d = np.maximum(r_2d, 0.01) # Overflow: energy that exceeds the 2D curvature ceiling overflow = np.maximum(r_raw - r_threshold, 0.0) # Accumulate z-displacement from overflow # Each cycle's overflow ADDS to the z-field (dimensional accumulation) z_field += overflow * 0.1 # scale factor to keep z in reasonable range # Compute z-modified Laplacian coupling # If z varies between neighbors, the effective coupling changes: # coupling_ij = dx² / (dx² + (z_i - z_j)²) # This reduces coupling where z differs (buckling separates neighbors) dz_x = np.zeros_like(z_field) dz_y = np.zeros_like(z_field) dz_x[1:-1, :] = z_field[2:, :] - z_field[:-2, :] # z gradient in x dz_y[:, 1:-1] = z_field[:, 2:] - z_field[:, :-2] # z gradient in y # Coupling modification factor: 1 where flat, < 1 where buckled z_coupling = 1.0 / (1.0 + (dz_x**2 + dz_y**2) / (dx**2)) for step in range(steps_per_cycle): t_local = step * dt cycle_phase = step / steps_per_cycle # Position-dependent source (using 2D r, not raw) source_mask = (cycle_phase < (1.0 - r_2d)).astype(float) J = np.zeros((grid_size, grid_size)) for j in range(3): J += source_mask * np.sin(kx[j]*X + ky[j]*Y - 2*np.pi*f0*(cycle*T + t_local)) # Modified FDTD: z-coupling modulates the Laplacian laplacian = np.zeros_like(psi) laplacian[1:-1, 1:-1] = z_coupling[1:-1, 1:-1] * ( psi[2:, 1:-1] + psi[:-2, 1:-1] + psi[1:-1, 2:] + psi[1:-1, :-2] - 4 * psi[1:-1, 1:-1] ) psi_next = 2*psi - psi_prev + courant2 * laplacian + dt**2 * J # Mur absorbing boundaries mur = (c*dt - dx) / (c*dt + dx) psi_next[:, 0] = psi[:, 1] + mur * (psi_next[:, 1] - psi[:, 0]) psi_next[:, -1] = psi[:, -2] + mur * (psi_next[:, -2] - psi[:, -1]) psi_next[0, :] = psi[1, :] + mur * (psi_next[1, :] - psi[0, :]) psi_next[-1, :] = psi[-2, :] + mur * (psi_next[-2, :] - psi[-1, :]) psi_prev = psi.copy() psi = psi_next.copy() I_this_cycle += psi**2 I_this_cycle /= steps_per_cycle I_accumulated += I_this_cycle # ---- SNAPSHOT ---- if cycle % snapshot_interval == 0 or cycle == n_cycles - 1: snap = analyze_overflow_snapshot( I_norm, z_field, r_raw, overflow, grid_size, cycle ) snap["cycle"] = cycle snap["feedback_alpha"] = feedback_alpha snapshots.append(snap) log(f" cycle {cycle:4d}: CV_2d={snap['cv_2d']:.4f} " f"z_max={snap['z_max']:.5f} z_cv={snap['z_cv']:.4f} " f"overflow%={snap['overflow_frac']*100:.1f}% " f"sym_5z={snap.get('z_sym_5',0):.3f} " f"sym_6z={snap.get('z_sym_6',0):.3f} " f"z_peaks={snap['z_n_peaks']}") return snapshots, I_norm, z_field, r_raw def analyze_overflow_snapshot(I_field, z_field, r_raw, overflow, grid_size, cycle): """Analyze both the 2D intensity and the z-displacement pattern.""" edge = int(grid_size * 0.15) # 2D intensity analysis int_2d = I_field[edge:-edge, edge:-edge] I_max = np.max(int_2d) if np.max(int_2d) > 0 else 1e-20 I_mean = np.mean(int_2d) max_filt = ndimage.maximum_filter(int_2d, size=7) is_max = (int_2d == max_filt) & (int_2d > np.min(int_2d) + 0.5*(I_max - np.min(int_2d))) peak_vals = int_2d[is_max] cv_2d = float(np.std(peak_vals) / np.mean(peak_vals)) if len(peak_vals) > 1 else 0.0 # Z-field analysis (the 3D component) z_int = z_field[edge:-edge, edge:-edge] z_max = float(np.max(z_int)) z_mean = float(np.mean(z_int)) z_std = float(np.std(z_int)) z_cv = z_std / z_mean if z_mean > 1e-15 else 0.0 # Overflow fraction (how much of the grid has exceeded the ceiling) overflow_int = overflow[edge:-edge, edge:-edge] overflow_frac = float(np.sum(overflow_int > 0) / overflow_int.size) # Z-field peak analysis (where does the 3D displacement concentrate?) z_n_peaks = 0 z_peak_positions = [] z_sym_scores = {3: 0.0, 4: 0.0, 5: 0.0, 6: 0.0} if z_max > 1e-10: z_max_filt = ndimage.maximum_filter(z_int, size=7) z_is_max = (z_int == z_max_filt) & (z_int > 0.3 * z_max) z_peak_positions = np.argwhere(z_is_max) z_n_peaks = len(z_peak_positions) # Angular symmetry of z-peaks if z_n_peaks >= 5: center = np.array([z_int.shape[0]//2, z_int.shape[1]//2]) relative = z_peak_positions - center angles = np.arctan2(relative[:, 0], relative[:, 1]) angle_diffs = np.abs(np.subtract.outer(angles, angles)) n_pairs = z_n_peaks * (z_n_peaks - 1) if n_pairs == 0: n_pairs = 1 tolerance = 0.15 random_baseline = tolerance / np.pi for n_fold in [3, 4, 5, 6]: count = 0 for harmonic in range(1, n_fold): target = harmonic * 2 * np.pi / n_fold count += np.sum(np.abs(angle_diffs - target) < tolerance) raw = count / (n_pairs * (n_fold - 1)) z_sym_scores[n_fold] = float(max(0, raw - random_baseline)) # Correlation between 2D peaks and z-displacement # Do the z-peaks coincide with 2D peaks, or are they at different positions? z_at_2d_peaks = 0.0 if len(peak_vals) > 0 and z_max > 1e-10: peak_positions_2d = np.argwhere(is_max) z_vals_at_peaks = z_int[is_max] z_at_2d_peaks = float(np.mean(z_vals_at_peaks) / z_max) if z_max > 0 else 0 # Phi angle check on z-peaks phi_angles = [] if z_n_peaks >= 3: try: tree = cKDTree(z_peak_positions) dists, idxs = tree.query(z_peak_positions, k=min(4, z_n_peaks)) for i in range(z_n_peaks): if dists.shape[1] >= 3: # Angle between first two neighbors at this peak p0 = z_peak_positions[i] p1 = z_peak_positions[idxs[i, 1]] p2 = z_peak_positions[idxs[i, 2]] e1 = p1 - p0 e2 = p2 - p0 cos_a = np.dot(e1, e2) / (np.linalg.norm(e1) * np.linalg.norm(e2) + 1e-15) cos_a = np.clip(cos_a, -1, 1) phi_angles.append(float(np.degrees(np.arccos(cos_a)))) except Exception: pass mean_phi_angle = float(np.mean(phi_angles)) if phi_angles else 0.0 return { "cv_2d": cv_2d, "n_peaks_2d": len(peak_vals), "z_max": z_max, "z_mean": z_mean, "z_cv": z_cv, "z_n_peaks": z_n_peaks, "z_sym_3": z_sym_scores[3], "z_sym_4": z_sym_scores[4], "z_sym_5": z_sym_scores[5], "z_sym_6": z_sym_scores[6], "overflow_frac": overflow_frac, "z_at_2d_peaks": z_at_2d_peaks, "mean_phi_angle": mean_phi_angle, "r_max": float(np.max(r_raw)), "r_mean": float(np.mean(r_raw)), } # ====================================================================== # MAIN # ====================================================================== def main(): log("=" * 70) log("B.6.8 DIMENSIONAL OVERFLOW TEST") log("Does curvature overflow at r=0.5 ceiling produce 3D structure?") log("=" * 70) log("") grid_size = 256 n_wavelengths = 10 n_cycles = 300 snapshot_interval = 20 r_base = 0.3 # Test at multiple feedback strengths # Low α: overflow takes many cycles to appear # High α: overflow appears quickly alpha_values = [0.02, 0.05, 0.08, 0.10, 0.15, 0.20] log(f"Grid: {grid_size}x{grid_size}, {n_wavelengths} wavelengths") log(f"Cycles: {n_cycles}, snapshots every {snapshot_interval}") log(f"r_base: {r_base}, r_threshold: 0.5") log(f"Feedback α: {alpha_values}") log("") all_results = {} t_start = time.time() for alpha in alpha_values: log("=" * 70) log(f"α = {alpha} — threshold overflow into z-dimension") log("=" * 70) t0 = time.time() snapshots, I_final, z_final, r_final = run_dimensional_overflow( grid_size=grid_size, n_wavelengths=n_wavelengths, r_base=r_base, feedback_alpha=alpha, n_cycles=n_cycles, snapshot_interval=snapshot_interval, ) elapsed = time.time() - t0 log(f" Elapsed: {elapsed:.0f}s") if snapshots: first = snapshots[0] last = snapshots[-1] log(f" z_max: {first['z_max']:.5f} → {last['z_max']:.5f}") log(f" overflow: {first['overflow_frac']*100:.1f}% → {last['overflow_frac']*100:.1f}%") log(f" z_peaks: {first['z_n_peaks']} → {last['z_n_peaks']}") if last['z_max'] > 0.01: log(f" ** Z-FIELD EMERGED: max displacement = {last['z_max']:.4f} **") if last['z_sym_5'] > last['z_sym_6'] and last['z_sym_5'] > 0.01: log(f" ** 5-FOLD DOMINATES in z-pattern: sym_5={last['z_sym_5']:.3f} > sym_6={last['z_sym_6']:.3f} **") elif last['z_sym_6'] > 0.01: log(f" ** 6-FOLD DOMINATES in z-pattern: sym_6={last['z_sym_6']:.3f} > sym_5={last['z_sym_5']:.3f} **") if last['mean_phi_angle'] > 0: dist_to_72 = abs(last['mean_phi_angle'] - 72) dist_to_108 = abs(last['mean_phi_angle'] - 108) dist_to_60 = abs(last['mean_phi_angle'] - 60) if min(dist_to_72, dist_to_108) < dist_to_60: log(f" ** PHI-RELATED ANGLE: {last['mean_phi_angle']:.1f}° " f"(closer to pentagon than hexagon) **") log("") all_results[f"alpha_{alpha}"] = { "feedback_alpha": alpha, "snapshots": snapshots, "elapsed": elapsed, } _save_intermediate(all_results) total_elapsed = time.time() - t_start # ---- SUMMARY ---- log("=" * 70) log("CROSS-ALPHA SUMMARY — DIMENSIONAL OVERFLOW") log("=" * 70) log("") log(f"{'α':>6s} | {'z_max':>8s} {'z_cv':>6s} {'z_peaks':>7s} {'over%':>6s} | " f"{'sym3z':>6s} {'sym5z':>6s} {'sym6z':>6s} | {'φ_angle':>7s} {'z@2d':>5s}") log("-" * 75) for alpha in alpha_values: key = f"alpha_{alpha}" if key in all_results: snaps = all_results[key]["snapshots"] if snaps: last = snaps[-1] log(f"{alpha:6.3f} | {last['z_max']:8.5f} {last['z_cv']:6.3f} " f"{last['z_n_peaks']:7d} {last['overflow_frac']*100:5.1f}% | " f"{last['z_sym_3']:6.3f} {last['z_sym_5']:6.3f} " f"{last['z_sym_6']:6.3f} | " f"{last['mean_phi_angle']:7.1f} {last['z_at_2d_peaks']:5.2f}") log("") log(f"Total elapsed: {total_elapsed:.0f}s") _save_final(all_results, total_elapsed) def _save_intermediate(results): output_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", "tlt notes", "theory", "mathematical_framework" ) path = os.path.join(output_dir, "B6_dimensional_overflow_partial.json") try: with open(path, 'w') as f: json.dump(results, f, indent=2, default=_jd) except Exception: pass def _save_final(results, elapsed): output_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", "tlt notes", "theory", "mathematical_framework" ) json_path = os.path.join(output_dir, "B6_dimensional_overflow_results.json") txt_path = os.path.join(output_dir, "B6_dimensional_overflow_results.txt") with open(json_path, 'w') as f: json.dump(results, f, indent=2, default=_jd) with open(txt_path, 'w') as f: f.write("=" * 70 + "\n") f.write("B.6.8 DIMENSIONAL OVERFLOW TEST — RESULTS\n") f.write("=" * 70 + "\n") f.write(f"Date: {time.strftime('%Y-%m-%d %H:%M:%S')}\n") f.write(f"Elapsed: {elapsed:.0f}s\n\n") f.write("See JSON for full data.\n") log(f" Results: {txt_path}") log(f" JSON: {json_path}") def _jd(obj): if isinstance(obj, (np.integer,)): return int(obj) if isinstance(obj, (np.floating,)): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return str(obj) if __name__ == "__main__": main()