@@ -10,7 +10,7 @@ The core mission of pvlib-python is to provide open, reliable,
10
10
interoperable, and benchmark implementations of PV system models.
11
11
12
12
There are at least as many opinions about how to model PV systems as
13
- there are modelers of PV systems, so
13
+ there are modelers of PV systems, so
14
14
pvlib-python provides several modeling paradigms.
15
15
16
16
@@ -36,28 +36,28 @@ configuration at a handful of sites listed below.
36
36
37
37
import pandas as pd
38
38
import matplotlib.pyplot as plt
39
-
39
+
40
40
# seaborn makes the plots look nicer
41
41
import seaborn as sns
42
42
sns.set_color_codes()
43
-
43
+
44
44
times = pd.DatetimeIndex(start = ' 2015' , end = ' 2016' , freq = ' 1h' )
45
-
45
+
46
46
# very approximate
47
47
# latitude, longitude, name, altitude
48
48
coordinates = [(30 , - 110 , ' Tucson' , 700 ),
49
49
(35 , - 105 , ' Albuquerque' , 1500 ),
50
50
(40 , - 120 , ' San Francisco' , 10 ),
51
51
(50 , 10 , ' Berlin' , 34 )]
52
-
52
+
53
53
import pvlib
54
-
54
+
55
55
# get the module and inverter specifications from SAM
56
56
sandia_modules = pvlib.pvsystem.retrieve_sam(' SandiaMod' )
57
57
sapm_inverters = pvlib.pvsystem.retrieve_sam(' sandiainverter' )
58
58
module = sandia_modules[' Canadian_Solar_CS5P_220M___2009_' ]
59
59
inverter = sapm_inverters[' ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_' ]
60
-
60
+
61
61
# specify constant ambient air temp and wind for simplicity
62
62
temp_air = 20
63
63
wind_speed = 0
@@ -73,7 +73,7 @@ The following code demonstrates how to use the procedural code
73
73
to accomplish our system modeling goal:
74
74
75
75
.. ipython :: python
76
-
76
+
77
77
system = {' module' : module, ' inverter' : inverter,
78
78
' surface_azimuth' : 180 }
79
79
@@ -104,32 +104,56 @@ to accomplish our system modeling goal:
104
104
ac = pvlib.pvsystem.snlinverter(inverter, dc[' v_mp' ], dc[' p_mp' ])
105
105
annual_energy = ac.sum()
106
106
energies[name] = annual_energy
107
-
107
+
108
108
energies = pd.Series(energies)
109
109
110
110
# based on the parameters specified above, these are in W*hrs
111
111
print (energies.round(0 ))
112
-
112
+
113
113
energies.plot(kind = ' bar' , rot = 0 )
114
114
@savefig proc -energies.png width=6in
115
115
plt.ylabel(' Yearly energy yield (W hr)' )
116
116
117
+ pvlib-python provides a :py:func: `~pvlib.modelchain.basic_chain `
118
+ function that implements much of the code above. Use this function with
119
+ a full understanding of what it is doing internally!
120
+
121
+ .. ipython :: python
122
+
123
+ from pvlib.modelchain import basic_chain
124
+
125
+ energies = {}
126
+ for latitude, longitude, name, altitude in coordinates:
127
+ dc, ac = basic_chain(times, latitude, longitude,
128
+ module, inverter,
129
+ altitude = altitude,
130
+ orientation_strategy = ' south_at_latitude_tilt' )
131
+ annual_energy = ac.sum()
132
+ energies[name] = annual_energy
133
+
134
+ energies = pd.Series(energies)
135
+
136
+ # based on the parameters specified above, these are in W*hrs
137
+ print (energies.round(0 ))
138
+
139
+ energies.plot(kind = ' bar' , rot = 0 )
140
+ @savefig basic -chain-energies.png width=6in
141
+ plt.ylabel(' Yearly energy yield (W hr)' )
142
+
117
143
118
144
Object oriented (Location, PVSystem, ModelChain)
119
145
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120
146
121
- The first object oriented paradigm uses a model where
122
- a :py:class: `~pvlib.pvsystem.PVSystem ` object represents an
123
- assembled collection of modules, inverters, etc.,
124
- a :py:class: `~pvlib.location.Location ` object represents a
125
- particular place on the planet,
126
- and a :py:class: `~pvlib.modelchain.ModelChain ` object describes
127
- the modeling chain used to calculate PV output at that Location.
128
- This can be a useful paradigm if you prefer to think about
129
- the PV system and its location as separate concepts or if
130
- you develop your own ModelChain subclasses.
131
- It can also be helpful if you make extensive use of Location-specific
132
- methods for other calculations.
147
+ The first object oriented paradigm uses a model where a
148
+ :py:class: `~pvlib.pvsystem.PVSystem ` object represents an assembled
149
+ collection of modules, inverters, etc., a
150
+ :py:class: `~pvlib.location.Location ` object represents a particular
151
+ place on the planet, and a :py:class: `~pvlib.modelchain.ModelChain `
152
+ object describes the modeling chain used to calculate PV output at that
153
+ Location. This can be a useful paradigm if you prefer to think about the
154
+ PV system and its location as separate concepts or if you develop your
155
+ own ModelChain subclasses. It can also be helpful if you make extensive
156
+ use of Location-specific methods for other calculations.
133
157
134
158
The following code demonstrates how to use
135
159
:py:class: `~pvlib.location.Location `,
@@ -138,14 +162,14 @@ The following code demonstrates how to use
138
162
objects to accomplish our system modeling goal:
139
163
140
164
.. ipython :: python
141
-
165
+
142
166
from pvlib.pvsystem import PVSystem
143
167
from pvlib.location import Location
144
168
from pvlib.modelchain import ModelChain
145
-
169
+
146
170
system = PVSystem(module_parameters = module,
147
171
inverter_parameters = inverter)
148
-
172
+
149
173
energies = {}
150
174
for latitude, longitude, name, altitude in coordinates:
151
175
location = Location(latitude, longitude, name = name, altitude = altitude)
@@ -156,12 +180,12 @@ objects to accomplish our system modeling goal:
156
180
dc, ac = mc.run_model(times)
157
181
annual_energy = ac.sum()
158
182
energies[name] = annual_energy
159
-
183
+
160
184
energies = pd.Series(energies)
161
-
185
+
162
186
# based on the parameters specified above, these are in W*hrs
163
187
print (energies.round(0 ))
164
-
188
+
165
189
energies.plot(kind = ' bar' , rot = 0 )
166
190
@savefig modelchain -energies.png width=6in
167
191
plt.ylabel(' Yearly energy yield (W hr)' )
@@ -170,18 +194,17 @@ objects to accomplish our system modeling goal:
170
194
Object oriented (LocalizedPVSystem)
171
195
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
172
196
173
- The second object oriented paradigm uses a model where a
197
+ The second object oriented paradigm uses a model where a
174
198
:py:class: `~pvlib.pvsystem.LocalizedPVSystem ` represents a
175
- PV system at a particular place on the planet.
176
- This can be a useful paradigm if you're thinking about
177
- a power plant that already exists.
199
+ PV system at a particular place on the planet. This can be a useful
200
+ paradigm if you're thinking about a power plant that already exists.
178
201
179
202
The following code demonstrates how to use a
180
203
:py:class: `~pvlib.pvsystem.LocalizedPVSystem `
181
204
object to accomplish our modeling goal:
182
205
183
206
.. ipython :: python
184
-
207
+
185
208
from pvlib.pvsystem import LocalizedPVSystem
186
209
187
210
energies = {}
@@ -214,22 +237,22 @@ object to accomplish our modeling goal:
214
237
ac = localized_system.snlinverter(dc[' v_mp' ], dc[' p_mp' ])
215
238
annual_energy = ac.sum()
216
239
energies[name] = annual_energy
217
-
240
+
218
241
energies = pd.Series(energies)
219
-
242
+
220
243
# based on the parameters specified above, these are in W*hrs
221
244
print (energies.round(0 ))
222
-
245
+
223
246
energies.plot(kind = ' bar' , rot = 0 )
224
247
@savefig localized -pvsystem-energies.png width=6in
225
248
plt.ylabel(' Yearly energy yield (W hr)' )
226
249
227
250
228
251
User extensions
229
252
---------------
230
- There are many other ways to organize PV modeling code.
231
- We encourage you to build on these paradigms and to share your experiences
232
- with the pvlib community via issues and pull requests.
253
+ There are many other ways to organize PV modeling code. We encourage you
254
+ to build on these paradigms and to share your experiences with the pvlib
255
+ community via issues and pull requests.
233
256
234
257
235
258
Getting support
0 commit comments