Пример #1
0
        private void BuildMatrices(Network network)
        {
            // Create the current measurement bus incidence matrix
            ComplexMatrix A = (new CurrentFlowMeasurementBusIncidenceMatrix(network)).Matrix;

            // Create the series admittance matrix
            ComplexMatrix Y = (new SeriesAdmittanceMatrix(network)).Matrix;

            // Create the shunt susceptance matrix
            ComplexMatrix Ys = (new LineShuntSusceptanceMatrix(network)).Matrix;

            // Compute the lower partition of the system matrix
            ComplexMatrix K = Y * A + Ys;

            List <int> rowsToBeRemoved         = RowsToRemove(network);
            int        numberOfRowsToBeRemoved = rowsToBeRemoved.Count();

            for (int i = 0; i < numberOfRowsToBeRemoved; i++)
            {
                int rowToRemove = rowsToBeRemoved.Max();
                K = MatrixCalculationExtensions.RemoveRow(K, rowToRemove);
                rowsToBeRemoved.Remove(rowToRemove);
            }

            List <int> columnsToBeRemoved         = ColumnsToRemove(network);
            int        numberOfColumnsToBeRemoved = columnsToBeRemoved.Count();

            for (int i = 0; i < numberOfColumnsToBeRemoved; i++)
            {
                int columnToRemove = columnsToBeRemoved.Max();
                K = MatrixCalculationExtensions.RemoveColumn(K, columnToRemove);
                columnsToBeRemoved.Remove(columnToRemove);
            }
        }
