--- id: model-05 title: "Resistance Optimization Methods" section: "Advanced Modeling" difficulty: "advanced" estimated_time: 45 prerequisites: ["model-03", "model-04"] objectives: - Master iterative resistance optimization algorithm with damping - Apply position-dependent physical bounds to resistance values - Understand circuit-determined resistance as simplified alternative - Validate total resistance ranges and convergence behavior tags: ["optimization", "resistance", "iterative-algorithm", "convergence", "validation"] --- # Resistance Optimization Methods This lesson covers methods for determining the resistance values R[i] for each segment in a distributed spark model. We present two approaches: a rigorous iterative optimization and a simplified circuit-determined method. ## The Optimization Problem ### Goal and Challenges **Objective:** ``` Find R[i] for i = 1 to n that maximizes total power dissipation: P_total = Σᵢ P[i] where P[i] = 0.5 × |I[i]|² × R[i] Subject to physical constraints: R_min[i] ≤ R[i] ≤ R_max[i] ``` **Challenge: Coupled optimization** ``` Changing R[j] affects current in segment i: - Alters network impedance - Changes voltage distribution - Modifies all currents I[1], I[2], ..., I[n] Cannot optimize each R[i] independently! Must use iterative approach ``` **Computational complexity:** ``` For each R[i]: - Sweep through candidate values (20-50 points) - Run SPICE AC analysis for each - Calculate power P[i] Total simulations per iteration: n × n_sweep n = 10, n_sweep = 20: 200 simulations Iterations: 5-10 typical Total: 1000-2000 AC analyses Compare to lumped: 1 analysis Trade-off: Accuracy vs computational cost ``` ## Iterative Optimization Algorithm ### Initialization: Tapered Profile **Physical expectation:** ``` Base: Hot, well-coupled → low R Tip: Cool, weakly-coupled → high R Monotonically increasing R[i] from base to tip ``` **Initialize with gradient:** ```python # Pseudocode R_base = 10e3 # 10 kΩ (hot leader) R_tip = 1e6 # 1 MΩ (cool streamer) for i in range(1, n+1): position = (i-1) / (n-1) # 0 at base (i=1), 1 at tip (i=n) R[i] = R_base + (R_tip - R_base) * position**2 ``` **Why quadratic taper?** ``` Linear: R[i] = R_base + (R_tip - R_base) × position - Simple, but too gradual - Doesn't capture rapid rise near tip Quadratic: position**2 - Gentle rise at base - Steeper rise near tip - Better matches physics Exponential: also valid, similar results ``` **Example: n=5, R_base=10k, R_tip=1M** ``` i=1: position=0.00 → R[1] = 10 + (1000-10)×0.00 = 10 kΩ i=2: position=0.25 → R[2] = 10 + 990×0.0625 = 72 kΩ i=3: position=0.50 → R[3] = 10 + 990×0.25 = 258 kΩ i=4: position=0.75 → R[4] = 10 + 990×0.5625 = 567 kΩ i=5: position=1.00 → R[5] = 10 + 990×1.0 = 1000 kΩ ``` ### Position-Dependent Bounds **Physical limits vary with position:** **Minimum resistance R_min[i]:** ``` Base can achieve low R (hot, well-coupled) Tip unlikely to reach very low R (cool, weak coupling) Formula: position = (i-1) / (n-1) R_min[i] = 1 kΩ + (10 kΩ - 1 kΩ) × position = 1 kΩ at base → 10 kΩ at tip ``` **Maximum resistance R_max[i]:** ``` Base unlikely to reach very high R (good power coupling) Tip can reach very high R (streamer regime) Formula: position = (i-1) / (n-1) R_max[i] = 100 kΩ + (100 MΩ - 100 kΩ) × position² = 100 kΩ at base → 100 MΩ at tip ``` **Example bounds: n=5** ``` Segment 1 (base, pos=0.00): R_min[1] = 1.0 kΩ R_max[1] = 100 kΩ Segment 2 (pos=0.25): R_min[2] = 3.25 kΩ R_max[2] = 6.3 MΩ Segment 3 (pos=0.50): R_min[3] = 5.5 kΩ R_max[3] = 25.1 MΩ Segment 4 (pos=0.75): R_min[4] = 7.75 kΩ R_max[4] = 56.3 MΩ Segment 5 (tip, pos=1.00): R_min[5] = 10.0 kΩ R_max[5] = 100 MΩ ``` **Rationale:** ``` 1. Prevents unphysical solutions - Tip with R = 1 kΩ: impossible (not hot enough) - Base with R = 100 MΩ: impossible (too much power) 2. Guides optimization - Narrows search space - Faster convergence - More stable 3. Based on physics - Leader regime: R ∝ 1/T, T high at base - Streamer regime: R very high, weakly coupled ``` ### Iterative Loop with Damping **Algorithm structure:** ```python # Pseudocode: Iterative resistance optimization # Initialize R = initialize_tapered_profile(n, R_base, R_tip) alpha = 0.3 # Damping factor max_iterations = 20 tolerance = 0.01 # 1% convergence threshold for iteration in range(max_iterations): R_old = R.copy() for i in range(1, n+1): # Sweep R[i] while keeping other R[j] (j≠i) fixed R_test = logspace(R_min[i], R_max[i], 20) # 20 test points P_test = [] for R_candidate in R_test: R[i] = R_candidate # Run SPICE AC analysis results = run_spice_ac(R, C_matrix, freq) I_i = results.current[i] P_i = 0.5 * abs(I_i)**2 * R_candidate P_test.append(P_i) # Find R that maximizes power in segment i idx_max = argmax(P_test) R_optimal[i] = R_test[idx_max] # Apply damping for stability R_new[i] = alpha * R_optimal[i] + (1 - alpha) * R_old[i] # Clip to physical bounds R[i] = clip(R_new[i], R_min[i], R_max[i]) # Check convergence max_change = max(abs(R[i] - R_old[i]) / R_old[i] for i in range(1,n+1)) print(f"Iteration {iteration}: max change = {max_change*100:.2f}%") if max_change < tolerance: print("Converged!") break # Final result: optimized R[1], R[2], ..., R[n] ``` **Key components:** **1. Logarithmic sweep:** ``` R_test = logspace(log10(R_min), log10(R_max), 20) Why logarithmic? - R varies over orders of magnitude (1k to 100M) - Linear spacing: wastes points at low end - Log spacing: uniform coverage across decades ``` **2. Power calculation:** ``` P[i] = 0.5 × |I[i]|² × R[i] AC steady-state: Factor of 0.5 for sinusoidal RMS values: P = I_rms² × R (without 0.5) Maximize power in segment i, not total power - Each segment optimized to extract maximum power - Self-consistent with hungry streamer physics ``` **3. Damping factor α:** ``` R_new[i] = α × R_optimal[i] + (1-α) × R_old[i] α = 0.3 to 0.5 typical Lower α (e.g., 0.2): - More stable (smaller steps) - Slower convergence (more iterations) - Use if oscillations occur Higher α (e.g., 0.7): - Faster convergence (larger steps) - Risk of oscillation (overshooting) - Use if convergence slow Start with α = 0.3, adjust if needed ``` **4. Clipping:** ``` R[i] = clip(R_new[i], R_min[i], R_max[i]) Ensures R stays within physical bounds Prevents optimizer from exploring unphysical regions ``` ### Convergence Behavior **Well-coupled base segments:** ``` Power curve P[i](R[i]) has sharp peak Example: Segment 1 R = 10k: P[1] = 5.2 kW R = 20k: P[1] = 8.1 kW R = 30k: P[1] = 9.4 kW ← maximum (sharp peak) R = 40k: P[1] = 8.9 kW R = 50k: P[1] = 7.8 kW Characteristics: - Clear optimal R - Fast convergence (2-3 iterations) - Stable solution ``` **Weakly-coupled tip segments:** ``` Power curve P[i](R[i]) is FLAT Example: Segment 5 (tip) R = 100k: P[5] = 0.82 kW R = 500k: P[5] = 0.85 kW R = 1M: P[5] = 0.83 kW R = 5M: P[5] = 0.81 kW All values give similar power! Characteristics: - Optimal R poorly defined - Slow/no convergence to unique value - May oscillate between similar R values - Physical: weak coupling, low power anyway ``` **Convergence criteria:** ``` Base segments: Converge quickly (<5 iterations) Middle segments: Moderate convergence (5-10 iterations) Tip segments: May not converge fully Solution: - Allow tip segments to remain at reasonable values - Check that change <5% for tip segments - Focus convergence on base/middle (where most power is) ``` **Expected final distribution:** ``` At 200 kHz, 2 m spark: R[1] ≈ 5-20 kΩ (base leader) R[2] ≈ 10-40 kΩ R[3] ≈ 20-80 kΩ ... R[n-1] ≈ 50-200 kΩ R[n] ≈ 100 kΩ - 10 MΩ (tip streamer, wide range) Total: R_total = Σ R[i] should be 50-500 kΩ at 200 kHz ``` ### Worked Example: n=3 Iterative Optimization **Given:** ``` 3 segments, f = 200 kHz Capacitance matrix from FEMM (simplified example) Initial: R[1]=50k, R[2]=100k, R[3]=500k Damping: α = 0.4 ``` **Iteration 1:** **Optimize R[1]** (keeping R[2]=100k, R[3]=500k fixed) ``` Sweep R[1] in [1k, 100k] (20 points, log scale) Results (example): R[1]=10k → P[1]=5.2 kW R[1]=20k → P[1]=8.1 kW R[1]=30k → P[1]=9.4 kW ← maximum R[1]=40k → P[1]=8.9 kW R[1]=50k → P[1]=7.8 kW (current value) ... R_optimal[1] = 30 kΩ ``` **Apply damping:** ``` R_new[1] = 0.4 × 30k + 0.6 × 50k = 12k + 30k = 42 kΩ Check bounds: 1k < 42k < 100k ✓ Update: R[1] = 42 kΩ ``` **Optimize R[2]** (with R[1]=42k, R[3]=500k) ``` Sweep R[2], find maximum at R_optimal[2] = 60 kΩ Current: R[2] = 100 kΩ R_new[2] = 0.4 × 60k + 0.6 × 100k = 24k + 60k = 84 kΩ Update: R[2] = 84 kΩ ``` **Optimize R[3]** (with R[1]=42k, R[2]=84k) ``` Sweep R[3], power curve is FLAT: R[3]=200k → P[3]=0.80 kW R[3]=500k → P[3]=0.85 kW R[3]=1M → P[3]=0.83 kW Maximum at 500k, but very weak peak (±5%) Tip segment: poorly coupled R_optimal[3] = 500 kΩ (no change) R_new[3] = 0.4 × 500k + 0.6 × 500k = 500 kΩ Update: R[3] = 500 kΩ ``` **Convergence check:** ``` Changes: R[1]: 50k → 42k (change = -16%) R[2]: 100k → 84k (change = -16%) R[3]: 500k → 500k (change = 0%) Max change = 16% > 1% tolerance → Not converged, continue ``` **Iteration 2:** Repeat with new R values... Typically base segments converge within 3-5 iterations **Final result (example):** ``` After 5 iterations: R[1] = 35 kΩ (converged, change <1%) R[2] = 75 kΩ (converged, change <1%) R[3] = 500 kΩ (tip, flat curve, acceptable) Total: 610 kΩ at 200 kHz ✓ Within expected range (50-500 kΩ, high end due to tip) ``` ## Simplified Method: Circuit-Determined Resistance ### Key Insight **Hungry streamer physics:** ``` Plasma adjusts diameter to seek R_opt_power for maximum power R_opt = 1 / (ω × C_total) For each segment: - Segment sees total capacitance C_total[i] - Adjusts to R[i] = 1 / (ω × C_total[i]) - Self-consistent with power optimization ``` **Capacitance weakly depends on diameter:** ``` C ∝ 1 / ln(h/d) Logarithmic dependence: - 2× diameter → ~10% capacitance change - R_opt also changes ~10% - Small error from assuming fixed C ``` ### Formula **For each segment i:** ``` C_total[i] = Σⱼ₌₀ⁿ |C[i,j]| Sum of absolute values of all capacitances involving segment i Then: R[i] = 1 / (ω × C_total[i]) R[i] = clip(R[i], R_min[i], R_max[i]) ``` **Why this works:** ``` 1. Hungry streamer: Seeks R_opt = 1/(ωC) 2. Diameter self-adjusts: Matches R to C 3. Logarithmic C(d): Error ~10-15% (small) 4. Other uncertainties: FEMM ±5-10%, physics ±30-50% 5. Diameter error is SMALL compared to total uncertainty ``` ### When to Use **Simplified method good for:** ``` 1. Standard cases - Typical geometries (vertical spark, toroid topload) - Typical frequencies (100-300 kHz) - Typical lengths (1-3 m) 2. First-pass analysis - Initial design evaluation - Quick parameter studies 3. Engineering estimates - ±20% accuracy sufficient - Fast turnaround needed 4. Educational purposes - Understanding physics - Building intuition ``` **Iterative method when:** ``` 1. Research/validation - Publication-quality results - Detailed physics studies 2. Extreme parameters - Very long sparks (>5 m) - Very short sparks (<0.5 m) - Very low frequency (<50 kHz) 3. Measurement comparison - Highest accuracy required - Factor of 1.5 differences matter 4. Unusual geometries - Horizontal sparks - Branched discharge - Non-uniform diameter ``` **Computational savings:** ``` Iterative: 5-10 iterations × 20 points × n segments = 1000-2000 AC analyses Time: 100-500 seconds for n=10 Simplified: 1 AC analysis (after R calculation) Time: <1 second Speedup: 1000-5000× faster! Use simplified unless specific need for iterative ``` ### Worked Example: Simplified Calculation **Given (same matrix as before):** ``` f = 190 kHz ω = 2π × 190×10³ = 1.194×10⁶ rad/s Capacitance matrix (n=5): [0] [1] [2] [3] [4] [5] [0] [ 32.5 -9.2 -3.1 -1.2 -0.6 -0.3 ] [1] [ -9.2 14.8 -2.8 -0.9 -0.4 -0.2 ] [2] [ -3.1 -2.8 10.4 -2.1 -0.7 -0.3 ] [3] [ -1.2 -0.9 -2.1 8.6 -1.8 -0.5 ] [4] [ -0.6 -0.4 -0.7 -1.8 7.4 -1.4 ] [5] [ -0.3 -0.2 -0.3 -0.5 -1.4 5.8 ] pF ``` **Calculate R[i] for each segment:** **Segment 1 (base):** ``` C_total[1] = |C[1,0]| + |C[1,2]| + |C[1,3]| + |C[1,4]| + |C[1,5]| = 9.2 + 2.8 + 0.9 + 0.4 + 0.2 = 13.5 pF R[1] = 1 / (ω × C_total[1]) = 1 / (1.194×10⁶ × 13.5×10⁻¹²) = 1 / (1.612×10⁻⁵) = 62.0 kΩ Check bounds: 1k < 62k < 100k ✓ ``` **Segment 2:** ``` C_total[2] = 3.1 + 2.8 + 2.1 + 0.7 + 0.3 = 9.0 pF R[2] = 1 / (1.194×10⁶ × 9.0×10⁻¹²) = 93.0 kΩ ✓ ``` **Segment 3:** ``` C_total[3] = 1.2 + 0.9 + 2.1 + 1.8 + 0.5 = 6.5 pF R[3] = 1 / (1.194×10⁶ × 6.5×10⁻¹²) = 129 kΩ ✓ ``` **Segment 4:** ``` C_total[4] = 0.6 + 0.4 + 0.7 + 1.8 + 1.4 = 4.9 pF R[4] = 1 / (1.194×10⁶ × 4.9×10⁻¹²) = 171 kΩ ✓ ``` **Segment 5 (tip):** ``` C_total[5] = 0.3 + 0.2 + 0.3 + 0.5 + 1.4 = 2.7 pF R[5] = 1 / (1.194×10⁶ × 2.7×10⁻¹²) = 310 kΩ ✓ ``` **Summary:** ``` R[1] = 62 kΩ (base, lowest) R[2] = 93 kΩ R[3] = 129 kΩ R[4] = 171 kΩ R[5] = 310 kΩ (tip, highest) ✓ Monotonically increasing ✓ All within position-dependent bounds Total: R_total = 765 kΩ ``` ### Validation **Total resistance check:** ``` Expected at 190 kHz for 2 m spark: Lower bound: ~50 kΩ (very hot, efficient) Typical: 100-300 kΩ Upper bound: ~500 kΩ (cool, streamer-dominated) Result: 765 kΩ Higher than typical, but reasonable because: 1. Long spark (2 m) 2. Distributed model (tip high R, 310 kΩ) 3. Tip weakly coupled (high R expected) Within factor of 2-3 of typical: Acceptable ``` **If result very different:** ``` R_total < 20 kΩ: - Check formula (missing units conversion?) - Check C values (pF vs F?) - Too low for plasma physics R_total > 2 MΩ: - Check frequency (Hz vs kHz?) - Tip resistance very high (check tip coupling) - May need iterative method to find lower solution ``` ## Total Resistance Validation Ranges **Frequency dependence:** ``` At 100 kHz: Typical: 100-600 kΩ (higher R at lower f) At 200 kHz: Typical: 50-300 kΩ At 400 kHz: Typical: 25-150 kΩ (lower R at higher f) Rule: R_total ∝ 1/f (approximately) ``` **Length dependence:** ``` At 200 kHz: 0.5 m: 30-100 kΩ 1.0 m: 50-150 kΩ 2.0 m: 100-300 kΩ 3.0 m: 150-500 kΩ Rule: R_total ∝ L (approximately, distributed effects complicate) ``` **Operating mode:** ``` QCW (long ramp): - Lower R (hot channel) - Factor 0.5-1× above estimates Burst (short pulse): - Higher R (cooler channel) - Factor 1-2× above estimates ``` ## Key Takeaways - **Iterative optimization** maximizes power per segment, uses damping (α ≈ 0.3-0.5) for stability, 5-10 iterations typical - **Position-dependent bounds:** R_min increases 1k→10k, R_max increases 100k→100M from base to tip (quadratic) - **Convergence:** Base segments converge fast (sharp power peak), tip segments slow (flat curve, weakly coupled) - **Simplified method:** R[i] = 1/(ω × C_total[i]) from circuit theory, 1000× faster, ±20% accuracy - **When simplified:** Standard cases, first-pass analysis, engineering estimates, educational use - **When iterative:** Research, extreme parameters, measurement comparison, publication quality - **Validation:** R_total should be 50-500 kΩ at 200 kHz for 1-3 m sparks, monotonic increase base→tip - **Total resistance:** Scales as R ∝ 1/f and R ∝ L approximately, QCW lower than burst mode ## Practice {exercise:model-ex-05} --- **Next Lesson:** [Part 4 Review and Comprehensive Exercises](06-review-exercises.md)