forked from pvlib/pvlib-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpvfactors.py
136 lines (123 loc) · 5.14 KB
/
pvfactors.py
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""
The ``bifacial.pvfactors`` module contains functions for modeling back surface
plane-of-array irradiance using the pvfactors package.
"""
import pandas as pd
import numpy as np
def pvfactors_timeseries(
solar_azimuth, solar_zenith, surface_azimuth, surface_tilt,
axis_azimuth, timestamps, dni, dhi, gcr, pvrow_height, pvrow_width,
albedo, n_pvrows=3, index_observed_pvrow=1,
rho_front_pvrow=0.03, rho_back_pvrow=0.05,
horizon_band_angle=15.):
"""
Calculate front and back surface plane-of-array irradiance on
a fixed tilt or single-axis tracker PV array configuration, and using
the open-source "pvfactors" package. pvfactors implements the model
described in [1]_.
Please refer to pvfactors online documentation for more details:
https://sunpower.github.io/pvfactors/
Parameters
----------
solar_azimuth : numeric
Sun's azimuth angles using pvlib's azimuth convention (deg)
solar_zenith : numeric
Sun's zenith angles (deg)
surface_azimuth : numeric
Azimuth angle of the front surface of the PV modules, using pvlib's
convention (deg)
surface_tilt : numeric
Tilt angle of the PV modules, going from 0 to 180 (deg)
axis_azimuth : float
Azimuth angle of the rotation axis of the PV modules, using pvlib's
convention (deg). This is supposed to be fixed for all timestamps.
When modeling fixed-tilt arrays, set this value to be 90 degrees
clockwise from ``surface_azimuth``.
timestamps : datetime or DatetimeIndex
List of simulation timestamps
dni : numeric
Direct normal irradiance (W/m2)
dhi : numeric
Diffuse horizontal irradiance (W/m2)
gcr : float
Ground coverage ratio of the pv array
pvrow_height : float
Height of the pv rows, measured at their center (m)
pvrow_width : float
Width of the pv rows in the considered 2D plane (m)
albedo : float
Ground albedo
n_pvrows : int, default 3
Number of PV rows to consider in the PV array
index_observed_pvrow : int, default 1
Index of the PV row whose incident irradiance will be returned. Indices
of PV rows go from 0 to n_pvrows-1.
rho_front_pvrow : float, default 0.03
Front surface reflectivity of PV rows
rho_back_pvrow : float, default 0.05
Back surface reflectivity of PV rows
horizon_band_angle : float, default 15
Elevation angle of the sky dome's diffuse horizon band (deg)
Returns
-------
poa_front : numeric
Calculated incident irradiance on the front surface of the PV modules
(W/m2)
poa_back : numeric
Calculated incident irradiance on the back surface of the PV modules
(W/m2)
poa_front_absorbed : numeric
Calculated absorbed irradiance on the front surface of the PV modules
(W/m2), after AOI losses
poa_back_absorbed : numeric
Calculated absorbed irradiance on the back surface of the PV modules
(W/m2), after AOI losses
References
----------
.. [1] Anoma, Marc Abou, et al. "View Factor Model and Validation for
Bifacial PV and Diffuse Shade on Single-Axis Trackers." 44th IEEE
Photovoltaic Specialist Conference. 2017.
"""
# Convert Series, list, float inputs to numpy arrays
solar_azimuth = np.array(solar_azimuth)
solar_zenith = np.array(solar_zenith)
dni = np.array(dni)
dhi = np.array(dhi)
# GH 1127, GH 1332
surface_tilt = np.full_like(solar_zenith, surface_tilt)
surface_azimuth = np.full_like(solar_zenith, surface_azimuth)
# Import pvfactors functions for timeseries calculations.
from pvfactors.run import run_timeseries_engine
# Build up pv array configuration parameters
pvarray_parameters = {
'n_pvrows': n_pvrows,
'axis_azimuth': axis_azimuth,
'pvrow_height': pvrow_height,
'pvrow_width': pvrow_width,
'gcr': gcr
}
irradiance_model_params = {
'rho_front': rho_front_pvrow,
'rho_back': rho_back_pvrow,
'horizon_band_angle': horizon_band_angle
}
# Create report function
def fn_build_report(pvarray):
return {'total_inc_back': pvarray.ts_pvrows[index_observed_pvrow]
.back.get_param_weighted('qinc'),
'total_inc_front': pvarray.ts_pvrows[index_observed_pvrow]
.front.get_param_weighted('qinc'),
'total_abs_back': pvarray.ts_pvrows[index_observed_pvrow]
.back.get_param_weighted('qabs'),
'total_abs_front': pvarray.ts_pvrows[index_observed_pvrow]
.front.get_param_weighted('qabs')}
# Run pvfactors calculations
report = run_timeseries_engine(
fn_build_report, pvarray_parameters,
timestamps, dni, dhi, solar_zenith, solar_azimuth,
surface_tilt, surface_azimuth, albedo,
irradiance_model_params=irradiance_model_params)
# Turn report into dataframe
df_report = pd.DataFrame(report, index=timestamps)
return (df_report.total_inc_front, df_report.total_inc_back,
df_report.total_abs_front, df_report.total_abs_back)