Skip to content

DISC fixes #26

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 3 commits into from
Mar 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 61 additions & 60 deletions pvlib/clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,10 @@ def _linearly_scale(inputmatrix, inputmin, inputmax, outputmin, outputmax):



def disc(GHI, SunZen, Time, pressure=101325):
def disc(GHI, zenith, times, pressure=101325):
'''
Estimate Direct Normal Irradiance from Global Horizontal Irradiance using the DISC model
Estimate Direct Normal Irradiance from Global Horizontal Irradiance
using the DISC model.

The DISC algorithm converts global horizontal irradiance to direct
normal irradiance through empirical relationships between the global
Expand All @@ -295,35 +296,27 @@ def disc(GHI, SunZen, Time, pressure=101325):
Parameters
----------

GHI : float or DataFrame
global horizontal irradiance in W/m^2. GHI must be >=0.
GHI : Series
Global horizontal irradiance in W/m^2.

Z : float or DataFrame
True (not refraction - corrected) zenith angles in decimal degrees.
Z must be >=0 and <=180.
zenith : Series
True (not refraction - corrected) solar zenith
angles in decimal degrees.

doy : float or DataFrame
the day of the year. doy must be >= 1 and < 367.
times : DatetimeIndex

Other Parameters
----------------

pressure : float or DataFrame (optional, Default=101325)

site pressure in Pascal. Pressure may be measured
or an average pressure may be calculated from site altitude. If
pressure is omitted, standard pressure (101325 Pa) will be used, this
is acceptable if the site is near sea level. If the site is not near
sea:level, inclusion of a measured or average pressure is highly
recommended.
pressure : float or Series
Site pressure in Pascal.

Returns
-------
DNI : float or DataFrame
The modeled direct normal irradiance in W/m^2 provided by the
Direct Insolation Simulation Code (DISC) model.
Kt : float or DataFrame
Ratio of global to extraterrestrial irradiance on a horizontal plane.
DataFrame with the following keys:
* ``DNI_gen_DISC``: The modeled direct normal irradiance
in W/m^2 provided by the
Direct Insolation Simulation Code (DISC) model.
* ``Kt_gen_DISC``: Ratio of global to extraterrestrial
irradiance on a horizontal plane.
* ``AM``: Airmass

References
----------
Expand All @@ -343,46 +336,54 @@ def disc(GHI, SunZen, Time, pressure=101325):
ephemeris
alt2pres
dirint

'''

#create a temporary dataframe to house masked values, initially filled with NaN
temp=pd.DataFrame(index=Time,columns=['A','B','C'])


pressure=101325
doy=Time.dayofyear
DayAngle=2.0 * np.pi*((doy - 1)) / 365
re=1.00011 + 0.034221*(np.cos(DayAngle)) + (0.00128)*(np.sin(DayAngle)) + 0.000719*(np.cos(2.0 * DayAngle)) + (7.7e-05)*(np.sin(2.0 * DayAngle))
I0=re*(1370)
I0h=I0*(np.cos(np.radians(SunZen)))
Ztemp=SunZen
Ztemp[SunZen > 87]=87
AM=1.0 / (np.cos(np.radians(Ztemp)) + 0.15*(((93.885 - Ztemp) ** (- 1.253))))*(pressure) / 101325
Kt=GHI / (I0h)
Kt[Kt < 0]=0
Kt[Kt > 2]=np.NaN
temp.A[Kt > 0.6]=- 5.743 + 21.77*(Kt[Kt > 0.6]) - 27.49*(Kt[Kt > 0.6] ** 2) + 11.56*(Kt[Kt > 0.6] ** 3)
temp.B[Kt > 0.6]=41.4 - 118.5*(Kt[Kt > 0.6]) + 66.05*(Kt[Kt > 0.6] ** 2) + 31.9*(Kt[Kt > 0.6] ** 3)
temp.C[Kt > 0.6]=- 47.01 + 184.2*(Kt[Kt > 0.6]) - 222.0 * Kt[Kt > 0.6] ** 2 + 73.81*(Kt[Kt > 0.6] ** 3)
temp.A[(Kt <= 0.6-1)]=0.512 - 1.56*(Kt[(Kt <= 0.6-1)]) + 2.286*(Kt[(Kt <= 0.6-1)] ** 2) - 2.222*(Kt[(Kt <= 0.6-1)] ** 3)
temp.B[(Kt <= 0.6-1)]=0.37 + 0.962*(Kt[(Kt <= 0.6-1)])
temp.C[(Kt <= 0.6-1)]=- 0.28 + 0.932*(Kt[(Kt <= 0.6-1)]) - 2.048*(Kt[(Kt <= 0.6-1)] ** 2)
logger.debug('clearsky.disc')

temp = pd.DataFrame(index=times, columns=['A','B','C'])

doy = times.dayofyear

DayAngle = 2. * np.pi*(doy - 1) / 365

re = (1.00011 + 0.034221*np.cos(DayAngle) + 0.00128*np.sin(DayAngle)
+ 0.000719*np.cos(2.*DayAngle) + 7.7e-05*np.sin(2.*DayAngle) )

I0 = re * 1370.
I0h = I0 * np.cos(np.radians(zenith))

Ztemp = zenith.copy()
Ztemp[zenith > 87] = np.NaN

AM = 1.0 / ( np.cos(np.radians(Ztemp)) + 0.15*( (93.885 - Ztemp)**(-1.253) ) ) * (pressure / 101325)

Kt = GHI / I0h
Kt[Kt < 0] = 0
Kt[Kt > 2] = np.NaN

temp.A[Kt > 0.6] = -5.743 + 21.77*(Kt[Kt > 0.6]) - 27.49*(Kt[Kt > 0.6] ** 2) + 11.56*(Kt[Kt > 0.6] ** 3)
temp.B[Kt > 0.6] = 41.4 - 118.5*(Kt[Kt > 0.6]) + 66.05*(Kt[Kt > 0.6] ** 2) + 31.9*(Kt[Kt > 0.6] ** 3)
temp.C[Kt > 0.6] = -47.01 + 184.2*(Kt[Kt > 0.6]) - 222.0 * Kt[Kt > 0.6] ** 2 + 73.81*(Kt[Kt > 0.6] ** 3)
temp.A[Kt <= 0.6] = 0.512 - 1.56*(Kt[Kt <= 0.6]) + 2.286*(Kt[Kt <= 0.6] ** 2) - 2.222*(Kt[Kt <= 0.6] ** 3)
temp.B[Kt <= 0.6] = 0.37 + 0.962*(Kt[Kt <= 0.6])
temp.C[Kt <= 0.6] = -0.28 + 0.932*(Kt[Kt <= 0.6]) - 2.048*(Kt[Kt <= 0.6] ** 2)

#return to numeric after masking operations
temp=temp.astype(float)
delKn=temp.A + temp.B*((temp.C*(AM)).apply(np.exp))
Knc=0.866 - 0.122*(AM) + 0.0121*(AM ** 2) - 0.000653*(AM ** 3) + 1.4e-05*(AM ** 4)
Kn=Knc - delKn
DNI=(Kn)*(I0)
temp = temp.astype(float)

DNI[SunZen > 87]=np.NaN
DNI[GHI < 1]=np.NaN
DNI[DNI < 0]=np.NaN
delKn = temp.A + temp.B * np.exp(temp.C*AM)

Knc = 0.866 - 0.122*(AM) + 0.0121*(AM ** 2) - 0.000653*(AM ** 3) + 1.4e-05*(AM ** 4)
Kn = Knc - delKn

DNI = Kn * I0

DFOut=pd.DataFrame({'DNI_gen_DISC':DNI})
DNI[zenith > 87] = np.NaN
DNI[GHI < 1] = np.NaN
DNI[DNI < 0] = np.NaN

DFOut['Kt_gen_DISC']=Kt
DFOut['AM']=AM
DFOut['Ztemp']=Ztemp
DFOut = pd.DataFrame({'DNI_gen_DISC':DNI})
DFOut['Kt_gen_DISC'] = Kt
DFOut['AM'] = AM

return DFOut
22 changes: 22 additions & 0 deletions pvlib/test/test_clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from nose.tools import raises

from numpy.testing import assert_almost_equal

from pvlib.location import Location
from pvlib import clearsky
from pvlib import solarposition
Expand Down Expand Up @@ -54,3 +56,23 @@ def test_haurwitz():
def test_haurwitz_keys():
clearsky_data = clearsky.haurwitz(ephem_data['zenith'])
assert 'GHI' in clearsky_data.columns


# test DISC
def test_disc_keys():
clearsky_data = clearsky.ineichen(times, tus)
disc_data = clearsky.disc(clearsky_data['GHI'], ephem_data['zenith'],
ephem_data.index)
assert 'DNI_gen_DISC' in disc_data.columns
assert 'Kt_gen_DISC' in disc_data.columns
assert 'AM' in disc_data.columns

def test_disc_value():
times = pd.DatetimeIndex(['2014-06-24T12-0700','2014-06-24T18-0700'])
ghi = pd.Series([1038.62, 254.53], index=times)
zenith = pd.Series([10.567, 72.469], index=times)
pressure = 93193.
disc_data = clearsky.disc(ghi, zenith, times, pressure=pressure)
assert_almost_equal(disc_data['DNI_gen_DISC'].values,
np.array([830.46, 676.09]), 1)