-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add SingleAxisArray. Array to BaseArray, FixedTiltArray #1146
Conversation
It actually mostly works without changing anything in import pandas as pd
import matplotlib.pyplot as plt
from pvlib import temperature, pvsystem, location, modelchain
temperature_model_parameters = temperature.TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer']
module_parameters = {'pdc0': 240, 'gamma_pdc': -0.003}
inverter_parameters = {'pdc0': 100000}
fixed_array = pvsystem.FixedTiltArray(
module_parameters=module_parameters,
temperature_model_parameters=temperature_model_parameters,
modules_per_string=60,
strings=4
)
tracking_array = pvsystem.SingleAxisArray(
module_parameters=module_parameters,
temperature_model_parameters=temperature_model_parameters,
strings=4,
modules_per_string=60
)
mixed_system = pvsystem.PVSystem(
arrays=[fixed_array, tracking_array],
inverter_parameters=inverter_parameters
)
loc = location.Location(32.2, -110.9, altitude=700)
times = pd.date_range(start='20201201', end='20201203', freq='5min', tz='America/Phoenix')
weather = loc.get_clearsky(times)
mc_kwargs = dict(
aoi_model='physical',
spectral_model='no_loss',
ac_model='pvwatts_multi'
)
mc = modelchain.ModelChain(mixed_system, loc, **mc_kwargs)
mc.run_model(weather)
fig, ax = plt.subplots()
mc.results.dc[0].plot()
fig.savefig('mixed_dc_fixed.png')
fig, ax = plt.subplots()
mc.results.dc[1].plot()
fig.savefig('mixed_dc_tracker.png')
fig, ax = plt.subplots()
mc.results.ac.plot()
fig.savefig('mixed_ac.png') DC power AC power |
Some scope creep as I wanted to explore adding type hints to the object layer to hopefully make the complicated code more robust during this proposed refactor. I'm also hoping it will help us as we and others develop other projects that use pvlib. I was kind of skeptical going into it but after playing with them in my IDE and mypy I think it's a win. If we do want to implement type hints, I'm open to reimplementing them in a new PR with the current object layer before continuing with this refactor. Output of
|
FWIW I have been recently introduced to type hints and find that they make the signature much harder to visually parse in, for example, a jupyter tooltip. |
Static analysis as part of the CI pipeline (and for other projects) could be hugely beneficial. I haven't been hugely impressed by mypy so far, particularly since many libraries are not typed, but I think adding type annotations is a great idea. I haven't seen type annotations in jupyter tooltips before, but I would argue that the benefit of static analysis is worth the extra eye strain. |
Thanks for the feedback on the type annotations. It seems we should probably discuss them in a separate issue, so I will remove them from this PR. Do you have any feedback on the |
+1 to discussing type annotations another day. I initially liked the idea of subclasses inheriting from a array = Array(mount=FixedMount(20, 180), module=..., temperature_model_parameters=...) where we have different class FixedMount:
def __init__(self, surface_tilt, surface_azimuth):
self.orientation = {
'surface_tilt': surface_tilt,
'surface_azimuth': surface_azimuth
}
def get_orientation(self, solar_zenith, solar_azimuth):
return self.orientation # maybe calculate and return aoi too?
class SingleAxisTrackingMount:
def __init__(self, axis_tilt, axis_azimuth, max_angle, backtrack, gcr,
cross_axis_tilt):
self.axis_tilt = axis_tilt
self.axis_azimuth = axis_azimuth
# and the rest
def get_orientation(self, solar_zenith, solar_azimuth):
tracking_data = pvlib.tracking.singleaxis(
solar_zenith, solar_azimuth,
self.axis_tilt, self.axis_azimuth, # and the rest
)
return tracking_data A benefit is that it would be very easy to add new mount strategies (e.g. a |
The idea of a |
2ab314d
to
cf9b607
Compare
@kanderso-nrel that's very interesting and certainly worth exploring in a draft PR. It fits with the rest of the object layer too: I rolled back this PR to its status before I added type annotations. For reference, the annotations are in my types branch. |
what's the scope of |
closing in favor of #1176 |
docs/sphinx/source/api.rst
for API changes.docs/sphinx/source/whatsnew
for all changes. Includes link to the GitHub Issue with:issue:`num`
or this Pull Request with:pull:`num`
. Includes contributor name and/or GitHub username (link with:ghuser:`user`
).Initial implementation of the ideas first discussed in #1076 (comment) and #1109. I'm looking for feedback on this approach before integrating it with ModelChain. Also fine to discard it if we decide it's not the right approach or the right time for it.
As first discussed in the linked issues, this pattern leads to repeated calls to
tracking.singleaxis
: one call to get AOI and another to get POA irradiance. Add yet another call if you want to save the actual tracking data like we do inModelChainResults
. We could get around the repeated calls by adding atracking_data=None
kwarg to the methods (if tracking_data is None: tracking_data = self.singleaxis()
). That wouldn't be horrible, but it also doesn't look great to me. In principle we could add a cache toSingleAxisArray
, but I'd rather leave that to other libraries to do right.