@@ -27,19 +27,18 @@ configuration at a handful of sites listed below.
27
27
28
28
.. ipython :: python
29
29
30
+ import pvlib
30
31
import pandas as pd
31
32
import matplotlib.pyplot as plt
32
33
33
- naive_times = pd.date_range(start = ' 2015' , end = ' 2016' , freq = ' 1h' )
34
-
35
34
# very approximate
36
35
# latitude, longitude, name, altitude, timezone
37
- coordinates = [( 30 , - 110 , ' Tucson ' , 700 , ' Etc/GMT+7 ' ),
38
- ( 35 , - 105 , ' Albuquerque ' , 1500 , ' Etc/GMT+7' ),
39
- ( 40 , - 120 , ' San Francisco ' , 10 , ' Etc/GMT+8 ' ),
40
- ( 50 , 10 , ' Berlin ' , 34 , ' Etc/GMT-1 ' )]
41
-
42
- import pvlib
36
+ coordinates = [
37
+ ( 30 , - 110 , ' Tucson ' , 700 , ' Etc/GMT+7' ),
38
+ ( 35 , - 105 , ' Albuquerque ' , 1500 , ' Etc/GMT+7 ' ),
39
+ ( 40 , - 120 , ' San Francisco ' , 10 , ' Etc/GMT+8 ' ),
40
+ ( 50 , 10 , ' Berlin ' , 34 , ' Etc/GMT-1 ' ),
41
+ ]
43
42
44
43
# get the module and inverter specifications from SAM
45
44
sandia_modules = pvlib.pvsystem.retrieve_sam(' SandiaMod' )
@@ -48,9 +47,32 @@ configuration at a handful of sites listed below.
48
47
inverter = sapm_inverters[' ABB__MICRO_0_25_I_OUTD_US_208__208V_' ]
49
48
temperature_model_parameters = pvlib.temperature.TEMPERATURE_MODEL_PARAMETERS [' sapm' ][' open_rack_glass_glass' ]
50
49
51
- # specify constant ambient air temp and wind for simplicity
52
- temp_air = 20
53
- wind_speed = 0
50
+
51
+ In order to retrieve meteorological data for the simulation, we can make use of
52
+ the :ref: `iotools ` module. In this example we will be using PVGIS, one of the
53
+ data sources available, to retrieve a Typical Meteorological Year (TMY) which
54
+ includes irradiation, temperature and wind speed.
55
+
56
+ .. note :: PVGIS uses different naming conventions, so it is required to rename
57
+ the weather data variables before using them. Data is already UTC-localized,
58
+ so conversion to local timezone is optional.
59
+
60
+ .. ipython :: python
61
+
62
+ variables_translation = {
63
+ " Gb(n)" : " dni" ,
64
+ " G(h)" : " ghi" ,
65
+ " Gd(h)" : " dhi" ,
66
+ " T2m" : " temp_air" ,
67
+ " WS10m" : " wind_speed" ,
68
+ }
69
+ tmys = []
70
+ for location in coordinates:
71
+ latitude, longitude, name, altitude, timezone = location
72
+ weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude)[0 ]
73
+ weather = weather.rename(columns = variables_translation)
74
+ weather.index.name = " utc_time"
75
+ tmys.append(weather)
54
76
55
77
56
78
Procedural
@@ -69,41 +91,60 @@ to accomplish our system modeling goal:
69
91
70
92
energies = {}
71
93
72
- for latitude, longitude, name, altitude, timezone in coordinates:
73
- times = naive_times.tz_localize( timezone)
94
+ for location, weather in zip ( coordinates, tmys) :
95
+ latitude, longitude, name, altitude, timezone = location
74
96
system[' surface_tilt' ] = latitude
75
- solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
76
- dni_extra = pvlib.irradiance.get_extra_radiation(times)
97
+ solpos = pvlib.solarposition.get_solarposition(
98
+ time = weather.index,
99
+ latitude = latitude,
100
+ longitude = longitude,
101
+ altitude = altitude,
102
+ temperature = weather[" temp_air" ],
103
+ pressure = pvlib.atmosphere.alt2pres(altitude),
104
+ )
105
+ dni_extra = pvlib.irradiance.get_extra_radiation(weather.index)
77
106
airmass = pvlib.atmosphere.get_relative_airmass(solpos[' apparent_zenith' ])
78
107
pressure = pvlib.atmosphere.alt2pres(altitude)
79
108
am_abs = pvlib.atmosphere.get_absolute_airmass(airmass, pressure)
80
- tl = pvlib.clearsky.lookup_linke_turbidity(times, latitude, longitude)
81
- cs = pvlib.clearsky.ineichen(solpos[' apparent_zenith' ], am_abs, tl,
82
- dni_extra = dni_extra, altitude = altitude)
83
- aoi = pvlib.irradiance.aoi(system[' surface_tilt' ], system[' surface_azimuth' ],
84
- solpos[' apparent_zenith' ], solpos[' azimuth' ])
85
- total_irrad = pvlib.irradiance.get_total_irradiance(system[' surface_tilt' ],
86
- system[' surface_azimuth' ],
87
- solpos[' apparent_zenith' ],
88
- solpos[' azimuth' ],
89
- cs[' dni' ], cs[' ghi' ], cs[' dhi' ],
90
- dni_extra = dni_extra,
91
- model = ' haydavies' )
92
- tcell = pvlib.temperature.sapm_cell(total_irrad[' poa_global' ],
93
- temp_air, wind_speed,
94
- ** temperature_model_parameters)
109
+ aoi = pvlib.irradiance.aoi(
110
+ system[' surface_tilt' ],
111
+ system[' surface_azimuth' ],
112
+ solpos[" apparent_zenith" ],
113
+ solpos[" azimuth" ],
114
+ )
115
+ total_irradiance = pvlib.irradiance.get_total_irradiance(
116
+ system[' surface_tilt' ],
117
+ system[' surface_azimuth' ],
118
+ solpos[' apparent_zenith' ],
119
+ solpos[' azimuth' ],
120
+ weather[' dni' ],
121
+ weather[' ghi' ],
122
+ weather[' dhi' ],
123
+ dni_extra = dni_extra,
124
+ model = ' haydavies' ,
125
+ )
126
+ cell_temperature = pvlib.temperature.sapm_cell(
127
+ total_irradiance[' poa_global' ],
128
+ weather[" temp_air" ],
129
+ weather[" wind_speed" ],
130
+ ** temperature_model_parameters,
131
+ )
95
132
effective_irradiance = pvlib.pvsystem.sapm_effective_irradiance(
96
- total_irrad[' poa_direct' ], total_irrad[' poa_diffuse' ],
97
- am_abs, aoi, module)
98
- dc = pvlib.pvsystem.sapm(effective_irradiance, tcell, module)
133
+ total_irradiance[' poa_direct' ],
134
+ total_irradiance[' poa_diffuse' ],
135
+ am_abs,
136
+ aoi,
137
+ module,
138
+ )
139
+ dc = pvlib.pvsystem.sapm(effective_irradiance, cell_temperature, module)
99
140
ac = pvlib.inverter.sandia(dc[' v_mp' ], dc[' p_mp' ], inverter)
100
141
annual_energy = ac.sum()
101
142
energies[name] = annual_energy
102
143
103
144
energies = pd.Series(energies)
104
145
105
146
# based on the parameters specified above, these are in W*hrs
106
- print (energies.round( 0 ) )
147
+ print (energies)
107
148
108
149
energies.plot(kind = ' bar' , rot = 0 )
109
150
@savefig proc -energies.png width=6in
@@ -150,28 +191,35 @@ by examining the parameters defined for the module.
150
191
from pvlib.location import Location
151
192
from pvlib.modelchain import ModelChain
152
193
153
- system = PVSystem(module_parameters = module,
154
- inverter_parameters = inverter,
155
- temperature_model_parameters = temperature_model_parameters)
194
+ system = PVSystem(
195
+ module_parameters = module,
196
+ inverter_parameters = inverter,
197
+ temperature_model_parameters = temperature_model_parameters,
198
+ )
156
199
157
200
energies = {}
158
- for latitude, longitude, name, altitude, timezone in coordinates:
159
- times = naive_times.tz_localize(timezone)
160
- location = Location(latitude, longitude, name = name, altitude = altitude,
161
- tz = timezone)
162
- weather = location.get_clearsky(times)
163
- mc = ModelChain(system, location,
164
- orientation_strategy = ' south_at_latitude_tilt' )
165
- # model results (ac, dc) and intermediates (aoi, temps, etc.)
166
- # assigned as mc object attributes
167
- mc.run_model(weather)
168
- annual_energy = mc.results.ac.sum()
201
+ for location, weather in zip (coordinates, tmys):
202
+ latitude, longitude, name, altitude, timezone = location
203
+ location = Location(
204
+ latitude,
205
+ longitude,
206
+ name = name,
207
+ altitude = altitude,
208
+ tz = timezone,
209
+ )
210
+ mc = ModelChain(
211
+ system,
212
+ location,
213
+ orientation_strategy = ' south_at_latitude_tilt' ,
214
+ )
215
+ results = mc.run_model(weather)
216
+ annual_energy = results.ac.sum()
169
217
energies[name] = annual_energy
170
218
171
219
energies = pd.Series(energies)
172
220
173
221
# based on the parameters specified above, these are in W*hrs
174
- print (energies.round( 0 ) )
222
+ print (energies)
175
223
176
224
energies.plot(kind = ' bar' , rot = 0 )
177
225
@savefig modelchain -energies.png width=6in
0 commit comments