Open and run in Colab (interactive) Edit on Gitlab Open and run in Kaggle (interactive) Launch with Binder

Advanced HPP Model

Evaluating the performance of a hybrid power plant using HyDesign

HyDesign is an open-source tool for design and optimization of utility scale wind-solar-storage based hybrid power plants.

In this notebook we will evaluate a hybrid power plant design in a specific location.

A hybrid power plant design consists on selecting the following parameters:

Wind Turbine design:

  1. Clearance [m] (clearance): Height from the ground to rotor tip at lowest posstion. This parameter controls the wind turbine hub height given a rotor radius: clearance =  HH - R.

  2. Specific power of the wind turbine [MW/m2] (sp): Defined as sp = p_rated / ( pi * R^2 ), it controls the turbine rotor size for a given rated power. Turbines with lower specific power produce more power at lower wind speeds, but are more expensive.

  3. Rated power of the wind turbine [MW] (p_rated)

Wind Plant design:

  1. Number of wind turbines in the wind plant [-] (Nwt)

  2. Wind power installation density [MW/km2] (wind_MW_per_km2): This parameter controls how closely spaced are the turbines, which in turns affect how much wake losses are present.

PV Plant design:

  1. Solar plant power capacity [MW] (solar_MW)

  2. Surface tilt [deg] (surface_tilt)

  3. Surface azimuth [deg] (surface_azimuth)

  4. DC-AC ratio [-] (solar_DCAC): This parameter controls how much over-planting of PV (in DC power) is connected to the inverters. It is common practice in PV design to have solar_DCAC = 1.5.

Battery Storage design:

  1. Battery power [MW] (b_P)

  2. Battery energy capacity in hours [MWh] (b_E_h): Battery storage capacity in hours of full battery power (b_E = b_E_h * b_P).

  3. Cost of battery power fluctuations in peak price ratio [-] (cost_of_batt_degr): This parameter controls how much penalty is given to do ramps in battery power in the HPP operation.

Imports

Install hydesign if needed. Import basic libraries. Import HPP model assembly class. Import the examples file path.

[ ]:
# Install hydesign if needed
import importlib
if not importlib.util.find_spec("hydesign"):
    !pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/hydesign.git
[ ]:
import os
import time
import yaml
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from hydesign.assembly.hpp_assembly import hpp_model
from hydesign.examples import examples_filepath

Specifying the site

Hydesign, provides example data from several sites in India and Europe.

The site coordinates (longitude, latitude, and altitude) are given in examples_sites.csv.

[ ]:
examples_sites = pd.read_csv(f'{examples_filepath}examples_sites.csv', index_col=0, sep=';')
examples_sites
[ ]:
name = 'Denmark_good_wind'
ex_site = examples_sites.loc[examples_sites.name == name]

longitude = ex_site['longitude'].values[0]
latitude = ex_site['latitude'].values[0]
altitude = ex_site['altitude'].values[0]

input_ts_fn = examples_filepath+ex_site['input_ts_fn'].values[0]
sim_pars_fn = examples_filepath+ex_site['sim_pars_fn'].values[0]

Initializing the HPP model

Initialize the HPP model (hpp_model class) with the coordinates and the necessary input files.

[ ]:
hpp = hpp_model(
        latitude=latitude,
        longitude=longitude,
        altitude=altitude,
        num_batteries = 5,
        work_dir = './',
        sim_pars_fn = sim_pars_fn,
        input_ts_fn = input_ts_fn,
)

Evaluating the HPP model

[ ]:
start = time.time()

clearance = 10
sp = 350
p_rated = 5
Nwt = 70
wind_MW_per_km2 = 7
solar_MW = 100
surface_tilt = 50
surface_azimuth = 180
solar_DCAC = 1.5
b_P = 50
b_E_h  = 3
cost_of_batt_degr = 10

x = [clearance, sp, p_rated, Nwt, wind_MW_per_km2, \
solar_MW, surface_tilt, surface_azimuth, solar_DCAC, \
b_P, b_E_h , cost_of_batt_degr]

outs = hpp.evaluate(*x)

hpp.print_design()

end = time.time()
print(f'exec. time [min]:', (end - start)/60 )
[ ]:
b_E_SOC_t = hpp.prob.get_val('ems.b_E_SOC_t')
b_t = hpp.prob.get_val('ems.b_t')
price_t = hpp.prob.get_val('ems.price_t')

wind_t = hpp.prob.get_val('ems.wind_t')
solar_t = hpp.prob.get_val('ems.solar_t')
hpp_t = hpp.prob.get_val('ems.hpp_t')
hpp_curt_t = hpp.prob.get_val('ems.hpp_curt_t')
grid_MW = hpp.prob.get_val('ems.G_MW')

n_days_plot = 14
plt.figure(figsize=[12,4])
plt.plot(price_t[:24*n_days_plot], label='price')
plt.plot(b_E_SOC_t[:24*n_days_plot], label='SoC [MWh]')
plt.plot(b_t[:24*n_days_plot], label='Battery P [MW]')
plt.xlabel('time [hours]')
plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15),
           ncol=3, fancybox=0, shadow=0)

plt.figure(figsize=[12,4])
plt.plot(wind_t[:24*n_days_plot], label='wind')
plt.plot(solar_t[:24*n_days_plot], label='PV')
plt.plot(hpp_t[:24*n_days_plot], label='HPP')
plt.plot(hpp_curt_t[:24*n_days_plot], label='HPP curtailed')
plt.axhline(grid_MW, label='Grid MW', color='k')
plt.xlabel('time [hours]')
plt.ylabel('Power [MW]')
plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15),
           ncol=5, fancybox=0, shadow=0)
[ ]:
results_1year = {'Electricity Price':price_t[:8760], 'Wind Power': wind_t[:8760],'Solar Power': solar_t[:8760],'HPP Power': hpp_t[:8760],'Curtailed Power': hpp_curt_t[:8760] ,'Battery SOC': b_E_SOC_t[:8760],'Battery Power': b_t[:8760]}
df = pd.DataFrame(results_1year)
df.to_csv('EMS_out.csv')
[ ]:
design_df = hpp.evaluation_in_df()
design_df.to_csv('output.csv')