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,166 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import os
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import time
|
|
5
|
+
import math
|
|
6
|
+
from itertools import chain
|
|
7
|
+
import bifacial_radiance
|
|
8
|
+
from dask.distributed import Client
|
|
9
|
+
from math import sin, cos, radians
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Run simulation using the given timestamp
|
|
13
|
+
def simulate_single(xgap=None, numpanels = None, sensorx=None,
|
|
14
|
+
test_folder_fmt=None, weather_file=None):
|
|
15
|
+
|
|
16
|
+
ft2m = 0.3048
|
|
17
|
+
hub_height = 8.0 * ft2m
|
|
18
|
+
y = 1
|
|
19
|
+
pitch = 0.001 # y * np.cos(np.radians(tilt))+D
|
|
20
|
+
ygap = 0.15
|
|
21
|
+
tilt = 18
|
|
22
|
+
|
|
23
|
+
sim_name = ('Coffee_'+str(numpanels)+'up_'+
|
|
24
|
+
str(round(xgap,1))+'_xgap_'+str(sensorx)+'posx')
|
|
25
|
+
|
|
26
|
+
# Verify test_folder exists before creating radiance obj
|
|
27
|
+
test_folder = test_folder_fmt.format(f'{numpanels}',
|
|
28
|
+
f'{round(xgap,1)}',f'{sensorx:03}')
|
|
29
|
+
|
|
30
|
+
if not os.path.exists(test_folder):
|
|
31
|
+
os.makedirs(test_folder)
|
|
32
|
+
|
|
33
|
+
lat = 18.202142
|
|
34
|
+
lon = -66.759187
|
|
35
|
+
albedo = 0.25 # Grass value from Torres Molina, "Measuring UHI in Puerto Rico" 18th LACCEI
|
|
36
|
+
# International Multi-Conference for Engineering, Education, and Technology
|
|
37
|
+
x = 1.64
|
|
38
|
+
|
|
39
|
+
azimuth = 180
|
|
40
|
+
if numpanels == 3:
|
|
41
|
+
nMods = 9
|
|
42
|
+
if numpanels == 4:
|
|
43
|
+
nMods = 7
|
|
44
|
+
nRows = 1
|
|
45
|
+
moduletype = 'PR_'+str(numpanels)+'up_'+str(round(xgap,1))+'xgap'
|
|
46
|
+
|
|
47
|
+
hpc = False
|
|
48
|
+
|
|
49
|
+
demo = bifacial_radiance.RadianceObj(sim_name,str(test_folder))
|
|
50
|
+
demo.setGround(albedo)
|
|
51
|
+
demo.readWeatherFile(weather_file)
|
|
52
|
+
|
|
53
|
+
sceneDict = {'tilt':tilt,'pitch':pitch,'hub_height':hub_height,'azimuth':azimuth, 'nMods': nMods, 'nRows': nRows}
|
|
54
|
+
scene = demo.makeScene(moduletype=moduletype,sceneDict=sceneDict, hpc=hpc, radname = sim_name)
|
|
55
|
+
|
|
56
|
+
demo.genCumSky()
|
|
57
|
+
|
|
58
|
+
octfile = demo.makeOct(filelist = demo.getfilelist(), octname = demo.basename, hpc=hpc)
|
|
59
|
+
analysis = bifacial_radiance.AnalysisObj(octfile=octfile, name=sim_name)
|
|
60
|
+
|
|
61
|
+
ii = 1
|
|
62
|
+
jj = 1
|
|
63
|
+
|
|
64
|
+
simplesim=False
|
|
65
|
+
if simplesim:
|
|
66
|
+
sensorsy_front = 20
|
|
67
|
+
sensorsy_back = 1
|
|
68
|
+
sensorsx_front = 1
|
|
69
|
+
sensorsx_back = 1
|
|
70
|
+
else:
|
|
71
|
+
sensorsy_front = 100
|
|
72
|
+
sensorsy_back = 100
|
|
73
|
+
sensorsx_front = 1
|
|
74
|
+
sensorsx_back = 1
|
|
75
|
+
|
|
76
|
+
frontscan, backscan = analysis.moduleAnalysis(scene, sensorsy_front=sensorsy_front,
|
|
77
|
+
sensorsx_front=sensorsx_front,
|
|
78
|
+
sensorsy_back=sensorsy_back,
|
|
79
|
+
sensorsx_back=sensorsx_back)
|
|
80
|
+
xinc = 0.05
|
|
81
|
+
frontscan['xstart'] = -1+sensorx*xinc
|
|
82
|
+
backscan['xstart'] = -1+sensorx*xinc
|
|
83
|
+
|
|
84
|
+
frontdict, backdict = analysis.analysis(octfile = octfile, name = 'xloc_'+str(sensorx),
|
|
85
|
+
frontscan=frontscan, backscan=backscan)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
frontdict, backdict = analysis.analysis(octfile = octfile, name = 'xloc_'+str(sensorx),
|
|
89
|
+
frontscan=frontscan, backscan=backscan)
|
|
90
|
+
|
|
91
|
+
results = 1
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
print("***** Finished simulation for "+ str(sim_name))
|
|
96
|
+
|
|
97
|
+
results=1
|
|
98
|
+
return results
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def run_simulations_dask(xgaps, numpanelss, sensorsxs, kwargs):
|
|
103
|
+
# Create client
|
|
104
|
+
|
|
105
|
+
scheduler_file = '/scratch/sayala/dask_testing/scheduler.json'
|
|
106
|
+
client = Client(scheduler_file=scheduler_file)
|
|
107
|
+
|
|
108
|
+
# Iterate over inputs
|
|
109
|
+
futures = []
|
|
110
|
+
|
|
111
|
+
for nn in range (0, len(numpanelss)):
|
|
112
|
+
numpanels = numpanelss[nn]
|
|
113
|
+
for xx in range (0, len(xgaps)):
|
|
114
|
+
xgap = xgaps[xx]
|
|
115
|
+
for ii in sensorsxs:
|
|
116
|
+
futures.append(client.submit(simulate_single, xgap=xgap, numpanels=numpanels, sensorx=ii,**kwargs))
|
|
117
|
+
|
|
118
|
+
# Get results for all simulations
|
|
119
|
+
res = client.gather(futures)
|
|
120
|
+
|
|
121
|
+
# Close all dask workers and scheduler
|
|
122
|
+
try:
|
|
123
|
+
client.shutdown()
|
|
124
|
+
except:
|
|
125
|
+
pass
|
|
126
|
+
|
|
127
|
+
# Close client
|
|
128
|
+
client.close()
|
|
129
|
+
|
|
130
|
+
res = 'FINISHED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
|
|
131
|
+
return res
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
# Define locations within file system
|
|
135
|
+
|
|
136
|
+
weather_file = '/scratch/sayala/JORDAN/PRI_Mercedita.AP.785203_TMY3.epw'
|
|
137
|
+
test_folder_fmt = '/scratch/sayala/JORDAN/PUERTO_RICO_NEW_P2/numpanels_{}_xgap_{}_Posx_{}'
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Define inputs
|
|
141
|
+
kwargs = {
|
|
142
|
+
'weather_file': weather_file,
|
|
143
|
+
'test_folder_fmt': test_folder_fmt
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# indices = np.array(list(range(2881, 6552)))
|
|
147
|
+
ft2m = 0.3048
|
|
148
|
+
lat = 18.202142
|
|
149
|
+
|
|
150
|
+
# Loops
|
|
151
|
+
|
|
152
|
+
# simplesim
|
|
153
|
+
simplesim=False
|
|
154
|
+
if simplesim:
|
|
155
|
+
xgaps = np.array([3, 4])*ft2m
|
|
156
|
+
numpanelss = np.array([3, 4])
|
|
157
|
+
sensorsxs = 2
|
|
158
|
+
else:
|
|
159
|
+
xgaps = np.array([3, 4, 6, 9, 12, 15, 18, 21]) * ft2m
|
|
160
|
+
numpanelss = np.array([3, 4])
|
|
161
|
+
sensorsxs = np.array(list(range(0, 41 )))
|
|
162
|
+
|
|
163
|
+
# Specify method for running simulation
|
|
164
|
+
use_dask = True
|
|
165
|
+
if use_dask:
|
|
166
|
+
run_simulations_dask(xgaps, numpanelss, sensorsxs, kwargs)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import os
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import time
|
|
5
|
+
import math
|
|
6
|
+
from itertools import chain
|
|
7
|
+
import bifacial_radiance
|
|
8
|
+
from dask.distributed import Client
|
|
9
|
+
from math import sin, cos, radians
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Run simulation using the given timestamp
|
|
13
|
+
def simulate_single(clearance_height=None, xgap=None,
|
|
14
|
+
tilt = None, D = None,
|
|
15
|
+
test_folder_fmt=None, weather_file=None):
|
|
16
|
+
|
|
17
|
+
ft2m = 0.3048
|
|
18
|
+
y = 1
|
|
19
|
+
pitch = y * np.cos(np.radians(tilt))+D
|
|
20
|
+
|
|
21
|
+
sim_name = ('Coffee_ch_'+str(round(clearance_height,1))+
|
|
22
|
+
'_xgap_'+str(round(xgap,1))+\
|
|
23
|
+
'_tilt_'+str(round(tilt,1))+
|
|
24
|
+
'_pitch_'+str(round(pitch,1)))
|
|
25
|
+
|
|
26
|
+
# Verify test_folder exists before creating radiance obj
|
|
27
|
+
test_folder = test_folder_fmt.format(f'{clearance_height}',
|
|
28
|
+
f'{xgap}',
|
|
29
|
+
f'{tilt}',
|
|
30
|
+
f'{pitch}')
|
|
31
|
+
|
|
32
|
+
if not os.path.exists(test_folder):
|
|
33
|
+
os.makedirs(test_folder)
|
|
34
|
+
|
|
35
|
+
lat = 18.202142
|
|
36
|
+
lon = -66.759187
|
|
37
|
+
albedo = 0.25 # Grass value from Torres Molina, "Measuring UHI in Puerto Rico" 18th LACCEI
|
|
38
|
+
# International Multi-Conference for Engineering, Education, and Technology
|
|
39
|
+
x = 1.64
|
|
40
|
+
|
|
41
|
+
azimuth = 180
|
|
42
|
+
nMods = 20
|
|
43
|
+
nRows = 7
|
|
44
|
+
numpanels = 1
|
|
45
|
+
moduletype = 'PR_'+str(round(xgap,1))
|
|
46
|
+
|
|
47
|
+
hpc = False
|
|
48
|
+
|
|
49
|
+
demo = bifacial_radiance.RadianceObj(sim_name,str(test_folder))
|
|
50
|
+
demo.setGround(albedo)
|
|
51
|
+
demo.readWeatherFile(weather_file)
|
|
52
|
+
|
|
53
|
+
sceneDict = {'tilt':tilt,'pitch':pitch,'clearance_height':clearance_height,'azimuth':azimuth, 'nMods': nMods, 'nRows': nRows}
|
|
54
|
+
scene = demo.makeScene(moduletype=moduletype,sceneDict=sceneDict, hpc=hpc, radname = sim_name)
|
|
55
|
+
|
|
56
|
+
text = ''
|
|
57
|
+
|
|
58
|
+
tree_albedo = 0.165 # Wikipedia [0.15-0.18]
|
|
59
|
+
trunk_x = 0.8 * ft2m
|
|
60
|
+
trunk_y = trunk_x
|
|
61
|
+
trunk_z = 1 * ft2m
|
|
62
|
+
|
|
63
|
+
tree_x = 3 * ft2m
|
|
64
|
+
tree_y = tree_x
|
|
65
|
+
tree_z = 4 * ft2m
|
|
66
|
+
|
|
67
|
+
for ii in range(0,3):
|
|
68
|
+
coffeeplant_x = (x+xgap)/2 + (x+xgap)*ii
|
|
69
|
+
for jj in range(0,3):
|
|
70
|
+
coffeeplant_y = pitch/2 + pitch*jj
|
|
71
|
+
name = 'tree'+str(ii)+str(jj)
|
|
72
|
+
text = '! genrev litesoil tube{}tree t*{} {} 32 | xform -t {} {} {}'.format('head'+str(ii)+str(jj),tree_z, tree_x/2.0,
|
|
73
|
+
-trunk_x/2.0 + coffeeplant_x,
|
|
74
|
+
-trunk_x/2.0 + coffeeplant_y, trunk_z)
|
|
75
|
+
text += '\r\n! genrev litesoil tube{}tree t*{} {} 32 | xform -t {} {} 0'.format('trunk'+str(ii)+str(jj),trunk_z, trunk_x/2.0,
|
|
76
|
+
-trunk_x/2.0 + coffeeplant_x,
|
|
77
|
+
-trunk_x/2.0 + coffeeplant_y)
|
|
78
|
+
|
|
79
|
+
customObject = demo.makeCustomObject(name,text)
|
|
80
|
+
demo.appendtoScene(radfile=scene.radfiles, customObject=customObject, text="!xform -rz 0")
|
|
81
|
+
demo.genCumSky()
|
|
82
|
+
|
|
83
|
+
octfile = demo.makeOct(filelist = demo.getfilelist(), octname = demo.basename, hpc=hpc)
|
|
84
|
+
analysis = bifacial_radiance.AnalysisObj(octfile=octfile, name=sim_name)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
ii = 1
|
|
88
|
+
jj = 1
|
|
89
|
+
coffeeplant_x = (x+xgap)/2 + (x+xgap)*ii
|
|
90
|
+
coffeeplant_y = pitch/2 + pitch*jj
|
|
91
|
+
frontscan, backscan = analysis.moduleAnalysis(scene=scene, sensorsy=1)
|
|
92
|
+
|
|
93
|
+
treescan_south = frontscan.copy()
|
|
94
|
+
treescan_north = frontscan.copy()
|
|
95
|
+
treescan_east = frontscan.copy()
|
|
96
|
+
treescan_west = frontscan.copy()
|
|
97
|
+
|
|
98
|
+
treescan_south['xstart'] = coffeeplant_x
|
|
99
|
+
treescan_south['ystart'] = coffeeplant_y - tree_x/2.0 - 0.05
|
|
100
|
+
treescan_south['zstart'] = tree_z
|
|
101
|
+
treescan_south['orient'] = '0 1 0'
|
|
102
|
+
|
|
103
|
+
treescan_north['xstart'] = coffeeplant_x
|
|
104
|
+
treescan_north['ystart'] = coffeeplant_y + tree_x/2.0 + 0.05
|
|
105
|
+
treescan_north['zstart'] = tree_z
|
|
106
|
+
treescan_north['orient'] = '0 -1 0'
|
|
107
|
+
|
|
108
|
+
treescan_east['xstart'] = coffeeplant_x + tree_x/2.0 + 0.05
|
|
109
|
+
treescan_east['ystart'] = coffeeplant_y
|
|
110
|
+
treescan_east['zstart'] = tree_z
|
|
111
|
+
treescan_east['orient'] = '-1 0 0'
|
|
112
|
+
|
|
113
|
+
treescan_west['xstart'] = coffeeplant_x - tree_x/2.0 - 0.05
|
|
114
|
+
treescan_west['ystart'] = coffeeplant_y
|
|
115
|
+
treescan_west['zstart'] = tree_z
|
|
116
|
+
treescan_west['orient'] = '1 0 0'
|
|
117
|
+
|
|
118
|
+
groundscan = frontscan.copy()
|
|
119
|
+
groundscan['xstart'] = coffeeplant_x
|
|
120
|
+
groundscan['ystart'] = coffeeplant_y
|
|
121
|
+
groundscan['zstart'] = 0.05
|
|
122
|
+
groundscan['orient'] = '0 0 -1'
|
|
123
|
+
analysis.analysis(octfile, name=sim_name+'_North&South', frontscan=treescan_north, backscan=treescan_south)
|
|
124
|
+
analysis.analysis(octfile, name=sim_name+'_East&West', frontscan=treescan_east, backscan=treescan_west)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
print("***** Finished simulation for "+ str(sim_name))
|
|
128
|
+
|
|
129
|
+
results=1
|
|
130
|
+
return results
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def run_simulations_dask(clearance_heights, xgaps, Ds, tilts, kwargs):
|
|
135
|
+
# Create client
|
|
136
|
+
|
|
137
|
+
scheduler_file = '/scratch/sayala/dask_testing/scheduler.json'
|
|
138
|
+
client = Client(scheduler_file=scheduler_file)
|
|
139
|
+
|
|
140
|
+
# Iterate over inputs
|
|
141
|
+
futures = []
|
|
142
|
+
|
|
143
|
+
for ch in range (0, len(clearance_heights)):
|
|
144
|
+
clearance_height = clearance_heights[ch]
|
|
145
|
+
for xx in range (0, len(xgaps)):
|
|
146
|
+
xgap = xgaps[xx]
|
|
147
|
+
for tt in range (0, len(tilts)):
|
|
148
|
+
tilt = tilts[tt]
|
|
149
|
+
for dd in range (0, len(Ds)):
|
|
150
|
+
D = Ds[dd]
|
|
151
|
+
futures.append(client.submit(simulate_single, clearance_height=clearance_height,
|
|
152
|
+
xgap=xgap, tilt=tilt, D=D, **kwargs))
|
|
153
|
+
|
|
154
|
+
# Get results for all simulations
|
|
155
|
+
res = client.gather(futures)
|
|
156
|
+
|
|
157
|
+
# Close all dask workers and scheduler
|
|
158
|
+
try:
|
|
159
|
+
client.shutdown()
|
|
160
|
+
except:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
# Close client
|
|
164
|
+
client.close()
|
|
165
|
+
|
|
166
|
+
res = 'FINISHED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
|
|
167
|
+
return res
|
|
168
|
+
|
|
169
|
+
if __name__ == "__main__":
|
|
170
|
+
# Define locations within file system
|
|
171
|
+
|
|
172
|
+
weather_file = '/scratch/sayala/JORDAN/PRI_Mercedita.AP.785203_TMY3.epw'
|
|
173
|
+
test_folder_fmt = '/scratch/sayala/JORDAN/PUERTO_RICO/CH_{}_xgap_{}_tilt_{}_pitch_{}'
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# Define inputs
|
|
177
|
+
kwargs = {
|
|
178
|
+
'weather_file': weather_file,
|
|
179
|
+
'test_folder_fmt': test_folder_fmt
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# indices = np.array(list(range(2881, 6552)))
|
|
183
|
+
ft2m = 0.3048
|
|
184
|
+
lat = 18.202142
|
|
185
|
+
|
|
186
|
+
# Loops
|
|
187
|
+
clearance_heights = np.array([6.0, 8.0, 10.0])* ft2m
|
|
188
|
+
xgaps = np.array([2, 3, 4]) * ft2m
|
|
189
|
+
Ds = np.array([2, 3, 4]) * ft2m # D is a variable that represents the spacing between rows, not-considering the collector areas.
|
|
190
|
+
tilts = [round(lat), 10]
|
|
191
|
+
|
|
192
|
+
# Specify method for running simulation
|
|
193
|
+
use_dask = True
|
|
194
|
+
if use_dask:
|
|
195
|
+
run_simulations_dask(clearance_heights, xgaps, Ds, tilts, kwargs)
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import os
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import time
|
|
5
|
+
import math
|
|
6
|
+
from itertools import chain
|
|
7
|
+
from itertools import product
|
|
8
|
+
import bifacial_radiance
|
|
9
|
+
from dask.distributed import Client
|
|
10
|
+
import math
|
|
11
|
+
|
|
12
|
+
# Generate spectra for DNI, DHI and albedo using smarts
|
|
13
|
+
|
|
14
|
+
# Run simulation using the given timestamp and wavelength
|
|
15
|
+
def simulate_single(daydate=None, posx=None, moduleWith=None, results_folder_fmt=None, weather_file=None):
|
|
16
|
+
|
|
17
|
+
# Verify test_folder exists
|
|
18
|
+
if moduleWith:
|
|
19
|
+
results_folder_fmt = '/scratch/sayala/RadianceScenes/BasicSimulations/Gendaylit1axis/WithResults/Day_{}_Posx_{}'
|
|
20
|
+
custname = '_WITH_'+'pos_'+str(posx)
|
|
21
|
+
moduletype = 'Prism Solar Bi60 landscape With' #for with case
|
|
22
|
+
|
|
23
|
+
else:
|
|
24
|
+
results_folder_fmt = '/scratch/sayala/RadianceScenes/BasicSimulations/Gendaylit1axis/WithoutResults/Day_{}_Posx_{}'
|
|
25
|
+
custname = '_WITHOUT_'+'pos_'+str(posx)
|
|
26
|
+
moduletype = 'FirstSolar Imaginary Without'
|
|
27
|
+
|
|
28
|
+
test_folder = results_folder_fmt.format(f'{daydate}', f'{str(posx)}')
|
|
29
|
+
if not os.path.exists(test_folder):
|
|
30
|
+
os.makedirs(test_folder)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Variables that stay the same
|
|
34
|
+
#Main Variables needed throughout
|
|
35
|
+
albedo = 0.2
|
|
36
|
+
sim_general_name = 'bifacial_example'
|
|
37
|
+
lat = 39.742
|
|
38
|
+
lon = -105.179
|
|
39
|
+
#moduletype = 'Prism Solar Bi60 landscape'
|
|
40
|
+
|
|
41
|
+
gcr = 0.35
|
|
42
|
+
hub_height = 1.35
|
|
43
|
+
|
|
44
|
+
nMods = 20
|
|
45
|
+
nRows = 10
|
|
46
|
+
hpc = True
|
|
47
|
+
cumulativesky = False
|
|
48
|
+
|
|
49
|
+
limit_angle = 60
|
|
50
|
+
backtrack = True
|
|
51
|
+
|
|
52
|
+
simplesim = False
|
|
53
|
+
if simplesim:
|
|
54
|
+
sensorsy = 1
|
|
55
|
+
else:
|
|
56
|
+
sensorsy = 40
|
|
57
|
+
|
|
58
|
+
sim_name = sim_general_name+'_'+str(daydate)
|
|
59
|
+
demo = bifacial_radiance.RadianceObj(sim_name,str(test_folder))
|
|
60
|
+
demo.setGround(albedo)
|
|
61
|
+
metdata = demo.readWeatherFile(weather_file, coerce_year=2021)
|
|
62
|
+
sceneDict = {'gcr':gcr,'hub_height':hub_height, 'nMods': nMods, 'nRows': nRows}
|
|
63
|
+
trackerdict = demo.set1axis(limit_angle = limit_angle, backtrack = backtrack, gcr = gcr, cumulativesky = cumulativesky)
|
|
64
|
+
|
|
65
|
+
# Restrict trackerdict here
|
|
66
|
+
#foodict = {k: v for k, v in trackerdict.items() if k.startswith('21'+'_'+day_date)}
|
|
67
|
+
#trackerdict = demo.gendaylit1axis(trackerdict = foodict)
|
|
68
|
+
trackerdict = demo.gendaylit1axis(startdate=daydate, enddate=daydate)
|
|
69
|
+
trackerdict = demo.makeScene1axis(moduletype=moduletype,sceneDict=sceneDict, cumulativesky=cumulativesky, hpc=hpc) #makeScene creates a .rad file with 20 modules per row, 7 rows.
|
|
70
|
+
trackerdict = demo.makeOct1axis(customname = sim_name, hpc=hpc)
|
|
71
|
+
#demo.analysis1axis(customname = sim_name, hpc=hpc)
|
|
72
|
+
|
|
73
|
+
frame_thickness = 0.01
|
|
74
|
+
mod_x=1
|
|
75
|
+
modscanBack = {}
|
|
76
|
+
|
|
77
|
+
modscanBack['ystart'] = mod_x/2.0 - (frame_thickness + 0.001) - 0.005*posx # (adding frame thicknes plus 1 mm so it does not overlay exactly)
|
|
78
|
+
|
|
79
|
+
demo.analysis1axis(singleindex=daydate+'_00', modscanfront=modscanBack,
|
|
80
|
+
modscanback=modscanBack, sensorsy = sensorsy,
|
|
81
|
+
customname = custname)
|
|
82
|
+
#customname ommitted for test (journal)
|
|
83
|
+
|
|
84
|
+
results = 1
|
|
85
|
+
|
|
86
|
+
return results
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def run_simulations_dask(daylist, posxs, moduleWiths, kwargs):
|
|
90
|
+
# Create client
|
|
91
|
+
|
|
92
|
+
scheduler_file = '/scratch/sayala/dask_testing/scheduler.json'
|
|
93
|
+
client = Client(scheduler_file=scheduler_file)
|
|
94
|
+
|
|
95
|
+
# Iterate over inputs
|
|
96
|
+
futures = []
|
|
97
|
+
|
|
98
|
+
# Add Iterations HERE
|
|
99
|
+
|
|
100
|
+
for daydate in daylist:
|
|
101
|
+
for posx in posxs:
|
|
102
|
+
for moduleWith in moduleWiths:
|
|
103
|
+
futures.append(client.submit(simulate_single, daydate=daydate, posx=posx, moduleWith=moduleWith, **kwargs))
|
|
104
|
+
|
|
105
|
+
# Get results for all simulations
|
|
106
|
+
res = client.gather(futures)
|
|
107
|
+
|
|
108
|
+
# Close all dask workers and scheduler
|
|
109
|
+
try:
|
|
110
|
+
client.shutdown()
|
|
111
|
+
except:
|
|
112
|
+
pass
|
|
113
|
+
|
|
114
|
+
# Close client
|
|
115
|
+
client.close()
|
|
116
|
+
|
|
117
|
+
res = 'FINISHED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
|
|
118
|
+
return res
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
# Define locations within file system
|
|
123
|
+
|
|
124
|
+
weather_file = '/home/sayala/WeatherFiles/SRRL_WeatherFile_TMY3_60_2020_FIXED.csv'
|
|
125
|
+
|
|
126
|
+
With = True
|
|
127
|
+
# weather_file = '/home/sarefeen/WeatherFiles/SRRL_WeatherFile_TMY3_60_2020.csv'
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Define inputs
|
|
132
|
+
kwargs = {
|
|
133
|
+
'weather_file': weather_file,
|
|
134
|
+
# 'results_folder_fmt': results_folder_fmt
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
import datetime
|
|
138
|
+
|
|
139
|
+
moduleWiths = [True, False]
|
|
140
|
+
|
|
141
|
+
# daylist = ['21_04_29_06', '21_04_29_07', '21_04_29_08', '21_04_29_09',
|
|
142
|
+
# '21_04_29_10', '21_04_29_11', '21_04_29_12', '21_04_29_13', '21_04_29_14',
|
|
143
|
+
# '21_04_29_15', '21_04_29_16', '21_04_29_17', '21_04_29_18']
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
daylist = ['21_04_29_11']
|
|
147
|
+
|
|
148
|
+
# posxs = np.array(list(range(0, 200)))
|
|
149
|
+
posxs = np.array(list(range(0, 200)))
|
|
150
|
+
|
|
151
|
+
# Pass variables being looped on, and kwargs
|
|
152
|
+
run_simulations_dask(daylist, posxs, moduleWiths, kwargs)
|
|
153
|
+
|
|
154
|
+
print("*********** DONE ************")
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import os
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import time
|
|
5
|
+
import math
|
|
6
|
+
from itertools import chain
|
|
7
|
+
import bifacial_radiance
|
|
8
|
+
from dask.distributed import Client
|
|
9
|
+
from math import sin, cos, radians
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Run simulation using the given timestamp
|
|
13
|
+
def simulate_single(idx=None, test_folder_fmt=None, weather_file=None):
|
|
14
|
+
|
|
15
|
+
# Verify test_folder exists before creating radiance obj
|
|
16
|
+
test_folder = test_folder_fmt.format(f'{idx}')
|
|
17
|
+
if not os.path.exists(test_folder):
|
|
18
|
+
os.makedirs(test_folder)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Input Values
|
|
22
|
+
radiance_name = 'JackSolar'
|
|
23
|
+
lat = 40.1217 # Given for the project site at Colorado
|
|
24
|
+
lon = -105.1310 # Given for the project site at Colorado
|
|
25
|
+
moduletype='CaseA'
|
|
26
|
+
numpanels = 1 # This site have 1 module in Y-direction
|
|
27
|
+
x = 1
|
|
28
|
+
y = 2.4384 # 6ft
|
|
29
|
+
zgap = 0.10 # no gap to torquetube.
|
|
30
|
+
torquetube = True
|
|
31
|
+
axisofrotationTorqueTube = True
|
|
32
|
+
diameter = 0.15 # 15 cm diameter for the torquetube
|
|
33
|
+
tubetype = 'square' # Put the right keyword upon reading the document
|
|
34
|
+
material = 'black' # Torque tube of this material (0% reflectivity)
|
|
35
|
+
|
|
36
|
+
# Scene variables
|
|
37
|
+
nMods = 20
|
|
38
|
+
nRows = 7
|
|
39
|
+
hub_height = 2.4384 # meters
|
|
40
|
+
pitch = 5.1816 # meters # Pitch is the known parameter
|
|
41
|
+
albedo = 0.2 #'Grass' # ground albedo
|
|
42
|
+
gcr = y/pitch
|
|
43
|
+
|
|
44
|
+
cumulativesky = False
|
|
45
|
+
limit_angle = 60 # tracker rotation limit angle
|
|
46
|
+
angledelta = 0.01 # we will be doing hourly simulation, we want the angle to be as close to real tracking as possible.
|
|
47
|
+
backtrack = True
|
|
48
|
+
|
|
49
|
+
# START SIMULATION
|
|
50
|
+
rad_obj = bifacial_radiance.RadianceObj(radiance_name, str(test_folder))
|
|
51
|
+
|
|
52
|
+
# Set ground
|
|
53
|
+
rad_obj.readWeatherFile(weather_file, label = 'center')
|
|
54
|
+
|
|
55
|
+
# Query data from metadata for index of interest
|
|
56
|
+
foo=rad_obj.metdata.datetime[idx]
|
|
57
|
+
dni = rad_obj.metdata.dni[idx]
|
|
58
|
+
dhi = rad_obj.metdata.dhi[idx]
|
|
59
|
+
res_name = "irr_Jacksolar_"+str(foo.year)+"_"+str(foo.month)+"_"+str(foo.day)+"_"+str(foo.hour)+"_"+str(foo.minute)
|
|
60
|
+
|
|
61
|
+
rad_obj.setGround(albedo)
|
|
62
|
+
|
|
63
|
+
# Set sky
|
|
64
|
+
solpos = rad_obj.metdata.solpos.iloc[idx]
|
|
65
|
+
zen = float(solpos.zenith)
|
|
66
|
+
azm = float(solpos.azimuth) - 180
|
|
67
|
+
|
|
68
|
+
if zen > 90:
|
|
69
|
+
print("Nightime ")
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
rad_obj.gendaylit2manual(dni, dhi, 90 - zen, azm)
|
|
73
|
+
|
|
74
|
+
# Set tracker information
|
|
75
|
+
tilt = round(rad_obj.getSingleTimestampTrackerAngle(rad_obj.metdata, idx, gcr, limit_angle=65),1)
|
|
76
|
+
|
|
77
|
+
sceneDict = {'pitch': pitch, 'tilt': tilt, 'azimuth': 90, 'hub_height':hub_height, 'nMods':nMods, 'nRows': nRows}
|
|
78
|
+
|
|
79
|
+
scene = rad_obj.makeScene(moduletype=moduletype,sceneDict=sceneDict)
|
|
80
|
+
octfile = rad_obj.makeOct(octname=res_name)
|
|
81
|
+
|
|
82
|
+
sensorsx = 22
|
|
83
|
+
sensorsy = 105
|
|
84
|
+
module_scenex = x+0.01
|
|
85
|
+
extra_sampling_space_x = 0.10
|
|
86
|
+
spacingsensorsx = (module_scenex+extra_sampling_space_x)/(sensorsx-1)
|
|
87
|
+
startxsensors = (module_scenex+extra_sampling_space_x)/2
|
|
88
|
+
xinc = pitch/(sensorsy-1)
|
|
89
|
+
|
|
90
|
+
analysis = bifacial_radiance.AnalysisObj()
|
|
91
|
+
|
|
92
|
+
frontscan, backscan = analysis.moduleAnalysis(scene, sensorsy=sensorsy)
|
|
93
|
+
|
|
94
|
+
#LOCATION_APOGEES
|
|
95
|
+
for senx in range(0,sensorsx):
|
|
96
|
+
frontscan['zstart'] = 0
|
|
97
|
+
frontscan['xstart'] = 0
|
|
98
|
+
frontscan['orient'] = '0 0 -1'
|
|
99
|
+
frontscan['zinc'] = 0
|
|
100
|
+
frontscan['xinc'] = xinc
|
|
101
|
+
frontscan['ystart'] = startxsensors-spacingsensorsx*senx
|
|
102
|
+
frontdict, backdict = analysis.analysis(octfile = octfile, name = 'xloc_'+str(senx),
|
|
103
|
+
frontscan=frontscan, backscan=backscan)
|
|
104
|
+
|
|
105
|
+
results = 1
|
|
106
|
+
|
|
107
|
+
# Saving one value for front of module to calculate bifacial gain
|
|
108
|
+
frontscan, backscan = analysis.moduleAnalysis(scene, sensorsy=1)
|
|
109
|
+
frontdict, backdict = analysis.analysis(octfile = octfile, name = 'frontSide',
|
|
110
|
+
frontscan=frontscan, backscan=backscan)
|
|
111
|
+
|
|
112
|
+
print("***** Finished simulation for "+ str(foo))
|
|
113
|
+
|
|
114
|
+
return results
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def run_simulations_dask(indices, kwargs):
|
|
119
|
+
# Create client
|
|
120
|
+
|
|
121
|
+
scheduler_file = '/scratch/sayala/dask_testing/scheduler.json'
|
|
122
|
+
client = Client(scheduler_file=scheduler_file)
|
|
123
|
+
|
|
124
|
+
# Iterate over inputs
|
|
125
|
+
futures = []
|
|
126
|
+
|
|
127
|
+
for idx in indices:
|
|
128
|
+
futures.append(client.submit(simulate_single, idx=idx, **kwargs))
|
|
129
|
+
|
|
130
|
+
# Get results for all simulations
|
|
131
|
+
res = client.gather(futures)
|
|
132
|
+
|
|
133
|
+
# Close all dask workers and scheduler
|
|
134
|
+
try:
|
|
135
|
+
client.shutdown()
|
|
136
|
+
except:
|
|
137
|
+
pass
|
|
138
|
+
|
|
139
|
+
# Close client
|
|
140
|
+
client.close()
|
|
141
|
+
|
|
142
|
+
res = 'FINISHED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
|
|
143
|
+
return res
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
# Define locations within file system
|
|
147
|
+
|
|
148
|
+
weather_file = '/scratch/sayala/JORDAN/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.epw'
|
|
149
|
+
test_folder_fmt = '/scratch/sayala/JORDAN/JackSolar_CaseC/Hour_{}'
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# Define inputs
|
|
153
|
+
kwargs = {
|
|
154
|
+
'weather_file': weather_file,
|
|
155
|
+
'test_folder_fmt': test_folder_fmt
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
indices = np.array(list(range(2881, 6552)))
|
|
159
|
+
# Specify method for running simulation
|
|
160
|
+
use_dask = True
|
|
161
|
+
if use_dask:
|
|
162
|
+
run_simulations_dask(indices, kwargs)
|