openstudio-standards 0.8.5 → 0.8.7

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.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/test_performance_expected_dd_results.csv +90 -90
  3. data/lib/openstudio-standards/btap/activity.rb +858 -61
  4. data/lib/openstudio-standards/btap/attributes.rb +297 -103
  5. data/lib/openstudio-standards/btap/bridging.rb +1335 -593
  6. data/lib/openstudio-standards/btap/btap.rb +60 -181
  7. data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +199 -142
  8. data/lib/openstudio-standards/btap/common/constructions.json +1275 -0
  9. data/lib/openstudio-standards/btap/common/costs.csv +1969 -0
  10. data/lib/openstudio-standards/btap/common/costs_local_factors.csv +2315 -0
  11. data/lib/openstudio-standards/btap/common/materials_glazing.csv +61 -0
  12. data/lib/openstudio-standards/btap/{common_resources → common}/materials_hvac.csv +1685 -1685
  13. data/lib/openstudio-standards/btap/{common_resources → common}/materials_lighting.csv +266 -266
  14. data/lib/openstudio-standards/btap/common/materials_opaque.csv +214 -0
  15. data/lib/openstudio-standards/btap/common/necb_building_types.csv +35 -0
  16. data/lib/openstudio-standards/btap/common/necb_space_types.csv +110 -0
  17. data/lib/openstudio-standards/btap/common/thermal_bridging.csv +73 -0
  18. data/lib/openstudio-standards/btap/costing/btap_costing.rb +346 -429
  19. data/lib/openstudio-standards/btap/costing/database.rb +104 -0
  20. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +356 -344
  21. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +282 -296
  22. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +179 -192
  23. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2477 -2316
  24. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +127 -142
  25. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +216 -198
  26. data/lib/openstudio-standards/btap/costing/nv_costing.rb +522 -523
  27. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +649 -649
  28. data/lib/openstudio-standards/btap/costing/shw_costing.rb +626 -625
  29. data/lib/openstudio-standards/btap/costing/thermal_bridging_costing.rb +72 -0
  30. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2363 -2361
  31. data/lib/openstudio-standards/btap/deprecated.rb +1033 -0
  32. data/lib/openstudio-standards/btap/envelope.rb +313 -572
  33. data/lib/openstudio-standards/btap/fileio.rb +152 -1070
  34. data/lib/openstudio-standards/btap/geometry.rb +486 -766
  35. data/lib/openstudio-standards/btap/linear_regression.rb +130 -0
  36. data/lib/openstudio-standards/btap/paths.rb +46 -0
  37. data/lib/openstudio-standards/btap/qaqc/analysis.rb +163 -0
  38. data/lib/openstudio-standards/btap/qaqc/data.rb +2293 -0
  39. data/lib/openstudio-standards/btap/qaqc/datapoint.rb +641 -0
  40. data/lib/openstudio-standards/btap/schedules.rb +11 -611
  41. data/lib/openstudio-standards/btap/structure.rb +574 -189
  42. data/lib/openstudio-standards/constructions/materials/information.rb +1 -1
  43. data/lib/openstudio-standards/create_typical/create_typical.rb +1 -1
  44. data/lib/openstudio-standards/exterior_lighting/create.rb +135 -85
  45. data/lib/openstudio-standards/exterior_lighting/data/typical_exterior_lighting.json +20 -0
  46. data/lib/openstudio-standards/exterior_lighting/information.rb +23 -2
  47. data/lib/openstudio-standards/geometry/create.rb +7 -3
  48. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +3 -2
  49. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +3 -2
  50. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +84 -84
  51. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +4 -4
  52. data/lib/openstudio-standards/refrigeration/create_walkin.rb +45 -5
  53. data/lib/openstudio-standards/refrigeration/data/refrigerated_walkins.csv +75 -75
  54. data/lib/openstudio-standards/schedules/parametric.rb +6 -0
  55. data/lib/openstudio-standards/service_water_heating/create_typical.rb +10 -3
  56. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +30 -14
  57. data/lib/openstudio-standards/service_water_heating/information.rb +4 -1
  58. data/lib/openstudio-standards/sql_file/unmet_hours.rb +2 -1
  59. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +3 -1
  60. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
  61. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +12 -0
  62. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +18432 -3072
  63. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +26 -0
  64. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8532 -1422
  65. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +26 -0
  66. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8532 -1422
  67. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +16 -0
  68. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.computer_room_acs.json +30 -30
  69. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7560 -1260
  70. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +1 -2
  71. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +16 -0
  72. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +7560 -1260
  73. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +3 -3
  74. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +1 -2
  75. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +22 -0
  76. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +7236 -1206
  77. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.furnaces.json +223 -19
  78. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +37 -1
  79. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +3 -0
  80. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6900 -1150
  81. data/lib/openstudio-standards/standards/cbes/data/cbes.schedules.json +1 -1
  82. data/lib/openstudio-standards/standards/deer/data/deer.schedules.json +1 -1
  83. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/surface_thermal_transmittance.json +76 -40
  84. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/surface_thermal_transmittance.json +76 -40
  85. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +6 -4
  86. data/lib/openstudio-standards/standards/necb/NECB2011/NECB2011_QAQC.json +2988 -0
  87. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +25 -3
  88. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +672 -534
  89. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Hospital.osm +1791 -1792
  90. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +7 -1
  91. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +7 -1
  92. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeHotel.osm +5 -6
  93. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeOffice.osm +8 -9
  94. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +10 -4
  95. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +14 -15
  96. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Outpatient.osm +7 -1
  97. data/lib/openstudio-standards/standards/necb/NECB2011/data/surface_thermal_transmittance.json +76 -40
  98. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +14 -6
  99. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +542 -130
  100. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +30 -63
  101. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +7 -2
  102. data/lib/openstudio-standards/standards/necb/NECB2015/data/surface_thermal_transmittance.json +90 -0
  103. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +8 -6
  104. data/lib/openstudio-standards/standards/necb/NECB2017/data/surface_thermal_transmittance.json +76 -40
  105. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +2 -1
  106. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +0 -117
  107. data/lib/openstudio-standards/standards/necb/NECB2020/data/surface_thermal_transmittance.json +76 -45
  108. data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +218 -0
  109. data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +12 -7
  110. data/lib/openstudio-standards/standards/standard.rb +1 -1
  111. data/lib/openstudio-standards/version.rb +1 -1
  112. data/lib/openstudio-standards.rb +9 -4
  113. metadata +59 -66
  114. data/data/inventory/thermal_bridging.csv +0 -90
  115. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  116. data/data/standards/openstudio_standards_duplicates_log.csv +0 -7962
  117. data/lib/openstudio-standards/btap/NECB_building_types.csv +0 -35
  118. data/lib/openstudio-standards/btap/NECB_space_types.csv +0 -109
  119. data/lib/openstudio-standards/btap/WeatherData1.json +0 -2110
  120. data/lib/openstudio-standards/btap/WeatherData1.xlsx +0 -0
  121. data/lib/openstudio-standards/btap/btap_result.rb +0 -1144
  122. data/lib/openstudio-standards/btap/btap_test_helper.rb +0 -86
  123. data/lib/openstudio-standards/btap/common_paths.rb +0 -81
  124. data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +0 -52
  125. data/lib/openstudio-standards/btap/common_resources/Constructions.csv +0 -37
  126. data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +0 -1270
  127. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +0 -121
  128. data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +0 -2256
  129. data/lib/openstudio-standards/btap/common_resources/costs.csv +0 -1897
  130. data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +0 -2315
  131. data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +0 -35
  132. data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +0 -164
  133. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +0 -359
  134. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +0 -117
  135. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +0 -11
  136. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +0 -136
  137. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +0 -173
  138. data/lib/openstudio-standards/btap/costing/dummy.epw +0 -8768
  139. data/lib/openstudio-standards/btap/costing/dummy.osm +0 -5320
  140. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +0 -42
  141. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +0 -225
  142. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +0 -28705
  143. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +0 -92
  144. data/lib/openstudio-standards/btap/costing/test_list.txt +0 -15
  145. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +0 -27
  146. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +0 -80
  147. data/lib/openstudio-standards/btap/necb_2011_spacetype_info.csv +0 -225
  148. data/lib/openstudio-standards/btap/utilities/Add_template_field_to_json.rb +0 -22
  149. data/lib/openstudio-standards/btap/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +0 -204
  150. data/lib/openstudio-standards/btap/utilities/generate_space_types.rb +0 -8
  151. data/lib/openstudio-standards/btap/utilities/necb_to_epw_map.rb +0 -50
  152. data/lib/openstudio-standards/btap/utilities/os_sim_extract.rb +0 -48
  153. data/lib/openstudio-standards/btap/utilities/rename_surfaces.rb +0 -24
  154. data/lib/openstudio-standards/btap/utilities/round_surf_coords.rb +0 -32
  155. data/lib/openstudio-standards/btap/utilities/sched_create.rb +0 -145
  156. data/lib/openstudio-standards/btap/utilities/set_mult_to_adiabatic.rb +0 -53
  157. data/lib/openstudio-standards/btap/utilities/space_type.rb +0 -78
  158. data/lib/openstudio-standards/btap/utilities/weatherData1_xlsx_to_json.rb +0 -56
  159. data/lib/openstudio-standards/btap/vintagizer.rb +0 -161
  160. data/lib/openstudio-standards/btap/visualization.rb +0 -72
  161. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2011_spacetype_info.csv +0 -225
  162. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +0 -79
  163. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +0 -2656
  164. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +0 -653
  165. data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +0 -28705
  166. data/lib/openstudio-standards/standards/necb/common/utility_pricing_2025-02-20.csv +0 -92
  167. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_frame.csv +0 -0
  168. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_glazing.csv +0 -0
  169. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_opaque.csv +0 -0
  170. /data/lib/openstudio-standards/btap/{common_resources → common}/hvac_vent_ahu.csv +0 -0
  171. /data/lib/openstudio-standards/btap/{common_resources → common}/lighting.csv +0 -0
  172. /data/lib/openstudio-standards/btap/{common_resources → common}/lighting_sets.csv +0 -0
  173. /data/lib/openstudio-standards/btap/{common_resources → common}/locations.csv +0 -0
  174. /data/lib/openstudio-standards/btap/{costing → common}/mech_sizing.json +0 -0