Пример #2
0
        /* Conduct pi section CTPT calibration of single line*/
        public int SingleLineCTPT(string LineID, Complex KV1, int FromBusNumber, TextBox textBoxMessages) //ALso need Complex KV1, Complex[,] Z
        {
            int CurrentToBus = 0;

            CurrentToBus = GetLineVI(LineID, FromBusNumber);
            bool ImpedanceAvailable = GetLineZ(LineID);

            if (!ImpedanceAvailable)
            {
                textBoxMessages.AppendLine("Calibration FAILED due to lack of Impedance data.\n");
                return(0);
            }

            Complex KI1 = new Complex();
            Complex KV2 = new Complex();
            Complex KI2 = new Complex();

            //Find the sample sets 30 samples per second, 60 seconds in all => 30 sets of samples, 60 samples per set, rule out -9999
            int i             = 0; //set number
            int feasible_flag = 0; //estimation feasible indicator, shows missing data quantity, if too large then the estimation is not feasible

            Complex[] Zhat11 = new Complex[30];
            Complex[] Zhat12 = new Complex[30];
            Complex[] Zhat21 = new Complex[30];
            Complex[] Zhat22 = new Complex[30];

            int SecondsNumber = (int)Math.Floor((double)(m_V1.Count() / 30));

            while (i < 30)
            {
                //get samples
                Complex[,] V_sample_temp = new Complex[SecondsNumber, 2];
                Complex[,] I_sample_temp = new Complex[SecondsNumber, 2];
                //Complex[] V2_sample_temp = new Complex[60];
                //Complex[] I2_sample_temp = new Complex[60];

                int current_row = 0;

                for (int j = 0; j < SecondsNumber; j++)
                {
                    current_row = j * 30 + i;
                    if ((m_V1[current_row] != -9999) && (m_I1[current_row] != -9999) && (m_V2[current_row] != -9999) && (m_I2[current_row] != -9999))
                    {
                        V_sample_temp[j, 0] = m_V1[current_row];
                        I_sample_temp[j, 0] = m_I1[current_row];
                        V_sample_temp[j, 1] = m_V2[current_row];
                        I_sample_temp[j, 1] = m_I2[current_row];
                    }
                    else
                    {
                        V_sample_temp[j, 0] = -9999;
                        I_sample_temp[j, 0] = -9999;
                        V_sample_temp[j, 1] = -9999;
                        I_sample_temp[j, 1] = -9999;
                    }
                }

                //transfer into matrix mode
                Complex     initial = 0;
                DenseMatrix Vhat    = DenseMatrix.Create(2, 1, initial);
                DenseMatrix Ihat    = DenseMatrix.Create(2, 1, initial);

                for (int k = 0; k < SecondsNumber; k++)
                {
                    if ((V_sample_temp[k, 0] != -9999) && (V_sample_temp[k, 0] != null))
                    {
                        Complex[,] V_temp_array = new Complex[2, 1];
                        V_temp_array[0, 0]      = V_sample_temp[k, 0];
                        V_temp_array[1, 0]      = V_sample_temp[k, 1];
                        DenseMatrix V_temp = DenseMatrix.OfArray(V_temp_array);

                        Complex[,] I_temp_array = new Complex[2, 1];
                        I_temp_array[0, 0]      = I_sample_temp[k, 0];
                        I_temp_array[1, 0]      = I_sample_temp[k, 1];
                        DenseMatrix I_temp = DenseMatrix.OfArray(I_temp_array);

                        if ((Vhat != null) && (V_temp != null) && (Ihat != null) && (I_temp != null))
                        {
                            if (Vhat[0, 0] == 0)
                            {
                                Vhat = V_temp;
                                Ihat = I_temp;
                            }
                            else
                            {
                                Vhat = MatrixCalculationExtensions.HorizontallyConcatenate(Vhat, V_temp);
                                Ihat = MatrixCalculationExtensions.HorizontallyConcatenate(Ihat, I_temp);
                            }
                        }
                    }
                }

                //check sample quantity, enough to do estimation or not
                if (Vhat.ColumnCount < 20)
                {
                    feasible_flag += 1;
                    i             += 1;
                    continue;
                }
                else
                {
                    Matrix <Complex> Vhat_T = Vhat.Transpose();
                    Matrix <Complex> Ihat_T = Ihat.Transpose();

                    if (Vhat_T.RowCount > Ihat_T.RowCount)
                    {
                        int a = 1;
                    }

                    //estimate Zhat
                    Matrix <Complex> Zhat_temp = null;

                    Zhat_temp = LeastSquareEstimation(Vhat_T, Ihat_T);// Ihat_T.Transpose().Multiply(Ihat_T).Inverse().Multiply(Ihat_T.Transpose()).Multiply(Vhat_T);
                    Zhat11[i] = Zhat_temp[0, 0];
                    Zhat12[i] = Zhat_temp[0, 1];
                    Zhat21[i] = Zhat_temp[1, 0];
                    Zhat22[i] = Zhat_temp[1, 1];

                    //Zhat12[i] = Zhat_temp[1, 0];
                    //Zhat21[i] = Zhat_temp[0, 1];
                }

                i += 1;
            }

            // Take average of Zhat to eliminate PMU error, if there is enough estimation results
            Complex from_bus_number     = FromBusNumber;
            Complex to_bus_number       = CurrentToBus;
            int     from_bus_number_int = FromBusNumber;
            int     to_bus_number_int   = CurrentToBus;

            if (feasible_flag < 15)
            {
                //Complex[] KI1_hat = new Complex[30];
                //Complex[] KV2_hat = new Complex[30];
                //Complex[] KI2_hat = new Complex[30];
                //Complex KI1_hat_sum = new Complex();
                //Complex KV2_hat_sum = new Complex();
                //Complex KI2_hat_sum = new Complex();

                //int valid_results_count = 0;

                //for (int l = 0; l < 30; l++)
                //{
                //    KI1_hat[l] = Zhat11[l] / m_Z[0, 0] * KV1;
                //    KV2_hat[l] = m_Z[1, 0] / Zhat12[l] * KI1_hat[l]; // Note that the estimated Zhat has been transposed, even though the matrix is symmetric, it should be transposed back for definition causes
                //    KI2_hat[l] = Zhat21[l] / m_Z[0, 1] * KV1;

                //    //if ((KI1_hat[l].Real < 2) && (KI1_hat[l].Real > 0))
                //    //{
                //        KI1_hat_sum = KI1_hat_sum + KI1_hat[l];
                //        KV2_hat_sum = KV2_hat_sum + KV2_hat[l];
                //        KI2_hat_sum = KI2_hat_sum + KI2_hat[l];
                //        valid_results_count += 1;
                //    //}
                //}

                //KI1 = KI1_hat_sum / valid_results_count;
                //KV2 = KV2_hat_sum / valid_results_count;
                //KI2 = KI2_hat_sum / valid_results_count;

                for (int l = 0; l < 30; l++)
                {
                    m_Zhat[0, 0] = m_Zhat[0, 0] + Zhat11[l];
                    m_Zhat[0, 1] = m_Zhat[0, 1] + Zhat12[l];
                    m_Zhat[1, 0] = m_Zhat[1, 0] + Zhat21[l];
                    m_Zhat[1, 1] = m_Zhat[1, 1] + Zhat22[l];
                }

                m_Zhat[0, 0] = m_Zhat[0, 0] / (30 - feasible_flag);
                m_Zhat[0, 1] = m_Zhat[0, 1] / (30 - feasible_flag);
                m_Zhat[1, 0] = m_Zhat[1, 0] / (30 - feasible_flag);
                m_Zhat[1, 1] = m_Zhat[1, 1] / (30 - feasible_flag);

                KI1 = m_Zhat[0, 0] / m_Z[0, 0] * KV1;
                KV2 = m_Z[1, 0] / m_Zhat[0, 1] * KI1; // Note that the estimated Zhat has been transposed, even though the matrix is symmetric, it should be transposed back for definition causes
                KI2 = m_Zhat[1, 0] / m_Z[0, 1] * KV1;

                //adding the computation results to K matrix and record KVs for both from_bus and to_bus for future calibrations
                int m = 0;
                while (m_K[m, 0] != 0)
                {
                    m += 1;
                }

                int Line_ID_int = Convert.ToInt32(LineID);
                m_K[m, 0] = Line_ID_int;
                m_K[m, 1] = from_bus_number;
                m_K[m, 2] = KV1;
                m_K[m, 3] = KI1;
                m_K[m, 4] = to_bus_number;
                m_K[m, 5] = KV2;
                m_K[m, 6] = KI2;
                m_K[m, 7] = new Complex(m_RXy[0], m_RXy[1]);
                m_K[m, 8] = m_RXy[2];

                ////m_KVBuses[from_bus_number_int - 1] = KV1;
                //m_KVBuses[to_bus_number_int - 1] = KV2;

                //update the propagation references
                int[]      injections_set      = FindInjections(to_bus_number_int);
                List <int> inaccurate_line_set = new List <int>(); //List to save all inaccurate lines
                for (int idx1 = 0; idx1 < injections_set.Count(); idx1++)
                {
                    if (injections_set[idx1] != Line_ID_int)
                    {
                        inaccurate_line_set.Add(injections_set[idx1]);
                    }
                }
                //Accurate Voltage Propagation
                Matrix <Complex> KV_injections_set = KVPropagation(inaccurate_line_set, Line_ID_int, to_bus_number_int, KV2);

                int pointer = 0;
                for (int idx1 = 0; idx1 < m_currentSystem.Network.LineNum; idx1++)
                {
                    if (m_KVLines[idx1].Line_ID == 0)
                    {
                        pointer = idx1;
                        break;
                    }
                }
                for (int idx2 = 0; idx2 < KV_injections_set.RowCount; idx2++)
                {
                    if ((pointer + idx2) < m_currentSystem.Network.LineNum)
                    {
                        m_KVLines[pointer + idx2].Line_ID      = inaccurate_line_set[idx2];
                        m_KVLines[pointer + idx2].From_bus_num = to_bus_number_int;
                        m_KVLines[pointer + idx2].KV1          = KV_injections_set[idx2, 0];
                    }
                }

                //Set visited line to be 1
                for (int n = 0; n < m_currentSystem.Network.LineNum; n++)
                {
                    if (Line_ID_int == m_lineVisited[n, 0])
                    {
                        m_lineVisited[n, 1] = 1;
                        break;
                    }
                }

                string msg0 = "### Line " + LineID.ToString() + " from bus " +
                              m_currentSystem.Network.BusOriginalLibrary[from_bus_number_int - 1].ToString() + " to bus " +
                              m_currentSystem.Network.BusOriginalLibrary[to_bus_number_int - 1].ToString() + " has been calibrated.\n";
                textBoxMessages.AppendLine(msg0);
            }
            else
            {
                string msg1 = "!!! Line " + LineID.ToString() + " from bus " +
                              m_currentSystem.Network.BusOriginalLibrary[from_bus_number_int - 1].ToString() + " to bus " +
                              m_currentSystem.Network.BusOriginalLibrary[to_bus_number_int - 1].ToString() + " can NOT be calibrated due to limited data.\n";
                textBoxMessages.AppendLine(msg1);
            }

            return(0);
        }
