Running a DC simulation

Spice.NET follows the original Spice framework. In order to run a simulation, we first need a SpiceTask. This SpiceTask object can contain multiple Analysis objects (such as DC, AC, etc.) that describe how to do a simulation. Finally, each Analysis object contains one or more Job objects, that tell the analysis what to analyze.

We are going to execute a DC simulation. We start out by creating a DC analysis object, and adding a TrcvJob object to it with the DC simulation data. For this we need to include the SpiceNet.Simulations namespace.

/// <summary>
/// Perform a DC simulation
/// </summary>
/// <param name="ckt">The circuit</param>
/// <param name="source">The name of the source to be swept</param>
/// <param name="start">The initial value of the source</param>
/// <param name="stop">The final value of the source</param>
/// <param name="step">The increment of dc values</param>
private void DoDC(Circuit ckt, string source, double start, double stop, double step)
{
    SpiceTask task = new SpiceTask("Task 1");

    // Create a DC analysis with a job
    DC dc = new DC();
    dc.AddJob(new TrcvJob(source, start, stop, step));
    dc.ExportData += Export;

    // Add the DC analysis to the task and run it
    task.Analyses.Add(dc);
    ckt.DoJob(true, task);
}

The property ExportData is the event that is called when new simulation data is available. This method is used to extract information that needs to be processed. Most of the information we need is contained in the State property of the circuit. The current solution is stored in State.Solution as a Math.NET vector. Every voltage is somewhere in this vector.
In order to find out which item we need to use as the voltage, we can use the Nodes property of the circuit.

For example, we are interested in the voltage of node "OUT". So we first ask the Nodes-property for the index number of node "OUT". Then we access that element in the State.Solution vector to finally get the voltage.

Here is the full code again:
using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using SpiceNet.Circuits;
using SpiceNet.Models;
using SpiceNet.Simulations;

namespace SpiceNetTest
{
    public partial class Form1 : Form
    {
        private Series serieOutput;

        /// <summary>
        /// Constructor
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            // Setup the chart
            chartResults.Series.Clear();
            serieOutput = chartResults.Series.Add("Output");
            serieOutput.ChartType = SeriesChartType.FastLine;
            chartResults.ChartAreas[0].AxisX.Minimum = -5.0;
            chartResults.ChartAreas[0].AxisX.Maximum = 5.0;

            // Create a circuit
            Circuit ckt = new Circuit();

            // Add devices to the circuit
            ckt.Add(new VoltageSource("V1", "IN", "GND", 1.0));
            ckt.Add(new Resistor("R1", "IN", "OUT", 1.0e3));

            // Create the diode model
            Model model = new DiodeModel("1N4148");
            model["is"] = 4.352e-9;
            model["n"] = 1.906;
            model["bv"] = 110;
            model["ibv"] = 0.0001;
            model["rs"] = 0.6458;
            model["cjo"] = 7.048e-13;
            model["vj"] = 0.869;
            model["m"] = 0.03;
            model["fc"] = 0.5;
            model["tt"] = 3.48e-9;
            model.Add(new Diode("D1", "OUT", "GND"));
            ckt.Add(model);

            // Perform a DC analysis from -5V to 5V in steps of 1mV
            DoDC(ckt, "V1", -5.0, 5.0, 1.0e-3);
        }

        /// <summary>
        /// Perform a DC simulation
        /// </summary>
        /// <param name="ckt">The circuit</param>
        /// <param name="source">The name of the source to be swept</param>
        /// <param name="start">The initial value of the source</param>
        /// <param name="stop">The final value of the source</param>
        /// <param name="step">The increment of dc values</param>
        private void DoDC(Circuit ckt, string source, double start, double stop, double step)
        {
            SpiceTask task = new SpiceTask("Task 1");

            // Create a DC analysis with a job
            DC dc = new DC();
            dc.AddJob(new TrcvJob(source, start, stop, step));
            dc.ExportData += Export;

            // Add the DC analysis to the task and run it
            task.Analyses.Add(dc);
            ckt.DoJob(true, task);
        }

        /// <summary>
        /// Export the data to the chart
        /// </summary>
        /// <param name="a"></param>
        /// <param name="ckt"></param>
        private void Export(Analysis a, Circuit ckt)
        {
            // Just like in the original Spice code, the "time" parameter is 
            // used for the swept variable value
            // Note that we could just as well extract the voltage at node "IN" as well
            double voltage_in = ckt.State.Time; // Not really time though...

            // Get the index of node "OUT" and use it to extract the voltage
            int index_out = ckt.Nodes["OUT"].Number;
            double voltage_out = ckt.State.Solution[index_out];

            // Add the point to the graph
            serieOutput.Points.AddXY(voltage_in, voltage_out);
        }
    }
}



 

Last edited Feb 5 at 8:27 AM by SBoulang, version 7