/// <summary> /// Executes the simulation. /// </summary> /// <exception cref="SpiceSharp.CircuitException"> /// Could not find source {0}".FormatString(sweep.Parameter) /// or /// Invalid sweep object /// </exception> protected override void Execute() { // Base base.Execute(); var exportargs = new ExportDataEventArgs(this); // Setup the state var state = RealState; var dcconfig = Configurations.Get <DCConfiguration>().ThrowIfNull("dc configuration"); state.Init = InitializationModes.Junction; state.UseIc = false; // UseIC is only used in transient simulations state.UseDc = true; // Initialize Sweeps = new NestedSweeps(dcconfig.Sweeps); var swept = new Parameter <double> [Sweeps.Count]; var original = new Parameter <double> [Sweeps.Count]; var levelNeedsTemperature = -1; // Initialize first time for (var i = 0; i < dcconfig.Sweeps.Count; i++) { // Get the component to be swept var sweep = Sweeps[i]; // Try finding the parameter to sweep var args = new DCParameterSearchEventArgs(sweep.Parameter, i); OnParameterSearch?.Invoke(this, args); if (args.Result != null) { swept[i] = args.Result; // Keep track of the highest level that needs to recalculate temperature if (args.TemperatureNeeded) { levelNeedsTemperature = Math.Max(levelNeedsTemperature, i); } } else { // Get entity parameters if (!EntityBehaviors.ContainsKey(sweep.Parameter)) { throw new CircuitException("Could not find source {0}".FormatString(sweep.Parameter)); } var eb = EntityParameters[sweep.Parameter]; // Check for a Voltage source or Current source parameters if (eb.TryGet <Components.CommonBehaviors.IndependentSourceParameters>(out var ibp)) { swept[i] = ibp.DcValue; } else { throw new CircuitException("Invalid sweep object"); } } original[i] = (Parameter <double>)swept[i].Clone(); swept[i].Value = sweep.Initial; } // Execute temperature behaviors if necessary the first time if (levelNeedsTemperature >= 0) { Temperature(); } // Execute the sweeps var level = Sweeps.Count - 1; while (level >= 0) { // Fill the values with start values while (level < Sweeps.Count - 1) { level++; Sweeps[level].Reset(); swept[level].Value = Sweeps[level].CurrentValue; state.Init = InitializationModes.Junction; } // Calculate the solution if (!Iterate(dcconfig.SweepMaxIterations)) { IterationFailed?.Invoke(this, EventArgs.Empty); Op(DcMaxIterations); } // Export data OnExport(exportargs); // Remove all values that are greater or equal to the maximum value while (level >= 0 && Sweeps[level].CurrentStep >= Sweeps[level].Limit) { level--; } // Go to the next step for the top level if (level >= 0) { Sweeps[level].Increment(); swept[level].Value = Sweeps[level].CurrentValue; // If temperature behavior is needed for this level or higher, run behaviors if (levelNeedsTemperature >= level) { Temperature(); } } } // Restore all the parameters of the swept components for (var i = 0; i < Sweeps.Count; i++) { swept[i].CopyFrom(original[i]); } }
/// <summary> /// Execute the DC simulation /// </summary> /// <param name="ckt">The circuit</param> public override void Execute(Circuit ckt) { // Setup the state var state = ckt.State; var rstate = state.Real; var config = CurrentConfig; state.Initialize(ckt); state.UseIC = false; // UseIC is only used in transient simulations state.UseDC = true; state.UseSmallSignal = false; state.Domain = CircuitState.DomainTypes.None; state.Gmin = config.Gmin; // Initialize IParameterized[] components = new IParameterized[Sweeps.Count]; Parameter[] parameters = new Parameter[Sweeps.Count]; // Initialize first time for (int i = 0; i < Sweeps.Count; i++) { // Get the component to be swept var sweep = Sweeps[i]; if (!ckt.Objects.Contains(sweep.ComponentName)) { throw new CircuitException($"Could not find source {sweep.ComponentName}"); } components[i] = (IParameterized)ckt.Objects[sweep.ComponentName]; // Get the parameter and save it for restoring later parameters[i] = (Parameter)GetDcParameter(components[i]).Clone(); // Start with the original values sweep.SetCurrentStep(0); components[i].Set("dc", sweep.CurrentValue); } Initialize(ckt); // Execute the sweeps int level = Sweeps.Count - 1; while (level >= 0) { // Fill the values with start values while (level < Sweeps.Count - 1) { level++; Sweeps[level].SetCurrentStep(0); components[level].Set("dc", Sweeps[level].CurrentValue); } // Calculate the solution if (!Iterate(config, ckt, config.SweepMaxIterations)) { IterationFailed?.Invoke(this, ckt); Op(config, ckt, config.DcMaxIterations); } // Export data Export(ckt); // Remove all values that are greater or equal to the maximum value while (level >= 0 && Sweeps[level].CurrentStep >= Sweeps[level].Limit) { level--; } // Go to the next step for the top level if (level >= 0) { Sweeps[level].SetCurrentStep(Sweeps[level].CurrentStep + 1); components[level].Set("dc", Sweeps[level].CurrentValue); } } // Restore all the parameters of the swept components for (int i = 0; i < Sweeps.Count; i++) { SetDcParameter(components[i], parameters[i]); } Finalize(ckt); }
/// <inheritdoc/> protected override void Execute() { // Base base.Execute(); var exportargs = new ExportDataEventArgs(this); // Setup the state Iteration.Mode = IterationModes.Junction; // Initialize var sweeps = DCParameters.Sweeps.ToArray(); _sweepEnumerators = new IEnumerator <double> [DCParameters.Sweeps.Count]; for (var i = 0; i < sweeps.Length; i++) { _sweepEnumerators[i] = sweeps[i].CreatePoints(this); if (!_sweepEnumerators[i].MoveNext()) { throw new SpiceSharpException(Properties.Resources.Simulations_DC_NoSweepPoints.FormatString(sweeps[i].Name)); } } // Execute the sweeps var level = sweeps.Length - 1; while (level >= 0) { // Fill the values up again by resetting while (level < sweeps.Length - 1) { level++; _sweepEnumerators[level] = sweeps[level].CreatePoints(this); if (!_sweepEnumerators[level].MoveNext()) { throw new SpiceSharpException(Properties.Resources.Simulations_DC_NoSweepPoints.FormatString(sweeps[level].Name)); } Iteration.Mode = IterationModes.Junction; } // Calculate the solution if (!Iterate(DCParameters.SweepMaxIterations)) { IterationFailed?.Invoke(this, EventArgs.Empty); Op(BiasingParameters.DcMaxIterations); } // Export data OnExport(exportargs); // Remove all values that are greater or equal to the maximum value while (level >= 0 && !_sweepEnumerators[level].MoveNext()) { level--; } if (level < 0) { break; } } }
/// <summary> /// Execute the DC simulation /// </summary> /// <param name="ckt">The circuit</param> /// <param name="reset">Restart the circuit if true</param> public override void Execute(Circuit ckt) { // Setup the state var state = ckt.State; var rstate = state.Real; state.UseIC = false; // UseIC is only used in transient simulations state.UseDC = true; state.UseSmallSignal = false; state.Domain = CircuitState.DomainTypes.None; // Initialize CircuitComponent[] components = new CircuitComponent[Sweeps.Count]; Parameter <double>[] parameters = new Parameter <double> [Sweeps.Count]; int[] values = new int[Sweeps.Count]; // Initialize first time for (int i = 0; i < Sweeps.Count; i++) { // Get the component to be swept var sweep = Sweeps[i]; if (!ckt.Components.Contains(sweep.ComponentName)) { throw new CircuitException($"Could not find source {sweep.ComponentName}"); } components[i] = ckt.Components[sweep.ComponentName]; // Get the parameter and save it for restoring later parameters[i] = (Parameter <double>)components[i].GetParameter <double>("dc").Clone(); // Start with the original values components[i].Set("dc", sweep.Start); values[i] = 0; } // Execute the sweeps int level = Sweeps.Count - 1; while (level >= 0) { // Fill the values with start values while (level < Sweeps.Count - 1) { level++; values[level] = 0; components[level].Set("dc", Sweeps[level].Start); } // Calculate the solution if (!this.Iterate(ckt, MyConfig.MaxIterations)) { IterationFailed?.Invoke(this, ckt); this.Op(ckt, MyConfig.MaxIterations); } // Export data Export(ckt); // Remove all values that are equal to the maximum value while (level >= 0 && values[level] >= Sweeps[level].Limit) { level--; } // Go to the next step for the top level if (level >= 0) { values[level]++; double newvalue = Sweeps[level].Start + values[level] * Sweeps[level].Step; components[level].Set("dc", newvalue); } } // Restore all the parameters of the swept components for (int i = 0; i < Sweeps.Count; i++) { components[i].GetParameter <double>("dc").CopyFrom(parameters[i]); } }