pvlib 0.11.0__py3-none-any.whl → 0.11.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvlib/atmosphere.py +157 -1
- pvlib/bifacial/__init__.py +4 -4
- pvlib/bifacial/loss_models.py +163 -0
- pvlib/clearsky.py +18 -29
- pvlib/data/pvgis_tmy_meta.json +32 -93
- pvlib/data/pvgis_tmy_test.dat +8761 -8761
- pvlib/data/tmy_45.000_8.000_2005_2020.csv +8789 -0
- pvlib/data/tmy_45.000_8.000_2005_2020.epw +8768 -0
- pvlib/data/tmy_45.000_8.000_2005_2020.json +1 -0
- pvlib/data/tmy_45.000_8.000_2005_2020.txt +8761 -0
- pvlib/data/tmy_45.000_8.000_userhorizon.json +1 -1
- pvlib/data/variables_style_rules.csv +2 -1
- pvlib/iotools/pvgis.py +39 -3
- pvlib/irradiance.py +141 -120
- pvlib/location.py +5 -5
- pvlib/modelchain.py +1 -1
- pvlib/pvsystem.py +2 -2
- pvlib/shading.py +8 -8
- pvlib/singlediode.py +1 -1
- pvlib/solarposition.py +55 -50
- pvlib/spa.py +24 -22
- pvlib/spectrum/__init__.py +9 -4
- pvlib/spectrum/irradiance.py +272 -0
- pvlib/spectrum/mismatch.py +118 -508
- pvlib/spectrum/response.py +280 -0
- pvlib/spectrum/spectrl2.py +16 -16
- pvlib/tests/bifacial/test_losses_models.py +54 -0
- pvlib/tests/iotools/test_pvgis.py +57 -11
- pvlib/tests/spectrum/__init__.py +0 -0
- pvlib/tests/spectrum/conftest.py +40 -0
- pvlib/tests/spectrum/test_irradiance.py +138 -0
- pvlib/tests/{test_spectrum.py → spectrum/test_mismatch.py} +32 -306
- pvlib/tests/spectrum/test_response.py +124 -0
- pvlib/tests/spectrum/test_spectrl2.py +72 -0
- pvlib/tests/test_atmosphere.py +71 -0
- pvlib/tests/test_clearsky.py +37 -25
- pvlib/tests/test_irradiance.py +6 -6
- pvlib/tests/test_solarposition.py +84 -36
- pvlib/tests/test_spa.py +1 -1
- pvlib/tools.py +26 -2
- pvlib/tracking.py +53 -47
- {pvlib-0.11.0.dist-info → pvlib-0.11.1.dist-info}/METADATA +31 -29
- {pvlib-0.11.0.dist-info → pvlib-0.11.1.dist-info}/RECORD +47 -38
- {pvlib-0.11.0.dist-info → pvlib-0.11.1.dist-info}/WHEEL +1 -1
- pvlib/data/tmy_45.000_8.000_2005_2016.csv +0 -8789
- pvlib/data/tmy_45.000_8.000_2005_2016.epw +0 -8768
- pvlib/data/tmy_45.000_8.000_2005_2016.json +0 -1
- pvlib/data/tmy_45.000_8.000_2005_2016.txt +0 -8761
- {pvlib-0.11.0.dist-info → pvlib-0.11.1.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.11.0.dist-info → pvlib-0.11.1.dist-info}/LICENSE +0 -0
- {pvlib-0.11.0.dist-info → pvlib-0.11.1.dist-info}/top_level.txt +0 -0
pvlib/atmosphere.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
The ``atmosphere`` module contains methods to calculate relative and
|
|
3
|
-
absolute airmass
|
|
3
|
+
absolute airmass, determine pressure from altitude or vice versa, and wind
|
|
4
|
+
speed at different heights.
|
|
4
5
|
"""
|
|
5
6
|
|
|
6
7
|
import numpy as np
|
|
@@ -533,3 +534,158 @@ def angstrom_alpha(aod1, lambda1, aod2, lambda2):
|
|
|
533
534
|
pvlib.atmosphere.angstrom_aod_at_lambda
|
|
534
535
|
"""
|
|
535
536
|
return - np.log(aod1 / aod2) / np.log(lambda1 / lambda2)
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
# Values of the Hellmann exponent
|
|
540
|
+
HELLMANN_SURFACE_EXPONENTS = {
|
|
541
|
+
'unstable_air_above_open_water_surface': 0.06,
|
|
542
|
+
'neutral_air_above_open_water_surface': 0.10,
|
|
543
|
+
'stable_air_above_open_water_surface': 0.27,
|
|
544
|
+
'unstable_air_above_flat_open_coast': 0.11,
|
|
545
|
+
'neutral_air_above_flat_open_coast': 0.16,
|
|
546
|
+
'stable_air_above_flat_open_coast': 0.40,
|
|
547
|
+
'unstable_air_above_human_inhabited_areas': 0.27,
|
|
548
|
+
'neutral_air_above_human_inhabited_areas': 0.34,
|
|
549
|
+
'stable_air_above_human_inhabited_areas': 0.60,
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def windspeed_powerlaw(wind_speed_reference, height_reference,
|
|
554
|
+
height_desired, exponent=None,
|
|
555
|
+
surface_type=None):
|
|
556
|
+
r"""
|
|
557
|
+
Estimate wind speed for different heights.
|
|
558
|
+
|
|
559
|
+
The model is based on the power law equation by Hellmann [1]_ [2]_.
|
|
560
|
+
|
|
561
|
+
Parameters
|
|
562
|
+
----------
|
|
563
|
+
wind_speed_reference : numeric
|
|
564
|
+
Measured wind speed. [m/s]
|
|
565
|
+
|
|
566
|
+
height_reference : float
|
|
567
|
+
The height above ground at which the wind speed is measured. [m]
|
|
568
|
+
|
|
569
|
+
height_desired : float
|
|
570
|
+
The height above ground at which the wind speed will be estimated. [m]
|
|
571
|
+
|
|
572
|
+
exponent : float, optional
|
|
573
|
+
Exponent based on the surface type. [unitless]
|
|
574
|
+
|
|
575
|
+
surface_type : string, optional
|
|
576
|
+
If supplied, overrides ``exponent``. Can be one of the following
|
|
577
|
+
(see [1]_):
|
|
578
|
+
|
|
579
|
+
* ``'unstable_air_above_open_water_surface'``
|
|
580
|
+
* ``'neutral_air_above_open_water_surface'``
|
|
581
|
+
* ``'stable_air_above_open_water_surface'``
|
|
582
|
+
* ``'unstable_air_above_flat_open_coast'``
|
|
583
|
+
* ``'neutral_air_above_flat_open_coast'``
|
|
584
|
+
* ``'stable_air_above_flat_open_coast'``
|
|
585
|
+
* ``'unstable_air_above_human_inhabited_areas'``
|
|
586
|
+
* ``'neutral_air_above_human_inhabited_areas'``
|
|
587
|
+
* ``'stable_air_above_human_inhabited_areas'``
|
|
588
|
+
|
|
589
|
+
Returns
|
|
590
|
+
-------
|
|
591
|
+
wind_speed : numeric
|
|
592
|
+
Adjusted wind speed for the desired height. [m/s]
|
|
593
|
+
|
|
594
|
+
Raises
|
|
595
|
+
------
|
|
596
|
+
ValueError
|
|
597
|
+
If neither of ``exponent`` nor a ``surface_type`` is given.
|
|
598
|
+
If both ``exponent`` and a ``surface_type`` is given. These parameters
|
|
599
|
+
are mutually exclusive.
|
|
600
|
+
|
|
601
|
+
KeyError
|
|
602
|
+
If the specified ``surface_type`` is invalid.
|
|
603
|
+
|
|
604
|
+
Notes
|
|
605
|
+
-----
|
|
606
|
+
Module temperature functions often require wind speeds at a height of 10 m
|
|
607
|
+
and not the wind speed at the module height.
|
|
608
|
+
|
|
609
|
+
For example, the following temperature functions require the input wind
|
|
610
|
+
speed to be 10 m: :py:func:`~pvlib.temperature.sapm_cell`, and
|
|
611
|
+
:py:func:`~pvlib.temperature.sapm_module` whereas the
|
|
612
|
+
:py:func:`~pvlib.temperature.fuentes` model requires wind speed at 9.144 m.
|
|
613
|
+
|
|
614
|
+
Additionally, the heat loss coefficients of some models have been developed
|
|
615
|
+
for wind speed measurements at 10 m (e.g.,
|
|
616
|
+
:py:func:`~pvlib.temperature.pvsyst_cell`,
|
|
617
|
+
:py:func:`~pvlib.temperature.faiman`, and
|
|
618
|
+
:py:func:`~pvlib.temperature.faiman_rad`).
|
|
619
|
+
|
|
620
|
+
The equation for calculating the wind speed at a height of :math:`h` is
|
|
621
|
+
given by the following power law equation [1]_ [2]_:
|
|
622
|
+
|
|
623
|
+
.. math::
|
|
624
|
+
:label: wind speed
|
|
625
|
+
|
|
626
|
+
WS_{h} = WS_{ref} \cdot \left( \frac{h}{h_{ref}} \right)^a
|
|
627
|
+
|
|
628
|
+
where :math:`h` [m] is the height at which we would like to calculate the
|
|
629
|
+
wind speed, :math:`h_{ref}` [m] is the reference height at which the wind
|
|
630
|
+
speed is known, and :math:`WS_{h}` [m/s] and :math:`WS_{ref}`
|
|
631
|
+
[m/s] are the corresponding wind speeds at these heights. The exponent
|
|
632
|
+
:math:`a` [unitless] depends on the surface type. Some values found in the
|
|
633
|
+
literature [1]_ for :math:`a` are:
|
|
634
|
+
|
|
635
|
+
.. table:: Values for the Hellmann-exponent
|
|
636
|
+
|
|
637
|
+
+-----------+--------------------+------------------+------------------+
|
|
638
|
+
| Stability | Open water surface | Flat, open coast | Cities, villages |
|
|
639
|
+
+===========+====================+==================+==================+
|
|
640
|
+
| Unstable | 0.06 | 0.10 | 0.27 |
|
|
641
|
+
+-----------+--------------------+------------------+------------------+
|
|
642
|
+
| Neutral | 0.11 | 0.16 | 0.40 |
|
|
643
|
+
+-----------+--------------------+------------------+------------------+
|
|
644
|
+
| Stable | 0.27 | 0.34 | 0.60 |
|
|
645
|
+
+-----------+--------------------+------------------+------------------+
|
|
646
|
+
|
|
647
|
+
In a report by Sandia [3]_, the equation was experimentally tested for a
|
|
648
|
+
height of 30 ft (:math:`h_{ref} = 9.144` [m]) at their test site in
|
|
649
|
+
Albuquerque for a period of six weeks where a coefficient of
|
|
650
|
+
:math:`a = 0.219` was calculated.
|
|
651
|
+
|
|
652
|
+
It should be noted that the equation returns a value of NaN if the
|
|
653
|
+
reference heights or wind speed are negative.
|
|
654
|
+
|
|
655
|
+
References
|
|
656
|
+
----------
|
|
657
|
+
.. [1] Kaltschmitt M., Streicher W., Wiese A. (2007). "Renewable Energy:
|
|
658
|
+
Technology, Economics and Environment." Springer,
|
|
659
|
+
:doi:`10.1007/3-540-70949-5`.
|
|
660
|
+
|
|
661
|
+
.. [2] Hellmann G. (1915). "Über die Bewegung der Luft in den untersten
|
|
662
|
+
Schichten der Atmosphäre." Meteorologische Zeitschrift, 32
|
|
663
|
+
|
|
664
|
+
.. [3] Menicucci D.F., Hall I.J. (1985). "Estimating wind speed as a
|
|
665
|
+
function of height above ground: An analysis of data obtained at the
|
|
666
|
+
southwest residential experiment station, Las Cruses, New Mexico."
|
|
667
|
+
SAND84-2530, Sandia National Laboratories.
|
|
668
|
+
Accessed at:
|
|
669
|
+
https://web.archive.org/web/20230418202422/https://www2.jpl.nasa.gov/adv_tech/photovol/2016CTR/SNL%20-%20Est%20Wind%20Speed%20vs%20Height_1985.pdf
|
|
670
|
+
""" # noqa:E501
|
|
671
|
+
if surface_type is not None and exponent is None:
|
|
672
|
+
# use the Hellmann exponent from dictionary
|
|
673
|
+
exponent = HELLMANN_SURFACE_EXPONENTS[surface_type]
|
|
674
|
+
elif surface_type is None and exponent is not None:
|
|
675
|
+
# use the provided exponent
|
|
676
|
+
pass
|
|
677
|
+
else:
|
|
678
|
+
raise ValueError(
|
|
679
|
+
"Either a 'surface_type' or an 'exponent' parameter must be given")
|
|
680
|
+
|
|
681
|
+
wind_speed = wind_speed_reference * (
|
|
682
|
+
(height_desired / height_reference) ** exponent)
|
|
683
|
+
|
|
684
|
+
# if wind speed is negative or complex return NaN
|
|
685
|
+
wind_speed = np.where(np.iscomplex(wind_speed) | (wind_speed < 0),
|
|
686
|
+
np.nan, wind_speed)
|
|
687
|
+
|
|
688
|
+
if isinstance(wind_speed_reference, pd.Series):
|
|
689
|
+
wind_speed = pd.Series(wind_speed, index=wind_speed_reference.index)
|
|
690
|
+
|
|
691
|
+
return wind_speed
|
pvlib/bifacial/__init__.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
The ``bifacial``
|
|
3
|
-
modules.
|
|
4
|
-
|
|
2
|
+
The ``bifacial`` submodule contains functions to model bifacial modules.
|
|
5
3
|
"""
|
|
4
|
+
|
|
6
5
|
from pvlib._deprecation import deprecated
|
|
7
|
-
from pvlib.bifacial import pvfactors, infinite_sheds, utils
|
|
6
|
+
from pvlib.bifacial import pvfactors, infinite_sheds, utils # noqa: F401
|
|
7
|
+
from .loss_models import power_mismatch_deline # noqa: F401
|
|
8
8
|
|
|
9
9
|
pvfactors_timeseries = deprecated(
|
|
10
10
|
since='0.9.1',
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def power_mismatch_deline(
|
|
6
|
+
rmad,
|
|
7
|
+
coefficients=(0, 0.142, 0.032 * 100),
|
|
8
|
+
fill_factor: float = None,
|
|
9
|
+
fill_factor_reference: float = 0.79,
|
|
10
|
+
):
|
|
11
|
+
r"""
|
|
12
|
+
Estimate DC power loss due to irradiance non-uniformity.
|
|
13
|
+
|
|
14
|
+
This model is described for bifacial modules in [1]_, where the backside
|
|
15
|
+
irradiance is less uniform due to mounting and site conditions.
|
|
16
|
+
|
|
17
|
+
The power loss is estimated by a polynomial model of the Relative Mean
|
|
18
|
+
Absolute Difference (RMAD) of the cell-by-cell total irradiance.
|
|
19
|
+
|
|
20
|
+
Use ``fill_factor`` to account for different fill factors between the
|
|
21
|
+
data used to fit the model and the module of interest. Specify the model's fill factor with
|
|
22
|
+
``fill_factor_reference``.
|
|
23
|
+
|
|
24
|
+
.. versionadded:: 0.11.1
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
rmad : numeric
|
|
29
|
+
The Relative Mean Absolute Difference of the cell-by-cell total
|
|
30
|
+
irradiance. [Unitless]
|
|
31
|
+
|
|
32
|
+
See the *Notes* section for the equation to calculate ``rmad`` from the
|
|
33
|
+
bifaciality and the front and back irradiances.
|
|
34
|
+
|
|
35
|
+
coefficients : float collection or numpy.polynomial.polynomial.Polynomial, default ``(0, 0.142, 0.032 * 100)``
|
|
36
|
+
The polynomial coefficients to use.
|
|
37
|
+
|
|
38
|
+
If a :external:class:`numpy.polynomial.polynomial.Polynomial`,
|
|
39
|
+
it is evaluated as is. If not a ``Polynomial``, it must be the
|
|
40
|
+
coefficients of a polynomial in ``rmad``, where the first element is
|
|
41
|
+
the constant term and the last element is the highest order term. A
|
|
42
|
+
:external:class:`~numpy.polynomial.polynomial.Polynomial`
|
|
43
|
+
will be created internally.
|
|
44
|
+
|
|
45
|
+
fill_factor : float, optional
|
|
46
|
+
Fill factor at standard test condition (STC) of the module.
|
|
47
|
+
Accounts for different fill factors between the trained model and the
|
|
48
|
+
module under non-uniform irradiance.
|
|
49
|
+
If not provided, the default ``fill_factor_reference`` of 0.79 is used.
|
|
50
|
+
|
|
51
|
+
fill_factor_reference : float, default 0.79
|
|
52
|
+
Fill factor at STC of the module used to train the model.
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
loss : numeric
|
|
57
|
+
The fractional power loss. [Unitless]
|
|
58
|
+
|
|
59
|
+
Output will be a ``pandas.Series`` if ``rmad`` is a ``pandas.Series``.
|
|
60
|
+
|
|
61
|
+
Notes
|
|
62
|
+
-----
|
|
63
|
+
The default model implemented is equation (11) [1]_:
|
|
64
|
+
|
|
65
|
+
.. math::
|
|
66
|
+
|
|
67
|
+
M[\%] &= 0.142 \Delta[\%] + 0.032 \Delta^2[\%] \qquad \text{(11)}
|
|
68
|
+
|
|
69
|
+
M[-] &= 0.142 \Delta[-] + 0.032 \times 100 \Delta^2[-]
|
|
70
|
+
|
|
71
|
+
where the upper equation is in percentage (same as paper) and the lower
|
|
72
|
+
one is unitless. The implementation uses the unitless version, where
|
|
73
|
+
:math:`M[-]` is the mismatch power loss [unitless] and
|
|
74
|
+
:math:`\Delta[-]` is the Relative Mean Absolute Difference (RMAD) [unitless]
|
|
75
|
+
of the global irradiance, Eq. (4) of [1]_ and [2]_.
|
|
76
|
+
Note that the n-th power coefficient is multiplied by :math:`100^{n-1}`
|
|
77
|
+
to convert the percentage to unitless.
|
|
78
|
+
|
|
79
|
+
The losses definition is Eq. (1) of [1]_, and it's defined as a loss of the
|
|
80
|
+
output power:
|
|
81
|
+
|
|
82
|
+
.. math::
|
|
83
|
+
|
|
84
|
+
M = 1 - \frac{P_{Array}}{\sum P_{Cells}} \qquad \text{(1)}
|
|
85
|
+
|
|
86
|
+
To account for a module with a fill factor distinct from the one used to
|
|
87
|
+
train the model (``0.79`` by default), the output of the model can be
|
|
88
|
+
modified with Eq. (7):
|
|
89
|
+
|
|
90
|
+
.. math::
|
|
91
|
+
|
|
92
|
+
M_{FF_1} = M_{FF_0} \frac{FF_1}{FF_0} \qquad \text{(7)}
|
|
93
|
+
|
|
94
|
+
where parameter ``fill_factor`` is :math:`FF_1` and
|
|
95
|
+
``fill_factor_reference`` is :math:`FF_0`.
|
|
96
|
+
|
|
97
|
+
In the section *See Also*, you will find two packages that can be used to
|
|
98
|
+
calculate the irradiance at different points of the module.
|
|
99
|
+
|
|
100
|
+
.. note::
|
|
101
|
+
The global irradiance RMAD is different from the backside irradiance
|
|
102
|
+
RMAD.
|
|
103
|
+
|
|
104
|
+
RMAD of a variable :math:`G_{total}` is defined as:
|
|
105
|
+
|
|
106
|
+
.. math::
|
|
107
|
+
|
|
108
|
+
RMAD \left[ unitless \right] = \Delta \left[ unitless \right] =
|
|
109
|
+
\frac{1}{n^2 \bar{G}_{total}} \sum_{i=1}^{n} \sum_{j=1}^{n}
|
|
110
|
+
\lvert G_{total,i} - G_{total,j} \rvert
|
|
111
|
+
|
|
112
|
+
In case the RMAD of the backside irradiance is known, the global RMAD can
|
|
113
|
+
be calculated as follows, assuming the front irradiance RMAD is
|
|
114
|
+
negligible [2]_:
|
|
115
|
+
|
|
116
|
+
.. math::
|
|
117
|
+
|
|
118
|
+
RMAD(k \cdot X + c) = RMAD(X) \cdot k \frac{k \bar{X}}{k \bar{X} + c}
|
|
119
|
+
= RMAD(X) \cdot \frac{k}{1 + \frac{c}{k \bar{X}}}
|
|
120
|
+
|
|
121
|
+
by similarity with equation (2) of [1]_:
|
|
122
|
+
|
|
123
|
+
.. math::
|
|
124
|
+
|
|
125
|
+
G_{total\,i} = G_{front\,i} + \phi_{Bifi} G_{rear\,i} \qquad \text{(2)}
|
|
126
|
+
|
|
127
|
+
which yields:
|
|
128
|
+
|
|
129
|
+
.. math::
|
|
130
|
+
|
|
131
|
+
RMAD_{total} = RMAD_{rear} \frac{\phi_{Bifi}}
|
|
132
|
+
{1 + \frac{G_{front}}{\phi_{Bifi} \bar{G}_{rear}}}
|
|
133
|
+
|
|
134
|
+
See Also
|
|
135
|
+
--------
|
|
136
|
+
`solarfactors <https://github.com/pvlib/solarfactors/>`_
|
|
137
|
+
Calculate the irradiance at different points of the module.
|
|
138
|
+
`bifacial_radiance <https://github.com/NREL/bifacial_radiance>`_
|
|
139
|
+
Calculate the irradiance at different points of the module.
|
|
140
|
+
|
|
141
|
+
References
|
|
142
|
+
----------
|
|
143
|
+
.. [1] C. Deline, S. Ayala Pelaez, S. MacAlpine, and C. Olalla, 'Estimating
|
|
144
|
+
and parameterizing mismatch power loss in bifacial photovoltaic
|
|
145
|
+
systems', Progress in Photovoltaics: Research and Applications, vol. 28,
|
|
146
|
+
no. 7, pp. 691-703, 2020, :doi:`10.1002/pip.3259`.
|
|
147
|
+
.. [2] “Mean absolute difference,” Wikipedia, Sep. 05, 2023.
|
|
148
|
+
https://en.wikipedia.org/wiki/Mean_absolute_difference#Relative_mean_absolute_difference
|
|
149
|
+
(accessed 2024-04-14).
|
|
150
|
+
""" # noqa: E501
|
|
151
|
+
if isinstance(coefficients, np.polynomial.Polynomial):
|
|
152
|
+
model_polynom = coefficients
|
|
153
|
+
else: # expect an iterable
|
|
154
|
+
model_polynom = np.polynomial.Polynomial(coef=coefficients)
|
|
155
|
+
|
|
156
|
+
if fill_factor: # Eq. (7), [1]
|
|
157
|
+
# Scale output of trained model to account for different fill factors
|
|
158
|
+
model_polynom = model_polynom * fill_factor / fill_factor_reference
|
|
159
|
+
|
|
160
|
+
mismatch = model_polynom(rmad)
|
|
161
|
+
if isinstance(rmad, pd.Series):
|
|
162
|
+
mismatch = pd.Series(mismatch, index=rmad.index)
|
|
163
|
+
return mismatch
|
pvlib/clearsky.py
CHANGED
|
@@ -9,7 +9,6 @@ import calendar
|
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
import pandas as pd
|
|
12
|
-
from scipy.optimize import minimize_scalar
|
|
13
12
|
from scipy.linalg import hankel
|
|
14
13
|
import h5py
|
|
15
14
|
|
|
@@ -169,6 +168,13 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None,
|
|
|
169
168
|
Returns
|
|
170
169
|
-------
|
|
171
170
|
turbidity : Series
|
|
171
|
+
|
|
172
|
+
Notes
|
|
173
|
+
-----
|
|
174
|
+
Linke turbidity is obtained from a file of historical monthly averages.
|
|
175
|
+
The returned value for each time is either the monthly value or an
|
|
176
|
+
interpolated value to smooth the transition between months.
|
|
177
|
+
Interpolation is done on the day of year as determined by UTC.
|
|
172
178
|
"""
|
|
173
179
|
|
|
174
180
|
# The .h5 file 'LinkeTurbidities.h5' contains a single 2160 x 4320 x 12
|
|
@@ -201,7 +207,7 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None,
|
|
|
201
207
|
if interp_turbidity:
|
|
202
208
|
linke_turbidity = _interpolate_turbidity(lts, time)
|
|
203
209
|
else:
|
|
204
|
-
months = time.month - 1
|
|
210
|
+
months = tools._pandas_to_utc(time).month - 1
|
|
205
211
|
linke_turbidity = pd.Series(lts[months], index=time)
|
|
206
212
|
|
|
207
213
|
linke_turbidity /= 20.
|
|
@@ -247,14 +253,11 @@ def _interpolate_turbidity(lts, time):
|
|
|
247
253
|
# Jan 1 - Jan 15 and Dec 16 - Dec 31.
|
|
248
254
|
lts_concat = np.concatenate([[lts[-1]], lts, [lts[0]]])
|
|
249
255
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
except AttributeError:
|
|
254
|
-
year = time.year
|
|
255
|
-
isleap = _is_leap_year(year)
|
|
256
|
+
time_utc = tools._pandas_to_utc(time)
|
|
257
|
+
|
|
258
|
+
isleap = time_utc.is_leap_year
|
|
256
259
|
|
|
257
|
-
dayofyear =
|
|
260
|
+
dayofyear = time_utc.dayofyear
|
|
258
261
|
days_leap = _calendar_month_middles(2016)
|
|
259
262
|
days_no_leap = _calendar_month_middles(2015)
|
|
260
263
|
|
|
@@ -874,25 +877,11 @@ def detect_clearsky(measured, clearsky, times=None, infer_limits=False,
|
|
|
874
877
|
clear_meas = meas[clear_samples]
|
|
875
878
|
clear_clear = clear[clear_samples]
|
|
876
879
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
try:
|
|
883
|
-
message = "Optimizer exited unsuccessfully: " \
|
|
884
|
-
+ optimize_result.message
|
|
885
|
-
except AttributeError:
|
|
886
|
-
message = "Optimizer exited unsuccessfully: \
|
|
887
|
-
No message explaining the failure was returned. \
|
|
888
|
-
If you would like to see this message, please \
|
|
889
|
-
update your scipy version (try version 1.8.0 \
|
|
890
|
-
or beyond)."
|
|
891
|
-
raise RuntimeError(message)
|
|
892
|
-
|
|
893
|
-
else:
|
|
894
|
-
alpha = optimize_result.x
|
|
895
|
-
|
|
880
|
+
# Compute arg min of MSE between model and observations
|
|
881
|
+
C = (clear_clear**2).sum()
|
|
882
|
+
if not (pd.isna(C) or C == 0): # safety check
|
|
883
|
+
# only update alpha if C is strictly positive
|
|
884
|
+
alpha = (clear_meas * clear_clear).sum() / C
|
|
896
885
|
if round(alpha*10000) == round(previous_alpha*10000):
|
|
897
886
|
break
|
|
898
887
|
else:
|
|
@@ -941,7 +930,7 @@ def bird(zenith, airmass_relative, aod380, aod500, precipitable_water,
|
|
|
941
930
|
zenith is never explicitly defined in the report, since the purpose
|
|
942
931
|
was to compare existing clear sky models with "rigorous radiative
|
|
943
932
|
transfer models" (RTM) it is possible that apparent zenith was
|
|
944
|
-
obtained as output from the RTM. However, the
|
|
933
|
+
obtained as output from the RTM. However, the implementation presented
|
|
945
934
|
in PVLIB is tested against the NREL Excel implementation by Daryl
|
|
946
935
|
Myers which uses an analytical expression for solar zenith instead
|
|
947
936
|
of apparent zenith.
|
pvlib/data/pvgis_tmy_meta.json
CHANGED
|
@@ -1,93 +1,32 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"description": "Last year of the calculations"
|
|
34
|
-
},
|
|
35
|
-
"use_horizon": {
|
|
36
|
-
"description": "Include horizon shadows"
|
|
37
|
-
},
|
|
38
|
-
"horizon_db": {
|
|
39
|
-
"description": "Source of horizon data"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
"outputs": {
|
|
45
|
-
"months_selected": {
|
|
46
|
-
"type": "time series",
|
|
47
|
-
"timestamp": "monthly",
|
|
48
|
-
"description": "months selected for the TMY"
|
|
49
|
-
},
|
|
50
|
-
"tmy_hourly": {
|
|
51
|
-
"type": "time series",
|
|
52
|
-
"timestamp": "hourly",
|
|
53
|
-
"variables": {
|
|
54
|
-
"T2m": {
|
|
55
|
-
"description": "2-m air temperature",
|
|
56
|
-
"units": "degree Celsius"
|
|
57
|
-
},
|
|
58
|
-
"RH": {
|
|
59
|
-
"description": "relative humidity",
|
|
60
|
-
"units": "%"
|
|
61
|
-
},
|
|
62
|
-
"G(h)": {
|
|
63
|
-
"description": "Global irradiance on the horizontal plane",
|
|
64
|
-
"units": "W/m2"
|
|
65
|
-
},
|
|
66
|
-
"Gb(n)": {
|
|
67
|
-
"description": "Beam/direct irradiance on a plane always normal to sun rays",
|
|
68
|
-
"units": "W/m2"
|
|
69
|
-
},
|
|
70
|
-
"Gd(h)": {
|
|
71
|
-
"description": "Diffuse irradiance on the horizontal plane",
|
|
72
|
-
"units": "W/m2"
|
|
73
|
-
},
|
|
74
|
-
"IR(h)": {
|
|
75
|
-
"description": "Surface infrared (thermal) irradiance on a horizontal plane",
|
|
76
|
-
"units": "W/m2"
|
|
77
|
-
},
|
|
78
|
-
"WS10m": {
|
|
79
|
-
"description": "10-m total wind speed",
|
|
80
|
-
"units": "m/s"
|
|
81
|
-
},
|
|
82
|
-
"WD10m": {
|
|
83
|
-
"description": "10-m wind direction (0 = N, 90 = E)",
|
|
84
|
-
"units": "degree"
|
|
85
|
-
},
|
|
86
|
-
"SP": {
|
|
87
|
-
"description": "Surface (air) pressure",
|
|
88
|
-
"units": "Pa"
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
1
|
+
{"inputs": {"location": {"description": "Selected location",
|
|
2
|
+
"variables": {"latitude": {"description": "Latitude",
|
|
3
|
+
"units": "decimal degree"},
|
|
4
|
+
"longitude": {"description": "Longitude", "units": "decimal degree"},
|
|
5
|
+
"elevation": {"description": "Elevation", "units": "m"}}},
|
|
6
|
+
"meteo_data": {"description": "Sources of meteorological data",
|
|
7
|
+
"variables": {"radiation_db": {"description": "Solar radiation database"},
|
|
8
|
+
"meteo_db": {"description": "Database used for meteorological variables other than solar radiation"},
|
|
9
|
+
"year_min": {"description": "First year of the calculations"},
|
|
10
|
+
"year_max": {"description": "Last year of the calculations"},
|
|
11
|
+
"use_horizon": {"description": "Include horizon shadows"},
|
|
12
|
+
"horizon_db": {"description": "Source of horizon data"}}}},
|
|
13
|
+
"outputs": {"months_selected": {"type": "time series",
|
|
14
|
+
"timestamp": "monthly",
|
|
15
|
+
"description": "months selected for the TMY"},
|
|
16
|
+
"tmy_hourly": {"type": "time series",
|
|
17
|
+
"timestamp": "hourly",
|
|
18
|
+
"variables": {"T2m": {"description": "2-m air temperature",
|
|
19
|
+
"units": "degree Celsius"},
|
|
20
|
+
"RH": {"description": "relative humidity", "units": "%"},
|
|
21
|
+
"G(h)": {"description": "Global irradiance on the horizontal plane",
|
|
22
|
+
"units": "W/m2"},
|
|
23
|
+
"Gb(n)": {"description": "Beam/direct irradiance on a plane always normal to sun rays",
|
|
24
|
+
"units": "W/m2"},
|
|
25
|
+
"Gd(h)": {"description": "Diffuse irradiance on the horizontal plane",
|
|
26
|
+
"units": "W/m2"},
|
|
27
|
+
"IR(h)": {"description": "Surface infrared (thermal) irradiance on a horizontal plane",
|
|
28
|
+
"units": "W/m2"},
|
|
29
|
+
"WS10m": {"description": "10-m total wind speed", "units": "m/s"},
|
|
30
|
+
"WD10m": {"description": "10-m wind direction (0 = N, 90 = E)",
|
|
31
|
+
"units": "degree"},
|
|
32
|
+
"SP": {"description": "Surface (air) pressure", "units": "Pa"}}}}}
|