@@ -1,9 +1,13 @@
1
- # BTAP Attributes: Currently stores model attributes related to envelopes.
2
- require "openstudio"
1
+ # BTAP Attributes
2
+ #
3
+ # This file extends some of the OpenStudio classes to add some new methods
4
+ # and parameters for convenience. Additionally, it also houses methods
5
+ # involving the pre-processing of an OpenStudio model for shared use in one
6
+ # of BTAP's facilities, for now BTAP Costing and BTAP Carbon. Currently, this
7
+ # pre-processing involves retrieving the correct constructions for envelopes and
8
+ # a few attributes for thermal bridging.
3
9
 
4
10
  module BTAP
5
-
6
- # Class modifications to simplyify post-analysis functions
7
11
  class OpenStudio::Model::Model
8
12
  def getThermalZonesSorted
9
13
  return @zones_sorted
@@ -19,40 +23,64 @@ module BTAP
19
23
  return @spaces_sorted
20
24
  end
21
25
 
22
- def <<(space)
26
+ def <<(space) # Override the append operator to compile the sorted spaces
23
27
  @spaces_sorted << space
24
28
  end
25
29
  end
26
30
 
27
- class OpenStudio::Model::Space
28
- attr_reader :construction_set
29
- attr_reader :surfaces_hash
30
- end
31
+ # Class for accessing and pre-processing model attributes.
32
+ class Attributes
33
+ attr_reader :model # [OpenStudio::Model::Model]
34
+ attr_reader :zones # [Array[OpenStudio::Model::Zone]]
35
+ attr_reader :spaces # [Array[OpenStudio::Model::Space]]
36
+ attr_reader :surface_types # [Array]
37
+ attr_reader :tbd_enabled # [Boolean]
38
+ attr_reader :tbd_edge_tallies # [Hash]
39
+ attr_reader :tbd_compliance # [Boolean]
40
+ attr_reader :surface_types_to_snake # [Hash]
41
+ attr_reader :constructions # [Hash]
42
+ attr_reader :surface_types_to_assembly_tallies # [Hash]
31
43
 
