Skip to content

Releases: NREL/bifacial_radiance

Development test release

30 Jul 19:46
Compare
Choose a tag to compare
Pre-release

This release includes .version functionality, and auto-deploy new tags to PyPi (just use pip install bifacial_radiance).

v 0.3.1 minor bug fix

06 Jun 16:10
87f8fd1
Compare
Choose a tag to compare

This fixes a small issue with initial orientation of scenes when using multiple scenes.

beta GUI and new internal geometry handling

14 May 21:26
Compare
Choose a tag to compare

GUI: Graphical User Interface

Finally! It's here! And it will help you make all your modeling dreams true! Or most of them at least. The GUI reads configuration files with input variables, saves configuration files with input variables, helps you set the necessary variables for the type of simulation you want to run, and finally runs it for you! Check it out and send us feedback, we need some beta testers!

image

modelChains

Powering the GUI, and as an option to simplify your own simulation-needs, we have bundled functions for the fixed and tracking simulation options into a modelChain available in modelChain.py. This modelChain covers all input parameters and options currently available as procedures on bifacial_radiance.

image

Installation and Tutorials Video

Installation video!

And tutorial video on how to install bifacial_radiance available here

https://youtu.be/4A9GocfHKyM

Keep an eye out for more videos describing bifacial_radiance inner workings, how to use the journals, the modelChains and the GUI soon!

Dictionary gallore.

The program options have grown so much, we have started to agglomerate variables into dictionaries. This are plenty useful with the modelChain and the GUI, and you can find an example with ALL of the possible inputvalues in data/default.ini.
image

Also, some of the functions on load.py help load saved dictionaries saved as *.ini files and validate that all of the necessary inputs needed by the simulation desired are present, so you never forget a variable anymore!

cell Level Module

In order to evaluate the importance of the packaging factor of a module (which was expressed as transmission factor in bifacial_vf for example) or in other words the effect of varying cell spacing / cell size in a module, makeModule now can take a dictionary that defines the sizes of the cell (xcell and ycell) and the spacing between the cells (xcellgap, ycellgap, and zcellgap).

image

axis of Rotation TorqueTube

This was bugging us, so we added the option to rotate the modules around themselves (which was the default case before) or around an axis of rotation, defined usually as the center of the torquetube.

image

The post marks the 0,0 location. The star marks where the rotation axis is at. For the image in the left, it is in the center between the 2-UP modules, so when they are inclined to this 45 degree the torquetube gets moved off from the X = 0 axis. On the image in the right, the rotation is around the torquetube's center.

clearance_height and hub_height distinction.

Before, we were using 'height' to define both clearance_height and hub_height, and the program internally decided how to interpret that depending if it was a fixed or a tracking system. Now, functions accept clearance_height and hub_height and generate the geometry based on that. Don't worry, height is still an option, although it might trigger some warnings to let you know how it is being interpreted as.

image

new internal Geometry Handling

