-
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
Test pvsystem.singlediode against precisely generated IV curves #1573
Conversation
…cise-ivcurves-tests
I updated the description of this pull request. The test cases added now test:
The tests for |
Ready for review. @markcampanelli would appreciate your input if this closes #411 |
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 for this submission. Generally looks good.
The big thing I would like to see is some better documentation in this repo (mostly for posterity) about how the precise I-V data points were generated elsewhere. For example, how did you choose the precision cutoff using mpmath
with respect to the precision used in the pvsystem.singlediode
calculations? The choice of constants in the upstream calculation could also have a better "paper trail".
@@ -0,0 +1,33 @@ | |||
Index,photocurrent,saturation_current,resistance_series,resistance_shunt,n,cells_in_series | |||
1,1.0,5e-10,0.1,300,1.01,72 |
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.
Because this is a Python repo, you might consider indexing from 0, not 1.
"cells_in_series": 72, | ||
"IV Curves": [ | ||
{ | ||
"Index": 1, |
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.
Because this is a Python repo, you might consider indexing from 0, not 1.
pvlib/tests/test_singlediode.py
Outdated
joined['Boltzman'] = 1.380649e-23 | ||
joined['Electron Charge'] = 1.60217663e-19 |
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.
For better traceability, I would think that the choice of values for these constants should documented as part of the files containing the parameters used to precisely compute the curves.
For comparison, scipy==1.8.1
gives:
scipy.constants.value("Boltzmann constant") = 1.380649e-23 J/K
scipy.constants.value("elementary charge") = 1.602176634e-19 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.
Also see #483
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 updated these constants to match The SI Brochure (https://www.bipm.org/en/publications/si-brochure) and cited that document in the docstring. In that docstring, I also added the precision cutoff of mpmath and more detail about the precision of the IV curve data. I avoided mentioning cwhanse/ivcurves, but maybe we should reference it. There is much more documentation and code that would help someone understand how the IV curve data was generated.
Also, if we use scipy.constants
, pvlib may need to update its minimum SciPy version requirement because Boltzmann's constant changes depending on the SciPy version. The value for SciPy 1.9.3 is 1.602176634e-19 C
, which matches the value hard-coded here; however, the value is 1.6021766208e-19 C
for SciPy 1.2.0. It changes in SciPy 1.4.0, and pvlib's minimum version of SciPy is 1.2.0.
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.
@pvlib/pvlib-maintainer I think we should advance scipy version and use the 2019 values, which are defined to be exact rather than with uncertainty.
pvlib/tests/test_singlediode.py
Outdated
assert np.allclose(pc['i_sc'], outs['i_sc'], atol=1e-10, rtol=0) | ||
assert np.allclose(pc['v_oc'], outs['v_oc'], atol=1e-10, rtol=0) | ||
assert np.allclose(pc['i_mp'], outs['i_mp'], atol=5e-8, rtol=0) | ||
assert np.allclose(pc['v_mp'], outs['v_mp'], atol=8e-7, rtol=0) | ||
assert np.allclose(pc['p_mp'], outs['p_mp'], atol=1e-10, rtol=0) | ||
assert np.allclose(pc['i_x'], outs['i_x'], atol=1e-10, rtol=0) | ||
assert np.allclose(pc['i_xx'], outs['i_xx'], atol=8e-8, rtol=0) |
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 super curious how these tolerances might be tightened for 'lambertw', 'brentq', vs. 'newton'.
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.
And I'm curious why there are test failures only on ubuntu and python <=3.9 for the 'lambertw' case. I suspect something buried fairly deep behind scipy.special.lambertw
which we won't solve.
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.
For this failed test, the 30th i_xx
value differs by 1e-6
. All of the tests related to this pull request pass with atol=1e-6
for the i_xx
value.
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.
@reepoi I think there's a mistake in the precise curve library somewhere.
I think this addresses #411, so that can be closed once this merges. I have closed #426, which this substitutes. |
…cise-ivcurves-tests
The current test failures are only on linux, only occur for numpy>=1.22.0, and have to do with precision checks, so I suspect this is due to the increased SIMD functionality added in numpy 1.22.0. In the past we have relaxed test tolerances to accommodate the slight numerical variation, but in this specific case that seems rather self-defeating :) It is possible to disable the relevant SIMD features by setting a magic environment variable when executing the tests (#1448 (comment)), but that would be a global change that affects all tests, which I'm not sure is desirable either. I'm not sure what to suggest here. |
My perspective is that the test tolerance is a measure of the pvlib functions' accuracy. Six digits (worst case) is at least useful for energy simulations and may also help provide context for other use cases. At least it establishes a benchmark from which we can measure improvements. |
@cwhanse a lot has happened in the https://github.com/cwhanse/ivcurves repository in the last couple months. Are any corresponding updates required in this PR? |
We may need to replace the json files |
…cise-ivcurves-tests
I regenerated the JSON files using the latest version of the https://github.com/cwhanse/ivcurves repository and there is no difference between them and the JSON files in this PR. |
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 minor docs suggestions but otherwise LGTM. Thanks @reepoi!
Thanks @reepoi for the contribution and @markcampanelli and @cwhanse for the reviews! |
[ ] Updates entries indocs/sphinx/source/reference
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`
).remote-data
) and Milestone are assigned to the Pull Request and linked Issue.Generated IV curves are added to
pvlib/data
to test the precision ofpvsystem.singlediode
,pvsystem.v_from_i
, andpvsystem.i_from_v
. The parameters of the single diode equation that generated each IV curve are in CSV files, and the IV curve data are in JSON files following this JSON schema.i_x
andi_xx
are added in addition to the fields of the JSON schema since they are also calculated bypvsystem.singlediode
.The generated IV curve data are calculated using the functions in the ivcurves repository. These functions use the arbitrary precision math library mpmath. The data may be reproduced by checking out the code of this commit of ivcurves and running the command
The data are in the files
test_sets/case1.json
andtest_sets/case2.json
.