Currently there is nothing stopping a user from specifying an array much wider than it is tall and proceeding to model it at steep tilts that cause the lower module edge to go to negative heights. When that happens, negative irradiance values are returned. For example, for static solar position and irradiance, here's how the returned rearside irradiance varies with surface tilt for an array with pvrow_width/pvrow_height=3 showing how irradiance goes negative when pvrow_width/2 * sin(surface_tilt) > pvrow_height:
Originally posted in https://github.com/SunPower/pvfactors/issues/141:
Currently there is nothing stopping a user from specifying an array much wider than it is tall and proceeding to model it at steep tilts that cause the lower module edge to go to negative heights. When that happens, negative irradiance values are returned. For example, for static solar position and irradiance, here's how the returned rearside irradiance varies with surface tilt for an array with
pvrow_width/pvrow_height=3
showing how irradiance goes negative whenpvrow_width/2 * sin(surface_tilt) > pvrow_height
:Code to reproduce above plot (v1.5.2):
Click to expand!
```python from pvfactors.geometry import OrderedPVArray from pvfactors.engine import PVEngine import pandas as pd import numpy as np import matplotlib.pyplot as plt ts_inputs = pd.DataFrame({ "timestamps": 0, "DNI": 1000, "DHI": 200, "solar_zenith": 45, "solar_azimuth": 90, "surface_tilt": np.linspace(0, 90, num=1000), "surface_azimuth": 90, "albedo": 0.2, }) pvarray_parameters = { "n_pvrows": 3, "pvrow_height": 1, "pvrow_width": 3, "axis_azimuth": 180, "gcr": 0.5, } # tilt when part of the module goes underground boundary_tilt = np.degrees(np.arcsin( pvarray_parameters["pvrow_height"] / (pvarray_parameters["pvrow_width"] / 2) )) pvarray = OrderedPVArray.init_from_dict(pvarray_parameters) engine = PVEngine(pvarray) engine.fit(**ts_inputs) engine.run_full_mode() grear = pvarray.ts_pvrows[0].back.get_param_weighted("qinc") plt.plot(ts_inputs["surface_tilt"], grear) plt.axvline(boundary_tilt, c='k', ls='--') plt.xlabel("Surface Tilt [degrees]") plt.ylabel("Rearside Irradiance [W/m2]") ```This behavior has tripped people up at least twice:
I think it would be good to raise an error, or at least emit a warning, in this situation. Perhaps a check like this in
OrderedPVArray.fit
?