@@ -540,7 +540,7 @@ def marion_diffuse(model, surface_tilt, **kwargs):
540540 ----------
541541 model : str
542542 The IAM function to evaluate across solid angle. Must be one of
543- `'ashrae', 'physical', 'martin_ruiz', 'sapm'`.
543+ `'ashrae', 'physical', 'martin_ruiz', 'sapm', 'schlick' `.
544544
545545 surface_tilt : numeric
546546 Surface tilt angles in decimal degrees.
@@ -591,6 +591,7 @@ def marion_diffuse(model, surface_tilt, **kwargs):
591591 'ashrae' : ashrae ,
592592 'sapm' : sapm ,
593593 'martin_ruiz' : martin_ruiz ,
594+ 'schlick' : schlick ,
594595 }
595596
596597 try :
@@ -747,3 +748,123 @@ def marion_integrate(function, surface_tilt, region, num=None):
747748 Fd = pd .Series (Fd , surface_tilt .index )
748749
749750 return Fd
751+
752+
753+ def schlick (aoi ):
754+ """
755+ Determine incidence angle modifier (IAM) for direct irradiance using the
756+ Schlick approximation to the Fresnel equations.
757+
758+ The Schlick approximation was proposed in [1]_ as a computationally
759+ efficient alternative to computing the Fresnel factor in computer
760+ graphics contexts. This implementation is a normalized form of the
761+ equation in [1]_ so that it can be used as a PV IAM model.
762+ Unlike other IAM models, this model has no ability to describe
763+ different reflection profiles.
764+
765+ In PV contexts, the Schlick approximation has been used as an analytically
766+ integrable alternative to the Fresnel equations for estimating IAM
767+ for diffuse irradiance [2]_.
768+
769+ Parameters
770+ ----------
771+ aoi : numeric
772+ The angle of incidence (AOI) between the module normal vector and the
773+ sun-beam vector. Angles of nan will result in nan. [degrees]
774+
775+ Returns
776+ -------
777+ iam : numeric
778+ The incident angle modifier.
779+
780+ References
781+ ----------
782+ .. [1] Schlick, C. An inexpensive BRDF model for physically-based
783+ rendering. Computer graphics forum 13 (1994).
784+
785+ .. [2] Xie, Y., M. Sengupta, A. Habte, A. Andreas, "The 'Fresnel Equations'
786+ for Diffuse radiation on Inclined photovoltaic Surfaces (FEDIS)",
787+ Renewable and Sustainable Energy Reviews, vol. 161, 112362. June 2022.
788+ :doi:`10.1016/j.rser.2022.112362`
789+
790+ See Also
791+ --------
792+ pvlib.iam.schlick_diffuse
793+ """
794+ iam = 1 - (1 - cosd (aoi )) ** 5
795+ iam = np .where (np .abs (aoi ) >= 90.0 , 0.0 , iam )
796+
797+ # preserve input type
798+ if np .isscalar (aoi ):
799+ iam = iam .item ()
800+ elif isinstance (aoi , pd .Series ):
801+ iam = pd .Series (iam , aoi .index )
802+
803+ return iam
804+
805+
806+ def schlick_diffuse (surface_tilt ):
807+ """
808+ Determine the incidence angle modifiers (IAM) for diffuse sky and
809+ ground-reflected irradiance on a tilted surface using the Schlick
810+ incident angle model.
811+
812+ The diffuse iam values are calculated using an analytical integration
813+ of the Schlick equation [1]_ over the portion of an isotropic sky and
814+ isotropic foreground that is visible from the tilted surface [2]_.
815+
816+ Parameters
817+ ----------
818+ surface_tilt : numeric
819+ Surface tilt angle measured from horizontal (e.g. surface facing
820+ up = 0, surface facing horizon = 90). [degrees]
821+
822+ Returns
823+ -------
824+ iam_sky : numeric
825+ The incident angle modifier for sky diffuse.
826+
827+ iam_ground : numeric
828+ The incident angle modifier for ground-reflected diffuse.
829+
830+ References
831+ ----------
832+ .. [1] Schlick, C. An inexpensive BRDF model for physically-based
833+ rendering. Computer graphics forum 13 (1994).
834+
835+ .. [2] Xie, Y., M. Sengupta, A. Habte, A. Andreas, "The 'Fresnel Equations'
836+ for Diffuse radiation on Inclined photovoltaic Surfaces (FEDIS)",
837+ Renewable and Sustainable Energy Reviews, vol. 161, 112362. June 2022.
838+ :doi:`10.1016/j.rser.2022.112362`
839+
840+ See Also
841+ --------
842+ pvlib.iam.schlick
843+ """
844+ # these calculations are as in [2]_, but with the refractive index
845+ # weighting coefficient w set to 1.0 (so it is omitted)
846+
847+ # relative transmittance of sky diffuse radiation by PV cover:
848+ cosB = cosd (surface_tilt )
849+ sinB = sind (surface_tilt )
850+ cuk = (2 / (np .pi * (1 + cosB ))) * (
851+ (30 / 7 )* np .pi - (160 / 21 )* np .radians (surface_tilt ) - (10 / 3 )* np .pi * cosB
852+ + (160 / 21 )* cosB * sinB - (5 / 3 )* np .pi * cosB * sinB ** 2 + (20 / 7 )* cosB * sinB ** 3
853+ - (5 / 16 )* np .pi * cosB * sinB ** 4 + (16 / 105 )* cosB * sinB ** 5
854+ ) # Eq 4 in [2]
855+
856+ # relative transmittance of ground-reflected radiation by PV cover:
857+ with np .errstate (divide = 'ignore' , invalid = 'ignore' ): # Eq 6 in [2]
858+ cug = 40 / (21 * (1 - cosB )) - (1 + cosB ) / (1 - cosB ) * cuk
859+
860+ cug = np .where (surface_tilt < 1e-6 , 0 , cug )
861+
862+ # respect input types:
863+ if np .isscalar (surface_tilt ):
864+ cuk = cuk .item ()
865+ cug = cug .item ()
866+ elif isinstance (surface_tilt , pd .Series ):
867+ cuk = pd .Series (cuk , surface_tilt .index )
868+ cug = pd .Series (cug , surface_tilt .index )
869+
870+ return cuk , cug
0 commit comments