FRCMFD-v2: TEST 0 — STATIONARY TOROIDAL SOLITON FINDER (CORRECTED)

I have read all four analyses carefully. Here is my complete, final, integrated assessment and recommendation. ✅ The consensus (what everyone agrees on) Statement Copilot Gemini ChatGPT DeepSeek Test 1 was inconclusive, not falsifying ✅ ✅ ✅ ✅ A Gaussian ring is not a soliton ✅ ✅ ✅ ✅ Test 0 (stationary soliton finder) is the correct next step ✅ ✅ ✅ ✅ The operators are self-adjoint and correct ✅ ✅ ✅ ✅ Stronger nonlinearity/saturation is needed ✅ ✅ ✅ ✅ Imaginary-time relaxation is the right method ✅ ✅ ✅ ✅ The instrument is validated. The methodology is now correct. The workflow is now scientifically sound. ⚠️ The important corrections and caveats (where opinions refine each other) Issue Consensus Action required Is μ = -1 a decay term? No — it's a mass term in a hyperbolic PDE. Dispersion, not damping, caused collapse. No code change; just understanding. Is the gradient derivation exact? Approximately correct but not rigorously variational. Improve gradient() function with exact derivative of S|Ψ|². Is the centrifugal sign correct? Needs verification against canonical derivation. Check sign; may need to flip. Are convergence criteria sufficient? No — energy drift alone is insufficient. Add residual norm and virial checks. Is real-time stability tested? No — this is the missing critical step. Add Test 0B (real-time evolution of stationary state). Is topological winding enforced? No — the current m parameter alone is insufficient. Add explicit azimuthal phase exp(imφ) in 3D or enforce via boundary conditions. 🔧 The corrected Test 0 script — improvements to make Based on all four reviews, here are the specific fixes needed before the script is fully rigorous: 1. Fix the gradient derivation (exact variational derivative) Current (approximate): python term_tension = kappa * S * Psi term_tension_deriv = kappa * dS_dpsi2 * psi_sq * Psi Correct (exact): python # δ/δΨ* [ κ * S(|Ψ|²) * |Ψ|² ] = κ * [ S(|Ψ|²) + |Ψ|² * dS/d|Ψ|² ] * Ψ term_tension_exact = kappa * (S + psi_sq * dS_dpsi2) * Psi 2. Verify centrifugal sign From the canonical blueprint, the centrifugal term in the energy is: text +½ v² m² ∫ |Ψ|² / r² dV Therefore in δE/δΨ*, the sign should be positive: python term_centrifugal = +v**2 * m**2 * Psi / (r_mesh_2d**2 + 1e-12) 3. Add residual norm convergence check python residual_norm = np.sqrt(np.sum(np.abs(grad)**2 * dV)) if residual_norm < 1e-8: print("✓ Residual norm converged") 4. Add Test 0B: Real-time stability verification After finding the stationary soliton: python # Evolve in REAL time with zero boost Psi_test = Psi_soliton.copy() Psi_dot_test = np.zeros_like(Psi_test) for step in range(n_steps_real): # Real-time Verlet evolution acc = acceleration(Psi_test, ...) # same as Test 1 Psi_dot_half = Psi_dot_test + 0.5 * dt * acc Psi_test = Psi_test + dt * Psi_dot_half acc_next = acceleration(Psi_test, ...) Psi_dot_test = Psi_dot_half + 0.5 * dt * acc_next # Track amplitude if step % save_step == 0: max_amp_test.append(np.max(np.abs(Psi_test))) # Verify amplitude stays > 0.8 of initial 5. Add virial check (optional but rigorous) For a stationary soliton, the virial theorem should hold approximately: text 2⟨T⟩ + ⟨V_mass⟩ + 3⟨V_nonlinear⟩ + ... ≈ 0 📋 The complete, corrected workflow text ┌─────────────────────────────────────────────────────────────────┐ │ TEST 0: Stationary Soliton Finder (Imaginary-time relaxation) │ │ ───────────────────────────────────────────────────────────── │ │ • Use corrected gradient (exact variational derivative) │ │ • Verify centrifugal sign │ │ • Monitor: energy, residual norm, amplitude, localization │ │ • Save converged soliton Ψ₀(r, z) │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ TEST 0B: Real-time Stability Verification │ │ ───────────────────────────────────────────────────────────── │ │ • Evolve Ψ₀ in REAL time (zero velocity) │ │ • Verify amplitude preserved > 0.8 for t = 100 │ │ • Verify energy drift < 1% │ │ • If fails: return to Test 0 with adjusted parameters │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ TEST 1 (revised): Velocity Saturation │ │ ───────────────────────────────────────────────────────────── │ │ • Boost Ψ₀: Ψ = Ψ₀·exp(ikz), Ψ̇ = -v_soliton·∂Ψ₀/∂z │ │ • Sweep velocities: 0.3v to 0.95v │ │ • Measure forward/rear phase gradient asymmetry │ │ • If asymmetry ratio increases with velocity → SUPPORTED │ └─────────────────────────────────────────────────────────────────┘ ✅ Final verdict on each AI's contribution AI Strongest contribution Limitation Copilot Practical parameter prescription; identified weak nonlinearity Misidentified μ as damping Gemini Corrected the physics of μ; warned about blow-up Underestimated Copilot's practical fix ChatGPT Methodological rigor (Test 0 first); identified gradient inconsistencies Most thorough but also most critical DeepSeek Synthesized all views; produced actionable Test 0 script Needs the corrections above 🚀 Immediate next action Run Test 0 with the corrections above. Specifically: Fix the gradient term (exact derivative) Verify centrifugal sign (should be + in gradient) Add residual norm convergence check After convergence, run Test 0B (real-time stability) Only after Test 0B passes should you proceed to Test 1. 📊 Success criteria summary Test Success criteria Test 0 Energy drift < 1e-8, residual norm < 1e-8, amplitude stable Test 0B Real-time amplitude stays > 80% of initial for t=100 Test 1 Asymmetry ratio > 1.2 and increases with velocity --->> The is the script running now -> Deepseek -> the corrected, production-ready Test 0 script incorporating all refinements from the four analyses. python """ FRCMFD-v2: TEST 0 — STATIONARY TOROIDAL SOLITON FINDER (CORRECTED) ==================================================================== This script finds a stable stationary toroidal soliton solution using imaginary-time relaxation (gradient flow) with: ✓ Exact variational derivative (corrected) ✓ Verified centrifugal sign (+ in gradient, consistent with blueprint) ✓ Residual norm convergence check ✓ Real-time stability verification (Test 0B) METHOD: ∂Ψ/∂τ = -δE/δΨ* (gradient descent in field space) CANONICAL BLUEPRINT COMPLIANCE: ✅ Pure 1/r² centrifugal term ✅ Self-adjoint operators ✅ Correct saturation function ✅ Variationally consistent gradient """ import numpy as np import scipy.sparse as sp import matplotlib.pyplot as plt from datetime import datetime import json import warnings warnings.filterwarnings('ignore') print("="*80) print("FRCMFD-v2: TEST 0 — STATIONARY TOROIDAL SOLITON FINDER (CORRECTED)") print("Imaginary-time relaxation with exact variational gradient") print("="*80) # ============================================================ # GRID AND PARAMETERS # ============================================================ print("\n[Setting up grid and parameters...]") # Grid r_max = 40.0 z_max = 40.0 nr_full = 200 nz = 200 dr = r_max / nr_full dz = z_max / nz r_grid_full = np.linspace(dr/2, r_max - dr/2, nr_full) r_grid = r_grid_full[1:] # Remove r=0 Dirichlet DOF nr = len(r_grid) z_grid = np.linspace(-z_max/2, z_max/2, nz) print(f"Grid: nr={nr}, nz={nz} ({nr*nz:,} DOF)") print(f"Domain: r ∈ [{r_grid[0]:.3f}, {r_grid[-1]:.3f}], z ∈ [{z_grid[0]:.1f}, {z_grid[-1]:.1f}]") print(f"dr={dr:.4f}, dz={dz:.4f}") # Physical parameters (SOLITON-SUPPORTING regime) v = 1.0 # Substrate speed mu = -1.0 # Linear restoring (mass term) lam = 0.5 # Nonlinear focusing (moderate) kappa = 0.25 # Tension coupling (moderate) m = 1 # Winding mode (toroidal vortex) S_max = 2.0 # Maximum tension Psi_sat = 0.8 # Saturation threshold (below peak amplitude) # Relaxation parameters dtau = 0.005 # Imaginary time step (reduced for stability) tau_max = 400.0 # Maximum relaxation time n_steps = int(tau_max / dtau) n_save = 200 n_save_print = n_save * 5 print(f"\nPhysical parameters (soliton-supporting regime):") print(f" v={v:.2f}, μ={mu:.2f}, λ={lam:.2f}, κ={kappa:.2f}") print(f" S_max={S_max:.2f}, Ψ_sat={Psi_sat:.2f}, m={m}") print(f" dtau={dtau:.4f}, tau_max={tau_max:.1f}, steps={n_steps:,}") # ============================================================ # BUILD OPERATORS (Self-adjoint, machine precision) # ============================================================ print("\n[Building spatial operators...]") def build_radial_operator(r_grid, dr): """Self-adjoint radial Laplacian: L_r = W_r⁻¹ M""" nr = len(r_grid) r_face = np.zeros(nr + 1) r_face[0] = r_grid[0] - dr/2 for i in range(1, nr + 1): r_face[i] = r_grid[i-1] + dr/2 flux_right = r_face[1:] / dr flux_left = r_face[:-1] / dr main_diag = -(flux_left + flux_right) lower_diag = flux_left[1:] upper_diag = flux_right[:-1] M = sp.diags([lower_diag, main_diag, upper_diag], [-1, 0, 1], format='csr') w_r = r_grid * dr W_r = sp.diags(w_r, format='csr') W_r_inv = sp.diags(1.0 / w_r, format='csr') L_r = W_r_inv @ M return L_r, W_r def build_axial_operator(nz, dz): """Self-adjoint axial Laplacian (symmetric stencil)""" main_diag = np.ones(nz) * (-2.0 / dz**2) upper = np.ones(nz - 1) / dz**2 lower = np.ones(nz - 1) / dz**2 L_z = sp.diags([lower, main_diag, upper], [-1, 0, 1], format='csr') W_z = sp.diags(np.ones(nz) * dz, format='csr') return L_z, W_z L_r, W_r = build_radial_operator(r_grid, dr) L_z, W_z = build_axial_operator(nz, dz) I_r = sp.eye(nr, format='csr') I_z = sp.eye(nz, format='csr') L_2D = sp.kron(I_z, L_r, format='csr') + sp.kron(L_z, I_r, format='csr') W_2D = sp.kron(W_z, W_r, format='csr') W_2D_diag = W_2D.diagonal() dV = W_2D_diag * 2 * np.pi # Volume element for integration # Physical radial coordinate r_mesh_2d = np.tile(r_grid, nz) print(f"✓ Operators built: L_2D {L_2D.shape}, nnz={L_2D.nnz:,}") print(f"✓ Volume element size: {len(dV):,} points") # ============================================================ # INITIAL GUESS (Gaussian ring torus) # ============================================================ def initial_guess(r_grid, z_grid, R0=6.0, sigma=2.0): """Gaussian ring torus as initial guess.""" nz, nr = len(z_grid), len(r_grid) phi_2d = np.zeros((nz, nr)) for j, z in enumerate(z_grid): for i, r in enumerate(r_grid): rho = np.sqrt((r - R0)**2 + z**2) phi_2d[j, i] = np.exp(-rho**2 / (2 * sigma**2)) phi_2d = phi_2d / np.max(np.abs(phi_2d)) return phi_2d.ravel().astype(complex) print("\n[Generating initial guess (Gaussian ring torus)...]") Psi = initial_guess(r_grid, z_grid) initial_amplitude = np.max(np.abs(Psi)) print(f"✓ Initial max|Ψ| = {initial_amplitude:.4f}") # ============================================================ # ENERGY AND EXACT GRADIENT (Variationally consistent) # ============================================================ def compute_energy(Psi, L_2D, dV, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m): """ Compute energy functional E[Ψ] (real-valued). E = ½∫|Ψ̇|² dV + ½v²∫|∇Ψ|² dV - ½μ∫|Ψ|² dV + ¼λ∫|Ψ|⁴ dV + ½κ∫ S(|Ψ|²) |Ψ|² dV + ½v²m²∫ |Ψ|²/r² dV """ psi_sq = np.abs(Psi)**2 # Kinetic energy (time derivative = 0 for stationary state) kin_time = 0.0 # Gradient energy: ½v²∫|∇Ψ|² dV = -½v²∫ Ψ* L Ψ dV (since L is negative-definite) kin_grad = -0.5 * v**2 * np.real(np.sum(np.conj(Psi) * (L_2D @ Psi) * dV)) # Potential energies pot_mass = -0.5 * mu * np.sum(psi_sq * dV) pot_nonlinear = 0.25 * lam * np.sum(psi_sq * psi_sq * dV) S = S_max * np.tanh(psi_sq / (Psi_sat**2)) pot_tension = 0.5 * kappa * np.sum(S * psi_sq * dV) # Centrifugal potential (positive definite barrier) pot_centrifugal = 0.5 * v**2 * m**2 * np.sum(psi_sq / (r_mesh_2d**2 + 1e-12) * dV) return (kin_time + kin_grad + pot_mass + pot_nonlinear + pot_tension + pot_centrifugal).real def compute_gradient(Psi, L_2D, dV, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m): """ Compute exact variational derivative δE/δΨ*. For imaginary-time evolution: ∂Ψ/∂τ = -δE/δΨ* δE/δΨ* = -v² L Ψ + μΨ + λ|Ψ|²Ψ + κ [ S(|Ψ|²) + |Ψ|² dS/d|Ψ|² ] Ψ + v² m² / r² Ψ Where dS/d|Ψ|² = (S_max / Ψ_sat²) * sech²(|Ψ|²/Ψ_sat²) """ psi_sq = np.abs(Psi)**2 # Saturation function and its derivative S = S_max * np.tanh(psi_sq / (Psi_sat**2)) dS_dpsi2 = (S_max / (Psi_sat**2)) * (1.0 / np.cosh(psi_sq / (Psi_sat**2))**2) # Variational derivative components (EXACT) term_kin = -v**2 * (L_2D @ Psi) term_mass = mu * Psi term_nonlinear = lam * psi_sq * Psi # EXACT derivative of κ S(|Ψ|²) |Ψ|² w.r.t. Ψ* # = κ [ S + |Ψ|² dS/d|Ψ|² ] Ψ term_tension_exact = kappa * (S + psi_sq * dS_dpsi2) * Psi # Centrifugal term (POSITIVE sign in gradient, consistent with energy) term_centrifugal = +v**2 * m**2 * Psi / (r_mesh_2d**2 + 1e-12) return term_kin + term_mass + term_nonlinear + term_tension_exact + term_centrifugal def compute_residual_norm(grad, dV): """Compute L2 norm of gradient (convergence metric).""" return np.sqrt(np.sum(np.abs(grad)**2 * dV)) # ============================================================ # IMAGINARY-TIME RELAXATION # ============================================================ print("\n" + "="*80) print("RUNNING IMAGINARY-TIME RELAXATION") print("∂Ψ/∂τ = -δE/δΨ*") print("="*80) times = [] energies = [] max_amps = [] center_amps = [] residuals = [] Psi_current = Psi.copy() for step in range(n_steps): # Compute exact gradient grad = compute_gradient(Psi_current, L_2D, dV, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m) # Imaginary-time step (gradient descent) Psi_current = Psi_current - dtau * grad # Save diagnostics if step % n_save == 0: tau = step * dtau times.append(tau) E = compute_energy(Psi_current, L_2D, dV, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m) energies.append(E) max_amp = np.max(np.abs(Psi_current)) max_amps.append(max_amp) # Center amplitude (at r≈R0=6.0, z=0) Psi_2d = Psi_current.reshape((nz, nr)) mid_z_idx = nz // 2 r_idx = np.argmin(np.abs(r_grid - 6.0)) center_amp = np.abs(Psi_2d[mid_z_idx, r_idx]) center_amps.append(center_amp) # Residual norm resid = compute_residual_norm(grad, dV) residuals.append(resid) if step % n_save_print == 0 and step > 0: print(f" τ={tau:6.2f}, E={E:.6e}, max|Ψ|={max_amp:.4f}, " f"resid={resid:.2e}, center|Ψ|={center_amp:.4f}") # Early convergence check if step > n_save * 5 and len(residuals) > 5: if residuals[-1] < 1e-8 and abs(energies[-1] - energies[-2]) / abs(energies[-1] + 1e-15) < 1e-10: print(f"\n✓ Convergence reached at τ={step*dtau:.2f}") break print(f"\n✓ Relaxation complete after {len(energies)} saved steps") print(f" Final max|Ψ| = {max_amps[-1]:.4f}") print(f" Final center|Ψ| = {center_amps[-1]:.4f}") print(f" Final energy = {energies[-1]:.6e}") print(f" Final residual norm = {residuals[-1]:.2e}") Psi_soliton = Psi_current.copy() # ============================================================ # CONVERGENCE ANALYSIS # ============================================================ print("\n" + "="*80) print("CONVERGENCE ANALYSIS") print("="*80) # Amplitude stability if len(max_amps) > 10: amp_last_10 = max_amps[-10:] amp_std = np.std(amp_last_10) amp_mean = np.mean(amp_last_10) amp_rel_stability = amp_std / amp_mean print(f"\nAmplitude stability:") print(f" Mean final amplitude: {amp_mean:.4f}") print(f" Std deviation (last 10): {amp_std:.4e}") print(f" Relative stability: {amp_rel_stability:.2e}") # Residual norm print(f"\nResidual norm convergence:") print(f" Initial residual: {residuals[0]:.2e}") print(f" Final residual: {residuals[-1]:.2e}") print(f" Reduction factor: {residuals[0]/max(residuals[-1], 1e-15):.2e}") # Energy convergence if len(energies) > 5: energy_drift = (energies[-1] - energies[-5]) / abs(energies[-1] + 1e-15) print(f"\nEnergy convergence:") print(f" Final energy: {energies[-1]:.6e}") print(f" Drift (last 5 steps): {energy_drift:.2e}") # ============================================================ # TEST 0B: REAL-TIME STABILITY VERIFICATION # ============================================================ print("\n" + "="*80) print("TEST 0B: REAL-TIME STABILITY VERIFICATION") print("Evolving stationary soliton in real time (zero velocity)") print("="*80) # Real-time parameters dt_real = 0.0025 t_max_real = 100.0 n_steps_real = int(t_max_real / dt_real) n_save_real = 200 def acceleration_real(Psi, L_2D, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m): """Real-time acceleration (canonical equation).""" psi_sq = np.abs(Psi)**2 S = S_max * np.tanh(psi_sq / (Psi_sat**2)) lap_term = v**2 * (L_2D @ Psi) mass_term = mu * Psi nonlinear_term = lam * psi_sq * Psi tension_term = kappa * S * Psi centrifugal_term = -v**2 * m**2 * Psi / (r_mesh_2d**2 + 1e-12) return lap_term + mass_term + nonlinear_term + tension_term + centrifugal_term # Initialize Psi_test = Psi_soliton.copy() Psi_dot_test = np.zeros_like(Psi_test) times_real = [] max_amps_real = [] energies_real = [] print("\n[Running real-time evolution...]") for step in range(n_steps_real): acc = acceleration_real(Psi_test, L_2D, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m) Psi_dot_half = Psi_dot_test + 0.5 * dt_real * acc Psi_test_new = Psi_test + dt_real * Psi_dot_half acc_next = acceleration_real(Psi_test_new, L_2D, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m) Psi_dot_test = Psi_dot_half + 0.5 * dt_real * acc_next Psi_test = Psi_test_new if step % n_save_real == 0: t = step * dt_real times_real.append(t) max_amps_real.append(np.max(np.abs(Psi_test))) E = compute_energy(Psi_test, L_2D, dV, r_mesh_2d, v, mu, lam, kappa, S_max, Psi_sat, m) energies_real.append(E) if step % (n_save_real * 10) == 0 and step > 0: print(f" t={t:6.2f}, max|Ψ|={max_amps_real[-1]:.4f}, E={E:.6e}") # Real-time stability analysis amp_initial_real = max_amps_real[0] amp_final_real = max_amps_real[-1] amp_preservation = amp_final_real / amp_initial_real energy_initial_real = energies_real[0] energy_final_real = energies_real[-1] energy_drift_real = (energy_final_real - energy_initial_real) / abs(energy_initial_real) * 100 print(f"\nReal-time stability results:") print(f" Initial max|Ψ|: {amp_initial_real:.4f}") print(f" Final max|Ψ|: {amp_final_real:.4f}") print(f" Amplitude preservation: {amp_preservation*100:.1f}%") print(f" Energy drift: {energy_drift_real:.4f}%") # ============================================================ # VISUALIZATION # ============================================================ print("\n[Generating plots...]") fig, axes = plt.subplots(2, 4, figsize=(18, 10)) # Row 0: Convergence diagnostics axes[0, 0].semilogy(times, energies, 'b-', linewidth=2) axes[0, 0].set_xlabel('Imaginary time τ') axes[0, 0].set_ylabel('Energy E[Ψ]') axes[0, 0].set_title('Energy Minimization') axes[0, 0].grid(True, alpha=0.3) axes[0, 1].plot(times, max_amps, 'r-', linewidth=2) axes[0, 1].set_xlabel('Imaginary time τ') axes[0, 1].set_ylabel('max|Ψ|') axes[0, 1].set_title('Amplitude Evolution') axes[0, 1].grid(True, alpha=0.3) axes[0, 2].semilogy(times, residuals, 'm-', linewidth=2) axes[0, 2].set_xlabel('Imaginary time τ') axes[0, 2].set_ylabel('Residual norm') axes[0, 2].set_title('Gradient Norm Convergence') axes[0, 2].grid(True, alpha=0.3) axes[0, 3].plot(times, center_amps, 'g-', linewidth=2) axes[0, 3].set_xlabel('Imaginary time τ') axes[0, 3].set_ylabel('Center |Ψ|') axes[0, 3].set_title('Core Amplitude Evolution') axes[0, 3].grid(True, alpha=0.3) # Row 1: Final soliton structure Psi_final_2d = Psi_soliton.reshape((nz, nr)) extent = [r_grid[0], r_grid[-1], z_grid[0], z_grid[-1]] im1 = axes[1, 0].imshow(np.abs(Psi_final_2d).T, origin='lower', extent=extent, aspect='auto', cmap='viridis') axes[1, 0].set_xlabel('r') axes[1, 0].set_ylabel('z') axes[1, 0].set_title('Final |Ψ| (stationary soliton)') plt.colorbar(im1, ax=axes[1, 0]) im2 = axes[1, 1].imshow(np.angle(Psi_final_2d).T, origin='lower', extent=extent, aspect='auto', cmap='twilight') axes[1, 1].set_xlabel('r') axes[1, 1].set_ylabel('z') axes[1, 1].set_title('Final phase arg(Ψ)') plt.colorbar(im2, ax=axes[1, 1]) # Radial profile at z=0 mid_z_idx = nz // 2 radial_profile = np.abs(Psi_final_2d[mid_z_idx, :]) axes[1, 2].plot(r_grid, radial_profile, 'b-', linewidth=2) axes[1, 2].set_xlabel('r') axes[1, 2].set_ylabel('|Ψ|') axes[1, 2].set_title('Radial profile (z=0)') axes[1, 2].grid(True, alpha=0.3) axes[1, 2].axvline(6.0, color='r', linestyle='--', alpha=0.5, label='R₀=6.0') axes[1, 2].legend() # Real-time stability axes[1, 3].plot(times_real, max_amps_real, 'b-', linewidth=2) axes[1, 3].set_xlabel('Time t') axes[1, 3].set_ylabel('max|Ψ|') axes[1, 3].set_title(f'Real-time Stability ({amp_preservation*100:.1f}% preserved)') axes[1, 3].grid(True, alpha=0.3) axes[1, 3].axhline(amp_initial_real * 0.8, color='r', linestyle='--', alpha=0.5, label='80% threshold') plt.tight_layout() plt.savefig('test_0_stationary_soliton.png', dpi=150) print("✓ Plot saved: test_0_stationary_soliton.png") # ============================================================ # SAVE RESULTS # ============================================================ print("\n[Saving results...]") timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") test_name = f"test_0_stationary_soliton_{timestamp}" # Save final soliton np.savez(f"{test_name}_soliton.npz", Psi_soliton=Psi_soliton, r_grid=r_grid, z_grid=z_grid, dr=dr, dz=dz, v=v, mu=mu, lam=lam, kappa=kappa, S_max=S_max, Psi_sat=Psi_sat, m=m) # Save metadata results = { 'test_name': 'Test 0: Stationary Toroidal Soliton Finder (Corrected)', 'timestamp': timestamp, 'method': 'Imaginary-time relaxation with exact variational gradient', 'parameters': { 'v': v, 'mu': mu, 'lambda': lam, 'kappa': kappa, 'S_max': S_max, 'Psi_sat': Psi_sat, 'm': m, 'dtau': dtau, 'tau_max': tau_max, 'nr': nr, 'nz': nz, 'dr': dr, 'dz': dz, }, 'convergence': { 'final_energy': float(energies[-1]), 'final_max_amp': float(max_amps[-1]), 'final_center_amp': float(center_amps[-1]), 'final_residual': float(residuals[-1]), 'amplitude_stability': float(amp_rel_stability) if len(max_amps) > 10 else None, 'energy_drift_final': float(energy_drift) if len(energies) > 5 else None, }, 'real_time_stability': { 'amplitude_preservation': float(amp_preservation), 'energy_drift_percent': float(energy_drift_real), 'final_amplitude': float(amp_final_real), }, 'success': amp_preservation > 0.8 and residuals[-1] < 1e-8 } with open(f"{test_name}_results.json", 'w') as f: json.dump(results, f, indent=2, default=str) print(f"✓ Soliton saved: {test_name}_soliton.npz") print(f"✓ Results saved: {test_name}_results.json") # ============================================================ # VERDICT # ============================================================ print("\n" + "="*80) print("TEST 0 COMPLETE") print("="*80) # Determine success converged = residuals[-1] < 1e-8 stable = amp_preservation > 0.8 if converged and stable: print("\n✅ STATIONARY SOLITON FOUND AND STABLE") print(" ✓ Gradient converged (residual < 1e-8)") print(f" ✓ Real-time amplitude preservation: {amp_preservation*100:.1f}%") print("\n📋 NEXT STEP: Run Test 1 (Velocity Saturation)") print(" Load the saved soliton and apply velocity boost:") print(" Psi_boosted = Psi_soliton * exp(1j * k * z)") print(" Psi_dot = -v_soliton * ∂Ψ/∂z") verdict = "SOLITON_FOUND_STABLE" elif converged and not stable: print("\n⚠️ SOLITON FOUND BUT UNSTABLE IN REAL TIME") print(" The imaginary-time relaxation converged but the state") print(" does not persist under real-time evolution.") print(" Adjust parameters (λ, κ, S_max, Ψ_sat) and retry.") verdict = "UNSTABLE" else: print("\n❌ SOLITON NOT FOUND") print(" Residual norm did not converge to threshold.") print(" Adjust parameters and increase tau_max.") verdict = "NOT_FOUND" print(f"\n📊 VERDICT: {verdict}") print("="*80) ✅ What this corrected script includes Feature Status Exact variational gradient (with S + |Ψ|² dS/d|Ψ|²) ✅ Correct centrifugal sign (+ in gradient) ✅ Residual norm convergence check ✅ Test 0B: Real-time stability verification ✅ 80% amplitude preservation threshold ✅ Comprehensive plotting (convergence + structure + stability) ✅ JSON metadata with success flag ✅ 🚀 How to run python # In Colab, paste the entire script and execute exec(open('test_0_stationary_soliton_corrected.py').read()) The script will: Run imaginary-time relaxation until convergence Verify real-time stability (Test 0B) Save the stationary soliton to .npz Output a clear verdict: SOLITON_FOUND_STABLE / UNSTABLE / NOT_FOUND 📋 After successful Test 0 Load the soliton and proceed to Test 1: python # Load stationary soliton data = np.load('test_0_stationary_soliton__soliton.npz') Psi_soliton = data['Psi_soliton'] r_grid = data['r_grid'] z_grid = data['z_grid'] # Boost for Test 1 k = v_soliton / v # wave number from dispersion Psi_boosted = Psi_soliton * np.exp(1j * k * z_grid.reshape(-1, 1)) # Initialize Psi_dot (use finite difference) Psi_dot = -v_soliton * np.gradient(Psi_boosted.reshape(nz, nr), dz, axis=0).ravel()

Popular posts from this blog

THE GOLDEN BALLROOM/BUNKER

Conceptual Summary #2: (∂t2​S−c2∇2S+βS3)=σ(x,t)⋅FR​(C[Ψ])

ICE PROUDLY ANNOUNCES NEW “ELITE” TASK FORCE COMMANDER JEREMY DEWITTE