|
9 | 9 |
|
10 | 10 | def pvfactors_timeseries(
|
11 | 11 | solar_azimuth, solar_zenith, surface_azimuth, surface_tilt,
|
12 |
| - axis_azimuth, |
13 |
| - timestamps, dni, dhi, gcr, pvrow_height, pvrow_width, albedo, |
14 |
| - n_pvrows=3, index_observed_pvrow=1, |
| 12 | + axis_azimuth, timestamps, dni, dhi, gcr, pvrow_height, pvrow_width, |
| 13 | + albedo, n_pvrows=3, index_observed_pvrow=1, |
15 | 14 | rho_front_pvrow=0.03, rho_back_pvrow=0.05,
|
16 |
| - horizon_band_angle=15., |
17 |
| - run_parallel_calculations=True, n_workers_for_parallel_calcs=2): |
| 15 | + horizon_band_angle=15.): |
18 | 16 | """
|
19 | 17 | Calculate front and back surface plane-of-array irradiance on
|
20 | 18 | a fixed tilt or single-axis tracker PV array configuration, and using
|
@@ -62,127 +60,92 @@ def pvfactors_timeseries(
|
62 | 60 | Back surface reflectivity of PV rows
|
63 | 61 | horizon_band_angle: float, default 15
|
64 | 62 | Elevation angle of the sky dome's diffuse horizon band (deg)
|
65 |
| - run_parallel_calculations: bool, default True |
66 |
| - pvfactors is capable of using multiprocessing. Use this flag to decide |
67 |
| - to run calculations in parallel (recommended) or not. |
68 |
| - n_workers_for_parallel_calcs: int, default 2 |
69 |
| - Number of workers to use in the case of parallel calculations. The |
70 |
| - '-1' value will lead to using a value equal to the number |
71 |
| - of CPU's on the machine running the model. |
72 | 63 |
|
73 | 64 | Returns
|
74 | 65 | -------
|
75 |
| - front_poa_irradiance: numeric |
| 66 | + poa_front: numeric |
76 | 67 | Calculated incident irradiance on the front surface of the PV modules
|
77 | 68 | (W/m2)
|
78 |
| - back_poa_irradiance: numeric |
| 69 | + poa_back: numeric |
79 | 70 | Calculated incident irradiance on the back surface of the PV modules
|
80 | 71 | (W/m2)
|
81 |
| - df_registries: pandas DataFrame |
82 |
| - DataFrame containing detailed outputs of the simulation; for |
83 |
| - instance the shapely geometries, the irradiance components incident on |
84 |
| - all surfaces of the PV array (for all timestamps), etc. |
85 |
| - In the pvfactors documentation, this is refered to as the "surface |
86 |
| - registry". |
| 72 | + poa_front_absorbed: numeric |
| 73 | + Calculated absorbed irradiance on the front surface of the PV modules |
| 74 | + (W/m2), after AOI losses |
| 75 | + poa_back_absorbed: numeric |
| 76 | + Calculated absorbed irradiance on the back surface of the PV modules |
| 77 | + (W/m2), after AOI losses |
87 | 78 |
|
88 | 79 | References
|
89 | 80 | ----------
|
90 | 81 | .. [1] Anoma, Marc Abou, et al. "View Factor Model and Validation for
|
91 | 82 | Bifacial PV and Diffuse Shade on Single-Axis Trackers." 44th IEEE
|
92 | 83 | Photovoltaic Specialist Conference. 2017.
|
93 | 84 | """
|
94 |
| - |
95 | 85 | # Convert pandas Series inputs (and some lists) to numpy arrays
|
96 | 86 | if isinstance(solar_azimuth, pd.Series):
|
97 | 87 | solar_azimuth = solar_azimuth.values
|
98 | 88 | elif isinstance(solar_azimuth, list):
|
99 | 89 | solar_azimuth = np.array(solar_azimuth)
|
100 | 90 | if isinstance(solar_zenith, pd.Series):
|
101 | 91 | solar_zenith = solar_zenith.values
|
| 92 | + elif isinstance(solar_zenith, list): |
| 93 | + solar_zenith = np.array(solar_zenith) |
102 | 94 | if isinstance(surface_azimuth, pd.Series):
|
103 | 95 | surface_azimuth = surface_azimuth.values
|
104 | 96 | elif isinstance(surface_azimuth, list):
|
105 | 97 | surface_azimuth = np.array(surface_azimuth)
|
106 | 98 | if isinstance(surface_tilt, pd.Series):
|
107 | 99 | surface_tilt = surface_tilt.values
|
| 100 | + elif isinstance(surface_tilt, list): |
| 101 | + surface_tilt = np.array(surface_tilt) |
108 | 102 | if isinstance(dni, pd.Series):
|
109 | 103 | dni = dni.values
|
| 104 | + elif isinstance(dni, list): |
| 105 | + dni = np.array(dni) |
110 | 106 | if isinstance(dhi, pd.Series):
|
111 | 107 | dhi = dhi.values
|
112 |
| - if isinstance(solar_azimuth, list): |
113 |
| - solar_azimuth = np.array(solar_azimuth) |
| 108 | + elif isinstance(dhi, list): |
| 109 | + dhi = np.array(dhi) |
114 | 110 |
|
115 | 111 | # Import pvfactors functions for timeseries calculations.
|
116 |
| - from pvfactors.run import (run_timeseries_engine, |
117 |
| - run_parallel_engine) |
| 112 | + from pvfactors.run import run_timeseries_engine |
118 | 113 |
|
119 | 114 | # Build up pv array configuration parameters
|
120 | 115 | pvarray_parameters = {
|
121 | 116 | 'n_pvrows': n_pvrows,
|
122 | 117 | 'axis_azimuth': axis_azimuth,
|
123 | 118 | 'pvrow_height': pvrow_height,
|
124 | 119 | 'pvrow_width': pvrow_width,
|
125 |
| - 'gcr': gcr, |
126 |
| - 'rho_front_pvrow': rho_front_pvrow, |
127 |
| - 'rho_back_pvrow': rho_back_pvrow, |
| 120 | + 'gcr': gcr |
| 121 | + } |
| 122 | + |
| 123 | + irradiance_model_params = { |
| 124 | + 'rho_front': rho_front_pvrow, |
| 125 | + 'rho_back': rho_back_pvrow, |
128 | 126 | 'horizon_band_angle': horizon_band_angle
|
129 | 127 | }
|
130 | 128 |
|
131 |
| - # Run pvfactors calculations: either in parallel or serially |
132 |
| - if run_parallel_calculations: |
133 |
| - report = run_parallel_engine( |
134 |
| - PVFactorsReportBuilder, pvarray_parameters, |
135 |
| - timestamps, dni, dhi, |
136 |
| - solar_zenith, solar_azimuth, |
137 |
| - surface_tilt, surface_azimuth, |
138 |
| - albedo, n_processes=n_workers_for_parallel_calcs) |
139 |
| - else: |
140 |
| - report = run_timeseries_engine( |
141 |
| - PVFactorsReportBuilder.build, pvarray_parameters, |
142 |
| - timestamps, dni, dhi, |
143 |
| - solar_zenith, solar_azimuth, |
144 |
| - surface_tilt, surface_azimuth, |
145 |
| - albedo) |
| 129 | + # Create report function |
| 130 | + def fn_build_report(pvarray): |
| 131 | + return {'total_inc_back': pvarray.ts_pvrows[index_observed_pvrow] |
| 132 | + .back.get_param_weighted('qinc'), |
| 133 | + 'total_inc_front': pvarray.ts_pvrows[index_observed_pvrow] |
| 134 | + .front.get_param_weighted('qinc'), |
| 135 | + 'total_abs_back': pvarray.ts_pvrows[index_observed_pvrow] |
| 136 | + .back.get_param_weighted('qabs'), |
| 137 | + 'total_abs_front': pvarray.ts_pvrows[index_observed_pvrow] |
| 138 | + .front.get_param_weighted('qabs')} |
| 139 | + |
| 140 | + # Run pvfactors calculations |
| 141 | + report = run_timeseries_engine( |
| 142 | + fn_build_report, pvarray_parameters, |
| 143 | + timestamps, dni, dhi, solar_zenith, solar_azimuth, |
| 144 | + surface_tilt, surface_azimuth, albedo, |
| 145 | + irradiance_model_params=irradiance_model_params) |
146 | 146 |
|
147 | 147 | # Turn report into dataframe
|
148 | 148 | df_report = pd.DataFrame(report, index=timestamps)
|
149 | 149 |
|
150 |
| - return df_report.total_inc_front, df_report.total_inc_back |
151 |
| - |
152 |
| - |
153 |
| -class PVFactorsReportBuilder(object): |
154 |
| - """In pvfactors, a class is required to build reports when running |
155 |
| - calculations with multiprocessing because of python constraints""" |
156 |
| - |
157 |
| - @staticmethod |
158 |
| - def build(report, pvarray): |
159 |
| - """Reports will have total incident irradiance on front and |
160 |
| - back surface of center pvrow (index=1)""" |
161 |
| - # Initialize the report as a dictionary |
162 |
| - if report is None: |
163 |
| - report = {'total_inc_back': [], 'total_inc_front': []} |
164 |
| - # Add elements to the report |
165 |
| - if pvarray is not None: |
166 |
| - pvrow = pvarray.pvrows[1] # use center pvrow |
167 |
| - report['total_inc_back'].append( |
168 |
| - pvrow.back.get_param_weighted('qinc')) |
169 |
| - report['total_inc_front'].append( |
170 |
| - pvrow.front.get_param_weighted('qinc')) |
171 |
| - else: |
172 |
| - # No calculation is performed when the sun is down |
173 |
| - report['total_inc_back'].append(np.nan) |
174 |
| - report['total_inc_front'].append(np.nan) |
175 |
| - |
176 |
| - return report |
177 |
| - |
178 |
| - @staticmethod |
179 |
| - def merge(reports): |
180 |
| - """Works for dictionary reports. Merges the reports list of |
181 |
| - dictionaries in a single dictionary. The list of the first |
182 |
| - dictionary are extended by those of all subsequent lists.""" |
183 |
| - report = reports[0] |
184 |
| - keys_report = list(report.keys()) |
185 |
| - for other_report in reports[1:]: # loop won't run if len(reports) < 2 |
186 |
| - for key in keys_report: |
187 |
| - report[key] += other_report[key] |
188 |
| - return report |
| 150 | + return (df_report.total_inc_front, df_report.total_inc_back, |
| 151 | + df_report.total_abs_front, df_report.total_abs_back) |
0 commit comments