Exemplo n.º 1
0
        /// <summary>
        /// Adds a new waveform to the signal, updates <see cref="FinalWaveform"/>
        /// </summary>
        /// <param name="description">Positive value</param>
        /// <param name="values"></param>
        protected void AddWaveformHelper(ISourceDescription description, IEnumerable <double> values)
        {
            // Null check
            if (description == null || values == null)
            {
                throw new ArgumentNullException();
            }

            // Check if number of samples in the waveform matches this time domain signal
            if (values.Count() != Samples)
            {
                throw new ArgumentException(nameof(values) + $" must have count equal to {Samples} ({nameof(Samples)})");
            }

            // If the source description is already present in the collection
            if (_Waveforms.ContainsKey(description))
            {
                // Add the new values to those already present
                _Waveforms[description] = _Waveforms[description].MergeSelect(values, (x, y) => x + y);
            }
            else
            {
                // Otherwise make a new entry
                _Waveforms.Add(description, values);
            }

            // And finally add values to the final waveform
            values.ForEach((x, i) => _FinalWaveform[i] += x);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Constructor with parameters
        /// </summary>
        /// <param name="nodeIndices">Nodes present in this instance</param>
        /// <param name="activeComponentsIndices">Active components indices present in this instance</param>
        /// <param name="defaultValueFactory">Func used for generating initial values in <see cref="Potentials"/> and <see cref="Currents"/>,
        /// if null (which is the default value) <see cref="default(T)"/> will be used</param>
        /// <param name="sourceDescription">Description of source that produced this state. Can be null - it means that it's indetermined or
        /// many sources produced this state</param>
        public GenericState(IEnumerable <int> nodeIndices, IEnumerable <int> activeComponentsIndices, ISourceDescription sourceDescription,
                            Func <T> defaultValueFactory = null)
        {
            // Null checks
            if (nodeIndices == null)
            {
                throw new ArgumentNullException(nameof(nodeIndices));
            }

            if (activeComponentsIndices == null)
            {
                throw new ArgumentNullException(nameof(activeComponentsIndices));
            }

            // Make an entry for each node
            foreach (var node in nodeIndices)
            {
                Potentials.Add(node, defaultValueFactory == null ? default(T) : defaultValueFactory());
            }

            // Make an entry for each index
            foreach (var index in activeComponentsIndices)
            {
                Currents.Add(index, defaultValueFactory == null ? default(T) : defaultValueFactory());
            }

            // Assign source description
            SourceDescription = sourceDescription;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Configures the <paramref name="source"/> for desired <paramref name="state"/>.
        /// Outputs is set to 1 in order to generate transfer functions.
        /// </summary>
        /// <param name="sourceIndex"></param>
        /// <param name="state">True if the source is active, false if not (it is considered as short-circuit)</param>
        private void ConfigureVoltageSource(AdmittanceMatrix matrix, ISourceDescription source, bool state)
        {
            // Get the voltage source's nodes
            var nodes = _SourcesNodes[source];

            // And its index
            var sourceIndex = _IndexedComponentsIndices[source];

            // If the positive terminal is not grounded
            if (nodes.Positive != ReferenceNode)
            {
                // Fill the entry in the row corresponding to the node and column corresponding to the source (plus start column)
                // with 1 (positive terminal)
                matrix._B[nodes.Positive, sourceIndex] = 1;

                // Fill the entry in the row corresponding to the source (plus starting row)
                // and column corresponding to the node with 1 (positive terminal)
                matrix._C[sourceIndex, nodes.Positive] = 1;
            }

            // If the negative terminal is not grounded
            if (nodes.Negative != ReferenceNode)
            {
                // Fill the entry in the row corresponding to the node and column corresponding to the source (plus start column)
                // with -1 (negative terminal)
                matrix._B[nodes.Negative, sourceIndex] = -1;

                // Fill the entry in the row corresponding to the source (plus starting row)
                // and column corresponding to the node with -1 (negative terminal)
                matrix._C[sourceIndex, nodes.Negative] = -1;
            }

            matrix._E[sourceIndex] = state ? source.OutputValue : 0;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Activates (all current sources are not active by default) the current source given by the index.
        /// </summary>
        /// <param name="sourceIndex"></param>
        private void ActivateCurrentSource(AdmittanceMatrix matrix, ISourceDescription source)
        {
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //                                                                                                                                         //
            // Matrix I has += and -= instead of just assignment because that's the actual correct way of building the matrix.                         //
            // However it only matters if there is more than one source active at a time. For example, if there would be 2 sources, each connected     //
            // to the same node, then the value in the corresponding entry in I matrix should be a sum of produced currents. Simply assigning value    //
            // would result in an error. Again, for now, admittance matrices are built only for one source, however if it would happen that it changes //
            // in the future then there won't be any errors because of assigning rather than adding / subtracting.                                     //
            //                                                                                                                                         //
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            // Get the nodes
            var nodes = _SourcesNodes[source];

            // If the positive terminal is not grounded
            if (nodes.Positive != ReferenceNode)
            {
                // Add source's current to the node
                matrix._I[nodes.Positive] += source.OutputValue;
            }

            // If the negative terminal is not grounded
            if (nodes.Negative != -1)
            {
                // Subtract source's current from the node
                matrix._I[nodes.Negative] -= source.OutputValue;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns an admittance matrix for current source given by <paramref name="source"/>.
        /// </summary>
        /// <returns></returns>
        private AdmittanceMatrix ConstructForCurrentSource(ISourceDescription source)
        {
            // Create initialized matrix
            var matrix = ConstructAndInitialize(source.Frequency);

            // Turn on the current source
            ActivateCurrentSource(matrix, source);

            return(matrix);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns an admittance matrix for voltage source given by <paramref name="source"/>.
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private AdmittanceMatrix ConstructForVoltageSource(ISourceDescription source)
        {
            // Create initialized matrix
            var matrix = ConstructAndInitialize(source.Frequency);

            // Turn on the voltage source
            ConfigureVoltageSource(matrix, source, true);

            return(matrix);
        }
Exemplo n.º 7
0
 /// <summary>
 /// Adds <paramref name="value"/> to this <see cref="PhasorDomainSignal"/>. Either creates a new entry or adds the <paramref name="value"/>
 /// to the entry already existing for <paramref name="source"/>.
 /// </summary>
 /// <param name="source"></param>
 /// <param name="value"></param>
 protected void AddPhasorHelper(ISourceDescription source, Complex value)
 {
     // If source is already present in the dictionary
     if (_Phasors.ContainsKey(source))
     {
         // Add the value to the stored value
         _Phasors[source] += value;
     }
     else
     {
         // Otherwise create a new entry
         _Phasors.Add(source, value);
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Returns phasors constructed for source given by <paramref name="sourceDescription"/>
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="sourceDescription"></param>
        private PhasorState GetPhasor(AdmittanceMatrixFactory factory, ISourceDescription sourceDescription)
        {
            var state = new PhasorState(factory.NodesCount, factory.ActiveComponentsCount, sourceDescription);

            // Create an admittance matrix corresponding to the given source
            factory.Construct(sourceDescription).
            // And solve it
            Solve(out var nodePotentials, out var activeComponentsCurrents);

            // Add the results to state
            state.AddValues(nodePotentials, activeComponentsCurrents);

            return(state);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Constructrs an admittance matrix for the given source.
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public AdmittanceMatrix Construct(ISourceDescription source)
        {
            switch (source.SourceType)
            {
            case SourceType.ACVoltageSource:
            case SourceType.DCVoltageSource:
            {
                return(ConstructForVoltageSource(source));
            }

            case SourceType.DCCurrentSource:
            {
                return(ConstructForCurrentSource(source));
            }

            default:
            {
                throw new Exception($"Unhandled {nameof(SourceType)}");
            }
            }
        }
Exemplo n.º 10
0
 /// <summary>
 /// Constructor with parameters
 /// </summary>
 /// <param name="nodeIndices">Nodes present in this instance</param>
 /// <param name="activeComponentsCount">Number of active components, indices available in this instance will be given by a
 /// range: 0 to <paramref name="activeComponentsCount"/> - 1</param>
 /// <param name="defaultValueFactory">Func used for generating initial values in <see cref="Potentials"/> and <see cref="Currents"/>,
 /// if null (which is the default value) <see cref="default(T)"/> will be used</param>
 /// <param name="sourceDescription">Description of source that produced this state. Can be null - it means that it's indetermined or
 /// many sources produced this state</param>
 public GenericState(IEnumerable <int> nodeIndices, int activeComponentsCount, ISourceDescription sourceDescription,
                     Func <T> defaultValueFactory = null) :
     this(nodeIndices, Enumerable.Range(0, activeComponentsCount), sourceDescription, defaultValueFactory)
 {
 }
Exemplo n.º 11
0
 /// <summary>
 /// Adds a new waveform to the signal. If one already exists for source described by <paramref name="description"/>, adds them together,
 /// otherwise makes a new entry in <see cref="ITimeDomainSignal.ACWaveforms"/> or <see cref="ITimeDomainSignal.DCWaveforms"/>
 /// </summary>
 /// <param name="description"></param>
 /// <param name="value"></param>
 /// <exception cref="ArgumentNullException"></exception>
 /// <exception cref="ArgumentException"></exception>
 public void AddWaveform(ISourceDescription description, IEnumerable <double> values) => AddWaveformHelper(description, values);
Exemplo n.º 12
0
 /// <summary>
 /// Used to add <see cref="KeyValuePair{TKey, TValue}"/> to <see cref="INodePotentialBias.Phasors"/>
 /// </summary>
 /// <param name="source"></param>
 /// <param name="value"></param>
 public void AddPhasor(ISourceDescription source, Complex value) => AddPhasorHelper(source, value);
Exemplo n.º 13
0
 /// <summary>
 /// Constructor with parameters
 /// </summary>
 /// <param name="nodeIndices">Nodes present in this instance</param>
 /// <param name="activeComponentsCount">Number of active components, indices available in this instance will be given by a
 /// range: 0 to <paramref name="activeComponentsCount"/> - 1</param>
 /// <param name="sourceDescription">Description of source that produced this state. Can be null - it means that it's indetermined or
 /// many sources produced this state</param>
 public InstantenousState(IEnumerable <int> nodeIndices, int activeComponentsCount, ISourceDescription sourceDescription) :
     this(nodeIndices, Enumerable.Range(0, activeComponentsCount), sourceDescription)
 {
 }
Exemplo n.º 14
0
 /// <summary>
 /// Constructor with parameters
 /// </summary>
 /// <param name="nodeIndices">Nodes present in this instance</param>
 /// <param name="activeComponentsIndices">Active components indices present in this instance</param>
 /// <param name="sourceDescription">Description of source that produced this state. Can be null - it means that it's indetermined or
 /// many sources produced this state</param>
 public InstantenousState(IEnumerable <int> nodeIndices, IEnumerable <int> activeComponentsIndices, ISourceDescription sourceDescription) :
     base(nodeIndices, activeComponentsIndices, sourceDescription)
 {
 }
Exemplo n.º 15
0
 /// <summary>
 /// Constructor with parameters
 /// </summary>
 /// <param name="nodesCount">Number of nodes, indicies available in this instance will be given by a range:
 /// 0 to <paramref name="nodesCount"/></param>
 /// <param name="activeComponentsCount">Number of active components, indices available in this instance will be given by a
 /// range: 0 to <paramref name="activeComponentsCount"/> - 1</param>
 /// <param name="sourceDescription">Description of source that produced this state. Can be null - it means that it's indetermined or
 /// many sources produced this state</param>
 public PhasorState(int nodesCount, int activeComponentsCount, ISourceDescription sourceDescription) :
     this(Enumerable.Range(0, nodesCount), Enumerable.Range(0, activeComponentsCount), sourceDescription)
 {
 }
Exemplo n.º 16
0
 /// <summary>
 /// Adds a new waveform to the signal. If one already exists for source described by <paramref name="description"/>, adds them together,
 /// otherwise makes a new entry in <see cref="ITimeDomainSignal.ACWaveforms"/>. or <see cref="ITimeDomainSignal.DCWaveforms"/>.
 /// The waveform is given by a constant value - full
 /// waveform will be constructed from it.
 /// </summary>
 /// <param name="description"></param>
 /// <param name="value"></param>
 /// <exception cref="ArgumentNullException"></exception>
 public void AddWaveform(ISourceDescription description, double value) =>
 AddWaveform(description, WaveformBuilder.ConstantWaveform(value, Samples));
Exemplo n.º 17
0
 /// <summary>
 /// Constructor with parameters
 /// </summary>
 /// <param name="nodeIndices">Nodes present in this instance</param>
 /// <param name="activeComponentsIndices">Active components indices present in this instance</param>
 /// <param name="sourceDescription">Description of source that produced this state. Can be null - it means that it's indetermined or
 /// many sources produced this state</param>
 public WaveformState(IEnumerable <int> nodeIndices, IEnumerable <int> activeComponentsIndices, ISourceDescription sourceDescription) :
     base(nodeIndices, activeComponentsIndices, sourceDescription, () => new List <double>())
 {
 }