bifacial-radiance 0.5.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bifacial_radiance/HPCScripts/BasicSimulations/addNewModule.py +15 -0
- bifacial_radiance/HPCScripts/BasicSimulations/dask_on_node.sh +11 -0
- bifacial_radiance/HPCScripts/BasicSimulations/run_sbatch.sbatch +51 -0
- bifacial_radiance/HPCScripts/BasicSimulations/simulate_fixedtilt_gencumsky.py +110 -0
- bifacial_radiance/HPCScripts/BasicSimulations/simulate_fixedtilt_gendaylit.py +102 -0
- bifacial_radiance/HPCScripts/BasicSimulations/simulate_tracking_gendaylit.py +126 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/PuertoRico.py +168 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/PuertoRico_2.py +166 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/PuertoRico_Original.py +195 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/basic_module_sampling.py +154 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_B.py +162 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_Cases.py +122 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_CasesMonth.py +142 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_PRNew.py +91 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_PRNewP2.py +95 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_TreeResults.py +108 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_basic_module_sampling.py +103 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/simulate_JackHourly.py +160 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/simulate_improvedArray_Oct2127.py +623 -0
- bifacial_radiance/TEMP/.gitignore +4 -0
- bifacial_radiance/__init__.py +24 -0
- bifacial_radiance/data/CEC Modules.csv +16860 -0
- bifacial_radiance/data/default.ini +65 -0
- bifacial_radiance/data/falsecolor.exe +0 -0
- bifacial_radiance/data/gencumsky/License.txt +54 -0
- bifacial_radiance/data/gencumsky/Makefile +17 -0
- bifacial_radiance/data/gencumsky/README.txt +9 -0
- bifacial_radiance/data/gencumsky/Solar Irradiation Modelling.doc +0 -0
- bifacial_radiance/data/gencumsky/Sun.cpp +118 -0
- bifacial_radiance/data/gencumsky/Sun.h +45 -0
- bifacial_radiance/data/gencumsky/average_val.awk +3 -0
- bifacial_radiance/data/gencumsky/cPerezSkyModel.cpp +238 -0
- bifacial_radiance/data/gencumsky/cPerezSkyModel.h +57 -0
- bifacial_radiance/data/gencumsky/cSkyVault.cpp +536 -0
- bifacial_radiance/data/gencumsky/cSkyVault.h +86 -0
- bifacial_radiance/data/gencumsky/climateFile.cpp +312 -0
- bifacial_radiance/data/gencumsky/climateFile.h +37 -0
- bifacial_radiance/data/gencumsky/cumulative.cal +177 -0
- bifacial_radiance/data/gencumsky/cumulative.rad +14 -0
- bifacial_radiance/data/gencumsky/cumulativesky_rotated.rad +2 -0
- bifacial_radiance/data/gencumsky/gencumulativesky +0 -0
- bifacial_radiance/data/gencumsky/gencumulativesky.cpp +269 -0
- bifacial_radiance/data/gencumsky/make_gencumskyexe.py +107 -0
- bifacial_radiance/data/gencumsky/paths.h +62 -0
- bifacial_radiance/data/gencumulativesky +0 -0
- bifacial_radiance/data/gencumulativesky.exe +0 -0
- bifacial_radiance/data/ground.rad +83 -0
- bifacial_radiance/data/module.json +103 -0
- bifacial_radiance/gui.py +1696 -0
- bifacial_radiance/images/fig1_fixed_small.gif +0 -0
- bifacial_radiance/images/fig2_tracked_small.gif +0 -0
- bifacial_radiance/load.py +1156 -0
- bifacial_radiance/main.py +5673 -0
- bifacial_radiance/mismatch.py +461 -0
- bifacial_radiance/modelchain.py +299 -0
- bifacial_radiance/module.py +1427 -0
- bifacial_radiance/performance.py +466 -0
- bifacial_radiance/spectral_utils.py +555 -0
- bifacial_radiance-0.5.1.dist-info/METADATA +129 -0
- bifacial_radiance-0.5.1.dist-info/RECORD +63 -0
- bifacial_radiance-0.5.1.dist-info/WHEEL +6 -0
- bifacial_radiance-0.5.1.dist-info/licenses/LICENSE +30 -0
- bifacial_radiance-0.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Sat Sep 11 15:48:21 2021
|
|
4
|
+
|
|
5
|
+
@author: sayala
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# -*- coding: utf-8 -*-
|
|
9
|
+
"""
|
|
10
|
+
Created on Thu Apr 25 16:39:39 2019
|
|
11
|
+
|
|
12
|
+
@author: sayala
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
#import bifacial_radiance
|
|
16
|
+
#from bifacial_radiance.config import *
|
|
17
|
+
#import os
|
|
18
|
+
|
|
19
|
+
# DATA_PATH = bifacial_radiance.main.DATA_PATH # directory with module.json etc.
|
|
20
|
+
|
|
21
|
+
def _append_dicts(x, y):
|
|
22
|
+
"""python2 compatible way to append 2 dictionaries
|
|
23
|
+
"""
|
|
24
|
+
z = x.copy() # start with x's keys and values
|
|
25
|
+
z.update(y) # modifies z with y's keys and values & returns None
|
|
26
|
+
return z
|
|
27
|
+
|
|
28
|
+
def runModelChain(simulationParamsDict, sceneParamsDict, timeControlParamsDict=None,
|
|
29
|
+
moduleParamsDict=None, trackingParamsDict=None, torquetubeParamsDict=None,
|
|
30
|
+
analysisParamsDict=None, cellModuleDict=None, CECModParamsDict=None,
|
|
31
|
+
frameParamsDict=None, omegaParamsDict=None, pilesParamsDict=None):
|
|
32
|
+
"""
|
|
33
|
+
This calls config.py values, which are arranged into dictionaries,
|
|
34
|
+
and runs all the respective processes based on the variables in the config.py.
|
|
35
|
+
|
|
36
|
+
To import the variables from a .ini file, use::
|
|
37
|
+
|
|
38
|
+
(simulationParamsDict, sceneParamsDict, timeControlParamsDict, moduleParamsDict,
|
|
39
|
+
trackingParamsDict,torquetubeParamsDict,analysisParamsDict,cellModuleDict,
|
|
40
|
+
CECModParamsDict, frameParamsDict, omegaParamsDict, pilesParamsDict) = \
|
|
41
|
+
bifacial_radiance.load.readconfigurationinputfile(inifile)
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
import bifacial_radiance
|
|
46
|
+
import os
|
|
47
|
+
import numpy as np
|
|
48
|
+
import pandas as pd
|
|
49
|
+
|
|
50
|
+
print("\nNew bifacial_radiance simulation starting. ")
|
|
51
|
+
print("Version: ", bifacial_radiance.__version__)
|
|
52
|
+
|
|
53
|
+
if not simulationParamsDict.get('testfolder'):
|
|
54
|
+
simulationParamsDict['testfolder'] = bifacial_radiance.main._interactive_directory(
|
|
55
|
+
title='Select or create an empty directory for the Radiance tree')
|
|
56
|
+
|
|
57
|
+
testfolder = simulationParamsDict['testfolder']
|
|
58
|
+
demo = bifacial_radiance.RadianceObj(
|
|
59
|
+
simulationParamsDict['simulationname'], path=testfolder) # Create a RadianceObj 'object'
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Save INIFILE in folder
|
|
63
|
+
inifilename = os.path.join(
|
|
64
|
+
simulationParamsDict['testfolder'], 'simulation.ini')
|
|
65
|
+
bifacial_radiance.load.savedictionariestoConfigurationIniFile(simulationParamsDict, sceneParamsDict, timeControlParamsDict,
|
|
66
|
+
moduleParamsDict, trackingParamsDict, torquetubeParamsDict, analysisParamsDict,
|
|
67
|
+
cellModuleDict, CECModParamsDict,
|
|
68
|
+
frameParamsDict, omegaParamsDict, pilesParamsDict,
|
|
69
|
+
inifilename)
|
|
70
|
+
# re-load configuration file to make sure all booleans are converted
|
|
71
|
+
(simulationParamsDict, sceneParamsDict, timeControlParamsDict,
|
|
72
|
+
moduleParamsDict, trackingParamsDict,torquetubeParamsDict,
|
|
73
|
+
analysisParamsDict,cellModuleDict, CECModParamsDict, frameParamsDict,
|
|
74
|
+
omegaParamsDict, pilesParamsDict ) = \
|
|
75
|
+
bifacial_radiance.load.readconfigurationinputfile(inifilename)
|
|
76
|
+
|
|
77
|
+
# Load weatherfile
|
|
78
|
+
|
|
79
|
+
if simulationParamsDict['getEPW']:
|
|
80
|
+
simulationParamsDict['weatherFile'] = demo.getEPW(
|
|
81
|
+
simulationParamsDict['latitude'], simulationParamsDict['longitude']) # pull EPW data for any global lat/lon
|
|
82
|
+
|
|
83
|
+
if simulationParamsDict['selectTimes']:
|
|
84
|
+
starttime = timeControlParamsDict['starttime']
|
|
85
|
+
endtime = timeControlParamsDict['endtime']
|
|
86
|
+
else: # read in full TMY file
|
|
87
|
+
starttime = None; endtime=None
|
|
88
|
+
|
|
89
|
+
if 'coerce_year' in simulationParamsDict:
|
|
90
|
+
coerce_year = simulationParamsDict['coerce_year']
|
|
91
|
+
else:
|
|
92
|
+
coerce_year = None
|
|
93
|
+
|
|
94
|
+
if 'weatherFileType' in simulationParamsDict:
|
|
95
|
+
source = simulationParamsDict['weatherFileType']
|
|
96
|
+
print("Weather file of type ", source, " passed.")
|
|
97
|
+
else:
|
|
98
|
+
source = None
|
|
99
|
+
|
|
100
|
+
print('Reading weather file {}'.format(simulationParamsDict['weatherFile']))
|
|
101
|
+
metdata = demo.readWeatherFile(simulationParamsDict['weatherFile'],
|
|
102
|
+
starttime=starttime, endtime=endtime,
|
|
103
|
+
coerce_year=coerce_year, source=source)
|
|
104
|
+
|
|
105
|
+
# input albedo number or material name like 'concrete'. To see options, run this without any input.
|
|
106
|
+
demo.setGround(sceneParamsDict['albedo'])
|
|
107
|
+
analysis = None # initialize default analysis return value to none.
|
|
108
|
+
|
|
109
|
+
A = demo.printModules()
|
|
110
|
+
|
|
111
|
+
#cellLeveLParams are none by default.
|
|
112
|
+
cellModule = None
|
|
113
|
+
try:
|
|
114
|
+
if simulationParamsDict['cellLevelModule']:
|
|
115
|
+
cellModule = cellModuleDict
|
|
116
|
+
except: pass
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
"""
|
|
120
|
+
if not torquetubeParamsDict:
|
|
121
|
+
#kwargs = {**torquetubeParamsDict, **moduleParamsDict} #Py3 Only
|
|
122
|
+
torquetubeParamsDict = {}
|
|
123
|
+
torquetubeParamsDict['axisofrotation'] = simulationParamsDict[
|
|
124
|
+
'axisofrotationTorqueTube']
|
|
125
|
+
"""
|
|
126
|
+
kwargs = moduleParamsDict
|
|
127
|
+
kwargs['rewriteModulefile'] = simulationParamsDict['rewriteModule']
|
|
128
|
+
if torquetubeParamsDict:
|
|
129
|
+
if not 'visible' in torquetubeParamsDict:
|
|
130
|
+
torquetubeParamsDict['visible'] = simulationParamsDict['torqueTube']
|
|
131
|
+
if 'axisofrotationTorqueTube' in simulationParamsDict:
|
|
132
|
+
torquetubeParamsDict['axisofrotation'] = simulationParamsDict[
|
|
133
|
+
'axisofrotationTorqueTube']
|
|
134
|
+
|
|
135
|
+
if (simulationParamsDict['moduletype'] in A) and not (kwargs['rewriteModulefile']):
|
|
136
|
+
|
|
137
|
+
module = simulationParamsDict['moduletype']
|
|
138
|
+
print("\nUsing Pre-determined Module Type: %s " %
|
|
139
|
+
simulationParamsDict['moduletype'])
|
|
140
|
+
else:
|
|
141
|
+
module = demo.makeModule(name=simulationParamsDict['moduletype'],
|
|
142
|
+
tubeParams=torquetubeParamsDict,
|
|
143
|
+
frameParams=frameParamsDict,
|
|
144
|
+
omegaParams=omegaParamsDict,
|
|
145
|
+
cellModule=cellModule, **kwargs)
|
|
146
|
+
|
|
147
|
+
# module CEC params
|
|
148
|
+
if CECModParamsDict:
|
|
149
|
+
module.addCEC(pd.DataFrame(CECModParamsDict, index=[0]))
|
|
150
|
+
|
|
151
|
+
customObject = None
|
|
152
|
+
|
|
153
|
+
if "customObject" in sceneParamsDict:
|
|
154
|
+
if sceneParamsDict["customObject"] is not None:
|
|
155
|
+
if sceneParamsDict["customObject"] != '':
|
|
156
|
+
customObject = sceneParamsDict['customObject']
|
|
157
|
+
print("Custom Object Found, will be added to all Scenes.")
|
|
158
|
+
|
|
159
|
+
if 'gcr' not in sceneParamsDict: # didn't get gcr passed - need to calculate it
|
|
160
|
+
sceneParamsDict['gcr'] = module.sceney / \
|
|
161
|
+
sceneParamsDict['pitch']
|
|
162
|
+
|
|
163
|
+
if simulationParamsDict['tracking'] == False and simulationParamsDict['cumulativeSky'] == True:
|
|
164
|
+
# Fixed gencumsky condition
|
|
165
|
+
scene = demo.makeScene(module=module,
|
|
166
|
+
sceneDict=sceneParamsDict, customtext=customObject)
|
|
167
|
+
demo.genCumSky(demo.gencumsky_metfile)
|
|
168
|
+
|
|
169
|
+
if pilesParamsDict:
|
|
170
|
+
demo.addPiles(spacingPiles=pilesParamsDict['spacingPiles'],
|
|
171
|
+
pile_lenx=pilesParamsDict['pile_lenx'],
|
|
172
|
+
pile_leny=pilesParamsDict['pile_leny'],
|
|
173
|
+
pile_height=pilesParamsDict['pile_height'])
|
|
174
|
+
|
|
175
|
+
octfile = demo.makeOct(demo.getfilelist())
|
|
176
|
+
analysis = bifacial_radiance.AnalysisObj(octfile, demo.name)
|
|
177
|
+
frontscan, backscan = analysis.moduleAnalysis(scene, modWanted=analysisParamsDict['modWanted'],
|
|
178
|
+
rowWanted=analysisParamsDict['rowWanted'],
|
|
179
|
+
sensorsy=analysisParamsDict['sensorsy'])
|
|
180
|
+
analysis.analysis(octfile, demo.name, frontscan, backscan)
|
|
181
|
+
print('Bifacial ratio yearly average: %0.3f' %
|
|
182
|
+
(np.mean(analysis.Wm2Back) / np.mean(analysis.Wm2Front)))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
else:
|
|
186
|
+
# Run everything through TrackerDict.
|
|
187
|
+
# check for deprecated axis_azimuth
|
|
188
|
+
if (sceneParamsDict.get('axis_azimuth') is not None) and (sceneParamsDict.get('azimuth') is None):
|
|
189
|
+
sceneParamsDict['azimuth'] = sceneParamsDict['axis_azimuth']
|
|
190
|
+
|
|
191
|
+
if simulationParamsDict['tracking'] == False:
|
|
192
|
+
trackerdict = demo.set1axis(metdata,
|
|
193
|
+
cumulativesky=simulationParamsDict["cumulativeSky"],
|
|
194
|
+
fixed_tilt_angle=sceneParamsDict['tilt'],
|
|
195
|
+
azimuth=sceneParamsDict['azimuth'])
|
|
196
|
+
else:
|
|
197
|
+
trackerdict = demo.set1axis(metdata, gcr=sceneParamsDict['gcr'],
|
|
198
|
+
azimuth=sceneParamsDict['azimuth'],
|
|
199
|
+
limit_angle=trackingParamsDict['limit_angle'],
|
|
200
|
+
angledelta=trackingParamsDict['angle_delta'],
|
|
201
|
+
backtrack=trackingParamsDict['backtrack'],
|
|
202
|
+
cumulativesky=simulationParamsDict["cumulativeSky"])
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
if simulationParamsDict['cumulativeSky']:
|
|
207
|
+
trackerdict = demo.genCumSky1axis(trackerdict=trackerdict)
|
|
208
|
+
else:
|
|
209
|
+
trackerdict = demo.gendaylit1axis()
|
|
210
|
+
|
|
211
|
+
trackerdict = demo.makeScene1axis(trackerdict=trackerdict,
|
|
212
|
+
module=module,
|
|
213
|
+
sceneDict=sceneParamsDict,
|
|
214
|
+
cumulativesky=simulationParamsDict['cumulativeSky'], customtext=customObject)
|
|
215
|
+
|
|
216
|
+
trackerdict = demo.makeOct1axis(trackerdict=trackerdict)
|
|
217
|
+
|
|
218
|
+
trackerdict = demo.analysis1axis(trackerdict=trackerdict,
|
|
219
|
+
modWanted=analysisParamsDict['modWanted'],
|
|
220
|
+
rowWanted=analysisParamsDict['rowWanted'],
|
|
221
|
+
sensorsy=analysisParamsDict['sensorsy'])
|
|
222
|
+
|
|
223
|
+
# TODO: Chris, not all functions were saving/returning analysis before.
|
|
224
|
+
# It is also not a very good return as it will only include the last key
|
|
225
|
+
# in teh trackerdict for this, but that is what we had before.
|
|
226
|
+
# I would consider removing analysis as a return and modifying
|
|
227
|
+
# the way teh ini_highAzimuth py test works.
|
|
228
|
+
# What was before:
|
|
229
|
+
# analysis = trackerdict[time]['AnalysisObj']
|
|
230
|
+
|
|
231
|
+
# TODO: this is only returning the first AnalysisObj for the trackerdict entry.
|
|
232
|
+
# check this for more complicated scenarios with multiple AnalysisObjs...
|
|
233
|
+
# analysis = demo.trackerdict[list(demo.trackerdict.keys())[-1]]['AnalysisObj'][0]
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
if not simulationParamsDict['cumulativeSky']:
|
|
240
|
+
|
|
241
|
+
print("\n--> Calculating Performance values")
|
|
242
|
+
|
|
243
|
+
demo.calculatePerformance1axis()
|
|
244
|
+
demo.exportTrackerDict(savefile=os.path.join('results','Final_Results.csv'),reindex=False)
|
|
245
|
+
|
|
246
|
+
# Save example image files
|
|
247
|
+
#print(simulationParamsDict)
|
|
248
|
+
if simulationParamsDict.get('saveImage'):
|
|
249
|
+
if hasattr(demo, 'trackerdict'):
|
|
250
|
+
bestkey = _getDesiredIndex(demo.trackerdict)
|
|
251
|
+
scene = demo.trackerdict[bestkey]['scenes'][0] #TODO: select which sceneNum chosen?
|
|
252
|
+
imagefilename = f'scene_{bestkey}'
|
|
253
|
+
viewfile = None # just use default value for now. Improve later..
|
|
254
|
+
elif hasattr(demo, 'scenes'):
|
|
255
|
+
scene = demo.scenes[0]
|
|
256
|
+
viewfile = None # just use default value for now. Improve later..
|
|
257
|
+
imagefilename = 'scene0'
|
|
258
|
+
try:
|
|
259
|
+
print("\nSaving scene and module .hdr to images/")
|
|
260
|
+
scene.saveImage(filename=imagefilename, view=viewfile)
|
|
261
|
+
#analysis.makeFalseColor('side.vp')
|
|
262
|
+
scene.module.saveImage()
|
|
263
|
+
except:
|
|
264
|
+
print("Failed to make image")
|
|
265
|
+
|
|
266
|
+
print("Finished! ")
|
|
267
|
+
return demo, analysis
|
|
268
|
+
|
|
269
|
+
def _getDesiredIndex(trackerdict):
|
|
270
|
+
"""
|
|
271
|
+
Identify 'optimal' best key of trackerdict to use for visualizations.
|
|
272
|
+
|
|
273
|
+
Parameters
|
|
274
|
+
----------
|
|
275
|
+
trackerdict : final trackerdict
|
|
276
|
+
|
|
277
|
+
Returns
|
|
278
|
+
-------
|
|
279
|
+
bestkey
|
|
280
|
+
|
|
281
|
+
viewfile
|
|
282
|
+
|
|
283
|
+
"""
|
|
284
|
+
import pandas as pd
|
|
285
|
+
|
|
286
|
+
df = pd.DataFrame.from_dict(trackerdict, orient='index')
|
|
287
|
+
try:
|
|
288
|
+
df = df[df['scenes'].notna()]
|
|
289
|
+
except KeyError:
|
|
290
|
+
print('Error in _getDesiredIndex - trackerdict has no scene defined.')
|
|
291
|
+
return df.index[-1]
|
|
292
|
+
# try to find an index close to 25 degree tilt
|
|
293
|
+
try:
|
|
294
|
+
df['objective_fn'] = abs(df.surf_tilt - 25) # choose an index closest to 25 tilt with
|
|
295
|
+
bestkey = df['objective_fn'].idxmin()
|
|
296
|
+
except:
|
|
297
|
+
bestkey = df.index[-1] # default to last index
|
|
298
|
+
|
|
299
|
+
return bestkey
|