Exemple #1
0
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="entities">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        /// <exception cref="SpiceSharp.CircuitException">
        /// {0}: No time configuration".FormatString(Name)
        /// or
        /// {0}: No integration method specified".FormatString(Name)
        /// </exception>
        protected override void Setup(EntityCollection entities)
        {
            entities.ThrowIfNull(nameof(entities));
            base.Setup(entities);

            // Get behaviors and configurations
            var config = Configurations.Get <TimeConfiguration>().ThrowIfNull("time configuration");

            _useIc = config.UseIc;
            Method = config.Method.ThrowIfNull("method");
            _transientBehaviors = EntityBehaviors.GetBehaviorList <ITimeBehavior>();
            _acceptBehaviors    = EntityBehaviors.GetBehaviorList <IAcceptBehavior>();

            // Allow all transient behaviors to allocate equation elements and create states
            for (var i = 0; i < _transientBehaviors.Count; i++)
            {
                _transientBehaviors[i].GetEquationPointers(RealState.Solver);
                _transientBehaviors[i].CreateStates(Method);
            }
            Method.Setup(this);

            // Set up initial conditions
            foreach (var ic in config.InitialConditions)
            {
                _initialConditions.Add(new ConvergenceAid(ic.Key, ic.Value));
            }
        }
Exemple #2
0
        /// <summary>
        /// A default implementation for validating entities and behaviors using the specified rules.
        /// </summary>
        /// <param name="rules">The rules.</param>
        /// <param name="entities">The entities.</param>
        /// <exception cref="ValidationFailedException">Thrown if the validation failed.</exception>
        protected void Validate(IRules rules, IEntityCollection entities)
        {
            if (rules == null)
            {
                return;
            }
            if (entities != null)
            {
                foreach (var entity in entities)
                {
                    if (entity is IRuleSubject subject)
                    {
                        subject.Apply(rules);
                    }
                }
            }
            foreach (var behavior in EntityBehaviors.SelectMany(p => p))
            {
                if (behavior is IRuleSubject subject)
                {
                    subject.Apply(rules);
                }
            }

            // Are there still violated rules?
            if (rules.ViolationCount > 0)
            {
                throw new ValidationFailedException(this, rules);
            }
        }
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="circuit">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        /// <exception cref="SpiceSharp.CircuitException">
        /// No frequency configuration found
        /// or
        /// No frequency sweep found
        /// </exception>
        protected override void Setup(Circuit circuit)
        {
            if (circuit == null)
            {
                throw new ArgumentNullException(nameof(circuit));
            }
            base.Setup(circuit);

            // Get behaviors, configurations and states
            var config = Configurations.Get <FrequencyConfiguration>();

            _frequencyBehaviors = EntityBehaviors.GetBehaviorList <IFrequencyBehavior>();
            FrequencySweep      = config.FrequencySweep ?? throw new CircuitException("No frequency sweep found");

            // Create the state for complex numbers
            ComplexState        = new ComplexSimulationState();
            _loadStateEventArgs = new LoadStateEventArgs(ComplexState);
            var strategy = ComplexState.Solver.Strategy;

            strategy.RelativePivotThreshold = config.RelativePivotThreshold;
            strategy.AbsolutePivotThreshold = config.AbsolutePivotThreshold;

            // Setup behaviors
            var solver = ComplexState.Solver;

            for (var i = 0; i < _frequencyBehaviors.Count; i++)
            {
                _frequencyBehaviors[i].GetEquationPointers(solver);
            }
            ComplexState.Setup(Variables);
        }
