@@ -1096,17 +1096,27 @@ def solar_azimuth_analytical(latitude, hour_angle, declination, zenith):
1096
1096
hour_angle
1097
1097
solar_zenith_analytical
1098
1098
"""
1099
+
1100
+ numer = (np .cos (zenith ) * np .sin (latitude ) - np .sin (declination ))
1101
+ denom = (np .sin (zenith ) * np .cos (latitude ))
1102
+
1103
+ # cases that would generate new NaN values are safely ignored here
1104
+ # since they are dealt with further below
1099
1105
with np .errstate (invalid = 'ignore' , divide = 'ignore' ):
1106
+ cos_azi = numer / denom
1107
+
1108
+ # when zero division occurs, use the limit value of the analytical expression
1109
+ cos_azi = np .where (np .isclose (denom , 0.0 , rtol = 0.0 , atol = 1e-8 ), 1.0 , cos_azi )
1100
1110
1101
- cos_azi = ((np .cos (zenith ) * np .sin (latitude ) - np .sin (declination )) /
1102
- (np .sin (zenith ) * np .cos (latitude )))
1111
+ # when too many round-ups in floating point math take cos_azi beyond 1.0, use 1.0
1112
+ cos_azi = np .where (np .isclose (cos_azi , 1.0 , rtol = 0.0 , atol = 1e-8 ), 1.0 , cos_azi )
1113
+ cos_azi = np .where (np .isclose (cos_azi , - 1.0 , rtol = 0.0 , atol = 1e-8 ), - 1.0 , cos_azi )
1103
1114
1104
- cos_azi = np .where (np .isclose (zenith , 0.0 ), 1.0 , cos_azi )
1105
- cos_azi = np .where (np .isclose (latitude , 0.0 ), 1.0 , cos_azi )
1106
- cos_azi = np .where (np .isclose (cos_azi , 1.0 ), 1.0 , cos_azi )
1107
- cos_azi = np .where (np .isclose (cos_azi , - 1.0 ), - 1.0 , cos_azi )
1115
+ # when NaN values occur in input, ignore and pass to output
1116
+ with np .errstate (invalid = 'ignore' ):
1117
+ sign_ha = np .sign (hour_angle )
1108
1118
1109
- return (np . sign ( hour_angle ) * np .arccos (cos_azi ) + np .pi )
1119
+ return (sign_ha * np .arccos (cos_azi ) + np .pi )
1110
1120
1111
1121
1112
1122
def solar_zenith_analytical (latitude , hour_angle , declination ):
0 commit comments