{
"cells": [
{
"cell_type": "markdown",
"id": "dcef197e-b2e7-4484-b83e-92d51176f385",
"metadata": {},
"source": [
"# Data Input"
]
},
{
"cell_type": "markdown",
"id": "25122e7c-2ced-48c6-9c32-27b06ee9e173",
"metadata": {},
"source": [
"`OptiWindNet` creates electrical cable networks for *problem instances* that are passed to it. The problem instance must define:\n",
"- positions (2D planar coordinates) of wind turbines and electrical substations\n",
"- some properties of the available electrical cables\n",
"- (optional) geometrical boundaries where cables are allowed: polygonal outer border, polygonal obstacles (exclusion zones)"
]
},
{
"cell_type": "markdown",
"id": "b638d99c-b592-4692-bccb-10eef30f51b5",
"metadata": {},
"source": [
"A *location* describes the geometrical part of the data: positions and boundaries. This notebook focuses on the alternatives to provide location data, which present a much greater volume and complexity than the cable properties."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "2d6f14e0-f975-454f-b3ae-cfa92566b9bf",
"metadata": {},
"source": [
"The problem instances are contained in instances of the `WindFarmNetwork` class. The geometric data can be initialized with:\n",
"- coordinates (contained in Numpy arrays)\n",
"- a location object `L` (a NetworkX Graph instance)\n",
"- an [windIO](https://github.com/IEAWindSystems/windIO) `.yaml` file\n",
"- a `.yaml` file (OptiWindNet's schema)\n",
"- a `.osm.pbf` file\n",
"\n",
"Additionally, the cable properties must also be provided at intialization."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "bb4a7960-c3ef-4f83-95c7-452103bc551e",
"metadata": {},
"outputs": [],
"source": [
"cables = 4"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fa29e2ac-26f7-4927-bebf-eeef30a5ab37",
"metadata": {},
"outputs": [],
"source": [
"from optiwindnet.api import WindFarmNetwork"
]
},
{
"cell_type": "markdown",
"id": "fca2771e-61e8-4f29-a6ae-8bbce26c4762",
"metadata": {},
"source": [
"## Provide coordinates"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "fe196c8d-21dc-4c26-b4c1-25bff5046e94",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e93a9280-594e-4840-8ea6-ec2a0bd800b3",
"metadata": {},
"outputs": [],
"source": [
"# all coordinates are sequences of (x, y) pairs\n",
"# if input coordinates are in arrays X and Y, use `np.hstack((X, Y))`\n",
"borderC = np.array( # coordinate sequence defines the polygon, last-first segment implicit\n",
" [[1951, 200], [1951, 1383], [386, 1383], [650, 708], [624, 678],\n",
" [4, 1036], [4, 3], [1152, 3], [917, 819], [957, 854]],\n",
" dtype=float)\n",
"obstacleC_ = [\n",
" # first obstacle\n",
" np.array([[1540, 920], [1600, 940], [1600, 1150], [1400, 1200]]),\n",
" # [second obstacle] ...\n",
"]\n",
"substationsC = np.array([[696, 1063],], dtype=float)\n",
"turbinesC = np.array(\n",
" [[1940, 279], [1920, 703], [1475, 696], [1839, 1250],\n",
" [1277, 1296], [442, 1359], [737, 435], [1060, 26],\n",
" [522, 176], [87, 35], [184, 417], [71, 878]],\n",
" dtype=float)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "06fae7b8",
"metadata": {},
"outputs": [],
"source": [
"wfn_coords = WindFarmNetwork(\n",
" turbinesC=turbinesC,\n",
" substationsC=substationsC,\n",
" cables=cables,\n",
" borderC=borderC,\n",
" obstacleC_=obstacleC_,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "7ce4abaa-3b40-41b8-8976-b8fdb264df25",
"metadata": {},
"source": [
"> **Note:** Many of the Jupyter notebooks provided include SVG figures as output. To ensure these visuals are displayed correctly in JupyterLab or Jupyter Notebook, make sure the notebook is marked as **trusted**.\n",
"> *In JupyterLab, you can do this by pressing* `Ctrl + Shift + C` *and selecting* **Trust Notebook**."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5539b8f8-a4d6-4aa6-b1c3-faf04331f38a",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wfn_coords"
]
},
{
"cell_type": "markdown",
"id": "036be03b-9bb4-4f36-bdb1-d3008a79be68",
"metadata": {},
"source": [
"## Provide a location instance `L`"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c640b447-bebc-4276-bf0c-35d141c6682a",
"metadata": {},
"outputs": [],
"source": [
"from optiwindnet.api import load_repository"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "32cc1cae-d0bd-4853-9269-95308b279cb9",
"metadata": {},
"outputs": [],
"source": [
"locations = load_repository()"
]
},
{
"cell_type": "markdown",
"id": "7442e039",
"metadata": {},
"source": [
"> Note: `load_repository()` loads locations from all `.yaml` (OptiWindNet) and `.osm.pbf` files in the given directory. If no path is given, it loads the locations distributed with *OptiWindNet*. For more details, see [Load repositories containing location data](a03_load_repositories.ipynb)."
]
},
{
"cell_type": "markdown",
"id": "b410179a",
"metadata": {},
"source": [
"Initialize `WindFarmNetwork()` instance with the loaded `L`:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "ec5d7fc6",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wfn_L = WindFarmNetwork(\n",
" L=locations.seagreen,\n",
" cables=cables,\n",
")\n",
"wfn_L"
]
},
{
"cell_type": "markdown",
"id": "ac064931-e789-467f-8378-0e64d098d46a",
"metadata": {},
"source": [
"## Provide an windIO YAML file"
]
},
{
"cell_type": "markdown",
"id": "6679b72d-0c49-4698-ae66-c072943d9428",
"metadata": {},
"source": [
"[windIO](https://github.com/IEAWindSystems/windIO) is a data format for inputs and outputs to wind energy system computational models. Historically, it has focused on systems engineering models, but it has been adopted in other topic areas of wind energy modeling, as well. The windIO data format is a community-focused effort to standardize the data format for wind energy system models."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "b5ebd4c0-e0bd-4953-ae8f-9cff2930e53b",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wfn_windIO = WindFarmNetwork.from_windIO(\n",
" filepath='data/IEA37_Borssele_Regular_System.yaml',\n",
" cables=cables,\n",
")\n",
"wfn_windIO"
]
},
{
"cell_type": "markdown",
"id": "eeaa1196-6c64-4f60-9010-72886cc15911",
"metadata": {},
"source": [
"## Provide an OptiWindNet YAML file"
]
},
{
"cell_type": "markdown",
"id": "64bdadd5-a4bd-4a03-9e7e-1718ed341724",
"metadata": {},
"source": [
"This option loads the location geometry from a `.yaml` file, which is useful for working with saved or external project files in this format. A sample code snippet for generating `.yaml` files with the proper structure is provided below."
]
},
{
"cell_type": "markdown",
"id": "57d65ab1",
"metadata": {},
"source": [
"Several `.yaml` examples can be found in the folder `optiwindnet/data`. Look for them in Python's `site-packages` or in [OptiWindNet's repository](https://gitlab.windenergy.dtu.dk/TOPFARM/OptiWindNet/-/tree/main/optiwindnet/data)."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "501eb6be-c087-46c2-85cd-11b5de328c57",
"metadata": {},
"outputs": [],
"source": [
"with open('data/example_location.yaml', 'w') as yaml_file:\n",
" yaml_file.write('''\n",
"# coordinate format can be \"planar\" or \"latlon\"\n",
"# - for \"latlon\" examples, see `optiwindnet/data/*.yaml`\n",
"# - this field is optional, default is \"latlon\"\n",
"# - coordinates are converted to floats, so floats may be used as well\n",
"COORDINATE_FORMAT: planar\n",
"\n",
"# extents define a polygon:\n",
"# - do not repeat the initial vertex at the end\n",
"# - line breaks are optional\n",
"EXTENTS: [\n",
" [1951, 200],\n",
" [1951, 1383],\n",
" [386, 1383],\n",
" [650, 708],\n",
" [624, 678],\n",
" [4, 1036],\n",
" [4, 3],\n",
" [1152, 3],\n",
" [917, 819],\n",
" [957, 854]\n",
"]\n",
"\n",
"# obstacles is optional and must be a list of polygons (even if 1 obstacle)\n",
"OBSTACLES: [\n",
" [ # first obstacle\n",
" [1540, 920],\n",
" [1600, 940],\n",
" [1600, 1150],\n",
" [1400, 1200],\n",
" ],\n",
" # [second obstacle]\n",
"]\n",
"\n",
"SUBSTATIONS: [\n",
" [696, 1063],\n",
"]\n",
"\n",
"TURBINES: [\n",
" [1940, 279],\n",
" [1920, 703],\n",
" [1475, 696],\n",
" [1839, 1250],\n",
" [1277, 1296],\n",
" [442, 1359],\n",
" [737, 435],\n",
" [1060, 26],\n",
" [522, 176],\n",
" [87, 35],\n",
" [184, 417],\n",
" [71, 878],\n",
"]\n",
"''')"
]
},