Exemple #1
0
        /// <inheritdoc/>
        protected override void Execute()
        {
            base.Execute();
            Op(BiasingParameters.DcMaxIterations);
            var exportargs = new ExportDataEventArgs(this);

            OnExport(exportargs);
        }
Exemple #2
0
        /// <summary>
        /// Executes the simulation.
        /// </summary>
        protected override void Execute()
        {
            base.Execute();

            var state  = RealState;
            var cstate = ComplexState;
            var nstate = NoiseState;

            var noiseconfig = NoiseConfiguration;
            var exportargs  = new ExportDataEventArgs(this);

            // Find the output nodes
            var posOutNode = noiseconfig.Output != null?Variables.GetNode(noiseconfig.Output).Index : 0;

            var negOutNode = noiseconfig.OutputRef != null?Variables.GetNode(noiseconfig.OutputRef).Index : 0;

            // Initialize
            nstate.Reset(FrequencySweep.Initial);
            cstate.Laplace = 0;
            state.UseIc    = false;
            state.UseDc    = true;
            Op(DcMaxIterations);

            // Load all in order to calculate the AC info for all devices
            InitializeAcParameters();

            // Connect noise sources
            for (var i = 0; i < _noiseBehaviors.Count; i++)
            {
                _noiseBehaviors[i].ConnectNoise();
            }

            // Loop through noise figures
            foreach (var freq in FrequencySweep.Points)
            {
                nstate.Frequency = freq;
                cstate.Laplace   = new Complex(0.0, 2.0 * Math.PI * freq);
                AcIterate();

                var val = cstate.Solution[posOutNode] - cstate.Solution[negOutNode];
                nstate.GainInverseSquared = 1.0 / Math.Max(val.Real * val.Real + val.Imaginary * val.Imaginary, 1e-20);

                // Solve the adjoint system
                NzIterate(posOutNode, negOutNode);

                // Now we use the adjoint system to calculate the noise
                // contributions of each generator in the circuit
                nstate.OutputNoiseDensity = 0.0;
                for (var i = 0; i < _noiseBehaviors.Count; i++)
                {
                    _noiseBehaviors[i].Noise();
                }

                // Export the data
                OnExport(exportargs);
            }
        }
Exemple #3
0
        /// <inheritdoc/>
        protected override void Execute()
        {
            base.Execute();
            var cstate = (ComplexSimulationState)GetState <IComplexSimulationState>();

            var noiseconfig = NoiseParameters;
            var exportargs  = new ExportDataEventArgs(this);

            // Find the output nodes
            var posOutNode = noiseconfig.Output != null ? cstate.Map[cstate.GetSharedVariable(noiseconfig.Output)] : 0;
            var negOutNode = noiseconfig.OutputRef != null ? cstate.Map[cstate.GetSharedVariable(noiseconfig.OutputRef)] : 0;

            // Initialize
            var freq = FrequencyParameters.Frequencies.GetEnumerator();

            if (!freq.MoveNext())
            {
                return;
            }
            cstate.Laplace = 0;
            Op(BiasingParameters.DcMaxIterations);

            // Initialize all devices for small-signal analysis and reset all noise contributions
            InitializeAcParameters();
            foreach (var behavior in _noiseBehaviors)
            {
                behavior.Initialize();
            }

            // Loop through noise figures
            do
            {
                // First compute the AC gain
                cstate.Laplace = new Complex(0.0, 2.0 * Math.PI * freq.Current);
                AcIterate();

                var val = cstate.Solution[posOutNode] - cstate.Solution[negOutNode];
                var inverseGainSquared = 1.0 / Math.Max(val.Real * val.Real + val.Imaginary * val.Imaginary, 1e-20);
                _state.SetCurrentPoint(new NoisePoint(freq.Current, inverseGainSquared));

                // Solve the adjoint system
                NzIterate(posOutNode, negOutNode);

                // Now we use the adjoint system to calculate the noise
                // contributions of each generator in the circuit
                foreach (var behavior in _noiseBehaviors)
                {
                    behavior.Compute();
                    _state.Add(behavior);
                }

                // Export the data
                OnExport(exportargs);
            }while (freq.MoveNext());
        }
