Problem 13.10

Problem 13.10#

Fundamentals of Solar Cells and Photovoltaic Systems Engineering

Solutions Manual - Chapter 13

Problem 13.10

In this problem, the economic viability of a household rooftop solar installation in Aarhus, Denmark is evaluated. To that end, hourly data will be used and can be accessed through the book repository. The file “Problem13.10_electricity_demand_and_price_data.csv” can be obtained at this book’s online repository. The data file includes:

1. hourly values of electricity demand for a household in Aarhus

2. electricity price in the wholesale electricity market for the power system DK1 [1]

3. capacity factors for a solar PV installation with optimal tilt angle and orientation in Aarhus. [2]

(a) As a first step, determine the capacity of the PV modules that must be installed so that the annual electricity generated by installation equals the household annual electricity demand.

Every hour in which the PV solar generation is lower than the demand, the energy deficit is imported from the utility power grid paying a price of 0.2924 EUR/kWh.3 Every hour in which the PV solar generation is higher than the demand, the excess energy is exported to the grid, and it is paid at the price of the wholesale market in the electricity market DK1. The installation cost for the rooftop PV system is 1243 EUR/kW. The cost of operation and maintenance (O&M) is neglected, and a discount rate of 4% is assumed.

(b) Calculate the net present value (NPV) of the installation in year 25.

(c) Calculate the year in which the initial investment will be recovered.

(d) Calculate the internal rate of return (IRR) of the investment.

(e) Aarhus municipality has decided to subsidize 20% of the cost of the installation. Repeat the sections (b)–(d) in this case.

(f) Aarhus municipality has decided to try a different strategy, and now, it does not subsidize rooftop PV installations, but it offers zero-interest loans to citizens, so it can be assumed that the discount rate is 0%. Repeat the sections (b)–(c) in this case and discuss the results.

[1] Data was obtained from Nordpoolgroup. It can be accessed at the Nordpoolgroup web by selecting “elspot-prices_2019_hourly_dkk”

[2] Data was obtained from PV-GIS, assuming a performance ratio of 86%. It can be retrieved from the webpage PVGIS selecting Aarhus on the map.

We start by importing the pandas package (useful to work with data tables) and importing the data

import pandas as pd

data=pd.read_csv('data/Problem13.10_electricity_demand_and_price_data.csv', sep=',', encoding='latin-1',
                index_col=(0)) #, header=0)

data.head() #show the initial lines to check that import is working fine
Hours Elspot Prices DK1 (EUR/MWh) Household Demand (kWh) Capacity factor solar
Day
01/01/2019 00 - 01 28.39 0.18 0.0
01/01/2019 01 - 02 10.09 0.17 0.0
01/01/2019 02 - 03 -4.09 0.20 0.0
01/01/2019 03 - 04 -9.93 0.17 0.0
01/01/2019 04 - 05 -7.43 0.18 0.0

(a) Determine the capacity of the PV modules that must be installed so that the annual electricity generated by them equals the annual electricity consumption.

We calculate the average capacity factor, the annual electricity consumption and the required PV capacity.

average_CF = data['Capacity factor solar'].mean()
annual_electricity_consumption = data['Household Demand (kWh)'].sum()

PV_capacity = annual_electricity_consumption / (average_CF*8760)
print('PV modules capacity = ' + str(PV_capacity.round(2)) + ' kW')
PV modules capacity = 2.85 kW

Every hour in which the PV solar generation is lower than the demand, the energy deficit is imported from the grid paying a price of 0.2924 €/kWh [3]. Every hour in which the PV solar generation is higher than the demand, the excess energy is exported to the grid and it is paid at the price of the wholesale market in the node DK1.

The installation cost for the rooftop PV system is 1,243 €/kW [4]. The cost of Operation and Maintenance (O&M) is neglected, and a discount rate of 4% is assumed.

(b) Calculate the Net Present Value (NPV) of the installation in year 25.

[3] This corresponds to the average price of electricity for consumes in Denmark in 2019 according to Eurostat

[4] This is the cost estimated for a rooftop PV installation in the report “Technology Data for Generation of Electricity and District Heating” by the Danish Energy Agency (DEA) and Energinet.dk

We start by calculating the mismatch in every hour, i.e., the difference between the PV electricity generation and demand.

mismatch = PV_capacity*data['Capacity factor solar'] - data['Household Demand (kWh)']
mismatch.tail()
Day
31/12/2019   -0.20
31/12/2019   -0.17
31/12/2019   -0.18
31/12/2019   -0.18
31/12/2019   -0.18
dtype: float64

We calculate the net cost of electricity with and without the PV installation.

market_price = data['Elspot Prices DK1 (EUR/MWh)']
electricity_cost_w_PV = -sum([mismatch_h*market_price_h/1000 if mismatch_h>0 else mismatch_h*0.2924
                         for mismatch_h, market_price_h in zip(mismatch, market_price)])

electricity_cost_wo_PV = annual_electricity_consumption*0.2924 

print('Annual electricicy price with PV = ' + str(round(electricity_cost_w_PV, 2))+ ' €')
print('Annual electricicy price without PV = ' + str(round(electricity_cost_wo_PV, 2))+ ' €')
Annual electricicy price with PV = 464.84 €
Annual electricicy price without PV = 779.44 €

The annual savings can be calculated as

annual_savings = electricity_cost_wo_PV - electricity_cost_w_PV
print('Annual savings = ' + str(round(annual_savings, 2))+ ' €')
Annual savings = 314.6 €

We create the a series with the cash flow in every year and calculate the discounted values, assuming 25 years lifetime and discount rate \(r\)=4.0%

cash_flow=pd.Series(index=range(0,25), data=annual_savings)
cash_flow[0] -= PV_capacity*1243 # Investment cost 1243 EUR/kW
r=0.04
discounted_cash_flow = pd.Series(index=range(0,25), data=[cash_flow[y]/(1+r)**y for y in cash_flow.index])

The Net Present Value (NPV) is calculated as the sum of the discounted cash flow.

print('NPV = ' + str(round(sum(discounted_cash_flow),2))+ ' €')
NPV = 1568.47 €

(c) Calculate the year in which the initial investment will be recovered.

We calculate the cumulative discounted cash flow and see that at year 14 NPV>0, that is, the investment is recovered.

discounted_cash_flow.cumsum()
0    -3228.177113
1    -2925.680379
2    -2634.818134
3    -2355.142898
4    -2086.224402
5    -1827.648926
6    -1579.018660
7    -1339.951096
8    -1110.078439
9     -889.047038
10    -676.516845
11    -472.160889
12    -275.664779
13     -86.726211
14      94.945489
15     269.629816
16     437.595515
17     599.100995
18     754.394726
19     903.715621
20    1047.293404
21    1185.348965
22    1318.094697
23    1445.734823
24    1568.465714
dtype: float64

(d) Calculate the Internal Rate of Return (IRR) of the investment.

The IRR can be calculated at the discount rate that makes the NPV=0 at the end of the installation lifetime.

NPV = pd.Series(dtype=float)

for n in range(0, 100):
    r=0.001*n
    discounted_cash_flow = pd.Series(index=range(0,25), data=[cash_flow[y]/(1+r)**y for y in cash_flow.index])
    NPV[r]=sum(discounted_cash_flow)
argmin=NPV.abs().argmin()
NPV.index[argmin]
print('IRR = ' + str(NPV.index[argmin]))
IRR = 0.083

(e) Aarhus municipality has decided to subsidize 20% of the cost of the installation. Repeat the sections (b)–(d) in this case.

Net Present value

cash_flow=pd.Series(index=range(0,25), data=annual_savings)
cash_flow[0] -= PV_capacity*1243*0.8 # Investment cost 1243 EUR/kW, 20% is subsidized
r=0.04
discounted_cash_flow = pd.Series(index=range(0,25), data=[cash_flow[y]/(1+r)**y for y in cash_flow.index])
print('NPV = ' + str(round(sum(discounted_cash_flow),2))+ ' €')
NPV = 2277.02 €

In this case, the investment is recoverd in 10 years.

discounted_cash_flow.cumsum()
0    -2519.622370
1    -2217.125635
2    -1926.263390
3    -1646.588155
4    -1377.669659
5    -1119.094182
6     -870.463916
7     -631.396353
8     -401.523696
9     -180.492294
10      32.037899
11     236.393854
12     432.889965
13     621.828533
14     803.500233
15     978.184560
16    1146.150259
17    1307.655739
18    1462.949469
19    1612.270364
20    1755.848147
21    1893.903708
22    2026.649440
23    2154.289567
24    2277.020458
dtype: float64

Internal Rate of Return (IRR)

NPV = pd.Series(dtype=float)

for n in range(0, 100):
    r=0.001*n
    discounted_cash_flow = pd.Series(index=range(0,25), data=[cash_flow[y]/(1+r)**y for y in cash_flow.index])
    NPV[r]=sum(discounted_cash_flow)
    
argmin=NPV.abs().argmin()
NPV.index[argmin]
print('IRR = ' + str(NPV.index[argmin]))
IRR = 0.099

(f) Aarhus municipality has decided to try a different strategy, and now, it does not subsidize rooftop PV installations, but it offers zero-interest loans to citizens, so it can be assumed that the discount rate is 0%. Repeat the sections (b)–(c) in this case.

Net Present value

cash_flow=pd.Series(index=range(0,25), data=annual_savings)
cash_flow[0] -= PV_capacity*1243# Investment cost 1243 EUR/kW, 20% is subsidized
r=0
discounted_cash_flow = pd.Series(index=range(0,25), data=[cash_flow[y]/(1+r)**y for y in cash_flow.index])
print('NPV = ' + str(round(sum(discounted_cash_flow),2))+ ' €')
NPV = 4322.14 €

In this case, the investment is recoverd in 11 years.

discounted_cash_flow.cumsum()
0    -3228.177113
1    -2913.580509
2    -2598.983905
3    -2284.387301
4    -1969.790697
5    -1655.194093
6    -1340.597488
7    -1026.000884
8     -711.404280
9     -396.807676
10     -82.211072
11     232.385532
12     546.982136
13     861.578741
14    1176.175345
15    1490.771949
16    1805.368553
17    2119.965157
18    2434.561761
19    2749.158365
20    3063.754970
21    3378.351574
22    3692.948178
23    4007.544782
24    4322.141386
dtype: float64