Beispiel #1
0
 public static MatrixComplex CreateUnitMatrix(int dimension)
 {
     if (dimension < 1)
     {
         throw new ArgumentException("UnitMatrix cannot be created. Check dimension.");
     }
     else
     {
         MatrixComplex UnitMatrix = new MatrixComplex(dimension, dimension);
         for (int i = 0; i < dimension; i++)
         {
             for (int j = 0; j < dimension; j++)
             {
                 if (i == j)
                 {
                     UnitMatrix.matrix[i, j] = new Complex(1.0, 0.0);
                 }
                 else
                 {
                     UnitMatrix.matrix[i, j] = new Complex(0.0, 0.0);
                 }
             }
         }
         return(UnitMatrix);
     }
 }
Beispiel #2
0
        public static MatrixComplex CopyMatrix(MatrixComplex MatrixForCopy)
        {
            MatrixComplex NewMatrix = new MatrixComplex(MatrixForCopy.GetRows, MatrixForCopy.GetColumns);

            for (int i = 0; i < NewMatrix.GetRows; i++)
            {
                for (int j = 0; j < NewMatrix.GetColumns; j++)
                {
                    NewMatrix.matrix[i, j] = new Complex(MatrixForCopy.matrix[i, j]);
                }
            }
            return(NewMatrix);
        }
Beispiel #3
0
        public static MatrixComplex operator *(MatrixComplex mat, Complex factor)
        {
            MatrixComplex result = CopyMatrix(mat);;

            for (int i = 0; i < mat.GetRows; i++)
            {
                for (int j = 0; j < mat.GetColumns; j++)
                {
                    result.matrix[i, j] = mat.matrix[i, j] * factor;
                }
            }
            return(result);
        }
Beispiel #4
0
        //Деление элементов матрицы на число
        public static MatrixComplex operator /(MatrixComplex mat, double factor)
        {
            MatrixComplex result = new MatrixComplex(mat.GetRows, mat.GetColumns);

            for (int i = 0; i < mat.GetRows; i++)
            {
                for (int j = 0; j < mat.GetColumns; j++)
                {
                    result.matrix[i, j] = mat.matrix[i, j] / factor;
                }
            }
            return(result);
        }
        public static MatrixComplex NodesVoltageInitialAprox(Node[] nodesArray, int baseNumber)
        {
            MatrixComplex InitialAprox = new MatrixComplex(nodesArray.Length - 1, 1);

            int k = 0;

            for (int i = 0; i < nodesArray.Length; i++)
            {
                if (i == baseNumber)
                {
                    continue;
                }
                InitialAprox.matrix[k, 0] = new Complex(nodesArray[i].NodeNominalVoltage, 0);
                k++;
            }
            return(InitialAprox);
        }
        public static MatrixComplex GetLoadMatrix(Node[] nodesArray, int baseNumber)
        {
            //Console.Write("GetLoadMatrix...");
            MatrixComplex LoadMatrix = new MatrixComplex(nodesArray.Length - 1, 1);
            int           k          = 0;

            for (int i = 0; i < nodesArray.Length; i++)
            {
                if (i == baseNumber)
                {
                    continue;
                }
                LoadMatrix.matrix[k, 0] = nodesArray[i].NodeLoad - nodesArray[i].NodeGeneration;
                k++;
            }
            //Console.WriteLine("Success!");
            return(LoadMatrix);
        }
Beispiel #7
0
                return(JointMatrix);  //Почему не на матрицу перестановок?

                static int FindNotZero(MatrixComplex GaussMatrix, int currentRow, int currentColumn, bool direction)
                {
                    //direction = false(down); direction = true(up)
                    bool IsFound = false;
                    int  row     = currentRow;

                    while (!IsFound)
                    {
                        if (GaussMatrix.matrix[row, currentColumn] == new Complex(0, 0))
                        {
                            if (direction)
                            {
                                if (row == 0)
                                {
                                    Console.WriteLine("Обнаружена сингулярность");
                                    break;
                                }
                                else
                                {
                                    row--;
                                }
                            }
                            else
                            {
                                if (row == GaussMatrix.GetRows - 1)
                                {
                                    Console.WriteLine("Обнаружена сингулярность");
                                    break;
                                }
                                else
                                {
                                    row++;
                                }
                            }
                        }
                        else
                        {
                            IsFound = true;
                        }
                    }
                    return(row);
                }
