commits
- Vg/Rg/RL inputs in a single horizontal row
- Segments and signal shape panels placed side by side below
- Time scale slider moved to left (segments) column
- Math/computed values section moved to bottom of page below plots
- Bump font sizes across UI (labels 12→14px, cfg-row 13→15px, etc.)
- Page title shortened to "Transmission line visualizer"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The centered erf (50% at wavefront arrival) was non-causal with a visible
precursor ahead of the front. Replace with shifted erf:
0.5*(1+erf(k*(2*dt/tr-1))), clamped to 0/1 outside [0, tr].
Both rise shapes (linear ramp and erf S-curve) now share the same tr
parameter and are strictly causal. Unify model.riseTimeTau/riseTimeTr
into model.riseTimeTr + model.riseShape ("step"|"linear"|"erf").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The first-order RC exponential (1-exp(-dt/tau)) had infinite slope at
dt=0 and a lazy asymptotic tail — not physically realistic. Replace with
0.5*(1+erf(dt/tau)), which models skin-effect losses (alpha proportional
to sqrt(f)) and gives zero slope at dt=0 with a smooth symmetric sigmoid.
- Add erf() rational approximation (Abramowitz & Stegun 7.1.26)
- Extend waveVoltageAt spatial window by 3*tau for precursor foot
- Update sumEventsWithRise to include events up to 3*tau ahead
- Rename UI option to "Gaussian rise (skin-effect)"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CSS grid makes every direct child a separate grid item, so inline
elements like <sub> within label text were stacking vertically instead
of rendering inline. Wrap label text in <span class="lbl"> to group
all inline content into a single grid item, and add white-space: nowrap
to prevent long labels from wrapping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sim/tline-sc.sp — short circuit (Vsc B GND 0, ΓL=−1)
sim/tline-rl.sp — resistive load (RL=100Ω param, ΓL=+1/3)
sim/run.sh — runs all *.sp files from sim/ directory
physics.test.js: replace one-off OC test with spiceCompare() helper that
- reads from sim/<tsvFile>
- skips with a clear message if the TSV hasn't been generated yet
- is called for OC, SC, and RL in one line each
To activate the new tests: cd sim && sh run.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In smooth (rise-time) mode, drawSampledWave samples totalVoltageAt at
evenly-spaced z values including exact boundary points (e.g. z=0.5 for
N=2 segments). At those points both the ending wave of the left segment
and the starting wave of the right segment passed the ±1e-9 range checks
in waveVoltageAt, doubling the displayed voltage — a visible spike.
Fix: add segmentForZ(z, N) which maps each sample to its owning segment,
and filter launchedWaves in totalVoltageAt to only sum waves whose segIdx
matches. The +1e-9 nudge in segmentForZ handles floating-point imprecision
when z lands exactly on a boundary (e.g. 200/400 = 0.5 exactly).
The bug was absent in step mode because totalSegmentsForWaves uses midpoints
between breakpoints, never probing the exact boundary z. It was also subtle
with 3 segments (boundary at 1/3) since 1/3·400 is never an integer.
Adds two regression tests that directly catch the spike.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a third signal shape alongside step and exponential:
- riseShapeLinear(dt, tr): clamp(dt/tr, 0, 1) — matches SPICE PULSE source behaviour
- sumEventsWithLinearRamp: applies linear ramp to each bounce event
- computeDynamicState: accepts riseTimeTr alongside existing riseTimeTau
- waveVoltageAt / totalVoltageAt: tr parameter selects linear over exponential
- UI: new "Linear ramp (trapezoidal)" option in Signal shape select;
rise time input now enabled for both exp and linear modes
- Tests: riseShapeLinear unit tests + SPICE golden-reference comparison
against results-tline-oc.tsv (ngspice LTRA, TR=100ps, τ_d=1ns, open circuit),
validated to <0.1mV across all ~300 time points
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the single hardcoded "0" label with auto-scaled tick marks,
right-aligned voltage labels, and horizontal grid lines at each tick.
The zero line remains slightly more prominent. Both panels share the
same voltage scale (vLo/vHi), with nice round step sizes (1-2-5 series).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Physics:
- Refactor physics.js to BFS lattice-diagram solver supporting N equal-length
segments with different Z0 values; each internal boundary generates reflected
and transmitted waves
- Add exponential rise time (RC): model.riseTimeTau > 0 gives
V = V_final·(1−exp(−Δt/τ_r)) wave shape
- Guard gL against RL=Infinity so open circuit (gL=1) works correctly
UI:
- Segment count input + per-segment Z0 inputs (up to 10 segments)
- ∞ toggle button on RL field for open circuit; disables number input
and sets RL=Infinity in the model
- Remove scrub feature
Circuit diagram:
- Draw open-circuit terminals (two filled dots) when RL=Infinity
- Draw short-circuit wire when RL=0
- Add missing top terminal dot at VL port; consistent rail length
across all three termination types
Tests & docs:
- physics.test.js: smoke tests for pure physics functions
(22 cases, node --test, zero dependencies)
- README.md: usage and how to run tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix zigzag segment count (off-by-one: segs = count*2-1)
- Rework source resistor wiring: explicit lead lines, tighter zigzag
- Reduce zigzag amplitude for cleaner look (8→5 for Rg, 6→5 for RL)
- Fade completed waves over time (FADE_DURATION=4τ, floor at 0.08 alpha)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rg default 50 → 20 Ω
- Show live timescale value in slider label
- Components panel shows all waves (no 6-wave cap)
- Expand wave styles from 6 to 10: add long-dash and dash-dot patterns
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Signal shape control: step (instantaneous) or exponential RC rise
- Rise time τ_r/τ_d input, enabled only in exponential mode
- physics.js: riseShape, waveVoltageAt, totalVoltageAt, sumEventsWithRise
- render.js: drawSampledWave for continuous V(z) curves when τ_r > 0
- Node voltages (VS, VL readouts) also use smooth rise in exponential mode
- Remove "show only one reflection" checkbox; Γ_S always active
- Animation now always plays through to end of bounce series and stops
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Vg/Rg/RL inputs in a single horizontal row
- Segments and signal shape panels placed side by side below
- Time scale slider moved to left (segments) column
- Math/computed values section moved to bottom of page below plots
- Bump font sizes across UI (labels 12→14px, cfg-row 13→15px, etc.)
- Page title shortened to "Transmission line visualizer"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The centered erf (50% at wavefront arrival) was non-causal with a visible
precursor ahead of the front. Replace with shifted erf:
0.5*(1+erf(k*(2*dt/tr-1))), clamped to 0/1 outside [0, tr].
Both rise shapes (linear ramp and erf S-curve) now share the same tr
parameter and are strictly causal. Unify model.riseTimeTau/riseTimeTr
into model.riseTimeTr + model.riseShape ("step"|"linear"|"erf").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The first-order RC exponential (1-exp(-dt/tau)) had infinite slope at
dt=0 and a lazy asymptotic tail — not physically realistic. Replace with
0.5*(1+erf(dt/tau)), which models skin-effect losses (alpha proportional
to sqrt(f)) and gives zero slope at dt=0 with a smooth symmetric sigmoid.
- Add erf() rational approximation (Abramowitz & Stegun 7.1.26)
- Extend waveVoltageAt spatial window by 3*tau for precursor foot
- Update sumEventsWithRise to include events up to 3*tau ahead
- Rename UI option to "Gaussian rise (skin-effect)"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CSS grid makes every direct child a separate grid item, so inline
elements like <sub> within label text were stacking vertically instead
of rendering inline. Wrap label text in <span class="lbl"> to group
all inline content into a single grid item, and add white-space: nowrap
to prevent long labels from wrapping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sim/tline-sc.sp — short circuit (Vsc B GND 0, ΓL=−1)
sim/tline-rl.sp — resistive load (RL=100Ω param, ΓL=+1/3)
sim/run.sh — runs all *.sp files from sim/ directory
physics.test.js: replace one-off OC test with spiceCompare() helper that
- reads from sim/<tsvFile>
- skips with a clear message if the TSV hasn't been generated yet
- is called for OC, SC, and RL in one line each
To activate the new tests: cd sim && sh run.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In smooth (rise-time) mode, drawSampledWave samples totalVoltageAt at
evenly-spaced z values including exact boundary points (e.g. z=0.5 for
N=2 segments). At those points both the ending wave of the left segment
and the starting wave of the right segment passed the ±1e-9 range checks
in waveVoltageAt, doubling the displayed voltage — a visible spike.
Fix: add segmentForZ(z, N) which maps each sample to its owning segment,
and filter launchedWaves in totalVoltageAt to only sum waves whose segIdx
matches. The +1e-9 nudge in segmentForZ handles floating-point imprecision
when z lands exactly on a boundary (e.g. 200/400 = 0.5 exactly).
The bug was absent in step mode because totalSegmentsForWaves uses midpoints
between breakpoints, never probing the exact boundary z. It was also subtle
with 3 segments (boundary at 1/3) since 1/3·400 is never an integer.
Adds two regression tests that directly catch the spike.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a third signal shape alongside step and exponential:
- riseShapeLinear(dt, tr): clamp(dt/tr, 0, 1) — matches SPICE PULSE source behaviour
- sumEventsWithLinearRamp: applies linear ramp to each bounce event
- computeDynamicState: accepts riseTimeTr alongside existing riseTimeTau
- waveVoltageAt / totalVoltageAt: tr parameter selects linear over exponential
- UI: new "Linear ramp (trapezoidal)" option in Signal shape select;
rise time input now enabled for both exp and linear modes
- Tests: riseShapeLinear unit tests + SPICE golden-reference comparison
against results-tline-oc.tsv (ngspice LTRA, TR=100ps, τ_d=1ns, open circuit),
validated to <0.1mV across all ~300 time points
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the single hardcoded "0" label with auto-scaled tick marks,
right-aligned voltage labels, and horizontal grid lines at each tick.
The zero line remains slightly more prominent. Both panels share the
same voltage scale (vLo/vHi), with nice round step sizes (1-2-5 series).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Physics:
- Refactor physics.js to BFS lattice-diagram solver supporting N equal-length
segments with different Z0 values; each internal boundary generates reflected
and transmitted waves
- Add exponential rise time (RC): model.riseTimeTau > 0 gives
V = V_final·(1−exp(−Δt/τ_r)) wave shape
- Guard gL against RL=Infinity so open circuit (gL=1) works correctly
UI:
- Segment count input + per-segment Z0 inputs (up to 10 segments)
- ∞ toggle button on RL field for open circuit; disables number input
and sets RL=Infinity in the model
- Remove scrub feature
Circuit diagram:
- Draw open-circuit terminals (two filled dots) when RL=Infinity
- Draw short-circuit wire when RL=0
- Add missing top terminal dot at VL port; consistent rail length
across all three termination types
Tests & docs:
- physics.test.js: smoke tests for pure physics functions
(22 cases, node --test, zero dependencies)
- README.md: usage and how to run tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix zigzag segment count (off-by-one: segs = count*2-1)
- Rework source resistor wiring: explicit lead lines, tighter zigzag
- Reduce zigzag amplitude for cleaner look (8→5 for Rg, 6→5 for RL)
- Fade completed waves over time (FADE_DURATION=4τ, floor at 0.08 alpha)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Signal shape control: step (instantaneous) or exponential RC rise
- Rise time τ_r/τ_d input, enabled only in exponential mode
- physics.js: riseShape, waveVoltageAt, totalVoltageAt, sumEventsWithRise
- render.js: drawSampledWave for continuous V(z) curves when τ_r > 0
- Node voltages (VS, VL readouts) also use smooth rise in exponential mode
- Remove "show only one reflection" checkbox; Γ_S always active
- Animation now always plays through to end of bounce series and stops
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>