Initial commit: Tesla Coil Spark Course
Complete educational course on Tesla coil spark physics: - 30 structured lessons across 4 parts (Fundamentals, Optimization, Spark Physics, Advanced Modeling) - 18 YAML-formatted exercises with auto-grading support - 5 comprehensive worked examples - Reference materials (equation sheet, physical bounds, glossary) - PyQt6 application skeleton for interactive learning - 37 generated images (matplotlib graphs and placeholders) - Image generation scripts for reproducibility Based on spark-physics.txt theoretical framework. Estimated 14 hours of learning content, 525 assessment points. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>main
-
19.claude/settings.local.json
-
20.gitignore
-
1073CLAUDE.md
-
51exercises/01-fundamentals/fund-ex-02a.yaml
-
31exercises/01-fundamentals/fund-ex-02b.yaml
-
48exercises/01-fundamentals/fund-ex-02c.yaml
-
46exercises/01-fundamentals/fund-ex-03a.yaml
-
46exercises/01-fundamentals/fund-ex-03b.yaml
-
35exercises/01-fundamentals/fund-ex-04a.yaml
-
41exercises/01-fundamentals/fund-ex-04b.yaml
-
57exercises/01-fundamentals/fund-ex-05a.yaml
-
84exercises/01-fundamentals/fund-ex-08-comprehensive.yaml
-
81exercises/01-fundamentals/fund-ex-checkpoint-quiz.yaml
-
52exercises/02-optimization/opt-ex-01a.yaml
-
51exercises/02-optimization/opt-ex-01b.yaml
-
91exercises/02-optimization/opt-ex-thevenin-complete.yaml
-
44exercises/03-spark-physics/phys-ex-01a.yaml
-
45exercises/03-spark-physics/phys-ex-03a.yaml
-
109exercises/03-spark-physics/phys-ex-comprehensive.yaml
-
77exercises/03-spark-physics/phys-ex-conceptual-limits.yaml
-
79exercises/04-advanced-modeling/model-ex-lumped-complete.yaml
-
59run.bat
-
7327spark-lesson.txt
-
470spark-lessons/CIRCUIT-SPECIFICATIONS.md
-
282spark-lessons/PyQt_PROGRESS.md
-
465spark-lessons/README.md
-
7327spark-lessons/_originals/spark-lesson.txt
-
856spark-lessons/_originals/spark-physics.txt
-
6spark-lessons/app/__init__.py
-
259spark-lessons/app/config.py
-
332spark-lessons/app/database.py
-
85spark-lessons/app/main.py
-
7spark-lessons/app/models/__init__.py
-
320spark-lessons/app/models/course_model.py
-
8spark-lessons/app/utils/__init__.py
-
107spark-lessons/app/utils/symbol_loader.py
-
159spark-lessons/app/utils/variable_wrapper.py
-
10spark-lessons/app/views/__init__.py
-
432spark-lessons/app/views/content_viewer.py
-
292spark-lessons/app/views/main_window.py
-
211spark-lessons/app/views/navigation_panel.py
-
299spark-lessons/app/views/progress_panel.py
-
1138spark-lessons/assets/IMAGE-REQUIREMENTS.md
-
BINspark-lessons/assets/shared/complex-number-review.png
-
446spark-lessons/course.json
-
382spark-lessons/generate_circuits.py
-
1655spark-lessons/generate_images.py
-
242spark-lessons/generate_placeholders.py
-
248spark-lessons/lessons/01-fundamentals/01-introduction.md
-
277spark-lessons/lessons/01-fundamentals/02-basic-circuit-model.md
-
265spark-lessons/lessons/01-fundamentals/03-admittance-analysis.md
-
203spark-lessons/lessons/01-fundamentals/04-phase-angles.md
-
235spark-lessons/lessons/01-fundamentals/05-phase-constraint.md
-
238spark-lessons/lessons/01-fundamentals/06-why-not-45-degrees.md
-
258spark-lessons/lessons/01-fundamentals/07-measurement-port.md
-
334spark-lessons/lessons/01-fundamentals/08-review-exercises.md
-
126spark-lessons/lessons/01-fundamentals/README.md
-
BINspark-lessons/lessons/01-fundamentals/assets/admittance-vector-addition.png
-
BINspark-lessons/lessons/01-fundamentals/assets/complex-plane-admittance.png
-
BINspark-lessons/lessons/01-fundamentals/assets/field-lines-capacitances.png
-
BINspark-lessons/lessons/01-fundamentals/assets/impedance-matching-concept.png
-
BINspark-lessons/lessons/01-fundamentals/assets/phase-angle-visualization.png
-
BINspark-lessons/lessons/01-fundamentals/assets/phase-constraint-graph.png
-
283spark-lessons/lessons/02-optimization/01-two-resistances.md
-
334spark-lessons/lessons/02-optimization/02-hungry-streamer.md
-
329spark-lessons/lessons/02-optimization/03-thevenin-method.md
-
397spark-lessons/lessons/02-optimization/04-thevenin-calculations.md
-
337spark-lessons/lessons/02-optimization/05-direct-measurement.md
-
485spark-lessons/lessons/02-optimization/06-frequency-tracking.md
-
464spark-lessons/lessons/02-optimization/07-review-exercises.md
-
BINspark-lessons/lessons/02-optimization/assets/drsstc-operating-modes.png
-
BINspark-lessons/lessons/02-optimization/assets/frequency-shift-with-loading.png
-
BINspark-lessons/lessons/02-optimization/assets/hungry-streamer-feedback-loop.png
-
BINspark-lessons/lessons/02-optimization/assets/loaded-pole-analysis.png
-
BINspark-lessons/lessons/02-optimization/assets/power-vs-resistance-curves.png
-
BINspark-lessons/lessons/02-optimization/assets/thevenin-measurement-setup.png
-
263spark-lessons/lessons/03-spark-physics/01-field-thresholds.md
-
275spark-lessons/lessons/03-spark-physics/02-voltage-limits.md
-
359spark-lessons/lessons/03-spark-physics/03-energy-per-meter.md
-
404spark-lessons/lessons/03-spark-physics/04-empirical-epsilon.md
-
460spark-lessons/lessons/03-spark-physics/05-thermal-memory.md
-
441spark-lessons/lessons/03-spark-physics/06-streamers-vs-leaders.md
-
471spark-lessons/lessons/03-spark-physics/07-capacitive-divider.md
-
457spark-lessons/lessons/03-spark-physics/08-freau-relationship.md
-
434spark-lessons/lessons/03-spark-physics/09-review-exercises.md
-
BINspark-lessons/lessons/03-spark-physics/assets/electric-field-enhancement.png
-
BINspark-lessons/lessons/03-spark-physics/assets/energy-budget-breakdown.png
-
BINspark-lessons/lessons/03-spark-physics/assets/epsilon-by-mode-comparison.png
-
BINspark-lessons/lessons/03-spark-physics/assets/femm-field-plot-example.png
-
BINspark-lessons/lessons/03-spark-physics/assets/length-vs-energy-scaling.png
-
BINspark-lessons/lessons/03-spark-physics/assets/qcw-vs-burst-timeline.png
-
BINspark-lessons/lessons/03-spark-physics/assets/spark-channel-persistence-sequence.png
-
BINspark-lessons/lessons/03-spark-physics/assets/streamer-to-leader-transition-sequence.png
-
BINspark-lessons/lessons/03-spark-physics/assets/streamers-vs-leaders-photos.png
-
BINspark-lessons/lessons/03-spark-physics/assets/thermal-diffusion-vs-diameter.png
-
BINspark-lessons/lessons/03-spark-physics/assets/voltage-division-vs-length-plot.png
-
440spark-lessons/lessons/04-advanced-modeling/01-lumped-model.md
-
703spark-lessons/lessons/04-advanced-modeling/02-femm-extraction-lumped.md
-
576spark-lessons/lessons/04-advanced-modeling/03-distributed-model.md
-
681spark-lessons/lessons/04-advanced-modeling/04-femm-extraction-distributed.md
@ -0,0 +1,19 @@ |
|||
{ |
|||
"permissions": { |
|||
"allow": [ |
|||
"Bash(dir:*)", |
|||
"Bash(pip install:*)", |
|||
"Bash(python:*)", |
|||
"Bash(xargs rm:*)", |
|||
"Bash(cmd.exe /c run.bat)", |
|||
"Bash(source:*)", |
|||
"Bash(timeout 10 python:*)", |
|||
"Bash(timeout:*)", |
|||
"Bash(git init:*)", |
|||
"Bash(git remote add:*)", |
|||
"Bash(git add:*)" |
|||
], |
|||
"deny": [], |
|||
"ask": [] |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
# Virtual environment |
|||
venv/ |
|||
__pycache__/ |
|||
*.pyc |
|||
|
|||
# IDE |
|||
.vscode/ |
|||
.idea/ |
|||
|
|||
# OS files |
|||
.DS_Store |
|||
Thumbs.db |
|||
|
|||
# Malformed directories (path errors from previous operations) |
|||
C:gitspark-lesson*/ |
|||
|
|||
# Build artifacts |
|||
*.egg-info/ |
|||
dist/ |
|||
build/ |
|||
1073
CLAUDE.md
File diff suppressed because it is too large
View File
@ -0,0 +1,51 @@ |
|||
id: fund-ex-02a |
|||
type: design |
|||
difficulty: easy |
|||
points: 10 |
|||
related_lesson: fund-02 |
|||
question: | |
|||
Draw the circuit for a spark with the following parameters: |
|||
- Spark length: L = 5 feet |
|||
- Mutual capacitance: C_mut = 12 pF (from FEMM) |
|||
- Plasma resistance: R = 50 kΩ |
|||
|
|||
Label all component values including the shunt capacitance C_sh. |
|||
|
|||
hints: |
|||
- "Use the empirical rule: C_sh ≈ 2 pF/foot" |
|||
- "The topology is (R || C_mut) in series with C_sh" |
|||
- "Draw from topload terminal to ground reference" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Calculate C_sh using empirical rule: C_sh = 2 pF/foot × 5 feet = 10 pF" |
|||
- "Draw topload at top as measurement terminal" |
|||
- "Draw C_mut in series from topload" |
|||
- "At node connecting C_mut, draw R and C_sh in parallel to ground" |
|||
- "Alternative: Show R || C_mut as parallel combination, then C_sh in series to ground" |
|||
|
|||
answer: | |
|||
Circuit diagram: |
|||
Topload (V_top) |
|||
| |
|||
[C_mut = 12 pF] |
|||
| |
|||
+----------- Node_spark |
|||
| | |
|||
[R = 50 kΩ] [C_sh = 10 pF] |
|||
| | |
|||
GND --------- GND |
|||
|
|||
component_values: |
|||
C_mut: "12 pF" |
|||
C_sh: "10 pF" |
|||
R: "50 kΩ" |
|||
|
|||
explanation: | |
|||
The spark circuit model uses three components: C_mut couples the topload to the |
|||
spark channel, R represents plasma resistance where power is dissipated, and C_sh |
|||
provides the shunt capacitance to ground. The empirical 2 pF/foot rule gives a |
|||
good estimate for C_sh, which for a 5-foot spark yields 10 pF. This topology |
|||
ensures current through R must also flow through either C_mut or C_sh. |
|||
|
|||
related_concepts: ["circuit-topology", "lumped-model", "C_sh-empirical-rule", "spark-capacitance"] |
|||
@ -0,0 +1,31 @@ |
|||
id: fund-ex-02b |
|||
type: calculation |
|||
difficulty: easy |
|||
points: 10 |
|||
related_lesson: fund-02 |
|||
question: | |
|||
A simulation shows C_sh = 10 pF for a given spark. What is the estimated spark |
|||
length using the empirical rule? |
|||
|
|||
hints: |
|||
- "The empirical rule is C_sh ≈ 2 pF/foot" |
|||
- "Solve for length: L = C_sh / (2 pF/foot)" |
|||
- "Don't forget the units!" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Use the empirical relationship: C_sh ≈ 2 pF/foot" |
|||
- "Rearrange to solve for length: L = C_sh / (2 pF/foot)" |
|||
- "Substitute: L = 10 pF / (2 pF/foot) = 5 feet" |
|||
|
|||
answer: "5" |
|||
unit: "feet" |
|||
tolerance: 0 |
|||
|
|||
explanation: | |
|||
The empirical rule C_sh ≈ 2 pF/foot is a remarkably accurate guideline for Tesla |
|||
coil sparks, typically within ±30% for common geometries. This relationship comes |
|||
from the capacitance of a vertical conductor above ground. By inverting the formula, |
|||
we can estimate spark length from measured or simulated shunt capacitance values. |
|||
|
|||
related_concepts: ["C_sh-empirical-rule", "spark-length-estimation", "capacitance-measurement"] |
|||
@ -0,0 +1,48 @@ |
|||
id: fund-ex-02c |
|||
type: multi-part |
|||
difficulty: medium |
|||
points: 15 |
|||
related_lesson: fund-02 |
|||
question: | |
|||
A 4-foot spark is formed. The topload has C_topload = 30 pF when unloaded. |
|||
|
|||
(a) Estimate C_sh using the empirical rule |
|||
(b) What is the total system capacitance with the spark? |
|||
|
|||
Hint: Consider how C_mut and C_sh combine in the circuit topology. |
|||
|
|||
hints: |
|||
- "Use C_sh ≈ 2 pF/foot for part (a)" |
|||
- "The circuit is (C_mut || R) in series with C_sh" |
|||
- "For DC or low frequency: R || C_mut looks like just C_mut" |
|||
- "Series capacitors: C_total = (C₁ × C₂)/(C₁ + C₂)" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate C_sh = 2 pF/foot × 4 feet = 8 pF" |
|||
- "Part (b): Recognize topload connects to (C_mut || R) in series with C_sh" |
|||
- "At RF frequencies, parallel combination C_mut || R ≈ C_mut dominates" |
|||
- "Series combination: C_series = (C_mut × C_sh)/(C_mut + C_sh)" |
|||
- "Need to estimate C_mut. For typical geometries, C_mut ≈ 0.5 to 0.8 × C_topload" |
|||
- "Assuming C_mut ≈ 0.6 × 30 pF = 18 pF (estimate)" |
|||
- "C_series = (18 × 8)/(18 + 8) = 144/26 = 5.5 pF" |
|||
- "Total system: C_total = C_topload + C_series (if in parallel to ground)" |
|||
- "More accurately: Spark adds C_series in series, reducing total C seen from topload" |
|||
|
|||
answer_part_a: "8" |
|||
unit_part_a: "pF" |
|||
answer_part_b: "approximately 5.5 pF from spark circuit (but depends on C_mut estimate)" |
|||
|
|||
explanation: | |
|||
Part (a) is straightforward using the empirical rule. Part (b) is more complex |
|||
because the spark adds a series combination of capacitances. The exact answer |
|||
depends on C_mut, which must be determined from FEMM or estimated based on |
|||
geometry. The key insight is that C_mut and C_sh form a capacitive divider that |
|||
reduces the effective capacitance seen from the topload terminal. |
|||
|
|||
In practice, the "total system capacitance" includes the topload self-capacitance |
|||
plus the series combination of the spark circuit elements. This problem illustrates |
|||
why FEMM extraction is necessary for accurate modeling - C_mut cannot be calculated |
|||
from simple formulas. |
|||
|
|||
related_concepts: ["series-capacitance", "capacitive-divider", "total-capacitance", "FEMM-extraction"] |
|||
@ -0,0 +1,46 @@ |
|||
id: fund-ex-03a |
|||
type: calculation |
|||
difficulty: medium |
|||
points: 15 |
|||
related_lesson: fund-03 |
|||
question: | |
|||
For a spark circuit with the following parameters: |
|||
- Frequency: f = 150 kHz |
|||
- Mutual capacitance: C_mut = 10 pF |
|||
- Shunt capacitance: C_sh = 8 pF |
|||
- Plasma resistance: R = 80 kΩ |
|||
|
|||
Calculate Y_total in rectangular form (real and imaginary parts). |
|||
|
|||
hints: |
|||
- "First calculate ω = 2πf" |
|||
- "Then calculate G = 1/R, B₁ = ωC_mut, B₂ = ωC_sh" |
|||
- "Use the formulas: Re{Y} = GB₂²/[G² + (B₁+B₂)²]" |
|||
- "And: Im{Y} = B₂[G² + B₁(B₁+B₂)]/[G² + (B₁+B₂)²]" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Calculate angular frequency: ω = 2π × 150×10³ = 9.425×10⁵ rad/s" |
|||
- "Calculate conductance: G = 1/R = 1/(80×10³) = 12.5 μS" |
|||
- "Calculate susceptances: B₁ = ω×C_mut = 9.425×10⁵ × 10×10⁻¹² = 9.425 μS" |
|||
- "B₂ = ω×C_sh = 9.425×10⁵ × 8×10⁻¹² = 7.54 μS" |
|||
- "Calculate denominator: G² + (B₁+B₂)² = 156.25 + (16.965)² = 156.25 + 287.8 = 444.05 μS²" |
|||
- "Calculate Re{Y}: Re{Y} = 12.5 × (7.54)² / 444.05 = 12.5 × 56.85 / 444.05 = 710.6 / 444.05 = 1.60 μS" |
|||
- "Calculate Im{Y} numerator: G² + B₁(B₁+B₂) = 156.25 + 9.425×16.965 = 156.25 + 159.9 = 316.15 μS²" |
|||
- "Calculate Im{Y}: Im{Y} = 7.54 × 316.15 / 444.05 = 2383.8 / 444.05 = 5.37 μS" |
|||
|
|||
answer: "Y = 1.60 + j5.37 μS" |
|||
real_part: "1.60" |
|||
imaginary_part: "5.37" |
|||
unit: "μS" |
|||
tolerance: 3.0 |
|||
|
|||
explanation: | |
|||
This calculation demonstrates the admittance analysis method for the spark circuit. |
|||
The real part (1.60 μS) represents conductance - the component that dissipates |
|||
power in the plasma resistance. The imaginary part (5.37 μS) is the susceptance, |
|||
representing energy storage in the capacitances. The susceptance is 3.4× larger |
|||
than the conductance, indicating a strongly capacitive circuit - typical for |
|||
Tesla coil sparks. |
|||
|
|||
related_concepts: ["admittance-calculation", "complex-numbers", "conductance", "susceptance"] |
|||
@ -0,0 +1,46 @@ |
|||
id: fund-ex-03b |
|||
type: calculation |
|||
difficulty: medium |
|||
points: 12 |
|||
related_lesson: fund-03 |
|||
question: | |
|||
An admittance is measured as Y = 2.0 + j4.5 μS. |
|||
|
|||
Convert this to impedance Z in both rectangular and polar forms. |
|||
|
|||
hints: |
|||
- "Use |Z| = 1/|Y| for the magnitude" |
|||
- "Use φ_Z = -φ_Y for the phase angle" |
|||
- "Calculate |Y| = √(Re{Y}² + Im{Y}²)" |
|||
- "For rectangular: Z = R + jX where R = |Z|cos(φ_Z), X = |Z|sin(φ_Z)" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Calculate magnitude of Y: |Y| = √(2.0² + 4.5²) = √(4 + 20.25) = √24.25 = 4.92 μS" |
|||
- "Calculate magnitude of Z: |Z| = 1/|Y| = 1/(4.92×10⁻⁶) = 203 kΩ" |
|||
- "Calculate admittance phase: φ_Y = atan(4.5/2.0) = atan(2.25) = 66.0°" |
|||
- "Calculate impedance phase: φ_Z = -φ_Y = -66.0°" |
|||
- "Polar form: Z = 203 kΩ ∠-66.0°" |
|||
- "Calculate rectangular components:" |
|||
- "R = |Z| × cos(φ_Z) = 203 × cos(-66°) = 203 × 0.407 = 82.6 kΩ" |
|||
- "X = |Z| × sin(φ_Z) = 203 × sin(-66°) = 203 × (-0.914) = -185.5 kΩ" |
|||
- "Rectangular form: Z = 82.6 - j185.5 kΩ" |
|||
|
|||
answer_polar: "203 kΩ ∠-66.0°" |
|||
answer_rectangular: "82.6 - j185.5 kΩ" |
|||
magnitude: "203" |
|||
phase: "-66.0" |
|||
resistance: "82.6" |
|||
reactance: "-185.5" |
|||
unit: "kΩ" |
|||
tolerance: 2.0 |
|||
|
|||
explanation: | |
|||
This conversion demonstrates the fundamental relationship between admittance and |
|||
impedance: they are reciprocals in the complex plane. The key relationships are |
|||
|Z| = 1/|Y| and φ_Z = -φ_Y. Note the opposite sign of the phase angle - this is |
|||
critical! A positive admittance phase (capacitive susceptance) corresponds to a |
|||
negative impedance phase (capacitive reactance). The negative reactance confirms |
|||
this is a capacitive impedance, as expected for spark circuits. |
|||
|
|||
related_concepts: ["admittance-to-impedance", "complex-reciprocal", "phase-relationship", "polar-rectangular"] |
|||
@ -0,0 +1,35 @@ |
|||
id: fund-ex-04a |
|||
type: calculation |
|||
difficulty: easy |
|||
points: 8 |
|||
related_lesson: fund-04 |
|||
question: | |
|||
An impedance is measured as Z = 60 + j40 kΩ. |
|||
|
|||
Calculate the phase angle φ_Z. Is this inductive or capacitive? |
|||
|
|||
hints: |
|||
- "Use φ_Z = atan(X/R)" |
|||
- "Positive X means inductive, negative X means capacitive" |
|||
- "The sign of φ_Z tells you about the reactive component" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Identify components: R = 60 kΩ, X = +40 kΩ" |
|||
- "Calculate phase: φ_Z = atan(X/R) = atan(40/60) = atan(0.667) = 33.7°" |
|||
- "Since X > 0, this is inductive" |
|||
- "Positive phase angle confirms inductive behavior" |
|||
|
|||
answer: "33.7" |
|||
unit: "degrees" |
|||
type_answer: "inductive" |
|||
tolerance: 1.0 |
|||
|
|||
explanation: | |
|||
The phase angle is calculated from the ratio of reactance to resistance. The |
|||
positive value of both X and φ_Z indicates inductive impedance - the current |
|||
lags the voltage. This would be unusual for a Tesla coil spark circuit, which |
|||
are typically capacitive (negative φ_Z). An inductive impedance might appear |
|||
in the primary circuit or at very low frequencies where inductance dominates. |
|||
|
|||
related_concepts: ["phase-angle", "inductive-vs-capacitive", "impedance-components"] |
|||
@ -0,0 +1,41 @@ |
|||
id: fund-ex-04b |
|||
type: multi-part |
|||
difficulty: medium |
|||
points: 15 |
|||
related_lesson: fund-04 |
|||
question: | |
|||
A spark has φ_Z = -60°. The impedance magnitude is |Z| = 150 kΩ. |
|||
|
|||
(a) Find R and X (rectangular components) |
|||
(b) Calculate the power factor |
|||
|
|||
hints: |
|||
- "Use R = |Z| × cos(φ_Z) and X = |Z| × sin(φ_Z)" |
|||
- "Power factor = cos(φ_Z)" |
|||
- "Negative angle means capacitive reactance (X < 0)" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate resistance" |
|||
- "R = |Z| × cos(φ_Z) = 150 × cos(-60°) = 150 × 0.5 = 75 kΩ" |
|||
- "Calculate reactance" |
|||
- "X = |Z| × sin(φ_Z) = 150 × sin(-60°) = 150 × (-0.866) = -130 kΩ" |
|||
- "Rectangular form: Z = 75 - j130 kΩ" |
|||
- "Part (b): Calculate power factor" |
|||
- "Power factor = cos(φ_Z) = cos(-60°) = 0.5" |
|||
|
|||
answer_R: "75" |
|||
answer_X: "-130" |
|||
unit: "kΩ" |
|||
power_factor: "0.5" |
|||
tolerance: 2.0 |
|||
|
|||
explanation: | |
|||
With a -60° phase angle, this spark is significantly capacitive. The resistance |
|||
(75 kΩ) equals half the impedance magnitude, while the capacitive reactance |
|||
(-130 kΩ) is 1.73× the resistance. The power factor of 0.5 means only 50% of |
|||
the apparent power (V×I) is real power dissipated in the plasma. The other 50% |
|||
is reactive power - energy oscillating in the capacitances. This is typical for |
|||
Tesla coil sparks, which operate with power factors in the 0.25-0.70 range. |
|||
|
|||
related_concepts: ["power-factor", "rectangular-components", "capacitive-impedance"] |
|||
@ -0,0 +1,57 @@ |
|||
id: fund-ex-05a |
|||
type: multi-part |
|||
difficulty: hard |
|||
points: 20 |
|||
related_lesson: fund-05 |
|||
question: | |
|||
Calculate the topological phase constraint for a spark circuit with: |
|||
- Frequency: f = 150 kHz |
|||
- Mutual capacitance: C_mut = 12 pF |
|||
- Shunt capacitance: C_sh = 8 pF |
|||
|
|||
(a) Calculate the capacitance ratio r |
|||
(b) Calculate the minimum achievable phase angle φ_Z,min |
|||
(c) Calculate R_opt_phase that achieves this minimum angle |
|||
|
|||
hints: |
|||
- "Ratio r = C_mut / C_sh" |
|||
- "Minimum phase: φ_Z,min = -atan(2√[r(1+r)])" |
|||
- "Optimal resistance: R_opt_phase = 1/[ω√(C_mut(C_mut+C_sh))]" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate ratio" |
|||
- "r = C_mut / C_sh = 12 pF / 8 pF = 1.5" |
|||
- "Part (b): Calculate minimum phase" |
|||
- "φ_Z,min = -atan(2√[r(1+r)])" |
|||
- "= -atan(2√[1.5 × 2.5])" |
|||
- "= -atan(2√3.75)" |
|||
- "= -atan(2 × 1.936)" |
|||
- "= -atan(3.873)" |
|||
- "= -75.5°" |
|||
- "Part (c): Calculate R_opt_phase" |
|||
- "ω = 2πf = 2π × 150×10³ = 9.425×10⁵ rad/s" |
|||
- "R_opt_phase = 1/[ω√(C_mut(C_mut+C_sh))]" |
|||
- "= 1/[9.425×10⁵ × √(12×10⁻¹² × 20×10⁻¹²)]" |
|||
- "= 1/[9.425×10⁵ × √(240×10⁻²⁴)]" |
|||
- "= 1/[9.425×10⁵ × 15.49×10⁻¹²]" |
|||
- "= 1/(14.60×10⁻⁶)" |
|||
- "= 68.5 kΩ" |
|||
|
|||
answer_r: "1.5" |
|||
answer_phi_min: "-75.5" |
|||
answer_R_opt: "68.5" |
|||
unit_R: "kΩ" |
|||
unit_phi: "degrees" |
|||
tolerance: 3.0 |
|||
|
|||
explanation: | |
|||
With r = 1.5, this circuit cannot achieve -45° (which requires r < 0.207). The |
|||
minimum achievable phase is -75.5°, which is quite capacitive. This occurs when |
|||
R = R_opt_phase = 68.5 kΩ. Any other resistance value will result in a phase |
|||
angle with magnitude greater than 75.5°. This topological constraint is fundamental |
|||
to the circuit structure - it's impossible to overcome by changing component |
|||
values. The ratio r = 1.5 is typical for medium Tesla coils with moderate-length |
|||
sparks. |
|||
|
|||
related_concepts: ["topological-constraint", "phase-optimization", "R_opt_phase", "capacitance-ratio"] |
|||
@ -0,0 +1,84 @@ |
|||
id: fund-ex-08-comprehensive |
|||
type: multi-part |
|||
difficulty: hard |
|||
points: 50 |
|||
related_lesson: fund-08 |
|||
question: | |
|||
COMPREHENSIVE INTEGRATION EXERCISE |
|||
|
|||
A Tesla coil operates at 220 kHz with a 3.5-foot spark. FEMM analysis gives |
|||
C_mut = 9 pF. Assume R = 60 kΩ. |
|||
|
|||
(a) Calculate C_sh, ω, G, B₁, B₂ |
|||
(b) Calculate Y_total and Z_total |
|||
(c) Find φ_Z and compare to -45° |
|||
(d) Calculate r and φ_Z,min |
|||
(e) If V_top = 350 kV, find power dissipated |
|||
|
|||
hints: |
|||
- "Use C_sh ≈ 2 pF/foot for estimation" |
|||
- "Calculate all intermediate values carefully" |
|||
- "Use admittance formulas from fund-03" |
|||
- "Compare actual φ_Z to φ_Z,min from topological constraint" |
|||
- "Power = 0.5 × |I|² × R or 0.5 × |V|² × Re{Y}" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate components" |
|||
- "C_sh = 2 pF/foot × 3.5 feet = 7 pF" |
|||
- "ω = 2πf = 2π × 220×10³ = 1.382×10⁶ rad/s" |
|||
- "G = 1/R = 1/(60×10³) = 16.67 μS" |
|||
- "B₁ = ωC_mut = 1.382×10⁶ × 9×10⁻¹² = 12.44 μS" |
|||
- "B₂ = ωC_sh = 1.382×10⁶ × 7×10⁻¹² = 9.67 μS" |
|||
- "Part (b): Calculate Y_total" |
|||
- "Denominator: G² + (B₁+B₂)² = 277.9 + (22.11)² = 277.9 + 488.9 = 766.8 μS²" |
|||
- "Re{Y} = GB₂²/[G²+(B₁+B₂)²] = 16.67×93.5/766.8 = 1559/766.8 = 2.03 μS" |
|||
- "Im{Y} = B₂[G²+B₁(B₁+B₂)]/[G²+(B₁+B₂)²]" |
|||
- "= 9.67×[277.9+12.44×22.11]/766.8" |
|||
- "= 9.67×[277.9+275.0]/766.8" |
|||
- "= 9.67×552.9/766.8 = 6.98 μS" |
|||
- "Y_total = 2.03 + j6.98 μS" |
|||
- "Convert to impedance:" |
|||
- "|Y| = √(2.03² + 6.98²) = √(4.12 + 48.72) = 7.27 μS" |
|||
- "|Z| = 1/|Y| = 137.5 kΩ" |
|||
- "φ_Y = atan(6.98/2.03) = 73.8°" |
|||
- "φ_Z = -φ_Y = -73.8°" |
|||
- "R_eq = 137.5 × cos(-73.8°) = 38.4 kΩ" |
|||
- "X_eq = 137.5 × sin(-73.8°) = -132 kΩ" |
|||
- "Z_total = 38.4 - j132 kΩ = 137.5 kΩ ∠-73.8°" |
|||
- "Part (c): Compare to -45°" |
|||
- "φ_Z = -73.8° is more capacitive than -45° (larger magnitude)" |
|||
- "|X|/R = 132/38.4 = 3.44" |
|||
- "Capacitive reactance is 3.44× the resistance" |
|||
- "Part (d): Calculate topological constraint" |
|||
- "r = C_mut/C_sh = 9/7 = 1.286" |
|||
- "φ_Z,min = -atan(2√[1.286×2.286]) = -atan(2×1.716) = -atan(3.43) = -73.7°" |
|||
- "Actual φ_Z = -73.8° ≈ φ_Z,min (operating near optimal phase!)" |
|||
- "Part (e): Calculate power" |
|||
- "Current: I = V/|Z| = 350×10³/137.5×10³ = 2.55 A peak" |
|||
- "Power: P = 0.5 × I² × R_eq = 0.5 × 2.55² × 38.4×10³" |
|||
- "= 0.5 × 6.50 × 38.4×10³ = 125 kW" |
|||
- "Alternative: P = 0.5 × V² × Re{Y}" |
|||
- "= 0.5 × (350×10³)² × 2.03×10⁻⁶ = 124 kW ✓" |
|||
|
|||
answer_a: "C_sh=7pF, ω=1.382e6 rad/s, G=16.67μS, B₁=12.44μS, B₂=9.67μS" |
|||
answer_b: "Y=2.03+j6.98 μS, Z=137.5kΩ∠-73.8° or 38.4-j132 kΩ" |
|||
answer_c: "φ_Z=-73.8°, more capacitive than -45°, ratio=3.44" |
|||
answer_d: "r=1.286, φ_Z,min=-73.7°" |
|||
answer_e: "125" |
|||
unit_e: "kW" |
|||
tolerance: 5.0 |
|||
|
|||
explanation: | |
|||
This comprehensive problem integrates all fundamental concepts from Part 1. The |
|||
solution demonstrates: (1) using empirical rules for estimation, (2) systematic |
|||
admittance calculation, (3) conversion between Y and Z, (4) understanding phase |
|||
constraints, and (5) power calculation methods. |
|||
|
|||
Key insights: The actual phase angle (-73.8°) is essentially at the minimum |
|||
possible value (-73.7°), suggesting this R value is close to R_opt_phase. The |
|||
power dissipated (125 kW) is substantial for a 3.5-foot spark. The capacitive |
|||
reactance dominates (3.44× the resistance), which is typical for Tesla coil |
|||
sparks with r > 1. |
|||
|
|||
related_concepts: ["integration", "complete-analysis", "power-calculation", "phase-optimization"] |
|||
@ -0,0 +1,81 @@ |
|||
id: fund-ex-checkpoint-quiz |
|||
type: conceptual |
|||
difficulty: medium |
|||
points: 100 |
|||
related_lesson: fund-08 |
|||
question: | |
|||
FUNDAMENTALS CHECKPOINT QUIZ - Answer all 10 questions |
|||
|
|||
1. What is the relationship between peak and RMS voltage? If V_peak = 100 kV, what is V_RMS? |
|||
|
|||
2. Write the power formula using peak phasors. Why is there a factor of 0.5? |
|||
|
|||
3. For a capacitor, why is X negative but B positive? |
|||
|
|||
4. Draw the circuit topology for a spark (show C_mut, R, C_sh). |
|||
|
|||
5. What is the empirical rule for C_sh? If a spark is 4 feet long, estimate C_sh. |
|||
|
|||
6. The admittance phase angle θ_Y = +60°. What is the impedance phase angle φ_Z? |
|||
|
|||
7. An impedance has φ_Z = -30°. Is this inductive or capacitive? |
|||
|
|||
8. Why is V_top/I_base not the correct impedance measurement? |
|||
|
|||
9. Describe the difference between streamers and leaders (two key differences). |
|||
|
|||
10. Explain the "hungry streamer" concept in one sentence. |
|||
|
|||
hints: |
|||
- "Review each fundamental lesson carefully" |
|||
- "Consider both mathematical and physical interpretations" |
|||
- "Draw diagrams where helpful" |
|||
|
|||
solution: |
|||
answer_1: "V_RMS = V_peak/√2. For V_peak = 100 kV, V_RMS = 100/√2 ≈ 70.7 kV" |
|||
|
|||
answer_2: "P = 0.5 × Re{V × I*}. The 0.5 factor comes from time-averaging cos²(ωt) over a full cycle." |
|||
|
|||
answer_3: | |
|||
For capacitors, reactance X_C = -1/(ωC) is negative, but susceptance B_C = ωC |
|||
is positive. The sign conventions are opposite for impedance vs admittance. |
|||
|
|||
answer_4: | |
|||
Topload |
|||
| |
|||
[C_mut] |
|||
| |
|||
+----+----+ |
|||
| | |
|||
[R] [C_sh] |
|||
| | |
|||
GND------GND |
|||
|
|||
answer_5: "C_sh ≈ 2 pF/foot. For 4 feet: C_sh ≈ 8 pF" |
|||
|
|||
answer_6: "φ_Z = -θ_Y = -60°" |
|||
|
|||
answer_7: "Capacitive (negative φ_Z indicates capacitive behavior)" |
|||
|
|||
answer_8: | |
|||
I_base includes displacement currents from the entire secondary, plus coupling |
|||
currents and environmental currents. Only I_spark flows through the spark. |
|||
V_top/I_base underestimates impedance because I_base > I_spark. |
|||
|
|||
answer_9: | |
|||
Any two of: Streamers are thin (10-100 μm), fast (~10⁶ m/s), cold (~1000 K), |
|||
high R, branched. Leaders are thick (mm-cm), slower (~10³ m/s), hot (5000-20000 K), |
|||
low R, straighter. |
|||
|
|||
answer_10: | |
|||
Plasma actively adjusts its conductivity to maximize power extraction from the |
|||
circuit, naturally seeking R ≈ R_opt_power. |
|||
|
|||
explanation: | |
|||
This checkpoint quiz verifies understanding of all fundamental concepts from |
|||
Part 1. Correct answers demonstrate mastery of: complex numbers and phasors, |
|||
circuit topology, capacitance relationships, admittance analysis, phase angles, |
|||
measurement ports, and spark physics basics. These concepts form the foundation |
|||
for optimization (Part 2), growth physics (Part 3), and advanced modeling (Part 4). |
|||
|
|||
related_concepts: ["fundamentals-review", "integration", "checkpoint", "mastery-verification"] |
|||
@ -0,0 +1,52 @@ |
|||
id: opt-ex-01a |
|||
type: calculation |
|||
difficulty: medium |
|||
points: 15 |
|||
related_lesson: opt-01 |
|||
question: | |
|||
For a spark circuit with the following parameters: |
|||
- Frequency: f = 150 kHz |
|||
- Mutual capacitance: C_mut = 10 pF |
|||
- Shunt capacitance: C_sh = 8 pF |
|||
|
|||
Calculate both R_opt_power and R_opt_phase. |
|||
|
|||
hints: |
|||
- "R_opt_power = 1/[ω(C_mut + C_sh)]" |
|||
- "R_opt_phase = 1/[ω√(C_mut(C_mut + C_sh))]" |
|||
- "Calculate ω = 2πf first" |
|||
- "R_opt_power is always smaller than R_opt_phase" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Calculate angular frequency: ω = 2π × 150×10³ = 9.425×10⁵ rad/s" |
|||
- "Calculate R_opt_power:" |
|||
- "C_total = C_mut + C_sh = 10 + 8 = 18 pF" |
|||
- "R_opt_power = 1/(ω × C_total)" |
|||
- "= 1/(9.425×10⁵ × 18×10⁻¹²)" |
|||
- "= 1/(16.965×10⁻⁶)" |
|||
- "= 58.9 kΩ" |
|||
- "Calculate R_opt_phase:" |
|||
- "Product: C_mut × (C_mut + C_sh) = 10 × 18 = 180 pF²" |
|||
- "Square root: √180 = 13.42 pF" |
|||
- "R_opt_phase = 1/(ω × √180×10⁻¹²)" |
|||
- "= 1/(9.425×10⁵ × 13.42×10⁻¹²)" |
|||
- "= 1/(12.65×10⁻⁶)" |
|||
- "= 79.1 kΩ" |
|||
- "Compare: R_opt_power/R_opt_phase = 58.9/79.1 = 0.745" |
|||
|
|||
answer_power: "58.9" |
|||
answer_phase: "79.1" |
|||
unit: "kΩ" |
|||
ratio: "0.745" |
|||
tolerance: 3.0 |
|||
|
|||
explanation: | |
|||
This problem demonstrates the two critical resistances for spark optimization. |
|||
R_opt_power (58.9 kΩ) maximizes real power transfer to the spark, while |
|||
R_opt_phase (79.1 kΩ) minimizes the impedance phase angle magnitude. The ratio |
|||
of 0.745 is typical - R_opt_power is usually 50-75% of R_opt_phase. These |
|||
different values show that maximum power transfer and minimum phase angle are |
|||
different optimization goals that cannot be achieved simultaneously. |
|||
|
|||
related_concepts: ["R_opt_power", "R_opt_phase", "power-optimization", "phase-optimization"] |
|||
@ -0,0 +1,51 @@ |
|||
id: opt-ex-01b |
|||
type: multi-part |
|||
difficulty: medium |
|||
points: 15 |
|||
related_lesson: opt-01 |
|||
question: | |
|||
At 200 kHz, a spark has total capacitance C_total = 12 pF. |
|||
|
|||
(a) What is R_opt_power? |
|||
(b) If V_top = 400 kV, estimate the maximum deliverable power (assume R is at |
|||
optimal value and φ_Z ≈ -70°) |
|||
|
|||
hints: |
|||
- "R_opt_power = 1/(ω × C_total)" |
|||
- "Power = 0.5 × |V|² × Re{Y}" |
|||
- "Or use: P = 0.5 × |V|²/|Z| × cos(φ_Z)" |
|||
- "At R_opt_power, typical phase is around -65° to -75°" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate R_opt_power" |
|||
- "ω = 2π × 200×10³ = 1.257×10⁶ rad/s" |
|||
- "R_opt_power = 1/(ω × C_total)" |
|||
- "= 1/(1.257×10⁶ × 12×10⁻¹²)" |
|||
- "= 1/(15.08×10⁻⁶)" |
|||
- "= 66.3 kΩ" |
|||
- "Part (b): Estimate maximum power" |
|||
- "At R_opt_power with given capacitances, φ_Z ≈ -70° (typical)" |
|||
- "Approximate |Z| ≈ R_opt_power / cos(-70°) = 66.3/0.342 ≈ 194 kΩ" |
|||
- "Current: I = V/|Z| = 400×10³/194×10³ = 2.06 A peak" |
|||
- "Power: P = 0.5 × V × I × cos(φ_Z)" |
|||
- "= 0.5 × 400×10³ × 2.06 × cos(-70°)" |
|||
- "= 0.5 × 400×10³ × 2.06 × 0.342" |
|||
- "= 141 kW" |
|||
- "Alternative: P ≈ 0.5 × I² × R = 0.5 × 2.06² × 66.3×10³ ≈ 141 kW" |
|||
|
|||
answer_a: "66.3" |
|||
answer_b: "141" |
|||
unit_a: "kΩ" |
|||
unit_b: "kW" |
|||
tolerance: 5.0 |
|||
|
|||
explanation: | |
|||
R_opt_power is determined solely by frequency and total capacitance. At this |
|||
resistance, power transfer is maximized. The estimated power (141 kW) is |
|||
substantial, but achievable for medium-to-large DRSSTCs. This calculation shows |
|||
why R_opt_power is critical for performance - operating far from this value |
|||
significantly reduces delivered power. The estimate uses typical phase angle |
|||
for operation at R_opt_power; exact value would require full admittance calculation. |
|||
|
|||
related_concepts: ["R_opt_power", "maximum-power-transfer", "power-estimation"] |
|||
@ -0,0 +1,91 @@ |
|||
id: opt-ex-thevenin-complete |
|||
type: multi-part |
|||
difficulty: hard |
|||
points: 40 |
|||
related_lesson: opt-03 |
|||
question: | |
|||
COMPLETE THÉVENIN ANALYSIS |
|||
|
|||
You measured the following Thévenin parameters for your DRSSTC at 188 kHz: |
|||
- Z_th = 115 - j2300 Ω (drive OFF, 1V test source) |
|||
- V_th = 340 kV (drive ON, no load) |
|||
|
|||
The spark has: |
|||
- C_mut = 8 pF, C_sh = 5 pF (from FEMM) |
|||
- R = 65 kΩ (assumed operating resistance) |
|||
|
|||
Tasks: |
|||
(a) Calculate the spark admittance Y_spark |
|||
(b) Convert to Z_spark |
|||
(c) Calculate total circuit impedance Z_total = Z_th + Z_spark |
|||
(d) Calculate current through the spark |
|||
(e) Calculate voltage across the spark |
|||
(f) Calculate real power dissipated in the spark |
|||
(g) Compare R to R_opt_power for these capacitances |
|||
|
|||
hints: |
|||
- "Use admittance formulas for parallel (R || C_mut) then series with C_sh" |
|||
- "Add impedances in series: Z_total = Z_th + Z_spark" |
|||
- "Current divider applies: I = V_th / Z_total" |
|||
- "Voltage across spark: V_spark = I × Z_spark" |
|||
- "Power: P = 0.5 × |I|² × Re{Z_spark}" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate Y_spark" |
|||
- "ω = 2π × 188×10³ = 1.181×10⁶ rad/s" |
|||
- "G = 1/65000 = 15.38 μS" |
|||
- "B₁ = 1.181×10⁶ × 8×10⁻¹² = 9.45 μS" |
|||
- "B₂ = 1.181×10⁶ × 5×10⁻¹² = 5.91 μS" |
|||
- "Denom: G² + (B₁+B₂)² = 236.5 + 236.2 = 472.7 μS²" |
|||
- "Re{Y} = 15.38 × 34.93 / 472.7 = 1.14 μS" |
|||
- "Im{Y} = 5.91 × [236.5 + 145.2] / 472.7 = 4.77 μS" |
|||
- "Y_spark = 1.14 + j4.77 μS" |
|||
- "Part (b): Convert to Z_spark" |
|||
- "|Y| = √(1.14² + 4.77²) = 4.90 μS" |
|||
- "|Z_spark| = 1/4.90×10⁻⁶ = 204 kΩ" |
|||
- "φ_Y = atan(4.77/1.14) = 76.6°" |
|||
- "φ_Z = -76.6°" |
|||
- "R_eq = 204 × cos(-76.6°) = 47.6 kΩ" |
|||
- "X_eq = 204 × sin(-76.6°) = -198 kΩ" |
|||
- "Z_spark = 47.6 - j198 kΩ" |
|||
- "Part (c): Calculate Z_total" |
|||
- "Z_total = Z_th + Z_spark" |
|||
- "= (115 - j2300) + (47600 - j198000)" |
|||
- "= (47715 - j200300) Ω" |
|||
- "= 47.7 - j200.3 kΩ" |
|||
- "|Z_total| = √(47.7² + 200.3²) = 205.9 kΩ" |
|||
- "Part (d): Calculate current" |
|||
- "I = V_th / Z_total = 340×10³ / 205.9×10³ = 1.65 A peak" |
|||
- "Part (e): Calculate voltage across spark" |
|||
- "V_spark = I × Z_spark = 1.65 × 204×10³ = 337 kV" |
|||
- "Part (f): Calculate power" |
|||
- "P = 0.5 × I² × R_eq = 0.5 × 1.65² × 47.6×10³" |
|||
- "= 0.5 × 2.72 × 47.6×10³ = 64.8 kW" |
|||
- "Part (g): Compare to R_opt_power" |
|||
- "R_opt = 1/(ω × (C_mut + C_sh))" |
|||
- "= 1/(1.181×10⁶ × 13×10⁻¹²) = 65.1 kΩ" |
|||
- "Actual R = 65 kΩ ≈ R_opt_power ✓" |
|||
- "Operating at optimal resistance for maximum power transfer!" |
|||
|
|||
answer_a: "1.14 + j4.77 μS" |
|||
answer_b: "204 kΩ ∠-76.6° or 47.6 - j198 kΩ" |
|||
answer_c: "205.9 kΩ" |
|||
answer_d: "1.65" |
|||
unit_d: "A peak" |
|||
answer_e: "337" |
|||
unit_e: "kV" |
|||
answer_f: "64.8" |
|||
unit_f: "kW" |
|||
answer_g: "R_opt = 65.1 kΩ, actual = 65 kΩ, at optimum!" |
|||
tolerance: 3.0 |
|||
|
|||
explanation: | |
|||
This complete Thévenin analysis demonstrates the power of the equivalent circuit |
|||
method. Key insights: (1) Most voltage appears across the spark (337 kV out of |
|||
340 kV) because |Z_spark| >> |Z_th|, (2) The actual R ≈ R_opt_power suggests |
|||
the plasma self-optimized to maximize power extraction, (3) Power dissipated |
|||
(64.8 kW) is substantial, (4) Strongly capacitive spark (φ_Z = -76.6°) is typical. |
|||
This analysis predicts performance without full coupled simulation. |
|||
|
|||
related_concepts: ["thevenin-method", "complete-analysis", "power-prediction", "self-optimization"] |
|||
@ -0,0 +1,44 @@ |
|||
id: phys-ex-01a |
|||
type: calculation |
|||
difficulty: easy |
|||
points: 10 |
|||
related_lesson: phys-01 |
|||
question: | |
|||
A 0.8 m spark has V_top = 280 kV and tip enhancement factor κ = 4. |
|||
|
|||
(a) Calculate E_tip |
|||
(b) If E_propagation = 0.5 MV/m, can the spark grow further? |
|||
|
|||
hints: |
|||
- "E_average = V_top / L" |
|||
- "E_tip = κ × E_average" |
|||
- "Growth continues when E_tip > E_propagation" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Calculate average field" |
|||
- "E_average = V_top / L = 280×10³ V / 0.8 m = 350 kV/m = 0.35 MV/m" |
|||
- "Calculate tip field" |
|||
- "E_tip = κ × E_average = 4 × 0.35 = 1.4 MV/m" |
|||
- "Part (b): Compare to threshold" |
|||
- "E_tip = 1.4 MV/m" |
|||
- "E_propagation = 0.5 MV/m" |
|||
- "E_tip > E_propagation ✓" |
|||
- "Yes, spark can grow further" |
|||
- "Safety margin: 1.4 / 0.5 = 2.8× above threshold" |
|||
|
|||
answer_a: "1.4" |
|||
unit_a: "MV/m" |
|||
answer_b: "yes" |
|||
margin: "2.8" |
|||
tolerance: 5.0 |
|||
|
|||
explanation: | |
|||
The tip field (1.4 MV/m) significantly exceeds the propagation threshold |
|||
(0.5 MV/m), with a comfortable 2.8× safety margin. This spark is not voltage- |
|||
limited and can continue growing. The enhancement factor κ = 4 concentrates the |
|||
average field (0.35 MV/m) at the tip, creating sufficient field strength for |
|||
sustained ionization and growth. If this spark has adequate power, it can extend |
|||
well beyond 0.8 m. |
|||
|
|||
related_concepts: ["electric-field", "tip-enhancement", "growth-criterion", "voltage-limited"] |
|||
@ -0,0 +1,45 @@ |
|||
id: phys-ex-03a |
|||
type: calculation |
|||
difficulty: hard |
|||
points: 20 |
|||
related_lesson: phys-03 |
|||
question: | |
|||
A burst-mode coil has ε = 60 J/m. To reach L = 1.5 m in a 200 μs pulse, |
|||
what power is required? Is this realistic for a burst-mode Tesla coil? |
|||
|
|||
hints: |
|||
- "Use growth rate equation: dL/dt = P/ε" |
|||
- "Rearrange: P = ε × dL/dt" |
|||
- "Calculate dL/dt = L/T for the pulse duration" |
|||
- "Consider typical DRSSTC power levels" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Calculate growth rate needed:" |
|||
- "dL/dt = L / T = 1.5 m / (200×10⁻⁶ s) = 7,500 m/s" |
|||
- "Calculate required power:" |
|||
- "P = ε × dL/dt" |
|||
- "P = 60 J/m × 7,500 m/s" |
|||
- "P = 450,000 W = 450 kW" |
|||
- "Analysis of realism:" |
|||
- "Energy per pulse: E = P × T = 450 kW × 200 μs = 90 J" |
|||
- "For primary: C = 0.5 μF, need V² = 2E/C = 360,000, so V ≈ 600 V" |
|||
- "Peak power: 450 kW is high but achievable for large DRSSTC" |
|||
- "Conclusion: Challenging but realistic for large coil" |
|||
|
|||
answer: "450" |
|||
unit: "kW" |
|||
energy_per_pulse: "90" |
|||
realistic: "yes, but requires large DRSSTC" |
|||
tolerance: 5.0 |
|||
|
|||
explanation: | |
|||
Growing 1.5 m in just 200 μs requires extremely high instantaneous power |
|||
(450 kW). However, the total energy per pulse is only 90 J, which is achievable |
|||
with a 0.5 μF primary capacitor charged to 600 V. This high power/short duration |
|||
trade-off is characteristic of burst mode operation. The high ε = 60 J/m reflects |
|||
inefficiency (branching, radiation) in burst mode. A QCW coil with ε = 10 J/m |
|||
would need only 75 kW for the same growth rate, or could grow the same length |
|||
with less power over a longer time. |
|||
|
|||
related_concepts: ["energy-per-meter", "growth-rate", "burst-mode", "power-requirements"] |
|||
@ -0,0 +1,109 @@ |
|||
id: phys-ex-comprehensive |
|||
type: design |
|||
difficulty: hard |
|||
points: 100 |
|||
related_lesson: phys-09 |
|||
question: | |
|||
COMPREHENSIVE SPARK PHYSICS DESIGN CHALLENGE |
|||
|
|||
Design a QCW coil from scratch to achieve 3.5 m sparks. |
|||
|
|||
Given constraints: |
|||
- Budget allows C_primary up to 1.0 μF |
|||
- V_primary limited to 600 V (safety) |
|||
- Topload options: 20 cm toroid (C_top ≈ 25 pF) or 35 cm toroid (C_top ≈ 45 pF) |
|||
- Target ramp time: 10-15 ms |
|||
- Sea level operation (E_propagation = 0.6 MV/m) |
|||
|
|||
Complete the following analysis: |
|||
|
|||
1. Energy calculation: |
|||
- Choose ε for QCW mode |
|||
- Calculate total energy required for 3.5 m |
|||
- Verify achievable with C_primary and V_primary |
|||
|
|||
2. Voltage requirement: |
|||
- Estimate C_mut for each topload (use C_mut ≈ 0.7 × C_top) |
|||
- Calculate C_sh for 3.5 m spark |
|||
- For each topload, calculate V_topload needed for E_tip = 0.7 MV/m at 3.5 m (κ = 3.0) |
|||
- Include capacitive division effects |
|||
|
|||
3. Power analysis: |
|||
- For T_ramp = 12 ms, calculate required average power |
|||
- Estimate peak power (assume 1.5× average for QCW) |
|||
- Check if reasonable for DRSSTC primary |
|||
|
|||
4. Thermal verification: |
|||
- Estimate leader diameter (2-4 mm typical) |
|||
- Calculate thermal time constant |
|||
- Verify ramp time << thermal time |
|||
|
|||
5. Final recommendation: |
|||
- Which topload should be used? |
|||
- Is 3.5 m target achievable? |
|||
- If not, what would you change? |
|||
|
|||
hints: |
|||
- "Use ε ≈ 10-12 J/m for QCW mode" |
|||
- "Remember capacitive divider: V_tip = V_topload × C_mut/(C_mut + C_sh)" |
|||
- "E_tip = κ × V_tip / L must exceed E_propagation" |
|||
- "Thermal time: τ = d²/(4α) with α = 2×10⁻⁵ m²/s" |
|||
|
|||
solution: |
|||
energy_calculation: |
|||
chosen_epsilon: "11 J/m (typical QCW)" |
|||
total_energy: "E = ε × L = 11 × 3.5 = 38.5 J" |
|||
primary_check: "E_primary = 0.5 × C × V² = 0.5 × 1.0×10⁻⁶ × 600² = 180 J" |
|||
verdict: "38.5 J << 180 J available ✓ Energy adequate" |
|||
|
|||
voltage_requirement: |
|||
small_toroid: |
|||
C_top: "25 pF" |
|||
C_mut_est: "17.5 pF" |
|||
C_sh: "23.1 pF (6.6 pF/m × 3.5 m)" |
|||
V_tip_needed: "V_tip = E_prop × L / κ = 0.7×10⁶ × 3.5 / 3.0 = 817 kV" |
|||
V_topload_needed: "V_top = V_tip × (C_mut + C_sh) / C_mut = 817 × 40.6/17.5 = 1,896 kV" |
|||
verdict: "Unrealistic voltage required ✗" |
|||
|
|||
large_toroid: |
|||
C_top: "45 pF" |
|||
C_mut_est: "31.5 pF" |
|||
C_sh: "23.1 pF" |
|||
V_tip_needed: "817 kV (same)" |
|||
V_topload_needed: "V_top = 817 × 54.6/31.5 = 1,416 kV" |
|||
verdict: "Still very high, challenging ✗" |
|||
|
|||
power_analysis: |
|||
ramp_time: "12 ms" |
|||
avg_power: "P = E/T = 38.5 J / 0.012 s = 3.2 kW" |
|||
peak_power: "~5 kW (1.5× average)" |
|||
verdict: "Power requirement is modest ✓" |
|||
|
|||
thermal_verification: |
|||
leader_diameter: "3 mm (estimate)" |
|||
thermal_constant: "τ = (0.003)² / (4 × 2×10⁻⁵) = 113 ms" |
|||
comparison: "T_ramp (12 ms) < τ (113 ms), ratio = 0.11" |
|||
verdict: "Leader stays hot during ramp ✓ QCW condition satisfied" |
|||
|
|||
final_recommendation: | |
|||
Neither topload can achieve 3.5 m with realistic voltages due to capacitive |
|||
division. To achieve 3.5 m: |
|||
|
|||
Option 1: Accept shorter sparks (~2-2.5 m achievable with large toroid) |
|||
Option 2: Increase primary voltage capability (beyond 600 V safety limit) |
|||
Option 3: Use active voltage ramping to counteract division |
|||
Option 4: Add intermediate electrode to reduce effective spark length |
|||
|
|||
Recommended: Use 35 cm toroid, target 2.5 m realistic goal, accept that |
|||
voltage limitation dominates. Energy and power are adequate, but voltage |
|||
limit prevents reaching 3.5 m target. |
|||
|
|||
explanation: | |
|||
This comprehensive design challenge demonstrates the interplay between energy, |
|||
voltage, and power limitations. The analysis reveals that voltage (electric field |
|||
requirement) is the primary constraint, not energy or power. Capacitive division |
|||
significantly increases the required topload voltage. The larger toroid helps but |
|||
doesn't fully solve the problem. This is typical for Tesla coils - voltage-limited |
|||
rather than power-limited. Realistic design must balance these constraints. |
|||
|
|||
related_concepts: ["design-integration", "voltage-vs-power-limits", "capacitive-divider", "QCW-optimization"] |
|||
@ -0,0 +1,77 @@ |
|||
id: phys-ex-conceptual-limits |
|||
type: conceptual |
|||
difficulty: medium |
|||
points: 20 |
|||
related_lesson: phys-09 |
|||
question: | |
|||
CONCEPTUAL UNDERSTANDING: Voltage vs Power Limitations |
|||
|
|||
A coiler claims: "I have 200 kW of power available in my DRSSTC, so I should |
|||
easily get 10 m sparks!" |
|||
|
|||
Identify the flaws in this reasoning. Your answer should discuss: |
|||
(a) Voltage vs power limitations |
|||
(b) Energy per meter constraints |
|||
(c) Capacitive divider effects |
|||
(d) Realistic expectations |
|||
|
|||
hints: |
|||
- "Consider both E-field requirements AND energy requirements" |
|||
- "What happens to E_tip as spark grows?" |
|||
- "How does capacitive division change with length?" |
|||
- "Typical maximum spark lengths for Tesla coils" |
|||
|
|||
solution: |
|||
answer: | |
|||
FLAWS IN REASONING: |
|||
|
|||
(a) Voltage vs Power Limitations: |
|||
Power alone doesn't determine spark length. The spark needs BOTH adequate |
|||
electric field (E_tip > E_propagation ≈ 0.6 MV/m) AND sufficient energy. |
|||
For a 10 m spark: |
|||
- Average field needed: E_avg ≈ 0.6 MV/m (if κ ≈ 3) |
|||
- This requires V_top ≈ 2,000 kV minimum |
|||
- But typical Tesla coil voltages: 300-600 kV (factor of 3-7 too low!) |
|||
- Voltage limitation dominates, not power |
|||
|
|||
(b) Energy Per Meter Constraints: |
|||
Even if power is adequate: |
|||
- For QCW with ε = 10 J/m: E_needed = 10 × 10 = 100 J |
|||
- Time available: T ≈ 10-20 ms typical |
|||
- Power needed: P = 100 J / 0.015 s = 6.7 kW (well below 200 kW!) |
|||
- So power is not the limiting factor |
|||
|
|||
(c) Capacitive Divider Effects: |
|||
As spark grows: |
|||
- C_sh increases (≈ 6.6 pF/m, so 66 pF for 10 m) |
|||
- V_tip = V_topload × C_mut/(C_mut + C_sh) decreases |
|||
- For typical C_mut = 20 pF: V_tip = V_top × 20/86 = 0.23 × V_top |
|||
- Lose 77% of voltage to division! |
|||
- Combined with 1/L² field reduction: E_tip ∝ 1/L² catastrophic drop |
|||
- This self-limiting effect prevents very long sparks |
|||
|
|||
(d) Realistic Expectations: |
|||
- Burst mode record sparks: ~2-3 m |
|||
- QCW mode record sparks: ~5-6 m |
|||
- 10 m would require: |
|||
* V_top ≈ 2+ MV (extreme) |
|||
* Careful voltage ramping to fight division |
|||
* Very large topload (high C_mut) |
|||
* Sea level operation (higher E_propagation at altitude) |
|||
- More power doesn't overcome voltage limit! |
|||
- The claim confuses power-limited with voltage-limited regimes |
|||
|
|||
CORRECT REASONING: |
|||
"I have adequate power, but am limited by achievable topload voltage and |
|||
capacitive division effects. Realistic maximum is ~3-4 m for my coil, |
|||
regardless of available power beyond ~20 kW." |
|||
|
|||
explanation: | |
|||
This conceptual problem addresses a common misconception. Tesla coils are almost |
|||
always voltage-limited, not power-limited. The E-field requirement (E_tip > |
|||
E_propagation) combined with capacitive division creates a fundamental voltage |
|||
barrier. Having excess power just makes the spark brighter and hotter, not longer. |
|||
Understanding this distinction is critical for realistic performance expectations |
|||
and efficient design decisions. |
|||
|
|||
related_concepts: ["voltage-vs-power", "limiting-factors", "capacitive-divider", "realistic-expectations"] |
|||
@ -0,0 +1,79 @@ |
|||
id: model-ex-lumped-complete |
|||
type: multi-part |
|||
difficulty: hard |
|||
points: 50 |
|||
related_lesson: model-02 |
|||
question: | |
|||
LUMPED MODEL COMPLETE WORKFLOW |
|||
|
|||
You extracted the following Maxwell capacitance matrix from FEMM for a 1.2 m |
|||
(4-foot) spark with a toroid topload: |
|||
|
|||
Maxwell Matrix (pF): |
|||
Topload Spark |
|||
Topload [ 32.5 -9.2 ] |
|||
Spark [ -9.2 15.6 ] |
|||
|
|||
Operating frequency: f = 185 kHz |
|||
|
|||
Tasks: |
|||
(a) Validate the matrix (check symmetry, signs, physical reasonableness) |
|||
(b) Extract C_mut and C_sh for the lumped circuit model |
|||
(c) Compare C_sh to the empirical 2 pF/foot rule |
|||
(d) Calculate R_opt_power and R_opt_phase |
|||
(e) Build the lumped model with R = R_opt_power and calculate Z_spark |
|||
|
|||
hints: |
|||
- "Maxwell matrix has negative off-diagonals" |
|||
- "C_mut = |C₁₂|, C_sh = C₂₂ - |C₁₂|" |
|||
- "Check if C_sh ≈ 2 pF/foot × 4 feet = 8 pF" |
|||
- "Use admittance formulas for part (e)" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Part (a): Matrix validation" |
|||
- "Symmetry: C₁₂ = C₂₁ = -9.2 pF ✓" |
|||
- "Diagonal positive: C₁₁ = 32.5 > 0, C₂₂ = 15.6 > 0 ✓" |
|||
- "Off-diagonal negative: C₁₂ = -9.2 < 0 ✓" |
|||
- "Row sums: R₁ = 32.5 - 9.2 = 23.3, R₂ = -9.2 + 15.6 = 6.4 (ground contribution) ✓" |
|||
- "Matrix is valid" |
|||
- "Part (b): Extract lumped parameters" |
|||
- "C_mut = |C₁₂| = |-9.2| = 9.2 pF" |
|||
- "C_sh = C₂₂ - |C₁₂| = 15.6 - 9.2 = 6.4 pF" |
|||
- "Part (c): Compare to empirical rule" |
|||
- "Empirical: C_sh ≈ 2 pF/foot × 4 feet = 8 pF" |
|||
- "FEMM: C_sh = 6.4 pF" |
|||
- "Ratio: 6.4/8 = 0.8 (within factor 2, acceptable) ✓" |
|||
- "Part (d): Calculate optimal resistances" |
|||
- "ω = 2π × 185×10³ = 1.162×10⁶ rad/s" |
|||
- "C_total = 9.2 + 6.4 = 15.6 pF" |
|||
- "R_opt_power = 1/(ω × C_total) = 1/(1.162×10⁶ × 15.6×10⁻¹²) = 55.2 kΩ" |
|||
- "Product: C_mut(C_mut + C_sh) = 9.2 × 15.6 = 143.5 pF²" |
|||
- "R_opt_phase = 1/(ω × √143.5×10⁻¹²) = 1/(1.162×10⁶ × 11.98×10⁻¹²) = 71.9 kΩ" |
|||
- "Part (e): Calculate Z_spark at R_opt_power" |
|||
- "Use R = 55.2 kΩ, so G = 18.12 μS" |
|||
- "B₁ = ω × C_mut = 1.162×10⁶ × 9.2×10⁻¹² = 10.69 μS" |
|||
- "B₂ = ω × C_sh = 1.162×10⁶ × 6.4×10⁻¹² = 7.44 μS" |
|||
- "Denominator: G² + (B₁+B₂)² = 328.3 + 328.1 = 656.4 μS²" |
|||
- "Re{Y} = 18.12 × 55.35 / 656.4 = 1.53 μS" |
|||
- "Im{Y} = 7.44 × [328.3 + 193.7] / 656.4 = 5.92 μS" |
|||
- "Y = 1.53 + j5.92 μS" |
|||
- "|Y| = 6.11 μS, |Z| = 163.6 kΩ" |
|||
- "φ_Y = atan(5.92/1.53) = 75.5°, φ_Z = -75.5°" |
|||
- "Z_spark = 163.6 kΩ ∠-75.5°" |
|||
|
|||
answer_b: "C_mut = 9.2 pF, C_sh = 6.4 pF" |
|||
answer_c: "6.4 pF vs 8 pF empirical, ratio 0.8, acceptable" |
|||
answer_d: "R_opt_power = 55.2 kΩ, R_opt_phase = 71.9 kΩ" |
|||
answer_e: "163.6 kΩ ∠-75.5°" |
|||
tolerance: 3.0 |
|||
|
|||
explanation: | |
|||
This complete workflow demonstrates lumped model extraction from FEMM. Key points: |
|||
(1) Matrix validation catches errors early, (2) Sign conversion is critical |
|||
(C_mut = |C₁₂|, not C₁₂), (3) FEMM values within factor 2 of empirical rules is |
|||
normal, (4) Both critical resistances are calculated for optimization, (5) Final |
|||
impedance is strongly capacitive (φ_Z = -75.5°) as expected. The 4-foot spark |
|||
shows typical behavior with r = C_mut/C_sh = 1.44, giving φ_Z,min ≈ -75°. |
|||
|
|||
related_concepts: ["FEMM-extraction", "lumped-model", "matrix-validation", "complete-workflow"] |
|||
@ -0,0 +1,59 @@ |
|||
@echo off |
|||
REM Tesla Coil Spark Course - Launch Script |
|||
REM Creates virtual environment and runs PyQt5 application |
|||
|
|||
echo ======================================== |
|||
echo Tesla Coil Spark Physics Course |
|||
echo ======================================== |
|||
echo. |
|||
|
|||
REM Navigate to spark-lessons directory |
|||
cd spark-lessons |
|||
|
|||
REM Check if virtual environment exists |
|||
if not exist venv ( |
|||
echo [*] Creating virtual environment... |
|||
python -m venv venv |
|||
if errorlevel 1 ( |
|||
echo [ERROR] Failed to create virtual environment! |
|||
echo Please ensure Python 3.8+ is installed and in PATH. |
|||
pause |
|||
exit /b 1 |
|||
) |
|||
echo [OK] Virtual environment created |
|||
) |
|||
|
|||
REM Activate virtual environment |
|||
echo [*] Activating virtual environment... |
|||
call venv\Scripts\activate.bat |
|||
|
|||
REM Check if dependencies are installed |
|||
if not exist venv\installed.flag ( |
|||
echo [*] Installing dependencies... |
|||
python -m pip install --upgrade pip |
|||
pip install -r requirements.txt |
|||
if errorlevel 1 ( |
|||
echo [ERROR] Failed to install dependencies! |
|||
pause |
|||
exit /b 1 |
|||
) |
|||
echo. > venv\installed.flag |
|||
echo [OK] Dependencies installed |
|||
) |
|||
|
|||
REM Run the application |
|||
echo [*] Launching Tesla Coil Spark Course... |
|||
echo. |
|||
python app/main.py |
|||
|
|||
REM Capture exit code |
|||
set EXIT_CODE=%ERRORLEVEL% |
|||
|
|||
REM Deactivate virtual environment |
|||
call deactivate |
|||
|
|||
REM Return to original directory |
|||
cd .. |
|||
|
|||
REM Exit with application's exit code |
|||
exit /b %EXIT_CODE% |
|||
7327
spark-lesson.txt
File diff suppressed because it is too large
View File
@ -0,0 +1,470 @@ |
|||
# Circuit Diagram Specifications |
|||
|
|||
This document provides **exact specifications** for creating 7 circuit diagrams that require manual attention for professional quality. |
|||
|
|||
**Recommended tools:** LTspice, CircuitLab, Inkscape, KiCad schematic editor, or professional drawing software. |
|||
|
|||
**Format:** PNG, 150 DPI minimum, white background |
|||
|
|||
--- |
|||
|
|||
## Circuit 1: Geometry to Circuit Translation |
|||
|
|||
**Filename:** `lessons/01-fundamentals/assets/geometry-to-circuit.png` |
|||
**Size:** 1000 x 600 px |
|||
**Referenced in:** fund-02 (Basic Circuit Model) |
|||
|
|||
### Description |
|||
Side-by-side diagram showing physical geometry on left, equivalent circuit on right. |
|||
|
|||
### Left Side: 3D Visualization (Conceptual) |
|||
``` |
|||
[Sketch/photo showing:] |
|||
- Toroidal topload (or spherical) |
|||
- Cylindrical spark channel extending downward |
|||
- Ground plane at bottom |
|||
- Arrows/labels indicating: |
|||
* C_mut (coupling between topload and spark) |
|||
* C_sh (spark to ground) |
|||
``` |
|||
|
|||
**Note:** Can use simplified 2D side-view sketch if 3D is difficult. |
|||
|
|||
### Right Side: Circuit Schematic |
|||
|
|||
**Topology (CRITICAL - verify this is correct):** |
|||
|
|||
``` |
|||
Topload node |
|||
| |
|||
+----[C_mut]----+ |
|||
| | |
|||
+----[R]--------+ |
|||
| |
|||
(Spark tip node) |
|||
| |
|||
[C_sh] |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
**Component values to show:** |
|||
- R: Variable (or "R_spark") |
|||
- C_mut: "~8 pF" (typical) |
|||
- C_sh: "~6 pF" (typical) |
|||
|
|||
**Layout guidelines:** |
|||
- Vertical orientation |
|||
- Clear node labels: "Topload", "Spark Tip", "GND" |
|||
- R and C_mut in parallel (side-by-side, same start/end nodes) |
|||
- C_sh in series below the parallel combination |
|||
|
|||
**Alternative if parallel is hard:** Show as impedance block "Z_mut = R || C_mut" |
|||
|
|||
--- |
|||
|
|||
## Circuit 2: Current Paths Diagram |
|||
|
|||
**Filename:** `lessons/01-fundamentals/assets/current-paths-diagram.png` |
|||
**Size:** 1000 x 1200 px (vertical) |
|||
**Referenced in:** fund-07 (Measurement Port) |
|||
|
|||
### Description |
|||
Complete Tesla coil schematic showing **all** current return paths. |
|||
|
|||
### Schematic Components |
|||
|
|||
**Primary circuit (left side):** |
|||
``` |
|||
[AC Source] -→ [IGBT/Switch] -→ [C_pri] -→ [L_pri] -→ GND |
|||
``` |
|||
|
|||
**Secondary circuit (right side, magnetically coupled):** |
|||
``` |
|||
L_sec (coil symbol, coupled to L_pri via k = 0.1-0.2) |
|||
| |
|||
+-- [C_topload] --| |
|||
| | |
|||
+-- [Spark] | |
|||
| | |
|||
+-- [C_stray] ----+ |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
**Current paths to label (USE DIFFERENT COLORS):** |
|||
1. **I_spark** (RED): Through spark resistance |
|||
2. **I_displacement** (BLUE): Through C_topload to ground |
|||
3. **I_coupling** (GREEN): Primary-to-secondary capacitive coupling |
|||
4. **I_secondary** (PURPLE): Distributed capacitance along secondary |
|||
5. **I_base** (BLACK, THICK): Total current at secondary base |
|||
|
|||
**Key annotation:** |
|||
``` |
|||
I_base = I_spark + I_displacement + I_coupling + I_secondary + ... |
|||
``` |
|||
|
|||
**Mark measurement points:** |
|||
- Correct: "Measure here" at topload-to-ground (V_top / I_spark) |
|||
- Incorrect: "NOT here" with X at base (V_top / I_base) |
|||
|
|||
### Layout Guidelines |
|||
- Primary on left, secondary on right |
|||
- Clear coupling indicator (dashed lines or k = 0.1-0.2) |
|||
- Use arrows for current directions |
|||
- Color code or use different line styles for each current path |
|||
- Legend showing which color = which current |
|||
|
|||
--- |
|||
|
|||
## Circuit 3: Thévenin Equivalent Circuit |
|||
|
|||
**Filename:** `lessons/02-optimization/assets/thevenin-equivalent-circuit.png` |
|||
**Size:** 800 x 600 px |
|||
**Referenced in:** opt-04 (Thévenin Calculations) |
|||
|
|||
### Description |
|||
Simple Thévenin equivalent driving a spark load. |
|||
|
|||
### Schematic |
|||
|
|||
``` |
|||
+-------[R_th]-----[jX_th]------+ |
|||
| | |
|||
[V_th source] [Z_spark load] |
|||
| | |
|||
+--------------------------------+ |
|||
``` |
|||
|
|||
**More detailed Z_spark:** |
|||
``` |
|||
Z_spark can be shown as: |
|||
[R_spark] in series with [jX_spark] |
|||
OR |
|||
[(R || C_mut) in series with C_sh] |
|||
``` |
|||
|
|||
**Component labels:** |
|||
- V_th: "350 kV" (typical value) |
|||
- R_th: "114 Ω" (typical) |
|||
- X_th: "-j2424 Ω" (typical, capacitive) |
|||
- Z_spark: "Variable" |
|||
|
|||
**Annotations:** |
|||
- "Thévenin Equivalent" label on left side |
|||
- "Spark Load" label on right side |
|||
- Formula below: **P = 0.5|V_th|² Re{Z_spark} / |Z_th + Z_spark|²** |
|||
|
|||
### Layout Guidelines |
|||
- Horizontal orientation, left to right |
|||
- V_th source on left |
|||
- R_th and X_th clearly in series |
|||
- Load impedance on right |
|||
- Clean, minimal style |
|||
|
|||
--- |
|||
|
|||
## Circuit 4: Capacitive Divider Circuit |
|||
|
|||
**Filename:** `lessons/03-spark-physics/assets/capacitive-divider-circuit.png` |
|||
**Size:** 600 x 800 px (vertical) |
|||
**Referenced in:** phys-07 (Capacitive Divider) |
|||
|
|||
### Description |
|||
Shows voltage division across C_mut and C_sh. |
|||
|
|||
### Schematic |
|||
|
|||
``` |
|||
V_topload (source) |
|||
| |
|||
+----[C_mut]----+ |
|||
| | |
|||
+----[R]--------+ |
|||
| |
|||
V_tip (measurement point) ← mark this clearly |
|||
| |
|||
[C_sh] |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
**Component labels:** |
|||
- V_topload: "Input" |
|||
- C_mut: "~10 pF" |
|||
- C_sh: "~6.6 L (pF)" where L is in meters |
|||
- R: "R_spark" |
|||
- V_tip: Mark with voltmeter symbol or arrow |
|||
|
|||
**Key formula (below circuit):** |
|||
``` |
|||
V_tip = V_topload × [C_mut / (C_mut + C_sh)] |
|||
|
|||
C_sh grows with spark length: ~6.6 pF/m |
|||
``` |
|||
|
|||
### Layout Guidelines |
|||
- Vertical orientation |
|||
- Show V_tip measurement clearly (voltmeter symbol or highlighted node) |
|||
- Annotate that C_sh increases with length |
|||
- Clean parallel R||C_mut representation |
|||
|
|||
--- |
|||
|
|||
## Circuit 5: Lumped Model Schematic |
|||
|
|||
**Filename:** `lessons/04-advanced-modeling/assets/lumped-model-schematic.png` |
|||
**Size:** 800 x 600 px |
|||
**Referenced in:** model-01 (Lumped Model) |
|||
|
|||
### Description |
|||
Clean, professional lumped spark model circuit. |
|||
|
|||
### Schematic (Same topology as Circuit 1, but cleaner) |
|||
|
|||
``` |
|||
Port (Topload connection) |
|||
| |
|||
+----[R]--------+ |
|||
| | |
|||
+----[C_mut]----+ |
|||
| |
|||
(Spark tip - internal node) |
|||
| |
|||
[C_sh] |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
**Component values:** |
|||
- R: "50 kΩ (typical)" |
|||
- C_mut: "8 pF (typical)" |
|||
- C_sh: "6 pF (typical)" |
|||
|
|||
**Annotations:** |
|||
- "Port" or "Topload Connection" at top |
|||
- "Internal Node" at spark tip |
|||
- Box or note: "Typical values at 200 kHz for 3-foot spark" |
|||
|
|||
### Layout Guidelines |
|||
- Very clean, professional appearance |
|||
- Grid-aligned components |
|||
- Perfect parallel alignment for R || C_mut |
|||
- Clear port indication (terminal symbols) |
|||
- Minimal, uncluttered |
|||
|
|||
--- |
|||
|
|||
## Circuit 6: Distributed Model Structure |
|||
|
|||
**Filename:** `lessons/04-advanced-modeling/assets/distributed-model-structure.png` |
|||
**Size:** 1200 x 600 px (horizontal) |
|||
**Referenced in:** model-03 (Distributed Model) |
|||
|
|||
### Description |
|||
Shows n-segment distributed model with proper transmission-line style layout. |
|||
|
|||
### Schematic |
|||
|
|||
**Horizontal cascade layout (recommended):** |
|||
|
|||
``` |
|||
Topload --[C_01]-- Node1 --[C_12]-- Node2 -- ... --[C_n-1,n]-- Node_n |
|||
| | | |
|||
[R_1] [R_2] [R_n] |
|||
| | | |
|||
[C_1,gnd] [C_2,gnd] [C_n,gnd] |
|||
| | | |
|||
GND GND GND |
|||
``` |
|||
|
|||
**Alternative vertical cascade** (if horizontal too wide): |
|||
``` |
|||
Topload |
|||
| |
|||
[C_01] |
|||
| |
|||
Node 1 --[R_1]-- |
|||
| | |
|||
[C_1,gnd] (parallel) |
|||
| |
|||
[C_12] |
|||
| |
|||
Node 2 --[R_2]-- |
|||
| | |
|||
[C_2,gnd] (parallel) |
|||
| |
|||
... |
|||
``` |
|||
|
|||
**Component labeling:** |
|||
- Show first 2 segments explicitly |
|||
- Use "..." for middle segments |
|||
- Show last segment (segment n) |
|||
- Label: "n = 5 to 20 segments (typically n = 10)" |
|||
|
|||
**Capacitance matrix note:** |
|||
- Annotation: "(n+1) × (n+1) capacitance matrix" |
|||
- "Extracted from FEMM electrostatic analysis" |
|||
|
|||
### Layout Guidelines |
|||
- Clear repeating pattern |
|||
- Ellipsis (...) to indicate continuation |
|||
- Symmetric, professional appearance |
|||
- Not too cluttered |
|||
|
|||
--- |
|||
|
|||
## Circuit 7: Tesla Coil System Overview |
|||
|
|||
**Filename:** `assets/shared/tesla-coil-system-overview.png` |
|||
**Size:** 1400 x 1000 px |
|||
**Referenced in:** Multiple lessons |
|||
|
|||
### Description |
|||
Complete DRSSTC system diagram showing all major components. |
|||
|
|||
### Schematic Components |
|||
|
|||
**Primary tank circuit:** |
|||
``` |
|||
[DC Bus] → [H-Bridge / IGBT switches] → [C_pri (MMC)] → [L_pri] → GND |
|||
↑ |
|||
[Gate Driver] |
|||
↑ |
|||
[Feedback/Control] |
|||
``` |
|||
|
|||
**Secondary resonator:** |
|||
``` |
|||
L_sec (large coil symbol, coupled to L_pri via k) |
|||
| |
|||
[C_topload] |
|||
| |
|||
[Spark gap or streamer symbol] |
|||
| |
|||
[Strike point / GND] |
|||
``` |
|||
|
|||
**Annotations:** |
|||
- Coupling coefficient: "k = 0.1 to 0.2" |
|||
- Primary frequency: "f_pri = f_resonant" |
|||
- Secondary resonance: "f_sec = 1/(2π√(L_sec × C_top))" |
|||
- Power flow arrows |
|||
- "DRSSTC" or "Double-Resonant Solid State Tesla Coil" title |
|||
|
|||
**Components to show:** |
|||
- DC power supply |
|||
- Full bridge (4 IGBTs/MOSFETs) or half bridge |
|||
- MMC (multiple capacitors in series-parallel) |
|||
- Primary coil (few turns, heavy wire) |
|||
- Secondary coil (many turns, fine wire) |
|||
- Topload (toroid or sphere symbol) |
|||
- Spark/streamer |
|||
- Feedback path (CT or antenna back to controller) |
|||
- Ground connections |
|||
|
|||
### Layout Guidelines |
|||
- Primary on left or bottom |
|||
- Secondary on right or top |
|||
- Clear separation of power vs signal paths |
|||
- Coupling indicated (dashed lines, double-headed arrow, or k annotation) |
|||
- Professional, complete system view |
|||
- Include legend if needed |
|||
|
|||
--- |
|||
|
|||
## General Guidelines for All Circuits |
|||
|
|||
### Style |
|||
- **Clean, professional appearance** |
|||
- Grid-aligned components |
|||
- Consistent component symbols (IEEE or European standard) |
|||
- Clear, readable labels (minimum 10pt font) |
|||
- No overlapping text or components |
|||
- White background |
|||
|
|||
### Components Symbols |
|||
- Resistor: Standard zigzag (IEEE) or rectangle (IEC) |
|||
- Capacitor: Two parallel lines |
|||
- Inductor: Coil/loops |
|||
- Ground: Standard ground symbol |
|||
- AC source: Sine wave in circle |
|||
- Voltage source: Circle with +/- or V label |
|||
|
|||
### Colors (if used) |
|||
- Use sparingly, only for clarity |
|||
- Current paths: different colors |
|||
- Otherwise: black on white for print compatibility |
|||
|
|||
### Verification |
|||
**CRITICAL:** Before finalizing any circuit: |
|||
1. Verify topology matches spark-physics.txt equations |
|||
2. Check that parallel vs series connections are correct |
|||
3. Ensure component values are realistic (refer to physical-bounds.md) |
|||
4. Review against worked examples for consistency |
|||
|
|||
--- |
|||
|
|||
## Priority Order |
|||
|
|||
**High Priority (needed for core lessons):** |
|||
1. Circuit 5: Lumped Model Schematic |
|||
2. Circuit 4: Capacitive Divider |
|||
3. Circuit 3: Thévenin Equivalent |
|||
|
|||
**Medium Priority:** |
|||
4. Circuit 1: Geometry to Circuit |
|||
5. Circuit 6: Distributed Model |
|||
|
|||
**Low Priority (nice-to-have):** |
|||
6. Circuit 2: Current Paths (complex, can use text description initially) |
|||
7. Circuit 7: System Overview (general reference, not lesson-critical) |
|||
|
|||
--- |
|||
|
|||
## Tools Recommendations |
|||
|
|||
**Easy (recommended for quick creation):** |
|||
- **CircuitLab** (web-based, clean output) |
|||
- **LTspice** (free, professional, can export schematics) |
|||
- **Falstad Circuit Simulator** (web-based, can screenshot) |
|||
|
|||
**Professional (for publication quality):** |
|||
- **KiCad Schematic Editor** (free, excellent output) |
|||
- **Inkscape** (manual drawing with circuit symbols) |
|||
- **Adobe Illustrator / Affinity Designer** (professional vector graphics) |
|||
|
|||
**Advanced (if familiar with LaTeX):** |
|||
- **CircuiTikZ** + LaTeX (publication-quality output) |
|||
|
|||
--- |
|||
|
|||
## Validation Checklist |
|||
|
|||
Before considering a circuit "done": |
|||
|
|||
- [ ] Topology verified against spark-physics.txt |
|||
- [ ] Component values realistic and labeled |
|||
- [ ] No overlapping elements |
|||
- [ ] Grid-aligned, professional appearance |
|||
- [ ] Clear node labels where needed |
|||
- [ ] Formula or key annotation included |
|||
- [ ] 150 DPI or vector format (scalable) |
|||
- [ ] White background, high contrast |
|||
- [ ] Filename matches specification |
|||
- [ ] Placed in correct assets directory |
|||
|
|||
--- |
|||
|
|||
## Notes |
|||
|
|||
- These specifications are based on analysis of spark-physics.txt |
|||
- Some topologies (especially parallel R||C_mut) are tricky - verify carefully |
|||
- When in doubt, consult reference physics document |
|||
- Can simplify complex parallel combinations as impedance blocks (Z = R||C) if clearer |
|||
- Professional quality > programmatic generation |
|||
|
|||
**Created:** 2025-10-10 |
|||
**Status:** Awaiting manual creation |
|||
**Current:** 0/7 circuits completed |
|||
@ -0,0 +1,282 @@ |
|||
# PyQt5 Application Development Progress |
|||
|
|||
**Project:** Tesla Coil Spark Physics Course - Interactive Desktop Application |
|||
**Started:** 2025-10-10 |
|||
**Current Status:** Phase 2 - Main Window Complete ✅ |
|||
|
|||
--- |
|||
|
|||
## Phase 1: Core Setup & Infrastructure (COMPLETED) |
|||
|
|||
### ✅ Completed Files |
|||
|
|||
**1. Environment & Launch** |
|||
- ✅ `run.bat` - Launch script with virtual environment management |
|||
- ✅ `requirements.txt` - PyQt5 and all dependencies |
|||
|
|||
**2. Database** |
|||
- ✅ `resources/database/schema.sql` - Complete SQLite schema (8 tables) |
|||
- ✅ `app/database.py` - Database manager with convenience methods |
|||
|
|||
**3. Configuration** |
|||
- ✅ `app/config.py` - All paths, constants, colors, settings |
|||
|
|||
**4. Course Model** |
|||
- ✅ `app/models/course_model.py` - Complete course structure loader |
|||
- Course, Part, Section, Lesson, LearningPath classes |
|||
- Fast lesson lookup by ID |
|||
- Navigation (next/prev lesson) |
|||
- Search by title/tag |
|||
- Learning path filtering |
|||
|
|||
**5. Application Entry** |
|||
- ✅ `app/main.py` - Basic application launcher |
|||
- ✅ `app/__init__.py` - Package initialization |
|||
- ✅ `app/models/__init__.py` - Models package |
|||
|
|||
### Database Schema |
|||
|
|||
**Tables Created:** |
|||
1. **users** - User profiles and preferences |
|||
2. **lesson_progress** - Lesson completion tracking |
|||
3. **exercise_attempts** - All exercise attempts |
|||
4. **exercise_completion** - Best scores per exercise |
|||
5. **study_sessions** - Daily session tracking |
|||
6. **achievements** - Badge system |
|||
7. **bookmarks** - Saved lessons/notes |
|||
8. **learning_path_progress** - Path-specific progress |
|||
|
|||
### Course Model Features |
|||
|
|||
**Loaded from course.json:** |
|||
- 4 Parts with 30 Lessons |
|||
- 18 Exercises (525 points) |
|||
- 4 Learning Paths |
|||
- Reference materials |
|||
- Worked examples |
|||
- Tags and metadata |
|||
|
|||
**Navigation Methods:** |
|||
- `get_lesson(id)` - Fast O(1) lookup |
|||
- `get_next_lesson(id)` - Sequential navigation |
|||
- `get_prev_lesson(id)` - Sequential navigation |
|||
- `get_lesson_by_index(i)` - Access by position (0-29) |
|||
- `search_lessons(query)` - Search by title |
|||
- `get_lessons_for_path(path_id)` - Filter by learning path |
|||
- `get_lessons_by_tag(tag)` - Filter by tag |
|||
|
|||
### Testing the Setup |
|||
|
|||
**To test current progress:** |
|||
```batch |
|||
cd C:\git\spark-lesson |
|||
run.bat |
|||
``` |
|||
|
|||
**Expected Behavior:** |
|||
1. Creates virtual environment (first run) |
|||
2. Installs PyQt5 and dependencies |
|||
3. Connects to SQLite database (~/.tesla_spark_course/progress.db) |
|||
4. Loads course.json (30 lessons, 4 parts) |
|||
5. Validates lesson files exist |
|||
6. Shows success dialog with course info |
|||
|
|||
**Current Output:** |
|||
``` |
|||
Tesla Coil Spark Physics Course v1.0.0 |
|||
[*] Initializing database... |
|||
[OK] Database ready: C:\Users\...\progress.db |
|||
[*] Loading course structure... |
|||
[OK] Course loaded: Tesla Coil Spark Physics: Complete Course |
|||
[*] Validating lesson files... |
|||
[OK] All lesson files found |
|||
[*] Application setup complete |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Phase 2: Main Window & UI (COMPLETED) |
|||
|
|||
### ✅ Completed Components |
|||
|
|||
**Priority 1: Main Window Layout** |
|||
- ✅ `app/views/main_window.py` - QMainWindow with 3-panel QSplitter |
|||
- ✅ `app/views/navigation_panel.py` - Left sidebar (QTreeWidget) |
|||
- ✅ `app/views/content_viewer.py` - Center (QWebEngineView) |
|||
- ✅ `app/views/progress_panel.py` - Right sidebar (QScrollArea) |
|||
- ✅ `app/views/__init__.py` - Views package |
|||
|
|||
**Priority 2: Navigation Tree** ✅ |
|||
- ✅ Tree structure showing 4 parts, 30 lessons |
|||
- ✅ Status icons (✓ ⊙ ○ 🔒) |
|||
- ✅ Learning path selector dropdown |
|||
- ✅ Search functionality |
|||
- ✅ Double-click to open lessons |
|||
- ✅ Continue Learning button |
|||
|
|||
**Priority 3: Content Viewer** ✅ |
|||
- ✅ Markdown rendering (python-markdown + pymdownx) |
|||
- ✅ MathJax equation rendering (CDN) |
|||
- ✅ Image loading from assets/ |
|||
- ✅ Custom tag parsing ({exercise:id}, {image:file}) |
|||
- ✅ Styled HTML output with syntax highlighting |
|||
- ⏳ Auto-scroll restoration (placeholder) |
|||
|
|||
**Priority 4: Progress Panel** ✅ |
|||
- ✅ Overall progress bar |
|||
- ✅ Part-by-part progress (4 parts) |
|||
- ✅ Current lesson info |
|||
- ✅ Quick stats (points, time, streak) |
|||
- ✅ Level system display |
|||
- ✅ Exercise completion tracking |
|||
|
|||
--- |
|||
|
|||
## Architecture Overview |
|||
|
|||
``` |
|||
spark-lessons/ |
|||
├── run.bat ✅ DONE |
|||
├── requirements.txt ✅ DONE |
|||
├── app/ |
|||
│ ├── __init__.py ✅ DONE |
|||
│ ├── main.py ✅ DONE |
|||
│ ├── config.py ✅ DONE |
|||
│ ├── database.py ✅ DONE |
|||
│ ├── models/ |
|||
│ │ ├── __init__.py ✅ DONE |
|||
│ │ ├── course_model.py ✅ DONE |
|||
│ │ ├── progress_model.py 🔄 TODO (optional) |
|||
│ │ └── user_model.py 🔄 TODO (optional) |
|||
│ ├── views/ ✅ DONE (all) |
|||
│ │ ├── __init__.py ✅ DONE |
|||
│ │ ├── main_window.py ✅ DONE |
|||
│ │ ├── navigation_panel.py ✅ DONE |
|||
│ │ ├── content_viewer.py ✅ DONE |
|||
│ │ └── progress_panel.py ✅ DONE |
|||
│ ├── controllers/ 🔄 TODO (optional) |
|||
│ │ ├── navigation_controller.py |
|||
│ │ └── progress_controller.py |
|||
│ └── utils/ 🔄 TODO (optional) |
|||
│ ├── markdown_renderer.py |
|||
│ └── icon_provider.py |
|||
└── resources/ |
|||
├── database/ |
|||
│ └── schema.sql ✅ DONE |
|||
├── styles/ 🔄 TODO |
|||
│ └── main.qss |
|||
└── icons/ 🔄 TODO |
|||
└── status/ |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Technical Stack |
|||
|
|||
**Core:** |
|||
- Python 3.8+ |
|||
- PyQt5 5.15.0+ |
|||
- SQLite3 |
|||
|
|||
**Content Rendering:** |
|||
- python-markdown 3.5.0+ |
|||
- pymdown-extensions 10.5.0+ (for equations, syntax highlighting) |
|||
- PyQt5-WebEngine (for rendering HTML/MathJax) |
|||
|
|||
**Data:** |
|||
- PyYAML 6.0.1+ (for exercises) |
|||
- JSON (for course structure) |
|||
|
|||
--- |
|||
|
|||
## Phase 3: Enhancements & Polish (NEXT) |
|||
|
|||
1. **Exercise System** (4-6 hours) |
|||
- Create exercise YAML files |
|||
- Exercise widget components |
|||
- Answer validation |
|||
- Hints system |
|||
- Score tracking |
|||
|
|||
2. **Keyboard Navigation** (2-3 hours) |
|||
- Next/prev lesson shortcuts |
|||
- Search hotkey |
|||
- Quick navigation |
|||
- Lesson completion shortcut |
|||
|
|||
3. **Additional Features** (3-4 hours) |
|||
- Bookmarking system |
|||
- Notes editor |
|||
- Export progress report |
|||
- Print lesson content |
|||
|
|||
4. **Polish & UX** (2-3 hours) |
|||
- Smooth scrolling |
|||
- Loading indicators |
|||
- Error handling improvements |
|||
- Tooltips and help text |
|||
|
|||
**Estimated Time:** 11-16 hours for Phase 3 |
|||
|
|||
--- |
|||
|
|||
## Known Issues / Notes |
|||
|
|||
1. **Lesson File Paths**: The course_model currently constructs paths by string manipulation. Works for current structure but may need refinement. |
|||
|
|||
2. **Exercise Files**: Exercise YAML files don't exist yet in the exercises/ directory. Need to create them or handle gracefully. |
|||
|
|||
3. **Images**: 22 images generated, 15 placeholders exist. Circuit diagrams (7) need manual creation. |
|||
|
|||
4. **MathJax CDN**: Currently points to CDN. For offline use, may want to bundle MathJax locally. |
|||
|
|||
5. **Single User**: Database designed for single-user desktop app. Multi-user would need authentication layer. |
|||
|
|||
--- |
|||
|
|||
## Success Metrics for Phase 2 |
|||
|
|||
- ✅ Main window opens without errors |
|||
- ✅ Navigation tree shows all 30 lessons with proper structure |
|||
- ✅ Click lesson → content loads and displays |
|||
- ✅ Markdown renders correctly with MathJax |
|||
- ⏳ Images display from assets/ (when files exist) |
|||
- ✅ Progress panel shows basic stats |
|||
- ✅ Learning path filter works |
|||
- ✅ Search functionality works |
|||
- ✅ Progress tracking in database |
|||
- ✅ Auto-save every 10 seconds |
|||
- ✅ Menu bar with File/View/Help |
|||
- ✅ 3-panel splitter layout |
|||
|
|||
**Phase 2 Complete!** All core UI components implemented and functional. |
|||
|
|||
--- |
|||
|
|||
**Last Updated:** 2025-10-10 |
|||
**Status:** Phase 2 complete - Full application UI working! |
|||
|
|||
## Testing the Application |
|||
|
|||
**To run the application:** |
|||
```batch |
|||
cd C:\git\spark-lesson\spark-lessons |
|||
run.bat |
|||
``` |
|||
|
|||
**Current Functionality:** |
|||
1. ✅ Browse all 30 lessons in tree structure |
|||
2. ✅ Double-click lessons to view content |
|||
3. ✅ Markdown content with equations renders properly |
|||
4. ✅ Progress tracking automatically saves |
|||
5. ✅ Filter by learning path |
|||
6. ✅ Search lessons by title |
|||
7. ✅ View overall and per-part progress |
|||
8. ✅ Points and level system |
|||
9. ✅ Study statistics (time, streak, exercises) |
|||
|
|||
**Known Limitations:** |
|||
- Exercise widgets not yet interactive (placeholders only) |
|||
- Scroll position restoration not implemented |
|||
- Some lesson images need to be created |
|||
- No keyboard shortcuts yet |
|||
@ -0,0 +1,465 @@ |
|||
# Tesla Coil Spark Physics: Interactive Course |
|||
|
|||
Complete educational course teaching the physics, mathematics, and simulation techniques for understanding and modeling Tesla coil sparks. From basic circuit theory to advanced distributed modeling with FEMM. |
|||
|
|||
**Version:** 1.0.0 |
|||
**Created:** 2025-10-10 |
|||
**Format:** Structured markdown lessons with YAML metadata |
|||
|
|||
--- |
|||
|
|||
## 📚 Course Overview |
|||
|
|||
### What You'll Learn |
|||
|
|||
This course provides comprehensive coverage of: |
|||
- Circuit fundamentals and admittance analysis |
|||
- Topological phase constraints and optimization |
|||
- Thévenin equivalent analysis and power calculations |
|||
- Spark growth physics and energy requirements |
|||
- Thermal dynamics and streamer-to-leader transitions |
|||
- FEMM-based capacitance extraction |
|||
- Lumped and distributed spark modeling |
|||
- Resistance optimization algorithms |
|||
|
|||
### Prerequisites |
|||
|
|||
**Required:** |
|||
- Basic AC circuit analysis (impedance, phasors) |
|||
- Complex number arithmetic |
|||
- Basic calculus (derivatives, integrals) |
|||
- Familiarity with SPICE circuit simulation |
|||
|
|||
**Recommended:** |
|||
- Electromagnetic field theory basics |
|||
- Experience with FEMM or similar FEA software |
|||
- Tesla coil operating experience |
|||
|
|||
### Course Statistics |
|||
|
|||
- **30 lessons** across 4 parts |
|||
- **18 exercises** (525 total points) |
|||
- **~14 hours** estimated completion time |
|||
- **5 comprehensive worked examples** |
|||
- **3 reference documents** (equations, bounds, glossary) |
|||
- **45+ images** needed (specifications provided) |
|||
|
|||
--- |
|||
|
|||
## 📂 Directory Structure |
|||
|
|||
``` |
|||
spark-lessons/ |
|||
├── course.json # Course structure and navigation |
|||
├── lessons/ # All lesson content |
|||
│ ├── 01-fundamentals/ # Part 1: Circuit Fundamentals (8 lessons) |
|||
│ ├── 02-optimization/ # Part 2: Optimization & Simulation (7 lessons) |
|||
│ ├── 03-spark-physics/ # Part 3: Spark Growth Physics (9 lessons) |
|||
│ └── 04-advanced-modeling/ # Part 4: Advanced Modeling (6 lessons) |
|||
├── exercises/ # Practice problems in YAML format |
|||
│ ├── 01-fundamentals/ # 10 exercises |
|||
│ ├── 02-optimization/ # 3 exercises |
|||
│ ├── 03-spark-physics/ # 4 exercises |
|||
│ └── 04-advanced-modeling/ # 1 exercise |
|||
├── worked-examples/ # Complete worked examples |
|||
│ ├── calculating-ropt.md |
|||
│ ├── thevenin-extraction.md |
|||
│ ├── spark-growth-timeline.md |
|||
│ ├── femm-lumped-extraction.md |
|||
│ └── distributed-model-complete.md |
|||
├── reference/ # Quick reference materials |
|||
│ ├── equation-sheet.md # All key formulas |
|||
│ ├── physical-bounds.md # Validation ranges |
|||
│ └── glossary.yaml # 64 technical terms |
|||
├── assets/ # Images and media |
|||
│ ├── shared/ # Shared images |
|||
│ └── IMAGE-REQUIREMENTS.md # Specifications for 45+ images |
|||
└── _originals/ # Backup of source files |
|||
├── spark-lesson.txt |
|||
└── spark-physics.txt |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 🎓 Course Structure |
|||
|
|||
### Part 1: Circuit Fundamentals (200 min) |
|||
**Lessons 01-08** | Beginner to Intermediate |
|||
|
|||
Learn the foundational circuit theory for spark modeling: |
|||
- AC circuit review and complex analysis |
|||
- Basic spark circuit model (C_mut, C_sh) |
|||
- Admittance analysis of parallel networks |
|||
- Phase angles and topological constraints |
|||
- Why -45° is often mathematically impossible |
|||
- Correct measurement port determination |
|||
|
|||
**Key Outcomes:** Understand spark impedance, phase constraints, and measurement techniques. |
|||
|
|||
--- |
|||
|
|||
### Part 2: Optimization & Simulation (280 min) |
|||
**Lessons 01-07** | Intermediate to Advanced |
|||
|
|||
Master power optimization and simulation methods: |
|||
- R_opt_power vs R_opt_phase (two critical resistances) |
|||
- The "hungry streamer" self-optimization principle |
|||
- Thévenin equivalent extraction and analysis |
|||
- Power calculations for any load impedance |
|||
- **Frequency tracking and loaded poles** (critical!) |
|||
- DRSSTC operating modes comparison |
|||
|
|||
**Key Outcomes:** Perform Thévenin analysis, optimize power transfer, understand frequency tracking importance. |
|||
|
|||
--- |
|||
|
|||
### Part 3: Spark Growth Physics (260 min) |
|||
**Lessons 01-09** | Intermediate to Advanced |
|||
|
|||
Understand the physics of spark formation and growth: |
|||
- Electric field thresholds (E_inception, E_propagation) |
|||
- Voltage-limited vs power-limited operation |
|||
- Energy per meter (ε) concept and calibration |
|||
- Thermal time constants and channel persistence |
|||
- Streamers vs leaders (transition mechanisms) |
|||
- Capacitive divider problem |
|||
- Freau's empirical scaling relationships |
|||
|
|||
**Key Outcomes:** Model spark growth, estimate energy requirements, understand operating mode differences. |
|||
|
|||
--- |
|||
|
|||
### Part 4: Advanced Modeling (285 min) |
|||
**Lessons 01-06** | Advanced |
|||
|
|||
Build sophisticated spark models using FEMM: |
|||
- Lumped model theory and workflow |
|||
- FEMM electrostatic extraction for lumped models |
|||
- Distributed nth-order model theory |
|||
- FEMM extraction for distributed models (capacitance matrices) |
|||
- Resistance optimization (iterative and circuit-determined methods) |
|||
- Complete modeling project with validation |
|||
|
|||
**Key Outcomes:** Extract capacitance matrices from FEMM, build lumped and distributed models, optimize resistance distribution. |
|||
|
|||
--- |
|||
|
|||
## 🎯 Learning Paths |
|||
|
|||
### Beginner Path (~8 hours) |
|||
Focus on fundamentals and basic simulation: |
|||
- Part 1: All lessons (fund-01 through fund-08) |
|||
- Part 2: Lessons 01, 03, 04 (skip hungry streamer details) |
|||
- Part 3: Lessons 01-03, 08 (basic physics and scaling) |
|||
- Part 4: Skip (or just lesson 01 for overview) |
|||
|
|||
### Complete Course (~14 hours) |
|||
Full curriculum for comprehensive understanding: |
|||
- All 30 lessons in sequence |
|||
- All 18 exercises |
|||
- All 5 worked examples |
|||
|
|||
### Simulation Focus (~10 hours) |
|||
For those primarily interested in modeling: |
|||
- Part 1: Lessons 01-03, 05, 08 |
|||
- Part 2: All lessons (especially 06!) |
|||
- Part 3: Lessons 01-04 |
|||
- Part 4: All lessons |
|||
|
|||
### Physics Focus (~9 hours) |
|||
For those primarily interested in spark physics: |
|||
- Part 1: Lessons 01-03 (circuit basics only) |
|||
- Part 2: Lessons 01-02 (optimization principles) |
|||
- Part 3: All lessons (complete physics coverage) |
|||
|
|||
--- |
|||
|
|||
## 📖 Lesson Format |
|||
|
|||
Each lesson file includes: |
|||
|
|||
```markdown |
|||
--- |
|||
id: fund-01 # Unique identifier |
|||
title: "Lesson Title" |
|||
section: "Fundamentals" |
|||
difficulty: "beginner" # beginner | intermediate | advanced |
|||
estimated_time: 20 # minutes |
|||
prerequisites: [] # List of required prior lessons |
|||
objectives: # Learning goals |
|||
- Objective 1 |
|||
- Objective 2 |
|||
tags: ["circuit-theory", ...] # Topic tags |
|||
--- |
|||
|
|||
# Lesson Title |
|||
|
|||
## Introduction |
|||
[Lesson content...] |
|||
|
|||
## Key Takeaways |
|||
- Bullet point 1 |
|||
- Bullet point 2 |
|||
|
|||
## Practice |
|||
{exercise:fund-ex-01} |
|||
|
|||
--- |
|||
**Next Lesson:** [Next Title](next-file.md) |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 📝 Exercise Format |
|||
|
|||
Practice problems are stored as YAML files: |
|||
|
|||
```yaml |
|||
id: fund-ex-01 |
|||
type: calculation # calculation | conceptual | design | multi-part |
|||
difficulty: easy # easy | medium | hard |
|||
points: 10 |
|||
related_lesson: fund-02 |
|||
question: | |
|||
[Full question text] |
|||
|
|||
hints: |
|||
- "Hint 1" |
|||
- "Hint 2" |
|||
|
|||
solution: |
|||
steps: |
|||
- "Step 1 description" |
|||
- "Step 2 description" |
|||
answer: "66.3" |
|||
unit: "kΩ" |
|||
tolerance: 2.0 # percentage |
|||
|
|||
explanation: | |
|||
[Why this matters] |
|||
|
|||
related_concepts: ["concept1", "concept2"] |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 🔧 Using This Course |
|||
|
|||
### For Self-Study |
|||
|
|||
1. Start with `course.json` to see overall structure |
|||
2. Follow your chosen learning path (see above) |
|||
3. Read lessons in order (prerequisites specified in frontmatter) |
|||
4. Complete exercises to reinforce learning |
|||
5. Refer to worked examples when stuck |
|||
6. Use reference materials (equation sheet, glossary) as needed |
|||
|
|||
### For Interactive App Development |
|||
|
|||
This course is **designed for PyQt application** development: |
|||
|
|||
1. **Parse `course.json`** for navigation structure |
|||
2. **Render markdown lessons** with proper equation support (MathJax) |
|||
3. **Load exercise YAML** for interactive practice |
|||
4. **Track progress** using lesson IDs |
|||
5. **Implement custom tags:** |
|||
- `{exercise:ex-id}` → Load and display exercise |
|||
- `{image:filename}` → Display image from assets/ |
|||
- `{interactive:type}` → Launch interactive element |
|||
|
|||
### For PDF Generation |
|||
|
|||
Compile to PDF using Pandoc: |
|||
|
|||
```bash |
|||
# All lessons |
|||
pandoc lessons/**/*.md -o tesla-coil-spark-course.pdf \ |
|||
--toc --number-sections --pdf-engine=xelatex |
|||
|
|||
# Single part |
|||
pandoc lessons/01-fundamentals/*.md -o part1-fundamentals.pdf \ |
|||
--toc --pdf-engine=xelatex |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 📊 Reference Materials |
|||
|
|||
### Equation Sheet |
|||
`reference/equation-sheet.md` |
|||
|
|||
45+ key formulas organized by category: |
|||
- Circuit analysis (Y, Z, φ) |
|||
- Optimization (R_opt_power, R_opt_phase) |
|||
- Thévenin equivalent |
|||
- Spark growth (ε, E_threshold, dL/dt) |
|||
- Thermal physics |
|||
- And more... |
|||
|
|||
### Physical Bounds |
|||
`reference/physical-bounds.md` |
|||
|
|||
Validation ranges and typical values: |
|||
- Resistance bounds (1 kΩ to 100 MΩ) |
|||
- Capacitance values (2 pF/foot rule) |
|||
- Field thresholds (0.4-3.0 MV/m) |
|||
- Energy per meter (5-100 J/m by mode) |
|||
- Phase angles (-55° to -75° typical) |
|||
- And more... |
|||
|
|||
### Glossary |
|||
`reference/glossary.yaml` |
|||
|
|||
64 technical terms with: |
|||
- Full definitions |
|||
- Units and typical ranges |
|||
- Related concepts |
|||
- Related lessons |
|||
|
|||
--- |
|||
|
|||
## 🖼️ Images |
|||
|
|||
**Status:** Specifications provided, images not yet created |
|||
|
|||
See `assets/IMAGE-REQUIREMENTS.md` for complete specifications of 45+ needed images: |
|||
- Circuit diagrams |
|||
- Field visualizations |
|||
- Graphs and charts |
|||
- FEMM screenshots |
|||
- High-speed photography |
|||
- Process flowcharts |
|||
|
|||
**Priority:** |
|||
- **High priority:** Images 1-6, 9-11, 16-19, 28-30 (core concepts) |
|||
- **Medium priority:** Images 7-8, 12-15, 20-27, 31-37 (supporting) |
|||
- **Low priority:** Images 38-45 (nice-to-have) |
|||
|
|||
--- |
|||
|
|||
## 🎯 Key Concepts |
|||
|
|||
### Circuit Theory |
|||
- **C_mut** (mutual capacitance): Coupling between spark and topload |
|||
- **C_sh** (shunt capacitance): Spark to ground, ~2 pF/foot |
|||
- **Admittance analysis**: Essential for parallel networks |
|||
- **Topological phase constraint**: φ_Z,min = -atan(2√[r(1+r)]) |
|||
|
|||
### Optimization |
|||
- **R_opt_power**: Maximizes power transfer = 1/(ω(C_mut+C_sh)) |
|||
- **R_opt_phase**: Minimizes phase magnitude |
|||
- **Hungry streamer**: Self-optimization toward R_opt_power |
|||
- **Thévenin equivalent**: Z_th, V_th extraction for any load analysis |
|||
|
|||
### Spark Physics |
|||
- **E_inception**: 2-3 MV/m (initial breakdown) |
|||
- **E_propagation**: 0.4-1.0 MV/m (sustained growth) |
|||
- **Energy per meter (ε)**: 5-15 J/m (QCW) to 30-100 J/m (burst) |
|||
- **Thermal time constant**: τ = d²/(4α) |
|||
- **Streamers**: Thin, fast, high-resistance, purple/blue |
|||
- **Leaders**: Thick, slower, low-resistance, white/orange |
|||
|
|||
### Advanced Modeling |
|||
- **Lumped model**: Single R, C_mut, C_sh (fast, <10 foot sparks) |
|||
- **Distributed model**: n segments (slow, accurate, any length) |
|||
- **Maxwell capacitance matrix**: Extract from FEMM electrostatics |
|||
- **Resistance optimization**: Iterative power maximization |
|||
|
|||
--- |
|||
|
|||
## ⚠️ Important Notes |
|||
|
|||
### Frequency Tracking |
|||
**Critical concept often overlooked!** |
|||
|
|||
When simulating with different R values, you MUST retune to the loaded pole frequency for each case. Comparing at fixed frequency measures detuning, not inherent matching quality. |
|||
|
|||
See: `lessons/02-optimization/06-frequency-tracking.md` |
|||
|
|||
### C_sh Validation |
|||
For distributed models, extracted C_sh may differ from the 2 pF/foot rule by factor 2-3. This is **normal** - the matrix method includes all segment couplings differently. Use FEMM values. |
|||
|
|||
### Sign Conventions |
|||
Maxwell capacitance matrices have **negative off-diagonal elements**. When extracting: |
|||
- C_mut = |C_12| (take absolute value!) |
|||
- C_sh = C_22 - |C_12| (subtract the absolute value) |
|||
|
|||
--- |
|||
|
|||
## 🚀 Next Steps |
|||
|
|||
### To Use This Course: |
|||
|
|||
1. **Review** `course.json` to understand structure |
|||
2. **Choose** a learning path (beginner/complete/simulation/physics) |
|||
3. **Start** with Part 1, Lesson 01 |
|||
4. **Complete** exercises as you go |
|||
5. **Reference** equation sheet and glossary as needed |
|||
|
|||
### To Build Interactive App: |
|||
|
|||
1. **Parse** course.json for navigation |
|||
2. **Implement** markdown renderer with MathJax |
|||
3. **Load** YAML exercises |
|||
4. **Track** user progress by lesson ID |
|||
5. **Add** interactive elements for {exercise:}, {interactive:} tags |
|||
|
|||
### To Create Images: |
|||
|
|||
1. **Review** `assets/IMAGE-REQUIREMENTS.md` |
|||
2. **Prioritize** high-priority images first |
|||
3. **Create** using tools specified (Inkscape, matplotlib, FEMM, etc.) |
|||
4. **Place** in appropriate assets/ subdirectories |
|||
5. **Update** lesson markdown with actual filenames |
|||
|
|||
--- |
|||
|
|||
## 📄 License |
|||
|
|||
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) |
|||
|
|||
You are free to: |
|||
- Share: Copy and redistribute |
|||
- Adapt: Remix, transform, and build upon |
|||
|
|||
Under these terms: |
|||
- Attribution: Give appropriate credit |
|||
- ShareAlike: Distribute under same license |
|||
|
|||
--- |
|||
|
|||
## 🙏 Acknowledgments |
|||
|
|||
Based on comprehensive Tesla coil spark modeling research from the community, including: |
|||
- Steve Conner's "hungry streamer" principle |
|||
- Empirical observations from builders worldwide |
|||
- FEMM electromagnetic analysis techniques |
|||
- Circuit-theoretical foundations |
|||
|
|||
--- |
|||
|
|||
## 📞 Support |
|||
|
|||
For questions or contributions: |
|||
- **Repository:** [GitHub link to be added] |
|||
- **Issues:** [GitHub issues link] |
|||
- **Community:** [Tesla coil community forum] |
|||
|
|||
--- |
|||
|
|||
## 📅 Version History |
|||
|
|||
### Version 1.0.0 (2025-10-10) |
|||
- Initial release |
|||
- 30 lessons across 4 parts |
|||
- 18 exercises in YAML format |
|||
- 5 comprehensive worked examples |
|||
- 3 reference documents |
|||
- Complete image specifications |
|||
- Course navigation structure |
|||
|
|||
--- |
|||
|
|||
**Ready to learn Tesla coil spark physics? Start with Part 1, Lesson 01!** |
|||
|
|||
`lessons/01-fundamentals/01-introduction.md` |
|||
7327
spark-lessons/_originals/spark-lesson.txt
File diff suppressed because it is too large
View File
@ -0,0 +1,856 @@ |
|||
# Tesla Coil Spark Modeling and Simulation Framework - Final Corrected Edition |
|||
|
|||
## Executive Summary |
|||
|
|||
This document presents a complete framework for modeling Tesla coil sparks using circuit analysis combined with electromagnetic field simulation (FEMM). The key insight is that spark plasma self-optimizes to maximize power transfer within circuit constraints, allowing accurate simulation without detailed plasma physics modeling. Two modeling approaches are presented: a simplified lumped model and a sophisticated nth-order distributed model. |
|||
|
|||
**Convention:** All phasor quantities use **peak values** (not RMS). Power formulas include the 0.5 factor: P = 0.5×Re{V×I*}. |
|||
|
|||
--- |
|||
|
|||
## Part 1: Fundamental Circuit Topology and Constraints |
|||
|
|||
### 1.1 Basic Spark Circuit Model |
|||
|
|||
Tesla coil sparks exhibit two capacitances revealed by FEMM electrostatic analysis: |
|||
- **Mutual capacitance (C_mut)**: Coupling between spark and topload |
|||
- **Shunt capacitance (C_sh)**: Spark-to-ground capacitance (~2 pF/foot empirically) |
|||
|
|||
The actual topology at the topload connection point is: |
|||
``` |
|||
Topload ---[C_mut || R]--- Spark tip |
|||
| | |
|||
| [C_sh] |
|||
| | |
|||
GND ---------------------- GND |
|||
``` |
|||
|
|||
### 1.2 Admittance Analysis |
|||
|
|||
At angular frequency ω, with G = 1/R, B₁ = ωC_mut (positive susceptance), B₂ = ωC_sh (positive susceptance): |
|||
|
|||
**Input admittance at topload (looking into spark):** |
|||
``` |
|||
Y = ((G + jB₁)·jB₂) / (G + j(B₁ + B₂)) |
|||
|
|||
Re{Y} = GB₂² / (G² + (B₁ + B₂)²) |
|||
|
|||
Im{Y} = B₂[G² + B₁(B₁ + B₂)] / (G² + (B₁ + B₂)²) |
|||
``` |
|||
|
|||
**Admittance phase angle:** |
|||
``` |
|||
θ_Y = atan(Im{Y}/Re{Y}) |
|||
``` |
|||
|
|||
**Impedance phase angle (what we typically measure):** |
|||
``` |
|||
φ_Z = -θ_Y = atan(-Im{Y}/Re{Y}) |
|||
``` |
|||
|
|||
**Important:** When discussing impedance phase, we reference φ_Z. The common "-45°" refers to impedance phase, not admittance phase. |
|||
|
|||
### 1.3 Fundamental Phase Constraint |
|||
|
|||
The circuit topology imposes a **minimum achievable impedance phase angle**: |
|||
|
|||
``` |
|||
φ_Z,min = -atan(2√(r(1+r))) |
|||
|
|||
where r = C_mut/C_sh |
|||
``` |
|||
|
|||
**Critical insight:** When r ≥ 0.207, achieving φ_Z = -45° (traditionally considered "matched") becomes **mathematically impossible** regardless of R value. This is a topological constraint, not a plasma limitation. |
|||
|
|||
For typical Tesla coil geometries: |
|||
- Large topload, short spark: r = 0.5 to 2.0 |
|||
- Resulting φ_Z,min ≈ -50° to -70° |
|||
|
|||
**Note:** Secondary losses add parallel conductance on the source side but don't change the spark's fundamental phase constraint. |
|||
|
|||
The commonly cited "R ≈ |X_c|" relationship emerges because power optimization within topological constraints naturally produces this approximate relationship, not because -45° is achievable. |
|||
|
|||
--- |
|||
|
|||
## Part 2: Two Critical Resistance Values |
|||
|
|||
### 2.1 R_opt_phase: Closest to Resistive |
|||
|
|||
Minimizes impedance phase magnitude to achieve φ_Z,min: |
|||
``` |
|||
R_opt_phase = 1 / (ω√(C_mut(C_mut + C_sh))) |
|||
``` |
|||
|
|||
This represents the "most resistive-looking" impedance the circuit can present. |
|||
|
|||
### 2.2 R_opt_power: Maximum Power Transfer |
|||
|
|||
Maximizes real power delivered to the load for fixed topload voltage: |
|||
``` |
|||
R_opt_power = 1 / (ω(C_mut + C_sh)) |
|||
``` |
|||
|
|||
**Numeric example:** At f = 200 kHz with C_mut + C_sh = 12 pF: |
|||
``` |
|||
R_opt_power = 1/(2π × 200×10³ × 12×10⁻¹²) ≈ 66 kΩ |
|||
``` |
|||
|
|||
**Key relationship:** |
|||
``` |
|||
R_opt_power < R_opt_phase always |
|||
|
|||
R_opt_power typically gives phase angles of -55° to -75° |
|||
``` |
|||
|
|||
### 2.3 The "Hungry Streamer" Principle |
|||
|
|||
**Steve Conner's insight:** Streamers actively optimize their impedance to maximize power extraction. The plasma adjusts its properties (temperature, ionization, diameter, conductivity) to extract maximum available power from the resonant circuit. |
|||
|
|||
**Physical mechanism:** |
|||
- More power → Joule heating (I²R) → increased temperature |
|||
- Higher temperature → thermal ionization → increased n_e |
|||
- Increased conductivity → R decreases |
|||
- Changed geometry/expansion → modified C_mut, C_sh |
|||
- Modified capacitances → new R_opt_power |
|||
- Plasma conductivity adjusts toward new R_opt_power |
|||
- **Stable equilibrium achieved when R_actual ≈ R_opt_power** |
|||
|
|||
**Constraints on optimization:** |
|||
- Insufficient source current/voltage (primary limited) |
|||
- Inception field not achieved (spark doesn't form) |
|||
- Physical conductivity limits (R_min, R_max) |
|||
- Thermal time constants (can't adjust faster than ~ms) |
|||
|
|||
When constraints prevent reaching R_opt_power, the spark operates sub-optimally or stalls. |
|||
|
|||
--- |
|||
|
|||
## Part 3: Impedance Measurement at Topload Port |
|||
|
|||
### 3.1 Why V_top/I_base is Wrong |
|||
|
|||
Measuring "impedance" as V_top/I_base is incorrect because I_base includes **all** displacement currents returning to ground: |
|||
- Every secondary section's capacitance to ground |
|||
- Strike ring coupling |
|||
- Primary-to-secondary capacitance |
|||
- **AND** the spark current |
|||
|
|||
This mixes the spark load with all parasitic return paths. |
|||
|
|||
### 3.2 Correct Measurement Port |
|||
|
|||
**The measurement port is topload-to-ground** where the spark physically connects. All impedance and power calculations reference this port. |
|||
|
|||
### 3.3 Thévenin Equivalent Extraction (Recommended) |
|||
|
|||
This method separates Tesla coil characterization from load analysis. |
|||
|
|||
**Step 1: Measure Z_th (output impedance with drive off)** |
|||
- Set primary drive source to AC 0V (short voltage source) |
|||
- Keep all tank components (MMC, L_primary, damping resistors) in circuit |
|||
- Apply 1V AC test source at topload-to-ground |
|||
- Measure current: I_test |
|||
- Calculate: **Z_th = 1V / I_test = R_th + jX_th** |
|||
|
|||
**Step 2: Measure V_th (open-circuit voltage with drive on)** |
|||
- Remove test source |
|||
- Turn primary drive source ON at operating frequency |
|||
- Remove spark load (open-circuit topload) |
|||
- Measure: **V_th = V(topload)** (complex magnitude and phase) |
|||
|
|||
**Step 3: Calculate power to any load** |
|||
For candidate load impedance Z_load: |
|||
``` |
|||
P_load = 0.5 × |V_th|² × Re{Z_load} / |Z_th + Z_load|² |
|||
``` |
|||
|
|||
**Theoretical maximum power (sanity check):** |
|||
If conjugate match were achievable (Z_load = Z_th*): |
|||
``` |
|||
P_max = 0.5 × |V_th|² / (4×Re{Z_th}) |
|||
``` |
|||
Actual spark power will be less than this due to topological constraints. |
|||
|
|||
**Advantages:** |
|||
- Characterize coil once, evaluate many loads instantly |
|||
- No re-simulation for different spark parameters |
|||
- Separates "coil behavior" (Z_th) from "drive conditions" (V_th) |
|||
|
|||
**Enhancement:** Measure Z_th(ω) and V_th(ω) over a frequency band (±10% of operating frequency) to account for frequency tracking as spark loads the system. |
|||
|
|||
### 3.4 Direct Power Measurement (Alternative) |
|||
|
|||
Keep full coupled model with spark load present: |
|||
- Drive primary at operating frequency and amplitude |
|||
- Run AC analysis |
|||
- Measure power in spark: P = 0.5 × Re{V(top) × conj(I(spark))} |
|||
- Step R to find maximum |
|||
- **Critical:** For each R, retune to loaded pole frequency (resonance shifts with loading) |
|||
|
|||
--- |
|||
|
|||
## Part 4: DRSSTC Operating Modes and Pole Frequencies |
|||
|
|||
### 4.1 Coupled System Poles |
|||
|
|||
A Tesla coil is a coupled resonant system. Even without a spark, coupling between primary and secondary creates two resonant modes (eigenfrequencies): |
|||
- **Lower pole:** Below the geometric mean |
|||
- **Upper pole:** Above the geometric mean |
|||
|
|||
The spark modifies both pole **frequency and damping**, not just frequency. |
|||
|
|||
### 4.2 Frequency Shift with Loading |
|||
|
|||
As spark grows: |
|||
- C_sh increases (~2 pF/foot) |
|||
- Both poles shift and become more damped |
|||
- Comparing different R values at fixed frequency measures detuning, not inherent matching quality |
|||
|
|||
**Best practice:** For each R value, sweep frequency to find loaded pole (max |V_top|), then measure power at that frequency. This gives true matched performance. |
|||
|
|||
--- |
|||
|
|||
## Part 5: Spark Growth Physics and Energy Requirements |
|||
|
|||
### 5.1 Voltage Limit: Field Threshold |
|||
|
|||
A spark continues to grow while the electric field at its tip exceeds a threshold. |
|||
|
|||
**Field requirements (at sea level, standard conditions):** |
|||
``` |
|||
E_inception ≈ 2-3 MV/m (initial breakdown from smooth topload) |
|||
E_propagation ≈ 0.4-1.0 MV/m (sustained leader growth) |
|||
E_tip = κ × E_average (tip enhancement factor κ ≈ 2-5) |
|||
``` |
|||
|
|||
**Maximum voltage-limited length:** |
|||
Solve: E_tip(V_top_peak, L) = E_propagation |
|||
|
|||
Use FEMM to compute E_tip for given V_top and length L. As spark grows, E_tip decreases due to: |
|||
- Increased distance from topload |
|||
- Geometric field dilution |
|||
- Capacitive voltage division (see below) |
|||
|
|||
**Note:** E_propagation varies with altitude and humidity by ±20-30%. |
|||
|
|||
### 5.2 Power Limit: Energy per Meter |
|||
|
|||
Growth consumes approximately constant energy per unit length ε [J/m]: |
|||
|
|||
**Growth rate equation:** |
|||
``` |
|||
dL/dt = P_stream / ε (when E_tip > E_propagation) |
|||
dL/dt ≈ 0 (when E_tip < E_propagation, stalled) |
|||
``` |
|||
|
|||
**Over time T to reach length L:** |
|||
``` |
|||
E_total ≈ ε × L |
|||
P_avg ≈ ε × L / T |
|||
``` |
|||
|
|||
### 5.3 Empirical Energy per Meter Values |
|||
|
|||
Requires calibration per coil. Starting values: |
|||
|
|||
**QCW-style growth:** |
|||
- ε ≈ 5-15 J/m |
|||
- Long ramp times (5-20 ms) |
|||
- Leader-dominated channels |
|||
- Energy efficiently extends length |
|||
|
|||
**High duty cycle DRSSTC:** |
|||
- ε ≈ 20-40 J/m |
|||
- Hybrid streamer/leader formation |
|||
- Some thermal accumulation |
|||
- Moderate efficiency |
|||
|
|||
**Hard-pulsed DRSSTC (burst mode):** |
|||
- ε ≈ 30-100+ J/m (single-shot) |
|||
- Short pulses, mostly streamers |
|||
- Much energy → brightening/branching |
|||
- Poor length efficiency |
|||
|
|||
**Advanced refinement:** ε decreases during heating due to thermal accumulation: |
|||
``` |
|||
ε(t) = ε₀ / (1 + α∫P_stream dt) |
|||
|
|||
where α has units [1/J] and ∫P_stream dt is accumulated energy |
|||
``` |
|||
|
|||
### 5.4 Thermal Memory and Operating Regimes |
|||
|
|||
**Pure thermal diffusion time constant:** |
|||
``` |
|||
τ_thermal = d² / (4α) |
|||
|
|||
where α = k/(ρ_air × c_p) ≈ 2×10⁻⁵ m²/s for air |
|||
|
|||
For thin streamers (d ~ 100 μm): τ ~ 0.1-0.2 ms |
|||
For thick leaders (d ~ 5 mm): τ ~ 300-600 ms |
|||
``` |
|||
|
|||
**Observed channel persistence is longer than pure thermal diffusion** due to: |
|||
- Buoyancy and convection maintaining hot gas column |
|||
- Ionization memory (recombination slower than thermal diffusion) |
|||
- Broadened effective channel diameter |
|||
|
|||
**Effective persistence times:** |
|||
- Thin streamers: ~1-5 ms (convection/ionization dominated) |
|||
- Thick leaders: seconds (buoyancy maintains hot column) |
|||
|
|||
**QCW advantage:** |
|||
- Ramps of 5-20 ms exploit ionization/convection persistence |
|||
- Channel stays hot throughout growth |
|||
- Continuous energy injection maintains E_tip |
|||
- Transitions streamers → leaders efficiently |
|||
|
|||
**Burst mode characteristics:** |
|||
- Widely spaced bursts: channel cools/deionizes between pulses |
|||
- Must re-ionize repeatedly |
|||
- High peak current → bright, thick but short |
|||
- Voltage collapse limits length before leader formation |
|||
|
|||
### 5.5 Streamers vs Leaders |
|||
|
|||
**Streamers:** |
|||
- Thin (10-100 μm), fast (~10⁶ m/s), low current (mA) |
|||
- Photoionization propagation |
|||
- High resistance, short-lived (μs thermal time) |
|||
- Purple/blue, highly branched |
|||
- High ε (inefficient) |
|||
|
|||
**Leaders:** |
|||
- Thick (mm-cm), slower (~10³ m/s), high current (A) |
|||
- Thermally ionized (5000-20000 K) |
|||
- Low resistance, persistent (seconds with convection) |
|||
- White/orange, straighter |
|||
- Low ε (efficient) |
|||
|
|||
**Transition sequence:** |
|||
1. High E-field creates streamers |
|||
2. Sufficient current → Joule heating |
|||
3. Heated channel → thermal ionization → leader |
|||
4. Leader grows from base |
|||
5. Leader tip launches new streamers |
|||
6. Fed streamers convert to leader |
|||
|
|||
### 5.6 The Capacitive Divider Problem |
|||
|
|||
As spark grows, voltage division limits tip voltage: |
|||
|
|||
``` |
|||
V_tip = V_topload × Z_mut/(Z_mut + Z_sh) |
|||
|
|||
where Z_mut = (1/jωC_mut) || R (complex) |
|||
Z_sh = 1/jωC_sh |
|||
``` |
|||
|
|||
**Open-circuit limit (R → ∞):** |
|||
``` |
|||
V_tip ≈ V_topload × C_mut/(C_mut + C_sh) |
|||
``` |
|||
|
|||
**With finite R ≈ R_opt_power:** V_tip is lower and complex. Since C_sh ∝ L: |
|||
- As spark grows, C_sh increases |
|||
- V_tip decreases even if V_topload maintained |
|||
- E_tip decreases |
|||
- Growth becomes harder |
|||
|
|||
This creates sub-linear scaling of length with energy. |
|||
|
|||
### 5.7 Freau's Empirical Relationship |
|||
|
|||
Community observations suggest: |
|||
``` |
|||
Single-shot burst: L ∝ √(bang energy) |
|||
Repetitive operation: L ∝ P_avg^(0.3 to 0.5) |
|||
``` |
|||
|
|||
**The single-shot √E relationship** applies when there's no thermal accumulation between events - each spark starts cold. |
|||
|
|||
**The repetitive power scaling** applies when thermal/ionization memory carries over between pulses. |
|||
|
|||
**Physical explanation for voltage-limited burst mode:** |
|||
``` |
|||
E_field ≈ V_top/L |
|||
Need: V_top > E_propagation × L |
|||
Power to maintain voltage: P ∝ V_top²/Z_spark |
|||
If Z_spark ∝ L, then: L ∝ √P |
|||
``` |
|||
|
|||
**QCW shows different scaling** (closer to linear, maybe L ∝ E^0.6-0.8) because: |
|||
- Active voltage ramping compensates for divider |
|||
- Leader formation more energy-efficient |
|||
- Still fights capacitive divider but with mitigation |
|||
|
|||
--- |
|||
|
|||
## Part 6: Practical Simulation Workflow |
|||
|
|||
### 6.1 Calibration Procedure |
|||
|
|||
**Required measurements (one-time per coil type):** |
|||
|
|||
1. **Energy per meter (ε):** |
|||
- Run coil with known drive, measure final spark length L |
|||
- From SPICE, compute E_delivered = ∫P_spark dt |
|||
- Calculate: ε = E_delivered/L |
|||
|
|||
2. **Field threshold (E_propagation):** |
|||
- Use FEMM to compute E_tip for measured V_top and final L |
|||
- E_propagation ≈ E_tip at stall point |
|||
- Typical: 0.4-1.0 MV/m |
|||
|
|||
### 6.2 Prediction Workflow |
|||
|
|||
**Step 1: Voltage capability check** |
|||
- Simulate to determine V_top(t) |
|||
- Use FEMM: E_tip(V_top, L_target) ≥ E_propagation? |
|||
- If not, target length is voltage-limited |
|||
|
|||
**Step 2: Power/energy requirement** |
|||
- Choose growth time T (e.g., 10 ms for QCW) |
|||
- Required: P_avg ≈ ε × L_target/T |
|||
- Required: E_total ≈ ε × L_target |
|||
|
|||
**Step 3: Verify in SPICE** |
|||
- Verify delivered P_stream meets requirement |
|||
- Check coil stays near loaded pole |
|||
|
|||
**Step 4: Power balance validation** |
|||
``` |
|||
P_primary_input = P_spark + P_secondary_losses + P_corona + P_radiation |
|||
|
|||
Check: P_spark / P_primary_input = expected efficiency |
|||
``` |
|||
|
|||
### 6.3 Growth Simulation (Advanced) |
|||
|
|||
For each time step dt: |
|||
``` |
|||
1. Check: E_tip(V_top(t), L) ≥ E_propagation? |
|||
2. If yes: dL/dt = P_stream(t)/ε(L,t) |
|||
3. If no: dL/dt = 0 (stalled) |
|||
4. Update: L = L + (dL/dt)×dt |
|||
5. Update spark model parameters for new L |
|||
6. Optionally track frequency to follow loaded pole |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Part 7: Lumped Spark Model Theory |
|||
|
|||
### 7.1 Model Structure |
|||
|
|||
Single lumped element: |
|||
``` |
|||
C_mut |
|||
Topload ----||---- Node_spark |
|||
| |
|||
[R] |
|||
| |
|||
[C_sh] |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
### 7.2 FEMM Extraction |
|||
|
|||
**Electrostatic simulation:** |
|||
- Topload at potential V |
|||
- Spark as cylindrical conductor |
|||
- Ground plane/boundaries |
|||
- Solve for 2×2 capacitance matrix |
|||
|
|||
**Extract values from Maxwell capacitance matrix:** |
|||
|
|||
The Maxwell matrix has C_ii > 0 (self-capacitance) and C_ij < 0 for i≠j (mutual capacitance, negative). |
|||
|
|||
``` |
|||
C_mut = -C[topload, spark] = |C_12| (take absolute value of negative off-diagonal) |
|||
C_sh = C[spark, spark] + C[spark, topload] = C_22 - |C_12| (total to ground) |
|||
``` |
|||
|
|||
**Sign convention note:** We're using the Maxwell capacitance matrix convention. If using partial capacitances, the extraction differs. |
|||
|
|||
**Typical validation:** C_sh ≈ 2 pF per foot confirms model accuracy. |
|||
|
|||
### 7.3 Determining R |
|||
|
|||
**Default (recommended):** |
|||
``` |
|||
R = R_opt_power = 1/(ω(C_mut + C_sh)) |
|||
``` |
|||
|
|||
**Physical bounds:** |
|||
``` |
|||
R_min ≈ 1 kΩ (very hot, thick leader plasma) |
|||
R_max ≈ 100 MΩ (cold, thin streamer plasma) |
|||
R_actual = clip(R_opt_power, R_min, R_max) |
|||
``` |
|||
|
|||
If clipping occurs, check if source can provide required power/voltage for this impedance. |
|||
|
|||
### 7.4 User Measurement Integration |
|||
|
|||
**Ringdown method (improved):** |
|||
|
|||
For a parallel RLC equivalent at the loaded resonance ω_L: |
|||
``` |
|||
Q_L = ω_L C_eq R_p = R_p/(ω_L L) |
|||
|
|||
Therefore: R_p = Q_L/(ω_L C_eq) or equivalently R_p = Q_L ω_L L |
|||
|
|||
And: G_total = 1/R_p = ω_L C_eq/Q_L or equivalently G_total = 1/(Q_L ω_L L) |
|||
``` |
|||
|
|||
**Measurement procedure:** |
|||
1. Measure unloaded: f₀, Q₀, C₀ (from geometry or separate measurement) |
|||
2. Measure with spark: f_L, Q_L |
|||
3. Calculate equivalent capacitance: C_eq = C₀(f₀/f_L)² |
|||
4. Calculate capacitance change: ΔC = C_eq - C₀ |
|||
5. Calculate total conductance: G_total = ω_L C_eq/Q_L (using either form above) |
|||
6. Calculate unloaded conductance: G_0 = ω₀ C₀/Q₀ |
|||
7. Spark admittance: Y_spark ≈ (G_total - G_0) + jω_L ΔC |
|||
|
|||
**Note:** This method is sensitive to primary coupling effects. The Thévenin port method (Section 3.3) is more robust. |
|||
|
|||
**Direct measurement:** |
|||
- Use E-field probe for V_top (isolated, calibrated) |
|||
- Use Rogowski/CT for I_spark return current (not I_base) |
|||
- Calculate: Y = I/V, extract R from circuit model |
|||
- Low-level option: VNA with capacitive pickup (no spark) to verify Z_th |
|||
|
|||
### 7.5 Limitations |
|||
|
|||
**Good for:** |
|||
- Impedance matching studies |
|||
- Fast simulation |
|||
- Coil design optimization |
|||
|
|||
**Cannot capture:** |
|||
- Current distribution along spark |
|||
- Tip vs. base differences |
|||
- Streamer/leader transitions |
|||
- Very long sparks (>10 feet) |
|||
|
|||
--- |
|||
|
|||
## Part 8: nth-Order Distributed Spark Model |
|||
|
|||
### 8.1 Model Structure |
|||
|
|||
Divide spark into n segments (typically n=10): |
|||
``` |
|||
Topload |
|||
| |
|||
[C_01][R_1][C_1,gnd] |
|||
| |
|||
[C_12][R_2][C_2,gnd] |
|||
| |
|||
... |
|||
| |
|||
[C_n-1,n][R_n][C_n,gnd] |
|||
``` |
|||
|
|||
Each segment: mutual capacitances, shunt capacitance, resistance. Optional: inductances if magnetic effects significant. |
|||
|
|||
### 8.2 FEMM Extraction |
|||
|
|||
**Electrostatic:** |
|||
- n cylindrical segments + topload + environment |
|||
- Solve for (n+1)×(n+1) capacitance matrix |
|||
- Includes all segment-to-segment and segment-to-environment couplings |
|||
|
|||
**SPICE implementation challenge:** |
|||
Maxwell C-matrix has negative off-diagonals (C_ij < 0 for i≠j). Direct implementation as literal capacitors problematic. Solutions: |
|||
1. **Partial-capacitance matrix:** Use capacitances to ground with all others grounded (positive definite) |
|||
2. **Controlled sources:** Implement via MNA: I_i = Σ_j C_ij dV_j/dt |
|||
3. **Nearest-neighbor approximation:** Approximate with local couplings, validate against full matrix |
|||
|
|||
**Passivity check:** Ensure C-matrix is symmetric positive semi-definite (SPD). If numerical noise creates slight non-passivity, add small diagonal term (+0.1 pF) or small series R for numerical stability. |
|||
|
|||
### 8.3 Resistance Optimization: Iterative Power Maximization |
|||
|
|||
**Initialization (tapered, recommended):** |
|||
``` |
|||
position = i/(n-1) # 0 at base, 1 at tip |
|||
R[i] = R_base + (R_tip - R_base)×position² |
|||
R_base = 10 kΩ, R_tip = 1 MΩ |
|||
``` |
|||
|
|||
**Iterative algorithm with damping:** |
|||
``` |
|||
Iterate until convergence: |
|||
For each segment i: |
|||
Sweep R[i] to find value maximizing P[i] |
|||
Apply damping: R_new[i] = α×R_optimal[i] + (1-α)×R_old[i] |
|||
where α ≈ 0.3-0.5 for stability |
|||
Clip to bounds: R[i] = clip(R_new[i], R_min[i], R_max[i]) |
|||
Check convergence: max relative change < 1% |
|||
|
|||
If poles shifted >5%, re-optimize at new frequency |
|||
``` |
|||
|
|||
**Physical bounds (position-dependent):** |
|||
``` |
|||
R_min[i] = 1 kΩ + (10 kΩ - 1 kΩ)×position |
|||
R_max[i] = 100 kΩ + (100 MΩ - 100 kΩ)×position |
|||
``` |
|||
|
|||
**Convergence behavior:** |
|||
- Well-coupled base segments: sharp power peak, fast convergence to low R |
|||
- Poorly-coupled tip segments: flat power curve, may not converge to unique value, stays at high R |
|||
- This naturally produces leader (base) + streamer (tip) distribution |
|||
|
|||
**Typical total resistance validation:** |
|||
|
|||
At 200 kHz for 1-3 meter sparks: |
|||
- **Streamer-dominated (burst mode):** Total R ≈ 50-300 kΩ |
|||
- **Leader-dominated (QCW):** Total R ≈ 5-50 kΩ (hot, thick channels) |
|||
- **Very low frequency (<100 kHz) or very long sparks:** Can approach 1-10 kΩ |
|||
|
|||
Calculate total: R_total = Σ R[i] |
|||
|
|||
Flag if significantly outside these ranges for your frequency and length. |
|||
|
|||
### 8.4 Circuit-Determined Resistance (Simplified Alternative) |
|||
|
|||
If plasma always adjusts to R_opt_power and C depends weakly on diameter (logarithmically): |
|||
|
|||
``` |
|||
For each segment: |
|||
C_total[i] = C_shunt[i] + sum(C_mutual[i,:]) |
|||
R[i] = 1/(ω × C_total[i]) |
|||
R[i] = clip(R[i], R_min[i], R_max[i]) |
|||
``` |
|||
|
|||
**Justification:** |
|||
- C ∝ 1/ln(h/d): weak diameter dependence |
|||
- R_opt ∝ 1/C: also weak diameter dependence |
|||
- 2× diameter → ~10-15% change in C, R |
|||
- Error acceptable given other uncertainties (FEMM ~10%, plasma variability ~50%) |
|||
|
|||
**When to use:** Standard cases within typical parameter ranges. |
|||
**When to iterate:** Edge cases, validation studies, highest accuracy needs. |
|||
|
|||
### 8.5 Diameter Considerations |
|||
|
|||
**Circuit-first view (recommended):** |
|||
1. Use nominal diameter in FEMM (e.g., 1 mm for burst, 3 mm for QCW) |
|||
2. Calculate C matrices |
|||
3. Calculate R_opt from C |
|||
4. Plasma adjusts properties to match R_opt |
|||
5. Diameter is dependent variable |
|||
|
|||
**Self-consistency check (optional):** |
|||
``` |
|||
d_nominal = 1e-3 m # 1 mm starting guess |
|||
C_mut, C_sh = FEMM(d_nominal) |
|||
R_opt = 1/(ω(C_mut + C_sh)) |
|||
|
|||
# Back-calculate implied diameter (typical partially ionized plasma): |
|||
ρ_typical = 10 Ω·m |
|||
L_segment = L_total/n_segments |
|||
d_implied = sqrt(4×ρ_typical×L_segment / (π×R_opt)) |
|||
|
|||
# If d_implied ≈ d_nominal (within factor of 2), self-consistent |
|||
# If not, iterate once with d = (d_nominal + d_implied)/2 |
|||
``` |
|||
|
|||
Because dependence is logarithmic, typically converges in 1-2 iterations if needed. |
|||
|
|||
--- |
|||
|
|||
## Part 9: Impedance Matching for Target Spark Length |
|||
|
|||
### 9.1 QCW Matching Strategy |
|||
|
|||
During QCW, spark grows from 0 to target length. Impedance changes dramatically. |
|||
|
|||
**Recommendation: Match at 50-70% of target length** |
|||
|
|||
**Reasoning:** |
|||
- Decent power transfer throughout ramp |
|||
- Spark grows fastest in middle phase |
|||
- Frequency tracking compensates for mismatch |
|||
|
|||
**Rule of thumb: Match at 60% for first design iteration** |
|||
|
|||
### 9.2 Optimization Approach |
|||
|
|||
Minimize total energy over growth: |
|||
``` |
|||
E_total = ∫₀ᵀ [ε × L(t)/η(t)] dt |
|||
η(t) = power transfer efficiency |
|||
``` |
|||
|
|||
**Procedure:** |
|||
1. Simulate growth with match points at 0%, 30%, 50%, 70%, 100% |
|||
2. Calculate E_total to reach target for each |
|||
3. Choose match point minimizing E_total |
|||
|
|||
### 9.3 Burst Mode Matching |
|||
|
|||
For non-ramping burst: |
|||
- Match to final spark length (100%) |
|||
- Coil rings up quickly |
|||
- Steady-state matching more important |
|||
|
|||
--- |
|||
|
|||
## Part 10: Implementation Summary |
|||
|
|||
### 10.1 Lumped Model Workflow |
|||
|
|||
1. FEMM electrostatic: topload + single spark cylinder |
|||
2. Extract C_mut = |C_12|, C_sh = C_22 - |C_12| from Maxwell matrix |
|||
3. Calculate R = 1/(ω(C_mut + C_sh)), clip to bounds |
|||
4. Build SPICE: (C_mut||R) in series with C_sh at topload port |
|||
5. AC analysis: Thévenin equivalent or direct power measurement |
|||
6. Use for matching optimization and performance prediction |
|||
|
|||
### 10.2 nth-Order Workflow |
|||
|
|||
1. FEMM: n segments + environment → full C-matrix |
|||
2. Optional: magnetic analysis → L-matrix |
|||
3. Initialize R with tapered profile |
|||
4. Choose approach: |
|||
- Full iterative optimization with damping (highest accuracy) |
|||
- Simplified R = 1/(ωC_total) (good for typical cases) |
|||
5. Export to SPICE with proper C-matrix handling (partial capacitances or controlled sources) |
|||
6. AC analysis or transient simulation |
|||
7. Validate: power balance, total R in expected range, R distribution physical |
|||
|
|||
### 10.3 Validation Strategy |
|||
|
|||
**Tests:** |
|||
- Lumped vs. 1-segment nth-order (should match exactly) |
|||
- Convergence: n=5 vs. n=10 vs. n=20 (diminishing changes) |
|||
- Measurements: compare impedance, power, length to real coil |
|||
- Self-consistency: R distribution shows base < tip, total R reasonable |
|||
|
|||
--- |
|||
|
|||
## Part 11: Key Equations Reference |
|||
|
|||
### Circuit Analysis |
|||
``` |
|||
R_opt_power = 1/(ω(C_mut + C_sh)) |
|||
Example: f=200 kHz, C_total=12 pF → R_opt ≈ 66 kΩ |
|||
|
|||
R_opt_phase = 1/(ω√(C_mut(C_mut + C_sh))) |
|||
|
|||
φ_Z,min = -atan(2√(r(1+r))), r = C_mut/C_sh |
|||
|
|||
Y = ((G+jB₁)·jB₂)/(G+j(B₁+B₂)) |
|||
where G = 1/R, B₁ = ωC_mut, B₂ = ωC_sh (positive susceptances) |
|||
|
|||
φ_Z = -atan(Im{Y}/Re{Y}) (impedance phase) |
|||
``` |
|||
|
|||
### Thévenin Equivalent |
|||
``` |
|||
Z_th = 1V/I_test (drive off, test source on) |
|||
V_th = V(topload) (drive on, no spark) |
|||
P_load = 0.5×|V_th|²×Re{Z_load}/|Z_th+Z_load|² |
|||
|
|||
Theoretical maximum (conjugate match): |
|||
P_max = 0.5×|V_th|²/(4×Re{Z_th}) |
|||
``` |
|||
|
|||
### Spark Growth |
|||
``` |
|||
E_inception ≈ 2-3 MV/m (initial breakdown) |
|||
E_propagation ≈ 0.4-1.0 MV/m (sustained growth) |
|||
|
|||
dL/dt = P_stream/ε (when E_tip > E_propagation) |
|||
|
|||
ε ≈ 5-15 J/m (QCW), 20-40 J/m (hybrid), 30-100 J/m (burst) |
|||
ε(t) = ε₀/(1 + α∫P dt), where [α] = 1/J |
|||
|
|||
V_tip ≈ V_topload×C_mut/(C_mut+C_sh) (open-circuit limit) |
|||
|
|||
τ_thermal = d²/(4α), α ≈ 2×10⁻⁵ m²/s for air |
|||
d=100 μm → τ~0.1 ms; d=5 mm → τ~300 ms |
|||
(Observed persistence longer due to convection/ionization) |
|||
``` |
|||
|
|||
### Physical Bounds |
|||
``` |
|||
R_min ≈ 1-10 kΩ (hot leader plasma, position-dependent) |
|||
R_max ≈ 100 kΩ - 100 MΩ (cold streamer, position-dependent) |
|||
|
|||
Typical total spark resistance at 200 kHz for 1-3 m: |
|||
- Burst/streamer: 50-300 kΩ |
|||
- QCW/leader: 5-50 kΩ |
|||
- Low frequency/very long: can approach 1-10 kΩ |
|||
|
|||
Typical impedance phase: -55° to -75° |
|||
``` |
|||
|
|||
### Ringdown Method |
|||
``` |
|||
At loaded resonance ω_L: |
|||
Q_L = ω_L C_eq R_p = R_p/(ω_L L) |
|||
|
|||
R_p = Q_L/(ω_L C_eq) = Q_L ω_L L |
|||
G_total = ω_L C_eq/Q_L = 1/(Q_L ω_L L) |
|||
|
|||
C_eq = C₀(f₀/f_L)² |
|||
Y_spark ≈ (G_total - G_0) + jω_L(C_eq - C_0) |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Part 12: Open Questions and Future Work |
|||
|
|||
### 12.1 Remaining Uncertainties |
|||
|
|||
- ε variability with current density, frequency, ambient conditions |
|||
- E_propagation dependence on geometry, humidity, altitude |
|||
- Full thermal evolution including convection and radiation |
|||
- Branching: power division among multiple channels |
|||
|
|||
### 12.2 Future Enhancements |
|||
|
|||
**Advanced physics:** |
|||
- Dynamic capacitance: d_eff(E) = d₀×(1 + β×ln(E/E_threshold)) |
|||
- Radial temperature profiles: hot core, cool edges |
|||
- Time-dependent ε with thermal memory |
|||
- Branching models: I_branch ∝ d_branch^1.5 |
|||
|
|||
**Simulation improvements:** |
|||
- Full transient with L(t) evolution |
|||
- 3D FEA for complex geometries |
|||
- Monte Carlo for stochastic breakout/branching |
|||
- Strike detection: R → few ohms when contact occurs |
|||
|
|||
**Validation needs:** |
|||
- Systematic measurements across coil types, frequencies, power levels |
|||
- High-speed photography for growth rate validation |
|||
- RF current distribution measurements at multiple points |
|||
- Database correlating spark parameters to operating conditions |
|||
|
|||
--- |
|||
|
|||
## Conclusion |
|||
|
|||
This framework provides practical, implementable Tesla coil spark modeling: |
|||
|
|||
**Core principles:** |
|||
1. Circuit topology imposes fundamental phase constraints |
|||
2. Plasma self-optimizes within constraints (hungry streamer) |
|||
3. R_opt_power maximizes power transfer |
|||
4. Capacitances depend weakly (logarithmically) on diameter |
|||
5. Circuit determines R; plasma adjusts to match |
|||
6. Growth requires E_tip > E_propagation AND sufficient energy (ε×L) |
|||
|
|||
**For basic use:** Lumped model with R = R_opt_power |
|||
|
|||
**For advanced use:** nth-order distributed model with iterative (highest accuracy) or simplified (good for typical cases) R optimization |
|||
|
|||
**Critical:** Calibrate ε and E_propagation from measurements, then predict new operating conditions with validated power balance. |
|||
|
|||
The framework balances theoretical rigor with practical implementation, acknowledging where empirical calibration fills gaps in complex plasma physics while maintaining solid circuit-theoretical foundations. |
|||
@ -0,0 +1,6 @@ |
|||
""" |
|||
Tesla Coil Spark Physics Course - PyQt5 Application |
|||
""" |
|||
|
|||
__version__ = '1.0.0' |
|||
__author__ = 'Tesla Coil Community' |
|||
@ -0,0 +1,259 @@ |
|||
""" |
|||
Configuration and constants for Tesla Coil Spark Course application |
|||
""" |
|||
|
|||
from pathlib import Path |
|||
|
|||
# ============================================================================ |
|||
# Paths |
|||
# ============================================================================ |
|||
|
|||
# Base directory (spark-lessons/) |
|||
BASE_DIR = Path(__file__).parent.parent |
|||
|
|||
# Content directories |
|||
LESSONS_DIR = BASE_DIR / 'lessons' |
|||
EXERCISES_DIR = BASE_DIR / 'exercises' |
|||
REFERENCE_DIR = BASE_DIR / 'reference' |
|||
WORKED_EXAMPLES_DIR = BASE_DIR / 'worked-examples' |
|||
ASSETS_DIR = BASE_DIR / 'assets' |
|||
|
|||
# Course structure |
|||
COURSE_JSON = BASE_DIR / 'course.json' |
|||
|
|||
# Resources |
|||
RESOURCES_DIR = BASE_DIR / 'resources' |
|||
STYLES_DIR = RESOURCES_DIR / 'styles' |
|||
ICONS_DIR = RESOURCES_DIR / 'icons' |
|||
DATABASE_DIR = RESOURCES_DIR / 'database' |
|||
SYMBOLS_JSON = RESOURCES_DIR / 'symbols_definitions.json' |
|||
IMAGES_DIR = ASSETS_DIR / 'images' |
|||
|
|||
# User data (created in user's home directory) |
|||
USER_HOME = Path.home() |
|||
USER_DATA_DIR = USER_HOME / '.tesla_spark_course' |
|||
USER_DATA_DIR.mkdir(exist_ok=True) |
|||
|
|||
DATABASE_PATH = USER_DATA_DIR / 'progress.db' |
|||
USER_NOTES_DIR = USER_DATA_DIR / 'notes' |
|||
USER_NOTES_DIR.mkdir(exist_ok=True) |
|||
|
|||
# ============================================================================ |
|||
# Application Constants |
|||
# ============================================================================ |
|||
|
|||
APP_NAME = "Tesla Coil Spark Physics Course" |
|||
APP_VERSION = "1.0.0" |
|||
APP_AUTHOR = "Tesla Coil Community" |
|||
|
|||
# ============================================================================ |
|||
# UI Constants |
|||
# ============================================================================ |
|||
|
|||
# Window dimensions |
|||
DEFAULT_WINDOW_WIDTH = 1400 |
|||
DEFAULT_WINDOW_HEIGHT = 900 |
|||
MIN_WINDOW_WIDTH = 1000 |
|||
MIN_WINDOW_HEIGHT = 600 |
|||
|
|||
# Panel sizes |
|||
NAVIGATION_PANEL_MIN_WIDTH = 250 |
|||
NAVIGATION_PANEL_DEFAULT_WIDTH = 300 |
|||
PROGRESS_PANEL_MIN_WIDTH = 280 |
|||
PROGRESS_PANEL_DEFAULT_WIDTH = 320 |
|||
CONTENT_PANEL_MIN_WIDTH = 600 |
|||
|
|||
# Font sizes |
|||
FONT_SIZE_SMALL = 10 |
|||
FONT_SIZE_NORMAL = 12 |
|||
FONT_SIZE_LARGE = 14 |
|||
FONT_SIZE_TITLE = 16 |
|||
|
|||
# Colors (light theme) |
|||
COLOR_PRIMARY = "#3498db" # Blue |
|||
COLOR_SECONDARY = "#9b59b6" # Purple |
|||
COLOR_SUCCESS = "#27ae60" # Green |
|||
COLOR_WARNING = "#f39c12" # Orange |
|||
COLOR_DANGER = "#e74c3c" # Red |
|||
COLOR_ERROR = "#e74c3c" # Red (alias) |
|||
COLOR_INFO = "#2ecc71" # Light green |
|||
COLOR_BACKGROUND = "#ffffff" # White |
|||
COLOR_PANEL_BACKGROUND = "#f8f9fa" # Light gray |
|||
COLOR_TEXT = "#2c3e50" # Dark blue-gray |
|||
COLOR_TEXT_SECONDARY = "#7f8c8d" # Gray |
|||
COLOR_BORDER = "#dee2e6" # Light border |
|||
COLOR_HIGHLIGHT = "#e3f2fd" # Light blue |
|||
|
|||
# Status colors |
|||
COLOR_STATUS_COMPLETE = "#27ae60" # Green |
|||
COLOR_STATUS_IN_PROGRESS = "#f39c12" # Orange |
|||
COLOR_STATUS_NOT_STARTED = "#95a5a6" # Gray |
|||
COLOR_STATUS_LOCKED = "#bdc3c7" # Light gray |
|||
|
|||
# Progress bar colors |
|||
COLOR_PROGRESS_BG = "#ecf0f1" |
|||
COLOR_PROGRESS_FG = "#3498db" |
|||
COLOR_PROGRESS_COMPLETE = "#2ecc71" |
|||
|
|||
# ============================================================================ |
|||
# Course Constants |
|||
# ============================================================================ |
|||
|
|||
TOTAL_LESSONS = 30 |
|||
TOTAL_EXERCISES = 18 |
|||
TOTAL_POINTS = 525 |
|||
TOTAL_PARTS = 4 |
|||
|
|||
# Difficulty levels |
|||
DIFFICULTY_BEGINNER = "beginner" |
|||
DIFFICULTY_INTERMEDIATE = "intermediate" |
|||
DIFFICULTY_ADVANCED = "advanced" |
|||
|
|||
DIFFICULTY_COLORS = { |
|||
DIFFICULTY_BEGINNER: "#2ecc71", # Green |
|||
DIFFICULTY_INTERMEDIATE: "#f39c12", # Orange |
|||
DIFFICULTY_ADVANCED: "#e74c3c" # Red |
|||
} |
|||
|
|||
# Lesson status |
|||
STATUS_NOT_STARTED = "not_started" |
|||
STATUS_IN_PROGRESS = "in_progress" |
|||
STATUS_COMPLETED = "completed" |
|||
|
|||
# Status icons (Unicode) |
|||
ICON_COMPLETE = "✓" |
|||
ICON_IN_PROGRESS = "⊙" |
|||
ICON_NOT_STARTED = "○" |
|||
ICON_LOCKED = "🔒" |
|||
ICON_EXERCISE = "⚡" |
|||
ICON_BOOKMARK = "⭐" |
|||
|
|||
# ============================================================================ |
|||
# Progress & Gamification Constants |
|||
# ============================================================================ |
|||
|
|||
# Level thresholds (points) |
|||
LEVELS = [ |
|||
(0, "Novice", "Circuit Curious"), |
|||
(100, "Learner", "Circuit Explorer"), |
|||
(250, "Practitioner", "Circuit Master"), |
|||
(400, "Expert", "Tesla Scholar"), |
|||
] |
|||
|
|||
# Achievement definitions |
|||
ACHIEVEMENTS = { |
|||
'quick_learner': { |
|||
'name': 'Quick Learner', |
|||
'description': 'Complete first lesson in under 15 minutes', |
|||
'icon': '🏆', |
|||
'condition': 'first_lesson_under_15min' |
|||
}, |
|||
'accuracy_master': { |
|||
'name': 'Accuracy Master', |
|||
'description': 'Maintain 85%+ average on exercises', |
|||
'icon': '🎯', |
|||
'condition': 'exercise_avg_85_percent' |
|||
}, |
|||
'bookworm': { |
|||
'name': 'Bookworm', |
|||
'description': 'Complete Part 1 in under 3 hours', |
|||
'icon': '📚', |
|||
'condition': 'part1_under_3hours' |
|||
}, |
|||
'streak_master': { |
|||
'name': 'Streak Master', |
|||
'description': 'Study for 7 consecutive days', |
|||
'icon': '🔥', |
|||
'condition': 'streak_7_days' |
|||
}, |
|||
'lab_rat': { |
|||
'name': 'Lab Rat', |
|||
'description': 'Complete 5 exercises with perfect scores', |
|||
'icon': '🧪', |
|||
'condition': 'perfect_5_exercises' |
|||
}, |
|||
'insight': { |
|||
'name': 'Insight', |
|||
'description': 'Average fewer than 2 hints per exercise', |
|||
'icon': '💡', |
|||
'condition': 'avg_hints_under_2' |
|||
}, |
|||
'power_user': { |
|||
'name': 'Power User', |
|||
'description': 'Use 10+ keyboard shortcuts', |
|||
'icon': '⚡', |
|||
'condition': 'shortcuts_10_plus' |
|||
}, |
|||
'graduate': { |
|||
'name': 'Graduate', |
|||
'description': 'Complete all 30 lessons', |
|||
'icon': '🎓', |
|||
'condition': 'all_lessons_complete' |
|||
}, |
|||
} |
|||
|
|||
# ============================================================================ |
|||
# Auto-save Settings |
|||
# ============================================================================ |
|||
|
|||
AUTO_SAVE_INTERVAL = 10000 # milliseconds (10 seconds) |
|||
PROGRESS_UPDATE_INTERVAL = 1000 # milliseconds (1 second for time tracking) |
|||
|
|||
# ============================================================================ |
|||
# Markdown Rendering |
|||
# ============================================================================ |
|||
|
|||
# MathJax CDN |
|||
MATHJAX_CDN = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" |
|||
|
|||
# Markdown extensions |
|||
MARKDOWN_EXTENSIONS = [ |
|||
'extra', |
|||
'codehilite', |
|||
'tables', |
|||
'toc', |
|||
'pymdownx.arithmatex', |
|||
'pymdownx.superfences', |
|||
'pymdownx.highlight', |
|||
] |
|||
|
|||
# ============================================================================ |
|||
# Keyboard Shortcuts |
|||
# ============================================================================ |
|||
|
|||
SHORTCUTS = { |
|||
'next_lesson': 'Ctrl+Right', |
|||
'prev_lesson': 'Ctrl+Left', |
|||
'first_lesson': 'Ctrl+Home', |
|||
'last_lesson': 'Ctrl+End', |
|||
'search': 'Ctrl+F', |
|||
'bookmark': 'Ctrl+B', |
|||
'mark_complete': 'Ctrl+M', |
|||
'exercises': 'Ctrl+E', |
|||
'references': 'Ctrl+R', |
|||
'notes': 'Ctrl+N', |
|||
'dashboard': 'Ctrl+P', |
|||
'fullscreen': 'F11', |
|||
'quit': 'Ctrl+Q', |
|||
} |
|||
|
|||
# ============================================================================ |
|||
# Default User Settings |
|||
# ============================================================================ |
|||
|
|||
DEFAULT_SETTINGS = { |
|||
'theme': 'light', |
|||
'font_size': FONT_SIZE_NORMAL, |
|||
'auto_save': True, |
|||
'show_hints': True, |
|||
'learning_path': 'intermediate', |
|||
'auto_mark_complete': True, # Auto-mark at 95% scroll |
|||
'sound_effects': False, |
|||
} |
|||
|
|||
# ============================================================================ |
|||
# Debug Mode |
|||
# ============================================================================ |
|||
|
|||
DEBUG = True # Set to False for production |
|||
VERBOSE_LOGGING = DEBUG |
|||
@ -0,0 +1,332 @@ |
|||
""" |
|||
Database connection manager for Tesla Coil Spark Course |
|||
Handles SQLite connections, schema creation, and queries |
|||
""" |
|||
|
|||
import sqlite3 |
|||
import os |
|||
from pathlib import Path |
|||
from datetime import datetime |
|||
|
|||
|
|||
class Database: |
|||
"""SQLite database manager""" |
|||
|
|||
def __init__(self, db_path=None): |
|||
""" |
|||
Initialize database connection |
|||
|
|||
Args: |
|||
db_path: Path to SQLite database file. If None, uses default location. |
|||
""" |
|||
if db_path is None: |
|||
# Default location: user's home directory |
|||
home = Path.home() |
|||
data_dir = home / '.tesla_spark_course' |
|||
data_dir.mkdir(exist_ok=True) |
|||
db_path = data_dir / 'progress.db' |
|||
|
|||
self.db_path = db_path |
|||
self.connection = None |
|||
self._connect() |
|||
self._initialize_schema() |
|||
|
|||
def _connect(self): |
|||
"""Establish database connection""" |
|||
try: |
|||
self.connection = sqlite3.connect( |
|||
self.db_path, |
|||
check_same_thread=False # Allow usage from multiple threads |
|||
) |
|||
self.connection.row_factory = sqlite3.Row # Access columns by name |
|||
print(f"[DB] Connected to database: {self.db_path}") |
|||
except sqlite3.Error as e: |
|||
print(f"[DB ERROR] Failed to connect: {e}") |
|||
raise |
|||
|
|||
def _initialize_schema(self): |
|||
"""Create tables if they don't exist""" |
|||
schema_file = Path(__file__).parent.parent / 'resources' / 'database' / 'schema.sql' |
|||
|
|||
if not schema_file.exists(): |
|||
print(f"[DB WARNING] Schema file not found: {schema_file}") |
|||
return |
|||
|
|||
try: |
|||
with open(schema_file, 'r') as f: |
|||
schema_sql = f.read() |
|||
|
|||
cursor = self.connection.cursor() |
|||
cursor.executescript(schema_sql) |
|||
self.connection.commit() |
|||
print("[DB] Schema initialized successfully") |
|||
except sqlite3.Error as e: |
|||
print(f"[DB ERROR] Failed to initialize schema: {e}") |
|||
raise |
|||
|
|||
def execute(self, query, params=None): |
|||
""" |
|||
Execute a query and return cursor |
|||
|
|||
Args: |
|||
query: SQL query string |
|||
params: Query parameters (tuple or dict) |
|||
|
|||
Returns: |
|||
sqlite3.Cursor |
|||
""" |
|||
try: |
|||
cursor = self.connection.cursor() |
|||
if params: |
|||
cursor.execute(query, params) |
|||
else: |
|||
cursor.execute(query) |
|||
return cursor |
|||
except sqlite3.Error as e: |
|||
print(f"[DB ERROR] Query failed: {e}") |
|||
print(f"[DB ERROR] Query: {query}") |
|||
raise |
|||
|
|||
def fetch_one(self, query, params=None): |
|||
"""Execute query and fetch one result""" |
|||
cursor = self.execute(query, params) |
|||
return cursor.fetchone() |
|||
|
|||
def fetch_all(self, query, params=None): |
|||
"""Execute query and fetch all results""" |
|||
cursor = self.execute(query, params) |
|||
return cursor.fetchall() |
|||
|
|||
def commit(self): |
|||
"""Commit transaction""" |
|||
self.connection.commit() |
|||
|
|||
def close(self): |
|||
"""Close database connection""" |
|||
if self.connection: |
|||
self.connection.close() |
|||
print("[DB] Connection closed") |
|||
|
|||
# ========================================================================= |
|||
# Convenience methods for common operations |
|||
# ========================================================================= |
|||
|
|||
def get_user(self, user_id=1): |
|||
"""Get user by ID (default user is ID 1)""" |
|||
return self.fetch_one( |
|||
"SELECT * FROM users WHERE user_id = ?", |
|||
(user_id,) |
|||
) |
|||
|
|||
def get_lesson_progress(self, user_id, lesson_id): |
|||
"""Get progress for a specific lesson""" |
|||
return self.fetch_one( |
|||
"SELECT * FROM lesson_progress WHERE user_id = ? AND lesson_id = ?", |
|||
(user_id, lesson_id) |
|||
) |
|||
|
|||
def update_lesson_progress(self, user_id, lesson_id, **kwargs): |
|||
""" |
|||
Update lesson progress |
|||
|
|||
Args: |
|||
user_id: User ID |
|||
lesson_id: Lesson ID |
|||
**kwargs: Fields to update (status, scroll_position, time_spent, etc.) |
|||
""" |
|||
# First, ensure record exists |
|||
existing = self.get_lesson_progress(user_id, lesson_id) |
|||
|
|||
if existing is None: |
|||
# Create new record |
|||
self.execute( |
|||
"""INSERT INTO lesson_progress |
|||
(user_id, lesson_id, first_opened, last_accessed) |
|||
VALUES (?, ?, ?, ?)""", |
|||
(user_id, lesson_id, datetime.now(), datetime.now()) |
|||
) |
|||
|
|||
# Update fields |
|||
if kwargs: |
|||
# Add last_accessed to every update |
|||
kwargs['last_accessed'] = datetime.now() |
|||
|
|||
set_clause = ', '.join([f"{key} = ?" for key in kwargs.keys()]) |
|||
values = list(kwargs.values()) + [user_id, lesson_id] |
|||
|
|||
query = f"""UPDATE lesson_progress |
|||
SET {set_clause} |
|||
WHERE user_id = ? AND lesson_id = ?""" |
|||
self.execute(query, values) |
|||
self.commit() |
|||
|
|||
def mark_lesson_complete(self, user_id, lesson_id): |
|||
"""Mark a lesson as completed""" |
|||
self.update_lesson_progress( |
|||
user_id, lesson_id, |
|||
status='completed', |
|||
completion_percentage=100, |
|||
completed_at=datetime.now() |
|||
) |
|||
|
|||
def get_all_lesson_progress(self, user_id): |
|||
"""Get progress for all lessons""" |
|||
return self.fetch_all( |
|||
"SELECT * FROM lesson_progress WHERE user_id = ?", |
|||
(user_id,) |
|||
) |
|||
|
|||
def record_exercise_attempt(self, user_id, exercise_id, user_answer, |
|||
is_correct, points_earned, points_possible, |
|||
hints_used=0, time_taken=0, lesson_id=None): |
|||
"""Record an exercise attempt""" |
|||
# Get attempt number |
|||
cursor = self.execute( |
|||
"""SELECT COALESCE(MAX(attempt_number), 0) + 1 as next_attempt |
|||
FROM exercise_attempts |
|||
WHERE user_id = ? AND exercise_id = ?""", |
|||
(user_id, exercise_id) |
|||
) |
|||
attempt_number = cursor.fetchone()['next_attempt'] |
|||
|
|||
# Insert attempt |
|||
self.execute( |
|||
"""INSERT INTO exercise_attempts |
|||
(user_id, exercise_id, lesson_id, attempt_number, user_answer, |
|||
is_correct, points_earned, points_possible, hints_used, time_taken) |
|||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", |
|||
(user_id, exercise_id, lesson_id, attempt_number, user_answer, |
|||
is_correct, points_earned, points_possible, hints_used, time_taken) |
|||
) |
|||
|
|||
# Update or create completion record |
|||
existing = self.fetch_one( |
|||
"SELECT * FROM exercise_completion WHERE user_id = ? AND exercise_id = ?", |
|||
(user_id, exercise_id) |
|||
) |
|||
|
|||
if existing is None: |
|||
# First attempt |
|||
self.execute( |
|||
"""INSERT INTO exercise_completion |
|||
(user_id, exercise_id, best_score, max_possible, total_attempts, |
|||
first_attempted, first_completed, last_attempted) |
|||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", |
|||
(user_id, exercise_id, points_earned, points_possible, 1, |
|||
datetime.now(), datetime.now() if is_correct else None, datetime.now()) |
|||
) |
|||
else: |
|||
# Update existing |
|||
best_score = max(existing['best_score'], points_earned) |
|||
first_completed = existing['first_completed'] |
|||
if is_correct and first_completed is None: |
|||
first_completed = datetime.now() |
|||
|
|||
self.execute( |
|||
"""UPDATE exercise_completion |
|||
SET best_score = ?, total_attempts = total_attempts + 1, |
|||
first_completed = ?, last_attempted = ? |
|||
WHERE user_id = ? AND exercise_id = ?""", |
|||
(best_score, first_completed, datetime.now(), user_id, exercise_id) |
|||
) |
|||
|
|||
self.commit() |
|||
|
|||
def get_overall_progress(self, user_id): |
|||
"""Get overall progress statistics""" |
|||
# Total points earned |
|||
points_result = self.fetch_one( |
|||
"""SELECT SUM(best_score) as total_points |
|||
FROM exercise_completion |
|||
WHERE user_id = ?""", |
|||
(user_id,) |
|||
) |
|||
total_points = points_result['total_points'] or 0 |
|||
|
|||
# Lessons completed |
|||
lessons_result = self.fetch_one( |
|||
"""SELECT COUNT(*) as completed |
|||
FROM lesson_progress |
|||
WHERE user_id = ? AND status = 'completed'""", |
|||
(user_id,) |
|||
) |
|||
lessons_completed = lessons_result['completed'] or 0 |
|||
|
|||
# Total study time |
|||
time_result = self.fetch_one( |
|||
"""SELECT SUM(time_spent) as total_time |
|||
FROM lesson_progress |
|||
WHERE user_id = ?""", |
|||
(user_id,) |
|||
) |
|||
total_time = time_result['total_time'] or 0 |
|||
|
|||
return { |
|||
'total_points': total_points, |
|||
'lessons_completed': lessons_completed, |
|||
'total_time': total_time, |
|||
'percentage': (lessons_completed / 30.0) * 100 # 30 total lessons |
|||
} |
|||
|
|||
def update_study_session(self, user_id): |
|||
"""Update or create today's study session""" |
|||
today = datetime.now().date() |
|||
|
|||
existing = self.fetch_one( |
|||
"SELECT * FROM study_sessions WHERE user_id = ? AND session_date = ?", |
|||
(user_id, today) |
|||
) |
|||
|
|||
if existing is None: |
|||
self.execute( |
|||
"""INSERT INTO study_sessions |
|||
(user_id, session_date, session_start) |
|||
VALUES (?, ?, ?)""", |
|||
(user_id, today, datetime.now()) |
|||
) |
|||
else: |
|||
self.execute( |
|||
"""UPDATE study_sessions |
|||
SET session_end = ? |
|||
WHERE user_id = ? AND session_date = ?""", |
|||
(datetime.now(), user_id, today) |
|||
) |
|||
|
|||
self.commit() |
|||
|
|||
def get_study_streak(self, user_id): |
|||
"""Calculate current study streak (consecutive days)""" |
|||
sessions = self.fetch_all( |
|||
"""SELECT session_date FROM study_sessions |
|||
WHERE user_id = ? |
|||
ORDER BY session_date DESC""", |
|||
(user_id,) |
|||
) |
|||
|
|||
if not sessions: |
|||
return 0 |
|||
|
|||
from datetime import timedelta |
|||
streak = 0 |
|||
expected_date = datetime.now().date() |
|||
|
|||
for session in sessions: |
|||
session_date = datetime.strptime(session['session_date'], '%Y-%m-%d').date() |
|||
if session_date == expected_date: |
|||
streak += 1 |
|||
expected_date -= timedelta(days=1) |
|||
else: |
|||
break |
|||
|
|||
return streak |
|||
|
|||
|
|||
# Global database instance |
|||
_db_instance = None |
|||
|
|||
def get_database(): |
|||
"""Get global database instance""" |
|||
global _db_instance |
|||
if _db_instance is None: |
|||
_db_instance = Database() |
|||
return _db_instance |
|||
@ -0,0 +1,85 @@ |
|||
""" |
|||
Tesla Coil Spark Physics Course - Main Application Entry Point |
|||
PyQt5 Desktop Application |
|||
""" |
|||
|
|||
import sys |
|||
from pathlib import Path |
|||
|
|||
# Add parent directory to path so we can import app package |
|||
sys.path.insert(0, str(Path(__file__).parent.parent)) |
|||
|
|||
from PyQt5.QtWidgets import QApplication, QMessageBox |
|||
from PyQt5.QtCore import Qt |
|||
|
|||
# Import configuration and models |
|||
from app import config |
|||
from app.database import get_database |
|||
from app.models import get_course |
|||
from app.views import MainWindow |
|||
|
|||
|
|||
def main(): |
|||
"""Main application entry point""" |
|||
|
|||
# Create QApplication |
|||
app = QApplication(sys.argv) |
|||
app.setApplicationName(config.APP_NAME) |
|||
app.setApplicationVersion(config.APP_VERSION) |
|||
app.setOrganizationName(config.APP_AUTHOR) |
|||
|
|||
# Enable high DPI scaling |
|||
app.setAttribute(Qt.AA_EnableHighDpiScaling, True) |
|||
app.setAttribute(Qt.AA_UseHighDpiPixmaps, True) |
|||
|
|||
print("="*60) |
|||
print(f"{config.APP_NAME} v{config.APP_VERSION}") |
|||
print("="*60) |
|||
|
|||
try: |
|||
# Initialize database |
|||
print("[*] Initializing database...") |
|||
db = get_database() |
|||
print(f"[OK] Database ready: {db.db_path}") |
|||
|
|||
# Load course structure |
|||
print("[*] Loading course structure...") |
|||
course = get_course() |
|||
print(f"[OK] Course loaded: {course.title}") |
|||
|
|||
# Validate lesson files |
|||
print("[*] Validating lesson files...") |
|||
if course.validate(): |
|||
print("[OK] All lesson files found") |
|||
else: |
|||
print("[WARN] Some lesson files missing (see above)") |
|||
|
|||
# Create and show main window |
|||
print("[*] Creating main window...") |
|||
window = MainWindow() |
|||
window.show() |
|||
|
|||
print("[OK] Application ready!\n") |
|||
|
|||
# Run application event loop |
|||
return app.exec_() |
|||
|
|||
except Exception as e: |
|||
# Show error dialog |
|||
print(f"\n[ERROR] {e}") |
|||
import traceback |
|||
traceback.print_exc() |
|||
|
|||
error_dialog = QMessageBox() |
|||
error_dialog.setIcon(QMessageBox.Critical) |
|||
error_dialog.setWindowTitle("Error") |
|||
error_dialog.setText("Failed to initialize application") |
|||
error_dialog.setInformativeText(str(e)) |
|||
error_dialog.setDetailedText(traceback.format_exc()) |
|||
error_dialog.exec_() |
|||
|
|||
return 1 |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
sys.exit(main()) |
|||
@ -0,0 +1,7 @@ |
|||
""" |
|||
Models package for Tesla Coil Spark Course |
|||
""" |
|||
|
|||
from .course_model import Course, Lesson, Section, Part, LearningPath, get_course |
|||
|
|||
__all__ = ['Course', 'Lesson', 'Section', 'Part', 'LearningPath', 'get_course'] |
|||
@ -0,0 +1,320 @@ |
|||
""" |
|||
Course Model - Loads and manages course structure from course.json |
|||
""" |
|||
|
|||
import json |
|||
from pathlib import Path |
|||
from typing import Dict, List, Optional |
|||
from app.config import COURSE_JSON, LESSONS_DIR |
|||
|
|||
|
|||
class Lesson: |
|||
"""Represents a single lesson""" |
|||
|
|||
def __init__(self, data: dict, part_id: str, section_id: str, order: int = 0): |
|||
self.id = data['id'] |
|||
self.filename = data['filename'] |
|||
self.title = data['title'] |
|||
self.estimated_time = data['estimated_time'] |
|||
self.difficulty = data['difficulty'] |
|||
self.part_id = part_id |
|||
self.section_id = section_id |
|||
self.order = order # Sequential order in course (1-30) |
|||
self.points = data.get('points', 0) # Points for completion |
|||
|
|||
# Construct full path to lesson file |
|||
section_path = LESSONS_DIR / section_id.replace('-', '_').replace('fundamentals', '01-fundamentals').replace('optimization', '02-optimization').replace('spark_physics', '03-spark-physics').replace('advanced_modeling', '04-advanced-modeling') |
|||
self.file_path = section_path / self.filename |
|||
|
|||
def __repr__(self): |
|||
return f"<Lesson {self.id}: {self.title}>" |
|||
|
|||
|
|||
class Section: |
|||
"""Represents a course section (e.g., 'fundamentals')""" |
|||
|
|||
def __init__(self, data: dict, part_id: str, lesson_order_start: int = 1): |
|||
self.id = data['id'] |
|||
self.title = data['title'] |
|||
self.path = data['path'] |
|||
self.description = data['description'] |
|||
self.part_id = part_id |
|||
|
|||
# Load lessons with sequential ordering |
|||
self.lessons = [] |
|||
for i, lesson_data in enumerate(data['lessons']): |
|||
lesson = Lesson(lesson_data, part_id, self.id, lesson_order_start + i) |
|||
self.lessons.append(lesson) |
|||
|
|||
self.exercises = data.get('exercises', []) |
|||
self.key_concepts = data.get('key_concepts', []) |
|||
|
|||
def get_lesson(self, lesson_id: str) -> Optional[Lesson]: |
|||
"""Get lesson by ID""" |
|||
for lesson in self.lessons: |
|||
if lesson.id == lesson_id: |
|||
return lesson |
|||
return None |
|||
|
|||
def __repr__(self): |
|||
return f"<Section {self.id}: {len(self.lessons)} lessons>" |
|||
|
|||
|
|||
class Part: |
|||
"""Represents a course part (e.g., 'Part 1: Fundamentals')""" |
|||
|
|||
def __init__(self, data: dict, part_number: int, lesson_order_start: int = 1): |
|||
self.id = data['id'] |
|||
self.title = data['title'] |
|||
self.description = data['description'] |
|||
self.estimated_time = data['estimated_time'] |
|||
self.number = part_number # Part number (1-4) |
|||
|
|||
# Load sections with sequential lesson ordering |
|||
self.sections = [] |
|||
current_order = lesson_order_start |
|||
for section_data in data['sections']: |
|||
section = Section(section_data, self.id, current_order) |
|||
self.sections.append(section) |
|||
current_order += len(section.lessons) |
|||
|
|||
# Create a convenience property for accessing all lessons in this part |
|||
self.lessons = self.get_all_lessons() |
|||
|
|||
def get_lesson(self, lesson_id: str) -> Optional[Lesson]: |
|||
"""Get lesson by ID from any section in this part""" |
|||
for section in self.sections: |
|||
lesson = section.get_lesson(lesson_id) |
|||
if lesson: |
|||
return lesson |
|||
return None |
|||
|
|||
def get_all_lessons(self) -> List[Lesson]: |
|||
"""Get all lessons in this part""" |
|||
lessons = [] |
|||
for section in self.sections: |
|||
lessons.extend(section.lessons) |
|||
return lessons |
|||
|
|||
def __repr__(self): |
|||
return f"<Part {self.id}: {len(self.sections)} sections>" |
|||
|
|||
|
|||
class LearningPath: |
|||
"""Represents a learning path (e.g., 'beginner', 'complete')""" |
|||
|
|||
def __init__(self, data: dict): |
|||
self.id = data['id'] |
|||
self.title = data['title'] |
|||
self.description = data['description'] |
|||
self.lessons = data.get('lessons', []) |
|||
self.skip = data.get('skip', []) |
|||
|
|||
def includes_lesson(self, lesson_id: str) -> bool: |
|||
"""Check if lesson is included in this path""" |
|||
if self.lessons == 'all': |
|||
return lesson_id not in self.skip |
|||
return lesson_id in self.lessons |
|||
|
|||
def __repr__(self): |
|||
return f"<LearningPath {self.id}: {self.title}>" |
|||
|
|||
|
|||
class Course: |
|||
"""Main course model - loads and manages entire course structure""" |
|||
|
|||
def __init__(self, course_json_path: Path = None): |
|||
""" |
|||
Load course from course.json |
|||
|
|||
Args: |
|||
course_json_path: Path to course.json file (default: from config) |
|||
""" |
|||
if course_json_path is None: |
|||
course_json_path = COURSE_JSON |
|||
|
|||
self.json_path = course_json_path |
|||
self._load_course() |
|||
|
|||
def _load_course(self): |
|||
"""Load and parse course.json""" |
|||
try: |
|||
with open(self.json_path, 'r', encoding='utf-8') as f: |
|||
data = json.load(f) |
|||
|
|||
# Course metadata |
|||
self.title = data['title'] |
|||
self.version = data['version'] |
|||
self.author = data['author'] |
|||
self.description = data['description'] |
|||
self.estimated_total_time = data['estimated_total_time'] |
|||
self.total_lessons = data['total_lessons'] |
|||
self.total_exercises = data['total_exercises'] |
|||
self.total_points = data['total_points'] |
|||
|
|||
# Prerequisites |
|||
self.prerequisites_required = data['prerequisites']['required'] |
|||
self.prerequisites_recommended = data['prerequisites']['recommended'] |
|||
|
|||
# Load course structure (4 parts) with sequential numbering |
|||
self.parts = [] |
|||
current_order = 1 |
|||
for i, part_data in enumerate(data['structure']): |
|||
part = Part(part_data, i + 1, current_order) |
|||
self.parts.append(part) |
|||
current_order += len(part.get_all_lessons()) |
|||
|
|||
# Reference materials |
|||
self.reference_materials = data['reference_materials'] |
|||
|
|||
# Worked examples |
|||
self.worked_examples = data['worked_examples'] |
|||
|
|||
# Learning paths |
|||
self.learning_paths = [ |
|||
LearningPath(path_data) |
|||
for path_data in data['learning_paths'] |
|||
] |
|||
|
|||
# Tags |
|||
self.tags = data.get('tags', {}) |
|||
|
|||
# Metadata |
|||
self.metadata = data.get('metadata', {}) |
|||
|
|||
# Build lesson index for quick lookup |
|||
self._build_lesson_index() |
|||
|
|||
print(f"[Course] Loaded: {self.title}") |
|||
print(f"[Course] {self.total_lessons} lessons across {len(self.parts)} parts") |
|||
|
|||
except FileNotFoundError: |
|||
print(f"[Course ERROR] course.json not found: {self.json_path}") |
|||
raise |
|||
except json.JSONDecodeError as e: |
|||
print(f"[Course ERROR] Invalid JSON: {e}") |
|||
raise |
|||
except KeyError as e: |
|||
print(f"[Course ERROR] Missing required field: {e}") |
|||
raise |
|||
|
|||
def _build_lesson_index(self): |
|||
"""Build index for fast lesson lookup by ID""" |
|||
self._lesson_index = {} |
|||
for part in self.parts: |
|||
for section in part.sections: |
|||
for lesson in section.lessons: |
|||
self._lesson_index[lesson.id] = lesson |
|||
|
|||
def get_lesson(self, lesson_id: str) -> Optional[Lesson]: |
|||
"""Get lesson by ID (fast lookup)""" |
|||
return self._lesson_index.get(lesson_id) |
|||
|
|||
def get_all_lessons(self) -> List[Lesson]: |
|||
"""Get all lessons in course order""" |
|||
lessons = [] |
|||
for part in self.parts: |
|||
lessons.extend(part.get_all_lessons()) |
|||
return lessons |
|||
|
|||
def get_lesson_by_index(self, index: int) -> Optional[Lesson]: |
|||
"""Get lesson by sequential index (0-29)""" |
|||
all_lessons = self.get_all_lessons() |
|||
if 0 <= index < len(all_lessons): |
|||
return all_lessons[index] |
|||
return None |
|||
|
|||
def get_lesson_index(self, lesson_id: str) -> Optional[int]: |
|||
"""Get sequential index of a lesson (0-29)""" |
|||
all_lessons = self.get_all_lessons() |
|||
for i, lesson in enumerate(all_lessons): |
|||
if lesson.id == lesson_id: |
|||
return i |
|||
return None |
|||
|
|||
def get_next_lesson(self, lesson_id: str) -> Optional[Lesson]: |
|||
"""Get next lesson in sequence""" |
|||
index = self.get_lesson_index(lesson_id) |
|||
if index is not None: |
|||
return self.get_lesson_by_index(index + 1) |
|||
return None |
|||
|
|||
def get_prev_lesson(self, lesson_id: str) -> Optional[Lesson]: |
|||
"""Get previous lesson in sequence""" |
|||
index = self.get_lesson_index(lesson_id) |
|||
if index is not None and index > 0: |
|||
return self.get_lesson_by_index(index - 1) |
|||
return None |
|||
|
|||
def get_part(self, part_id: str) -> Optional[Part]: |
|||
"""Get part by ID""" |
|||
for part in self.parts: |
|||
if part.id == part_id: |
|||
return part |
|||
return None |
|||
|
|||
def get_learning_path(self, path_id: str) -> Optional[LearningPath]: |
|||
"""Get learning path by ID""" |
|||
for path in self.learning_paths: |
|||
if path.id == path_id: |
|||
return path |
|||
return None |
|||
|
|||
def get_lessons_for_path(self, path_id: str) -> List[Lesson]: |
|||
"""Get all lessons for a specific learning path""" |
|||
path = self.get_learning_path(path_id) |
|||
if not path: |
|||
return [] |
|||
|
|||
all_lessons = self.get_all_lessons() |
|||
if path.lessons == 'all': |
|||
return [l for l in all_lessons if l.id not in path.skip] |
|||
else: |
|||
return [l for l in all_lessons if l.id in path.lessons] |
|||
|
|||
def get_lessons_by_tag(self, tag: str) -> List[Lesson]: |
|||
"""Get all lessons with a specific tag""" |
|||
if tag not in self.tags: |
|||
return [] |
|||
|
|||
lesson_ids = self.tags[tag] |
|||
return [self.get_lesson(lid) for lid in lesson_ids if self.get_lesson(lid)] |
|||
|
|||
def get_part_for_lesson(self, lesson_id: str) -> Optional[Part]: |
|||
"""Get the part that contains a lesson""" |
|||
for part in self.parts: |
|||
if part.get_lesson(lesson_id): |
|||
return part |
|||
return None |
|||
|
|||
def search_lessons(self, query: str) -> List[Lesson]: |
|||
"""Simple search by lesson title""" |
|||
query = query.lower() |
|||
results = [] |
|||
for lesson in self.get_all_lessons(): |
|||
if query in lesson.title.lower() or query in lesson.id.lower(): |
|||
results.append(lesson) |
|||
return results |
|||
|
|||
def validate(self) -> bool: |
|||
"""Validate that all lesson files exist""" |
|||
all_valid = True |
|||
for lesson in self.get_all_lessons(): |
|||
if not lesson.file_path.exists(): |
|||
print(f"[Course WARN] Missing lesson file: {lesson.file_path}") |
|||
all_valid = False |
|||
return all_valid |
|||
|
|||
def __repr__(self): |
|||
return f"<Course: {self.total_lessons} lessons, {len(self.parts)} parts>" |
|||
|
|||
|
|||
# Global course instance |
|||
_course_instance = None |
|||
|
|||
def get_course() -> Course: |
|||
"""Get global course instance (singleton)""" |
|||
global _course_instance |
|||
if _course_instance is None: |
|||
_course_instance = Course() |
|||
return _course_instance |
|||
@ -0,0 +1,8 @@ |
|||
""" |
|||
Utilities package for Tesla Coil Spark Course |
|||
""" |
|||
|
|||
from .symbol_loader import get_symbol_definitions, SymbolDefinitions |
|||
from .variable_wrapper import VariableWrapper |
|||
|
|||
__all__ = ['get_symbol_definitions', 'SymbolDefinitions', 'VariableWrapper'] |
|||
@ -0,0 +1,107 @@ |
|||
""" |
|||
Symbol Definitions Loader |
|||
Loads and manages symbol/variable definitions for tooltips |
|||
""" |
|||
|
|||
import json |
|||
from pathlib import Path |
|||
from typing import Dict, Optional |
|||
|
|||
|
|||
class SymbolDefinitions: |
|||
"""Manages symbol definitions for variable tooltips""" |
|||
|
|||
def __init__(self, json_path: Optional[Path] = None): |
|||
""" |
|||
Initialize symbol definitions |
|||
|
|||
Args: |
|||
json_path: Path to symbols JSON file. If None, uses default from config. |
|||
""" |
|||
if json_path is None: |
|||
from app import config |
|||
json_path = config.RESOURCES_DIR / 'symbols_definitions.json' |
|||
|
|||
self.json_path = json_path |
|||
self.symbols = self._load_symbols() |
|||
|
|||
def _load_symbols(self) -> Dict: |
|||
"""Load symbols from JSON file""" |
|||
try: |
|||
with open(self.json_path, 'r', encoding='utf-8') as f: |
|||
data = json.load(f) |
|||
|
|||
symbols = data.get('variables', {}) |
|||
print(f"[Symbols] Loaded {len(symbols)} symbol definitions") |
|||
return symbols |
|||
|
|||
except FileNotFoundError: |
|||
print(f"[Symbols WARNING] Symbol definitions file not found: {self.json_path}") |
|||
return {} |
|||
except json.JSONDecodeError as e: |
|||
print(f"[Symbols ERROR] Invalid JSON in symbols file: {e}") |
|||
return {} |
|||
|
|||
def get_tooltip(self, symbol: str) -> Optional[str]: |
|||
""" |
|||
Get plain text tooltip content for a symbol (no HTML) |
|||
|
|||
Args: |
|||
symbol: The symbol/variable name (e.g., "ω", "C_mut") |
|||
|
|||
Returns: |
|||
Plain text string for tooltip, or None if symbol not defined |
|||
""" |
|||
if symbol not in self.symbols: |
|||
return None |
|||
|
|||
s = self.symbols[symbol] |
|||
|
|||
# Build tooltip as plain text with line breaks |
|||
tooltip_parts = [] |
|||
|
|||
# Symbol name |
|||
tooltip_parts.append(f"{symbol}") |
|||
|
|||
# Add pronunciation/name if different from symbol |
|||
if 'name' in s and s['name'] != symbol: |
|||
tooltip_parts.append(f" ({s['name']})") |
|||
|
|||
# Definition |
|||
if 'definition' in s: |
|||
tooltip_parts.append(f"\n{s['definition']}") |
|||
|
|||
# Formula |
|||
if 'formula' in s: |
|||
tooltip_parts.append(f"\nFormula: {s['formula']}") |
|||
|
|||
# Units |
|||
if 'units' in s: |
|||
tooltip_parts.append(f"\nUnits: {s['units']}") |
|||
|
|||
return ''.join(tooltip_parts) |
|||
|
|||
def has_symbol(self, symbol: str) -> bool: |
|||
"""Check if a symbol is defined""" |
|||
return symbol in self.symbols |
|||
|
|||
def get_all_symbols(self) -> list: |
|||
"""Get list of all defined symbols""" |
|||
return list(self.symbols.keys()) |
|||
|
|||
|
|||
# Global singleton instance |
|||
_symbol_defs_instance = None |
|||
|
|||
|
|||
def get_symbol_definitions() -> SymbolDefinitions: |
|||
""" |
|||
Get global SymbolDefinitions instance (singleton pattern) |
|||
|
|||
Returns: |
|||
SymbolDefinitions instance |
|||
""" |
|||
global _symbol_defs_instance |
|||
if _symbol_defs_instance is None: |
|||
_symbol_defs_instance = SymbolDefinitions() |
|||
return _symbol_defs_instance |
|||
@ -0,0 +1,159 @@ |
|||
""" |
|||
Variable Wrapper Utility |
|||
Automatically wraps variables in HTML content with tooltip spans |
|||
""" |
|||
|
|||
import re |
|||
import html |
|||
from typing import List, Tuple |
|||
from .symbol_loader import get_symbol_definitions |
|||
|
|||
|
|||
class VariableWrapper: |
|||
"""Wraps known variables in HTML content with tooltip markup""" |
|||
|
|||
def __init__(self): |
|||
"""Initialize variable wrapper with symbol definitions""" |
|||
self.symbols = get_symbol_definitions() |
|||
self._build_patterns() |
|||
|
|||
def _build_patterns(self) -> None: |
|||
"""Build regex patterns for all known symbols""" |
|||
# Get all symbols and sort by length (longest first) to avoid partial matches |
|||
symbols_list = sorted( |
|||
self.symbols.get_all_symbols(), |
|||
key=len, |
|||
reverse=True |
|||
) |
|||
|
|||
# Single letters that commonly appear in regular text |
|||
# Only match these in specific mathematical contexts |
|||
common_words = {'A', 'I', 'V', 'P', 'Q', 'R', 'L', 'C', 'E', 'B', 'G', 'X', 'Y', 'Z', 'f', 'd', 'h'} |
|||
|
|||
# Very common English words that need extra-strict matching |
|||
very_common = {'A', 'I'} |
|||
|
|||
self.patterns: List[Tuple[str, str]] = [] |
|||
self.context_patterns: List[Tuple[str, str]] = [] # Patterns requiring context |
|||
|
|||
for symbol in symbols_list: |
|||
# Escape special regex characters |
|||
escaped = re.escape(symbol) |
|||
|
|||
# For single-letter variables, only match in formula/code contexts |
|||
if symbol in common_words: |
|||
if symbol in very_common: |
|||
# Extra restrictive for A, I - only in clear math context |
|||
# Must be preceded by =, ×, +, -, /, ( with optional single space |
|||
# Multiple patterns to handle both "=A" and "= A" cases |
|||
# Use alternation to avoid variable-width lookbehind |
|||
pattern = f'(?<=[=×+\\-/\\(])\\s?({escaped})(?=[\\s=+\\-*/()\\[\\]])' |
|||
self.context_patterns.append((pattern, symbol)) |
|||
else: |
|||
# More restrictive pattern - requires mathematical context |
|||
# Match if preceded by: =, mathematical operators, but NOT punctuation |
|||
pattern = f'(?<=[=])\\s?({escaped})(?=[\\s=+\\-*/()\\[\\],;<>])|(?<=\\s)({escaped})(?=[\\s=+\\-*/()\\[\\],;<>])' |
|||
self.context_patterns.append((pattern, symbol)) |
|||
else: |
|||
# Normal pattern for multi-character symbols |
|||
# Use word boundaries but allow underscores and subscripts |
|||
pattern = f'(?<!\\w)({escaped})(?!\\w)' |
|||
self.patterns.append((pattern, symbol)) |
|||
|
|||
print(f"[VariableWrapper] Built {len(self.patterns)} normal patterns + {len(self.context_patterns)} context-sensitive patterns") |
|||
|
|||
def wrap_variables(self, html_content: str) -> str: |
|||
""" |
|||
Wrap known variables in HTML content with tooltip spans |
|||
|
|||
Args: |
|||
html_content: HTML content to process |
|||
|
|||
Returns: |
|||
HTML content with variables wrapped in tooltip spans |
|||
""" |
|||
# Track which variables were found (for debugging) |
|||
wrapped_vars = set() |
|||
|
|||
# Process normal patterns |
|||
all_patterns = self.patterns + self.context_patterns |
|||
|
|||
for pattern, symbol in all_patterns: |
|||
tooltip_text = self.symbols.get_tooltip(symbol) |
|||
if not tooltip_text: |
|||
continue |
|||
|
|||
# Escape for HTML attribute (newlines become ) |
|||
tooltip_escaped = html.escape(tooltip_text, quote=True).replace('\n', ' ') |
|||
|
|||
# Create replacement span with tooltip |
|||
replacement = ( |
|||
f'<span class="var-tooltip" ' |
|||
f'data-symbol="{symbol}" ' |
|||
f'title="{tooltip_escaped}">' |
|||
f'\\1' # Captured group (the symbol itself) |
|||
f'</span>' |
|||
) |
|||
|
|||
# Count matches before replacement |
|||
matches = list(re.finditer(pattern, html_content)) |
|||
|
|||
if matches: |
|||
wrapped_vars.add(symbol) |
|||
|
|||
# Replace pattern with wrapped version |
|||
# Use negative lookahead to avoid wrapping already-wrapped variables |
|||
pattern_with_check = f'(?<!var-tooltip">)(?<!var-tooltip" )(?<!title=")({pattern})(?!</span>)' |
|||
html_content = re.sub( |
|||
pattern_with_check, |
|||
replacement, |
|||
html_content |
|||
) |
|||
|
|||
if wrapped_vars: |
|||
print(f"[VariableWrapper] Wrapped {len(wrapped_vars)} unique variables: {', '.join(sorted(wrapped_vars)[:10])}...") |
|||
|
|||
return html_content |
|||
|
|||
def wrap_in_context(self, html_content: str) -> str: |
|||
""" |
|||
More sophisticated wrapping that parses HTML structure |
|||
to avoid wrapping in code blocks, headings, etc. |
|||
|
|||
Args: |
|||
html_content: HTML content to process |
|||
|
|||
Returns: |
|||
HTML content with variables wrapped (context-aware) |
|||
""" |
|||
# For now, use simple wrapping |
|||
# TODO: Implement HTML parsing to be more selective |
|||
# (e.g., skip <code>, <pre>, <h1>-<h6> tags) |
|||
|
|||
# Simple exclusion: Don't process content inside <code> or <pre> |
|||
code_blocks = [] |
|||
|
|||
def preserve_code(match): |
|||
"""Preserve code blocks and replace with placeholder""" |
|||
code_blocks.append(match.group(0)) |
|||
return f"___CODE_BLOCK_{len(code_blocks) - 1}___" |
|||
|
|||
# Temporarily remove code blocks |
|||
html_content = re.sub( |
|||
r'<(code|pre)>(.*?)</\1>', |
|||
preserve_code, |
|||
html_content, |
|||
flags=re.DOTALL |
|||
) |
|||
|
|||
# Wrap variables |
|||
html_content = self.wrap_variables(html_content) |
|||
|
|||
# Restore code blocks |
|||
for i, code_block in enumerate(code_blocks): |
|||
html_content = html_content.replace( |
|||
f"___CODE_BLOCK_{i}___", |
|||
code_block |
|||
) |
|||
|
|||
return html_content |
|||
@ -0,0 +1,10 @@ |
|||
""" |
|||
Views package for Tesla Coil Spark Course |
|||
""" |
|||
|
|||
from .main_window import MainWindow |
|||
from .navigation_panel import NavigationPanel |
|||
from .content_viewer import ContentViewer |
|||
from .progress_panel import ProgressPanel |
|||
|
|||
__all__ = ['MainWindow', 'NavigationPanel', 'ContentViewer', 'ProgressPanel'] |
|||
@ -0,0 +1,432 @@ |
|||
""" |
|||
Content Viewer - Center panel for displaying lesson content |
|||
""" |
|||
|
|||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel |
|||
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage |
|||
from PyQt5.QtCore import Qt, pyqtSignal, QUrl |
|||
from pathlib import Path |
|||
import markdown |
|||
from pymdownx import superfences, arithmatex |
|||
|
|||
from app import config |
|||
from app.models import Lesson |
|||
from app.utils import VariableWrapper |
|||
|
|||
|
|||
class ContentViewer(QWidget): |
|||
"""Center panel for displaying lesson content with markdown and MathJax""" |
|||
|
|||
# Signals |
|||
scroll_position_changed = pyqtSignal(float) # For auto-save |
|||
|
|||
def __init__(self, parent=None): |
|||
super().__init__(parent) |
|||
self.current_lesson = None |
|||
self.markdown_converter = self._init_markdown() |
|||
self.variable_wrapper = VariableWrapper() |
|||
|
|||
self.init_ui() |
|||
|
|||
def init_ui(self): |
|||
"""Initialize the UI components""" |
|||
layout = QVBoxLayout(self) |
|||
layout.setContentsMargins(0, 0, 0, 0) |
|||
|
|||
# Lesson title bar |
|||
self.title_label = QLabel("No lesson selected") |
|||
self.title_label.setStyleSheet(f""" |
|||
background-color: {config.COLOR_PRIMARY}; |
|||
color: white; |
|||
font-size: 16pt; |
|||
font-weight: bold; |
|||
padding: 12px; |
|||
""") |
|||
self.title_label.setWordWrap(True) |
|||
layout.addWidget(self.title_label) |
|||
|
|||
# Web view for content |
|||
self.web_view = QWebEngineView() |
|||
self.web_view.setPage(QWebEnginePage(self.web_view)) |
|||
layout.addWidget(self.web_view, 1) |
|||
|
|||
# Load welcome page |
|||
self.show_welcome() |
|||
|
|||
def _init_markdown(self): |
|||
"""Initialize markdown converter with extensions""" |
|||
return markdown.Markdown( |
|||
extensions=[ |
|||
'extra', |
|||
'codehilite', |
|||
'tables', |
|||
'toc', |
|||
'pymdownx.arithmatex', |
|||
'pymdownx.superfences', |
|||
'pymdownx.highlight', |
|||
'pymdownx.inlinehilite', |
|||
], |
|||
extension_configs={ |
|||
'pymdownx.arithmatex': { |
|||
'generic': True |
|||
}, |
|||
'codehilite': { |
|||
'css_class': 'highlight', |
|||
'linenums': False |
|||
} |
|||
} |
|||
) |
|||
|
|||
def show_welcome(self): |
|||
"""Display welcome message""" |
|||
html = self._wrap_html(""" |
|||
<div style="text-align: center; padding: 60px 20px;"> |
|||
<h1>Welcome to Tesla Coil Spark Physics Course</h1> |
|||
<p style="font-size: 18px; color: #666;"> |
|||
Select a lesson from the navigation panel to begin learning. |
|||
</p> |
|||
<p style="margin-top: 40px; color: #999;"> |
|||
⚡ Explore the fascinating world of Tesla coils and electromagnetic theory ⚡ |
|||
</p> |
|||
</div> |
|||
""", "Welcome") |
|||
self.web_view.setHtml(html) |
|||
self.title_label.setText("Welcome") |
|||
|
|||
def load_lesson(self, lesson: Lesson): |
|||
"""Load and display a lesson""" |
|||
self.current_lesson = lesson |
|||
self.title_label.setText(f"{lesson.order}. {lesson.title}") |
|||
|
|||
# Read markdown file |
|||
lesson_path = Path(lesson.file_path) |
|||
if not lesson_path.exists(): |
|||
self.show_error(f"Lesson file not found: {lesson.file_path}") |
|||
return |
|||
|
|||
try: |
|||
with open(lesson_path, 'r', encoding='utf-8') as f: |
|||
markdown_content = f.read() |
|||
|
|||
# Convert markdown to HTML |
|||
html_content = self.markdown_converter.convert(markdown_content) |
|||
|
|||
# Process custom tags |
|||
html_content = self._process_custom_tags(html_content, lesson) |
|||
|
|||
# Wrap variables with tooltips |
|||
html_content = self.variable_wrapper.wrap_in_context(html_content) |
|||
|
|||
# Wrap in full HTML document |
|||
full_html = self._wrap_html(html_content, lesson.title) |
|||
|
|||
# Load into web view |
|||
self.web_view.setHtml(full_html, QUrl.fromLocalFile(str(lesson_path.parent))) |
|||
|
|||
except Exception as e: |
|||
self.show_error(f"Error loading lesson: {str(e)}") |
|||
|
|||
def _process_custom_tags(self, html: str, lesson: Lesson) -> str: |
|||
"""Process custom tags like {exercise:id} and {image:file}""" |
|||
import re |
|||
|
|||
# Process {exercise:id} tags |
|||
def replace_exercise(match): |
|||
exercise_id = match.group(1) |
|||
return f''' |
|||
<div class="exercise-placeholder" data-exercise-id="{exercise_id}"> |
|||
<h3>📝 Exercise: {exercise_id}</h3> |
|||
<p><em>Interactive exercise will be loaded here</em></p> |
|||
</div> |
|||
''' |
|||
html = re.sub(r'\{exercise:([^}]+)\}', replace_exercise, html) |
|||
|
|||
# Process {image:file} tags |
|||
def replace_image(match): |
|||
image_file = match.group(1) |
|||
image_path = config.IMAGES_DIR / image_file |
|||
return f'<img src="{image_path}" alt="{image_file}" style="max-width: 100%; height: auto;" />' |
|||
html = re.sub(r'\{image:([^}]+)\}', replace_image, html) |
|||
|
|||
return html |
|||
|
|||
def _wrap_html(self, content: str, title: str) -> str: |
|||
"""Wrap content in full HTML document with styling and MathJax""" |
|||
return f""" |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>{title}</title> |
|||
<style> |
|||
body {{ |
|||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|||
line-height: 1.6; |
|||
color: {config.COLOR_TEXT}; |
|||
max-width: 900px; |
|||
margin: 0 auto; |
|||
padding: 20px 40px; |
|||
background-color: white; |
|||
}} |
|||
|
|||
h1, h2, h3, h4, h5, h6 {{ |
|||
color: {config.COLOR_PRIMARY}; |
|||
margin-top: 1.5em; |
|||
margin-bottom: 0.5em; |
|||
}} |
|||
|
|||
h1 {{ font-size: 2.2em; border-bottom: 3px solid {config.COLOR_PRIMARY}; padding-bottom: 10px; }} |
|||
h2 {{ font-size: 1.8em; border-bottom: 2px solid {config.COLOR_SECONDARY}; padding-bottom: 8px; }} |
|||
h3 {{ font-size: 1.4em; }} |
|||
|
|||
p {{ margin: 1em 0; }} |
|||
|
|||
code {{ |
|||
background-color: #f4f4f4; |
|||
padding: 2px 6px; |
|||
border-radius: 3px; |
|||
font-family: 'Consolas', 'Monaco', monospace; |
|||
font-size: 0.9em; |
|||
}} |
|||
|
|||
pre {{ |
|||
background-color: #f4f4f4; |
|||
padding: 15px; |
|||
border-radius: 5px; |
|||
overflow-x: auto; |
|||
border-left: 4px solid {config.COLOR_PRIMARY}; |
|||
}} |
|||
|
|||
pre code {{ |
|||
background-color: transparent; |
|||
padding: 0; |
|||
}} |
|||
|
|||
blockquote {{ |
|||
border-left: 4px solid {config.COLOR_WARNING}; |
|||
padding-left: 20px; |
|||
margin-left: 0; |
|||
color: #666; |
|||
font-style: italic; |
|||
}} |
|||
|
|||
table {{ |
|||
border-collapse: collapse; |
|||
width: 100%; |
|||
margin: 1.5em 0; |
|||
}} |
|||
|
|||
th, td {{ |
|||
border: 1px solid #ddd; |
|||
padding: 10px; |
|||
text-align: left; |
|||
}} |
|||
|
|||
th {{ |
|||
background-color: {config.COLOR_PRIMARY}; |
|||
color: white; |
|||
font-weight: bold; |
|||
}} |
|||
|
|||
tr:nth-child(even) {{ |
|||
background-color: #f9f9f9; |
|||
}} |
|||
|
|||
img {{ |
|||
max-width: 100%; |
|||
height: auto; |
|||
display: block; |
|||
margin: 20px auto; |
|||
border-radius: 5px; |
|||
box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
|||
}} |
|||
|
|||
.exercise-placeholder {{ |
|||
background-color: #fff8dc; |
|||
border: 2px dashed {config.COLOR_WARNING}; |
|||
padding: 20px; |
|||
margin: 20px 0; |
|||
border-radius: 5px; |
|||
}} |
|||
|
|||
.math {{ |
|||
font-size: 1.1em; |
|||
}} |
|||
|
|||
/* Syntax highlighting */ |
|||
.highlight {{ |
|||
background: #f4f4f4; |
|||
}} |
|||
|
|||
/* Variable tooltip styles */ |
|||
.var-tooltip {{ |
|||
color: {config.COLOR_PRIMARY}; |
|||
font-weight: 600; |
|||
cursor: help; |
|||
border-bottom: 1px dotted {config.COLOR_PRIMARY}; |
|||
position: relative; |
|||
display: inline-block; |
|||
transition: all 0.2s ease; |
|||
}} |
|||
|
|||
.var-tooltip:hover {{ |
|||
color: {config.COLOR_SECONDARY}; |
|||
border-bottom-color: {config.COLOR_SECONDARY}; |
|||
}} |
|||
|
|||
/* Tooltip popup */ |
|||
.tooltip-popup {{ |
|||
position: absolute; |
|||
background-color: #2c3e50; |
|||
color: white; |
|||
padding: 12px 16px; |
|||
border-radius: 6px; |
|||
font-size: 13px; |
|||
font-weight: normal; |
|||
max-width: 350px; |
|||
z-index: 10000; |
|||
box-shadow: 0 4px 12px rgba(0,0,0,0.4); |
|||
line-height: 1.6; |
|||
white-space: pre-wrap; |
|||
pointer-events: none; |
|||
opacity: 0; |
|||
transition: opacity 0.2s ease; |
|||
}} |
|||
|
|||
.tooltip-popup.show {{ |
|||
opacity: 1; |
|||
}} |
|||
|
|||
.tooltip-arrow {{ |
|||
position: absolute; |
|||
width: 0; |
|||
height: 0; |
|||
border-left: 8px solid transparent; |
|||
border-right: 8px solid transparent; |
|||
border-top: 8px solid #2c3e50; |
|||
bottom: -8px; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
}} |
|||
</style> |
|||
|
|||
<!-- MathJax for equation rendering --> |
|||
<script> |
|||
MathJax = {{ |
|||
tex: {{ |
|||
inlineMath: [['$', '$'], ['\\\\(', '\\\\)']], |
|||
displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']], |
|||
processEscapes: true |
|||
}}, |
|||
svg: {{ |
|||
fontCache: 'global' |
|||
}} |
|||
}}; |
|||
</script> |
|||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js" async></script> |
|||
|
|||
<!-- Variable tooltip JavaScript --> |
|||
<script> |
|||
// Create tooltip element |
|||
let tooltipPopup = null; |
|||
|
|||
function createTooltip() {{ |
|||
if (!tooltipPopup) {{ |
|||
tooltipPopup = document.createElement('div'); |
|||
tooltipPopup.className = 'tooltip-popup'; |
|||
|
|||
const arrow = document.createElement('div'); |
|||
arrow.className = 'tooltip-arrow'; |
|||
tooltipPopup.appendChild(arrow); |
|||
|
|||
const content = document.createElement('div'); |
|||
content.className = 'tooltip-content'; |
|||
tooltipPopup.appendChild(content); |
|||
|
|||
document.body.appendChild(tooltipPopup); |
|||
}} |
|||
}} |
|||
|
|||
function showTooltip(element, text) {{ |
|||
createTooltip(); |
|||
|
|||
// Set content |
|||
const content = tooltipPopup.querySelector('.tooltip-content'); |
|||
content.textContent = text.replace(/ /g, '\\n'); |
|||
|
|||
// Position tooltip |
|||
const rect = element.getBoundingClientRect(); |
|||
const tooltipRect = tooltipPopup.getBoundingClientRect(); |
|||
|
|||
const left = rect.left + (rect.width / 2) - (tooltipPopup.offsetWidth / 2); |
|||
const top = rect.top - tooltipPopup.offsetHeight - 10; |
|||
|
|||
tooltipPopup.style.left = Math.max(10, left) + 'px'; |
|||
tooltipPopup.style.top = Math.max(10, top) + window.scrollY + 'px'; |
|||
|
|||
// Show tooltip |
|||
setTimeout(() => {{ |
|||
tooltipPopup.classList.add('show'); |
|||
}}, 10); |
|||
}} |
|||
|
|||
function hideTooltip() {{ |
|||
if (tooltipPopup) {{ |
|||
tooltipPopup.classList.remove('show'); |
|||
}} |
|||
}} |
|||
|
|||
// Attach event listeners after DOM loads |
|||
document.addEventListener('DOMContentLoaded', function() {{ |
|||
const varTooltips = document.querySelectorAll('.var-tooltip'); |
|||
|
|||
varTooltips.forEach(element => {{ |
|||
element.addEventListener('mouseenter', function() {{ |
|||
const tooltipText = this.getAttribute('title'); |
|||
if (tooltipText) {{ |
|||
showTooltip(this, tooltipText); |
|||
// Remove title to prevent browser default tooltip |
|||
this.setAttribute('data-original-title', tooltipText); |
|||
this.removeAttribute('title'); |
|||
}} |
|||
}}); |
|||
|
|||
element.addEventListener('mouseleave', function() {{ |
|||
hideTooltip(); |
|||
// Restore title |
|||
const originalTitle = this.getAttribute('data-original-title'); |
|||
if (originalTitle) {{ |
|||
this.setAttribute('title', originalTitle); |
|||
}} |
|||
}}); |
|||
}}); |
|||
}}); |
|||
</script> |
|||
</head> |
|||
<body> |
|||
{content} |
|||
</body> |
|||
</html> |
|||
""" |
|||
|
|||
def show_error(self, message: str): |
|||
"""Display an error message""" |
|||
html = self._wrap_html(f""" |
|||
<div style="text-align: center; padding: 60px 20px; color: {config.COLOR_ERROR};"> |
|||
<h1>⚠ Error</h1> |
|||
<p style="font-size: 18px;">{message}</p> |
|||
</div> |
|||
""", "Error") |
|||
self.web_view.setHtml(html) |
|||
|
|||
def get_scroll_position(self) -> float: |
|||
"""Get current scroll position (0.0 to 1.0)""" |
|||
# This would require JavaScript execution in QWebEngineView |
|||
# For now, return 0.0 - can be implemented later |
|||
return 0.0 |
|||
|
|||
def set_scroll_position(self, position: float): |
|||
"""Set scroll position (0.0 to 1.0)""" |
|||
# This would require JavaScript execution in QWebEngineView |
|||
# For now, do nothing - can be implemented later |
|||
pass |
|||
@ -0,0 +1,292 @@ |
|||
""" |
|||
Main Window - Primary application window with 3-panel layout |
|||
""" |
|||
|
|||
from PyQt5.QtWidgets import ( |
|||
QMainWindow, QSplitter, QStatusBar, QMenuBar, QMenu, |
|||
QAction, QMessageBox, QApplication |
|||
) |
|||
from PyQt5.QtCore import Qt, QTimer |
|||
from PyQt5.QtGui import QKeySequence |
|||
|
|||
from app import config |
|||
from app.models import Course, get_course |
|||
from app.database import Database, get_database |
|||
from .navigation_panel import NavigationPanel |
|||
from .content_viewer import ContentViewer |
|||
from .progress_panel import ProgressPanel |
|||
|
|||
|
|||
class MainWindow(QMainWindow): |
|||
"""Main application window with 3-panel layout""" |
|||
|
|||
def __init__(self): |
|||
super().__init__() |
|||
|
|||
# Load course and database |
|||
self.course = get_course() |
|||
self.db = get_database() |
|||
|
|||
# Get or create default user |
|||
self.user_id = self._get_or_create_user() |
|||
|
|||
# Current state |
|||
self.current_lesson_id = None |
|||
|
|||
# Initialize UI |
|||
self.init_ui() |
|||
self.create_menus() |
|||
|
|||
# Connect signals |
|||
self.connect_signals() |
|||
|
|||
# Auto-save timer |
|||
self.auto_save_timer = QTimer(self) |
|||
self.auto_save_timer.timeout.connect(self.auto_save) |
|||
self.auto_save_timer.start(config.AUTO_SAVE_INTERVAL * 1000) # Convert to ms |
|||
|
|||
# Load progress and restore state |
|||
self.load_initial_state() |
|||
|
|||
def init_ui(self): |
|||
"""Initialize the user interface""" |
|||
self.setWindowTitle(f"{config.APP_NAME} v{config.APP_VERSION}") |
|||
self.setGeometry(100, 100, config.DEFAULT_WINDOW_WIDTH, config.DEFAULT_WINDOW_HEIGHT) |
|||
|
|||
# Create 3-panel splitter layout |
|||
self.splitter = QSplitter(Qt.Horizontal) |
|||
|
|||
# Create panels |
|||
self.navigation_panel = NavigationPanel(self.course, self) |
|||
self.content_viewer = ContentViewer(self) |
|||
self.progress_panel = ProgressPanel(self.course, self) |
|||
|
|||
# Add panels to splitter |
|||
self.splitter.addWidget(self.navigation_panel) |
|||
self.splitter.addWidget(self.content_viewer) |
|||
self.splitter.addWidget(self.progress_panel) |
|||
|
|||
# Set initial splitter sizes |
|||
self.splitter.setSizes([ |
|||
config.NAVIGATION_PANEL_DEFAULT_WIDTH, |
|||
config.DEFAULT_WINDOW_WIDTH - config.NAVIGATION_PANEL_DEFAULT_WIDTH - config.PROGRESS_PANEL_DEFAULT_WIDTH, |
|||
config.PROGRESS_PANEL_DEFAULT_WIDTH |
|||
]) |
|||
|
|||
# Set as central widget |
|||
self.setCentralWidget(self.splitter) |
|||
|
|||
# Create status bar |
|||
self.status_bar = QStatusBar() |
|||
self.setStatusBar(self.status_bar) |
|||
self.status_bar.showMessage("Ready") |
|||
|
|||
def create_menus(self): |
|||
"""Create menu bar""" |
|||
menubar = self.menuBar() |
|||
|
|||
# File Menu |
|||
file_menu = menubar.addMenu("&File") |
|||
|
|||
exit_action = QAction("E&xit", self) |
|||
exit_action.setShortcut(QKeySequence.Quit) |
|||
exit_action.triggered.connect(self.close) |
|||
file_menu.addAction(exit_action) |
|||
|
|||
# View Menu |
|||
view_menu = menubar.addMenu("&View") |
|||
|
|||
toggle_nav_action = QAction("Toggle &Navigation Panel", self) |
|||
toggle_nav_action.setShortcut("Ctrl+1") |
|||
toggle_nav_action.triggered.connect(lambda: self.navigation_panel.setVisible(not self.navigation_panel.isVisible())) |
|||
view_menu.addAction(toggle_nav_action) |
|||
|
|||
toggle_progress_action = QAction("Toggle &Progress Panel", self) |
|||
toggle_progress_action.setShortcut("Ctrl+2") |
|||
toggle_progress_action.triggered.connect(lambda: self.progress_panel.setVisible(not self.progress_panel.isVisible())) |
|||
view_menu.addAction(toggle_progress_action) |
|||
|
|||
view_menu.addSeparator() |
|||
|
|||
reset_layout_action = QAction("&Reset Layout", self) |
|||
reset_layout_action.triggered.connect(self.reset_layout) |
|||
view_menu.addAction(reset_layout_action) |
|||
|
|||
# Help Menu |
|||
help_menu = menubar.addMenu("&Help") |
|||
|
|||
about_action = QAction("&About", self) |
|||
about_action.triggered.connect(self.show_about) |
|||
help_menu.addAction(about_action) |
|||
|
|||
def connect_signals(self): |
|||
"""Connect signals between components""" |
|||
self.navigation_panel.lesson_selected.connect(self.on_lesson_selected) |
|||
|
|||
def _get_or_create_user(self) -> int: |
|||
"""Get or create default user""" |
|||
# Check if user exists |
|||
row = self.db.fetch_one("SELECT user_id FROM users LIMIT 1") |
|||
|
|||
if row: |
|||
return row[0] |
|||
|
|||
# Create default user |
|||
cursor = self.db.execute(""" |
|||
INSERT INTO users (username, created_at) |
|||
VALUES (?, datetime('now')) |
|||
""", ("default",)) |
|||
self.db.commit() |
|||
|
|||
return cursor.lastrowid |
|||
|
|||
def load_initial_state(self): |
|||
"""Load progress and restore application state""" |
|||
# Get overall progress |
|||
progress = self.db.get_overall_progress(self.user_id) |
|||
|
|||
# Update progress panel |
|||
completed_lessons = progress.get('lessons_completed', 0) |
|||
total_points = progress.get('total_points', 0) |
|||
total_time = progress.get('total_time', 0) |
|||
|
|||
self.progress_panel.update_progress(completed_lessons, total_points, total_time) |
|||
|
|||
# Update part progress |
|||
for part in self.course.parts: |
|||
part_completed = 0 |
|||
for lesson in part.lessons: |
|||
lesson_prog = self.db.get_lesson_progress(self.user_id, lesson.id) |
|||
if lesson_prog and lesson_prog['status'] == 'completed': |
|||
part_completed += 1 |
|||
part_total = len(part.lessons) |
|||
self.progress_panel.update_part_progress(part.number, part_completed, part_total) |
|||
|
|||
# Update study streak |
|||
streak = self.db.get_study_streak(self.user_id) if hasattr(self.db, 'get_study_streak') else 0 |
|||
self.progress_panel.update_streak(streak) |
|||
|
|||
# Update exercises |
|||
if hasattr(self.db, 'get_exercise_progress'): |
|||
exercise_progress = self.db.get_exercise_progress(self.user_id) |
|||
if exercise_progress: |
|||
self.progress_panel.update_exercises( |
|||
exercise_progress.get('completed', 0), |
|||
self.course.total_exercises |
|||
) |
|||
else: |
|||
self.progress_panel.update_exercises(0, self.course.total_exercises) |
|||
|
|||
# Update lesson statuses in navigation |
|||
for lesson in self.course.get_all_lessons(): |
|||
lesson_progress = self.db.get_lesson_progress(self.user_id, lesson.id) |
|||
status = lesson_progress['status'] if lesson_progress else 'not_started' |
|||
self.navigation_panel.update_lesson_status(lesson.id, status) |
|||
|
|||
# Get last viewed lesson |
|||
row = self.db.fetch_one(""" |
|||
SELECT lesson_id FROM lesson_progress |
|||
WHERE user_id = ? |
|||
ORDER BY last_accessed DESC |
|||
LIMIT 1 |
|||
""", (self.user_id,)) |
|||
|
|||
if row: |
|||
last_lesson_id = row[0] |
|||
# Don't auto-load, just highlight it |
|||
self.navigation_panel.set_current_lesson(last_lesson_id) |
|||
|
|||
def on_lesson_selected(self, lesson_id: str): |
|||
"""Handle lesson selection from navigation""" |
|||
lesson = self.course.get_lesson(lesson_id) |
|||
if not lesson: |
|||
return |
|||
|
|||
self.current_lesson_id = lesson_id |
|||
|
|||
# Update navigation highlight |
|||
self.navigation_panel.set_current_lesson(lesson_id) |
|||
|
|||
# Load lesson content |
|||
self.content_viewer.load_lesson(lesson) |
|||
|
|||
# Update progress panel |
|||
self.progress_panel.update_current_lesson( |
|||
lesson.title, |
|||
lesson.points, |
|||
lesson.estimated_time |
|||
) |
|||
|
|||
# Update database (mark as in_progress if not already completed) |
|||
lesson_progress = self.db.get_lesson_progress(self.user_id, lesson_id) |
|||
current_status = lesson_progress['status'] if lesson_progress else 'not_started' |
|||
if current_status == 'not_started': |
|||
self.db.update_lesson_progress( |
|||
self.user_id, |
|||
lesson_id, |
|||
status='in_progress' |
|||
) |
|||
self.navigation_panel.update_lesson_status(lesson_id, 'in_progress') |
|||
|
|||
# Update last accessed |
|||
self.db.update_lesson_progress( |
|||
self.user_id, |
|||
lesson_id, |
|||
last_accessed=True |
|||
) |
|||
|
|||
# Update status bar |
|||
self.status_bar.showMessage(f"Lesson {lesson.order}: {lesson.title}") |
|||
|
|||
def auto_save(self): |
|||
"""Auto-save progress""" |
|||
if not self.current_lesson_id: |
|||
return |
|||
|
|||
# Get scroll position |
|||
scroll_pos = self.content_viewer.get_scroll_position() |
|||
|
|||
# Update in database |
|||
self.db.update_lesson_progress( |
|||
self.user_id, |
|||
self.current_lesson_id, |
|||
scroll_position=scroll_pos, |
|||
time_spent_increment=config.AUTO_SAVE_INTERVAL |
|||
) |
|||
|
|||
def reset_layout(self): |
|||
"""Reset window layout to defaults""" |
|||
self.splitter.setSizes([ |
|||
config.NAVIGATION_PANEL_DEFAULT_WIDTH, |
|||
config.DEFAULT_WINDOW_WIDTH - config.NAVIGATION_PANEL_DEFAULT_WIDTH - config.PROGRESS_PANEL_DEFAULT_WIDTH, |
|||
config.PROGRESS_PANEL_DEFAULT_WIDTH |
|||
]) |
|||
self.navigation_panel.setVisible(True) |
|||
self.progress_panel.setVisible(True) |
|||
|
|||
def show_about(self): |
|||
"""Show about dialog""" |
|||
QMessageBox.about(self, "About", f""" |
|||
<h2>{config.APP_NAME}</h2> |
|||
<p>Version {config.APP_VERSION}</p> |
|||
<p>By {config.APP_AUTHOR}</p> |
|||
<br> |
|||
<p>An interactive desktop application for learning about Tesla coils |
|||
and electromagnetic theory.</p> |
|||
<br> |
|||
<p><b>Course Statistics:</b></p> |
|||
<ul> |
|||
<li>{self.course.total_lessons} Lessons</li> |
|||
<li>{self.course.total_exercises} Exercises</li> |
|||
<li>{self.course.total_points} Total Points</li> |
|||
<li>{len(self.course.parts)} Parts</li> |
|||
</ul> |
|||
""") |
|||
|
|||
def closeEvent(self, event): |
|||
"""Handle window close event""" |
|||
# Final auto-save |
|||
self.auto_save() |
|||
|
|||
# Accept close |
|||
event.accept() |
|||
@ -0,0 +1,211 @@ |
|||
""" |
|||
Navigation Panel - Left sidebar with course tree and navigation |
|||
""" |
|||
|
|||
from PyQt5.QtWidgets import ( |
|||
QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem, |
|||
QLabel, QComboBox, QPushButton, QLineEdit, QHBoxLayout |
|||
) |
|||
from PyQt5.QtCore import Qt, pyqtSignal |
|||
from PyQt5.QtGui import QIcon, QColor, QBrush |
|||
|
|||
from app import config |
|||
from app.models import Course, Lesson, Part, Section |
|||
|
|||
|
|||
class NavigationPanel(QWidget): |
|||
"""Left sidebar panel with course navigation tree""" |
|||
|
|||
# Signals |
|||
lesson_selected = pyqtSignal(str) # lesson_id |
|||
|
|||
def __init__(self, course: Course, parent=None): |
|||
super().__init__(parent) |
|||
self.course = course |
|||
self.current_lesson_id = None |
|||
self.lesson_items = {} # lesson_id -> QTreeWidgetItem mapping |
|||
|
|||
self.init_ui() |
|||
self.populate_tree() |
|||
|
|||
def init_ui(self): |
|||
"""Initialize the UI components""" |
|||
layout = QVBoxLayout(self) |
|||
layout.setContentsMargins(10, 10, 10, 10) |
|||
layout.setSpacing(10) |
|||
|
|||
# Title |
|||
title = QLabel("Course Navigation") |
|||
title.setStyleSheet(f"font-size: 14pt; font-weight: bold; color: {config.COLOR_PRIMARY};") |
|||
layout.addWidget(title) |
|||
|
|||
# Learning Path Filter (optional for Phase 2+) |
|||
path_layout = QHBoxLayout() |
|||
path_label = QLabel("Path:") |
|||
self.path_combo = QComboBox() |
|||
self.path_combo.addItem("All Lessons", None) |
|||
for path in self.course.learning_paths: |
|||
self.path_combo.addItem(path.title, path.id) |
|||
self.path_combo.currentIndexChanged.connect(self.on_path_filter_changed) |
|||
path_layout.addWidget(path_label) |
|||
path_layout.addWidget(self.path_combo, 1) |
|||
layout.addLayout(path_layout) |
|||
|
|||
# Search box |
|||
search_layout = QHBoxLayout() |
|||
self.search_box = QLineEdit() |
|||
self.search_box.setPlaceholderText("Search lessons...") |
|||
self.search_box.textChanged.connect(self.on_search_changed) |
|||
search_layout.addWidget(self.search_box) |
|||
layout.addLayout(search_layout) |
|||
|
|||
# Course tree |
|||
self.tree = QTreeWidget() |
|||
self.tree.setHeaderHidden(True) |
|||
self.tree.setIndentation(20) |
|||
self.tree.itemDoubleClicked.connect(self.on_item_double_clicked) |
|||
layout.addWidget(self.tree, 1) # Expand to fill space |
|||
|
|||
# Quick actions |
|||
btn_layout = QVBoxLayout() |
|||
self.btn_continue = QPushButton("Continue Learning") |
|||
self.btn_continue.setStyleSheet(f"background-color: {config.COLOR_SUCCESS}; color: white; font-weight: bold; padding: 8px;") |
|||
self.btn_continue.clicked.connect(self.on_continue_learning) |
|||
btn_layout.addWidget(self.btn_continue) |
|||
layout.addLayout(btn_layout) |
|||
|
|||
self.setMinimumWidth(config.NAVIGATION_PANEL_MIN_WIDTH) |
|||
|
|||
def populate_tree(self): |
|||
"""Populate the tree with course structure""" |
|||
self.tree.clear() |
|||
self.lesson_items.clear() |
|||
|
|||
# Add course title as root |
|||
root = QTreeWidgetItem(self.tree) |
|||
root.setText(0, self.course.title) |
|||
root.setExpanded(True) |
|||
root.setFlags(root.flags() & ~Qt.ItemIsSelectable) |
|||
|
|||
# Add parts |
|||
for part in self.course.parts: |
|||
part_item = QTreeWidgetItem(root) |
|||
part_item.setText(0, f"Part {part.number}: {part.title}") |
|||
part_item.setExpanded(True) |
|||
part_item.setFlags(part_item.flags() & ~Qt.ItemIsSelectable) |
|||
part_item.setForeground(0, QBrush(QColor(config.COLOR_PRIMARY))) |
|||
|
|||
# Add sections (if any) |
|||
if part.sections: |
|||
for section in part.sections: |
|||
section_item = QTreeWidgetItem(part_item) |
|||
section_item.setText(0, section.title) |
|||
section_item.setExpanded(True) |
|||
section_item.setFlags(section_item.flags() & ~Qt.ItemIsSelectable) |
|||
|
|||
# Add lessons in section |
|||
for lesson in section.lessons: |
|||
self._add_lesson_item(section_item, lesson) |
|||
else: |
|||
# Add lessons directly to part |
|||
for lesson in part.lessons: |
|||
self._add_lesson_item(part_item, lesson) |
|||
|
|||
def _add_lesson_item(self, parent_item: QTreeWidgetItem, lesson: Lesson): |
|||
"""Add a lesson item to the tree""" |
|||
lesson_item = QTreeWidgetItem(parent_item) |
|||
lesson_item.setText(0, f"{lesson.order}. {lesson.title}") |
|||
lesson_item.setData(0, Qt.UserRole, lesson.id) # Store lesson_id |
|||
|
|||
# Store reference for quick lookup |
|||
self.lesson_items[lesson.id] = lesson_item |
|||
|
|||
# Add status icon (default: not started) |
|||
self.update_lesson_status(lesson.id, 'not_started') |
|||
|
|||
def update_lesson_status(self, lesson_id: str, status: str): |
|||
"""Update the visual status of a lesson""" |
|||
if lesson_id not in self.lesson_items: |
|||
return |
|||
|
|||
item = self.lesson_items[lesson_id] |
|||
lesson = self.course.get_lesson(lesson_id) |
|||
|
|||
# Status icons |
|||
icon_map = { |
|||
'completed': '✓', |
|||
'in_progress': '⊙', |
|||
'not_started': '○', |
|||
'locked': '🔒' |
|||
} |
|||
|
|||
icon = icon_map.get(status, '○') |
|||
item.setText(0, f"{icon} {lesson.order}. {lesson.title}") |
|||
|
|||
# Color coding |
|||
if status == 'completed': |
|||
item.setForeground(0, QBrush(QColor(config.COLOR_SUCCESS))) |
|||
elif status == 'in_progress': |
|||
item.setForeground(0, QBrush(QColor(config.COLOR_WARNING))) |
|||
else: |
|||
item.setForeground(0, QBrush(QColor(config.COLOR_TEXT))) |
|||
|
|||
def set_current_lesson(self, lesson_id: str): |
|||
"""Highlight the current lesson""" |
|||
# Clear previous selection |
|||
if self.current_lesson_id and self.current_lesson_id in self.lesson_items: |
|||
prev_item = self.lesson_items[self.current_lesson_id] |
|||
prev_item.setBackground(0, QBrush(Qt.transparent)) |
|||
|
|||
# Set new selection |
|||
self.current_lesson_id = lesson_id |
|||
if lesson_id in self.lesson_items: |
|||
item = self.lesson_items[lesson_id] |
|||
item.setBackground(0, QBrush(QColor(config.COLOR_HIGHLIGHT))) |
|||
self.tree.scrollToItem(item) |
|||
|
|||
def on_item_double_clicked(self, item: QTreeWidgetItem, column: int): |
|||
"""Handle double-click on tree item""" |
|||
lesson_id = item.data(0, Qt.UserRole) |
|||
if lesson_id: |
|||
self.lesson_selected.emit(lesson_id) |
|||
|
|||
def on_continue_learning(self): |
|||
"""Handle 'Continue Learning' button click""" |
|||
# TODO: Get the next incomplete lesson from database |
|||
# For now, just select the first lesson |
|||
if self.course.lessons: |
|||
first_lesson = self.course.lessons[0] |
|||
self.lesson_selected.emit(first_lesson.id) |
|||
|
|||
def on_path_filter_changed(self, index: int): |
|||
"""Handle learning path filter change""" |
|||
path_id = self.path_combo.itemData(index) |
|||
if path_id: |
|||
# Filter tree to show only lessons in this path |
|||
lessons_in_path = self.course.get_lessons_for_path(path_id) |
|||
path_lesson_ids = {lesson.id for lesson in lessons_in_path} |
|||
|
|||
# Hide/show items |
|||
for lesson_id, item in self.lesson_items.items(): |
|||
item.setHidden(lesson_id not in path_lesson_ids) |
|||
else: |
|||
# Show all |
|||
for item in self.lesson_items.values(): |
|||
item.setHidden(False) |
|||
|
|||
def on_search_changed(self, text: str): |
|||
"""Handle search text change""" |
|||
if not text: |
|||
# Show all |
|||
for item in self.lesson_items.values(): |
|||
item.setHidden(False) |
|||
return |
|||
|
|||
# Search lessons |
|||
results = self.course.search_lessons(text) |
|||
result_ids = {lesson.id for lesson in results} |
|||
|
|||
# Hide/show items |
|||
for lesson_id, item in self.lesson_items.items(): |
|||
item.setHidden(lesson_id not in result_ids) |
|||
@ -0,0 +1,299 @@ |
|||
""" |
|||
Progress Panel - Right sidebar with progress tracking and statistics |
|||
""" |
|||
|
|||
from PyQt5.QtWidgets import ( |
|||
QWidget, QVBoxLayout, QHBoxLayout, QLabel, |
|||
QProgressBar, QPushButton, QFrame, QScrollArea |
|||
) |
|||
from PyQt5.QtCore import Qt |
|||
from PyQt5.QtGui import QFont |
|||
|
|||
from app import config |
|||
from app.models import Course |
|||
|
|||
|
|||
class ProgressPanel(QWidget): |
|||
"""Right sidebar panel with progress statistics and tracking""" |
|||
|
|||
def __init__(self, course: Course, parent=None): |
|||
super().__init__(parent) |
|||
self.course = course |
|||
|
|||
self.init_ui() |
|||
|
|||
def init_ui(self): |
|||
"""Initialize the UI components""" |
|||
# Main layout |
|||
main_layout = QVBoxLayout(self) |
|||
main_layout.setContentsMargins(10, 10, 10, 10) |
|||
main_layout.setSpacing(10) |
|||
|
|||
# Title |
|||
title = QLabel("Your Progress") |
|||
title.setStyleSheet(f"font-size: 14pt; font-weight: bold; color: {config.COLOR_PRIMARY};") |
|||
main_layout.addWidget(title) |
|||
|
|||
# Scroll area for content |
|||
scroll = QScrollArea() |
|||
scroll.setWidgetResizable(True) |
|||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) |
|||
scroll.setFrameShape(QFrame.NoFrame) |
|||
|
|||
# Content widget |
|||
content_widget = QWidget() |
|||
layout = QVBoxLayout(content_widget) |
|||
layout.setContentsMargins(0, 0, 5, 0) |
|||
layout.setSpacing(15) |
|||
|
|||
# === Overall Progress Section === |
|||
layout.addWidget(self._create_section_header("Overall Progress")) |
|||
|
|||
self.overall_progress_bar = QProgressBar() |
|||
self.overall_progress_bar.setStyleSheet(f""" |
|||
QProgressBar {{ |
|||
border: 2px solid {config.COLOR_PRIMARY}; |
|||
border-radius: 5px; |
|||
text-align: center; |
|||
height: 25px; |
|||
}} |
|||
QProgressBar::chunk {{ |
|||
background-color: {config.COLOR_SUCCESS}; |
|||
}} |
|||
""") |
|||
layout.addWidget(self.overall_progress_bar) |
|||
|
|||
self.overall_stats_label = QLabel("0 / 30 lessons completed") |
|||
self.overall_stats_label.setStyleSheet("font-size: 10pt; color: #666;") |
|||
layout.addWidget(self.overall_stats_label) |
|||
|
|||
layout.addWidget(self._create_separator()) |
|||
|
|||
# === Points and Level Section === |
|||
layout.addWidget(self._create_section_header("Points & Level")) |
|||
|
|||
points_layout = QHBoxLayout() |
|||
self.points_label = QLabel("0 pts") |
|||
self.points_label.setStyleSheet(f"font-size: 24pt; font-weight: bold; color: {config.COLOR_WARNING};") |
|||
points_layout.addWidget(self.points_label) |
|||
points_layout.addStretch() |
|||
layout.addLayout(points_layout) |
|||
|
|||
self.level_label = QLabel("Level 1: Novice") |
|||
self.level_label.setStyleSheet("font-size: 11pt; color: #666;") |
|||
layout.addWidget(self.level_label) |
|||
|
|||
self.level_progress_bar = QProgressBar() |
|||
self.level_progress_bar.setStyleSheet(f""" |
|||
QProgressBar {{ |
|||
border: 1px solid #ccc; |
|||
border-radius: 3px; |
|||
text-align: center; |
|||
height: 15px; |
|||
}} |
|||
QProgressBar::chunk {{ |
|||
background-color: {config.COLOR_WARNING}; |
|||
}} |
|||
""") |
|||
layout.addWidget(self.level_progress_bar) |
|||
|
|||
layout.addWidget(self._create_separator()) |
|||
|
|||
# === Part Progress Section === |
|||
layout.addWidget(self._create_section_header("Progress by Part")) |
|||
|
|||
self.part_progress_widgets = [] |
|||
for part in self.course.parts: |
|||
part_widget = self._create_part_progress(part.number, part.title, 0) |
|||
self.part_progress_widgets.append(part_widget) |
|||
layout.addWidget(part_widget) |
|||
|
|||
layout.addWidget(self._create_separator()) |
|||
|
|||
# === Study Stats Section === |
|||
layout.addWidget(self._create_section_header("Study Statistics")) |
|||
|
|||
stats_grid = QVBoxLayout() |
|||
stats_grid.setSpacing(8) |
|||
|
|||
self.time_stat = self._create_stat_row("⏱", "Total Time", "0 min") |
|||
self.streak_stat = self._create_stat_row("🔥", "Streak", "0 days") |
|||
self.exercises_stat = self._create_stat_row("📝", "Exercises", "0 / 18") |
|||
|
|||
stats_grid.addWidget(self.time_stat) |
|||
stats_grid.addWidget(self.streak_stat) |
|||
stats_grid.addWidget(self.exercises_stat) |
|||
|
|||
layout.addLayout(stats_grid) |
|||
|
|||
layout.addWidget(self._create_separator()) |
|||
|
|||
# === Current Lesson Section === |
|||
layout.addWidget(self._create_section_header("Current Lesson")) |
|||
|
|||
self.current_lesson_label = QLabel("No lesson selected") |
|||
self.current_lesson_label.setStyleSheet("font-size: 10pt; color: #666; padding: 10px;") |
|||
self.current_lesson_label.setWordWrap(True) |
|||
layout.addWidget(self.current_lesson_label) |
|||
|
|||
# Push everything to top |
|||
layout.addStretch() |
|||
|
|||
# Set content widget to scroll area |
|||
scroll.setWidget(content_widget) |
|||
main_layout.addWidget(scroll, 1) |
|||
|
|||
# Initialize with default values |
|||
self.update_progress(0, 0, 0) |
|||
|
|||
self.setMinimumWidth(config.PROGRESS_PANEL_MIN_WIDTH) |
|||
|
|||
def _create_section_header(self, text: str) -> QLabel: |
|||
"""Create a section header label""" |
|||
label = QLabel(text) |
|||
label.setStyleSheet(f"font-size: 11pt; font-weight: bold; color: {config.COLOR_SECONDARY};") |
|||
return label |
|||
|
|||
def _create_separator(self) -> QFrame: |
|||
"""Create a horizontal separator line""" |
|||
line = QFrame() |
|||
line.setFrameShape(QFrame.HLine) |
|||
line.setFrameShadow(QFrame.Sunken) |
|||
line.setStyleSheet("color: #ddd;") |
|||
return line |
|||
|
|||
def _create_part_progress(self, part_number: int, part_title: str, progress: int) -> QWidget: |
|||
"""Create a part progress widget""" |
|||
widget = QWidget() |
|||
layout = QVBoxLayout(widget) |
|||
layout.setContentsMargins(0, 5, 0, 5) |
|||
layout.setSpacing(5) |
|||
|
|||
# Part title |
|||
title_label = QLabel(f"Part {part_number}: {part_title[:30]}...") |
|||
title_label.setStyleSheet("font-size: 9pt; font-weight: bold;") |
|||
layout.addWidget(title_label) |
|||
|
|||
# Progress bar |
|||
progress_bar = QProgressBar() |
|||
progress_bar.setValue(progress) |
|||
progress_bar.setStyleSheet(f""" |
|||
QProgressBar {{ |
|||
border: 1px solid #ccc; |
|||
border-radius: 3px; |
|||
text-align: center; |
|||
height: 12px; |
|||
font-size: 8pt; |
|||
}} |
|||
QProgressBar::chunk {{ |
|||
background-color: {config.COLOR_PRIMARY}; |
|||
}} |
|||
""") |
|||
layout.addWidget(progress_bar) |
|||
|
|||
# Store reference for updates |
|||
widget.progress_bar = progress_bar |
|||
|
|||
return widget |
|||
|
|||
def _create_stat_row(self, icon: str, label: str, value: str) -> QWidget: |
|||
"""Create a statistics row""" |
|||
widget = QWidget() |
|||
layout = QHBoxLayout(widget) |
|||
layout.setContentsMargins(5, 5, 5, 5) |
|||
layout.setSpacing(10) |
|||
|
|||
# Icon |
|||
icon_label = QLabel(icon) |
|||
icon_label.setStyleSheet("font-size: 16pt;") |
|||
layout.addWidget(icon_label) |
|||
|
|||
# Label |
|||
text_label = QLabel(label) |
|||
text_label.setStyleSheet("font-size: 10pt; color: #666;") |
|||
layout.addWidget(text_label) |
|||
|
|||
layout.addStretch() |
|||
|
|||
# Value |
|||
value_label = QLabel(value) |
|||
value_label.setStyleSheet("font-size: 10pt; font-weight: bold;") |
|||
layout.addWidget(value_label) |
|||
|
|||
# Store reference for updates |
|||
widget.value_label = value_label |
|||
|
|||
return widget |
|||
|
|||
def update_progress(self, completed_lessons: int, total_points: int, total_time_minutes: int): |
|||
"""Update overall progress display""" |
|||
# Overall progress |
|||
total_lessons = self.course.total_lessons |
|||
progress_percent = int((completed_lessons / total_lessons) * 100) if total_lessons > 0 else 0 |
|||
self.overall_progress_bar.setValue(progress_percent) |
|||
self.overall_stats_label.setText(f"{completed_lessons} / {total_lessons} lessons completed") |
|||
|
|||
# Points |
|||
self.points_label.setText(f"{total_points} pts") |
|||
|
|||
# Level |
|||
level_info = self._get_level_info(total_points) |
|||
self.level_label.setText(f"Level {level_info['level']}: {level_info['title']}") |
|||
self.level_progress_bar.setValue(level_info['progress']) |
|||
|
|||
# Time |
|||
if total_time_minutes < 60: |
|||
time_str = f"{total_time_minutes} min" |
|||
else: |
|||
hours = total_time_minutes // 60 |
|||
minutes = total_time_minutes % 60 |
|||
time_str = f"{hours}h {minutes}m" |
|||
self.time_stat.value_label.setText(time_str) |
|||
|
|||
def update_part_progress(self, part_number: int, completed: int, total: int): |
|||
"""Update progress for a specific part""" |
|||
if 0 < part_number <= len(self.part_progress_widgets): |
|||
widget = self.part_progress_widgets[part_number - 1] |
|||
progress = int((completed / total) * 100) if total > 0 else 0 |
|||
widget.progress_bar.setValue(progress) |
|||
widget.progress_bar.setFormat(f"{completed}/{total} ({progress}%)") |
|||
|
|||
def update_streak(self, days: int): |
|||
"""Update study streak""" |
|||
self.streak_stat.value_label.setText(f"{days} days") |
|||
|
|||
def update_exercises(self, completed: int, total: int): |
|||
"""Update exercise completion""" |
|||
self.exercises_stat.value_label.setText(f"{completed} / {total}") |
|||
|
|||
def update_current_lesson(self, lesson_title: str, lesson_points: int, estimated_time: int): |
|||
"""Update current lesson information""" |
|||
text = f""" |
|||
<b>{lesson_title}</b><br> |
|||
Points: {lesson_points} | Est. time: {estimated_time} min |
|||
""" |
|||
self.current_lesson_label.setText(text) |
|||
|
|||
def _get_level_info(self, points: int) -> dict: |
|||
"""Get level information based on points""" |
|||
for i, (threshold, title, subtitle) in enumerate(config.LEVELS): |
|||
if i < len(config.LEVELS) - 1: |
|||
next_threshold = config.LEVELS[i + 1][0] |
|||
if points < next_threshold: |
|||
progress = int(((points - threshold) / (next_threshold - threshold)) * 100) |
|||
return { |
|||
'level': i + 1, |
|||
'title': title, |
|||
'subtitle': subtitle, |
|||
'progress': progress, |
|||
'next_threshold': next_threshold |
|||
} |
|||
|
|||
# Max level |
|||
return { |
|||
'level': len(config.LEVELS), |
|||
'title': config.LEVELS[-1][1], |
|||
'subtitle': config.LEVELS[-1][2], |
|||
'progress': 100, |
|||
'next_threshold': config.LEVELS[-1][0] |
|||
} |
|||
1138
spark-lessons/assets/IMAGE-REQUIREMENTS.md
File diff suppressed because it is too large
View File
|
After Width: 2063 | Height: 1754 | Size: 237 KiB |
@ -0,0 +1,446 @@ |
|||
{ |
|||
"title": "Tesla Coil Spark Physics: Complete Course", |
|||
"version": "1.0.0", |
|||
"author": "Tesla Coil Community", |
|||
"description": "A comprehensive course teaching the physics, mathematics, and simulation techniques required to understand and model Tesla coil sparks. From basic circuit theory to advanced distributed modeling with FEMM.", |
|||
"estimated_total_time": 840, |
|||
"total_lessons": 30, |
|||
"total_exercises": 18, |
|||
"total_points": 525, |
|||
|
|||
"prerequisites": { |
|||
"required": [ |
|||
"Basic AC circuit analysis (impedance, phasors)", |
|||
"Complex number arithmetic", |
|||
"Basic calculus (derivatives, integrals)", |
|||
"Familiarity with SPICE circuit simulation" |
|||
], |
|||
"recommended": [ |
|||
"Electromagnetic field theory basics", |
|||
"Experience with FEMM or similar FEA software", |
|||
"Tesla coil operating experience" |
|||
] |
|||
}, |
|||
|
|||
"structure": [ |
|||
{ |
|||
"id": "part-1", |
|||
"title": "Part 1: Circuit Fundamentals", |
|||
"description": "Foundation concepts for understanding spark impedance, admittance analysis, and topological constraints", |
|||
"estimated_time": 200, |
|||
"sections": [ |
|||
{ |
|||
"id": "fundamentals", |
|||
"title": "Circuit Fundamentals", |
|||
"path": "lessons/01-fundamentals", |
|||
"description": "Learn the basic circuit model, admittance analysis, phase constraints, and measurement techniques", |
|||
"lessons": [ |
|||
{ |
|||
"id": "fund-01", |
|||
"filename": "01-introduction.md", |
|||
"title": "Introduction and AC Circuit Review", |
|||
"estimated_time": 20, |
|||
"difficulty": "beginner" |
|||
}, |
|||
{ |
|||
"id": "fund-02", |
|||
"filename": "02-basic-circuit-model.md", |
|||
"title": "Basic Spark Circuit Model", |
|||
"estimated_time": 25, |
|||
"difficulty": "beginner" |
|||
}, |
|||
{ |
|||
"id": "fund-03", |
|||
"filename": "03-admittance-analysis.md", |
|||
"title": "Admittance Analysis of Parallel Circuits", |
|||
"estimated_time": 30, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "fund-04", |
|||
"filename": "04-phase-angles.md", |
|||
"title": "Understanding Phase Angles", |
|||
"estimated_time": 20, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "fund-05", |
|||
"filename": "05-phase-constraint.md", |
|||
"title": "Topological Phase Constraint", |
|||
"estimated_time": 25, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "fund-06", |
|||
"filename": "06-why-not-45-degrees.md", |
|||
"title": "Why Not -45 Degrees?", |
|||
"estimated_time": 15, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "fund-07", |
|||
"filename": "07-measurement-port.md", |
|||
"title": "Correct Measurement Port", |
|||
"estimated_time": 20, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "fund-08", |
|||
"filename": "08-review-exercises.md", |
|||
"title": "Part 1 Review and Integration", |
|||
"estimated_time": 45, |
|||
"difficulty": "intermediate" |
|||
} |
|||
], |
|||
"exercises": [ |
|||
"fund-ex-02a", "fund-ex-02b", "fund-ex-02c", |
|||
"fund-ex-03a", "fund-ex-03b", |
|||
"fund-ex-04a", "fund-ex-04b", |
|||
"fund-ex-05a", |
|||
"fund-ex-08-comprehensive", |
|||
"fund-ex-checkpoint-quiz" |
|||
], |
|||
"key_concepts": [ |
|||
"mutual_capacitance", |
|||
"shunt_capacitance", |
|||
"admittance_analysis", |
|||
"phase_constraint", |
|||
"measurement_port", |
|||
"topological_limits" |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"id": "part-2", |
|||
"title": "Part 2: Optimization & Simulation", |
|||
"description": "Learn optimization principles, Thévenin analysis, and simulation techniques for Tesla coil sparks", |
|||
"estimated_time": 280, |
|||
"sections": [ |
|||
{ |
|||
"id": "optimization", |
|||
"title": "Optimization & Simulation", |
|||
"path": "lessons/02-optimization", |
|||
"description": "Master power optimization, self-adjustment mechanisms, and Thévenin equivalent analysis", |
|||
"lessons": [ |
|||
{ |
|||
"id": "opt-01", |
|||
"filename": "01-two-resistances.md", |
|||
"title": "Two Critical Resistances", |
|||
"estimated_time": 35, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "opt-02", |
|||
"filename": "02-hungry-streamer.md", |
|||
"title": "The Hungry Streamer Principle", |
|||
"estimated_time": 30, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "opt-03", |
|||
"filename": "03-thevenin-method.md", |
|||
"title": "Thévenin Equivalent Extraction", |
|||
"estimated_time": 40, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "opt-04", |
|||
"filename": "04-thevenin-calculations.md", |
|||
"title": "Power Calculations with Thévenin", |
|||
"estimated_time": 45, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "opt-05", |
|||
"filename": "05-direct-measurement.md", |
|||
"title": "Direct Power Measurement", |
|||
"estimated_time": 25, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "opt-06", |
|||
"filename": "06-frequency-tracking.md", |
|||
"title": "Frequency Tracking and Loaded Poles", |
|||
"estimated_time": 45, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "opt-07", |
|||
"filename": "07-review-exercises.md", |
|||
"title": "Part 2 Review and Design Challenge", |
|||
"estimated_time": 60, |
|||
"difficulty": "intermediate" |
|||
} |
|||
], |
|||
"exercises": [ |
|||
"opt-ex-01a", |
|||
"opt-ex-01b", |
|||
"opt-ex-thevenin-complete" |
|||
], |
|||
"key_concepts": [ |
|||
"R_opt_power", |
|||
"R_opt_phase", |
|||
"hungry_streamer", |
|||
"thevenin_equivalent", |
|||
"frequency_tracking", |
|||
"loaded_poles", |
|||
"power_optimization" |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"id": "part-3", |
|||
"title": "Part 3: Spark Growth Physics", |
|||
"description": "Understand the physics of spark formation, growth, and energy requirements", |
|||
"estimated_time": 260, |
|||
"sections": [ |
|||
{ |
|||
"id": "spark-physics", |
|||
"title": "Spark Growth Physics", |
|||
"path": "lessons/03-spark-physics", |
|||
"description": "Master electric field thresholds, energy per meter, thermal dynamics, and streamer-to-leader transitions", |
|||
"lessons": [ |
|||
{ |
|||
"id": "phys-01", |
|||
"filename": "01-field-thresholds.md", |
|||
"title": "Electric Field Thresholds", |
|||
"estimated_time": 20, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "phys-02", |
|||
"filename": "02-voltage-limits.md", |
|||
"title": "Voltage-Limited Spark Length", |
|||
"estimated_time": 25, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "phys-03", |
|||
"filename": "03-energy-per-meter.md", |
|||
"title": "Energy Per Meter Concept", |
|||
"estimated_time": 30, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "phys-04", |
|||
"filename": "04-empirical-epsilon.md", |
|||
"title": "Empirical ε Values by Mode", |
|||
"estimated_time": 35, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "phys-05", |
|||
"filename": "05-thermal-memory.md", |
|||
"title": "Thermal Memory and Persistence", |
|||
"estimated_time": 40, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "phys-06", |
|||
"filename": "06-streamers-vs-leaders.md", |
|||
"title": "Streamers vs Leaders", |
|||
"estimated_time": 35, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "phys-07", |
|||
"filename": "07-capacitive-divider.md", |
|||
"title": "The Capacitive Divider Problem", |
|||
"estimated_time": 30, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "phys-08", |
|||
"filename": "08-freau-relationship.md", |
|||
"title": "Freau's Empirical Scaling", |
|||
"estimated_time": 25, |
|||
"difficulty": "intermediate" |
|||
}, |
|||
{ |
|||
"id": "phys-09", |
|||
"filename": "09-review-exercises.md", |
|||
"title": "Part 3 Review and QCW Design", |
|||
"estimated_time": 20, |
|||
"difficulty": "advanced" |
|||
} |
|||
], |
|||
"exercises": [ |
|||
"phys-ex-01a", |
|||
"phys-ex-03a", |
|||
"phys-ex-comprehensive", |
|||
"phys-ex-conceptual-limits" |
|||
], |
|||
"key_concepts": [ |
|||
"E_inception", |
|||
"E_propagation", |
|||
"energy_per_meter", |
|||
"epsilon_calibration", |
|||
"thermal_diffusion", |
|||
"streamers", |
|||
"leaders", |
|||
"capacitive_divider", |
|||
"voltage_limited", |
|||
"power_limited" |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"id": "part-4", |
|||
"title": "Part 4: Advanced Modeling", |
|||
"description": "Learn FEMM extraction techniques and build lumped and distributed spark models", |
|||
"estimated_time": 285, |
|||
"sections": [ |
|||
{ |
|||
"id": "advanced-modeling", |
|||
"title": "Advanced Modeling Techniques", |
|||
"path": "lessons/04-advanced-modeling", |
|||
"description": "Master FEMM capacitance extraction, lumped models, distributed models, and resistance optimization", |
|||
"lessons": [ |
|||
{ |
|||
"id": "model-01", |
|||
"filename": "01-lumped-model.md", |
|||
"title": "Lumped Spark Model Theory", |
|||
"estimated_time": 35, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "model-02", |
|||
"filename": "02-femm-extraction-lumped.md", |
|||
"title": "FEMM Extraction for Lumped Model", |
|||
"estimated_time": 50, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "model-03", |
|||
"filename": "03-distributed-model.md", |
|||
"title": "Distributed Model Introduction", |
|||
"estimated_time": 40, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "model-04", |
|||
"filename": "04-femm-extraction-distributed.md", |
|||
"title": "FEMM Extraction for Distributed Model", |
|||
"estimated_time": 55, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "model-05", |
|||
"filename": "05-resistance-optimization.md", |
|||
"title": "Resistance Optimization Algorithms", |
|||
"estimated_time": 55, |
|||
"difficulty": "advanced" |
|||
}, |
|||
{ |
|||
"id": "model-06", |
|||
"filename": "06-review-exercises.md", |
|||
"title": "Part 4 Review and Complete Project", |
|||
"estimated_time": 50, |
|||
"difficulty": "advanced" |
|||
} |
|||
], |
|||
"exercises": [ |
|||
"model-ex-lumped-complete" |
|||
], |
|||
"key_concepts": [ |
|||
"lumped_model", |
|||
"distributed_model", |
|||
"FEMM_extraction", |
|||
"Maxwell_capacitance_matrix", |
|||
"partial_capacitance", |
|||
"resistance_optimization", |
|||
"iterative_algorithm", |
|||
"circuit_determined_R", |
|||
"passivity_check", |
|||
"matrix_validation" |
|||
] |
|||
} |
|||
] |
|||
} |
|||
], |
|||
|
|||
"reference_materials": { |
|||
"equation_sheet": "reference/equation-sheet.md", |
|||
"physical_bounds": "reference/physical-bounds.md", |
|||
"glossary": "reference/glossary.yaml" |
|||
}, |
|||
|
|||
"worked_examples": { |
|||
"path": "worked-examples", |
|||
"examples": [ |
|||
"calculating-ropt.md", |
|||
"thevenin-extraction.md", |
|||
"spark-growth-timeline.md", |
|||
"femm-lumped-extraction.md", |
|||
"distributed-model-complete.md" |
|||
] |
|||
}, |
|||
|
|||
"learning_paths": [ |
|||
{ |
|||
"id": "beginner", |
|||
"title": "Beginner Path", |
|||
"description": "For those new to Tesla coils or RF circuit analysis", |
|||
"lessons": [ |
|||
"fund-01", "fund-02", "fund-03", "fund-04", "fund-06", "fund-07", "fund-08", |
|||
"opt-01", "opt-03", "opt-04", |
|||
"phys-01", "phys-02", "phys-03", "phys-08" |
|||
], |
|||
"skip": ["opt-02", "opt-06", "phys-04", "phys-05", "phys-06", "phys-07", "part-4"] |
|||
}, |
|||
{ |
|||
"id": "intermediate", |
|||
"title": "Complete Course", |
|||
"description": "Full course for comprehensive understanding", |
|||
"lessons": "all" |
|||
}, |
|||
{ |
|||
"id": "simulation-focus", |
|||
"title": "Simulation Focus", |
|||
"description": "For those primarily interested in modeling and simulation", |
|||
"lessons": [ |
|||
"fund-01", "fund-02", "fund-03", "fund-05", "fund-08", |
|||
"opt-01", "opt-03", "opt-04", "opt-05", "opt-06", |
|||
"phys-01", "phys-02", "phys-03", "phys-04", |
|||
"model-01", "model-02", "model-03", "model-04", "model-05" |
|||
] |
|||
}, |
|||
{ |
|||
"id": "physics-focus", |
|||
"title": "Physics Focus", |
|||
"description": "For those primarily interested in spark physics", |
|||
"lessons": [ |
|||
"fund-01", "fund-02", "fund-03", |
|||
"opt-01", "opt-02", |
|||
"phys-01", "phys-02", "phys-03", "phys-04", "phys-05", "phys-06", "phys-07", "phys-08", "phys-09" |
|||
] |
|||
} |
|||
], |
|||
|
|||
"tags": { |
|||
"circuit-theory": ["fund-01", "fund-02", "fund-03", "fund-04", "fund-05", "fund-07"], |
|||
"admittance": ["fund-03", "fund-04", "opt-01", "opt-03"], |
|||
"optimization": ["opt-01", "opt-02", "opt-03", "opt-04", "opt-05", "opt-06"], |
|||
"thevenin": ["opt-03", "opt-04"], |
|||
"frequency-tracking": ["opt-06"], |
|||
"field-theory": ["phys-01", "phys-02", "phys-07"], |
|||
"energy-budget": ["phys-03", "phys-04", "phys-08"], |
|||
"thermal-physics": ["phys-05", "phys-06"], |
|||
"plasma-physics": ["phys-06"], |
|||
"FEMM": ["model-02", "model-04"], |
|||
"modeling": ["model-01", "model-02", "model-03", "model-04", "model-05"], |
|||
"SPICE": ["opt-05", "model-01", "model-04", "model-05"], |
|||
"advanced": ["opt-02", "opt-06", "phys-04", "phys-05", "phys-06", "phys-07", "model-01", "model-02", "model-03", "model-04", "model-05"] |
|||
}, |
|||
|
|||
"metadata": { |
|||
"created": "2025-10-10", |
|||
"last_updated": "2025-10-10", |
|||
"format_version": "1.0", |
|||
"license": "Creative Commons Attribution-ShareAlike 4.0", |
|||
"repository": "https://github.com/your-repo/spark-lessons" |
|||
} |
|||
} |
|||
@ -0,0 +1,382 @@ |
|||
""" |
|||
Tesla Coil Spark Course - Circuit Diagram Generation |
|||
|
|||
Generates circuit schematics using schemdraw. |
|||
Run from spark-lessons directory. |
|||
|
|||
Usage: python generate_circuits.py |
|||
""" |
|||
|
|||
import schemdraw |
|||
import schemdraw.elements as elm |
|||
from pathlib import Path |
|||
import matplotlib.pyplot as plt |
|||
|
|||
# Directories |
|||
BASE_DIR = Path(__file__).parent |
|||
ASSETS_DIRS = { |
|||
'fundamentals': BASE_DIR / 'lessons' / '01-fundamentals' / 'assets', |
|||
'optimization': BASE_DIR / 'lessons' / '02-optimization' / 'assets', |
|||
'spark-physics': BASE_DIR / 'lessons' / '03-spark-physics' / 'assets', |
|||
'advanced-modeling': BASE_DIR / 'lessons' / '04-advanced-modeling' / 'assets', |
|||
'shared': BASE_DIR / 'assets' / 'shared', |
|||
} |
|||
|
|||
def save_circuit(drawing, filename, directory='fundamentals'): |
|||
"""Save circuit diagram""" |
|||
filepath = ASSETS_DIRS[directory] / filename |
|||
drawing.save(str(filepath), dpi=150) |
|||
print(f"[OK] Generated: {filepath}") |
|||
|
|||
|
|||
# ============================================================================ |
|||
# PART 1: FUNDAMENTALS CIRCUITS |
|||
# ============================================================================ |
|||
|
|||
def generate_geometry_to_circuit(): |
|||
"""Image 2: Geometry to circuit schematic translation""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=12, font='sans-serif') |
|||
|
|||
# Draw the circuit on the right side |
|||
# Topload node at top |
|||
d += elm.Line().right(1).label('Topload', loc='top') |
|||
d.push() |
|||
|
|||
# Parallel R and C_mut |
|||
d += elm.Line().down(0.5) |
|||
d.push() |
|||
d += elm.Resistor().down(1.5).label('R', loc='right') |
|||
d.pop() |
|||
d += elm.Capacitor().down(1.5).label('C_mut', loc='right').at((1, d.here[1])) |
|||
d += elm.Line().left(1) |
|||
|
|||
# Series point (spark tip node) |
|||
d += elm.Dot().label('Spark Tip', loc='right', ofst=0.3) |
|||
d += elm.Line().down(0.5) |
|||
|
|||
# C_sh to ground |
|||
d += elm.Capacitor().down(1.5).label('C_sh', loc='right') |
|||
d += elm.Ground() |
|||
|
|||
# Title is implicit in context - no annotation needed |
|||
|
|||
save_circuit(d, 'geometry-to-circuit.png', 'fundamentals') |
|||
|
|||
|
|||
def generate_current_paths_diagram(): |
|||
"""Image 6: Tesla coil showing all current paths""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=10, font='sans-serif') |
|||
|
|||
# Primary circuit (left) |
|||
d += elm.SourceSin().label('Drive') |
|||
d += elm.Capacitor().right(1.5).label('C_pri') |
|||
d += elm.Inductor().down(2).label('L_pri') |
|||
d += elm.Line().left(1.5) |
|||
d += elm.Ground() |
|||
|
|||
# Coupling to secondary |
|||
d.move(2, 1.5) |
|||
d += elm.Inductor().up(3).label('L_sec', loc='right') |
|||
d.push() |
|||
|
|||
# Topload capacitance |
|||
d += elm.Line().right(0.5) |
|||
d += elm.Capacitor().right(1).label('C_top') |
|||
d += elm.Line().down(0.5) |
|||
|
|||
# Spark circuit |
|||
d.push() |
|||
d += elm.Capacitor().down(1).label('C_mut', loc='right') |
|||
d += elm.Line().down(0.5) |
|||
d += elm.Capacitor().down(1).label('C_sh', loc='right') |
|||
d += elm.Ground() |
|||
d.pop() |
|||
|
|||
# Ground path |
|||
d += elm.Line().right(1.5) |
|||
d += elm.Ground() |
|||
|
|||
# Add current labels |
|||
d.here = (0, -2.5) |
|||
d += elm.Annotate().label('I_base', fontsize=10, color='red') |
|||
|
|||
save_circuit(d, 'current-paths-diagram.png', 'fundamentals') |
|||
|
|||
|
|||
# ============================================================================ |
|||
# PART 2: OPTIMIZATION CIRCUITS |
|||
# ============================================================================ |
|||
|
|||
def generate_thevenin_equivalent_circuit(): |
|||
"""Image 12: Thévenin equivalent with spark load""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=12, font='sans-serif') |
|||
|
|||
# Thévenin source |
|||
d += elm.SourceV().label('V_th') |
|||
d.push() |
|||
|
|||
# Z_th (impedance) |
|||
d += elm.Resistor().right(1.5).label('R_th') |
|||
d += elm.Capacitor().right(1.5).label('X_th', loc='bottom') |
|||
|
|||
# Connection point |
|||
d += elm.Dot() |
|||
d.push() |
|||
|
|||
# Load (spark) |
|||
d += elm.Line().down(0.5) |
|||
d += elm.Resistor().down(1.5).label('R_spark', loc='right') |
|||
d += elm.Capacitor().down(1.5).label('X_spark', loc='right') |
|||
d += elm.Ground() |
|||
|
|||
# Close circuit |
|||
d.pop() |
|||
d += elm.Line().down(4.5) |
|||
d += elm.Line().left(3) |
|||
|
|||
# Add formula annotation |
|||
d.here = (1, -5.5) |
|||
d += elm.Annotate(ofst=(0, -0.5)).label( |
|||
'P = 0.5|V_th|² Re{Z_spark} / |Z_th+Z_spark|²', |
|||
fontsize=11 |
|||
) |
|||
|
|||
save_circuit(d, 'thevenin-equivalent-circuit.png', 'optimization') |
|||
|
|||
|
|||
# ============================================================================ |
|||
# PART 3: SPARK PHYSICS CIRCUITS |
|||
# ============================================================================ |
|||
|
|||
def generate_capacitive_divider_circuit(): |
|||
"""Image 25: Capacitive divider circuit""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=12, font='sans-serif') |
|||
|
|||
# Voltage source (topload) |
|||
d += elm.Line().right(1).label('V_topload', loc='top') |
|||
d += elm.Dot() |
|||
d.push() |
|||
|
|||
# Parallel R and C_mut |
|||
d += elm.Line().down(0.5) |
|||
d.push() |
|||
d += elm.Resistor().down(1.5).label('R') |
|||
d.pop() |
|||
d += elm.Capacitor().right(1.5).down(1.5).label('C_mut') |
|||
d += elm.Line().left(1.5) |
|||
|
|||
# V_tip measurement point |
|||
d += elm.Dot().label('V_tip', loc='right', ofst=0.3) |
|||
d += elm.Line().down(0.5) |
|||
|
|||
# C_sh to ground |
|||
d += elm.Capacitor().down(1.5).label('C_sh = L×6.6pF/m', loc='right') |
|||
d += elm.Ground() |
|||
|
|||
# Add formula |
|||
d.here = (0, -5) |
|||
d += elm.Annotate().label( |
|||
'V_tip = V_topload × C_mut/(C_mut + C_sh)', |
|||
fontsize=11 |
|||
) |
|||
|
|||
save_circuit(d, 'capacitive-divider-circuit.png', 'spark-physics') |
|||
|
|||
|
|||
# ============================================================================ |
|||
# PART 4: ADVANCED MODELING CIRCUITS |
|||
# ============================================================================ |
|||
|
|||
def generate_lumped_model_schematic(): |
|||
"""Image 28: Lumped model circuit schematic""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=11, font='sans-serif') |
|||
|
|||
# Topload connection |
|||
d += elm.Line().right(1).label('Topload', loc='top') |
|||
d += elm.Dot().label('Port') |
|||
d.push() |
|||
|
|||
# Parallel combination |
|||
d += elm.Line().down(0.3) |
|||
d.push() |
|||
|
|||
# R branch |
|||
d += elm.Resistor().down(2).label('R', loc='left') |
|||
|
|||
# C_mut branch |
|||
d.pop() |
|||
d += elm.Capacitor().right(2).down(2).label('C_mut', loc='right') |
|||
d += elm.Line().left(2) |
|||
|
|||
# Spark tip node |
|||
d += elm.Dot().label('Spark Tip', loc='right', ofst=0.3) |
|||
|
|||
# C_sh to ground |
|||
d += elm.Line().down(0.3) |
|||
d += elm.Capacitor().down(1.5).label('C_sh', loc='right') |
|||
d += elm.Ground() |
|||
|
|||
# Add typical values |
|||
d.here = (0, -5) |
|||
d += elm.Annotate().label( |
|||
'Typical: R=50kΩ, C_mut=8pF, C_sh=6pF', |
|||
fontsize=10 |
|||
) |
|||
|
|||
save_circuit(d, 'lumped-model-schematic.png', 'advanced-modeling') |
|||
|
|||
|
|||
def generate_distributed_model_structure(): |
|||
"""Image 32: nth-order distributed model structure""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=9, font='sans-serif') |
|||
|
|||
# Topload |
|||
d += elm.Line().right(0.5).label('Topload', loc='top') |
|||
d += elm.Dot().label('Node 0') |
|||
|
|||
# Segment 1 |
|||
d.push() |
|||
d += elm.Capacitor().down(1.2).label('C_01', loc='left', ofst=-0.2) |
|||
d += elm.Dot().label('Node 1', loc='right', ofst=0.2) |
|||
d.push() |
|||
d += elm.Resistor().right(1.5).label('R_1', loc='top') |
|||
d.pop() |
|||
d += elm.Capacitor().down(1.2).label('C_1,gnd', loc='left') |
|||
d += elm.Ground() |
|||
|
|||
# Segment 2 |
|||
d.pop() |
|||
d += elm.Line().right(3) |
|||
d.push() |
|||
d += elm.Capacitor().down(1.2).label('C_12', loc='left', ofst=-0.2) |
|||
d += elm.Dot().label('Node 2', loc='right', ofst=0.2) |
|||
d.push() |
|||
d += elm.Resistor().right(1.5).label('R_2', loc='top') |
|||
d.pop() |
|||
d += elm.Capacitor().down(1.2).label('C_2,gnd', loc='left') |
|||
d += elm.Ground() |
|||
|
|||
# Ellipsis |
|||
d.pop() |
|||
d += elm.Line().right(1.5) |
|||
d += elm.Dot() |
|||
d += elm.Line().right(0.3).linestyle('dotted') |
|||
d += elm.Line().right(0.3) |
|||
d += elm.Dot() |
|||
d += elm.Line().right(1.5) |
|||
|
|||
# Segment n |
|||
d.push() |
|||
d += elm.Capacitor().down(1.2).label('C_n-1,n', loc='left', ofst=-0.2) |
|||
d += elm.Dot().label('Node n', loc='right', ofst=0.2) |
|||
d.push() |
|||
d += elm.Resistor().right(1.5).label('R_n', loc='top') |
|||
d.pop() |
|||
d += elm.Capacitor().down(1.2).label('C_n,gnd', loc='left') |
|||
d += elm.Ground() |
|||
|
|||
# Add note |
|||
d.here = (3, -3.5) |
|||
d += elm.Annotate().label( |
|||
'n = 5-20 segments\n(n+1)×(n+1) capacitance matrix', |
|||
fontsize=9 |
|||
) |
|||
|
|||
save_circuit(d, 'distributed-model-structure.png', 'advanced-modeling') |
|||
|
|||
|
|||
# ============================================================================ |
|||
# SHARED CIRCUITS |
|||
# ============================================================================ |
|||
|
|||
def generate_tesla_coil_system_overview(): |
|||
"""Image 44: Complete Tesla coil system diagram""" |
|||
with schemdraw.Drawing(show=False) as d: |
|||
d.config(fontsize=10, font='sans-serif') |
|||
|
|||
# Primary side |
|||
d += elm.SourceSin().label('Drive\nSource') |
|||
d += elm.Line().right(0.5) |
|||
d += elm.Switch().label('IGBT/FET') |
|||
d += elm.Line().right(0.5) |
|||
d += elm.Capacitor().right(1.5).label('MMC\n(C_pri)') |
|||
d += elm.Inductor().down(3).label('L_primary', loc='bottom') |
|||
d += elm.Line().left(3.5) |
|||
d += elm.Ground() |
|||
|
|||
# Secondary side (coupled) |
|||
d.move(4, 2) |
|||
d += elm.Inductor().up(4).label('L_secondary', loc='right') |
|||
d += elm.Line().up(0.5) |
|||
|
|||
# Topload |
|||
d += elm.Capacitor().right(1.5).label('C_topload') |
|||
d.push() |
|||
|
|||
# Spark |
|||
d += elm.Line().down(1) |
|||
d += elm.Gap().down(2).label('Spark\nGap') |
|||
d += elm.Line().down(1) |
|||
d += elm.Ground().label('Strike\nPoint') |
|||
|
|||
# Ground return |
|||
d.pop() |
|||
d += elm.Line().right(2) |
|||
d += elm.Line().down(5.5) |
|||
d += elm.Ground() |
|||
|
|||
# Add coupling annotation |
|||
d.here = (2, 0) |
|||
d += elm.Annotate(ofst=(0, 2)).label('k = 0.1-0.2', fontsize=10) |
|||
|
|||
# Add title |
|||
d.here = (0, 7) |
|||
d += elm.Annotate().label( |
|||
'Double-Resonant Solid State Tesla Coil (DRSSTC)', |
|||
fontsize=12 |
|||
) |
|||
|
|||
save_circuit(d, 'tesla-coil-system-overview.png', 'shared') |
|||
|
|||
|
|||
# ============================================================================ |
|||
# MAIN |
|||
# ============================================================================ |
|||
|
|||
def main(): |
|||
print("\n" + "="*60) |
|||
print("TESLA COIL SPARK COURSE - CIRCUIT DIAGRAM GENERATION") |
|||
print("="*60) |
|||
|
|||
print("\nGenerating Part 1 circuits...") |
|||
generate_geometry_to_circuit() |
|||
generate_current_paths_diagram() |
|||
|
|||
print("\nGenerating Part 2 circuits...") |
|||
generate_thevenin_equivalent_circuit() |
|||
|
|||
print("\nGenerating Part 3 circuits...") |
|||
generate_capacitive_divider_circuit() |
|||
|
|||
print("\nGenerating Part 4 circuits...") |
|||
generate_lumped_model_schematic() |
|||
generate_distributed_model_structure() |
|||
|
|||
print("\nGenerating shared circuits...") |
|||
generate_tesla_coil_system_overview() |
|||
|
|||
print("\n" + "="*60) |
|||
print("CIRCUIT GENERATION COMPLETE!") |
|||
print("="*60) |
|||
print(f"\nTotal circuit diagrams generated: 7") |
|||
print("="*60 + "\n") |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
main() |
|||
1655
spark-lessons/generate_images.py
File diff suppressed because it is too large
View File
@ -0,0 +1,242 @@ |
|||
""" |
|||
Generate placeholder images for manual creation tasks |
|||
(FEMM screenshots, photos, complex diagrams) |
|||
""" |
|||
|
|||
from PIL import Image, ImageDraw, ImageFont |
|||
import os |
|||
|
|||
# Configuration |
|||
PLACEHOLDER_COLOR = (240, 240, 250) # Light blue-gray |
|||
TEXT_COLOR = (60, 60, 60) |
|||
BORDER_COLOR = (100, 100, 200) |
|||
FONT_SIZE = 14 |
|||
|
|||
def create_placeholder(filepath, title, description, size=(1000, 800), tool="Manual Creation Required"): |
|||
"""Create a placeholder image with descriptive text""" |
|||
|
|||
# Ensure directory exists |
|||
os.makedirs(os.path.dirname(filepath), exist_ok=True) |
|||
|
|||
# Create image |
|||
img = Image.new('RGB', size, PLACEHOLDER_COLOR) |
|||
draw = ImageDraw.Draw(img) |
|||
|
|||
# Draw border |
|||
border_width = 10 |
|||
draw.rectangle([border_width, border_width, size[0]-border_width, size[1]-border_width], |
|||
outline=BORDER_COLOR, width=border_width) |
|||
|
|||
# Try to use a default font, fallback to default if not available |
|||
try: |
|||
font_title = ImageFont.truetype("arial.ttf", FONT_SIZE + 4) |
|||
font_text = ImageFont.truetype("arial.ttf", FONT_SIZE) |
|||
except: |
|||
font_title = ImageFont.load_default() |
|||
font_text = ImageFont.load_default() |
|||
|
|||
# Draw title |
|||
title_text = f"PLACEHOLDER: {title}" |
|||
title_bbox = draw.textbbox((0, 0), title_text, font=font_title) |
|||
title_width = title_bbox[2] - title_bbox[0] |
|||
title_x = (size[0] - title_width) // 2 |
|||
draw.text((title_x, 50), title_text, fill=TEXT_COLOR, font=font_title) |
|||
|
|||
# Draw tool requirement |
|||
tool_y = 100 |
|||
tool_bbox = draw.textbbox((0, 0), tool, font=font_text) |
|||
tool_width = tool_bbox[2] - tool_bbox[0] |
|||
tool_x = (size[0] - tool_width) // 2 |
|||
draw.text((tool_x, tool_y), tool, fill=(150, 50, 50), font=font_text) |
|||
|
|||
# Draw description (word-wrapped) |
|||
desc_y = 150 |
|||
margin = 80 |
|||
max_width = size[0] - 2 * margin |
|||
|
|||
# Simple word wrapping |
|||
words = description.split() |
|||
lines = [] |
|||
current_line = [] |
|||
|
|||
for word in words: |
|||
test_line = ' '.join(current_line + [word]) |
|||
test_bbox = draw.textbbox((0, 0), test_line, font=font_text) |
|||
test_width = test_bbox[2] - test_bbox[0] |
|||
|
|||
if test_width <= max_width: |
|||
current_line.append(word) |
|||
else: |
|||
if current_line: |
|||
lines.append(' '.join(current_line)) |
|||
current_line = [word] |
|||
|
|||
if current_line: |
|||
lines.append(' '.join(current_line)) |
|||
|
|||
# Draw lines |
|||
for i, line in enumerate(lines): |
|||
draw.text((margin, desc_y + i * 25), line, fill=TEXT_COLOR, font=font_text) |
|||
|
|||
# Save |
|||
img.save(filepath) |
|||
print(f"[OK] Created placeholder: {filepath}") |
|||
|
|||
|
|||
# ============================================================================ |
|||
# FEMM Screenshots |
|||
# ============================================================================ |
|||
|
|||
create_placeholder( |
|||
'lessons/01-fundamentals/assets/field-lines-capacitances.png', |
|||
'Electric Field Lines Visualization', |
|||
'FEMM electrostatic simulation required. Show side-by-side: (Left) C_mut field lines between topload and spark, (Right) C_sh field lines from spark to ground. Use different colors (blue for C_mut, red for C_sh). Label dimensions and include typical values: C_mut ~ 8 pF, C_sh ~ 6 pF for 3-foot spark. Size: 1200x600 px.', |
|||
size=(1200, 600), |
|||
tool="FEMM Electrostatic Analysis" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/03-spark-physics/assets/electric-field-enhancement.png', |
|||
'Field Enhancement at Spark Tip', |
|||
'FEMM field plot showing field enhancement factor. Side-by-side: (Left) Smooth topload with no spark showing E_average, (Right) With spark tip showing E_tip with enhancement factor kappa = 2-5. Use color gradient for field magnitude. Include scale bar and annotations for enhancement factor. Size: 1400x700 px.', |
|||
size=(1400, 700), |
|||
tool="FEMM Electrostatic Analysis" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/03-spark-physics/assets/femm-field-plot-example.png', |
|||
'Complete FEMM Field Solution', |
|||
'Full FEMM electrostatic simulation output. Toroid topload at 350 kV with 2-meter spark extending downward. Color-coded field magnitude (rainbow scale) with equipotential lines overlaid. Ground plane at bottom. Annotate field values at key points. Show E_propagation threshold line (~0.5 MV/m). Size: 800x1200 px.', |
|||
size=(800, 1200), |
|||
tool="FEMM Electrostatic Analysis" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/femm-geometry-setup-lumped.png', |
|||
'FEMM Geometry Setup for Lumped Model', |
|||
'FEMM geometry window screenshot showing axisymmetric setup. Show toroidal topload cross-section, single cylindrical spark segment, ground plane, and outer boundary. Label materials (air, perfect conductor), dimensions, and boundary conditions. Mesh should be visible but not too dense. Size: 800x1000 px.', |
|||
size=(800, 1000), |
|||
tool="FEMM Geometry Setup Screenshot" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/femm-geometry-setup-distributed.png', |
|||
'FEMM Geometry Setup for Distributed Model', |
|||
'FEMM axisymmetric view with multiple segments. Show toroid topload and 10 cylindrical segments stacked vertically. Each segment clearly labeled (1-10). Ground plane and outer boundary visible. Show segment numbering and equal length segments. Materials and boundaries labeled. Size: 800x1200 px.', |
|||
size=(800, 1200), |
|||
tool="FEMM Geometry Setup Screenshot" |
|||
) |
|||
|
|||
# ============================================================================ |
|||
# High-Speed Photography |
|||
# ============================================================================ |
|||
|
|||
create_placeholder( |
|||
'lessons/03-spark-physics/assets/streamers-vs-leaders-photos.png', |
|||
'Streamers vs Leaders High-Speed Photography', |
|||
'High-speed photos comparing spark morphology. Top: Burst mode showing purple/blue highly branched streamers. Bottom: QCW mode showing white/orange thick straight leaders. Same scale for comparison. Annotate: branch density, channel diameter, color differences, straightness. Include camera settings and coil parameters. Size: 1200x1000 px.', |
|||
size=(1200, 1000), |
|||
tool="High-Speed Photography" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/03-spark-physics/assets/spark-channel-persistence-sequence.png', |
|||
'Spark Channel Cooling Time-Lapse', |
|||
'Time-lapse sequence showing spark channel cooling over time. 5-6 frames: t=0ms (bright, hot), t=1ms (visible), t=5ms (fading), t=20ms (nearly gone), t=100ms (dissipated for streamer OR still visible for leader). Use false color for temperature. Label time and temperature. Show two tracks: thin streamer vs thick leader. Size: 1500x600 px.', |
|||
size=(1500, 600), |
|||
tool="High-Speed Photography + Time-Lapse" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/03-spark-physics/assets/streamer-to-leader-transition-sequence.png', |
|||
'Streamer-to-Leader Transition Mechanism', |
|||
'Six-panel sequential diagram showing evolution: 1) Initial streamers (thin, branched, purple), 2) Current flowing (heat accumulation), 3) Channel heating (color shift to blue-white), 4) Leader forms at base (thick, bright), 5) Leader propagates (tip launches new streamers), 6) Full leader with streamer corona. Arrows showing progression. Temperature scale (1000K to 20000K). Time scale (microseconds to milliseconds). Size: 1500x1000 px.', |
|||
size=(1500, 1000), |
|||
tool="High-Speed Photography / Illustration" |
|||
) |
|||
|
|||
# ============================================================================ |
|||
# Complex Diagrams (Manual Illustration) |
|||
# ============================================================================ |
|||
|
|||
create_placeholder( |
|||
'lessons/02-optimization/assets/hungry-streamer-feedback-loop.png', |
|||
'Hungry Streamer Feedback Loop Diagram', |
|||
'Circular feedback loop diagram with 6 steps: 1) More power leads to Joule heating (I^2 R), 2) Higher temperature causes thermal ionization, 3) Increased n_e increases conductivity, 4) Lower R moves closer to R_opt, 5) Better matching extracts more power, 6) Loop back to step 1. Use arrows showing flow. Add constraint boxes: R_min, R_max, source limits. Show equilibrium point: R_actual approximately equal to R_opt_power. Color code: Power (red), Temperature (orange), Conductivity (blue). Size: 1000x1000 px.', |
|||
size=(1000, 1000), |
|||
tool="Diagram Illustration Tool (Inkscape / Draw.io)" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/02-optimization/assets/thevenin-measurement-setup.png', |
|||
'Thevenin Measurement Procedure Diagrams', |
|||
'Two diagrams showing measurement procedures. Top: Z_th measurement with primary drive OFF, 1V AC test source at topload, current measurement arrow, labels for "Measure I_test" and "Z_th = 1V / I_test". Bottom: V_th measurement with primary drive ON, no load (open circuit at topload), voltage measurement, labels for "No spark load" and "Measure V_th". Size: 1000x1000 px.', |
|||
size=(1000, 1000), |
|||
tool="Circuit Diagram Tool (See CIRCUIT-SPECIFICATIONS.md)" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/maxwell-matrix-extraction.png', |
|||
'Maxwell Matrix Extraction Process', |
|||
'Diagram showing FEMM capacitance matrix (2x2) output with arrows showing extraction formulas: C_mut = |C_12| = |C_21|, C_sh = C_22 + C_12. Include sign convention explanation. Show example values. Add visual representation of what each capacitance means (field lines). Size: 1000x700 px.', |
|||
size=(1000, 700), |
|||
tool="Diagram Illustration Tool" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/partial-capacitance-transformation.png', |
|||
'Maxwell to Partial Capacitance Transformation', |
|||
'Two matrices side-by-side with transformation arrows. Left: Maxwell matrix (with negative off-diagonals), Right: Partial capacitance matrix (all positive). Show transformation formulas. Use 3x3 example for clarity. Add physical interpretation. Note: "All SPICE capacitors must be positive". Size: 1400x700 px.', |
|||
size=(1400, 700), |
|||
tool="Diagram Illustration Tool" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/lumped-model-validation-checks.png', |
|||
'Validation Procedure Flowchart', |
|||
'Decision tree flowchart: 1) Check matrix symmetry (Pass/Fail), 2) Check C_sh vs empirical rule (Within factor 2?), 3) Mesh convergence (Refine and recheck), 4) Boundary distance (Far enough?), 5) Calculate R_opt (Physical range?). Color code: Green (pass), Yellow (warning), Red (fail). Include typical pass criteria. Size: 800x1000 px.', |
|||
size=(800, 1000), |
|||
tool="Flowchart Tool (Draw.io / Lucidchart)" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/iterative-optimization-convergence.png', |
|||
'Resistance Optimization Convergence Plot', |
|||
'Convergence plot showing resistance values over iterations. X-axis: Iteration number (0 to 5), Y-axis: Resistance (log scale, kOhm to MOhm). Multiple curves for each segment (10 total). Show convergence: Base segments (fast, 1-2 iterations), Mid segments (moderate, 2-3 iterations), Tip segments (slow, 3-4 iterations). Horizontal lines for convergence criteria (+/-1%). Color gradient by position (base to tip). Size: 1200x800 px.', |
|||
size=(1200, 800), |
|||
tool="Advanced Plotting (Consider matplotlib animation)" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/04-advanced-modeling/assets/spice-implementation-methods.png', |
|||
'SPICE Implementation Methods Comparison', |
|||
'Three circuit diagrams side-by-side showing different SPICE implementations: 1) Partial capacitance (all positive capacitors to ground), 2) Controlled sources (VCCS implementing C_ij dV/dt), 3) Nearest-neighbor (simplified with only adjacent couplings). Label pros/cons: Partial (accurate, complex transformation), Controlled (direct, requires behavioral sources), Nearest-neighbor (simple, approximate). Show 3-node example for each. Size: 1500x600 px.', |
|||
size=(1500, 600), |
|||
tool="Circuit Diagram Tool" |
|||
) |
|||
|
|||
create_placeholder( |
|||
'lessons/01-fundamentals/assets/impedance-matching-concept.png', |
|||
'Impedance Matching: Ideal vs Constrained', |
|||
'Conceptual diagram comparing two scenarios. Left: Ideal matching where load impedance can be anywhere (full circle on complex plane), conjugate match achievable, mark -45 degree target. Right: Constrained matching where load impedance confined to sector (Tesla coil reality), highlight phi_Z_min boundary. Mark R_opt_power and R_opt_phase locations. Show -45 degree target outside feasible region. Use complex plane visualization. Size: 1200x600 px.', |
|||
size=(1200, 600), |
|||
tool="Diagram Illustration Tool" |
|||
) |
|||
|
|||
print("\n" + "="*60) |
|||
print("PLACEHOLDER GENERATION COMPLETE") |
|||
print("="*60) |
|||
print(f"\nCreated 15 placeholder images for manual creation:") |
|||
print(f" - FEMM screenshots: 5 images") |
|||
print(f" - High-speed photography: 3 images") |
|||
print(f" - Complex diagrams: 7 images") |
|||
print("\nThese placeholders indicate images that require:") |
|||
print(" - Professional FEMM electrostatic simulations") |
|||
print(" - High-speed photography of actual Tesla coil sparks") |
|||
print(" - Manual illustration with diagram tools") |
|||
print("\nTotal course image status:") |
|||
print(" - Generated (matplotlib): 22 images") |
|||
print(" - Placeholders created: 15 images") |
|||
print(" - Circuit specifications: 7 circuits (see CIRCUIT-SPECIFICATIONS.md)") |
|||
print(" - TOTAL: 44 images (2 optional images not yet specified)") |
|||
print("="*60 + "\n") |
|||
@ -0,0 +1,248 @@ |
|||
--- |
|||
id: fund-01 |
|||
title: "Introduction to Tesla Coil Spark Modeling" |
|||
section: "Fundamentals" |
|||
difficulty: "beginner" |
|||
estimated_time: 20 |
|||
prerequisites: [] |
|||
objectives: |
|||
- Understand the scope and goals of Tesla coil spark modeling |
|||
- Review essential AC circuit fundamentals including peak vs RMS values |
|||
- Master complex number notation and phasor representation |
|||
- Learn power calculations using peak phasors |
|||
- Understand impedance and admittance concepts |
|||
tags: ["introduction", "ac-circuits", "phasors", "complex-numbers", "power"] |
|||
--- |
|||
|
|||
# Introduction to Tesla Coil Spark Modeling |
|||
|
|||
## Overview |
|||
|
|||
This lesson plan is designed to take you from basic circuit concepts through advanced Tesla coil spark modeling. Tesla coil sparks are complex plasma phenomena that require understanding of AC circuits, electromagnetic fields, and plasma physics. By the end of this series, you'll be able to predict spark behavior and optimize coil performance. |
|||
|
|||
### What You'll Learn |
|||
|
|||
The complete course is divided into four parts: |
|||
|
|||
1. **Part 1: Fundamentals** - Circuits, impedance, and basic spark behavior |
|||
2. **Part 2: Optimization** - Power transfer and efficiency |
|||
3. **Part 3: Growth Physics** - FEMM modeling and energy requirements |
|||
4. **Part 4: Advanced Topics** - Distributed models and real-world application |
|||
|
|||
This lesson begins Part 1 by establishing the circuit theory foundation you'll need throughout. |
|||
|
|||
## AC Circuit Fundamentals Review |
|||
|
|||
### Peak vs RMS Values |
|||
|
|||
In AC circuits, voltage and current vary sinusoidally with time: |
|||
|
|||
**Time domain:** |
|||
``` |
|||
v(t) = V_peak × cos(ωt + φ) |
|||
``` |
|||
|
|||
**Two amplitude conventions:** |
|||
- **Peak value:** The maximum value reached (V_peak) |
|||
- **RMS value:** Root-Mean-Square, V_RMS = V_peak/√2 ≈ 0.707 × V_peak |
|||
|
|||
**For this entire framework, we use PEAK VALUES exclusively.** |
|||
|
|||
**Why peak values?** |
|||
1. Tesla coils are concerned with maximum voltage (breakdown, field stress) |
|||
2. Consistent with phasor notation in engineering |
|||
3. Power formula becomes: P = 0.5 × V_peak × I_peak × cos(θ) |
|||
|
|||
**Example:** If your oscilloscope shows a 100 kV peak-to-peak waveform: |
|||
- V_peak-to-peak = 100 kV |
|||
- V_peak = 50 kV (one-sided amplitude) |
|||
- V_RMS = 50 kV / √2 ≈ 35.4 kV |
|||
|
|||
### Complex Numbers and Phasors |
|||
|
|||
AC circuit analysis uses complex numbers to represent magnitude and phase simultaneously. |
|||
|
|||
**Rectangular form:** |
|||
``` |
|||
Z = R + jX |
|||
where j = √(-1) (imaginary unit, engineers use 'j' instead of 'i') |
|||
R = real part (resistance) |
|||
X = imaginary part (reactance) |
|||
``` |
|||
|
|||
**Polar form:** |
|||
``` |
|||
Z = |Z| ∠φ = |Z| × e^(jφ) |
|||
where |Z| = √(R² + X²) (magnitude) |
|||
φ = atan(X/R) (phase angle) |
|||
``` |
|||
|
|||
**Conversion:** |
|||
``` |
|||
R = |Z| × cos(φ) |
|||
X = |Z| × sin(φ) |
|||
``` |
|||
|
|||
**Phasor notation:** A complex number representing sinusoidal amplitude and phase: |
|||
``` |
|||
V = V_peak ∠φ_v |
|||
I = I_peak ∠φ_i |
|||
``` |
|||
|
|||
**Complex conjugate:** Used in power calculations |
|||
``` |
|||
If I = a + jb, then I* = a - jb (flip sign of imaginary part) |
|||
``` |
|||
|
|||
### Resistance, Reactance, Impedance |
|||
|
|||
**Resistance (R):** Opposition to current that dissipates energy as heat |
|||
- Units: Ω (ohms) |
|||
- Always real and positive |
|||
- V = I × R (Ohm's law) |
|||
|
|||
**Reactance (X):** Opposition to current that stores energy (no dissipation) |
|||
- Units: Ω (ohms) |
|||
- Can be positive (inductive) or negative (capacitive) |
|||
- **Capacitive reactance:** X_C = -1/(ωC) where ω = 2πf |
|||
- **Inductive reactance:** X_L = ωL |
|||
|
|||
**Impedance (Z):** Total opposition to AC current |
|||
``` |
|||
Z = R + jX (complex) |
|||
|Z| = √(R² + X²) |
|||
φ_Z = atan(X/R) |
|||
``` |
|||
|
|||
**Sign conventions:** |
|||
- X > 0: inductive (current lags voltage) |
|||
- X < 0: capacitive (current leads voltage) |
|||
- φ_Z > 0: inductive |
|||
- φ_Z < 0: capacitive |
|||
|
|||
### Conductance, Susceptance, Admittance |
|||
|
|||
For parallel circuits, **admittance (Y)** is more convenient than impedance. |
|||
|
|||
**Conductance (G):** Inverse of resistance |
|||
``` |
|||
G = 1/R |
|||
Units: S (siemens) |
|||
``` |
|||
|
|||
**Susceptance (B):** Inverse of reactance (BUT with opposite sign convention!) |
|||
``` |
|||
For capacitor: B_C = ωC (positive!) |
|||
For inductor: B_L = -1/(ωL) (negative) |
|||
``` |
|||
|
|||
**Important:** Susceptance sign convention is OPPOSITE of reactance: |
|||
- Capacitor: X_C < 0, but B_C > 0 |
|||
- Inductor: X_L > 0, but B_L < 0 |
|||
|
|||
**Admittance (Y):** Inverse of impedance |
|||
``` |
|||
Y = G + jB = 1/Z |
|||
|Y| = 1/|Z| |
|||
φ_Y = -φ_Z (opposite sign!) |
|||
``` |
|||
|
|||
**Conversion between Z and Y:** |
|||
``` |
|||
Y = 1/Z = 1/(R + jX) = R/(R² + X²) - jX/(R² + X²) |
|||
|
|||
Therefore: |
|||
G = R/(R² + X²) |
|||
B = -X/(R² + X²) |
|||
``` |
|||
|
|||
### Power in AC Circuits |
|||
|
|||
**Using peak phasors:** |
|||
``` |
|||
P = 0.5 × Re{V × I*} |
|||
|
|||
where V and I are complex peak phasors |
|||
I* is the complex conjugate of I |
|||
Re{·} means "real part of" |
|||
``` |
|||
|
|||
**Why the 0.5 factor?** |
|||
- Average power over a full AC cycle |
|||
- Comes from time-averaging cos²(ωt), which equals 0.5 |
|||
- If you used RMS values, formula would be P = V_RMS × I_RMS × cos(θ), NO 0.5 |
|||
|
|||
**Expanded form:** |
|||
``` |
|||
If V = V_peak ∠φ_v and I = I_peak ∠φ_i, then: |
|||
P = 0.5 × V_peak × I_peak × cos(φ_v - φ_i) |
|||
``` |
|||
|
|||
The angle difference (φ_v - φ_i) is the power factor angle. |
|||
|
|||
## Worked Example: Power Calculation with Peak Phasors |
|||
|
|||
**Given:** |
|||
- Voltage: V = 50 kV ∠0° (peak, using 0° as reference) |
|||
- Impedance: Z = 100 kΩ ∠-60° (capacitive load) |
|||
|
|||
**Find:** Real power dissipated |
|||
|
|||
**Solution:** |
|||
|
|||
Step 1: Calculate current using Ohm's law |
|||
``` |
|||
I = V/Z = (50 kV ∠0°)/(100 kΩ ∠-60°) |
|||
I = 0.5 A ∠(0° - (-60°)) = 0.5 A ∠60° |
|||
``` |
|||
|
|||
Step 2: Calculate power |
|||
``` |
|||
P = 0.5 × Re{V × I*} |
|||
P = 0.5 × Re{(50 kV ∠0°) × (0.5 A ∠-60°)} |
|||
P = 0.5 × Re{25 kW ∠-60°} |
|||
``` |
|||
|
|||
Step 3: Convert to rectangular to get real part |
|||
``` |
|||
25 kW ∠-60° = 25 kW × (cos(-60°) + j×sin(-60°)) |
|||
= 25 kW × (0.5 - j×0.866) |
|||
= 12.5 kW - j×21.65 kW |
|||
``` |
|||
|
|||
Step 4: Extract real part and apply 0.5 factor |
|||
``` |
|||
P = 0.5 × 12.5 kW = 6.25 kW |
|||
``` |
|||
|
|||
**Alternative method:** Using power factor angle |
|||
``` |
|||
P = 0.5 × V_peak × I_peak × cos(φ_v - φ_i) |
|||
P = 0.5 × 50 kV × 0.5 A × cos(0° - 60°) |
|||
P = 0.5 × 25 kW × cos(-60°) |
|||
P = 0.5 × 25 kW × 0.5 |
|||
P = 6.25 kW |
|||
``` |
|||
|
|||
## Key Takeaways |
|||
|
|||
- Always use **peak values** for Tesla coil analysis |
|||
- Complex numbers combine magnitude and phase: Z = R + jX = |Z|∠φ |
|||
- Power calculation: **P = 0.5 × Re{V × I*}** with peak phasors |
|||
- Admittance (Y = G + jB) is the inverse of impedance |
|||
- **Sign convention critical:** X < 0 for capacitors, but B > 0 |
|||
- Phase angles are opposite: φ_Y = -φ_Z |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-01} |
|||
|
|||
**Problem 1:** A capacitor has reactance X_C = -80 kΩ at 200 kHz. What is its capacitance? What is its susceptance? |
|||
|
|||
**Problem 2:** An impedance Z = 50 kΩ - j75 kΩ has current I = 0.2 A ∠30° (peak). Calculate: (a) Voltage magnitude and phase, (b) Real power |
|||
|
|||
**Problem 3:** An admittance Y = 0.00001 + j0.00002 S. Convert to impedance Z = R + jX. |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [Basic Circuit Model](02-basic-circuit-model.md) |
|||
@ -0,0 +1,277 @@ |
|||
--- |
|||
id: fund-02 |
|||
title: "The Basic Spark Circuit Model" |
|||
section: "Fundamentals" |
|||
difficulty: "beginner" |
|||
estimated_time: 25 |
|||
prerequisites: ["fund-01"] |
|||
objectives: |
|||
- Understand what capacitance represents physically |
|||
- Distinguish between mutual capacitance (C_mut) and shunt capacitance (C_sh) |
|||
- Learn the empirical 2 pF/foot rule for spark capacitance |
|||
- Draw the correct circuit topology for a Tesla coil spark |
|||
- Identify the topload port as the measurement reference |
|||
tags: ["capacitance", "circuit-topology", "C_mut", "C_sh", "measurement"] |
|||
--- |
|||
|
|||
# The Basic Spark Circuit Model |
|||
|
|||
## Introduction |
|||
|
|||
A spark isn't just a resistor - it's a complex structure with multiple electrical properties. Understanding how to model a spark as a circuit with the correct topology is essential for analyzing Tesla coil performance. |
|||
|
|||
## What is Capacitance Physically? |
|||
|
|||
**Definition:** Capacitance (C) is the ability to store electric charge for a given voltage: |
|||
``` |
|||
Q = C × V |
|||
Units: Farads (F), typically pF (10⁻¹² F) for Tesla coils |
|||
``` |
|||
|
|||
**Physical picture:** |
|||
- Electric field between two conductors stores energy |
|||
- Higher field → more stored energy → more capacitance |
|||
- Capacitance depends on geometry, NOT on voltage |
|||
|
|||
**For parallel plates:** |
|||
``` |
|||
C = ε₀ × A / d |
|||
|
|||
where ε₀ = 8.854×10⁻¹² F/m (permittivity of free space) |
|||
A = plate area (m²) |
|||
d = separation distance (m) |
|||
``` |
|||
|
|||
**Key insight:** Capacitance increases with: |
|||
- Larger conductor area (more field lines) |
|||
- Smaller separation (stronger field concentration) |
|||
|
|||
## Self-Capacitance vs Mutual Capacitance |
|||
|
|||
**Self-capacitance:** Capacitance of a single conductor to infinity (or ground) |
|||
- Topload has self-capacitance to ground |
|||
- Depends on size and shape |
|||
- Toroid: C ≈ 4πε₀√(D×d) where D = major diameter, d = minor diameter |
|||
|
|||
**Mutual capacitance:** Capacitance between two conductors |
|||
- Energy stored in field between them |
|||
- Both conductors at different potentials |
|||
- Can be positive or negative in matrix formulation |
|||
|
|||
**For Tesla coils with sparks:** |
|||
- **C_mut:** mutual capacitance between topload and spark channel |
|||
- **C_sh:** capacitance from spark to ground (shunt capacitance) |
|||
|
|||
## Shunt Capacitance and the 2 pF/Foot Rule |
|||
|
|||
Any conductor elevated above ground has capacitance to ground. |
|||
|
|||
**For vertical wire above ground plane:** |
|||
``` |
|||
C ≈ 2πε₀L / ln(2h/d) |
|||
|
|||
where L = wire length |
|||
h = height above ground |
|||
d = wire diameter |
|||
``` |
|||
|
|||
**For Tesla coil sparks:** Empirical rule based on community measurements: |
|||
``` |
|||
C_sh ≈ 2 pF per foot of spark length |
|||
|
|||
Examples: |
|||
1 foot (0.3 m) spark: C_sh ≈ 2 pF |
|||
3 feet (0.9 m) spark: C_sh ≈ 6 pF |
|||
6 feet (1.8 m) spark: C_sh ≈ 12 pF |
|||
``` |
|||
|
|||
This rule is surprisingly accurate (±30%) for typical Tesla coil geometries. |
|||
|
|||
### Worked Example: Estimating C_sh |
|||
|
|||
**Given:** A 2-meter (6.6 foot) spark |
|||
|
|||
**Find:** Estimated shunt capacitance |
|||
|
|||
**Solution:** |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 6.6 feet |
|||
C_sh ≈ 13.2 pF |
|||
``` |
|||
|
|||
**Refined estimate using cylinder formula:** |
|||
|
|||
Assume spark is vertical cylinder: |
|||
- Length L = 2 m |
|||
- Diameter d = 2 mm (typical for bright spark) |
|||
- Height above ground h = L/2 = 1 m (average height) |
|||
|
|||
``` |
|||
C ≈ 2πε₀L / ln(2h/d) |
|||
C ≈ 2π × 8.854×10⁻¹² × 2 / ln(2×1/0.002) |
|||
C ≈ 1.112×10⁻¹⁰ / ln(1000) |
|||
C ≈ 1.112×10⁻¹⁰ / 6.91 |
|||
C ≈ 16 pF |
|||
``` |
|||
|
|||
The empirical rule (13 pF) and formula (16 pF) agree reasonably well. |
|||
|
|||
## Why Sparks Have TWO Capacitances |
|||
|
|||
A spark channel is a conductor in space with: |
|||
1. **Proximity to the topload** → mutual capacitance C_mut |
|||
2. **Proximity to ground/environment** → shunt capacitance C_sh |
|||
|
|||
**Both exist simultaneously** because the spark interacts with multiple conductors. |
|||
|
|||
**Analogy:** A wire near two metal plates |
|||
- Capacitance to plate 1: C₁ |
|||
- Capacitance to plate 2: C₂ |
|||
- Both must be included in the circuit model |
|||
|
|||
 |
|||
|
|||
**Field line visualization:** |
|||
- **C_mut field lines:** Connect topload surface to spark channel |
|||
- Start on topload outer surface |
|||
- End on spark channel surface |
|||
- Concentrated near base of spark |
|||
- These store mutual electric field energy |
|||
|
|||
- **C_sh field lines:** Connect spark to remote ground |
|||
- Start on spark surface |
|||
- Radiate outward to walls, floor, ceiling |
|||
- Distributed along entire spark length |
|||
- These store shunt field energy |
|||
|
|||
**Key observation:** The same spark channel participates in BOTH capacitances! This is why we need a specific circuit topology. |
|||
|
|||
## The Correct Circuit Topology |
|||
|
|||
``` |
|||
Topload (measurement reference) |
|||
| |
|||
[C_mut] ← Mutual capacitance between topload and spark |
|||
| |
|||
+---------+--------- Node_spark |
|||
| | |
|||
[R] [C_sh] ← Shunt capacitance spark-to-ground |
|||
| | |
|||
GND ------------ GND |
|||
``` |
|||
|
|||
**Equivalent description:** |
|||
- C_mut and R in parallel |
|||
- That parallel combination in series with C_sh |
|||
- All connected between topload and ground |
|||
|
|||
**Why this topology?** |
|||
1. C_mut couples topload voltage to spark |
|||
2. R represents plasma resistance (where power is dissipated) |
|||
3. C_sh provides current return path to ground |
|||
4. Current through R must also flow through either C_mut or C_sh (series connection) |
|||
|
|||
## Where is "Ground" in a Tesla Coil? |
|||
|
|||
**Earth ground:** Actual connection to soil/building ground |
|||
**Circuit ground (reference):** Arbitrary 0V reference point |
|||
|
|||
**For Tesla coils:** |
|||
- Primary circuit: Chassis/mains ground is reference |
|||
- Secondary base: Usually connected to primary ground via RF ground |
|||
- **Practical ground:** Floor, walls, nearby objects, you standing nearby |
|||
- **Measurement ground:** Choose ONE point as 0V reference (usually secondary base) |
|||
|
|||
**Important:** "Ground" in spark model means "remote return path" - could be walls, floor, strike ring, or actual earth. |
|||
|
|||
## The Topload Port |
|||
|
|||
**Definition:** The two-terminal measurement point between topload and ground where we characterize impedance and power. |
|||
|
|||
``` |
|||
Port definition: |
|||
Terminal 1: Topload terminal (high voltage) |
|||
Terminal 2: Ground reference (0V) |
|||
``` |
|||
|
|||
**All impedance measurements reference this port:** |
|||
- Z_spark: impedance looking into spark from topload |
|||
- Z_th: Thévenin impedance of coil at this port |
|||
- V_th: Open-circuit voltage at this port |
|||
|
|||
**Not the same as:** |
|||
- V_top / I_base (includes displacement currents from entire secondary) |
|||
- Any two-point measurement along the secondary winding |
|||
|
|||
We'll explore why V_top/I_base is incorrect in a later lesson. |
|||
|
|||
## Worked Example: Drawing the Complete Circuit |
|||
|
|||
**Given:** |
|||
- Spark is 3 feet long |
|||
- FEMM analysis gives C_mut = 8 pF (between topload and spark) |
|||
- Assume R = 100 kΩ |
|||
- Estimate C_sh using empirical rule |
|||
|
|||
**Task:** Draw complete circuit diagram |
|||
|
|||
**Solution:** |
|||
|
|||
Step 1: Calculate C_sh |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 3 feet = 6 pF |
|||
``` |
|||
|
|||
Step 2: Draw topology |
|||
``` |
|||
Topload (V_top) |
|||
| |
|||
[C_mut = 8 pF] |
|||
| |
|||
+-------- Node_spark |
|||
| | |
|||
[R = 100 kΩ] [C_sh = 6 pF] |
|||
| | |
|||
GND -------- GND |
|||
``` |
|||
|
|||
Step 3: Alternative representation showing parallel/series structure |
|||
``` |
|||
Topload |
|||
| |
|||
+---- [C_mut = 8 pF] ----+ |
|||
| | |
|||
+---- [R = 100 kΩ] ------+ Node_spark |
|||
| |
|||
[C_sh = 6 pF] |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
This is the basic lumped model for a Tesla coil spark. |
|||
|
|||
 |
|||
|
|||
## Key Takeaways |
|||
|
|||
- Capacitance stores energy in electric fields, depends on geometry |
|||
- **C_mut:** mutual capacitance between topload and spark |
|||
- **C_sh:** shunt capacitance from spark to ground, approximately **2 pF/foot** |
|||
- Both capacitances exist simultaneously on the same conductor |
|||
- **Correct topology:** (R || C_mut) in series with C_sh |
|||
- **Topload port:** measurement reference between topload and ground |
|||
- Ground means "remote return path" in this context |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-02} |
|||
|
|||
**Problem 1:** Draw the circuit for a spark with: L = 5 feet, C_mut = 12 pF (from FEMM), R = 50 kΩ. Label all component values. |
|||
|
|||
**Problem 2:** A simulation shows C_sh = 10 pF for a given spark. What is the estimated spark length using the empirical rule? |
|||
|
|||
**Problem 3:** A 4-foot spark is formed. Estimate C_sh using the empirical rule. If the topload has C_topload = 30 pF unloaded, what is the total system capacitance with the spark? (Hint: Consider how C_mut and C_sh combine in the circuit.) |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [Admittance Analysis](03-admittance-analysis.md) |
|||
@ -0,0 +1,265 @@ |
|||
--- |
|||
id: fund-03 |
|||
title: "Admittance Analysis of the Spark Circuit" |
|||
section: "Fundamentals" |
|||
difficulty: "intermediate" |
|||
estimated_time: 30 |
|||
prerequisites: ["fund-01", "fund-02"] |
|||
objectives: |
|||
- Understand why admittance is preferred over impedance for parallel circuits |
|||
- Derive the total admittance formula for the spark circuit |
|||
- Calculate real and imaginary parts of admittance |
|||
- Convert between admittance and impedance representations |
|||
- Apply formulas to practical Tesla coil examples |
|||
tags: ["admittance", "circuit-analysis", "complex-algebra", "formulas"] |
|||
--- |
|||
|
|||
# Admittance Analysis of the Spark Circuit |
|||
|
|||
## Introduction |
|||
|
|||
The spark circuit topology (R || C_mut in series with C_sh) requires careful analysis. While we could work entirely with impedances, using admittance simplifies the parallel combination and provides clearer insight into circuit behavior. |
|||
|
|||
## Why Use Admittance? |
|||
|
|||
For the spark circuit topology (parallel R||C_mut, in series with C_sh), admittance simplifies calculations. |
|||
|
|||
**Parallel elements:** Add admittances directly |
|||
``` |
|||
Y_total = Y₁ + Y₂ + Y₃ + ... |
|||
vs impedances: 1/Z_total = 1/Z₁ + 1/Z₂ + ... (messy!) |
|||
``` |
|||
|
|||
**Our circuit:** |
|||
``` |
|||
Y_mut_R = Y_Cmut + Y_R (parallel: C_mut || R) |
|||
Then series with C_sh requires impedance: Z = Z_mut_R + Z_Csh |
|||
Then convert back: Y_total = 1/Z_total |
|||
``` |
|||
|
|||
Admittance makes the first step (parallel combination) trivial, and we only need to handle the series combination once. |
|||
|
|||
## Deriving the Total Admittance Formula |
|||
|
|||
Let's work through the complete derivation step by step. |
|||
|
|||
**Step 1:** Admittance of R and C_mut in parallel |
|||
|
|||
``` |
|||
Y_R = G = 1/R |
|||
Y_Cmut = jωC_mut = jB₁ (where B₁ = ωC_mut) |
|||
|
|||
Y_mut_R = G + jB₁ |
|||
``` |
|||
|
|||
**Step 2:** Convert to impedance for series combination |
|||
|
|||
``` |
|||
Z_mut_R = 1/(G + jB₁) |
|||
``` |
|||
|
|||
**Step 3:** Add impedance of C_sh in series |
|||
|
|||
``` |
|||
Z_Csh = 1/(jωC_sh) = -j/(ωC_sh) = 1/(jB₂) (where B₂ = ωC_sh) |
|||
|
|||
Z_total = Z_mut_R + Z_Csh |
|||
Z_total = 1/(G + jB₁) + 1/(jB₂) |
|||
``` |
|||
|
|||
**Step 4:** Find common denominator |
|||
|
|||
``` |
|||
Z_total = [jB₂ + (G + jB₁)] / [(G + jB₁) × jB₂] |
|||
Z_total = [G + j(B₁ + B₂)] / [jB₂(G + jB₁)] |
|||
``` |
|||
|
|||
**Step 5:** Invert to get admittance |
|||
|
|||
``` |
|||
Y_total = 1/Z_total = [jB₂(G + jB₁)] / [G + j(B₁ + B₂)] |
|||
|
|||
Y_total = [(G + jB₁) × jB₂] / [G + j(B₁ + B₂)] |
|||
``` |
|||
|
|||
This is the **fundamental admittance equation** for the spark circuit. |
|||
|
|||
## Extracting Real and Imaginary Parts |
|||
|
|||
To use this formula, we need to separate it into Re{Y} and Im{Y}. |
|||
|
|||
Multiply numerator: |
|||
``` |
|||
(G + jB₁) × jB₂ = jGB₂ + j²B₁B₂ = jGB₂ - B₁B₂ |
|||
= -B₁B₂ + jGB₂ |
|||
``` |
|||
|
|||
So: |
|||
``` |
|||
Y = [-B₁B₂ + jGB₂] / [G + j(B₁ + B₂)] |
|||
``` |
|||
|
|||
To separate real and imaginary parts, multiply numerator and denominator by complex conjugate of denominator: |
|||
|
|||
``` |
|||
Denominator conjugate: G - j(B₁ + B₂) |
|||
Denominator magnitude squared: G² + (B₁ + B₂)² |
|||
``` |
|||
|
|||
After algebra (multiply out and simplify): |
|||
|
|||
``` |
|||
Re{Y} = GB₂² / [G² + (B₁ + B₂)²] |
|||
|
|||
Im{Y} = B₂[G² + B₁(B₁ + B₂)] / [G² + (B₁ + B₂)²] |
|||
``` |
|||
|
|||
These are the **working formulas** for calculating admittance from R, C_mut, C_sh. |
|||
|
|||
### Formula Summary |
|||
|
|||
Given R, C_mut, C_sh, and frequency f: |
|||
|
|||
**Step 1:** Calculate component values |
|||
``` |
|||
ω = 2πf |
|||
G = 1/R |
|||
B₁ = ωC_mut |
|||
B₂ = ωC_sh |
|||
``` |
|||
|
|||
**Step 2:** Calculate admittance |
|||
``` |
|||
Re{Y} = GB₂² / [G² + (B₁ + B₂)²] |
|||
|
|||
Im{Y} = B₂[G² + B₁(B₁ + B₂)] / [G² + (B₁ + B₂)²] |
|||
|
|||
Y = Re{Y} + j×Im{Y} |
|||
``` |
|||
|
|||
**Step 3:** Magnitude and phase |
|||
``` |
|||
|Y| = √[Re{Y}² + Im{Y}²] |
|||
φ_Y = atan(Im{Y}/Re{Y}) |
|||
``` |
|||
|
|||
## Converting to Impedance |
|||
|
|||
From Y = G_total + jB_total: |
|||
|
|||
``` |
|||
Z = 1/Y = 1/(G_total + jB_total) |
|||
|
|||
Multiply by conjugate: |
|||
Z = (G_total - jB_total) / (G_total² + B_total²) |
|||
|
|||
R_total = G_total / (G_total² + B_total²) |
|||
X_total = -B_total / (G_total² + B_total²) |
|||
|
|||
Or directly: |
|||
|Z| = 1/|Y| |
|||
φ_Z = -φ_Y (opposite sign!) |
|||
``` |
|||
|
|||
## Worked Example: Complete Y and Z Calculation |
|||
|
|||
**Given:** |
|||
- Frequency: f = 200 kHz → ω = 2π × 200×10³ = 1.257×10⁶ rad/s |
|||
- C_mut = 8 pF = 8×10⁻¹² F |
|||
- C_sh = 6 pF = 6×10⁻¹² F |
|||
- R = 100 kΩ = 10⁵ Ω |
|||
|
|||
**Find:** Y_total (rectangular), Z_total (rectangular and polar) |
|||
|
|||
**Solution:** |
|||
|
|||
Step 1: Calculate component values |
|||
``` |
|||
G = 1/R = 1/(10⁵) = 10⁻⁵ S = 10 μS |
|||
B₁ = ωC_mut = 1.257×10⁶ × 8×10⁻¹² = 10.06×10⁻⁶ S = 10.06 μS |
|||
B₂ = ωC_sh = 1.257×10⁶ × 6×10⁻¹² = 7.54×10⁻⁶ S = 7.54 μS |
|||
``` |
|||
|
|||
Step 2: Calculate Re{Y} |
|||
``` |
|||
Re{Y} = GB₂² / [G² + (B₁ + B₂)²] |
|||
|
|||
Numerator: 10 × (7.54)² = 10 × 56.85 = 568.5 μS² |
|||
Denominator: (10)² + (10.06 + 7.54)² = 100 + (17.6)² = 100 + 309.8 = 409.8 μS² |
|||
|
|||
Re{Y} = 568.5 / 409.8 = 1.387 μS |
|||
``` |
|||
|
|||
Step 3: Calculate Im{Y} |
|||
``` |
|||
Im{Y} = B₂[G² + B₁(B₁ + B₂)] / [G² + (B₁ + B₂)²] |
|||
|
|||
Numerator inner: G² + B₁(B₁ + B₂) = 100 + 10.06×17.6 = 100 + 177.1 = 277.1 μS² |
|||
Numerator: 7.54 × 277.1 = 2089.3 μS³ |
|||
Denominator: 409.8 μS² (same as before) |
|||
|
|||
Im{Y} = 2089.3 / 409.8 = 5.10 μS |
|||
``` |
|||
|
|||
Step 4: Admittance result |
|||
``` |
|||
Y_total = 1.387 + j5.10 μS |
|||
|Y| = √(1.387² + 5.10²) = √(1.92 + 26.01) = √27.93 = 5.28 μS |
|||
φ_Y = atan(5.10/1.387) = atan(3.68) = 74.8° |
|||
``` |
|||
|
|||
Step 5: Convert to impedance |
|||
``` |
|||
|Z| = 1/|Y| = 1/(5.28×10⁻⁶) = 189 kΩ |
|||
φ_Z = -φ_Y = -74.8° |
|||
|
|||
In rectangular: |
|||
R_total = |Z| × cos(φ_Z) = 189 × cos(-74.8°) = 189 × 0.263 = 49.7 kΩ |
|||
X_total = |Z| × sin(φ_Z) = 189 × sin(-74.8°) = 189 × (-0.965) = -182 kΩ |
|||
|
|||
Z_total = 49.7 - j182 kΩ = 189 kΩ ∠-74.8° |
|||
``` |
|||
|
|||
**Interpretation:** |
|||
- Impedance is strongly capacitive (φ_Z = -74.8°) |
|||
- Equivalent resistance ≈ 50 kΩ (half of actual R due to capacitive divider) |
|||
- Large capacitive reactance dominates |
|||
|
|||
 |
|||
|
|||
**Visualization notes:** |
|||
- LEFT: Admittance plane (Y = G + jB) |
|||
- Point at (1.387, 5.10) μS |
|||
- Angle φ_Y = 74.8° from horizontal |
|||
- Positive B means capacitive in admittance |
|||
|
|||
- RIGHT: Impedance plane (Z = R + jX) |
|||
- Point at (49.7, -182) kΩ |
|||
- Angle φ_Z = -74.8° below horizontal |
|||
- Negative X means capacitive in impedance |
|||
|
|||
- Connection: Angles are opposite (φ_Z = -φ_Y), magnitudes invert (|Z| = 1/|Y|) |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Admittance simplifies parallel combinations:** Y_parallel = Y₁ + Y₂ + ... |
|||
- **Fundamental formula:** Y = [(G + jB₁) × jB₂] / [G + j(B₁ + B₂)] |
|||
- **Working formulas:** |
|||
- Re{Y} = GB₂² / [G² + (B₁ + B₂)²] |
|||
- Im{Y} = B₂[G² + B₁(B₁ + B₂)] / [G² + (B₁ + B₂)²] |
|||
- **Conversion:** |Z| = 1/|Y| and φ_Z = -φ_Y |
|||
- Typical spark: strongly capacitive with large |Im{Y}| compared to Re{Y} |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-03} |
|||
|
|||
**Problem 1:** For f = 150 kHz, C_mut = 10 pF, C_sh = 8 pF, R = 80 kΩ, calculate Y_total (real and imaginary parts). |
|||
|
|||
**Problem 2:** An admittance Y = 2.0 + j4.5 μS. Convert to impedance Z in both rectangular and polar forms. |
|||
|
|||
**Problem 3:** Show algebraically that if R → ∞ (open circuit), the formula reduces to Y = jωC_mut × C_sh/(C_mut + C_sh), which is two capacitors in series. |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [Phase Angles and Their Meaning](04-phase-angles.md) |
|||
@ -0,0 +1,203 @@ |
|||
--- |
|||
id: fund-04 |
|||
title: "Phase Angles and What They Mean" |
|||
section: "Fundamentals" |
|||
difficulty: "beginner" |
|||
estimated_time: 20 |
|||
prerequisites: ["fund-01", "fund-02", "fund-03"] |
|||
objectives: |
|||
- Distinguish between impedance phase φ_Z and admittance phase φ_Y |
|||
- Understand the relationship φ_Z = -φ_Y |
|||
- Interpret the physical meaning of different phase angles |
|||
- Learn why -45° is considered "balanced" |
|||
- Recognize typical phase angles for Tesla coil sparks |
|||
tags: ["phase-angle", "impedance", "admittance", "power-factor"] |
|||
--- |
|||
|
|||
# Phase Angles and What They Mean |
|||
|
|||
## Introduction |
|||
|
|||
Phase angles tell us about the balance between resistive and reactive components in our circuit. Understanding what different phase angles mean physically helps us interpret circuit behavior and optimize performance. |
|||
|
|||
## Impedance Phase vs Admittance Phase |
|||
|
|||
**Impedance phase angle φ_Z:** |
|||
``` |
|||
φ_Z = atan(X/R) = atan(Im{Z}/Re{Z}) |
|||
|
|||
Interpretation: |
|||
φ_Z > 0: inductive (current lags voltage) |
|||
φ_Z = 0: purely resistive (in phase) |
|||
φ_Z < 0: capacitive (current leads voltage) |
|||
``` |
|||
|
|||
**Admittance phase angle θ_Y:** |
|||
``` |
|||
θ_Y = atan(B/G) = atan(Im{Y}/Re{Y}) |
|||
|
|||
Relationship: θ_Y = -φ_Z (OPPOSITE SIGNS!) |
|||
``` |
|||
|
|||
**Why opposite?** Because Y = 1/Z, so angles subtract: |
|||
``` |
|||
If Z = |Z|∠φ_Z, then Y = (1/|Z|)∠(-φ_Z) |
|||
``` |
|||
|
|||
**Convention in this framework:** We primarily discuss **impedance phase φ_Z** because that's what measurements typically report. |
|||
|
|||
## The "Famous -45°" and Why It's Special |
|||
|
|||
In power electronics, a load with φ_Z = -45° is sometimes called "well-matched" because: |
|||
- Equal resistive and capacitive components: |R| = |X_C| |
|||
- Power factor = cos(-45°) = 0.707 (reasonable power transfer) |
|||
- Not maximum power transfer, but balanced |
|||
|
|||
**Formula:** For φ_Z = -45°: |
|||
``` |
|||
tan(-45°) = -1 = X/R |
|||
Therefore: R = |X| = 1/(ωC) for capacitive load |
|||
Or: R ≈ |X_C| = 1/(ωC_total) approximately |
|||
``` |
|||
|
|||
This is why you'll see "spark resistance should equal capacitive reactance" in old Tesla coil literature. |
|||
|
|||
**BUT:** As we'll see in the next lesson, achieving exactly -45° is **impossible** for many Tesla coil geometries due to topological constraints! |
|||
|
|||
## Physical Meaning of Phase Angle |
|||
|
|||
Let's explore what different phase angles mean for circuit behavior. |
|||
|
|||
**φ_Z = 0° (purely resistive):** |
|||
- All power dissipated |
|||
- No energy storage/return |
|||
- Voltage and current in phase |
|||
- Power factor = cos(0°) = 1.0 (100%) |
|||
|
|||
**φ_Z = -45° (mixed):** |
|||
- Some power dissipated (cos(-45°) ≈ 71% of |V||I|) |
|||
- Some energy stored |
|||
- Current leads voltage by 45° |
|||
- Equal R and |X|: balanced condition |
|||
|
|||
**φ_Z = -90° (purely capacitive):** |
|||
- No power dissipated |
|||
- All energy stored and returned each cycle |
|||
- Current leads voltage by 90° |
|||
- Power factor = cos(-90°) = 0 (no real power) |
|||
|
|||
**For Tesla coil sparks:** Typical φ_Z = -55° to -75° |
|||
- Significant capacitive component (energy storage in C_mut, C_sh) |
|||
- Moderate power dissipation (plasma heating) |
|||
- More capacitive than the "ideal" -45° |
|||
|
|||
## Worked Example: Calculating and Interpreting Phase Angle |
|||
|
|||
**Given:** (from previous lesson) |
|||
- Z_total = 49.7 - j182 kΩ |
|||
|
|||
**Find:** φ_Z and interpret |
|||
|
|||
**Solution:** |
|||
|
|||
Step 1: Calculate phase angle |
|||
``` |
|||
φ_Z = atan(X/R) = atan(-182/49.7) |
|||
φ_Z = atan(-3.66) = -74.8° |
|||
``` |
|||
|
|||
Step 2: Verify with magnitude and components |
|||
``` |
|||
|Z| = √(49.7² + 182²) = √(2470 + 33124) = √35594 = 189 kΩ ✓ |
|||
|
|||
cos(φ_Z) = R/|Z| = 49.7/189 = 0.263 |
|||
φ_Z = arccos(0.263) = 74.8°, but X is negative, so φ_Z = -74.8° ✓ |
|||
``` |
|||
|
|||
Step 3: Interpret |
|||
- **Strongly capacitive:** |φ_Z| = 74.8° is much larger than 45° |
|||
- **Comparison:** |R| = 49.7 kΩ, but |X| = 182 kΩ |
|||
- Capacitive reactance is 3.66× larger than resistance |
|||
- Far from "balanced" -45° condition |
|||
- **Power factor:** cos(-74.8°) = 0.263 |
|||
- Only 26.3% of |V||I| is real power |
|||
- Most current is reactive (charging/discharging capacitances) |
|||
|
|||
This is typical for Tesla coil sparks: strongly capacitive impedance. |
|||
|
|||
## Visualizing Phase Angles |
|||
|
|||
 |
|||
|
|||
**Impedance plane (Z = R + jX):** |
|||
|
|||
Three key vectors from origin: |
|||
|
|||
1. **Resistive (φ_Z = 0°):** |
|||
- Horizontal vector along R axis |
|||
- Pure resistance, no reactance |
|||
- All power dissipated |
|||
|
|||
2. **Balanced (φ_Z = -45°):** |
|||
- Vector at -45° angle |
|||
- Equal R and |X| |
|||
- Traditional "well-matched" condition |
|||
|
|||
3. **Typical spark (φ_Z = -75°):** |
|||
- Vector at -75° angle |
|||
- Strongly capacitive |
|||
- |X| >> R |
|||
|
|||
**Key regions:** |
|||
- φ_Z = 0°: Pure resistance (horizontal axis) |
|||
- φ_Z = -45°: Balanced point |
|||
- -45° to -90°: Typical Tesla coil spark range (shaded region) |
|||
- φ_Z = -90°: Pure capacitor (vertical downward) |
|||
|
|||
**Note:** More negative φ_Z means more capacitive behavior |
|||
|
|||
## Relationship to Power Factor |
|||
|
|||
The power factor relates phase angle to real power delivery: |
|||
|
|||
``` |
|||
Power Factor = cos(φ_Z) |
|||
|
|||
Real Power: P = 0.5 × |V| × |I| × cos(φ_Z) |
|||
Reactive Power: Q = 0.5 × |V| × |I| × sin(φ_Z) |
|||
``` |
|||
|
|||
**Examples:** |
|||
| φ_Z | Power Factor | % of Maximum Power | |
|||
|-----|--------------|-------------------| |
|||
| 0° | 1.00 | 100% | |
|||
| -30° | 0.866 | 86.6% | |
|||
| -45° | 0.707 | 70.7% | |
|||
| -60° | 0.500 | 50.0% | |
|||
| -75° | 0.259 | 25.9% | |
|||
| -90° | 0.000 | 0% | |
|||
|
|||
Tesla coil sparks typically operate at 25-50% power factor - much energy is reactive (stored and returned each cycle) rather than dissipated in the plasma. |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Phase relationship:** φ_Z = -φ_Y (opposite signs) |
|||
- **Negative φ_Z:** means capacitive (current leads voltage) |
|||
- **φ_Z = -45°:** balanced condition with R = |X| |
|||
- **Typical sparks:** φ_Z ≈ -55° to -75° (strongly capacitive) |
|||
- **Power factor:** cos(φ_Z) determines fraction of power dissipated |
|||
- More capacitive → lower power factor → less efficient power transfer |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-04} |
|||
|
|||
**Problem 1:** An impedance Z = 60 + j40 kΩ. Calculate φ_Z. Is this inductive or capacitive? |
|||
|
|||
**Problem 2:** A spark has φ_Z = -60°. If |Z| = 150 kΩ, find R and X. Calculate the power factor. |
|||
|
|||
**Problem 3:** Two sparks have the same |Z| = 200 kΩ. Spark A has φ_Z = -50°, Spark B has φ_Z = -70°. Which dissipates more power for the same applied voltage? By what factor? |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [The Phase Constraint](05-phase-constraint.md) |
|||
@ -0,0 +1,235 @@ |
|||
--- |
|||
id: fund-05 |
|||
title: "The Topological Phase Constraint" |
|||
section: "Fundamentals" |
|||
difficulty: "intermediate" |
|||
estimated_time: 25 |
|||
prerequisites: ["fund-01", "fund-02", "fund-03", "fund-04"] |
|||
objectives: |
|||
- Understand what a topological constraint is |
|||
- Derive the minimum achievable phase angle φ_Z,min |
|||
- Learn the critical capacitance ratio r = C_mut/C_sh |
|||
- Calculate φ_Z,min for typical Tesla coil geometries |
|||
- Understand R_opt_phase that achieves minimum phase |
|||
tags: ["topology", "phase-constraint", "optimization", "mathematical-limit"] |
|||
--- |
|||
|
|||
# The Topological Phase Constraint |
|||
|
|||
## Introduction |
|||
|
|||
Can we make a spark look purely resistive (φ_Z = 0°)? Can we at least achieve the "balanced" -45° condition? Surprisingly, the circuit topology itself imposes fundamental limits on what phase angles are achievable, regardless of component values. |
|||
|
|||
## What is a Topological Constraint? |
|||
|
|||
**Definition:** A limitation imposed by the **structure** of the circuit itself, independent of component values. |
|||
|
|||
**Example:** Series RLC circuit |
|||
- Can only have impedance phase between -90° (pure C) and +90° (pure L) |
|||
- Cannot have φ_Z = +120° no matter what component values you choose |
|||
- This is a topological constraint |
|||
|
|||
**For spark circuits:** The specific arrangement (R||C_mut) in series with C_sh creates a fundamental limit on how resistive the impedance can appear. |
|||
|
|||
## Deriving the Minimum Phase Angle |
|||
|
|||
From our previous lesson, we have: |
|||
``` |
|||
Y = [(G + jB₁) × jB₂] / [G + j(B₁ + B₂)] |
|||
|
|||
where G = 1/R, B₁ = ωC_mut, B₂ = ωC_sh |
|||
``` |
|||
|
|||
The impedance phase is: |
|||
``` |
|||
φ_Z = atan(-Im{Y}/Re{Y}) |
|||
``` |
|||
|
|||
**Question:** For fixed C_mut and C_sh, which R value minimizes |φ_Z| (makes most resistive)? |
|||
|
|||
**Mathematical result:** Taking derivative ∂φ_Z/∂G = 0 and solving: |
|||
``` |
|||
G_opt = ω√[C_mut(C_mut + C_sh)] |
|||
|
|||
Therefore: |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
``` |
|||
|
|||
At this resistance, the phase angle magnitude is minimized to: |
|||
``` |
|||
φ_Z,min = -atan(2√[r(1 + r)]) |
|||
|
|||
where r = C_mut/C_sh (capacitance ratio) |
|||
``` |
|||
|
|||
**Key insight:** φ_Z,min depends only on the ratio r, not on absolute capacitance values or frequency! |
|||
|
|||
## The Critical Ratio r = 0.207 |
|||
|
|||
Let's find when φ_Z,min = -45° is achievable: |
|||
``` |
|||
-45° = -atan(2√[r(1 + r)]) |
|||
tan(45°) = 1 = 2√[r(1 + r)] |
|||
0.5 = √[r(1 + r)] |
|||
0.25 = r(1 + r) = r + r² |
|||
r² + r - 0.25 = 0 |
|||
|
|||
Using quadratic formula: |
|||
r = [-1 ± √(1 + 1)] / 2 = [-1 ± √2] / 2 |
|||
|
|||
Taking positive root: |
|||
r = (√2 - 1) / 2 ≈ 0.207 |
|||
``` |
|||
|
|||
**Critical insight:** |
|||
- If **r < 0.207:** Can achieve φ_Z = -45° (with appropriate R) |
|||
- If **r = 0.207:** Minimum achievable phase is exactly -45° |
|||
- If **r > 0.207:** **Cannot achieve φ_Z = -45° no matter what R you choose!** |
|||
- If r ≥ 0.207: φ_Z,min is more negative than -45° |
|||
|
|||
## Typical Tesla Coil Values |
|||
|
|||
Let's examine realistic scenarios: |
|||
|
|||
**Large topload, short spark:** |
|||
``` |
|||
C_mut = 10 pF, C_sh = 4 pF (2 feet) |
|||
r = 10/4 = 2.5 |
|||
|
|||
φ_Z,min = -atan(2√[2.5 × 3.5]) = -atan(2 × 2.96) = -atan(5.92) = -80.4° |
|||
``` |
|||
|
|||
**Medium configuration:** |
|||
``` |
|||
C_mut = 8 pF, C_sh = 6 pF (3 feet) |
|||
r = 8/6 = 1.33 |
|||
|
|||
φ_Z,min = -atan(2√[1.33 × 2.33]) = -atan(2 × 1.76) = -atan(3.53) = -74.2° |
|||
``` |
|||
|
|||
**Small topload, long spark:** |
|||
``` |
|||
C_mut = 6 pF, C_sh = 12 pF (6 feet) |
|||
r = 6/12 = 0.5 |
|||
|
|||
φ_Z,min = -atan(2√[0.5 × 1.5]) = -atan(2 × 0.866) = -atan(1.732) = -60.0° |
|||
``` |
|||
|
|||
**Common range:** r = 0.5 to 2.0, giving φ_Z,min ≈ -60° to -80° |
|||
|
|||
**Conclusion:** For most Tesla coil geometries, -45° is **mathematically impossible**! |
|||
|
|||
## Worked Example: Calculate Minimum Phase Angle |
|||
|
|||
**Given:** |
|||
- Frequency: f = 200 kHz |
|||
- C_mut = 8 pF |
|||
- C_sh = 6 pF |
|||
|
|||
**Find:** |
|||
(a) Capacitance ratio r |
|||
(b) Minimum achievable phase angle φ_Z,min |
|||
(c) R_opt_phase that achieves this angle |
|||
|
|||
**Solution:** |
|||
|
|||
**Part (a):** Capacitance ratio |
|||
``` |
|||
r = C_mut / C_sh = 8 / 6 = 1.333 |
|||
``` |
|||
|
|||
**Part (b):** Minimum phase angle |
|||
``` |
|||
φ_Z,min = -atan(2√[r(1 + r)]) |
|||
= -atan(2√[1.333 × 2.333]) |
|||
= -atan(2√3.11) |
|||
= -atan(2 × 1.764) |
|||
= -atan(3.528) |
|||
= -74.2° |
|||
``` |
|||
|
|||
**Part (c):** Resistance for minimum phase |
|||
``` |
|||
ω = 2πf = 2π × 200×10³ = 1.257×10⁶ rad/s |
|||
|
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
= 1 / [1.257×10⁶ × √(8×10⁻¹² × 14×10⁻¹²)] |
|||
= 1 / [1.257×10⁶ × √(112×10⁻²⁴)] |
|||
= 1 / [1.257×10⁶ × 10.58×10⁻¹²] |
|||
= 1 / (13.30×10⁻⁶) |
|||
= 75.2 kΩ |
|||
``` |
|||
|
|||
**Interpretation:** |
|||
- With r = 1.333, cannot achieve -45° |
|||
- Best possible is -74.2° (much more capacitive) |
|||
- This requires R = 75.2 kΩ |
|||
- Any other R value gives |φ_Z| > 74.2° |
|||
|
|||
## Understanding the Constraint Graphically |
|||
|
|||
 |
|||
|
|||
**Graph characteristics:** |
|||
- X-axis: r = C_mut/C_sh (log scale), range 0.1 to 10 |
|||
- Y-axis: φ_Z,min (degrees), range -90° to -40° |
|||
- Curve: φ_Z,min = -atan(2√[r(1+r)]) |
|||
|
|||
**Key features:** |
|||
- r = 0.207 marked: φ_Z,min = -45° (horizontal dashed line) |
|||
- Region r < 0.207 (shaded): "Can achieve -45°" |
|||
- Region r > 0.207 (different shade): "Cannot achieve -45°" |
|||
- Typical Tesla coil range r = 0.5 to 2.0 highlighted |
|||
|
|||
**Example points:** |
|||
- r = 0.1: φ_Z,min ≈ -35° |
|||
- r = 0.207: φ_Z,min = -45° (critical point) |
|||
- r = 0.5: φ_Z,min = -60° |
|||
- r = 1.0: φ_Z,min = -70.5° |
|||
- r = 2.0: φ_Z,min = -79.7° |
|||
- r = 5.0: φ_Z,min = -84.5° |
|||
|
|||
**Trends:** |
|||
- Larger r → more capacitive minimum |
|||
- Large topload + short spark → high r → very capacitive |
|||
- Small topload + long spark → low r → less capacitive (but still > -45° usually) |
|||
|
|||
## Physical Interpretation |
|||
|
|||
**Why does this constraint exist?** |
|||
|
|||
The series connection of C_sh means current must flow through it to reach ground. This creates a capacitive voltage drop that can never be completely eliminated, no matter how you adjust R. |
|||
|
|||
**Analogy:** Trying to make water flow uphill |
|||
- C_sh is like a mandatory uphill section in your pipe |
|||
- R adjusts resistance elsewhere, but can't remove the uphill section |
|||
- The uphill section imposes a minimum "difficulty" for flow |
|||
|
|||
**Engineering implications:** |
|||
1. Can't achieve purely resistive load (φ_Z = 0°) |
|||
2. Usually can't achieve "balanced" -45° condition |
|||
3. Must work with more capacitive phase angles |
|||
4. Power transfer is inherently less efficient than with purely resistive load |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Topological constraint:** Circuit structure limits achievable phase angles |
|||
- **Minimum phase:** φ_Z,min = -atan(2√[r(1 + r)]) where r = C_mut/C_sh |
|||
- **Critical ratio:** r = 0.207 allows exactly -45° |
|||
- **Typical range:** r = 0.5 to 2.0 → φ_Z,min ≈ -60° to -80° |
|||
- **Optimal resistance:** R_opt_phase = 1/[ω√(C_mut(C_mut + C_sh))] |
|||
- Most Tesla coils **cannot achieve -45°** due to geometry |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-05} |
|||
|
|||
**Problem 1:** Calculate r, φ_Z,min, and R_opt_phase for: f = 150 kHz, C_mut = 12 pF, C_sh = 8 pF. |
|||
|
|||
**Problem 2:** A coil designer wants to achieve φ_Z = -45°. If C_sh = 10 pF (5-foot spark), what maximum C_mut is allowed? |
|||
|
|||
**Problem 3:** Two coils have the same frequency and total capacitance (C_mut + C_sh = 20 pF). Coil A has r = 0.5, Coil B has r = 2.0. Which can achieve a more resistive phase angle? Calculate φ_Z,min for both. |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [Why Not -45 Degrees?](06-why-not-45-degrees.md) |
|||
@ -0,0 +1,238 @@ |
|||
--- |
|||
id: fund-06 |
|||
title: "Why Not -45 Degrees?" |
|||
section: "Fundamentals" |
|||
difficulty: "beginner" |
|||
estimated_time: 15 |
|||
prerequisites: ["fund-04", "fund-05"] |
|||
objectives: |
|||
- Understand the historical origin of the -45° target |
|||
- Recognize why -45° is often impossible for Tesla coils |
|||
- Distinguish between R_opt_phase and R_opt_power |
|||
- Learn what resistance values are actually optimal |
|||
tags: ["misconceptions", "optimization", "history", "phase-angle"] |
|||
--- |
|||
|
|||
# Why Not -45 Degrees? |
|||
|
|||
## Introduction |
|||
|
|||
If you've read Tesla coil literature or online discussions, you've probably encountered the advice: "Make the spark resistance equal to the capacitive reactance for -45° phase angle." This lesson explains where this comes from, why it's often impossible, and what you should actually target instead. |
|||
|
|||
## The Historical -45° Target |
|||
|
|||
### Where Did This Come From? |
|||
|
|||
In power electronics and RF engineering, a load with φ_Z = -45° has some appealing properties: |
|||
|
|||
**Mathematical simplicity:** |
|||
``` |
|||
φ_Z = -45° means tan(-45°) = -1 |
|||
Therefore: X/R = -1 |
|||
So: R = |X| |
|||
``` |
|||
|
|||
For a capacitive load: R = 1/(ωC_total) |
|||
|
|||
**Balanced characteristics:** |
|||
- Equal resistive and reactive components |
|||
- Power factor = cos(-45°) ≈ 0.707 |
|||
- Reasonable compromise between power delivery and energy storage |
|||
|
|||
**Easy to remember:** "Make resistance equal to reactance" |
|||
|
|||
### Why It Became Popular in Tesla Coil Literature |
|||
|
|||
Early Tesla coil experimenters borrowed concepts from radio engineering, where matching impedances for -45° was a common practice. The simple rule "R should equal capacitive reactance" was easy to communicate and remember. |
|||
|
|||
**The problem:** This advice doesn't account for the specific topology of the spark circuit! |
|||
|
|||
## The Reality: Why -45° is Often Impossible |
|||
|
|||
### The Topological Constraint |
|||
|
|||
As we learned in the previous lesson, the minimum achievable phase angle is: |
|||
``` |
|||
φ_Z,min = -atan(2√[r(1 + r)]) |
|||
|
|||
where r = C_mut/C_sh |
|||
``` |
|||
|
|||
**For -45° to be achievable:** r must be ≤ 0.207 |
|||
|
|||
**What this means:** |
|||
``` |
|||
C_mut/C_sh ≤ 0.207 |
|||
C_mut ≤ 0.207 × C_sh |
|||
``` |
|||
|
|||
### Realistic Tesla Coil Scenarios |
|||
|
|||
Let's check if typical geometries can achieve -45°: |
|||
|
|||
**Scenario 1: 3-foot spark, medium topload** |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 3 = 6 pF |
|||
C_mut ≈ 8 pF (from FEMM) |
|||
r = 8/6 = 1.33 |
|||
|
|||
Required for -45°: r ≤ 0.207 |
|||
Actual: r = 1.33 |
|||
|
|||
1.33 > 0.207 → Cannot achieve -45°! |
|||
φ_Z,min = -74.2° (actual minimum) |
|||
``` |
|||
|
|||
**Scenario 2: 5-foot spark, large topload** |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 5 = 10 pF |
|||
C_mut ≈ 12 pF (larger topload) |
|||
r = 12/10 = 1.2 |
|||
|
|||
1.2 > 0.207 → Cannot achieve -45°! |
|||
φ_Z,min = -71.6° (actual minimum) |
|||
``` |
|||
|
|||
**Scenario 3: 6-foot spark, small topload** |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 6 = 12 pF |
|||
C_mut ≈ 6 pF (minimal topload) |
|||
r = 6/12 = 0.5 |
|||
|
|||
0.5 > 0.207 → Still cannot achieve -45°! |
|||
φ_Z,min = -60° (actual minimum) |
|||
``` |
|||
|
|||
**The pattern:** Typical Tesla coils have r = 0.5 to 2.5, all well above the critical 0.207 threshold. |
|||
|
|||
### When CAN You Achieve -45°? |
|||
|
|||
You would need an extremely unusual geometry: |
|||
``` |
|||
If C_sh = 10 pF (5-foot spark) |
|||
Required: C_mut ≤ 0.207 × 10 = 2.07 pF |
|||
|
|||
This implies an extremely small topload with a very long spark! |
|||
``` |
|||
|
|||
Such configurations are rare because: |
|||
1. Small topload = lower voltage capability |
|||
2. Lower voltage = harder to initiate long sparks |
|||
3. Contradictory requirements for practical operation |
|||
|
|||
## What Should You Target Instead? |
|||
|
|||
### Two Different Optimal Resistances |
|||
|
|||
There are actually **two** different optimal resistance values with different purposes: |
|||
|
|||
**1. R_opt_phase:** Minimizes |φ_Z| (most resistive phase angle) |
|||
``` |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
|
|||
Achieves: φ_Z = φ_Z,min = -atan(2√[r(1+r)]) |
|||
``` |
|||
|
|||
**2. R_opt_power:** Maximizes power transfer to the load |
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
|
|||
Achieves: Maximum real power dissipation |
|||
``` |
|||
|
|||
**Important relationship:** |
|||
``` |
|||
R_opt_power < R_opt_phase (always!) |
|||
|
|||
Specifically: R_opt_power = R_opt_phase / √(1 + r) |
|||
``` |
|||
|
|||
### Which One Should You Use? |
|||
|
|||
**For Tesla coil sparks: Use R_opt_power!** |
|||
|
|||
**Why?** |
|||
1. Sparks need **power** to grow (energy per meter) |
|||
2. Maximum power = fastest growth = longest sparks |
|||
3. The "hungry streamer" naturally seeks R_opt_power |
|||
4. Phase angle is a consequence, not a goal |
|||
|
|||
**The -45° target is a red herring!** It doesn't maximize spark length or performance. |
|||
|
|||
## Worked Example: Comparing the Two Optima |
|||
|
|||
**Given:** |
|||
- f = 200 kHz → ω = 1.257×10⁶ rad/s |
|||
- C_mut = 8 pF |
|||
- C_sh = 6 pF |
|||
- r = 8/6 = 1.333 |
|||
|
|||
**Calculate both optimal resistances:** |
|||
|
|||
**R_opt_power:** |
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
= 1 / [1.257×10⁶ × (8 + 6)×10⁻¹²] |
|||
= 1 / [1.257×10⁶ × 14×10⁻¹²] |
|||
= 1 / (17.60×10⁻⁶) |
|||
= 56.8 kΩ |
|||
``` |
|||
|
|||
**R_opt_phase:** |
|||
``` |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
= 1 / [1.257×10⁶ × √(8 × 14)×10⁻¹²] |
|||
= 1 / [1.257×10⁶ × 10.58×10⁻¹²] |
|||
= 1 / (13.30×10⁻⁶) |
|||
= 75.2 kΩ |
|||
``` |
|||
|
|||
**Comparison:** |
|||
``` |
|||
R_opt_power = 56.8 kΩ → Maximizes power transfer |
|||
R_opt_phase = 75.2 kΩ → Minimizes |φ_Z| (= -74.2°) |
|||
|
|||
Ratio: R_opt_phase / R_opt_power = 75.2 / 56.8 = 1.32 = √(1 + r) ✓ |
|||
``` |
|||
|
|||
**What phase angle at R_opt_power?** |
|||
Using the admittance formulas with R = 56.8 kΩ would give φ_Z ≈ -78° (slightly more capacitive than the minimum -74.2°, but delivers more power!) |
|||
|
|||
## The Bottom Line |
|||
|
|||
**Common misconception:** |
|||
"Spark resistance should equal capacitive reactance for -45° phase angle." |
|||
|
|||
**Why it's wrong:** |
|||
1. **Topology prevents it:** r > 0.207 for typical geometries |
|||
2. **Wrong optimization target:** Should maximize power, not minimize |φ_Z| |
|||
3. **Ignores self-optimization:** Plasma adjusts to R_opt_power naturally |
|||
|
|||
**What to do instead:** |
|||
1. Calculate R_opt_power = 1/[ω(C_mut + C_sh)] |
|||
2. Expect φ_Z ≈ -60° to -80° (more capacitive than -45°) |
|||
3. Accept this is optimal for spark growth |
|||
4. Don't worry about achieving -45°! |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **-45° target:** Historical artifact from RF engineering |
|||
- **Usually impossible:** Requires r ≤ 0.207, but typical coils have r = 0.5 to 2.5 |
|||
- **Two optima:** R_opt_phase (most resistive) vs R_opt_power (maximum power) |
|||
- **Use R_opt_power:** Maximizes spark growth and length |
|||
- **Expect highly capacitive:** φ_Z ≈ -60° to -80° is normal and optimal |
|||
- **Don't chase -45°:** It's neither achievable nor desirable for most coils |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-06} |
|||
|
|||
**Problem 1:** For a coil with C_mut = 10 pF, C_sh = 8 pF, f = 180 kHz, calculate both R_opt_power and R_opt_phase. What is their ratio? |
|||
|
|||
**Problem 2:** A coil has r = 1.5. Can it achieve -45°? If not, what is φ_Z,min? Calculate the ratio R_opt_phase / R_opt_power and verify it equals √(1+r). |
|||
|
|||
**Problem 3:** Someone claims they achieved -45° on their Tesla coil. They measured C_sh = 8 pF for a 4-foot spark. What is the maximum C_mut their topload could have if this claim is true? Is this realistic? |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [The Measurement Port](07-measurement-port.md) |
|||
@ -0,0 +1,258 @@ |
|||
--- |
|||
id: fund-07 |
|||
title: "The Measurement Port and Why V_top/I_base is Wrong" |
|||
section: "Fundamentals" |
|||
difficulty: "intermediate" |
|||
estimated_time: 20 |
|||
prerequisites: ["fund-01", "fund-02"] |
|||
objectives: |
|||
- Understand what displacement current is and why it matters |
|||
- Recognize why V_top/I_base gives incorrect impedance |
|||
- Identify all current paths in a Tesla coil system |
|||
- Learn the correct measurement port definition |
|||
- Calculate power using the correct method |
|||
tags: ["measurement", "displacement-current", "power", "troubleshooting"] |
|||
--- |
|||
|
|||
# The Measurement Port and Why V_top/I_base is Wrong |
|||
|
|||
## Introduction |
|||
|
|||
One of the most common mistakes in Tesla coil analysis is using V_top/I_base to calculate spark impedance. This seems logical - measure the voltage at the top and the current at the base - but it gives completely wrong results. This lesson explains why and shows the correct approach. |
|||
|
|||
## The Displacement Current Problem |
|||
|
|||
### What is Displacement Current? |
|||
|
|||
**Displacement current** flows through capacitances, not through physical conductors. It's given by: |
|||
``` |
|||
I_displacement = jωC × V |
|||
``` |
|||
|
|||
**Key insight:** At AC, capacitors conduct current even though no charge physically crosses the dielectric! |
|||
|
|||
**For Tesla coils:** |
|||
- Every turn of the secondary has capacitance to ground |
|||
- Higher frequency → larger displacement current (proportional to ω) |
|||
- These currents return to ground through the secondary base |
|||
|
|||
### Multiple Current Paths in a Tesla Coil |
|||
|
|||
A Tesla coil has **many** current paths returning to ground: |
|||
|
|||
**1. Spark current** (what we want to measure) |
|||
``` |
|||
I_spark: From topload → through spark → remote ground → back to secondary base |
|||
``` |
|||
|
|||
**2. Displacement currents along secondary** |
|||
``` |
|||
I_displacement: From each turn → through C_turn_to_ground → to ground → base |
|||
Sum of all displacement currents: I_displacement = Σ(jωC_turn × V_turn) |
|||
``` |
|||
|
|||
**3. Primary-secondary coupling** |
|||
``` |
|||
I_coupling: Displacement current through C_ps (primary-to-secondary capacitance) |
|||
Part of transformer action |
|||
``` |
|||
|
|||
**4. Environmental coupling** |
|||
``` |
|||
I_environment: Displacement currents to nearby objects, walls, strike ring |
|||
Any grounded conductor near the secondary |
|||
``` |
|||
|
|||
**Total current at secondary base:** |
|||
``` |
|||
I_base = I_spark + I_displacement + I_coupling + I_environment |
|||
``` |
|||
|
|||
**The problem:** Only I_spark goes through the spark! The other currents are parasitic paths that don't tell us about spark behavior. |
|||
|
|||
### Why V_top/I_base is Wrong |
|||
|
|||
``` |
|||
Z_apparent = V_top / I_base |
|||
|
|||
But I_base >> I_spark (often 3-5× larger!) |
|||
|
|||
Therefore: Z_apparent << Z_spark (impedance appears much lower than actual) |
|||
``` |
|||
|
|||
**Consequences:** |
|||
- **Underestimate impedance:** Think load is more resistive than it is |
|||
- **Overestimate power:** Calculate far too much power to spark |
|||
- **Wrong optimization:** Make decisions based on incorrect data |
|||
- **Model mismatch:** Can't reconcile measurements with theory |
|||
|
|||
 |
|||
|
|||
**Diagram description:** |
|||
- **RED path:** Spark current (I_spark) - the one we want |
|||
- **BLUE paths:** Displacement currents along secondary (I_displacement) |
|||
- **GREEN path:** Primary-secondary coupling current (I_coupling) |
|||
- **YELLOW paths:** Environmental coupling currents (I_environment) |
|||
- **At base:** All paths converge: I_base = sum of all currents |
|||
|
|||
**Key insight box:** "I_base ≠ I_spark! Cannot use V_top/I_base for spark impedance!" |
|||
|
|||
## The Correct Measurement Port |
|||
|
|||
**Definition:** The **topload port** is the two-terminal reference between topload and ground. |
|||
|
|||
``` |
|||
Port definition: |
|||
Terminal 1: Topload (high voltage) |
|||
Terminal 2: Ground reference (0V) |
|||
``` |
|||
|
|||
**Correct impedance:** |
|||
``` |
|||
Z_spark = V_top / I_spark |
|||
|
|||
where I_spark is the current ONLY through the spark path |
|||
``` |
|||
|
|||
**Correct power:** |
|||
``` |
|||
P = 0.5 × Re{V_top × I_spark*} |
|||
P = 0.5 × |V_top| × |I_spark| × cos(φ_Z) |
|||
``` |
|||
|
|||
### Methods to Measure I_spark Correctly |
|||
|
|||
**Method 1: Separate return path measurement** |
|||
- Run spark ground return through isolated conductor |
|||
- Measure current with Rogowski coil or current transformer |
|||
- Only captures I_spark, excludes parasitic currents |
|||
|
|||
**Method 2: Circuit modeling** |
|||
- Know V_top (measure with voltage probe/antenna) |
|||
- Calculate I_spark from circuit model using component values |
|||
- Use admittance formulas from Lesson 3 |
|||
|
|||
**Method 3: Thévenin extraction** |
|||
- Characterize coil as Thévenin equivalent (covered in Part 2) |
|||
- Predict load current from Z_th and V_th |
|||
- Most accurate for design work |
|||
|
|||
## Worked Example: Correct vs Incorrect Power Calculation |
|||
|
|||
**Given:** |
|||
- V_top = 300 kV peak |
|||
- I_base (measured at secondary base) = 5 A peak |
|||
- I_spark (actual spark current) = 1.5 A peak |
|||
- Spark impedance phase: φ_Z = -70° |
|||
|
|||
**Find:** Power using incorrect method, power using correct method |
|||
|
|||
**Solution:** |
|||
|
|||
### Incorrect Method: Using V_top/I_base |
|||
|
|||
``` |
|||
Z_apparent = V_top / I_base = 300 kV / 5 A = 60 kΩ |
|||
|
|||
This is NOT the spark impedance! |
|||
|
|||
If we naively calculated power: |
|||
P_wrong = 0.5 × 300 kV × 5 A × cos(-70°) |
|||
= 0.5 × 1500 kW × 0.342 |
|||
= 257 kW |
|||
|
|||
This is way too high! |
|||
``` |
|||
|
|||
### Correct Method: Using Actual Spark Current |
|||
|
|||
``` |
|||
I_spark = 1.5 A peak |
|||
|
|||
Real spark impedance: |
|||
Z_spark = V_top / I_spark = 300 kV / 1.5 A = 200 kΩ |
|||
|
|||
Power: |
|||
P_correct = 0.5 × V_top × I_spark × cos(φ_Z) |
|||
= 0.5 × 300 kV × 1.5 A × cos(-70°) |
|||
= 0.5 × 450 kW × 0.342 |
|||
= 77 kW |
|||
|
|||
Or using resistance directly: |
|||
R = |Z| × cos(φ_Z) = 200 kΩ × 0.342 = 68.4 kΩ |
|||
P = 0.5 × I² × R = 0.5 × 1.5² × 68.4 kΩ = 77 kW ✓ |
|||
``` |
|||
|
|||
### Error Analysis |
|||
|
|||
``` |
|||
P_wrong / P_correct = 257 / 77 = 3.3× |
|||
|
|||
The incorrect method overestimates power by 330%! |
|||
``` |
|||
|
|||
**Impedance error:** |
|||
``` |
|||
Z_apparent = 60 kΩ (wrong) |
|||
Z_spark = 200 kΩ (correct) |
|||
|
|||
Ratio: 200/60 = 3.3× (impedance underestimated) |
|||
``` |
|||
|
|||
**Why the same ratio?** Because I_base/I_spark = 5/1.5 = 3.3× - the displacement currents are 3.3× larger than the spark current in this example! |
|||
|
|||
## Why Displacement Current Increases with Frequency |
|||
|
|||
From the capacitor current equation: |
|||
``` |
|||
I_C = jωC × V |
|||
|
|||
|I_C| = ω × C × |V| = 2πf × C × |V| |
|||
``` |
|||
|
|||
**Implication:** If frequency doubles, displacement current doubles! |
|||
|
|||
**For Tesla coils:** |
|||
- Higher frequency operation → larger displacement currents |
|||
- I_base becomes increasingly dominated by parasitics |
|||
- V_top/I_base becomes even more wrong at high frequency |
|||
- 200 kHz vs 400 kHz: displacement current 2× larger at 400 kHz |
|||
|
|||
**This is why measurement port definition is critical for comparison across different coils.** |
|||
|
|||
## Common Symptoms of Using I_base |
|||
|
|||
If you're using I_base incorrectly, you'll see: |
|||
|
|||
1. **Impedance too low:** Calculate 30-60 kΩ when should be 150-250 kΩ |
|||
2. **Power too high:** Predict hundreds of kW when actual is tens of kW |
|||
3. **Can't match models:** Circuit simulations disagree with "measurements" |
|||
4. **Phase angle confusion:** Measured phase doesn't match expected |
|||
5. **Efficiency paradox:** Calculate >100% efficiency (impossible!) |
|||
|
|||
**If you see these symptoms, check your measurement method!** |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **I_base includes multiple current paths:** spark + displacement + coupling + environment |
|||
- **Displacement current:** I = jωC×V, proportional to frequency |
|||
- **V_top/I_base is wrong:** Gives impedance too low, power too high |
|||
- **Correct port:** Topload-to-ground with I_spark only |
|||
- **Typical error:** 3-5× underestimate of impedance |
|||
- **Frequency dependence:** Displacement current ∝ ω, problem worse at high frequency |
|||
|
|||
## Practice |
|||
|
|||
{exercise:fund-ex-07} |
|||
|
|||
**Problem 1:** A simulation shows V_top = 250 kV, I_base = 3.5 A, but the spark circuit model predicts Z_spark = 180 kΩ. Calculate the actual spark current and power (assume φ_Z = -72°). |
|||
|
|||
**Problem 2:** Explain why displacement current is proportional to frequency (ω). If frequency doubles from 200 kHz to 400 kHz, what happens to I_displacement? |
|||
|
|||
**Problem 3:** An experimenter measures I_base = 4 A and calculates Z = V_top/I_base = 75 kΩ. Another measurement with a Rogowski coil on the spark return path shows I_spark = 1.2 A. What is the true spark impedance? What fraction of I_base is parasitic displacement current? |
|||
|
|||
**Problem 4:** A coil operates at 300 kV with Z_spark = 200 kΩ, φ_Z = -68°. Calculate the correct spark power. If someone incorrectly uses I_base = 4 A instead of the correct I_spark, what power would they calculate? What is the percentage error? |
|||
|
|||
--- |
|||
|
|||
**Next Lesson:** [Review and Exercises](08-review-exercises.md) |
|||
@ -0,0 +1,334 @@ |
|||
--- |
|||
id: fund-08 |
|||
title: "Part 1 Review and Integration" |
|||
section: "Fundamentals" |
|||
difficulty: "intermediate" |
|||
estimated_time: 45 |
|||
prerequisites: ["fund-01", "fund-02", "fund-03", "fund-04", "fund-05", "fund-06", "fund-07"] |
|||
objectives: |
|||
- Review all fundamental concepts from Part 1 |
|||
- Apply concepts in an integrated example problem |
|||
- Verify understanding through checkpoint quiz |
|||
- Prepare for Part 2 optimization topics |
|||
tags: ["review", "integration", "checkpoint", "summary"] |
|||
--- |
|||
|
|||
# Part 1 Review and Integration |
|||
|
|||
## Introduction |
|||
|
|||
Congratulations on completing the fundamentals! This lesson reviews key concepts, provides an integration exercise that combines everything you've learned, and includes a checkpoint quiz to verify your understanding before moving to Part 2. |
|||
|
|||
## Concepts Checklist |
|||
|
|||
Before proceeding to Part 2, ensure you understand: |
|||
|
|||
### Circuit Fundamentals |
|||
- [ ] Difference between peak and RMS values |
|||
- [ ] Complex number representation: rectangular (R+jX) and polar (|Z|∠φ) |
|||
- [ ] Power calculation: P = 0.5 × Re{V × I*} with peak phasors |
|||
- [ ] Impedance Z = R + jX and admittance Y = G + jB |
|||
- [ ] Relationship: Y = 1/Z, and φ_Y = -φ_Z |
|||
|
|||
### Capacitances |
|||
- [ ] Physical meaning of capacitance (charge storage) |
|||
- [ ] Self-capacitance vs mutual capacitance |
|||
- [ ] Shunt capacitance C_sh ≈ 2 pF/foot for sparks |
|||
- [ ] Both C_mut and C_sh exist simultaneously |
|||
|
|||
### Circuit Topology |
|||
- [ ] Spark circuit: (R || C_mut) in series with C_sh |
|||
- [ ] Topload port as measurement reference (topload-to-ground) |
|||
- [ ] Why V_top/I_base is incorrect |
|||
|
|||
### Admittance Analysis |
|||
- [ ] Advantages of Y for parallel circuits |
|||
- [ ] Formula: Y = [(G+jB₁)×jB₂]/[G+j(B₁+B₂)] |
|||
- [ ] Extracting Re{Y} and Im{Y} |
|||
- [ ] Converting Y ↔ Z |
|||
|
|||
### Phase Angles |
|||
- [ ] φ_Z = atan(X/R) for impedance |
|||
- [ ] Negative φ_Z means capacitive |
|||
- [ ] The -45° "balanced" condition: R = |X| |
|||
- [ ] Typical sparks: φ_Z ≈ -55° to -75° (more capacitive than -45°) |
|||
|
|||
### Topological Constraints |
|||
- [ ] φ_Z,min = -atan(2√[r(1+r)]) where r = C_mut/C_sh |
|||
- [ ] Critical ratio r = 0.207 for -45° |
|||
- [ ] Most Tesla coils cannot achieve -45° |
|||
- [ ] R_opt_phase minimizes |φ_Z|, R_opt_power maximizes power |
|||
|
|||
### Measurement |
|||
- [ ] Displacement current in secondary |
|||
- [ ] I_base = I_spark + I_displacement + I_coupling + I_environment |
|||
- [ ] V_top/I_base gives wrong impedance (too low) |
|||
- [ ] Correct port: topload-to-ground with I_spark only |
|||
|
|||
### Spark Physics (Qualitative) |
|||
- [ ] Streamers: thin, fast, cold, high R, branched |
|||
- [ ] Leaders: thick, slower, hot, low R, straighter |
|||
- [ ] Need both voltage (E-field) and power (energy/time) |
|||
- [ ] "Hungry streamer": plasma self-optimizes R |
|||
|
|||
## Integration Exercise: Putting It All Together |
|||
|
|||
**Scenario:** You have a Tesla coil operating at 180 kHz with a 2-foot spark. |
|||
|
|||
**Given data:** |
|||
- C_mut = 7 pF (from FEMM) |
|||
- Assume R = 75 kΩ (plasma resistance) |
|||
- Estimate C_sh using empirical rule |
|||
|
|||
**Tasks:** |
|||
1. Calculate ω, B₁, B₂, G |
|||
2. Calculate Y_total (real and imaginary parts) |
|||
3. Convert to Z_total (magnitude and phase) |
|||
4. Calculate φ_Z and interpret (is it more or less capacitive than -45°?) |
|||
5. If V_top = 300 kV peak, calculate power dissipated |
|||
|
|||
**Work through this problem completely before checking the solution below.** |
|||
|
|||
--- |
|||
|
|||
### Integration Exercise Solution |
|||
|
|||
**Step 1:** Calculate C_sh |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 2 feet = 4 pF |
|||
``` |
|||
|
|||
**Step 2:** Calculate ω and component values |
|||
``` |
|||
ω = 2πf = 2π × 180×10³ = 1.131×10⁶ rad/s |
|||
|
|||
G = 1/R = 1/(75×10³) = 13.33 μS |
|||
B₁ = ωC_mut = 1.131×10⁶ × 7×10⁻¹² = 7.92 μS |
|||
B₂ = ωC_sh = 1.131×10⁶ × 4×10⁻¹² = 4.52 μS |
|||
``` |
|||
|
|||
**Step 3:** Calculate Y_total |
|||
``` |
|||
Re{Y} = GB₂²/[G² + (B₁+B₂)²] |
|||
= 13.33 × (4.52)² / [13.33² + (7.92+4.52)²] |
|||
= 13.33 × 20.43 / [177.7 + 154.4] |
|||
= 272.3 / 332.1 |
|||
= 0.82 μS |
|||
|
|||
Im{Y} = B₂[G² + B₁(B₁+B₂)] / [G² + (B₁+B₂)²] |
|||
= 4.52 × [177.7 + 7.92×12.44] / 332.1 |
|||
= 4.52 × [177.7 + 98.5] / 332.1 |
|||
= 4.52 × 276.2 / 332.1 |
|||
= 3.76 μS |
|||
|
|||
Y_total = 0.82 + j3.76 μS |
|||
``` |
|||
|
|||
**Step 4:** Convert to impedance |
|||
``` |
|||
|Y| = √(0.82² + 3.76²) = √(0.67 + 14.14) = √14.81 = 3.85 μS |
|||
|
|||
|Z| = 1/|Y| = 1/(3.85×10⁻⁶) = 260 kΩ |
|||
|
|||
φ_Y = atan(3.76/0.82) = atan(4.59) = 77.7° |
|||
φ_Z = -φ_Y = -77.7° |
|||
|
|||
Z_total = 260 kΩ ∠-77.7° |
|||
|
|||
In rectangular: |
|||
R_eq = 260 × cos(-77.7°) = 260 × 0.213 = 55.4 kΩ |
|||
X_eq = 260 × sin(-77.7°) = 260 × (-0.977) = -254 kΩ |
|||
|
|||
Z_total = 55.4 - j254 kΩ |
|||
``` |
|||
|
|||
**Step 5:** Interpret phase |
|||
``` |
|||
φ_Z = -77.7° is more capacitive than -45° (larger magnitude) |
|||
Ratio: |X|/R = 254/55.4 = 4.6 |
|||
Capacitive reactance is 4.6× the resistance |
|||
Very capacitive load! |
|||
``` |
|||
|
|||
**Step 6:** Calculate power |
|||
``` |
|||
Current: I = V/Z = (300 kV)/(260 kΩ) = 1.15 A peak |
|||
|
|||
Power: P = 0.5 × V × I × cos(φ_Z) |
|||
= 0.5 × 300×10³ × 1.15 × cos(-77.7°) |
|||
= 0.5 × 345×10³ × 0.213 |
|||
= 36.7 kW |
|||
|
|||
Alternative: P = 0.5 × I² × R_eq |
|||
= 0.5 × 1.15² × 55.4×10³ |
|||
= 0.5 × 1.32 × 55.4×10³ |
|||
= 36.6 kW ✓ (checks!) |
|||
``` |
|||
|
|||
**Result:** 36.7 kW dissipated in the spark plasma. |
|||
|
|||
## Checkpoint Quiz |
|||
|
|||
Answer these questions to verify your understanding: |
|||
|
|||
**Question 1:** What is the relationship between peak and RMS voltage? If V_peak = 100 kV, what is V_RMS? |
|||
|
|||
**Question 2:** Write the power formula using peak phasors. Why is there a factor of 0.5? |
|||
|
|||
**Question 3:** For a capacitor, why is X negative but B positive? |
|||
|
|||
**Question 4:** Draw the circuit topology for a spark (show C_mut, R, C_sh). |
|||
|
|||
**Question 5:** What is the empirical rule for C_sh? If a spark is 4 feet long, estimate C_sh. |
|||
|
|||
**Question 6:** The admittance phase angle θ_Y = +60°. What is the impedance phase angle φ_Z? |
|||
|
|||
**Question 7:** An impedance has φ_Z = -30°. Is this inductive or capacitive? |
|||
|
|||
**Question 8:** Why is V_top/I_base not the correct impedance measurement? |
|||
|
|||
**Question 9:** Describe the difference between streamers and leaders (two key differences). |
|||
|
|||
**Question 10:** Explain the "hungry streamer" concept in one sentence. |
|||
|
|||
### Quiz Answers |
|||
|
|||
<details> |
|||
<summary>Click to reveal answers</summary> |
|||
|
|||
**Answer 1:** V_RMS = V_peak/√2. For V_peak = 100 kV, V_RMS = 100/√2 ≈ 70.7 kV |
|||
|
|||
**Answer 2:** P = 0.5 × Re{V × I*}. The 0.5 factor comes from time-averaging cos²(ωt) over a full cycle. |
|||
|
|||
**Answer 3:** For capacitors, reactance X_C = -1/(ωC) is negative, but susceptance B_C = ωC is positive. The sign conventions are opposite for impedance vs admittance. |
|||
|
|||
**Answer 4:** |
|||
``` |
|||
Topload |
|||
| |
|||
[C_mut] |
|||
| |
|||
+----+----+ |
|||
| | |
|||
[R] [C_sh] |
|||
| | |
|||
GND------GND |
|||
``` |
|||
|
|||
**Answer 5:** C_sh ≈ 2 pF/foot. For 4 feet: C_sh ≈ 8 pF. |
|||
|
|||
**Answer 6:** φ_Z = -θ_Y = -60° |
|||
|
|||
**Answer 7:** Capacitive (negative φ_Z indicates capacitive behavior) |
|||
|
|||
**Answer 8:** I_base includes displacement currents from the entire secondary, plus coupling currents and environmental currents. Only I_spark flows through the spark. V_top/I_base underestimates impedance because I_base > I_spark. |
|||
|
|||
**Answer 9:** (Any two of these) |
|||
- Streamers: thin (10-100 μm), fast (~10⁶ m/s), cold (~1000 K), high R, branched |
|||
- Leaders: thick (mm-cm), slower (~10³ m/s), hot (5000-20000 K), low R, straighter |
|||
|
|||
**Answer 10:** Plasma actively adjusts its conductivity to maximize power extraction from the circuit, naturally seeking R ≈ R_opt_power. |
|||
|
|||
</details> |
|||
|
|||
## Key Formulas Summary |
|||
|
|||
**Admittance components:** |
|||
``` |
|||
G = 1/R |
|||
B₁ = ωC_mut |
|||
B₂ = ωC_sh |
|||
``` |
|||
|
|||
**Total admittance:** |
|||
``` |
|||
Re{Y} = GB₂² / [G² + (B₁ + B₂)²] |
|||
Im{Y} = B₂[G² + B₁(B₁ + B₂)] / [G² + (B₁ + B₂)²] |
|||
``` |
|||
|
|||
**Conversion to impedance:** |
|||
``` |
|||
|Z| = 1/|Y| |
|||
φ_Z = -φ_Y |
|||
``` |
|||
|
|||
**Topological constraint:** |
|||
``` |
|||
φ_Z,min = -atan(2√[r(1 + r)]) |
|||
where r = C_mut/C_sh |
|||
``` |
|||
|
|||
**Optimal resistances:** |
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
``` |
|||
|
|||
**Power:** |
|||
``` |
|||
P = 0.5 × Re{V × I*} |
|||
P = 0.5 × |V| × |I| × cos(φ_Z) |
|||
P = 0.5 × |I|² × R |
|||
``` |
|||
|
|||
**Empirical rule:** |
|||
``` |
|||
C_sh ≈ 2 pF/foot |
|||
``` |
|||
|
|||
## Common Mistakes to Avoid |
|||
|
|||
1. **Using RMS instead of peak values** - Always use peak for this framework |
|||
2. **Using V_top/I_base** - Includes displacement currents, gives wrong Z |
|||
3. **Expecting -45°** - Usually impossible due to topological constraint |
|||
4. **Confusing R_opt_power and R_opt_phase** - Use R_opt_power for spark growth |
|||
5. **Forgetting sign conventions** - X < 0 but B > 0 for capacitors |
|||
6. **Ignoring phase in power calculations** - Must include cos(φ_Z) factor |
|||
|
|||
## Preview of Part 2 |
|||
|
|||
In Part 2: Optimization and Power Transfer, we'll explore: |
|||
|
|||
- **Two critical resistances:** Detailed derivation and comparison of R_opt_power and R_opt_phase |
|||
- **Thévenin method:** Properly characterizing the Tesla coil as V_th and Z_th |
|||
- **Power optimization:** How the "hungry streamer" finds R_opt_power |
|||
- **Measurements:** Extracting spark parameters from real coils using Q and ringdown |
|||
- **Load line analysis:** Predicting performance with any load |
|||
|
|||
These concepts build directly on the circuit analysis and phase relationships you've mastered in Part 1. |
|||
|
|||
## Practice Problems |
|||
|
|||
{exercise:fund-ex-08} |
|||
|
|||
**Comprehensive Problem 1:** |
|||
A Tesla coil operates at 220 kHz with a 3.5-foot spark. FEMM analysis gives C_mut = 9 pF. Assume R = 60 kΩ. |
|||
- (a) Calculate C_sh, ω, G, B₁, B₂ |
|||
- (b) Calculate Y_total and Z_total |
|||
- (c) Find φ_Z and compare to -45° |
|||
- (d) Calculate r and φ_Z,min |
|||
- (e) If V_top = 350 kV, find power dissipated |
|||
|
|||
**Comprehensive Problem 2:** |
|||
Two coils have identical frequency (200 kHz) and total capacitance (C_mut + C_sh = 15 pF). |
|||
- Coil A: C_mut = 10 pF, C_sh = 5 pF |
|||
- Coil B: C_mut = 5 pF, C_sh = 10 pF |
|||
- (a) Calculate r for both coils |
|||
- (b) Calculate φ_Z,min for both |
|||
- (c) Which can achieve more resistive phase? |
|||
- (d) Calculate R_opt_power and R_opt_phase for both |
|||
|
|||
**Measurement Problem:** |
|||
An experimenter measures V_top = 280 kV and I_base = 4.2 A. A separate measurement with a current probe on the spark return path shows I_spark = 1.3 A. The spark is 4 feet long. |
|||
- (a) What is the true spark impedance? |
|||
- (b) What would they calculate using V_top/I_base (incorrect)? |
|||
- (c) What percentage of I_base is parasitic displacement current? |
|||
- (d) Calculate the correct spark power (assume φ_Z = -68°) |
|||
|
|||
--- |
|||
|
|||
**Congratulations on completing Part 1: Fundamentals!** |
|||
|
|||
You now have a solid foundation in Tesla coil spark circuit modeling. You understand the topology, can calculate impedances, recognize the phase constraints, and know how to measure correctly. You're ready to move on to optimization and power transfer in Part 2. |
|||
|
|||
**Next:** [Part 2: Optimization and Power Transfer](../../02-optimization/01-introduction.md) |
|||
@ -0,0 +1,126 @@ |
|||
# Part 1: Fundamentals |
|||
|
|||
## Overview |
|||
|
|||
This section provides the foundational knowledge for Tesla coil spark modeling. You'll learn the circuit theory, analysis techniques, and key concepts needed to understand and predict spark behavior. |
|||
|
|||
## Lessons |
|||
|
|||
1. **[Introduction to Tesla Coil Spark Modeling](01-introduction.md)** (20 min) |
|||
- AC circuit fundamentals review |
|||
- Peak vs RMS values |
|||
- Complex numbers and phasors |
|||
- Power calculations with peak phasors |
|||
|
|||
2. **[The Basic Spark Circuit Model](02-basic-circuit-model.md)** (25 min) |
|||
- Physical meaning of capacitance |
|||
- Mutual capacitance (C_mut) vs shunt capacitance (C_sh) |
|||
- The 2 pF/foot empirical rule |
|||
- Correct circuit topology: (R || C_mut) in series with C_sh |
|||
|
|||
3. **[Admittance Analysis](03-admittance-analysis.md)** (30 min) |
|||
- Why use admittance for parallel circuits |
|||
- Deriving the total admittance formula |
|||
- Calculating Re{Y} and Im{Y} |
|||
- Converting between Y and Z |
|||
|
|||
4. **[Phase Angles and Their Meaning](04-phase-angles.md)** (20 min) |
|||
- Impedance phase φ_Z vs admittance phase φ_Y |
|||
- Physical interpretation of phase angles |
|||
- The "famous -45°" and why it's special |
|||
- Typical spark phase angles: -55° to -75° |
|||
|
|||
5. **[The Topological Phase Constraint](05-phase-constraint.md)** (25 min) |
|||
- What is a topological constraint? |
|||
- Deriving φ_Z,min = -atan(2√[r(1+r)]) |
|||
- The critical ratio r = 0.207 |
|||
- Why -45° is usually impossible |
|||
|
|||
6. **[Why Not -45 Degrees?](06-why-not-45-degrees.md)** (15 min) |
|||
- Historical origin of the -45° target |
|||
- Why it's often impossible for Tesla coils |
|||
- R_opt_phase vs R_opt_power |
|||
- What to target instead |
|||
|
|||
7. **[The Measurement Port](07-measurement-port.md)** (20 min) |
|||
- Understanding displacement current |
|||
- Why V_top/I_base gives wrong impedance |
|||
- Multiple current paths in a Tesla coil |
|||
- Correct measurement methods |
|||
|
|||
8. **[Review and Integration](08-review-exercises.md)** (45 min) |
|||
- Complete concepts checklist |
|||
- Integration exercise combining all topics |
|||
- Checkpoint quiz |
|||
- Preview of Part 2 |
|||
|
|||
## Total Time |
|||
|
|||
Approximately 3-4 hours for complete mastery |
|||
|
|||
## Learning Outcomes |
|||
|
|||
After completing Part 1, you will be able to: |
|||
|
|||
- Use peak values and phasor notation correctly |
|||
- Model a spark with proper circuit topology |
|||
- Calculate impedance using admittance formulas |
|||
- Understand phase angle constraints and their physical meaning |
|||
- Recognize why -45° is rarely achievable |
|||
- Measure spark impedance correctly |
|||
- Avoid common measurement pitfalls |
|||
- Apply integrated circuit analysis to real Tesla coil scenarios |
|||
|
|||
## Prerequisites |
|||
|
|||
- Basic algebra and trigonometry |
|||
- Familiarity with sine waves and AC circuits (helpful but not required) |
|||
- Scientific calculator or Python/MATLAB for calculations |
|||
|
|||
## Key Formulas |
|||
|
|||
**Admittance:** |
|||
``` |
|||
Re{Y} = GB₂² / [G² + (B₁ + B₂)²] |
|||
Im{Y} = B₂[G² + B₁(B₁ + B₂)] / [G² + (B₁ + B₂)²] |
|||
where G = 1/R, B₁ = ωC_mut, B₂ = ωC_sh |
|||
``` |
|||
|
|||
**Topological constraint:** |
|||
``` |
|||
φ_Z,min = -atan(2√[r(1 + r)]) |
|||
where r = C_mut/C_sh |
|||
``` |
|||
|
|||
**Empirical rule:** |
|||
``` |
|||
C_sh ≈ 2 pF/foot |
|||
``` |
|||
|
|||
**Power:** |
|||
``` |
|||
P = 0.5 × Re{V × I*} |
|||
``` |
|||
|
|||
## Image Placeholders |
|||
|
|||
The following images should be created for the assets folder: |
|||
|
|||
1. `field-lines-capacitances.png` - C_mut and C_sh field lines |
|||
2. `geometry-to-circuit.png` - 3D geometry to circuit schematic |
|||
3. `complex-plane-admittance.png` - Y and Z on complex planes |
|||
4. `phase-angle-visualization.png` - Phase angles on impedance plane |
|||
5. `phase-constraint-graph.png` - φ_Z,min vs r graph |
|||
6. `current-paths-diagram.png` - Multiple current paths in Tesla coil |
|||
|
|||
## Next Steps |
|||
|
|||
After mastering Part 1, proceed to: |
|||
|
|||
**[Part 2: Optimization and Power Transfer](../02-optimization/README.md)** |
|||
|
|||
Topics include: |
|||
- R_opt_power and R_opt_phase derivations |
|||
- Thévenin equivalent method |
|||
- The "hungry streamer" self-optimization |
|||
- Q measurements and ringdown analysis |
|||
|
After Width: 906 | Height: 1055 | Size: 96 KiB |
|
After Width: 1420 | Height: 779 | Size: 119 KiB |
|
After Width: 1200 | Height: 600 | Size: 24 KiB |
|
After Width: 1200 | Height: 600 | Size: 29 KiB |
|
After Width: 1241 | Height: 1055 | Size: 155 KiB |
|
After Width: 1409 | Height: 940 | Size: 135 KiB |
@ -0,0 +1,283 @@ |
|||
--- |
|||
id: opt-01 |
|||
title: "The Two Critical Resistances" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "intermediate" |
|||
estimated_time: 35 |
|||
prerequisites: ["fund-08"] |
|||
objectives: |
|||
- Derive and understand R_opt_phase for minimum phase angle |
|||
- Derive and understand R_opt_power for maximum power transfer |
|||
- Compare the two resistances and their physical meanings |
|||
- Calculate phase angles at different operating points |
|||
tags: ["optimization", "impedance", "power-transfer", "phase-angle"] |
|||
--- |
|||
|
|||
# The Two Critical Resistances |
|||
|
|||
In spark gap modeling, we encounter two fundamentally different optimization criteria that lead to two different "optimal" resistance values. Understanding the distinction between these is critical for both analysis and practical coil operation. |
|||
|
|||
## The Topological Phase Constraint |
|||
|
|||
Before we dive into the two resistances, we need to understand a fundamental limitation imposed by circuit topology. |
|||
|
|||
### What is a Topological Constraint? |
|||
|
|||
**Definition:** A limitation imposed by the **structure** of the circuit itself, independent of component values. |
|||
|
|||
**Example:** A series RLC circuit can only have impedance phase between -90° (pure capacitive) and +90° (pure inductive). You cannot achieve φ_Z = +120° no matter what component values you choose. This is a topological constraint. |
|||
|
|||
**For spark circuits:** The specific arrangement (R||C_mut) in series with C_sh creates a fundamental limit on how resistive the impedance can appear. |
|||
|
|||
### Deriving the Minimum Phase Angle |
|||
|
|||
From Part 1 fundamentals, we have the spark admittance: |
|||
|
|||
``` |
|||
Y = [(G + jB₁) × jB₂] / [G + j(B₁ + B₂)] |
|||
|
|||
where: |
|||
G = 1/R (conductance) |
|||
B₁ = ωC_mut (mutual capacitance susceptance) |
|||
B₂ = ωC_sh (sheath capacitance susceptance) |
|||
``` |
|||
|
|||
The impedance phase is: |
|||
``` |
|||
φ_Z = atan(-Im{Y}/Re{Y}) |
|||
``` |
|||
|
|||
**Question:** For fixed C_mut and C_sh, which R value minimizes |φ_Z| (makes the impedance most resistive)? |
|||
|
|||
**Mathematical result:** Taking the derivative ∂φ_Z/∂G = 0 and solving: |
|||
|
|||
``` |
|||
G_opt = ω√[C_mut(C_mut + C_sh)] |
|||
|
|||
Therefore: |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
``` |
|||
|
|||
At this resistance, the phase angle magnitude is minimized to: |
|||
|
|||
``` |
|||
φ_Z,min = -atan(2√[r(1 + r)]) |
|||
|
|||
where r = C_mut/C_sh (capacitance ratio) |
|||
``` |
|||
|
|||
### The Critical Ratio r = 0.207 |
|||
|
|||
Let's find when φ_Z,min = -45° is achievable: |
|||
|
|||
``` |
|||
-45° = -atan(2√[r(1 + r)]) |
|||
tan(45°) = 1 = 2√[r(1 + r)] |
|||
0.5 = √[r(1 + r)] |
|||
0.25 = r(1 + r) = r + r² |
|||
r² + r - 0.25 = 0 |
|||
|
|||
Using quadratic formula: |
|||
r = [-1 ± √(1 + 1)] / 2 = [-1 ± √2] / 2 |
|||
|
|||
Taking positive root: |
|||
r = (√2 - 1) / 2 ≈ 0.207 |
|||
``` |
|||
|
|||
**Critical insight:** |
|||
- If r < 0.207: Can achieve φ_Z = -45° (with appropriate R) |
|||
- If r > 0.207: **Cannot achieve φ_Z = -45° no matter what R you choose!** |
|||
- If r ≥ 0.207: φ_Z,min is more negative than -45° |
|||
|
|||
### Typical Tesla Coil Values |
|||
|
|||
**Large topload, short spark:** |
|||
``` |
|||
C_mut = 10 pF, C_sh = 4 pF (2 feet) |
|||
r = 10/4 = 2.5 |
|||
|
|||
φ_Z,min = -atan(2√[2.5 × 3.5]) = -atan(2 × 2.96) = -atan(5.92) = -80.4° |
|||
``` |
|||
|
|||
**Small topload, long spark:** |
|||
``` |
|||
C_mut = 6 pF, C_sh = 12 pF (6 feet) |
|||
r = 6/12 = 0.5 |
|||
|
|||
φ_Z,min = -atan(2√[0.5 × 1.5]) = -atan(2 × 0.866) = -atan(1.732) = -60.0° |
|||
``` |
|||
|
|||
**Common range:** r = 0.5 to 2.0, giving φ_Z,min ≈ -60° to -80° |
|||
|
|||
**Conclusion:** For most Tesla coil geometries, achieving -45° is **mathematically impossible**! |
|||
|
|||
## R_opt_phase: Closest to Resistive |
|||
|
|||
**Formula:** |
|||
``` |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
``` |
|||
|
|||
**Purpose:** Minimizes |φ_Z| to achieve φ_Z,min |
|||
|
|||
**Use case:** If you want the "most resistive-looking" impedance possible for your given capacitances. |
|||
|
|||
**Physical meaning:** This is the geometric mean of the capacitive reactances, representing the resistance that balances the phase contributions from C_mut and C_sh. |
|||
|
|||
## R_opt_power: Maximum Power Transfer |
|||
|
|||
**Different question:** Which R maximizes real power delivered to the spark for a given topload voltage? |
|||
|
|||
**Setup:** Fixed voltage source V_top, variable load resistance R |
|||
|
|||
**Power to load:** |
|||
``` |
|||
P = 0.5 × |V_top|² × Re{Y(R)} |
|||
``` |
|||
|
|||
where Y(R) depends on R through G = 1/R. |
|||
|
|||
**Mathematical derivation:** Take ∂P/∂G = 0 and solve for G: |
|||
|
|||
After applying calculus (expanding Re{Y} and differentiating): |
|||
|
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
``` |
|||
|
|||
**Simpler formula!** Just the total capacitance reactance, not a geometric mean. |
|||
|
|||
## Comparing the Two Resistances |
|||
|
|||
### Relationship |
|||
|
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
|
|||
Since √(C_mut(C_mut + C_sh)) < (C_mut + C_sh): |
|||
|
|||
R_opt_power < R_opt_phase ALWAYS |
|||
``` |
|||
|
|||
**Numerical relationship:** For typical r = 0.5 to 2: |
|||
``` |
|||
R_opt_power ≈ (0.5 to 0.7) × R_opt_phase |
|||
``` |
|||
|
|||
### Phase Angle at R_opt_power |
|||
|
|||
- Always more negative (more capacitive) than φ_Z,min |
|||
- Typically φ_Z ≈ -55° to -75° at R_opt_power |
|||
- More capacitive than R_opt_phase, but delivers more power |
|||
|
|||
**Key insight:** The impedance that transfers maximum power is NOT the same as the impedance with minimum phase angle! |
|||
|
|||
## Worked Example: Calculating Both Critical Resistances |
|||
|
|||
**Given:** |
|||
- Frequency: f = 200 kHz → ω = 1.257×10⁶ rad/s |
|||
- C_mut = 8 pF = 8×10⁻¹² F |
|||
- C_sh = 6 pF = 6×10⁻¹² F |
|||
|
|||
**Find:** R_opt_phase, R_opt_power, and compare |
|||
|
|||
### Solution |
|||
|
|||
**Part 1: R_opt_phase** |
|||
``` |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
= 1 / [1.257×10⁶ × √(8×10⁻¹² × 14×10⁻¹²)] |
|||
= 1 / [1.257×10⁶ × √(112×10⁻²⁴)] |
|||
= 1 / [1.257×10⁶ × 10.58×10⁻¹²] |
|||
= 1 / (13.30×10⁻⁶) |
|||
= 75.2 kΩ |
|||
``` |
|||
|
|||
**Part 2: R_opt_power** |
|||
``` |
|||
C_total = C_mut + C_sh = 8 + 6 = 14 pF = 14×10⁻¹² F |
|||
|
|||
R_opt_power = 1 / (ωC_total) |
|||
= 1 / (1.257×10⁶ × 14×10⁻¹²) |
|||
= 1 / (17.60×10⁻⁶) |
|||
= 56.8 kΩ |
|||
``` |
|||
|
|||
**Part 3: Comparison** |
|||
``` |
|||
Ratio: R_opt_power / R_opt_phase = 56.8 / 75.2 = 0.755 |
|||
|
|||
R_opt_power is 75.5% of R_opt_phase |
|||
``` |
|||
|
|||
**Part 4: Phase angle at R_opt_power** |
|||
|
|||
Calculate admittance with R = 56.8 kΩ: |
|||
``` |
|||
G = 1/56800 = 17.61 μS |
|||
B₁ = ωC_mut = 1.257×10⁶ × 8×10⁻¹² = 10.06 μS |
|||
B₂ = ωC_sh = 1.257×10⁶ × 6×10⁻¹² = 7.54 μS |
|||
|
|||
Re{Y} = GB₂²/[G² + (B₁+B₂)²] |
|||
= 17.61 × 56.85 / [310 + 309.8] |
|||
= 1001.2 / 619.8 |
|||
= 1.615 μS |
|||
|
|||
Im{Y} = 7.54[310 + 176.9] / 619.8 |
|||
= 7.54 × 486.9 / 619.8 |
|||
= 5.928 μS |
|||
|
|||
φ_Y = atan(5.928/1.615) = atan(3.67) = 74.7° |
|||
φ_Z = -74.7° |
|||
``` |
|||
|
|||
**Summary:** |
|||
- R_opt_phase = 75.2 kΩ gives φ_Z = -74.2° (minimum) |
|||
- R_opt_power = 56.8 kΩ gives φ_Z = -74.7° (slightly more capacitive) |
|||
- Power is maximized at R_opt_power despite not having minimum phase |
|||
- Difference is small: both are strongly capacitive |
|||
|
|||
## Visual Aid: Power vs Resistance Curves |
|||
|
|||
 |
|||
|
|||
*Image shows two overlaid plots:* |
|||
- *Top: Power vs R (bell curve peaking at R_opt_power = 56.8 kΩ)* |
|||
- *Bottom: Phase angle vs R (minimum at R_opt_phase = 75.2 kΩ)* |
|||
- *Key insight: The two optimal points do not coincide* |
|||
|
|||
**Key features:** |
|||
- X-axis: R (kΩ), range 20 to 150, log scale |
|||
- Power curve: Bell-shaped, peaks at R_opt_power |
|||
- Phase curve: Rises from -90° (R→0), peaks at R_opt_phase, falls back |
|||
- Vertical lines show the two different optimum points |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **R_opt_phase = 1/[ω√(C_mut(C_mut + C_sh))]** minimizes phase angle magnitude |
|||
- **R_opt_power = 1/[ω(C_mut + C_sh)]** maximizes power transfer |
|||
- **R_opt_power < R_opt_phase** always (typically 50-75% of R_opt_phase) |
|||
- Most Tesla coils operate with r > 0.207, making φ_Z = -45° impossible |
|||
- The impedance must be strongly capacitive due to topological constraints |
|||
- Power optimization and phase optimization are different goals with different solutions |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-01} |
|||
|
|||
**Problem 1:** For f = 150 kHz, C_mut = 10 pF, C_sh = 8 pF: |
|||
Calculate R_opt_power and R_opt_phase. |
|||
|
|||
**Problem 2:** At 200 kHz, a spark has C_total = 12 pF. What is R_opt_power? If V_top = 400 kV, estimate the maximum deliverable power (assume R at optimal value). |
|||
|
|||
**Problem 3:** Prove algebraically that R_opt_power < R_opt_phase always (hint: compare 1/(C_mut+C_sh) with 1/√(C_mut(C_mut+C_sh))). |
|||
|
|||
**Problem 4:** A measurement shows φ_Z = -68° at the operating point. Is R likely above or below R_opt_phase? Above or below R_opt_power? Explain your reasoning. |
|||
|
|||
**Problem 5:** Calculate the capacitance ratio r and minimum achievable phase angle φ_Z,min for: |
|||
(a) C_mut = 12 pF, C_sh = 8 pF |
|||
(b) Can this circuit achieve -45°? |
|||
|
|||
--- |
|||
**Next Lesson:** [The Hungry Streamer - Self-Optimization](02-hungry-streamer.md) |
|||
@ -0,0 +1,334 @@ |
|||
--- |
|||
id: opt-02 |
|||
title: "The Hungry Streamer - Self-Optimization" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "advanced" |
|||
estimated_time: 30 |
|||
prerequisites: ["opt-01", "fund-06"] |
|||
objectives: |
|||
- Understand the physical feedback loop between power and plasma conductivity |
|||
- Trace the thermal-electrical evolution of a spark |
|||
- Recognize when and why plasma self-optimizes to R_opt_power |
|||
- Identify physical constraints that prevent optimization |
|||
tags: ["plasma-physics", "self-optimization", "thermal-dynamics", "feedback"] |
|||
--- |
|||
|
|||
# The Hungry Streamer - Self-Optimization |
|||
|
|||
One of the most remarkable features of spark plasmas is their ability to **self-adjust** their resistance to maximize power extraction from the coil. This phenomenon, often described by Steve Conner's principle of the "hungry streamer," is a consequence of fundamental plasma physics and thermal dynamics. |
|||
|
|||
## The Physical Feedback Loop |
|||
|
|||
Plasma conductivity changes dynamically with the power it receives, creating a feedback mechanism: |
|||
|
|||
### Step 1: More Power → Joule Heating |
|||
|
|||
``` |
|||
Heating rate: dT/dt ∝ I²R |
|||
|
|||
Higher current → faster heating |
|||
``` |
|||
|
|||
The plasma channel experiences resistive heating (Joule heating) from the current flowing through it. The heating rate is proportional to I²R, so higher currents lead to faster temperature rise. |
|||
|
|||
### Step 2: Higher Temperature → Ionization |
|||
|
|||
``` |
|||
Thermal ionization: fraction ∝ exp(-E_ionization / kT) |
|||
|
|||
Hotter plasma → more free electrons |
|||
``` |
|||
|
|||
As temperature increases, more air molecules have sufficient thermal energy to ionize. The ionization fraction follows a Boltzmann-like distribution, increasing exponentially with temperature once the thermal energy approaches the ionization energy (~13.6 eV for many atmospheric species). |
|||
|
|||
### Step 3: More Electrons → Higher Conductivity |
|||
|
|||
``` |
|||
σ = n_e × e × μ_e |
|||
|
|||
where: |
|||
n_e = electron density |
|||
μ_e = electron mobility |
|||
e = elementary charge |
|||
|
|||
σ ∝ n_e ∝ exp(-E_ionization / kT) |
|||
``` |
|||
|
|||
Electrical conductivity is directly proportional to the free electron density. More ionization means more free charge carriers, which means higher conductivity. |
|||
|
|||
### Step 4: Higher Conductivity → Lower R |
|||
|
|||
``` |
|||
R = ρL/A = L/(σA) |
|||
|
|||
σ increases → R decreases |
|||
``` |
|||
|
|||
The resistance of the plasma channel is inversely proportional to conductivity. As the plasma heats up and becomes more conductive, its resistance drops. |
|||
|
|||
### Step 5: Changed R → New Circuit Behavior |
|||
|
|||
``` |
|||
New R changes Y_spark, power transfer changes: |
|||
|
|||
If R < R_opt_power: reducing R further DECREASES power |
|||
If R > R_opt_power: reducing R INCREASES power |
|||
``` |
|||
|
|||
This is the crucial step. The circuit's power transfer characteristics depend on the load resistance. From our previous lesson, we know that power is maximized at R_opt_power. |
|||
|
|||
### Step 6: Stable Equilibrium at R ≈ R_opt_power |
|||
|
|||
``` |
|||
When R approaches R_opt_power: |
|||
- Small decrease → power decreases → cooling → R rises |
|||
- Small increase → power increases → heating → R falls |
|||
- Negative feedback stabilizes at R_opt_power |
|||
``` |
|||
|
|||
**This creates a stable operating point!** The system naturally seeks the resistance value that maximizes power transfer through negative feedback. |
|||
|
|||
## Time Scales |
|||
|
|||
Understanding the time scales involved is critical to predicting when self-optimization occurs. |
|||
|
|||
### Thermal Response: ~0.1-1 ms for Thin Channels |
|||
|
|||
**Heat diffusion time:** |
|||
``` |
|||
τ = d²/(4α) |
|||
|
|||
where: |
|||
d = channel diameter |
|||
α = thermal diffusivity ≈ 2×10⁻⁵ m²/s for air |
|||
|
|||
For d = 100 μm (thin streamer): τ ≈ 0.1 ms |
|||
For d = 5 mm (thick leader): τ ≈ 300 ms |
|||
``` |
|||
|
|||
**Implications:** |
|||
- Fast enough to track AC envelope (kHz modulation in QCW/burst mode) |
|||
- Too slow to track RF oscillation (hundreds of kHz carrier) |
|||
- The plasma "sees" the RMS or average power, not instantaneous RF cycles |
|||
|
|||
### Ionization Response: ~μs to ms |
|||
|
|||
**Recombination time varies with:** |
|||
- Electron density (higher density → faster recombination) |
|||
- Temperature (higher temperature → slower recombination) |
|||
- Gas composition (different species have different rates) |
|||
|
|||
**Typical:** ~1-10 ms for atmospheric pressure air plasmas |
|||
|
|||
### Result: 0.1-10 ms Adjustment Time |
|||
|
|||
The plasma can adjust its resistance on timescales of 0.1-10 ms, allowing it to: |
|||
- Track power delivery changes in burst mode or QCW operation |
|||
- Respond to voltage variations |
|||
- Seek optimal operating conditions dynamically |
|||
|
|||
## Physical Constraints |
|||
|
|||
While the feedback mechanism drives the plasma toward R_opt_power, physical limitations can prevent this optimization: |
|||
|
|||
### Lower Bound: R_min |
|||
|
|||
**Physical limit:** |
|||
- Maximum conductivity limited by electron-ion collision frequency |
|||
- Even fully ionized plasma has finite conductivity |
|||
- Typical: R_min ≈ 1-10 kΩ for hot, dense leader channels |
|||
|
|||
**If R_opt_power < R_min:** |
|||
- Plasma stuck at R_min (cannot achieve lower resistance) |
|||
- Power transfer is suboptimal |
|||
- Spark cannot extract as much power as theoretically possible |
|||
|
|||
### Upper Bound: R_max |
|||
|
|||
**Physical limit:** |
|||
- Minimum conductivity of partially ionized gas |
|||
- Cool plasma or weak ionization |
|||
- Typical: R_max ≈ 100 kΩ to 100 MΩ for cool streamers |
|||
|
|||
**If R_opt_power > R_max:** |
|||
- Plasma stuck at R_max (cannot achieve higher resistance) |
|||
- Usually not the limiting factor in Tesla coils |
|||
- More common with very weak discharges |
|||
|
|||
### Source Limitations |
|||
|
|||
**Insufficient voltage:** |
|||
- Spark won't form at all if V_top < V_breakdown |
|||
- No optimization possible without a spark |
|||
|
|||
**Insufficient current:** |
|||
- Cannot heat plasma enough to reach R_opt_power |
|||
- Spark remains in cool streamer regime |
|||
- High resistance, low power transfer |
|||
|
|||
**Power supply impedance:** |
|||
- If Z_source >> Z_spark, source impedance limits available power |
|||
- The "hungry streamer" is starved by a weak source |
|||
|
|||
## When Optimization Fails |
|||
|
|||
Several scenarios prevent the plasma from reaching R_opt_power: |
|||
|
|||
### Source Too Weak |
|||
|
|||
**Scenario:** Available power insufficient to heat plasma |
|||
|
|||
**Result:** |
|||
- Spark operates at whatever R it can sustain |
|||
- Typically remains at high R (cool streamers) |
|||
- Low power transfer, short sparks |
|||
|
|||
### Thermal Time Too Long |
|||
|
|||
**Scenario:** Burst mode with pulse width << thermal time constant |
|||
|
|||
**Example:** 50 μs pulses with τ_thermal = 0.5 ms |
|||
|
|||
**Result:** |
|||
- Plasma cannot respond fast enough |
|||
- Operates in transient regime |
|||
- Does not reach steady-state R_opt_power |
|||
|
|||
### Branching |
|||
|
|||
**Scenario:** Multiple discharge paths from topload |
|||
|
|||
**Result:** |
|||
- Available power divides among branches |
|||
- No single branch gets enough power to optimize |
|||
- Multiple weak streamers rather than one strong leader |
|||
|
|||
## Worked Example: Tracing Optimization Process |
|||
|
|||
**Scenario:** Spark initially forms with R = 200 kΩ (cold streamer). Circuit has R_opt_power = 60 kΩ. Let's trace the thermal-electrical evolution: |
|||
|
|||
### Initial State (t = 0) |
|||
|
|||
``` |
|||
R = 200 kΩ >> R_opt_power |
|||
Power delivered: P_initial (suboptimal, low) |
|||
Temperature: T_initial (cool, ~1000 K) |
|||
Current: I_initial ≈ V_top / Z_total (low) |
|||
``` |
|||
|
|||
The spark has just formed. It's essentially a weakly ionized streamer with high resistance. |
|||
|
|||
### Early Phase (0 < t < 1 ms) |
|||
|
|||
``` |
|||
Current flows → Joule heating: dT/dt = I²R/c_p |
|||
R is high → voltage division favorable → some heating occurs |
|||
Temperature rises → ionization begins → n_e increases |
|||
Conductivity σ ∝ n_e increases → R decreases |
|||
R drops toward 150 kΩ |
|||
``` |
|||
|
|||
**What's happening:** |
|||
- Even though R is far from optimal, some power flows |
|||
- Joule heating warms the plasma channel |
|||
- Thermal ionization begins to create more free electrons |
|||
- Resistance starts to drop |
|||
|
|||
### Middle Phase (1 ms < t < 5 ms) |
|||
|
|||
``` |
|||
R approaches 100 kΩ range |
|||
Now closer to R_opt_power → power transfer improves |
|||
More power → faster heating → faster ionization |
|||
Positive feedback: lower R → more power → lower R |
|||
R drops rapidly: 100 kΩ → 80 kΩ → 70 kΩ → 65 kΩ |
|||
``` |
|||
|
|||
**What's happening:** |
|||
- As R approaches R_opt_power, power transfer increases |
|||
- Positive feedback accelerates the process |
|||
- This is the "hungry" phase - the plasma eagerly draws more power |
|||
- Temperature may reach 5000-10000 K (transition to leader) |
|||
|
|||
### Approach to Equilibrium (5 ms < t < 10 ms) |
|||
|
|||
``` |
|||
R approaches R_opt_power = 60 kΩ |
|||
Power maximized at this R |
|||
|
|||
If R < 60 kΩ: power would decrease → cooling → R rises |
|||
If R > 60 kΩ: power would increase → heating → R falls |
|||
|
|||
Negative feedback stabilizes around R ≈ 60 kΩ |
|||
``` |
|||
|
|||
**What's happening:** |
|||
- Feedback changes from positive to negative near R_opt_power |
|||
- System naturally seeks the stable equilibrium point |
|||
- Small perturbations are self-correcting |
|||
|
|||
### Steady State (t > 10 ms) |
|||
|
|||
``` |
|||
R oscillates around 60 kΩ ± 10% |
|||
Temperature stable at equilibrium (~8000-15000 K for leaders) |
|||
Power maximized and stable |
|||
Spark is "optimized" |
|||
``` |
|||
|
|||
**What's happening:** |
|||
- Plasma has reached thermal and electrical equilibrium |
|||
- Continuous power input balances radiative/convective losses |
|||
- The spark maintains maximum power extraction |
|||
|
|||
## What If Physical Limits Intervene? |
|||
|
|||
**Example with R_min constraint:** |
|||
|
|||
``` |
|||
If R_opt_power = 30 kΩ but R_min = 50 kΩ (plasma physics limit): |
|||
Plasma can only reach R = 50 kΩ (not optimal) |
|||
Power is less than theoretical maximum |
|||
Spark is "starved" - wants more current than physics allows |
|||
``` |
|||
|
|||
This can happen with very hot, dense plasmas where even full ionization cannot achieve the low resistance needed for optimization. |
|||
|
|||
## Steve Conner's Principle |
|||
|
|||
**The "Hungry Streamer" Concept:** |
|||
|
|||
A spark will adjust its resistance to extract maximum power from the source, subject to physical constraints. The plasma behaves as if it is "hungry" for energy and actively optimizes its impedance to feed that hunger. |
|||
|
|||
**Why this matters:** |
|||
- Explains why measured spark resistance tends to cluster around R_opt_power |
|||
- Justifies using R_opt_power as a design target |
|||
- Helps predict spark behavior in different operating modes |
|||
- Guides optimization of coil parameters |
|||
|
|||
## Key Takeaways |
|||
|
|||
- Plasma resistance is not fixed - it dynamically adjusts based on power |
|||
- **Feedback loop:** Power → Heating → Ionization → Conductivity → R changes → Power changes |
|||
- **Stable equilibrium at R ≈ R_opt_power** due to negative feedback |
|||
- Time scales: 0.1-10 ms for thermal/ionization response |
|||
- Physical constraints: R_min (hot plasma limit), R_max (cool plasma limit), source limitations |
|||
- Burst mode with short pulses may not reach equilibrium |
|||
- The "hungry streamer" actively seeks maximum power extraction |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-02} |
|||
|
|||
**Question 1:** Why does the optimization work? Why doesn't the plasma just pick a random R value and stay there? |
|||
|
|||
**Question 2:** In burst mode (short pulses, <100 μs), thermal time constants are longer than pulse duration. Would you expect the plasma to reach R_opt_power? Why or why not? |
|||
|
|||
**Question 3:** A coil produces sparks with measured R ≈ 20 kΩ, but calculations show R_opt_power = 80 kΩ. What might explain this discrepancy? (Hint: Consider multiple possibilities) |
|||
|
|||
**Question 4:** Sketch the time evolution of R, T, and P for a spark that starts at R = 150 kΩ with R_opt_power = 50 kΩ. Label key phases. |
|||
|
|||
**Question 5:** Why might a branched spark (multiple discharge paths) fail to optimize? Explain in terms of power distribution. |
|||
|
|||
--- |
|||
**Next Lesson:** [Thévenin Equivalent Method - Extraction](03-thevenin-method.md) |
|||
@ -0,0 +1,329 @@ |
|||
--- |
|||
id: opt-03 |
|||
title: "Thévenin Equivalent Method - Extraction" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "intermediate" |
|||
estimated_time: 40 |
|||
prerequisites: ["opt-01", "fund-08"] |
|||
objectives: |
|||
- Understand Thévenin's theorem applied to Tesla coils |
|||
- Extract output impedance Z_th through test measurements |
|||
- Extract open-circuit voltage V_th |
|||
- Interpret Z_th components physically |
|||
tags: ["thevenin", "impedance-measurement", "circuit-analysis", "simulation"] |
|||
--- |
|||
|
|||
# Thévenin Equivalent Method - Extraction |
|||
|
|||
The Thévenin equivalent method is a powerful technique that allows us to characterize a Tesla coil **once** and then predict its behavior with **any load** without re-running full simulations. This dramatically simplifies optimization and design work. |
|||
|
|||
## What is a Thévenin Equivalent? |
|||
|
|||
### Thévenin's Theorem |
|||
|
|||
**Statement:** Any linear two-terminal network can be replaced by: |
|||
- A voltage source **V_th** (the open-circuit voltage) |
|||
- In series with an impedance **Z_th** (the output impedance) |
|||
|
|||
``` |
|||
┌─────────────┐ ┌────┐ |
|||
│ Complex │ │V_th├───[Z_th]───o Output |
|||
│ Network │──o Output ≡ └────┘ | |
|||
│ │ | GND |
|||
└─────────────┘ GND |
|||
``` |
|||
|
|||
**Key advantage:** The Thévenin equivalent completely characterizes the network's behavior at the output terminals. Once extracted, you can predict performance with any load by simple circuit analysis. |
|||
|
|||
### Application to Tesla Coils |
|||
|
|||
For a Tesla coil, the "complex network" includes: |
|||
- Primary tank circuit (L_primary, C_MMC) |
|||
- Primary drive (inverter or spark gap) |
|||
- Magnetic coupling |
|||
- Secondary coil with all its distributed properties |
|||
- Topload capacitance |
|||
- All parasitic elements |
|||
|
|||
The **output port** is the topload-to-ground connection, where we connect the spark load. |
|||
|
|||
**Thévenin parameters:** |
|||
- **V_th:** The voltage that appears at the topload with no spark (open circuit) |
|||
- **Z_th:** The impedance "looking into" the topload terminal with the drive turned off |
|||
|
|||
## Step 1: Measuring Z_th (Output Impedance) |
|||
|
|||
The output impedance tells us how the coil "pushes back" against a load. It represents all the losses and reactive elements as seen from the topload. |
|||
|
|||
### Procedure |
|||
|
|||
**Step 1.1: Turn OFF primary drive** |
|||
- Set drive voltage to 0V (AC short circuit) |
|||
- Keep all tank components in place (MMC, L_primary, damping resistors) |
|||
- The tank circuit is still present, just not energized |
|||
- This "deactivates" all voltage sources in the network |
|||
|
|||
**Step 1.2: Apply test source** |
|||
- Apply 1V AC at operating frequency to topload-to-ground port |
|||
- Use small-signal AC source (in simulation or actual test equipment) |
|||
- Frequency should match your intended operating frequency |
|||
|
|||
**Step 1.3: Measure current** |
|||
``` |
|||
I_test = current flowing into topload port with 1V applied |
|||
``` |
|||
|
|||
In SPICE/simulation: |
|||
- Place 1V AC source between topload and ground |
|||
- Run AC analysis at operating frequency |
|||
- Read current magnitude and phase |
|||
|
|||
**Step 1.4: Calculate Z_th** |
|||
``` |
|||
Z_th = V_test / I_test = 1V / I_test |
|||
|
|||
Z_th = R_th + jX_th (complex impedance) |
|||
``` |
|||
|
|||
### Physical Meaning of Components |
|||
|
|||
**R_th (Resistance):** |
|||
- Secondary winding resistance (copper losses) |
|||
- Dielectric losses in the coil form |
|||
- Damping resistors in primary circuit |
|||
- Core losses (if any) |
|||
- Typical: 10-100 Ω for medium coils at RF frequencies |
|||
|
|||
**X_th (Reactance):** |
|||
- Usually negative (capacitive) due to topload |
|||
- Includes reflected impedances from coupling |
|||
- May include inductive component from coil |
|||
- Typical: -500 to -3000 Ω (strongly capacitive) |
|||
|
|||
**Magnitude |Z_th|:** |
|||
- Total opposition to current |
|||
- Typical: 500-3000 Ω for Tesla coils at 100-400 kHz |
|||
|
|||
**Phase φ_Z_th:** |
|||
- Usually -85° to -88° (nearly pure capacitive) |
|||
- Small R_th compared to |X_th| gives phase close to -90° |
|||
|
|||
### Quality Factor from Z_th |
|||
|
|||
The quality factor Q represents how "lossy" the coil is: |
|||
|
|||
``` |
|||
Q = |X_th| / R_th |
|||
|
|||
Higher Q → lower losses → more efficient |
|||
``` |
|||
|
|||
Typical values: |
|||
- Small coils: Q = 50-150 |
|||
- Medium coils: Q = 100-300 |
|||
- Large coils: Q = 200-500 |
|||
|
|||
## Step 2: Measuring V_th (Open-Circuit Voltage) |
|||
|
|||
The open-circuit voltage tells us what voltage the coil produces with no load attached. |
|||
|
|||
### Procedure |
|||
|
|||
**Step 2.1: Remove load** |
|||
- Disconnect spark (or ensure spark won't break out) |
|||
- Topload is in open-circuit condition |
|||
- No current flows to external loads |
|||
|
|||
**Step 2.2: Turn ON primary drive** |
|||
- Normal operating frequency and amplitude |
|||
- Drive the coil exactly as you would for spark operation |
|||
- Primary current flows, secondary is excited |
|||
|
|||
**Step 2.3: Measure topload voltage** |
|||
``` |
|||
V_th = V(topload) with no load |
|||
|
|||
Record both magnitude and phase (complex phasor) |
|||
``` |
|||
|
|||
In simulation: |
|||
- Run AC analysis with drive on |
|||
- Read voltage at topload node |
|||
- This is your V_th |
|||
|
|||
In practice: |
|||
- Use high-impedance voltage probe |
|||
- Capacitive divider for high voltages |
|||
- Or measure primary current and use coupling theory |
|||
|
|||
**Typical values:** |
|||
- Small coils (few hundred watts): V_th = 100-300 kV |
|||
- Medium coils (1-3 kW): V_th = 200-500 kV |
|||
- Large coils (5-10+ kW): V_th = 500 kV - 1 MV+ |
|||
|
|||
### Important Notes |
|||
|
|||
**Frequency dependence:** |
|||
- Both Z_th and V_th depend on frequency |
|||
- Extract at your operating frequency |
|||
- Near resonance, small frequency changes cause large V_th changes |
|||
|
|||
**Linearity assumption:** |
|||
- Thévenin theorem assumes linear network |
|||
- Valid for small-signal analysis |
|||
- For large sparks, nonlinear effects may require iterative refinement |
|||
|
|||
**Enhancement for frequency tracking:** |
|||
- Measure Z_th(ω) and V_th(ω) over frequency band (±10%) |
|||
- Accounts for resonance shift when spark loads the coil |
|||
- Enables accurate predictions with different loads |
|||
|
|||
## Worked Example: Extracting Z_th from Simulation |
|||
|
|||
**Simulation setup:** |
|||
- DRSSTC at f = 185 kHz |
|||
- Primary drive set to 0V (AC short) |
|||
- All components remain (L_primary, C_MMC, secondary, topload) |
|||
- AC test source: 1V ∠0° at topload-to-ground |
|||
|
|||
**Simulation results:** |
|||
``` |
|||
I_test = 0.000412 ∠87.3° A = 0.412 mA ∠87.3° |
|||
``` |
|||
|
|||
### Calculate Z_th |
|||
|
|||
**Step 1: Impedance magnitude** |
|||
``` |
|||
|Z_th| = |V| / |I| = 1 V / 0.000412 A = 2427 Ω |
|||
``` |
|||
|
|||
**Step 2: Impedance phase** |
|||
``` |
|||
φ_Z_th = φ_V - φ_I = 0° - 87.3° = -87.3° |
|||
``` |
|||
|
|||
**Step 3: Polar form** |
|||
``` |
|||
Z_th = 2427 Ω ∠-87.3° |
|||
``` |
|||
|
|||
**Step 4: Convert to rectangular form** |
|||
``` |
|||
R_th = |Z_th| × cos(φ_Z_th) = 2427 × cos(-87.3°) = 2427 × 0.0471 = 114 Ω |
|||
|
|||
X_th = |Z_th| × sin(φ_Z_th) = 2427 × sin(-87.3°) = 2427 × (-0.9989) = -2424 Ω |
|||
|
|||
Z_th = 114 - j2424 Ω |
|||
``` |
|||
|
|||
### Interpretation |
|||
|
|||
**R_th = 114 Ω:** |
|||
- Represents all resistive losses in the system |
|||
- Includes secondary winding resistance |
|||
- Includes reflected primary losses |
|||
- This is the "cost" of extracting power from the coil |
|||
|
|||
**X_th = -2424 Ω:** |
|||
- Strongly capacitive (negative reactance) |
|||
- Topload capacitance dominates |
|||
- At 185 kHz: C_equivalent ≈ 1/(ω|X_th|) ≈ 35 pF |
|||
|
|||
**Phase ≈ -87°:** |
|||
- Nearly pure capacitor (ideal would be -90°) |
|||
- Small resistive component (R_th << |X_th|) |
|||
- Typical for well-designed Tesla coils |
|||
|
|||
**Quality factor:** |
|||
``` |
|||
Q = |X_th| / R_th = 2424 / 114 ≈ 21 |
|||
``` |
|||
|
|||
This Q is relatively low, likely because: |
|||
- Measurement includes all system damping |
|||
- Primary circuit losses are reflected |
|||
- This is the "loaded" Q of the coupled system |
|||
|
|||
## Visual Aid: Thévenin Measurement Setup |
|||
|
|||
 |
|||
|
|||
*Image shows comparison between:* |
|||
- *Left: Full Tesla coil circuit (complex, many components)* |
|||
- *Right: Thévenin equivalent (simple: V_th in series with Z_th)* |
|||
- *Bottom: Measurement configuration for Z_th extraction* |
|||
|
|||
**Key elements:** |
|||
- Primary drive: OFF (0V) for Z_th measurement |
|||
- Test source: 1V AC at topload for Z_th |
|||
- All tank components remain in circuit |
|||
- Ammeter measures test current I_test |
|||
- Calculation: Z_th = 1V / I_test |
|||
|
|||
## Common Pitfalls |
|||
|
|||
### Pitfall 1: Removing Tank Components |
|||
|
|||
**Wrong:** Disconnecting C_MMC or shorting L_primary |
|||
|
|||
**Right:** Keep all components, just set drive to 0V |
|||
|
|||
**Why:** The tank circuit affects the output impedance. Removing components gives incorrect Z_th. |
|||
|
|||
### Pitfall 2: Wrong Frequency |
|||
|
|||
**Wrong:** Extracting Z_th at one frequency, using at another |
|||
|
|||
**Right:** Extract at operating frequency, or measure Z_th(ω) over range |
|||
|
|||
**Why:** Impedance is highly frequency-dependent near resonance |
|||
|
|||
### Pitfall 3: Ignoring Phase |
|||
|
|||
**Wrong:** Using only |Z_th| without phase information |
|||
|
|||
**Right:** Keep full complex impedance Z_th = R_th + jX_th |
|||
|
|||
**Why:** Phase affects power calculations and matching |
|||
|
|||
### Pitfall 4: Using I_base Instead of Port Current |
|||
|
|||
**Wrong:** Measuring current at secondary base for Z_th test |
|||
|
|||
**Right:** Measure current through test source at topload port |
|||
|
|||
**Why:** Base current includes displacement currents (see Module 2.4) |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Thévenin equivalent** reduces complex coil to simple V_th and Z_th |
|||
- **Z_th extraction:** Drive OFF, apply 1V test, measure current, Z_th = 1V/I_test |
|||
- **V_th extraction:** Drive ON, no load, measure topload voltage |
|||
- **Z_th components:** R_th (losses), X_th (reactance, usually capacitive) |
|||
- **Typical values:** R_th = 10-100 Ω, X_th = -500 to -3000 Ω, |Z_th| = 500-3000 Ω |
|||
- **Quality factor:** Q = |X_th|/R_th indicates coil efficiency |
|||
- **Frequency matters:** Extract at operating frequency or measure Z_th(ω) |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-03} |
|||
|
|||
**Problem 1:** A test measurement gives I_test = 0.00035 ∠82° A for V_test = 1 ∠0° V at f = 200 kHz. Calculate: |
|||
(a) Z_th in polar form |
|||
(b) Z_th in rectangular form (R_th + jX_th) |
|||
(c) Quality factor Q |
|||
|
|||
**Problem 2:** If Z_th = 85 - j1800 Ω, what is the equivalent capacitance at f = 180 kHz? |
|||
|
|||
**Problem 3:** A coil has Z_th = 120 - j2100 Ω. Calculate: |
|||
(a) Impedance magnitude and phase |
|||
(b) Quality factor |
|||
(c) Would you describe this as "high Q" or "low Q"? |
|||
|
|||
**Problem 4:** Explain why we short the drive voltage source (set to 0V) when measuring Z_th, but keep all passive components in place. |
|||
|
|||
**Problem 5:** Two coils have the same |Z_th| = 2000 Ω but different phases: Coil A has φ = -88°, Coil B has φ = -75°. Which coil has lower losses (higher Q)? Calculate Q for both. |
|||
|
|||
--- |
|||
**Next Lesson:** [Thévenin Calculations - Using the Equivalent](04-thevenin-calculations.md) |
|||
@ -0,0 +1,397 @@ |
|||
--- |
|||
id: opt-04 |
|||
title: "Using the Thévenin Equivalent - Power Calculations" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "intermediate" |
|||
estimated_time: 45 |
|||
prerequisites: ["opt-03", "opt-01"] |
|||
objectives: |
|||
- Calculate load voltage and current using Thévenin equivalent |
|||
- Compute power delivered to arbitrary loads |
|||
- Determine maximum theoretical power (conjugate match) |
|||
- Understand why conjugate match is usually unachievable |
|||
tags: ["thevenin", "power-calculation", "impedance-matching", "circuit-analysis"] |
|||
--- |
|||
|
|||
# Using the Thévenin Equivalent - Power Calculations |
|||
|
|||
Now that we've extracted the Thévenin equivalent (V_th and Z_th), we can use it to predict coil performance with any load without re-running full simulations. This lesson shows how to perform these calculations and interpret the results. |
|||
|
|||
## Predicting Behavior with Any Load |
|||
|
|||
Once you have V_th and Z_th, the Tesla coil looks like this simple circuit: |
|||
|
|||
``` |
|||
┌────┐ |
|||
│V_th├───[Z_th]───┬─── Output |
|||
└────┘ │ |
|||
[Z_load] |
|||
│ |
|||
GND |
|||
``` |
|||
|
|||
This is just a voltage divider! We can apply basic circuit analysis. |
|||
|
|||
### Voltage Across Load |
|||
|
|||
Using voltage divider rule: |
|||
|
|||
``` |
|||
V_load = V_th × [Z_load / (Z_th + Z_load)] |
|||
``` |
|||
|
|||
**Complex arithmetic:** Both numerator and denominator are complex numbers, so you need to handle magnitude and phase carefully. |
|||
|
|||
### Current Through Load |
|||
|
|||
Using Ohm's law on the series circuit: |
|||
|
|||
``` |
|||
I = V_th / (Z_th + Z_load) |
|||
``` |
|||
|
|||
This current flows through both Z_th and Z_load since they're in series. |
|||
|
|||
### Power Delivered to Load |
|||
|
|||
Power dissipated in the load (real power only): |
|||
|
|||
``` |
|||
P_load = 0.5 × |I|² × Re{Z_load} |
|||
``` |
|||
|
|||
Or equivalently: |
|||
|
|||
``` |
|||
P_load = 0.5 × Re{V_load × I*} |
|||
``` |
|||
|
|||
where I* is the complex conjugate of I. |
|||
|
|||
**Direct formula combining everything:** |
|||
|
|||
``` |
|||
P_load = 0.5 × |V_th|² × Re{Z_load} / |Z_th + Z_load|² |
|||
``` |
|||
|
|||
This formula is gold! It lets you sweep different Z_load values and calculate power without any additional simulation. |
|||
|
|||
## Step-by-Step Calculation Process |
|||
|
|||
### Given Information |
|||
- V_th (complex voltage phasor) |
|||
- Z_th = R_th + jX_th (complex impedance) |
|||
- Z_load = R_load + jX_load (spark impedance from model) |
|||
|
|||
### Step 1: Calculate Total Impedance |
|||
|
|||
``` |
|||
Z_total = Z_th + Z_load |
|||
= (R_th + R_load) + j(X_th + X_load) |
|||
|
|||
R_total = R_th + R_load |
|||
X_total = X_th + X_load |
|||
|
|||
|Z_total| = √(R_total² + X_total²) |
|||
``` |
|||
|
|||
### Step 2: Calculate Current |
|||
|
|||
``` |
|||
I = V_th / Z_total |
|||
|
|||
|I| = |V_th| / |Z_total| |
|||
|
|||
φ_I = φ_V_th - φ_Z_total |
|||
``` |
|||
|
|||
where φ_Z_total = atan(X_total / R_total) |
|||
|
|||
### Step 3: Calculate Load Voltage |
|||
|
|||
``` |
|||
V_load = I × Z_load |
|||
|
|||
|V_load| = |I| × |Z_load| |
|||
|
|||
φ_V_load = φ_I + φ_Z_load |
|||
``` |
|||
|
|||
Or use voltage divider directly (often simpler): |
|||
|
|||
``` |
|||
|V_load| = |V_th| × |Z_load| / |Z_total| |
|||
``` |
|||
|
|||
### Step 4: Calculate Power in Load |
|||
|
|||
``` |
|||
P_load = 0.5 × |I|² × R_load |
|||
|
|||
P_load = 0.5 × |I|² × Re{Z_load} |
|||
``` |
|||
|
|||
The factor of 0.5 accounts for peak phasor to RMS conversion in AC power. |
|||
|
|||
## Worked Example: Complete Thévenin Analysis |
|||
|
|||
**Given:** |
|||
- Z_th = 114 - j2424 Ω (from previous lesson) |
|||
- V_th = 350 kV ∠0° (measured with drive on, no load) |
|||
- Spark load: Z_spark = 60 kΩ - j160 kΩ (from lumped model) |
|||
|
|||
**Find:** |
|||
(a) Current through spark |
|||
(b) Voltage across spark |
|||
(c) Power dissipated in spark |
|||
(d) Theoretical maximum power (conjugate match) |
|||
|
|||
### Part (a): Current Through Spark |
|||
|
|||
**Calculate total impedance:** |
|||
``` |
|||
Z_total = Z_th + Z_spark |
|||
= (114 - j2424) + (60000 - j160000) |
|||
= (60114 - j162424) Ω |
|||
|
|||
R_total = 60114 Ω |
|||
X_total = -162424 Ω |
|||
|
|||
|Z_total| = √(60114² + 162424²) |
|||
= √(3.614×10⁹ + 2.638×10¹⁰) |
|||
= √(3.000×10¹⁰) |
|||
= 173.2 kΩ |
|||
``` |
|||
|
|||
**Calculate current:** |
|||
``` |
|||
I = V_th / Z_total |
|||
|I| = 350 kV / 173.2 kΩ = 2.02 A peak |
|||
``` |
|||
|
|||
### Part (b): Voltage Across Spark |
|||
|
|||
**Method 1: Voltage divider** |
|||
``` |
|||
|Z_spark| = √(60000² + 160000²) |
|||
= √(3.6×10⁹ + 2.56×10¹⁰) |
|||
= √(2.92×10¹⁰) |
|||
= 171 kΩ |
|||
|
|||
|V_spark| = |V_th| × |Z_spark| / |Z_total| |
|||
= 350 kV × (171 kΩ / 173.2 kΩ) |
|||
= 350 kV × 0.987 |
|||
= 345 kV |
|||
``` |
|||
|
|||
**Method 2: Using current** |
|||
``` |
|||
|V_spark| = |I| × |Z_spark| |
|||
= 2.02 A × 171 kΩ |
|||
= 345 kV |
|||
``` |
|||
|
|||
**Observation:** Most voltage appears across the spark! This makes sense because Z_spark >> Z_th. |
|||
|
|||
### Part (c): Power in Spark |
|||
|
|||
``` |
|||
P_spark = 0.5 × |I|² × Re{Z_spark} |
|||
= 0.5 × (2.02)² × 60000 |
|||
= 0.5 × 4.08 × 60000 |
|||
= 122 kW |
|||
``` |
|||
|
|||
This is the real power dissipated in heating, ionization, radiation, and sound in the spark. |
|||
|
|||
### Part (d): Theoretical Maximum Power |
|||
|
|||
The maximum power transfer theorem states that power is maximized when the load impedance is the **complex conjugate** of the source impedance. |
|||
|
|||
**Conjugate match condition:** |
|||
``` |
|||
Z_load = Z_th* (complex conjugate) |
|||
|
|||
If Z_th = R_th + jX_th |
|||
Then Z_load = R_th - jX_th |
|||
|
|||
For our case: |
|||
Z_th = 114 - j2424 Ω |
|||
Z_load_optimal = 114 + j2424 Ω |
|||
``` |
|||
|
|||
**Why this maximizes power:** |
|||
- Reactive components cancel: Z_total = Z_th + Z_th* = 2R_th (purely real) |
|||
- No reactive power circulation |
|||
- All delivered power is real |
|||
|
|||
**Maximum power formula:** |
|||
``` |
|||
P_max = |V_th|² / (8 × R_th) |
|||
``` |
|||
|
|||
**Calculate:** |
|||
``` |
|||
P_max = (350×10³)² / (8 × 114) |
|||
= 1.225×10¹¹ / 912 |
|||
= 134.3 MW |
|||
``` |
|||
|
|||
**Wait, this seems enormous!** |
|||
|
|||
Let's double-check: |
|||
``` |
|||
With Z_load = 114 + j2424 Ω: |
|||
|
|||
Z_total = (114 - j2424) + (114 + j2424) = 228 Ω (purely resistive!) |
|||
|
|||
I = 350 kV / 228 Ω = 1535 A |
|||
|
|||
P = 0.5 × (1535)² × 114 = 134.3 MW ✓ |
|||
``` |
|||
|
|||
### Part (e): Reality Check - Why Such a Huge Difference? |
|||
|
|||
**Actual spark power:** 122 kW |
|||
**Theoretical maximum:** 134.3 MW |
|||
**Efficiency:** 122 / 134,300 = 0.09% of theoretical maximum |
|||
|
|||
**Why such a huge discrepancy?** |
|||
|
|||
1. **Conjugate match requires Z_load = 114 + j2424 Ω** |
|||
- This means R_load = 114 Ω (extremely low!) |
|||
- This means X_load = +2424 Ω (inductive, not capacitive) |
|||
|
|||
2. **Actual spark: Z_spark = 60 kΩ - j160 kΩ** |
|||
- R_spark = 60 kΩ (525× too high!) |
|||
- X_spark = -160 kΩ (capacitive, wrong sign, 66× too large) |
|||
|
|||
3. **Topological constraints prevent achieving conjugate match:** |
|||
- Spark structure (R||C_mut in series with C_sh) is inherently capacitive |
|||
- Cannot produce positive (inductive) reactance |
|||
- Cannot achieve R_load as low as 114 Ω with realistic plasma |
|||
|
|||
**This is normal for Tesla coils!** The impedance mismatch is fundamental to the physics of spark discharges. We cannot achieve conjugate match in practice. |
|||
|
|||
## Understanding Efficiency |
|||
|
|||
### What Does 0.09% Mean? |
|||
|
|||
It does NOT mean the coil is "inefficient" in the usual sense. Rather: |
|||
|
|||
- The coil has very low output impedance (114 Ω) |
|||
- The spark has very high impedance (171 kΩ) |
|||
- This is a 1500:1 impedance mismatch |
|||
- The voltage divider heavily favors the spark (good!) |
|||
- Most voltage appears at the spark, but current is limited |
|||
|
|||
### Voltage Transfer Efficiency |
|||
|
|||
``` |
|||
Voltage across spark / Total voltage: |
|||
345 kV / 350 kV = 98.6% |
|||
``` |
|||
|
|||
We achieve excellent voltage transfer! This is what matters for spark length (field at tip). |
|||
|
|||
### Why Not Match Impedances? |
|||
|
|||
**In conventional circuits:** Match impedances for maximum power transfer |
|||
|
|||
**In Tesla coils:** We WANT high spark impedance because: |
|||
- High voltage at spark tip drives field |
|||
- High resistance means controlled current (safety) |
|||
- Mismatch is unavoidable due to plasma physics |
|||
- Optimization focuses on maximizing power given the constraints |
|||
|
|||
## Practical Use: Sweeping Spark Parameters |
|||
|
|||
The real power of Thévenin analysis is rapid parameter sweeps: |
|||
|
|||
**Given:** V_th = 350 kV, Z_th = 114 - j2424 Ω |
|||
|
|||
**Sweep:** Spark resistance R from 10 kΩ to 200 kΩ |
|||
|
|||
**For each R value:** |
|||
1. Construct Z_spark from R and capacitances (using lumped model) |
|||
2. Calculate Z_total = Z_th + Z_spark |
|||
3. Calculate I = V_th / Z_total |
|||
4. Calculate P = 0.5 × |I|² × R |
|||
5. Plot P vs R |
|||
|
|||
**Result:** You find P_max at R ≈ R_opt_power without any new simulations! |
|||
|
|||
## When Thévenin Analysis Fails |
|||
|
|||
### Nonlinearity |
|||
|
|||
**Assumption:** Coil behaves linearly (impedances don't change with voltage/current) |
|||
|
|||
**Breaks down when:** |
|||
- Magnetic cores saturate |
|||
- Component heating changes parameters |
|||
- Very large sparks significantly load the coil |
|||
|
|||
**Solution:** Iterate - use results to update model, re-extract Thévenin |
|||
|
|||
### Frequency Dependence |
|||
|
|||
**Assumption:** Operating at a single frequency |
|||
|
|||
**Breaks down when:** |
|||
- Spark loading shifts resonant frequency |
|||
- Comparing different loads at fixed frequency (detuning varies) |
|||
|
|||
**Solution:** Extract Z_th(ω) and V_th(ω), account for frequency shift (next lessons) |
|||
|
|||
### Coupled Modes |
|||
|
|||
**Assumption:** Single-mode operation |
|||
|
|||
**Breaks down when:** |
|||
- Operating between two coupled poles |
|||
- Mode hopping as spark changes loading |
|||
|
|||
**Solution:** Full coupled-mode analysis or stay clearly in one mode |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Thévenin circuit:** Simple series combination of V_th and Z_th |
|||
- **Load voltage:** V_load = V_th × Z_load/(Z_th + Z_load) |
|||
- **Load current:** I = V_th / (Z_th + Z_load) |
|||
- **Load power:** P = 0.5 × |I|² × Re{Z_load} or P = 0.5 × |V_th|² × Re{Z_load}/|Z_th + Z_load|² |
|||
- **Maximum power:** Requires conjugate match Z_load = Z_th* |
|||
- **P_max = |V_th|²/(8R_th)** but usually unachievable |
|||
- **Tesla coils operate far from conjugate match** due to physics constraints |
|||
- **High voltage transfer efficiency** matters more than impedance matching |
|||
- **Parameter sweeps** become trivial with Thévenin equivalent |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-04} |
|||
|
|||
**Problem 1:** Given Z_th = 95 - j1850 Ω, V_th = 280 kV, and a spark model with Z_spark = 50 kΩ - j140 kΩ: |
|||
(a) Calculate total impedance |
|||
(b) Calculate current through spark |
|||
(c) Calculate power delivered to spark |
|||
(d) Calculate theoretical maximum power (conjugate match) |
|||
(e) What percentage of theoretical maximum is achieved? |
|||
|
|||
**Problem 2:** A load Z_load = 200 + j200 Ω is connected to a coil with Z_th = 100 - j2000 Ω and V_th = 300 kV. |
|||
(a) Calculate the load voltage |
|||
(b) Calculate power delivered |
|||
(c) Is this load inductive or capacitive? |
|||
(d) Is this load closer to conjugate match than a typical spark? |
|||
|
|||
**Problem 3:** For Z_th = 120 - j2200 Ω: |
|||
(a) What load impedance gives conjugate match? |
|||
(b) Calculate P_max if V_th = 400 kV |
|||
(c) If actual spark has R = 70 kΩ, X = -180 kΩ, calculate actual power |
|||
(d) Calculate the power transfer efficiency ratio |
|||
|
|||
**Problem 4:** A coil has V_th = 350 kV and Z_th = 110 - j2500 Ω. You want to deliver 100 kW to a purely resistive load. What resistance value is required? (Hint: Set P = 100 kW in power formula and solve for R) |
|||
|
|||
**Problem 5:** Explain physically why Tesla coils operate so far from conjugate match. Why can't we just add inductance to the spark to cancel its capacitive reactance? |
|||
|
|||
--- |
|||
**Next Lesson:** [Direct Power Measurement Method](05-direct-measurement.md) |
|||
@ -0,0 +1,337 @@ |
|||
--- |
|||
id: opt-05 |
|||
title: "Direct Power Measurement Method" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "intermediate" |
|||
estimated_time: 25 |
|||
prerequisites: ["opt-04", "opt-01"] |
|||
objectives: |
|||
- Understand the direct measurement alternative to Thévenin |
|||
- Set up simulations for direct power measurement |
|||
- Extract spark resistance through power optimization |
|||
- Compare advantages and disadvantages of each method |
|||
tags: ["power-measurement", "simulation", "optimization", "methodology"] |
|||
--- |
|||
|
|||
# Direct Power Measurement Method |
|||
|
|||
While the Thévenin equivalent method is powerful and elegant, there's an alternative approach: directly measure power delivered to the spark in a full simulation. Each method has advantages and trade-offs. |
|||
|
|||
## The Direct Measurement Approach |
|||
|
|||
### Concept |
|||
|
|||
Instead of extracting a simplified equivalent circuit, keep the **full coupled model** with the spark load present and directly measure power flow. |
|||
|
|||
**Setup:** |
|||
1. Build complete simulation (primary, secondary, coupling, spark load) |
|||
2. Drive primary at operating frequency and amplitude |
|||
3. Run AC analysis (or transient with post-processing) |
|||
4. Measure power dissipated in spark resistance |
|||
5. Repeat for different spark resistance values |
|||
|
|||
**Goal:** Find the spark resistance R that maximizes measured power |
|||
|
|||
### Procedure |
|||
|
|||
**Step 1: Build Full Model** |
|||
- Primary tank circuit (L_primary, C_MMC) |
|||
- Secondary coil (distributed or lumped model) |
|||
- Topload capacitance |
|||
- Magnetic coupling k |
|||
- **Spark load** modeled as R||C_mut in series with C_sh |
|||
|
|||
**Step 2: Set Operating Point** |
|||
- Drive frequency: f_drive (initially at unloaded resonance) |
|||
- Drive amplitude: V_drive or I_drive |
|||
- Spark parameters: Choose initial R, C_mut, C_sh |
|||
|
|||
**Step 3: Run AC Analysis** |
|||
- Solve circuit at drive frequency |
|||
- Extract voltage and current at spark resistor |
|||
- Calculate power: P = 0.5 × Re{V_spark × I_spark*} |
|||
|
|||
Or more directly: |
|||
``` |
|||
P = 0.5 × |I_R|² × R |
|||
|
|||
where I_R is current through the resistance R |
|||
``` |
|||
|
|||
**Step 4: Sweep R Values** |
|||
- Vary R from 10 kΩ to 200 kΩ (typical range) |
|||
- For each R, measure P |
|||
- Plot P vs R |
|||
- Find R that gives maximum P → this is R_opt_power |
|||
|
|||
**Step 5: Validate** |
|||
- Compare numerical R_opt_power to analytical formula |
|||
- Check that it matches: R_opt = 1/[ω(C_mut + C_sh)] |
|||
|
|||
## Power Measurement in SPICE |
|||
|
|||
### Method 1: Using Current Through Resistor |
|||
|
|||
``` |
|||
.param Rspark = 50k |
|||
Rspark topload node2 {Rspark} |
|||
Cmut node2 0 8p |
|||
Csh topload 0 6p |
|||
|
|||
.ac lin 1 185k 185k |
|||
.step param Rspark list 10k 30k 50k 70k 100k 150k |
|||
|
|||
.meas ac Ispark_mag find mag(I(Rspark)) |
|||
.meas ac Pspark param '0.5 * Ispark_mag^2 * Rspark' |
|||
``` |
|||
|
|||
This sweeps Rspark and calculates power for each value. |
|||
|
|||
### Method 2: Direct Power Function |
|||
|
|||
Some SPICE variants support direct power measurement: |
|||
|
|||
``` |
|||
.meas ac Pspark_real find Re(V(topload)*conj(I(Rspark))) |
|||
``` |
|||
|
|||
This directly computes complex power and extracts the real part. |
|||
|
|||
### Method 3: Voltage and Current |
|||
|
|||
``` |
|||
.meas ac Vtop_mag find mag(V(topload)) |
|||
.meas ac Ispark_mag find mag(I(Rspark)) |
|||
.meas ac phase_diff param 'ph(V(topload)) - ph(I(Rspark))' |
|||
.meas ac Pspark param '0.5 * Vtop_mag * Ispark_mag * cos(phase_diff)' |
|||
``` |
|||
|
|||
This accounts for phase difference in power calculation. |
|||
|
|||
## Worked Example: Direct Optimization |
|||
|
|||
**Given:** |
|||
- DRSSTC simulation at f = 185 kHz |
|||
- Primary drive: V_drive produces V_top ≈ 350 kV (unloaded) |
|||
- Spark model: C_mut = 8 pF, C_sh = 6 pF, R = variable |
|||
|
|||
**Goal:** Find R_opt_power |
|||
|
|||
### Analytical Prediction |
|||
|
|||
First, predict what we should find: |
|||
|
|||
``` |
|||
C_total = C_mut + C_sh = 8 + 6 = 14 pF |
|||
ω = 2π × 185×10³ = 1.162×10⁶ rad/s |
|||
|
|||
R_opt_power = 1/(ωC_total) |
|||
= 1/(1.162×10⁶ × 14×10⁻¹²) |
|||
= 61.5 kΩ |
|||
``` |
|||
|
|||
We expect maximum power near 61.5 kΩ. |
|||
|
|||
### Simulation Sweep |
|||
|
|||
**Run AC analysis with R values:** |
|||
- R = 20 kΩ → P = 85 kW |
|||
- R = 40 kΩ → P = 115 kW |
|||
- R = 60 kΩ → P = 125 kW ← **Maximum** |
|||
- R = 80 kΩ → P = 118 kW |
|||
- R = 100 kΩ → P = 105 kW |
|||
|
|||
**Result:** Maximum power at R ≈ 60 kΩ |
|||
|
|||
**Validation:** Simulation (60 kΩ) matches theory (61.5 kΩ) within rounding! |
|||
|
|||
## Advantages of Direct Measurement |
|||
|
|||
### 1. No Approximations |
|||
|
|||
- Full coupled model captures all interactions |
|||
- No linearization assumptions |
|||
- Includes all nonlinear effects (if using transient analysis) |
|||
|
|||
### 2. Intuitive |
|||
|
|||
- Directly see what you care about: power to spark |
|||
- No intermediate steps |
|||
- Easy to visualize results |
|||
|
|||
### 3. Flexibility |
|||
|
|||
- Can use any circuit simulator |
|||
- Works with complex topologies |
|||
- Easy to add additional elements (damping, protection, etc.) |
|||
|
|||
### 4. Transient Capability |
|||
|
|||
- Can extend to time-domain (transient) analysis |
|||
- Capture burst mode, ramping, dynamics |
|||
- See energy transfer over time |
|||
|
|||
## Disadvantages of Direct Measurement |
|||
|
|||
### 1. Computational Cost |
|||
|
|||
- Must re-run full simulation for each R value |
|||
- Sweep of 20 points = 20 full simulations |
|||
- Slow for large parameter spaces |
|||
|
|||
### 2. Limited Insight |
|||
|
|||
- Doesn't reveal underlying equivalent circuit |
|||
- Harder to understand why maximum occurs where it does |
|||
- Less portable to different load types |
|||
|
|||
### 3. Frequency Coupling |
|||
|
|||
- Operating frequency may need adjustment for each R (see next lesson!) |
|||
- Fixed-frequency comparison can be misleading |
|||
- Must account for resonance shift |
|||
|
|||
### 4. Sensitivity to Setup |
|||
|
|||
- Results depend on drive amplitude, frequency, damping |
|||
- Harder to isolate spark effects from system effects |
|||
|
|||
## Comparison: Thévenin vs Direct |
|||
|
|||
| Aspect | Thévenin Method | Direct Method | |
|||
|--------|----------------|---------------| |
|||
| **Speed** | Fast (single extraction + algebra) | Slow (simulation per R value) | |
|||
| **Insight** | High (reveals equivalent circuit) | Moderate | |
|||
| **Accuracy** | Excellent (if linear) | Excellent (includes nonlinearities) | |
|||
| **Flexibility** | Any load instantly | One load per simulation | |
|||
| **Complexity** | Requires understanding of method | Straightforward | |
|||
| **Best for** | Sweeps, optimization, understanding | Validation, nonlinear cases | |
|||
|
|||
## When to Use Each Method |
|||
|
|||
### Use Thévenin When: |
|||
- Exploring many different load configurations |
|||
- Optimizing spark parameters |
|||
- Building intuition about matching |
|||
- Preparing design curves |
|||
- Speed is important |
|||
|
|||
### Use Direct Measurement When: |
|||
- Validating Thévenin results |
|||
- Dealing with significant nonlinearities |
|||
- Need transient/time-domain behavior |
|||
- Checking specific operating points |
|||
- Learning circuit behavior |
|||
|
|||
### Best Practice: Use Both |
|||
|
|||
1. **Start with Thévenin:** Fast exploration, find optimal regions |
|||
2. **Validate with Direct:** Confirm key points, check assumptions |
|||
3. **Iterate:** If discrepancies exist, understand why |
|||
|
|||
## Accounting for Displacement Currents |
|||
|
|||
Both methods can fall victim to the "I_base error" discussed in Module 2.4. |
|||
|
|||
### The Problem |
|||
|
|||
**Wrong:** Measuring total current returning through secondary base |
|||
|
|||
**Right:** Measuring current specifically through spark resistance |
|||
|
|||
### Why It Matters |
|||
|
|||
Total base current includes: |
|||
- Spark current (what we want) |
|||
- Displacement currents from secondary to ground |
|||
- Coupling currents to primary |
|||
- Environmental coupling |
|||
|
|||
**In SPICE:** This isn't usually a problem because you can measure specific branch currents. Use I(Rspark) not I(V_secondary_base). |
|||
|
|||
**In physical measurements:** You must use current probes on the spark return path, not the coil base. |
|||
|
|||
## Implementation Tips |
|||
|
|||
### Tip 1: Automate Sweeps |
|||
|
|||
Use SPICE .STEP or scripting: |
|||
|
|||
``` |
|||
.step param Rspark 10k 200k 5k |
|||
``` |
|||
|
|||
This automatically sweeps from 10 kΩ to 200 kΩ in 5 kΩ steps. |
|||
|
|||
### Tip 2: Log Scale for Wide Ranges |
|||
|
|||
Spark resistance varies over decades (10 kΩ to 1 MΩ). Use logarithmic stepping: |
|||
|
|||
``` |
|||
.step param Rspark list 10k 20k 50k 100k 200k 500k |
|||
``` |
|||
|
|||
### Tip 3: Extract Peak Directly |
|||
|
|||
Use .MEAS to find maximum automatically: |
|||
|
|||
``` |
|||
.meas ac Pmax MAX Pspark |
|||
.meas ac Ropt WHEN Pspark=Pmax |
|||
``` |
|||
|
|||
### Tip 4: Verify Power Components |
|||
|
|||
Separately measure real and reactive power: |
|||
|
|||
``` |
|||
P_real = Re{V × I*} |
|||
Q_reactive = Im{V × I*} |
|||
S_apparent = |V × I*| |
|||
``` |
|||
|
|||
Check that Q >> P (highly reactive, as expected). |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Direct measurement:** Keep full model, measure power in spark, sweep R |
|||
- **Advantages:** Intuitive, no approximations, handles nonlinearity |
|||
- **Disadvantages:** Slow, less insight, multiple simulations required |
|||
- **Power formula:** P = 0.5 × |I_R|² × R or P = 0.5 × Re{V × I*} |
|||
- **Find R_opt:** Sweep R, plot P vs R, identify maximum |
|||
- **Validation:** Should match analytical R_opt = 1/[ω(C_mut + C_sh)] |
|||
- **Best practice:** Use Thévenin for exploration, direct measurement for validation |
|||
- **Beware:** Measure spark current, not base current (displacement current issue) |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-05} |
|||
|
|||
**Problem 1:** You run simulations with the following results: |
|||
|
|||
| R (kΩ) | P (kW) | |
|||
|--------|--------| |
|||
| 30 | 92 | |
|||
| 50 | 118 | |
|||
| 70 | 128 | |
|||
| 90 | 125 | |
|||
| 110 | 115 | |
|||
|
|||
(a) Estimate R_opt_power from this data |
|||
(b) If C_total = 12 pF and f = 200 kHz, what does theory predict? |
|||
(c) Do they match? |
|||
|
|||
**Problem 2:** A simulation reports I_R = 2.1 A (peak) through R = 55 kΩ. Calculate the power dissipated. |
|||
|
|||
**Problem 3:** You measure V_topload = 340 kV ∠0° and I_spark = 1.8 A ∠-72°. |
|||
(a) Calculate apparent power S = V × I* |
|||
(b) Extract real power P = Re{S} |
|||
(c) Extract reactive power Q = Im{S} |
|||
(d) Is the spark more resistive or reactive? |
|||
|
|||
**Problem 4:** List two scenarios where direct measurement would be preferred over Thévenin extraction. |
|||
|
|||
**Problem 5:** Why is it important to measure I(Rspark) rather than I(V_secondary_base) when calculating power? Sketch the circuit showing both current paths. |
|||
|
|||
--- |
|||
**Next Lesson:** [Frequency Tracking and Loaded Poles](06-frequency-tracking.md) |
|||
@ -0,0 +1,485 @@ |
|||
--- |
|||
id: opt-06 |
|||
title: "Frequency Tracking and Loaded Poles" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "advanced" |
|||
estimated_time: 45 |
|||
prerequisites: ["opt-05", "opt-01", "fund-08"] |
|||
objectives: |
|||
- Understand coupled system poles and eigenfrequencies |
|||
- Recognize frequency shift with loading |
|||
- Implement proper frequency tracking in measurements |
|||
- Avoid common detuning errors in optimization |
|||
- Apply frequency tracking to DRSSTC operating modes |
|||
tags: ["frequency-tracking", "coupled-resonators", "detuning", "poles", "DRSSTC"] |
|||
--- |
|||
|
|||
# Frequency Tracking and Loaded Poles |
|||
|
|||
**This is one of the most commonly overlooked aspects of Tesla coil optimization.** Failing to account for frequency tracking leads to misleading power measurements and incorrect conclusions about optimal operating points. |
|||
|
|||
## The Critical Problem: Fixed-Frequency Comparison |
|||
|
|||
### Common Mistake |
|||
|
|||
**Scenario:** You want to find R_opt_power by measuring power delivered to different spark resistances. |
|||
|
|||
**Wrong approach:** |
|||
1. Set drive frequency to f = 200 kHz (unloaded resonance) |
|||
2. Measure power with R = 30 kΩ → P₁ = 95 kW |
|||
3. Measure power with R = 60 kΩ → P₂ = 110 kW |
|||
4. Measure power with R = 90 kΩ → P₃ = 105 kW |
|||
5. Conclude: R_opt ≈ 60 kΩ |
|||
|
|||
**What's wrong?** Each different R value changes the system's resonant frequency. By staying at fixed f = 200 kHz, you're comparing: |
|||
- R = 30 kΩ at **Δf = +8 kHz detuned** |
|||
- R = 60 kΩ at **Δf = +3 kHz detuned** |
|||
- R = 90 kΩ at **Δf = -2 kHz detuned** |
|||
|
|||
**You're not measuring inherent matching quality - you're measuring a combination of matching AND detuning!** |
|||
|
|||
### Right Approach |
|||
|
|||
**Correct procedure:** |
|||
1. Set R = 30 kΩ |
|||
2. **Sweep frequency to find loaded resonance** → f₁ = 192 kHz |
|||
3. Measure power at f₁ → P₁ = 108 kW |
|||
4. Set R = 60 kΩ |
|||
5. **Sweep frequency to find new loaded resonance** → f₂ = 188 kHz |
|||
6. Measure power at f₂ → P₂ = 125 kW |
|||
7. Set R = 90 kΩ |
|||
8. **Sweep frequency to find new loaded resonance** → f₃ = 185 kHz |
|||
9. Measure power at f₃ → P₃ = 118 kW |
|||
10. Conclude: R_opt ≈ 60 kΩ **(and each was measured at its optimal frequency)** |
|||
|
|||
**Key principle: For each R value, retune to the loaded pole frequency.** |
|||
|
|||
## Why Does Loading Change Frequency? |
|||
|
|||
### Capacitance Changes Resonance |
|||
|
|||
When you change the spark, you change its sheath capacitance C_sh: |
|||
|
|||
**Unloaded:** |
|||
``` |
|||
C_total,0 = C_topload + C_secondary_stray ≈ 28 pF |
|||
f₀ = 1/(2π√(L_sec × C_total,0)) = 200 kHz |
|||
``` |
|||
|
|||
**With spark (R = 60 kΩ, 3-foot leader):** |
|||
``` |
|||
C_sh ≈ 2 pF/foot × 3 feet = 6 pF |
|||
C_total,1 = C_total,0 + C_sh = 28 + 6 = 34 pF |
|||
|
|||
f₁ = f₀ × √(C_total,0 / C_total,1) |
|||
= 200 × √(28/34) |
|||
= 200 × 0.907 |
|||
= 181 kHz |
|||
``` |
|||
|
|||
**Frequency dropped by 19 kHz!** This is not a small shift. |
|||
|
|||
### Different Sparks → Different Frequencies |
|||
|
|||
| Spark Length | C_sh | C_total | f_loaded | Δf | |
|||
|--------------|------|---------|----------|-----| |
|||
| No spark | 0 pF | 28 pF | 200 kHz | 0 | |
|||
| 2 feet | 4 pF | 32 pF | 187 kHz | -13 kHz | |
|||
| 4 feet | 8 pF | 36 pF | 176 kHz | -24 kHz | |
|||
| 6 feet | 12 pF | 40 pF | 167 kHz | -33 kHz | |
|||
|
|||
**Even for the same length, changing R changes the effective loading!** |
|||
|
|||
## Coupled System Poles |
|||
|
|||
Tesla coils are **coupled resonant systems**. Even without a spark, the primary-secondary coupling creates two resonant modes. |
|||
|
|||
### The Two Poles |
|||
|
|||
For coupled resonators with coupling coefficient k: |
|||
|
|||
**Lower pole (f₁):** |
|||
``` |
|||
f₁ = f₀ / √(1 + k) < f₀ |
|||
``` |
|||
|
|||
**Upper pole (f₂):** |
|||
``` |
|||
f₂ = f₀ / √(1 - k) > f₀ |
|||
``` |
|||
|
|||
where f₀ = √(f_primary × f_secondary) is the geometric mean. |
|||
|
|||
**Example with k = 0.15:** |
|||
``` |
|||
f₀ = 200 kHz (geometric mean) |
|||
f₁ = 200 / √(1.15) = 186.5 kHz (lower pole) |
|||
f₂ = 200 / √(0.85) = 217.0 kHz (upper pole) |
|||
``` |
|||
|
|||
### Loading Modifies Both Poles |
|||
|
|||
When a spark loads the secondary: |
|||
- **Both pole frequencies shift** (usually downward) |
|||
- **Both pole damping increases** (Q decreases) |
|||
- **Pole separation changes** |
|||
|
|||
The spark doesn't just add capacitance - it adds a complex load that couples into both modes. |
|||
|
|||
### Which Pole Should You Use? |
|||
|
|||
**For DRSSTC operation:** |
|||
- Most coils operate on the **lower pole** (more stable) |
|||
- Some operate between poles (dual-resonance mode) |
|||
- Upper pole is rarely used (harder to control) |
|||
|
|||
**The loaded pole frequency is where voltage gain is maximized.** |
|||
|
|||
## DRSSTC Operating Modes |
|||
|
|||
Different DRSSTC drive strategies interact with frequency tracking differently. |
|||
|
|||
### Mode 1: Fixed Frequency (No Tracking) |
|||
|
|||
**Strategy:** Drive at fixed frequency (e.g., 200 kHz) regardless of loading |
|||
|
|||
**Advantages:** |
|||
- Simple control electronics |
|||
- No frequency sensing required |
|||
- Predictable timing |
|||
|
|||
**Disadvantages:** |
|||
- **Detunes as spark grows** |
|||
- Voltage gain drops with larger sparks |
|||
- Suboptimal power transfer |
|||
- Risk of operating off-resonance |
|||
|
|||
**When acceptable:** |
|||
- Very short bursts (spark doesn't grow much) |
|||
- Controlled environments with consistent sparks |
|||
- Systems designed with wide bandwidth |
|||
|
|||
### Mode 2: Frequency Tracking (PLL or Feedback) |
|||
|
|||
**Strategy:** Continuously adjust drive frequency to match loaded pole |
|||
|
|||
**Implementation:** |
|||
- Phase-locked loop (PLL) tracks zero-crossing |
|||
- Feedback from antenna or current sensor |
|||
- Drive frequency follows resonance in real-time |
|||
|
|||
**Advantages:** |
|||
- **Always at optimal frequency** |
|||
- Maximum voltage gain throughout growth |
|||
- Efficient power transfer |
|||
- Adapts to varying sparks |
|||
|
|||
**Disadvantages:** |
|||
- More complex electronics |
|||
- Requires feedback sensing |
|||
- Can be unstable if poorly tuned |
|||
- Frequency limits needed for safety |
|||
|
|||
**This is the gold standard for QCW and high-performance DRSSTCs.** |
|||
|
|||
### Mode 3: Pre-Programmed Sweep |
|||
|
|||
**Strategy:** Drive frequency ramps down over time (anticipating C_sh increase) |
|||
|
|||
**Implementation:** |
|||
- Start at f₀ (unloaded resonance) |
|||
- Linearly or exponentially decrease frequency |
|||
- End at f_target (expected loaded resonance) |
|||
|
|||
**Advantages:** |
|||
- Simpler than PLL |
|||
- No feedback required |
|||
- Can be optimized per coil |
|||
|
|||
**Disadvantages:** |
|||
- Not adaptive (doesn't match actual spark) |
|||
- Requires characterization/tuning |
|||
- Mismatch if spark growth differs from expectation |
|||
|
|||
**When useful:** |
|||
- QCW with consistent spark growth patterns |
|||
- Transition from no-spark to steady spark |
|||
- Combined with current limiting |
|||
|
|||
## Frequency Response and Bandwidth |
|||
|
|||
### Quality Factor Limits Bandwidth |
|||
|
|||
The resonance has finite width determined by Q: |
|||
|
|||
``` |
|||
Δf_3dB = f₀ / Q (3 dB bandwidth) |
|||
|
|||
For Q = 100 at f₀ = 200 kHz: |
|||
Δf_3dB = 200 kHz / 100 = 2 kHz |
|||
``` |
|||
|
|||
**Within ±1 kHz:** Still >70% of peak voltage (acceptable detuning) |
|||
**Beyond ±5 kHz:** Down to ~30% of peak voltage (severe detuning) |
|||
|
|||
### High Q vs Low Q |
|||
|
|||
**High Q (narrow bandwidth):** |
|||
- Sharper resonance peak |
|||
- More sensitive to detuning |
|||
- **Frequency tracking more critical** |
|||
- Better efficiency when matched |
|||
|
|||
**Low Q (wide bandwidth):** |
|||
- Broader resonance peak |
|||
- More forgiving of detuning |
|||
- Frequency tracking less critical |
|||
- Lower peak voltage gain |
|||
|
|||
### Loaded Q vs Unloaded Q |
|||
|
|||
**Unloaded Q₀:** |
|||
- No spark, only coil losses |
|||
- Typically Q₀ = 100-300 |
|||
|
|||
**Loaded Q_L:** |
|||
- With spark, additional damping |
|||
- Spark resistance adds loss |
|||
- Typically Q_L = 20-80 |
|||
|
|||
**Effect on bandwidth:** |
|||
``` |
|||
Unloaded: Δf₀ = 200 kHz / 200 = 1 kHz (narrow!) |
|||
Loaded: Δf_L = 185 kHz / 50 = 3.7 kHz (wider) |
|||
``` |
|||
|
|||
**Ironically, the spark broadens the resonance, making detuning slightly less critical. But the frequency shift is still large enough that you must track it.** |
|||
|
|||
## Implementing Frequency Tracking in Measurements |
|||
|
|||
### Simulation Approach |
|||
|
|||
**For each R value:** |
|||
|
|||
```python |
|||
# Pseudocode for proper frequency tracking |
|||
for R in [10k, 20k, 30k, ..., 200k]: |
|||
set_spark_resistance(R) |
|||
|
|||
# Sweep frequency to find loaded pole |
|||
for f in range(150k, 220k, 1k): |
|||
run_AC_analysis(frequency=f) |
|||
V_top[f] = measure_topload_voltage() |
|||
|
|||
# Find frequency with maximum voltage |
|||
f_loaded = frequency_at_max(V_top) |
|||
|
|||
# Measure power at loaded frequency |
|||
run_AC_analysis(frequency=f_loaded) |
|||
P[R] = measure_spark_power() |
|||
|
|||
# Store results |
|||
results[R] = { |
|||
'f_loaded': f_loaded, |
|||
'V_top': V_top[f_loaded], |
|||
'P': P[R] |
|||
} |
|||
|
|||
# Now P[R] represents true matching, not detuning! |
|||
R_opt = R_at_max(P) |
|||
``` |
|||
|
|||
### SPICE Implementation |
|||
|
|||
```spice |
|||
* Sweep R and frequency together |
|||
.param Rspark = 60k |
|||
|
|||
* First find loaded frequency for this R |
|||
.ac dec 100 150k 220k |
|||
.meas ac f_loaded WHEN mag(V(topload))=MAX(mag(V(topload))) |
|||
|
|||
* Then measure power at that frequency |
|||
.ac lin 1 {f_loaded} {f_loaded} |
|||
.meas ac Pspark param '0.5 * mag(I(Rspark))^2 * Rspark' |
|||
|
|||
* Repeat for each R value |
|||
.step param Rspark list 10k 30k 50k 70k 90k 110k 150k 200k |
|||
``` |
|||
|
|||
**Challenge:** SPICE doesn't easily allow nested sweeps where inner result affects outer analysis. You may need to: |
|||
- Run multiple simulations |
|||
- Use scripting (Python + PySpice, MATLAB, etc.) |
|||
- Manually extract f_loaded for key R values |
|||
|
|||
## Worked Example: Impact of Tracking vs Not Tracking |
|||
|
|||
**System:** |
|||
- Unloaded: f₀ = 200 kHz, Q₀ = 150 |
|||
- V_th = 350 kV (at resonance) |
|||
- Z_th = 110 - j2400 Ω (at 200 kHz) |
|||
|
|||
**Spark configurations:** |
|||
|
|||
| R | C_sh | C_total | f_loaded | Shift | |
|||
|---|------|---------|----------|-------| |
|||
| 40k | 5 pF | 33 pF | 188 kHz | -12 kHz | |
|||
| 60k | 6 pF | 34 pF | 185 kHz | -15 kHz | |
|||
| 80k | 7 pF | 35 pF | 183 kHz | -17 kHz | |
|||
|
|||
### Without Tracking (Fixed f = 200 kHz) |
|||
|
|||
**R = 40 kΩ:** |
|||
``` |
|||
Detuning: Δf = +12 kHz |
|||
Voltage penalty: V_actual / V_max ≈ 0.65 |
|||
Z_spark = 40k - j140k → |Z| = 146 kΩ |
|||
I ≈ 350 kV × 0.65 / 146 kΩ = 1.56 A |
|||
P = 0.5 × 1.56² × 40k = 48.6 kW |
|||
``` |
|||
|
|||
**R = 60 kΩ:** |
|||
``` |
|||
Detuning: Δf = +15 kHz |
|||
Voltage penalty: ≈ 0.55 |
|||
Z_spark = 60k - j160k → |Z| = 171 kΩ |
|||
I ≈ 350 kV × 0.55 / 171 kΩ = 1.13 A |
|||
P = 0.5 × 1.13² × 60k = 38.3 kW (WORSE despite higher R!) |
|||
``` |
|||
|
|||
**R = 80 kΩ:** |
|||
``` |
|||
Detuning: Δf = +17 kHz |
|||
Voltage penalty: ≈ 0.48 |
|||
Z_spark = 80k - j180k → |Z| = 197 kΩ |
|||
I ≈ 350 kV × 0.48 / 197 kΩ = 0.85 A |
|||
P = 0.5 × 0.85² × 80k = 28.9 kW |
|||
``` |
|||
|
|||
**Conclusion from fixed-frequency:** R_opt ≈ 40 kΩ (WRONG!) |
|||
|
|||
### With Tracking (Tune to f_loaded for each R) |
|||
|
|||
**R = 40 kΩ at f = 188 kHz:** |
|||
``` |
|||
Detuning: 0 (by definition - we tuned to loaded pole) |
|||
Voltage penalty: 1.0 (at resonance) |
|||
I ≈ 350 kV / 146 kΩ = 2.40 A |
|||
P = 0.5 × 2.40² × 40k = 115 kW |
|||
``` |
|||
|
|||
**R = 60 kΩ at f = 185 kHz:** |
|||
``` |
|||
Detuning: 0 |
|||
Voltage penalty: 1.0 |
|||
I ≈ 350 kV / 171 kΩ = 2.05 A |
|||
P = 0.5 × 2.05² × 60k = 126 kW (MAXIMUM!) |
|||
``` |
|||
|
|||
**R = 80 kΩ at f = 183 kHz:** |
|||
``` |
|||
Detuning: 0 |
|||
Voltage penalty: 1.0 |
|||
I ≈ 350 kV / 197 kΩ = 1.78 A |
|||
P = 0.5 × 1.78² × 80k = 127 kW (close!) |
|||
``` |
|||
|
|||
**Conclusion with tracking:** R_opt ≈ 60 kΩ (CORRECT!) |
|||
|
|||
**Power improvement with tracking:** |
|||
- At R = 60 kΩ: 126 kW vs 38 kW = **3.3× more power!** |
|||
- At R = 80 kΩ: 127 kW vs 29 kW = **4.4× more power!** |
|||
|
|||
**This is not a small effect. Frequency tracking is critical.** |
|||
|
|||
## Practical Implications |
|||
|
|||
### For Simulation Studies |
|||
|
|||
**Always:** |
|||
- Report frequency used for each measurement |
|||
- Either track frequency or clearly state fixed-frequency limitations |
|||
- Specify whether results assume optimal tuning |
|||
|
|||
**When comparing:** |
|||
- Ensure fair comparison (same tracking strategy) |
|||
- Document detuning if fixed-frequency is used |
|||
|
|||
### For Physical Coils |
|||
|
|||
**DRSSTC with PLL:** |
|||
- Tracks automatically - excellent |
|||
- Monitor actual operating frequency |
|||
- Check frequency stays within safe limits |
|||
|
|||
**DRSSTC with fixed frequency:** |
|||
- Accept voltage/power reduction as spark grows |
|||
- Consider pre-tuning to expected loaded frequency |
|||
- Wider-bandwidth design helps (lower Q) |
|||
|
|||
**SGTC (Spark Gap):** |
|||
- Frequency self-adjusts with loading (inherent tracking) |
|||
- Spark gap firing adapts to LC resonance |
|||
- Less of an issue for spark gap coils |
|||
|
|||
### For Optimization |
|||
|
|||
**When finding R_opt_power:** |
|||
1. Use frequency tracking (simulation or actual) |
|||
2. Report f_loaded for each R tested |
|||
3. Verify analytical formula matches |
|||
|
|||
**When designing:** |
|||
1. Choose f₀ based on unloaded resonance |
|||
2. Expect f_operating ≈ f₀ - 10 to 30 kHz with sparks |
|||
3. Ensure drive can operate over this range |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Critical principle:** For each R value, retune to loaded pole frequency |
|||
- **Why it matters:** Loading changes C_sh, which shifts resonance by 10-30+ kHz |
|||
- **Fixed-frequency comparison is misleading:** Measures detuning, not matching quality |
|||
- **Coupled system has two poles:** Lower and upper, both shift with loading |
|||
- **DRSSTC modes:** Fixed frequency (simple), PLL tracking (optimal), programmed sweep (compromise) |
|||
- **Q affects sensitivity:** Higher Q = narrower bandwidth = more critical tracking |
|||
- **Power difference:** Can be 3-5× between tracked and non-tracked measurements |
|||
- **Simulation best practice:** Sweep frequency for each load to find f_loaded |
|||
- **Physical coils:** PLL tracking gives best performance, fixed frequency is acceptable for short bursts |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-06} |
|||
|
|||
**Problem 1:** A coil has f₀ = 195 kHz unloaded with C_total,0 = 30 pF. A 4-foot spark adds C_sh = 8 pF. |
|||
(a) Calculate the loaded capacitance |
|||
(b) Calculate the loaded frequency |
|||
(c) What is Δf (frequency shift)? |
|||
|
|||
**Problem 2:** You measure power at fixed f = 200 kHz: |
|||
- R = 50 kΩ, f_loaded = 188 kHz → P₁ = 85 kW |
|||
- R = 70 kΩ, f_loaded = 185 kHz → P₂ = 95 kW |
|||
|
|||
If Q = 80, estimate the voltage penalty factor for each case and calculate what power would be measured if you had tracked frequency. |
|||
|
|||
**Problem 3:** Explain why frequency tracking is MORE critical for high-Q coils than low-Q coils. |
|||
|
|||
**Problem 4:** A DRSSTC operates with fixed frequency drive. As the spark grows from 2 feet to 5 feet, what happens to: |
|||
(a) Loaded resonant frequency |
|||
(b) Detuning (if drive frequency is fixed) |
|||
(c) Voltage gain |
|||
(d) Power delivered |
|||
|
|||
**Problem 5:** For coupled resonators with k = 0.18 and f₀ = 210 kHz: |
|||
(a) Calculate the lower pole frequency |
|||
(b) Calculate the upper pole frequency |
|||
(c) Which pole is typically used for DRSSTC operation? |
|||
|
|||
**Problem 6:** Sketch V_top vs frequency for three cases: |
|||
(a) No spark (unloaded) |
|||
(b) R = 60 kΩ spark (lightly loaded) |
|||
(c) R = 30 kΩ spark (heavily loaded) |
|||
|
|||
Label the peak frequencies and relative peak heights. Explain how tracking helps maintain peak operation. |
|||
|
|||
--- |
|||
**Next Lesson:** [Part 2 Review and Comprehensive Exercises](07-review-exercises.md) |
|||
@ -0,0 +1,464 @@ |
|||
--- |
|||
id: opt-07 |
|||
title: "Part 2 Review - Optimization & Power Transfer" |
|||
section: "Optimization & Simulation" |
|||
difficulty: "intermediate" |
|||
estimated_time: 60 |
|||
prerequisites: ["opt-01", "opt-02", "opt-03", "opt-04", "opt-05", "opt-06"] |
|||
objectives: |
|||
- Synthesize concepts from all optimization lessons |
|||
- Apply multiple techniques to comprehensive design problems |
|||
- Troubleshoot common optimization errors |
|||
- Build complete optimization workflow |
|||
tags: ["review", "comprehensive", "integration", "design"] |
|||
--- |
|||
|
|||
# Part 2 Review - Optimization & Power Transfer |
|||
|
|||
This lesson integrates all concepts from Part 2, providing comprehensive exercises that require applying multiple techniques together. |
|||
|
|||
## Part 2 Summary: Key Concepts |
|||
|
|||
### Lesson 1: The Two Critical Resistances |
|||
|
|||
**R_opt_phase:** |
|||
``` |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
``` |
|||
- Minimizes impedance phase angle magnitude |
|||
- Achieves φ_Z,min = -atan(2√[r(1+r)]) |
|||
- Makes impedance "most resistive" possible |
|||
|
|||
**R_opt_power:** |
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
``` |
|||
- Maximizes real power transfer to load |
|||
- Always smaller than R_opt_phase |
|||
- Typical ratio: R_opt_power ≈ 0.5-0.7 × R_opt_phase |
|||
|
|||
**Topological constraint:** |
|||
``` |
|||
If r = C_mut/C_sh > 0.207: |
|||
Cannot achieve φ_Z = -45° (inherently capacitive) |
|||
|
|||
Most Tesla coils: r = 0.5 to 2.0 → φ_Z,min = -60° to -80° |
|||
``` |
|||
|
|||
### Lesson 2: The Hungry Streamer |
|||
|
|||
**Self-optimization mechanism:** |
|||
1. Power → Joule heating |
|||
2. Temperature → Ionization (exp(-E_i/kT)) |
|||
3. Ionization → Conductivity (σ ∝ n_e) |
|||
4. Conductivity → Resistance (R = L/σA) |
|||
5. Resistance → Circuit power |
|||
6. **Feedback stabilizes at R ≈ R_opt_power** |
|||
|
|||
**Time scales:** |
|||
- Thermal response: 0.1-1 ms (thin channels) |
|||
- Ionization response: μs to ms |
|||
- Can track kHz modulation, not RF cycles |
|||
|
|||
**Physical limits:** |
|||
- R_min ≈ 1-10 kΩ (maximum conductivity) |
|||
- R_max ≈ 100 kΩ to 100 MΩ (minimum conductivity) |
|||
- Source limitations prevent optimization if insufficient power |
|||
|
|||
### Lesson 3-4: Thévenin Equivalent |
|||
|
|||
**Extraction:** |
|||
``` |
|||
Z_th: Drive OFF, apply 1V test, measure I_test |
|||
Z_th = 1V / I_test = R_th + jX_th |
|||
|
|||
V_th: Drive ON, no load, measure V_topload |
|||
``` |
|||
|
|||
**Using the equivalent:** |
|||
``` |
|||
I = V_th / (Z_th + Z_load) |
|||
V_load = V_th × Z_load / (Z_th + Z_load) |
|||
P_load = 0.5 × |I|² × Re{Z_load} |
|||
P_load = 0.5 × |V_th|² × Re{Z_load} / |Z_th + Z_load|² |
|||
``` |
|||
|
|||
**Maximum power (conjugate match):** |
|||
``` |
|||
Z_load = Z_th* → P_max = |V_th|² / (8 R_th) |
|||
|
|||
Usually unachievable due to topological constraints! |
|||
``` |
|||
|
|||
### Lesson 5: Direct Measurement |
|||
|
|||
**Alternative to Thévenin:** |
|||
- Keep full coupled model |
|||
- Measure power in spark directly |
|||
- Sweep R, find maximum |
|||
- Slower but handles nonlinearity |
|||
|
|||
**Best practice:** |
|||
- Use Thévenin for exploration |
|||
- Validate with direct measurement |
|||
|
|||
### Lesson 6: Frequency Tracking |
|||
|
|||
**Critical principle:** |
|||
``` |
|||
For each R value, retune to loaded pole frequency! |
|||
``` |
|||
|
|||
**Why:** |
|||
- Loading changes C_sh → shifts resonance |
|||
- Typical shift: 10-30 kHz for medium sparks |
|||
- Fixed-frequency comparison measures detuning, not matching |
|||
|
|||
**Loaded frequency:** |
|||
``` |
|||
f_loaded = f₀ × √(C_total,0 / C_total,loaded) |
|||
|
|||
C_total,loaded = C_total,0 + C_sh |
|||
``` |
|||
|
|||
**DRSSTC modes:** |
|||
- Fixed frequency: Simple, but detunes with loading |
|||
- PLL tracking: Optimal, adapts in real-time |
|||
- Programmed sweep: Compromise |
|||
|
|||
## Comprehensive Design Exercise |
|||
|
|||
**Scenario:** You're optimizing a medium DRSSTC for a 3-foot spark target. |
|||
|
|||
**Given System Parameters:** |
|||
- Operating frequency: f ≈ 190 kHz (to be refined) |
|||
- Topload: C_topload = 30 pF (measured) |
|||
- Target spark: 3 feet |
|||
- FEMM analysis gives: C_mut = 9 pF for 3-foot spark |
|||
- Secondary stray capacitance: C_stray = 5 pF |
|||
- Thévenin measurement (unloaded): Z_th = 105 - j2100 Ω at 200 kHz, V_th = 320 kV |
|||
|
|||
**Your tasks:** Work through the complete optimization workflow. |
|||
|
|||
--- |
|||
|
|||
### Task 1: Estimate Spark Capacitance |
|||
|
|||
Using the 2 pF/foot rule: |
|||
|
|||
**Question 1a:** What is C_sh for a 3-foot spark? |
|||
|
|||
**Question 1b:** What is the total secondary capacitance (unloaded)? |
|||
|
|||
**Question 1c:** What is the total capacitance with the 3-foot spark? |
|||
|
|||
--- |
|||
|
|||
### Task 2: Calculate Loaded Frequency |
|||
|
|||
**Question 2a:** If unloaded resonance is f₀ = 200 kHz, calculate the loaded resonance frequency with the 3-foot spark. |
|||
|
|||
**Question 2b:** What is the frequency shift Δf? |
|||
|
|||
**Question 2c:** If you operated at fixed f = 200 kHz (unloaded resonance), how detuned would you be? Express as a percentage of the original frequency. |
|||
|
|||
--- |
|||
|
|||
### Task 3: Determine Optimal Resistances |
|||
|
|||
**Question 3a:** Calculate R_opt_power at the loaded frequency (use result from Task 2). |
|||
|
|||
**Question 3b:** Calculate R_opt_phase at the loaded frequency. |
|||
|
|||
**Question 3c:** What is the ratio R_opt_power / R_opt_phase? |
|||
|
|||
**Question 3d:** Calculate the capacitance ratio r = C_mut / C_sh. |
|||
|
|||
**Question 3e:** Calculate the minimum achievable phase angle φ_Z,min. Can this system achieve -45°? |
|||
|
|||
--- |
|||
|
|||
### Task 4: Build Lumped Spark Model |
|||
|
|||
**Question 4a:** Draw the lumped spark circuit showing R, C_mut, and C_sh. Label all component values, using R = R_opt_power from Task 3a. |
|||
|
|||
**Question 4b:** Calculate the spark admittance Y_spark at the loaded frequency. Express in rectangular form (G + jB). |
|||
|
|||
**Question 4c:** Convert Y_spark to impedance Z_spark. Express in both polar and rectangular forms. |
|||
|
|||
**Question 4d:** Verify that the phase angle matches expectations from the topological constraint. |
|||
|
|||
--- |
|||
|
|||
### Task 5: Predict Performance with Thévenin |
|||
|
|||
Now use the Thévenin equivalent to predict performance. Adjust Z_th for the loaded frequency: |
|||
|
|||
**Note:** Z_th changes with frequency. For this exercise, assume: |
|||
- Z_th ≈ 108 - j2050 Ω at f_loaded (slightly adjusted from 200 kHz value) |
|||
- V_th ≈ 320 kV (approximately constant near resonance) |
|||
|
|||
**Question 5a:** Calculate the total impedance Z_total = Z_th + Z_spark. |
|||
|
|||
**Question 5b:** Calculate the current through the spark. |
|||
|
|||
**Question 5c:** Calculate the voltage across the spark. |
|||
|
|||
**Question 5d:** Calculate the real power dissipated in the spark. |
|||
|
|||
**Question 5e:** What percentage of V_th appears across the spark? Why is this ratio so high? |
|||
|
|||
--- |
|||
|
|||
### Task 6: Compare to Theoretical Maximum |
|||
|
|||
**Question 6a:** What load impedance would give conjugate match? |
|||
|
|||
**Question 6b:** Calculate P_max (maximum theoretical power with conjugate match). |
|||
|
|||
**Question 6c:** What percentage of P_max is actually delivered to the spark (from Task 5d)? |
|||
|
|||
**Question 6d:** Explain physically why the actual power is so much less than P_max. Why can't we achieve conjugate match? |
|||
|
|||
--- |
|||
|
|||
### Task 7: Frequency Tracking Impact |
|||
|
|||
Suppose you made a mistake and measured power at fixed f = 200 kHz instead of the loaded frequency. |
|||
|
|||
**Question 7a:** Estimate the voltage penalty factor. Assume Q_loaded ≈ 40 and use: |
|||
``` |
|||
Voltage_ratio ≈ 1 / √[1 + (2Q × Δf/f)²] |
|||
``` |
|||
|
|||
**Question 7b:** How much would the measured power differ from the correctly tracked measurement? |
|||
|
|||
**Question 7c:** If you compared three different spark resistances at fixed f = 200 kHz, would you correctly identify R_opt_power? Why or why not? |
|||
|
|||
--- |
|||
|
|||
### Task 8: Self-Optimization Analysis |
|||
|
|||
**Question 8a:** Suppose the spark initially forms with R = 150 kΩ (cold streamer). Describe qualitatively what happens over the next 5-10 ms as the plasma heats up. Include R, T, σ, and P in your description. |
|||
|
|||
**Question 8b:** Why does the plasma naturally evolve toward R ≈ R_opt_power? |
|||
|
|||
**Question 8c:** If the calculated R_opt_power = 55 kΩ but physical limits give R_min = 80 kΩ, what would happen? Would the plasma reach R_opt_power? |
|||
|
|||
**Question 8d:** In burst mode with 50 μs pulses, would you expect the plasma to reach R_opt_power? Explain using thermal time constants. |
|||
|
|||
--- |
|||
|
|||
### Task 9: Alternative Measurement Validation |
|||
|
|||
You decide to validate your Thévenin results with direct power measurement. |
|||
|
|||
**Question 9a:** Describe the simulation setup for direct measurement. What components are included? What is varied? |
|||
|
|||
**Question 9b:** You sweep R from 20 kΩ to 120 kΩ. For each R value, should you: |
|||
- (A) Measure at fixed f = 200 kHz? |
|||
- (B) Sweep frequency to find loaded pole, then measure? |
|||
|
|||
Explain your choice. |
|||
|
|||
**Question 9c:** The direct measurement gives P_max at R = 58 kΩ, while your calculation gave R_opt_power = 55 kΩ. Is this agreement acceptable? What might explain the small difference? |
|||
|
|||
--- |
|||
|
|||
### Task 10: Design Recommendations |
|||
|
|||
Based on your analysis, provide design recommendations: |
|||
|
|||
**Question 10a:** What operating frequency should the DRSSTC use when driving this spark? |
|||
|
|||
**Question 10b:** Should the drive use fixed frequency or frequency tracking? Justify your recommendation. |
|||
|
|||
**Question 10c:** If using fixed frequency, what single frequency would you choose to balance unloaded and loaded operation? |
|||
|
|||
**Question 10d:** What power level should the primary tank be designed to deliver (approximately)? |
|||
|
|||
**Question 10e:** If you wanted a 4-foot spark instead, qualitatively describe how C_sh, f_loaded, R_opt_power, and delivered power would change. |
|||
|
|||
--- |
|||
|
|||
## Troubleshooting Common Errors |
|||
|
|||
### Error 1: "My calculated R_opt doesn't match simulation!" |
|||
|
|||
**Possible causes:** |
|||
- Forgot to account for loaded frequency (used unloaded f₀) |
|||
- Used wrong capacitance values (forgot C_stray or miscounted C_sh) |
|||
- Simulation measured at wrong port (I_base instead of I_spark) |
|||
- Simulation didn't converge properly |
|||
|
|||
**How to check:** |
|||
- Verify C_total = C_topload + C_stray + C_sh |
|||
- Verify ω = 2πf_loaded (not f₀!) |
|||
- Plot power vs R to visually confirm peak location |
|||
- Check simulation settings and convergence |
|||
|
|||
### Error 2: "Power is much lower than expected!" |
|||
|
|||
**Possible causes:** |
|||
- Operating at wrong frequency (detuned) |
|||
- High losses in simulation (R_th too large) |
|||
- Incorrect power measurement (forgot factor of 0.5, or using wrong current) |
|||
- Displacement currents included in measurement |
|||
|
|||
**How to check:** |
|||
- Verify frequency matches loaded pole |
|||
- Check Z_th extraction (is R_th reasonable? 10-100 Ω typical) |
|||
- Verify power formula: P = 0.5 × I² × R for peak phasors |
|||
- Measure current through R specifically, not total base current |
|||
|
|||
### Error 3: "Phase angle doesn't match theory!" |
|||
|
|||
**Possible causes:** |
|||
- Using unloaded frequency instead of loaded |
|||
- Incorrect capacitance ratio calculation |
|||
- Measurement includes other components (not just spark) |
|||
- Non-ideal behavior (resistance not purely in parallel with C_mut) |
|||
|
|||
**How to check:** |
|||
- Recalculate r = C_mut/C_sh carefully |
|||
- Verify φ_Z,min = -atan(2√[r(1+r)]) |
|||
- Check measurement port (topload to ground, not base) |
|||
- Consider more complex model if simple lumped model doesn't fit |
|||
|
|||
### Error 4: "Conjugate match power is impossibly high!" |
|||
|
|||
**This is normal!** For Tesla coils: |
|||
- Z_th has low R_th (10-100 Ω) |
|||
- P_max = V_th²/(8R_th) can be tens or hundreds of MW |
|||
- Sparks cannot achieve conjugate match (topological constraints) |
|||
- Actual power is typically 0.01% to 1% of P_max |
|||
|
|||
**Not an error** - just shows extreme impedance mismatch is fundamental to Tesla coil operation. |
|||
|
|||
## Key Formulas Reference |
|||
|
|||
### Optimal Resistances |
|||
``` |
|||
R_opt_power = 1 / [ω(C_mut + C_sh)] |
|||
R_opt_phase = 1 / [ω√(C_mut(C_mut + C_sh))] |
|||
φ_Z,min = -atan(2√[r(1+r)]) where r = C_mut/C_sh |
|||
``` |
|||
|
|||
### Thévenin Equivalent |
|||
``` |
|||
Z_th = 1V / I_test (drive OFF, 1V test source) |
|||
V_th = V_topload (drive ON, no load) |
|||
P_load = 0.5 × |V_th|² × Re{Z_load} / |Z_th + Z_load|² |
|||
P_max = |V_th|² / (8 R_th) |
|||
``` |
|||
|
|||
### Frequency Tracking |
|||
``` |
|||
C_total,loaded = C_total,0 + C_sh |
|||
f_loaded = f₀ √(C_total,0 / C_total,loaded) |
|||
C_sh ≈ 2 pF/foot for typical sparks |
|||
``` |
|||
|
|||
### Lumped Model |
|||
``` |
|||
Y_spark = [(G + jωC_mut) × jωC_sh] / [G + jω(C_mut + C_sh)] |
|||
where G = 1/R |
|||
``` |
|||
|
|||
### Power Measurement |
|||
``` |
|||
P = 0.5 × |I|² × Re{Z} (peak phasors) |
|||
P = 0.5 × Re{V × I*} (complex power) |
|||
``` |
|||
|
|||
## Practice Problems - Solutions in Appendix |
|||
|
|||
### Problem Set A: Quick Calculations |
|||
|
|||
**A1.** Calculate R_opt_power for f = 180 kHz, C_mut = 7 pF, C_sh = 9 pF. |
|||
|
|||
**A2.** A spark has r = 1.5. Calculate φ_Z,min. Can it achieve -45°? |
|||
|
|||
**A3.** Z_th = 92 - j1950 Ω, V_th = 290 kV. Calculate P_max. |
|||
|
|||
**A4.** Unloaded f₀ = 205 kHz, C₀ = 32 pF. A 3.5-foot spark appears. Calculate f_loaded. |
|||
|
|||
**A5.** At f = 190 kHz with Q = 60, you're detuned by Δf = +8 kHz. Estimate the voltage penalty. |
|||
|
|||
### Problem Set B: Integration Problems |
|||
|
|||
**B1.** Complete Thévenin analysis: |
|||
- Z_th = 115 - j2300 Ω, V_th = 340 kV |
|||
- Spark: C_mut = 8 pF, C_sh = 5 pF, R = 65 kΩ, f = 188 kHz |
|||
- Find: Current, voltage, power, compare to R_opt_power |
|||
|
|||
**B2.** Optimization with tracking: |
|||
- f₀ = 198 kHz unloaded, C₀ = 28 pF |
|||
- Test R = 40k, 60k, 80k with C_sh = 6 pF, C_mut = 9 pF |
|||
- Calculate f_loaded for each R |
|||
- Which R is closest to R_opt_power? |
|||
|
|||
**B3.** Self-optimization timeline: |
|||
- R_opt_power = 70 kΩ, spark forms at R = 200 kΩ |
|||
- Sketch R(t), P(t), T(t) vs time from t = 0 to 15 ms |
|||
- Label key phases: initial, runaway, approach, equilibrium |
|||
|
|||
### Problem Set C: Design Challenges |
|||
|
|||
**C1.** Design matching for 4-foot target: |
|||
- Given: f = 185 kHz, C_topload = 35 pF, C_stray = 6 pF |
|||
- Determine: C_sh, C_total, f_loaded, R_opt_power, R_opt_phase |
|||
- Build lumped model and calculate Z_spark |
|||
|
|||
**C2.** Frequency tracking implementation: |
|||
- Coil operates 170-210 kHz range |
|||
- Sparks vary from 2 to 5 feet |
|||
- Calculate frequency range needed |
|||
- Recommend: fixed frequency, PLL, or sweep? |
|||
|
|||
**C3.** Troubleshooting: |
|||
- Simulation shows maximum power at R = 45 kΩ |
|||
- Analytical R_opt_power = 62 kΩ |
|||
- What could explain the discrepancy? List 3 possible causes and how to verify each. |
|||
|
|||
--- |
|||
|
|||
## Transition to Part 3 |
|||
|
|||
You now have a complete toolkit for optimization and power transfer analysis: |
|||
- Understanding the two critical resistances |
|||
- Physical self-optimization mechanism |
|||
- Thévenin equivalent extraction and use |
|||
- Direct measurement validation |
|||
- Frequency tracking principles |
|||
|
|||
**Part 3** builds on this foundation to explore: |
|||
- Spark growth physics and field requirements |
|||
- FEMM modeling for capacitance extraction |
|||
- Energy budgets and growth rates |
|||
- Voltage vs power limits |
|||
- Complete growth simulations |
|||
|
|||
The optimization techniques from Part 2 combine with the growth physics of Part 3 to enable **full spark length prediction**. |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Two optimizations:** R_opt_power (max power) and R_opt_phase (min phase) are different |
|||
- **Self-optimization:** Plasma naturally seeks R ≈ R_opt_power via thermal feedback |
|||
- **Thévenin method:** Extract once, predict any load instantly |
|||
- **Direct measurement:** Slower but handles nonlinearity, good for validation |
|||
- **Frequency tracking is critical:** Must retune for each load to avoid detuning errors |
|||
- **Topological constraints:** Most Tesla coils cannot achieve -45°, inherently capacitive |
|||
- **Conjugate match unachievable:** Sparks operate far from theoretical maximum power |
|||
- **Complete workflow:** Capacitance → frequency → R_opt → lumped model → power prediction |
|||
|
|||
## Practice |
|||
|
|||
{exercise:opt-ex-07} |
|||
|
|||
Work through the Comprehensive Design Exercise (Tasks 1-10) completely. Show all calculations and reasoning. Compare your results with the solutions appendix. |
|||
|
|||
--- |
|||
**Next Section:** [Part 3: Spark Growth Physics and FEMM Modeling](../../03-spark-physics/01-electric-fields.md) |
|||
|
After Width: 1786 | Height: 1329 | Size: 214 KiB |
|
After Width: 1373 | Height: 972 | Size: 191 KiB |
|
After Width: 1000 | Height: 1000 | Size: 37 KiB |
|
After Width: 1482 | Height: 1030 | Size: 136 KiB |
|
After Width: 1284 | Height: 1429 | Size: 179 KiB |
|
After Width: 1000 | Height: 1000 | Size: 31 KiB |
@ -0,0 +1,263 @@ |
|||
--- |
|||
id: phys-01 |
|||
title: "Electric Field Thresholds for Breakdown" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 35 |
|||
prerequisites: ["fund-07", "opt-07"] |
|||
objectives: |
|||
- Understand the electric field requirements for air breakdown |
|||
- Calculate average and tip electric fields from voltage and geometry |
|||
- Apply tip enhancement factors to predict spark inception |
|||
- Determine when sparks can continue growing vs when they stall |
|||
tags: ["electric-field", "breakdown", "tip-enhancement", "E-field", "threshold"] |
|||
--- |
|||
|
|||
# Electric Field Thresholds for Breakdown |
|||
|
|||
Understanding electric fields is fundamental to predicting spark behavior. A spark will only initiate and grow when the electric field strength exceeds specific thresholds. This lesson covers the critical field values and how to calculate them. |
|||
|
|||
## Electric Field Basics |
|||
|
|||
**Definition:** The electric field E is force per unit charge: |
|||
|
|||
``` |
|||
E = F/q [units: N/C or V/m] |
|||
``` |
|||
|
|||
The electric field is related to voltage through the gradient: |
|||
|
|||
``` |
|||
E = -dV/dx (field is voltage gradient) |
|||
``` |
|||
|
|||
For a uniform field between parallel plates: |
|||
|
|||
``` |
|||
E ≈ V/d (voltage divided by distance) |
|||
``` |
|||
|
|||
**Critical insight:** The field at a spark tip is NOT uniform - it is concentrated by the sharp geometry. |
|||
|
|||
## Breakdown Field Thresholds |
|||
|
|||
Two key field thresholds govern spark behavior: |
|||
|
|||
### E_inception: Initial Breakdown Field |
|||
|
|||
**E_inception** is the field required to initiate breakdown from a smooth electrode: |
|||
|
|||
``` |
|||
E_inception ≈ 2-3 MV/m (at sea level, dry air) |
|||
``` |
|||
|
|||
**Physical process:** |
|||
1. Natural cosmic rays create seed electrons |
|||
2. Strong field accelerates these electrons |
|||
3. High-energy electrons collide with air molecules |
|||
4. Collisions ionize more atoms (avalanche breakdown) |
|||
5. Breakdown begins when ionization exceeds losses |
|||
|
|||
### E_propagation: Sustained Growth Field |
|||
|
|||
**E_propagation** is the field required to sustain spark growth after initiation: |
|||
|
|||
``` |
|||
E_propagation ≈ 0.4-1.0 MV/m (for leader propagation) |
|||
``` |
|||
|
|||
**Why is E_propagation < E_inception?** |
|||
- The channel is already partially ionized |
|||
- Hot gas is easier to ionize than cold air |
|||
- Photoionization helps (UV from plasma creates seed electrons ahead) |
|||
- Thermal effects reduce the energy barrier |
|||
|
|||
### Environmental Effects |
|||
|
|||
Field thresholds vary with atmospheric conditions: |
|||
|
|||
**Altitude effects:** |
|||
- Lower air density → lower E_threshold |
|||
- Variation: ±20-30% from sea level to moderate altitude |
|||
- Higher altitude → easier breakdown (less air to ionize) |
|||
|
|||
**Humidity effects:** |
|||
- Water vapor changes breakdown characteristics |
|||
- Typical variation: ~10% |
|||
- Complex effects: water molecules have different ionization energy |
|||
|
|||
**Temperature effects:** |
|||
- Affects air density |
|||
- Small effect compared to altitude/humidity |
|||
|
|||
## Tip Enhancement Factor (κ) |
|||
|
|||
Sharp tips concentrate the electric field dramatically. The **tip enhancement factor** κ quantifies this concentration: |
|||
|
|||
``` |
|||
E_tip = κ × E_average |
|||
|
|||
where: |
|||
E_average = V/L (voltage divided by spark length) |
|||
κ = enhancement factor ≈ 2-5 typical |
|||
``` |
|||
|
|||
### Physical Origin of Enhancement |
|||
|
|||
**Why do tips concentrate field?** |
|||
1. Charge accumulates at sharp points (boundary condition) |
|||
2. Field lines must be perpendicular to conductor surfaces |
|||
3. Closer spacing of equipotential lines near high curvature |
|||
4. Smaller radius of curvature → higher κ |
|||
|
|||
**Typical values:** |
|||
- Smooth sphere: κ ≈ 1.0 (no enhancement) |
|||
- Mild tip (radius ~cm): κ ≈ 2-3 |
|||
- Sharp tip (radius ~mm): κ ≈ 3-5 |
|||
- Very sharp needle: κ ≈ 5-10 |
|||
|
|||
**FEMM calculates E_tip directly** from geometry and voltage, eliminating the need to estimate κ. |
|||
|
|||
## Growth Criterion |
|||
|
|||
A spark continues growing when: |
|||
|
|||
``` |
|||
E_tip > E_propagation |
|||
``` |
|||
|
|||
**When growth stalls:** |
|||
|
|||
``` |
|||
If E_tip < E_propagation: |
|||
- Growth stalls |
|||
- Spark cannot extend further |
|||
- System is "voltage-limited" |
|||
- More power doesn't help without more voltage |
|||
``` |
|||
|
|||
**Practical implications:** |
|||
- Small topload → lower voltage → shorter maximum length |
|||
- Long target spark requires higher voltage to maintain E_tip |
|||
- Enhancement factor κ helps by concentrating field at tip |
|||
- But κ decreases as tip becomes less sharp |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE 3.1: Field Calculation |
|||
|
|||
**Given:** |
|||
- Spark length: L = 1.5 m |
|||
- Topload voltage: V_top = 400 kV |
|||
- Tip enhancement: κ = 3.5 (from FEMM or estimate) |
|||
|
|||
**Find:** |
|||
(a) Average field |
|||
(b) Tip field |
|||
(c) Can spark grow if E_propagation = 0.6 MV/m? |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Average field** |
|||
|
|||
``` |
|||
E_average = V_top / L |
|||
= 400×10³ V / 1.5 m |
|||
= 267 kV/m |
|||
= 0.267 MV/m |
|||
``` |
|||
|
|||
**Part (b): Tip field** |
|||
|
|||
``` |
|||
E_tip = κ × E_average |
|||
= 3.5 × 0.267 MV/m |
|||
= 0.93 MV/m |
|||
``` |
|||
|
|||
**Part (c): Compare to threshold** |
|||
|
|||
``` |
|||
E_tip = 0.93 MV/m |
|||
E_propagation = 0.6 MV/m |
|||
|
|||
E_tip > E_propagation ✓ |
|||
|
|||
Yes, spark can continue growing. |
|||
Safety margin: 0.93/0.6 = 1.55× above threshold |
|||
``` |
|||
|
|||
**If voltage drops to 300 kV:** |
|||
|
|||
``` |
|||
E_average = 300 kV / 1.5 m = 0.2 MV/m |
|||
E_tip = 3.5 × 0.2 = 0.7 MV/m |
|||
|
|||
Still above 0.6 MV/m, but margin reduced to 1.17× |
|||
``` |
|||
|
|||
**If voltage drops to 250 kV:** |
|||
|
|||
``` |
|||
E_average = 250 kV / 1.5 m = 0.167 MV/m |
|||
E_tip = 3.5 × 0.167 = 0.58 MV/m |
|||
|
|||
Below 0.6 MV/m - growth stalls! |
|||
``` |
|||
|
|||
**Key insight:** Even moderate voltage reduction can cause growth to stall. Maintaining adequate voltage throughout the ramp is critical for long sparks. |
|||
|
|||
--- |
|||
|
|||
## Visual Understanding: Field Enhancement |
|||
|
|||
Imagine two scenarios: |
|||
|
|||
**LEFT: Uniform field (parallel plates)** |
|||
- Two flat plates with voltage V between them |
|||
- Evenly spaced field lines (vertical) |
|||
- Formula: E = V/d (constant everywhere) |
|||
- No enhancement: κ = 1 |
|||
|
|||
**RIGHT: Point-to-plane (spark geometry)** |
|||
- Spherical topload at top (voltage V) |
|||
- Sharp spark tip pointing down |
|||
- Ground plane at bottom |
|||
- Field lines: |
|||
- Sparse near topload (low field density) |
|||
- Highly concentrated at tip (high field density) |
|||
- Spread out below tip |
|||
- Color gradient showing field strength: |
|||
- Blue (low field) far from tip |
|||
- Red (high field) at tip |
|||
- E_average = V/L along spark |
|||
- E_tip at very tip (red zone) |
|||
- Enhancement: E_tip = κ × E_average, κ = 2-5 |
|||
|
|||
**Field vs distance from tip:** Sharp peak at tip, drops rapidly with distance, approaches E_average far from tip. |
|||
|
|||
{image:field-enhancement-comparison} |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **E_inception ≈ 2-3 MV/m**: Required to start breakdown from smooth surface |
|||
- **E_propagation ≈ 0.4-1.0 MV/m**: Required to sustain spark growth (lower than inception) |
|||
- **Tip enhancement**: E_tip = κ × E_average, where κ ≈ 2-5 for typical geometries |
|||
- **Growth criterion**: Spark grows when E_tip > E_propagation, stalls when E_tip < E_propagation |
|||
- **Environmental effects**: Altitude and humidity affect thresholds by ±20-30% |
|||
- **FEMM advantage**: Directly computes E_tip from geometry, no need to estimate κ |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-01} |
|||
|
|||
**Problem 1:** A 0.8 m spark has V_top = 280 kV and κ = 4. Calculate E_tip. If E_propagation = 0.5 MV/m, can it grow? |
|||
|
|||
**Problem 2:** A spark stalls at 2.0 m length with V_top = 500 kV and κ = 3. Estimate E_propagation for these conditions. |
|||
|
|||
**Problem 3:** Why is E_inception > E_propagation? Explain the physical difference in 2-3 sentences. |
|||
|
|||
--- |
|||
**Next Lesson:** [Voltage-Limited Length](02-voltage-limits.md) |
|||
@ -0,0 +1,275 @@ |
|||
--- |
|||
id: phys-02 |
|||
title: "Maximum Voltage-Limited Length" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 30 |
|||
prerequisites: ["phys-01", "opt-07"] |
|||
objectives: |
|||
- Understand what causes voltage-limited spark growth |
|||
- Calculate maximum achievable spark length for given voltage |
|||
- Use FEMM to compute tip fields for realistic geometries |
|||
- Recognize when more power cannot help extend sparks |
|||
tags: ["voltage-limit", "FEMM", "E-field", "maximum-length", "altitude"] |
|||
--- |
|||
|
|||
# Maximum Voltage-Limited Length |
|||
|
|||
Even with unlimited power, a spark cannot grow indefinitely. The maximum length is determined by the **voltage-limited condition**: when the tip field drops below the propagation threshold, growth stalls regardless of available power. |
|||
|
|||
## The Voltage-Limited Condition |
|||
|
|||
A spark is **voltage-limited** when: |
|||
|
|||
``` |
|||
E_tip < E_propagation |
|||
``` |
|||
|
|||
Under this condition: |
|||
- Field at tip is too weak to sustain ionization |
|||
- Spark cannot extend further |
|||
- Growth rate: dL/dt = 0 (stalled) |
|||
- More power doesn't help (without more voltage) |
|||
- Common scenario: small topload, long target length |
|||
|
|||
**Contrast with power-limited:** |
|||
- E_tip > E_propagation (field is adequate) |
|||
- But P_stream < ε × (dL/dt)_desired |
|||
- Spark grows slowly or stalls before reaching potential |
|||
- More voltage doesn't help (without more power) |
|||
- Common scenario: high-Q coils, weak drive |
|||
|
|||
## Calculating Maximum Length |
|||
|
|||
The maximum voltage-limited length L_max occurs when: |
|||
|
|||
``` |
|||
E_tip(V_top, L_max) = E_propagation |
|||
``` |
|||
|
|||
Using the tip enhancement approximation: |
|||
|
|||
``` |
|||
κ × (V_top / L_max) = E_propagation |
|||
|
|||
Solving for L_max: |
|||
L_max = κ × V_top / E_propagation |
|||
``` |
|||
|
|||
**Important caveats:** |
|||
- This assumes κ remains constant (simplification) |
|||
- Reality: κ decreases as spark grows and tip becomes less sharp |
|||
- Capacitive voltage division reduces V_tip (covered in Lesson 07) |
|||
- Best accuracy: use FEMM to compute E_tip(V_top, L) iteratively |
|||
|
|||
### FEMM Field Computation |
|||
|
|||
**Finite Element Method Magnetics (FEMM)** provides accurate field calculations: |
|||
|
|||
**Workflow:** |
|||
1. Define geometry (topload, spark channel, ground) |
|||
2. Set boundary conditions (V_top on topload, 0V on ground) |
|||
3. Mesh and solve Laplace's equation (∇²V = 0) |
|||
4. Extract E_tip at spark endpoint |
|||
5. Check: E_tip ≥ E_propagation? |
|||
|
|||
**Advantages over analytical formulas:** |
|||
- Accounts for realistic topload geometry (toroids, spheres) |
|||
- Includes ground plane proximity effects |
|||
- Automatically computes κ from geometry |
|||
- Handles multiple conductors and complex shapes |
|||
|
|||
**Iterative approach for L_max:** |
|||
``` |
|||
1. Start with initial guess: L = L_guess |
|||
2. Run FEMM with topload at V_top and spark length L |
|||
3. Extract E_tip from FEMM results |
|||
4. Compare E_tip to E_propagation: |
|||
- If E_tip > E_propagation: try longer L |
|||
- If E_tip < E_propagation: try shorter L |
|||
5. Repeat until E_tip ≈ E_propagation (within tolerance) |
|||
6. Result: L_max |
|||
``` |
|||
|
|||
## Altitude and Environmental Effects |
|||
|
|||
The propagation threshold E_propagation varies with environmental conditions: |
|||
|
|||
### Altitude Effects |
|||
|
|||
**Lower air density at higher altitude:** |
|||
|
|||
``` |
|||
ρ_air ∝ exp(-h/H) where H ≈ 8.5 km (scale height) |
|||
|
|||
E_propagation ∝ ρ_air |
|||
|
|||
Typical variation: ±20-30% from sea level to moderate altitude |
|||
``` |
|||
|
|||
**Practical implications:** |
|||
- At 1500 m elevation: E_propagation reduced by ~15% |
|||
- Same voltage produces ~15% longer sparks |
|||
- Important for coilers at altitude to adjust expectations |
|||
|
|||
**Example:** |
|||
``` |
|||
Sea level (ρ = 1.0): E_propagation = 0.6 MV/m |
|||
1500 m (ρ ≈ 0.85): E_propagation ≈ 0.51 MV/m |
|||
|
|||
For V_top = 400 kV, κ = 3: |
|||
Sea level: L_max = 3 × 400 kV / 0.6 MV/m = 2.0 m |
|||
1500 m: L_max = 3 × 400 kV / 0.51 MV/m = 2.35 m (17% longer) |
|||
``` |
|||
|
|||
### Humidity Effects |
|||
|
|||
**Water vapor changes breakdown characteristics:** |
|||
- Typical variation: ~10% |
|||
- Less significant than altitude |
|||
- Complex dependency on partial pressure |
|||
|
|||
### Temperature Effects |
|||
|
|||
**Affects air density:** |
|||
- ρ_air ∝ 1/T (ideal gas law) |
|||
- Small effect: ~10-15% from winter to summer |
|||
- Usually overshadowed by altitude effects |
|||
|
|||
## Common Misconceptions |
|||
|
|||
**Misconception 1:** "More power always makes longer sparks" |
|||
|
|||
**Reality:** If voltage-limited, adding power just makes the spark brighter/hotter but not longer. Both adequate voltage AND adequate power are required. |
|||
|
|||
**Misconception 2:** "κ is constant for a given coil" |
|||
|
|||
**Reality:** κ changes as the spark grows. Initial sharp tip has high κ, but as spark extends and tip becomes less defined, κ decreases. This further limits maximum length. |
|||
|
|||
**Misconception 3:** "Small topload is fine if I have enough power" |
|||
|
|||
**Reality:** Small topload limits maximum voltage capability. Even unlimited power cannot overcome voltage limitation from inadequate topload capacitance. |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Maximum Length Calculation |
|||
|
|||
**Given:** |
|||
- Topload voltage capability: V_top_max = 500 kV |
|||
- Tip enhancement factor: κ = 3.2 (estimated for this geometry) |
|||
- Propagation threshold: E_propagation = 0.7 MV/m (sea level) |
|||
- Same coil operated at 1500 m altitude |
|||
|
|||
**Find:** |
|||
(a) Maximum spark length at sea level |
|||
(b) Maximum spark length at 1500 m (assume E_propagation reduced by 15%) |
|||
(c) Voltage required for 3 m spark at sea level |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Sea level maximum length** |
|||
|
|||
``` |
|||
L_max = κ × V_top_max / E_propagation |
|||
= 3.2 × 500 kV / 0.7 MV/m |
|||
= 3.2 × 500×10³ V / (0.7×10⁶ V/m) |
|||
= 1600 kV / 700 kV/m |
|||
= 2.29 m |
|||
|
|||
Maximum spark length ≈ 2.3 m |
|||
``` |
|||
|
|||
**Part (b): 1500 m altitude** |
|||
|
|||
At altitude, E_propagation reduced by 15%: |
|||
|
|||
``` |
|||
E_propagation(1500m) = 0.7 MV/m × 0.85 = 0.595 MV/m |
|||
|
|||
L_max = 3.2 × 500 kV / 0.595 MV/m |
|||
= 1600 kV / 595 kV/m |
|||
= 2.69 m |
|||
|
|||
Maximum spark length ≈ 2.7 m (17% longer than sea level) |
|||
``` |
|||
|
|||
**Part (c): Voltage for 3 m at sea level** |
|||
|
|||
Rearrange the equation: |
|||
|
|||
``` |
|||
V_required = E_propagation × L_target / κ |
|||
= 0.7 MV/m × 3 m / 3.2 |
|||
= 2.1 MV / 3.2 |
|||
= 0.656 MV |
|||
= 656 kV |
|||
|
|||
Need 656 kV to reach 3 m at sea level |
|||
This exceeds V_top_max = 500 kV |
|||
Therefore 3 m is not achievable with current topload |
|||
``` |
|||
|
|||
**Conclusion:** To reach 3 m at sea level, need to: |
|||
- Increase topload size (higher voltage capability), OR |
|||
- Operate at altitude (lower E_propagation), OR |
|||
- Improve tip enhancement (sharper geometry, higher κ) |
|||
|
|||
--- |
|||
|
|||
## FEMM Tutorial Concept |
|||
|
|||
While detailed FEMM usage is beyond this lesson, here's the conceptual workflow: |
|||
|
|||
**Problem setup (axisymmetric):** |
|||
``` |
|||
Geometry in r-z coordinates: |
|||
- Toroid: major radius 20 cm, minor radius 7 cm, center at z = 0 |
|||
- Spark: cylinder radius 1 mm, extends from toroid to length L |
|||
- Ground plane: large disk at z = -L - 30 cm |
|||
- Outer boundary: large box (r = 150 cm, z = ±200 cm) |
|||
|
|||
Materials: |
|||
- Air everywhere (ε_r = 1.0) |
|||
|
|||
Boundaries: |
|||
- r = 0: Axisymmetric boundary (symmetry axis) |
|||
- Outer box: V = 0 V (Dirichlet, grounded far field) |
|||
- Topload surface: V = V_top |
|||
- Ground plane: V = 0 V |
|||
|
|||
Solve: |
|||
- Laplace equation: ∇²V = 0 |
|||
- Extract E_tip at spark endpoint |
|||
``` |
|||
|
|||
**Reading results:** |
|||
- FEMM displays field magnitude |E| as color contours |
|||
- Highest concentration (red) at spark tip |
|||
- Extract numerical value at tip location |
|||
- Compare to E_propagation threshold |
|||
|
|||
{image:femm-field-plot-example} |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Voltage-limited**: Growth stalls when E_tip < E_propagation, regardless of available power |
|||
- **Maximum length**: L_max ≈ κ × V_top / E_propagation (simplified formula) |
|||
- **FEMM accuracy**: Finite element analysis accounts for realistic geometry and provides E_tip directly |
|||
- **Altitude benefit**: Lower air density reduces E_propagation by ~20-30%, enabling longer sparks |
|||
- **Design implication**: Both adequate voltage AND adequate power are necessary for target length |
|||
- **κ is not constant**: Tip enhancement decreases as spark grows, further limiting length |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-02} |
|||
|
|||
**Problem 1:** A coil has V_top = 350 kV, κ = 3.5, and E_propagation = 0.6 MV/m. Calculate L_max. If operating at 2000 m altitude (E_propagation reduced 20%), what is the new L_max? |
|||
|
|||
**Problem 2:** FEMM simulation shows E_tip = 0.55 MV/m for a 2.5 m spark at V_top = 450 kV. If E_propagation = 0.6 MV/m, what happens? Estimate the maximum length this voltage can support if κ ≈ 3. |
|||
|
|||
**Problem 3:** Explain why having 100 kW of available power doesn't guarantee a 3 m spark if the topload can only reach 400 kV. Use the concepts of voltage-limited vs power-limited growth. |
|||
|
|||
--- |
|||
**Next Lesson:** [Energy Per Meter Concept](03-energy-per-meter.md) |
|||
@ -0,0 +1,359 @@ |
|||
--- |
|||
id: phys-03 |
|||
title: "Energy Per Meter Concept" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 40 |
|||
prerequisites: ["phys-01", "phys-02"] |
|||
objectives: |
|||
- Understand the concept of energy per meter (ε) for spark growth |
|||
- Apply the growth rate equation dL/dt = P/ε |
|||
- Calculate total energy and average power for target spark length |
|||
- Recognize the difference between theoretical minimum and practical ε values |
|||
tags: ["energy-per-meter", "epsilon", "growth-rate", "power", "ionization"] |
|||
--- |
|||
|
|||
# Energy Per Meter Concept |
|||
|
|||
Extending a spark requires energy. Surprisingly, the energy needed is approximately **constant per unit length**, regardless of how long the spark already is. This fundamental concept enables practical spark growth modeling. |
|||
|
|||
## The Energy Per Meter Parameter (ε) |
|||
|
|||
**Definition:** ε (epsilon) is the energy required to extend a spark by one meter. |
|||
|
|||
``` |
|||
Energy to grow from L₁ to L₂: |
|||
ΔE ≈ ε × (L₂ - L₁) [Joules] |
|||
|
|||
where ε has units [J/m] |
|||
``` |
|||
|
|||
**Key characteristics:** |
|||
- Approximately constant for a given operating mode |
|||
- Independent of current spark length (first-order approximation) |
|||
- Depends strongly on operating regime (QCW vs burst) |
|||
- Empirical parameter that must be calibrated per coil |
|||
|
|||
**Why is this useful?** |
|||
- Simple relationship: energy scales linearly with length |
|||
- Easy to calculate power requirements |
|||
- Enables growth rate predictions |
|||
- Separates voltage limit (field) from power limit (energy) |
|||
|
|||
## What Does ε Include? |
|||
|
|||
The energy per meter is **NOT** just the ionization energy. It includes all energy processes: |
|||
|
|||
### 1. Initial Ionization |
|||
Breaking molecular bonds to create ions and free electrons: |
|||
``` |
|||
E_ionize ≈ 15 eV per molecule |
|||
``` |
|||
|
|||
### 2. Heating to Operating Temperature |
|||
Raising channel temperature from ambient to 5,000-20,000 K: |
|||
``` |
|||
E_thermal = m × c_p × ΔT |
|||
``` |
|||
|
|||
### 3. Work Against Pressure |
|||
Expanding the channel against atmospheric pressure: |
|||
``` |
|||
E_expansion = P × ΔV |
|||
``` |
|||
|
|||
### 4. Radiation Losses |
|||
Emitted light, UV, infrared, and RF: |
|||
``` |
|||
E_radiation = ∫ σ T⁴ dA dt (blackbody + line emission) |
|||
``` |
|||
|
|||
### 5. Branching Losses |
|||
Energy wasted in short branches that don't contribute to main channel: |
|||
``` |
|||
E_branching = ε × L_branches (failed growth attempts) |
|||
``` |
|||
|
|||
### 6. General Inefficiencies |
|||
Non-productive heating, turbulence, and other losses: |
|||
``` |
|||
E_losses = various mechanisms |
|||
``` |
|||
|
|||
**Result:** Practical ε is 20-300× larger than theoretical ionization minimum! |
|||
|
|||
## Theoretical Minimum Energy |
|||
|
|||
Let's estimate the absolute minimum energy needed for ionization alone: |
|||
|
|||
**Given:** |
|||
- Ionization energy per molecule: ~15 eV |
|||
- Air density: n ≈ 2.5×10²⁵ molecules/m³ |
|||
- Channel diameter: d = 1 mm (typical) |
|||
- Length increment: ΔL = 1 m |
|||
|
|||
**Calculation:** |
|||
|
|||
``` |
|||
Volume of 1 m channel: |
|||
V = π(d/2)² × L = π(0.5×10⁻³)² × 1 = 7.85×10⁻⁷ m³ |
|||
|
|||
Number of molecules: |
|||
N = n × V = 2.5×10²⁵ × 7.85×10⁻⁷ = 1.96×10¹⁹ molecules |
|||
|
|||
Energy to ionize: |
|||
E_min = N × 15 eV × (1.6×10⁻¹⁹ J/eV) |
|||
= 1.96×10¹⁹ × 15 × 1.6×10⁻¹⁹ |
|||
= 0.47 J/m |
|||
|
|||
Theoretical minimum: ε_theory ≈ 0.3-0.5 J/m |
|||
``` |
|||
|
|||
**Why is practical ε so much higher?** |
|||
|
|||
Compare to real values: |
|||
- QCW: ε ≈ 5-15 J/m (10-30× theoretical) |
|||
- Burst mode: ε ≈ 30-100 J/m (60-200× theoretical) |
|||
|
|||
The difference accounts for: |
|||
- Heating to high temperature (major contribution) |
|||
- Radiation losses (visible light alone is significant) |
|||
- Expansion work (pushing air aside) |
|||
- Branching inefficiency (many failed paths) |
|||
- Re-ionization (especially in pulsed modes) |
|||
|
|||
## The Growth Rate Equation |
|||
|
|||
When the field threshold is met (E_tip > E_propagation), the growth rate is determined by power: |
|||
|
|||
``` |
|||
dL/dt = P_stream / ε [m/s] |
|||
|
|||
where: |
|||
P_stream = power delivered to spark [W] |
|||
ε = energy per meter [J/m] |
|||
``` |
|||
|
|||
**Physical interpretation:** |
|||
- More power → faster growth |
|||
- Higher ε (inefficiency) → slower growth for same power |
|||
- Linear relationship: double power → double growth rate |
|||
|
|||
**When growth stops:** |
|||
|
|||
``` |
|||
If E_tip < E_propagation: |
|||
dL/dt = 0 (stalled) |
|||
|
|||
Cannot grow regardless of available power |
|||
(voltage-limited condition) |
|||
``` |
|||
|
|||
### Predicting Growth Time |
|||
|
|||
For constant power during ramp: |
|||
|
|||
``` |
|||
Growth rate: dL/dt = P_stream / ε |
|||
|
|||
Integrating: L(t) = (P_stream / ε) × t |
|||
|
|||
Time to reach target length: |
|||
T = ε × L_target / P_stream |
|||
``` |
|||
|
|||
**More realistic scenario:** Power changes as spark grows (loading changes): |
|||
|
|||
``` |
|||
T = ∫₀^L_target (ε / P_stream(L)) dL |
|||
|
|||
Requires simulation or numerical integration |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE 3.2: Energy Budget |
|||
|
|||
**Given:** |
|||
- Target spark length: L = 2 m |
|||
- Operating mode: QCW with ε = 10 J/m |
|||
- Growth time: T = 12 ms |
|||
|
|||
**Find:** |
|||
(a) Total energy required |
|||
(b) Average power required |
|||
(c) If 80 kW is available, what changes? |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Total energy** |
|||
|
|||
``` |
|||
E_total = ε × L |
|||
= 10 J/m × 2 m |
|||
= 20 J |
|||
``` |
|||
|
|||
Remarkably modest! Only 20 J to create a 2 m spark. |
|||
|
|||
**Part (b): Average power** |
|||
|
|||
``` |
|||
P_avg = E_total / T |
|||
= 20 J / 0.012 s |
|||
= 1,667 W |
|||
≈ 1.7 kW |
|||
``` |
|||
|
|||
For 12 ms growth, need ~1.7 kW average power. |
|||
|
|||
**Part (c): With 80 kW available** |
|||
|
|||
Available power is 80 kW, but only need 1.7 kW! |
|||
|
|||
``` |
|||
Power ratio: 80 kW / 1.7 kW = 47× more than needed |
|||
``` |
|||
|
|||
**Option 1: Grow much faster** |
|||
``` |
|||
T_min = E_total / P_available |
|||
= 20 J / 80,000 W |
|||
= 0.00025 s |
|||
= 0.25 ms (burst-like growth) |
|||
``` |
|||
|
|||
**Option 2: Grow to longer length (in same 12 ms)** |
|||
``` |
|||
L_max_power = P_available × T / ε |
|||
= 80,000 W × 0.012 s / 10 J/m |
|||
= 960 J / 10 J/m |
|||
= 96 m (!!) |
|||
``` |
|||
|
|||
**Reality check:** 96 m is absurd! What limits this? |
|||
|
|||
**Voltage limit kicks in first:** |
|||
- Cannot maintain E_tip > E_propagation for 96 m |
|||
- Spark stalls at voltage-limited length |
|||
- Typical: L_max ≈ 2-4 m for practical topload voltages |
|||
|
|||
**Key insight:** Tesla coils are almost always **voltage-limited**, not power-limited. Excess power goes into brightening, heating, and branching rather than length. |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE 3.3: Comparing Operating Modes |
|||
|
|||
**Given:** |
|||
- Two coils both deliver P = 50 kW average |
|||
- Coil A: QCW mode, ε_A = 8 J/m |
|||
- Coil B: Burst mode, ε_B = 50 J/m |
|||
- Both operate for T = 10 ms |
|||
|
|||
**Find:** Which produces longer sparks? |
|||
|
|||
### Solution |
|||
|
|||
**Coil A (QCW):** |
|||
|
|||
``` |
|||
L_A = P × T / ε_A |
|||
= 50,000 W × 0.010 s / 8 J/m |
|||
= 500 J / 8 J/m |
|||
= 62.5 m (voltage-limited in practice) |
|||
``` |
|||
|
|||
**Coil B (Burst):** |
|||
|
|||
``` |
|||
L_B = P × T / ε_B |
|||
= 50,000 W × 0.010 s / 50 J/m |
|||
= 500 J / 50 J/m |
|||
= 10 m (still voltage-limited in practice) |
|||
``` |
|||
|
|||
**Comparison:** |
|||
|
|||
``` |
|||
Ratio: L_A / L_B = ε_B / ε_A = 50/8 = 6.25× |
|||
|
|||
QCW coil produces 6.25× longer sparks for same power! |
|||
``` |
|||
|
|||
**Practical reality:** |
|||
- Both limited by voltage before reaching these lengths |
|||
- But ratio still applies: QCW gives much better length efficiency |
|||
- Coil A might reach 2.5 m while Coil B reaches 0.4 m |
|||
- Burst mode wastes energy on brightness and branching |
|||
|
|||
**Why choose burst mode then?** |
|||
- Spectacular brightness and branches (visual appeal) |
|||
- Higher peak current (electromagnetic effects) |
|||
- Simpler drive electronics |
|||
- Better for musical/modulated output |
|||
- Different aesthetic goals than pure length |
|||
|
|||
--- |
|||
|
|||
## Power-Limited vs Voltage-Limited |
|||
|
|||
Understanding the interplay between power and voltage limits: |
|||
|
|||
### Voltage-Limited Condition |
|||
``` |
|||
E_tip < E_propagation |
|||
- Field too weak at tip |
|||
- Spark cannot extend |
|||
- More power → brighter/hotter, not longer |
|||
- Common for Tesla coils |
|||
``` |
|||
|
|||
### Power-Limited Condition |
|||
``` |
|||
E_tip > E_propagation, but P_stream insufficient |
|||
- Field adequate but not enough energy |
|||
- Spark grows slowly or stalls before reaching potential |
|||
- More voltage doesn't help without more power |
|||
- Less common for Tesla coils (usually have excess power) |
|||
``` |
|||
|
|||
### Practical Implications |
|||
|
|||
**For most Tesla coils:** |
|||
1. Design for adequate voltage (large topload, high primary voltage) |
|||
2. Ensure sufficient power (but don't need enormous amounts) |
|||
3. Optimize ε by choosing appropriate operating mode |
|||
4. Accept that voltage limit dominates final length |
|||
|
|||
**Rule of thumb:** |
|||
- If P × T / ε >> L_actual, you're voltage-limited |
|||
- If P × T / ε ≈ L_actual, you might be power-limited |
|||
- Most coils fall in first category (voltage-limited) |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **ε definition**: Energy per meter [J/m], approximately constant for a given mode |
|||
- **Growth rate**: dL/dt = P/ε when field threshold is met |
|||
- **Total energy**: E_total ≈ ε × L (linear scaling) |
|||
- **Theoretical minimum**: ε_theory ≈ 0.3-0.5 J/m (ionization only) |
|||
- **Practical values**: 10-300× higher than theoretical (includes heating, radiation, losses) |
|||
- **Operating mode matters**: QCW has low ε (efficient), burst has high ε (inefficient) |
|||
- **Voltage limit dominates**: Most Tesla coils have more than enough power, limited by voltage |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-03} |
|||
|
|||
**Problem 1:** A burst-mode coil has ε = 60 J/m. To reach L = 1.5 m in a 200 μs pulse, what power is required? Is this realistic? |
|||
|
|||
**Problem 2:** A QCW coil delivers 30 kW average power for 15 ms with ε = 12 J/m. Calculate: |
|||
(a) Total energy delivered |
|||
(b) Maximum length if power-limited |
|||
(c) If actual length is only 1.8 m, what does this tell you? |
|||
|
|||
**Problem 3:** Explain why practical ε is 50-100× larger than the theoretical ionization minimum. List at least three major energy sinks. |
|||
|
|||
--- |
|||
**Next Lesson:** [Empirical ε Values](04-empirical-epsilon.md) |
|||
@ -0,0 +1,404 @@ |
|||
--- |
|||
id: phys-04 |
|||
title: "Empirical ε Values and Calibration" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 35 |
|||
prerequisites: ["phys-03"] |
|||
objectives: |
|||
- Learn typical ε values for different operating modes |
|||
- Understand why QCW, DRSSTC, and burst modes have different ε |
|||
- Calibrate ε from experimental measurements |
|||
- Apply thermal accumulation effects to refine ε predictions |
|||
tags: ["epsilon", "calibration", "QCW", "DRSSTC", "burst-mode", "thermal-accumulation"] |
|||
--- |
|||
|
|||
# Empirical ε Values and Calibration |
|||
|
|||
The energy per meter (ε) is not a universal constant - it depends strongly on the operating mode. Understanding typical values and calibration methods is essential for accurate spark growth modeling. |
|||
|
|||
## Typical ε Values by Operating Mode |
|||
|
|||
### QCW (Quasi-Continuous Wave) |
|||
|
|||
**ε ≈ 5-15 J/m** |
|||
|
|||
**Characteristics:** |
|||
- Long ramp times: 5-20 ms |
|||
- Channel stays hot throughout growth |
|||
- Efficient leader formation |
|||
- Minimal re-ionization needed |
|||
- Each joule efficiently extends length |
|||
|
|||
**Why low ε (efficient)?** |
|||
- Continuous power maintains channel ionization |
|||
- Thermal ionization kept active |
|||
- Leaders form and persist |
|||
- Minimal energy wasted on re-starting |
|||
|
|||
**Typical coil parameters:** |
|||
- Medium-high power: 10-100 kW |
|||
- Moderate duty cycle: 1-10% |
|||
- Linear voltage ramp |
|||
- Long sparks: 2-5+ m |
|||
|
|||
### Hybrid DRSSTC (Moderate Duty Cycle) |
|||
|
|||
**ε ≈ 20-40 J/m** |
|||
|
|||
**Characteristics:** |
|||
- Medium pulse lengths: 1-5 ms |
|||
- Mix of streamers and leaders |
|||
- Some thermal accumulation between pulses |
|||
- Moderate efficiency |
|||
|
|||
**Why moderate ε?** |
|||
- Not quite continuous like QCW |
|||
- Some cooling between bursts |
|||
- Partial re-ionization required |
|||
- Both streamer and leader mechanisms active |
|||
|
|||
**Typical coil parameters:** |
|||
- High power: 50-200 kW peak |
|||
- Moderate duty cycle: 5-15% |
|||
- Partial interrupter control |
|||
- Good balance: length and brightness |
|||
|
|||
### Burst Mode (Hard-Pulsed) |
|||
|
|||
**ε ≈ 30-100+ J/m** |
|||
|
|||
**Characteristics:** |
|||
- Short pulses: <500 μs typical |
|||
- Channel cools between pulses |
|||
- Mostly streamers, bright but short |
|||
- Must re-ionize repeatedly |
|||
- Poor length efficiency |
|||
|
|||
**Why high ε (inefficient)?** |
|||
- Peak power → intense brightening and branching |
|||
- Channel cools between bursts (ms timescale) |
|||
- Energy dumped into light and heat, not length |
|||
- Must restart from cold each time |
|||
- High ionization overhead |
|||
|
|||
**Typical coil parameters:** |
|||
- Very high peak power: 100-500+ kW |
|||
- Low duty cycle: 0.1-2% |
|||
- Bang energy: 10-100+ J per burst |
|||
- Short sparks: 0.5-2 m despite high energy |
|||
|
|||
### Single-Shot Impulse |
|||
|
|||
**ε ≈ 50-150+ J/m** |
|||
|
|||
**Characteristics:** |
|||
- One-time discharge (capacitor bank) |
|||
- No thermal memory from previous events |
|||
- All energy must come from single pulse |
|||
- Very high ε due to complete inefficiency |
|||
|
|||
**Why very high ε?** |
|||
- Starting from completely cold air |
|||
- No accumulated ionization |
|||
- Transient streamer formation |
|||
- Most energy into flash and noise |
|||
|
|||
## Physical Explanation for ε Differences |
|||
|
|||
### QCW Efficiency (Low ε) |
|||
|
|||
**Energy flow:** |
|||
``` |
|||
1. Initial streamers form (t = 0) |
|||
2. Current flows → Joule heating (t = 0-1 ms) |
|||
3. Channel heats → thermal ionization (t = 1-2 ms) |
|||
4. Leader forms from base (t = 2-5 ms) |
|||
5. Leader maintained by continuous power (t = 5-20 ms) |
|||
6. New growth builds on existing hot ionization |
|||
7. Minimal wasted energy |
|||
``` |
|||
|
|||
**Result:** Each joule goes into extending the channel, not re-creating what already exists. |
|||
|
|||
### Burst Inefficiency (High ε) |
|||
|
|||
**Energy flow:** |
|||
``` |
|||
1. Pulse creates bright streamer (t = 0-100 μs) |
|||
2. Pulse ends, no more power (t = 100 μs) |
|||
3. Channel begins cooling (t = 0.1-1 ms) |
|||
4. Thermal diffusion and convection cool channel |
|||
5. Ionization recombines |
|||
6. Next pulse must re-ionize cold gas (t = 1-10 ms) |
|||
7. Energy wasted heating the same air repeatedly |
|||
``` |
|||
|
|||
**Result:** Energy into brightening and repeated ionization overhead, not cumulative length. |
|||
|
|||
### Analogy: Boiling Water |
|||
|
|||
**Low ε (QCW):** |
|||
- Keep burner on continuously |
|||
- Maintain simmer (steady state) |
|||
- Efficient: minimal energy to maintain temperature |
|||
|
|||
**High ε (Burst):** |
|||
- Pulse burner on/off repeatedly |
|||
- Water cools between pulses |
|||
- Inefficient: must reheat repeatedly |
|||
|
|||
## Calibration Procedure |
|||
|
|||
To calibrate ε for your specific coil: |
|||
|
|||
### Step 1: Measure Delivered Energy |
|||
|
|||
**From SPICE simulation:** |
|||
``` |
|||
E_delivered = ∫ P_spark(t) dt |
|||
|
|||
where P_spark = instantaneous power to spark |
|||
Integration from t = 0 to end of ramp |
|||
``` |
|||
|
|||
**From measurements (if available):** |
|||
``` |
|||
E_delivered ≈ E_capacitor - E_losses |
|||
|
|||
where E_capacitor = ½ C_primary V_primary² |
|||
E_losses = resistive, core, switching losses |
|||
``` |
|||
|
|||
### Step 2: Measure Final Spark Length |
|||
|
|||
**Direct measurement:** |
|||
- Photograph spark with scale reference |
|||
- Measure from topload to tip |
|||
- Average over multiple runs (sparks vary!) |
|||
- Use median or typical length, not maximum outlier |
|||
|
|||
**Typical measurement uncertainty:** |
|||
- ±10-20% due to spark variability |
|||
- Branching makes "length" ambiguous |
|||
- Use main channel length |
|||
|
|||
### Step 3: Calculate ε |
|||
|
|||
``` |
|||
ε = E_delivered / L_final [J/m] |
|||
|
|||
Example: |
|||
E_delivered = 45 J (from SPICE) |
|||
L_final = 1.8 m (measured) |
|||
|
|||
ε = 45 J / 1.8 m = 25 J/m |
|||
``` |
|||
|
|||
### Step 4: Verify and Refine |
|||
|
|||
**Repeat for different power levels:** |
|||
- Change primary voltage or pulse width |
|||
- Measure new E_delivered and L_final |
|||
- Calculate ε for each run |
|||
- Average to get robust estimate |
|||
|
|||
**Check for consistency:** |
|||
- ε should be approximately constant (±30%) |
|||
- Large variations indicate: |
|||
- Voltage-limited at some power levels |
|||
- Thermal accumulation effects |
|||
- Operating mode changes |
|||
|
|||
## Thermal Accumulation Effects |
|||
|
|||
For more advanced modeling, ε can decrease during long ramps due to thermal accumulation: |
|||
|
|||
``` |
|||
ε(t) = ε₀ / (1 + α × ∫P_stream dt) |
|||
|
|||
where: |
|||
ε₀ = initial energy per meter [J/m] |
|||
α = thermal accumulation factor [1/J] |
|||
∫P_stream dt = accumulated energy [J] |
|||
``` |
|||
|
|||
**Physical meaning:** |
|||
- As channel heats up, ionization becomes easier |
|||
- Less energy needed per meter as temperature rises |
|||
- ε decreases with accumulated heating |
|||
|
|||
**Typical values:** |
|||
- ε₀ ≈ 15 J/m (initial, cold start) |
|||
- α ≈ 0.01-0.05 [1/J] |
|||
- After 50 J accumulated: ε ≈ 15/(1 + 0.03×50) = 6 J/m |
|||
|
|||
**When to use:** |
|||
- Long QCW ramps (>10 ms) |
|||
- High accumulated energy (>30 J) |
|||
- For short bursts: ε ≈ ε₀ (constant) |
|||
|
|||
**Simplified model:** |
|||
Most practitioners use constant ε for simplicity: |
|||
- Choose ε representing average over ramp |
|||
- Simpler and usually adequate |
|||
- Advanced users can implement ε(t) in simulation |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Calibration from Data |
|||
|
|||
**Given:** |
|||
Three experimental runs on a QCW coil: |
|||
|
|||
| Run | V_primary | E_delivered | L_measured | |
|||
|-----|-----------|-------------|------------| |
|||
| 1 | 200 V | 25 J | 2.2 m | |
|||
| 2 | 250 V | 38 J | 3.1 m | |
|||
| 3 | 300 V | 55 J | 4.5 m | |
|||
|
|||
**Find:** |
|||
(a) Calculate ε for each run |
|||
(b) Average ε for this coil |
|||
(c) Assess consistency |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): ε for each run** |
|||
|
|||
``` |
|||
Run 1: ε₁ = E₁ / L₁ = 25 J / 2.2 m = 11.4 J/m |
|||
Run 2: ε₂ = E₂ / L₂ = 38 J / 3.1 m = 12.3 J/m |
|||
Run 3: ε₃ = E₃ / L₃ = 55 J / 4.5 m = 12.2 J/m |
|||
``` |
|||
|
|||
**Part (b): Average ε** |
|||
|
|||
``` |
|||
ε_avg = (ε₁ + ε₂ + ε₃) / 3 |
|||
= (11.4 + 12.3 + 12.2) / 3 |
|||
= 12.0 J/m |
|||
|
|||
Recommended value: ε ≈ 12 J/m |
|||
``` |
|||
|
|||
**Part (c): Consistency assessment** |
|||
|
|||
``` |
|||
Standard deviation: σ ≈ 0.5 J/m |
|||
Coefficient of variation: CV = σ/μ = 0.5/12 = 4.2% |
|||
|
|||
Excellent consistency! (<5% variation) |
|||
``` |
|||
|
|||
**Interpretation:** |
|||
- ε is nearly constant across power range |
|||
- Coil is NOT voltage-limited in this range |
|||
- Pure power-limited growth (field threshold always met) |
|||
- Can confidently use ε = 12 J/m for predictions |
|||
|
|||
**If we saw large variation:** |
|||
``` |
|||
Example: ε₁ = 10 J/m, ε₂ = 15 J/m, ε₃ = 30 J/m |
|||
|
|||
This would indicate: |
|||
- Run 3 hitting voltage limit (inefficient growth) |
|||
- Possible mode transition (streamers vs leaders) |
|||
- Need to reassess model assumptions |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Predicting Performance Change |
|||
|
|||
**Given:** |
|||
- Current coil: Burst mode, ε = 65 J/m, E_bang = 80 J, L_typical = 1.2 m |
|||
- Proposed upgrade: Convert to QCW with ε = 12 J/m, same E_total = 80 J |
|||
|
|||
**Find:** |
|||
(a) Predicted length after QCW conversion |
|||
(b) Percentage improvement |
|||
(c) Required power for 10 ms ramp |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Predicted QCW length** |
|||
|
|||
``` |
|||
L_QCW = E_total / ε_QCW |
|||
= 80 J / 12 J/m |
|||
= 6.67 m |
|||
|
|||
Predicted length ≈ 6.7 m |
|||
``` |
|||
|
|||
**Part (b): Improvement** |
|||
|
|||
``` |
|||
Improvement = (L_QCW - L_burst) / L_burst × 100% |
|||
= (6.67 - 1.2) / 1.2 × 100% |
|||
= 456% increase in length! |
|||
|
|||
Or: 6.67/1.2 = 5.6× longer sparks |
|||
``` |
|||
|
|||
**Part (c): Required power** |
|||
|
|||
``` |
|||
For 10 ms ramp: |
|||
P_avg = E_total / T_ramp |
|||
= 80 J / 0.010 s |
|||
= 8,000 W |
|||
= 8 kW average |
|||
|
|||
Peak power higher (depends on waveform) |
|||
Typical: P_peak ≈ 1.5-2 × P_avg ≈ 12-16 kW |
|||
``` |
|||
|
|||
**Reality check:** |
|||
- 6.7 m prediction assumes NOT voltage-limited |
|||
- Actual length limited by topload voltage capability |
|||
- Still expect major improvement over burst mode |
|||
- Might achieve 3-4 m instead of 6.7 m (voltage limit) |
|||
|
|||
--- |
|||
|
|||
## Summary Table: ε by Operating Mode |
|||
|
|||
| Mode | ε Range [J/m] | Characteristics | Best For | |
|||
|------|---------------|-----------------|----------| |
|||
| **QCW** | 5-15 | Efficient leaders, long ramps | Maximum length | |
|||
| **DRSSTC Hybrid** | 20-40 | Mixed streamers/leaders | Balanced length & brightness | |
|||
| **Burst Mode** | 30-100+ | Bright streamers, short pulses | Visual spectacle, music | |
|||
| **Single-Shot** | 50-150+ | One-time discharge | Impulse testing, demonstrations | |
|||
|
|||
**Choosing operating mode:** |
|||
- **Goal: Length** → QCW (low ε) |
|||
- **Goal: Brightness** → Burst (high peak power) |
|||
- **Goal: Music/modulation** → Burst (rapid on/off) |
|||
- **Goal: Efficiency** → QCW (low ε, lower losses) |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **QCW: ε ≈ 5-15 J/m** - Most efficient, maintains hot channel |
|||
- **Hybrid DRSSTC: ε ≈ 20-40 J/m** - Moderate efficiency, mixed mechanisms |
|||
- **Burst mode: ε ≈ 30-100+ J/m** - Least efficient, repeated re-ionization |
|||
- **Calibration**: ε = E_delivered / L_measured from experimental runs |
|||
- **Consistency check**: ε should be approximately constant if power-limited |
|||
- **Thermal accumulation**: Advanced models use ε(t) decreasing with heating |
|||
- **Operating mode choice**: Trades off length efficiency vs brightness/aesthetics |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-04} |
|||
|
|||
**Problem 1:** A coil delivers 60 J in burst mode and produces 0.9 m sparks. Calculate ε. If converted to QCW with same energy, estimate new length assuming ε = 10 J/m. |
|||
|
|||
**Problem 2:** Calibration runs give: ε₁ = 14 J/m (25 J delivered), ε₂ = 13 J/m (40 J), ε₃ = 28 J/m (90 J). What does the sudden increase in ε₃ suggest? |
|||
|
|||
**Problem 3:** Explain why burst mode has higher ε than QCW despite delivering the same total energy. What happens to the "wasted" energy? |
|||
|
|||
--- |
|||
**Next Lesson:** [Thermal Memory Effects](05-thermal-memory.md) |
|||
@ -0,0 +1,460 @@ |
|||
--- |
|||
id: phys-05 |
|||
title: "Thermal Memory and Channel Persistence" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 40 |
|||
prerequisites: ["phys-03", "phys-04"] |
|||
objectives: |
|||
- Understand thermal diffusion time constants for plasma channels |
|||
- Calculate channel persistence times for different diameters |
|||
- Recognize the role of convection in extending channel lifetime |
|||
- Apply thermal memory concepts to QCW vs burst mode operation |
|||
tags: ["thermal-diffusion", "convection", "channel-persistence", "time-constants", "ionization-memory"] |
|||
--- |
|||
|
|||
# Thermal Memory and Channel Persistence |
|||
|
|||
Once formed, a plasma channel doesn't instantly disappear. It has **thermal memory** - the channel stays hot and partially ionized for some time after power is removed. Understanding these timescales is crucial for optimizing operating modes. |
|||
|
|||
## Temperature Regimes |
|||
|
|||
Plasma channels exist in different temperature regimes depending on current and power density: |
|||
|
|||
### Streamers (Cold Plasma) |
|||
|
|||
``` |
|||
Temperature: T ≈ 1000-3000 K |
|||
- Weakly ionized (few % ionization) |
|||
- Mostly neutral gas with some ions/electrons |
|||
- Purple/blue color (N₂ molecular emission) |
|||
- Low conductivity |
|||
``` |
|||
|
|||
### Leaders (Hot Plasma) |
|||
|
|||
``` |
|||
Temperature: T ≈ 5000-20,000 K |
|||
- Fully ionized plasma |
|||
- White/orange color (blackbody + line emission) |
|||
- High conductivity |
|||
- Approaching temperatures of stellar photospheres! |
|||
``` |
|||
|
|||
**Temperature comparison:** |
|||
- Room temperature: 300 K |
|||
- Candle flame: 1500 K |
|||
- Thin streamers: 1000-3000 K |
|||
- Thick leaders: 5000-20,000 K |
|||
- Sun's photosphere: 5800 K |
|||
|
|||
Leaders are literally as hot as the surface of the Sun! |
|||
|
|||
## Thermal Diffusion Time |
|||
|
|||
Heat diffuses radially outward from the hot channel core according to: |
|||
|
|||
``` |
|||
τ_thermal = d² / (4α_thermal) |
|||
|
|||
where: |
|||
d = channel diameter [m] |
|||
α_thermal ≈ 2×10⁻⁵ m²/s (thermal diffusivity of air) |
|||
``` |
|||
|
|||
**Physical meaning:** Time for heat to diffuse a distance d through air by conduction. |
|||
|
|||
### Examples for Different Channel Sizes |
|||
|
|||
**Thin streamer (d = 100 μm):** |
|||
|
|||
``` |
|||
τ = (100×10⁻⁶)² / (4 × 2×10⁻⁵) |
|||
= 10⁻⁸ m² / (8×10⁻⁵ m²/s) |
|||
= 1.25×10⁻⁴ s |
|||
= 0.125 ms |
|||
≈ 0.1-0.2 ms |
|||
``` |
|||
|
|||
**Medium channel (d = 2 mm):** |
|||
|
|||
``` |
|||
τ = (2×10⁻³)² / (4 × 2×10⁻⁵) |
|||
= 4×10⁻⁶ m² / (8×10⁻⁵ m²/s) |
|||
= 0.05 s |
|||
= 50 ms |
|||
``` |
|||
|
|||
**Thick leader (d = 5 mm):** |
|||
|
|||
``` |
|||
τ = (5×10⁻³)² / (4 × 2×10⁻⁵) |
|||
= 25×10⁻⁶ m² / (8×10⁻⁵ m²/s) |
|||
= 0.3125 s |
|||
= 312 ms |
|||
≈ 0.3-0.6 s |
|||
``` |
|||
|
|||
**Key insight:** Thermal diffusion time scales as d² - thicker channels persist much longer! |
|||
|
|||
## Why Observed Persistence is Longer |
|||
|
|||
Pure thermal diffusion predicts cooling in 0.1-300 ms, but channels persist longer due to additional effects: |
|||
|
|||
### 1. Convection (Buoyancy) |
|||
|
|||
Hot gas is less dense and rises: |
|||
|
|||
``` |
|||
Buoyancy velocity: v ≈ √(g × d × ΔT/T_amb) |
|||
|
|||
where: |
|||
g = 9.8 m/s² (gravity) |
|||
d = channel diameter |
|||
ΔT = temperature excess above ambient |
|||
T_amb = ambient temperature (≈300 K) |
|||
``` |
|||
|
|||
**Example: 2 mm channel at ΔT = 10,000 K** |
|||
|
|||
``` |
|||
v ≈ √(9.8 × 0.002 × 10000/300) |
|||
≈ √(9.8 × 0.002 × 33.3) |
|||
≈ √(0.653) |
|||
≈ 0.81 m/s |
|||
``` |
|||
|
|||
The hot channel rises at ~0.8 m/s, creating a continuously renewing hot column! |
|||
|
|||
**Effect on persistence:** |
|||
- Rising column remains coherent (doesn't diffuse sideways as fast) |
|||
- Maintains hot gas path for seconds |
|||
- Why Tesla coil sparks leave visible "smoke trails" |
|||
- Enhances thermal memory significantly |
|||
|
|||
### 2. Ionization Memory |
|||
|
|||
Even after thermal cooling begins, ions and electrons persist: |
|||
|
|||
``` |
|||
Recombination time: τ_recomb = 1/(α_recomb × n_e) |
|||
|
|||
where: |
|||
α_recomb ≈ 10⁻¹³ m³/s (recombination coefficient) |
|||
n_e = electron density [m⁻³] |
|||
|
|||
Typical: τ_recomb ≈ 10 μs to 10 ms |
|||
``` |
|||
|
|||
**Effect on persistence:** |
|||
- Channel remains partially ionized after cooling |
|||
- Lower resistance than cold air |
|||
- Easier to re-ionize than virgin air |
|||
- "Memory" of previous discharge path |
|||
|
|||
### 3. Broadened Effective Diameter |
|||
|
|||
Turbulence and mixing increase effective channel size: |
|||
|
|||
``` |
|||
d_effective > d_initial (due to turbulence) |
|||
|
|||
Larger diameter → longer τ_thermal |
|||
``` |
|||
|
|||
## Effective Persistence Times |
|||
|
|||
Combining all effects: |
|||
|
|||
**Thin streamers:** |
|||
``` |
|||
Pure thermal: ~0.1-0.2 ms |
|||
With convection: ~1-5 ms |
|||
Ionization memory: ~0.1-1 ms |
|||
Effective persistence: ~1-5 ms |
|||
``` |
|||
|
|||
**Thick leaders:** |
|||
``` |
|||
Pure thermal: ~50-300 ms |
|||
With convection: seconds (buoyant column maintained) |
|||
Ionization memory: ~1-10 ms |
|||
Effective persistence: seconds |
|||
``` |
|||
|
|||
**Visual evidence:** High-speed photography shows spark channels glowing and rising for seconds after power is removed. |
|||
|
|||
{image:spark-channel-persistence-sequence} |
|||
|
|||
## QCW Advantage |
|||
|
|||
QCW ramp times (5-20 ms) are designed to exploit channel persistence: |
|||
|
|||
### Timeline of QCW Growth |
|||
|
|||
``` |
|||
t = 0 ms: |
|||
- Initial streamers form from topload |
|||
- Thin, fast, purple channels |
|||
- Temperature: ~2000 K |
|||
|
|||
t = 0.5-1 ms: |
|||
- Current begins flowing through streamers |
|||
- Joule heating: P = I²R |
|||
- Temperature rising |
|||
|
|||
t = 1-2 ms: |
|||
- Channel heats to 5000+ K |
|||
- Thermal ionization becomes dominant |
|||
- Leader formation begins at base |
|||
|
|||
t = 2-5 ms: |
|||
- Leader established and growing |
|||
- Hot channel maintained by continuous power |
|||
- New growth builds on existing ionization |
|||
- Temperature: 10,000-20,000 K |
|||
|
|||
t = 5-20 ms: |
|||
- Leader continues extending |
|||
- Persistence time >> growth time |
|||
- Channel stays hot entire duration |
|||
- Efficient energy use: no re-ionization needed |
|||
|
|||
t > 20 ms (after ramp ends): |
|||
- Power removed |
|||
- Channel begins cooling |
|||
- Buoyancy carries hot gas upward |
|||
- Visible glow for seconds |
|||
``` |
|||
|
|||
**Key advantage:** The ramp duration (5-20 ms) is shorter than thermal diffusion time (50+ ms for leaders), so the channel NEVER cools during growth! |
|||
|
|||
### Energy Efficiency Mechanism |
|||
|
|||
**QCW flow:** |
|||
``` |
|||
Energy → Initial ionization (startup cost) |
|||
→ Heating to leader temperature |
|||
→ Maintaining hot channel (low cost) |
|||
→ Extending length (efficient) |
|||
|
|||
Result: Most energy after startup goes into extension |
|||
ε_QCW ≈ 5-15 J/m (low, efficient) |
|||
``` |
|||
|
|||
## Burst Mode Problem |
|||
|
|||
Burst mode pulses are short (50-500 μs) with long gaps (ms): |
|||
|
|||
### Timeline of Burst Mode |
|||
|
|||
``` |
|||
t = 0 μs: |
|||
- High voltage, cold air |
|||
- Streamer inception |
|||
|
|||
t = 0-100 μs: |
|||
- First pulse (high peak power) |
|||
- Bright streamers form |
|||
- Some heating but limited |
|||
- Temperature reaches ~3000-5000 K |
|||
|
|||
t = 100 μs (pulse ends): |
|||
- Power removed |
|||
- Channel begins cooling immediately |
|||
- Thermal diffusion time ~0.1-0.5 ms for thin channels |
|||
|
|||
t = 0.1-1 ms: |
|||
- Channel cools significantly |
|||
- Temperature drops to ~1000 K |
|||
- Ionization recombines |
|||
- Channel approaching cold air |
|||
|
|||
t = 1-10 ms (between pulses): |
|||
- Next pulse arrives |
|||
- Must re-ionize mostly cold gas |
|||
- Energy wasted on re-heating |
|||
- Little thermal memory remains |
|||
|
|||
Result: Each pulse restarts from nearly cold conditions! |
|||
``` |
|||
|
|||
**Energy inefficiency mechanism:** |
|||
|
|||
``` |
|||
Energy → Initial ionization (EVERY pulse) |
|||
→ Heating (REPEATED) |
|||
→ Brief brightening |
|||
→ Cooling (wasted) |
|||
→ Re-ionization overhead (high) |
|||
|
|||
Result: Energy into repeated startup, not cumulative growth |
|||
ε_burst ≈ 30-100+ J/m (high, inefficient) |
|||
``` |
|||
|
|||
### Analogy: Boiling Water |
|||
|
|||
**QCW (efficient):** |
|||
``` |
|||
Turn stove on and keep it on |
|||
Water heats up once |
|||
Maintain boiling continuously |
|||
Minimal energy to sustain |
|||
``` |
|||
|
|||
**Burst (inefficient):** |
|||
``` |
|||
Pulse stove on/off rapidly |
|||
Water heats briefly |
|||
Water cools between pulses |
|||
Must reheat repeatedly |
|||
High energy for little sustained boiling |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Thermal Time Constants |
|||
|
|||
**Given:** |
|||
- Channel diameter: d = 2 mm (typical leader) |
|||
- Air thermal diffusivity: α = 2×10⁻⁵ m²/s |
|||
- Temperature excess: ΔT = 8000 K |
|||
- Ambient temperature: T_amb = 300 K |
|||
|
|||
**Find:** |
|||
(a) Pure thermal diffusion time |
|||
(b) Convection velocity |
|||
(c) QCW ramp time recommendation |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Thermal diffusion time** |
|||
|
|||
``` |
|||
τ_thermal = d² / (4α) |
|||
= (2×10⁻³)² / (4 × 2×10⁻⁵) |
|||
= 4×10⁻⁶ m² / (8×10⁻⁵ m²/s) |
|||
= 0.05 s |
|||
= 50 ms |
|||
``` |
|||
|
|||
**Part (b): Convection velocity** |
|||
|
|||
``` |
|||
v ≈ √(g × d × ΔT/T_amb) |
|||
≈ √(9.8 × 0.002 × 8000/300) |
|||
≈ √(9.8 × 0.002 × 26.67) |
|||
≈ √(0.523) |
|||
≈ 0.72 m/s |
|||
``` |
|||
|
|||
Upward velocity of ~0.7 m/s helps maintain hot column. |
|||
|
|||
**Part (c): QCW ramp recommendation** |
|||
|
|||
``` |
|||
τ_thermal = 50 ms |
|||
|
|||
For efficient QCW operation: |
|||
T_ramp << τ_thermal (finish before significant cooling) |
|||
|
|||
Recommended: T_ramp = 0.1 × τ to 0.4 × τ |
|||
= 5-20 ms |
|||
|
|||
Sweet spot: ~10 ms (20% of τ_thermal) |
|||
``` |
|||
|
|||
**Reasoning:** |
|||
- If T_ramp >> τ_thermal (e.g., 200 ms): |
|||
- Channel cools during ramp |
|||
- Must reheat repeatedly |
|||
- Loses QCW efficiency advantage |
|||
|
|||
- If T_ramp << τ_thermal (e.g., 1 ms): |
|||
- May not form thick leaders |
|||
- Closer to burst behavior |
|||
- Doesn't exploit full persistence |
|||
|
|||
- Optimal: T_ramp ≈ 10-20 ms |
|||
- Channel stays hot throughout |
|||
- Leaders form and persist |
|||
- Maximum efficiency |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Burst vs QCW Timing |
|||
|
|||
**Given:** |
|||
- Burst pulse: 200 μs every 5 ms (5 ms period) |
|||
- QCW ramp: 15 ms continuous |
|||
- Both use same average power |
|||
|
|||
**Find:** |
|||
(a) Why burst is inefficient for thin channels (d = 100 μm) |
|||
(b) Why QCW is efficient for thick channels (d = 3 mm) |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Burst with thin streamers** |
|||
|
|||
``` |
|||
Channel diameter: d = 100 μm |
|||
Thermal time: τ = (100×10⁻⁶)² / (8×10⁻⁵) = 0.125 ms |
|||
|
|||
Timeline: |
|||
t = 0: Pulse starts, channel forms |
|||
t = 200 μs: Pulse ends (0.2 ms) |
|||
Channel cooling for: 0.125 ms ≈ τ/1 |
|||
t = 5 ms: Next pulse |
|||
Channel has cooled for: 5 ms = 40 × τ |
|||
COMPLETELY COLD |
|||
|
|||
Result: Each pulse re-ionizes from scratch |
|||
High ε (inefficient) |
|||
``` |
|||
|
|||
**Part (b): QCW with thick leaders** |
|||
|
|||
``` |
|||
Channel diameter: d = 3 mm |
|||
Thermal time: τ = (3×10⁻³)² / (8×10⁻⁵) = 112 ms |
|||
|
|||
Timeline: |
|||
t = 0: Ramp starts, initial streamers |
|||
t = 2 ms: Heating → leader formation begins |
|||
t = 5 ms: Leader well-established (hot) |
|||
t = 15 ms: Ramp ends |
|||
Total time elapsed: 15 ms = 0.13 × τ |
|||
|
|||
Cooling fraction: exp(-15/112) ≈ exp(-0.13) ≈ 0.88 |
|||
|
|||
Result: Channel stays at 88% of peak temperature! |
|||
Leader persists throughout ramp |
|||
Low ε (efficient) |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Thermal diffusion time**: τ = d²/(4α), scales quadratically with diameter |
|||
- **Thin streamers**: τ ≈ 0.1-0.2 ms (fast cooling) |
|||
- **Thick leaders**: τ ≈ 50-600 ms (slow cooling) |
|||
- **Convection**: Hot gas rises at ~0.5-1 m/s, maintains hot column for seconds |
|||
- **Ionization memory**: Partial ionization persists 0.1-10 ms after thermal cooling |
|||
- **Effective persistence**: 1-5 ms for streamers, seconds for leaders |
|||
- **QCW advantage**: Ramp time (5-20 ms) << leader thermal time (~50+ ms) |
|||
- **Burst problem**: Gap between pulses (ms) >> streamer thermal time (~0.1 ms) |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-05} |
|||
|
|||
**Problem 1:** A streamer has d = 150 μm. Calculate τ_thermal. If burst pulse width is 500 μs with 10 ms between pulses, does the channel cool significantly? |
|||
|
|||
**Problem 2:** Why do thick leaders persist longer than thin streamers? Give two physical reasons with approximate timescales. |
|||
|
|||
**Problem 3:** A QCW coil uses 25 ms ramps. For a 3 mm diameter leader (τ ≈ 100 ms), estimate the fraction of peak temperature remaining at end of ramp (use exponential cooling approximation). |
|||
|
|||
--- |
|||
**Next Lesson:** [Streamers vs Leaders](06-streamers-vs-leaders.md) |
|||
@ -0,0 +1,441 @@ |
|||
--- |
|||
id: phys-06 |
|||
title: "Streamers vs Leaders: Transition Sequence" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 45 |
|||
prerequisites: ["phys-05"] |
|||
objectives: |
|||
- Distinguish between streamer and leader discharge mechanisms |
|||
- Understand the 6-step streamer-to-leader transition sequence |
|||
- Recognize the efficiency differences between streamer and leader growth |
|||
- Apply this knowledge to optimize coil operating modes |
|||
tags: ["streamers", "leaders", "photoionization", "thermal-ionization", "transition", "mechanisms"] |
|||
--- |
|||
|
|||
# Streamers vs Leaders: Transition Sequence |
|||
|
|||
Not all sparks are created equal. Two fundamentally different propagation mechanisms exist: **streamers** and **leaders**. Understanding the differences and transition between them is crucial for optimizing Tesla coil performance. |
|||
|
|||
## Streamer Characteristics |
|||
|
|||
**Streamers** are thin, fast, cold plasma channels: |
|||
|
|||
### Physical Properties |
|||
|
|||
``` |
|||
Diameter: 10-100 μm (thinner than human hair) |
|||
Velocity: ~10⁶ m/s (1% speed of light!) |
|||
Temperature: 1000-3000 K (weakly ionized) |
|||
Current: mA to tens of mA (low) |
|||
Resistance: MΩ range (high) |
|||
Thermal time: ~0.1-0.2 ms (fast cooling) |
|||
``` |
|||
|
|||
### Propagation Mechanism: Photoionization |
|||
|
|||
**How streamers propagate:** |
|||
|
|||
1. **Electric field accelerates electrons** in partially ionized tip region |
|||
2. **Energetic electrons collide** with neutral molecules, creating excited states |
|||
3. **Excited molecules emit UV photons** (de-excitation radiation) |
|||
4. **UV photons travel ahead** of the streamer tip (speed of light) |
|||
5. **UV ionizes neutral air ahead** (photoelectric effect), creating seed electrons |
|||
6. **Seed electrons avalanche** in high field at tip |
|||
7. **New ionized region forms** ahead of previous tip |
|||
8. **Process repeats** → rapid propagation |
|||
|
|||
**Key insight:** Propagation driven by photons (electromagnetic radiation), not thermal effects. This is why streamers are FAST - limited only by ionization avalanche time, not thermal diffusion. |
|||
|
|||
### Visual Appearance |
|||
|
|||
``` |
|||
Color: Purple/blue (N₂ molecular emission lines) |
|||
Structure: Highly branched, tree-like |
|||
Persistence: Brief flashes (<1 ms visible) |
|||
Brightness: Moderate (low current) |
|||
Pattern: Random, fractal-like branching |
|||
``` |
|||
|
|||
### Energy Efficiency |
|||
|
|||
``` |
|||
ε_streamer ≈ 50-150+ J/m (high, inefficient) |
|||
|
|||
Energy distribution: |
|||
- Ionization: ~1% |
|||
- Radiation (UV, visible): ~30-50% |
|||
- Heating: ~20-40% |
|||
- Branching losses: ~20-40% |
|||
- Extension: ~5-10% (poor efficiency!) |
|||
``` |
|||
|
|||
**Why inefficient?** |
|||
- Energy dumped into radiation (bright UV and visible light) |
|||
- Massive branching (many failed paths) |
|||
- Low current → high resistance → voltage drop limits length |
|||
- No thermal memory between events |
|||
|
|||
## Leader Characteristics |
|||
|
|||
**Leaders** are thick, slower, hot plasma channels: |
|||
|
|||
### Physical Properties |
|||
|
|||
``` |
|||
Diameter: 1-10 mm (visible as bright core) |
|||
Velocity: ~10³ m/s (walking speed to car speed) |
|||
Temperature: 5000-20,000 K (fully ionized) |
|||
Current: 100 mA to several A (high) |
|||
Resistance: kΩ range (low) |
|||
Thermal time: ~50-600 ms (slow cooling) |
|||
``` |
|||
|
|||
### Propagation Mechanism: Thermal Ionization |
|||
|
|||
**How leaders propagate:** |
|||
|
|||
1. **High current flows** through existing channel |
|||
2. **Joule heating** (I²R) raises channel temperature |
|||
3. **Thermal ionization** occurs as temperature exceeds ~5000 K |
|||
- Collisional ionization from thermal energy |
|||
- Lower resistance as more ions/electrons created |
|||
4. **Hot channel tip** heats adjacent air by conduction/radiation |
|||
5. **Adjacent air ionizes** thermally |
|||
6. **Leader extends** into newly ionized region |
|||
7. **Process repeats** → steady growth |
|||
|
|||
**Key insight:** Propagation driven by heat transfer (thermal effects), much slower than photoionization. But more efficient energy use - heat stays in channel. |
|||
|
|||
### Visual Appearance |
|||
|
|||
``` |
|||
Color: White/orange (blackbody + line emission) |
|||
Structure: Straighter, fewer branches |
|||
Persistence: Seconds with sustained power (or buoyant rise) |
|||
Brightness: Very bright (high current) |
|||
Pattern: More directed, follows field lines |
|||
``` |
|||
|
|||
### Energy Efficiency |
|||
|
|||
``` |
|||
ε_leader ≈ 5-20 J/m (low, efficient) |
|||
|
|||
Energy distribution: |
|||
- Ionization: ~5-10% |
|||
- Heating to operating T: ~30-50% |
|||
- Extension work: ~20-40% |
|||
- Radiation: ~10-20% |
|||
- Branching: ~5-10% (minimal) |
|||
``` |
|||
|
|||
**Why efficient?** |
|||
- Heat stays in channel (thermal memory) |
|||
- High current → low resistance → efficient power transfer |
|||
- Straighter path (less branching waste) |
|||
- Thermal ionization more efficient than repeated photoionization |
|||
- Energy accumulates in single hot channel |
|||
|
|||
## Comparison Table |
|||
|
|||
| Property | Streamers | Leaders | |
|||
|----------|-----------|---------| |
|||
| **Diameter** | 10-100 μm | 1-10 mm | |
|||
| **Velocity** | ~10⁶ m/s | ~10³ m/s | |
|||
| **Temperature** | 1000-3000 K | 5000-20,000 K | |
|||
| **Current** | mA | 100 mA - A | |
|||
| **Resistance** | MΩ | kΩ | |
|||
| **Color** | Purple/blue | White/orange | |
|||
| **Branching** | Highly branched | Straighter | |
|||
| **Persistence** | <1 ms | Seconds | |
|||
| **Mechanism** | Photoionization | Thermal ionization | |
|||
| **ε (J/m)** | 50-150+ | 5-20 | |
|||
| **Efficiency** | Poor | Good | |
|||
|
|||
## The 6-Step Transition Sequence |
|||
|
|||
Streamers can transition to leaders if sufficient current and time are provided: |
|||
|
|||
### Step 1: High E-Field Creates Initial Streamers |
|||
|
|||
``` |
|||
t = 0 μs |
|||
- High voltage applied to topload |
|||
- E_tip exceeds E_inception (~2-3 MV/m) |
|||
- Photoionization avalanche begins |
|||
- Multiple thin streamers form from topload |
|||
- Characteristics: Fast, purple, branched |
|||
- Temperature: ~2000 K |
|||
- Current: mA per streamer |
|||
``` |
|||
|
|||
### Step 2: Sufficient Current Flows → Joule Heating |
|||
|
|||
``` |
|||
t = 10-100 μs |
|||
- Circuit provides sustained current (not just brief discharge) |
|||
- Current concentrates in one or few dominant streamers |
|||
- Joule heating: P = I²R |
|||
- Channel temperature begins rising |
|||
- Temperature: 2000 → 3000 K |
|||
- Resistance begins decreasing |
|||
``` |
|||
|
|||
### Step 3: Heated Channel → Thermal Ionization Begins |
|||
|
|||
``` |
|||
t = 100 μs - 1 ms |
|||
- Temperature reaches ~5000 K (thermal ionization threshold) |
|||
- Collisional ionization adds to photoionization |
|||
- Ionization density increases dramatically |
|||
- Resistance drops further → more current → more heating |
|||
- Positive feedback loop: heat → ionization → conductivity → current → heat |
|||
- Temperature: 3000 → 8000 K |
|||
- Current increasing to 100+ mA |
|||
``` |
|||
|
|||
### Step 4: Leader Forms from Base |
|||
|
|||
``` |
|||
t = 1-3 ms |
|||
- Hottest region (base, near topload) becomes fully ionized |
|||
- True leader channel established at base |
|||
- Leader characteristics appear: thick, white, hot |
|||
- Temperature: 8000 → 15,000 K at base |
|||
- Current: several 100 mA |
|||
- Diameter expands to ~1-3 mm |
|||
``` |
|||
|
|||
**Critical insight:** Leader forms **from base** (topload) and grows **downward**, not from tip! |
|||
|
|||
### Step 5: Leader Tip Launches New Streamers |
|||
|
|||
``` |
|||
t = 3-10 ms |
|||
- Hot leader base established |
|||
- Leader tip (interface) still has high E-field |
|||
- Tip launches new streamers ahead (photoionization) |
|||
- Streamers probe forward, find path |
|||
- Temperature gradient: 15,000 K (base) → 5000 K (tip) → 2000 K (streamers) |
|||
``` |
|||
|
|||
### Step 6: Fed Streamers Convert to Leader |
|||
|
|||
``` |
|||
t = 5-20 ms (continuous process) |
|||
- Current flows through newly formed streamers |
|||
- Streamers heat up → thermal ionization |
|||
- Hot leader channel "catches up" to streamer paths |
|||
- Leader extends forward |
|||
- Process repeats: tip launches streamers → streamers heat → leader extends |
|||
- Continuous growth cycle |
|||
|
|||
Final state: |
|||
- Main channel: hot leader (white, thick, efficient) |
|||
- Active tip: transition zone with streamers |
|||
- Failed branches: cool streamers (purple, thin) |
|||
``` |
|||
|
|||
{image:streamer-to-leader-transition-sequence} |
|||
|
|||
## Why This Transition Matters |
|||
|
|||
### For QCW Coils (Designed for Leader Formation) |
|||
|
|||
``` |
|||
Timeline optimized for transition: |
|||
t = 0-1 ms: Streamer inception |
|||
t = 1-5 ms: Transition to leader |
|||
t = 5-20 ms: Leader growth dominates |
|||
Result: Low ε (5-15 J/m), long sparks |
|||
``` |
|||
|
|||
**QCW design requirements:** |
|||
- Sustained current capability (not just brief pulse) |
|||
- Moderate ramp time (5-20 ms allows transition) |
|||
- Adequate voltage maintenance |
|||
- Result: Efficient leader formation |
|||
|
|||
### For Burst Mode (Mostly Streamers) |
|||
|
|||
``` |
|||
Timeline too short for transition: |
|||
t = 0-50 μs: Streamer inception |
|||
t = 50-200 μs: Brief heating begins |
|||
t = 200 μs: Pulse ends (typical) |
|||
t = 200 μs - 5 ms: Cooling (no power) |
|||
Result: High ε (30-100+ J/m), short bright sparks |
|||
``` |
|||
|
|||
**Burst mode characteristics:** |
|||
- High peak power creates bright streamers |
|||
- Pulse too short for full leader transition |
|||
- Channel cools between pulses |
|||
- Next pulse restarts from streamers |
|||
- Result: Spectacular but inefficient |
|||
|
|||
### Hybrid Modes (Mixed Behavior) |
|||
|
|||
``` |
|||
Timeline allows partial transition: |
|||
t = 0-0.5 ms: Streamers |
|||
t = 0.5-2 ms: Partial leader formation at base |
|||
t = 2-5 ms: Mixed streamer/leader growth |
|||
Result: Moderate ε (20-40 J/m), balanced performance |
|||
``` |
|||
|
|||
## Physical Intuition: The "Thermal Runway" |
|||
|
|||
Think of the transition as climbing a thermal runway: |
|||
|
|||
**Altitude (Temperature) vs Time:** |
|||
|
|||
``` |
|||
0 K ▬▬▬▬▬ Ground (cold air, insulator) |
|||
|
|||
2000 K ━━━━━ Streamer plateau (photoionization) |
|||
▲ |
|||
│ Need sustained current to climb |
|||
│ |
|||
5000 K ━━━━━ Leader threshold (thermal ionization begins) |
|||
▲ |
|||
│ Positive feedback: easier to climb |
|||
│ |
|||
15000 K ━━━━━ Fully developed leader |
|||
|
|||
Time → |
|||
``` |
|||
|
|||
**Burst mode:** Brief rocket boost (high power) gets to 2000 K, but fuel runs out (pulse ends) before reaching 5000 K. Falls back to ground. |
|||
|
|||
**QCW mode:** Sustained climb (continuous power) reaches 5000 K and beyond. Once at leader plateau, stays there efficiently. |
|||
|
|||
## Practical Observations |
|||
|
|||
### High-Speed Photography Evidence |
|||
|
|||
Time-resolved imaging shows: |
|||
|
|||
**0-100 μs:** |
|||
- Multiple thin purple streamers from topload |
|||
- Branching, exploring paths |
|||
- No thick core visible |
|||
|
|||
**1-3 ms:** |
|||
- White glow appearing near topload |
|||
- Base region brightening |
|||
- Purple streamers still at extremities |
|||
|
|||
**5-20 ms:** |
|||
- Thick white core from topload partway down |
|||
- Purple streamers at tip only |
|||
- Clear leader/streamer boundary |
|||
|
|||
**After power off:** |
|||
- White leader core persists (seconds, rising) |
|||
- Purple streamers disappear immediately |
|||
|
|||
{image:high-speed-photography-leader-formation} |
|||
|
|||
### Energy Measurements |
|||
|
|||
Direct calorimetry and electrical measurements confirm: |
|||
|
|||
``` |
|||
Same total energy (100 J): |
|||
|
|||
Burst mode: 100 J → 1.2 m spark |
|||
ε ≈ 83 J/m |
|||
Mostly streamers |
|||
|
|||
QCW mode: 100 J → 8 m spark |
|||
ε ≈ 12.5 J/m |
|||
Mostly leaders |
|||
|
|||
Ratio: 6.7× better length efficiency for leaders! |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Estimating Transition Time |
|||
|
|||
**Given:** |
|||
- Initial streamer resistance: R₀ = 10 MΩ |
|||
- Initial current: I₀ = 20 mA (from voltage source) |
|||
- Power deposition: P = I²R = (0.02)² × 10×10⁶ = 4000 W |
|||
- Channel mass per meter: m ≈ 0.001 kg/m (100 μm diameter, 1 m long) |
|||
- Heat capacity of air: c_p ≈ 1000 J/(kg·K) |
|||
- Target temperature for leader: T_leader = 5000 K (from T_amb = 300 K) |
|||
|
|||
**Find:** Estimated heating time to leader threshold (simplified model) |
|||
|
|||
### Solution |
|||
|
|||
``` |
|||
Energy required to heat channel: |
|||
Q = m × c_p × ΔT |
|||
= 0.001 kg/m × 1000 J/(kg·K) × (5000 - 300) K |
|||
= 1 kg·J/(kg·K) × 4700 K |
|||
= 4700 J per meter |
|||
|
|||
Time to deliver this energy: |
|||
t = Q / P |
|||
= 4700 J/m / 4000 W |
|||
= 1.175 s per meter (!) |
|||
``` |
|||
|
|||
**Wait, this seems too long!** What's wrong? |
|||
|
|||
**Reality check - positive feedback:** |
|||
1. As temperature rises, resistance drops |
|||
2. Lower resistance → more current (V = I×R, fixed V) |
|||
3. More current → more heating (P = I²R) |
|||
4. Exponential growth, not linear! |
|||
|
|||
**Improved estimate with feedback:** |
|||
|
|||
``` |
|||
R(T) ≈ R₀ × (T₀/T)^2 (approximate scaling) |
|||
|
|||
At T = 5000 K: |
|||
R ≈ 10 MΩ × (300/5000)² ≈ 36 kΩ (250× reduction!) |
|||
|
|||
Current increases dramatically: |
|||
I ≈ 20 mA × √(10 MΩ / 36 kΩ) ≈ 330 mA |
|||
|
|||
Power increases: |
|||
P ≈ (330 mA)² × 36 kΩ ≈ 3,920 W (similar, but delivered more efficiently) |
|||
|
|||
More realistic time (accounting for exponential feedback): |
|||
t_transition ≈ 1-5 ms (observed in experiments) |
|||
``` |
|||
|
|||
**Key insight:** Positive feedback accelerates the transition once started. This is why leaders form "explosively" after threshold. |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Streamers**: Thin (10-100 μm), fast (~10⁶ m/s), cold (1000-3000 K), photoionization-driven, high ε (50-150 J/m) |
|||
- **Leaders**: Thick (1-10 mm), slower (~10³ m/s), hot (5000-20000 K), thermal-ionization-driven, low ε (5-20 J/m) |
|||
- **6-step transition**: High E-field → current flows → Joule heating → thermal ionization → leader forms from base → tip launches streamers → fed streamers convert |
|||
- **Leader formation requires**: Sustained current (not brief pulse) + adequate time (ms range) + sufficient voltage maintenance |
|||
- **QCW optimized**: 5-20 ms ramps allow full leader development, ε ≈ 5-15 J/m |
|||
- **Burst mode limitation**: <500 μs pulses too short for leader transition, ε ≈ 30-100+ J/m |
|||
- **Efficiency difference**: Leaders ~6-10× more efficient than streamers for length extension |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-06} |
|||
|
|||
**Problem 1:** Explain why streamers propagate faster than leaders despite being at lower temperature. What fundamental mechanisms are different? |
|||
|
|||
**Problem 2:** A coil produces 2 m sparks in burst mode (ε = 70 J/m). If converted to QCW with ε = 12 J/m and same total energy, estimate the new spark length. What physical transition enables this improvement? |
|||
|
|||
**Problem 3:** In the 6-step transition sequence, why does the leader form from the base (topload) first, rather than from the tip? Consider where current density and heating are highest. |
|||
|
|||
**Problem 4:** High-speed photography shows purple streamers at t = 0.1 ms, then white glow at base by t = 2 ms, then white core extending by t = 10 ms. Which step(s) of the transition correspond to each observation? |
|||
|
|||
--- |
|||
**Next Lesson:** [Capacitive Divider Problem](07-capacitive-divider.md) |
|||
@ -0,0 +1,471 @@ |
|||
--- |
|||
id: phys-07 |
|||
title: "The Capacitive Divider Problem" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "advanced" |
|||
estimated_time: 45 |
|||
prerequisites: ["fund-04", "fund-05", "phys-01", "phys-02"] |
|||
objectives: |
|||
- Understand how voltage divides between C_mut and C_sh |
|||
- Calculate V_tip as a function of spark length |
|||
- Recognize why tip voltage drops as spark grows |
|||
- Apply capacitive division to predict sub-linear scaling |
|||
tags: ["capacitive-divider", "voltage-division", "C_mut", "C_sh", "V_tip", "sub-linear"] |
|||
--- |
|||
|
|||
# The Capacitive Divider Problem |
|||
|
|||
A critical limitation affects all Tesla coils: as the spark grows longer, the voltage at the tip **decreases** even if topload voltage is maintained. This "capacitive divider effect" creates progressively harder conditions for continued growth. |
|||
|
|||
## Review: Spark Circuit Topology |
|||
|
|||
From Fundamentals, recall the spark circuit: |
|||
|
|||
``` |
|||
[C_mut] |
|||
Topload ----||---- Node_spark (spark base) |
|||
| |
|||
[R] |
|||
| |
|||
[C_sh] |
|||
| |
|||
GND |
|||
``` |
|||
|
|||
**Components:** |
|||
- **C_mut**: Mutual capacitance between topload and spark |
|||
- **C_sh**: Shunt capacitance from spark to ground |
|||
- **R**: Spark resistance (varies with ionization) |
|||
|
|||
**Key insight:** The spark sees a **voltage divider** between topload and ground! |
|||
|
|||
## Voltage Division Equation |
|||
|
|||
The general voltage divider with complex impedances: |
|||
|
|||
``` |
|||
V_tip = V_topload × Z_mut / (Z_mut + Z_sh) |
|||
|
|||
where: |
|||
Z_mut = (1/jωC_mut) || R (parallel combination of capacitance and resistance) |
|||
Z_sh = 1/(jωC_sh) (capacitive reactance) |
|||
``` |
|||
|
|||
**In complex form:** |
|||
|
|||
``` |
|||
Y_mut = jωC_mut + 1/R (admittance of parallel combination) |
|||
Z_mut = 1/Y_mut |
|||
|
|||
Y_sh = jωC_sh |
|||
Z_sh = 1/Y_sh |
|||
|
|||
V_tip = V_topload × Z_mut / (Z_mut + Z_sh) |
|||
``` |
|||
|
|||
This is complex-valued (magnitude and phase). |
|||
|
|||
## Open-Circuit Limit (No Current Flow) |
|||
|
|||
**Simplified case:** When R → ∞ (no conduction, purely capacitive): |
|||
|
|||
``` |
|||
V_tip = V_topload × C_mut / (C_mut + C_sh) |
|||
``` |
|||
|
|||
This is the **capacitive voltage divider** formula. |
|||
|
|||
**Physical interpretation:** |
|||
- Charges distribute between two capacitors in series |
|||
- Voltage splits proportionally to inverse capacitances |
|||
- As C_sh increases, V_tip decreases |
|||
|
|||
### The Problem: C_sh Grows with Length |
|||
|
|||
**Empirical relationship:** |
|||
|
|||
``` |
|||
C_sh ≈ 2 pF/foot × L_feet |
|||
|
|||
Or in SI units: |
|||
C_sh ≈ 6.6 pF/m × L_meters |
|||
``` |
|||
|
|||
**As spark grows:** |
|||
- Length L increases |
|||
- C_sh increases (proportional to length) |
|||
- Denominator (C_mut + C_sh) increases |
|||
- V_tip decreases! |
|||
|
|||
**This is self-limiting:** Longer sparks make it harder to grow even longer. |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Open-Circuit Voltage Division |
|||
|
|||
**Given:** |
|||
- V_topload = 400 kV (constant, maintained by primary) |
|||
- C_mut = 8 pF (approximately constant) |
|||
- Spark grows from 1 ft to 6 ft |
|||
|
|||
**Find:** V_tip at L = 1, 2, 3, 4, 5, 6 feet |
|||
|
|||
### Solution |
|||
|
|||
**At L = 1 ft:** |
|||
|
|||
``` |
|||
C_sh = 2 pF/ft × 1 ft = 2 pF |
|||
|
|||
V_tip = 400 kV × 8/(8+2) |
|||
= 400 kV × 8/10 |
|||
= 320 kV (80% of V_topload) |
|||
``` |
|||
|
|||
**At L = 2 ft:** |
|||
|
|||
``` |
|||
C_sh = 4 pF |
|||
|
|||
V_tip = 400 × 8/12 |
|||
= 267 kV (67%) |
|||
``` |
|||
|
|||
**At L = 3 ft:** |
|||
|
|||
``` |
|||
C_sh = 6 pF |
|||
|
|||
V_tip = 400 × 8/14 |
|||
= 229 kV (57%) |
|||
``` |
|||
|
|||
**At L = 4 ft:** |
|||
|
|||
``` |
|||
C_sh = 8 pF |
|||
|
|||
V_tip = 400 × 8/16 |
|||
= 200 kV (50%) |
|||
``` |
|||
|
|||
**At L = 5 ft:** |
|||
|
|||
``` |
|||
C_sh = 10 pF |
|||
|
|||
V_tip = 400 × 8/18 |
|||
= 178 kV (44%) |
|||
``` |
|||
|
|||
**At L = 6 ft:** |
|||
|
|||
``` |
|||
C_sh = 12 pF |
|||
|
|||
V_tip = 400 × 8/20 |
|||
= 160 kV (40%) |
|||
``` |
|||
|
|||
### Summary Table |
|||
|
|||
| Length | C_sh | V_tip | % of V_top | E_avg (MV/m) | |
|||
|--------|------|-------|------------|--------------| |
|||
| 1 ft (0.3 m) | 2 pF | 320 kV | 80% | 1.07 | |
|||
| 2 ft (0.6 m) | 4 pF | 267 kV | 67% | 0.89 | |
|||
| 3 ft (0.9 m) | 6 pF | 229 kV | 57% | 0.76 | |
|||
| 4 ft (1.2 m) | 8 pF | 200 kV | 50% | 0.67 | |
|||
| 5 ft (1.5 m) | 10 pF | 178 kV | 44% | 0.59 | |
|||
| 6 ft (1.8 m) | 12 pF | 160 kV | 40% | 0.53 | |
|||
|
|||
**Observations:** |
|||
- V_tip drops to 40% of V_topload by 6 ft |
|||
- E_avg = V_tip/L decreases even faster |
|||
- Growth becomes progressively harder |
|||
|
|||
{image:voltage-division-vs-length-plot} |
|||
|
|||
--- |
|||
|
|||
## With Finite Resistance |
|||
|
|||
Real sparks have finite resistance R ≈ R_opt_power (from optimization): |
|||
|
|||
``` |
|||
R_opt_power ≈ 1/(ω(C_mut + C_sh)) |
|||
``` |
|||
|
|||
**Effect of finite R:** |
|||
|
|||
``` |
|||
Z_mut = R || (1/jωC_mut) |
|||
|
|||
For R ≈ R_opt: |
|||
Z_mut ≈ (1-j)/(2ωC_mut) (complex, 45° phase lag) |
|||
|
|||
V_tip magnitude is LOWER than open-circuit case |
|||
V_tip has phase shift relative to V_topload |
|||
``` |
|||
|
|||
**Result:** Voltage division is **worse** than the open-circuit case! |
|||
|
|||
### Detailed Calculation (Advanced) |
|||
|
|||
For R = R_opt_power = 1/(ω(C_mut + C_sh)): |
|||
|
|||
``` |
|||
Y_mut = jωC_mut + 1/R |
|||
= jωC_mut + ω(C_mut + C_sh) |
|||
= ω(C_mut + C_sh) + jωC_mut |
|||
|
|||
Z_mut = 1/Y_mut |
|||
= 1 / [ω(C_mut + C_sh)(1 + jC_mut/(C_mut + C_sh))] |
|||
|
|||
Z_sh = 1/(jωC_sh) |
|||
|
|||
Ratio: |
|||
V_tip/V_top = Z_mut/(Z_mut + Z_sh) |
|||
|
|||
After algebra (details omitted): |
|||
|V_tip/V_top| ≈ C_mut/(C_mut + C_sh) × (1/√2) |
|||
|
|||
Approximately 0.707× the open-circuit value! |
|||
``` |
|||
|
|||
**Practical conclusion:** With conduction current, voltage division is ~30% worse than capacitive-only case. |
|||
|
|||
## Impact on E_tip and Growth |
|||
|
|||
Recall the tip field: |
|||
|
|||
``` |
|||
E_tip = κ × V_tip / L |
|||
``` |
|||
|
|||
**As L increases:** |
|||
|
|||
**Numerator effect (voltage division):** |
|||
``` |
|||
V_tip ∝ C_mut / (C_mut + C_sh) |
|||
≈ C_mut / (C_mut + αL) (where α = 6.6 pF/m) |
|||
≈ 1 / (1 + αL/C_mut) |
|||
|
|||
For large L: V_tip ∝ 1/L |
|||
``` |
|||
|
|||
**Denominator effect (geometry):** |
|||
``` |
|||
Division by L |
|||
``` |
|||
|
|||
**Combined:** |
|||
``` |
|||
E_tip ∝ V_tip / L |
|||
∝ (1/L) / L |
|||
∝ 1/L² |
|||
|
|||
E_tip decreases as L²! |
|||
``` |
|||
|
|||
**This is devastating for long spark growth.** |
|||
|
|||
## Sub-Linear Scaling Prediction |
|||
|
|||
From the capacitive divider effect, we can predict scaling: |
|||
|
|||
**Growth stops when:** |
|||
``` |
|||
E_tip(L_max) = E_propagation |
|||
|
|||
κ × V_tip(L_max) / L_max = E_propagation |
|||
``` |
|||
|
|||
**Substituting voltage division:** |
|||
``` |
|||
κ × [V_topload × C_mut/(C_mut + αL_max)] / L_max = E_propagation |
|||
|
|||
Rearranging: |
|||
V_topload × C_mut / (C_mut + αL_max) = E_propagation × L_max / κ |
|||
|
|||
V_topload × C_mut = E_propagation × L_max × (C_mut + αL_max) / κ |
|||
``` |
|||
|
|||
**For large L (C_sh >> C_mut):** |
|||
``` |
|||
V_topload × C_mut ≈ E_propagation × L_max × αL_max / κ |
|||
|
|||
V_topload × C_mut ≈ (E_propagation × α / κ) × L_max² |
|||
|
|||
Solving for L_max: |
|||
L_max ∝ √(V_topload × C_mut) |
|||
∝ √(V_topload) (if C_mut approximately constant) |
|||
``` |
|||
|
|||
**Connection to energy:** |
|||
|
|||
If topload voltage is limited by breakdown, V_top ∝ √E (from capacitor energy): |
|||
``` |
|||
E_cap = ½ C_top V_top² |
|||
V_top ∝ √E |
|||
|
|||
Therefore: |
|||
L_max ∝ √V_top ∝ √(√E) ∝ E^(1/4) to E^(1/2) |
|||
|
|||
Approximately: L ∝ √E |
|||
``` |
|||
|
|||
**This explains Freau's empirical observation:** For burst mode (voltage-limited), spark length scales as square root of energy! |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Scaling Prediction |
|||
|
|||
**Given:** |
|||
- Coil A: V_top = 300 kV, produces L = 1.2 m spark |
|||
- Coil B: Same design, but V_top = 450 kV (1.5× voltage) |
|||
|
|||
**Find:** Predicted length for Coil B using: |
|||
(a) Linear scaling (naive) |
|||
(b) Sub-linear scaling (capacitive divider) |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): Linear scaling (incorrect)** |
|||
|
|||
``` |
|||
If L ∝ V: |
|||
L_B = L_A × (V_B/V_A) |
|||
= 1.2 m × (450/300) |
|||
= 1.2 m × 1.5 |
|||
= 1.8 m |
|||
``` |
|||
|
|||
**Part (b): Sub-linear scaling (more realistic)** |
|||
|
|||
``` |
|||
If L ∝ √V (from capacitive divider): |
|||
L_B = L_A × √(V_B/V_A) |
|||
= 1.2 m × √(450/300) |
|||
= 1.2 m × √1.5 |
|||
= 1.2 m × 1.225 |
|||
= 1.47 m |
|||
|
|||
Only 1.47 m instead of 1.8 m! |
|||
``` |
|||
|
|||
**Actual measurements typically show:** L_B ≈ 1.4-1.5 m, confirming sub-linear scaling. |
|||
|
|||
**Percentage improvement:** |
|||
- Linear prediction: 50% longer (wrong) |
|||
- Sub-linear prediction: 23% longer (correct) |
|||
- Capacitive divider limits gains from higher voltage |
|||
|
|||
--- |
|||
|
|||
## Mitigation Strategies |
|||
|
|||
How can we fight the capacitive divider effect? |
|||
|
|||
### 1. Increase C_mut |
|||
|
|||
**Larger topload:** |
|||
``` |
|||
C_top increases → C_mut increases |
|||
→ C_mut/(C_mut + C_sh) ratio improves |
|||
→ Better V_tip retention |
|||
``` |
|||
|
|||
**Effect:** |
|||
- Diminishes relative impact of C_sh |
|||
- Requires larger topload (practical limits) |
|||
|
|||
### 2. Active Voltage Ramping (QCW) |
|||
|
|||
**Strategy:** |
|||
``` |
|||
Ramp V_topload upward as spark grows |
|||
Compensate for voltage division |
|||
Maintain E_tip above threshold longer |
|||
``` |
|||
|
|||
**This is the QCW advantage:** |
|||
- Not fighting capacitive divider directly |
|||
- But actively increasing numerator (V_topload) |
|||
- Allows longer sparks than fixed voltage |
|||
|
|||
### 3. Reduce C_sh (Limited Options) |
|||
|
|||
**Physical constraints:** |
|||
- C_sh ∝ L (fundamental geometry) |
|||
- Cannot eliminate |
|||
- Thin spark slightly better (smaller cross-section) |
|||
- But thermal/ionization requirements limit how thin |
|||
|
|||
### 4. Accept the Limitation |
|||
|
|||
**Reality:** |
|||
- Capacitive divider is fundamental |
|||
- Cannot be eliminated |
|||
- Design around it (optimize topload, use QCW ramping) |
|||
- Accept sub-linear scaling |
|||
|
|||
--- |
|||
|
|||
## Comparison: QCW vs Burst Mode |
|||
|
|||
### Burst Mode (Fixed Voltage) |
|||
|
|||
``` |
|||
V_topload = constant (capacitor discharge) |
|||
|
|||
As spark grows: |
|||
- V_tip decreases (capacitive divider) |
|||
- E_tip decreases rapidly |
|||
- Growth stalls at voltage limit |
|||
- L ∝ √E scaling dominates |
|||
``` |
|||
|
|||
### QCW Mode (Ramped Voltage) |
|||
|
|||
``` |
|||
V_topload(t) increases with time |
|||
|
|||
As spark grows: |
|||
- V_tip still affected by divider |
|||
- But V_topload increasing compensates partially |
|||
- Can maintain E_tip > E_propagation longer |
|||
- Better scaling: L ∝ E^0.6 to E^0.8 |
|||
``` |
|||
|
|||
**QCW doesn't eliminate the divider, but actively fights it!** |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Voltage divider**: V_tip = V_topload × C_mut/(C_mut + C_sh) |
|||
- **C_sh grows with length**: C_sh ≈ 6.6 pF/m × L, making growth self-limiting |
|||
- **V_tip drops dramatically**: Can reach 40% of V_topload by 6 ft |
|||
- **E_tip ∝ 1/L²**: Combined effect of voltage division and geometric scaling |
|||
- **Sub-linear scaling**: L ∝ √E for voltage-limited burst mode (Freau's observation) |
|||
- **Finite R worsens effect**: Conduction current creates additional voltage drop |
|||
- **QCW mitigation**: Active voltage ramping compensates for divider effect |
|||
- **Fundamental limit**: Cannot be eliminated, only managed through design |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-07} |
|||
|
|||
**Problem 1:** V_top = 350 kV, C_mut = 10 pF. Calculate V_tip for: |
|||
(a) L = 1 ft (C_sh = 2 pF) |
|||
(b) L = 5 ft (C_sh = 10 pF) |
|||
What percentage of voltage is lost? |
|||
|
|||
**Problem 2:** A spark needs E_propagation = 0.6 MV/m and κ = 3 to grow. For a 2 m spark, calculate the required V_tip. Then, if C_mut = 8 pF and C_sh = 13 pF (for 2 m), what V_topload is needed? |
|||
|
|||
**Problem 3:** Explain why spark length scales as L ∝ √E for voltage-limited burst mode. Connect this to the capacitive divider effect and the E_tip ∝ 1/L² relationship. |
|||
|
|||
**Problem 4:** Two coils: Coil A has C_mut = 6 pF, Coil B has C_mut = 12 pF (larger topload). Both operate at V_top = 400 kV and grow 1.5 m sparks. Calculate V_tip for each. Which suffers less from voltage division? |
|||
|
|||
--- |
|||
**Next Lesson:** [Freau's Empirical Relationship](08-freau-relationship.md) |
|||
@ -0,0 +1,457 @@ |
|||
--- |
|||
id: phys-08 |
|||
title: "Freau's Empirical Relationship" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "advanced" |
|||
estimated_time: 35 |
|||
prerequisites: ["phys-03", "phys-04", "phys-07"] |
|||
objectives: |
|||
- Understand Freau's empirical L ∝ √E scaling for burst mode |
|||
- Derive the physical explanation from capacitive divider effects |
|||
- Recognize differences between burst mode and QCW scaling |
|||
- Apply scaling laws to predict performance changes |
|||
tags: ["freau", "scaling-laws", "sub-linear", "burst-mode", "QCW", "empirical"] |
|||
--- |
|||
|
|||
# Freau's Empirical Relationship |
|||
|
|||
Tesla coil community observations have revealed consistent patterns in how spark length scales with energy. Understanding these **scaling laws** helps predict performance and set realistic expectations. |
|||
|
|||
## The Empirical Observations |
|||
|
|||
Daniel Freau and others in the Tesla coil community documented: |
|||
|
|||
### Single-Shot Burst Mode |
|||
|
|||
``` |
|||
L ∝ √E |
|||
|
|||
where: |
|||
L = spark length [m] |
|||
E = bang energy (capacitor energy per pulse) [J] |
|||
``` |
|||
|
|||
**Example measurements:** |
|||
- 25 J → 0.8 m |
|||
- 100 J → 1.6 m (4× energy → 2× length) |
|||
- 400 J → 3.2 m (16× energy → 4× length) |
|||
|
|||
**Sub-linear scaling:** Doubling energy does NOT double length; only increases by √2 ≈ 1.41×. |
|||
|
|||
### Repetitive Burst Operation |
|||
|
|||
``` |
|||
L ∝ P_avg^n |
|||
|
|||
where: |
|||
P_avg = average power [W] |
|||
n ≈ 0.3 to 0.5 (empirical exponent) |
|||
``` |
|||
|
|||
**Example:** |
|||
- 10 kW → 1.2 m |
|||
- 40 kW → 2.0 m (4× power → 1.67× length, n ≈ 0.4) |
|||
|
|||
**Still sub-linear:** More power helps, but with diminishing returns. |
|||
|
|||
### QCW Mode |
|||
|
|||
``` |
|||
L ∝ E^m |
|||
|
|||
where: |
|||
m ≈ 0.6 to 0.8 (closer to linear than burst) |
|||
``` |
|||
|
|||
**Example:** |
|||
- 50 J → 3.5 m |
|||
- 200 J → 9.0 m (4× energy → 2.6× length, m ≈ 0.7) |
|||
|
|||
**Less sub-linear:** QCW shows better scaling than burst mode. |
|||
|
|||
## Physical Explanation: Voltage-Limited Burst Mode |
|||
|
|||
The L ∝ √E relationship for burst mode comes from the interplay of capacitive divider effects and voltage limitations. |
|||
|
|||
### Derivation from First Principles |
|||
|
|||
**Step 1: Growth stops when E_tip = E_propagation** |
|||
|
|||
``` |
|||
E_tip = κ × V_tip / L |
|||
|
|||
At stall: |
|||
κ × V_tip / L_max = E_propagation |
|||
|
|||
Solving for L_max: |
|||
L_max = κ × V_tip / E_propagation |
|||
``` |
|||
|
|||
**Step 2: Voltage division affects V_tip** |
|||
|
|||
From capacitive divider (Lesson 07): |
|||
|
|||
``` |
|||
V_tip ≈ V_topload × C_mut / (C_mut + C_sh) |
|||
|
|||
For long sparks (C_sh >> C_mut): |
|||
C_sh ≈ αL (α ≈ 6.6 pF/m) |
|||
|
|||
V_tip ≈ V_topload × C_mut / (αL) |
|||
∝ V_topload / L |
|||
``` |
|||
|
|||
**Step 3: Substitute into stall condition** |
|||
|
|||
``` |
|||
L_max = κ × V_tip / E_propagation |
|||
= κ × (V_topload/L_max) / E_propagation |
|||
|
|||
Multiply both sides by L_max: |
|||
L_max² = κ × V_topload / E_propagation |
|||
|
|||
Solving for L_max: |
|||
L_max = √(κ × V_topload / E_propagation) |
|||
∝ √V_topload |
|||
``` |
|||
|
|||
**Step 4: Connect to energy** |
|||
|
|||
For a capacitor discharge (burst mode): |
|||
|
|||
``` |
|||
E_bang = ½ C_primary V_primary² |
|||
|
|||
If transformer ratio is fixed: |
|||
V_topload ∝ V_primary ∝ √E_bang |
|||
|
|||
Therefore: |
|||
L_max ∝ √V_topload ∝ √(√E_bang) ∝ E_bang^(1/4) to E_bang^(1/2) |
|||
``` |
|||
|
|||
**The exact exponent depends on:** |
|||
- Whether topload voltage saturates (breakdown limit) |
|||
- Impedance matching (affects voltage transfer) |
|||
- Spark loading (changes transformer ratio during pulse) |
|||
|
|||
**Empirically observed:** The exponent clusters around **0.5**, giving **L ∝ √E**. |
|||
|
|||
### Simplified Intuition |
|||
|
|||
**The vicious cycle:** |
|||
|
|||
``` |
|||
Longer spark → Higher C_sh → Lower V_tip → Lower E_tip → Harder to grow |
|||
|
|||
E_tip ∝ V_tip/L ∝ (V_top/L)/L ∝ V_top/L² |
|||
|
|||
Growth requires: V_top/L² ≥ E_propagation/κ |
|||
V_top ≥ (E_propagation/κ) × L² |
|||
|
|||
For fixed V_top: |
|||
L_max² ≤ κ × V_top/E_propagation |
|||
L_max ∝ √V_top ∝ √E |
|||
``` |
|||
|
|||
**Physical meaning:** The capacitive divider creates a **quadratic penalty** (E_tip ∝ 1/L²), resulting in square-root scaling with energy/voltage. |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Burst Mode Scaling |
|||
|
|||
**Given:** |
|||
- Coil operates in burst mode |
|||
- Test 1: E_bang = 40 J → L = 1.1 m |
|||
- Test 2: E_bang = 160 J → L = ? |
|||
|
|||
**Find:** Predicted length for Test 2 using L ∝ √E |
|||
|
|||
### Solution |
|||
|
|||
``` |
|||
L₂/L₁ = √(E₂/E₁) |
|||
|
|||
L₂ = L₁ × √(E₂/E₁) |
|||
= 1.1 m × √(160/40) |
|||
= 1.1 m × √4 |
|||
= 1.1 m × 2 |
|||
= 2.2 m |
|||
|
|||
Predicted: 2.2 m for 160 J |
|||
``` |
|||
|
|||
**Verification:** |
|||
- 4× energy (40 J → 160 J) |
|||
- 2× length (1.1 m → 2.2 m) |
|||
- Consistent with √E scaling ✓ |
|||
|
|||
**If scaling were linear (wrong):** |
|||
``` |
|||
L₂ = 1.1 m × (160/40) = 4.4 m (incorrect!) |
|||
``` |
|||
|
|||
**Key insight:** Quadrupling energy only doubles length in voltage-limited burst mode. |
|||
|
|||
--- |
|||
|
|||
## Why QCW Shows Different Scaling |
|||
|
|||
QCW mode shows less sub-linear scaling (L ∝ E^0.6 to E^0.8) because of active mitigation: |
|||
|
|||
### QCW Advantages |
|||
|
|||
**1. Voltage ramping:** |
|||
``` |
|||
V_topload(t) increases during ramp |
|||
Actively compensates for capacitive divider |
|||
Can maintain E_tip > E_propagation longer |
|||
``` |
|||
|
|||
**2. Leader formation:** |
|||
``` |
|||
Lower ε (5-15 J/m vs 30-100 J/m for burst) |
|||
Same energy produces longer spark |
|||
Better inherent efficiency |
|||
``` |
|||
|
|||
**3. Thermal accumulation:** |
|||
``` |
|||
Channel stays hot (no cooling between pulses) |
|||
Effective ε decreases during ramp |
|||
Later growth more efficient than early growth |
|||
``` |
|||
|
|||
### Modified Scaling |
|||
|
|||
**Effective relationship:** |
|||
|
|||
``` |
|||
L_max ∝ (V_top(t_final) / ε_effective) |
|||
|
|||
Both numerator and denominator improve during QCW ramp: |
|||
- V_top(t) increases (ramping) |
|||
- ε_effective decreases (thermal accumulation) |
|||
|
|||
Result: L ∝ E^m where m ≈ 0.6-0.8 |
|||
``` |
|||
|
|||
**Still sub-linear, but better than burst mode:** |
|||
- Burst: L ∝ E^0.5 |
|||
- QCW: L ∝ E^0.7 (typical) |
|||
|
|||
**Ratio improvement:** |
|||
``` |
|||
For 4× energy increase: |
|||
Burst: 4^0.5 = 2.0× longer |
|||
QCW: 4^0.7 = 2.64× longer |
|||
|
|||
QCW gains 32% more length for same energy increase! |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## WORKED EXAMPLE: Comparing Modes |
|||
|
|||
**Given:** |
|||
- Burst mode coil: 100 J → 1.5 m (baseline) |
|||
- QCW conversion: Same 100 J total energy |
|||
- Burst scaling: L ∝ E^0.5 |
|||
- QCW scaling: L ∝ E^0.7 |
|||
|
|||
**Find:** |
|||
(a) Predicted QCW length at 100 J |
|||
(b) Energy needed for 3 m in each mode |
|||
(c) Which mode is more "scalable"? |
|||
|
|||
### Solution |
|||
|
|||
**Part (a): QCW length at 100 J** |
|||
|
|||
Need calibration point for QCW. Assume QCW has lower ε: |
|||
|
|||
``` |
|||
From ε perspective: |
|||
Burst: ε_burst = 100 J / 1.5 m = 67 J/m |
|||
QCW: ε_QCW ≈ 12 J/m (typical) |
|||
|
|||
Linear estimate: |
|||
L_QCW = 100 J / 12 J/m = 8.3 m |
|||
|
|||
But voltage limit will reduce this. |
|||
Realistic with same topload: ~4-5 m |
|||
|
|||
We'll use 4.5 m as calibration point. |
|||
``` |
|||
|
|||
**Part (b): Energy for 3 m in each mode** |
|||
|
|||
**Burst mode:** |
|||
``` |
|||
L ∝ E^0.5 |
|||
L₁ = 1.5 m at E₁ = 100 J |
|||
L₂ = 3 m at E₂ = ? |
|||
|
|||
(L₂/L₁)² = E₂/E₁ |
|||
(3/1.5)² = E₂/100 |
|||
4 = E₂/100 |
|||
E₂ = 400 J needed for 3 m |
|||
``` |
|||
|
|||
**QCW mode:** |
|||
``` |
|||
L ∝ E^0.7 |
|||
L₁ = 4.5 m at E₁ = 100 J |
|||
L₂ = 3 m at E₂ = ? |
|||
|
|||
(L₂/L₁)^(1/0.7) = E₂/E₁ |
|||
(3/4.5)^1.43 = E₂/100 |
|||
0.667^1.43 = E₂/100 |
|||
0.568 = E₂/100 |
|||
E₂ = 56.8 J needed for 3 m |
|||
|
|||
Actually, 3 m < 4.5 m, so less energy needed. |
|||
Correct calculation: |
|||
(3/4.5)^1.43 = E₂/100 |
|||
E₂ ≈ 56.8 J |
|||
``` |
|||
|
|||
Wait, let me recalculate for going DOWN in length: |
|||
|
|||
``` |
|||
If QCW produces 4.5 m at 100 J, then for 3 m: |
|||
(E₂/E₁) = (L₂/L₁)^(1/0.7) |
|||
E₂/100 = (3/4.5)^1.43 |
|||
E₂ = 100 × 0.568 ≈ 57 J |
|||
|
|||
QCW needs only 57 J for 3 m |
|||
Burst needs 400 J for 3 m |
|||
|
|||
QCW is 7× more energy-efficient! |
|||
``` |
|||
|
|||
**Part (c): Which is more scalable?** |
|||
|
|||
``` |
|||
Scalability = how much length increases per energy increase |
|||
|
|||
Burst: L ∝ E^0.5 |
|||
Doubling energy: 2^0.5 = 1.41× length gain |
|||
|
|||
QCW: L ∝ E^0.7 |
|||
Doubling energy: 2^0.7 = 1.62× length gain |
|||
|
|||
QCW is more scalable: 15% better length gain per energy doubling |
|||
``` |
|||
|
|||
**Practical implication:** QCW benefits more from increased energy/power than burst mode. |
|||
|
|||
--- |
|||
|
|||
## Repetitive Operation Scaling |
|||
|
|||
For repetitive burst mode (many pulses per second): |
|||
|
|||
``` |
|||
L ∝ P_avg^n where n ≈ 0.3-0.5 |
|||
``` |
|||
|
|||
**Physical explanation:** |
|||
|
|||
**Thermal memory between pulses:** |
|||
- If repetition rate is fast enough (~100+ Hz) |
|||
- Some ionization/thermal memory carries over |
|||
- Effective ε decreases slightly |
|||
- Better scaling than single-shot (n > 0.5) |
|||
|
|||
**Power vs energy:** |
|||
``` |
|||
P_avg = E_bang × f (f = pulse rate) |
|||
|
|||
For fixed E_bang: |
|||
L ∝ P^n ∝ (E × f)^n ∝ f^n |
|||
|
|||
More frequent pulses help, but sub-linearly |
|||
``` |
|||
|
|||
**Example:** |
|||
``` |
|||
100 Hz, 40 J per pulse: P_avg = 4 kW → L₁ |
|||
200 Hz, 40 J per pulse: P_avg = 8 kW → L₂ |
|||
|
|||
L₂/L₁ = (8/4)^0.4 = 2^0.4 = 1.32 |
|||
|
|||
Only 32% longer despite doubling pulse rate |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Practical Implications |
|||
|
|||
### Design Decisions |
|||
|
|||
**For maximum length:** |
|||
- Use QCW mode (better scaling, lower ε) |
|||
- Large topload (fight capacitive divider) |
|||
- Modest energy with long ramp (exploit thermal accumulation) |
|||
|
|||
**For visual spectacle:** |
|||
- Use burst mode (bright, branched) |
|||
- High peak power (dramatic but short sparks) |
|||
- Accept poor energy efficiency |
|||
|
|||
### Performance Predictions |
|||
|
|||
**When upgrading primary capacitance:** |
|||
|
|||
``` |
|||
C_primary doubles → E_bang doubles (same V_primary) |
|||
|
|||
Burst mode: L increases by √2 = 1.41× |
|||
QCW mode: L increases by 2^0.7 = 1.62× |
|||
|
|||
QCW benefits more from the upgrade |
|||
``` |
|||
|
|||
**When adding more power:** |
|||
|
|||
``` |
|||
QCW mode: More sensitive to power increases |
|||
Can ramp voltage higher/faster |
|||
Better return on investment |
|||
|
|||
Burst mode: Less sensitive |
|||
Voltage-limited earlier |
|||
Diminishing returns |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Burst mode scaling**: L ∝ √E (square root of energy) |
|||
- **Physical origin**: Capacitive divider creates E_tip ∝ 1/L² penalty |
|||
- **QCW scaling**: L ∝ E^0.7 (less sub-linear, better than burst) |
|||
- **QCW advantages**: Voltage ramping + lower ε + thermal accumulation |
|||
- **Repetitive burst**: L ∝ P^0.3-0.5, slight improvement over single-shot |
|||
- **Design implication**: QCW is more "scalable" - better returns on energy/power increases |
|||
- **Realistic expectations**: Quadrupling energy only doubles burst-mode length |
|||
|
|||
## Practice |
|||
|
|||
{exercise:phys-ex-08} |
|||
|
|||
**Problem 1:** A burst coil produces 1.4 m sparks with 60 J per pulse. Using L ∝ √E, predict: |
|||
(a) Length with 135 J per pulse |
|||
(b) Energy needed for 2.1 m sparks |
|||
|
|||
**Problem 2:** Compare two upgrade paths for a QCW coil currently at 80 J, 3.2 m (assume L ∝ E^0.7): |
|||
- Option A: Upgrade to 160 J |
|||
- Option B: Upgrade to 240 J |
|||
Calculate expected length for each option. |
|||
|
|||
**Problem 3:** Explain why QCW shows L ∝ E^0.7 instead of L ∝ √E. What three mechanisms contribute to better-than-square-root scaling? |
|||
|
|||
**Problem 4:** A repetitive burst coil runs at 150 Hz with 30 J/pulse (4.5 kW average) and produces 1.0 m sparks. If pulse rate increases to 300 Hz (9 kW, same energy/pulse) and L ∝ P^0.4, predict new length. |
|||
|
|||
--- |
|||
**Next Lesson:** [Part 3 Review & Exercises](09-review-exercises.md) |
|||
@ -0,0 +1,434 @@ |
|||
--- |
|||
id: phys-09 |
|||
title: "Part 3 Review: Spark Growth Physics" |
|||
section: "Spark Growth Physics" |
|||
difficulty: "intermediate" |
|||
estimated_time: 60 |
|||
prerequisites: ["phys-01", "phys-02", "phys-03", "phys-04", "phys-05", "phys-06", "phys-07", "phys-08"] |
|||
objectives: |
|||
- Synthesize understanding of spark growth physics |
|||
- Apply multiple concepts to realistic design problems |
|||
- Troubleshoot common performance issues |
|||
- Make informed design decisions based on physics principles |
|||
tags: ["review", "synthesis", "design", "troubleshooting", "comprehensive"] |
|||
--- |
|||
|
|||
# Part 3 Review: Spark Growth Physics |
|||
|
|||
This lesson synthesizes the spark growth physics concepts from Part 3 and provides comprehensive practice problems integrating multiple topics. |
|||
|
|||
## Concepts Summary |
|||
|
|||
### Electric Field Thresholds (Lesson phys-01) |
|||
|
|||
**Key equations:** |
|||
``` |
|||
E_inception ≈ 2-3 MV/m (initial breakdown) |
|||
E_propagation ≈ 0.4-1.0 MV/m (sustained growth) |
|||
E_tip = κ × E_average = κ × V/L |
|||
Growth criterion: E_tip > E_propagation |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- Tip enhancement factor κ ≈ 2-5 |
|||
- Altitude/humidity effects: ±20-30% |
|||
- Voltage-limited when E_tip < E_propagation |
|||
|
|||
### Maximum Voltage-Limited Length (Lesson phys-02) |
|||
|
|||
**Key equations:** |
|||
``` |
|||
L_max ≈ κ × V_top / E_propagation |
|||
|
|||
FEMM provides: E_tip(V_top, L, geometry) |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- Both voltage AND power are necessary |
|||
- FEMM computes realistic field distributions |
|||
- Environmental effects reduce E_propagation at altitude |
|||
|
|||
### Energy Per Meter (Lesson phys-03) |
|||
|
|||
**Key equations:** |
|||
``` |
|||
ΔE ≈ ε × ΔL |
|||
dL/dt = P_stream / ε (when E_tip > E_propagation) |
|||
T = ε × L / P_stream (time to grow) |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- ε [J/m] is energy per meter of growth |
|||
- Includes ionization, heating, radiation, branching |
|||
- Theoretical minimum ε ≈ 0.3-0.5 J/m |
|||
- Practical values 20-300× higher |
|||
|
|||
### Empirical ε Values (Lesson phys-04) |
|||
|
|||
**Typical ranges:** |
|||
``` |
|||
QCW: ε ≈ 5-15 J/m (efficient leaders) |
|||
Hybrid DRSSTC: ε ≈ 20-40 J/m (mixed) |
|||
Burst mode: ε ≈ 30-100+ J/m (inefficient streamers) |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- Calibration: ε = E_delivered / L_measured |
|||
- Thermal accumulation: ε(t) = ε₀/(1 + α∫P dt) |
|||
- Operating mode choice trades efficiency vs aesthetics |
|||
|
|||
### Thermal Memory (Lesson phys-05) |
|||
|
|||
**Key equations:** |
|||
``` |
|||
τ_thermal = d² / (4α) where α ≈ 2×10⁻⁵ m²/s |
|||
v_convection ≈ √(g × d × ΔT/T_amb) |
|||
``` |
|||
|
|||
**Typical times:** |
|||
``` |
|||
Thin streamers (d ~ 100 μm): τ ~ 0.1-0.2 ms |
|||
Thick leaders (d ~ 3 mm): τ ~ 50-300 ms |
|||
Effective persistence: 1-5 ms (streamers), seconds (leaders) |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- Convection extends persistence beyond pure diffusion |
|||
- QCW ramp time << leader thermal time (stays hot) |
|||
- Burst gap >> streamer thermal time (cools completely) |
|||
|
|||
### Streamers vs Leaders (Lesson phys-06) |
|||
|
|||
**Comparison:** |
|||
``` |
|||
Streamers Leaders |
|||
Diameter: 10-100 μm 1-10 mm |
|||
Velocity: ~10⁶ m/s ~10³ m/s |
|||
Temperature: 1000-3000 K 5000-20,000 K |
|||
Mechanism: Photoionization Thermal ionization |
|||
ε: 50-150+ J/m 5-20 J/m |
|||
``` |
|||
|
|||
**6-step transition:** |
|||
1. High E-field creates streamers |
|||
2. Current flows → Joule heating |
|||
3. Thermal ionization begins |
|||
4. Leader forms from base |
|||
5. Leader tip launches streamers |
|||
6. Fed streamers convert to leader |
|||
|
|||
### Capacitive Divider (Lesson phys-07) |
|||
|
|||
**Key equations:** |
|||
``` |
|||
V_tip = V_topload × C_mut/(C_mut + C_sh) |
|||
C_sh ≈ 6.6 pF/m × L |
|||
E_tip ∝ V_tip/L ∝ 1/L² (combined effect) |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- Voltage division worsens as spark grows |
|||
- Self-limiting: longer sparks harder to extend |
|||
- Causes sub-linear scaling |
|||
- QCW mitigation: active voltage ramping |
|||
|
|||
### Freau's Scaling Laws (Lesson phys-08) |
|||
|
|||
**Empirical relationships:** |
|||
``` |
|||
Burst mode: L ∝ √E (sub-linear) |
|||
QCW mode: L ∝ E^0.7 (less sub-linear) |
|||
Repetitive burst: L ∝ P^0.4 (moderate) |
|||
``` |
|||
|
|||
**Key concepts:** |
|||
- Physical origin: capacitive divider + voltage limitation |
|||
- QCW advantages: ramping + low ε + thermal accumulation |
|||
- Realistic expectations: 4× energy → 2× length (burst) |
|||
|
|||
--- |
|||
|
|||
## Comprehensive Practice Problems |
|||
|
|||
### Problem 1: Integrated Design Analysis |
|||
|
|||
**Scenario:** |
|||
You are designing a QCW Tesla coil with the following targets: |
|||
- Target spark length: L = 2.5 m |
|||
- Ramp time: T = 15 ms |
|||
- Operating frequency: f = 150 kHz |
|||
|
|||
**Measurements from FEMM:** |
|||
- At L = 2.5 m, V_top = 550 kV: E_tip = 0.65 MV/m |
|||
- C_mut ≈ 9 pF |
|||
- C_sh ≈ 16.5 pF (for 2.5 m spark) |
|||
|
|||
**Questions:** |
|||
|
|||
**(a)** If E_propagation = 0.6 MV/m at your altitude, can the spark reach 2.5 m with 550 kV? Calculate the margin. |
|||
|
|||
**(b)** Assuming ε = 11 J/m for your QCW mode, calculate: |
|||
- Total energy required |
|||
- Average power required |
|||
|
|||
**(c)** Calculate V_tip using the capacitive divider formula. Compare to the voltage needed if there were no division (C_sh = 0). What percentage is lost? |
|||
|
|||
**(d)** If thermal accumulation reduces ε by 20% during the ramp (ε_effective = 8.8 J/m), recalculate the required power. How much benefit does thermal accumulation provide? |
|||
|
|||
--- |
|||
|
|||
### Problem 2: Mode Comparison |
|||
|
|||
**Scenario:** |
|||
You have a coil that can operate in either burst mode or QCW mode with the same primary energy E = 120 J. |
|||
|
|||
**Burst mode characteristics:** |
|||
- ε_burst = 55 J/m |
|||
- No thermal accumulation |
|||
- Voltage-limited to L_max = 2.0 m |
|||
|
|||
**QCW mode characteristics:** |
|||
- ε_QCW = 13 J/m (initial) |
|||
- With thermal accumulation: ε_effective ≈ 10 J/m (average) |
|||
- Can ramp voltage to overcome divider partially |
|||
- Voltage-limited to L_max = 4.5 m |
|||
|
|||
**Questions:** |
|||
|
|||
**(a)** Calculate predicted spark length for each mode using the power-limited formula L = E/ε. Which limit (power or voltage) dominates in each case? |
|||
|
|||
**(b)** For burst mode at 200 Hz repetition (P_avg = 24 kW), estimate whether thermal memory between pulses affects performance. Use τ_thermal ≈ 0.15 ms for thin streamers. |
|||
|
|||
**(c)** If you want 3 m sparks, which mode should you use? If neither reaches 3 m, what design changes would help? |
|||
|
|||
--- |
|||
|
|||
### Problem 3: Thermal Physics Analysis |
|||
|
|||
**Scenario:** |
|||
High-speed photography of your QCW coil shows: |
|||
- t = 0-0.5 ms: Purple streamers, d ≈ 80 μm |
|||
- t = 2-15 ms: White core at base, d ≈ 3 mm |
|||
- t > 15 ms (after ramp): Glowing channel rises for ~2 seconds |
|||
|
|||
**Questions:** |
|||
|
|||
**(a)** Calculate thermal diffusion time for: |
|||
- Thin streamers (d = 80 μm) |
|||
- Thick leaders (d = 3 mm) |
|||
|
|||
**(b)** The observation of leader persistence suggests thermal time constants alone don't explain the 2-second glow. Calculate convection velocity for the 3 mm leader with ΔT = 12,000 K. How does this explain the extended visibility? |
|||
|
|||
**(c)** Your ramp time is 15 ms. Compare this to the leader thermal time constant. Does the leader cool significantly during the ramp? (Use exponential cooling: T(t) ≈ T₀ × exp(-t/τ)) |
|||
|
|||
**(d)** Estimate at what time during the ramp the streamer-to-leader transition occurs, given that thermal ionization requires ~5000 K and Joule heating provides ~20 kW to a 1.5 m channel. Use: |
|||
- Channel mass: m ≈ d² × L × ρ_air ≈ (3×10⁻³)² × 1.5 × 1.2 ≈ 1.6×10⁻⁵ kg |
|||
- Heat capacity: c_p ≈ 1000 J/(kg·K) |
|||
|
|||
--- |
|||
|
|||
### Problem 4: Scaling and Optimization |
|||
|
|||
**Scenario:** |
|||
You have experimental data from three runs: |
|||
|
|||
| Run | V_primary | E_bang | L_measured | Notes | |
|||
|-----|-----------|--------|------------|-------| |
|||
| 1 | 300 V | 45 J | 1.3 m | Burst mode | |
|||
| 2 | 400 V | 80 J | 1.65 m | Burst mode | |
|||
| 3 | 400 V | 80 J | 4.2 m | QCW mode, 12 ms ramp | |
|||
|
|||
**Questions:** |
|||
|
|||
**(a)** Calculate ε for each run. What do the values tell you about the operating modes? |
|||
|
|||
**(b)** Check if Runs 1 and 2 follow L ∝ √E scaling (burst mode). Calculate the predicted L for Run 2 based on Run 1 data. |
|||
|
|||
**(c)** The QCW mode (Run 3) uses the same energy but produces 4.2 m vs 1.65 m for burst. Calculate the efficiency ratio. Where does the "extra length" come from physically? |
|||
|
|||
**(d)** You want to reach 2.5 m in burst mode. Using the L ∝ √E relationship from Runs 1-2, estimate the required energy. Is this upgrade worth it compared to just using QCW mode? |
|||
|
|||
--- |
|||
|
|||
### Problem 5: Capacitive Divider Deep Dive |
|||
|
|||
**Scenario:** |
|||
Your coil has C_mut = 8.5 pF and operates at V_topload = 480 kV. You want to analyze voltage division effects. |
|||
|
|||
**Questions:** |
|||
|
|||
**(a)** Create a table showing L, C_sh, V_tip, and E_tip (with κ = 3.2) for spark lengths: 0.5 m, 1.0 m, 1.5 m, 2.0 m, 2.5 m, 3.0 m. Use C_sh ≈ 6.6 pF/m × L. |
|||
|
|||
**(b)** If E_propagation = 0.55 MV/m, at what length does growth stall (E_tip = E_propagation)? Use your table and interpolate if needed. |
|||
|
|||
**(c)** Calculate what V_topload would be required to reach 3.0 m if E_propagation = 0.55 MV/m and κ = 3.2. Compare to your current 480 kV capability. |
|||
|
|||
**(d)** Propose two design changes to improve maximum length without increasing V_topload. For each, explain the physical mechanism and estimate the improvement. |
|||
|
|||
--- |
|||
|
|||
### Problem 6: Troubleshooting Scenario |
|||
|
|||
**Scenario:** |
|||
A coiler reports the following symptoms: |
|||
- Coil produces bright, purple, highly-branched 0.8 m sparks |
|||
- Primary energy: E_bang = 95 J |
|||
- Topload voltage measured: V_top ≈ 420 kV (from FEMM calibration) |
|||
- Expected much longer sparks based on energy |
|||
|
|||
**Your analysis:** |
|||
- FEMM shows E_tip ≈ 1.1 MV/m at 0.8 m length with 420 kV |
|||
- C_mut ≈ 7 pF, C_sh ≈ 5.3 pF (for 0.8 m) |
|||
- Operating mode: Hard-pulsed burst, 150 μs pulse width, 200 Hz |
|||
|
|||
**Questions:** |
|||
|
|||
**(a)** Calculate ε from the observed performance. Compare to expected values for burst mode. What does this indicate? |
|||
|
|||
**(b)** The E_tip = 1.1 MV/m is well above typical E_propagation ≈ 0.6 MV/m. Is the coil voltage-limited? What other limit explains the short sparks? |
|||
|
|||
**(c)** The symptom "bright, purple, highly-branched" suggests what type of discharge mechanism? Explain using the streamer vs leader concepts. |
|||
|
|||
**(d)** Calculate thermal diffusion time for a 100 μm streamer. Compare to the 150 μs pulse width and 5 ms gap between pulses. Does thermal memory persist between pulses? |
|||
|
|||
**(e)** Recommend three specific changes to improve spark length. For each, explain the physical principle and estimate the potential improvement. |
|||
|
|||
--- |
|||
|
|||
## Conceptual Questions |
|||
|
|||
### Question 1: Synthesis |
|||
Explain the complete chain of physics that causes burst mode to scale as L ∝ √E: |
|||
- Start with capacitive divider effect |
|||
- Connect to E_tip ∝ 1/L² |
|||
- Relate to voltage-limited stall condition |
|||
- Conclude with scaling relationship |
|||
|
|||
### Question 2: Design Trade-offs |
|||
Compare QCW and burst mode for: |
|||
- Energy efficiency (ε values) |
|||
- Thermal memory utilization |
|||
- Voltage division mitigation |
|||
- Practical applications |
|||
Conclude: when would you choose each mode? |
|||
|
|||
### Question 3: Physical Mechanisms |
|||
The streamer-to-leader transition requires three things: |
|||
1. Sufficient current |
|||
2. Sufficient time |
|||
3. Sufficient voltage maintenance |
|||
|
|||
Explain WHY each is necessary using the physics of: |
|||
- Joule heating |
|||
- Thermal ionization threshold |
|||
- Positive feedback mechanisms |
|||
|
|||
### Question 4: Limitations |
|||
A coiler claims: "I have 200 kW available, so I should easily get 10 m sparks!" |
|||
|
|||
Identify the flaws in this reasoning. Discuss: |
|||
- Voltage vs power limitations |
|||
- Energy per meter constraints |
|||
- Capacitive divider effects |
|||
- Realistic expectations |
|||
|
|||
--- |
|||
|
|||
## Part 3 Mastery Checklist |
|||
|
|||
Before proceeding to Part 4, ensure you can: |
|||
|
|||
### Electric Fields |
|||
- [ ] Calculate E_average and E_tip from V and L |
|||
- [ ] Apply tip enhancement factor κ |
|||
- [ ] Determine growth criterion (E_tip vs E_propagation) |
|||
- [ ] Account for altitude/environmental effects |
|||
|
|||
### Energy and Power |
|||
- [ ] Calculate total energy from ε and L |
|||
- [ ] Apply growth rate equation dL/dt = P/ε |
|||
- [ ] Predict growth time for target length |
|||
- [ ] Distinguish voltage-limited from power-limited |
|||
|
|||
### Operating Modes |
|||
- [ ] Explain ε differences between QCW, hybrid, burst |
|||
- [ ] Calculate expected length from energy and ε |
|||
- [ ] Recognize mode from observed spark characteristics |
|||
- [ ] Choose appropriate mode for design goals |
|||
|
|||
### Thermal Physics |
|||
- [ ] Calculate thermal diffusion times for different diameters |
|||
- [ ] Estimate convection velocity from temperature excess |
|||
- [ ] Explain QCW advantage via thermal memory |
|||
- [ ] Predict streamer vs leader formation based on timescales |
|||
|
|||
### Discharge Mechanisms |
|||
- [ ] Distinguish streamers from leaders (6 key properties) |
|||
- [ ] Describe the 6-step transition sequence |
|||
- [ ] Explain photoionization vs thermal ionization |
|||
- [ ] Predict which mechanism dominates in a given mode |
|||
|
|||
### Capacitive Divider |
|||
- [ ] Calculate V_tip from C_mut, C_sh, V_topload |
|||
- [ ] Explain how C_sh increases with length |
|||
- [ ] Derive E_tip ∝ 1/L² relationship |
|||
- [ ] Identify mitigation strategies |
|||
|
|||
### Scaling Laws |
|||
- [ ] Apply L ∝ √E for burst mode predictions |
|||
- [ ] Explain physical origin of sub-linear scaling |
|||
- [ ] Recognize QCW shows better scaling (L ∝ E^0.7) |
|||
- [ ] Set realistic expectations for energy/power increases |
|||
|
|||
--- |
|||
|
|||
## Advanced Challenge Problem |
|||
|
|||
**Scenario:** Design a QCW coil from scratch to achieve 3.5 m sparks. |
|||
|
|||
**Given constraints:** |
|||
- Budget allows C_primary up to 1.0 μF |
|||
- V_primary limited to 600 V (safety) |
|||
- Topload options: 20 cm toroid (C_top ≈ 25 pF) or 35 cm toroid (C_top ≈ 45 pF) |
|||
- Target ramp time: 10-15 ms |
|||
- Sea level operation (E_propagation = 0.6 MV/m) |
|||
|
|||
**Your task:** |
|||
|
|||
1. **Energy calculation:** |
|||
- Choose ε for QCW mode |
|||
- Calculate total energy required for 3.5 m |
|||
- Verify this is achievable with C_primary and V_primary |
|||
|
|||
2. **Voltage requirement:** |
|||
- Estimate C_mut for each topload option (use C_mut ≈ 0.7 × C_top as approximation) |
|||
- Calculate C_sh for 3.5 m spark |
|||
- For each topload, calculate V_topload needed to achieve E_tip = 0.7 MV/m at 3.5 m (assume κ = 3.0) |
|||
- Include capacitive division effects |
|||
|
|||
3. **Power analysis:** |
|||
- For T_ramp = 12 ms, calculate required average power |
|||
- Estimate peak power (assume 1.5× average for QCW) |
|||
- Check if this is reasonable for DRSSTC primary |
|||
|
|||
4. **Thermal verification:** |
|||
- Estimate leader diameter (2-4 mm typical) |
|||
- Calculate thermal time constant |
|||
- Verify ramp time << thermal time (QCW condition satisfied) |
|||
|
|||
5. **Final recommendation:** |
|||
- Which topload should be used? Why? |
|||
- Is the 3.5 m target achievable with given constraints? |
|||
- If not, what would you change and why? |
|||
|
|||
--- |
|||
|
|||
**Next Section:** [Part 4: Advanced Modeling](../04-advanced-modeling/01-introduction.md) |
|||
|
|||
--- |
|||
|
|||
## Solutions Provided Separately |
|||
|
|||
{exercise:phys-ex-comprehensive} |
|||
|
|||
Detailed solutions to all practice problems are available in the solutions guide to allow self-assessment and learning. |
|||
|
After Width: 1400 | Height: 700 | Size: 24 KiB |
|
After Width: 1775 | Height: 1233 | Size: 130 KiB |
|
After Width: 1481 | Height: 1032 | Size: 81 KiB |
|
After Width: 800 | Height: 1200 | Size: 30 KiB |
|
After Width: 1288 | Height: 1093 | Size: 171 KiB |
|
After Width: 2086 | Height: 1183 | Size: 193 KiB |
|
After Width: 1500 | Height: 600 | Size: 25 KiB |
|
After Width: 1500 | Height: 1000 | Size: 31 KiB |
|
After Width: 1200 | Height: 1000 | Size: 28 KiB |
|
After Width: 1288 | Height: 977 | Size: 148 KiB |
|
After Width: 1602 | Height: 1026 | Size: 141 KiB |
@ -0,0 +1,440 @@ |
|||
--- |
|||
id: model-01 |
|||
title: "Lumped Spark Model Theory" |
|||
section: "Advanced Modeling" |
|||
difficulty: "advanced" |
|||
estimated_time: 35 |
|||
prerequisites: ["phys-09", "phys-10", "phys-11"] |
|||
objectives: |
|||
- Understand single-element lumped model structure and assumptions |
|||
- Learn when lumped models are appropriate vs distributed models |
|||
- Master the complete workflow for building lumped spark models |
|||
- Integrate lumped spark models with full Tesla coil circuit analysis |
|||
tags: ["modeling", "lumped-model", "circuit-theory", "SPICE"] |
|||
--- |
|||
|
|||
# Lumped Spark Model Theory |
|||
|
|||
The **lumped spark model** treats the entire spark as a single equivalent circuit element. This is the simplest and most computationally efficient approach for Tesla coil spark modeling, suitable for most practical engineering applications. |
|||
|
|||
## What is a Lumped Model? |
|||
|
|||
### Circuit Structure |
|||
|
|||
The lumped spark model represents the spark channel as three components: |
|||
|
|||
``` |
|||
Topload (V_top) |
|||
| |
|||
+---[C_mut]---+---[R]---+---[C_sh]---+ |
|||
| | |
|||
Node Node GND |
|||
``` |
|||
|
|||
**Components:** |
|||
|
|||
1. **C_mut (Mutual Capacitance):** Capacitance between topload and spark channel |
|||
- Typical range: 5-15 pF |
|||
- Extracted from FEMM electrostatic analysis |
|||
|
|||
2. **R (Plasma Resistance):** Effective resistance of the entire spark |
|||
- Typical range: 10-500 kΩ at 200 kHz |
|||
- Optimized for maximum power transfer |
|||
- Variable, depends on plasma state |
|||
|
|||
3. **C_sh (Shunt Capacitance):** Capacitance from spark to ground |
|||
- Typical rule: ~2 pF/foot of spark length |
|||
- Also extracted from FEMM |
|||
- Critical for capacitive divider effect |
|||
|
|||
### Physical Meaning |
|||
|
|||
**The lumped model assumes:** |
|||
- Uniform current distribution along spark |
|||
- Single averaged resistance value |
|||
- Quasi-static voltage distribution |
|||
- Spark can be treated as electrically short at operating frequency |
|||
|
|||
**This works when:** |
|||
- λ >> L (wavelength much greater than spark length) |
|||
- At 200 kHz: λ = 1500 m, sparks typically <3 m |
|||
- Distributed effects are second-order corrections |
|||
|
|||
## When to Use Lumped Models |
|||
|
|||
### Appropriate Applications |
|||
|
|||
**Use lumped models for:** |
|||
|
|||
1. **Short to Medium Sparks (<1-2 m)** |
|||
- Uniform properties dominate |
|||
- Single R approximation valid |
|||
|
|||
2. **Impedance Matching Studies** |
|||
- Quick evaluation of different topload sizes |
|||
- Coil-level optimization |
|||
- Matching network design |
|||
|
|||
3. **First-Order Power Estimates** |
|||
- Energy transfer calculations |
|||
- Efficiency predictions |
|||
- Quick design iterations |
|||
|
|||
4. **Engineering Estimates** |
|||
- Performance predictions |
|||
- Component selection |
|||
- Safety margins |
|||
|
|||
**Computational cost:** <1 second per simulation |
|||
|
|||
### When Lumped Models Fail |
|||
|
|||
**Switch to distributed models when:** |
|||
|
|||
1. **Long Sparks (>2-3 m)** |
|||
- Base vs tip properties differ significantly |
|||
- Leader/streamer transition critical |
|||
- Current distribution non-uniform |
|||
|
|||
2. **Current Distribution Matters** |
|||
- Measuring actual current along spark |
|||
- Validating against detailed measurements |
|||
- Research applications |
|||
|
|||
3. **Extreme Parameters** |
|||
- Very low frequency (λ approaches L) |
|||
- Very high voltage (breakdown physics critical) |
|||
- Unusual geometries |
|||
|
|||
4. **Publication-Quality Results** |
|||
- Peer review requires distributed model |
|||
- Detailed physics validation |
|||
|
|||
**Trade-off:** Distributed models 1000-2000× slower |
|||
|
|||
## Complete Lumped Model Workflow |
|||
|
|||
### Step 1: FEMM Electrostatic Analysis |
|||
|
|||
**Setup requirements:** |
|||
``` |
|||
Geometry: |
|||
- Axisymmetric (r-z coordinates) |
|||
- Topload: toroid or sphere |
|||
- Spark: vertical cylinder |
|||
- Ground plane below |
|||
|
|||
Problem type: |
|||
- Electrostatic (frequency = 0) |
|||
- Two conductors: topload (V=1V), spark (floating) |
|||
- Ground boundary condition |
|||
|
|||
Solve: |
|||
- Extract 2×2 capacitance matrix [C] |
|||
``` |
|||
|
|||
Detailed FEMM procedure covered in next lesson. |
|||
|
|||
### Step 2: Extract Circuit Elements |
|||
|
|||
**From FEMM capacitance matrix:** |
|||
|
|||
``` |
|||
[Topload] [Spark] |
|||
[Top] [ C₁₁ C₁₂ ] |
|||
[Spark][ C₂₁ C₂₂ ] |
|||
|
|||
Where: |
|||
- C_ii > 0 (diagonal: self-capacitance) |
|||
- C_ij < 0 (off-diagonal: mutual capacitance, negative) |
|||
- C₁₂ = C₂₁ (symmetric) |
|||
``` |
|||
|
|||
**Extraction formulas:** |
|||
|
|||
**Mutual capacitance:** |
|||
``` |
|||
C_mut = |C₁₂| = |C₂₁| |
|||
``` |
|||
Take absolute value of off-diagonal element. |
|||
|
|||
**Shunt capacitance:** |
|||
``` |
|||
C_sh = C₂₂ + C₂₁ |
|||
= C₂₂ - |C₁₂| (since C₂₁ < 0) |
|||
``` |
|||
|
|||
This is spark-to-ground capacitance with topload present. |
|||
|
|||
### Step 3: Calculate Optimal Resistance |
|||
|
|||
**Power-optimal resistance formula:** |
|||
``` |
|||
R_opt_power = 1 / (ω × C_total) |
|||
|
|||
Where: |
|||
ω = 2πf (angular frequency) |
|||
C_total = C_mut + C_sh |
|||
``` |
|||
|
|||
**Physical basis:** Hungry streamer theory |
|||
- Plasma adjusts to maximize power extraction |
|||
- R = 1/(ωC) gives optimal power transfer for capacitive load |
|||
- Valid for streamer-dominated discharge |
|||
|
|||
**Apply physical bounds:** |
|||
``` |
|||
R_min = 5 kΩ (hot leader, best case) |
|||
R_max = 500 kΩ (cool streamer, worst case) |
|||
|
|||
R_clipped = clip(R_opt_power, R_min, R_max) |
|||
``` |
|||
|
|||
Use R_clipped in final model. |
|||
|
|||
### Step 4: Build SPICE Netlist |
|||
|
|||
**Example SPICE implementation:** |
|||
|
|||
```spice |
|||
* Lumped spark model - Tesla coil discharge |
|||
.param freq=200k |
|||
.param omega={2*pi*freq} |
|||
|
|||
* Operating frequency |
|||
* Angular frequency |
|||
|
|||
* Test voltage source (or connect to coil model) |
|||
V_topload topload 0 AC 1V |
|||
|
|||
* Spark circuit elements |
|||
C_mut topload spark_node {C_mut_value} |
|||
R_spark spark_node spark_r {R_value} |
|||
C_sh spark_r 0 {C_sh_value} |
|||
|
|||
* AC analysis |
|||
.ac lin 1 {freq} {freq} |
|||
|
|||
* Output admittance at topload |
|||
.print ac v(topload) i(V_topload) vp(topload) ip(V_topload) |
|||
|
|||
.end |
|||
``` |
|||
|
|||
### Step 5: Run AC Analysis and Extract Results |
|||
|
|||
**Calculate admittance:** |
|||
``` |
|||
Y = I / V (complex admittance) |
|||
|
|||
Re{Y} = real part (conductance) |
|||
Im{Y} = imaginary part (susceptance) |
|||
``` |
|||
|
|||
**Convert to impedance if needed:** |
|||
``` |
|||
Z = 1/Y |
|||
|
|||
|Z| = magnitude |
|||
φ_Z = phase angle |
|||
``` |
|||
|
|||
**Calculate power (for actual operating voltage):** |
|||
``` |
|||
P_spark = 0.5 × |V_actual|² × Re{Y} |
|||
|
|||
Example: |
|||
If V_actual = 320 kV, Re{Y} = 1.5 μS |
|||
P_spark = 0.5 × (320×10³)² × 1.5×10⁻⁶ |
|||
= 76.8 kW |
|||
``` |
|||
|
|||
### Step 6: Validation Checks |
|||
|
|||
**1. Phase angle check:** |
|||
``` |
|||
Expected: φ_Z = -55° to -75° |
|||
(Capacitive-resistive, more capacitive than resistive) |
|||
|
|||
If outside range: |
|||
- Check C values (FEMM errors?) |
|||
- Check R (unphysical value?) |
|||
- Review frequency |
|||
``` |
|||
|
|||
**2. Resistance range check:** |
|||
``` |
|||
At 200 kHz: |
|||
- Short spark (0.5 m): R ≈ 50-150 kΩ |
|||
- Medium spark (1.5 m): R ≈ 100-300 kΩ |
|||
- Long spark (3 m): R ≈ 200-500 kΩ |
|||
|
|||
If much higher: likely streamer-dominated (OK but low power) |
|||
If much lower: check calculations |
|||
``` |
|||
|
|||
**3. Capacitance validation:** |
|||
``` |
|||
C_sh ≈ 2 pF/foot × L_spark |
|||
|
|||
Within factor of 2 is acceptable: |
|||
- Higher: concentrated field near ground |
|||
- Lower: elevated geometry, less ground coupling |
|||
|
|||
Exact match not expected (geometry dependent) |
|||
``` |
|||
|
|||
**4. Compare to measurements:** |
|||
``` |
|||
If available: |
|||
- Ringdown frequency shift → Y_spark |
|||
- E-field probe + current probe → Z_spark |
|||
|
|||
Adjust R within bounds to match measurements |
|||
``` |
|||
|
|||
## Integration with Full Coil Model |
|||
|
|||
### Connection to Secondary Circuit |
|||
|
|||
The lumped spark model appears as a **load impedance** at the topload terminal: |
|||
|
|||
``` |
|||
[Primary] → [Coupled Transformer] → [Secondary L_sec, R_sec] → [C_topload] → [Z_spark] |
|||
↓ |
|||
GND |
|||
``` |
|||
|
|||
**Effects on coil performance:** |
|||
|
|||
1. **Loaded Q reduction:** |
|||
``` |
|||
Q_loaded < Q_unloaded |
|||
|
|||
More resistive spark → lower Q → faster ringdown |
|||
``` |
|||
|
|||
2. **Resonant frequency shift:** |
|||
``` |
|||
f_loaded ≠ f₀ |
|||
|
|||
Spark adds capacitance → lowers frequency |
|||
Magnitude: Δf ≈ 1-5 kHz typical |
|||
``` |
|||
|
|||
3. **Power extraction:** |
|||
``` |
|||
P_spark = fraction of total power |
|||
|
|||
Well-matched: 50-70% to spark |
|||
Poorly matched: <30% to spark |
|||
``` |
|||
|
|||
### Impedance Matching |
|||
|
|||
**For maximum power transfer:** |
|||
``` |
|||
Want: Z_spark ≈ Z_secondary* |
|||
|
|||
Where Z_secondary* is complex conjugate of secondary impedance |
|||
|
|||
Practical approach: |
|||
- Adjust C_topload to tune frequency |
|||
- Spark length determines Z_spark |
|||
- Iterate to find optimal balance |
|||
``` |
|||
|
|||
**Trade-offs:** |
|||
- Larger topload: better coupling, heavier load |
|||
- Smaller topload: higher voltage, weaker coupling |
|||
- Spark impedance: fixed by physics (less control) |
|||
|
|||
## Worked Example: Complete Lumped Model |
|||
|
|||
**Given parameters:** |
|||
- Frequency: f = 190 kHz |
|||
- FEMM results: C_mut = 9.5 pF, C_sh = 7.2 pF |
|||
- Physical bounds: R_min = 5 kΩ, R_max = 500 kΩ |
|||
|
|||
**Step 1: Calculate R_opt_power** |
|||
``` |
|||
ω = 2π × 190×10³ = 1.194×10⁶ rad/s |
|||
|
|||
C_total = C_mut + C_sh |
|||
= 9.5 + 7.2 |
|||
= 16.7 pF |
|||
|
|||
R_opt = 1/(ω × C_total) |
|||
= 1/(1.194×10⁶ × 16.7×10⁻¹²) |
|||
= 1/(1.994×10⁻⁵) |
|||
= 50.2 kΩ |
|||
``` |
|||
|
|||
**Step 2: Check bounds** |
|||
``` |
|||
R_min = 5 kΩ |
|||
R_opt = 50.2 kΩ ✓ Within bounds |
|||
R_max = 500 kΩ |
|||
|
|||
Use R = 50.2 kΩ |
|||
``` |
|||
|
|||
**Step 3: Build SPICE model** |
|||
```spice |
|||
V_test topload 0 AC 1V |
|||
C_mut topload n1 9.5p |
|||
R_spark n1 n2 50.2k |
|||
C_sh n2 0 7.2p |
|||
|
|||
.ac lin 1 190k 190k |
|||
.end |
|||
``` |
|||
|
|||
**Step 4: Simulate** (example results) |
|||
``` |
|||
Y = I/V = 5.23 μS ∠74.5° |
|||
|
|||
Re{Y} = 5.23 × cos(74.5°) = 1.39 μS |
|||
Im{Y} = 5.23 × sin(74.5°) = 5.04 μS |
|||
|
|||
Convert to Z: |
|||
|Z| = 1/5.23×10⁻⁶ = 191 kΩ |
|||
φ_Z = -74.5° |
|||
``` |
|||
|
|||
**Step 5: Validate** |
|||
``` |
|||
✓ φ_Z = -74.5° in expected range (-55° to -75°) |
|||
✓ R_eq ≈ 51 kΩ close to R_opt = 50.2 kΩ |
|||
✓ Physical: Between 5-500 kΩ |
|||
|
|||
C_sh check: |
|||
L ≈ 7.2 pF / (2 pF/ft) = 3.6 ft ≈ 1.1 m |
|||
✓ Reasonable for medium spark |
|||
``` |
|||
|
|||
**Step 6: Power calculation** (if V_topload = 320 kV actual) |
|||
``` |
|||
P = 0.5 × |V|² × Re{Y} |
|||
= 0.5 × (320×10³)² × 1.39×10⁻⁶ |
|||
= 71.2 kW |
|||
``` |
|||
|
|||
Model complete and ready for coil integration! |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Lumped model** treats spark as single R-C-C network: simple, fast, accurate for most cases |
|||
- **Use for:** sparks <2 m, impedance matching, engineering estimates, quick iterations |
|||
- **FEMM extraction:** C_mut = |C₁₂|, C_sh = C₂₂ - |C₁₂| from Maxwell matrix |
|||
- **Optimal resistance:** R = 1/(ω × C_total) from hungry streamer theory, with physical bounds |
|||
- **Validation checks:** phase angle, resistance range, C_sh ≈ 2 pF/ft, compare to measurements |
|||
- **Integration:** appears as load impedance at topload, affects Q, frequency, power transfer |
|||
- **When to upgrade:** long sparks (>2 m), current distribution needed, research applications |
|||
|
|||
## Practice |
|||
|
|||
{exercise:model-ex-01} |
|||
|
|||
--- |
|||
**Next Lesson:** [FEMM Extraction for Lumped Models](02-femm-extraction-lumped.md) |
|||
@ -0,0 +1,703 @@ |
|||
--- |
|||
id: model-02 |
|||
title: "FEMM Extraction for Lumped Models" |
|||
section: "Advanced Modeling" |
|||
difficulty: "advanced" |
|||
estimated_time: 45 |
|||
prerequisites: ["model-01", "phys-08"] |
|||
objectives: |
|||
- Master FEMM setup for two-body electrostatic problems (topload + spark) |
|||
- Extract and interpret Maxwell capacitance matrices |
|||
- Apply correct sign conventions for mutual and shunt capacitances |
|||
- Validate extracted capacitances against empirical rules |
|||
tags: ["FEMM", "electrostatics", "capacitance-matrix", "extraction", "validation"] |
|||
--- |
|||
|
|||
# FEMM Extraction for Lumped Models |
|||
|
|||
This lesson covers the detailed procedure for using FEMM (Finite Element Method Magnetics) to extract capacitances for lumped spark models. We'll focus on the two-body problem: topload and spark channel. |
|||
|
|||
## The Maxwell Capacitance Matrix |
|||
|
|||
### Mathematical Definition |
|||
|
|||
FEMM outputs the **Maxwell capacitance matrix** [C] which relates charges to voltages: |
|||
|
|||
``` |
|||
[Q] = [C] × [V] |
|||
|
|||
Where: |
|||
Q_i = charge on conductor i (coulombs) |
|||
V_i = potential of conductor i (volts) |
|||
[C] = capacitance matrix (farads) |
|||
``` |
|||
|
|||
### Matrix Properties |
|||
|
|||
The Maxwell matrix has specific mathematical properties: |
|||
|
|||
**1. Symmetry:** |
|||
``` |
|||
C_ij = C_ji |
|||
|
|||
Physical basis: Maxwell's equations are symmetric |
|||
Numerical check: |C_ij - C_ji| / |C_ij| < 0.01 |
|||
``` |
|||
|
|||
**2. Diagonal elements positive:** |
|||
``` |
|||
C_ii > 0 (self-capacitance) |
|||
|
|||
Physical meaning: Charge required to raise conductor i to 1V |
|||
``` |
|||
|
|||
**3. Off-diagonal elements negative:** |
|||
``` |
|||
C_ij < 0 for i ≠ j |
|||
|
|||
IMPORTANT: This is the Maxwell convention! |
|||
|
|||
Physical meaning: Negative charge induced on conductor j |
|||
when conductor i is at +1V (field lines terminate) |
|||
``` |
|||
|
|||
**4. Row sum equals zero:** |
|||
``` |
|||
Σ_j C_ij = 0 for each row i |
|||
|
|||
Conservation: Total charge to ground = 0 when far-field grounded |
|||
``` |
|||
|
|||
### Two-Body System |
|||
|
|||
For topload (conductor 1) and spark (conductor 2), with ground implicit: |
|||
|
|||
``` |
|||
[1] [2] |
|||
[1] [ C₁₁ C₁₂ ] |
|||
[2] [ C₂₁ C₂₂ ] |
|||
|
|||
Example values: |
|||
[Top] [Spark] |
|||
[Top] [ 30 -8 ] pF |
|||
[Spark][ -8 14 ] pF |
|||
``` |
|||
|
|||
**Interpretation:** |
|||
|
|||
- **C₁₁ = 30 pF:** Topload self-capacitance (to infinity/ground at ∞) |
|||
- **C₂₂ = 14 pF:** Spark self-capacitance (to infinity) |
|||
- **C₁₂ = C₂₁ = -8 pF:** Mutual capacitance (negative per convention) |
|||
|
|||
**Note:** These are NOT the circuit elements we need directly. Extraction required! |
|||
|
|||
## FEMM Setup for Lumped Model |
|||
|
|||
### Problem Type and Geometry |
|||
|
|||
**Problem configuration:** |
|||
``` |
|||
Type: Electrostatic, axisymmetric |
|||
Coordinates: r-z (cylindrical) |
|||
Frequency: 0 Hz (pure electrostatic) |
|||
Precision: 1e-8 (default) |
|||
``` |
|||
|
|||
**Geometry components:** |
|||
|
|||
**1. Topload (Conductor 1):** |
|||
``` |
|||
Typical: Toroid |
|||
- Major diameter: 20-50 cm |
|||
- Minor diameter: 5-15 cm |
|||
- Or sphere: radius 10-25 cm |
|||
|
|||
Position: Origin at center |
|||
Material: Perfect conductor (grouped as Conductor 1) |
|||
``` |
|||
|
|||
**2. Spark channel (Conductor 2):** |
|||
``` |
|||
Shape: Vertical cylinder |
|||
- Length: Target spark length (e.g., 1.5 m) |
|||
- Diameter: 1-3 mm (typical plasma channel) |
|||
- Position: Base at topload bottom, extending downward |
|||
|
|||
Material: Perfect conductor (grouped as Conductor 2) |
|||
|
|||
Note: Small gap (0.1 mm) between topload and spark base |
|||
This is numerical convenience; results insensitive |
|||
``` |
|||
|
|||
**3. Ground plane:** |
|||
``` |
|||
Position: Below spark tip |
|||
Distance: 10-20 cm below tip (or room floor distance) |
|||
Extent: Large radius (3-5× max dimension) |
|||
|
|||
Boundary: V = 0 (Dirichlet condition) |
|||
``` |
|||
|
|||
**4. Outer boundary:** |
|||
``` |
|||
Shape: Large cylindrical volume |
|||
Radius: 3-5× maximum geometry dimension |
|||
Height: Extends above and below structure |
|||
|
|||
Boundary condition: V = 0 (or mixed, grounded at ∞) |
|||
``` |
|||
|
|||
**5. Medium:** |
|||
``` |
|||
All regions: Air |
|||
ε_r = 1 (vacuum permittivity) |
|||
``` |
|||
|
|||
### Step-by-Step FEMM Procedure |
|||
|
|||
**Step 1: Create geometry** |
|||
|
|||
``` |
|||
1. Draw toroid in r-z plane (right half only, axisymmetric) |
|||
- Use arc and line segments |
|||
- Close contour |
|||
|
|||
2. Draw spark cylinder |
|||
- Rectangle in r-z coordinates |
|||
- r: [0, radius], z: [z_base, z_tip] |
|||
|
|||
3. Draw ground plane |
|||
- Horizontal line at z = z_ground |
|||
- r: [0, r_max] |
|||
|
|||
4. Draw outer boundary box |
|||
- Enclose all geometry |
|||
- Large enough to avoid boundary effects |
|||
``` |
|||
|
|||
**Step 2: Define materials** |
|||
``` |
|||
Create air material block: |
|||
- Name: "Air" |
|||
- Relative permittivity: ε_r = 1 |
|||
- Apply to all regions |
|||
``` |
|||
|
|||
**Step 3: Define conductors** |
|||
|
|||
``` |
|||
Property → Conductors → Add Conductors: |
|||
|
|||
Conductor 1 (Topload): |
|||
- Select all topload surface nodes/segments |
|||
- Group: "1" |
|||
- Voltage: 1V (test voltage) |
|||
|
|||
Conductor 2 (Spark): |
|||
- Select all spark cylinder surfaces |
|||
- Group: "2" |
|||
- Voltage: <In Group> (floating potential) |
|||
|
|||
Ground plane: |
|||
- Boundary condition: V = 0 (not a separate conductor) |
|||
``` |
|||
|
|||
**Step 4: Mesh generation** |
|||
|
|||
``` |
|||
Mesh → Create Mesh |
|||
|
|||
Automatic meshing with refinement near conductors: |
|||
- Typical element size: 1-5 mm near spark |
|||
- 10-50 mm in far field |
|||
- Total elements: 5,000-20,000 for lumped model |
|||
|
|||
Check mesh quality visually (no overly elongated triangles) |
|||
``` |
|||
|
|||
**Step 5: Solve** |
|||
|
|||
``` |
|||
Analysis → Solve |
|||
|
|||
Solver runs (typically <10 seconds for lumped model) |
|||
|
|||
Check for convergence: |
|||
- Should converge in <100 iterations |
|||
- Final residual < 1e-8 |
|||
- No warnings about poor mesh quality |
|||
``` |
|||
|
|||
**Step 6: Extract capacitance matrix** |
|||
|
|||
``` |
|||
View → Circuit Props |
|||
|
|||
Output shows: |
|||
- Conductor properties (V, Q for each) |
|||
- Capacitance matrix [C] |
|||
|
|||
Copy matrix values to spreadsheet or script |
|||
``` |
|||
|
|||
### Example FEMM Output |
|||
|
|||
**Conductor properties:** |
|||
``` |
|||
Conductor 1 (Topload): |
|||
Voltage: 1.0000 V (fixed) |
|||
Charge: 3.52e-11 C = 35.2 pC |
|||
|
|||
Conductor 2 (Spark): |
|||
Voltage: 0.2982 V (computed, floating) |
|||
Charge: 1.68e-11 C = 16.8 pC |
|||
``` |
|||
|
|||
**Capacitance matrix [C]:** |
|||
``` |
|||
[1] [2] |
|||
[1] [ 35.2 -10.5 ] pF |
|||
[2] [-10.5 16.8 ] pF |
|||
``` |
|||
|
|||
**Verify properties:** |
|||
``` |
|||
✓ Symmetric: C₁₂ = C₂₁ = -10.5 pF |
|||
✓ Diagonal positive: C₁₁, C₂₂ > 0 |
|||
✓ Off-diagonal negative: C₁₂, C₂₁ < 0 |
|||
✓ Row sum: 35.2 + (-10.5) = 24.7 ≈ 0? NO - ground implicit! |
|||
|
|||
Row sum ≠ 0 is OK: ground is not in matrix (infinite conductor) |
|||
``` |
|||
|
|||
## Extracting Circuit Elements |
|||
|
|||
### Formula Derivation |
|||
|
|||
**Goal:** Extract C_mut and C_sh for this circuit: |
|||
|
|||
``` |
|||
Topload ---[C_mut]--- Spark ---[C_sh]--- Ground |
|||
``` |
|||
|
|||
**C_mut (Mutual Capacitance):** |
|||
|
|||
Mutual capacitance is the capacitance *between* topload and spark. |
|||
|
|||
``` |
|||
C_mut = |C₁₂| = |C₂₁| |
|||
|
|||
Take absolute value of off-diagonal element |
|||
|
|||
Why absolute? |
|||
- Circuit element capacitances are positive |
|||
- Maxwell convention uses negative for mutual coupling |
|||
- |C₁₂| converts to standard circuit convention |
|||
``` |
|||
|
|||
**Example:** |
|||
``` |
|||
C₁₂ = -10.5 pF |
|||
C_mut = |-10.5| = 10.5 pF ✓ |
|||
``` |
|||
|
|||
**C_sh (Shunt Capacitance to Ground):** |
|||
|
|||
Shunt capacitance is spark-to-ground with topload present. |
|||
|
|||
**Method 1: From row sum** |
|||
|
|||
The charge on spark (row 2) with V₁=V_topload, V₂=V_spark is: |
|||
``` |
|||
Q₂ = C₂₁ × V₁ + C₂₂ × V₂ |
|||
|
|||
Charge to ground = -(Q₂) assuming no other charges |
|||
But this includes charge from topload coupling! |
|||
|
|||
Actual spark-to-ground capacitance: |
|||
C_sh = C₂₂ + C₂₁ |
|||
= C₂₂ - |C₁₂| (since C₂₁ = C₁₂ < 0) |
|||
``` |
|||
|
|||
**Derivation:** |
|||
``` |
|||
Consider: Topload grounded (V₁ = 0), spark at V₂ = 1V |
|||
|
|||
Charge on spark: Q₂ = C₂₁ × 0 + C₂₂ × 1 = C₂₂ |
|||
But part of this is coupled to topload! |
|||
|
|||
Spark-to-actual-ground capacitance: |
|||
Total capacitance to ∞ = C₂₂ |
|||
Minus coupling through topload = -C₂₁ = |C₁₂| |
|||
Net shunt: C_sh = C₂₂ - |C₁₂| |
|||
``` |
|||
|
|||
**Example:** |
|||
``` |
|||
C₂₂ = 16.8 pF |
|||
C₁₂ = -10.5 pF |
|||
C_sh = 16.8 - 10.5 = 6.3 pF ✓ |
|||
``` |
|||
|
|||
**Method 2: Direct measurement** (verification) |
|||
|
|||
Run second FEMM simulation: |
|||
``` |
|||
- Topload: V = 0 (grounded) |
|||
- Spark: V = 1V |
|||
- Ground: V = 0 |
|||
|
|||
Measure charge on spark → this is C_sh directly |
|||
|
|||
Should match Method 1 result |
|||
``` |
|||
|
|||
### Sign Convention Summary |
|||
|
|||
**CRITICAL: Understand the sign conventions!** |
|||
|
|||
``` |
|||
Maxwell Matrix: |
|||
C_ij < 0 for i ≠ j (negative mutual elements) |
|||
|
|||
Circuit Elements: |
|||
All capacitances > 0 (positive values) |
|||
|
|||
Conversion: |
|||
C_mut = |C₁₂| (absolute value) |
|||
C_sh = C₂₂ - |C₁₂| (subtract absolute value) |
|||
``` |
|||
|
|||
**Common error:** Using C₁₂ directly as C_mut without absolute value |
|||
**Result:** Negative capacitance in SPICE → error or nonsensical results |
|||
|
|||
## Validation Checks |
|||
|
|||
### 1. Matrix Symmetry |
|||
|
|||
``` |
|||
Check: |C₁₂ - C₂₁| / |C₁₂| < 0.01 |
|||
|
|||
If not symmetric: |
|||
- Mesh too coarse → refine near conductors |
|||
- Convergence issue → lower tolerance |
|||
- Geometry problem → check closed contours |
|||
``` |
|||
|
|||
### 2. Physical Value Ranges |
|||
|
|||
**C_mut (Mutual):** |
|||
``` |
|||
Expected: 5-20 pF for typical Tesla coil toploads |
|||
|
|||
Too high (>30 pF): Check geometry (topload too large?) |
|||
Too low (<2 pF): Check geometry (spark too short/far?) |
|||
``` |
|||
|
|||
**C_sh (Shunt):** |
|||
``` |
|||
Empirical rule: C_sh ≈ 2 pF/foot × L_spark |
|||
|
|||
Example: L = 1.8 m = 5.9 ft |
|||
Expected: C_sh ≈ 2 × 5.9 = 11.8 pF |
|||
|
|||
Acceptable range: 0.5× to 2.5× empirical prediction |
|||
``` |
|||
|
|||
**Why deviations occur:** |
|||
``` |
|||
Higher than expected: |
|||
- Nearby ground objects (walls, floor close) |
|||
- Wide spark base (cone shape) |
|||
- Ground plane too close in simulation |
|||
|
|||
Lower than expected: |
|||
- Elevated spark (no ground plane modeled) |
|||
- Thin diameter (<1 mm) |
|||
- Topload shielding effect strong |
|||
- Empirical rule may include mutual capacitance |
|||
``` |
|||
|
|||
**Important note for distributed models:** |
|||
When using distributed models (Part 4, Lesson 4), the total C_sh from summing all segments may differ from the 2 pF/foot rule by a larger factor. This is because: |
|||
- Matrix extraction method sums individual contributions |
|||
- Mutual couplings between segments affect total |
|||
- Distributed geometry changes field distribution |
|||
- Factor of 2-3 deviation is normal and acceptable |
|||
- Use FEMM value (more accurate for specific geometry) |
|||
|
|||
### 3. Energy Conservation Check |
|||
|
|||
``` |
|||
Total energy stored should be conserved: |
|||
|
|||
W = 0.5 × V^T × C × V |
|||
|
|||
For V = [1, V₂]: |
|||
W = 0.5 × (C₁₁ + 2×C₁₂×V₂ + C₂₂×V₂²) |
|||
|
|||
Check: Should be positive, finite |
|||
``` |
|||
|
|||
### 4. Ground Distance Sensitivity |
|||
|
|||
**Test:** Vary ground plane distance, check C_sh |
|||
|
|||
``` |
|||
Ground at z = -2.0 m: C_sh = 6.8 pF |
|||
Ground at z = -3.0 m: C_sh = 6.2 pF |
|||
Ground at z = -5.0 m: C_sh = 6.0 pF |
|||
|
|||
Expect: C_sh decreases as ground moves away |
|||
Convergence: <5% change when distance > 2× spark length |
|||
``` |
|||
|
|||
If C_sh changes significantly (>20%) with ground distance: |
|||
- Ground plane too close |
|||
- Move ground further away |
|||
- Or accept measured geometry (e.g., actual room) |
|||
|
|||
## Worked Example: Complete Extraction |
|||
|
|||
**Given:** |
|||
- Spark length: 1.8 m = 5.9 feet |
|||
- FEMM simulation output (see above) |
|||
- Operating frequency: 200 kHz |
|||
|
|||
**FEMM capacitance matrix:** |
|||
``` |
|||
[1] [2] |
|||
[1] [ 35.2 -10.5 ] pF |
|||
[2] [-10.5 16.8 ] pF |
|||
``` |
|||
|
|||
**Step 1: Extract C_mut** |
|||
``` |
|||
C_mut = |C₁₂| = |-10.5| = 10.5 pF ✓ |
|||
``` |
|||
|
|||
**Step 2: Extract C_sh** |
|||
``` |
|||
C_sh = C₂₂ + C₂₁ |
|||
= C₂₂ - |C₁₂| |
|||
= 16.8 - 10.5 |
|||
= 6.3 pF ✓ |
|||
``` |
|||
|
|||
**Step 3: Validate C_sh** |
|||
``` |
|||
Empirical prediction: |
|||
C_sh_predicted = 2 pF/ft × 5.9 ft = 11.8 pF |
|||
|
|||
FEMM result: |
|||
C_sh_FEMM = 6.3 pF |
|||
|
|||
Ratio: 6.3 / 11.8 = 0.53 |
|||
|
|||
This is LOWER than expected by factor ~2 |
|||
``` |
|||
|
|||
**Analysis of discrepancy:** |
|||
|
|||
**Possible explanations:** |
|||
``` |
|||
1. Empirical rule assumes straight vertical spark |
|||
- If spark is angled or curved: less capacitance |
|||
- FEMM models idealized vertical cylinder |
|||
|
|||
2. Empirical rule from community measurements |
|||
- May include some C_mut in "measured" value |
|||
- Difficult to separate mutual from shunt experimentally |
|||
- Pure C_sh might be lower |
|||
|
|||
3. Ground plane distance matters |
|||
- FEMM: specific ground geometry (15 cm below tip) |
|||
- Empirical rule: "typical" room (floor 1-2 m away) |
|||
- Closer ground in measurements → higher C_sh |
|||
|
|||
4. Diameter assumption |
|||
- Thinner diameter → lower C_sh (logarithmic dependence) |
|||
- C ∝ 1/ln(h/d), so d = 1 mm vs 3 mm changes C by ~30% |
|||
``` |
|||
|
|||
**Decision: Use FEMM value** |
|||
``` |
|||
For modeling: Use C_sh = 6.3 pF (FEMM result) |
|||
Reason: More accurate for specific geometry |
|||
Empirical rule: Rough check only |
|||
|
|||
Within factor of 2-3: Acceptable agreement |
|||
``` |
|||
|
|||
**Step 4: Calculate total capacitance** |
|||
``` |
|||
C_total = C_mut + C_sh |
|||
= 10.5 + 6.3 |
|||
= 16.8 pF |
|||
``` |
|||
|
|||
**Step 5: Calculate R_opt** |
|||
``` |
|||
f = 200 kHz |
|||
ω = 2π × 200×10³ = 1.257×10⁶ rad/s |
|||
|
|||
R_opt = 1/(ω × C_total) |
|||
= 1/(1.257×10⁶ × 16.8×10⁻¹²) |
|||
= 47.3 kΩ ✓ |
|||
|
|||
Within physical bounds (5-500 kΩ) |
|||
``` |
|||
|
|||
**Step 6: Build circuit** |
|||
``` |
|||
SPICE netlist: |
|||
C_mut topload spark_n 10.5p |
|||
R_spark spark_n spark_r 47.3k |
|||
C_sh spark_r 0 6.3p |
|||
``` |
|||
|
|||
Ready for simulation! |
|||
|
|||
## Common FEMM Errors and Troubleshooting |
|||
|
|||
### Problem: Matrix not symmetric |
|||
|
|||
**Symptoms:** |
|||
``` |
|||
|C₁₂ - C₂₁| / |C₁₂| > 0.05 |
|||
``` |
|||
|
|||
**Causes and fixes:** |
|||
``` |
|||
1. Mesh too coarse |
|||
→ Refine mesh near conductors |
|||
→ Increase total element count |
|||
|
|||
2. Poor convergence |
|||
→ Lower precision requirement (1e-9 or 1e-10) |
|||
→ Check mesh quality |
|||
|
|||
3. Geometry errors |
|||
→ Verify all contours closed |
|||
→ Check no overlapping regions |
|||
``` |
|||
|
|||
### Problem: Negative C_sh |
|||
|
|||
**Symptoms:** |
|||
``` |
|||
C_sh = C₂₂ - |C₁₂| < 0 |
|||
``` |
|||
|
|||
**Causes:** |
|||
``` |
|||
This should NEVER happen physically! |
|||
|
|||
1. Wrong extraction formula used |
|||
→ Double-check: C_sh = C₂₂ - |C₁₂|, not C₂₂ + C₁₂ |
|||
|
|||
2. FEMM simulation error |
|||
→ Check conductor assignments |
|||
→ Verify boundary conditions |
|||
→ Remake geometry from scratch |
|||
|
|||
3. Conductors not properly grouped |
|||
→ Each conductor must be single contiguous group |
|||
``` |
|||
|
|||
### Problem: C_sh >> empirical rule (factor >5) |
|||
|
|||
**Symptoms:** |
|||
``` |
|||
C_sh = 50 pF for 1 m spark (expected: 6 pF) |
|||
``` |
|||
|
|||
**Causes:** |
|||
``` |
|||
1. Ground plane too close |
|||
→ Move ground plane further away |
|||
→ Check z-coordinate |
|||
|
|||
2. Spark diameter too large |
|||
→ Should be 1-3 mm, not 1-3 cm! |
|||
→ Check units |
|||
|
|||
3. Multiple ground connections |
|||
→ Check only one ground boundary condition |
|||
``` |
|||
|
|||
### Problem: C_mut unreasonably large |
|||
|
|||
**Symptoms:** |
|||
``` |
|||
C_mut > 50 pF for medium toroid |
|||
``` |
|||
|
|||
**Causes:** |
|||
``` |
|||
1. Topload size too large |
|||
→ Check diameter in correct units |
|||
|
|||
2. Spark embedded in topload |
|||
→ Should have small gap (0.1-1 mm) |
|||
|
|||
3. Scale error |
|||
→ Check all dimensions (cm? m? mm?) |
|||
``` |
|||
|
|||
## Best Practices |
|||
|
|||
**1. Consistent units:** |
|||
``` |
|||
Recommended: Centimeters throughout FEMM |
|||
- Easy to work with Tesla coil scales |
|||
- Avoid mixing mm/cm/m |
|||
- Output still in standard SI units |
|||
``` |
|||
|
|||
**2. Mesh refinement:** |
|||
``` |
|||
Start coarse → check matrix → refine if needed |
|||
|
|||
Adequate: Symmetry <1% error |
|||
Overkill: >50,000 elements for lumped model (slow, no benefit) |
|||
``` |
|||
|
|||
**3. Parametric studies:** |
|||
``` |
|||
Vary one parameter at a time: |
|||
- Spark length: C_sh should scale linearly |
|||
- Ground distance: C_sh should saturate at large distance |
|||
- Diameter: C_sh logarithmic dependence (weak) |
|||
|
|||
Check trends make physical sense |
|||
``` |
|||
|
|||
**4. Documentation:** |
|||
``` |
|||
Save for each simulation: |
|||
- Geometry parameters (toroid size, spark length, ground position) |
|||
- Mesh statistics (elements, convergence) |
|||
- Raw matrix output |
|||
- Extracted C_mut, C_sh |
|||
- Validation checks |
|||
|
|||
Build database for future reference |
|||
``` |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Maxwell matrix** uses negative off-diagonals for mutual capacitance (standard convention) |
|||
- **Extraction formulas:** C_mut = |C₁₂|, C_sh = C₂₂ - |C₁₂| (absolute value critical!) |
|||
- **FEMM setup:** Axisymmetric, two conductors (topload at 1V, spark floating), ground boundary |
|||
- **Validation:** Check symmetry, C_sh ≈ 2 pF/ft ± factor 2, physical value ranges |
|||
- **Discrepancies:** FEMM more accurate than empirical rules for specific geometry |
|||
- **Common errors:** Wrong sign conversion, mesh too coarse, units mismatch, ground too close |
|||
- **Use FEMM values** in circuit model, not empirical estimates |
|||
|
|||
## Practice |
|||
|
|||
{exercise:model-ex-02} |
|||
|
|||
--- |
|||
**Next Lesson:** [Distributed Model Theory](03-distributed-model.md) |
|||
@ -0,0 +1,576 @@ |
|||
--- |
|||
id: model-03 |
|||
title: "Distributed Model Theory" |
|||
section: "Advanced Modeling" |
|||
difficulty: "advanced" |
|||
estimated_time: 40 |
|||
prerequisites: ["model-01", "model-02"] |
|||
objectives: |
|||
- Understand when and why distributed models are necessary |
|||
- Master nth-order segmentation strategy and circuit topology |
|||
- Learn the trade-offs between lumped and distributed approaches |
|||
- Apply distributed models to long sparks and research applications |
|||
tags: ["distributed-model", "segmentation", "nth-order", "circuit-topology"] |
|||
--- |
|||
|
|||
# Distributed Model Theory |
|||
|
|||
The **distributed spark model** divides the spark into multiple segments, each with its own resistance and capacitance network. This captures spatial variations in current, voltage, and plasma properties along the spark length. |
|||
|
|||
## Why Distributed Models? |
|||
|
|||
### Limitations of Lumped Models |
|||
|
|||
Lumped models treat the entire spark as a single element, which **fails to capture:** |
|||
|
|||
**1. Current distribution along spark** |
|||
``` |
|||
Base: Full current (directly coupled to topload) |
|||
Middle: Reduced current (capacitive shunting) |
|||
Tip: Much lower current (weak coupling, high shunt) |
|||
|
|||
Lumped model: Assumes uniform current everywhere (wrong!) |
|||
``` |
|||
|
|||
**2. Voltage distribution** |
|||
``` |
|||
Actual: Non-linear voltage drop due to distributed capacitance |
|||
Lumped: Assumes simple voltage divider (oversimplified) |
|||
|
|||
Capacitive divider effects occur at EACH point along spark |
|||
``` |
|||
|
|||
**3. Base vs tip physical differences** |
|||
``` |
|||
Base properties: |
|||
- Hot plasma (continuously heated) |
|||
- Well-coupled to topload |
|||
- Low resistance (leader regime) |
|||
- High current density |
|||
|
|||
Tip properties: |
|||
- Cool plasma (sporadic heating) |
|||
- Weakly coupled |
|||
- High resistance (streamer regime) |
|||
- Low current density |
|||
|
|||
Lumped model: Single R averages this out (loses physics!) |
|||
``` |
|||
|
|||
**4. Leader/streamer transitions** |
|||
``` |
|||
Long sparks: Base forms leader, tip remains streamer |
|||
Different physics: Different R, different behavior |
|||
Lumped R: Cannot represent this transition zone |
|||
``` |
|||
|
|||
**5. Very long sparks (>3 m)** |
|||
``` |
|||
Distributed effects dominate |
|||
Single lumped R is poor approximation |
|||
Error: Can be factor of 2-5 in current distribution |
|||
``` |
|||
|
|||
### When to Use Distributed Models |
|||
|
|||
**Use distributed when:** |
|||
|
|||
1. **Spark length > 1-2 meters** |
|||
- Spatial variations become significant |
|||
- Base-to-tip differences critical |
|||
|
|||
2. **Current distribution matters** |
|||
- Measuring actual current profile along spark |
|||
- Validating against detailed experimental data |
|||
- Understanding leader formation dynamics |
|||
|
|||
3. **Research applications** |
|||
- Physics investigations |
|||
- Leader/streamer transition studies |
|||
- Publication-quality results |
|||
|
|||
4. **Extreme parameters** |
|||
- Very low frequency (λ comparable to L) |
|||
- Very high voltage (breakdown physics critical) |
|||
- Unusual geometries (horizontal, branched) |
|||
|
|||
**Stick with lumped when:** |
|||
|
|||
1. **Quick design iterations** |
|||
- Impedance matching studies |
|||
- Component selection |
|||
- Performance estimates |
|||
|
|||
2. **Short sparks (<1 m)** |
|||
- Uniform properties adequate |
|||
- Computational efficiency critical |
|||
|
|||
3. **Engineering estimates** |
|||
- ±20% accuracy sufficient |
|||
- Fast turnaround needed |
|||
|
|||
**Computational trade-off:** |
|||
``` |
|||
Lumped model: <1 second |
|||
Distributed (n=10): ~10-30 seconds |
|||
Distributed (n=20): ~1-5 minutes |
|||
|
|||
Speedup factor: 600-18000× |
|||
|
|||
Use distributed only when benefits justify cost! |
|||
``` |
|||
|
|||
## Segmentation Strategy |
|||
|
|||
### Dividing the Spark |
|||
|
|||
**Equal-length segments:** |
|||
``` |
|||
n = number of segments (typically 5-20) |
|||
L_segment = L_total / n |
|||
|
|||
Segment numbering: |
|||
i = 1: Base (connected to topload) |
|||
i = 2, 3, ..., n-1: Middle sections |
|||
i = n: Tip (furthest from topload) |
|||
``` |
|||
|
|||
**Example: 2.4 m spark, n=6 segments** |
|||
``` |
|||
L_segment = 2.4 / 6 = 0.4 m each |
|||
|
|||
Segment 1 (base): z = 0 to -0.4 m |
|||
Segment 2: z = -0.4 to -0.8 m |
|||
Segment 3: z = -0.8 to -1.2 m |
|||
Segment 4: z = -1.2 to -1.6 m |
|||
Segment 5: z = -1.6 to -2.0 m |
|||
Segment 6 (tip): z = -2.0 to -2.4 m |
|||
``` |
|||
|
|||
### Why Equal Lengths? |
|||
|
|||
**Advantages:** |
|||
``` |
|||
1. Simple FEMM geometry |
|||
- Uniform cylinder sections |
|||
- Easy to script/automate |
|||
|
|||
2. Uniform discretization |
|||
- No bias toward any region |
|||
- Straightforward convergence analysis |
|||
|
|||
3. Easy implementation |
|||
- Regular array indexing |
|||
- Simple matrix structure |
|||
|
|||
4. Standard practice |
|||
- Literature comparisons |
|||
- Validated approach |
|||
``` |
|||
|
|||
**Non-uniform segmentation possible:** |
|||
``` |
|||
Alternative: Finer near tip (where R changes rapidly) |
|||
|
|||
Example: Geometric progression |
|||
L[i] = L_base × ratio^(i-1) |
|||
|
|||
Benefits: Better captures tip physics with fewer segments |
|||
|
|||
Drawbacks: |
|||
- More complex FEMM setup |
|||
- Harder to interpret results |
|||
- Diminishing returns for extra complexity |
|||
|
|||
Recommendation: Use equal lengths unless specific research need |
|||
``` |
|||
|
|||
### Choosing n (Number of Segments) |
|||
|
|||
**Convergence vs computational cost:** |
|||
|
|||
``` |
|||
n = 1: Lumped model (fastest, least accurate for long sparks) |
|||
n = 5: Coarse distributed (captures main trends) |
|||
n = 10: Standard distributed (good balance) |
|||
n = 20: Fine distributed (research quality) |
|||
n = 50: Overkill (no improvement, much slower) |
|||
``` |
|||
|
|||
**Rule of thumb:** |
|||
``` |
|||
L < 1 m: Use lumped (n=1) |
|||
L = 1-2 m: n = 5-10 |
|||
L = 2-4 m: n = 10-15 |
|||
L > 4 m: n = 15-20 |
|||
|
|||
Convergence test: Double n, check if results change <10% |
|||
If yes: Original n sufficient |
|||
If no: Use higher n |
|||
``` |
|||
|
|||
**Practical limitations:** |
|||
``` |
|||
FEMM: (n+1)×(n+1) matrix, scales as O(n²) |
|||
SPICE: Network complexity, scales as O(n²-n³) |
|||
Optimization: R sweep, scales as O(n) |
|||
|
|||
Total time ≈ t_FEMM × n² + t_SPICE × n² + t_optimize × n |
|||
|
|||
Diminishing returns beyond n ≈ 20 |
|||
``` |
|||
|
|||
## Circuit Topology |
|||
|
|||
### Per-Segment Components |
|||
|
|||
**Each segment i has:** |
|||
|
|||
**1. Resistance R[i]** |
|||
``` |
|||
Physical meaning: Plasma resistance of that segment |
|||
Units: Ohms (typically kΩ to MΩ) |
|||
Variable: To be optimized |
|||
Expectation: Monotonically increasing from base to tip |
|||
``` |
|||
|
|||
**2. Mutual capacitances C[i,j]** |
|||
``` |
|||
Coupling to: |
|||
- Topload (j=0) |
|||
- All other segments (j=1 to n, j≠i) |
|||
|
|||
Extracted from FEMM (n+1)×(n+1) matrix |
|||
|
|||
Expectation: |
|||
- Stronger coupling to nearby segments |
|||
- Weaker coupling to distant segments |
|||
- C[i,j] decreases with |i-j| |
|||
``` |
|||
|
|||
**3. Shunt capacitance to ground** |
|||
``` |
|||
Included in capacitance matrix diagonal |
|||
NOT a separate component in circuit |
|||
|
|||
C[i,i] (diagonal) represents self-capacitance |
|||
Includes ground coupling implicitly |
|||
``` |
|||
|
|||
### Network Structure |
|||
|
|||
**Full distributed network:** |
|||
|
|||
``` |
|||
Topload (node 0, V_top) |
|||
| |
|||
+---[C[0,1]]---+ |
|||
| | |
|||
+---[C[0,2]]---|---+ |
|||
| | | |
|||
+---[C[0,3]]---|---|---+ |
|||
| | | | |
|||
... | | | |
|||
| | | |
|||
[R[1]] | | |
|||
| | | |
|||
Node 1 | | |
|||
| | | |
|||
[C[1,2]]| | |
|||
[C[1,3]]|---| |
|||
| | | |
|||
[R[2]] | | |
|||
| | | |
|||
Node 2 | | |
|||
| | | |
|||
[C[2,3]]|---| |
|||
| | | |
|||
[R[3]] | | |
|||
| | | |
|||
Node 3 | | |
|||
| | | |
|||
| | | |
|||
GND GND GND |
|||
(implicit in C matrix) |
|||
``` |
|||
|
|||
**Matrix representation:** |
|||
``` |
|||
For n=3 segments + topload (4×4 matrix): |
|||
|
|||
[0] [1] [2] [3] |
|||
[0] [ C₀₀ C₀₁ C₀₂ C₀₃ ] Topload |
|||
[1] [ C₁₀ C₁₁ C₁₂ C₁₃ ] Segment 1 (base) |
|||
[2] [ C₂₀ C₂₁ C₂₂ C₂₃ ] Segment 2 |
|||
[3] [ C₃₀ C₃₁ C₃₂ C₃₃ ] Segment 3 (tip) |
|||
|
|||
Plus resistances: |
|||
R[1], R[2], R[3] (one per segment) |
|||
|
|||
Total unknowns: 3 R values (n in general) |
|||
``` |
|||
|
|||
### Complexity Analysis |
|||
|
|||
**For n segments:** |
|||
``` |
|||
Capacitance matrix: (n+1)×(n+1) = n² + 2n + 1 elements |
|||
Due to symmetry: (n+1)(n+2)/2 unique values |
|||
|
|||
Resistances: n values |
|||
|
|||
Circuit nodes: n+1 (including topload) |
|||
|
|||
SPICE equations: O(n²) for capacitance network |
|||
O(n) for resistances |
|||
|
|||
Total complexity: O(n²) dominated by capacitance couplings |
|||
``` |
|||
|
|||
## Physical Expectations |
|||
|
|||
### Resistance Distribution |
|||
|
|||
**Expected profile:** |
|||
``` |
|||
R[1] < R[2] < R[3] < ... < R[n] |
|||
|
|||
Monotonically increasing from base to tip |
|||
``` |
|||
|
|||
**Typical values at 200 kHz:** |
|||
``` |
|||
Base (segment 1): |
|||
R[1] ≈ 5-20 kΩ |
|||
Hot leader, well-coupled |
|||
High current, low resistance |
|||
|
|||
Middle (segments 2 to n-1): |
|||
R[i] ≈ 10-100 kΩ |
|||
Transition region |
|||
Moderate coupling |
|||
|
|||
Tip (segment n): |
|||
R[n] ≈ 100 kΩ - 10 MΩ |
|||
Cool streamer, weakly coupled |
|||
Low current, high resistance |
|||
``` |
|||
|
|||
**Total resistance:** |
|||
``` |
|||
R_total = Σ R[i] |
|||
|
|||
Expected: 50-500 kΩ at 200 kHz for 2-3 m spark |
|||
|
|||
Compare to lumped: Should be similar order of magnitude |
|||
If factor >5 different: Check model carefully |
|||
``` |
|||
|
|||
### Capacitance Patterns |
|||
|
|||
**Mutual capacitance C[i,j] (i≠j):** |
|||
``` |
|||
Nearby segments: Larger |C[i,j]| |
|||
Example: |C[2,3]| > |C[2,5]| |
|||
|
|||
Distant segments: Smaller |C[i,j]| |
|||
Example: |C[1,10]| << |C[1,2]| |
|||
|
|||
Topload coupling: Decreases with distance |
|||
|C[0,1]| > |C[0,2]| > ... > |C[0,n]| |
|||
``` |
|||
|
|||
**Self-capacitance C[i,i] (diagonal):** |
|||
``` |
|||
Positive (always) |
|||
Includes shunt to ground |
|||
Typically: 5-15 pF per segment |
|||
|
|||
Total shunt: Σᵢ (C[i,i] - |C[i,0]|) ≈ 2 pF/ft × L_total |
|||
(Approximate, factor of 2-3 variation acceptable) |
|||
``` |
|||
|
|||
### Current Distribution |
|||
|
|||
**Expected behavior:** |
|||
``` |
|||
|I[1]| > |I[2]| > ... > |I[n]| |
|||
|
|||
Current decreases from base to tip |
|||
``` |
|||
|
|||
**Physical reason:** |
|||
``` |
|||
Capacitive shunting at each segment: |
|||
- Some current diverts to ground through C_sh |
|||
- Less current reaches next segment |
|||
- Accumulates along spark length |
|||
|
|||
Weak coupling at tip: |
|||
- High R, low current naturally |
|||
- Capacitive shunting reduces current further |
|||
- Tip current can be 10-50× lower than base |
|||
``` |
|||
|
|||
**Validation:** |
|||
``` |
|||
After simulation, plot I[i] vs position |
|||
Should be monotonically decreasing |
|||
If not: Check R distribution, C matrix |
|||
``` |
|||
|
|||
### Voltage Distribution |
|||
|
|||
**Expected behavior:** |
|||
``` |
|||
V[1] > V[2] > ... > V[n] |
|||
|
|||
Voltage decreases from base to tip |
|||
``` |
|||
|
|||
**But NOT linear!** |
|||
``` |
|||
Simple resistor chain: ΔV = I × R (linear) |
|||
|
|||
Distributed spark: Capacitive divider at each point |
|||
- Voltage "leaks" to ground through shunt capacitance |
|||
- Non-linear profile |
|||
- Steeper drop near base (high current) |
|||
- Flatter near tip (low current) |
|||
``` |
|||
|
|||
## Lumped vs Distributed Comparison |
|||
|
|||
### Equivalent Impedance |
|||
|
|||
**Both models should give similar Z_spark at topload:** |
|||
``` |
|||
Lumped: Z = R + 1/(jωC_total) |
|||
Distributed: Z = [complex network impedance] |
|||
|
|||
At topload port, similar order of magnitude |
|||
Difference: Typically 10-30% for well-designed models |
|||
``` |
|||
|
|||
**If very different (factor >2):** |
|||
``` |
|||
Check: |
|||
1. Total resistance: Σ R[i] vs R_lumped |
|||
2. Total capacitance: C_total_distributed vs C_mut + C_sh |
|||
3. Matrix extraction errors |
|||
4. Convergence of n (try higher n) |
|||
``` |
|||
|
|||
### Power Dissipation |
|||
|
|||
**Lumped:** |
|||
``` |
|||
P_total = 0.5 × I² × R |
|||
|
|||
Single power value |
|||
``` |
|||
|
|||
**Distributed:** |
|||
``` |
|||
P[i] = 0.5 × I[i]² × R[i] |
|||
P_total = Σ P[i] |
|||
|
|||
Can see where power is dissipated: |
|||
- Base: High current, moderate R → high power |
|||
- Middle: Moderate current and R → moderate power |
|||
- Tip: Low current, high R → low power (often <10% of base) |
|||
``` |
|||
|
|||
**Insight from distributed model:** |
|||
``` |
|||
Most power dissipated in base 1/3 of spark |
|||
Tip contributes little to total power |
|||
But tip electric field critical for growth! |
|||
|
|||
This explains why: |
|||
- Short sparks easier (more efficient power coupling) |
|||
- Long sparks harder (tip poorly coupled) |
|||
- QCW benefits (maintains hot base channel) |
|||
``` |
|||
|
|||
## Worked Example: 3-Segment Model |
|||
|
|||
**Given:** |
|||
- Total spark: 1.5 m |
|||
- Divide into n = 3 equal segments |
|||
- Each segment: 0.5 m |
|||
|
|||
**Segment locations:** |
|||
``` |
|||
Segment 1 (base): z = 0 to -0.5 m |
|||
Segment 2 (middle): z = -0.5 to -1.0 m |
|||
Segment 3 (tip): z = -1.0 to -1.5 m |
|||
``` |
|||
|
|||
**Expected capacitance matrix (example values):** |
|||
``` |
|||
[0] [1] [2] [3] |
|||
[0] [ 30.0 -9.0 -3.5 -1.5 ] pF |
|||
[1] [ -9.0 14.0 -3.0 -1.0 ] |
|||
[2] [ -3.5 -3.0 10.5 -2.5 ] |
|||
[3] [ -1.5 -1.0 -2.5 8.0 ] |
|||
|
|||
Properties: |
|||
✓ Symmetric |
|||
✓ Diagonal positive |
|||
✓ Off-diagonal negative |
|||
✓ Nearby segments more strongly coupled |
|||
``` |
|||
|
|||
**Expected resistance distribution:** |
|||
``` |
|||
R[1] = 30 kΩ (base, hot) |
|||
R[2] = 60 kΩ (middle, moderate) |
|||
R[3] = 150 kΩ (tip, cool) |
|||
|
|||
Total: 240 kΩ |
|||
|
|||
Monotonically increasing ✓ |
|||
``` |
|||
|
|||
**Circuit implementation:** |
|||
``` |
|||
Convert capacitance matrix to SPICE (see next lesson) |
|||
Add resistances R[1], R[2], R[3] |
|||
Simulate to get currents and voltages |
|||
``` |
|||
|
|||
**Expected results (qualitative):** |
|||
``` |
|||
If V_topload = 1 V (test): |
|||
|
|||
I[1] ≈ 15 μA (base current) |
|||
I[2] ≈ 8 μA (middle current, ~50% of base) |
|||
I[3] ≈ 3 μA (tip current, ~20% of base) |
|||
|
|||
V[1] ≈ 0.8 V (base voltage) |
|||
V[2] ≈ 0.5 V (middle voltage) |
|||
V[3] ≈ 0.2 V (tip voltage, non-linear drop!) |
|||
|
|||
P[1] ≈ 7 μW (base power, 50% of total) |
|||
P[2] ≈ 4 μW (middle power, 30%) |
|||
P[3] ≈ 3 μW (tip power, 20%) |
|||
``` |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **Distributed models** divide spark into n segments, capturing spatial variations in current, voltage, and resistance |
|||
- **Use when:** sparks >2 m, current distribution needed, research applications, extreme parameters |
|||
- **Segmentation:** equal-length segments, n = 5-20 typical, convergence test by doubling n |
|||
- **Circuit topology:** (n+1)×(n+1) capacitance matrix plus n resistances, O(n²) complexity |
|||
- **Physical expectations:** R monotonically increasing, current decreasing, voltage non-linear, power concentrated at base |
|||
- **Trade-off:** 1000-2000× slower than lumped, use only when benefits justify computational cost |
|||
- **Validation:** Compare to lumped model (similar Z_spark), check physical trends (I, V, R distributions) |
|||
- **Next steps:** FEMM extraction for n-segment geometry (Lesson 4), resistance optimization (Lesson 5) |
|||
|
|||
## Practice |
|||
|
|||
{exercise:model-ex-03} |
|||
|
|||
--- |
|||
**Next Lesson:** [FEMM Extraction for Distributed Models](04-femm-extraction-distributed.md) |
|||
@ -0,0 +1,681 @@ |
|||
--- |
|||
id: model-04 |
|||
title: "FEMM Extraction for Distributed Models" |
|||
section: "Advanced Modeling" |
|||
difficulty: "advanced" |
|||
estimated_time: 50 |
|||
prerequisites: ["model-02", "model-03"] |
|||
objectives: |
|||
- Set up multi-body FEMM geometries for n-segment spark models |
|||
- Extract and validate (n+1)×(n+1) capacitance matrices |
|||
- Implement capacitance matrices in SPICE with correct sign handling |
|||
- Apply passivity checks and matrix validation procedures |
|||
tags: ["FEMM", "distributed-model", "capacitance-matrix", "SPICE", "validation"] |
|||
--- |
|||
|
|||
# FEMM Extraction for Distributed Models |
|||
|
|||
This lesson covers the complete procedure for extracting capacitance matrices from FEMM for distributed spark models and implementing them in SPICE circuit simulators. |
|||
|
|||
## Multi-Body Electrostatic Setup |
|||
|
|||
### Geometry Definition |
|||
|
|||
**For n segments + topload → (n+1) conductors:** |
|||
|
|||
``` |
|||
Example: n=5 segments |
|||
|
|||
Conductors: |
|||
Body 0: Toroid topload |
|||
Body 1: Cylinder segment 1 (base) |
|||
Body 2: Cylinder segment 2 |
|||
Body 3: Cylinder segment 3 |
|||
Body 4: Cylinder segment 4 |
|||
Body 5: Cylinder segment 5 (tip) |
|||
Ground: Boundary condition (not explicit conductor) |
|||
``` |
|||
|
|||
**Cylindrical segments:** |
|||
``` |
|||
Each segment i: |
|||
Length: L_segment = L_total / n |
|||
Diameter: d (typically 1-3 mm, uniform) |
|||
Position: Vertical stack from topload to ground |
|||
|
|||
Gap between segments: 0.1 mm (numerical convenience) |
|||
- Prevents touching in FEMM |
|||
- Results insensitive to small gap |
|||
- Represents continuous channel physically |
|||
``` |
|||
|
|||
### FEMM Axisymmetric Coordinates |
|||
|
|||
**r-z coordinate system:** |
|||
|
|||
``` |
|||
Example: 2.0 m spark, n=5, each segment 0.4 m |
|||
|
|||
Topload (toroid): |
|||
Major diameter: 30 cm → r_major = 15 cm |
|||
Minor diameter: 10 cm → r_minor = 5 cm |
|||
Center: z = 0 |
|||
Lowest point: z = -5 cm |
|||
|
|||
Segment 1 (base): |
|||
r = 0.1 cm (diameter = 2 mm) |
|||
z from -5.1 cm to -45.1 cm |
|||
Length: 40 cm |
|||
Gap: 0.1 cm below topload |
|||
|
|||
Segment 2: |
|||
z from -45.2 cm to -85.2 cm |
|||
Gap: 0.1 cm above segment 1 |
|||
|
|||
Segment 3: |
|||
z from -85.3 cm to -125.3 cm |
|||
|
|||
Segment 4: |
|||
z from -125.4 cm to -165.4 cm |
|||
|
|||
Segment 5 (tip): |
|||
z from -165.5 cm to -205.5 cm |
|||
|
|||
Ground plane: |
|||
z = -220 cm (15 cm below tip) |
|||
r = 0 to 300 cm (large extent) |
|||
Boundary: V = 0 |
|||
|
|||
Outer boundary: |
|||
r = 300 cm |
|||
z = -250 cm to +50 cm |
|||
Boundary: V = 0 (far field) |
|||
``` |
|||
|
|||
**Critical: Consistent numbering!** |
|||
``` |
|||
FEMM conductor numbers must match array indices: |
|||
Conductor 0 = Topload = C[0,:] |
|||
Conductor 1 = Segment 1 (base) = C[1,:] |
|||
... |
|||
Conductor n = Segment n (tip) = C[n,:] |
|||
``` |
|||
|
|||
### Step-by-Step FEMM Procedure |
|||
|
|||
**Step 1: Problem setup** |
|||
``` |
|||
File → New |
|||
Problem Type: Electrostatic, Axisymmetric |
|||
Frequency: 0 Hz |
|||
Length units: Centimeters (recommended) |
|||
Precision: 1e-8 |
|||
``` |
|||
|
|||
**Step 2: Draw geometry** |
|||
``` |
|||
1. Draw toroid (arcs + lines, right half only) |
|||
2. Draw n rectangles for spark segments |
|||
- Each: width = r_spark, height = L_segment |
|||
- Stack vertically with small gaps |
|||
3. Draw ground plane (horizontal line) |
|||
4. Draw outer boundary (large rectangle) |
|||
5. Close all contours (check with "Show Points") |
|||
``` |
|||
|
|||
**Step 3: Define materials** |
|||
``` |
|||
Materials → Add Material: |
|||
Name: "Air" |
|||
Relative permittivity: εr = 1 |
|||
|
|||
Apply "Air" to all regions (click inside each) |
|||
``` |
|||
|
|||
**Step 4: Define conductors** |
|||
``` |
|||
Properties → Conductors → Add Property: |
|||
|
|||
For i = 0 to n: |
|||
Name: "Conductor_i" |
|||
Voltage: |
|||
i = 0: V = 1V (topload excitation) |
|||
i = 1 to n: <In Group> (floating) |
|||
|
|||
Assign conductor properties: |
|||
- Select all boundary nodes/segments for each body |
|||
- Right-click → Set Conductor |
|||
- Choose corresponding conductor number |
|||
|
|||
CRITICAL: Verify numbering matches geometry! |
|||
``` |
|||
|
|||
**Step 5: Boundary conditions** |
|||
``` |
|||
Ground plane and outer boundary: |
|||
Select boundary segments |
|||
Properties → Boundary → Add Property: |
|||
Name: "Ground" |
|||
Type: Fixed Voltage V = 0 |
|||
Apply to ground plane and outer boundary |
|||
``` |
|||
|
|||
**Step 6: Meshing** |
|||
``` |
|||
Mesh → Create Mesh |
|||
|
|||
Automatic mesh with adaptive refinement: |
|||
Near conductors: ~0.5 mm triangle size |
|||
Mid-field: ~5 mm |
|||
Far field: ~50 mm |
|||
|
|||
Expected element count: |
|||
n = 5: ~15,000-30,000 elements |
|||
n = 10: ~30,000-60,000 elements |
|||
n = 20: ~60,000-120,000 elements |
|||
|
|||
Visual check: No extremely elongated triangles |
|||
``` |
|||
|
|||
**Step 7: Solve** |
|||
``` |
|||
Analysis → Solve |
|||
|
|||
Convergence: |
|||
- Should complete in <1 minute for n≤10 |
|||
- Iterations: 50-200 typical |
|||
- Final residual < 1e-8 |
|||
|
|||
Check for warnings: |
|||
- Mesh quality issues |
|||
- Conductor connectivity problems |
|||
- Non-convergence (increase iterations or refine mesh) |
|||
``` |
|||
|
|||
**Step 8: Extract capacitance matrix** |
|||
``` |
|||
View Results → Circuit Props |
|||
|
|||
Conductor properties window shows: |
|||
- Voltage on each conductor |
|||
- Charge on each conductor |
|||
- Capacitance matrix [C] |
|||
|
|||
Copy matrix to file: |
|||
- Select all text |
|||
- Copy to spreadsheet or script |
|||
- Save for processing |
|||
``` |
|||
|
|||
## Capacitance Matrix Output |
|||
|
|||
### Matrix Structure |
|||
|
|||
**For n=5 segments (6×6 matrix):** |
|||
|
|||
``` |
|||
[0] [1] [2] [3] [4] [5] |
|||
[0] [ C₀₀ C₀₁ C₀₂ C₀₃ C₀₄ C₀₅ ] |
|||
[1] [ C₁₀ C₁₁ C₁₂ C₁₃ C₁₄ C₁₅ ] |
|||
[2] [ C₂₀ C₂₁ C₂₂ C₂₃ C₂₄ C₂₅ ] |
|||
[3] [ C₃₀ C₃₁ C₃₂ C₃₃ C₃₄ C₃₅ ] |
|||
[4] [ C₄₀ C₄₁ C₄₂ C₄₃ C₄₄ C₄₅ ] |
|||
[5] [ C₅₀ C₅₁ C₅₂ C₅₃ C₅₄ C₅₅ ] |
|||
|
|||
All values in pF (picofarads) |
|||
``` |
|||
|
|||
**Example numerical values:** |
|||
``` |
|||
[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 ] |
|||
|
|||
(Illustrative values for 2 m spark, n=5) |
|||
``` |
|||
|
|||
### Matrix Properties |
|||
|
|||
**1. Symmetry:** |
|||
``` |
|||
C[i,j] = C[j,i] |
|||
|
|||
Check: For all i<j, verify |C[i,j] - C[j,i]| / |C[i,j]| < 0.01 |
|||
|
|||
Example: |
|||
C[1,3] = -0.9 pF |
|||
C[3,1] = -0.9 pF |
|||
✓ Symmetric |
|||
``` |
|||
|
|||
**2. Diagonal positive:** |
|||
``` |
|||
C[i,i] > 0 for all i |
|||
|
|||
Self-capacitance (conductor to infinity) |
|||
Always positive by definition |
|||
|
|||
Example: |
|||
C[0,0] = 32.5 pF ✓ |
|||
C[1,1] = 14.8 pF ✓ |
|||
...all positive |
|||
``` |
|||
|
|||
**3. Off-diagonal negative:** |
|||
``` |
|||
C[i,j] < 0 for all i ≠ j |
|||
|
|||
Maxwell convention: Mutual capacitances negative |
|||
|
|||
Example: |
|||
C[0,1] = -9.2 pF ✓ |
|||
C[2,4] = -0.7 pF ✓ |
|||
...all negative |
|||
``` |
|||
|
|||
**4. Row sum ≈ 0:** |
|||
``` |
|||
Σⱼ C[i,j] ≈ 0 (but not exact due to ground at infinity) |
|||
|
|||
Check: Sum should be small compared to diagonal |
|||
|
|||
Example row 2: |
|||
-3.1 + (-2.8) + 10.4 + (-2.1) + (-0.7) + (-0.3) = 1.4 pF |
|||
Compared to C[2,2] = 10.4: ratio = 13% |
|||
|
|||
Acceptable if <20% |
|||
``` |
|||
|
|||
## Matrix Validation |
|||
|
|||
### Check 1: Symmetry |
|||
|
|||
**Procedure:** |
|||
```python |
|||
# Pseudocode |
|||
for i in range(n+1): |
|||
for j in range(i+1, n+1): |
|||
error = abs(C[i,j] - C[j,i]) / abs(C[i,j]) |
|||
if error > 0.01: |
|||
print(f"Asymmetry at [{i},{j}]: {error*100:.2f}%") |
|||
# ACTION: Refine mesh, check convergence |
|||
``` |
|||
|
|||
**If not symmetric:** |
|||
- Mesh too coarse → refine near conductors |
|||
- Poor convergence → increase precision or iterations |
|||
- Geometry error → check conductor assignments |
|||
|
|||
### Check 2: Positive Semi-Definite (Passivity) |
|||
|
|||
**Eigenvalue test:** |
|||
``` |
|||
Calculate eigenvalues λ of matrix C |
|||
|
|||
Physically passive if: |
|||
- All λ ≥ 0 (non-negative) |
|||
- One λ = 0 (ground reference freedom) |
|||
- Rest λ > 0 (strictly positive) |
|||
|
|||
If any λ < 0 (within numerical precision): |
|||
- Matrix not physically realizable |
|||
- Check FEMM setup (conductor assignments) |
|||
- Refine mesh |
|||
- Verify boundary conditions |
|||
``` |
|||
|
|||
**Why this matters:** |
|||
``` |
|||
Negative eigenvalue → negative energy stored |
|||
Physically impossible for passive capacitance network |
|||
Indicates error in simulation or extraction |
|||
``` |
|||
|
|||
### Check 3: Physical Value Patterns |
|||
|
|||
**Nearby vs distant coupling:** |
|||
``` |
|||
Expectation: |C[i,j]| decreases with |i-j| |
|||
|
|||
Example: Row 3 (segment 3) |
|||
C[3,0] = -1.2 (distant from topload) |
|||
C[3,2] = -2.1 (adjacent segment) |
|||
C[3,4] = -1.8 (adjacent segment) |
|||
C[3,5] = -0.5 (distant, tip) |
|||
|
|||
Check: |C[3,2]| = 2.1 > |C[3,5]| = 0.5 ✓ |
|||
|C[3,4]| = 1.8 > |C[3,0]| = 1.2 ✓ |
|||
|
|||
Adjacent segments most strongly coupled ✓ |
|||
``` |
|||
|
|||
**Topload coupling:** |
|||
``` |
|||
Expectation: |C[0,i]| decreases with i (distance from topload) |
|||
|
|||
|C[0,1]| = 9.2 (base, closest) |
|||
|C[0,2]| = 3.1 |
|||
|C[0,3]| = 1.2 |
|||
|C[0,4]| = 0.6 |
|||
|C[0,5]| = 0.3 (tip, farthest) |
|||
|
|||
Monotonically decreasing ✓ |
|||
``` |
|||
|
|||
### Check 4: Total Shunt Capacitance |
|||
|
|||
**Approximate formula:** |
|||
``` |
|||
C_sh_total ≈ Σᵢ₌₁ⁿ (C[i,i] - |C[i,0]|) |
|||
|
|||
This sums shunt capacitance of all segments |
|||
|
|||
Empirical check: C_sh_total ≈ 2 pF/foot × L_total |
|||
``` |
|||
|
|||
**Example calculation:** |
|||
``` |
|||
Segment 1: C[1,1] - |C[1,0]| = 14.8 - 9.2 = 5.6 pF |
|||
Segment 2: C[2,2] - |C[2,0]| = 10.4 - 3.1 = 7.3 pF |
|||
Segment 3: C[3,3] - |C[3,0]| = 8.6 - 1.2 = 7.4 pF |
|||
Segment 4: C[4,4] - |C[4,0]| = 7.4 - 0.6 = 6.8 pF |
|||
Segment 5: C[5,5] - |C[5,0]| = 5.8 - 0.3 = 5.5 pF |
|||
|
|||
C_sh_total = 5.6 + 7.3 + 7.4 + 6.8 + 5.5 = 32.6 pF |
|||
|
|||
Expected: 2 pF/ft × 6.56 ft = 13.1 pF |
|||
|
|||
Ratio: 32.6 / 13.1 = 2.5 |
|||
|
|||
Higher than expected, but within factor of 2-3 (acceptable) |
|||
``` |
|||
|
|||
**Why discrepancy?** |
|||
``` |
|||
1. Matrix interpretation method |
|||
- C[i,i] includes all field terminations |
|||
- Simple sum may overcount mutual terms |
|||
- Exact extraction more complex |
|||
|
|||
2. Distributed vs lumped geometry |
|||
- Segmentation changes field distribution |
|||
- Not directly comparable to continuous cylinder |
|||
|
|||
3. Empirical rule uncertainty |
|||
- ±50% variation typical |
|||
- Geometry and environment dependent |
|||
|
|||
Conclusion: Factor of 2-3 deviation is NORMAL for distributed models |
|||
Use FEMM values (more accurate for specific geometry) |
|||
``` |
|||
|
|||
## Implementing in SPICE |
|||
|
|||
### The Challenge: Negative Off-Diagonals |
|||
|
|||
**Problem:** |
|||
``` |
|||
SPICE capacitor syntax: |
|||
C_name node1 node2 value |
|||
|
|||
Value must be positive! |
|||
C1 n1 n2 10p ← OK |
|||
C1 n1 n2 -10p ← ERROR! Unphysical |
|||
|
|||
But Maxwell matrix has C[i,j] < 0 for i≠j |
|||
Cannot use directly in SPICE! |
|||
``` |
|||
|
|||
### Solution 1: Partial Capacitance Transformation |
|||
|
|||
**Convert Maxwell → Partial (all positive):** |
|||
|
|||
**Formula:** |
|||
``` |
|||
For off-diagonal (between nodes): |
|||
C_partial[i,j] = -C_Maxwell[i,j] (flip sign!) |
|||
|
|||
For diagonal (to ground): |
|||
C_partial[i,ground] = C[i,i] - Σⱼ₌₀ⁿ C_partial[i,j] |
|||
(j≠i) |
|||
``` |
|||
|
|||
**SPICE implementation:** |
|||
```spice |
|||
* Partial capacitance network |
|||
* Between every node pair i,j where i<j: |
|||
C_0_1 node0 node1 {-C[0,1]} |
|||
C_0_2 node0 node2 {-C[0,2]} |
|||
... |
|||
C_1_2 node1 node2 {-C[1,2]} |
|||
C_1_3 node1 node3 {-C[1,3]} |
|||
... |
|||
|
|||
* Each node to ground: |
|||
C_0_gnd node0 0 {C[0,0] - sum_of_partial_from_0} |
|||
C_1_gnd node1 0 {C[1,1] - sum_of_partial_from_1} |
|||
... |
|||
|
|||
* Resistances (in series with segments): |
|||
R1 node1 node1_r {R[1]} |
|||
R2 node2 node2_r {R[2]} |
|||
... |
|||
``` |
|||
|
|||
**Example: 3×3 matrix (topload + 2 segments):** |
|||
|
|||
**Given Maxwell matrix:** |
|||
``` |
|||
[0] [1] [2] |
|||
[0] [ 30.0 -8.0 -2.0 ] pF |
|||
[1] [ -8.0 14.0 -3.0 ] pF |
|||
[2] [ -2.0 -3.0 9.0 ] pF |
|||
``` |
|||
|
|||
**Step 1: Between-node capacitances (flip signs)** |
|||
``` |
|||
C_partial[0,1] = -(-8.0) = 8.0 pF |
|||
C_partial[0,2] = -(-2.0) = 2.0 pF |
|||
C_partial[1,2] = -(-3.0) = 3.0 pF |
|||
``` |
|||
|
|||
**Step 2: Ground capacitances** |
|||
``` |
|||
Node 0: C[0,0] = 30.0, partials = 8.0 + 2.0 = 10.0 |
|||
C_0_gnd = 30.0 - 10.0 = 20.0 pF |
|||
|
|||
Node 1: C[1,1] = 14.0, partials = 8.0 + 3.0 = 11.0 |
|||
C_1_gnd = 14.0 - 11.0 = 3.0 pF |
|||
|
|||
Node 2: C[2,2] = 9.0, partials = 2.0 + 3.0 = 5.0 |
|||
C_2_gnd = 9.0 - 5.0 = 4.0 pF |
|||
``` |
|||
|
|||
**Step 3: SPICE netlist** |
|||
```spice |
|||
* Partial capacitance implementation |
|||
C_0_1 node0 node1 8.0p |
|||
C_0_2 node0 node2 2.0p |
|||
C_1_2 node1 node2 3.0p |
|||
|
|||
C_0_gnd node0 0 20.0p |
|||
C_1_gnd node1 0 3.0p |
|||
C_2_gnd node2 0 4.0p |
|||
|
|||
* Resistances |
|||
R1 node1 node1_r 50k |
|||
R2 node2 node2_r 100k |
|||
``` |
|||
|
|||
**Validation:** |
|||
``` |
|||
Total capacitance node0 to ground (all other nodes grounded): |
|||
C_total = C_0_gnd + (C_0_1 || C_1_gnd) + (C_0_2 || C_2_gnd) |
|||
|
|||
Should approximately equal C[0,0] = 30 pF |
|||
(Small differences due to network topology) |
|||
``` |
|||
|
|||
### Solution 2: Controlled Sources (VCCS) |
|||
|
|||
**Use voltage-controlled current sources:** |
|||
|
|||
**Laplace domain relation:** |
|||
``` |
|||
I[i] = Σⱼ₌₀ⁿ (jω × C[i,j] × V[j]) |
|||
|
|||
In SPICE: G-sources (transconductance) |
|||
``` |
|||
|
|||
**Implementation:** |
|||
```spice |
|||
* For each node i, current from all couplings: |
|||
* G_source_i_from_j nodei 0 (nodej 0) {j*omega*C[i,j]} |
|||
|
|||
Example node 1, coupling to node 2: |
|||
G_1_from_2 node1 0 node2 0 {2*pi*freq*C[1,2]} |
|||
|
|||
Where C[1,2] is Maxwell value (negative OK!) |
|||
``` |
|||
|
|||
**Advantages:** |
|||
- Directly implements Maxwell matrix |
|||
- Handles negatives naturally |
|||
- Exact representation |
|||
|
|||
**Disadvantages:** |
|||
- More complex netlist |
|||
- Some SPICE versions have limited frequency-dependent sources |
|||
- Behavioral sources may be needed (B-sources) |
|||
- Debugging harder |
|||
|
|||
### Solution 3: Nearest-Neighbor Approximation |
|||
|
|||
**Simplification: Ignore weak couplings** |
|||
|
|||
**Keep only:** |
|||
``` |
|||
1. Topload to all segments: C[0,i] for i=1 to n |
|||
2. Adjacent segments: C[i,i+1] for i=1 to n-1 |
|||
3. Diagonal (self): C[i,i] for all i |
|||
|
|||
Discard: C[i,j] for |i-j| > 1 and both i,j ≥ 1 |
|||
``` |
|||
|
|||
**When acceptable:** |
|||
``` |
|||
Large n (≥10): Distant couplings small (<10% of adjacent) |
|||
Quick estimates: Engineering accuracy sufficient |
|||
Weak segment-to-segment coupling: Topload dominates |
|||
|
|||
Example: |C[2,8]| << |C[2,3]| |
|||
Dropping C[2,8] has negligible effect |
|||
``` |
|||
|
|||
**Validation:** |
|||
``` |
|||
Compare: |
|||
Full matrix: Z_spark = Z_full |
|||
Nearest-neighbor: Z_spark = Z_approx |
|||
|
|||
If |Z_full - Z_approx| / |Z_full| < 0.1: |
|||
Approximation acceptable |
|||
|
|||
Typically valid for n ≥ 10 |
|||
``` |
|||
|
|||
## Worked Example: n=5 Complete Extraction |
|||
|
|||
**Given FEMM output (from earlier):** |
|||
``` |
|||
[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 |
|||
``` |
|||
|
|||
**Validation:** |
|||
``` |
|||
✓ Symmetric: C[i,j] = C[j,i] for all i,j |
|||
✓ Diagonal positive: All C[i,i] > 0 |
|||
✓ Off-diagonal negative: All C[i,j] < 0 for i≠j |
|||
✓ Adjacent > distant: |C[2,3]| = 2.1 > |C[2,5]| = 0.3 |
|||
✓ Total C_sh ≈ 32.6 pF vs expected 13.1 pF (factor 2.5, acceptable) |
|||
``` |
|||
|
|||
**Convert to partial capacitances (selected):** |
|||
``` |
|||
Between nodes (flip signs): |
|||
C_0_1 = 9.2 pF |
|||
C_0_2 = 3.1 pF |
|||
C_1_2 = 2.8 pF |
|||
C_2_3 = 2.1 pF |
|||
C_3_4 = 1.8 pF |
|||
C_4_5 = 1.4 pF |
|||
... (15 between-node caps total) |
|||
|
|||
To ground: |
|||
C_0_gnd = 32.5 - (9.2+3.1+1.2+0.6+0.3) = 18.1 pF |
|||
C_1_gnd = 14.8 - (9.2+2.8+0.9+0.4+0.2) = 1.3 pF |
|||
... (calculate for all nodes) |
|||
``` |
|||
|
|||
**SPICE implementation (abbreviated):** |
|||
```spice |
|||
* 5-segment distributed spark model |
|||
.param freq=190k |
|||
|
|||
V_test topload 0 AC 1V |
|||
|
|||
* Partial capacitances (between nodes) |
|||
C_0_1 topload seg1 9.2p |
|||
C_0_2 topload seg2 3.1p |
|||
C_1_2 seg1 seg2 2.8p |
|||
C_2_3 seg2 seg3 2.1p |
|||
C_3_4 seg3 seg4 1.8p |
|||
C_4_5 seg4 seg5 1.4p |
|||
* ... (add all others) |
|||
|
|||
* To ground |
|||
C_0_gnd topload 0 18.1p |
|||
C_1_gnd seg1 0 1.3p |
|||
* ... (add all segments) |
|||
|
|||
* Resistances (to be optimized, placeholder values) |
|||
R1 seg1 seg1_r 50k |
|||
R2 seg2 seg2_r 80k |
|||
R3 seg3 seg3_r 120k |
|||
R4 seg4 seg4_r 180k |
|||
R5 seg5 seg5_r 300k |
|||
|
|||
.ac lin 1 190k 190k |
|||
.print ac v(topload) i(V_test) v(seg1) v(seg2) v(seg3) v(seg4) v(seg5) |
|||
.end |
|||
``` |
|||
|
|||
**Next step:** Optimize R values (Lesson 5) |
|||
|
|||
## Key Takeaways |
|||
|
|||
- **(n+1)×(n+1) matrix** for n segments + topload, extracted from FEMM multi-body electrostatic simulation |
|||
- **FEMM setup:** Axisymmetric, equal-length cylinder segments, 0.1 mm gaps, conductor numbering consistent with indices |
|||
- **Matrix validation:** Check symmetry (<1% error), positive semi-definite (passivity), physical patterns (adjacent > distant) |
|||
- **Total C_sh check:** Σ(C[i,i] - |C[i,0]|) vs 2 pF/ft rule, factor 2-3 deviation normal for distributed models |
|||
- **SPICE implementation:** Three methods - partial capacitance (flip signs), controlled sources (direct), nearest-neighbor (approximation) |
|||
- **Partial capacitance:** C_partial[i,j] = -C_Maxwell[i,j], all positive values, standard for SPICE |
|||
- **Passivity check:** All eigenvalues ≥ 0, ensures physical realizability, critical validation step |
|||
- **Use FEMM values** over empirical rules for distributed models (more accurate for segmented geometry) |
|||
|
|||
## Practice |
|||
|
|||
{exercise:model-ex-04} |
|||
|
|||
--- |
|||
**Next Lesson:** [Resistance Optimization Methods](05-resistance-optimization.md) |
|||