Exemple #4
0
        /// <summary>
        /// Executes the simulation.
        /// </summary>
        protected override void Execute()
        {
            // Execute base behavior
            base.Execute();

            var state  = RealState;
            var cstate = ComplexState;

            // Calculate the operating point
            cstate.Laplace = 0.0;
            state.UseIc    = false;
            state.UseDc    = true;
            Op(DcMaxIterations);

            // Load all in order to calculate the AC info for all devices
            FrequencySimulationStatistics.ComplexTime.Start();
            try
            {
                InitializeAcParameters();

                // Export operating point if requested
                var exportargs = new ExportDataEventArgs(this);
                if (_keepOpInfo)
                {
                    OnExport(exportargs);
                }

                // Sweep the frequency
                foreach (var freq in FrequencySweep.Points)
                {
                    // Calculate the current frequency
                    cstate.Laplace = new Complex(0.0, 2.0 * Math.PI * freq);

                    // Solve
                    AcIterate();

                    // Export the timepoint
                    OnExport(exportargs);
                }

                FrequencySimulationStatistics.ComplexTime.Stop();
            }
            catch (Exception)
            {
                FrequencySimulationStatistics.ComplexTime.Stop();
                throw;
            }
        }
Exemple #5
0
        /// <summary>
        /// Executes the simulation.
        /// </summary>
        protected override void Execute()
        {
            base.Execute();

            // Setup the state
            var state = RealState;

            state.UseIc = false; // UseIC is only used in transient simulations
            state.UseDc = true;

            Op(DcMaxIterations);

            var exportargs = new ExportDataEventArgs(this);

            OnExport(exportargs);
        }
Exemple #6
0
        /// <summary>
        /// Execute
        /// </summary>
        protected override void Execute()
        {
            // Execute base behavior
            base.Execute();

            var state      = RealState;
            var cstate     = ComplexState;
            var baseconfig = BaseConfiguration;
            var freqconfig = FrequencyConfiguration;

            // Calculate the operating point
            cstate.Laplace = 0.0;
            state.Domain   = RealState.DomainType.Frequency;
            state.Gmin     = baseconfig.Gmin;
            Op(baseconfig.DcMaxIterations);

            // Load all in order to calculate the AC info for all devices
            for (int i = 0; i < LoadBehaviors.Count; i++)
            {
                LoadBehaviors[i].Load(this);
            }
            for (int i = 0; i < FrequencyBehaviors.Count; i++)
            {
                FrequencyBehaviors[i].InitializeParameters(this);
            }

            // Export operating point if requested
            var exportargs = new ExportDataEventArgs(this);

            if (freqconfig.KeepOpInfo)
            {
                Export(exportargs);
            }

            // Sweep the frequency
            foreach (double freq in FrequencySweep.Points)
            {
                // Calculate the current frequency
                cstate.Laplace = new Complex(0.0, 2.0 * Math.PI * freq);

                // Solve
                AcIterate();

                // Export the timepoint
                Export(exportargs);
            }
        }
Exemple #7
0
        /// <summary>
        /// Executes the simulation.
        /// </summary>
        /// <exception cref="SpiceSharp.CircuitException">{0}: transient terminated".FormatString(Name)</exception>
        protected override void Execute()
        {
            // First do temperature-dependent calculations and IC
            base.Execute();
            exportargs = new ExportDataEventArgs(this);
            timeConfig = Configurations.Get <TimeConfiguration>();

            // Start our statistics
            Statistics.TransientTime.Start();
            startIters    = Statistics.Iterations;
            startselapsed = Statistics.SolveTime.Elapsed;

            simulationRunning = true;

            if (!StepByStepSimulation)
            {
                DoTick();
            }
        }
