@@ -2886,53 +2886,118 @@ def scale_voltage_current_power(data, voltage=1, current=1):
28862886
28872887@renamed_kwarg_warning (
28882888 "0.13.0" , "g_poa_effective" , "effective_irradiance" )
2889- def pvwatts_dc (effective_irradiance , temp_cell , pdc0 , gamma_pdc , temp_ref = 25. ):
2889+ def pvwatts_dc (effective_irradiance , temp_cell , pdc0 , gamma_pdc , temp_ref = 25. ,
2890+ k = None , cap_adjustment = False ):
28902891 r"""
2891- Implements NREL's PVWatts DC power model. The PVWatts DC model [1]_ is:
2892-
2893- .. math::
2894-
2895- P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref}))
2896-
2897- Note that ``pdc0`` is also used as a symbol in
2898- :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC
2899- power of the modules at reference conditions. ``pdc0`` in
2900- :py:func:`pvlib.inverter.pvwatts` refers to the DC power input limit of
2901- the inverter.
2892+ Implement NREL's PVWatts (Version 5) DC power model.
29022893
29032894 Parameters
29042895 ----------
29052896 effective_irradiance: numeric
2906- Irradiance transmitted to the PV cells. To be
2907- fully consistent with PVWatts, the user must have already
2908- applied angle of incidence losses, but not soiling, spectral,
2909- etc. [W/m^2]
2897+ Irradiance transmitted to the PV cells. To be fully consistent with
2898+ PVWatts, the user must have already applied angle of incidence losses,
2899+ but not soiling, spectral, etc. [Wm⁻²]
29102900 temp_cell: numeric
29112901 Cell temperature [C].
29122902 pdc0: numeric
2913- Power of the modules at 1000 W/m^2 and cell reference temperature. [W]
2903+ Power of the modules at 1000 Wm⁻² and cell reference temperature. [W]
29142904 gamma_pdc: numeric
2915- The temperature coefficient of power. Typically -0.002 to
2916- -0.005 per degree C. [1/C]
2905+ The temperature coefficient of power. Typically -0.002 to -0.005 per
2906+ degree C. [1/° C]
29172907 temp_ref: numeric, default 25.0
2918- Cell reference temperature. PVWatts defines it to be 25 C and
2919- is included here for flexibility. [C]
2908+ Cell reference temperature. PVWatts defines it to be 25 °C and is
2909+ included here for flexibility. [°C]
2910+ k: numeric, optional
2911+ Irradiance correction factor, defined in [2]_. Typically positive.
2912+ [unitless]
2913+ cap_adjustment: Boolean, default False
2914+ If True, only apply the optional adjustment at and below 1000 Wm⁻²
29202915
29212916 Returns
29222917 -------
29232918 pdc: numeric
29242919 DC power. [W]
29252920
2921+ Notes
2922+ -----
2923+ The PVWatts Version 5 DC model [1]_ is:
2924+
2925+ .. math::
2926+
2927+ P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref}))
2928+
2929+ This model has also been referred to as the power temperature coefficient
2930+ model.
2931+
2932+ An optional adjustment can be applied to :math:`P_{dc}` as described in
2933+ [2]_. The adjustment accounts for the variation in module efficiency with
2934+ irradiance. The piece-wise adjustment to power is parameterized by `k`,
2935+ where `k` is the reduction in actual power at 200 Wm⁻² relative to power
2936+ calculated at 200 Wm⁻² as 0.2*`pdc0`. For example, a module that is rated
2937+ at 500 W at STC but produces 95 W at 200 Wm⁻² (a 5% relative reduction in
2938+ efficiency) would have a value of `k` = 0.01.
2939+
2940+ .. math::
2941+
2942+ k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}}
2943+
2944+ For positive `k` values, and `k` is typically positive, this adjustment
2945+ would also increase relative efficiency when irradiance is above 1000 Wm⁻².
2946+ This may not be desired, as modules with nonlinear irradiance response
2947+ often have peak efficiency near 1000 Wm⁻², and it is either flat or
2948+ declining at higher irradiance. An optional parameter, `cap_adjustment`,
2949+ can address this by modifying the adjustment from [2]_ to only apply below
2950+ 1000 Wm⁻².
2951+
2952+ Note that ``pdc0`` is also used as a symbol in
2953+ :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the
2954+ DC power of the modules at reference conditions. ``pdc0`` in
2955+ :py:func:`pvlib.inverter.pvwatts` refers to the DC power input limit of
2956+ the inverter.
2957+
29262958 References
29272959 ----------
29282960 .. [1] A. P. Dobos, "PVWatts Version 5 Manual"
29292961 http://pvwatts.nrel.gov/downloads/pvwattsv5.pdf
29302962 (2014).
2963+ .. [2] B. Marion, "Comparison of Predictive Models for
2964+ Photovoltaic Module Performance,"
2965+ :doi:`10.1109/PVSC.2008.4922586`,
2966+ https://docs.nrel.gov/docs/fy08osti/42511.pdf
2967+ (2008).
29312968 """ # noqa: E501
29322969
29332970 pdc = (effective_irradiance * 0.001 * pdc0 *
29342971 (1 + gamma_pdc * (temp_cell - temp_ref )))
29352972
2973+ # apply Marion's correction if k is provided
2974+ if k is not None :
2975+
2976+ # preserve input types
2977+ index = pdc .index if isinstance (pdc , pd .Series ) else None
2978+ is_scalar = np .isscalar (pdc )
2979+
2980+ # calculate error adjustments
2981+ err_1 = k * (1 - (1 - effective_irradiance / 200 )** 4 )
2982+ err_2 = k * (1000 - effective_irradiance ) / (1000 - 200 )
2983+ err = np .where (effective_irradiance <= 200 , err_1 , err_2 )
2984+
2985+ # cap adjustment, if needed
2986+ if cap_adjustment :
2987+ err = np .where (effective_irradiance >= 1000 , 0 , err )
2988+
2989+ # make error adjustment
2990+ pdc = pdc - pdc0 * err
2991+
2992+ # set negative power to zero
2993+ pdc = np .where (pdc < 0 , 0 , pdc )
2994+
2995+ # preserve input types
2996+ if index is not None :
2997+ pdc = pd .Series (pdc , index = index )
2998+ elif is_scalar :
2999+ pdc = float (pdc )
3000+
29363001 return pdc
29373002
29383003
0 commit comments