public void When_ParallelMultiplierTransient_Expect_Reference() { // Create circuit // WARNING: We simulate both possibilities together, because the // timestep varies if we split them due to different timestep truncation. var ckt = new Circuit( new VoltageSource("V1r", "inr", "0", new Pulse(1, 5, 1e-6, 1e-9, 0.5e-6, 2e-6, 6e-6)), new VoltageSource("Vsupplyr", "vddr", "0", 5), new Resistor("R1r", "outr", "vddr", 1.0e3), CreateMOS1("M1r", "outr", "inr", "0", "0", "MM"), CreateMOS1("M2r", "outr", "inr", "0", "0", "MM"), new VoltageSource("V1a", "ina", "0", new Pulse(1, 5, 1e-6, 1e-9, 0.5e-6, 2e-6, 6e-6)), new VoltageSource("Vsupplya", "vdda", "0", 5), new Resistor("R1a", "outa", "vdda", 1.0e3), CreateMOS1("M1a", "outa", "ina", "0", "0", "MM") .SetParameter("m", 2.0), CreateMOS1Model("MM", "IS=1e-32 VTO=3.03646 LAMBDA=0 KP=5.28747 CGSO=6.5761e-06 CGDO=1e-11") ); // Create simulation var tran = new Transient("tran", 1e-9, 10e-6); tran.BiasingParameters.Gmin = 0.0; // May interfere with comparison var v_ref = new RealVoltageExport(tran, "outr"); var v_act = new RealVoltageExport(tran, "outa"); tran.ExportSimulationData += (sender, args) => { var tol = Math.Max(Math.Abs(v_ref.Value), Math.Abs(v_act.Value)) * CompareRelTol + CompareAbsTol; Assert.AreEqual(v_ref.Value, v_act.Value, tol); }; tran.Run(ckt); }
public void When_LowpassRLOP_Expect_Reference() { /* * Lowpass RL circuit * The inductor should act like an short circuit */ var ckt = new Circuit( new VoltageSource("V1", "IN", "0", 1.0), new Inductor("L1", "IN", "OUT", 1e-3), new Resistor("R1", "OUT", "0", 1.0e3)); // Create simulation var op = new OP("op"); // Create exports var exports = new IExport <double> [1]; exports[0] = new RealVoltageExport(op, "OUT"); // Create references double[] references = { 1.0 }; // Run test AnalyzeOp(op, ckt, exports, references); DestroyExports(exports); }
public void When_BasicCircuitExports_Expect_NoException() { // Build the circuit var ckt = new Circuit( new VoltageSource("V1", "in", "0", 1.0), new Resistor("R1", "in", "out", 1.0e4), new Resistor("R2", "out", "0", 2.0e4) ); // <example01_simulate2> // Create a DC simulation that sweeps V1 from -1V to 1V in steps of 100mV var dc = new DC("DC 1", "V1", -1.0, 1.0, 0.2); // Create exports Export <double> inputExport = new RealVoltageExport(dc, "in"); Export <double> outputExport = new RealVoltageExport(dc, "out"); Export <double> currentExport = new RealPropertyExport(dc, "V1", "i"); // Catch exported data dc.ExportSimulationData += (sender, args) => { var input = inputExport.Value; var output = outputExport.Value; var current = currentExport.Value; }; dc.Run(ckt); // </example01_simulate2> }
public void When_Inductor_LowpassRLOperatingPoint_Expect_Reference() { /* * Lowpass RL circuit * The inductor should act like an short circuit */ Circuit ckt = new Circuit(); ckt.Objects.Add( new VoltageSource("V1", "IN", "0", 1.0), new Inductor("L1", "IN", "OUT", 1e-3), new Resistor("R1", "OUT", "0", 1.0e3)); // Create simulation OP op = new OP("op"); // Create exports Export <double>[] exports = new Export <double> [1]; exports[0] = new RealVoltageExport(op, "OUT"); // Create references double[] references = { 1.0 }; // Run test AnalyzeOp(op, ckt, exports, references); }
public void When_IntegrateTransient_Expect_Reference() { var ckt = new Circuit( new CurrentSource("Itmp", "a", "0", new Sine(0, 1, 100)), new Capacitor("C1", "a", "0", 1.0), // this will integrate the variable new VoltageSource("Vtmp", "b", "0", new Sine(0, 1, 100)), new BehavioralVoltageSource("V1", "in", "0", "idt(V(b))")); var tran = new Transient("tran", 1e-3, 0.1); tran.TimeParameters.InitialConditions["a"] = 0.0; var expectedExport = new RealVoltageExport(tran, "a"); var actualExport = new RealVoltageExport(tran, "in"); tran.ExportSimulationData += (sender, args) => { if (args.Time > 0) { var expected = expectedExport.Value; var actual = -actualExport.Value; Assert.AreEqual(expected, actual, 1e-9); } }; tran.Run(ckt); }
public void When_TransientRerun_Expect_Same() { // Create the circuit var ckt = new Circuit( new VoltageSource("V1", "in", "0", 10.0), new Resistor("R1", "in", "out", 10), new Capacitor("C1", "out", "0", 20) ); // Create the transient analysis var tran = new Transient("tran 1", 1.0, 10.0); tran.TimeParameters.InitialConditions["out"] = 0; var export = new RealVoltageExport(tran, "out"); // Run the simulation a first time for building the reference values var r = new List <double>(); void BuildReference(object sender, ExportDataEventArgs args) => r.Add(export.Value); tran.ExportSimulationData += BuildReference; tran.Run(ckt); tran.ExportSimulationData -= BuildReference; // Rerun the simulation for building the reference values var index = 0; void CheckReference(object sender, ExportDataEventArgs args) => Assert.AreEqual(r[index++], export.Value, 1e-20); tran.ExportSimulationData += CheckReference; tran.Rerun(); tran.ExportSimulationData -= CheckReference; }
public void When_Capacitor_LowpassRCOperatingPoint_Expect_Reference() { /* * Lowpass RC circuit * The capacitor should act like an open circuit */ var ckt = new Circuit( new VoltageSource("V1", "IN", "0", 1.0), new Resistor("R1", "IN", "OUT", 10e3), new Capacitor("C1", "OUT", "0", 1e-6)); // Create simulation var op = new OP("op"); // Create exports var exports = new Export <double> [1]; exports[0] = new RealVoltageExport(op, "OUT"); // Create references double[] references = { 1.0 }; // Run test AnalyzeOp(op, ckt, exports, references); }
public void When_RCFilterTransient_Expect_NoException() { // <example_Transient> // Build the circuit var ckt = new Circuit( new VoltageSource("V1", "in", "0", new Pulse(0.0, 5.0, 0.01, 1e-3, 1e-3, 0.02, 0.04)), new Resistor("R1", "in", "out", 10.0e3), new Capacitor("C1", "out", "0", 1e-6) ); // Create the simulation var tran = new Transient("Tran 1", 1e-3, 0.1); // Make the exports var inputExport = new RealVoltageExport(tran, "in"); var outputExport = new RealVoltageExport(tran, "out"); // Simulate tran.ExportSimulationData += (sender, args) => { var input = inputExport.Value; var output = outputExport.Value; }; tran.Run(ckt); // </example_Transient> }
public void When_ChangeParameterInTransient_Expect_NoException() { // <example_change_parameter_circuit> // Build a circuit var ckt = new Circuit( new Resistor("R1", "in", "out", 1.0e3), new Resistor("R2", "out", "0", 1.0e3), new Capacitor("C1", "out", "0", 0.5e-9), new VoltageSource("V1", "in", "0", new Pulse(0, 5, 1e-6, 1e-6, 1e-6, 1e-5, 2e-5)) ); // </example_change_parameter_circuit> // <example_change_parameter_transient> // Create the transient analysis and exports var tran = new Transient("tran", 1e-6, 10e-5); var outputExport = new RealVoltageExport(tran, "out"); tran.ExportSimulationData += (sender, args) => { var time = args.Time; var output = outputExport.Value; }; // </example_change_parameter_transient> // <example_change_parameter_setup> // Now we need to make sure we have a reference to both the base parameters and temperature behavior // of the resistor SpiceSharp.Components.ResistorBehaviors.BaseParameters bp = null; SpiceSharp.Components.ResistorBehaviors.TemperatureBehavior tb = null; tran.AfterSetup += (sender, args) => { tran.EntityParameters["R2"].TryGet(out bp); tran.EntityBehaviors["R2"].TryGet(out tb); }; // </example_change_parameter_setup> // <example_change_parameter_load> // Before loading the resistor, let's change its value first! tran.BeforeLoad += (sender, args) => { // First we need to figure out the timepoint that will be loaded var time = tran.Method.Time; // Then we need to calculate the resistance for "R2" var resistance = 1.0e3 * (1 + time * 1.0e5); // Now let's update the parameter if (bp == null || tb == null) { return; } bp.Resistance.Value = resistance; tb.Temperature(tran); }; // Run the simulation tran.Run(ckt); // </example_change_parameter_load> }
/// <summary> /// Initializes a new instance of the <see cref="VoltageRealExport"/> class. /// </summary> /// <param name="name">Name of export.</param> /// <param name="simulation">Simulation</param> /// <param name="node">Positive node</param> /// <param name="reference">Negative reference node</param> public VoltageRealExport(string name, Simulation simulation, string node, string reference = null) : base(simulation) { Name = name ?? throw new System.ArgumentNullException(nameof(name)); Node = node ?? throw new System.ArgumentNullException(nameof(node)); Reference = reference; ExportImpl = new RealVoltageExport((BaseSimulation)simulation, node, reference); }
public void When_MutualInductanceTransient_Expect_Reference() { /* * Step function generator connect to a resistor-inductor in series, coupled to an inductor shunted by another resistor. * This linear circuit can be solved analytically. The result may deviate because of truncation errors (going to discrete * time points). */ // Create circuit var r1 = 100.0; var r2 = 500.0; var l1 = 10e-3; var l2 = 2e-3; var k = 0.693; var ckt = new Circuit( new VoltageSource("V1", "IN", "0", 1.0), new Resistor("R1", "IN", "1", r1), new Inductor("L1", "1", "0", l1) .SetParameter("ic", 0.0), new Inductor("L2", "OUT", "0", l2), new Resistor("R2", "OUT", "0", r2), new MutualInductance("M1", "L1", "L2", k) ); // Create simulation var tran = new Transient("tran", 1e-9, 1e-4, 1e-6); tran.TimeParameters.InitialConditions["1"] = 0; // Create exports var exports = new IExport <double> [1]; exports[0] = new RealVoltageExport(tran, "OUT"); // Create references var mut = k * Math.Sqrt(l1 * l2); var a = l1 * l2 - mut * mut; var b = r1 * l2 + r2 * l1; var c = r1 * r2; var discriminant = Math.Sqrt(b * b - 4 * a * c); var invtau1 = (-b + discriminant) / (2.0 * a); var invtau2 = (-b - discriminant) / (2.0 * a); var factor = mut * r2 / a / (invtau1 - invtau2); Func <double, double>[] references = { t => factor * (Math.Exp(t * invtau1) - Math.Exp(t * invtau2)) }; // Increase the allowed threshold // It should also be verfied that the error decreases if the maximum timestep is decreased AbsTol = 1.5e-3; // Run test AnalyzeTransient(tran, ckt, exports, references); DestroyExports(exports); }
/// <summary> /// Initializes a new instance of the <see cref="VoltageExport"/> class. /// </summary> /// <param name="name">Name of export.</param> /// <param name="simulation">Simulation.</param> /// <param name="node">Positive node.</param> /// <param name="reference">Negative reference node.</param> public VoltageExport(string name, Simulation simulation, string node, string reference = null) : base(simulation) { Name = name ?? throw new System.ArgumentNullException(nameof(name)); Node = node ?? throw new System.ArgumentNullException(nameof(node)); Reference = reference; if (simulation is FrequencySimulation fs) { ExportImpl = new ComplexVoltageExport(fs, node, reference); } else { ExportRealImpl = new RealVoltageExport((IBiasingSimulation)simulation, node, reference); } }
public void When_Static_Expect_Reference() { var ckt = new Circuit( new VoltageSource("V1", "in", "0", 1.0), new VoltageControlledVoltageSource("E1", "ref", "0", "in", "0", 2.0), new LaplaceVoltageControlledVoltageSource("E2", "act", "0", "in", "0", new[] { 2.0 }, new[] { 1.0 })); var op = new OP("op"); var r = new RealVoltageExport(op, "ref"); var a = new RealVoltageExport(op, "act"); op.ExportSimulationData += (sender, args) => { Assert.AreEqual(r.Value, a.Value, 1e-12); }; op.Run(ckt); }
public void When_TransientLC_Expect_Reference() { var ckt = new Circuit( new VoltageSource("V1", "in", "0", new Pulse(0, 1, 1e-6, 1e-9, 1e-9, 1e-6, 2e-6)), new Inductor("L1", "in", "out", 1e-3), new Capacitor("C1", "out", "0", 1e-3), new LaplaceVoltageControlledVoltageSource("E1", "act", "0", "in", "0", new[] { 1.0 }, new[] { 1.0, 0.0, 1.0e-6 })); var tran = new Transient("tran", 1e-7, 5e-6); var r = new RealVoltageExport(tran, "out"); var a = new RealVoltageExport(tran, "act"); tran.ExportSimulationData += (sender, args) => { Assert.AreEqual(r.Value, a.Value, 1e-12); }; tran.Run(ckt); }
public void When_ParallelMultiplierTransient_Expect_Reference() { // Create circuit // WARNING: We simulate both possibilities together, because the // timestep varies if we split them due to different timestep truncation. var ckt = new Circuit( new VoltageSource("V1r", "inr", "0", new Pulse(1, 5, 1e-6, 1e-9, 0.5e-6, 2e-6, 6e-6)), new VoltageSource("Vsupplyr", "vddr", "0", 5), new Resistor("R1r", "outr", "0", 1.0e3), CreateMOS3("M1r", "outr", "inr", "vddr", "vddr", "DMOS") .SetParameter("w", 1e-6) .SetParameter("l", 1e-6), CreateMOS3("M2r", "outr", "inr", "vddr", "vddr", "DMOS") .SetParameter("w", 1e-6) .SetParameter("l", 1e-6), new VoltageSource("V1a", "ina", "0", new Pulse(1, 5, 1e-6, 1e-9, 0.5e-6, 2e-6, 6e-6)), new VoltageSource("Vsupplya", "vdda", "0", 5), new Resistor("R1a", "outa", "0", 1.0e3), CreateMOS3("M1a", "outa", "ina", "vdda", "vdda", "DMOS") .SetParameter("w", 1e-6) .SetParameter("l", 1e-6) .SetParameter("m", 2.0), CreateMOS3Model("DMOS", false, "VTO = -0.7 KP = 3.8E+1 THETA = .25 VMAX = 3.5E5 KF=1e-24")); // Create simulation var tran = new Transient("tran", 1e-9, 10e-6); tran.BiasingParameters.Gmin = 0.0; // May interfere with comparison var v_ref = new RealVoltageExport(tran, "outr"); var v_act = new RealVoltageExport(tran, "outa"); tran.ExportSimulationData += (sender, args) => { var tol = Math.Max(Math.Abs(v_ref.Value), Math.Abs(v_act.Value)) * CompareRelTol + CompareAbsTol; Assert.AreEqual(v_ref.Value, v_act.Value, tol); }; tran.Run(ckt); v_ref.Destroy(); v_act.Destroy(); }
public void When_TransientCR_Expect_Reference() { // High-pass RC filter var ckt = new Circuit( new VoltageSource("V1", "in", "0", new Pulse(0, 1, 1e-6, 1e-9, 1e-9, 1e-6, 2e-6)), new Capacitor("C1", "in", "out", 1e-6), new Resistor("R1", "out", "0", 1e3), new LaplaceVoltageControlledCurrentSource("G1", "0", "act", "in", "0", new[] { 0.0, 1.0e-3 }, new[] { 1.0, 1.0e-3 }), new Resistor("R2", "act", "0", 1.0)); var tran = new Transient("tran", 1e-7, 5e-6); var r = new RealVoltageExport(tran, "out"); var a = new RealVoltageExport(tran, "act"); tran.ExportSimulationData += (sender, args) => { Assert.AreEqual(r.Value, a.Value, 1e-12); }; tran.Run(ckt); }
public void When_MultipliersTransient_Expect_Reference() { /* * Pulsed voltage source towards a resistive voltage divider between 0V and 5V * Output voltage is expected to behavior like the reference */ // Build circuit var model = CreateDiodeModel("1N914", "Is = 2.52e-9 Rs = 0.568 N = 1.752 Cjo = 4e-12 M = 0.4 tt = 20e-9"); var ckt = new Circuit( new VoltageSource("V1r", "inr", "0", new Pulse(0, 5, 1e-6, 10e-9, 10e-9, 1e-6, 2e-6)), new VoltageSource("Vsupplyr", "vddr", "0", 5.0), new Resistor("R1r", "vddr", "outr", 10.0e3), new Resistor("R2r", "outr", "0", 10.0e3), new VoltageSource("V1a", "ina", "0", new Pulse(0, 5, 1e-6, 10e-9, 10e-9, 1e-6, 2e-6)), new VoltageSource("Vsupplya", "vdda", "0", 5.0), new Resistor("R1a", "vdda", "outa", 10.0e3), new Resistor("R2a", "outa", "0", 10.0e3), model, new Diode("D1", "ina", "outa", model.Name) .SetParameter("m", 3.0) .SetParameter("n", 2.0)); ParallelSeries(ckt, name => new Diode(name, "", "", model.Name), "inr", "outr", 3, 2); // Create simulation var tran = new Transient("tran", 1e-9, 10e-6); tran.BiasingParameters.Gmin = 0.0; // May interfere with comparison var v_ref = new RealVoltageExport(tran, "outr"); var v_act = new RealVoltageExport(tran, "outa"); tran.ExportSimulationData += (sender, args) => { var tol = Math.Max(Math.Abs(v_ref.Value), Math.Abs(v_act.Value)) * CompareRelTol + CompareAbsTol; Assert.AreEqual(v_ref.Value, v_act.Value, tol); }; tran.Run(ckt); v_ref.Destroy(); v_act.Destroy(); }
public void When_DerivativeTransient_Expect_Reference() { var ckt = new Circuit( new VoltageSource("Vtmp", "a", "0", new Sine(0, 1, 100)), new Capacitor("C1", "a", "0", 1.0), // this will derive the variable new BehavioralVoltageSource("V1", "in", "0", "ddt(V(a))")); var tran = new Transient("tran", 1e-3, 0.1); var expectedExport = new RealCurrentExport(tran, "Vtmp"); var actualExport = new RealVoltageExport(tran, "in"); tran.ExportSimulationData += (sender, args) => { if (args.Time > 0) { var expected = expectedExport.Value; var actual = -actualExport.Value; Assert.AreEqual(expected, actual, 1e-9); } }; tran.Run(ckt); }
public void When_ExportSwitch_Expect_Reference() { var ckt = new Circuit( new VoltageSource("V1", "in", "0", new Sine(1, 1, 10)), new Resistor("R1", "in", "out", 1e3), new Resistor("R2", "out", "0", 1e3)); var sim1 = new DC("dc", "V1", 0, 2, 0.2); var sim2 = new Transient("tran", 1e-3, 0.5); var vexport = new RealVoltageExport(sim1, "out"); var iexport = new RealCurrentExport(sim1, "V1"); var pexport = new RealPropertyExport(sim1, "R1", "p"); sim1.ExportSimulationData += (sender, e) => { var input = e.GetVoltage("in"); Assert.AreEqual(input * 0.5, vexport.Value, 1e-9); Assert.AreEqual(-input / 2.0e3, iexport.Value, 1e-9); Assert.AreEqual(input * input / 4.0 / 1.0e3, pexport.Value, 1e-9); }; sim2.ExportSimulationData += (sender, e) => { var input = e.GetVoltage("in"); Assert.AreEqual(Math.Sin(2 * Math.PI * 10 * e.Time) + 1.0, input, 1e-9); Assert.AreEqual(input * 0.5, vexport.Value, 1e-9); Assert.AreEqual(-input / 2.0e3, iexport.Value, 1e-9); Assert.AreEqual(input * input / 4.0 / 1.0e3, pexport.Value, 1e-9); }; sim1.Run(ckt); // Switch exports vexport.Simulation = sim2; iexport.Simulation = sim2; pexport.Simulation = sim2; sim2.Run(ckt); }