Exemple #8
0
        /// <inheritdoc/>
        protected override void Execute()
        {
            // Execute base behavior
            base.Execute();

            var cstate = (ComplexSimulationState)GetState <IComplexSimulationState>();

            // Calculate the operating point
            cstate.Laplace = 0.0;
            Op(BiasingParameters.DcMaxIterations);

            // Load all in order to calculate the AC info for all devices
            Statistics.ComplexTime.Start();
            try
            {
                InitializeAcParameters();

                // Export operating point if requested
                var exportargs = new ExportDataEventArgs(this);
                if (FrequencyParameters.KeepOpInfo)
                {
                    OnExport(exportargs);
                }

                // Sweep the frequency
                foreach (var freq in FrequencyParameters.Frequencies)
                {
                    // Calculate the current frequency
                    cstate.Laplace = new Complex(0.0, 2.0 * Math.PI * freq);

                    // Solve
                    AcIterate();

                    // Export the timepoint
                    OnExport(exportargs);
                }
            }
            finally
            {
                Statistics.ComplexTime.Stop();
            }
        }
Exemple #9
0
        /// <inheritdoc/>
        protected override void Execute()
        {
            base.Execute();

            // Calculate the operating point of the circuit
            _time.UseIc = TimeParameters.UseIc;
            _time.UseDc = true;
            if (_time.UseIc)
            {
                // Copy initial conditions in the current solution such that device may be able to copy them
                // in InitializeStates()
                var state = GetState <IBiasingSimulationState>();
                foreach (var ic in _initialConditions)
                {
                    var index = state.Map[ic.Variable];
                    state.Solution[index]    = ic.Value;
                    state.OldSolution[index] = ic.Value; // Just to make sure...
                }
            }
            else
            {
                if (_initialConditions.Count > 0)
                {
                    AfterLoad += LoadInitialConditions;
                    Op(BiasingParameters.DcMaxIterations);
                    AfterLoad -= LoadInitialConditions;
                }
                else
                {
                    Op(BiasingParameters.DcMaxIterations);
                }
            }
            Statistics.TimePoints++;

            // Stop calculating the operating point and allow the devices to
            // retrieve their initial conditions if necessary
            InitializeStates();
            _time.UseIc = false;
            _time.UseDc = false;
            var exportargs = new ExportDataEventArgs(this);

            // Start our statistics
            var stats         = ((BiasingSimulation)this).Statistics;
            var startIters    = stats.Iterations;
            var startselapsed = stats.SolveTime.Elapsed;

            Statistics.TransientTime.Start();
            try
            {
                while (true)
                {
                    // Accept the last evaluated time point
                    Accept();

                    // Export the current timepoint
                    if (_method.Time >= TimeParameters.StartTime)
                    {
                        OnExport(exportargs);
                    }

                    // Detect the end of the simulation
                    if (_method.Time >= TimeParameters.StopTime)
                    {
                        // Keep our statistics
                        Statistics.TransientTime.Stop();
                        Statistics.TransientIterations += stats.Iterations - startIters;
                        Statistics.TransientSolveTime  += stats.SolveTime.Elapsed - startselapsed;

                        // Finished!
                        return;
                    }

                    // Continue integration
                    foreach (var behavior in _truncatingBehaviors)
                    {
                        _method.Truncate(behavior.Prepare());
                    }
                    _method.Prepare();

                    // Find a valid time point
                    while (true)
                    {
                        // Probe the next time point
                        Probe();

                        // Try to solve the new point
                        var converged = TimeIterate(TimeParameters.TransientMaxIterations);
                        Statistics.TimePoints++;

                        // Did we fail to converge to a solution?
                        if (!converged)
                        {
                            _method.Reject();
                            Statistics.Rejected++;
                        }
                        else
                        {
                            // If our integration method approves of our solution, continue to the next timepoint
                            var max = double.PositiveInfinity;
                            foreach (var behavior in _truncatingBehaviors)
                            {
                                max = Math.Min(behavior.Evaluate(), max);
                            }
                            if (_method.Evaluate(max))
                            {
                                break;
                            }
                            Statistics.Rejected++;
                        }
                    }
                }
            }
            catch (SpiceSharpException ex)
            {
                throw new SpiceSharpException(Properties.Resources.Simulations_Time_Terminated.FormatString(Name), ex);
            }
            finally
            {
                Statistics.TransientTime.Stop();
                Statistics.TransientIterations += stats.Iterations - startIters;
                Statistics.TransientSolveTime  += stats.SolveTime.Elapsed - startselapsed;
            }
        }