Exemple #4
0
        /// <inheritdoc/>
        protected override void CreateBehaviors(IEntityCollection entities)
        {
            base.CreateBehaviors(entities);
            _temperatureBehaviors = EntityBehaviors.GetBehaviorList <ITemperatureBehavior>();
            _loadBehaviors        = EntityBehaviors.GetBehaviorList <IBiasingBehavior>();
            _convergenceBehaviors = EntityBehaviors.GetBehaviorList <IConvergenceBehavior>();
            _updateBehaviors      = EntityBehaviors.GetBehaviorList <IBiasingUpdateBehavior>();

            // We're going to set up our state now that all behaviors have allocated elements in the solver
            _state.Setup();

            // Set up nodesets for nodes that were referenced by an entity
            _nodesets.Clear();
            foreach (var ns in BiasingParameters.Nodesets)
            {
                if (_state.TryGetValue(ns.Key, out var variable))
                {
                    _nodesets.Add(new ConvergenceAid(variable, _state, ns.Value));
                }
                else
                {
                    SpiceSharpWarning.Warning(this, Properties.Resources.Simulations_ConvergenceAidVariableNotFound.FormatString(ns.Key));
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="entities">The circuit that will be used.</param>
        protected override void Setup(EntityCollection entities)
        {
            entities.ThrowIfNull(nameof(entities));

            // Get behaviors, configurations and states
            var config = Configurations.Get <FrequencyConfiguration>();

            FrequencySweep = config.FrequencySweep.ThrowIfNull("frequency sweep");

            // Create the state for complex numbers
            ComplexState = new ComplexSimulationState();
            var strategy = ComplexState.Solver.Strategy;

            strategy.RelativePivotThreshold = config.RelativePivotThreshold;
            strategy.AbsolutePivotThreshold = config.AbsolutePivotThreshold;

            // Setup the rest of the behaviors
            base.Setup(entities);

            // Cache local variables
            _frequencyBehaviors = EntityBehaviors.GetBehaviorList <IFrequencyBehavior>();
            _loadStateEventArgs = new LoadStateEventArgs(ComplexState);

            ComplexState.Setup(Variables);
        }
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="entities">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        /// <exception cref="SpiceSharp.CircuitException">
        /// No frequency configuration found
        /// or
        /// No frequency sweep found
        /// </exception>
        protected override void Setup(EntityCollection entities)
        {
            entities.ThrowIfNull(nameof(entities));
            base.Setup(entities);

            // Get behaviors, configurations and states
            var config = Configurations.Get <FrequencyConfiguration>();

            _frequencyBehaviors = EntityBehaviors.GetBehaviorList <IFrequencyBehavior>();
            FrequencySweep      = config.FrequencySweep.ThrowIfNull("frequency sweep");

            // Create the state for complex numbers
            ComplexState        = new ComplexSimulationState();
            _loadStateEventArgs = new LoadStateEventArgs(ComplexState);
            var strategy = ComplexState.Solver.Strategy;

            strategy.RelativePivotThreshold = config.RelativePivotThreshold;
            strategy.AbsolutePivotThreshold = config.AbsolutePivotThreshold;

            // Setup behaviors
            var solver = ComplexState.Solver;

            for (var i = 0; i < _frequencyBehaviors.Count; i++)
            {
                _frequencyBehaviors[i].GetEquationPointers(solver);
            }
            ComplexState.Setup(Variables);
        }
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="entities">The circuit that will be used.</param>
        protected override void Setup(EntityCollection entities)
        {
            entities.ThrowIfNull(nameof(entities));

            // Get behaviors and configurations
            var config = Configurations.Get <TimeConfiguration>().ThrowIfNull("time configuration");

            _useIc = config.UseIc;
            Method = config.Method.ThrowIfNull("method");

            // Setup
            base.Setup(entities);

            // Cache local variables
            _transientBehaviors = EntityBehaviors.GetBehaviorList <ITimeBehavior>();
            _acceptBehaviors    = EntityBehaviors.GetBehaviorList <IAcceptBehavior>();

            Method.Setup(this);

            // Set up initial conditions
            foreach (var ic in config.InitialConditions)
            {
                _initialConditions.Add(new ConvergenceAid(ic.Key, ic.Value));
            }
        }
Exemple #8
0
 /// <inheritdoc />
 protected override void CreateBehaviors(IEntityCollection entities)
 {
     base.CreateBehaviors(entities);
     _frequencyBehaviors       = EntityBehaviors.GetBehaviorList <IFrequencyBehavior>();
     _frequencyUpdateBehaviors = EntityBehaviors.GetBehaviorList <IFrequencyUpdateBehavior>();
     _state.Setup();
 }
Exemple #9
0
        /// <summary>
        /// Destroys the simulation.
        /// </summary>
        protected virtual void Unsetup()
        {
            // Clear all parameters
            EntityBehaviors.Clear();
            EntityBehaviors = null;
            EntityParameters.Clear();
            EntityParameters = null;

            // Clear all nodes
            Variables.Clear();
            Variables = null;
        }
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="circuit">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        protected override void Setup(Circuit circuit)
        {
            if (circuit == null)
            {
                throw new ArgumentNullException(nameof(circuit));
            }
            base.Setup(circuit);

            // Get behaviors and configuration data
            var config = Configurations.Get <BaseConfiguration>();

            DcMaxIterations            = config.DcMaxIterations;
            AbsTol                     = config.AbsoluteTolerance;
            RelTol                     = config.RelativeTolerance;
            _temperatureBehaviors      = EntityBehaviors.GetBehaviorList <ITemperatureBehavior>();
            _loadBehaviors             = EntityBehaviors.GetBehaviorList <IBiasingBehavior>();
            _initialConditionBehaviors = EntityBehaviors.GetBehaviorList <IInitialConditionBehavior>();

            // Create the state for this simulation
            RealState = new BaseSimulationState
            {
                Gmin = config.Gmin
            };
            _isPreordered  = false;
            _shouldReorder = true;
            var strategy = RealState.Solver.Strategy;

            strategy.RelativePivotThreshold = config.RelativePivotThreshold;
            strategy.AbsolutePivotThreshold = config.AbsolutePivotThreshold;

            // Setup the load behaviors
            _realStateLoadArgs = new LoadStateEventArgs(RealState);
            for (var i = 0; i < _loadBehaviors.Count; i++)
            {
                _loadBehaviors[i].GetEquationPointers(Variables, RealState.Solver);
            }
            RealState.Setup(Variables);

            // TODO: Compatibility - nodesets from nodes instead of configuration should be removed eventually
            if (config.Nodesets.Count == 0)
            {
                foreach (var ns in Variables.NodeSets)
                {
                    _nodesets.Add(new ConvergenceAid(ns.Key, ns.Value));
                }
            }

            // Set up nodesets
            foreach (var ns in config.Nodesets)
            {
                _nodesets.Add(new ConvergenceAid(ns.Key, ns.Value));
            }
        }
Exemple #11
0
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="entities">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        protected override void Setup(EntityCollection entities)
        {
            entities.ThrowIfNull(nameof(entities));
            base.Setup(entities);

            // Get behaviors
            _noiseBehaviors = EntityBehaviors.GetBehaviorList <INoiseBehavior>();

            // Get behaviors, parameters and states
            NoiseConfiguration = Configurations.Get <NoiseConfiguration>();
            NoiseState         = new NoiseState();
            NoiseState.Setup(Variables);
        }
Exemple #12
0
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="circuit">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        protected override void Setup(Circuit circuit)
        {
            if (circuit == null)
            {
                throw new ArgumentNullException(nameof(circuit));
            }
            base.Setup(circuit);

            // Get behaviors
            _noiseBehaviors = EntityBehaviors.GetBehaviorList <INoiseBehavior>();

            // Get behaviors, parameters and states
            NoiseConfiguration = Configurations.Get <NoiseConfiguration>();
            NoiseState         = new NoiseState();
            NoiseState.Setup(Variables);
        }
Exemple #13
0
        /// <summary>
        /// Collect behaviors of all circuit entities while also setting them up
        /// </summary>
        /// <typeparam name="T">Base behavior</typeparam>
        /// <returns></returns>
        protected BehaviorList <T> SetupBehaviors <T>(IEnumerable <Entity> entities) where T : Behavior
        {
            if (entities == null)
            {
                throw new ArgumentNullException(nameof(entities));
            }

            // Register all behaviors
            foreach (var o in entities)
            {
                T behavior = o.CreateBehavior <T>(this);
                if (behavior != null)
                {
                    EntityBehaviors.Add(o.Name, behavior);
                }
            }
            return(EntityBehaviors.GetBehaviorList <T>());
        }
Exemple #14
0
        /// <summary>
        /// Set up all behaviors previously created.
        /// </summary>
        /// <param name="entities">The circuit entities.</param>
        private void SetupBehaviors(IEnumerable <Entity> entities)
        {
            var behaviors = new HashSet <IBehavior>();

            foreach (var entity in entities)
            {
                behaviors.Clear();

                // Create the behaviors in the reverse order to allow inheritance
                for (var i = BehaviorTypes.Count - 1; i >= 0; i--)
                {
                    IBehavior behavior = null;
                    var       type     = BehaviorTypes[i];

                    // Try to reuse a behavior first
                    if (EntityBehaviors.TryGetBehaviors(entity.Name, out var ebd))
                    {
                        // If the entity behaviors already contains the type, reuse that object
                        ebd.TryGetValue(type, out behavior);
                    }

                    // If it doesn't exist, request a new behavior
                    if (behavior == null)
                    {
                        behavior = entity.CreateBehavior(type, this);
                    }

                    // Add the behavior to the pool
                    if (behavior != null)
                    {
                        EntityBehaviors.Add(type, entity.Name, behavior);
                        behaviors.Add(behavior);
                    }
                }

                // Setup the distinct behaviors
                foreach (var behavior in behaviors)
                {
                    entity.SetupBehavior(behavior, this);
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="circuit">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        protected override void Setup(EntityCollection circuit)
        {
            circuit.ThrowIfNull(nameof(circuit));
            base.Setup(circuit);

            // Get behaviors and configuration data
            var config = Configurations.Get <BaseConfiguration>().ThrowIfNull("base configuration");

            DcMaxIterations            = config.DcMaxIterations;
            AbsTol                     = config.AbsoluteTolerance;
            RelTol                     = config.RelativeTolerance;
            _temperatureBehaviors      = EntityBehaviors.GetBehaviorList <ITemperatureBehavior>();
            _loadBehaviors             = EntityBehaviors.GetBehaviorList <IBiasingBehavior>();
            _initialConditionBehaviors = EntityBehaviors.GetBehaviorList <IInitialConditionBehavior>();

            // Create the state for this simulation
            RealState = new BaseSimulationState
            {
                Gmin = config.Gmin
            };
            _isPreordered  = false;
            _shouldReorder = true;
            var strategy = RealState.Solver.Strategy;

            strategy.RelativePivotThreshold = config.RelativePivotThreshold;
            strategy.AbsolutePivotThreshold = config.AbsolutePivotThreshold;

            // Setup the load behaviors
            _realStateLoadArgs = new LoadStateEventArgs(RealState);
            for (var i = 0; i < _loadBehaviors.Count; i++)
            {
                _loadBehaviors[i].GetEquationPointers(Variables, RealState.Solver);
            }
            RealState.Setup(Variables);

            // Set up nodesets
            foreach (var ns in config.Nodesets)
            {
                _nodesets.Add(new ConvergenceAid(ns.Key, ns.Value));
            }
        }
        /// <summary>
        /// Set up the simulation.
        /// </summary>
        /// <param name="circuit">The circuit that will be used.</param>
        /// <exception cref="ArgumentNullException">circuit</exception>
        /// <exception cref="SpiceSharp.CircuitException">
        /// {0}: No time configuration".FormatString(Name)
        /// or
        /// {0}: No integration method specified".FormatString(Name)
        /// </exception>
        protected override void Setup(Circuit circuit)
        {
            if (circuit == null)
            {
                throw new ArgumentNullException(nameof(circuit));
            }
            base.Setup(circuit);

            // Get behaviors and configurations
            var config = Configurations.Get <TimeConfiguration>() ?? throw new CircuitException("{0}: No time configuration".FormatString(Name));

            _useIc = config.UseIc;
            Method = config.Method ?? throw new CircuitException("{0}: No integration method specified".FormatString(Name));
            _transientBehaviors = EntityBehaviors.GetBehaviorList <ITimeBehavior>();
            _acceptBehaviors    = EntityBehaviors.GetBehaviorList <IAcceptBehavior>();

            // Allow all transient behaviors to allocate equation elements and create states
            for (var i = 0; i < _transientBehaviors.Count; i++)
            {
                _transientBehaviors[i].GetEquationPointers(RealState.Solver);
                _transientBehaviors[i].CreateStates(Method);
            }
            Method.Setup(this);

            // TODO: Compatibility - initial conditions from nodes instead of configuration should be removed eventually
            if (config.InitialConditions.Count == 0)
            {
                foreach (var ns in Variables.InitialConditions)
                {
                    _initialConditions.Add(new ConvergenceAid(ns.Key, ns.Value));
                }
            }

            // Set up initial conditions
            foreach (var ic in config.InitialConditions)
            {
                _initialConditions.Add(new ConvergenceAid(ic.Key, ic.Value));
            }
        }
Exemple #17
0
        /// <inheritdoc/>
        protected override void CreateBehaviors(IEntityCollection entities)
        {
            base.CreateBehaviors(entities);
            _transientBehaviors  = EntityBehaviors.GetBehaviorList <ITimeBehavior>();
            _acceptBehaviors     = EntityBehaviors.GetBehaviorList <IAcceptBehavior>();
            _truncatingBehaviors = EntityBehaviors.GetBehaviorList <ITruncatingBehavior>();
            _method.Initialize();

            // Set up initial conditions
            var state = GetState <IBiasingSimulationState>();

            _initialConditions.Clear();
            foreach (var ic in TimeParameters.InitialConditions)
            {
                if (state.ContainsKey(ic.Key))
                {
                    _initialConditions.Add(new ConvergenceAid(state.GetSharedVariable(ic.Key), GetState <IBiasingSimulationState>(), ic.Value));
                }
                else
                {
                    SpiceSharpWarning.Warning(this, Properties.Resources.Simulations_ConvergenceAidVariableNotFound.FormatString(ic.Key));
                }
            }
        }
Exemple #18
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 #19
0
 /// <inheritdoc />
 protected override void CreateBehaviors(IEntityCollection entities)
 {
     base.CreateBehaviors(entities);
     _noiseBehaviors = EntityBehaviors.GetBehaviorList <INoiseBehavior>();
 }