32
- class OpenStudio::Model::Surface
33
- attr_reader :construction_hash # Stores the construction for this surface.
34
- end
44
+ class << self
45
+ attr_reader :surface_types_to_assembly_names # [Hash]
46
+ end
35
47
 
36
- class OpenStudio::Model::SubSurface
37
- attr_reader :construction_hash # Same as the previous.
38
- end
48
+ # TODO: Temporary default constructions for underatable surface types.
49
+ @surface_types_to_assembly_names = {
50
+ "ExteriorFixedWindow" => "BTAP-ExteriorWindow-FixedWindow-1",
51
+ "ExteriorOperableWindow" => "BTAP-ExteriorWindow-OperableWindow-5b",
52
+ "ExteriorSkylight" => "BTAP-Skylight-2",
53
+ "ExteriorTubularDaylightDiffuser" => "BTAP-Skylight-2",
54
+ "ExteriorTubularDaylightDome" => "BTAP-Skylight-2",
55
+ "ExteriorDoor" => "BTAP-ExteriorDoor-Metal-1",
56
+ "ExteriorGlassDoor" => "BTAP-ExteriorWindow-GlazedDoor-4",
57
+ "ExteriorOverheadDoor" => "BTAP-ExteriorOverheadDoor-Metal-1",
58
+ "GroundContactWall" => "BTAP-GroundContactWall-Mass-2",
59
+ "GroundContactRoof" => "BTAP-GroundContactRoof-Mass-2",
60
+ "GroundContactFloor" => "BTAP-GroundContactFloor-Unheated-1"
61
+ }
39
62
 
