├── Netload.xlsx ├── NetloadForecast.xlsx ├── NetloadnForecast.m ├── ParamStudy_storage_cutoff_reliability.m ├── ParamStudy_storage_vs_cutoff.m ├── README.md ├── SampleFilterPlot.m ├── SamplePreqPlot.m ├── ThermalGenPlot.m ├── ThermalGeneration.xlsx ├── WindGeneration.xlsx ├── load_data.m └── saveTightFigure.m /Netload.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saivemu/DiCELab_16_storage_required/8c9e1d413aa53e42bb6d9761ba91f516504e5491/Netload.xlsx -------------------------------------------------------------------------------- /NetloadForecast.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saivemu/DiCELab_16_storage_required/8c9e1d413aa53e42bb6d9761ba91f516504e5491/NetloadForecast.xlsx -------------------------------------------------------------------------------- /NetloadnForecast.m: -------------------------------------------------------------------------------- 1 | %% Net load and Netload Forecast comparision plot from the available data 2 | 3 | %% Clearing all the previous variables and data 4 | clear all 5 | clc 6 | show_plots = 1; 7 | printfigs = 1; 8 | %% Function to load the demand data to the program 9 | if isunix 10 | Netload_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/Netload.xlsx','2015'); 11 | Netload_Cast_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/NetloadForecast.xlsx','2015'); 12 | end 13 | 14 | if ispc 15 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 16 | Netload_Cast_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/NetloadForecast.xlsx','2015'); 17 | end 18 | %% Filter 19 | Ts_min = 5; % Sampling time in minutes 20 | Ts = Ts_min*60 ;% Sampling time in seconds 21 | T = 24 ; % Time span for which data is being collected in hours 22 | Tfinal = T*3600 - 300; % Final time for data sampling 23 | t = [0:Ts:Tfinal] ; % Data being collected at an interval of dt min or Ts 24 | ws = (2*pi)/(Ts); % Sampling Frequency in rad/s 25 | w_nyq = ws/2; % Nyquist Frequency in rad/s 26 | min2rad = 2*pi()/60 ; % Converting minutes to 27 | w2wnorm = (w_nyq)^-1; 28 | 29 | % Low Pass filter 30 | Tlow = 300; % Cut off Frequency in minutes 31 | wlow1_min = min2rad*(Tlow^-1); % Cut off frequency for Low pass butterworth filter 32 | w_norm_low1 = wlow1_min*w2wnorm; % Normalized cut off frequency 33 | [b1,a1] = butter(2,w_norm_low1,'low'); 34 | %% Netload and Netload Forecast signals 35 | 36 | n = 200; % Day 'n' of a year 37 | 38 | Netload_today = timeseries(Netload_365([((n-1)*288)+1:n*288],1), [0:300:86100]); % Time series data for the net load on a particular day 39 | Netload = Netload_today.data; 40 | Netload(isnan(Netload))= nanmean(Netload); 41 | Netload_Cast_today = timeseries(Netload_Cast_365([((n-1)*288)+1:n*288],1), [0:300:86100]); 42 | NetloadForecast = Netload_Cast_today.Data; 43 | NetloadForecast(NetloadForecast==0) = mean(NetloadForecast); 44 | 45 | % Non causal / Zero Phase filter 46 | lowpass_signal = filtfilt(b1,a1,Netload); % Calculating the rating for the battery required based on Netload - Lowpass Signal 47 | lowpass_Forecast = filtfilt(b1,a1,NetloadForecast); 48 | 49 | if showplots 50 | plot(Netload,'linewidth',2); 51 | hold on 52 | plot(NetloadForecast,'r','linewidth',2); 53 | set(gca,'fontsize',14) 54 | xlabel('K') 55 | ylabel('Netload(MW)') 56 | legend('Netload','Netload Forecast') 57 | end 58 | 59 | if printfigs 60 | if isunix 61 | saveTightFigure(gcf,'~/Dropbox/Sai - Research Work/Report/OperatorNetloadnForecast.pdf') 62 | %print(gcf,'-dpdf','~/Dropbox/Sai - Research Work/Report/OperatorPOVSignal.pdf') 63 | end 64 | if ispc 65 | saveTightFigure(gcf,'C:\Users\Sai\Dropbox\Sai - Research Work/Report/OperatorNetloadnForecast.pdf') 66 | %print(gcf,'-dpdf','~/Dropbox/Sai - Research Work/Report/OperatorPOVSignal.pdf') 67 | end 68 | end -------------------------------------------------------------------------------- /ParamStudy_storage_cutoff_reliability.m: -------------------------------------------------------------------------------- 1 | %% Clearing all the previous variables and data 2 | clear all 3 | clc 4 | show_plots = 1; 5 | printfigs = 1; 6 | %% Function to load the demand data to the program 7 | if isunix 8 | Netload_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/Netload.xlsx','2015'); 9 | end 10 | 11 | if ispc 12 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 13 | end 14 | %% Filter Parameters 15 | 16 | Ts_min = 5; % Sampling time in minutes 17 | Ts = Ts_min*60 ;% Sampling time in seconds 18 | T = 24 ; % Time span for which data is being collected in hours 19 | Tfinal = T*3600 - 300; % Final time for data sampling 20 | t = [0:Ts:Tfinal] ; % Data being collected at an interval of dt min or Ts 21 | ws = (2*pi)/(Ts); % Sampling Frequency in rad/s 22 | w_nyq = ws/2; % Nyquist Frequency in rad/s 23 | min2rad = 2*pi()/60 ; % Converting minutes to rad/s 24 | w2wnorm = (w_nyq)^-1; 25 | 26 | %% Parametric Study 27 | % Low Pass filter 28 | Tlow2 = 180; 29 | Tlow1 = 450; 30 | wlow1 = min2rad*(Tlow1^-1); 31 | wlow2 = min2rad*(Tlow2^-1); 32 | Pbatt = zeros(27,1); 33 | Pbattery = zeros(365,1); 34 | Ebattery = zeros(365,1); 35 | 36 | for Tlow = Tlow2:10:Tlow1 % Cut off Frequency in minutes 37 | 38 | wlow1_min = min2rad*(Tlow^-1); % Cut off frequency for Low pass butterworth filter 39 | w_norm_low1 = wlow1_min*w2wnorm; % Normalized cut off frequency 40 | [b1,a1] = butter(2,w_norm_low1,'low'); 41 | 42 | % For loop to calculate storage requirements for each day in a year 43 | 44 | for n = 1:1:365 45 | 46 | Netload_today = timeseries(Netload_365([((n-1)*288)+1:n*288],1), [0:300:86100]); % Time series data for the net load on a particular day 47 | Netload = Netload_today.data; 48 | Netload(isnan(Netload))= nanmean(Netload); 49 | 50 | % Non causal / Zero Phase filter 51 | lowpass_signal = filtfilt(b1,a1,Netload); 52 | 53 | StorageSignal = Netload-lowpass_signal; % Calculating the storage required based on Netload - Lowpass Signal 54 | 55 | z = gt(max(abs(StorageSignal)),1000) ; 56 | 57 | if z == 1 58 | 59 | Pbattery(n,1) = NaN; 60 | 61 | else 62 | 63 | Pbattery(n,1) = max(abs(StorageSignal)); 64 | 65 | end 66 | 67 | if max(abs(cumtrapz(t,StorageSignal)))/3600 == 0 68 | Ebattery(n,1) = NaN; 69 | else 70 | Ebattery(n,1) = max(abs(cumtrapz(t,StorageSignal)))/3600; % Area under curve 71 | end 72 | 73 | end 74 | 75 | k = ((Tlow-Tlow2)/10)+1; 76 | 77 | % Kernel Density Estimation for Battery Power Capacity (MW) 78 | row = 1; 79 | for rel_req = 0.90:0.01:0.99 % required reliability 80 | pts = (min(Pbattery(:,1)):0.1:max(Pbattery(:,1))); 81 | [f_Pstorage,xPbatt,~] = ksdensity(Pbattery(:,1),pts,'support','positive',... 82 | 'function','cdf'); % Kernel Density Estimation of Power Capacity of Battery Storage 83 | Pbatt(k,row) = interp1(f_Pstorage,xPbatt,rel_req); % Power Capacity of Battery Storage to be installed for required reliability 84 | 85 | pts = (min(Ebattery(:,1)):0.1:max(Ebattery(:,1))); 86 | [f_Estorage,xEbatt,~] = ksdensity(Ebattery(:,1),pts,'support','positive',... 87 | 'function','cdf'); % Kernel Density Estimation of Power Capacity of Battery Storage 88 | Ebatt(k,row) = interp1(f_Estorage,xEbatt,rel_req); % Power Capacity of Battery Storage to be installed for required reliability 89 | if isnan(Ebatt(k,row)) 90 | Ebatt(k,row) = Ebatt(k-1,row)+(Ebatt(k-1,row)-Ebatt(k-2,row)); 91 | end 92 | row = row +1; 93 | end 94 | end 95 | 96 | Pbatt = flipud(Pbatt); 97 | Ebatt = flipud(Ebatt); 98 | surfaxis = [wlow1:(wlow2-wlow1)/27:wlow2]; 99 | relreq = 0.90:0.01:0.99; 100 | 101 | % Pbatt surface plot 102 | figure('Name','Pbatt Surf') 103 | surf(relreq',surfaxis',Pbatt) 104 | xlabel('Reliability') 105 | ylabel('Frequency (1/hrs)') 106 | zlabel('Pbatt(MW)') 107 | 108 | % Ebatt surface plot 109 | figure('Name','Ebatt Surf') 110 | surf(relreq',surfaxis',Ebatt) 111 | xlabel('Reliability') 112 | ylabel('Frequency (1/hrs)') 113 | zlabel('Ebatt(MW)') 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /ParamStudy_storage_vs_cutoff.m: -------------------------------------------------------------------------------- 1 | %% Parametric Study of Storage vs Cut-off frequency vs Reliability 2 | 3 | %% Clearing all the previous variables and data 4 | clear all 5 | clc 6 | show_plots = 1; 7 | printfigs = 1; 8 | %% Function to load the demand data to the program 9 | if isunix 10 | Netload_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/Netload.xlsx','2015'); 11 | end 12 | 13 | if ispc 14 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 15 | end 16 | %% Filter Parameters 17 | 18 | Ts_min = 5; % Sampling time in minutes 19 | Ts = Ts_min*60 ;% Sampling time in seconds 20 | T = 24 ; % Time span for which data is being collected in hours 21 | Tfinal = T*3600 - 300; % Final time for data sampling 22 | t = [0:Ts:Tfinal] ; % Data being collected at an interval of dt min or Ts 23 | ws = (2*pi)/(Ts); % Sampling Frequency in rad/s 24 | w_nyq = ws/2; % Nyquist Frequency in rad/s 25 | min2rad = 2*pi()/60 ; % Converting minutes to rad/s 26 | w2wnorm = (w_nyq)^-1; 27 | 28 | %% Parametric Study - Storage vs Tlow (Wlow1_min) aka Cut-off frequency vs Reliability 29 | 30 | % Low Pass filter 31 | Tlow2 = 180; 32 | Tlow1 = 450; 33 | %Tlow = 360; 34 | wlow1 = min2rad*(Tlow1^-1); 35 | wlow2 = min2rad*(Tlow2^-1); 36 | Pbatt = zeros(27,1); 37 | Pbattery = zeros(365,1); 38 | Ebattery = zeros(365,1); 39 | 40 | for Tlow = Tlow2:10:Tlow1 % Cut off Frequency in minutes 41 | 42 | wlow1_min = min2rad*(Tlow^-1); % Cut off frequency for Low pass butterworth filter 43 | w_norm_low1 = wlow1_min*w2wnorm; % Normalized cut off frequency 44 | [b1,a1] = butter(2,w_norm_low1,'low'); % butterworth filter 45 | 46 | % For loop to calculate storage requirements for each day in a year 47 | 48 | for n = 1:1:365 49 | 50 | Netload_today = timeseries(Netload_365([((n-1)*288)+1:n*288],1), [0:300:86100]); % Time series data for the net load on a particular day 51 | Netload = Netload_today.data; 52 | Netload(isnan(Netload))= nanmean(Netload); % replace blank/missing data from excel sheet with mean of the data 53 | 54 | % Non causal / Zero Phase filter 55 | lowpass_signal = filtfilt(b1,a1,Netload); % Calculating the rating for the battery required based on Netload - Lowpass Signal 56 | 57 | StorageSignal = Netload-lowpass_signal; 58 | 59 | z = gt(max(abs(StorageSignal)),1000) ; % To remove the anamolies/outliers 60 | 61 | if z == 1 62 | 63 | Pbattery(n,1) = NaN; 64 | 65 | else 66 | 67 | Pbattery(n,1) = max(abs(StorageSignal)); % Maximum storage required in a day 68 | 69 | end 70 | 71 | if max(abs(cumtrapz(t,StorageSignal)))/4000 == 0 72 | Ebattery(n,1) = NaN; 73 | else 74 | Ebattery(n,1) = max(abs(cumtrapz(t,StorageSignal)))/3600; 75 | end 76 | 77 | end 78 | 79 | k = ((Tlow-Tlow2)/10)+1; 80 | % k = ((wlow-wlow1)*(10^5))+1; 81 | 82 | % Kernel Density Estimation for Power Capacity (MW) 83 | row = 1; 84 | for rel_req = 0.90:0.01:0.99 % required reliability 85 | pts = (min(Pbattery(:,1)):0.1:max(Pbattery(:,1))); 86 | [f_Pstorage,xPbatt,~] = ksdensity(Pbattery(:,1),pts,'support','positive',... 87 | 'function','cdf'); % Kernel Density Estimation of Power Capacity of Battery Storage 88 | Pbatt(k,row) = interp1(f_Pstorage,xPbatt,rel_req); % Power Capacity of Battery Storage to be installed for required reliability 89 | 90 | % Kernel Density Estimation for Energy Capacity (MW) 91 | pts = (min(Ebattery(:,1)):0.1:max(Ebattery(:,1))); 92 | [f_Estorage,xEbatt,~] = ksdensity(Ebattery(:,1),pts,'support','positive',... 93 | 'function','cdf'); % Kernel Density Estimation of Power Capacity of Battery Storage 94 | Ebatt(k,row) = interp1(f_Estorage,xEbatt,rel_req); % Power Capacity of Battery Storage to be installed for required reliability 95 | if isnan(Ebatt(k,row)) 96 | Ebatt(k,row) = Ebatt(k-1,row)+(Ebatt(k-1,row)-Ebatt(k-2,row)); 97 | end 98 | row = row +1; 99 | end 100 | end 101 | 102 | Pbatt = flipud(Pbatt); 103 | Ebatt = flipud(Ebatt); 104 | surfaxis = [wlow1:(wlow2-wlow1)/27:wlow2]; 105 | relreq = 0.90:0.01:0.99; 106 | 107 | % Power Storage vs Reliability vs Cut-off Frequency Surface plot 108 | figure('Name','Pbatt Surf') 109 | surf(relreq',surfaxis',Pbatt) 110 | xlabel('Reliability') 111 | ylabel('Frequency (rad/s)') 112 | zlabel('Pbatt(MW)') 113 | % Energy Storage vs Reliability vs Cut-off Frequency Surface plot 114 | figure('Name','Ebatt Surf') 115 | surf(relreq',surfaxis',Ebatt) 116 | xlabel('Reliability') 117 | ylabel('Frequency (rad/s)') 118 | zlabel('Ebatt(MW)') 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DiCELab_16_storage_required 2 | 3 | 4 | #Optimal storage sizing for grid level energy storage to tackle intermittent renewable energy sources 5 | 6 | 7 | This repository comprises of the code I wrote for my research project at Distributed Control of Energy Systems Lab, University of Florida, under the guidance of [Dr. Prabir Barooah](http://web.mae.ufl.edu/pbarooah/). 8 | 9 | 10 | ##Instructions 11 | 12 | In order for most of the MATLAB files in the repository to run they require a accompanying excel datasheet from which to extract the data and perform the analysis. 13 | 14 | Example: 15 | ``` 16 | if ispc 17 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 18 | end 19 | ``` 20 | For the code to work download the excel sheets and add the path of the excel file you want to work on along with the sheet name to the **load_data** function at the beginning of the code. 21 | 22 | Most of the code is self-explanatory and appropriately commented. Anyone who wants to continue the work on the project or analyse the work done should be able to get it up and running fairly quick. If you find something where a little more explanation is required, please let me know. 23 | 24 | The two functions **load_data** and **saveTightFigure** are must have for all other m files to run. Download these two before attempting to run any of the remaining m files. 25 | 26 | #load_data.m 27 | 28 | The function **load_data** reads the specified worksheet in the Microsoft® Excel® spreadsheet workbook and returns the numeric data in a matrix. 29 | 30 | #saveTightFigure 31 | 32 | The function **saveTightFigure** takes a figure and removes most of the blank white space MATLAB adds to the figure while saving it in pdf/jpg form. 33 | -------------------------------------------------------------------------------- /SampleFilterPlot.m: -------------------------------------------------------------------------------- 1 | %% Figure 1 - Net load and low pass signal plots 2 | 3 | %% Clearing all the previous variables and data 4 | clear all 5 | clc 6 | show_plots = 1; 7 | printfigs = 1; 8 | %% Function to load the demand data to the program 9 | if isunix 10 | Netload_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/Netload.xlsx','2015'); 11 | %Netload_Cast_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/NetloadForecast.xlsx','2015'); 12 | end 13 | 14 | if ispc 15 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 16 | % Netload_Cast_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/NetloadForecast.xlsx','2015'); 17 | end 18 | %% Filter 19 | Ts_min = 5; % Sampling time in minutes 20 | Ts = Ts_min*60 ;% Sampling time in seconds 21 | T = 24 ; % Time span for which data is being collected in hours 22 | Tfinal = T*3600 - 300; % Final time for data sampling 23 | t = [0:Ts:Tfinal] ; % Data being collected at an interval of dt min or Ts 24 | ws = (2*pi)/(Ts); % Sampling Frequency in rad/s 25 | w_nyq = ws/2; % Nyquist Frequency in rad/s 26 | min2rad = 2*pi()/60 ; % Converting minutes to 27 | w2wnorm = (w_nyq)^-1; 28 | 29 | % Low Pass filter 30 | Tlow = 360; % Cut off Frequency in minutes 31 | wlow1_min = min2rad*(Tlow^-1); % Cut off frequency for Low pass butterworth filter 32 | w_norm_low1 = wlow1_min*w2wnorm; % Normalized cut off frequency 33 | [b1,a1] = butter(2,w_norm_low1,'low'); 34 | 35 | %% For loop to calculate storage requirements for each day in a year 36 | 37 | for n = 1:1:365 38 | 39 | Netload_today = timeseries(Netload_365([((n-1)*288)+1:n*288],1), [0:300:86100]); % Time series data for the net load on a particular day 40 | 41 | % Non causal / Zero Phase filter 42 | lowpass_signal = filtfilt(b1,a1,Netload_today.Data); % Calculating the rating for the battery required based on Netload - Lowpass Signal 43 | 44 | end 45 | 46 | Storage_required = Netload-lowpass_signal; 47 | k = 1:1:288; 48 | t_plot = k/12; 49 | 50 | if show_plots 51 | plot(t_plot',Netload_today.Data,'b','LineWidth',2) 52 | hold on 53 | plot(t_plot',lowpass_signal,'r-','LineWidth',2) 54 | set(gca,'fontsize',14,'XTick',[0 6 12 18 24]); 55 | xlabel('Hours') 56 | ylabel('Power(MW)') 57 | I = legend('$L$','$\tilde{L}_{lp}$') 58 | set(I,'Interpreter','latex') 59 | end 60 | 61 | if printfigs 62 | if isunix 63 | saveTightFigure(gcf,'~/Dropbox/Sai - Research Work/Report/SampleFilterPlot.pdf') % Function to remove the white margins added by MATLAB to pdf plots 64 | %print(gcf,'-dpdf','~/Dropbox/Sai - Research Work/Report/SampleFilterRemPlot.jpg') 65 | end 66 | if ispc 67 | saveTightFigure(gcf,'C:\Users\Sai\Dropbox\Sai - Research Work/Report/SampleFilterPlot.pdf') 68 | %print(gcf,'C:\Users\Sai\Dropbox\Sai - Research Work/Report/SampleFilterRemPlot.jpeg') 69 | end 70 | end 71 | 72 | %% Code to Obtain a required storage plot 73 | % if show_plots 74 | % 75 | % figure('Name','Power Capacity') 76 | % plot(t_plot',Storage_required,'b') 77 | % hold on 78 | % set(gca,'fontsize',14) 79 | % set(gca,'XTick',[0 6 12 18 24]) % customize axes to hours 80 | % xlabel('Hours') 81 | % ylabel('$P^{(i)}_{k}\ (MW)$','Interpreter','latex') 82 | % 83 | % end -------------------------------------------------------------------------------- /SamplePreqPlot.m: -------------------------------------------------------------------------------- 1 | %% Figure 1 - Net load and low pass signal plots 2 | 3 | %% Clearing all the previous variables and data 4 | clear all 5 | clc 6 | show_plots = 1; 7 | printfigs = 1; 8 | 9 | %% Function to load the demand data 10 | if isunix 11 | Netload_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/Netload.xlsx','2015'); 12 | end 13 | 14 | if ispc 15 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 16 | end 17 | 18 | %% Filter Specifications 19 | Ts_min = 5; % Sampling time in minutes 20 | Ts = Ts_min*60 ;% Sampling time in seconds 21 | T = 24 ; % Time span for which data is being collected in hours 22 | Tfinal = T*3600 - 300; % Final time for data sampling 23 | t = [0:Ts:Tfinal] ; % Data being collected at an interval of dt min or Ts 24 | ws = (2*pi)/(Ts); % Sampling Frequency in rad/s 25 | w_nyq = ws/2; % Nyquist Frequency in rad/s 26 | min2rad = 2*pi()/60 ; % Converting minutes to 27 | w2wnorm = (w_nyq)^-1; 28 | 29 | % Low Pass filter 30 | Tlow = 360; % Cut off Frequency in minutes 31 | wlow1_min = min2rad*(Tlow^-1); % Cut off frequency for Low pass butterworth filter 32 | w_norm_low1 = wlow1_min*w2wnorm; % Normalized cut off frequency 33 | [b1,a1] = butter(2,w_norm_low1,'low'); 34 | 35 | % Low range bandpass filter 36 | 37 | Tbpl1 = 120; % higher limit for low band pass 38 | Tbpl2 = 360; % Lower limit for low band pass 39 | 40 | wbpl1 = min2rad*(Tbpl1^-1); 41 | wbpl2 = min2rad*(Tbpl2^-1); 42 | 43 | w_norm_bpl1 = w2wnorm*wbpl1; 44 | w_norm_bpl2 = w2wnorm*wbpl2; 45 | w_bpl = [w_norm_bpl2,w_norm_bpl1]; 46 | [b2,a2] = butter(2,w_bpl,'bandpass'); 47 | 48 | % High range bandpass filter 49 | 50 | Tbph1 = 20; % higher limit 51 | Tbph2 = 120; % Lower limit 52 | 53 | wbph1 = min2rad*(Tbph1^-1); 54 | wbph2 = min2rad*(Tbph2^-1); 55 | 56 | w_norm_bph1 = w2wnorm*wbph1; 57 | w_norm_bph2 = w2wnorm*wbph2; 58 | w_bph = [w_norm_bph2,w_norm_bph1]; 59 | [b3,a3] = butter(2,w_bph,'bandpass'); 60 | 61 | 62 | 63 | %% For loop to calculate storage requirements for each day in a year 64 | 65 | for n = 1:1:365 66 | 67 | Netload_today = timeseries(Netload_365([((n-1)*288)+1:n*288],1), [0:300:86100]); % Time series data for the net load on a particular day 68 | Netload = Netload_today.data; 69 | Netload(isnan(Netload))= nanmean(Netload); 70 | 71 | % Non causal / Zero Phase filter 72 | lowpass_signal = filtfilt(b1,a1,Netload); % Calculating the rating for the battery required based on Netload - Lowpass Signal 73 | 74 | end 75 | 76 | Storage_required = Netload-lowpass_signal; 77 | k = 1:1:288; 78 | t_plot = k/12; 79 | 80 | if show_plots 81 | 82 | figure('Name','Power Capacity') 83 | plot(t_plot',Storage_required,'b') 84 | hold on 85 | refline(0,max(abs(Storage_required))); 86 | set(gca,'fontsize',14) 87 | set(gca,'XTick',[0 6 12 18 24]) % Trying to customize axes to hours 88 | xlabel('Hours') 89 | ylabel('$P^{(i)}_{k}\ (MW)$','Interpreter','latex') 90 | 91 | end 92 | 93 | if printfigs 94 | if isunix 95 | saveTightFigure(gcf,'~/Dropbox/Sai - Research Work/Report/SamplePreqPlot.pdf') % Function to remove the white margins added by MATLAB to pdf plots 96 | end 97 | if ispc 98 | print(gcf,'C:\Users\Sai\Dropbox\Sai - Research Work/Report/SamplePreqPlot.jpg') 99 | %saveTightFigure('Power Capacity','C:\Users\Sai\Dropbox\Sai - Research Work/Report/SamplePreqPlot.pdf') % Function to remove the white margins added by MATLAB to pdf plots 100 | end 101 | end 102 | 103 | if show_plots 104 | figure('Name','Energy Storage') 105 | plot(t_plot',cumtrapz(t,Storage_required)/3600,'r') 106 | hold on 107 | refline(0,min(cumtrapz(t,Storage_required)/3600)); 108 | set(gca,'fontsize',14) 109 | set(gca,'XTick',[0 6 12 18 24]) % Trying to customize axes to hours 110 | xlabel('Hours') 111 | ylabel('$E^{(i)}_{k}\ (MWh)$','Interpreter','latex') 112 | 113 | end 114 | 115 | if printfigs 116 | if isunix 117 | saveTightFigure(gcf,'~/Dropbox/Sai - Research Work/Report/SampleEreqPlot.pdf')% Function to remove the white margins added by MATLAB to pdf plots 118 | end 119 | if ispc 120 | saveTightFigure(gcf,'C:\Users\Sai\Dropbox\Sai - Research Work/Report/SampleEreqPlot.pdf') 121 | end 122 | end -------------------------------------------------------------------------------- /ThermalGenPlot.m: -------------------------------------------------------------------------------- 1 | %% This script plots the Thermal Generation in the area(BPA) based on the available generation data 2 | %% Clearing all the previous variables and data 3 | clear all 4 | clc 5 | 6 | %% Variables to suppress/show/save the plots 7 | show_plots = 1; 8 | printfigs = 1; 9 | 10 | %% Function to load the demand data from excel to MATLAB 11 | % isunix and ispc determine the current OS 12 | if isunix 13 | 14 | ThermalGen_365 = load_data('/home/vemu/Downloads/ThermalGeneration.xlsx','2014'); 15 | Netload_365 = load_data('/home/vemu/Dropbox/Sai - Research Work/Excel sheet Backup/Netload.xlsx','2015'); 16 | WindGen_365 = load_data('/home/vemu/Downloads/WindGeneration.xlsx','2014'); 17 | end 18 | if ispc 19 | 20 | ThermalGen_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/ThermalGeneration.xlsx','2014'); 21 | Netload_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/Netload.xlsx','2015'); 22 | WindGen_365 = load_data('C:\Users\Sai\Dropbox\Sai - Research Work\Excel sheet Backup/WindGeneration.xlsx','2014'); 23 | end 24 | 25 | %% Timeseries for Daily Thermal Generation 26 | 27 | % 288 data points correspond to one day - 2016 correspond to one week 28 | 29 | % n=1; 30 | 31 | % ThermalGen_today = timeseries(ThermalGen_365([((n-1)*288)+1:n*288],1), [0:300:86100]); % Time series data for the Thermal generation on day 'n' 32 | 33 | ThermalGen_today = timeseries(ThermalGen_365((1:2016),1)); % Time series data for the Thermal generation for a week 34 | 35 | Netload_today = timeseries(Netload_365((1:2016),1)); % Time series data for the net load on a particular day 36 | 37 | WindGen_today = timeseries(WindGen_365((1:2016),1)); % Time series data for the Wind generation for a week 38 | 39 | if show_plots 40 | plot(Netload_today.data,'r') % Netload plot 41 | hold on 42 | plot(ThermalGen_today.data,'c') % Thermal Generation 43 | hold on 44 | plot(WindGen_today.data,'g') % Wind Generation 45 | legend('Net load','Thermal Generation','Wind Generation') 46 | set(gca,'fontsize',12) 47 | set(gca,'linewidth',2) 48 | ylabel('Power (MW)') 49 | xlabel('K') 50 | end 51 | 52 | xlim([0 2016]) 53 | 54 | %% Print/Save figures - specify the address and filename 55 | if printfigs 56 | if isunix 57 | saveTightFigure(gcf,'~/Dropbox/Sai - Research Work/Report/WeekGenPlot.pdf') 58 | end 59 | if ispc 60 | saveTightFigure(gcf,'C:\Users\Sai\Dropbox\Sai - Research Work/Report/WeekGenPlot.pdf') 61 | end 62 | end -------------------------------------------------------------------------------- /ThermalGeneration.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saivemu/DiCELab_16_storage_required/8c9e1d413aa53e42bb6d9761ba91f516504e5491/ThermalGeneration.xlsx -------------------------------------------------------------------------------- /WindGeneration.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saivemu/DiCELab_16_storage_required/8c9e1d413aa53e42bb6d9761ba91f516504e5491/WindGeneration.xlsx -------------------------------------------------------------------------------- /load_data.m: -------------------------------------------------------------------------------- 1 | %% Import data from spreadsheet 2 | % Script for importing data from the following spreadsheet: 3 | % 4 | % Workbook: /home/vemu/Downloads/WindData 2014 - Mean.xlsx 5 | % Worksheet: January-June 6 | % 7 | % To extend the code for use with different selected data or a different 8 | % spreadsheet, generate a function instead of a script. 9 | 10 | function Netload = load_data(path,sheet) 11 | %% Import the data 12 | [~, ~, raw] = xlsread(path,sheet); 13 | raw = raw(2:end,2); 14 | raw(cellfun(@(x) ~isempty(x) && isnumeric(x) && isnan(x),raw)) = {''}; 15 | 16 | %% Replace non-numeric cells with NaN 17 | R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),raw); % Find non-numeric cells 18 | raw(R) = {NaN}; % Replace non-numeric cells 19 | 20 | %% Create output variable 21 | Netload = reshape([raw{:}],size(raw)); 22 | 23 | %% Clear temporary variables 24 | clearvars raw R; 25 | -------------------------------------------------------------------------------- /saveTightFigure.m: -------------------------------------------------------------------------------- 1 | function saveTightFigure(h,outfilename) 2 | % SAVETIGHTFIGURE(H,OUTFILENAME) Saves figure H in file OUTFILENAME without 3 | % the white space around it. 4 | 5 | % get the current axes 6 | ax = get(h, 'CurrentAxes'); 7 | 8 | % make it tight 9 | ti = get(ax,'TightInset'); 10 | set(ax,'Position',[ti(1) ti(2) 1-ti(3)-ti(1) 1-ti(4)-ti(2)]); 11 | 12 | % adjust the papersize 13 | set(ax,'units','centimeters'); 14 | pos = get(ax,'Position'); 15 | ti = get(ax,'TightInset'); 16 | set(h, 'PaperUnits','centimeters'); 17 | set(h, 'PaperSize', [pos(3)+ti(1)+ti(3)+1 pos(4)+ti(2)+ti(4)+1]); 18 | set(h, 'PaperPositionMode', 'manual'); 19 | set(h, 'PaperPosition',[0 0 pos(3)+ti(1)+ti(3)+1 pos(4)+ti(2)+ti(4)+1]); 20 | 21 | % save it 22 | saveas(h,outfilename); 23 | --------------------------------------------------------------------------------