Skip to contents

Runs a SPICE3 deck once per assignment of the swept parameters. The deck stays pure SPICE3 (there is no .step card): it is parsed once, and each run writes its values into the parsed deck, builds the circuit afresh and runs every analysis card, exactly as spice_run() would on the deck edited by hand – bit for bit.

Usage

spice_sweep(
  deck,
  ...,
  .mode = c("grid", "zip"),
  .includes = NULL,
  .options = NULL,
  .threads = 1L,
  .tmax_divisor = NULL
)

Arguments

deck

The deck, as in spice_run().

...

Named numeric vectors: swept parameter = its values. A data frame or list of draws can be spliced with !!!.

.mode

"grid" runs every combination, the first parameter varying slowest (as tidyr::expand_grid()); "zip" runs row by row and needs equal lengths (length-one values are recycled).

.includes, .options

As includes and options in spice_run(); the options apply to every run (a swept temp overrides options$temp).

.threads

Worker threads: 1 (the default) runs sequentially, 0 uses one per core, n uses n. Results are identical either way: every run is an independent circuit.

.tmax_divisor

As tmax_divisor in spice_run(), for every run.

Value

A spice_sweep: a list with

  • title: the deck's title line;

  • params: a tibble with run (the run index, from 1) and one double column per swept parameter, named in canonical form ("r1", "@m1[w]", "temp");

  • runs: a list of spice_result, one per run (each with the deck's .measure cards evaluated in its measurements);

  • diagnostics: the deck's parser warnings, as in spice_run().

spice_tidy() turns it into one long tibble.

Details

The simulator holds no random generator: a Monte Carlo is a "zip" sweep over draws you make with stats::rnorm() and friends, so it is reproducible from your own set.seed().

Parameter names

Matched case-insensitively:

  • temp: circuit temperature in degrees Celsius (as .options temp=);

  • an element name: r1, c1, l1 for its value, vin, iin for a source's DC level;

  • the ngspice form @name[param]: @r1[resistance], @c1[capacitance], @l1[inductance], @vin[dc], @vin[acmag], @vin[acphase] (degrees), @m1[w], @m1[l] (MOSFET width and length, m). Non-syntactic names need backticks: spice_sweep(deck, `@m1[w]` = c(2e-6, 4e-6)).

Elements inside subcircuits go by their expanded names (r.x1.r1). Model parameters are not sweepable yet.

Errors

An unknown element or parameter, a parameter given twice or a non-finite value is a spice_error_sweep. A run that fails to build or simulate stops the sweep with the error class of spice_run() (spice_error_elaborate, spice_error_analysis, or spice_error_pss with the shooting history for a .pss that did not converge), naming the run and its values.

Mirror of the Python package

This is the R face of spice.sweep() in Python. Run indices are 1-based here and 0-based in Python.

Examples

deck <- "rc low-pass
vin 1 0 dc 0 ac 1
r1 1 2 1k
c1 2 0 1u
.ac dec 5 10 10k
.end"
sw <- spice_sweep(deck, r1 = c(500, 1000, 2000))
sw
#> <spice_sweep> rc low-pass
#> 3 runs over r1
#> plots: "AC Analysis"
head(spice_tidy(sw))
#> # A tibble: 6 × 13
#>     run    r1 plot       point scale_name scale variable type     re    im   mag
#>   <int> <dbl> <chr>      <int> <chr>      <dbl> <chr>    <chr> <dbl> <dbl> <dbl>
#> 1     1   500 AC Analys…     1 frequency   10   v(1)     volt…     1     0     1
#> 2     1   500 AC Analys…     2 frequency   15.8 v(1)     volt…     1     0     1
#> 3     1   500 AC Analys…     3 frequency   25.1 v(1)     volt…     1     0     1
#> 4     1   500 AC Analys…     4 frequency   39.8 v(1)     volt…     1     0     1
#> 5     1   500 AC Analys…     5 frequency   63.1 v(1)     volt…     1     0     1
#> 6     1   500 AC Analys…     6 frequency  100   v(1)     volt…     1     0     1
#> # ℹ 2 more variables: db <dbl>, phase <dbl>

# Monte Carlo: 5% resistor and capacitor, reproducible from the seed
set.seed(1)
mc <- spice_sweep(deck,
  r1 = rnorm(20, 1000, 50), c1 = rnorm(20, 1e-6, 5e-8),
  .mode = "zip"
)
mc$params
#> # A tibble: 20 × 3
#>      run    r1          c1
#>    <int> <dbl>       <dbl>
#>  1     1  969. 0.00000105 
#>  2     2 1009. 0.00000104 
#>  3     3  958. 0.00000100 
#>  4     4 1080. 0.000000901
#>  5     5 1016. 0.00000103 
#>  6     6  959. 0.000000997
#>  7     7 1024. 0.000000992
#>  8     8 1037. 0.000000926
#>  9     9 1029. 0.000000976
#> 10    10  985. 0.00000102 
#> 11    11 1076. 0.00000107 
#> 12    12 1019. 0.000000995
#> 13    13  969. 0.00000102 
#> 14    14  889. 0.000000997
#> 15    15 1056. 0.000000931
#> 16    16  998. 0.000000979
#> 17    17  999. 0.000000980
#> 18    18 1047. 0.000000997
#> 19    19 1041. 0.00000106 
#> 20    20 1030. 0.00000104