コード例 #1
0
        public void Update()
        {
            ResetNodesState();                                                                      // Сброс состояния нод, присвоение им номеров

            foreach (Connector connector in Connectors)
            {
                if (connector.NodeA.Connections.Count == 1 && connector.NodeB.Connections.Count > 1 ||
                    connector.NodeA.Connections.Count > 1 && connector.NodeB.Connections.Count == 1)
                {
                    throw new WrongSchemeException("Unconnected pin found!");
                }
            }

            ContoursSearch();                                                                       // Получаем список замкнутых контуров

            if (Contours.Count < 1)
            {
                return;
            }

            if (Contours.Count == 1)
            {
                if (Contours.First().Connectors.Count(i => i is Battery) != 1)
                {
                    throw new WrongSchemeException("Check layout! Wrong batteries amount!");
                }

                Battery       bat      = Contours.First().Connectors.First(i => i is Battery) as Battery;
                ElementsChain batChain = new ElementsChain(new Node[] { bat.NodeA, bat.NodeB });
                double        amp      = bat.Eds / Contours.First().Connectors.Sum(i => i.Resistance) * Contours.First().SameDirected(batChain);

                Contours.First().RunElectricCurrent(amp);
                return;
            }

            ChainsSerach();                                                                         // Получаем список цепей
            UpdateChainNumbers();

            Rule1Count = Nodes.Count(i => i.Connections.Count > 2) - 1;                   // Количество уравнений по первому правилу
            int matrixSize = Chains.Count;                                                // Размер матрицы (количество неизвестных)

            CountMatrix  = new double[matrixSize, matrixSize];                            // Матрица для левой части уравнений
            resultVector = new double[matrixSize];                                        // Вектор для правой части уравнений

            for (int i = 0; i < matrixSize; i++)                                          // Уравнение
            {
                for (int j = 0; j < matrixSize; j++)                                      // Неизвестная
                {
                    if (i < Rule1Count)                                                   // Первое правило
                    {
                        Node curNode = Nodes                                              // Следующая по списку нода с >2 ног
                                       .Where(nd => nd.Connections.Count > 2)
                                       .ElementAt(i);
                        CountMatrix[i, j] = Chains[j].GetCurrentDirection(curNode);
                    }
                    else                                                                            // Второе правило
                    {
                        // Если контур включает в себя хотябы один коннектор из цепочки, то он включает в себя всю цепочку
                        if (Contours[i - Rule1Count].Connectors.Contains(Chains[j].Connectors.First()))
                        {
                            CountMatrix[i, j] = Chains[j].GetResistance() * Contours[i - Rule1Count].SameDirected(Chains[j]);
                        }
                    }
                }
                resultVector[i] = i < Rule1Count ? 0 : Contours[i - Rule1Count].GetEds();      // Результирующий вектор (0 или сумма ЭДС)
            }

            KramerCounter kc = new KramerCounter(CountMatrix, resultVector);            // Крамер

            double[] xv = kc.Answer;

            for (int i = 0; i < xv.Length; i++)
            {
                Chains[i].RunElectricCurrent(-xv[i]);
            }
            Fire("Quations", "DisplayMatrix");
        }