Skip to content
Snippets Groups Projects
Commit 929de10b authored by Debolskiy Andrey's avatar Debolskiy Andrey :bicyclist_tone5:
Browse files

Merge branch 'anton' of http://tesla.parallel.ru/debol/MES_Wind into second_round_andrey

parents 9a67b5f7 f901b6e6
No related branches found
No related tags found
No related merge requests found
...@@ -127,12 +127,15 @@ namespace MES_Wind ...@@ -127,12 +127,15 @@ namespace MES_Wind
IFeatureSet pwpointsSet = pwstLayer.DataSet; IFeatureSet pwpointsSet = pwstLayer.DataSet;
// Start to cast raster to PRM classes // Start to cast raster to PRM classes
// prognostic wind massives first // prognostic wind massives first
List<List<WindStressPRM.PrognosticCell>> prognosticWind = new List<List<WindStressPRM.PrognosticCell>>();
int rcountPrognostic = uRasterLayer.DataSet.NumRows; int rcountPrognostic = uRasterLayer.DataSet.NumRows;
int ccountPrognostic = uRasterLayer.DataSet.NumColumns; int ccountPrognostic = uRasterLayer.DataSet.NumColumns;
WindStressPRM.Matrix<WindStressPRM.PrognosticCell> prognosticMatrix = new WindStressPRM.Matrix<WindStressPRM.PrognosticCell>();
prognosticMatrix.Cells = new WindStressPRM.PrognosticCell[rcountPrognostic, ccountPrognostic];
prognosticMatrix.Size = new WindStressPRM.CellSize(uRasterLayer.DataSet.CellWidth, uRasterLayer.DataSet.CellHeight);
prognosticMatrix.AffineCoefficients = uRasterLayer.Bounds.AffineCoefficients;
// fill cells of prognostic matrix
for (int i = 0; i < rcountPrognostic; i++) for (int i = 0; i < rcountPrognostic; i++)
{ {
List<WindStressPRM.PrognosticCell> progWindRow = new List<WindStressPRM.PrognosticCell>();
for (int j = 0; j < ccountPrognostic; j++) for (int j = 0; j < ccountPrognostic; j++)
{ {
Coordinate dummyRCoords = uRasterLayer.Bounds.CellCenter_ToProj(i,j); Coordinate dummyRCoords = uRasterLayer.Bounds.CellCenter_ToProj(i,j);
...@@ -146,21 +149,19 @@ namespace MES_Wind ...@@ -146,21 +149,19 @@ namespace MES_Wind
vValue = Double.NaN; vValue = Double.NaN;
} }
WindStressPRM.PrognosticCell dummyPrognosticCell = new WindStressPRM.PrognosticCell(cellCoords, uValue, vValue); WindStressPRM.PrognosticCell dummyPrognosticCell = new WindStressPRM.PrognosticCell(cellCoords, uValue, vValue);
progWindRow.Add(dummyPrognosticCell); prognosticMatrix.Cells[i, j] = dummyPrognosticCell;
} }
prognosticWind.Add(progWindRow);
//prog_wind_row.Clear();
} }
//Get cell info and Affine transform coefficients from prognostic wind rasters
WindStressPRM.CellSize progcellsize = new WindStressPRM.CellSize(uRasterLayer.DataSet.CellWidth, uRasterLayer.DataSet.CellHeight);
double[] prog_aff = uRasterLayer.Bounds.AffineCoefficients;
//Now we create climate raster class //Now we create climate raster class
List<List<WindStressPRM.ClimateCell>> climWind = new List<List<WindStressPRM.ClimateCell>>();
int rowCountClim = clim5RasterLayer.DataSet.NumRows; int rowCountClim = clim5RasterLayer.DataSet.NumRows;
int columnCountClim = clim5RasterLayer.DataSet.NumColumns; int columnCountClim = clim5RasterLayer.DataSet.NumColumns;
WindStressPRM.Matrix<WindStressPRM.ClimateCell> climateMatrix = new WindStressPRM.Matrix<WindStressPRM.ClimateCell>();
climateMatrix.Cells = new WindStressPRM.ClimateCell[rowCountClim, columnCountClim];
climateMatrix.Size = new WindStressPRM.CellSize(clim5RasterLayer.DataSet.CellWidth, clim5RasterLayer.DataSet.CellHeight);
climateMatrix.AffineCoefficients = clim5RasterLayer.Bounds.AffineCoefficients;
// fill cells of climate matrix
for (int i = 0; i < rowCountClim; i++) for (int i = 0; i < rowCountClim; i++)
{ {
List<WindStressPRM.ClimateCell> climWindRow = new List<WindStressPRM.ClimateCell>();
for (int j = 0; j < columnCountClim; j++) for (int j = 0; j < columnCountClim; j++)
{ {
Coordinate dummyCellCoords = clim15RasterLayer.Bounds.CellCenter_ToProj(i,j); Coordinate dummyCellCoords = clim15RasterLayer.Bounds.CellCenter_ToProj(i,j);
...@@ -182,14 +183,9 @@ namespace MES_Wind ...@@ -182,14 +183,9 @@ namespace MES_Wind
clim15 = Double.NaN; clim15 = Double.NaN;
} }
WindStressPRM.ClimateCell dummyClim = new WindStressPRM.ClimateCell(dummyClimCoords, clim5, clim10, clim15); WindStressPRM.ClimateCell dummyClim = new WindStressPRM.ClimateCell(dummyClimCoords, clim5, clim10, clim15);
climWindRow.Add(dummyClim); climateMatrix.Cells[i, j] = dummyClim;
} }
climWind.Add(climWindRow);
//clim_wind_row.Clear();
} }
//Get cell info and affine transform coeff from climate rasters
WindStressPRM.CellSize climCellsize = new WindStressPRM.CellSize(clim5RasterLayer.DataSet.CellWidth, clim5RasterLayer.DataSet.CellHeight);
double[] climAffinecoeffs = clim5RasterLayer.Bounds.AffineCoefficients;
// create PRM_line list to pass to PRM_wind from loaded line layer // create PRM_line list to pass to PRM_wind from loaded line layer
List<WindStressPRM.Powerline> powerlinesToPRM = new List<WindStressPRM.Powerline>(); List<WindStressPRM.Powerline> powerlinesToPRM = new List<WindStressPRM.Powerline>();
foreach (IFeature feature in pwlineSet.Features) foreach (IFeature feature in pwlineSet.Features)
...@@ -251,19 +247,14 @@ namespace MES_Wind ...@@ -251,19 +247,14 @@ namespace MES_Wind
IPoint featurepointcoords = featurepoint.BasicGeometry as IPoint; IPoint featurepointcoords = featurepoint.BasicGeometry as IPoint;
dummystation.Coordinate = DotspPointToPRM(featurepointcoords); dummystation.Coordinate = DotspPointToPRM(featurepointcoords);
powerpointsToPRM.Add(dummystation); powerpointsToPRM.Add(dummystation);
} }
//Create a PRM_wind class and add all the properties from above //Create a PRM_wind class and add all the properties from above
WindStressPRM.StressPowerChecker prmwind = new WindStressPRM.StressPowerChecker(); WindStressPRM.StressPowerChecker prmwind = new WindStressPRM.StressPowerChecker();
WindStressPRM.Input input = new WindStressPRM.Input(); WindStressPRM.Input input = new WindStressPRM.Input();
input.PowerLines = powerlinesToPRM; input.PowerLines = powerlinesToPRM;
input.PowerStations = powerpointsToPRM; input.PowerStations = powerpointsToPRM;
input.PrognosticCells = prognosticWind; input.PrognosticCells = prognosticMatrix;
input.PrognosticCellSize = progcellsize; input.ClimateCells = climateMatrix;
input.PrognosticAffineCoefficients = prog_aff;
input.ClimateCells = climWind;
input.ClimateCellSize = climCellsize;
input.ClimateAffineCoefficients = climAffinecoeffs;
WindStressPRM.Output output = prmwind.CheckPower(input); WindStressPRM.Output output = prmwind.CheckPower(input);
// new FeatureSet for resulting disabled points // new FeatureSet for resulting disabled points
IFeatureSet disabledPointSet = new FeatureSet(FeatureType.Point); IFeatureSet disabledPointSet = new FeatureSet(FeatureType.Point);
...@@ -310,7 +301,6 @@ namespace MES_Wind ...@@ -310,7 +301,6 @@ namespace MES_Wind
disabledLineLayer.Symbolizer = lineSymbol; disabledLineLayer.Symbolizer = lineSymbol;
disabledLineLayer.LegendText = "Disabled Lines"; disabledLineLayer.LegendText = "Disabled Lines";
// new FeatureSet for resulting broken powerlines // new FeatureSet for resulting broken powerlines
//IFeatureSet brklineSet = new FeatureSet(FeatureType.Line); //IFeatureSet brklineSet = new FeatureSet(FeatureType.Line);
//DataTable dt = pwlineSet.DataTable; //DataTable dt = pwlineSet.DataTable;
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// DTO for input
/// </summary>
public class Input
{
/// <summary>
/// prognistic raster info
/// массив прогностического ветра
/// </summary>
public Matrix<PrognosticCell> PrognosticCells { get; set; }
/// <summary>
/// climate raster array
/// массив климатических полей скорости ветра заданной повторяемости
/// </summary>
public Matrix<ClimateCell> ClimateCells { get; set; }
/// <summary>
/// lines list
/// список ЛЭП
/// </summary>
public List<Powerline> PowerLines { get; set; }
/// <summary>
/// stations/poles list
/// список точечных объектов - трансформаторных подстанций/столбов/понижающих(конечных) подстанций
/// </summary>
public List<PowerStation> PowerStations { get; set; }
/// <summary>
/// maximum distance for line segment, meters
/// максимальное расстояние между точками ЛЭП, для которых проверяется сломаются/несломаются под действием ветра
/// </summary>
public double DistThreshold
{
get
{
return 500;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// Output
/// </summary>
public class Output
{
/// <summary>
/// stations list without power
/// Список подстанций на которые не поступит питание в результате предсказанных поломок ЛЭП в сети
/// </summary>
public List<PowerStation> DisabledStations { get; set; }
/// <summary>
/// broken lines list
/// Список прогнозируемых сломанных ЛЭП в результате ветрового воздействия
/// </summary>
public List<Powerline> DisabledLines { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// Cell obj for climate wind regular data
/// Объект - ячейка полей ветра определенной повторяемости на 10м на регулярной сетке
/// </summary>
public class ClimateCell
{
/// <summary>
/// once-in-5-years frequency wind, m/s
/// скорость ветра повторяемости один раз в 5 лет, м/с
/// </summary>
public double Wind5;
/// <summary>
/// once-in-10-years frequency wind, m/s
/// скорость ветра повторяемости один раз в 10 лет, м/с
/// </summary>
public double Wind10 { get; private set; }
/// <summary>
/// once-in-15-years frequency wind, m/s
/// скорость ветра повторяемости один раз в 15 лет, м/с
/// </summary>
public double Wind15 { get; private set; }
/// <summary>
/// Cell center coordinate pair
/// Координаты центра ячейки
/// </summary>
public Coordinate Coordinate { 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(Coordinate coord, double w5, double w10, double w15)
{
this.Coordinate = coord;
this.Wind5 = w5;
this.Wind10 = w10;
this.Wind15 = w15;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Climate wind value is not correct");
}
}
/// <summary>
/// Провекра валидности полей класса
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
double w5 = Wind5;
double w10 = Wind10;
double w15 = Wind15;
if (Double.IsNaN(w5)) // if is Nan - zerofied it.
{
w5 = 0;
}
if (Double.IsNaN(w10))
{
w10 = 0;
}
if (Double.IsNaN(w15))
{
w15 = 0;
}
// ветер по модулю не должен превышать 70м/с
return Math.Abs(w5) < 70 && Math.Abs(w10) < 70 && Math.Abs(w15) < 70;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// powerstation/pole point class
/// класс для трансформаторных подстанций/столбов/понижающих(конечных) подстанций
/// </summary>
public class PowerStation
{
/// <summary>
/// unique id
/// уникальный идентификатор подстанции/столба
/// </summary>
public int Identifier { get; set; }
/// <summary>
/// Coordinates
/// </summary>
public Coordinate Coordinate { get; set; }
/// <summary>
/// station name field
/// название подстанции
/// </summary>
public string Name { get; set; }
/// <summary>
/// power, kW
/// мощность, кВ
/// </summary>
public int Power { get; set; }
/// <summary>
/// type of point - trans/pole/endpoint
/// тип станции - трансформаторная подстанция/столб/понижающая(конечная)подстанция
/// </summary>
public enum StationType
{
Pole, Trans, Endstat
};
/// <summary>
/// тип подстанции
/// </summary>
public StationType Stationtype { get; set; }
/// <summary>
/// is point a source?
/// является ли подстаниция источником питания (в случае ТЭЦ или питания от внешних для рассматриваемой цепи ЛЭП)
/// </summary>
public bool IsSource { get; set; }
/// <summary>
/// power on switch
/// поступает (true) или нет (false) на подстанцию питание
/// </summary>
public bool IsON { get; set; }
/// <summary>
/// asigned powerlines list
/// список оканчивающихся/начинающихся на подстанции ЛЭП
/// </summary>
public IList<Powerline> LineList { get; set; }
public PowerStation()
{
//default constructor
}
/// <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)
{
this.Coordinate = crds;
this.Identifier = id;
this.Name = stname;
this.Power = stpower;
this.Stationtype = sttype;
this.IsSource = issource;
this.IsON = false;
}
public bool CheckValue()
{
bool checker = Identifier >= 0 && Power > 0 && Power < 1000;
return checker;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// power line object
/// объект - ЛЭП
/// </summary>
public class Powerline
{
/// <summary>
/// unique id
/// уникальный идентификатор
/// </summary>
public int Identifier { get; set; }
/// <summary>
/// year of construction
/// год постройки ЛЭП
/// </summary>
public int Year { get; set; }
/// <summary>
/// average height of cable span between two poles, meters
/// средняя высота пролета, м
/// </summary>
public double Height { get; set; }
/// <summary>
/// power kV for switches
/// Напряжение ЛЭП, кВ
/// </summary>
public int Power { get; set; }
/// <summary>
/// Line vertices coordinate list
/// список координат вершин ЛЭП как линейного объекта
/// </summary>
public IList<Coordinate> Coordinates { get; set; }
/// <summary>
/// assigned powerstation/pole
/// идентификатор соответсвующего конца/начала линии (столб, трансформаторная подстанция, понижающая подстанция)
/// </summary>
public int PointFromID { get; set; }
/// <summary>
/// assigned powerstation/pole
/// идентификатор соответсвующего конца/начала линии (столб, трансформаторная подстанция, понижающая подстанция)
/// </summary>
public int PointToID { get; set; }
/// <summary>
/// broken/not broken switch
/// сломана (true) или нет (false) линяя
/// </summary>
public bool IsBroken { get; set; }
/// <summary>
/// power on switch
/// получает (true) или нет (false) линия питание
/// </summary>
public bool IsON { get; set; }
public Powerline()
{
//default constructor body
}
/// <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>
public Powerline(IList<Coordinate> coordinates, int id, int year, double height, int power, int toID, int fromID)
{
this.Coordinates = coordinates;
this.Identifier = id;
this.Year = year;
this.Height = height;
this.Power = power;
this.IsBroken = false;
this.IsON = false;
this.PointFromID = fromID;
this.PointToID = toID;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Powerline object wasn't initialized correctly");
}
}
/// <summary>
/// проверка валидности полей
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
bool checker =
Identifier >= 0 && Math.Abs(Year - 1985) < 45 &&
Math.Abs(Height - 15) < 15 && Power > 0 && Power < 1000 &&
PointFromID >= 0 && PointToID >= 0;
return checker;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// Cell obj for regular prognostic wind field
/// Объект ячейки для поля прогностического ветра на высоте 10м на регулярной сетке
/// </summary>
public class PrognosticCell
{
/// <summary>
/// U - component of wind velocity, m/s
/// U - компонента скорости ветра, м/с
/// </summary>
public double VelocityX { get; private set; }
/// <summary>
/// V - component of wind velocity, m/s
/// V - компонента скорости ветра, м/с
/// </summary>
public double VelocityY { get; private set; }
/// <summary>
/// Cell center coordinates
/// Координаты центра ячейки
/// </summary>
public Coordinate Coordinate { get; private set; }
/// <summary>
/// designated constructor
/// </summary>
/// <param name="coord"> Coordinate pair</param>
/// <param name="vX"> U component</param>
/// <param name="vY"> V component</param>
public PrognosticCell(Coordinate coord, double vX, double vY)
{
this.Coordinate = coord;
this.VelocityX = vX;
this.VelocityY = vY;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Prognostic wind velocities are incorrect");
}
}
/// <summary>
/// Проверка полей на валидность
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
bool res1 = Double.IsNaN(VelocityX);
bool res2 = Double.IsNaN(VelocityY);
if (res1 != res2)
{
return false;
}
// пустые данные
if (res1 == res2 == true)
{
return true;
}
///Скорость ветра на высоте 10м от поверхности на Земле не может превышать 70м/c
return Math.Abs(Math.Pow(VelocityX, 2) + Math.Pow(VelocityY, 2)) <= 4900;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindStressPRM
{
/// <summary>
/// Cell Sizes
/// Параметры ячейки (регулярной сетки)
/// </summary>
public class CellSize
{
/// <summary>
/// ширина ячейки (расстояние между соседними по широте центрами ячеек)
/// </summary>
public double Width { get; set; }
/// <summary>
/// высота ячейки (расстояние между соседними по долготе центрами ячеек)
/// </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)
{
this.Width = wdh;
this.Height = hgh;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Cell width or height values are incorrect!");
}
}
/// <summary>
/// Проверка валидности полей
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
return Width > 0 && Height > 0;
}
}
}
using System;
using System.Collections.Generic;
namespace WindStressPRM
{
/// <summary>
/// Coordinate pair
/// </summary>
public class Coordinate
{
/// <summary>
/// easting coordinate
/// Координата по широте
/// </summary>
public double X { get; private set; }
/// <summary>
/// northing coordinate
/// Координата по долготе
/// </summary>
public double Y { get; private set; }
/// <summary>
/// designated constructor
/// Основной конструктор
/// </summary>
/// <param name="X"></param>
/// <param name="Y"></param>
public Coordinate(double X, double Y)
{
this.X = X;
this.Y = Y;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Passed coordinates are not valid!");
}
}
/// <summary>
/// Проверка на валидность значений
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
return !Double.IsNaN(X) && !Double.IsInfinity(X) && !Double.IsNaN(Y) && !Double.IsInfinity(Y);
}
}
}
using System;
using System.Collections.Generic;
namespace WindStressPRM
{
/// <summary>
/// Index class for raster lists in list
/// Индекс-класс для растровых массивов
/// </summary>
public class Index
{
/// <summary>
/// Outer index
/// Внешний индекс
/// </summary>
public int Row { get; set; }
/// <summary>
/// Inner index
/// Внутренний индекс
/// </summary>
public int Col { get; set; }
/// <summary>
/// designated constructor
/// </summary>
/// <param name="Row">row index</param>
/// <param name="Col">column index</param>
public Index(int Row, int Col)
{
if (Row <= -1 || Col <= -1)
{
throw new System.ArgumentOutOfRangeException("Index must be initialized with nonegative integer value");
}
this.Row = Row;
this.Col = Col;
}
}
}
using System;
using System.Collections.Generic;
namespace WindStressPRM
{
/// <summary>
/// Generic Matrix of type T
/// </summary>
/// <typeparam name="T"></typeparam>
public class Matrix<T>
{
/// <summary>
/// AffineCoefficients for matrix from raster projection
/// </summary>
public double[] AffineCoefficients { get; set; }
/// <summary>
/// Size of cell. In meters
/// </summary>
public CellSize Size { get; set; }
/// <summary>
/// Cells Container
/// </summary>
public T[,] Cells { get; set; }
/// <summary>
/// Number of rows in matrix
/// </summary>
/// <returns></returns>
public int RowsCount()
{
return Cells.Rank > 0 ? Cells.GetLength(0) : 0;
}
/// <summary>
/// Number of columns
/// </summary>
/// <returns></returns>
public int ColumnCount()
{
return Cells.Rank > 1 ? Cells.GetLength(1) : 0;
}
}
}
...@@ -3,411 +3,6 @@ using System.Collections.Generic; ...@@ -3,411 +3,6 @@ using System.Collections.Generic;
namespace WindStressPRM namespace WindStressPRM
{ {
/// <summary>
/// Index class for raster lists in list
/// Индекс-класс для растровых массивов
/// </summary>
public class Index
{
/// <summary>
/// Outer index
/// Внешний индекс
/// </summary>
public int Row { get; set; }
/// <summary>
/// Inner index
/// Внутренний индекс
/// </summary>
public int Col { get; set; }
/// <summary>
/// designated constructor
/// </summary>
/// <param name="Row">row index</param>
/// <param name="Col">column index</param>
public Index(int Row, int Col)
{
if (Row <= -1 || Col <= -1) {
throw new System.ArgumentOutOfRangeException("Index must be initialized with nonegative integer value");
}
this.Row = Row;
this.Col = Col;
}
}
/// <summary>
/// Coordinate pair
/// </summary>
public class Coordinate
{
/// <summary>
/// easting coordinate
/// Координата по широте
/// </summary>
public double X { get; private set;}
/// <summary>
/// northing coordinate
/// Координата по долготе
/// </summary>
public double Y { get; private set; }
/// <summary>
/// designated constructor
/// Основной конструктор
/// </summary>
/// <param name="X"></param>
/// <param name="Y"></param>
public Coordinate(double X, double Y)
{
this.X = X;
this.Y = Y;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Passed coordinates are not valid!");
}
}
/// <summary>
/// Проверка на валидность значений
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
return !Double.IsNaN(X) && !Double.IsInfinity(X) && !Double.IsNaN(Y) && !Double.IsInfinity(Y);
}
}
/// <summary>
/// Cell obj for regular prognostic wind field
/// Объект ячейки для поля прогностического ветра на высоте 10м на регулярной сетке
/// </summary>
public class PrognosticCell
{
/// <summary>
/// U - component of wind velocity, m/s
/// U - компонента скорости ветра, м/с
/// </summary>
public double VelocityX { get; private set; }
/// <summary>
/// V - component of wind velocity, m/s
/// V - компонента скорости ветра, м/с
/// </summary>
public double VelocityY { get; private set; }
/// <summary>
/// Cell center coordinates
/// Координаты центра ячейки
/// </summary>
public Coordinate Coordinate { get; private set; }
/// <summary>
/// designated constructor
/// </summary>
/// <param name="coord"> Coordinate pair</param>
/// <param name="vX"> U component</param>
/// <param name="vY"> V component</param>
public PrognosticCell(Coordinate coord, double vX, double vY)
{
this.Coordinate = coord;
this.VelocityX = vX;
this.VelocityY = vY;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Prognostic wind velocities are incorrect");
}
}
/// <summary>
/// Проверка полей на валидность
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
bool res1 = Double.IsNaN(VelocityX);
bool res2 = Double.IsNaN(VelocityY);
if (res1 != res2) {
return false;
}
// пустые данные
if (res1) {
return true;
}
///Скорость ветра на высоте 10м от поверхности на Земле не может превышать 70м/c
return Math.Abs(Math.Pow(VelocityX, 2) + Math.Pow(VelocityY, 2)) <= 4900;
}
}
/// <summary>
/// Cell obj for climate wind regular data
/// Объект - ячейка полей ветра определенной повторяемости на 10м на регулярной сетке
/// </summary>
public class ClimateCell
{
/// <summary>
/// once-in-5-years frequency wind, m/s
/// скорость ветра повторяемости один раз в 5 лет, м/с
/// </summary>
public double Wind5;
/// <summary>
/// once-in-10-years frequency wind, m/s
/// скорость ветра повторяемости один раз в 10 лет, м/с
/// </summary>
public double Wind10 { get; private set; }
/// <summary>
/// once-in-15-years frequency wind, m/s
/// скорость ветра повторяемости один раз в 15 лет, м/с
/// </summary>
public double Wind15 { get; private set; }
/// <summary>
/// Cell center coordinate pair
/// Координаты центра ячейки
/// </summary>
public Coordinate Coordinate { 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(Coordinate coord, double w5, double w10, double w15)
{
this.Coordinate = coord;
this.Wind5 = w5;
this.Wind10 = w10;
this.Wind15 = w15;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Climate wind value is not correct");
}
}
/// <summary>
/// Провекра валидности полей класса
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
bool c5 = Double.IsNaN(Wind5);
bool c10 = Double.IsNaN(Wind10);
bool c15 = Double.IsNaN(Wind15);
if (c5 != c10 || c5 != c15 || c5 != c10) {
return false;
}
if (c5) {
return true;
}
// ветер по модулю не должен превышать 70м/с
return Math.Abs(Wind5) < 70 && Math.Abs(Wind10) < 70 && Math.Abs(Wind15) < 70;
}
}
/// <summary>
/// Cell Size parameters
/// Параметры ячейки (регулярной сетки)
/// </summary>
public class CellSize
{
/// <summary>
/// ширина ячейки (расстояние между соседними по широте центрами ячеек)
/// </summary>
public double Width { get; set; }
/// <summary>
/// высота ячейки (расстояние между соседними по долготе центрами ячеек)
/// </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)
{
this.Width = wdh;
this.Height = hgh;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Cell width or height values are incorrect!");
}
}
/// <summary>
/// Проверка валидности полей
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
return Width > 0 && Height > 0;
}
}
/// <summary>
/// power line object
/// объект - ЛЭП
/// </summary>
public class Powerline
{
/// <summary>
/// unique id
/// уникальный идентификатор
/// </summary>
public int Identifier { get; set; }
/// <summary>
/// year of construction
/// год постройки ЛЭП
/// </summary>
public int Year { get; set; }
/// <summary>
/// average height of cable span between two poles, meters
/// средняя высота пролета, м
/// </summary>
public double Height { get; set; }
/// <summary>
/// power kV for switches
/// Напряжение ЛЭП, кВ
/// </summary>
public int Power { get; set; }
/// <summary>
/// Line vertices coordinate list
/// список координат вершин ЛЭП как линейного объекта
/// </summary>
public IList<Coordinate> Coordinates { get; set; }
/// <summary>
/// assigned powerstation/pole
/// идентификатор соответсвующего конца/начала линии (столб, трансформаторная подстанция, понижающая подстанция)
/// </summary>
public int PointFromID { get; set; }
/// <summary>
/// assigned powerstation/pole
/// идентификатор соответсвующего конца/начала линии (столб, трансформаторная подстанция, понижающая подстанция)
/// </summary>
public int PointToID { get; set; }
/// <summary>
/// broken/not broken switch
/// сломана (true) или нет (false) линяя
/// </summary>
public bool IsBroken { get; set; }
/// <summary>
/// power on switch
/// получает (true) или нет (false) линия питание
/// </summary>
public bool IsON { get; set; }
public Powerline()
{
//default constructor body
}
/// <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>
public Powerline(IList<Coordinate> coordinates, int id, int year, double height, int power, int toID, int fromID)
{
this.Coordinates = coordinates;
this.Identifier = id;
this.Year = year;
this.Height = height;
this.Power = power;
this.IsBroken = false;
this.IsON = false;
this.PointFromID = fromID;
this.PointToID = toID;
if (!(this.CheckValue()))
{
throw new System.ArgumentException("Powerline object wasn't initialized correctly");
}
}
/// <summary>
/// проверка валидности полей
/// </summary>
/// <returns></returns>
public bool CheckValue()
{
bool checker =
Identifier >= 0 && Math.Abs(Year - 1985) < 45 &&
Math.Abs(Height - 15) < 15 && Power > 0 && Power < 1000 &&
PointFromID >= 0 && PointToID >= 0;
return checker;
}
}
/// <summary>
/// powerstation/pole point class
/// класс для трансформаторных подстанций/столбов/понижающих(конечных) подстанций
/// </summary>
public class PowerStation
{
/// <summary>
/// unique id
/// уникальный идентификатор подстанции/столба
/// </summary>
public int Identifier { get; set; }
/// <summary>
/// Coordinates
/// </summary>
public Coordinate Coordinate { get; set; }
/// <summary>
/// station name field
/// название подстанции
/// </summary>
public string Name { get; set; }
/// <summary>
/// power, kW
/// мощность, кВ
/// </summary>
public int Power { get; set; }
/// <summary>
/// type of point - trans/pole/endpoint
/// тип станции - трансформаторная подстанция/столб/понижающая(конечная)подстанция
/// </summary>
public enum StationType
{
Pole, Trans, Endstat
};
/// <summary>
/// тип подстанции
/// </summary>
public StationType Stationtype { get; set; }
/// <summary>
/// is point a source?
/// является ли подстаниция источником питания (в случае ТЭЦ или питания от внешних для рассматриваемой цепи ЛЭП)
/// </summary>
public bool IsSource { get; set; }
/// <summary>
/// power on switch
/// поступает (true) или нет (false) на подстанцию питание
/// </summary>
public bool IsON { get; set; }
/// <summary>
/// asigned powerlines list
/// список оканчивающихся/начинающихся на подстанции ЛЭП
/// </summary>
public IList<Powerline> LineList { get; set; }
public PowerStation()
{
//default constructor
}
/// <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)
{
this.Coordinate = crds;
this.Identifier = id;
this.Name = stname;
this.Power = stpower;
this.Stationtype = sttype;
this.IsSource = issource;
this.IsON = false;
}
public bool CheckValue()
{
bool checker = Identifier >=0 && Power >0 && Power < 1000;
return checker;
}
}
enum FunctionType enum FunctionType
{ {
FunctionVelocityX = 0, FunctionVelocityX = 0,
...@@ -417,81 +12,6 @@ namespace WindStressPRM ...@@ -417,81 +12,6 @@ namespace WindStressPRM
FunctionClimate15 = 4 FunctionClimate15 = 4
} }
/// <summary> /// <summary>
/// DTO for input
/// </summary>
public class Input
{
/// <summary>
/// prognistic raster info
/// массив прогностического ветра
/// </summary>
public List<List<PrognosticCell>> PrognosticCells { get; set; }
/// <summary>
/// prognostic raster cell info
/// параметры ячеек регулярной сетки прогностического ветра
/// </summary>
public CellSize PrognosticCellSize { get; set; }
/// <summary>
/// affine coefficients from prognostic raster projections
/// коэффициенты аффиного проеобразования из проекции массива прогностического ветра
/// </summary>
public double[] PrognosticAffineCoefficients { get; set; }
/// <summary>
/// climate raster array
/// массив климатических полей скорости ветра заданной повторяемости
/// </summary>
public List<List<ClimateCell>> ClimateCells { get; set; }
/// <summary>
/// climate raster cell info
/// параметры ячеек регулярной сетки климатических полей скорости ветра заданной повторяемости
/// </summary>
public CellSize ClimateCellSize { get; set; }
/// <summary>
/// affine coefficients from climate raster projection
/// коэффициенты аффинного преобразования из проекции массива климатических полей скорости ветра заданной повторяемости
/// </summary>
public double[] ClimateAffineCoefficients { get; set; }
/// <summary>
/// lines list
/// список ЛЭП
/// </summary>
public List<Powerline> PowerLines { get; set; }
/// <summary>
/// stations/poles list
/// список точечных объектов - трансформаторных подстанций/столбов/понижающих(конечных) подстанций
/// </summary>
public List<PowerStation> PowerStations { get; set; }
/// <summary>
/// maximum distance for line segment, meters
/// максимальное расстояние между точками ЛЭП, для которых проверяется сломаются/несломаются под действием ветра
/// </summary>
public double DistThreshold
{
get
{
return 500;
}
}
}
/// <summary>
/// Output
/// </summary>
public class Output
{
/// <summary>
/// stations list without power
/// Список подстанций на которые не поступит питание в результате предсказанных поломок ЛЭП в сети
/// </summary>
public List<PowerStation> DisabledStations { get; set; }
/// <summary>
/// broken lines list
/// Список прогнозируемых сломанных ЛЭП в результате ветрового воздействия
/// </summary>
public List<Powerline> DisabledLines { get; set; }
}
/// <summary>
/// main calculations class /// main calculations class
/// </summary> /// </summary>
public class StressPowerChecker public class StressPowerChecker
...@@ -523,14 +43,7 @@ namespace WindStressPRM ...@@ -523,14 +43,7 @@ namespace WindStressPRM
//fill output //fill output
Output output = new Output(); Output output = new Output();
output.DisabledStations = new List<PowerStation>(); output.DisabledStations = new List<PowerStation>();
output.DisabledLines = new List<Powerline>(); output.DisabledLines = prmBrokenLines;
foreach (Powerline line in input.PowerLines)
{
if (line.IsBroken)
{
output.DisabledLines.Add(line);
}
}
foreach (PowerStation powerStation in input.PowerStations) foreach (PowerStation powerStation in input.PowerStations)
{ {
//stations of type pole can be disabled if the line is broken //stations of type pole can be disabled if the line is broken
...@@ -720,6 +233,13 @@ namespace WindStressPRM ...@@ -720,6 +233,13 @@ namespace WindStressPRM
double uwind = interpol(coords, FunctionType.FunctionVelocityX); double uwind = interpol(coords, FunctionType.FunctionVelocityX);
double vwind = interpol(coords, FunctionType.FunctionVelocityY); double vwind = interpol(coords, FunctionType.FunctionVelocityY);
double climwind = interpol(coords, climateType); double climwind = interpol(coords, climateType);
if (Double.IsNaN(uwind) || Double.IsNaN(vwind) || Double.IsNaN(climwind))
{
// interpolation fail. we can't say everything about here
// discussion: also we can save these points for detail analysis
res = false;
continue;
}
double umod = Math.Sqrt(uwind * uwind + vwind * vwind); ; double umod = Math.Sqrt(uwind * uwind + vwind * vwind); ;
double angleline = Math.Atan2((coord2.Y - coord1.Y), (coord2.X - coord1.X)); double angleline = Math.Atan2((coord2.Y - coord1.Y), (coord2.X - coord1.X));
double anglewind = Math.Atan2(vwind, uwind) - angleline; double anglewind = Math.Atan2(vwind, uwind) - angleline;
...@@ -765,13 +285,13 @@ namespace WindStressPRM ...@@ -765,13 +285,13 @@ namespace WindStressPRM
case FunctionType.FunctionVelocityX: case FunctionType.FunctionVelocityX:
case FunctionType.FunctionVelocityY: case FunctionType.FunctionVelocityY:
{ {
return Input.PrognosticAffineCoefficients; return Input.PrognosticCells.AffineCoefficients;
} }
case FunctionType.FunctionClimate5: case FunctionType.FunctionClimate5:
case FunctionType.FunctionClimate10: case FunctionType.FunctionClimate10:
case FunctionType.FunctionClimate15: case FunctionType.FunctionClimate15:
{ {
return Input.ClimateAffineCoefficients; return Input.ClimateCells.AffineCoefficients;
} }
default: default:
break; break;
...@@ -821,13 +341,13 @@ namespace WindStressPRM ...@@ -821,13 +341,13 @@ namespace WindStressPRM
case FunctionType.FunctionVelocityX: case FunctionType.FunctionVelocityX:
case FunctionType.FunctionVelocityY: case FunctionType.FunctionVelocityY:
{ {
return Input.PrognosticCells[index.Row][index.Col].Coordinate; return Input.PrognosticCells.Cells[index.Row, index.Col].Coordinate;
} }
case FunctionType.FunctionClimate5: case FunctionType.FunctionClimate5:
case FunctionType.FunctionClimate10: case FunctionType.FunctionClimate10:
case FunctionType.FunctionClimate15: case FunctionType.FunctionClimate15:
{ {
return Input.ClimateCells[index.Row][index.Col].Coordinate; return Input.ClimateCells.Cells[index.Row, index.Col].Coordinate;
} }
default: default:
break; break;
...@@ -842,13 +362,13 @@ namespace WindStressPRM ...@@ -842,13 +362,13 @@ namespace WindStressPRM
case FunctionType.FunctionVelocityX: case FunctionType.FunctionVelocityX:
case FunctionType.FunctionVelocityY: case FunctionType.FunctionVelocityY:
{ {
return forRows ? Input.PrognosticCells.Count : Input.PrognosticCells[0].Count; return forRows ? Input.PrognosticCells.RowsCount() : Input.PrognosticCells.ColumnCount();
} }
case FunctionType.FunctionClimate5: case FunctionType.FunctionClimate5:
case FunctionType.FunctionClimate10: case FunctionType.FunctionClimate10:
case FunctionType.FunctionClimate15: case FunctionType.FunctionClimate15:
{ {
return forRows ? Input.ClimateCells.Count : Input.ClimateCells[0].Count; return forRows ? Input.ClimateCells.RowsCount() : Input.ClimateCells.ColumnCount();
} }
default: default:
break; break;
...@@ -862,23 +382,23 @@ namespace WindStressPRM ...@@ -862,23 +382,23 @@ namespace WindStressPRM
{ {
case FunctionType.FunctionVelocityX: case FunctionType.FunctionVelocityX:
{ {
return Input.PrognosticCells[index.Row][index.Col].VelocityX; return Input.PrognosticCells.Cells[index.Row, index.Col].VelocityX;
} }
case FunctionType.FunctionVelocityY: case FunctionType.FunctionVelocityY:
{ {
return Input.PrognosticCells[index.Row][index.Col].VelocityY; return Input.PrognosticCells.Cells[index.Row, index.Col].VelocityY;
} }
case FunctionType.FunctionClimate5: case FunctionType.FunctionClimate5:
{ {
return Input.ClimateCells[index.Row][index.Col].Wind5; return Input.ClimateCells.Cells[index.Row, index.Col].Wind5;
} }
case FunctionType.FunctionClimate10: case FunctionType.FunctionClimate10:
{ {
return Input.ClimateCells[index.Row][index.Col].Wind10; return Input.ClimateCells.Cells[index.Row, index.Col].Wind10;
} }
case FunctionType.FunctionClimate15: case FunctionType.FunctionClimate15:
{ {
return Input.ClimateCells[index.Row][index.Col].Wind15; return Input.ClimateCells.Cells[index.Row, index.Col].Wind15;
} }
default: default:
break; break;
...@@ -893,13 +413,13 @@ namespace WindStressPRM ...@@ -893,13 +413,13 @@ namespace WindStressPRM
case FunctionType.FunctionVelocityX: case FunctionType.FunctionVelocityX:
case FunctionType.FunctionVelocityY: case FunctionType.FunctionVelocityY:
{ {
return Input.PrognosticCellSize; return Input.PrognosticCells.Size;
} }
case FunctionType.FunctionClimate5: case FunctionType.FunctionClimate5:
case FunctionType.FunctionClimate10: case FunctionType.FunctionClimate10:
case FunctionType.FunctionClimate15: case FunctionType.FunctionClimate15:
{ {
return Input.ClimateCellSize; return Input.ClimateCells.Size;
} }
default: default:
break; break;
...@@ -954,7 +474,8 @@ namespace WindStressPRM ...@@ -954,7 +474,8 @@ namespace WindStressPRM
// tests indicates that value at test-cell is missed. // tests indicates that value at test-cell is missed.
if (testTopRight && testTopLeft && testBotLeft && testBotRight) if (testTopRight && testTopLeft && testBotLeft && testBotRight)
{ {
throw new Exception("Current value in such a bad place, you need to fill these place with raster values"); // Current value in such a bad place, you need to fill these place with raster values
return Double.NaN;
} }
int count = 0; int count = 0;
if (testBotLeft) if (testBotLeft)
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
<ProjectGuid>{599B5E9B-293A-4866-A50F-6BB7DC36A81C}</ProjectGuid> <ProjectGuid>{599B5E9B-293A-4866-A50F-6BB7DC36A81C}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PRMLibrary</RootNamespace> <RootNamespace>WindStressPRM</RootNamespace>
<AssemblyName>PRMLibrary</AssemblyName> <AssemblyName>WindStressPRM</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
</PropertyGroup> </PropertyGroup>
...@@ -35,6 +35,16 @@ ...@@ -35,6 +35,16 @@
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DTO\Input.cs" />
<Compile Include="DTO\Output.cs" />
<Compile Include="Objects\ClimateCell.cs" />
<Compile Include="Utils\CellSize.cs" />
<Compile Include="Utils\Coordinate.cs" />
<Compile Include="Utils\Index.cs" />
<Compile Include="Utils\Matrix.cs" />
<Compile Include="Objects\Powerline.cs" />
<Compile Include="Objects\PowerStation.cs" />
<Compile Include="Objects\PrognosticCell.cs" />
<Compile Include="WindStressPRM.cs" /> <Compile Include="WindStressPRM.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment