Skip to content

Python API reference

This page is a one-stop reference for the pulsim Python module. Everything here is also exposed in C++ under pulsim::* — the Python surface mirrors the C++ API.

Module overview

import pulsim as p

# High-level entry point.
p.simulate(builder, t_end, dt, **kwargs) -> SimulationResult

# Builder.
p.CircuitBuilder()
  .add_voltage_source(...)
  .add_current_source(...)
  .add_pwm_voltage_source(...)
  .add_sine_voltage_source(...)
  .add_pulse_voltage_source(...)
  .add_resistor(...)
  .add_capacitor(...)
  .add_inductor(...)
  .add_transformer(...)
  .add_saturable_inductor(...)
  .add_multi_winding_transformer(...)
  .add_diode(...)
  .add_nonlinear_diode(...)
  .add_switch(...)
  .add_mosfet(...)
  .add_mosfet_with_body_diode(...)
  .add_mosfet_level1(...)
  .add_igbt(...)
  .add_igbt_level1(...)
  .add_vcvs(...)

# Topology / device handles.
p.Graph, p.DevicePool, p.SwitchStateMask

# Cache + simulation.
p.PwlStateSpaceCache, p.SimulationOptions, p.SimulationResult,
p.CommutationEvent, p.run_transient

# Nonlinear diode params.
p.IdealDiodeParams

# YAML loader.
p.load_yaml_string, p.load_yaml_file, p.LoadedCircuit

# Source-helper factories.
p.make_pwm_switch_fn
p.make_dead_time_pwm_pair_fn
p.make_spwm_pair_fn
p.ThreePhaseLegIndices, p.make_three_phase_spwm_fn
p.make_phase_shift_full_bridge_fn
p.make_combined_switch_fn

simulate(builder, t_end, dt, **kwargs)

