diff --git a/MES_Wind/frmMain.cs b/MES_Wind/frmMain.cs index 1d3ff9d4748a60c8790daa796ca93bd557a6e185..3061656d036d9490b5373bb63676340d64a54f25 100644 --- a/MES_Wind/frmMain.cs +++ b/MES_Wind/frmMain.cs @@ -175,6 +175,8 @@ namespace MES_Wind double clim5 = clim5RasterLayer.DataSet.Value[i, j]; double clim10 = clim10RasterLayer.DataSet.Value[i, j] +1; double clim15 = clim15RasterLayer.DataSet.Value[i, j]; +// TODO: Add clim25 layer + double clim25 = 0; if (Math.Abs(clim5 - RasterMissingValue) < eps) { clim5 = Double.NaN; @@ -187,7 +189,11 @@ namespace MES_Wind { clim15 = Double.NaN; } - WindStressPRM.ClimateCell dummyClim = new WindStressPRM.ClimateCell(clim5, clim10, clim15); + if (Math.Abs(clim25 - RasterMissingValue) < eps) + { + clim25 = Double.NaN; + } + WindStressPRM.ClimateCell dummyClim = new WindStressPRM.ClimateCell(clim5, clim10, clim15, clim25); climateMatrix.Cells[j, i] = dummyClim; } } @@ -200,7 +206,7 @@ namespace MES_Wind dummyline.Identifier = feature.Fid; dummyline.Year = int.Parse(featureData["Year"].ToString()); dummyline.Height = double.Parse(featureData["HeightOffs"].ToString()); - dummyline.Power = int.Parse(featureData["Voltage"].ToString()); + dummyline.Voltage = int.Parse(featureData["Voltage"].ToString()); dummyline.PointFromID = int.Parse(featureData["PointFrom"].ToString()); dummyline.PointToID = int.Parse(featureData["PointTo"].ToString()); LineString featureline = feature.BasicGeometry as LineString; diff --git a/WindStressPRM/Objects/ClimateCell.cs b/WindStressPRM/Objects/ClimateCell.cs index ecd01d76c463acf7f6366c4d19446446a3530074..24d0f9980e12eb581aa433d8182607169afde516 100644 --- a/WindStressPRM/Objects/ClimateCell.cs +++ b/WindStressPRM/Objects/ClimateCell.cs @@ -27,17 +27,24 @@ namespace WindStressPRM /// </summary> public double Wind15 { get; private set; } /// <summary> + /// once-in-25-years frequency wind, m/s + /// скорость ветра повторяемости один раз в 25 лет, м/с + /// для ЛЭП, построенных после 1987 года. + /// </summary> + public double Wind25 { get; private set; } + /// <summary> /// designated constructor /// </summary> /// <param name="coord"></param> /// <param name="w5"></param> /// <param name="w10"></param> /// <param name="w15"></param> - public ClimateCell(double w5, double w10, double w15) + public ClimateCell(double w5, double w10, double w15, double w25) { this.Wind5 = w5; this.Wind10 = w10; this.Wind15 = w15; + this.Wind25 = w25; if (!(this.CheckValue())) { throw new System.ArgumentException("Climate wind value is not correct"); @@ -52,6 +59,7 @@ namespace WindStressPRM double w5 = Wind5; double w10 = Wind10; double w15 = Wind15; + double w25 = Wind25; if (Double.IsNaN(w5)) // if is Nan - zerofied it. { w5 = 0; @@ -64,8 +72,12 @@ namespace WindStressPRM { w15 = 0; } + if (Double.IsNaN(w25)) + { + w25 = 0; + } // ветер по модулю не должен превышать 70м/с - return Math.Abs(w5) < 70 && Math.Abs(w10) < 70 && Math.Abs(w15) < 70; + return Math.Abs(w5) < 70 && Math.Abs(w10) < 70 && Math.Abs(w15) < 70 && Math.Abs(w25) < 70; } } } diff --git a/WindStressPRM/Objects/Powerline.cs b/WindStressPRM/Objects/Powerline.cs index 171a3ce2f0b17190427d4230618ce1e2f2cc1c4e..e69f2c25cac47ccf3c8b2cc99d400a574e26b6bf 100644 --- a/WindStressPRM/Objects/Powerline.cs +++ b/WindStressPRM/Objects/Powerline.cs @@ -30,7 +30,7 @@ namespace WindStressPRM /// power kV for switches /// Напряжение ЛЭП, кВ /// </summary> - public int Power { get; set; } + public int Voltage { get; set; } /// <summary> /// Line vertices coordinate list /// список координат вершин ЛЭП как линейного объекта @@ -73,13 +73,13 @@ namespace WindStressPRM /// <param name="ison"></param> /// <param name="toID"></param> /// <param name="fromID"></param> - public Powerline(IList<Coordinate> coordinates, int id, int year, double height, int power, int toID, int fromID) + public Powerline(IList<Coordinate> coordinates, int id, int year, double height, int voltage, int toID, int fromID) { this.Coordinates = coordinates; this.Identifier = id; this.Year = year; this.Height = height; - this.Power = power; + this.Voltage = voltage; this.IsBroken = false; this.IsON = false; this.PointFromID = fromID; @@ -97,7 +97,7 @@ namespace WindStressPRM { bool checker = Identifier >= 0 && Math.Abs(Year - 1985) < 45 && - Math.Abs(Height - 15) < 15 && Power > 0 && Power < 1000 && + Math.Abs(Height - 15) < 15 && Voltage > 0 && Voltage < 1000 && PointFromID >= 0 && PointToID >= 0; return checker; } diff --git a/WindStressPRM/WindStressPRM.cs b/WindStressPRM/WindStressPRM.cs index fa46b9996d2fe275da99f11affc461503e09aef2..568376a010140cf16c7802a02df11e5a69817dfa 100644 --- a/WindStressPRM/WindStressPRM.cs +++ b/WindStressPRM/WindStressPRM.cs @@ -3,14 +3,6 @@ using System.Collections.Generic; namespace WindStressPRM { - enum FunctionType - { - FunctionVelocityX = 0, - FunctionVelocityY = 1, - FunctionClimate5 = 2, - FunctionClimate10 = 3, - FunctionClimate15 = 4 - } /// <summary> /// main calculations class /// </summary> @@ -153,7 +145,7 @@ namespace WindStressPRM double y1 = points[i - 1].Y; double x2 = points[i].X; double y2 = points[i].Y; - bool result = linearLineIsBroken(points[i - 1], points[i], powerCurve.Height, powerCurve.Power); + bool result = linearLineIsBroken(points[i - 1], points[i], powerCurve.Height, powerCurve.Voltage); checkList.Add(result); } foreach (bool chkpnt in checkList) @@ -207,32 +199,34 @@ namespace WindStressPRM pointlist.Add(midpoint); } } - else - { + else { midpoint = new Coordinate( (coord1.X + coord2.X) / 2, (coord1.Y + coord2.Y) / 2); pointlist.Add(midpoint); } - FunctionType climateType; - if (power > 5 && power < 330) - { - climateType = FunctionType.FunctionClimate10; - } - else - { - if (power <= 5) { - climateType = FunctionType.FunctionClimate5; + Func<ClimateCell, double> climateClosure = delegate(ClimateCell cell) { + // if year > 1987 + // clim type = 25 + // + if (power > 5 && power < 330) + { + return cell.Wind10; } - else { - climateType = FunctionType.FunctionClimate15; + else if (power <= 5) + { + return cell.Wind5; } - } + else + { + return cell.Wind15; + } + }; List<bool> checkbool = new List<bool>(); foreach (Coordinate coords in pointlist) { bool res = false; - double uwind = interpol(coords, FunctionType.FunctionVelocityX); - double vwind = interpol(coords, FunctionType.FunctionVelocityY); - double climwind = interpol(coords, climateType); + double uwind = interpol(coords, Input.PrognosticCells, delegate(PrognosticCell cell) { return cell.VelocityX; }); + double vwind = interpol(coords, Input.PrognosticCells, delegate(PrognosticCell cell) { return cell.VelocityY; }); + double climwind = interpol(coords, Input.ClimateCells, climateClosure); if (Double.IsNaN(uwind) || Double.IsNaN(vwind) || Double.IsNaN(climwind)) { // interpolation fail. we can't say everything about here @@ -278,133 +272,20 @@ namespace WindStressPRM return result; } - private Coordinate cellToProjection(Index index, FunctionType functionType) - { - switch (functionType) - { - case FunctionType.FunctionVelocityX: - case FunctionType.FunctionVelocityY: - { - return Input.PrognosticCells.CellToProjection(index); - } - case FunctionType.FunctionClimate5: - case FunctionType.FunctionClimate10: - case FunctionType.FunctionClimate15: - { - return Input.ClimateCells.CellToProjection(index); - } - default: - break; - } - return null; - } - - int countInList(FunctionType functionType, bool forRows) - { - switch (functionType) - { - case FunctionType.FunctionVelocityX: - case FunctionType.FunctionVelocityY: - { - return forRows ? Input.PrognosticCells.RowsCount() : Input.PrognosticCells.ColumnCount(); - } - case FunctionType.FunctionClimate5: - case FunctionType.FunctionClimate10: - case FunctionType.FunctionClimate15: - { - return forRows ? Input.ClimateCells.RowsCount() : Input.ClimateCells.ColumnCount(); - } - default: - break; - } - return 0; - } - - private double valueForFunction(FunctionType functionType, Index index) - { - switch (functionType) - { - case FunctionType.FunctionVelocityX: - { - return Input.PrognosticCells.Cells[index.Row, index.Col].VelocityX; - } - case FunctionType.FunctionVelocityY: - { - return Input.PrognosticCells.Cells[index.Row, index.Col].VelocityY; - } - case FunctionType.FunctionClimate5: - { - return Input.ClimateCells.Cells[index.Row, index.Col].Wind5; - } - case FunctionType.FunctionClimate10: - { - return Input.ClimateCells.Cells[index.Row, index.Col].Wind10; - } - case FunctionType.FunctionClimate15: - { - return Input.ClimateCells.Cells[index.Row, index.Col].Wind15; - } - default: - break; - } - return 0; - } - - private CellSize cellSizeForFunction(FunctionType functionType) - { - switch (functionType) - { - case FunctionType.FunctionVelocityX: - case FunctionType.FunctionVelocityY: - { - return Input.PrognosticCells.Size; - } - case FunctionType.FunctionClimate5: - case FunctionType.FunctionClimate10: - case FunctionType.FunctionClimate15: - { - return Input.ClimateCells.Size; - } - default: - break; - } - throw new Exception("There is no cell size"); - } - - private Index projectionToCell(Coordinate coords, FunctionType functionType) - { - switch(functionType) { - case FunctionType.FunctionClimate5: - case FunctionType.FunctionClimate10: - case FunctionType.FunctionClimate15: - { - return Input.ClimateCells.ProjectionToCell(coords); - } - case FunctionType.FunctionVelocityX: - case FunctionType.FunctionVelocityY: - { - return Input.PrognosticCells.ProjectionToCell(coords); - } - default: - break; - } - throw new Exception("There is no associated matrix"); - } - - private double interpol(Coordinate coords, FunctionType functionType) + private double interpol<T>(Coordinate coords, Matrix<T> matrix, Func<T, double> valueGetter) { // select directions for projections const bool normalX = true;// true - East, false West const bool normalY = false;// true - North, false South - Index rc = projectionToCell(coords, functionType); - Coordinate center = cellToProjection(rc, functionType); + Index rc = matrix.ProjectionToCell(coords); + Coordinate center = matrix.CellToProjection(rc); double xDiff = coords.X - center.X; double yDiff = coords.Y - center.Y; //calculate second index int row2, col2; if ((xDiff >= 0 && normalX) || (!normalX && xDiff < 0)) { - row2 = rc.Row >= countInList(functionType, true) - 1 ? rc.Row - 1 : rc.Row + 1; + row2 = rc.Row >= matrix.RowsCount() - 1 ? rc.Row - 1 : rc.Row + 1; } else { @@ -412,7 +293,7 @@ namespace WindStressPRM } if ((yDiff >= 0 && normalY) || (!normalY && yDiff < 0)) { - col2 = rc.Col >= countInList(functionType, false) - 1 ? rc.Col - 1 : rc.Col + 1; + col2 = rc.Col >= matrix.ColumnCount() - 1 ? rc.Col - 1 : rc.Col + 1; } else { @@ -423,11 +304,11 @@ namespace WindStressPRM Index rcBotRight = new Index(Math.Max(row2, rc.Row), Math.Min(col2, rc.Col)); Index rcTopLeft = new Index(Math.Min(row2, rc.Row), Math.Max(col2, rc.Col)); Index rcTopRight = new Index(Math.Max(row2, rc.Row), Math.Max(col2, rc.Col)); - double valBotLeft = valueForFunction(functionType, rcBotLeft); - double valBotRight = valueForFunction(functionType, rcBotRight); - double valTopLeft = valueForFunction(functionType, rcTopLeft); - double valTopRight = valueForFunction(functionType, rcTopRight); - Coordinate origin = cellToProjection(rcBotLeft, functionType); + double valBotLeft = valueGetter(matrix.Cells[rcBotLeft.Row, rcBotLeft.Col]); + double valBotRight = valueGetter(matrix.Cells[rcBotRight.Row, rcBotRight.Col]); + double valTopLeft = valueGetter(matrix.Cells[rcTopLeft.Row, rcTopLeft.Col]); + double valTopRight = valueGetter(matrix.Cells[rcTopRight.Row, rcTopRight.Col]); + Coordinate origin = matrix.CellToProjection(rcBotLeft); bool testBotLeft = Double.IsNaN(valBotLeft); bool testBotRight = Double.IsNaN(valBotRight); @@ -485,8 +366,8 @@ namespace WindStressPRM } } // sizes for cell - double hx = cellSizeForFunction(functionType).Width; - double hy = cellSizeForFunction(functionType).Height; + double hx = matrix.Size.Width; + double hy = matrix.Size.Height; // coefficients double px = (coords.X - origin.X) / hx; double py = (coords.Y - origin.Y) / hy;