Beispiel #8
0
 public static MatrixComplex CreateDiagMatrix(MatrixComplex VectorMatrix)
 {
     if (VectorMatrix.GetRows > VectorMatrix.GetColumns)
     {
         MatrixComplex DiagMatrix = new MatrixComplex(VectorMatrix.GetRows, VectorMatrix.GetRows);
         for (int i = 0; i < DiagMatrix.GetRows; i++)
         {
             for (int j = 0; j < DiagMatrix.GetColumns; j++)
             {
                 if (i == j)
                 {
                     DiagMatrix.matrix[i, j] = VectorMatrix.matrix[i, 0];
                 }
                 else
                 {
                     DiagMatrix.matrix[i, j] = new Complex(0.0, 0.0);
                 }
             }
         }
         return(DiagMatrix);
     }
     else
     {
         MatrixComplex DiagMatrix = new MatrixComplex(VectorMatrix.GetColumns, VectorMatrix.GetColumns);
         for (int i = 0; i < DiagMatrix.GetRows; i++)
         {
             for (int j = 0; j < DiagMatrix.GetColumns; j++)
             {
                 if (i == j)
                 {
                     DiagMatrix.matrix[i, j] = VectorMatrix.matrix[0, i];
                 }
                 else
                 {
                     DiagMatrix.matrix[i, j] = new Complex(0.0, 0.0);
                 }
             }
         }
         return(DiagMatrix);
     }
 }
Beispiel #9
0
        //Вычитание матриц
        public static MatrixComplex operator -(MatrixComplex mat1, MatrixComplex mat2)
        {
            if ((mat1.GetRows != mat2.GetRows) | (mat1.GetColumns != mat2.GetColumns))
            {
                throw new ArgumentException("Matrices can not be deducted");
            }
            else
            {
                MatrixComplex result = new MatrixComplex(mat1.GetRows, mat1.GetColumns);

                for (int i = 0; i < mat1.GetRows; i++)
                {
                    for (int j = 0; j < mat1.GetColumns; j++)
                    {
                        result.matrix[i, j] = new Complex(0, 0);
                        result.matrix[i, j] = mat1.matrix[i, j] - mat2.matrix[i, j];
                    }
                }
                return(result);
            }
        }
        public static MatrixComplex CalcJacobiMatrix(MatrixComplex ConductivityMatrix, MatrixComplex baseConductivity, MatrixComplex NodesVoltage, MatrixComplex diagConjugateNodesVoltage, Complex baseVoltage)
        {
            MatrixComplex JacobiMatrix = new MatrixComplex(ConductivityMatrix.GetRows, ConductivityMatrix.GetColumns);

            for (int i = 0; i < JacobiMatrix.GetRows; i++)
            {
                for (int j = 0; j < JacobiMatrix.GetColumns; j++)
                {
                    if (i == j) //Диагональные элементы
                    {
                        JacobiMatrix.matrix[i, j] = diagConjugateNodesVoltage.matrix[i, j] * ConductivityMatrix.matrix[i, j];
                    }
                    else //Недиагональные элементы
                    {
                        JacobiMatrix.matrix[i, j] = diagConjugateNodesVoltage.matrix[i, i] * ConductivityMatrix.matrix[i, j];
                    }
                }
            }

            return(JacobiMatrix);
        }
        public static MatrixComplex GetConductivityMatrix(Node[] nodesArray, Line[] linesArray, int numberNodes, ref MatrixComplex baseConductivity, ref int baseNumber)
        {
            //Console.Write("GetConductivityMatrix...");
            MatrixComplex ConductivityMatrix = new MatrixComplex(numberNodes, numberNodes);

            for (int i = 0; i < numberNodes; i++)
            {
                if (nodesArray[i].NodeType == "База")
                {
                    baseNumber = i;
                }
                for (int j = 0; j < numberNodes; j++)
                {
                    ConductivityMatrix.matrix[i, j] = new Complex();
                    if (i == j)
                    {
                        ConductivityMatrix.matrix[i, j] = (-1) * (FindAllInclusions(nodesArray, linesArray, i)) - nodesArray[i].NodeConductivity;
                    }
                    else
                    {
                        ConductivityMatrix.matrix[i, j] = FindBranches(nodesArray, linesArray, i, j);
                    }
                }
            }
            Console.WriteLine("Полная матрица проводимостей:\n" + ConductivityMatrix);
            int k = 0;

            for (int i = 0; i < numberNodes; i++)
            {
                if (i == baseNumber)
                {
                    continue;
                }
                baseConductivity.matrix[k, 0] = ConductivityMatrix.matrix[i, baseNumber];
                k++;
            }
            //Console.WriteLine("Success!");
            return(MatrixComplex.CreateMinor(ConductivityMatrix, baseNumber, baseNumber));
        }
        public static void UseSolverComplex(int numberNodes, int step, int numberComutations, int baseNumber,
                                            Line[] linesArray, Node[] nodesArray, Stopwatch swWholeProgram, Stopwatch sw, LinkWithExcel link)
        {
            #region ComplexCalc

            sw.Start();

            MatrixComplex baseConductivityC   = new MatrixComplex(numberNodes - 1);
            MatrixComplex ConductivityMatrixC = SolverComplex.GetConductivityMatrix(nodesArray, linesArray, numberNodes, ref baseConductivityC, ref baseNumber);
            MatrixComplex LoadMatrixC         = SolverComplex.GetLoadMatrix(nodesArray, baseNumber);
            MatrixComplex NodesVoltageC       = SolverComplex.NodesVoltageInitialAprox(nodesArray, baseNumber);
            Complex       baseVoltageC        = new Complex(nodesArray[baseNumber].NodeNominalVoltage, 0);

            sw.Stop();

            Console.WriteLine("Матрица проводимостей:\n" + ConductivityMatrixC);
            Console.WriteLine("Вектор проводимостей базисного узла\n" + baseConductivityC);
            Console.WriteLine("Вектор напряжений\n" + NodesVoltageC);
            Console.WriteLine("Напряжение базисного узла: " + baseVoltageC + "\n");
            Console.WriteLine("Вектор мощностей:\n" + LoadMatrixC + "\n");
            Console.WriteLine("Параметры схемы загружены за " + sw.ElapsedMilliseconds + " мс\n"); sw.Reset();

            double AccuracyC = 0.1; //МВт
            int    stepC;

            sw.Reset();
            sw.Start();

            MatrixComplex EstimatedNodesVoltageC = SolverComplex.SolveEquation(NodesVoltageC, ConductivityMatrixC, baseConductivityC, LoadMatrixC, baseVoltageC, AccuracyC, out stepC);

            sw.Stop();
            Console.WriteLine($"Итераций расчета: {stepC}\nВремя расчета: {sw.ElapsedMilliseconds} мс\nТочность: {AccuracyC} МВт\n\n" + EstimatedNodesVoltageC);
            Console.WriteLine(EstimatedNodesVoltageC.matrix[0, 0].Module + "<" + EstimatedNodesVoltageC.matrix[0, 0].Angle);
            Console.WriteLine(EstimatedNodesVoltageC.matrix[1, 0].Module + "<" + EstimatedNodesVoltageC.matrix[1, 0].Angle);

            #endregion
        }
Beispiel #13
0
        //Перемножение матриц
        public static MatrixComplex operator *(MatrixComplex mat1, MatrixComplex mat2)
        {
            if (mat1.GetColumns != mat2.GetRows)
            {
                throw new ArgumentException("Matrices can not be multiplied");
            }
            else
            {
                MatrixComplex result = new MatrixComplex(mat1.GetRows, mat2.GetColumns);

                for (int i = 0; i < mat1.GetRows; i++)
                {
                    for (int j = 0; j < mat2.GetColumns; j++)
                    {
                        result.matrix[i, j] = new Complex(0, 0);
                        for (int k = 0; k < mat1.GetColumns; k++)
                        {
                            result.matrix[i, j] += mat1.matrix[i, k] * mat2.matrix[k, j];
                        }
                    }
                }
                return(result);
            }
        }
Beispiel #14
0
        public static MatrixComplex CreateInvertedMatrixGauss(MatrixComplex mat)
        {
            //Console.WriteLine("CreateInvertedMatrixGauss...");
            if (mat.GetRows != mat.GetColumns)
            {
                throw new ArgumentException("MatrixComplex cannot be inverted");
            }
            else
            {
                MatrixComplex GaussMatrix = CopyMatrix(mat);;

                MatrixComplex JointMatrix = CreateUnitMatrix(mat.GetRows);

                MatrixComplex TranspositionMatrix = CreateUnitMatrix(mat.GetRows);
                Complex       zero = new Complex(0.0, 0.0);

                //Прямой ход
                for (int j = 0; j < GaussMatrix.GetColumns; j++)
                {
                    for (int i = j; i < GaussMatrix.GetRows; i++)
                    {
                        if (GaussMatrix.matrix[j, j] == zero)
                        {
                            int newRow = FindNotZero(GaussMatrix, j, j, false);
                            SwapRows(GaussMatrix, i, newRow);
                            SwapRows(JointMatrix, i, newRow);
                            SwapRows(TranspositionMatrix, i, newRow);
                        }
                        if (i == j)
                        {
                            continue;
                        }
                        SummRows(JointMatrix, j, i, (-1.0) * GaussMatrix.matrix[i, j] / GaussMatrix.matrix[j, j]);
                        SummRows(GaussMatrix, j, i, (-1.0) * GaussMatrix.matrix[i, j] / GaussMatrix.matrix[j, j]);
                    }
                }
                //Обратный ход
                for (int j = GaussMatrix.GetColumns - 1; j > -1; j--)
                {
                    for (int i = j; i > -1; i--)
                    {
                        if (GaussMatrix.matrix[j, j] == zero)
                        {
                            int newRow = FindNotZero(GaussMatrix, j, j, true);
                            SwapRows(GaussMatrix, i, newRow);
                            SwapRows(JointMatrix, i, newRow);
                            SwapRows(TranspositionMatrix, i, newRow);
                        }
                        if (i == j)
                        {
                            continue;
                        }
                        SummRows(JointMatrix, j, i, (-1.0) * GaussMatrix.matrix[i, j] / GaussMatrix.matrix[j, j]);
                        SummRows(GaussMatrix, j, i, (-1.0) * GaussMatrix.matrix[i, j] / GaussMatrix.matrix[j, j]);
                    }
                }
                for (int i = 0; i < GaussMatrix.GetRows; i++)
                {
                    MultiplyRow(JointMatrix, i, GaussMatrix.matrix[i, i]);
                    MultiplyRow(GaussMatrix, i, GaussMatrix.matrix[i, i]);
                }
                return(JointMatrix);  //Почему не на матрицу перестановок?
        public static MatrixComplex SolveEquation(MatrixComplex NodesVoltage, MatrixComplex ConductivityMatrixC, MatrixComplex baseConductivityC, MatrixComplex LoadMatrixC, Complex baseVoltage, double Accuracy, out int step)
        {
            int           r = NodesVoltage.GetRows;
            int           c = NodesVoltage.GetColumns;
            MatrixComplex diagNodesVoltage = new MatrixComplex(r, r);                                              //Create diagonal nodes voltage matrix
            MatrixComplex ConjLoadMatrix   = MatrixComplex.ConjugateMatrixElements(LoadMatrixC);                   //Create matrix with conjugated voltages
            MatrixComplex ConjNodesVoltage = MatrixComplex.ConjugateMatrixElements(NodesVoltage);
            MatrixComplex PowerMismatch    = new MatrixComplex(r, c);
            MatrixComplex PowerMismatch2   = new MatrixComplex(r, c);


            bool   AccuracyIsReached = false;
            double EuqlidianNorm     = 0;
            double EuqlidianNormN_0;
            int    counter = -1;

            step = 0;

            while (!AccuracyIsReached)
            {
                EuqlidianNormN_0 = EuqlidianNorm;

                //Метод Зейделя
                for (int i = 0; i < NodesVoltage.GetRows; i++)
                {
                    NodesVoltage.matrix[i, 0] = ConjLoadMatrix.matrix[i, 0] / ConjNodesVoltage.matrix[i, 0] - baseConductivityC.matrix[i, 0] * baseVoltage;

                    for (int j = 0; j < NodesVoltage.GetRows; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }
                        NodesVoltage.matrix[i, 0] -= NodesVoltage.matrix[j, 0] * ConductivityMatrixC.matrix[i, j];
                    }

                    NodesVoltage.matrix[i, 0] = NodesVoltage.matrix[i, 0] / ConductivityMatrixC.matrix[i, i];
                }

                ConjNodesVoltage = MatrixComplex.ConjugateMatrixElements(NodesVoltage);

                step++;

                for (int i = 0; i < NodesVoltage.GetRows; i++)
                {
                    PowerMismatch.matrix[i, 0] = baseConductivityC.matrix[i, 0] * baseVoltage;
                    for (int j = 0; j < NodesVoltage.GetRows; j++)
                    {
                        PowerMismatch.matrix[i, 0] += ConductivityMatrixC.matrix[i, j] * NodesVoltage.matrix[j, 0];
                    }
                    PowerMismatch.matrix[i, 0] *= ConjNodesVoltage.matrix[i, 0];
                    PowerMismatch.matrix[i, 0] -= ConjLoadMatrix.matrix[i, 0];
                }

                EuqlidianNorm = Math.Abs(PowerMismatch.matrix[0, 0].Real);
                for (int i = 1; i < r; i++)
                {
                    if (EuqlidianNorm < Math.Abs(PowerMismatch.matrix[i, 0].Real))
                    {
                        EuqlidianNorm = Math.Abs(PowerMismatch.matrix[i, 0].Real);
                    }
                }

                if (EuqlidianNorm < Accuracy)
                {
                    AccuracyIsReached = true;
                }
                if (EuqlidianNormN_0 < EuqlidianNorm)
                {
                    counter++;
                }
                if (counter > 50)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Режим расходится, необходимо введение в допустимую область");
                    Console.ResetColor();
                    return(NodesVoltage);
                }
                if (step >= 500)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Расчет завершился, достигнуто максимальное количество итераций");
                    Console.ResetColor();
                    return(NodesVoltage);
                }
            }
            return(NodesVoltage);
        }