Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Negative irradiance values when PV modules go underground #141

Open
kandersolar opened this issue Apr 9, 2022 · 1 comment
Open

Negative irradiance values when PV modules go underground #141

kandersolar opened this issue Apr 9, 2022 · 1 comment

Comments

@kandersolar
Copy link
Contributor

kandersolar commented Apr 9, 2022

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:

image

Code to reproduce above plot (v1.5.2):

Click to expand!
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?

        # Check whether the lower module edge ever goes underground
        lower_edge_height = self.height - 0.5 * self.width * np.sin(np.radians(surface_tilt))
        if np.any(lower_edge_height < 0):
            msg = ("Input pvrow_height is not large enough to prevent modules "
                   "from colliding with ground. Check pvrow_width, "
                   "pvrow_height, and surface_tilt.")
            raise ValueError(msg)
@anomam
Copy link
Contributor

anomam commented Oct 1, 2022

😔 yeah I tripped on this a few times also... the fit() function does sound like a good place to add a validation layer, not only on the geometry side but also on the irradiance too (maybe looking for negative values, ...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants