示例#1
0
        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);
        }
示例#2
0
        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);
        }