Skip to content

Commit

Permalink
Merge pull request #5 from NREL/1axis_tracking
Browse files Browse the repository at this point in the history
1axis tracking critical update
  • Loading branch information
cdeline authored Mar 21, 2018
2 parents fac4591 + a1d63d8 commit ea1f0be
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 28 deletions.
49 changes: 45 additions & 4 deletions bifacial_radiance/bifacial_radiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ def makeOct(self,filelist=None,octname = None):
raise Exception, err[7:]

#use rvu to see if everything looks good. use cmd for this since it locks out the terminal.
#'rvu -vf views\CUside.vp -e .01 monopanel_test.oct'
#'rvu -vf views\side.vp -e .01 monopanel_test.oct'
print("created %s.oct" % (octname)),
self.octfile = '%s.oct' % (octname)
return '%s.oct' % (octname)
Expand Down Expand Up @@ -810,8 +810,8 @@ def makeScene1axis(self, trackerdict=None, moduletype=None, sceneDict=None, nMod
module_y = scene.y
elif sceneDict['orientation'] == 'landscape':
module_y = scene.x
# Calculate the ground clearance height based on the hub height
height = hubheight - 0.5* math.sin(theta * math.pi / 180) * module_y
# Calculate the ground clearance height based on the hub height. Add abs(theta) to avoid negative tilt angle errors
height = hubheight - 0.5* math.sin(abs(theta) * math.pi / 180) * module_y
radfile = scene.makeSceneNxR(surf_tilt, height,sceneDict['pitch'],orientation = sceneDict['orientation'], azimuth = surf_azm, nMods = nMods, nRows = nRows, radname = radname)
trackerdict[theta]['radfile'] = radfile
trackerdict[theta]['scene'] = scene
Expand Down Expand Up @@ -1521,7 +1521,7 @@ def analysis(self, octfile, basename, frontscan, backscan, plotflag = False):

if __name__ == "__main__":
'''
Example of how to run a Radiance routine for a simple bifacial system
Example of how to run a Radiance routine for a simple rooftop bifacial system
'''

Expand Down Expand Up @@ -1551,4 +1551,45 @@ def analysis(self, octfile, basename, frontscan, backscan, plotflag = False):
analysis.analysis(octfile, demo.basename, scene.frontscan, scene.backscan) # compare the back vs front irradiance
print('Annual bifacial ratio: %0.3f - %0.3f' %(min(analysis.backRatio), np.mean(analysis.backRatio)) )

'''
Single Axis Tracking example
Note: this takes significantly longer than a single simulation!
'''
print('\n******\nStarting 1-axis tracking example \n********\n' )
# tracker geometry options:
module_height = 1.7 # module portrait dimension in meters
gcr = 0.33 # ground cover ratio, = module_height / pitch
albedo = 0.3 # ground albedo
hub_height = 2 # tracker height at 0 tilt in meters (hub height)
limit_angle = 45 # tracker rotation limit angle

# Example 1-axis tracking system using Radiance. This takes 5-10 minutes to complete, depending on computer.

demo2 = RadianceObj(path = testfolder) # Create a RadianceObj 'object' named 'demo'
demo2.setGround(albedo) # input albedo number or material name like 'concrete'. To see options, run this without any input.
epwfile = demo2.getEPW(37.5,-77.6) #Pull TMY weather data for any global lat/lon. In this case, Richmond, VA
metdata = demo2.readEPW(epwfile) # read in the weather data

## Begin 1-axis SAT specific functions
# create separate metdata files for each 1-axis tracker angle (5 degree resolution).
trackerdict = demo2.set1axis(metdata, limit_angle = limit_angle, backtrack = True, gcr = gcr)
# create cumulativesky functions for each tracker angle: demo.genCumSky1axis
trackerdict = demo2.genCumSky1axis(trackerdict)
# Create a new moduletype: Prism Solar Bi60. width = .984m height = 1.695m.
demo2.makeModule(name='Prism Solar Bi60',x=0.984,y=module_height)
# print available module types
demo2.printModules()

# create a 1-axis scene using panels in portrait, 2m hub height, 0.33 GCR. NOTE: clearance is calculated at each step. hub height is constant
sceneDict = {'pitch': module_height / gcr,'height':hub_height,'orientation':'portrait'}
module_type = 'Prism Solar Bi60'
trackerdict = demo2.makeScene1axis(trackerdict,module_type,sceneDict, nMods = 20, nRows = 7) #makeScene creates a .rad file with 20 modules per row, 7 rows.
# TODO: can this 20x7 scene be reduced in size without encountering edge effects?
trackerdict = demo2.makeOct1axis(trackerdict)
# Now we need to run analysis and combine the results into an annual total. This can be done by calling scene.frontscan and scene.backscan
trackerdict = demo2.analysis1axis(trackerdict)

# the frontscan and backscan include a linescan along a chord of the module, both on the front and back.
# Return the minimum of the irradiance ratio, and the average of the irradiance ratio along a chord of the module.
print('Annual RADIANCE bifacial ratio for 1-axis tracking: %0.3f - %0.3f' %(min(demo2.backRatio), np.mean(demo2.backRatio)) )
2 changes: 1 addition & 1 deletion bifacial_radiance/data/module.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"mini_panel": {"orientation": "landscape", "text": "!genbox black PVmodule 0.6096 0.9144 0.012192 | xform -t -0.3048 0 0 ", "bifi": 1, "modulefile": "objects\\mini_panel.rad", "y": 0.9144, "x": 0.6096}, "simple_panel": {"orientation": "portrait", "text": "! genbox black PVmodule 0.95 1.59 0.02 | xform -t -0.475 0 0", "bifi": 1, "modulefile": "objects\\simple_panel.rad", "y": 1.59, "x": 0.95}, "monopanel": {"orientation": "portrait", "text": "", "bifi": 1, "modulefile": "objects\\monopanel_1.rad", "y": 1.59, "x": 0.95}, "Prism Solar Bi60": {"orientation": "portrait", "text": "! genbox black PVmodule 0.984 1.695 0.02 | xform -t -0.492 0 0", "bifi": 0.9, "modulefile": "objects\\Prism_Solar_Bi60.rad", "y": 1.695, "x": 0.984}}
{"mini_panel": {"orientation": "landscape", "text": "!genbox black PVmodule 0.6096 0.9144 0.012192 | xform -t -0.3048 0 0 ", "bifi": 1, "modulefile": "objects\\mini_panel.rad", "y": 0.9144, "x": 0.6096}, "simple_panel": {"orientation": "portrait", "text": "! genbox black PVmodule 0.95 1.59 0.02 | xform -t -0.475 0 0", "bifi": 1, "modulefile": "objects\\simple_panel.rad", "y": 1.59, "x": 0.95}, "monopanel": {"orientation": "portrait", "text": "", "bifi": 1, "modulefile": "objects\\monopanel_1.rad", "y": 1.59, "x": 0.95}, "Prism Solar Bi60": {"orientation": "portrait", "text": "! genbox black PVmodule 0.984 1.7 0.02 | xform -t -0.492 0 0", "bifi": 0.9, "modulefile": "objects\\Prism_Solar_Bi60.rad", "y": 1.7, "x": 0.984}}
43 changes: 21 additions & 22 deletions docs/1Axis_tracking_example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,19 @@
},
"outputs": [],
"source": [
"testfolder = r'E:\\Documents\\Python Scripts\\Test1axisFolder' #point to an empty directory or existing Radiance directory"
"#testfolder = r'E:\\Documents\\Python Scripts\\Test1axisFolder' #point to an empty directory or existing Radiance directory\n",
"# tracker geometry options:\n",
"module_height = 1.7 # module portrait dimension in meters\n",
"gcr = 0.33 # ground cover ratio, = module_height / pitch\n",
"albedo = 0.3 # ground albedo\n",
"hub_height = 2 # tracker height at 0 tilt in meters (hub height)\n",
"limit_angle = 45 # tracker rotation limit angle"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
Expand Down Expand Up @@ -159,34 +163,29 @@
"except ImportError:\n",
" raise RuntimeError('bifacial_radiance is required. download distribution')\n",
" # Simple example system using Radiance.\n",
"#import easygui # this is only required if you want a graphical directory picker. Note: easygui sometimes opens in the background forcing you to hunt for the window! \n",
"#testfolder = easygui.diropenbox(msg = 'Select or create an empty directory for the Radiance tree',title='Browse for empty Radiance directory')\n",
"import easygui # this is only required if you want a graphical directory picker. Note: easygui sometimes opens in the background forcing you to hunt for the window! \n",
"testfolder = easygui.diropenbox(msg = 'Select or create an empty directory for the Radiance tree',title='Browse for empty Radiance directory')\n",
"\n",
"demo = RadianceObj(path = testfolder) # Create a RadianceObj 'object'\n",
"\n",
"demo.setGround(0.2) # input albedo number or material name like 'concrete'. To see options, run this without any input.\n",
"\n",
"epwfile = demo.getEPW(37.5,-77.6) #Pull TMY data for any global lat/lon\n",
" \n",
"demo.setGround(albedo) # input albedo number or material name like 'concrete'. To see options, run this without any input.\n",
"epwfile = demo.getEPW(37.5,-77.6) #Pull TMY data for any global lat/lon. In this case, Richmond, VA\n",
"metdata = demo.readEPW(epwfile) # read in the weather data\n",
"\n",
"# create metdata files for each condition\n",
"trackerdict = demo.set1axis(metdata, limit_angle = 45, backtrack = True, gcr = 1.0/3.0)\n",
"trackerdict = demo.set1axis(metdata, limit_angle = limit_angle, backtrack = True, gcr = gcr)\n",
"\n",
"# new gencumulativesky function: demo.genCumSky1axis\n",
"trackerdict = demo.genCumSky1axis(trackerdict)\n",
"# Create a new moduletype: Prism Solar Bi60. width = .984m height = 1.695m. Bifaciality = 0.90\n",
"demo.makeModule(name='Prism Solar Bi60',x=0.984,y=1.695,bifi = 0.90)\n",
"demo.makeModule(name='Prism Solar Bi60',x=0.984,y=module_height)\n",
"# print available module types\n",
"demo.printModules()\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
Expand Down Expand Up @@ -255,7 +254,7 @@
],
"source": [
"# create a scene using panels in portrait, 2m hub height, 0.33 GCR. NOTE: clearance needs to be calculated at each step. hub height is constant\n",
"sceneDict = {'pitch':1.7*3,'height':2,'orientation':'portrait'} \n",
"sceneDict = {'pitch':module_height / gcr,'height':hub_height,'orientation':'portrait'} \n",
"module_type = 'Prism Solar Bi60'\n",
"trackerdict = demo.makeScene1axis(trackerdict,module_type,sceneDict, nMods = 20, nRows = 7) #makeScene creates a .rad file with 20 modules per row, 7 rows.\n",
"\n",
Expand All @@ -265,7 +264,7 @@
"\n",
"# the frontscan and backscan include a linescan along a chord of the module, both on the front and back. \n",
"# Return the minimum of the irradiance ratio, and the average of the irradiance ratio along a chord of the module.\n",
"print('Annual bifacial ratio for 1-axis tracking: %0.3f - %0.3f' %(min(demo.backRatio), np.mean(demo.backRatio)) )\n",
"print('Annual RADIANCE bifacial ratio for 1-axis tracking: %0.3f - %0.3f' %(min(demo.backRatio), np.mean(demo.backRatio)) )\n",
"\n"
]
},
Expand Down Expand Up @@ -301,11 +300,11 @@
"# new gencumulativesky function: demo.genCumSky1axis\n",
"demo.genCumSky1axis()\n",
"# Create a new moduletype: Prism Solar Bi60. x = .984 y = 1.695. Bifaciality = 0.90\n",
"demo.makeModule(name='Prism Solar Bi60',x=0.984,y=1.695,bifi = 0.90)\n",
"demo.makeModule(name='Prism Solar Bi60',x=0.984,y=1.695)\n",
"# print available module types\n",
"demo.printModules()\n",
"# create a scene using panels in portrait, 2m hub height, 0.33 GCR. NOTE: clearance needs to be calculated at each step. hub height is constant\n",
"sceneDict = {'pitch':1.7*3,'height':2,'orientation':'portrait'} \n",
"sceneDict = {'pitch':module_height / gcr,'height':hub_height,'orientation':'portrait'} \n",
"module_type = 'Prism Solar Bi60'\n",
"demo.makeScene1axis(moduletype=module_type,sceneDict = sceneDict, nMods = 20, nRows = 7) #makeScene creates a .rad file with 20 modules per row, 7 rows.\n",
"\n",
Expand All @@ -332,7 +331,7 @@
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [default]",
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
Expand All @@ -346,7 +345,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
"version": "2.7.14"
}
},
"nbformat": 4,
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='0.1.1',
version='0.2.0',

description='Tools to interface with Radiance',
long_description=long_description,
Expand Down

0 comments on commit ea1f0be

Please sign in to comment.