.. _wind_climates: ============= Wind Climates ============= In PyWAsP's :ref:`Terminology ` and :ref:`Data Structures ` sections we outlined how we define the meaning and data structures of different kinds of wind climate objects. Here we present how common wind climate workflows can be carried out. PyWAsP relies heavily on :doc:`WindKit ` for a lot of this functionality, so to illustrate it let's start by importing ``windkit``, ``pywasp`` and ``xarray``. .. ipython:: python import pywasp as pw import windkit as wk import xarray as xr Wind climate I/O ---------------- Reading and writing wind climates is a core part of :doc:`WindKit ` .. list-table:: Wind climate I/O :widths: 20, 40, 20, 20 :align: center :header-rows: 1 * - Format - Wind Climate - Read - Write * - ``.nc`` - BWC, GWC, WWC - yes - yes * - ``.tab`` - BWC - yes - yes * - ``.owc`` - BWC - yes - no * - ``.omwc`` - BWC - yes - no * - ``.lib`` - GWC - yes - yes * - ``.gwc`` - GWC - yes - no * - ``.rsf`` - WWC - yes - yes * - ``.wrg`` - WWC - yes - yes * - ``.grd`` - WWC - yes - no * - ``.pwc`` - WWC - yes - no All supported BWC's and GWC's can be read using :py:func:`windkit.read_bwc` and :py:func:`windkit.read_gwc`, respectively. For WWC's, file-specific readers are available: - ``.rsf``: :py:func:`windkit.read_rsffile` - ``.wrg``: :py:func:`windkit.read_wrgfile` - ``.grd``: :py:func:`windkit.read_grdfile` - ``.pwc``: :py:func:`windkit.read_pwcfile` For writing wind climate files, `windkit` have the function :py:func:`windkit.bwc_to_tabfile` for writing BWC's to the ``.tab`` format, :py:func:`windkit.to_libfile` for writing GWC's to ``.lib`` files, and :py:func:`windkit.to_rsffile` and :py:func:`windkit.to_wrgfile` for writing WWC's to ``.rsf`` and ``.wrg``. To explify, lets start by reading in a BWC stored in the ``.omwc`` file format: .. ipython:: python :okwarning: bwc = wk.read_bwc("source/tutorials/data/SerraSantaLuzia.omwc", crs="EPSG:4326") print(bwc) In this case, the ``.owmc`` file only contains coordinates, but not the coordinate reference system (CRS), so we have to set that explicitly with the ``crs="ESPG:4326"`` argument. As :ref:`Discussed ` BWC's are :py:class:`xarray.Dataset`'s' so it is easy to use the all the built-in methods of `xarray` to interact with the data through the labeled dimensions and coordinates. For example, we can plot the omni-directional wind speed frequencies by multiplying the wind speed frequencies, that are stored as sector-relative frequencies, with the wind direction frequencies, summing the sectors, and then plotting with the wind speed bins on the x-axis: .. ipython:: python :okwarning: @savefig bwc_histogram_example.png width=5in (bwc.wsfreq * bwc.wdfreq).sum(dim="sector").plot.line(x="wsbin") Geospatial transforms ------------------------ :py:mod:`WindKit's spatial module ` makes it easy to work with geospatial data, like the ``point`` associated with the BWC above, and to perform typical transforms, such as reprojection, spatial clipping, and spatial masking. To illustrate this, let's transform the BWC from lat-long coordinates to UTM 29N coordinates: .. ipython:: python :okwarning: bwc = wk.spatial.reproject(bwc, to_crs="EPSG:32629") print(bwc) .. note:: Note that the ``west_east`` and ``south_north`` coordinate values have changed after reprojection. To set and get the ``crs`` of an object, use `windkit.spatial.add_crs` and `windkit.spatial.get_crs`. Calculate statistics -------------------- WindKit includes functions to calculate common statistics from wind climate objects, such as the mean wind speed or mean power density: .. ipython:: python :okwarning: mean_ws = wk.mean_windspeed(bwc) print(mean_ws) .. note:: The omni-directional statistics are returned by default. To return statistics by wind direction sector, use the argument ``bysector=True`` Fit weibull distribution ------------------------ WindKit can fit weibull parameters to the wind speed frequencies in a binned wind climate, thereby transforming it to a weibull wind climate. This can be done using :func:`windkit.weibull_fit`: .. ipython:: python :okwarning: wwc = wk.weibull_fit(bwc) print(wwc) We can check that the estimated mean wind speed of the WWC is close to the BWC above: .. ipython:: python :okwarning: mean_ws_wwc = wk.mean_windspeed(wwc) print(mean_ws_wwc) We see that the mean wind speed of the BWC and WWC differ by about 0.7% (6.29 vs 6.24 m/s). The weibull fit in WindKit (and in WAsP) uses the third moment of wind speed to fit Weibull parameters, thus preserving the mean power density well, but not the mean wind speed. We can check this by calculating and comparing the mean power densities pf the BWC and WWC. .. ipython:: python diff_prc = 100.0 * (1.0 - wk.power_density(wwc) / wk.power_density(bwc)) print(diff_prc) We see that the difference in mean power density between the two is just 0.04%. Using wind climates as site objects in PyWake --------------------------------------------- PyWAsP wind climates objects can be used as site objects for wind farm flow modeling in :doc:`PyWake `. This is done by instanciating an ``XRSite`` using the :py:meth:`py_wake.Site.XRSsite.from_pwc` method. .. ipython:: python :okwarning: import py_wake site = py_wake.site.XRSite.from_pwc(wwc) print(site.ds) Spatial inhomogeneity can be taken into account in PyWake by ``speedup`` and ``turning`` variables in the site object. These variables track the relative speed-up and turning of the wind in the spatial domain during the wind farm flow modeling. The :py:meth:`py_wake.Site.XRSsite.from_pwc` method can take different ``speedup`` arguments for specifying the way to calculate speed-ups between spatial points. By default, the "park" method is used, which calculates the sector-wise speed-ups relative to the maximum mean wind speed in that sector. Depending on how the speed-up is defined/calculated in the PyWake site object, the post-processing, or aggregation, of wind farm flow results should take this into account.