diff --git a/Mes_Wind_console/Program.cs b/Mes_Wind_console/Program.cs index a44a872b096f718f9d725692d433f697f91f93df..db1f09157ef28f95ea5d2d2323794624b11becd2 100644 --- a/Mes_Wind_console/Program.cs +++ b/Mes_Wind_console/Program.cs @@ -1,109 +1,121 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; + +using WindStressPRM; namespace Mes_Wind_console { class Program { static void Main(string[] args) + { + Test(); + } + + static void Test() { const int rowCountPrognostic = 3; const int colCountPrognostic = 3; - WindStressPRM.Matrix<WindStressPRM.PrognosticCell> prognosticMatrix = new WindStressPRM.Matrix<WindStressPRM.PrognosticCell>(); - prognosticMatrix.Cells = new WindStressPRM.PrognosticCell[rowCountPrognostic, colCountPrognostic]; - prognosticMatrix.Size = new WindStressPRM.CellSize(500, 500); - prognosticMatrix.Origin = new WindStressPRM.Coordinate(3555223.71, 5828444.07); + var prognosticMatrix = new Matrix<PrognosticCell> // TODO: Matrix Лишняя проверка Cells.Rank в RowsCount() / ColumnCount()? + { + Cells = new PrognosticCell[rowCountPrognostic, colCountPrognostic], + Size = new CellSize(500, 500), + Origin = new Coordinate(3555223.71, 5828444.07), // TODO: Coordinate в комментариях к полям - широта и долгота ?? done + }; // fill cells of prognostic matrix for (int i = 0; i < rowCountPrognostic; i++) { for (int j = 0; j < colCountPrognostic; j++) { // Also you can use Double.NaN; - double uValue = 100*( i + j * 10); + double uValue = 100 * (i + j * 10); double vValue = -(i + j * 10); - prognosticMatrix.Cells[i, j] = new WindStressPRM.PrognosticCell(uValue, vValue); + prognosticMatrix.Cells[i, j] = new PrognosticCell(uValue, vValue); // TODO: PrognosticCell комментарии к параметрам - размерность, про NaN } } + //Now we create climate raster class const int rowCountClim = 3; const int columnCountClim = 3; - WindStressPRM.Matrix<WindStressPRM.ClimateCell> climateMatrix = new WindStressPRM.Matrix<WindStressPRM.ClimateCell>(); - climateMatrix.Cells = new WindStressPRM.ClimateCell[rowCountClim, columnCountClim]; - climateMatrix.Size = new WindStressPRM.CellSize(500, 500); - climateMatrix.Origin = new WindStressPRM.Coordinate(3555223.71, 5828444.07); + var climateMatrix = new Matrix<ClimateCell> + { + Cells = new ClimateCell[rowCountClim, columnCountClim], + Size = new CellSize(500, 500),// TODO: CellSize названия width/height. DONE + Origin = new Coordinate(3555223.71, 5828444.07), + }; // fill cells of climate matrix for (int i = 0; i < rowCountClim; i++) { for (int j = 0; j < columnCountClim; j++) { //add or substruct in range 0 - 27 to change what lines will be broken - double clim5 = 5; - double clim10 = 10; - double clim15 = 15; - double clim25 = 20; - climateMatrix.Cells[i, j] = new WindStressPRM.ClimateCell(clim5, clim10, clim15, clim25); + climateMatrix.Cells[i, j] = new ClimateCell(5, 10, 15, 20); // TODO: ClimateCell комментарии к параметрам - размерность, про NaN. DONE } } + // create powerlines layer - List<WindStressPRM.Powerline> powerlines = new List<WindStressPRM.Powerline>(); - WindStressPRM.Coordinate first = climateMatrix.Origin; - const int numbStations = 5; + var powerlines = new List<Powerline>(); + Coordinate first = climateMatrix.Origin; + const int numStations = 5; const double step = 100; - for (int i = 0; i < numbStations - 1; i++) + for (int i = 0; i < numStations - 1; i++) { - WindStressPRM.Powerline dummyline = new WindStressPRM.Powerline(); - dummyline.Identifier = 100 + i; - dummyline.Year = 2000; - dummyline.Height = 10; - dummyline.Voltage = 330; - dummyline.PointFromID = i; - dummyline.PointToID = i + 1; - dummyline.Coordinates = new List<WindStressPRM.Coordinate>(); + // TODO: Powerline и др. детализация сообщения об ошибке (какой параметр вышел за пределы и его значение). DONE + var dummyline = new Powerline(new List<Coordinate>(), 100 + i, 2000, 10, 330, i + 1, i); dummyline.Coordinates.Add(first); - WindStressPRM.Coordinate second = new WindStressPRM.Coordinate(first.X + step, first.Y - step); + var second = new Coordinate(first.X + step, first.Y - step); dummyline.Coordinates.Add(second); first = second; powerlines.Add(dummyline); } + //create Powerstation list - List<WindStressPRM.PowerStation> powerpoints = new List<WindStressPRM.PowerStation>(); - for (int i = 0; i < numbStations; i++) + var powerpoints = new List<PowerStation>(); + for (int i = 0; i < numStations; i++) { - WindStressPRM.PowerStation dummystation = new WindStressPRM.PowerStation(); - dummystation.Identifier = i; - dummystation.Name = "dummy name"; - dummystation.Power = 330; - dummystation.IsSource = i == 0; - - //casting stationtype - dummystation.Stationtype = WindStressPRM.PowerStation.StationType.Pole; - if (i == numbStations - 1) - { - dummystation.Stationtype = WindStressPRM.PowerStation.StationType.Endstat; - } - dummystation.Coordinate = new WindStressPRM.Coordinate(climateMatrix.Origin.X + step * i, climateMatrix.Origin.X - step * i); - powerpoints.Add(dummystation); + // TODO: PowerStation и др. соответствие названий полей и параметров конструкторов. DONE + // TODO: PowerStation проверка параметров на допустимый диапазон. DONE + powerpoints.Add(new PowerStation( + new Coordinate(climateMatrix.Origin.X + step * i, climateMatrix.Origin.X - step * i), + i, + String.Format("Station #{0}", i), + 330, // TODO: PowerStation - название поля Voltage вместо Power?. DONE + ((i == numStations - 1) ? PowerStation.StationType.Endstat : PowerStation.StationType.Pole), // TODO: StationType комментарии к значениям enum. Done + (i == 0))); } + //Create a PRM_wind class and add all the properties from above - WindStressPRM.StressPowerChecker prmwind = new WindStressPRM.StressPowerChecker(); - WindStressPRM.Input input = new WindStressPRM.Input(); - input.PowerLines = powerlines; - input.PowerStations = powerpoints; - input.PrognosticCells = prognosticMatrix; - input.ClimateCells = climateMatrix; - WindStressPRM.Output output = prmwind.CheckPower(input); - foreach (WindStressPRM.Powerline line in output.DisabledLines) { - Console.WriteLine("disabled line identifier is " + line.Identifier.ToString()); + var prmwind = new StressPowerChecker(); + var input = new Input + { + PowerLines = powerlines, + PowerStations = powerpoints, + // TODO: PrognosticCells/ClimateCells - требуется ли совпадение размеров и координат узлов двух данных матриц? Если требуется, то нужна проверка в CheckPower() + // DONE, не требуется. + PrognosticCells = prognosticMatrix, + ClimateCells = climateMatrix, + }; + + var output = prmwind.CheckPower(input); + + foreach (var line in output.DisabledLines) + { + Console.WriteLine("disabled line identifier is {0}", line.Identifier); } - foreach (WindStressPRM.PowerStation station in output.DisabledStations) { - Console.WriteLine("disabled station identifier is " + station.Identifier.ToString()); + + foreach (var station in output.DisabledStations) + { + Console.WriteLine("disabled station identifier is {0}", station.Identifier); } - foreach (WindStressPRM.Coordinate coordinate in output.SpectificCoordinates) { - Console.WriteLine("in coordinate " + coordinate.X.ToString() + "; " + coordinate.Y.ToString() + " 35kV and less could be broken"); + + foreach (var coordinate in output.SpectificCoordinates) // TODO: Название Output.Spectific -> Specific ? + { + Console.WriteLine("in coordinate ({0}; {1}) 35kV and less could be broken", coordinate.X, coordinate.Y); } + Console.WriteLine("end"); + Console.ReadKey(); } + } } diff --git a/WindStressPRM/Objects/ClimateCell.cs b/WindStressPRM/Objects/ClimateCell.cs index 24d0f9980e12eb581aa433d8182607169afde516..8f67c2eeeafc8698709ec725baf7b1fd1bc23cde 100644 --- a/WindStressPRM/Objects/ClimateCell.cs +++ b/WindStressPRM/Objects/ClimateCell.cs @@ -7,7 +7,7 @@ namespace WindStressPRM { /// <summary> /// Cell obj for climate wind regular data - /// Объект - ячейка полей ветра определенной повторяемости на 10м на регулярной сетке + /// Объект - ячейка поля модуля ветра определенной повторяемости на 10м на регулярной сетке /// </summary> public class ClimateCell { @@ -33,12 +33,13 @@ namespace WindStressPRM /// </summary> public double Wind25 { get; private set; } /// <summary> - /// designated constructor + /// designated constructor, NaN интерпретируется как отсутствие значения параметра в ячейке. /// </summary> /// <param name="coord"></param> - /// <param name="w5"></param> - /// <param name="w10"></param> - /// <param name="w15"></param> + /// <param name="w5"> скорость ветра повторяемости один раз в 5 лет, м/с</param> + /// <param name="w10"> скорость ветра повторяемости один раз в 10 лет, м/с</param> + /// <param name="w15"> скорость ветра повторяемости один раз в 15 лет, м/с</param> + /// <param name="w25"> скорость ветра повторяемости один раз в 25 лет, м/с (для ЛЭП постройки после 1986г)</param> public ClimateCell(double w5, double w10, double w15, double w25) { this.Wind5 = w5; @@ -77,7 +78,11 @@ namespace WindStressPRM w25 = 0; } // ветер по модулю не должен превышать 70м/с - return Math.Abs(w5) < 70 && Math.Abs(w10) < 70 && Math.Abs(w15) < 70 && Math.Abs(w25) < 70; + if (w5 >= 0 && w5 > 70) { throw new System.ArgumentOutOfRangeException("w5", w5, "Expected 0=<w5<70"); } + if (w10 >= 0 && w10 > 70) { throw new System.ArgumentOutOfRangeException("w10", w10, "Expected 0=<w10<70"); } + if (w15 >= 0 && w15 > 70) { throw new System.ArgumentOutOfRangeException("w15", w15, "Expected 0=<w15<70"); } + if (w25 >= 0 && w25 > 70) { throw new System.ArgumentOutOfRangeException("w25", w25, "Expected 0=<w25<70"); } + return w5 >=0 && w5 < 70 && w10 >=0 && w10 < 70 && w15 >= 0 && w15 < 70 && w25 >= 0 && w25 < 70; } } } diff --git a/WindStressPRM/Objects/PowerStation.cs b/WindStressPRM/Objects/PowerStation.cs index 9783b396a8aa76ee19749de4c86badf7b7cbf7ad..c2f07eda85ec3a80547a54032b9d0604bd90b5fb 100644 --- a/WindStressPRM/Objects/PowerStation.cs +++ b/WindStressPRM/Objects/PowerStation.cs @@ -26,22 +26,25 @@ namespace WindStressPRM /// </summary> public string Name { get; set; } /// <summary> - /// power, kV + /// voltage, kV /// напряжение, кВ /// </summary> - public int Power { get; set; } + public int Voltage { get; set; } /// <summary> /// type of point - trans/pole/endpoint /// тип станции - трансформаторная подстанция/столб/понижающая(конечная)подстанция ///столбы не идут в аутпут, и обрабатываються алгоритмом, так что если есть на куске графа, саязанного только столбами есть сломанный сегмент - /// весб кусок графа обесточен + /// весь кусок графа обесточен /// </summary> public enum StationType { Pole, Trans, Endstat }; /// <summary> - /// тип подстанции + /// тип подстанции: pole/trans/endstat: является ли станция столбом, распределительной подстанцией, или станцией в вершине графа питания + /// тип столб - в картографической дишифровке ЛЭП могут ветвиться на столбах, при этом, очевидно, столбы не распределяют питание в отличии от подстанций. + /// распределительная подстанция - станция на которой граф ветвиться и известно что это не столб. + /// станция в вершине графа /// </summary> public StationType Stationtype { get; set; } /// <summary> @@ -71,26 +74,28 @@ namespace WindStressPRM /// <summary> /// designated constructor /// </summary> - /// <param name="crds"></param> - /// <param name="id"></param> - /// <param name="stname"></param> - /// <param name="stpower"></param> - /// <param name="sttype"></param> - /// <param name="issource"></param> - /// <param name="ison"></param> - public PowerStation(Coordinate crds, int id, string stname, int stpower, StationType sttype, bool issource) + /// <param name="coords"> Coordinates/координаты станции </param> + /// <param name="id">Station ID/ ИД станции </param> + /// <param name="name">Station Name/Название станции</param> + /// <param name="voltage"> voltage, класс напряжения кВ</param> + /// <param name="stationtype">Тип станции: столб/Подстанция/Конечная станция</param> + /// <param name="issource"> является ли станция генерирующей</param> + public PowerStation(Coordinate coords, int id, string name, int voltage, StationType stationtype, bool issource) { - this.Coordinate = crds; + this.Coordinate = coords; this.Identifier = id; - this.Name = stname; - this.Power = stpower; - this.Stationtype = sttype; + this.Name = name; + this.Voltage = voltage; + this.Stationtype = stationtype; this.IsSource = issource; this.IsON = false; } public bool CheckValue() { - bool checker = Identifier >= 0 && Power > 0 && Power < 1000; + bool checker = Identifier >= 0; + if (!checker) { throw new System.ArgumentOutOfRangeException("Identifier", Identifier, "Identifer expected to be more than 0"); } + checker = checker && Voltage > 0 && Voltage < 1500; + if (!checker) { throw new System.ArgumentOutOfRangeException("Voltage", Voltage, "Voltage expected to be in range (0,1500)"); } return checker; } /// <summary> @@ -107,6 +112,7 @@ namespace WindStressPRM this.LineList.Add(line); } } + if (this.LineList.Count == 0) { throw new System.Exception("Station has no corresponding/attached lines"); } return; } /// <summary> @@ -139,6 +145,7 @@ namespace WindStressPRM } /// <summary> /// Sets CurrentVolt parameter based on the highest voltage of lines powering it + /// Задает текущее значение питающего напряжения станции /// </summary> public void SetCurrentVolt() { @@ -148,6 +155,9 @@ namespace WindStressPRM } return; } + /// <summary> + /// Выключить питание на соединенных со станцией линиях + /// </summary> public void TurnOffAttachedLines() { foreach(Powerline line in this.LineList) { line.IsON = false; } diff --git a/WindStressPRM/Objects/Powerline.cs b/WindStressPRM/Objects/Powerline.cs index e69f2c25cac47ccf3c8b2cc99d400a574e26b6bf..9fd1ee9999fc5e8f5ec654ab69e4893a99b1b9ba 100644 --- a/WindStressPRM/Objects/Powerline.cs +++ b/WindStressPRM/Objects/Powerline.cs @@ -27,7 +27,7 @@ namespace WindStressPRM /// </summary> public double Height { get; set; } /// <summary> - /// power kV for switches + /// voltage class kV for switches /// Напряжение ЛЭП, кВ /// </summary> public int Voltage { get; set; } @@ -64,15 +64,13 @@ namespace WindStressPRM /// <summary> /// designated constructor /// </summary> - /// <param name="coord"></param> - /// <param name="id"></param> - /// <param name="yer"></param> - /// <param name="h"></param> - /// <param name="pw"></param> - /// <param name="isbrkn"></param> - /// <param name="ison"></param> - /// <param name="toID"></param> - /// <param name="fromID"></param> + /// <param name="coord"> Line vertices coordinate list/список координат вершин ЛЭП как линейного объекта</param> + /// <param name="id"> uniq id/уникальный идентификатор </param> + /// <param name="year">year of construction/год постройки ЛЭП </param> + /// <param name="height"> average height of cable span between two poles, meters/средняя высота пролета, м</param> + /// <param name="voltage"> voltage class kV for switches, Напряжение ЛЭП, кВ</param> + /// <param name="toID"> assigned powerstation/pole/идентификатор соответсвующего конца/начала линии (столб, трансформаторная подстанция, понижающая подстанция)</param> + /// <param name="fromID"> assigned powerstation/pole/идентификатор соответсвующего конца/начала линии (столб, трансформаторная подстанция, понижающая подстанция)</param> public Powerline(IList<Coordinate> coordinates, int id, int year, double height, int voltage, int toID, int fromID) { this.Coordinates = coordinates; @@ -96,9 +94,18 @@ namespace WindStressPRM public bool CheckValue() { bool checker = - Identifier >= 0 && Math.Abs(Year - 1985) < 45 && - Math.Abs(Height - 15) < 15 && Voltage > 0 && Voltage < 1000 && - PointFromID >= 0 && PointToID >= 0; + Identifier >= 0; + if (!checker) { throw new System.ArgumentOutOfRangeException("Identifier", Identifier, "Expected >0"); } + checker = checker && Year > 1900 && Year < 2050; + if (!checker) { throw new System.ArgumentOutOfRangeException("Year", Year, "Expected 1900<Year<2050"); } + checker = checker && Height > 0 && Height < 50; + if (!checker) { throw new System.ArgumentOutOfRangeException("Height", Height, "Expected 0<Height<50"); } + checker = checker && Voltage > 0 && Voltage < 1500; + if (!checker) { throw new System.ArgumentOutOfRangeException("Voltage", Voltage, "Expected 0<Voltage<1500"); } + checker = checker && PointFromID >= 0; + if (!checker) { throw new System.ArgumentOutOfRangeException("PointFromID", PointFromID, "Expected >0"); } + checker = checker && PointToID >= 0; + if (!checker) { throw new System.ArgumentOutOfRangeException("PointToID", PointToID, "Expected >0"); } return checker; } } diff --git a/WindStressPRM/Objects/PrognosticCell.cs b/WindStressPRM/Objects/PrognosticCell.cs index 320d7942e99467a21380914c69508faaecc62eef..e2e5b0acce4d8eff997de5c90ed31c66c5a70a12 100644 --- a/WindStressPRM/Objects/PrognosticCell.cs +++ b/WindStressPRM/Objects/PrognosticCell.cs @@ -24,9 +24,9 @@ namespace WindStressPRM /// <summary> /// designated constructor /// </summary> - /// <param name="coord"> Coordinate pair</param> - /// <param name="vX"> U component</param> - /// <param name="vY"> V component</param> + /// <param name="coord"> Coordinate pair, координаты ячейки </param> + /// <param name="vX"> U component m/s, скорость ветра по X м/с, NaN если значение отсутствует </param> + /// <param name="vY"> V component m/s, скорость ветра по Y м/с, NaN если значение отсутствует</param> public PrognosticCell(double vX, double vY) { this.VelocityX = vX; diff --git a/WindStressPRM/Utils/CellSize.cs b/WindStressPRM/Utils/CellSize.cs index 0a76f253eb009c9424660d7492fb90c712b274ac..4bb470b25a16315cf3c1adbc86d4d9b43cbc403d 100644 --- a/WindStressPRM/Utils/CellSize.cs +++ b/WindStressPRM/Utils/CellSize.cs @@ -12,22 +12,22 @@ namespace WindStressPRM public class CellSize { /// <summary> - /// ширина ячейки (расстояние между соседними по широте центрами ячеек) + /// ширина ячейки (расстояние между соседними по X центрами ячеек, в размерности координат) /// </summary> public double Width { get; set; } /// <summary> - /// высота ячейки (расстояние между соседними по долготе центрами ячеек) + /// высота ячейки (расстояние между соседними по Y центрами ячеек, в размерности координат) /// </summary> public double Height { get; set; } /// <summary> /// designated constructor /// </summary> - /// <param name="wdh">Cell Width</param> - /// <param name="hgh">Cell Height</param> - public CellSize(double wdh, double hgh) + /// <param name="wdh">Cell Width, ширина ячейки (расстояние между соседними по X центрами ячеек, в размерности координат)</param> + /// <param name="hgh">Cell Height, высота ячейки (расстояние между соседними по Y центрами ячеек, в размерности координат)</param> + public CellSize(double width, double height) { - this.Width = wdh; - this.Height = hgh; + this.Width = width; + this.Height = height; if (!(this.CheckValue())) { throw new System.ArgumentException("Cell width or height values are incorrect!"); diff --git a/WindStressPRM/Utils/Coordinate.cs b/WindStressPRM/Utils/Coordinate.cs index 07a764f9400cf185284a8d05a8a217f7909104a5..6e2f0c89129bf586b2261bb344308705c7dc375b 100644 --- a/WindStressPRM/Utils/Coordinate.cs +++ b/WindStressPRM/Utils/Coordinate.cs @@ -4,18 +4,19 @@ using System.Collections.Generic; namespace WindStressPRM { /// <summary> - /// Coordinate pair + /// Coordinate pair + /// пара координат, может быть рамерности: м, км, градус, однако для всех экземпляров должна быть одной и той же. /// </summary> public class Coordinate { /// <summary> /// easting coordinate - /// Координата по широте + /// Координата по долготе/ X, (м, км, градус) /// </summary> public double X { get; private set; } /// <summary> /// northing coordinate - /// Координата по долготе + /// Координата по широте/Y, (м, км, градус) /// </summary> public double Y { get; private set; } /// <summary>