Skip to content

Commit 4073821

Browse files
committed
add SingleAxisTracker support to ModelChain
* add SingleAxisTracker support to ModelChain * whitespace * add mc.tracking assertion * add note to whatsnew
1 parent 645eefe commit 4073821

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

docs/sphinx/source/whatsnew/v0.3.3.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Enhancements
1212
* Adds the Erbs model. (:issue:`2`)
1313
* Adds the ``scale_voltage_current_power`` function and ``PVSystem`` method
1414
to support simple array modeling. (:issue:`159`)
15+
* Adds support for ``SingleAxisTracker`` objects in ``ModelChain``.
16+
(:issue:`169`)
1517

1618

1719
Bug fixes

pvlib/modelchain.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
the time to read the source code for the module.
77
"""
88

9+
from functools import partial
10+
911
import pandas as pd
1012

1113
from pvlib import solarposition, pvsystem, clearsky, atmosphere
14+
from pvlib.tracking import SingleAxisTracker
1215
import pvlib.irradiance # avoid name conflict with full import
1316

1417

@@ -317,9 +320,32 @@ def run_model(self, times, irradiance=None, weather=None):
317320
airmass_data=self.airmass['airmass_absolute'])
318321
self.irradiance = irradiance
319322

320-
self.total_irrad = self.system.get_irradiance(
321-
self.solar_position['apparent_zenith'],
322-
self.solar_position['azimuth'],
323+
# PVSystem.get_irradiance and SingleAxisTracker.get_irradiance
324+
# have different method signatures, so use partial to handle
325+
# the differences.
326+
if isinstance(self.system, SingleAxisTracker):
327+
self.tracking = self.system.singleaxis(
328+
self.solar_position['apparent_zenith'],
329+
self.solar_position['azimuth'])
330+
self.tracking['surface_tilt'] = (
331+
self.tracking['surface_tilt']
332+
.fillna(self.system.axis_tilt))
333+
self.tracking['surface_azimuth'] = (
334+
self.tracking['surface_azimuth']
335+
.fillna(self.system.axis_azimuth))
336+
get_irradiance = partial(
337+
self.system.get_irradiance,
338+
surface_tilt=self.tracking['surface_tilt'],
339+
surface_azimuth=self.tracking['surface_azimuth'],
340+
solar_zenith=self.solar_position['apparent_zenith'],
341+
solar_azimuth=self.solar_position['azimuth'])
342+
else:
343+
get_irradiance = partial(
344+
self.system.get_irradiance,
345+
self.solar_position['apparent_zenith'],
346+
self.solar_position['azimuth'])
347+
348+
self.total_irrad = get_irradiance(
323349
self.irradiance['dni'],
324350
self.irradiance['ghi'],
325351
self.irradiance['dhi'],

pvlib/test/test_modelchain.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import numpy as np
22
import pandas as pd
3+
from numpy import nan
34

45
from pvlib import modelchain, pvsystem
56
from pvlib.modelchain import ModelChain
67
from pvlib.pvsystem import PVSystem
8+
from pvlib.tracking import SingleAxisTracker
79
from pvlib.location import Location
810

911
from pandas.util.testing import assert_series_equal, assert_frame_equal
@@ -100,6 +102,26 @@ def test_run_model_with_weather():
100102
assert_series_equal(ac, expected)
101103

102104

105+
def test_run_model_tracker():
106+
system, location = mc_setup()
107+
system = SingleAxisTracker(module_parameters=system.module_parameters,
108+
inverter_parameters=system.inverter_parameters)
109+
mc = ModelChain(system, location)
110+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6H')
111+
ac = mc.run_model(times).ac
112+
113+
expected = pd.Series(np.array([ 121.421719, -2.00000000e-02]),
114+
index=times)
115+
assert_series_equal(ac, expected)
116+
117+
expected = pd.DataFrame(np.
118+
array([[ 54.82513187, 90. , 11.0039221 , 11.0039221 ],
119+
[ nan, 0. , 0. , nan]]),
120+
columns=['aoi', 'surface_azimuth', 'surface_tilt', 'tracker_theta'],
121+
index=times)
122+
assert_frame_equal(mc.tracking, expected)
123+
124+
103125
@raises(ValueError)
104126
def test_bad_get_orientation():
105127
modelchain.get_orientation('bad value')

0 commit comments

Comments
 (0)