Skip to content

DC Ohmic Losses for pvsystem and modelchain #1168

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

Merged
merged 17 commits into from
Mar 16, 2021

Conversation

ncroft-b4
Copy link
Contributor

@ncroft-b4 ncroft-b4 commented Feb 15, 2021

  • partially addresses Applied PVsyst-type losses in ModelChain #1069
  • I am familiar with the contributing guidelines
  • Tests added
  • Updates entries to docs/sphinx/source/api.rst for API changes.
  • Adds description and name entries in the appropriate "what's new" file in 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`).
  • New code is fully documented. Includes numpydoc compliant docstrings, examples, and comments where necessary.
  • Pull request is nearly complete and ready for detailed review.
  • Maintainer: Appropriate GitHub Labels and Milestone are assigned to the Pull Request and linked Issue.

Adds functionality for array level losses and adds functions for dc ohmic losses to pvsystem and modelchain. Replaces #1084 for compatibility with Array update.

kwargs = _build_kwargs(['dc_ohmic_percent'],
self.array_losses_parameters)

kwargs.update(_build_kwargs(['V_mp_ref', 'I_mp_ref'],
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if there is a way to extend this to the other DC module models. If module_parameters is taken from the CEC database, it will include V_mp_ref and I_mp_ref.

The other cases are Pvsyst, SAPM and PVWatts.

For Pvsyst, pvlib provides no parameter database. The pvsyst DC power functions don't require V_mp_ref or I_mp_ref, so the user would need to know that these must be added.

For SAPM, the expected names are Vmpo and Impo.

For PVWatts, the ohmic losses model can't be applied since PVWatts only deals with power (not voltage and current separately).

V_mp_ref, I_mp_ref and dc_ohmic_percent are required by the downstream method. Maybe raise a ValueError here if any are missing at this step.

In the ModelChain dc_ohms_from_percent method, we could check dc_model and raise a more informative message how to correct the ValueError.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. I need to sort out the relations between the DC models and the module parameters, which have always been a bit confusing, I admit. I would like to make this applicable for CEC, SAPM, and PVsyst models. Sounds like for SAPM, I can add the option to use Vmpo and Impo if those are present in the module parameters. But for PVsyst, it may require a different workflow, or like you say, to raise a ValueError to say that those parameters need to be added. I will look into this to add an update.

Copy link
Member

Choose a reason for hiding this comment

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

Do you know if the Pvsyst software names these two quantities? If so, I'd use those names. A user will have to add them to module_parameters regardless since there's no data source from which to inherit the names.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a section that checks from and adds the parameters in sets of either V_mp_ref, I_mp_ref; Vmpo, Impo; or Vmpp, Impp` (pvsyst-like, from the documentation and pan file parameters). It should raise a value error if these are not found. If this looks like a workable solution, should more tests be added for each case?

Copy link
Member

@kandersolar kandersolar left a comment

Choose a reason for hiding this comment

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

A few quick comments about docstring formatting

