/
LB Radiation Dome.py
215 lines (194 loc) Β· 10.3 KB
/
LB Radiation Dome.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# Ladybug: A Plugin for Environmental Analysis (GPL)
# This file is part of Ladybug.
#
# Copyright (c) 2024, Ladybug Tools.
# You should have received a copy of the GNU Affero General Public License
# along with Ladybug; If not, see <http://www.gnu.org/licenses/>.
#
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
"""
Visualize the radiation falling on an object from different directions over a dome.
_
The Radiation Dome depicts the amount of solar energy received by all directions
over a dome. This is useful for understanding the optimal orientation of solar
panels and how the performance of the panel might change if it's orientation
is off from the optimal position. It can also be used to identify the optimal
wall orientation for passive solar heating when used with skies of
radiation harm/benefit. When used with clear sky matrices, it can identify
the orientations that result in the highest and lowest peak cooling load.
_
The Radiation Dome can be understood in different ways:
1) It's a 3D representation of the "LB Radiation Rose," depicting all tilt angles
for that rose at once.
2) It's the reciprocal of the "LB Sky Dome," since it shows how the radiation from
that sky falls onto a hemispherical object.
3) It's an radiation study of a hemisphere. The results here are effectively the
same as running a hemisphere through the "LB Incident Radiation" component.
-
Args:
_sky_mtx: A Sky Matrix from the "LB Cumulative Sky Matrix" component or the
"LB Benefit Sky Matrix" component, which describes the radiation
coming from the various patches of the sky.
context_: Rhino Breps and/or Rhino Meshes representing context geometry
that can block solar radiation to the center of the radiation dome.
_az_count_: An integer greater than or equal to 3, which notes the number of
horizontal orientations to be evaluated on the dome. (Default: 72).
_alt_count_: An integer greater than or equal to 3, which notes the number of
vertical orientations to be evaluated on the dome. (Default: 18).
_center_pt_: A point for the center of the radiation dome. (Default: (0, 0, 0))
_scale_: A number to set the scale of the Radiation Dome. The default is 1,
which corresponds to a radius of 100 meters in the current Rhino
model's unit system.
projection_: Optional text for the name of a projection to use from the sky
dome hemisphere to the 2D plane. If None, a 3D sky dome will be drawn
instead of a 2D one. (Default: None) Choose from the following:
* Orthographic
* Stereographic
irradiance_: Boolean to note whether the radiation dome should be plotted with units
of cumulative Radiation (kWh/m2) [False] or with units of average
Irradiance (W/m2) [True]. (Default: False).
show_comp_: Boolean to indicate whether only one dome with total radiation
should be displayed (False) or three domes with the solar radiation
components (total, direct, and diffuse) should be shown. (Default: False).
legend_par_: An optional LegendParameter object to change the display of the
radiation dome (Default: None).
Returns:
report: ...
mesh: A colored mesh of a dome, representing the intensity of radiation/irradiance
from different cardinal directions.
compass: A set of circles, lines and text objects that mark the cardinal
directions in relation to the radiation dome.
legend: A legend showing the kWh/m2 or W/m2 values that correspond to the colors
of the mesh.
title: A text object for the title of the radiation dome.
dir_vecs: A list of vectors for each of the directions the dome is facing.
All vectors are unit vectors.
dir_values: Radiation values for each of the dome directions in kWh/m2 or W/m2.
This will be one list if show_comp_ is "False" and a list of 3
lists (aka. a Data Tree) for total, direct, diffuse if show_comp_
is "True".
max_pt: A point on the radiation dome with the greatest amount of solar
radiation/irradiance. For a radiation benefit sky, this is the
orientation with the greatest benefit. This can be used to
understand the optimalorientation of solar panels or the best
direction to face for passive solar heating.
max_info: Information about the direction with the greates amount of radiation.
This includes the altitude, azimuth, and radiation/irradiance value.
vis_set: An object containing VisualizationSet arguments for drawing a detailed
version of the Radiation Dome in the Rhino scene. This can be
connected to the "LB Preview Visualization Set" component to display
this version of the Radiation Dome in Rhino.
"""
ghenv.Component.Name = 'LB Radiation Dome'
ghenv.Component.NickName = 'RadiationDome'
ghenv.Component.Message = '1.8.0'
ghenv.Component.Category = 'Ladybug'
ghenv.Component.SubCategory = '2 :: Visualize Data'
ghenv.Component.AdditionalHelpFromDocStrings = '4'
try:
from ladybug_geometry.geometry3d.pointvector import Point3D
except ImportError as e:
raise ImportError('\nFailed to import ladybug_geometry:\n\t{}'.format(e))
try:
from ladybug.viewsphere import view_sphere
except ImportError as e:
raise ImportError('\nFailed to import ladybug:\n\t{}'.format(e))
try:
from ladybug_radiance.visualize.raddome import RadiationDome
except ImportError as e:
raise ImportError('\nFailed to import ladybug_radiance:\n\t{}'.format(e))
try:
from ladybug_rhino.config import conversion_to_meters
from ladybug_rhino.togeometry import to_point3d
from ladybug_rhino.fromgeometry import from_point3d, \
from_vector3d, from_mesh3d
from ladybug_rhino.intersect import join_geometry_to_mesh, intersect_mesh_rays
from ladybug_rhino.fromobjects import legend_objects, compass_objects
from ladybug_rhino.text import text_objects
from ladybug_rhino.grasshopper import all_required_inputs, \
objectify_output, list_to_data_tree
except ImportError as e:
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
def translate_dome(lb_mesh, lb_compass, graphic, title_txt):
"""Translate radiation dome geometry into a format suitable for Rhino.
Args:
lb_mesh: A ladybug Mesh3D for the dome.
lb_compass: A ladybug Compass object.
graphic: A GraphicContainer for the dome.
title_txt: Text for title of the dome.
Returns:
dome_mesh: A Rhino colored mesh for the dome.
dome_compass: Rhino objects for the dome compass.
dome_legend: Rhino objects for the dome legend.
dome_title: A bake-able title for the dome.
"""
# translate the dome visualization, including legend and compass
dome_mesh = from_mesh3d(lb_mesh)
dome_legend = legend_objects(graphic.legend)
dome_angles = list(range(0, 360, int(360 / _az_count_)))
start, stop, step, dome_angles = 0, 360, 360 / _az_count_, []
while start < stop:
dome_angles.append(start)
start += step
dome_angles = [int(n) for n in dome_angles]
if len(dome_angles) > 36:
dome_angles = dome_angles[::2]
dome_compass = compass_objects(
lb_compass, z, dome_angles, projection_, graphic.legend_parameters.font)
# construct a title from the metadata
dome_title = text_objects(title_txt, graphic.lower_title_location,
graphic.legend_parameters.text_height,
graphic.legend_parameters.font)
return dome_mesh, dome_compass, dome_legend, dome_title
if all_required_inputs(ghenv.Component):
# set defaults for global variables
_az_count_ = 72 if _az_count_ is None else _az_count_
_alt_count_ = 18 if _alt_count_ is None else _alt_count_
_scale_ = 1 if _scale_ is None else _scale_
radius = (100 * _scale_) / conversion_to_meters()
if _center_pt_ is not None: # process the center point
center_pt3d = to_point3d(_center_pt_)
z = center_pt3d.z
else:
center_pt3d, z = Point3D(), 0
# compute the intersection matrix if context is specified
n_vecs = RadiationDome.dome_vectors(_az_count_, _alt_count_)
dir_vecs = [from_vector3d(vec) for vec in n_vecs]
int_mtx = None
if len(context_) != 0 and context_[0] is not None:
shade_mesh = join_geometry_to_mesh(context_)
p_vecs = view_sphere.tregenza_sphere_vectors if len(_sky_mtx.data[1]) == 145 \
else view_sphere.reinhart_sphere_vectors
patch_dirs = [from_vector3d(vec) for vec in p_vecs]
int_mtx, angles = intersect_mesh_rays(
shade_mesh, [from_point3d(center_pt3d)] * len(dir_vecs),
patch_dirs, dir_vecs)
# create the RadiationRose object
rad_dome = RadiationDome(
_sky_mtx, int_mtx, _az_count_, _alt_count_, legend_par_,
irradiance_, center_pt3d, radius, projection_)
# create the dome visualization
if not show_comp_: # only create the total dome mesh
mesh, compass, legend, title = translate_dome(*rad_dome.draw())
dir_values = rad_dome.total_values
else: # create domes for total, direct and diffuse
# loop through the 3 radiation types and produce a dome
mesh, compass, legend, title = [], [], [], []
rad_types = ('total', 'direct', 'diffuse')
for dome_i in range(3):
cent_pt = Point3D(center_pt3d.x + radius * 3 * dome_i,
center_pt3d.y, center_pt3d.z)
dome_mesh, dome_compass, dome_legend, dome_title = \
translate_dome(*rad_dome.draw(rad_types[dome_i], cent_pt))
mesh.append(dome_mesh)
compass.extend(dome_compass)
legend.extend(dome_legend)
title.append(dome_title)
dir_values = list_to_data_tree(
(rad_dome.total_values, rad_dome.direct_values, rad_dome.diffuse_values))
# output infomration about the maximum direction
max_pt = from_point3d(rad_dome.max_point)
max_info = rad_dome.max_info
# output the visualization set
vis_set = [rad_dome, show_comp_]
vis_set = objectify_output('VisualizationSet Aruments [RadiationDome]', vis_set)