Exemple #10
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]);
            }
        }
Exemple #11
0
 /// <summary>
 /// Raises the <see cref="E:ExportSimulationData" /> event.
 /// </summary>
 /// <param name="args">The <see cref="ExportDataEventArgs"/> instance containing the event data.</param>
 protected virtual void OnExport(ExportDataEventArgs args) => ExportSimulationData?.Invoke(this, args);
Exemple #12
0
        /// <inheritdoc/>
        protected override void Execute()
        {
            base.Execute();
            var cstate      = (ComplexSimulationState)GetState <IComplexSimulationState>();
            var noiseconfig = NoiseParameters;
            var exportargs  = new ExportDataEventArgs(this);

            // Find the output nodes
            var posOutNode = noiseconfig.Output != null ? cstate.Map[cstate.GetSharedVariable(noiseconfig.Output)] : 0;
            var negOutNode = noiseconfig.OutputRef != null ? cstate.Map[cstate.GetSharedVariable(noiseconfig.OutputRef)] : 0;

            // We only want to enable the source that is flagged as the input
            var source             = EntityBehaviors[NoiseParameters.InputSource];
            var originalParameters = new List <Tuple <IndependentSourceParameters, double, double> >();

            foreach (var container in EntityBehaviors)
            {
                if (container.TryGetParameterSet(out IndependentSourceParameters parameters))
                {
                    originalParameters.Add(Tuple.Create(parameters, parameters.AcMagnitude, parameters.AcPhase));
                    if (ReferenceEquals(container, source))
                    {
                        parameters.AcMagnitude = 1.0;
                        parameters.AcPhase     = 0.0;
                    }
                    else
                    {
                        parameters.AcMagnitude = 0.0;
                        parameters.AcPhase     = 0.0;
                    }
                }
            }

            try
            {
                // Initialize
                var freq = FrequencyParameters.Frequencies.GetEnumerator();
                if (!freq.MoveNext())
                {
                    return;
                }
                cstate.Laplace = 0;
                Op(BiasingParameters.DcMaxIterations);

                // Initialize all devices for small-signal analysis and reset all noise contributions
                InitializeAcParameters();
                foreach (var behavior in _noiseBehaviors)
                {
                    behavior.Initialize();
                }

                // Loop through noise figures
                do
                {
                    // First compute the AC gain
                    cstate.Laplace = new Complex(0.0, 2.0 * Math.PI * freq.Current);
                    AcIterate();

                    var val = cstate.Solution[posOutNode] - cstate.Solution[negOutNode];
                    var inverseGainSquared = 1.0 / Math.Max(val.Real * val.Real + val.Imaginary * val.Imaginary, 1e-20);
                    _state.SetCurrentPoint(new NoisePoint(freq.Current, inverseGainSquared));

                    // Solve the adjoint system
                    NzIterate(posOutNode, negOutNode);

                    // Now we use the adjoint system to calculate the noise
                    // contributions of each generator in the circuit
                    foreach (var behavior in _noiseBehaviors)
                    {
                        behavior.Compute();
                        _state.Add(behavior);
                    }

                    // Export the data
                    OnExport(exportargs);
                }while (freq.MoveNext());
            }
            finally
            {
                foreach (var parameters in originalParameters)
                {
                    parameters.Item1.AcMagnitude = parameters.Item2;
                    parameters.Item1.AcPhase     = parameters.Item3;
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Executes the simulation.
        /// </summary>
        /// <exception cref="SpiceSharp.CircuitException">{0}: transient terminated".FormatString(Name)</exception>
        protected override void Execute()
        {
            // First do temperature-dependent calculations and IC
            base.Execute();
            var exportargs = new ExportDataEventArgs(this);
            var timeConfig = Configurations.Get <TimeConfiguration>();

            // Start our statistics
            Statistics.TransientTime.Start();
            var startIters    = Statistics.Iterations;
            var startselapsed = Statistics.SolveTime.Elapsed;

            try
            {
                var newDelta = Math.Min(timeConfig.FinalTime / 50.0, timeConfig.Step) / 10.0;
                while (true)
                {
                    // Accept the last evaluated time point
                    Accept();

                    // Export the current timepoint
                    if (Method.Time >= timeConfig.InitTime)
                    {
                        OnExport(exportargs);
                    }

                    // Detect the end of the simulation
                    if (Method.Time >= timeConfig.FinalTime)
                    {
                        // Keep our statistics
                        Statistics.TransientTime.Stop();
                        Statistics.TransientIterations += Statistics.Iterations - startIters;
                        Statistics.TransientSolveTime  += Statistics.SolveTime.Elapsed - startselapsed;

                        // Finished!
                        return;
                    }

                    // Continue integration
                    Method.Continue(this, ref newDelta);

                    // Find a valid time point
                    while (true)
                    {
                        // Probe the next time point
                        Probe(newDelta);

                        // Try to solve the new point
                        var converged = TimeIterate(timeConfig.TranMaxIterations);
                        Statistics.TimePoints++;

                        // Did we fail to converge to a solution?
                        if (!converged)
                        {
                            Method.NonConvergence(this, out newDelta);
                            Statistics.Rejected++;
                        }
                        else
                        {
                            // If our integration method approves of our solution, continue to the next timepoint
                            if (Method.Evaluate(this, out newDelta))
                            {
                                break;
                            }
                            Statistics.Rejected++;
                        }
                    }
                }
            }
            catch (CircuitException ex)
            {
                // Keep our statistics
                Statistics.TransientTime.Stop();
                Statistics.TransientIterations += Statistics.Iterations - startIters;
                Statistics.TransientSolveTime  += Statistics.SolveTime.Elapsed - startselapsed;
                throw new CircuitException("{0}: transient terminated".FormatString(Name), ex);
            }
        }
Exemple #14
0
        /// <summary>
        /// Execute the transient simulation
        /// </summary>
        protected override void Execute()
        {
            // First do temperature-dependent calculations and IC
            base.Execute();
            var exportargs = new ExportDataEventArgs(this);

            var state      = RealState;
            var baseConfig = BaseConfiguration;
            var timeConfig = TimeConfiguration;

            double delta = Math.Min(timeConfig.FinalTime / 50.0, timeConfig.Step) / 10.0;

            // Initialize before starting the simulation
            state.UseIc  = timeConfig.UseIc;
            state.Domain = RealState.DomainType.Time;
            state.Gmin   = baseConfig.Gmin;

            // Use node initial conditions if device initial conditions are not used
            if (!timeConfig.UseIc)
            {
                OnLoad += LoadInitialConditions;
            }

            // Calculate the operating point
            Op(baseConfig.DcMaxIterations);
            Statistics.TimePoints++;
            Method.DeltaOld.Clear(timeConfig.MaxStep);
            Method.Delta     = delta;
            Method.SaveDelta = timeConfig.FinalTime / 50.0;

            // Stop calculating a DC solution
            state.UseIc = false;
            state.UseDc = false;
            for (int i = 0; i < TransientBehaviors.Count; i++)
            {
                TransientBehaviors[i].GetDcState(this);
            }
            StatePool.ClearDc();
            OnLoad -= LoadInitialConditions;

            // Start our statistics
            Statistics.TransientTime.Start();
            int startIters    = Statistics.Iterations;
            var startselapsed = Statistics.SolveTime.Elapsed;

            try
            {
                while (true)
                {
                    // nextTime:

                    // Accept the current timepoint (CKTaccept())
                    for (int i = 0; i < AcceptBehaviors.Count; i++)
                    {
                        AcceptBehaviors[i].Accept(this);
                    }
                    Method.SaveSolution(state.Solution);
                    // end of CKTaccept()

                    // Check if current breakpoint is outdated; if so, clear
                    Method.UpdateBreakpoints();
                    Statistics.Accepted++;

                    // Export the current timepoint
                    if (Method.Time >= timeConfig.InitTime)
                    {
                        Export(exportargs);
                    }

                    // Detect the end of the simulation
                    if (Method.Time >= timeConfig.FinalTime)
                    {
                        // Keep our statistics
                        Statistics.TransientTime.Stop();
                        Statistics.TransientIterations += Statistics.Iterations - startIters;
                        Statistics.TransientSolveTime  += Statistics.SolveTime.Elapsed - startselapsed;

                        // Finished!
                        OnLoad -= LoadInitialConditions;
                        return;
                    }

                    // Pause test - pausing not supported

                    // resume:
                    Method.Delta = Math.Min(Method.Delta, timeConfig.MaxStep);
                    Method.Resume();
                    StatePool.History.Cycle();

                    // Calculate a new solution
                    while (true)
                    {
                        Method.TryDelta();

                        // Compute coefficients and predict a solution and reset states to our previous solution
                        Method.ComputeCoefficients(this);
                        Method.Predict(this);

                        // Try to solve the new point
                        if (Method.SavedTime.Equals(0.0))
                        {
                            state.Init = RealState.InitializationStates.InitTransient;
                        }
                        bool converged = TimeIterate(timeConfig.TranMaxIterations);
                        Statistics.TimePoints++;

                        // Spice copies the states the first time, we're not
                        // I believe this is because Spice treats the first timepoint after the OP as special (MODEINITTRAN)
                        // We don't treat it special (we just assume it started from a circuit in rest)

                        if (!converged)
                        {
                            // Failed to converge, let's try again with a smaller timestep
                            Method.Rollback();
                            Statistics.Rejected++;
                            Method.Delta /= 8.0;
                            Method.CutOrder();

                            var data = new TimestepCutEventArgs(Method.Delta / 8.0, TimestepCutEventArgs.TimestepCutReason.Convergence);
                            TimestepCut?.Invoke(this, data);
                        }
                        else
                        {
                            // Do not check the first time point
                            if (Method.SavedTime.Equals(0.0) || Method.LteControl(this))
                            {
                                // goto nextTime;
                                break;
                            }

                            Statistics.Rejected++;
                            var data = new TimestepCutEventArgs(Method.Delta, TimestepCutEventArgs.TimestepCutReason.Truncation);
                            TimestepCut?.Invoke(this, data);
                        }

                        if (Method.Delta <= timeConfig.DeltaMin)
                        {
                            if (Method.OldDelta > timeConfig.DeltaMin)
                            {
                                Method.Delta = timeConfig.DeltaMin;
                            }
                            else
                            {
                                throw new CircuitException("Timestep too small at t={0:e}: {1:e}".FormatString(Method.SavedTime, Method.Delta));
                            }
                        }
                    }
                }
            }
            catch (CircuitException ex)
            {
                // Keep our statistics
                Statistics.TransientTime.Stop();
                Statistics.TransientIterations += Statistics.Iterations - startIters;
                Statistics.TransientSolveTime  += Statistics.SolveTime.Elapsed - startselapsed;
                throw new CircuitException("{0}: transient terminated".FormatString(Name), ex);
            }
        }
Exemple #15
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;
                }
            }
        }
Exemple #16
0
 /// <summary>
 /// Export the data
 /// </summary>
 protected void Export(ExportDataEventArgs args)
 {
     OnExportSimulationData?.Invoke(this, args);
 }