/* 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); }
/* 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); }