-
Notifications
You must be signed in to change notification settings - Fork 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
Function to calculate temperature coefficient of power for pvsyst #1190
Conversation
Ready for review |
pvlib/ivtools/sdm.py
Outdated
from pvlib.pvsystem import singlediode, v_from_i | ||
from pvlib.pvsystem import calcparams_pvsyst |
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.
from pvlib.pvsystem import singlediode, v_from_i | |
from pvlib.pvsystem import calcparams_pvsyst | |
from pvlib.pvsystem import calcparams_pvsyst, singlediode, v_from_i |
pvlib/ivtools/sdm.py
Outdated
------- | ||
gamma_pmp : float | ||
Temperature coefficient of power at maximum power point at reference | ||
conditions. [%/C] |
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 was surprised to see %/C since the units of gamma_pdc
are 1/C in pvwatts_dc
. But I see we do use %/C in sdm.py
. So either is fine with me at this point.
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.
+1 to 1/C, more consistent with pvlib and the downstream PV Insight use. I probably cut/pasted from sdm.fit_cec_sam
then didn't think about the interface again. We use %/C in sdm.fit_cec_sam
because that's the quantity SAM requests.
pvlib/ivtools/sdm.py
Outdated
Temperature coefficient of power at maximum power point at reference | ||
conditions. [%/C] | ||
|
||
p_mp_ref : float |
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 little strange to see gamma_pmp
(p m p) and then p_mp_ref
(p underscore m p)
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.
Also a little strange to see pmp returned by a function that is ostensibly for finding temperature coefficient. I might argue that it would make more sense to either just return gamma_pmp
or change the name of the function and also return vmp and imp. But I don't feel strongly about it.
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.
Pvsyst doesn't name this parameter, so I'll call it gamma_pdc
with units of 1/C, same as is used by the PVWatts model. If the function is returning a value with units of 1/C, then p_mp_ref
isn't needed (it is if the unit is %/C).
pvlib/tests/ivtools/test_sdm.py
Outdated
res_hiT = pvsystem.singlediode(*params_hiT) | ||
expected = (res_hiT['p_mp'] - res_lowT['p_mp']) / 2. | ||
# convert to %/C | ||
expected = expected * 100 / (0.5 * (res_hiT['p_mp'] + res_lowT['p_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'd prefer for this value to be hard coded and for the function calls above to be removed.
pvlib/tests/ivtools/test_sdm.py
Outdated
expected = (res_hiT['p_mp'] - res_lowT['p_mp']) / 2. | ||
# convert to %/C | ||
expected = expected * 100 / (0.5 * (res_hiT['p_mp'] + res_lowT['p_mp'])) | ||
gamma_pdc, pdc_0 = sdm.pvsyst_temperature_coeff(**params) |
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 going to be a stickler again for passing args as args and kwargs as kwargs because it helps guard against unintended API changes.
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.
or we can make them keyword-only arguments without defaults, though I don't think we've introduced that pattern in pvlib.
* Added :py:func:`~pvlib.temperature.noct_sam`, a cell temperature model | ||
implemented in SAM. (:pull:`1177`) | ||
* Added :py:func:`~pvlib.ivtools.sdm.pvsyst_temperature_coeff` to calculate | ||
the temperature coefficient of power for the pvsyst module model. | ||
(:pull:`1190`) | ||
implemented in SAM (:pull:`1177`, :pull:`1195`) |
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.
bad merge
pvlib/tests/ivtools/test_sdm.py
Outdated
params = {'alpha_sc': 0., 'gamma_ref': 1.1, 'mu_gamma': 0., | ||
'I_L_ref': 6., 'I_o_ref': 5.e-9, 'R_sh_ref': 200., | ||
'R_sh_0': 2000., 'R_s': 0.5, 'cells_in_series': 60} | ||
expected = -0.7489980887568493 |
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.
Seems a bit large for a realistic module. I don't have enough intuition with the params values to say more. I just want to double check that this really is the expected value and the function really is returning the right thing.
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.
Good catch. The value was in W/C. Fixed now.
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.
merging tomorrow morning unless there is further discussion.
params = {'alpha_sc': 0., 'gamma_ref': 1.1, 'mu_gamma': 0., | ||
'I_L_ref': 6., 'I_o_ref': 5.e-9, 'R_sh_ref': 200., | ||
'R_sh_0': 2000., 'R_s': 0.5, 'cells_in_series': 60} | ||
expected = -0.004886706494879083 |
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.
expected = -0.004886706494879083 | |
expected = -0.004887 |
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.
In the past @adriesse has gently nudged us towards using reasonable precision when testing expected. While it can be a pain, I do think it makes the tests more understandable and makes it easier to catch issues like the one you fixed in the last 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 don't object on principle to the suggestion. But here I think more precision is useful, in case the test goes wonky in the future, and someone is reconstructing the expected value to know they have that calculation the same as when the test was created.
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 only vaguely recall the nudging occasion, but I have a general pet peeve about people producing too many digits of noise (e.g. NSRDB). You can't even compress it!
For tests I think it depends on what the test is aiming to accomplish. In this case you might see what happens if someone passes in float32 or maybe even float16. I often use float32.
Looking in the code now it seems like lots of potential changes/improvements in the functions that are called could affect the numeric result without breaking the fundamental calculation. Do you want that detected?
One thing you could perhaps consider would be to not rely on defaults when calling derivative
. Or do away with derivative
and call pmax
twice yourself. Then the user doesn't have to go to scipy documentation to figure out what is actually being done.
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.
Good points about the options in scipy.misc.derivative
. I didn't see an advantage to explicitly choosing options, or alternatively, hardcoding a particular derivative rule, but I'm open to doing either.
Peeve acknowledged and shared. The precision for expected
is to enable reconstructing this value and being confident that the reconstruction is the same as the test originator's calculation.
I wasn't thinking about detecting small deviations in the output of pvsyst_temperature_coeff
, only producing a value that is "good enough" in some sense. That's why I set rtol=0.0005
; I think 4 digits agreement is enough to say two temperature coefficients are the same.
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, I hadn't noticed the rtol. I got mislead by all those digit thinking the must be there because you wanted them to be there.
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.
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 merging this and improving it later, if issues arise. The only options are point spacing and order of the derivative rule, and the defaults (dx=1.0C, order=3) are reasonable for this case.
[ ] Closes #xxxxdocs/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`
).The temperature coefficient of power is not an input to the pvsyst single diode model. Rather, it is a result of the model, the derivative of power with respect to cell temperature, at the maximum power point, at reference conditions.