/// <summary> /// Perform a test for DC analysis /// </summary> /// <param name="sim">Simulation</param> /// <param name="ckt">Circuit</param> /// <param name="exports">Exports</param> /// <param name="references">References</param> protected void AnalyzeDC(DC sim, Circuit ckt, IEnumerable <IExport <double> > exports, IEnumerable <Func <double, double> > references) { sim.ExportSimulationData += (sender, data) => { using var exportIt = exports.GetEnumerator(); using var referencesIt = references.GetEnumerator(); while (exportIt.MoveNext() && referencesIt.MoveNext()) { var actual = exportIt.Current?.Value ?? throw new ArgumentNullException(); var expected = referencesIt.Current?.Invoke(sim.GetCurrentSweepValue()[0]) ?? throw new ArgumentNullException(); var tol = Math.Max(Math.Abs(actual), Math.Abs(expected)) * RelTol + AbsTol; try { Assert.AreEqual(expected, actual, tol); } catch (Exception ex) { var sweeps = sim.DCParameters.Sweeps; var values = sim.GetCurrentSweepValue(); var msg = ex.Message + " at "; var index = 0; foreach (var sweep in sweeps) { msg += "{0}={1}".FormatString(sweep.Name, values[index++]) + ", "; } throw new Exception(msg, ex); } } }; sim.Run(ckt); }
public void When_DCSweepResistorParameter_Expect_Reference() { // Create the circuit var ckt = new Circuit( new VoltageSource("V1", "in", "0", 0), new Resistor("R1", "in", "out", 1.0e4), new Resistor("R2", "out", "0", 1.0e4) ); // Do a DC sweep where one of the sweeps is a parameter var dc = new DC("DC 1"); dc.DCParameters.Sweeps.Add(new ParameterSweep("R2", "resistance", new LinearSweep(0.0, 1e4, 1e3), container => { container.GetValue <ITemperatureBehavior>().Temperature(); })); // Sweep R2 from 0 to 10k per 1k dc.DCParameters.Sweeps.Add(new ParameterSweep("V1", new LinearSweep(0, 5, 0.1))); // Sweep V1 from 0V to 5V per 100mV // Run simulation dc.ExportSimulationData += (sender, args) => { var resistance = Math.Max(dc.GetCurrentSweepValue()[0], SpiceSharp.Components.Resistors.Parameters.MinimumResistance); var voltage = dc.GetCurrentSweepValue()[1]; var expected = voltage * resistance / (resistance + 1.0e4); Assert.AreEqual(expected, args.GetVoltage("out"), 1e-12); }; dc.Run(ckt); }
public void When_DCSweepResistorParameter_Expect_Reference() { // Note: We specify LinkParameters = false for entities that should not share data across different threads. // The voltage source and resistor R2 are swept for different instances so they should be completely independent. var ckt = new Circuit( new VoltageSource("V1", "in", "0", 0) { LinkParameters = false }, new Resistor("R1", "in", "out", 1.0e4), new Resistor("R2", "out", "0", 1.0e4) { LinkParameters = false } ); // Do a DC sweep where one of the sweeps is a parameter var dcSimulations = new List <DC>(); var n = 4; for (var i = 0; i < n; i++) { var dc = new DC("DC " + i); dc.DCParameters.Sweeps.Add(new ParameterSweep("R2", "resistance", new LinearSweep(0.0, 1e4, 1e3), container => { container.GetValue <ITemperatureBehavior>().Temperature(); })); // Sweep R2 from 0 to 10k per 1k dc.DCParameters.Sweeps.Add(new ParameterSweep("V1", new LinearSweep(1, 5, 0.1))); // Sweep V1 from 1V to 5V per 100mV dc.ExportSimulationData += (sender, args) => { var resistance = Math.Max(dc.GetCurrentSweepValue()[0], SpiceSharp.Components.Resistors.Parameters.MinimumResistance); var voltage = dc.GetCurrentSweepValue()[1]; var expected = voltage * resistance / (resistance + 1.0e4); Assert.AreEqual(expected, args.GetVoltage("out"), 1e-12); }; dcSimulations.Add(dc); } var maxConcurrentSimulations = 2; System.Threading.Tasks.Parallel.ForEach( dcSimulations, new ParallelOptions() { MaxDegreeOfParallelism = maxConcurrentSimulations }, (simulation) => simulation.Run(ckt)); }
public void When_NMOSIVCharacteristic_Expect_NoException() { // <example_DC> // Create the mosfet and its model var nmos = new Mosfet1("M1", "d", "g", "0", "0", "example"); var nmosmodel = new Mosfet1Model("example"); nmosmodel.SetParameter("kp", 150.0e-3); // Build the circuit var ckt = new Circuit( new VoltageSource("Vgs", "g", "0", 0), new VoltageSource("Vds", "d", "0", 0), nmosmodel, nmos ); // Sweep the base current and vce voltage var dc = new DC("DC 1", new[] { new ParameterSweep("Vgs", new LinearSweep(0, 3, 0.2)), new ParameterSweep("Vds", new LinearSweep(0, 5, 0.1)), }); // Export the collector current var currentExport = new RealPropertyExport(dc, "M1", "id"); // Run the simulation dc.ExportSimulationData += (sender, args) => { var vgsVoltage = dc.GetCurrentSweepValue()[0]; var vdsVoltage = dc.GetCurrentSweepValue()[1]; var current = currentExport.Value; }; dc.Run(ckt); // </example_DC> }