Beispiel #1
0
        /// <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]);
            }
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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;
                }
            }
        }
Beispiel #4
0
        /// <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]);
            }
        }