of the PVsystem.
"""
Rw = self.system.dc_ohms_from_percent()
self.dc_ohmic_losses = pvsystem.dc_ohmic_losses(Rw, self.dc['i_mp'])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just realized this might need to be rewritten to handle the case where there are multiple arrays and so dc_ohms_from_percent returns a tuple instead of a single value. In that case what will self.dc[i_mp] be? Commenting to mark to investigate and fix.

Copy link
Member

Choose a reason for hiding this comment

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

self.results.dc will be a tuple of DataFrame.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I added functionality for multiple arrays in the latest commit. I think all of the comments are addressed now and it is ready for the review and push forward.

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.

Thanks @ncroft-b4. Minor items below. Nice job with the tests.

"""
Rw = self.system.dc_ohms_from_percent()
if isinstance(self.results.dc, tuple):
self.dc_ohmic_losses = tuple(
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to assign this to self.results.dc_ohmic_losses? If yes, we'll need to add it to the ModelChainResults class. If not, we should drop self. and leave it as a variable that's just used within this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it should be assigned to the results. Otherwise there is no record of what power was taken out of p_mp and no way to confirm, test, or just review the losses after the fact.

It looks like pvwatts_losses still creates a self.losses attribute. Do we want to think about coordinating the storage of those losses with other losses like dc_ohmic_losses now and any others that get added later? Or treat each separately?

Copy link
Member

Choose a reason for hiding this comment

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

It looks like pvwatts_losses still creates a self.losses attribute.

Thanks for catching that. pvwatts_losses and no_extra_losses should assign values to ModelChainResults, and ModelChain._deprecated_attrs should include losses. We can address that in another issue/pr.

Do we want to think about coordinating the storage of those losses with other losses like dc_ohmic_losses now and any others that get added later? Or treat each separately?

Good question. I'd lean toward treating them separately for now unless we have a good idea of how the losses models will evolve in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I will work on adding dc_ohmic_losses to ModelChainResults in the next commit.

Copy link
Member

Choose a reason for hiding this comment

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

I'd lean toward treating them separately for now

I agree. If losses attributes pile up in ModelChainResults we can consider creating a Losses dataclass or other mechanism to group losses together.

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.

almost there...

@@ -1068,6 +1076,51 @@ def faiman_temp(self):
def fuentes_temp(self):
return self._set_celltemp(self.system.fuentes_celltemp)

@property
def dc_ohmic_model(self):
return self._dc_ohmic_model
Copy link
Member

Choose a reason for hiding this comment

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

any idea why codecov says this line isn't tested? It looks like it should be.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was confusing for me as well. And now it is telling me that blank lines 1082 and 1095 are not covered, and that 1090 is not covered which it should be as there is a test specifically for dc_ohmic_model='no_loss'. I'd welcome an assist from someone more familiar with the tests on what might be leading to the failed coverage if anyone has an idea.

Copy link
Member

Choose a reason for hiding this comment

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

I ran a coverage report locally and cannot reproduce the codecov results. Adding exceptions to these lines causes errors, as you would expect.

@wholmgren wholmgren added this to the 0.9.0 milestone Mar 10, 2021
@wholmgren wholmgren added the SPI DOE SETO Solar Performance Insight project label Mar 16, 2021
@@ -1149,6 +1166,9 @@ class Array:
Valid strings are 'open_rack', 'close_mount', and 'insulated_back'.
Used to identify a parameter set for the SAPM cell temperature model.

array_losses_parameters: None, dict or Series, default None.
Copy link
Member

Choose a reason for hiding this comment

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

sorry, should have caught this earlier.... it seems repetitive to call this parameter array_losses_parameters since it's already on an Array. I suppose there is some risk of user confusion if this and the PVSystem losses_parameters are called the same thing, but it doesn't hurt to have extra keys in these dictionaries. It's unlikely that would change in the future.

Maybe we should live with the current API on master in an alpha release or two and then maybe take up renaming in a follow up issue. I could see something like #1176 providing more clarity on this.

Thoughts @ncroft-b4 @cwhanse ?

Copy link
Member

Choose a reason for hiding this comment

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

I'm OK with either array_losses_parameters or Array.losses_parameters (and PVSystem.losses_parameters) in this PR.

I think as loss models are added to pvlib and we work those models into ModelChain, we'll end up refactoring the parameter containers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I think my concern was making it distinguishable from the PVSystem parameter. Also, to keep compatibility with initializing a PVSystem directly, there needs to be a difference between the losses_parameters that would be passed into the Array and the ones that would stay with the PVSystem.

That makes me realize that I added array_losses_parameters to the list of keys that get passed to Array from PVSystem if an Array is not specified, but I did not add array_losses_parameters explicitly to the documentation for PVSystem or to the init. That makes sense to be because array_losses_parameters is only an Array parameter, but it does make it different from the other Array parameters that are still part of PVSystem by legacy. I'm good with it as it is but if you want to keep it uniform with the legacy parameters we could change it.

@wholmgren
Copy link
Member

Ok, let's move on for now. Thanks @ncroft-b4 for the contribution and your patience as we worked through it!

@wholmgren wholmgren merged commit 2a1ed55 into pvlib:master Mar 16, 2021
@wholmgren
Copy link
Member

and after I scrolled to the top to go to my notifications I realized that we don't have a whats new entry. Sorry. I can add that in another PR.

@adriesse
Copy link
Member

I have just quickly scrolled through this and wanted to mention something that may be relevant to someone sometime: PVsyst models DC ohmic losses by increasing the series resistance in the single-diode model parameters. This seems like a good approach to me, and I suppose one can still do that independently of this new code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement SPI DOE SETO Solar Performance Insight project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants