Problem 1.11

Problem 1.11#

Fundamentals of Solar Cells and Photovoltaic Systems Engineering

Solutions Manual - Chapter 1

Problem 1.11

Estimate the maximum solar PV capacity that can be installed in a country based on land availability.Remove areas that are not suitable for solar PV because they are protected areas. Assume a capacity density for the remaining areas of 50 W/m\(^2\).

This problem needs to be solved with software that can read and interpret maps with information on the land use in a country and different types of land use. See one option to approach this problem in the online repository of this book.

In this problem, we will calculate the maximum solar PV capacity that can be installed in a country based on the available land.

To that end, we will use the package Atlite (version>0.2.5)

This solution is based on the example Landuse Availability

We start by importing the packages that we will need and define the size of the figure.

import atlite
import xarray as xr
import geopandas as gpd
import matplotlib.pyplot as plt
from rasterio.plot import show
from atlite.gis import shape_availability, ExclusionContainer

plt.rcParams['figure.figsize'] = [7, 7]

We will use the world map included in the package geopandas. We select the country that we want to analyze and we plot it. In this example, we select Spain.

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

countries= ['Spain']

shapes = world[world.name.isin(countries)].set_index('name')

shapes.plot();
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[2], line 1
----> 1 world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
      3 countries= ['Spain']
      5 shapes = world[world.name.isin(countries)].set_index('name')

File /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/geopandas/datasets/__init__.py:18, in get_path(dataset)
     12 error_msg = (
     13     "The geopandas.dataset has been deprecated and was removed in GeoPandas "
     14     f"1.0. You can get the original '{dataset}' data from "
     15     f"{ne_message if 'natural' in dataset else nybb_message}"
     16 )
     17 if dataset in _prev_available:
---> 18     raise AttributeError(error_msg)
     19 else:
     20     error_msg = (
     21         "The geopandas.dataset has been deprecated and "
     22         "was removed in GeoPandas 1.0. New sample datasets are now available "
     23         "in the geodatasets package (https://geodatasets.readthedocs.io/en/latest/)"
     24     )

AttributeError: The geopandas.dataset has been deprecated and was removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.

We want to include only the areas of the country that are suitable to install solar PV.

To that end we use the CORINE Land Cover (CLC) database. It provides a 100 m x 100 m raster which, for each raster cell, indicates the type of landuse (forest, urban, industrial). In total there are 44 classes.

The raster (.tif file) from the download page needs to be stored as data/corine.tif

CORINE = 'data/corine.tif'

We consider the following codes to be suitable for solar PV:

  • artificial surfaces (1-11)

  • agriculture land except for those areas already occupied by agriculture with significant natural vegetation and agro-forestry areas (12-20)

  • natural grasslands (26)

  • bare rocks (31)

  • sparsely vegetated areas (32)

We define an ExclusionContainer that includes all the raster cell that we want to exclude, apply the exclusion and calculate the eligible area, and the percentage of total area that it represents.

excluder = ExclusionContainer()

excluder.add_raster(CORINE, codes=(21, 22, 23, 24, 25, 27, 28, 29, 30, 33,
                                   34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44))

country = shapes.geometry.to_crs(excluder.crs)

masked, transform = shape_availability(country, excluder)
eligible_area = masked.sum() * excluder.res**2
eligible_share = masked.sum() * excluder.res**2 / country.geometry.item().area
C:\Users\34620\.conda\envs\env_pv_textbook\lib\site-packages\atlite\gis.py:470: UserWarning: Output dtype of shape_availability changed from float to boolean.
  "Output dtype of shape_availability changed from float to boolean.", UserWarning
C:\Users\34620\.conda\envs\env_pv_textbook\lib\site-packages\ipykernel_launcher.py:9: RuntimeWarning: overflow encountered in long_scalars
  if __name__ == "__main__":
C:\Users\34620\.conda\envs\env_pv_textbook\lib\site-packages\ipykernel_launcher.py:10: RuntimeWarning: overflow encountered in long_scalars
  # Remove the CWD from sys.path while we load stuff.

We plot the map of the country and the eligible area in orange.

fig, ax = plt.subplots()
ax = show(masked, transform=transform, cmap='Oranges', ax=ax)
country.plot(ax=ax, edgecolor='k', color='None')
ax.set_title(f'Eligible area (orange) {eligible_share * 100:2.2f}% \n {eligible_area * 0.000001:2.0f}km$^2$' );
../../_images/842f632ade4293b0d49fb69ae6d66eca7d17810f5f97ec61fa79cb752096cbeb.png

We assume a capacity density for solar PV installations of 50 W/m2, and calculate the total potential by multiplying the capacity density times the available land.

PV_potential = eligible_area*50*0.000000001 #W ->GW
print(f'PV potential {PV_potential:2.1f} GW')
PV potential 1.0 GW
C:\Users\34620\.conda\envs\env_pv_textbook\lib\site-packages\ipykernel_launcher.py:1: RuntimeWarning: overflow encountered in long_scalars
  """Entry point for launching an IPython kernel.