Beispiel #1
0
        /// <summary>
        /// Find a voltage driver that closes a voltage drive loop.
        /// </summary>
        /// <returns>
        /// The component that closes the loop.
        /// </returns>
        private Component FindVoltageDriveLoop()
        {
            // Remove the ground node and make a map for reducing the matrix complexity
            var index = 1;
            var map   = new Dictionary <int, int> {
                { 0, 0 }
            };

            foreach (var vd in _voltageDriven)
            {
                if (vd.Node1 != 0)
                {
                    if (!map.ContainsKey(vd.Node1))
                    {
                        map.Add(vd.Node1, index++);
                    }
                }
                if (vd.Node2 != 0)
                {
                    if (!map.ContainsKey(vd.Node2))
                    {
                        map.Add(vd.Node2, index++);
                    }
                }
            }

            // Determine the rank of the matrix
            var solver = new RealSolver(Math.Max(_voltageDriven.Count, map.Count));

            for (var i = 0; i < _voltageDriven.Count; i++)
            {
                var pins = _voltageDriven[i];
                solver.GetMatrixElement(i + 1, map[pins.Node1]).Value += 1.0;
                solver.GetMatrixElement(i + 1, map[pins.Node2]).Value += 1.0;
            }
            try
            {
                // Try refactoring the matrix
                solver.OrderAndFactor();
            }
            catch (SingularException exception)
            {
                /*
                 * If the rank of the matrix is lower than the number of driven nodes, then
                 * the matrix is not solvable for those nodes. This means that there are
                 * voltage sources driving nodes in such a way that they cannot be solved.
                 */
                if (exception.Index <= _voltageDriven.Count)
                {
                    var indices = new LinearSystemIndices(exception.Index);
                    solver.InternalToExternal(indices);
                    return(_voltageDriven[indices.Row - 1].Source);
                }
            }
            return(null);
        }
        /// <summary>
        /// Assert internal element
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="expected"></param>
        void AssertInternal(Solver <double> solver, int row, int col, double expected)
        {
            var indices = new LinearSystemIndices(row, col);

            solver.InternalToExternal(indices);
            var elt = solver.FindMatrixElement(indices.Row, indices.Column);

            Assert.AreNotEqual(null, elt);
            Assert.AreEqual(expected, elt.Value);
        }