public IEnumerable <LoadFlowResult> Get([FromRoute] int id) { //-------------Load Flow Algorithm--------------- //-----obliczenia wykonywane sa na jednostkach wzglednych List <int> buses = new List <int>(); int N_bus; //liczba szyn/wezlow int N_ser; //liczba elementow galeziowych double Sb = 100; //MVA moc bazowa double Ub = 60; //kV napiecie bazowe double Zb = Math.Pow(Ub, 2) / Sb; //Ohm impedancja bazowa double Yb = 1 / Zb; //admitancja bazowa double Ib = Sb / (Math.Sqrt(3) * Ub) * 1000; //A - prad bazowy //obliczenia wykonuj na danym projekcie ExternalGrid[] extgrids = _context.ExternalGrids.Where(m => m.ProjectId == id).ToArray(); OverheadLine[] ovheads = _context.OverheadLines.Where(m => m.ProjectId == id).ToArray(); TwoPhaseTransformer[] twophasetrafo = _context.TwoPhaseTransformers.Where(m => m.ProjectId == id).ToArray(); Bus[] busbars = _context.Buses.Where(m => m.ProjectId == id).ToArray(); /* * if (project == null) * { * return NotFound(); * } */ //Jesli nie istnieja tego typu elementy to oznacza sie numer szyny rowny 1 oraz wartosc zero w drugiej kolumnie. int[] shunts = new int[] { 1, 0 }; //elementy poprzeczne //int N_sh = 1; // liczba element�w poprzecznych //pomocnicze tablice List <int> Is = new List <int>(); //numery szyn poczatkowych List <int> Js = new List <int>(); // numery szyn koncowych List <string> Itype = new List <string>(); List <double> Pb = new List <double>(); List <double> Qb = new List <double>(); //Complex c1 = new Complex(1.2, 2.0); //ilosc elementow podluznych N_ser = ovheads.Count() + twophasetrafo.Count(); //okresl ilosc szyn foreach (var row in extgrids) { if (!buses.Contains(row.NodeNo)) { buses.Add(row.NodeNo); } Itype.Add(row.NodeType); //obliczenia na podstawie jednostek wzglednych Pb.Add((row.ActivePower.HasValue) ? row.ActivePower.Value / Sb : 0); Qb.Add((row.ReactivePower.HasValue) ? row.ReactivePower.Value / Sb : 0); } foreach (var row in ovheads) { if (!buses.Contains(row.StartNodeNo)) { buses.Add(row.StartNodeNo); } if (!buses.Contains(row.EndNodeNo)) { buses.Add(row.EndNodeNo); } Is.Add(row.StartNodeNo); Js.Add(row.EndNodeNo); } N_bus = buses.Count; System.Diagnostics.Debug.WriteLine("BUS.COUNT: " + buses.Count); System.Diagnostics.Debug.WriteLine("ExternalGrid.COUNT: " + _context.ExternalGrids.Count()); //uformuj macierz z elementami podluznymi - Series_pu Complex[,] Series_pu = new Complex[N_ser, 5]; int irow = 0; foreach (var row in ovheads) { Complex RX = new Complex(row.UnitaryResistance * row.Length, row.UnitaryReactance * row.Length); Complex B = new Complex(0, row.UnitaryCapacitance * row.Length); Series_pu[irow, 0] = row.StartNodeNo; Series_pu[irow, 1] = row.EndNodeNo; Series_pu[irow, 2] = RX / Zb; Series_pu[irow, 3] = B / (Yb * Math.Pow(10, 6)); //przeliczenie z uS Series_pu[irow, 4] = 1; //TUTAJ BEDA PRZEKLADNIE TRANSFORMATOROW irow++; } foreach (var row in twophasetrafo) { Complex RX = new Complex((row.LoadLossesRated * row.HVVoltageRated * row.HVVoltageRated) / (1000 * row.ApparentPowerRated * row.ApparentPowerRated), row.ShortCircuitVoltage / 100); //zastanow sie jak wyliczac parametry transformatora Complex B = new Complex(0, 0); Series_pu[irow, 0] = row.HVNodeNo; Series_pu[irow, 1] = row.LVNodeNo; Series_pu[irow, 2] = RX / Zb; Series_pu[irow, 3] = B / Yb; irow++; } double?[] sigma = new double?[N_bus]; //uformuj macierz - buses foreach (var row in extgrids) { sigma[row.NodeNo] = row.VoltageAngle; //row.ID-1 } double[] U = new double[N_bus]; double[] Upu = new double[N_bus]; //uformuj macierz - U foreach (var row in busbars) { Upu[row.NodeNo] = row.NominalVoltage / Ub; //row.ID-1 } /* * //wartosci napiec z bezwglednych na wzgledne * * for (int c = 0; c <= (U.Length-1); c++) * { * Upu[c] = U[c] / Ub; * } */ double[] normalSigma = new double[N_bus]; for (int n = 0; n <= (N_bus - 1); n++) { normalSigma[n] = (sigma[n].HasValue) ? sigma[n].Value : 0; //przekonwertowanie double? na double } //uformuj macierz admitancyjna Complex[,] Ybus = new Complex[N_bus, N_bus]; Ybus = formYmatrix(N_bus, N_ser, Is, Js, Series_pu, shunts); //oblicz macierz Jacobiego double[,] Jac = new double[N_bus + 1, N_bus + 1]; Jac = calcJacobiMatrix(N_bus, Ybus, Upu, normalSigma, Itype); //odwroc macierz Jacobiego double[,] JacInv = new double[Jac.GetLength(0), Jac.GetLength(1)]; JacInv = MatrixInverseFunc.Main(Jac); int maxIter = 25; //maksymalna liczba iteracji double lambda = 1; //acceleration coefficient. This coefficient takes values less than one and improves the convergence characteristics of the problem. The user may change the value of l to see its effect on the mismatch at the end of the iterations. for (int i = 0; i <= (maxIter - 1); i++) { for (int m = 1; m <= (N_bus - 1); m++) { Upu[m] = Upu[m] + deltaV(m, N_bus, Itype, JacInv, Ybus, normalSigma, Upu, Pb, Qb) * lambda; normalSigma[m] = normalSigma[m] + deltaSigma(m, N_bus, Itype, JacInv, Ybus, normalSigma, Upu, Pb, Qb) * lambda; //System.Diagnostics.Debug.WriteLine("m " + m + "normalSigma[m]" + normalSigma[m]); //System.Diagnostics.Debug.WriteLine("m " + m + "deltaSigma" + deltaSigma(m, N_bus, Itype, JacInv, Ybus, normalSigma, U, Pb, Qb)); } } //z wartosci wzglednych na bezwzgledne for (int m = 0; m <= (Upu.Length - 1); m++) { U[m] = Upu[m] * Ub; } //obliczanie strat mocy na poszczególnych gałeziach double[] Ploss = new double[N_bus]; Ploss = activePowerLoss(Upu, normalSigma, Series_pu, N_bus, Is, Js, Sb); double[] Qloss = new double[N_bus]; Qloss = reactivePowerLoss(Upu, normalSigma, Series_pu, N_bus, Is, Js, Sb); //prąd wpywajacy od wezla i i doplywajacy do wezla j Complex[] IloadI = new Complex[N_bus]; IloadI = Iload_i(Upu, normalSigma, Series_pu, N_bus, Is, Js, Ib); Complex[] IloadJ = new Complex[N_bus]; IloadJ = Iload_j(Upu, normalSigma, Series_pu, N_bus, Is, Js, Ib); int[] busStart_I = new int[N_bus]; busStart_I = busStartI(N_bus, Is); int[] busEnd_J = new int[N_bus]; busEnd_J = busEndJ(N_bus, Js); //radian to degree double[] normalSigmaDegrees = new double[N_bus]; for (int c = 0; c <= (normalSigma.Length - 1); c++) { normalSigmaDegrees[c] = normalSigma[c] * (180.0 / Math.PI); } var list = new LoadFlows(); list.Results = new List <LoadFlowResult>(); for (int z = 0; z <= (N_bus - 1); z++) { var a = new LoadFlowResult() { busNo = z, resultU = U[z], resultUpu = Upu[z], resultSigma = normalSigmaDegrees[z], resultPloss = Ploss[z], resultQloss = Qloss[z], resultIload_i = IloadI[z].Magnitude, resultIload_j = IloadJ[z].Magnitude, busNoStart = busStart_I[z], busNoEnd = busEnd_J[z] }; list.Results.Add(a); } return(list.Results); }
public IEnumerable <LoadFlowResult> Get() { //-------------Load Flow Algorithm--------------- List <int> buses = new List <int>(); int N_bus; //liczba szyn/w�z��w int N_ser; //liczba element�w ga��ziowych //Je�li nie istniej� tego typu elementy to oznacza si� numer szyny r�wny 1 oraz warto�� zero w drugiej kolumnie. int[] shunts = new int[] { 1, 0 }; //elementy poprzeczne //int N_sh = 1; // liczba element�w poprzecznych //pomocnicze tablice List <int> Is = new List <int>(); //numery szyn pocz�tkowych List <int> Js = new List <int>(); // numery szyn ko�cowych List <string> Itype = new List <string>(); List <double> Pb = new List <double>(); List <double> Qb = new List <double>(); //Complex c1 = new Complex(1.2, 2.0); //ilo�� element�w pod�u�nych N_ser = _context.OverheadLines.Count() + _context.TwoPhaseTransformers.Count(); //okre�l ilo�� szyn foreach (var row in _context.ExternalGrids) { if (!buses.Contains(row.NodeNo)) { buses.Add(row.NodeNo); } Itype.Add(row.NodeType); //normalSigma[n] = (sigma[n].HasValue) ? sigma[n].Value : 0; Pb.Add((row.ActivePower.HasValue) ? row.ActivePower.Value : 0); Qb.Add((row.ReactivePower.HasValue) ? row.ReactivePower.Value : 0); } foreach (var row in _context.OverheadLines) { if (!buses.Contains(row.StartNodeNo)) { buses.Add(row.StartNodeNo); } if (!buses.Contains(row.EndNodeNo)) { buses.Add(row.EndNodeNo); } Is.Add(row.StartNodeNo); Js.Add(row.EndNodeNo); } N_bus = buses.Count; System.Diagnostics.Debug.WriteLine("BUS.COUNT: " + buses.Count); System.Diagnostics.Debug.WriteLine("ExternalGrid.COUNT: " + _context.ExternalGrids.Count()); //uformuj macierz z elementami pod�u�nymi - series Complex[,] Series = new Complex[N_ser, 5]; foreach (var row in _context.OverheadLines) { Complex RX = new Complex(row.UnitaryResistance * row.Length, row.UnitaryReactance * row.Length); Complex B = new Complex(0, row.UnitaryCapacitance * row.Length); Series[(row.ID - 1), 0] = row.StartNodeNo; Series[(row.ID - 1), 1] = row.EndNodeNo; Series[(row.ID - 1), 2] = RX; Series[(row.ID - 1), 3] = B; Series[(row.ID - 1), 4] = 1; //TUTAJ BED� PRZEK�ADNIE TRANSFORMATOROW } double[] U = new double[N_bus]; double?[] sigma = new double?[N_bus]; //uformuj macierz - buses foreach (var row in _context.ExternalGrids) { // Buses[row.ID-1, 1] = row.NodeType; sigma[row.ID - 1] = row.VoltageAngle; } double[] normalSigma = new double[N_bus]; for (int n = 0; n <= (N_bus - 1); n++) { normalSigma[n] = (sigma[n].HasValue) ? sigma[n].Value : 0; //przekonwertowanie double? na double } //sztucznie dodane napi�cia U[0] = 60; U[1] = 60; U[2] = 60; //uformuj macierz admitancyjn� Complex[,] Ybus = new Complex[N_bus, N_bus]; Ybus = formYmatrix(N_bus, N_ser, Is, Js, Series, shunts); //oblicz macierz Jacobiego double[,] Jac = new double[N_bus + 1, N_bus + 1]; Jac = calcJacobiMatrix(N_bus, Ybus, U, normalSigma, Itype); //odwr�� macierz Jacobiego double[,] JacInv = new double[Jac.GetLength(0), Jac.GetLength(1)]; JacInv = MatrixInverseFunc.Main(Jac); int maxIter = 12; //maksymalna liczba iteracji double lambda = 1; //acceleration coefficient. This coefficient takes values less than one and improves the convergence characteristics of the problem. The user may change the value of l to see its effect on the mismatch at the end of the iterations. for (int i = 0; i <= (maxIter - 1); i++) { for (int m = 1; m <= (N_bus - 1); m++) { U[m] = U[m] + deltaV(m, N_bus, Itype, JacInv, Ybus, normalSigma, U, Pb, Qb) * lambda; normalSigma[m] = normalSigma[m] + deltaSigma(m, N_bus, Itype, JacInv, Ybus, normalSigma, U, Pb, Qb) * lambda; //System.Diagnostics.Debug.WriteLine("m " + m + "normalSigma[m]" + normalSigma[m]); //System.Diagnostics.Debug.WriteLine("m " + m + "deltaSigma" + deltaSigma(m, N_bus, Itype, JacInv, Ybus, normalSigma, U, Pb, Qb)); } } //radian to degree for (int c = 0; c <= (normalSigma.Length - 1); c++) { normalSigma[c] = normalSigma[c] * (180.0 / Math.PI); } // var viewModel = new LoadFlowViewModel(U, normalSigma); /* * var viewModel = new List<LoadFlowViewModel>(); * for(int z = 0; z <= (N_bus-1); z++) * { * var row = new LoadFlowViewModel(); * row.busNo = z; * row.resultU = U[z]; * row.resultSigma = normalSigma[z]; * viewModel.Add(row); * } * return viewModel; */ var list = new LoadFlows(); list.Results = new List <LoadFlowResult>(); for (int z = 0; z <= (N_bus - 1); z++) { var a = new LoadFlowResult() { busNo = z, resultU = U[z], resultSigma = normalSigma[z] }; list.Results.Add(a); } return(list.Results); }