-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Dividing by cos(solar_zenith) in haydavies and reindl functions #432
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
Comments
A related issue was discussed and a potential solution was proposed, but it was not merged.
I see that a similar issue could come up in I'll post a few # surface_tilt, surface_azimuth, dhi, dni, dni_et, solar_zenith, solar_azimuth
In [148]: pvlib.irradiance.haydavies(30, 180, 50, 0, 1360, 90, 270)
Out[148]: 46.65063509461097
In [149]: pvlib.irradiance.haydavies(30, 180, 50, 1, 1360, 90, 270)
Out[149]: 46.66655467923936
In [150]: pvlib.irradiance.haydavies(30, 180, 50, 1, 1360, 90, 230)
Out[150]: 192969086526870.06
In [151]: pvlib.irradiance.haydavies(30, 180, 50, 0, 1360, 90, 230)
Out[151]: 46.65063509461097
In [152]: pvlib.irradiance.haydavies(30, 180, 50, 1, 1360, 89.9, 230)
Out[152]: 53.41820537086939
In [153]: pvlib.irradiance.haydavies(30, 180, 50, 1, 1360, 89.99, 230)
Out[153]: 114.34857082698177
In [154]: pvlib.irradiance.haydavies(30, 180, 50, 1, 1360, 89.999, 230)
Out[154]: 723.6521641382168
In [158]: pvlib.irradiance.reindl(30, 180, 50, 1, 50, 1360, 89.999, 230)
Out[158]: 723.6526416460301 So the functions behave ok for some problematic inputs but not for others. I think it's in the scope of pvlib to be able to gracefully handle these inputs.
We could do this here for consistency. It seems somewhat arbitrary but pragmatic to me. I looked at the git history and I saw that the original port did contain this code, but I removed it as one of many changes to clean up and simplify the library. My bad.
The pvlib implementation roughly follows the Loutzenhiser 2007 description of the model.
See Loutzenhiser 2007. The implementation is correct, it's just not numerically the best way to do it. |
I think the Sandia National Laboratories documentation is wrong on this one. Just imagine 100% circumsolar diffuse: tilted diffuse could never be greater than horizontal diffuse with this formula, even with the array pointed at the sun. |
Essentially the same problem occurs in the function |
I agree with this. Maybe focus on the ratio |
@adriesse you are correct, thanks for catching that. We wrote Loutzenhiser doesn't give an explicit expression for for example. |
The handling of zenith near 90 in PVLib for Matlab was our addition to Hay and Davies. An alternative value for Hay and Davies at zenith = 90 would be the isotropic sky diffuse component, reasoning that at zenith = 90 there is not direct or circumsolar irradiance that reaches a tilted surface near ground level. We could linearly interpolate from 89 (or 88) to 90. I am confident that the Hay and Davies model did not anticipate being applied at zenith = 90 and that we won't find any guidance in the original paper. |
The Hay-Davies model is equal to the isotropic model when DNI is 0. So, I think the matlab approach of ensuring that There is one more difference with the matlab implementation. In
Our python cos_tt = aoi_projection(surface_tilt, surface_azimuth,
solar_zenith, solar_azimuth)
cos_solar_zenith = tools.cosd(solar_zenith)
Rb = cos_tt / cos_solar_zenith The same discrepancy is also present in the Reindl implementations. So, that's another problem with the python implementations. |
A few issues with the pvlib package seem to be caused by dividing by cos(solar_zenith) since solar zenith can vary from 0-180 degrees. As the solar_zenith approaches 90 degrees, these results will approach infinity. The problem becomes very apparent when the value of solar_zenith is between 89 and 90 degrees which is rare unless working with minute interval (or smaller) because the denominator then becomes a large scaling factor. I have attached a quick sample code to illustrate the issue.
cos(solar_zenith)_errors.txt
A few questions and comments to note:
This seems to have been addressed in a similar context in the DISC Model and Zenith Threshold issue but appear again in the haydavies algorithm implementation on line 729 of irradiance.py when calculating the projection_ratio and could potentially appear elsewhere in the package.
The MATLAB version of the haydavies algorithm, pvl_haydavies1980.m, uses the formula "RB = max(COSTT, 0) ./ max(cosd(SunZen), 0.01745))" where 0.01745 corresponds to a zenith angle of 89 degrees to avoid the issue.
Sandia National Laboratories documentation seems to suggest that dividing by cos(solar_zenith) is not part of the Hay and Davies diffuse model.
Is there a documented reason for the differences between these formulas or is this a mistake in implementation?
The text was updated successfully, but these errors were encountered: