@@ -135,25 +135,10 @@ annual irradiance than the best fixed panel from the previous example.
135135
136136## One day of tracker operation
137137
138- One day of operation makes the behaviour concrete. The site is the Van Gogh Museum in
139- Amsterdam with the tracker axis aimed due south. Negative rotation faces the panel
140- east. All curves run from 00:00 to 24:00, with the tracker holding its sunrise and
141- sunset angles overnight. The upper panel compares the tracker rotation against the
142- analytical rotation computed from first principles with only the solstice declination,
143- the latitude, and the hour angle, ignoring the equation of time. The dashed curve lies
144- exactly on the solid one until the ±60° limits cut it off, while the analytical ideal
145- keeps following the sun below the horizon and wraps at ±180° late in the evening when
146- the sun passes due north. The lower panel shows the sun elevation, negative at night,
147- and the angle of incidence between the panel normal and the sun, for the tracker and
148- for a fixed panel at 30° tilt facing south. The tracked angle of incidence touches
149- zero exactly when the sun crosses due east and due west, because only then does the
150- sun lie in the tracker's rotation plane, and its local maximum at noon equals the
151- solar zenith angle because the panel is flat at that moment. The fixed panel aligns
152- with the sun only once, near noon, where it beats the tracker: the horizontal axis
153- cannot tilt the panel toward the south, so around midday the south facing fixed panel
154- points closer to the sun. Recovering that noon deficit is why tilted single axis
155- trackers exist. At night both angles of incidence exceed 90° since the sun is behind
156- the panels:
138+ A full day makes the behaviour concrete: the Van Gogh Museum in Amsterdam, tracker axis
139+ aimed due south, negative rotation facing the panel east.
140+
141+ Start with the sun's position at one minute resolution across the whole day.
157142
158143``` @example autodiff
159144using CairoMakie
@@ -164,31 +149,42 @@ axis_south = 180.0
164149day = collect(DateTime(2024, 6, 21):Minute(1):DateTime(2024, 6, 22))
165150day_pos = solar_position(vgm, day, PSA(), NoRefraction())
166151hours = [Dates.value(t - day[1]) / 3_600_000 for t in day]
152+ elevation = [p.elevation for p in day_pos]
153+ nothing # hide
154+ ```
155+
156+ The tracker rotation, clamped to ±60° and held at its sunrise and sunset angles overnight.
167157
168- # tracker rotation, held at its sunrise and sunset angles overnight
158+ ``` @example autodiff
169159rot(p) = clamp(atand(tand(p.zenith) * sind(p.azimuth - axis_south)), -60.0, 60.0)
170160sunup = [p.elevation > 0 for p in day_pos]
171161first_up, last_up = findfirst(sunup), findlast(sunup)
172162rotation = [rot(day_pos[clamp(i, first_up, last_up)]) for i in eachindex(day_pos)]
163+ nothing # hide
164+ ```
173165
174- elevation = [p.elevation for p in day_pos]
166+ The angle between the sun and the panel normal, for the tracker and for a fixed reference
167+ panel at 30° tilt facing south.
175168
176- # angle of incidence against the actual panel orientation
169+ ``` @example autodiff
177170function cos_aoi(p, R, axis_azimuth)
178171 panel_azimuth = axis_azimuth + (R < 0 ? -90 : 90)
179172 return cosd(p.zenith) * cosd(R) +
180173 sind(p.zenith) * sind(abs(R)) * cosd(p.azimuth - panel_azimuth)
181174end
182175aoi = [acosd(clamp(cos_aoi(p, R, axis_south), -1, 1)) for (p, R) in zip(day_pos, rotation)]
183176
184- # fixed reference panel at 30 degree tilt facing south
185177aoi_fixed = [
186178 acosd(clamp(cosd(p.zenith) * cosd(30) + sind(p.zenith) * sind(30) * cosd(p.azimuth - 180), -1, 1))
187179 for p in day_pos
188180]
181+ nothing # hide
182+ ```
183+
184+ The analytical ideal, from the solstice declination, latitude, and hour angle alone,
185+ ignoring the equation of time. A ` NaN ` marks where it wraps at ±180°.
189186
190- # analytical ideal rotation from declination, latitude, and hour angle alone,
191- # with one NaN inserted at the 180 degree wrap
187+ ``` @example autodiff
192188decl = 23.437
193189lat, lon = vgm.latitude, vgm.longitude
194190omega = [15 * (h - 12) + lon for h in hours]
@@ -199,7 +195,12 @@ analytical = [
199195for i in eachindex(analytical)[2:end]
200196 abs(analytical[i] - analytical[i - 1]) > 180 && (analytical[i - 1] = NaN)
201197end
198+ nothing # hide
199+ ```
202200
201+ Finally the figure, rotation above and angles below.
202+
203+ ``` @example autodiff
203204# colorblind safe hues from the Wong palette, validated for each within panel group
204205blue, orange, green, vermilion, skyblue = "#0072B2", "#E69F00", "#009E73", "#D55E00", "#56B4E9"
205206
@@ -227,3 +228,11 @@ xlims!(ax2, 0, 24)
227228axislegend(ax2; position = :ct)
228229fig
229230```
231+
232+ Three things to read from it. The tracker rotation lies exactly on the analytical curve
233+ until the ±60° limits cut it off, while the ideal keeps following the sun below the horizon
234+ and wraps when it passes due north. The tracked angle of incidence touches zero exactly when
235+ the sun crosses due east and due west, the only moments the sun lies in the tracker's
236+ rotation plane, and its local maximum at noon equals the solar zenith because the panel is
237+ flat then. The fixed panel beats the tracker around midday, since a horizontal axis cannot
238+ tilt the panel south; recovering that noon deficit is why tilted single axis trackers exist.
0 commit comments