Skip to content

Commit 5b0d7b7

Browse files
committed
Add test for vf_ground_sky_2d view factor bounds
1 parent 802dfc6 commit 5b0d7b7

2 files changed

Lines changed: 26 additions & 13 deletions

File tree

pvlib/bifacial/utils.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,25 @@ def vf_ground_sky_2d(rotation, gcr, x, pitch, height, max_rows=10):
159159
# swap angles so that phi[0,:,:,:] is the lesser angle
160160
phi.sort(axis=0)
161161

162-
# now re-use phi's memory again, this time storing cos(phi).
163-
next_edge = phi[1, :, :, 1:]
164-
np.cos(next_edge, out=next_edge)
165-
prev_edge = phi[0, :, :, :-1]
166-
np.cos(prev_edge, out=prev_edge)
167-
# right edge of next row - left edge of previous row, again
168-
# reusing memory so that the difference is stored in next_edge.
169-
# Note that the 0.5 view factor coefficient is applied after summing
170-
# as a minor speed optimization.
171-
np.subtract(next_edge, prev_edge, out=next_edge)
172-
np.clip(next_edge, a_min=0., a_max=None, out=next_edge)
173-
vf = np.sum(next_edge, axis=-1) / 2
162+
# compute cos(phi) into new arrays (avoid overwriting phi)
163+
upper = phi[1].copy()
164+
lower = phi[0].copy()
165+
np.cos(upper, out=upper)
166+
np.cos(lower, out=lower)
167+
168+
# include horizon bounds
169+
# leftmost bound: cos(0)=1
170+
# rightmost bound: cos(pi)=-1
171+
upper = np.concatenate([upper, -np.ones_like(upper[..., :1])], axis=-1)
172+
lower = np.concatenate([np.ones_like(lower[..., :1]), lower], axis=-1)
173+
174+
# wedge contribution = upper - lower for each wedge
175+
diff = upper - lower
176+
np.clip(diff, a_min=0., a_max=None, out=diff)
177+
178+
vf = np.sum(diff, axis=-1) / 2
174179
return vf
175180

176-
177181
def vf_ground_sky_2d_integ(surface_tilt, gcr, height, pitch, max_rows=10,
178182
npoints=100, vectorize=False):
179183
"""

tests/bifacial/test_utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pvlib.shading import masking_angle, ground_angle
88
from pvlib.tools import cosd
99
from scipy.integrate import trapezoid
10+
from pvlib.bifacial.utils import vf_ground_sky_2d
1011

1112

1213
@pytest.fixture
@@ -190,3 +191,11 @@ def test_vf_ground_2d_integ(test_system_fixed_tilt):
190191
y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
191192
y1 = trapezoid(y, x) / (1 - 0)
192193
assert np.allclose(vf, y1, rtol=1e-2)
194+
195+
def test_vf_ground_sky_2d_returns_valid_range():
196+
vf = vf_ground_sky_2d(rotation=0, gcr=0.5, x=0.5,
197+
pitch=1, height=1, max_rows=3)
198+
199+
assert vf.shape == (1, 1)
200+
assert np.all(vf >= 0.0)
201+
assert np.all(vf <= 1.0)

0 commit comments

Comments
 (0)