The ahkab core module

Introduction

This is the core module of the simulator. It provides helper functions to save you the need to call directly the functions in most submodules.

Do you have a circuit?

To run a simulation, you’ll need a circuit first: a circuit can be described with a simulation deck or with a circuit object.

Define your circuit by means of a Circuit object

In a Python script, describing the circuit through the ahkab.circuit.Circuit interface is a very versatile a choice.

Refer to ahkab.circuit.Circuit for a complete description of the process and the documentation of several helper functions to assist you in this task.

You may then jump to How to create a simulation object.

Define your circuit by means of a netlist file

The circuit description can also be provided as a text file, also known as netlist deck, for historical reason. This file will also typically include simulation and post-processing directives, such as plotting.

The netlist should be described according to the rules in Netlist Syntax.

If you have a netlist (simulation deck) available, you have several possibilities.

The first, assuming your netlist defines some simulation would be to run it:

  • you may call ahkab from the command line. The command line interface is described in Command line help.
  • you may call main() directly from Python. Running the simulation through main() function allows to process the result in Python.

Alternatively, you may parse the netlist through ahkab.netlist_parser.parse_circuit(), which will return the circuit instance, all the simulations defined in the deck and all the post-processing directives as well.

You may now modify the circuit and simulation objects as you please, or create new ones, as well as run them as described in the Run it! section.

How to create a simulation object

Next, you need to have a simulation object you would like to run.

The following functions are available to quickly create a simulation object:

new_ac(start, stop, points[, x0, ...]) Assembles an AC analysis and returns the analysis object.
new_dc(start, stop, points, source[, ...]) Assembles a DC sweep analysis and returns the analysis object.
new_op([guess, x0, outfile, verbose]) Assembles an OP analysis and returns the analysis object.
new_pss(period[, x0, points, method, ...]) Assembles a Periodic Steady State (PSS) analysis and returns the analysis object.
new_pz([input_source, output_port, shift, ...]) Assembles a Pole-Zero analysis and returns the analysis object.
new_symbolic([source, ac_enable, r0s, subs, ...]) Assembles a Symbolic analysis and returns the analysis object.
new_tran(tstart, tstop, tstep[, x0, method, ...]) Assembles a TRAN analysis and returns the analysis object.

Click on one of the above hyperlinks to be taken to the corresponding documentation section.

Note

The functions above allow you to specify an output file. This is due to two main reasons:

  • Saving to a file allows you to keep a copy of the simulation results, which you can then inspect at a later time.
  • Simulation results may take an uncomfortably large amount of memory. The approach we take is that we save everything to file, and only load the data to memory when the user actually accesses it.

In order for the latter to work when no output file is specified, ahkab stores the simulation data in a temporary file provided by your OS. When the user exits the Python interpreter (or IPython or debugger), the file is removed.

Run it!

Once you have a circuit and one or more simulations, it’s time to run them!

The following methods are available to do so:

run(circ[, an_list]) Run analyses on a circuit.
queue(*analysis) Queue one or more analyses to execute them subsequently with run().

The run() function will return the results in dictionary form.

Extras

The core module also contains a few extra methods which were deemed important enough to be inserted here.

In particular, the get_op_x0() method allows the user to quickly compute an operating point to be used to specify the linearization point for a more complex analysis and icmodified_x0() allows the user to modify said operating point to take into account the user-specified initial conditions in the circuit description.

Lastly, set_temperature() can be used to quickly set the simulation temperature.

All methods in alphabetical order

get_op_x0(circ)[source]

Shorthand to specify and run an OP analysis to get a linearization point.

Parameters:

circ : circuit instance
The circuit instance for which the linearization point is sought.

Returns:

x0 : an OP solution object
The linearization point.
icmodified_x0(circ, x0)[source]

Modify x0 to take into account the ICs in the circuit.

Parameters:

circ : circuit instance
The circuit instance from which the initial conditions are to be extracted.
x0 : numpy array
The vector to which the initial conditions are to be applied.
main(filename, outfile=u'stdout', verbose=3)[source]

Method to call ahkab from a Python script with a netlist file.

Parameters:

filename : string
The netlist filename.
outfile : string, optional
The outfiles base name, the suffixes shown below will be added. With the exception of the magic value stdout which causes ahkab to print out instead of to disk.
verbose : int, optional
the verbosity level, from 0 (silent) to 6 (debug). It defaults to 3, the same as running ahkab through its command line interface.

Filename suffixes, for each analysis:

  • Alternate Current (AC): .ac
  • Direct Current (DC): .dc
  • Operating Point (OP): .opinfo
  • Periodic Steady State (PSS): .pss
  • Pole-zero Analysis (PZ): .pz
  • TRANsient (TRAN): .tran
  • Symbolic: .symbolic

Returns:

res : dict
A dictionary containing the computed results.
new_ac(start, stop, points, x0=u'op', sweep_type=u'LOG', outfile=None, verbose=0)[source]

Assembles an AC analysis and returns the analysis object.

The analysis itself can be run with ahkab.run(...) or queued with ahkab.queue(...) and then run subsequently.