The one-call high-level API (proposal #3.3). Builds the PWL cache, derives a default switch_fn, constructs SimulationOptions, runs the transient.

Arg Type Default Meaning
builder CircuitBuilder required The populated builder.
t_end float required End time, seconds.
dt float required Fixed time step, seconds.
t_start float 0.0 Start time.
switch_fn Callable[[float], SwitchStateMask] all closed Switch driver.
b_extra_fn Callable[[float], list[float]] None Per-step constant residual extras.
start_from_dc_op bool False Seed initial state from DC OP.
enable_nonlinear_refresh bool or None auto-detect Force-enable Newton refresh. None = auto via pool.has_nonlinear_devices().
max_newton_iterations int 0 (engine default) Newton iteration cap.
max_event_iterations int 0 (engine default) Event-iteration cap.

Returns a SimulationResult with parallel arrays: - result.timeslist[float], length (t_end − t_start) / dt + 1. - result.stateslist[numpy.ndarray], each of length pool.state_size(graph). - result.num_steps() — convenience accessor.

CircuitBuilder

Top-level fluent builder. Stores a Graph (topology) + DevicePool (per-device parameters) + an internal node-name → node-id map.

Node accessors

Method Returns Notes
b.node(name) int Get-or-create. "gnd", "GND", "0" all map to Graph.ground().
b.node_id_of(name) int Throws if name doesn't exist.
b.graph Graph The underlying topology.
b.pool DevicePool The underlying parameter pool.
b.num_branches int Branch count.

Source devices

Method Signature
add_voltage_source (name, from, to, V)
add_current_source (name, from, to, I)
add_pwm_voltage_source (name, from, to, *, v_high, v_low, frequency, duty, phase=0)
add_sine_voltage_source (name, from, to, *, v_dc=0, v_amplitude, frequency, phase=0)
add_pulse_voltage_source (name, from, to, *, v_initial, v_pulsed, t_start, pulse_width, period=0, rise_time=0, fall_time=0)
add_vcvs (name, *, in_pos, in_neg, out_pos, out_neg, gain)

Passive devices

Method Signature
add_resistor (name, from, to, R_ohms)
add_capacitor (name, from, to, C_farads)
add_inductor (name, from, to, L_henries)
add_transformer (name, primary_pos, primary_neg, secondary_pos, secondary_neg, L_p, L_s, k)
add_saturable_inductor (name, from, to, L_0, I_sat, L_residual=L_0/100)
add_multi_winding_transformer (name, windings, k_matrix)

Switches + diodes

Method Signature
add_switch (name, from, to, g_on, g_off)
add_diode (name, from, to, g_on, g_off, V_th=0)
add_nonlinear_diode (name, from, to, params: IdealDiodeParams)

Nonlinear actives

Method Signature
add_mosfet (name, drain, source, R_on=1e-3, R_off=1e9) (linear switch model)
add_mosfet_with_body_diode (name, drain, source, R_on=1e-3, R_off=1e9, V_F=0.7, g_on_diode=1e3, g_off_diode=1e-9)
add_mosfet_level1 (name, drain, source, gate, K, V_T, lambda_=0.02, kappa=15.0, with_body_diode=False)
add_igbt (name, collector, emitter, R_on=10e-3, R_off=1e9) (linear)
add_igbt_level1 (name, collector, emitter, gate, V_CE_sat=2.0, R_CE_sat=0.05, V_T=5.0, kappa=10.0)

DevicePool

Opaque parameter store. Most methods are not exposed to Python — you go through CircuitBuilder. Exceptions:

Method Returns Use case
has_nonlinear_devices() bool Auto-detect by simulate().

Source-helper factories

All return a Callable[[float], SwitchStateMask] ready for switch_fn=.

make_pwm_switch_fn(switch_index, frequency, duty, phase=0)

Single-bit PWM. Sets bit switch_index ON for the first duty · T of each period.

make_dead_time_pwm_pair_fn(high_switch_index, low_switch_index, frequency, duty, dead_time, phase=0)

Complementary half-bridge with anti-shoot-through dead-time.

make_spwm_pair_fn(high_switch_index, low_switch_index, carrier_frequency, modulating_frequency, modulation_index, phase=0)

Sinusoidal modulation of the duty.

make_three_phase_spwm_fn(leg_indices, carrier_frequency, modulating_frequency, modulation_index, phase=0)

6-switch inverter. leg_indices = ThreePhaseLegIndices(a_high, a_low, b_high, b_low, c_high, c_low).

make_phase_shift_full_bridge_fn(diag1_switch_index, diag2_switch_index, frequency, phase_shift)

4-switch full-bridge ZVS phase-shifted modulation.

make_combined_switch_fn(*switch_fns)

Bit-wise OR of multiple switch_fn callables. Useful when you have an SPWM scheduler + an auxiliary low-frequency relay on the same mask.

SimulationOptions / SimulationResult

opts = p.SimulationOptions(t_start=0.0, t_end=1e-3, dt=1e-5)
opts.valid()                  # bool
opts.max_newton_iterations    # int (engine default if 0)
opts.max_event_iterations     # int
opts.newton_tol_dx            # float
opts.event_tol_v              # float
opts.event_tol_i              # float

SimulationResult: - result.times — list[float] - result.states — list[numpy.ndarray] - result.commutations — list[CommutationEvent] (event-detection details) - result.num_steps() — int

YAML loader

loaded = p.load_yaml_file("examples/buck.yaml")
# or
loaded = p.load_yaml_string("""
nodes: [n0]
components: ...
""")
loaded.builder              # CircuitBuilder
loaded.switch_fn            # combined Callable
loaded.t_start, loaded.t_end, loaded.dt

Pass the result straight to simulate(loaded.builder, loaded.t_end, loaded.dt, switch_fn=loaded.switch_fn).

C++ namespace mapping

Python C++
pulsim.CircuitBuilder pulsim::builder::CircuitBuilder
pulsim.PwlStateSpaceCache pulsim::pwl::PwlStateSpaceCache
pulsim.run_transient pulsim::solver::run_transient
pulsim.make_pwm_switch_fn pulsim::sources::make_pwm_switch_fn

C++ code lives header-only under core/include/pulsim/. Includes you'll commonly need:

#include "pulsim/builder/circuit_builder.hpp"
#include "pulsim/pwl/pwl_state_space_cache.hpp"
#include "pulsim/solver/run_transient.hpp"
#include "pulsim/sources/make_pwm_switch_fn.hpp"
#include "pulsim/pwl/nonlinear_refresh_mosfet_level1.hpp"   // for combined refresh