makeScene and makeModule were re-built from the ground-up for this version. Exciting, I know!!!!! Now, an array gets created so the center of the center module of the center row (or the round-down module if it's an even number of modules/rows) coincides with 0,0, regardless of tilt, azimuth, array size, etc! This allows for simpler visualizations/animations of the visualizations if you want to, but more importantly: it enables easier analysis / sensor location options.

image

new/improved SENSOR

Speaking of the new sensor/location options:

image

And, it's more easier than ever to define your own sensor locations / hack the location. check out the carport journal for examples on this!

Multiple Scene Objects for Fixed tilt:

And, if you wanted to do a scene with different types of trackers/racked objects, you can do this too! check out multipleSceneObjs:
image

new Journals: carport, multipleScenes, and Mismatch.

Have you ever wanted to make a carport on bifacial_radiance and evaluate the rear-irradiance? Have you wanted to add posts to simulate the structure holding your carport up? Have you wondered how to add 'car' surfaces that reflect more light during certain periods of your simulation, or perhaps grass and ground albedos on the same scene? And how to sample the whole structure, not just the center of a specific module/module slope?

Check our new carport journal to learn how to do all of this!

And if you are worried about mismatch, check our development journal on mismatch (and our forthcoming oral presentations/outreach events listed in the Wiki ~).

gendaylit fix with tracker angle

Weatherfiles hour values represent the accumulated irradiance received during the hour before. I.e.: 11 AM, it is the irradiance received between 10 and 11 AM. Therefore, bifacial_radiance follows the standard of calculating the sun position (and tracker position) for 10:30 AM.
image

However, this is problematic for the sunrise and sunset hours. For example - if there is DNI / DHI vlaues for 7 AM, but the sun rises at 6:40, when the sky was generated for 6:30 the sun position was negative and the program didn't like this. We've fixed this by doing a correction of the sunrise/sunset times, and adjusts the sunposition angle for the midpoint between the hour and that sunrise/sunset time. So for the example of the sunrise at 6:40 AM, the sunposition would be calculated at 6:50 AM. The tracker angles also get calculated for this sunposition. The new changes also handle hours that are before/after the hour of the sunrise/sunset cases (there are some!) avoiding NaN values for the trackers.

Now you should be able to run yearly tracking simulations by hour! (Be warned: this takes us ~4 days on a good computer.)

High Performance Computing:

If you have access to an HPC, several of our functions have HPC capability, and there are working examples in the main.py function as well. Most of the hpc inner-code changes are waiting for files to be created; the runJob() for HPC and HPC example show how to call the bifacial radiance functions and assign them to specific Nodes/Cores. It runs a whole year of hourly tracking simulation in less than a minute on NREL's Eagle HPC!

We do not offer HPC support at the moment, but feel free to try this sections.

still under development but worth mentioning:

analysis and cleanup functions are still being developed, mostly to fit our needs of research. If you have any suggestions, we'd like to hear it on our issues tracker!

Current cleanup functions remove ground, torquetube and side of the modules from results files.

Analysis has some functions to tie with PV Mismatch and calculate electrical loss and shading losses. (There's a journal for this too!).

def some code examples here....

Torque tube customization, and more inner-working improvements

28 Feb 00:27
9063e2b
Compare
Choose a tag to compare

There are a lot of improvements in this version 0.2.4,

new WIKI Section:

The software has grown enough that a good tutorial with colorful diagrams and insider tips was needed. You can always refer to the jupyter notebooks for code examples, but now the Wiki has some things we consider important of how the geometry is being created, and of some of the main questions we receive by e-mail.

Btw: If you have feedback, questions, etc., open an Issue so we can answer you and maybe the answer will be useful for others as well :)

Now to real updates:

Deprecating ORIENTATION

Orientation no longer shifts the module in x and y. There is no more orientaiton! Now, if you want your module in landscape, set your x > y, and in portrait, x < y, x and y being the module sizes. X will be the size of the module along the row (regardless of the row's azimuth)

image

makeModule allows different torque tube shapes and materials:

On last release, makeModule was able to do a 1-up or 2-up configurations. Here is a schematic of the variables that it takes:
image

hub height or clearance height get defined on makeScene. makeScene1axis expects hub height, while makeScene (for fixed tilt) expects the clearance height). A new function _getTrackingGeometryTimeIndex calculates the clearance height in case you want to simulate just one point in time for a tracker.

RadianceObj.makeScene(module_name,sceneDict, nMods = 20, nRows = 7,sensorsy = 4, modwanted = 5, rowwanted = 2)
def makeModule(name=None,x=1,y=1,modulefile=None, text=None, customtext='', 
               torquetube=False, diameter=0.1, tubetype='Round', material='Metal_Grey', zgap=0.1, numpanels=1, ygap=0.0, rewriteModulefile=True, xgap=0.01):

Torque tube's material can now be defined (they must be pre-existing on the ground.rad material list). Also, there are different shapes to choose from: round, square, hex and octogonal tube.
image

a new 'customtext' variable has been added, in case user wants to add a replicable element to the unit-geometry (brackets, for example). This text must be in Radiance lingo, and it gets added after the geometry is created to the objects\MODULENAME.rad

Panel Spacing on 'X' , 'Y', and 'Z':

We had before gap between modules (panelgap) for 2-up configurations. This became ygap.
the distance between the torque tube (if included) and the modules is zgap.
And the new variable introduced is xgap, which allows the modules to be separated along the row.

You only need to pass this variables when making the module and they will get propagated to the scene. Here is an example of a 2-up landscape module with xgap = 0.5, zgap = 0.15, and ygap = 0.10 (all of this are meters)

image
image

New Gendaylit

Gendaylit, still using the same metdata and timestamp inputs, now calls PVLib to calculate the sun position, and generate the sky model based on this values. The previous option to have Radiance calculate the sun position and generate the sky is still available (gendaylit_old), but we find using this new gendaylit more useful to be able to control at what point in time we are calculating the sun and tracker positions (Hint: for hourly TMY3, it is with a delta of 30 minutes before the hour stated in the EPW/TMY file).

And in case you want even more customization power, there is a gendaylit_manual option now. When using this, please remember that Radiance bases it's 0 degrees azimuth coordinate on the South (whereas bifacial_radiance and PVLib implementation consider North the 0 azimuth).

image

gendaylit2manual(dni, dhi, sunalt, sunaz)

Accuracy of simulations

New accuracy input option for 1-axis scans.
'low' or 'high' - resolution option used during irrPlotNew and rtrace

analysis1axis(trackerdict=None, singleindex=None, accuracy='low', customname='my custom name for this simulation')

Higher accuracy takes more time. Since raytrace is a stochastic process, we suggest running several simulations (~10) in 'low' accuracy and averaging results. More on this topic to be potentially presented at EU PVSEC 2019.

let our inner geek rejoice: Py36 code compliance implemented, and cross-platform compatibility

It's a though world out there for non-PY36 compliante code. Bifacial_radiance is not in the wild-wild west anymore.

AND! Cross-platform compatibility implemented. This should all work in Linux now, but if you have any feedback please open an issue, we are keeping an eye out for those!

Bugs Catched:

Selection of module to be sampled was selecting one module over in the row instead of the desired module. Now it is fixed. For big-array simulations this does not impact results, but for smaller arrays, edge effects would have been noticeable.

image

Also sensor position (and module sampled) is switched automatically when doing tracking, so the same relative-position module is added for the yearly simulations. The matterial type for this release will be misguiding, but you can check your geometry by adding custom objects on your sensor positions (follow the journal example of add Custom Object)

image

((Star marks the first sensor location (so now they are being measured in the same direction))

Hourly tracking, advanced module geometry, custom scans

14 Nov 16:20
3d581f6
Compare
Choose a tag to compare

Version 0.2.3 has a lot of new features!

RadianceObj.makeModule has new input parameters:

RadianceObj.makeModule(name = '1axis_2up', x = 0.995, y = 1.995, torquetube = True, tubetype = 'round', 
    diameter = 0.1, tubeZgap = 0.1, panelgap = 0.05, numpanels = 2)

In the above example, numpanels = 2 makes the array 2-up.
torquetube = True adds a torque tube behind the panels.

this tube is 0.1m in diameter, round with a 0.1m gap between panels and the tube.
There is a 5cm gap from one panel to the next in the slope direction.

Here's a 1-up example with round tube, 0.05m gap between panels and tube:

1up_tube

makeScene now allows custom length and location scans:

RadianceObj.makeScene(module_name,sceneDict, nMods = 20, nRows = 7,sensorsy = 4, modwanted = 5, rowwanted = 2)

In the above example the normal 9-point scan is modified by only doing 4 measurement points with sensorsy = 4. modwanted = 5 scans along the 5th module in the row (from the south or west) out of 20. rowwanted = 2 scans along the second row in the array (out of 7).

1-axis tracking hourly workflow:

# NEW hourly gendaylit workflow.  trackerdict is now returned with hourly time points as keys 
#   instead of tracker angles.
trackerdict = RadianceObj.set1axis(cumulativesky = False)  
# this cumulativesky = False key is crucial to set up the hourly workflow.  

Note that the new trackerdict returned by set1axis has keys of timesteps, not angles

# create the skyfiles needed for 1-axis tracking - hourly timesteps now.
trackerdict = RadianceObj.gendaylit1axis()  
# optional parameters 'startdate', 'enddate' inputs = string 'MM/DD' or 'MM_DD' 

It doesn't take too long to create 8760 skyfiles, but if you don't need a full year, you can pass in startdate and /or enddate strings (mm/dd or mm_dd format) to only create the skyfiles you need.

sceneDict = {'pitch': module_height / gcr,'height':hub_height,'orientation':'portrait'}  
trackerdict = demo2.makeScene1axis(trackerdict, module_type,sceneDict, cumulativesky = False, nMods = 20, nRows = 7) 
#makeScene with cumulativesky = False begins to make hourly tracker Radfiles

This step isn't too different from the original workflow. makeScene1axis goes through the geometry in trackerdict and makes .RAD files for each hourly point.

# Loop over the 8760 timepoints in trackerdict.keys(). 
#   Note this takes a long time, and will probably require parallel computing. 
for time in sorted(trackerdict.keys()):  # the full year. if you want a partial year, loop over e.g. ['01_01_11','01_01_12']
    RadianceObj.makeOct1axis(trackerdict,time)
    RadianceObj.analysis1axis(trackerdict,time)

The existing functions makeOct1axis and analysis1axis now allow a specific key from trackerdict to be passed in. They'll only run on the specific key (hour or tracker angle, depending on whether cumulativesky = False or not)

This functionality allows you to run through multiple hourly simulations and create a new simulation for each. The RadianceObj keeps track of the overall RadianceObj.Wm2Front and RadianceObj.Wm2Back, so you should have a cumulative value when you're done.

Critical 1-axis tracking update plus unit testing

29 Aug 23:03
Compare
Choose a tag to compare

A sign error in calculating the tracker angle resulted in a 1-hour offset between the calculated tracker angle and actual tracker angle. This resulted in over-estimates of bifacial gain. v0.2.2 fixes this problem. Unit tests are also introduced. These can be run from the command line by running 'pytest' in the repository root folder.

Model intercomparisons look favorable with PVSyst, SAM (beta) and bifacialvf for fixed-tilt conditions.

image

Single-axis tracking also checks out within 10%-15% (relative) for rear irradiance.

image

TMY3 support

21 May 15:29
Compare
Choose a tag to compare

Updated TMY3 support - allows reading in .csv files in the TMY3 format.
No longer using pyepw to read in EPW files - now using readepw.py file from S. Quiolin from the pvlib forums.
Improved stability should result.

Critical 1-axis tracking update

21 Mar 21:55
ea1f0be
Compare
Choose a tag to compare

A geometry error was resulting in over-estimation of rear irradiance for single-axis tracked systems. Version 0.2.0 has fixed the problem.

Update calculations for southern latitudes

08 Mar 18:28
fac4591
Compare
Choose a tag to compare

A minor change is made to allow orientation azimuths in all directions from 0 to 360 degrees. This will help with modeling southern latitude systems.

bifacial_radiance 0.1.0

18 Dec 23:02
Compare
Choose a tag to compare

Update to 1-axis tracking and validation

There was an important update to how 1-axis tracking .csv weather files are saved and passed to gencumulativesky.

Now we have favorable front irradiance comparison with PVSyst, SAM and bifacialvf

image

Favorable rear irradiance comparison with bifacialvf

image

1-axis tracking examples

See /docs/1Axis_tracking_example.ipynb for usage examples.
See /docs/1Axis_Radiance_VF_comparison.py for a comparison with our partner project - BifacialVF (view factor model)

RadianceObj.set1axis(metdata, axis_azimuth, limit_angle, angledelta, backtrack, gcr): import weather file and parse into sub-files based on the tracker angle during those times. Return: trackerdict (dictionary with relevant tracker-specific data)
RadianceObj.genCumSky1axis(trackerdict) : Generate cumulative sky data for each tracker angle
RadianceObj.makeScene1axis(trackerdict, moduletype, sceneDict, nMods, nRows ) : Generate .rad file geometries for each tracker angle
RadianceObj.makeOct1axis(trackerdict) : Generate octfiles incorporating all of the above for each tracker angle

PREREQUISITES (Step 0):

This software requires the previous installation of RADIANCE .

Make sure you add radiance to the system PATH so Python can interact with the radiance program

If you are on a PC you should also copy the Jaloxa radwinexe-5.0.a.8-win64.zip executables into program files/radiance/bin:

STEP 1: Install and import bifacial_radiance

  • clone the bifacial_radiance repo to your local directory or download and unzip the .zip file
  • navigate to the \bifacial_radiance directory using anaconda command line
  • run pip install -e . ( the period . is required, the -e flag is optional and installs in development mode where changes to the bifacial_radiance.py files are immediately incorporated into the module if you re-start the python kernel)

STEP 2: Move gencumulativesky.exe

Copy gencumulativesky.exe from the repo's /bifacial_radiance/data/ directory and copy into your Radiance install directory.
This is typically found in /program files/radiance/bin/.

STEP 3: Create a local Radiance directory for storing the scene files created

Keep scene geometry files separate from the bifacial_radiance directory. Create a local directory somewhere to be used for storing scene files.

STEP 4: Reboot the computer

This makes sure the PATH is updated