40
- class Attributes
41
- attr_reader :model
42
- attr_reader :zones
43
- attr_reader :spaces
44
- attr_reader :surface_types
45
-
46
- def initialize(model, prototype_creator)
47
- @model = model
48
- @prototype_creator = prototype_creator
49
- @costing_database = CostingDatabase.instance
63
+ # @param model [OpenStudio::Model::Model]
64
+ # @param standard [Standard]
65
+ # @param tbd_enabled [Boolean]
66
+ # @param tbd_edge_tallies [Hash]
67
+ def initialize(model:, standard:, tbd_enabled:, tbd_edge_tallies:)
68
+ @model = model
69
+ @standard = standard
70
+ @costing_database = Database.instance
71
+ @tbd_enabled = tbd_enabled
72
+ @tbd_edge_tallies = tbd_edge_tallies
73
+ @tbd_compliance = @model.getBuilding.additionalProperties.hasFeature("tbd_compliance") ?
74
+ @model.getBuilding.additionalProperties.getFeatureAsBoolean("tbd_compliance").get : nil
50
75
 
51
76
  # Surfaces considered for envelope costing and carbon.
52
- @surface_types = [
77
+ @surface_types = [
53
78
  "ExteriorWall",
54
79
  "ExteriorRoof",
55
80
  "ExteriorFloor",
81
+ "InterzonalRoof",
82
+ "InterzonalSkylightWalls",
83
+ "InterzonalFloor",
56
84
  "ExteriorFixedWindow",
57
85
  "ExteriorOperableWindow",
58
86
  "ExteriorSkylight",
@@ -66,101 +94,267 @@ module BTAP
66
94
  "GroundContactFloor"
67
95
  ]
68
96
 
69
- @zones = []
70
- @spaces = []
97
+ # Formatted dictionary of surface types from camel case to snake case
98
+ # for neat reporting.
99
+ @surface_types_to_snake = @surface_types.map { |type|
100
+ [type, type.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase] }.to_h
101
+
102
+ @surface_types_to_envelope_type = {
103
+ "ExteriorWall" => "wall",
104
+ "ExteriorRoof" => "roof",
105
+ "ExteriorFloor" => "floor",
106
+ "InterzonalRoof" => "roof",
107
+ "InterzonalFloor" => "floor",
108
+
109
+ # TODO: Although we don't have specific constructions on interzonal
110
+ # skylight walls, using external wall constructions is better than
111
+ # ignoring them.
112
+ "InterzonalSkylightWalls" => "wall",
113
+ "ExteriorFixedWindow" => "window",
114
+ "ExteriorOperableWindow" => "window",
115
+ "ExteriorSkylight" => "skylight",
116
+ "ExteriorTubularDaylightDiffuser" => "skylight",
117
+ "ExteriorTubularDaylightDome" => "skylight",
118
+ "ExteriorDoor" => "door",
119
+ "ExteriorGlassDoor" => "door_glass",
120
+ "ExteriorOverheadDoor" => "door",
121
+ "GroundContactWall" => "bg_wall",
122
+ "GroundContactRoof" => "bg_roof",
123
+ "GroundContactFloor" => "slab"
124
+ }
71
125
 
72
- self.compile
126
+ # Store area, cost, and carbon emission tallies of assemblies by surface
127
+ # type, stored as hashes as some surface types may have different
128
+ # assemblies.
129
+ @surface_types_to_assembly_tallies = @surface_types.to_h { |surface_type| [surface_type, {}] }
130
+
131
+ @zones = []
132
+ @spaces = []
133
+ @constructions = {}
134
+
135
+ self.compile_model
136
+ self.compile_constructions
73
137
  end
74
138
 
75
- # Compile all the pertinent data into the data structures of this class while also appending
76
- # to the exisitng OpenStudio ones.
77
- def compile
78
- template_type = @prototype_creator.template
79
- num_of_above_ground_stories = @model.getBuilding.standardsNumberOfAboveGroundStories.to_i
80
-
139
+ # Fetch the additional properties in each default construction set which
140
+ # reflects the attributes of all the surfaces of a type. Populate the
141
+ # members of the `@constructions` and `@surface_types_to_assembly_tallies`
142
+ # hashes.
143
+ def compile_constructions
144
+
145
+ @model.getDefaultConstructionSets.each do |set|
146
+
147
+ # Plenum construction sets don't contain any information pertinent to
148
+ # costing, skip them.
149
+ if set.nameString =~ /PLENUM$/
150
+ next
151
+
152
+ # Attic construction sets concern insulated interzonal surfaces. This
153
+ # also concerns crawlspaces, of which the interzonal floors will be
154
+ # tallied.
155
+ elsif set.nameString =~ /ATTIC$/
156
+
157
+ compile_construction_by_type(
158
+ construction: set.defaultInteriorSurfaceConstructions.get.wallConstruction.get,
159
+ surface_type: "InterzonalSkylightWalls")
160
+
161
+ compile_construction_by_type(
162
+ construction: set.defaultInteriorSurfaceConstructions.get.floorConstruction.get,
163
+ surface_type: "InterzonalRoof")
164
+
165
+ compile_construction_by_type(
166
+ construction: set.defaultInteriorSurfaceConstructions.get.roofCeilingConstruction.get,
167
+ surface_type: "InterzonalFloor")
168
+
169
+ # The following default construction sets concern the surfaces of the
170
+ # whole building:
171
+ elsif set.nameString =~ /BLDG$/
172
+ compile_construction_by_type(
173
+ construction: set.defaultExteriorSurfaceConstructions.get.wallConstruction.get,
174
+ surface_type: "ExteriorWall")
175
+
176
+ compile_construction_by_type(
177
+ construction: set.defaultExteriorSurfaceConstructions.get.roofCeilingConstruction.get,
178
+ surface_type: "ExteriorRoof")
179
+
180
+ compile_construction_by_type(
181
+ construction: set.defaultExteriorSurfaceConstructions.get.floorConstruction.get,
182
+ surface_type: "ExteriorFloor")
183
+
184
+ compile_construction_by_type(
185
+ construction: set.defaultGroundContactSurfaceConstructions.get.wallConstruction.get,
186
+ surface_type: "GroundContactWall")
187
+
188
+ # Basement ground contact floors are removed from this default
189
+ # construction set beforehand in prototype creation with the
190
+ # `NECB2011/building_envelope.rb:set_basement_floor_construction()`
191
+ # method since they're uninsulated and shouldn't be costed. So this
192
+ # only tallies slabs on grade.
193
+ compile_construction_by_type(
194
+ construction: set.defaultGroundContactSurfaceConstructions.get.floorConstruction.get,
195
+ surface_type: "GroundContactFloor")
196
+
197
+ # From NECB2011 to NECB2025, ground contact floors only need to be
198
+ # insulated wholly in climate zone 8. Otherwise, they need to be
199
+ # insulated only for 1.2m about the perimeter. Insulation for the
200
+ # low-conductnace ground contact floor U-factor variant have been
201
+ # manually seperated into its own assembly below. Also check for the
202
+ # presence of the perimeter additional property which denotes that
203
+ # there are slab on grade ground contact floors.
204
+ if @standard.get_necb_hdd18(model: @model) < 7000 and
205
+ @model.getBuilding.additionalProperties.hasFeature("btap_slab_perimeter_m2")
206
+
207
+ isoboard_name = "BTAP-GroundContactFloor-Isoboard"
208
+ compile_construction_attributes(
209
+ construction: set.defaultGroundContactSurfaceConstructions.get.floorConstruction.get,
210
+ name: isoboard_name,
211
+ entry: @costing_database["constructions"]["slab"][isoboard_name])
212
+
213
+ @surface_types_to_assembly_tallies["GroundContactFloor"][isoboard_name] = {}
214
+ @surface_types_to_assembly_tallies["GroundContactFloor"][isoboard_name]["area"] = \
215
+ @model.getBuilding.additionalProperties.getFeatureAsDouble("btap_slab_perimeter_m2").get
216
+
217
+ end
218
+
219
+ compile_construction_by_type(
220
+ construction: set.defaultGroundContactSurfaceConstructions.get.roofCeilingConstruction.get,
221
+ surface_type: "GroundContactRoof")
222
+
223
+ compile_construction_by_type(
224
+ construction: set.defaultExteriorSubSurfaceConstructions.get.fixedWindowConstruction.get,
225
+ surface_type: "ExteriorFixedWindow")
226
+
227
+ compile_construction_by_type(
228
+ construction: set.defaultExteriorSubSurfaceConstructions.get.operableWindowConstruction.get,
229
+ surface_type: "ExteriorOperableWindow")
230
+
231
+ compile_construction_by_type(
232
+ construction: set.defaultExteriorSubSurfaceConstructions.get.skylightConstruction.get,
233
+ surface_type: "ExteriorSkylight")
234
+
235
+ compile_construction_by_type(
236
+ construction: set.defaultExteriorSubSurfaceConstructions.get.tubularDaylightDiffuserConstruction.get,
237
+ surface_type: "ExteriorTubularDaylightDiffuser")
238
+
239
+ compile_construction_by_type(
240
+ construction: set.defaultExteriorSubSurfaceConstructions.get.tubularDaylightDomeConstruction.get,
241
+ surface_type: "ExteriorTubularDaylightDome")
242
+
243
+ compile_construction_by_type(
244
+ construction: set.defaultExteriorSubSurfaceConstructions.get.doorConstruction.get,
245
+ surface_type: "ExteriorDoor")
246
+
247
+ compile_construction_by_type(
248
+ construction: set.defaultExteriorSubSurfaceConstructions.get.glassDoorConstruction.get,
249
+ surface_type: "ExteriorGlassDoor")
250
+
251
+ compile_construction_by_type(
252
+ construction: set.defaultExteriorSubSurfaceConstructions.get.overheadDoorConstruction.get,
253
+ surface_type: "ExteriorOverheadDoor")
254
+
255
+ # Any remaining construction sets will be custom and defined
256
+ # by the user by manually adding additional properties to
257
+ # spaces and will only comprise exterior-facing surfaces.
258
+ # (see NECB2011/building_envelope.rb:add_construction_sets())
259
+ else
260
+ compile_construction_by_type(
261
+ construction: set.defaultExteriorSurfaceConstructions.get.wallConstruction.get,
262
+ surface_type: "ExteriorWall")
263
+
264
+ compile_construction_by_type(
265
+ construction: set.defaultExteriorSurfaceConstructions.get.roofCeilingConstruction.get,
266
+ surface_type: "ExteriorRoof")
267
+
268
+ compile_construction_by_type(
269
+ construction: set.defaultExteriorSurfaceConstructions.get.floorConstruction.get,
270
+ surface_type: "ExteriorFloor")
271
+
272
+ end
273
+ end
274
+ end
275
+
276
+ # @param construction: [OpenStudio::Model::ConstructionBase]
277
+ # @param surface_type: [String]
278
+ def compile_construction_by_type(construction:, surface_type:)
279
+ assembly_name = construction.additionalProperties.getFeatureAsString("btap_id").get
280
+
281
+ # If the construction isn't already present in the `@constructions` hash,
282
+ # add it in.
283
+ unless @constructions.key?(assembly_name)
284
+ compile_construction_attributes(
285
+ construction: construction,
286
+ name: assembly_name,
287
+ entry: @costing_database["constructions"][@surface_types_to_envelope_type[surface_type]][assembly_name])
288
+ end
289
+
290
+ # Only include the assembly in the tallies hash if its area is non-zero.
291
+ area = construction.additionalProperties.getFeatureAsDouble("btap_area").get
292
+ unless area == 0
293
+ @surface_types_to_assembly_tallies[surface_type][assembly_name] = {}
294
+ @surface_types_to_assembly_tallies[surface_type][assembly_name]["area"] = area
295
+ end
296
+ end
297
+
298
+ # @param construction: [OpenStudio::Model::ConstructionBase]
299
+ # @param name: [Hash] Assembly name.
300
+ # @param entry: [Hash] BTAP construction attributes.
301
+ def compile_construction_attributes(construction:, name:, entry:)
302
+ construction_btap = {}
303
+ construction_btap["type"] = entry["type"]
304
+ construction_btap["rsi"] = 1 / construction.additionalProperties.getFeatureAsDouble("btap_uo").get
305
+ construction_btap["subsets"] = \
306
+ entry["usi"].transform_keys { |usi| 1 / usi.to_f }.map { |rsi, hash| hash["rsi"] = rsi; hash }
307
+
308
+ construction_btap["shgc"] = OpenstudioStandards::Constructions.construction_get_solar_transmittance(
309
+ construction.to_Construction.get) unless construction.isOpaque
310
+
311
+ @constructions[name] = construction_btap
312
+ end
313
+
314
+ # Add new accessors for zones, spaces, and surfaces while keeping them
315
+ # sorted for future accesses.
316
+ def compile_model
317
+
81
318
  # Iterate through the data structures while also saving their sorted order later for reference.
82
319
  @model.instance_variable_set(:@zones_sorted, [])
83
-
84
320
  @model.getThermalZones.sort.each do |zone|
85
321
  @model << zone
86
322
  @zones << zone
87
323
  zone.instance_variable_set(:@spaces_sorted, [])
88
-
89
324
  zone.spaces.sort.each do |space|
90
- if space.spaceType.empty? or space.spaceType.get.standardsSpaceType.empty? or space.spaceType.get.standardsBuildingType.empty?
91
- raise ("standards Space type and building type is not defined for space:#{space.name.get}. Skipping this space.")
325
+ if space.spaceType.empty? or
326
+ space.spaceType.get.standardsSpaceType.empty? or
327
+ space.spaceType.get.standardsBuildingType.empty?
328
+ raise("Error: Space type not defined for #{space.name.get}")
92
329
  end
93
330
  zone << space
94
331
  @spaces << space
332
+ end
333
+ end
334
+ end
95
335
 
96
- space_type = space.spaceType.get.standardsSpaceType
97
- building_type = space.spaceType.get.standardsBuildingType
98
-
99
- # Compile a list of construction sets for each space.
100
- construction_set = @costing_database["raw"]["construction_sets"].select { |data|
101
- data["template"].to_s.gsub(/\s*/, "") == template_type and
102
- data["building_type"].to_s.downcase == building_type.to_s.downcase and
103
- data["space_type"].to_s.downcase == space_type.to_s.downcase and
104
- data["min_stories"].to_i <= num_of_above_ground_stories and
105
- data["max_stories"].to_i >= num_of_above_ground_stories
106
- }.first
107
- space.instance_variable_set(:@construction_set, construction_set)
108
-
109
- surfaces_hash = {}
110
-
111
- # Exterior
112
- exterior_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(space.surfaces, "Outdoors")
113
- surfaces_hash["ExteriorWall"] = BTAP::Geometry::Surfaces::filter_by_surface_types(exterior_surfaces, "Wall").sort
114
- surfaces_hash["ExteriorRoof"] = BTAP::Geometry::Surfaces::filter_by_surface_types(exterior_surfaces, "RoofCeiling").sort
115
- surfaces_hash["ExteriorFloor"] = BTAP::Geometry::Surfaces::filter_by_surface_types(exterior_surfaces, "Floor").sort
116
-
117
- # Exterior Subsurfaces
118
- exterior_subsurfaces = exterior_surfaces.flat_map(&:subSurfaces)
119
- surfaces_hash["ExteriorFixedWindow"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["FixedWindow"]).sort
120
- surfaces_hash["ExteriorOperableWindow"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["OperableWindow"]).sort
121
- surfaces_hash["ExteriorSkylight"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["Skylight"]).sort
122
- surfaces_hash["ExteriorTubularDaylightDiffuser"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["TubularDaylightDiffuser"]).sort
123
- surfaces_hash["ExteriorTubularDaylightDome"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["TubularDaylightDome"]).sort
124
- surfaces_hash["ExteriorDoor"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["Door"]).sort
125
- surfaces_hash["ExteriorGlassDoor"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["GlassDoor"]).sort
126
- surfaces_hash["ExteriorOverheadDoor"] = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(exterior_subsurfaces, ["OverheadDoor"]).sort
127
-
128
- # Ground Surfaces
129
- ground_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(space.surfaces, "Ground")
130
- ground_surfaces += BTAP::Geometry::Surfaces::filter_by_boundary_condition(space.surfaces, "Foundation")
131
- surfaces_hash["GroundContactWall"] = BTAP::Geometry::Surfaces::filter_by_surface_types(ground_surfaces, "Wall").sort
132
- surfaces_hash["GroundContactRoof"] = BTAP::Geometry::Surfaces::filter_by_surface_types(ground_surfaces, "RoofCeiling").sort
133
- surfaces_hash["GroundContactFloor"] = BTAP::Geometry::Surfaces::filter_by_surface_types(ground_surfaces, "Floor").sort
134
-
135
- space.instance_variable_set(:@surfaces_hash, surfaces_hash)
136
-
137
- if construction_set.nil?
138
- next
139
- end
336
+ # Only relevant surface-specific tally is window perimeter for BTAP
337
+ # Carbon. Add surface-specific tallies for underatable surfaces.
338
+ # Currently only windows have emissions data for frames.
339
+ def compile_window_perimeter
340
+ windows = ["ExteriorFixedWindow", "ExteriorOperableWindow"]
341
+ windows.each do |window|
342
+ @surface_types_to_assembly_tallies[window][self.class.surface_types_to_assembly_names[window]]["perimeter"] = 0
343
+ end
344
+
345
+ @spaces.each do |space|
346
+ windows.each do |window|
347
+ assembly_name = self.class.surface_types_to_assembly_names[window]
348
+ BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(BTAP::Geometry::Surfaces::filter_by_boundary_condition(
349
+ space.surfaces, "Outdoors").flat_map(&:subSurfaces), ["FixedWindow", "OperableWindow"]).each do |surface|
350
+
351
+ @surface_types_to_assembly_tallies[window][assembly_name]["perimeter"] += \
352
+ BTAP::Geometry::Surfaces.getSurfacePerimeterFromVertices(vertices: surface.vertices)
140
353
 
141
- @surface_types.each do |surface_type|
142
- space.surfaces_hash[surface_type].each do |surface|
143
-
144
- # Search for a matching opaque or glazing construction and append the type to the hash.
145
- construction_hash = @costing_database["raw"]["constructions_opaque"].find { |construction|
146
- construction["construction_type_name"] == construction_set[surface_type]
147
- }
148
- if not construction_hash.nil?
149
- construction_hash["type"] = "opaque"
150
- surface.instance_variable_set(:@construction_hash, construction_hash)
151
- else
152
- construction_hash = @costing_database["raw"]["constructions_glazing"].find { |construction|
153
- construction["construction_type_name"] == construction_set[surface_type]
154
- }
155
- if not construction_hash.nil?
156
- construction_hash["type"] = "glazing"
157
- surface.instance_variable_set(:@construction_hash, construction_hash)
158
- end
159
- end
160
- end
161
354
  end
162
355
  end
163
356
  end
164
357
  end
165
358
  end
166
359
  end
360
+