Parameters:

start : float
the start angular frequency, \(\omega _{start}\).
stop : float
the stop angular frequency, \(\omega _{stop}\) (included in the sweep).
points : float
the number of points to be used the discretize the [start, stop] interval.
x0 : string or ndarray, optional
The linearization point for the AC analysis. If set to ‘op’ (default), the latest Operating point analysis will be used. Otherwise, you may supply your own linearization point in ndarray format.
sweep_type : string, optional
It can be set to either options.ac_lin_step (linear stepping) or options.ac_log_step (log10 stepping). Defaults to logarithmic stepping.
outfile : string, optional
the filename of the output file where the results will be written. ‘.ac’ is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
verbose : int, optional
the verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : dict
the analysis object (a dict)

See also

run(), queue()

new_dc(start, stop, points, source, sweep_type=u'LINEAR', guess=True, x0=None, outfile=None, verbose=0)[source]

Assembles a DC sweep analysis and returns the analysis object.

The analysis itself can be run with: ahkab.run(...) or queued and then run subsequently.

Parameters:

start : float
the start value for the sweep.
stop : float
the stop value for the sweep (included in the sweep points).
points : int
the number of sweep points.
source : string
the part_id of the independent current or voltage source to be swept.
sweep_type : string, optional
can be set to either options.dc_lin_step (linear stepping) or options.dc_log_step (log10 stepping). Defaults to linear.
guess : boolean, optional
if set to True, the analysis will start from an initial guess, hopefully speeding up the convergence of particularly stiff circuits.
x0 : numpy array, optional
if the guess option above is not used, one can provide a starting point directly, setting x0 to an opportunely sized numpy array. If both x0 and guess are set, x0 takes the precedence.
outfile : string, optional
the filename of the output file where the results will be written. ‘.dc’ is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
verbose : int, optional
the verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : dict
the analysis description

See also

run(), queue()

new_op(guess=None, x0=None, outfile=None, verbose=0)[source]

Assembles an OP analysis and returns the analysis object.

The analysis itself can then be run with: ahkab.run(...) or queued with ahkab.queue(...) and then run subsequently.

Parameters:

guess : boolean, optional
if set to True, the analysis will start from an initial guess, hopefully speeding up the convergence of stiff circuits.
x0 : matrix, optional
In alternative to the guess option above, one can provide an explicit starting point to the OP algorithm, setting x0 to an opportunely sized numpy array. FIXME mention help method here If both x0 and guess are set, x0 takes the precedence.
outfile : string, optional
the filename of the output file where the results will be written. .opinfo is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
verbose : int, optional
the verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : dict
the analysis description

See also

run(), queue()

new_pss(period, x0=None, points=None, method=u'brute-force', autonomous=False, outfile=None, verbose=0)[source]

Assembles a Periodic Steady State (PSS) analysis and returns the analysis object.

The analysis itself can be run with: ahkab.run(...) or queued with ahkab.queue(...) and then run subsequently.

Parameters:

period : float
the time period of the solution, in seconds. This value is required, autonomous circuits are currently unsupported.
x0 : numpy array, optional
the starting point solution, used at \(t=0\).
points : int, optional
the number of points to use to discretize the PSS solution. If not set, if method is ‘shooting’, defaults to options.shooting_default_points
method : string, optional
The method to be employed to attempt a PSS solution of the circuit. It can be either ahkab.BFPSS or ahkab.SHOOTING.
autonomous : bool, optional
Whether the circuit is autonomous or not. Non-autonomous circuits are currently unsupported!
mna, Tf, D : numpy arrays, optional
The matrices to be used to solve the circuit. They are optional, if they have already been computed, reusing them saves time.
outfile : string, optional
The filename of the output file where the results will be written. ‘.tran’ is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
verbose : int, optional
The verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : dict
the analysis object (a dict)

See also

run(), queue()

new_pz(input_source=None, output_port=None, shift=0.0, MNA=None, outfile=None, x0=u'op', verbose=0)[source]

Assembles a Pole-Zero analysis and returns the analysis object.

The analysis itself can be run with: ahkab.run(...) or queued with ahkab.queue(...) and then run subsequently.

Parameters:

input_source : str or instance
the input source for zero calculation
output_port : tuple or single node
the output port. If it is composed of only one node, then the second node is assumed to be GND.
shift : float, optional
Perform the calculation at a shifted freq shift.
MNA : ndarray, optional
the numpy matrix to be used to solve the circuit. It is optional, but, if it’s already been computed, reusing it will save time.
outfile : string, optional
The filename of the output file where the results will be written. ‘.pz’ is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
x0 : numpy array or str, optional
the optional linearization point. If set to a string, it must be the result of an .OP analysis (use 'op') or an .IC condition defined in the netlist. It has no effect on linear circuits.
verbose : int, optional
The verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : the analysis description object, a dict instance.

new_symbolic(source=None, ac_enable=True, r0s=False, subs=None, outfile=None, verbose=0)[source]

Assembles a Symbolic analysis and returns the analysis object.

