@@ -287,3 +287,118 @@ def _linearly_scale(inputmatrix, inputmin, inputmax, outputmin, outputmax):
287
287
outputrange = outputmax - outputmin
288
288
OutputMatrix = (inputmatrix - inputmin ) * outputrange / inputrange + outputmin
289
289
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