Пример #3
0
        /* Conduct PI section Impedance calibration of single line*/
        public int SingleLineImpedanceEstimation(string LineID, int FromBusNumber, Complex KV1, Complex KI1, TextBox textBoxMessages) //ALso need Complex KV1, Complex[,] Z
        {
            int CurrentToBus = 0;

            CurrentToBus = GetLineVI(LineID, FromBusNumber);

            //if (LineID == "2")
            //{ int a = 1; }

            Complex KV2 = new Complex();
            Complex KI2 = new Complex();
            Complex Z   = new Complex();
            Complex y   = new Complex();

            //Find the sample sets 30 samples per second, 60 seconds in all => 30 sets of samples, 60 samples per set, rule out -9999
            int i             = 0; //set number
            int feasible_flag = 0; //estimation feasible indicator, shows missing data quantity, if too large then the estimation is not feasible

            Complex[] Zhat11 = new Complex[30];
            Complex[] Zhat12 = new Complex[30];
            Complex[] Zhat21 = new Complex[30];
            Complex[] Zhat22 = new Complex[30];

            int SecondsNumber = (int)Math.Floor((double)(m_V1.Count() / 30));

            while (i < 30)
            {
                //get samples
                Complex[,] V_sample_temp = new Complex[SecondsNumber, 2];
                Complex[,] I_sample_temp = new Complex[SecondsNumber, 2];

                int current_row = 0;

                for (int j = 0; j < SecondsNumber; j++)
                {
                    current_row = j * 30 + i;
                    if ((m_V1[current_row] != -9999) && (m_I1[current_row] != -9999) && (m_V2[current_row] != -9999) && (m_I2[current_row] != -9999))
                    {
                        V_sample_temp[j, 0] = m_V1[current_row];
                        I_sample_temp[j, 0] = m_I1[current_row];
                        V_sample_temp[j, 1] = m_V2[current_row];
                        I_sample_temp[j, 1] = m_I2[current_row];
                    }
                    else
                    {
                        V_sample_temp[j, 0] = -9999;
                        I_sample_temp[j, 0] = -9999;
                        V_sample_temp[j, 1] = -9999;
                        I_sample_temp[j, 1] = -9999;
                    }
                }

                //transfer into matrix mode
                Complex     initial = 0;
                DenseMatrix Vhat    = DenseMatrix.Create(2, 1, initial);
                DenseMatrix Ihat    = DenseMatrix.Create(2, 1, initial);

                for (int k = 0; k < SecondsNumber; k++)
                {
                    if ((V_sample_temp[k, 0] != -9999) && (V_sample_temp[k, 0] != null))
                    {
                        Complex[,] V_temp_array = new Complex[2, 1];
                        V_temp_array[0, 0]      = V_sample_temp[k, 0];
                        V_temp_array[1, 0]      = V_sample_temp[k, 1];
                        DenseMatrix V_temp = DenseMatrix.OfArray(V_temp_array);

                        if ((Vhat != null) && (V_temp != null))
                        {
                            if (Vhat[0, 0] == 0)
                            {
                                Vhat = V_temp;
                            }
                            else
                            {
                                Vhat = MatrixCalculationExtensions.HorizontallyConcatenate(Vhat, V_temp);
                            }
                        }


                        Complex[,] I_temp_array = new Complex[2, 1];
                        I_temp_array[0, 0]      = I_sample_temp[k, 0];
                        I_temp_array[1, 0]      = I_sample_temp[k, 1];
                        DenseMatrix I_temp = DenseMatrix.OfArray(I_temp_array);

                        if ((Ihat != null) && (I_temp != null))
                        {
                            if (Ihat[0, 0] == 0)
                            {
                                Ihat = I_temp;
                            }
                            else
                            {
                                Ihat = MatrixCalculationExtensions.HorizontallyConcatenate(Ihat, I_temp);
                            }
                        }
                    }
                }

                //check sample quantity, enough to do estimation or not
                if (Vhat.ColumnCount < 20)
                {
                    feasible_flag += 1;
                    i             += 1;
                    continue;
                }
                else
                {
                    MathNetNumLin.Matrix <Complex> Vhat_T = Vhat.Transpose();
                    MathNetNumLin.Matrix <Complex> Ihat_T = Ihat.Transpose();

                    //estimate Zhat
                    MathNetNumLin.Matrix <Complex> Zhat_temp = null;

                    Zhat_temp = LeastSquareEstimation(Vhat_T, Ihat_T);// Ihat_T.Transpose().Multiply(Ihat_T).Inverse().Multiply(Ihat_T.Transpose()).Multiply(Vhat_T);
                    Zhat11[i] = Zhat_temp[0, 0];
                    Zhat12[i] = Zhat_temp[0, 1];
                    Zhat21[i] = Zhat_temp[1, 0];
                    Zhat22[i] = Zhat_temp[1, 1];

                    //Zhat12[i] = Zhat_temp[1, 0];
                    //Zhat21[i] = Zhat_temp[0, 1];
                }

                i += 1;
            }

            // Take average of Zhat to eliminate PMU error, if there is enough estimation results
            Complex from_bus_number     = FromBusNumber;
            Complex to_bus_number       = CurrentToBus;
            int     from_bus_number_int = FromBusNumber;
            int     to_bus_number_int   = CurrentToBus;

            double BaseZ = m_currentSystem.Network.BaseKV * m_currentSystem.Network.BaseKV / m_currentSystem.Network.BaseMVA;

            if (feasible_flag < 15)
            {
                Complex   W            = new Complex();
                Complex[] KV2_hat      = new Complex[30];
                Complex[] KI2_hat      = new Complex[30];
                Complex[] Z_hat_pu     = new Complex[30];
                Complex[] y_hat_pu     = new Complex[30];
                Complex   KV2_hat_sum  = new Complex();
                Complex   KI2_hat_sum  = new Complex();
                Complex   Z_hat_pu_sum = new Complex();
                Complex   y_hat_pu_sum = new Complex();

                for (int l = 0; l < 30; l++)
                {
                    if ((Zhat11[l] != null) || (Zhat12[l] != null) || (Zhat21[l] != null) || (Zhat22[l] != null))
                    {
                        Complex Zhat11_temp = Zhat11[l];
                        Complex Zhat12_temp = Zhat12[l];
                        Complex Zhat21_temp = Zhat21[l];
                        Complex Zhat22_temp = Zhat22[l];

                        W = (Zhat11_temp * Zhat22_temp) / (Zhat12_temp * Zhat21_temp);
                        W = Complex.Sqrt(W);
                        if (W.Imaginary < 0)
                        {
                            W = -1 * W;
                        }

                        KV2_hat[l] = 1 / W * Zhat11_temp / Zhat12_temp * KV1;
                        KI2_hat[l] = W * Zhat21_temp / Zhat11_temp * KI1;

                        if (KV2_hat[l].Real < 0)
                        {
                            KV2_hat[l] = KV2_hat[l] * (-1);
                        }
                        if (KI2_hat[l].Real < 0)
                        {
                            KI2_hat[l] = KI2_hat[l] * (-1);
                        }
                        y_hat_pu[l] = BaseZ * Complex.Sqrt((KI2_hat[l] * (W - 1)) / (KV2_hat[l] * (W + 1) * (Zhat11_temp * Zhat22_temp - Zhat12_temp * Zhat21_temp)) * KI1 / KV1);
                        //y_hat_pu[l] = Complex.Sqrt((KI2_hat[l] * (W - 1)) / (KV2_hat[l] * (W + 1) * (Zhat11_temp * Zhat22_temp - Zhat12_temp * Zhat21_temp)) * KI1 / KV1);

                        if (y_hat_pu[l].Imaginary < 0)
                        {
                            y_hat_pu[l] = Complex.Conjugate(y_hat_pu[l]);
                        }

                        Z_hat_pu[l] = (W - 1) / y_hat_pu[l];

                        if (Z_hat_pu[l].Real < 0)
                        {
                            Z_hat_pu[l] = Complex.Conjugate(-1 * Z_hat_pu[l]);
                        }

                        if (Z_hat_pu[l].Imaginary < 0)
                        {
                            Z_hat_pu[l] = Complex.Conjugate(Z_hat_pu[l]);
                        }
                    }

                    KV2_hat_sum  = KV2_hat_sum + KV2_hat[l];
                    KI2_hat_sum  = KI2_hat_sum + KI2_hat[l];
                    Z_hat_pu_sum = Z_hat_pu_sum + Z_hat_pu[l];
                    y_hat_pu_sum = y_hat_pu_sum + y_hat_pu[l];
                }

                KV2 = KV2_hat_sum / (30 - feasible_flag);
                KI2 = KI2_hat_sum / (30 - feasible_flag);
                Z   = Z_hat_pu_sum / (30 - feasible_flag); // * BaseZ;
                y   = y_hat_pu_sum / (30 - feasible_flag); // / BaseZ;

                //adding the computation results to K matrix and record KVs for both from_bus and to_bus for future calibrations
                int m = 0;
                while (m_K[m, 0] != 0)
                {
                    m += 1;
                }

                int Line_ID_int = Convert.ToInt32(LineID);
                m_K[m, 0] = Line_ID_int;
                m_K[m, 1] = from_bus_number;
                m_K[m, 2] = KV1;
                m_K[m, 3] = KI1;
                m_K[m, 4] = to_bus_number;
                m_K[m, 5] = KV2;
                m_K[m, 6] = KI2;
                m_K[m, 7] = Z;
                m_K[m, 8] = y.Imaginary;

                //update the propagation references
                int[]      injections_set      = FindInjections(to_bus_number_int);
                List <int> inaccurate_line_set = new List <int>(); //List to save all inaccurate lines
                for (int idx1 = 0; idx1 < injections_set.Count(); idx1++)
                {
                    if (injections_set[idx1] != Line_ID_int)
                    {
                        inaccurate_line_set.Add(injections_set[idx1]);
                    }
                }
                //Accurate Voltage Propagation
                MathNetNumLin.Matrix <Complex> KV_injections_set = KVPropagation(inaccurate_line_set, Line_ID_int, to_bus_number_int, KV2);
                //Accurate Current Propagation
                MathNetNumLin.Matrix <Complex> KI_injections_set = KIPropagation(inaccurate_line_set, Line_ID_int, to_bus_number_int, KI2);

                int pointer = 0;
                for (int idx1 = 0; idx1 < m_currentSystem.Network.LineNum; idx1++)
                {
                    if (m_KVKILines[idx1].Line_ID == 0)
                    {
                        pointer = idx1;
                        break;
                    }
                }
                for (int idx2 = 0; idx2 < KV_injections_set.RowCount; idx2++)
                {
                    if ((pointer + idx2) < m_currentSystem.Network.LineNum)
                    {
                        m_KVKILines[pointer + idx2].Line_ID      = inaccurate_line_set[idx2];
                        m_KVKILines[pointer + idx2].From_bus_num = to_bus_number_int;
                        m_KVKILines[pointer + idx2].KV1          = KV_injections_set[idx2, 0];
                        m_KVKILines[pointer + idx2].KI1          = KI_injections_set[idx2, 0];
                    }
                }

                //Set visited line to be 1
                for (int n = 0; n < m_currentSystem.Network.LineNum; n++)
                {
                    if (Line_ID_int == m_lineVisited[n, 0])
                    {
                        m_lineVisited[n, 1] = 1;
                        break;
                    }
                }

                string msg0 = "### Line " + LineID.ToString() + " from bus " +
                              m_currentSystem.Network.BusOriginalLibrary[from_bus_number_int - 1].ToString() + " to bus " +
                              m_currentSystem.Network.BusOriginalLibrary[to_bus_number_int - 1].ToString() + " has been estimated.\n";
                textBoxMessages.AppendLine(msg0);
            }
            else
            {
                string msg1 = "!!! Line " + LineID.ToString() + " from bus " +
                              m_currentSystem.Network.BusOriginalLibrary[from_bus_number_int - 1].ToString() + " to bus " +
                              m_currentSystem.Network.BusOriginalLibrary[to_bus_number_int - 1].ToString() + " can NOT be calibrated due to limited data.\n";
                textBoxMessages.AppendLine(msg1);
            }

            return(0);
        }