Skip to content

Commit

Permalink
Merge pull request #3 from cdeline/cleanup
Browse files Browse the repository at this point in the history
Fixing single-axis tracking workflow and errors
  • Loading branch information
cdeline committed Oct 6, 2017
2 parents 3ccbf56 + fbc288a commit e4ef1e8
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 248 deletions.
146 changes: 69 additions & 77 deletions bifacialvf/bifacialvf.py
Expand Up @@ -25,20 +25,36 @@
import csv
import pvlib
import os
#import sys
#sys.path.insert(0, '../BF_BifacialIrradiances')

from vf import getBackSurfaceIrradiances, getFrontSurfaceIrradiances, getGroundShadeFactors
from vf import getSkyConfigurationFactors, trackingBFvaluescalculator, rowSpacing
from sun import hrSolarPos, perezComp, solarPos, sunIncident
import pandas as pd



def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
def simulate(TMYtoread, writefiletitle, beta = 0, sazm = 180, C = 0.5, D = None,
rowType = 'interior', transFactor = 0.01, cellRows = 6,
PVfrontSurface = 'glass', PVbackSurface = 'glass', albedo = 0.62,
tracking = False, backtrack = True, r2r = 1.5, Cv= 0.05, offset = 0):
PVfrontSurface = 'glass', PVbackSurface = 'glass', albedo = 0.2,
tracking = False, backtrack = True, rtr = None, Cv = None, offset = 0):


if tracking == True:
axis_tilt = 0 # algorithm only allows for zero north-south tilt with SAT
max_angle = 90 # maximum tracker rotation
axis_azimuth=sazm # axis_azimuth is degrees east of North
beta = 0 # start with tracker tilt = 0
hub_height = C # Ground clearance at tilt = 0. C >= 0.5
if hub_height < 0.5:
print('Warning: tracker hub height C < 0.5 may result in ground clearance errors')

if (D == None) & (rtr != None):
D = rtr - math.cos(beta / 180.0 * math.pi)
elif (rtr == None) & (D != None):
rtr = D + math.cos(beta / 180.0 * math.pi)
elif (D == None) & (rtr == None):
raise Exception('No row distance specified in either D or rtr')
else:
print('Warning: Gap D and rtr passed in. Using ' + ('rtr' if tracking else 'D') )

## Read TMY3 data and start loop ~
(myTMY3,meta)=pvlib.tmy.readtmy3(TMYtoread)
#myAxisTitles=myTMY3.axes
Expand All @@ -55,7 +71,7 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
print "Running Simulation for TMY3: ", TMYtoread
print "Location: ", name
print "Lat: ", lat, " Long: ", lng, " Tz ", tz
print "Parameters: beta: ", beta, " Sazm: ", sazm, " Height: ", C, " D separation: ", D, " Row type: ", rowType, " Albedo: ", albedo
print "Parameters: beta: ", beta, " Sazm: ", sazm, " Height: ", C, " rtr separation: ", rtr, " Row type: ", rowType, " Albedo: ", albedo
print "Saving into", writefiletitle
print " "
print " "
Expand All @@ -80,23 +96,12 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
sw = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
# Write Simulation Parameters (from setup file)

if tracking==True:
Ctype='Vertical GroundClearance(panel slope lengths) Cv'
Dtype='Row-to-Row-Distance rtr'
Ctypevar=Cv
Dtypevar=r2r
else:
Ctype='GroundClearance(panel slope lengths)'
Dtype='DistanceBetweenRows(panel slope lengths)'
Ctypevar=C
Dtypevar=D

outputheader=['Latitude(deg)','Longitude(deg)', 'Time Zone','Tilt(deg)',
'PV Azimuth(deg)',Ctype, Dtype, 'RowType(first interior last single)',
'PV Azimuth(deg)','GroundClearance(panel slope lengths)', 'Row-to-Row-Distance rtr', 'RowType(first interior last single)',
'TransmissionFactor(open area fraction)','CellRows(# hor rows in panel)',
'PVfrontSurface(glass or AR glass)', 'PVbackSurface(glass or AR glass)',
'CellOffsetFromBack(panel slope lengths)','Albedo', 'Tracking']
outputheadervars=[lat, lng, tz, beta, sazm, Ctypevar, Dtypevar, rowType, transFactor, cellRows, PVfrontSurface,
outputheadervars=[lat, lng, tz, beta, sazm, C, rtr, rowType, transFactor, cellRows, PVfrontSurface,
PVbackSurface, offset, albedo, tracking]


Expand Down Expand Up @@ -125,6 +130,7 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
print " ***** IMPORTANT --> THIS SIMULATION Has Tracking Activated"
print "Backtracking Option is set to: ", backtrack
outputtitles+=['beta']
outputtitles+=['sazm']
outputtitles+=['height']
outputtitles+=['D']

Expand All @@ -134,10 +140,7 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
rl = 0

while (rl < noRows):
#while (rl < 8): # Test while
# rl = 8 # Test value



myTimestamp=myTMY3.index[rl]
year = myTimestamp.year
month = myTimestamp.month
Expand All @@ -156,7 +159,7 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
azm, zen, elv, dec, sunrise, sunset, Eo, tst, suntime = hrSolarPos(year, month, day, hour, lat, lng, tz)

elif (dataInterval == 1 or dataInterval == 5 or dataInterval == 15):
azm, zen, elv, dec, sunrise, sunset, Eo, tst = solarPos(year, month, day, hour, minute - 0.5 * dataInterval, lat, lng, tz)
azm, zen, elv, dec, sunrise, sunset, Eo, tst = solarPos(year, month, day, hour, minute - 0.5 * dataInterval, lat, lng, tz)
else :
print("ERROR: data interval not 1, 5, 15, or 60 minutes.");

Expand All @@ -172,56 +175,29 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,

# TRACKING ROUTINE CALULATING GETSKYCONFIGURATION FACTORS
if tracking == True:

daystr=str(day)
if day<10:
daystr="0"+str(day)

monthstr=str(month)
if month<10:
monthstr="0"+str(month)

hourstr = str(hour)
if hour<10:
hourstr="0"+str(hour)

minutestr=str(minute)
if minute<10:
minutestr="0"+str(minute)

if tz >= 0 and tz < 10:
tzstr="+0"+str(int(tz))
if tz >= 10:
tzstr="+"+str(tz)
if tz <0 and tz>-10:
tzstr="-0"+str(abs(int(tz)))
if tz<=-10:
tzstr=str(int(tz))

times_loc=str(year)+"-"+monthstr+"-"+daystr+" "+hourstr+":"+minutestr+":00"+tzstr+":00"

solpos = pvlib.solarposition.get_solarposition(times_loc, lat, lng)
aazi= solpos['azimuth']
azen= solpos['apparent_zenith']
axis_tilt = 0
axis_azimuth=sazm # 180 axis N-S
max_angle=180
#solpos = pvlib.solarposition.get_solarposition(myTimestamp, lat, lng)
#aazi= solpos['azimuth']
#azen= solpos['zenith']
aazi = pd.Series([azm*180.0/math.pi], index =[myTimestamp])
azen = pd.Series([zen*180.0/math.pi], index =[myTimestamp])



gcr=0.2857142857142857 # A value denoting the ground coverage ratio of a tracker system which utilizes backtracking; i.e. the ratio between the PV array surface area to total ground area. A tracker system with modules 2 meters wide, centered on the tracking axis, with 6 meters between the tracking axes has a gcr of 2/6=0.333. If gcr is not provided, a gcr of 2/7 is default. gcr must be <=1.
gcr=1/rtr
trackingdata = pvlib.tracking.singleaxis(azen, aazi, axis_tilt, axis_azimuth, max_angle, backtrack, gcr)
## Sky configuration factors are not the same for all times, since the geometry is changing with the tracking.
beta=trackingdata.iloc[0][3] # Trackingdata tracker_theta

beta=trackingdata['surface_tilt'][0] # Trackingdata tracker_theta
sazm = trackingdata['surface_azimuth'][0]
if math.isnan(beta):
beta=90
#print beta

# Rotate system if past sun's zenith ~ #123 Check if system breaks withot doing this.
if beta<0:
sazm = sazm+180 # Rotate detectors
#sazm = sazm+180 # Rotate detectors
beta = -beta;
rotatedetectors = True
[C, D] = trackingBFvaluescalculator(beta, Cv, r2r)

[C, D] = trackingBFvaluescalculator(beta, hub_height, rtr)
[rearSkyConfigFactors, frontSkyConfigFactors, ffConfigFactors] = getSkyConfigurationFactors(rowType, beta, C, D); ## Sky configuration factors are the same for all times, only based on geometry and row type


Expand Down Expand Up @@ -294,6 +270,7 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,

if tracking==True:
outputvalues.append(beta)
outputvalues.append(sazm)
outputvalues.append(C)
outputvalues.append(D)

Expand All @@ -310,31 +287,46 @@ def simulate(TMYtoread, writefiletitle, beta, sazm, C = 1, D = 0.5,
return;

if __name__ == "__main__":
#import time
#start_time = time.time()


beta = 10 # PV tilt (deg)
sazm = 180 # PV Azimuth(deg)
C = 1 # GroundClearance(panel slope lengths)
sazm = 180 # PV Azimuth(deg) or tracker axis direction
C = 1 # GroundClearance(panel slope lengths). For tracking this is tilt = 0 hub height
D = 0.51519 # DistanceBetweenRows(panel slope lengths)
rowType = "interior" # RowType(first interior last single)
transFactor = 0.013 # TransmissionFactor(open area fraction)
cellRows = 6 # CellRows(# hor rows in panel) <--> THIS IS FOR LANDSCAPE, YINLI MODEL
PVfrontSurface = "glass" #PVfrontSurface(glass or AR glass)
cellRows = 6 # CellRows(# hor rows in panel) <--> THIS ASSUMES LANDSCAPE ORIENTATION
PVfrontSurface = "glass" # PVfrontSurface(glass or AR glass)
PVbackSurface = "glass" # PVbackSurface(glass or AR glass)
albedo = 0.62 # albedo
dataInterval = 60 # DataInterval(minutes)
albedo = 0.62 # ground albedo



# Tracking instructions
tracking=False
backtrack=True
r2r = 1.5 # meters. This input is not used (D is used instead) except for in tracking
Cv = 0.05 # GroundClearance when panel is in vertical position (panel slope lengths)
rtr = 1.5 # row to row spacing in normalized panel lengths.

TMYtoread="data/724010TYA.csv" # VA Richmond
writefiletitle="data/Output/TEST.csv"

simulate(TMYtoread, writefiletitle, beta, sazm,
C, D, rowType= rowType, transFactor= transFactor, cellRows= cellRows,
simulate(TMYtoread, writefiletitle, beta, sazm, C, rtr= rtr,
rowType= rowType, transFactor= transFactor, cellRows= cellRows,
PVfrontSurface= PVfrontSurface, PVbackSurface= PVbackSurface,
albedo= albedo, tracking= tracking, backtrack= backtrack, r2r= r2r, Cv= Cv)
albedo= albedo, tracking= tracking, backtrack= backtrack)

#Load the results from the resultfile
from loadVFresults import loadVFresults
(data, metadata) = loadVFresults(writefiletitle)
#print data.keys()
# calculate average front and back global tilted irradiance across the module chord
data['GTIFrontavg'] = data[['No_1_RowFrontGTI', 'No_2_RowFrontGTI','No_3_RowFrontGTI','No_4_RowFrontGTI','No_5_RowFrontGTI','No_6_RowFrontGTI']].mean(axis=1)
data['GTIBackavg'] = data[['No_1_RowBackGTI', 'No_2_RowBackGTI','No_3_RowBackGTI','No_4_RowBackGTI','No_5_RowBackGTI','No_6_RowBackGTI']].mean(axis=1)

# Print the annual bifacial ratio.
frontIrrSum = data['GTIFrontavg'].sum()
backIrrSum = data['GTIBackavg'].sum()
print('The bifacial ratio for ground clearance {} and rtr spacing {} is: {:.1f}%'.format(C,rtr,backIrrSum/frontIrrSum*100))
#print("--- %s seconds ---" % (time.time() - start_time))

0 comments on commit e4ef1e8

Please sign in to comment.