""" TLT-002 EXTENDED: Full 2D Lattice Suite ======================================== Tests all well-studied 2D materials against N-wave interference patterns. For each material: 1. Compute Compton frequencies of constituent elements 2. Compare known lattice geometry against N=2,3,4,6 interference patterns 3. Calculate scale ratios (lattice constant / Compton wavelength) 4. Generate overlay images (known lattice + matching interference pattern) 5. Output comparative data Materials tested: Single-element: Graphene (C), Silicene (Si), Germanene (Ge), Stanene (Sn), Phosphorene (P), Borophene (B) Compounds: hBN, MoS2, WS2, MoSe2, WSe2 Variables: f (Compton frequency per element), c (speed of light). No other parameters. The geometry is the answer. """ import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from pathlib import Path # ============================================================================ # CONSTANTS # ============================================================================ C_LIGHT = 299_792_458.0 # m/s (exact, SI definition) H_PLANCK = 6.62607015e-34 # J·s (exact, 2019 SI) AMU_KG = 1.66053906660e-27 # kg per amu AMU_TO_HZ = AMU_KG * C_LIGHT**2 / H_PLANCK # conversion: 1 amu in Compton Hz OUTPUT_DIR = Path("/root/rhetroiluso/project_prometheus/time_ledger_theory/" "tlt results/unaudited/2D_lattice_images") OUTPUT_DIR.mkdir(parents=True, exist_ok=True) def compton_freq(mass_amu): """Compton frequency from atomic mass in amu.""" return mass_amu * AMU_TO_HZ def compton_wavelength(mass_amu): """Compton wavelength from atomic mass in amu.""" return C_LIGHT / compton_freq(mass_amu) # ============================================================================ # MATERIAL DATABASE # ============================================================================ # Each entry: name, formula, lattice_type, lattice_constants (dict in Angstroms), # elements (list of (symbol, mass_amu)), known_N (expected symmetry), # lattice_description MATERIALS = [ { 'name': 'Graphene', 'formula': 'C', 'lattice_type': 'honeycomb', 'lattice_a': 2.46, # Angstroms 'lattice_b': None, # same as a for hexagonal 'elements': [('C', 12.011)], 'expected_N': 3, 'coordination': 3, 'bond_angle': 120.0, 'space_group': 'P6/mmm', 'notes': 'Benchmark — already tested in TLT-002' }, { 'name': 'Hexagonal Boron Nitride', 'formula': 'hBN', 'lattice_type': 'honeycomb', 'lattice_a': 2.50, 'lattice_b': None, 'elements': [('B', 10.81), ('N', 14.007)], 'expected_N': 3, 'coordination': 3, 'bond_angle': 120.0, 'space_group': 'P6_3/mmc', 'notes': 'Isostructural to graphene, 1.8% lattice mismatch' }, { 'name': 'Molybdenum Disulfide', 'formula': 'MoS2', 'lattice_type': 'hexagonal_2H', 'lattice_a': 3.16, 'lattice_b': None, 'elements': [('Mo', 95.95), ('S', 32.06)], 'expected_N': 3, 'coordination': 6, # Mo in trigonal prismatic coordination 'bond_angle': 120.0, # in-plane hexagonal 'space_group': 'P6_3/mmc', 'notes': '2H phase, trigonal prismatic, monolayer direct gap 1.8 eV' }, { 'name': 'Tungsten Disulfide', 'formula': 'WS2', 'lattice_type': 'hexagonal_2H', 'lattice_a': 3.15, 'lattice_b': None, 'elements': [('W', 183.84), ('S', 32.06)], 'expected_N': 3, 'coordination': 6, 'bond_angle': 120.0, 'space_group': 'P6_3/mmc', 'notes': '2H phase, monolayer direct gap 2.0 eV' }, { 'name': 'Molybdenum Diselenide', 'formula': 'MoSe2', 'lattice_type': 'hexagonal_2H', 'lattice_a': 3.29, 'lattice_b': None, 'elements': [('Mo', 95.95), ('Se', 78.971)], 'expected_N': 3, 'coordination': 6, 'bond_angle': 120.0, 'space_group': 'P6_3/mmc', 'notes': '2H phase, monolayer direct gap 1.5 eV' }, { 'name': 'Tungsten Diselenide', 'formula': 'WSe2', 'lattice_type': 'hexagonal_2H', 'lattice_a': 3.28, 'lattice_b': None, 'elements': [('W', 183.84), ('Se', 78.971)], 'expected_N': 3, 'coordination': 6, 'bond_angle': 120.0, 'space_group': 'P6_3/mmc', 'notes': '2H phase, monolayer direct gap 1.7 eV, strong SOC' }, { 'name': 'Silicene', 'formula': 'Si', 'lattice_type': 'buckled_honeycomb', 'lattice_a': 3.87, 'lattice_b': None, 'elements': [('Si', 28.085)], 'expected_N': 3, 'coordination': 3, 'bond_angle': 116.0, # reduced from 120 due to buckling 'space_group': 'P-3m1', 'notes': 'Buckled 0.44 A, synthesized 2012 on Ag(111)' }, { 'name': 'Germanene', 'formula': 'Ge', 'lattice_type': 'buckled_honeycomb', 'lattice_a': 3.97, 'lattice_b': None, 'elements': [('Ge', 72.630)], 'expected_N': 3, 'coordination': 3, 'bond_angle': 113.0, # more buckled 'space_group': 'P-3m1', 'notes': 'Buckled 0.65 A, synthesized 2014' }, { 'name': 'Stanene', 'formula': 'Sn', 'lattice_type': 'buckled_honeycomb', 'lattice_a': 4.67, 'lattice_b': None, 'elements': [('Sn', 118.710)], 'expected_N': 3, 'coordination': 3, 'bond_angle': 109.5, # heavily buckled, approaching tetrahedral 'space_group': 'P-3m1', 'notes': 'Buckled 0.85 A, synthesized 2015, topological gap ~100 meV' }, { 'name': 'Phosphorene', 'formula': 'P', 'lattice_type': 'puckered_orthorhombic', 'lattice_a': 3.31, 'lattice_b': 4.38, # anisotropic — two distinct lattice params 'elements': [('P', 30.974)], 'expected_N': None, # NOT hexagonal — this is the test 'coordination': 3, 'bond_angle': None, # anisotropic 'space_group': 'Cmca', 'notes': 'Puckered, strongly anisotropic, bandgap 0.3-2.0 eV' }, { 'name': 'Borophene', 'formula': 'B', 'lattice_type': 'triangular_polymorphic', 'lattice_a': 2.87, # beta12 phase 'lattice_b': 5.00, # beta12 is rectangular 'elements': [('B', 10.81)], 'expected_N': None, # polymorphic — may not be simple N 'coordination': 5, # 5 or 6 depending on phase 'bond_angle': None, 'space_group': 'Pmmn', 'notes': 'beta12 phase, metallic, highly polymorphic' }, ] # ============================================================================ # N-WAVE INTERFERENCE (same as TLT-002, for reference patterns) # ============================================================================ def generate_nwave_interference(N, wavelength, grid_extent, resolution=800): """Generate 2D interference pattern from N plane waves at equal angles.""" x = np.linspace(-grid_extent, grid_extent, resolution) y = np.linspace(-grid_extent, grid_extent, resolution) X, Y = np.meshgrid(x, y) k = 2.0 * np.pi / wavelength psi = np.zeros_like(X, dtype=complex) for n in range(N): theta = 2.0 * np.pi * n / N kx = k * np.cos(theta) ky = k * np.sin(theta) psi += np.exp(1j * (kx * X + ky * Y)) intensity = np.abs(psi) ** 2 return X, Y, intensity, psi def generate_lattice_points(lattice_type, a, b=None, n_range=8): """ Generate lattice points for known 2D structures. Returns array of (x, y) positions in units of the lattice constant. """ atoms = [] if lattice_type in ('honeycomb', 'buckled_honeycomb'): # Hexagonal lattice with two-atom basis (honeycomb) a1 = np.array([1.0, 0.0]) a2 = np.array([0.5, np.sqrt(3.0) / 2.0]) d1 = np.array([0.0, 0.0]) d2 = (a1 + a2) / 3.0 for i in range(-n_range, n_range + 1): for j in range(-n_range, n_range + 1): R = i * a1 + j * a2 atoms.append(R + d1) atoms.append(R + d2) elif lattice_type == 'hexagonal_2H': # Hexagonal with metal at center of trigonal prism # In-plane projection is still hexagonal a1 = np.array([1.0, 0.0]) a2 = np.array([0.5, np.sqrt(3.0) / 2.0]) # Metal positions (one per unit cell) d_metal = np.array([0.0, 0.0]) # Chalcogen positions (two per unit cell, projections) d_X1 = (a1 + a2) / 3.0 d_X2 = (2.0 * a1 + 2.0 * a2) / 3.0 for i in range(-n_range, n_range + 1): for j in range(-n_range, n_range + 1): R = i * a1 + j * a2 atoms.append(R + d_metal) atoms.append(R + d_X1) atoms.append(R + d_X2) elif lattice_type == 'puckered_orthorhombic': # Rectangular lattice (phosphorene) b_ratio = b / a if b else 1.0 a1 = np.array([1.0, 0.0]) a2 = np.array([0.0, b_ratio]) # Four atoms per unit cell in phosphorene d1 = np.array([0.0, 0.0]) d2 = np.array([0.5, 0.17 * b_ratio]) d3 = np.array([0.5, 0.5 * b_ratio]) d4 = np.array([0.0, 0.67 * b_ratio]) for i in range(-n_range, n_range + 1): for j in range(-n_range, n_range + 1): R = i * a1 + j * a2 atoms.append(R + d1) atoms.append(R + d2) atoms.append(R + d3) atoms.append(R + d4) elif lattice_type == 'triangular_polymorphic': # Borophene beta12: triangular base with hexagonal vacancies # Rectangular unit cell b_ratio = b / a if b else 1.0 a1 = np.array([1.0, 0.0]) a2 = np.array([0.0, b_ratio]) # Approximate beta12 positions (5 atoms per rectangular unit cell) positions = [ np.array([0.0, 0.0]), np.array([0.5, 0.0]), np.array([0.25, 0.5 * b_ratio]), np.array([0.75, 0.5 * b_ratio]), np.array([0.5, b_ratio]), ] for i in range(-n_range, n_range + 1): for j in range(-n_range, n_range + 1): R = i * a1 + j * a2 for d in positions: atoms.append(R + d) return np.array(atoms) def find_bonds(atoms, max_bond_length): """Find pairs of atoms within bond distance.""" bonds = [] for i in range(len(atoms)): for j in range(i + 1, len(atoms)): dist = np.linalg.norm(atoms[i] - atoms[j]) if dist < max_bond_length and dist > 0.01: bonds.append((i, j)) return bonds def plot_material_comparison(material, X, Y, intensity, atoms, bonds, grid_extent): """Generate 3-panel comparison: N-wave pattern | known lattice | overlay.""" fig, axes = plt.subplots(1, 3, figsize=(30, 9)) N = material['expected_N'] if material['expected_N'] else 3 # Panel 1: N-wave interference pattern im0 = axes[0].pcolormesh(X, Y, intensity, cmap='inferno', shading='auto') fig.colorbar(im0, ax=axes[0], shrink=0.8, label='Intensity |psi|^2') axes[0].set_title(f'N={N} Interference Pattern\n' f'({N} plane waves at {360//N} deg)', fontsize=14) axes[0].set_aspect('equal') axes[0].set_xlabel('x / lambda') axes[0].set_ylabel('y / lambda') # Panel 2: Known lattice structure for i, j in bonds: axes[1].plot([atoms[i, 0], atoms[j, 0]], [atoms[i, 1], atoms[j, 1]], 'k-', linewidth=1.0, alpha=0.5) axes[1].scatter(atoms[:, 0], atoms[:, 1], c='black', s=20, zorder=5) axes[1].set_xlim(-4, 4) axes[1].set_ylim(-4, 4) axes[1].set_aspect('equal') a_str = f"a = {material['lattice_a']} A" if material['lattice_b']: a_str += f", b = {material['lattice_b']} A" axes[1].set_title(f"{material['name']} Lattice\n({a_str})", fontsize=14) axes[1].set_xlabel('x / a') axes[1].set_ylabel('y / a') axes[1].grid(True, alpha=0.2) # Panel 3: Overlay im2 = axes[2].pcolormesh(X, Y, intensity, cmap='inferno', shading='auto', alpha=0.8) # Scale lattice points to interference pattern coordinates # For N=3 hexagonal: maxima spacing a_tri = 2*lambda/3 # For N=4 square: maxima spacing = lambda # For N=2: spacing = lambda/2 # For N=6: maxima spacing = 2*lambda wavelength = 1.0 if N == 2: pattern_spacing = wavelength / 2.0 elif N == 3: pattern_spacing = 2.0 * wavelength / 3.0 elif N == 4: pattern_spacing = wavelength elif N == 6: pattern_spacing = 2.0 * wavelength else: pattern_spacing = wavelength scale = pattern_spacing atoms_scaled = atoms * scale mask = (np.abs(atoms_scaled[:, 0]) < grid_extent) & \ (np.abs(atoms_scaled[:, 1]) < grid_extent) axes[2].scatter(atoms_scaled[mask, 0], atoms_scaled[mask, 1], c='cyan', s=30, zorder=5, edgecolors='white', linewidths=0.5, alpha=0.9) axes[2].set_xlim(-grid_extent, grid_extent) axes[2].set_ylim(-grid_extent, grid_extent) axes[2].set_aspect('equal') axes[2].set_title(f"Overlay: N={N} + {material['name']}\n" f"(cyan = known atom positions)", fontsize=14) axes[2].set_xlabel('x / lambda') axes[2].set_ylabel('y / lambda') fig.colorbar(im2, ax=axes[2], shrink=0.8) plt.tight_layout() safe_name = material['formula'].replace('/', '_') filepath = OUTPUT_DIR / f"{safe_name}_N{N}_vs_lattice_overlay.png" fig.savefig(filepath, dpi=150, bbox_inches='tight') print(f" Saved: {filepath}") plt.close(fig) def plot_all_N_for_material(material): """Generate N=2,3,4,6 patterns with the known lattice overlaid on each.""" fig, axes = plt.subplots(2, 2, figsize=(20, 20)) axes = axes.flatten() wavelength = 1.0 grid_extent = 4.0 resolution = 800 # Generate lattice points atoms = generate_lattice_points( material['lattice_type'], material['lattice_a'], material['lattice_b'] ) N_values = [2, 3, 4, 6] spacing_map = {2: 0.5, 3: 2.0/3.0, 4: 1.0, 6: 2.0} for idx, N in enumerate(N_values): X, Y, intensity, _ = generate_nwave_interference( N, wavelength, grid_extent, resolution ) ax = axes[idx] im = ax.pcolormesh(X, Y, intensity, cmap='inferno', shading='auto', alpha=0.85) # Overlay lattice scale = spacing_map[N] * wavelength atoms_scaled = atoms * scale mask = (np.abs(atoms_scaled[:, 0]) < grid_extent) & \ (np.abs(atoms_scaled[:, 1]) < grid_extent) ax.scatter(atoms_scaled[mask, 0], atoms_scaled[mask, 1], c='cyan', s=15, zorder=5, edgecolors='white', linewidths=0.3, alpha=0.9) ax.set_xlim(-grid_extent, grid_extent) ax.set_ylim(-grid_extent, grid_extent) ax.set_aspect('equal') match_str = "" if material['expected_N'] == N: match_str = " << EXPECTED MATCH" ax.set_title(f"N={N} ({360//N} deg){match_str}", fontsize=14) ax.set_xlabel('x / lambda') ax.set_ylabel('y / lambda') plt.suptitle(f"{material['name']} ({material['formula']}) — " f"All Symmetries vs Known Lattice\n" f"Cyan dots = known atom positions", fontsize=16, y=1.02) plt.tight_layout() safe_name = material['formula'].replace('/', '_') filepath = OUTPUT_DIR / f"{safe_name}_all_N_comparison.png" fig.savefig(filepath, dpi=150, bbox_inches='tight') print(f" Saved: {filepath}") plt.close(fig) return atoms # ============================================================================ # MAIN # ============================================================================ def main(): print("=" * 70) print("TLT-002 EXTENDED: FULL 2D LATTICE SUITE") print("=" * 70) # Print conversion factor print(f"\n 1 amu = {AMU_TO_HZ:.6e} Hz (Compton frequency)") print(f" c = {C_LIGHT:.0f} m/s") print(f" h = {H_PLANCK:.5e} J·s") # ======================================================================== # COMPUTE ALL ELEMENT DATA # ======================================================================== print("\n" + "=" * 70) print("ELEMENT COMPTON FREQUENCIES") print("=" * 70) # Collect unique elements across all materials all_elements = {} for mat in MATERIALS: for sym, mass in mat['elements']: if sym not in all_elements: freq = compton_freq(mass) wvl = compton_wavelength(mass) all_elements[sym] = { 'mass_amu': mass, 'compton_freq_Hz': freq, 'compton_wavelength_m': wvl, } # Print sorted by mass for sym, data in sorted(all_elements.items(), key=lambda x: x[1]['mass_amu']): print(f" {sym:3s} mass = {data['mass_amu']:>8.3f} amu " f"f_C = {data['compton_freq_Hz']:.4e} Hz " f"lambda_C = {data['compton_wavelength_m']:.4e} m") # ======================================================================== # COMPUTE SCALE RATIOS FOR ALL MATERIALS # ======================================================================== print("\n" + "=" * 70) print("SCALE RATIOS: lattice constant / Compton wavelength") print("=" * 70) all_results = {} for mat in MATERIALS: print(f"\n {mat['name']} ({mat['formula']}):") print(f" Lattice: {mat['lattice_type']}, a = {mat['lattice_a']} A" + (f", b = {mat['lattice_b']} A" if mat['lattice_b'] else "")) mat_results = { 'name': mat['name'], 'formula': mat['formula'], 'lattice_type': mat['lattice_type'], 'lattice_a_angstrom': mat['lattice_a'], 'lattice_b_angstrom': mat['lattice_b'], 'expected_N': mat['expected_N'], 'elements': {}, } a_m = mat['lattice_a'] * 1e-10 # convert Angstroms to meters for sym, mass in mat['elements']: elem = all_elements[sym] ratio_a = a_m / elem['compton_wavelength_m'] # Also compute for b if it exists ratio_b = None if mat['lattice_b']: b_m = mat['lattice_b'] * 1e-10 ratio_b = b_m / elem['compton_wavelength_m'] mat_results['elements'][sym] = { 'mass_amu': mass, 'compton_freq_Hz': elem['compton_freq_Hz'], 'compton_wavelength_m': elem['compton_wavelength_m'], 'ratio_a_over_lambda': ratio_a, 'ratio_b_over_lambda': ratio_b, } ratio_str = f"a/lambda_C = {ratio_a:.4e}" if ratio_b: ratio_str += f", b/lambda_C = {ratio_b:.4e}" print(f" {sym}: {ratio_str}") all_results[mat['formula']] = mat_results # ======================================================================== # GENERATE IMAGES # ======================================================================== print("\n" + "=" * 70) print("GENERATING IMAGES") print("=" * 70) wavelength = 1.0 grid_extent = 4.0 resolution = 800 # Pre-generate N-wave patterns (universal — same for all materials) patterns = {} for N in [2, 3, 4, 6]: print(f"\n Computing N={N} pattern...") X, Y, intensity, psi = generate_nwave_interference( N, wavelength, grid_extent, resolution ) patterns[N] = (X, Y, intensity) # For each material: overlay comparison + all-N comparison for mat in MATERIALS: print(f"\n Processing {mat['name']} ({mat['formula']})...") # Generate lattice points atoms = generate_lattice_points( mat['lattice_type'], mat['lattice_a'], mat['lattice_b'] ) # Bond length for drawing if mat['lattice_type'] in ('honeycomb', 'buckled_honeycomb'): max_bond = 1.0 / np.sqrt(3.0) * 1.1 elif mat['lattice_type'] == 'hexagonal_2H': max_bond = 0.7 elif mat['lattice_type'] == 'puckered_orthorhombic': max_bond = 0.6 elif mat['lattice_type'] == 'triangular_polymorphic': max_bond = 0.6 else: max_bond = 0.7 # Limit atoms for bond drawing (performance) view_atoms = atoms[(np.abs(atoms[:, 0]) < 5) & (np.abs(atoms[:, 1]) < 5)] bonds = find_bonds(view_atoms, max_bond) # 3-panel comparison with best-matching N best_N = mat['expected_N'] if mat['expected_N'] else 3 X, Y, intensity = patterns[best_N] plot_material_comparison(mat, X, Y, intensity, view_atoms, bonds, grid_extent) # All-N comparison (2x2 grid) plot_all_N_for_material(mat) # ======================================================================== # WRITE DATA FILE # ======================================================================== print("\n" + "=" * 70) print("WRITING DATA FILE") print("=" * 70) data_path = OUTPUT_DIR / "full_2D_lattice_suite_data.txt" with open(data_path, 'w') as f: f.write("=" * 70 + "\n") f.write("TLT-002 EXTENDED: FULL 2D LATTICE SUITE — DATA\n") f.write("=" * 70 + "\n\n") f.write("CONVERSION FACTORS\n") f.write("-" * 40 + "\n") f.write(f" 1 amu = {AMU_TO_HZ:.6e} Hz (Compton frequency)\n") f.write(f" c = {C_LIGHT:.0f} m/s\n") f.write(f" h = {H_PLANCK:.5e} J·s\n\n") f.write("ELEMENT COMPTON DATA\n") f.write("-" * 40 + "\n") for sym, data in sorted(all_elements.items(), key=lambda x: x[1]['mass_amu']): f.write(f" {sym:3s}: mass = {data['mass_amu']:>8.3f} amu, " f"f_C = {data['compton_freq_Hz']:.6e} Hz, " f"lambda_C = {data['compton_wavelength_m']:.6e} m\n") f.write("\n\nMATERIAL SCALE RATIOS\n") f.write("-" * 40 + "\n") # Summary table f.write("\n SUMMARY TABLE: a / lambda_C for each element in each material\n") f.write(" " + "-" * 75 + "\n") f.write(f" {'Material':<25s} {'Element':<8s} {'a (A)':<8s} " f"{'lambda_C (m)':<14s} {'a/lambda_C':<14s}\n") f.write(" " + "-" * 75 + "\n") for mat_key, mat_data in all_results.items(): for sym, elem_data in mat_data['elements'].items(): f.write(f" {mat_data['name']:<25s} {sym:<8s} " f"{mat_data['lattice_a_angstrom']:<8.2f} " f"{elem_data['compton_wavelength_m']:<14.4e} " f"{elem_data['ratio_a_over_lambda']:<14.4e}\n") f.write("\n\nDETAILED PER-MATERIAL DATA\n") f.write("-" * 40 + "\n") for mat_key, mat_data in all_results.items(): f.write(f"\n {mat_data['name']} ({mat_data['formula']}):\n") f.write(f" Lattice type: {mat_data['lattice_type']}\n") f.write(f" Lattice a: {mat_data['lattice_a_angstrom']} Angstroms\n") if mat_data['lattice_b_angstrom']: f.write(f" Lattice b: {mat_data['lattice_b_angstrom']} Angstroms\n") f.write(f" Expected N: {mat_data['expected_N']}\n") for sym, elem_data in mat_data['elements'].items(): f.write(f" Element {sym}:\n") f.write(f" Mass: {elem_data['mass_amu']} amu\n") f.write(f" Compton freq: {elem_data['compton_freq_Hz']:.6e} Hz\n") f.write(f" Compton wvl: {elem_data['compton_wavelength_m']:.6e} m\n") f.write(f" a/lambda_C: {elem_data['ratio_a_over_lambda']:.6e}\n") if elem_data['ratio_b_over_lambda']: f.write(f" b/lambda_C: {elem_data['ratio_b_over_lambda']:.6e}\n") # Cross-material comparison f.write("\n\n" + "=" * 70 + "\n") f.write("CROSS-MATERIAL ANALYSIS\n") f.write("=" * 70 + "\n\n") f.write("QUESTION 1: Is the scale ratio consistent across materials?\n") f.write("-" * 50 + "\n") f.write("If the decoherence parameter t is universal, then a/lambda_C\n") f.write("should follow a predictable pattern across all materials.\n\n") # Collect all single-element honeycomb materials f.write("Single-element honeycomb materials (direct comparison):\n") honeycomb_ratios = [] for mat_key, mat_data in all_results.items(): if mat_data['lattice_type'] in ('honeycomb', 'buckled_honeycomb') \ and len(mat_data['elements']) == 1: sym = list(mat_data['elements'].keys())[0] elem = mat_data['elements'][sym] honeycomb_ratios.append({ 'name': mat_data['name'], 'symbol': sym, 'mass': elem['mass_amu'], 'ratio': elem['ratio_a_over_lambda'], 'a': mat_data['lattice_a_angstrom'], }) f.write(f" {mat_data['name']:15s} ({sym:2s}): " f"mass = {elem['mass_amu']:>8.3f} amu, " f"a = {mat_data['lattice_a_angstrom']:5.2f} A, " f"a/lambda_C = {elem['ratio_a_over_lambda']:.4e}\n") f.write("\nQUESTION 2: Do the ratios scale with atomic mass?\n") f.write("-" * 50 + "\n") if len(honeycomb_ratios) >= 2: masses = [r['mass'] for r in honeycomb_ratios] ratios = [r['ratio'] for r in honeycomb_ratios] lattice_as = [r['a'] for r in honeycomb_ratios] f.write(" If ratio = a / lambda_C, and lambda_C ~ 1/mass,\n") f.write(" then ratio ~ a * mass.\n") f.write(" If t is universal, a * mass should be proportional to\n") f.write(" a constant across all honeycomb materials.\n\n") for r in honeycomb_ratios: a_times_mass = r['a'] * r['mass'] f.write(f" {r['name']:15s}: a * mass = {r['a']:.2f} * " f"{r['mass']:.3f} = {a_times_mass:.2f} A·amu\n") f.write("\nQUESTION 3: What is phosphorene telling us?\n") f.write("-" * 50 + "\n") f.write("Phosphorene is orthorhombic (NOT hexagonal). It has two\n") f.write("distinct lattice constants (a=3.31, b=4.38 A). If all other\n") f.write("materials select N=3, does phosphorene select a different N?\n") f.write("The anisotropy (a != b) cannot be produced by equal-angle\n") f.write("plane waves. This may require unequal angular spacing or\n") f.write("a superposition of different N values.\n") f.write("\nQUESTION 4: What do compounds tell us about multi-frequency lattices?\n") f.write("-" * 50 + "\n") f.write("Compounds (hBN, MoS2, WS2, MoSe2, WSe2) have multiple\n") f.write("constituent elements, each with a different Compton frequency.\n") f.write("The scale ratio differs depending on which element is used.\n") f.write("This raises the question: does the lattice arise from one\n") f.write("dominant frequency, a combination, or the interaction between\n") f.write("the constituent frequencies?\n") print(f"\n Data saved: {data_path}") print("\n" + "=" * 70) print("FULL SUITE COMPLETE") print(f"All outputs in: {OUTPUT_DIR}") print("=" * 70) if __name__ == "__main__": main()