This is the source code for the Radiation On Collector program. This program estimates the solar radiation on a flat plate solar collector based on its orientation, the date, and the time.
This is just to take a look at before you download -- if you want to download it, then download all the solar classes here: Solar Tools Source
'Solar Analysis Tools - 'Copyright (C) 2005 Gary Reysa (gary@BuildItSolar.com)
' This program is free software; you can redistribute it and/or modify it ' under the terms of the GNU General Public License as published by the Free ' Software Foundation; either version 2 of the License, or (at your option) ' any later version.
' This program is distributed in the hope that it will be useful and encourage ' further development of solar tools, but WITHOUT ANY WARRANTY; without even ' the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ' See the GNU General Public License for more details.
'Radiation On Collector ' ' Given the following: ' Collector orientation (azimuth and tilt) ' Date ' Altitude above sea level ' ' Radiation on collector will provide: ' With "Day Output" selected: ' Hour by hour values for: ' Direct and diffuse Sun intensity ' Solar azimuth and elevation ' Radiation incident on the collector (corrected for incidence angle) ' Solar incidence angle on collector ' Day totals for above ' ' With "Monthly Output" selected: ' Month by Month values for: ' Direct and Diffuse radiation incident on collector ' for one full day of each month. ' ' 'Sample Daily Output: ' 'Solar Radiation on Collector for day of: 11/21 ' ' Collector Area: 1.0 (sqft) ' Collector Azimuth: 0.0 (deg) measured from South, + is to East ' Collector Tilt: 45.0 (deg) measured from horizontal ' Latitude: 45.0 (deg) ' Altitude: 0.0 (ft) Above Sea Level ' Sun Rise: 7.4 (hr) Sunrise in solar time
'Time Sun -------------------------------- Collector ------------------------------ 'Hour Az Elev DirNormal Diffuse Total HorzTot IncidAng Direct Diffuse ITotal
' 4 96.4 -35.0 0 0 0 0 90 0 0 0 ' 5 85.6 -24.4 0 0 0 0 90 0 0 0 ' 6 75.6 -14.0 0 0 0 0 90 0 0 0 ' 7 65.5 -4.0 0 0 0 0 76 0 0 0 ' 8 54.8 5.2 75 5 80 12 62 35 4 39 ' 9 43.1 13.2 202 13 214 59 48 134 11 145 ' 10 29.9 19.5 248 16 264 98 36 202 13 215 ' 11 15.4 23.6 267 17 284 124 25 242 14 257 ' 12 0.0 25.0 272 17 289 132 20 256 15 271 ' 13 -15.4 23.6 267 17 284 124 25 242 14 257 ' 14 -29.9 19.5 248 16 264 98 36 202 13 215 ' 15 -43.1 13.2 202 13 214 59 48 134 11 145 ' 16 -54.8 5.2 75 5 80 12 62 35 4 39 ' 17 -65.5 -4.0 0 0 0 0 76 0 0 0 ' 18 -75.6 -14.0 0 0 0 0 90 0 0 0 ' 19 -85.6 -24.4 0 0 0 0 90 0 0 0 ' 20 -96.4 -35.0 0 0 0 0 90 0 0 0 ' ----- ------ ------ ----- ----- ----- ----- 'Day Total 1856 117 1973 717 1483 100 1583
'Angles in degrees, Radiations in BTU/hr, DayTotal in BTU/day '1 BTU/hr-ft^2 = 3.152 W/m^2
' Sample Monthly Output: 'Month by Month Summary of Sun on Collector '(100% sunny weather)
' Collector Area: 1.0 (sqft) ' Collector Azimuth: 0.0 (deg) measured from South ' Collector Tilt: 45.0 (deg) measured from horiz ' Latitude: 45.0 (deg) ' Altitude above SL: 0.0 (ft) Above Sea Level
'Date ---- Sun ---------------- Collector ----------------------- 'Month Day Direct Di- Total Direct Difuse Total ' Normal fuse ' 1 21 1933 112 2045 1540 96 1636 ' 2 21 2407 144 2551 1899 123 2022 ' 3 21 2838 201 3039 2099 172 2270 ' 4 21 3090 301 3391 2031 257 2288 ' 5 21 3217 390 3608 1913 333 2246 ' 6 21 3268 437 3706 1841 373 2214 ' 7 21 3117 424 3541 1852 362 2213 ' 8 21 2906 353 3260 1924 301 2225 ' 9 21 2634 245 2879 1959 209 2168 ' 10 21 2241 162 2404 1783 139 1921 ' 11 21 1856 117 1973 1483 100 1583 ' 12 21 1632 94 1726 1316 80 1396 'Sum 31140 2981 34121 21639 2545 24183
'Radiation in BTU/day
' Things To Remember: ' The method assumes 100% sunny weather (no clouds, no fog, no dust, no smog) ' The method is from: Lunde, Solar Thermal Engineering ' ' The method gives the value of solar radiation on the collector surface. ' It is calculated as: ' Icoldir = Idn * cos(IncidenceAngle) -- direct radiation on panel ' Icoldif = Idif * -- diffuse radiation on panel ' Icoltot = Icoldir + Icoldif -- the total radiation on panel ' ' Where Idn is the direct normal clear day solar radiation ' IncidenceAngle is the angle that direct rays from the sun make with the collector surface. ' Idif is the clear day diffuse solar radiation ' ' The effects of the following are not included: ' Ground reflectance (would increase radiation) ' Clouds, fog, smog, dust... (would decrease radiation) ' Absorbtion by glazing (would decrease radiation) ' Reflection by glazing (would decrease radiation) ' ' Also not included is any allowance for the fact that at high incidence angles a glass faced ' collector will reflect more and more of the incident sun (this is in addition to the cosine ' factor, which is included as shown above). ' ' Updated 2/12/05 to use the updated version of CollectorCls Imports System.io Module RadOnCol
Public Const DegPerRad As Single = 57.296 Public Const RadPerDeg As Single = 1.0 / 57.296
Structure DayRec Dim Month As Short Dim Day As Short Dim IdnCum As Double Dim IdifCum As Double Dim IcoldirCum As Double Dim IcoldifCum As Double End Structure
'' To do the plot 'Dim Plot As New PlotFileCls 'Dim Run1 As RunCls
Public csv As Boolean = False
' ' Sunny Day Run -- based on inputs, reports the hour by hour performance of the collector for the ' requested day. ' Sun data is provided by the SunCls object per the Lunde book Function SunnyDay(ByVal Month As Short, ByVal Day As Short, _ ByVal Tilt As Single, ByVal Azimuth As Single, _ ByVal Area As Single, _ ByVal Latitude As Single, _ ByVal Altitude As Single, _ ByVal outStream As Stream) As DayRec
Dim DR As New DayRec
Dim Col As New CollectorCls Dim Sun As New SunCls Dim ToSunVec As New VectorCls
Dim Hour As Integer Dim SunRise As Single Dim AzAng As Double ' Solar azimuth angle (rad) measured from due South, + to East Dim ElevAng As Double ' Solar Elevation Angle (rad) measured from horizontal Dim Idn As Double ' Solar direct normal radiation Dim Idif As Double ' Solar diffuse radiation Dim IhorzTot As Double ' total radiation on horz surface Dim Icoldir As Double ' Direct radiation on collector Dim Icoldif As Double ' diffuse radiation on collector Dim Icoltot As Double ' sum of Idn and Idif Dim IncidAng As Double
' Cumulative Total Vars: Dim DCumIdn As Double Dim DCumIdif As Double Dim DCumIhorzTot As Double Dim DCumIcoldir As Double ' Cum direct rad on collector Dim DCumIcoldif As Double ' Cum diffuse rad on collector Dim DCumIcoltot As Double ' Cum total rad on collector
' Hourly Totals Dim HAzAng(24) As Double Dim HElevAng(24) As Double Dim HIdn(24) As Double Dim HIdif(24) As Double Dim HIhorzTot(24) As Double Dim HIcoldir(24) As Double Dim HIcoldif(24) As Double Dim HIcoltot(24) As Double Dim HIncidAng(24) As Double
' Collector inputs that do not change with time Col.Area = Area ' Col.Tilt = Tilt Col.Azimuth = Azimuth
' Get Idn, Idif, sunvector Sun.Year = 2003 ' use a non leap year for tmy compatibility Sun.Month = Month Sun.DayOfMonth = Day Sun.Longitude = 0 Sun.Latitude = Latitude Sun.Altitude = Altitude ' ft above sealevel SunRise = Sun.Sunrise()
' Step through the day For Hour = 1 To 24 ' Update Sun to new hour Sun.ASThr = Hour
' Get vector to sun position ToSunVec = Sun.ToSunVector AzAng = Sun.AzimuthAng ElevAng = Sun.AltAng
'Use full sun weather instead Idn = Sun.Idn ' note no factor for ground reflectance Idif = Sun.Idiffuse IhorzTot = Sun.Ihorz ' radiation on horz surface
'send updates to collector Col.Idn = Idn Col.Idif = Idif Col.SunVector = ToSunVec
' get updated collector outputs Icoldir = Col.Icoldir Icoldif = Col.Icoldif Icoltot = Col.Icoltot IncidAng = Col.IncidAngle
' store sums and whatever you want 'Col.Dump() 'Sun.Dump() ' Store sums HAzAng(Hour) = AzAng HElevAng(Hour) = ElevAng HIdn(Hour) = Idn DCumIdn += HIdn(Hour) HIdif(Hour) = Idif DCumIdif += HIdif(Hour) HIhorzTot(Hour) = IhorzTot DCumIhorzTot += HIhorzTot(Hour) HIcoldir(Hour) = Icoldir DCumIcoldir += HIcoldir(Hour) HIcoldif(Hour) = Icoldif DCumIcoldif += HIcoldif(Hour) HIcoltot(Hour) = Icoltot DCumIcoltot += HIcoltot(Hour) HIncidAng(Hour) = IncidAng
Next Hour ' end of main sim loop
' Don't output daily info to file if outStream is null If Not (outStream Is Nothing) Then 'Dim sw As New StreamWriter(DFN) Dim sw As StreamWriter sw = New StreamWriter(outStream)
If (csv) Then sw.WriteLine() sw.WriteLine("Solar Radiation on Collector for day of: {0,2}/{1,2}", Month, Day) sw.WriteLine() sw.WriteLine(" Collector Area:,{0,8:F1},(sqft)", Area) sw.WriteLine(" Collector Azimuth:,{0,8:F1},(deg) measured from South, + is to East", Azimuth * DegPerRad) sw.WriteLine(" Collector Tilt:,{0,8:F1},(deg) measured from horizontal", Tilt * DegPerRad) sw.WriteLine(" Latitude:,{0,8:F1},(deg)", Latitude * DegPerRad) sw.WriteLine(" Altitude:,{0,8:F1},(ft) Above Sea Level", Altitude) sw.WriteLine(" Sun Rise:,{0,8:F1},(hr) Sunrise in solar time", SunRise)
sw.WriteLine() sw.WriteLine("Time,Sun ---,,,,Collector --") sw.WriteLine("Hour,Az,Elev,DirNormal,Diffuse,Total,HorzTot,IncidAng,Direct,Diffuse,ITotal") sw.WriteLine()
For hx As Short = 4 To 20 sw.WriteLine("{0,4:N0},{1,6:F1},{2,6:F1},{3,6:F0},{4,6:F0},{5,6:F0},{6,6:F0},{7,6:F0},{8,6:F0},{9,6:F0},{10,6:F0}", _ hx, HAzAng(hx) * DegPerRad, HElevAng(hx) * DegPerRad, _ HIdn(hx), HIdif(hx), HIdn(hx) + HIdif(hx), Area * HIhorzTot(hx), _ HIncidAng(hx) * DegPerRad, Area * HIcoldir(hx), Area * HIcoldif(hx), Area * HIcoltot(hx)) 'sw.WriteLine("{0,4:N0}" + ControlChars.Tab + "{1,6:F1}" + ControlChars.Tab + "{2,6:F1}" + ControlChars.Tab + "{3,6:F0}" + ControlChars.Tab + "{4,6:F0}" + ControlChars.Tab + "{5,6:F0}" + ControlChars.Tab + "{6,6:F0}" + ControlChars.Tab + "{7,6:F0}" + ControlChars.Tab + "{8,6:F0}" + ControlChars.Tab + "{9,6:F0}" + ControlChars.Tab + "{10,6:F0}", _ ' hx, HAzAng(hx) * DegPerRad, HElevAng(hx) * DegPerRad, _ ' HIdn(hx), HIdif(hx), HIdn(hx) + HIdif(hx), Area * HIhorzTot(hx), _ ' HIncidAng(hx) * DegPerRad, Area * HIcoldir(hx), Area * HIcoldif(hx), Area * HIcoltot(hx)) Next sw.WriteLine(",,,-----,------,------,-----,,-----,-----,-----") sw.WriteLine("Day Total,,,{0,6:F0},{1,6:F0},{2,6:F0},{3,6:F0},,{4,6:F0},{5,6:F0},{6,6:F0} ", _ DCumIdn, DCumIdif, DCumIdn + DCumIdif, _ Area * DCumIhorzTot, Area * DCumIcoldir, Area * DCumIcoldif, Area * DCumIcoltot)
sw.WriteLine() sw.WriteLine("Angles in degrees") sw.WriteLine("Radiations in BTU/hr") sw.WriteLine("DayTotal in BTU/day ") sw.WriteLine("1 BTU/hr-ft^2 = 3.152 W/m^2 ") Else sw.WriteLine() sw.WriteLine("Solar Radiation on Collector for day of: {0,2}/{1,2}", Month, Day) sw.WriteLine() sw.WriteLine(" Collector Area: {0,8:F1} (sqft)", Area) sw.WriteLine(" Collector Azimuth: {0,8:F1} (deg) measured from South, + is to East", Azimuth * DegPerRad) sw.WriteLine(" Collector Tilt: {0,8:F1} (deg) measured from horizontal", Tilt * DegPerRad) sw.WriteLine(" Latitude: {0,8:F1} (deg)", Latitude * DegPerRad) sw.WriteLine(" Altitude: {0,8:F1} (ft) Above Sea Level", Altitude) sw.WriteLine(" Sun Rise: {0,8:F1} (hr) Sunrise in solar time", SunRise)
sw.WriteLine() sw.WriteLine("Time Sun -------------------------------- Collector ------------------------------") sw.WriteLine("Hour Az Elev DirNormal Diffuse Total HorzTot IncidAng Direct Diffuse ITotal") sw.WriteLine()
For hx As Short = 4 To 20 sw.WriteLine("{0,4:N0} {1,6:F1} {2,6:F1} {3,6:F0} {4,6:F0} {5,6:F0} {6,6:F0} {7,6:F0} {8,6:F0} {9,6:F0} {10,6:F0}", _ hx, HAzAng(hx) * DegPerRad, HElevAng(hx) * DegPerRad, _ HIdn(hx), HIdif(hx), HIdn(hx) + HIdif(hx), Area * HIhorzTot(hx), _ HIncidAng(hx) * DegPerRad, Area * HIcoldir(hx), Area * HIcoldif(hx), Area * HIcoltot(hx)) 'sw.WriteLine("{0,4:N0}" + ControlChars.Tab + "{1,6:F1}" + ControlChars.Tab + "{2,6:F1}" + ControlChars.Tab + "{3,6:F0}" + ControlChars.Tab + "{4,6:F0}" + ControlChars.Tab + "{5,6:F0}" + ControlChars.Tab + "{6,6:F0}" + ControlChars.Tab + "{7,6:F0}" + ControlChars.Tab + "{8,6:F0}" + ControlChars.Tab + "{9,6:F0}" + ControlChars.Tab + "{10,6:F0}", _ ' hx, HAzAng(hx) * DegPerRad, HElevAng(hx) * DegPerRad, _ ' HIdn(hx), HIdif(hx), HIdn(hx) + HIdif(hx), Area * HIhorzTot(hx), _ ' HIncidAng(hx) * DegPerRad, Area * HIcoldir(hx), Area * HIcoldif(hx), Area * HIcoltot(hx)) Next sw.WriteLine(" ----- ------ ------ ----- ----- ----- -----") sw.WriteLine("Day Total {0,6:F0} {1,6:F0} {2,6:F0} {3,6:F0} {4,6:F0} {5,6:F0} {6,6:F0} ", _ DCumIdn, DCumIdif, DCumIdn + DCumIdif, _ Area * DCumIhorzTot, Area * DCumIcoldir, Area * DCumIcoldif, Area * DCumIcoltot)
sw.WriteLine() sw.WriteLine("Angles in degrees, Radiations in BTU/hr, DayTotal in BTU/day ") sw.WriteLine("1 BTU/hr-ft^2 = 3.152 W/m^2 ") End If sw.Close() End If
DR.Month = Month DR.Day = Day DR.IdnCum = DCumIdn DR.IdifCum = DCumIdif DR.IcoldirCum = DCumIcoldir DR.IcoldifCum = DCumIcoldif Return DR
End Function ' SunnyDay
' Sunny Year ' Write to a file the month by month summary of solar incidence on a collector ' that is defined by the passed parms. ' Each month is represented by the Day that is passed (e.g. you could pass 15 for middle of ' month, or 21 to jibe with the solar calendar)
Function SunnyYear(ByVal Day As Short, _ ByVal Tilt As Single, ByVal Azimuth As Single, _ ByVal Area As Single, _ ByVal Latitude As Single, _ ByVal Altitude As Single, _ ByVal outStream As Stream) As DayRec
Dim DayOutStream As Stream = Nothing Dim MRecs(13) As DayRec Dim YCumIdn As Double Dim YCumIdif As Double Dim YCumColDir As Double Dim YCumColDif As Double
For ix As Short = 0 To 13 MRecs(ix) = New DayRec Next
Dim mw As StreamWriter mw = New StreamWriter(outStream)
For Month As Short = 1 To 12 MRecs(Month) = SunnyDay(Month, Day, Tilt, Azimuth, Area, Latitude, Altitude, DayOutStream) YCumIdn += MRecs(Month).IdnCum YCumIdif += MRecs(Month).IdifCum YCumColDir += MRecs(Month).IcoldirCum YCumColDif += MRecs(Month).IcoldifCum Next
If csv Then ' write out the year summary mw.WriteLine() mw.WriteLine("Month by Month Summary of Sun on Collector") mw.WriteLine("(100% sunny weather)") mw.WriteLine() mw.WriteLine(" Collector Area:,{0,8:F1},(sqft)", Area) mw.WriteLine(" Collector Azimuth:,{0,8:F1},(deg) measured from South", Azimuth * DegPerRad) mw.WriteLine(" Collector Tilt:,{0,8:F1}, (deg) measured from horiz", Tilt * DegPerRad) mw.WriteLine(" Latitude:,{0,8:F1}, (deg)", Latitude * DegPerRad) mw.WriteLine(" Altitude above SL:,{0,8:F1}, (ft) Above Sea Level", Altitude) mw.WriteLine()
mw.WriteLine("Date --,,Sun -----,,, Collector --")
mw.WriteLine("Month,Day,Direct Normal,Difuse, Total, Direct, Difuse, Total")
For mx As Short = 1 To 12
mw.WriteLine("{0,4},{1,4},{2,6:F0},{3,6:F0},{4,6:F0},{5,10:F0},{6,10:F0},{7,10:F0}", _ mx, Day, _ MRecs(mx).IdnCum, MRecs(mx).IdifCum, _ MRecs(mx).IdnCum + MRecs(mx).IdifCum, _ Area * MRecs(mx).IcoldirCum, _ Area * MRecs(mx).IcoldifCum, _ Area * MRecs(mx).IcoldifCum + Area * MRecs(mx).IcoldirCum)
Next mw.WriteLine("Sum,,{0,6:F0}, {1,6:F0},{2,6:F0},{3,10:F0},{4,10:F0},{5,10:F0}", _ YCumIdn, YCumIdif, YCumIdn + YCumIdif, _ Area * YCumColDir, Area * YCumColDif, Area * YCumColDir + Area * YCumColDif)
mw.WriteLine() mw.WriteLine("Radiation in BTU/day") Else ' write out the year summary mw.WriteLine() mw.WriteLine("Month by Month Summary of Sun on Collector") mw.WriteLine("(100% sunny weather)") mw.WriteLine() mw.WriteLine(" Collector Area: {0,8:F1} (sqft)", Area) mw.WriteLine(" Collector Azimuth:{0,8:F1} (deg) measured from South", Azimuth * DegPerRad) mw.WriteLine(" Collector Tilt: {0,8:F1} (deg) measured from horiz", Tilt * DegPerRad) mw.WriteLine(" Latitude: {0,8:F1} (deg)", Latitude * DegPerRad) mw.WriteLine(" Altitude above SL:{0,8:F1} (ft) Above Sea Level", Altitude) mw.WriteLine()
mw.WriteLine("Date ---- Sun ---------------- Collector -----------------------")
mw.WriteLine("Month Day Direct Di- Total Direct Difuse Total") mw.WriteLine(" Normal fuse ")
For mx As Short = 1 To 12
mw.WriteLine("{0,4} {1,4} {2,6:F0} {3,6:F0} {4,6:F0} {5,10:F0} {6,10:F0} {7,10:F0}", _ mx, Day, _ MRecs(mx).IdnCum, MRecs(mx).IdifCum, _ MRecs(mx).IdnCum + MRecs(mx).IdifCum, _ Area * MRecs(mx).IcoldirCum, _ Area * MRecs(mx).IcoldifCum, _ Area * MRecs(mx).IcoldifCum + Area * MRecs(mx).IcoldirCum)
Next mw.WriteLine("Sum {0,6:F0} {1,6:F0} {2,6:F0} {3,10:F0} {4,10:F0} {5,10:F0}", _ YCumIdn, YCumIdif, YCumIdn + YCumIdif, _ Area * YCumColDir, Area * YCumColDif, Area * YCumColDir + Area * YCumColDif)
mw.WriteLine() mw.WriteLine("Radiation in BTU/day") End If mw.Close()
End Function
Sub main() Dim CD As String = Directory.GetCurrentDirectory() ' rtns the dir that program is executing from (Collector/bin)
Dim Month As Short = 6 ' month of year ( 1 to 12) Dim Day As Short = 21 ' Day of month Dim Tilt As Single = 40 / DegPerRad ' Collector tilt from horizontal (rad) Dim Azimuth As Single = 0 / DegPerRad ' Collector azimuth (0 is true south, + to east, (rad) ) Dim Area As Single = 1 ' Collector area in ft^2 Dim Longitude As Single = 0 / DegPerRad ' Longitude + to West (rad) Dim Latitude As Single = 40 / DegPerRad ' Latitude + North (rad) Dim Altitude As Single = 0 ' feet above SL Dim DFN As String ' filename for output from SunnyDay Dim YFN As String ' filename for output from SunnyYear Dim FN As String
DFN = "c:\Documents and Settings\Gary\My Documents\Visual Studio Projects\RadOnCol\DayOut.txt" YFN = "c:\Documents and Settings\Gary\My Documents\Visual Studio Projects\RadOnCol\YearOut"
' calc solar indicidence on collector for one day 'DR = SunnyDay(Month, Day, Tilt, Azimuth, Area, Latitude, Altitude, DFN)
For Tilt = 0 To 40 Step 10 FN = YFN & Tilt & ".txt" 'SunnyYear(Day, Tilt / DegPerRad, Azimuth, Area, Latitude, Altitude, FN) Next
End Sub ' main
End Module