
{
"cell_type": "markdown",
"id": "d4f1fcec",
"metadata": {},
"source": [
"Initialize `WindFarmNetwork()` instance with an existing `.yaml` file:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "a42be570-4222-4faf-a247-60611d55a09a",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wfn_yaml = WindFarmNetwork.from_yaml(\n",
" filepath='data/example_location.yaml',\n",
" cables=cables,\n",
")\n",
"wfn_yaml"
]
},
{
"cell_type": "markdown",
"id": "4127cd2b-3272-41a2-b9f4-4acb2e7f9a67",
"metadata": {},
"source": [
"## Provide an OSM.PBF file"
]
},
{
"cell_type": "markdown",
"id": "c468e88c",
"metadata": {},
"source": [
"> `osm.pbf` stands for *OpenStreetMap Protocolbuffer Binary Format (PBF)*."
]
},
{
"cell_type": "markdown",
"id": "aa8ed17c",
"metadata": {},
"source": [
"This option loads the location geometry from a `.osm.pbf` file, which is useful for working with saved or external project files in this format."
]
},
{
"cell_type": "markdown",
"id": "c89b2571-8fd2-4d4a-9147-798d4937f6bf",
"metadata": {},
"source": [
"Several `.osm.pbf` examples can be found in the folder `optiwindnet/data`. Look for them in Python's `site-packages` or in [OptiWindNet's repository](https://gitlab.windenergy.dtu.dk/TOPFARM/OptiWindNet/-/tree/main/optiwindnet/data)."
]
},
{
"cell_type": "markdown",
"id": "f22ca611-8370-4504-bc0b-f24df9454269",
"metadata": {},
"source": [
">The JOSM open-source map editor is recommended if using this format: . In addition, the JOSM plugin **pbf** is required to save in the `.osm.pbf` format. The plugin **opendata** is useful for importing many common GIS file formats.\n",
">\n",
">The OpenStreetMap objects used for representing a wind farm location geometry are:\n",
">- *nodes*\n",
">- *ways*\n",
">- *multipolygons* (relation between closed ways)\n",
">\n",
">Wind turbines are represented by *nodes* with the tag `power=generator`. Substations are represented either by *nodes* or by closed *ways* tagged `power=substation` or `power=transformer`. Substations based on *ways* will be reduced to the point at the centroid of the polygon defined by the *way*.\n",
">\n",
">The border of the wind farm can be a closed *way* tagged `power=plant`. If obstacles are required, then the closed *way* for the border must be combined with the closed *ways* for the obstacles in a *multipolygon* with the tag `power=plant` (in which case the *ways* themselves should not be tagged).\n",
">\n",
">See `optiwindnet/data/*.osm.pbf` for more examples."
]
},
{
"cell_type": "markdown",
"id": "1cb621d8",
"metadata": {},
"source": [
"Initialize `WindFarmNetwork()` instance with an existing `.osm.pbf` file:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "0baae019-4743-40cd-b7d9-bfbd49dc3137",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wfn_pbf = WindFarmNetwork.from_pbf(\n",
" filepath='data/example_location.osm.pbf',\n",
" cables=cables,\n",
")\n",
"wfn_pbf"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}