You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When working with the current set_wwr function from the recipes.py file, I noticed two opportunities for improvement:
when applying different WWR with the wwr_map function the case WWR = 0 adds 20% windows on the wall instead of 0.
the orientation of the building (North Axis parameter in E+) isn't taken in account which leads to different WWR compared to the HTML tab
Here an example with the original recipes.py with a building with EP-North Axis = 65°
The WWR setted to 0 is equal to 20% in the HTML Tab and the WWR are shifted counterclockwise.
I spent some hours in the last days trying to solve these problems and came to the following lines of code which, after extensive testing, couldn't reproduce the bugs listed above.
def set_wwr(
idf, wwr=0.2, construction=None, force=False, wwr_map=None, orientation=None
):
# type: (IDF, Optional[float], Optional[str], Optional[bool], Optional[dict], Optional[str]) -> None
"""Set the window to wall ratio on all external walls.
:param idf: The IDF to edit.
:param wwr: The window to wall ratio.
:param construction: Name of a window construction.
:param force: True to remove all subsurfaces before setting the WWR.
:param wwr_map: Mapping from wall orientation (azimuth) to WWR, e.g. {180: 0.25, 90: 0.2}.
:param orientation: One of "north", "east", "south", "west". Walls within 45 degrees will be affected.
"""
try:
ggr = idf.idfobjects["GLOBALGEOMETRYRULES"][0] # type: Optional[Idf_MSequence]
except IndexError:
ggr = None
# determine EP building orientation
building_northaxis = idf.idfobjects["BUILDING"][0].North_Axis
# List ext walls
external_walls = list(filter(
lambda x: x.Outside_Boundary_Condition.lower() == "outdoors",
idf.getsurfaces("wall"),
))
# Case where the "orientation" parameter is used
if orientation != None:
# check orientation
orientations = {
"north": 0.0,
"east": 90.0,
"south": 180.0,
"west": 270.0,
None: None,
}
degrees = orientations.get(orientation, None)
# filter the walls having the same orientation as the one passed to the orientation parameter
external_walls = list(filter(
lambda x: _has_correct_orientation(x, degrees, building_northaxis), external_walls
))
wwr_orientation = wwr
wwr_map_final = {None: None}
# When no "orientation" parameter is passed
else:
wwr_orientation = None
wwr_map_final = {0: wwr ,90: wwr, 180: wwr, 270: wwr}
#Replaces with value from wwr_map in case not empty
for key,value in wwr_map.items():
wwr_map_final[key] = value
subsurfaces = idf.getsubsurfaces()
for wall in external_walls:
# get any subsurfaces on the wall
wall_subsurfaces = list(
filter(lambda x: x.Building_Surface_Name == wall.Name, subsurfaces)
)
if not all(_is_window(wss) for wss in wall_subsurfaces) and not force:
raise ValueError(
'Not all subsurfaces on wall "{name}" are windows. '
"Use `force=True` to replace all subsurfaces.".format(name=wall.Name)
)
if wall_subsurfaces and not construction:
constructions = list(
{wss.Construction_Name for wss in wall_subsurfaces if _is_window(wss)}
)
if len(constructions) > 1:
raise ValueError(
'Not all subsurfaces on wall "{name}" have the same construction'.format(
name=wall.Name
)
)
construction = constructions[0]
# remove all subsurfaces
for ss in wall_subsurfaces:
idf.removeidfobject(ss)
# get the WWR for every wall taking in account the EnergyPlus North Axis
wall_cardinalorientation = wall.azimuth + building_northaxis
# wall_NESW result can be 0 (316° >= wall_cardinalorientation <= 45°), 90 (46° >= wall_cardinalorientation <= 135°), 180 (136° >= wall_cardinalorientation <= 225°) or 270 (226° >= wall_cardinalorientation <= 315°)
wall_NESW = (Decimal(wall_cardinalorientation%360/90).quantize(0, ROUND_HALF_DOWN))%4*90
if wwr_orientation != None:
wwr = wwr_orientation
else:
wwr = wwr_map_final.get(wall_NESW)
if wwr == 0:
pass
else:
coords = window_vertices_given_wall(wall, wwr)
window = idf.newidfobject(
"FENESTRATIONSURFACE:DETAILED",
Name="%s window" % wall.Name,
Surface_Type="Window",
Construction_Name=construction or "",
Building_Surface_Name=wall.Name,
View_Factor_to_Ground="autocalculate", # from the surface angle
)
window.setcoords(coords, ggr)
def _has_correct_orientation(wall, orientation_degrees, building_northaxis):
# type: (EpBunch, Optional[float]) -> bool
"""Check that the wall has an orientation which requires WWR to be set.
:param wall: An EpBunch representing a wall.
:param orientation_degrees: Orientation in degrees.
:return: True if the wall is within 45 degrees of the orientation passed, or no orientation passed.
False if the wall is not within 45 of the orientation passed.
"""
if orientation_degrees is None:
return True
cardinal_orientation = wall.azimuth + building_northaxis
if (Decimal(cardinal_orientation%360/90).quantize(0, ROUND_HALF_DOWN))%4*90 == orientation_degrees:
return True
return False
Here an example with the modified recipes.py with a building with EP-North Axis = 65°
Here the WWR of 0 is not overwritten by the standard 20%, and the WWR from the HTML Tab correspond to the inputs.
I'll create a new PR if you are happy with these modifications.
The text was updated successfully, but these errors were encountered:
JoLo90
changed the title
Bug: wwr_map sets WWR to 0.2 instead of 0
Suggestion: improvement of set_wwr and _has_correct_orientation from recipes.py
Aug 17, 2020
When working with the current set_wwr function from the recipes.py file, I noticed two opportunities for improvement:
when applying different WWR with the wwr_map function the case WWR = 0 adds 20% windows on the wall instead of 0.
the orientation of the building (North Axis parameter in E+) isn't taken in account which leads to different WWR compared to the HTML tab
Here an example with the original recipes.py with a building with EP-North Axis = 65°
The WWR setted to 0 is equal to 20% in the HTML Tab and the WWR are shifted counterclockwise.
I spent some hours in the last days trying to solve these problems and came to the following lines of code which, after extensive testing, couldn't reproduce the bugs listed above.
Here an example with the modified recipes.py with a building with EP-North Axis = 65°
Here the WWR of 0 is not overwritten by the standard 20%, and the WWR from the HTML Tab correspond to the inputs.
I'll create a new PR if you are happy with these modifications.
The text was updated successfully, but these errors were encountered: