Skip to content
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 compute functions for use case 2A #169

Merged
merged 15 commits into from
Mar 15, 2021

Conversation

alorenzo175
Copy link
Contributor

@alorenzo175 alorenzo175 commented Mar 10, 2021

In order to convert from any temperature and irradiance input to cell temp and POA global, this just runs the full pvlib.ModelChain on the the reference and actual weather and grabs the results. It also calculates the adjusted power at the inverter level and sums up to the system level. POArat and TempFactor are calculated at the array level (with the array gamma_pdc, poas, and temps) and the simple mean is taken to get to the inverter level.

@codecov
Copy link

codecov bot commented Mar 10, 2021

Codecov Report

Merging #169 (a27cde9) into main (33304ec) will increase coverage by 0.55%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #169      +/-   ##
==========================================
+ Coverage   87.88%   88.43%   +0.55%     
==========================================
  Files          83       83              
  Lines        3210     3364     +154     
  Branches      273      273              
==========================================
+ Hits         2821     2975     +154     
  Misses        343      343              
  Partials       46       46              
Flag Coverage Δ
javascript 76.46% <ø> (ø)
python 99.15% <100.00%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
api/solarperformanceinsight_api/compute.py 100.00% <100.00%> (ø)
api/solarperformanceinsight_api/conftest.py 100.00% <100.00%> (ø)
api/solarperformanceinsight_api/models.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 33304ec...a27cde9. Read the comment docs.

@wholmgren
Copy link
Member

In order to convert from any temperature and irradiance input to cell temp and POA global, this just runs the full pvlib.ModelChain on the the reference and actual weather and grabs the results.

Here's a copy of the table of subcases 2A-1 -- 2A-4 in the powerpoint that @cwhanse provided (nice that something handles the formatting to make copy/paste just work!), plus my understanding of what this approach enables (2A-5 -- 2A-8)

Subcase Time step Reference weather Reference DC power Reference temperature
2A-1 Hourly POA Yes Cell/module
2A-2 Hourly POA No Cell/module
2A-3 Monthly POA No Cell/module
2A-4 Hourly GHI, DNI, DHI No Ambient
2A-5 Hourly POA No Ambient
2A-6 Hourly GHI, DNI, DHI No Cell/module
2A-7 Hourly effective irradiance No Ambient
2A-8 Hourly effective irradiance No Cell/module

Is that right? If so, I think that's ok. Less efficient some situations, but the flexibility win is pretty big. We could pass no-op functions for dc_model, losses_model, and ac_model to make it clear that we're not computing those quantities.

def no_op(mc):
    return mc

ModelChain(dc_model=no_op,...)

Probably not worth the effort with our well-defined metadata requirements - we're not likely to run into a problem when ModelChain tries to calculate those quantities that we don't actually need.

Does your approach also enable the same permutations with/without reference DC power? I didn't dig that hard.

Maybe we should turn modechain._irrad_for_celltemp into a public function if we're going to call it directly here.

@alorenzo175
Copy link
Contributor Author

Is that right? If so, I think that's ok. Less efficient some situations, but the flexibility win is pretty big. We could pass no-op functions for dc_model, losses_model, and ac_model to make it clear that we're not computing those quantities.

yes

Does your approach also enable the same permutations with/without reference DC power? I didn't dig that hard.

and yes

Maybe we should turn modechain._irrad_for_celltemp into a public function if we're going to call it directly here.

sounds good to me

@alorenzo175 alorenzo175 changed the title Add compute function for 2A-1,2,4 Add compute functions for use case 2A Mar 10, 2021
@alorenzo175 alorenzo175 marked this pull request as ready for review March 11, 2021 23:51
@alorenzo175
Copy link
Contributor Author

@lboeman do you want to take an initial look? there will likely be some minor changes coming later

@lboeman
Copy link
Contributor

lboeman commented Mar 12, 2021

@lboeman do you want to take an initial look? there will likely be some minor changes coming later

Yep, I'll take a look through it right now.

Copy link
Contributor

@lboeman lboeman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very reasonable to me 👍

@alorenzo175 alorenzo175 requested a review from wholmgren March 12, 2021 19:54
api/requirements.txt Outdated Show resolved Hide resolved
Copy link
Member

@wholmgren wholmgren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a handful of nits. overall looks very good.

if isinstance(self.module_parameters, PVWattsModuleParameters):
self._gamma = self.module_parameters.gamma_pdc
elif isinstance(self.module_parameters, CECModuleParameters):
self._gamma = self.module_parameters.gamma_r
Copy link
Member

@wholmgren wholmgren Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the plan to add something like

        elif isinstance(self.module_parameters, PVsystModuleParameters):
            # https://github.com/pvlib/pvlib-python/pull/1190
            from pvlib.ivtools.sdm import pvsyst_temperature_coeff
            self._gamma = pvsyst_temperature_coeff(self.module_parameters)

cc @cwhanse

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not handle this in an __init__ for each ModuleParameters class like you've done for the inverters and _pac0? Or vice versa.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with PVsystModuleParameters, yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wholmgren pvlib #1190 hung up on crafting a test case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cwhanse no worries. we'll go ahead with this and add support for pvsyst module parameters in a follow up PR after you're done.

api/solarperformanceinsight_api/models.py Outdated Show resolved Hide resolved
api/solarperformanceinsight_api/models.py Outdated Show resolved Hide resolved
api/solarperformanceinsight_api/compute.py Outdated Show resolved Hide resolved
api/solarperformanceinsight_api/compute.py Show resolved Hide resolved
# to cell temperature via the array's temperature model. If
# module_temperature was supplied and the temperature model is
# sapm, it is converted to cell_temperature, otherwise module
# temperature is used in place of cell_temperature
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we don't just use chain.results.cell_temperature. Doesn't ModelChain already handle all that logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. If you just give ModelChain module_temperature and the temperature model is not SAPM, it runs a default air_temp = 20 and wind_speed = 0 through the temperature model to calculate cell_temperature

Copy link
Contributor Author

@alorenzo175 alorenzo175 Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the model is SAPM, it does appropriately convert from module to cell temp

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@cwhanse cwhanse Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wholmgren would this SPI issue be fixed by pvlib/pvlib-python#1113? Or made worse by that pvlib issue?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it depends on what we mean by made worse. Removing the defaults would mean that the SPI code would break unless we handled the cases properly. But explicitly handling those cases would have prevented my confusion.

api/solarperformanceinsight_api/compute.py Show resolved Hide resolved
api/solarperformanceinsight_api/compute.py Outdated Show resolved Hide resolved
@alorenzo175
Copy link
Contributor Author

Ah, I did forget to drop feb. 29 from the actual data if not present in predicted. At this point, I think a follow up issue/PR for that makes sense

@alorenzo175 alorenzo175 requested a review from wholmgren March 12, 2021 23:32
@alorenzo175 alorenzo175 merged commit 40625c9 into SolarPerformanceInsight:main Mar 15, 2021
@alorenzo175 alorenzo175 deleted the 2acomputation branch March 15, 2021 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants