@@ -710,3 +710,102 @@ def spectral_factor_jrc(airmass, clearsky_index, module_type=None,
710710 + coeff [2 ] * (airmass - 1.5 )
711711 )
712712 return mismatch
713+
714+ def spectral_factor_polo (precipitable_water , airmass_absolute , aod500 , aoi , altitude ,
715+ module_type = None , coefficients = None , albedo = 0.2 ):
716+ """
717+ Estimation of spectral mismatch for BIPV application in vertical facades.
718+
719+
720+
721+ Parameters
722+ ----------
723+ precipitable_water : numeric
724+ atmospheric precipitable water. [cm]
725+
726+ airmass_absolute : numeric
727+ absolute (pressure-adjusted) airmass. [unitless]
728+
729+ aod500 : numeric
730+ atmospheric aerosol optical depth at 500 nm. [unitless]
731+
732+ aoi : numeric
733+ angle of incidence. [degrees]
734+
735+ altitude: numeric
736+ altitude over sea level. [m]
737+
738+ module_type : str, optional
739+ One of the following PV technology strings from [1]_:
740+
741+ * ``'cdte'`` - anonymous CdTe module.
742+ * ``'monosi'`` - anonymous sc-si module.
743+ * ``'cigs'`` - anonymous copper indium gallium selenide module.
744+ * ``'asi'`` - anonymous amorphous silicon module.
745+ albedo
746+ Ground albedo (default value if 0.2). [unitless]
747+
748+ coefficients : array-like, optional
749+ user-defined coefficients, if not using one of the default coefficient
750+ sets via the ``module_type`` parameter.
751+
752+ Returns
753+ -------
754+ modifier: numeric
755+ spectral mismatch factor (unitless) which is multiplied
756+ with broadband irradiance reaching a module's cells to estimate
757+ effective irradiance, i.e., the irradiance that is converted to
758+ electrical current.
759+
760+ References
761+ ----------
762+ [1]. Polo, J., Sanz-saiz, C., Development of spectral mismatch models
763+ for BIPV applications in building façades Abbreviations : Renew. Energy 245, 122820, 2025.
764+ https://doi.org/10.1016/j.renene.2025.122820
765+
766+ """
767+ if module_type is None and coefficients is None :
768+ raise ValueError ('Must provide either `module_type` or `coefficients`' )
769+ if module_type is not None and coefficients is not None :
770+ raise ValueError ('Only one of `module_type` and `coefficients` should '
771+ 'be provided' )
772+
773+ am_aoi = pvlib .atmosphere .get_relative_airmass (aoi )
774+ pressure = pvlib .atmosphere .alt2pres (altitude )
775+ am90 = pvlib .atmosphere .get_absolute_airmass (am_aoi ,pressure )
776+ Ram = am90 / airmass_absolute
777+
778+ _coefficients = {}
779+ _coefficients ['cdte' ]= (
780+ - 0.0009 ,46.80 ,49.20 ,- 0.87 , 0.00041 ,0.053 )
781+ _coefficients ['monosi' ]= (
782+ 0.0027 ,10.34 ,9.48 ,0.307 ,0.00077 ,0.006 )
783+ _coefficients ['cigs' ]= (
784+ 0.0017 ,2.33 ,1.30 ,0.11 ,0.00098 ,- 0.0177 )
785+ _coefficients ['asi' ]= (
786+ 0.0024 ,7.32 ,7.09 ,- 0.72 ,- 0.0013 ,0.089 )
787+
788+ c = {}
789+ c ['asi' ]= (0.0056 ,- 0.020 ,1.014 )
790+ c ['cigs' ]= (- 0.0009 ,- 0.0003 ,1 )
791+ c ['cdte' ]= (0.0021 ,- 0.01 ,1.01 )
792+ c ['monosi' ]= (0 ,- 0.003 ,1.0 )
793+
794+
795+ if module_type is not None :
796+ coeff = _coefficients [module_type ]
797+ c_albedo = c [module_type ]
798+ else :
799+ coeff = coefficients
800+ c_albedo = (0.0 ,0.0 ,1.0 ) # 0.2 albedo assumed
801+ albedo = 0.2
802+
803+
804+ smm = coeff [0 ]* Ram + coeff [1 ]/ (coeff [2 ]+ Ram ** coeff [3 ])+ coeff [4 ]/ aod500 + coeff [5 ]* np .sqrt (precipitable_water )
805+ # Ground albedo correction
806+
807+ g = c_albedo [0 ]* (albedo / 0.2 )** 2 + c_albedo [1 ]* (albedo / 0.2 )+ c_albedo [2 ]
808+
809+
810+ return g * smm
811+
0 commit comments