Skip to content

Commit

Permalink
Merge branch 'main' into ref_ground_diffuse
Browse files Browse the repository at this point in the history
  • Loading branch information
cwhanse authored Feb 27, 2024
2 parents 2e4f2f2 + 1e4d6f5 commit 816a8f8
Show file tree
Hide file tree
Showing 17 changed files with 378 additions and 124 deletions.
10 changes: 5 additions & 5 deletions docs/sphinx/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ Additional pvlib python publications include:

* J. S. Stein, “The photovoltaic performance modeling
collaborative (PVPMC),” in Photovoltaic Specialists Conference, 2012.
* R.W. Andrews, J.S. Stein, C. Hansen, and D. Riley, Introduction
to the open source pvlib for python photovoltaic system
modelling package,” in 40th IEEE Photovoltaic Specialist
Conference, 2014.
* R. W. Andrews, J. S. Stein, C. Hansen and D. Riley, "Introduction to the open
source PV LIB for python Photovoltaic system modelling package,"
2014 IEEE 40th Photovoltaic Specialist Conference (PVSC), Denver, CO, USA,
2014, pp. 0170-0174, https://doi.org/10.1109/PVSC.2014.6925501
(`paper
<http://energy.sandia.gov/wp/wp-content/gallery/uploads/PV_LIB_Python_final_SAND2014-18444C.pdf>`__)
<https://www.osti.gov/servlets/purl/1241774>`__)
* W.F. Holmgren, R.W. Andrews, A.T. Lorenzo, and J.S. Stein,
“PVLIB Python 2015,” in 42nd Photovoltaic Specialists Conference, 2015.
(`paper
Expand Down
8 changes: 8 additions & 0 deletions docs/sphinx/source/reference/pv_modeling/system_models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@ ADR model

pvarray.pvefficiency_adr
pvarray.fit_pvefficiency_adr

PVGIS model
^^^^^^^^^^^

.. autosummary::
:toctree: ../generated/

pvarray.huld
16 changes: 1 addition & 15 deletions docs/sphinx/source/user_guide/clearsky.rst
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,6 @@ Validation

See [Ine02]_, [Ren12]_.

Will Holmgren compared pvlib's Ineichen model and climatological
turbidity to `SoDa's McClear service
<http://www.soda-pro.com/web-services/radiation/cams-mcclear>`_ in
Arizona. Here are links to an
`ipynb notebook
<https://forecasting.energy.arizona.edu/media/ineichen_vs_mcclear.ipynb>`_
and its `html rendering
<https://forecasting.energy.arizona.edu/media/ineichen_vs_mcclear.html>`_.


.. _simplified_solis:

Expand All @@ -370,9 +361,7 @@ Aerosol and precipitable water data
There are a number of sources for aerosol and precipitable water data
of varying accuracy, global coverage, and temporal resolution.
Ground based aerosol data can be obtained from
`Aeronet <http://aeronet.gsfc.nasa.gov>`_. Precipitable water can be obtained
from `radiosondes <http://weather.uwyo.edu/upperair/sounding.html>`_,
`ESRL GPS-MET <http://gpsmet.noaa.gov/cgi-bin/gnuplots/rti.cgi>`_, or
`Aeronet <http://aeronet.gsfc.nasa.gov>`_. Precipitable water can be
derived from surface relative humidity using functions such as
:py:func:`pvlib.atmosphere.gueymard94_pw`.
Numerous gridded products from satellites, weather models, and climate models
Expand Down Expand Up @@ -577,9 +566,6 @@ Validation

See [Ine16]_.

We encourage users to compare the pvlib implementation to Ineichen's
`Excel tool <http://www.unige.ch/energie/fr/equipe/ineichen/solis-tool/>`_.

.. _detect_clearsky:

Detect Clearsky
Expand Down
6 changes: 1 addition & 5 deletions docs/sphinx/source/user_guide/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ for pvlib, including Pandas, NumPy, and SciPy.
#. **Install** the Anaconda Python distribution available at
`Anaconda.com <https://www.anaconda.com/download/>`_.

See `What is Anaconda? <https://www.anaconda.com/what-is-anaconda/>`_
and the `Anaconda Documentation <https://docs.anaconda.com/anaconda/>`_
for more information.

You can now install pvlib-python by one of the methods below.


Expand All @@ -56,7 +52,7 @@ Users may install pvlib-python using either the
`conda <https://conda.io/docs/>`_ or `pip <https://pip.pypa.io>`_
package manager. We recommend that most users install pvlib-python
using the conda package manager in the
`Anaconda Python distribution <https://www.anaconda.com/what-is-anaconda/>`_.
Anaconda python distribution.
To install the most recent stable release of pvlib-python in a
non-editable way, use one of the following commands to install pvlib-python::

Expand Down
13 changes: 3 additions & 10 deletions docs/sphinx/source/user_guide/timetimezones.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,6 @@ You cannot localize a native Python date object.
pvlib-specific functionality
----------------------------

.. note::

This section applies to pvlib >= 0.3. Version 0.2 of pvlib used a
``Location`` object's ``tz`` attribute to auto-magically correct for
some time zone issues. This behavior was counter-intuitive to many
users and was removed in version 0.3.

How does this general functionality interact with pvlib? Perhaps the two
most common places to get tripped up with time and time zone issues in
solar power analysis occur during data import and solar position
Expand Down Expand Up @@ -315,9 +308,9 @@ DataFrame's index since the index has been localized.
ax.set_ylabel('(degrees)');
`According to the US Navy
<http://aa.usno.navy.mil/rstt/onedaytable?ID=AA&year=1997&month=1&day=1&state=AK&place=sand+point>`_,
on January 1, 1997 at Sand Point, Alaska, sunrise was at 10:09 am, solar
noon was at 1:46 pm, and sunset was at 5:23 pm. This is consistent with
<https://aa.usno.navy.mil/data/RS_OneDay>`_,
on January 1, 2024 at Sand Point, Alaska (55.34N, -160.5W), sunrise was at 10:09 am, solar
noon was at 1:46 pm, and sunset was at 5:22 pm. This is consistent with
the data plotted above (and depressing).

Solar position (assumed UTC)
Expand Down
10 changes: 3 additions & 7 deletions docs/sphinx/source/user_guide/variables_style_rules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ There is a convention on consistent variable names throughout the library:
For a definition and further explanation on the variables, common symbols and units refer to the following sources:


* `Reference Variable List by PVPMC <https://pvpmc.sandia.gov/resources-and-events/variable-list/>`_
* `IEC 61724-1:2017 -- Photovoltaic system performance - Part 1: Monitoring <https://webstore.iec.ch/publication/33622>`_ section: 3 -- Terms and definitions; the Indian Standard referencing the withdrawn earlier global IEC standard IEC 61724:1998 is available online: `IS/IEC 61724 (1998) <https://archive.org/details/gov.in.is.iec.61724.1998>`_ and can provide relevant contents.
* Explanation of Solar irradiation and solar geometry by `SoDa Service <http://www.soda-pro.com/home>`_

* `Acronyms, Terminology and Units <http://www.soda-pro.com/help/general/acronyms-terminology-and-units>`_
* `Plane orientations and radiation components <http://www.soda-pro.com/help/general/plane-orientations-and-radiation-components>`_
* `Time references <http://www.soda-pro.com/help/general/time-references>`_
* `Units and conversion tool <http://www.soda-is.com/eng/education/units.html>`_
* `Terminology: definitions of the main quantities. <http://www.soda-is.com/eng/education/terminology.html>`_
* `Acronyms in solar radiation <http://www.soda-is.com/eng/education/acronymes.html>`_ (more extensive list)
* `Acronyms, Terminology and Units <https://www.soda-pro.com/help/general/acronyms-terminology-and-units>`_
* `Plane orientations and radiation components <https://www.soda-pro.com/help/general/plane-orientations-and-radiation-components>`_
* `Time references <https://www.soda-pro.com/help/general/time-references>`_

.. note:: These further references might not use the same terminology as *pvlib*. But the physical process referred to is the same.
24 changes: 22 additions & 2 deletions docs/sphinx/source/whatsnew/v0.10.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,26 @@ v0.10.4 (Anticipated March, 2024)

Enhancements
~~~~~~~~~~~~
* Added the Huld PV model used by PVGIS (:pull:`1940`)


Bug fixes
~~~~~~~~~
* Fixed an error in solar position calculations when using
:py:class:`pandas.DatetimeIndex` with ``unit`` other than ``'ns'`` (:issue:`1932`).
The following functions were affected:

- :py:class:`~pvlib.modelchain.ModelChain` and :py:func:`~pvlib.solarposition.get_solarposition` with the ``nrel_numpy`` and ``nrel_numba`` methods
- :py:func:`~pvlib.solarposition.spa_python`
- :py:func:`~pvlib.solarposition.sun_rise_set_transit_spa`
- :py:func:`~pvlib.solarposition.nrel_earthsun_distance`
- :py:func:`~pvlib.solarposition.hour_angle`
- :py:func:`~pvlib.solarposition.sun_rise_set_transit_geometric`

* :py:class:`~pvlib.modelchain.ModelChain` now raises a more useful error when
``temperature_model_parameters`` are specified on the passed ``system`` instead of on its ``arrays``. (:issue:`1759`).
* :py:func:`pvlib.irradiance.ghi_from_poa_driesse_2023` now correctly makes use
of the ``xtol`` argument. Previously, it was ignored. (:issue:`1970`, :pull:`1971`)

Testing
~~~~~~~
Expand All @@ -21,7 +35,8 @@ Testing
Documentation
~~~~~~~~~~~~~
* Improved references and description for :py:func:`~pvlib.irradiance.get_ground_diffuse`. (:pull:`1953`)
* Fixed broken URLs in various docstrings. (:pull:`1957`)
* Fixed broken URLs in various places. (:pull:`1957`, :pull:`1960`)
* Clarified documentation for :py:func:`~pvlib.irradiance.get_ground_diffuse`. (:pull:`1883`)


Requirements
Expand All @@ -30,5 +45,10 @@ Requirements

Contributors
~~~~~~~~~~~~
* Patrick Sheehan (:ghuser:`patricksheehan`)
* Echedey Luis (:ghuser:`echedey-ls`)
* Kevin Anderson (:ghuser:`kandersolar`)
* Cliff Hansen (:ghuser:`cwhanse`)
* :ghuser:`matsuobasho`
* :ghuser:`cwhanse`
* Adam R. Jensen (:ghuser:`AdamRJensen`)
* Peter Dudfield (:ghuser:`peterdudfield`)
15 changes: 7 additions & 8 deletions pvlib/clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ def ineichen(apparent_zenith, airmass_absolute, linke_turbidity,
Implements the Ineichen and Perez clear sky model for global
horizontal irradiance (GHI), direct normal irradiance (DNI), and
calculates the clear-sky diffuse horizontal (DHI) component as the
difference between GHI and DNI*cos(zenith) as presented in [1, 2]. A
difference between GHI and DNI*cos(zenith) as presented in [1]_ [2]_. A
report on clear sky models found the Ineichen/Perez model to have
excellent performance with a minimal input data set [3].
excellent performance with a minimal input data set [3]_.
Default values for monthly Linke turbidity provided by SoDa [4, 5].
Default values for monthly Linke turbidity provided by SoDa [4]_, [5]_.
Parameters
-----------
Expand Down Expand Up @@ -80,12 +80,12 @@ def ineichen(apparent_zenith, airmass_absolute, linke_turbidity,
Clear Sky Models: Implementation and Analysis", Sandia National
Laboratories, SAND2012-2389, 2012.
.. [4] http://www.soda-is.com/eng/services/climat_free_eng.php#c5 (obtained
July 17, 2012).
.. [4] https://www.soda-pro.com/help/general-knowledge/linke-turbidity-factor
(accessed February 2, 2024).
.. [5] J. Remund, et. al., "Worldwide Linke Turbidity Information", Proc.
ISES Solar World Congress, June 2003. Goteborg, Sweden.
'''
''' # noqa: E501

# ghi is calculated using either the equations in [1] by setting
# perez_enhancement=False (default behavior) or using the model
Expand Down Expand Up @@ -993,8 +993,7 @@ def bird(zenith, airmass_relative, aod380, aod500, precipitable_water,
.. [3] `NREL Bird Clear Sky Model <http://rredc.nrel.gov/solar/models/
clearsky/>`_
.. [4] `SERI/TR-642-761 <http://rredc.nrel.gov/solar/pubs/pdfs/
tr-642-761.pdf>`_
.. [4] `SERI/TR-642-761 <https://www.nrel.gov/docs/legosti/old/761.pdf>`_
.. [5] `Error Reports <http://rredc.nrel.gov/solar/models/clearsky/
error_reports.html>`_
Expand Down
9 changes: 6 additions & 3 deletions pvlib/irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -1558,8 +1558,8 @@ def ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
albedo : numeric, default 0.25
Ground surface albedo. [unitless]
xtol : numeric, default 0.01
Convergence criterion. The estimated GHI will be within xtol of the
true value. [W/m^2]
Convergence criterion. The estimated GHI will be within xtol of the
true value. Must be positive. [W/m^2]
full_output : boolean, default False
If full_output is False, only ghi is returned, otherwise the return
value is (ghi, converged, niter). (see Returns section for details).
Expand Down Expand Up @@ -1594,13 +1594,16 @@ def ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
'''
# Contributed by Anton Driesse (@adriesse), PV Performance Labs. Nov., 2023

if xtol <= 0:
raise ValueError(f"xtol too small ({xtol:g} <= 0)")

ghi_from_poa_array = np.vectorize(_ghi_from_poa)

ghi, conv, niter = ghi_from_poa_array(surface_tilt, surface_azimuth,
solar_zenith, solar_azimuth,
poa_global,
dni_extra, airmass, albedo,
xtol=0.01)
xtol=xtol)

if isinstance(poa_global, pd.Series):
ghi = pd.Series(ghi, poa_global.index)
Expand Down
125 changes: 125 additions & 0 deletions pvlib/pvarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,128 @@ def adr_wrapper(xdata, *params):
return dict(zip(P_NAMES, popt))
else:
return popt


def _infer_k_huld(cell_type, pdc0):
# from PVGIS documentation, "PVGIS data sources & calculation methods",
# Section 5.2.3, accessed 12/22/2023
# The parameters in PVGIS' documentation are for a version of Huld's
# equation that has factored Pdc0 out of the polynomial:
# P = G/1000 * Pdc0 * (1 + k1 log(Geff) + ...) so these parameters are
# multiplied by pdc0
huld_params = {'csi': (-0.017237, -0.040465, -0.004702, 0.000149,
0.000170, 0.000005),
'cis': (-0.005554, -0.038724, -0.003723, -0.000905,
-0.001256, 0.000001),
'cdte': (-0.046689, -0.072844, -0.002262, 0.000276,
0.000159, -0.000006)}
k = tuple([x*pdc0 for x in huld_params[cell_type.lower()]])
return k


def huld(effective_irradiance, temp_mod, pdc0, k=None, cell_type=None):
r"""
Power (DC) using the Huld model.
The Huld model [1]_ is used by PVGIS and is given by
.. math::
P_{dc} &= G' ( P_{dc0} + k_1 \log(G') + k_2 \log^2 (G') + k_3 T' +
k_4 T' \log(G') + k_5 T' \log^2 (G') + k_6 T'^2)
G' &= \frac{G_{poa eff}}{1000}
T' &= T_{mod} - 25^{\circ}C
Parameters
----------
effective_irradiance : numeric
The irradiance that is converted to photocurrent. [:math:`W/m^2`]
temp_mod: numeric
Module back-surface temperature. [C]
pdc0: numeric
Power of the modules at reference conditions 1000 :math:`W/m^2`
and :math:`25^{\circ}C`. [W]
k : tuple, optional
Empirical coefficients used in the power model. Length 6. If ``k`` is
not provided, ``cell_type`` must be specified.
cell_type : str, optional
If provided, must be one of ``'cSi'``, ``'CIS'``, or ``'CdTe'``.
Used to look up default values for ``k`` if ``k`` is not specified.
Returns
-------
pdc: numeric
DC power. [W]
Raises
------
ValueError
If neither ``k`` nor ``cell_type`` are specified.
Notes
-----
The equation for :math:`P_{dc}` is from [1]_. The expression used in PVGIS
documentation differs by factoring :math:`P_{dc0}` out of the
polynomial:
.. math::
P_{dc} = G' P_{dc0} (1 + k'_1 \log(G') + k'_2 \log^2 (G') + k'_3 T' +
k'_4 T' \log(G') + k'_5 T' \log^2 (G') + k'_6 T'^2)
PVGIS documentation shows a table of default parameters :math:`k'` for
different cell types. The parameters :math:`k'` differ from the parameters
:math:`k` for :py:func:`huld` by the factor ``pdc0``, that is,
.. math::
k = P_{dc0} k'
With default values for :math:`k`, at very low irradiance, i.e.,
:math:`G' < 20 W/m^2`, :math:`P_{dc}` may be negative
due to the terms involving :math:`\log(G')`.
:py:func:`huld` is a component of the PV performance model implemented in
PVGIS. Among other components, the full PVGIS model includes:
- the Faiman model for module temperature
:py:func:`pvlib.temperature.faiman`
- the Martin and Ruiz model for the incidence angle modifier (IAM)
:py:func:`pvlib.iam.martin_ruiz`
- a custom model for a spectral adjustment factor
The PVGIS API (see :py:func:`pvlib.iotools.get_pvgis_hourly`) returns
broadband plane-of-array irradiance (``poa_global``) and DC power (``P``).
``poa_global`` is irradiance before applying the IAM and spectral
adjustments. In contrast the ``effective_irradiance`` for :py:func:`huld`
should have the IAM and spectral adjustments. Users comparing output of
:py:func:`huld` to PVGIS' ``P`` values should expect differences unless
``effective_irradiance`` is computed in the same way as done by PVGIS.
References
----------
.. [1] T. Huld, G. Friesen, A. Skoczek, R. Kenny, T. Sample, M. Field,
E. Dunlop. A power-rating model for crystalline silicon PV modules.
Solar Energy Materials and Solar Cells 95, (2011), pp. 3359-3369.
:doi:`10.1016/j.solmat.2011.07.026`.
"""
if k is None:
if cell_type is not None:
k = _infer_k_huld(cell_type, pdc0)
else:
raise ValueError('Either k or cell_type must be specified')

gprime = effective_irradiance / 1000
tprime = temp_mod - 25
# accomodate gprime<=0
with np.errstate(divide='ignore'):
logGprime = np.log(gprime, out=np.zeros_like(gprime),
where=np.array(gprime > 0))
# Eq. 1 in [1]
pdc = gprime * (pdc0 + k[0] * logGprime + k[1] * logGprime**2 +
k[2] * tprime + k[3] * tprime * logGprime +
k[4] * tprime * logGprime**2 + k[5] * tprime**2)
return pdc
Loading

0 comments on commit 816a8f8

Please sign in to comment.