-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Conversation
pvlib/pvsystem.py
Outdated
kwargs = _build_kwargs(['dc_ohmic_percent'], | ||
self.array_losses_parameters) | ||
|
||
kwargs.update(_build_kwargs(['V_mp_ref', 'I_mp_ref'], |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this 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
pvlib/modelchain.py
Outdated
of the PVsystem. | ||
""" | ||
Rw = self.system.dc_ohms_from_percent() | ||
self.dc_ohmic_losses = pvsystem.dc_ohmic_losses(Rw, self.dc['i_mp']) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
pvlib/modelchain.py
Outdated
""" | ||
Rw = self.system.dc_ohms_from_percent() | ||
if isinstance(self.results.dc, tuple): | ||
self.dc_ohmic_losses = tuple( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
@@ -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. |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Ok, let's move on for now. Thanks @ncroft-b4 for the contribution and your patience as we worked through it! |
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. |
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. |
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`
).Adds functionality for array level losses and adds functions for dc ohmic losses to
pvsystem
andmodelchain
. Replaces #1084 for compatibility withArray
update.