Skip to content

Commit 3b751e1

Browse files
committed
Merge pull request #14 from wholmgren/develop
merge sandia cherry-pick via develop
2 parents b850108 + 688058f commit 3b751e1

File tree

2 files changed

+116
-2
lines changed

2 files changed

+116
-2
lines changed

Diff for: pvlib/__init__.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11

22
import logging
33
logging.basicConfig()
4-
4+
from . import pvl_tools
55
from . import atmosphere
66
from . import clearsky
77
from . import irradiance
88
from . import location
9-
from . import pvl_tools
109
from . import solarposition
1110
from . import tmy
1211

Diff for: pvlib/clearsky.py

+115
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,118 @@ def _linearly_scale(inputmatrix, inputmin, inputmax, outputmin, outputmax):
287287
outputrange = outputmax - outputmin
288288
OutputMatrix = (inputmatrix - inputmin) * outputrange / inputrange + outputmin
289289
return OutputMatrix
290+
291+
292+
293+
def disc(GHI, SunZen, Time, pressure=101325):
294+
'''
295+
Estimate Direct Normal Irradiance from Global Horizontal Irradiance using the DISC model
296+
297+
The DISC algorithm converts global horizontal irradiance to direct
298+
normal irradiance through empirical relationships between the global
299+
and direct clearness indices.
300+
301+
Parameters
302+
----------
303+
304+
GHI : float or DataFrame
305+
global horizontal irradiance in W/m^2. GHI must be >=0.
306+
307+
Z : float or DataFrame
308+
True (not refraction - corrected) zenith angles in decimal degrees.
309+
Z must be >=0 and <=180.
310+
311+
doy : float or DataFrame
312+
313+
the day of the year. doy must be >= 1 and < 367.
314+
315+
Other Parameters
316+
----------------
317+
318+
pressure : float or DataFrame (optional, Default=101325)
319+
320+
site pressure in Pascal. Pressure may be measured
321+
or an average pressure may be calculated from site altitude. If
322+
pressure is omitted, standard pressure (101325 Pa) will be used, this
323+
is acceptable if the site is near sea level. If the site is not near
324+
sea:level, inclusion of a measured or average pressure is highly
325+
recommended.
326+
327+
Returns
328+
-------
329+
DNI : float or DataFrame
330+
The modeled direct normal irradiance in W/m^2 provided by the
331+
Direct Insolation Simulation Code (DISC) model.
332+
Kt : float or DataFrame
333+
Ratio of global to extraterrestrial irradiance on a horizontal plane.
334+
335+
References
336+
----------
337+
338+
[1] Maxwell, E. L., "A Quasi-Physical Model for Converting Hourly
339+
Global Horizontal to Direct Normal Insolation", Technical
340+
Report No. SERI/TR-215-3087, Golden, CO: Solar Energy Research
341+
Institute, 1987.
342+
343+
[2] J.W. "Fourier series representation of the position of the sun".
344+
Found at:
345+
http://www.mail-archive.com/[email protected]/msg01050.html on
346+
January 12, 2012
347+
348+
See Also
349+
--------
350+
pvl_ephemeris
351+
pvl_alt2pres
352+
pvl_dirint
353+
354+
'''
355+
356+
Vars=locals()
357+
Expect={'GHI': ('array','num','x>=0'),
358+
'SunZen': ('array','num','x<=180','x>=0'),
359+
'Time':'',
360+
'pressure':('num','default','default=101325','x>=0'),
361+
}
362+
363+
var=pvl_tools.Parse(Vars,Expect)
364+
365+
#create a temporary dataframe to house masked values, initially filled with NaN
366+
temp=pd.DataFrame(index=var.Time,columns=['A','B','C'])
367+
368+
369+
var.pressure=101325
370+
doy=var.Time.dayofyear
371+
DayAngle=2.0 * np.pi*((doy - 1)) / 365
372+
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))
373+
I0=re*(1370)
374+
I0h=I0*(np.cos(np.radians(var.SunZen)))
375+
Ztemp=var.SunZen
376+
Ztemp[var.SunZen > 87]=87
377+
AM=1.0 / (np.cos(np.radians(Ztemp)) + 0.15*(((93.885 - Ztemp) ** (- 1.253))))*(var.pressure) / 101325
378+
Kt=var.GHI / (I0h)
379+
Kt[Kt < 0]=0
380+
Kt[Kt > 2]=np.NaN
381+
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)
382+
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)
383+
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)
384+
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)
385+
temp.B[(Kt <= 0.6-1)]=0.37 + 0.962*(Kt[(Kt <= 0.6-1)])
386+
temp.C[(Kt <= 0.6-1)]=- 0.28 + 0.932*(Kt[(Kt <= 0.6-1)]) - 2.048*(Kt[(Kt <= 0.6-1)] ** 2)
387+
#return to numeric after masking operations
388+
temp=temp.astype(float)
389+
delKn=temp.A + temp.B*((temp.C*(AM)).apply(np.exp))
390+
Knc=0.866 - 0.122*(AM) + 0.0121*(AM ** 2) - 0.000653*(AM ** 3) + 1.4e-05*(AM ** 4)
391+
Kn=Knc - delKn
392+
DNI=(Kn)*(I0)
393+
394+
DNI[var.SunZen > 87]=np.NaN
395+
DNI[var.GHI < 1]=np.NaN
396+
DNI[DNI < 0]=np.NaN
397+
398+
DFOut=pd.DataFrame({'DNI_gen_DISC':DNI})
399+
400+
DFOut['Kt_gen_DISC']=Kt
401+
DFOut['AM']=AM
402+
DFOut['Ztemp']=Ztemp
403+
404+
return DFOut

0 commit comments

Comments
 (0)