def test_calculate_circumsolar_shading(): """ Test that the disk shading function stays consistent """ # Test for one value of 20% of the diameter being covered percentage_distance_covered = 20. percent_shading = calculate_circumsolar_shading( percentage_distance_covered, model='uniform_disk') # Compare to expected expected_disk_shading_perc = 14.2378489933 atol = 0 rtol = 1e-8 np.testing.assert_allclose(expected_disk_shading_perc, percent_shading, atol=atol, rtol=rtol)
def calculate_circumsolar_shading_pct(self, surface, idx_neighbor, pvrows, solar_2d_vector): """Model method to calculate circumsolar shading on surfaces of the ordered PV array. TODO: This needs to be merged with horizon shading for performance Parameters ---------- surface : :py:class:`~pvfactors.geometry.base.PVSurface` object PV surface for which some horizon band shading will occur idx_neighbor : int Index of the neighboring PV row (can be ``None``) pvrows : list of :py:class:`~pvfactors.geometry.pvrow.PVRow` objects List of PV rows on which ``idx_neighbor`` will be used solar_2d_vector : list Solar vector in the 2D PV array representation Returns ------- circ_shading_pct : float Percentage of circumsolar irradiance shaded (from 0 to 100) """ # TODO: should be applied to all pvrow surfaces if idx_neighbor is not None: # Calculate the solar and circumsolar elevation angles in 2D plane solar_2d_elevation = np.abs( np.arctan(solar_2d_vector[1] / solar_2d_vector[0]) ) * 180. / np.pi lower_angle_circumsolar = (solar_2d_elevation - self.circumsolar_angle / 2.) centroid = surface.centroid neighbor_point = pvrows[idx_neighbor].highest_point shading_angle = np.abs(np.arctan( (neighbor_point.y - centroid.y) / (neighbor_point.x - centroid.x))) * 180. / np.pi percentage_circ_angle_covered = \ (shading_angle - lower_angle_circumsolar) \ / self.circumsolar_angle * 100. circ_shading_pct = calculate_circumsolar_shading( percentage_circ_angle_covered, model=self.circumsolar_model) return circ_shading_pct