Skip to content

Commit 948d99a

Browse files
authored
Merge branch 'main' into ape_example
2 parents 5cfc22d + ad89390 commit 948d99a

32 files changed

+1234
-847
lines changed

docs/examples/irradiance-transposition/plot_seasonal_tilt.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class SeasonalTiltMount(pvsystem.AbstractMount):
3232
surface_azimuth: float = 180.0
3333

3434
def get_orientation(self, solar_zenith, solar_azimuth):
35+
# note: determining tilt based on month may produce different
36+
# results depending on the time zone of the timestamps
3537
tilts = [self.monthly_tilts[m-1] for m in solar_zenith.index.month]
3638
return pd.DataFrame({
3739
'surface_tilt': tilts,
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"""
2+
Use different Perez coefficients with the ModelChain
3+
====================================================
4+
5+
This example demonstrates how to customize the ModelChain
6+
to use site-specific Perez transposition coefficients.
7+
"""
8+
9+
# %%
10+
# The :py:class:`pvlib.modelchain.ModelChain` object provides a useful method
11+
# for easily constructing a PV system model with a simple, unified interface.
12+
# However, a user may want to customize the steps
13+
# in the system model in various ways.
14+
# One such example is during the irradiance transposition step.
15+
# The Perez model perform very well on field data, but
16+
# it requires a set of fitted coefficients from various sites.
17+
# It has been noted that these coefficients can be specific to
18+
# various climates, so users may see improved model accuracy
19+
# when using a site-specific set of coefficients.
20+
# However, the base :py:class:`~pvlib.modelchain.ModelChain`
21+
# only supports the default coefficients.
22+
# This example shows how the :py:class:`~pvlib.modelchain.ModelChain` can
23+
# be adjusted to use a different set of Perez coefficients.
24+
25+
import pandas as pd
26+
from pvlib.pvsystem import PVSystem
27+
from pvlib.modelchain import ModelChain
28+
from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
29+
from pvlib import iotools, location, irradiance
30+
import pvlib
31+
import os
32+
import matplotlib.pyplot as plt
33+
34+
# load in TMY weather data from North Carolina included with pvlib
35+
PVLIB_DIR = pvlib.__path__[0]
36+
DATA_FILE = os.path.join(PVLIB_DIR, 'data', '723170TYA.CSV')
37+
38+
tmy, metadata = iotools.read_tmy3(DATA_FILE, coerce_year=1990,
39+
map_variables=True)
40+
41+
weather_data = tmy[['ghi', 'dhi', 'dni', 'temp_air', 'wind_speed']]
42+
43+
loc = location.Location.from_tmy(metadata)
44+
45+
#%%
46+
# Now, let's set up a standard PV model using the ``ModelChain``
47+
48+
surface_tilt = metadata['latitude']
49+
surface_azimuth = 180
50+
51+
# define an example module and inverter
52+
sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod')
53+
cec_inverters = pvlib.pvsystem.retrieve_sam('cecinverter')
54+
sandia_module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
55+
cec_inverter = cec_inverters['ABB__MICRO_0_25_I_OUTD_US_208__208V_']
56+
57+
temp_params = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
58+
59+
# define the system and ModelChain
60+
system = PVSystem(arrays=None,
61+
surface_tilt=surface_tilt,
62+
surface_azimuth=surface_azimuth,
63+
module_parameters=sandia_module,
64+
inverter_parameters=cec_inverter,
65+
temperature_model_parameters=temp_params)
66+
67+
mc = ModelChain(system, location=loc)
68+
69+
# %%
70+
# Now, let's calculate POA irradiance values outside of the ``ModelChain``.
71+
# We do this for both the default Perez coefficients and the desired
72+
# alternative Perez coefficients. This enables comparison at the end.
73+
74+
# Cape Canaveral seems like the most likely match for climate
75+
model_perez = 'capecanaveral1988'
76+
77+
solar_position = loc.get_solarposition(times=weather_data.index)
78+
dni_extra = irradiance.get_extra_radiation(weather_data.index)
79+
80+
POA_irradiance = irradiance.get_total_irradiance(
81+
surface_tilt=surface_tilt,
82+
surface_azimuth=surface_azimuth,
83+
dni=weather_data['dni'],
84+
ghi=weather_data['ghi'],
85+
dhi=weather_data['dhi'],
86+
solar_zenith=solar_position['apparent_zenith'],
87+
solar_azimuth=solar_position['azimuth'],
88+
model='perez',
89+
dni_extra=dni_extra)
90+
91+
POA_irradiance_new_perez = irradiance.get_total_irradiance(
92+
surface_tilt=surface_tilt,
93+
surface_azimuth=surface_azimuth,
94+
dni=weather_data['dni'],
95+
ghi=weather_data['ghi'],
96+
dhi=weather_data['dhi'],
97+
solar_zenith=solar_position['apparent_zenith'],
98+
solar_azimuth=solar_position['azimuth'],
99+
model='perez',
100+
model_perez=model_perez,
101+
dni_extra=dni_extra)
102+
103+
# %%
104+
# Now, run the ``ModelChain`` with both sets of irradiance data and compare
105+
# (note that to use POA irradiance as input to the ModelChain the method
106+
# `.run_model_from_poa` is used):
107+
108+
mc.run_model_from_poa(POA_irradiance)
109+
ac_power_default = mc.results.ac
110+
111+
mc.run_model_from_poa(POA_irradiance_new_perez)
112+
ac_power_new_perez = mc.results.ac
113+
114+
start, stop = '1990-05-05 06:00:00', '1990-05-05 19:00:00'
115+
plt.plot(ac_power_default.loc[start:stop],
116+
label="Default Composite Perez Model")
117+
plt.plot(ac_power_new_perez.loc[start:stop],
118+
label="Cape Canaveral Perez Model")
119+
plt.xticks(rotation=90)
120+
plt.ylabel("AC Power ($W$)")
121+
plt.legend()
122+
plt.tight_layout()
123+
plt.show()
124+
# %%
125+
# Note that there is a small, but noticeable difference from the default
126+
# coefficients that may add up over longer periods of time.

docs/examples/iv-modeling/plot_singlediode.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@
114114
# mark the MPP
115115
plt.plot([v_mp], [i_mp], ls='', marker='o', c='k')
116116

117+
plt.xlim(left=0)
118+
plt.ylim(bottom=0)
117119
plt.legend(loc=(1.0, 0))
118120
plt.xlabel('Module voltage [V]')
119121
plt.ylabel('Module current [A]')

docs/examples/spectrum/plot_spectrl2_fig51A.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@
1313
# This example recreates an example figure from the SPECTRL2 NREL Technical
1414
# Report [1]_. The figure shows modeled spectra at hourly intervals across
1515
# a single morning.
16-
#
17-
# References
18-
# ----------
19-
# .. [1] Bird, R, and Riordan, C., 1984, "Simple solar spectral model for
20-
# direct and diffuse irradiance on horizontal and tilted planes at the
21-
# earth's surface for cloudless atmospheres", NREL Technical Report
22-
# TR-215-2436 doi:10.2172/5986936.
2316

2417
# %%
2518
# The SPECTRL2 model has several inputs; some can be calculated with pvlib,
@@ -53,9 +46,10 @@
5346

5447
# %%
5548
# With all the necessary inputs in hand we can model spectral irradiance using
56-
# :py:func:`pvlib.spectrum.spectrl2`. Note that because we are calculating
57-
# the spectra for more than one set of conditions, we will get back 2-D
58-
# arrays (one dimension for wavelength, one for time).
49+
# :py:func:`pvlib.spectrum.spectrl2`. Note that because we are calculating
50+
# the spectra for more than one set of conditions, the spectral irradiance
51+
# components will be returned in a dictionary as 2-D arrays, with one dimension
52+
# for wavelength and one for time.
5953

6054
spectra = spectrum.spectrl2(
6155
apparent_zenith=solpos.apparent_zenith,
@@ -95,3 +89,11 @@
9589
# position and the solar position calculation in the technical report does not
9690
# exactly match the one used here. However, the differences are minor enough
9791
# to not materially change the spectra.
92+
93+
# %%
94+
# References
95+
# ----------
96+
# .. [1] Bird, R, and Riordan, C., 1984, "Simple solar spectral model for
97+
# direct and diffuse irradiance on horizontal and tilted planes at the
98+
# earth's surface for cloudless atmospheres", NREL Technical Report
99+
# TR-215-2436 :doi:`10.2172/5986936`

docs/sphinx/source/conf.py

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
# use napoleon in lieu of numpydoc 2019-04-23
3939

4040
# If your documentation needs a minimal Sphinx version, state it here.
41-
#needs_sphinx = '1.0'
41+
# needs_sphinx = '1.0'
4242

4343
# Add any Sphinx extension module names here, as strings. They can be
4444
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -70,7 +70,7 @@
7070
source_suffix = '.rst'
7171

7272
# The encoding of source files.
73-
#source_encoding = 'utf-8-sig'
73+
# source_encoding = 'utf-8-sig'
7474

7575
# The master toctree document.
7676
master_doc = 'index'
@@ -94,41 +94,41 @@
9494

9595
# The language for content autogenerated by Sphinx. Refer to documentation
9696
# for a list of supported languages.
97-
#language = None
97+
# language = None
9898

9999
# There are two options for replacing |today|: either, you set today to some
100100
# non-false value, then it is used:
101-
#today = ''
101+
# today = ''
102102
# Else, today_fmt is used as the format for a strftime call.
103-
#today_fmt = '%B %d, %Y'
103+
# today_fmt = '%B %d, %Y'
104104

105105
# List of patterns, relative to source directory, that match files and
106106
# directories to ignore when looking for source files.
107107
exclude_patterns = ['whatsnew/*', '**.ipynb_checkpoints']
108108

109109
# The reST default role (used for this markup: `text`) to use for all
110110
# documents.
111-
#default_role = None
111+
# default_role = None
112112

113113
# If true, '()' will be appended to :func: etc. cross-reference text.
114-
#add_function_parentheses = True
114+
# add_function_parentheses = True
115115

116116
# If true, the current module name will be prepended to all description
117117
# unit titles (such as .. function::).
118-
#add_module_names = True
118+
# add_module_names = True
119119

120120
# If true, sectionauthor and moduleauthor directives will be shown in the
121121
# output. They are ignored by default.
122-
#show_authors = False
122+
# show_authors = False
123123

124124
# The name of the Pygments (syntax highlighting) style to use.
125125
pygments_style = 'sphinx'
126126

127127
# A list of ignored prefixes for module index sorting.
128-
#modindex_common_prefix = []
128+
# modindex_common_prefix = []
129129

130130
# If true, keep warnings as "system message" paragraphs in the built documents.
131-
#keep_warnings = False
131+
# keep_warnings = False
132132

133133
autosummary_generate = True
134134

@@ -183,10 +183,10 @@
183183

184184
# The name for this set of Sphinx documents. If None, it defaults to
185185
# "<project> v<release> documentation".
186-
#html_title = None
186+
# html_title = None
187187

188188
# A shorter title for the navigation bar. Default is the same as html_title.
189-
#html_short_title = None
189+
# html_short_title = None
190190

191191
# The name of an image file (relative to this directory) to place at the top
192192
# of the sidebar.
@@ -195,7 +195,7 @@
195195
# The name of an image file (within the static path) to use as favicon of the
196196
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
197197
# pixels large.
198-
#html_favicon = None
198+
# html_favicon = None
199199

200200
# Add any paths that contain custom static files (such as style sheets) here,
201201
# relative to this directory. They are copied after the builtin static files,
@@ -245,10 +245,10 @@
245245
# If true, an OpenSearch description file will be output, and all pages will
246246
# contain a <link> tag referring to it. The value of this option must be the
247247
# base URL from which the finished HTML is served.
248-
#html_use_opensearch = ''
248+
# html_use_opensearch = ''
249249

250250
# This is the file name suffix for HTML files (e.g. ".xhtml").
251-
#html_file_suffix = None
251+
# html_file_suffix = None
252252

253253
# Output file base name for HTML help builder.
254254
htmlhelp_basename = 'pvlib_pythondoc'
@@ -266,15 +266,16 @@ def setup(app):
266266

267267
# -- Options for LaTeX output ---------------------------------------------
268268

269+
269270
latex_elements = {
270-
# The paper size ('letterpaper' or 'a4paper').
271-
#'papersize': 'letterpaper',
271+
# The paper size ('letterpaper' or 'a4paper').
272+
# 'papersize': 'letterpaper',
272273

273-
# The font size ('10pt', '11pt' or '12pt').
274-
#'pointsize': '10pt',
274+
# The font size ('10pt', '11pt' or '12pt').
275+
# 'pointsize': '10pt',
275276

276-
# Additional stuff for the LaTeX preamble.
277-
#'preamble': '',
277+
# Additional stuff for the LaTeX preamble.
278+
# 'preamble': '',
278279
}
279280

280281
# Grouping the document tree into LaTeX files. List of tuples
@@ -288,23 +289,23 @@ def setup(app):
288289

289290
# The name of an image file (relative to this directory) to place at the top of
290291
# the title page.
291-
#latex_logo = None
292+
# latex_logo = None
292293

293294
# For "manual" documents, if this is true, then toplevel headings are parts,
294295
# not chapters.
295-
#latex_use_parts = False
296+
# latex_use_parts = False
296297

297298
# If true, show page references after internal links.
298-
#latex_show_pagerefs = False
299+
# latex_show_pagerefs = False
299300

300301
# If true, show URL addresses after external links.
301-
#latex_show_urls = False
302+
# latex_show_urls = False
302303

303304
# Documents to append as an appendix to all manuals.
304-
#latex_appendices = []
305+
# latex_appendices = []
305306

306307
# If false, no module index is generated.
307-
#latex_domain_indices = True
308+
# latex_domain_indices = True
308309

309310
# extlinks alias
310311
extlinks = {
@@ -329,7 +330,7 @@ def setup(app):
329330
]
330331

331332
# If true, show URL addresses after external links.
332-
#man_show_urls = False
333+
# man_show_urls = False
333334

334335

335336
# -- Options for Texinfo output -------------------------------------------
@@ -345,16 +346,16 @@ def setup(app):
345346
]
346347

347348
# Documents to append as an appendix to all manuals.
348-
#texinfo_appendices = []
349+
# texinfo_appendices = []
349350

350351
# If false, no module index is generated.
351-
#texinfo_domain_indices = True
352+
# texinfo_domain_indices = True
352353

353354
# How to display URL addresses: 'footnote', 'no', or 'inline'.
354-
#texinfo_show_urls = 'footnote'
355+
# texinfo_show_urls = 'footnote'
355356

356357
# If true, do not generate a @detailmenu in the "Top" node's menu.
357-
#texinfo_no_detailmenu = False
358+
# texinfo_no_detailmenu = False
358359

359360
# Example configuration for intersphinx: refer to the Python standard library.
360361
intersphinx_mapping = {

0 commit comments

Comments
 (0)