{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Multi-height wind data" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "In this example we explore the calculation of multi-height wind data, as for example obtained from WRF results or downloaded from the [NEWA website](https://map.neweuropeanwindatlas.eu/) at a single point.\n", "\n", "Here we will use the static data file `WRF-Timeseries-4464.csv.gz` that is part of the `foxes` static data. It has the following data structure:\n", "\n", "```\n", "Time,WS-50,WS-75,...,WS-500,WD-50,WD-75,...,WD-500,TKE-50,TKE-75,...,TKE-500,RHO\n", "2009-01-01 00:00:00,7.37214,7.42685,...,1.28838\n", "...\n", "2009-01-31 23:50:00,10.27767,10.36368,...,1.30095\n", "```\n", "\n", "The time stamp column marks one month in 10 minute steps, and the wind speed (WS), wind direction (WD) and turbulent kinetic energy (TKE) are provided at 8 heights between 50 and 500 m. The air density (RHO) does not have height dependency but varies with time.\n", "\n", "The basic assumption of this example is that we can calculate our wind farm results based on this data, i.e., that the horizontal variation can be neglected (for completely heterogeneous inflow data, see the corresponding example)." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "These are the imports for this example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "\n", "import foxes\n", "import foxes.variables as FV\n", "import foxes.constants as FC" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "First, we setup the model book and the wind farm. We choose 5 turbines in a row:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "# Create model book:\n", "mbook = foxes.ModelBook()\n", "\n", "# create wind farm, a single row of turbines:\n", "farm = foxes.WindFarm()\n", "foxes.input.farm_layout.add_row(\n", " farm=farm,\n", " xy_base=[0.0, 0.0],\n", " xy_step=[600.0, 0.0],\n", " n_turbines=5,\n", " turbine_models=[\"NREL5MW\"],\n", " H=200.,\n", " verbosity=0,\n", ")\n", "\n", "ax = foxes.output.FarmLayoutOutput(farm).get_figure(figsize=(5,3))\n", "plt.show()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Note that we manually change the hub height from 90 m to 200 m here. Next, we create the states based on the static data file `WRF-Timeseries-4464.csv.gz`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "states = foxes.input.states.MultiHeightTimeseries(\n", " data_source=\"WRF-Timeseries-4464.csv.gz\",\n", " output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],\n", " var2col={},\n", " heights=[50, 75, 90, 100, 150, 200, 250, 500],\n", " fixed_vars={FV.TI: 0.05},\n", ")\n", "\n", "o = foxes.output.StatesRosePlotOutput(states, point=[0., 0., 100.])\n", "fig = o.get_figure(16, FV.AMB_WS, [0, 3.5, 6, 10, 15, 20], figsize=(6, 6))\n", "plt.show()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Our file has already the default column names as expected by `foxes`. However, otherwise you can use the `var2col` option as a mapping from the expected to the actual column names, if needed. Note that the `heights` are searched for all output variables that are neither mentioned in `fixed_vars` not appear as height independent column names (e.g. `RHO` instead of `RHO-50`, etc.).\n", "\n", "Let's next setup our algorithm:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "algo = foxes.algorithms.Downwind(\n", " mbook,\n", " farm,\n", " states=states,\n", " rotor_model=\"grid9\",\n", " wake_models=[\"Bastankhah2014_linear_k002\"],\n", " wake_frame=\"rotor_wd\",\n", " partial_wakes_model=\"auto\",\n", " chunks={FC.STATE: 1000},\n", " verbosity=0,\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Our next goal is the visualization of the vertical wind profile. For that we select a certain time step where the wind direction is approximately from the west. We can do this by initializing the states using the `states_loc` option:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "states.reset(states_loc=[\"2009-01-06 13:50:00\"])" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "We now calculate this single state and create the vertical flow figure:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "farm_results = algo.calc_farm()\n", "\n", "o = foxes.output.FlowPlots2D(algo, farm_results)\n", "g = o.gen_states_fig_xz(FV.AMB_WS, resolution=10, x_direction=270,\n", " xmin=0., xmax=1000., zmin=50., zmax=500., figsize=(8,6))\n", "fig = next(g)\n", "plt.show()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "For the full calculation of all 4464 states, we now undo our earlier states selection:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "states.reset(states_loc=None)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "We can now calculate the full states results:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "farm_results = algo.calc_farm()\n", "\n", "fr = farm_results.to_dataframe()\n", "print(fr[[FV.WD, FV.REWS, FV.P]])\n", "\n", "o = foxes.output.FarmLayoutOutput(farm, farm_results)\n", "o.get_figure(color_by=\"mean_REWS\", title=\"Mean REWS [m/s]\", s=150, annotate=0)\n", "plt.show()\n", "\n", "o = foxes.output.FarmResultsEval(farm_results)\n", "P0 = o.calc_mean_farm_power(ambient=True)\n", "P = o.calc_mean_farm_power()\n", "print(f\"\\nFarm power : {P/1000:.1f} MW\")\n", "print(f\"Farm ambient power: {P0/1000:.1f} MW\")\n", "print(f\"Farm efficiency : {o.calc_farm_efficiency()*100:.2f} %\")\n", "print(f\"Annual farm yield : {o.calc_farm_yield(algo=algo):.2f} GWh\")" ] } ], "metadata": { "kernelspec": { "display_name": "foxes", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "vscode": { "interpreter": { "hash": "4fb778166dae186e4d4cfa777e9f30c32eb0bc447af40b9aef55a0c1baf561be" } } }, "nbformat": 4, "nbformat_minor": 2 }