The analysis itself can be run with ahkab.run(...) or queued with ahkab.queue(...) and then run subsequently.

Parameters:

source : string, optional
if source is set, the transfer function between the current or voltage source source and each circuit unknown will be evaluated, with symbolic evaluation of DC gain, poles and zeros. source is to be set to the part_id of an independent current or voltage source in the circuit, eg. 'V1' or 'Iin'. This computation should be avoided for large circuit, as indiscriminate transfer function, gain and singularities evaluation in large circuits can result in very long run times and needs a significant amount of RAM, on top of an already resource intensive symbolic analysis. We suggest manually evaluating selected transfer functions of interest instead.
ac_enable : bool, optional
If set to True (default), the frequency-dependent elements will be considered, otherwise the algorithm will focus on low frequency solutions, where all capacitors are replaced with open circuits and all inductors are short circuits, usually providing a much easier circuit.
r0s : bool, optional
If set to True, the finite output conductances of transistors go (where \(go = 1/r_0\)) will be taken into account, otherwise they will be considered infinite (default). The finite output conductances generally introduce a significant additional complexity in large circuits, sometimes of interest to the designer, sometimes simply introducing 2nd and 3rd order effects of little-to-no interest, which would produce no significant contribution in a numerical analysis, but come at a high computation price in a symbolic analysis. A possible approach in those cases may be disabling this option and explicitly introducing additional conductances where deemed of interest.
subs : dict, optional
subs is a dictionary of substitutions to be performed before attempting to solve the circuit. For example, if two resistances R1 and R2 are to be equal, set subs={'R2':'R1'} and R1 will be replaced by an instance of R2. This may simplify the solution (or allow finding one in reasonable time for complex circuits).
outfile : string, optional
The filename of the output file where the results will be written. ‘.symbolic’ is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
verbose : int, optional
The verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : dict
the analysis description

See also

run(), queue()

new_tran(tstart, tstop, tstep, x0=u'op', method=u'TRAP', use_step_control=True, outfile=None, verbose=0)[source]

Assembles a TRAN analysis and returns the analysis object.

The analysis itself can be run with ahkab.run(...) or queued with ahkab.queue(...) and then run subsequently.

Parameters:

tstart : float
the start time for the transient analysis.
tstop : float
the stop time.
tstep :float
the time step. If the step control is active, this is the minimum time step value that will be allowed during simulation.
x0 : numpy array, optional
the optional initial conditions point, \(x0 = x(t=0)\).
method : string , optional
the differentiation method to be used. Can be set to ‘IMPLICIT_EULER’, ‘TRAP’, ‘GEAR4’, ‘GEAR5’ or ‘GEAR6’. It defaults to ‘TRAP’.
use_step_control : boolean, optional
Whether ste control should be enabled or not. if set to False, the differentiation method will use a fixed time step equal to tstep.
outfile : string, optional
the filename of the output file where the results will be written. ‘.tran’ is automatically added at the end to prevent different analyses from overwriting each-other’s results. If unset or set to None, defaults to stdout, if the simulator was called from the command line, otherwise, if the simulator is run from an interactive session, a temporary file will be used to store the data.
verbose : int, optional
the verbosity level, from 0 (silent, default) to 6 (debug).

Returns:

an : dict
the analysis description

See also

run(), queue()

new_x0(circ, icdict)[source]

Builds an x0 matrix from user supplied values.

Supplying a custom x0 can be useful: - To aid convergence in tough circuits. - To start a transient simulation from a particular x0

Parameters:

circ : circuit instance
The circuit
icdict : dict
a dictionary specifying the node voltages and branch currents, where appropriate, in V and A, respectively, assembled as shown in the next section. All unspecified node voltages default to 0 V and all unspecified currents default to 0.

The user-specified values are to be provided as follows:

  • to specify a nodal voltage: {'V(node)':<voltage value>}
  • to specify a branch current: 'I(<element>)':<current value>}

Examples:

  • {'V(n1)':2.3, 'V(n2)':0.45, ...}
  • {'I(L1)':1.03e-3, I(V4):2.3e-6, ...}

Note

This simulator uses the normal convention, also known as the Passive sign convention.

Returns:

x0 : numpy array
The assembled x0.
process_postproc(postproc_list, title, results, outfilename)[source]

Runs the post-processing operations, such as plotting.

Not meant for end users.

deprecated in 0.10

Parameters:

postproc_list : list,
list of post processing operations
title : string
the deck title
results: dict
the results to be plotted (which may include including ones that are not needed too).
outfilename: string
if the plots are saved to disk, this is the filename without extension
queue(*analysis)[source]

Queue one or more analyses to execute them subsequently with run().

Parameters

analysis : one or more analysis descriptions.
The analyses to be queued.

Returns:

None

run(circ, an_list=None)[source]

Run analyses on a circuit.

Parameters:

circ : circuit instance
The circuit to be simulated.
an_list : list, optional
the list of analyses to be performed. If unset, it defaults to those queued with queue.

Returns:

results : dict
the results (in dict form)

See also

queue()

set_temperature(T)[source]

Set the simulation temperature, in Celsius.