Class: OpenStudio::Model::Model
- Inherits:
-
Object
- Object
- OpenStudio::Model::Model
- Defined in:
- lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb,
lib/openstudio-standards/prototypes/Prototype.full_service_restaurant.rb,
lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb,
lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb,
lib/openstudio-standards/prototypes/Prototype.mid_rise_apartment.rb,
lib/openstudio-standards/prototypes/Prototype.retail_standalone.rb,
lib/openstudio-standards/prototypes/Prototype.secondary_school.rb,
lib/openstudio-standards/prototypes/Prototype.retail_stripmall.rb,
lib/openstudio-standards/prototypes/Prototype.primary_school.rb,
lib/openstudio-standards/prototypes/Prototype.medium_office.rb,
lib/openstudio-standards/prototypes/Prototype.small_office.rb,
lib/openstudio-standards/prototypes/Prototype.large_office.rb,
lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb,
lib/openstudio-standards/prototypes/Prototype.small_hotel.rb,
lib/openstudio-standards/prototypes/Prototype.large_hotel.rb,
lib/openstudio-standards/prototypes/Prototype.add_objects.rb,
lib/openstudio-standards/prototypes/Prototype.outpatient.rb,
lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb,
lib/openstudio-standards/prototypes/Prototype.warehouse.rb,
lib/openstudio-standards/prototypes/Prototype.Model.swh.rb,
lib/openstudio-standards/prototypes/Prototype.hospital.rb,
lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb,
lib/openstudio-standards/prototypes/Prototype.Model.rb,
lib/openstudio-standards/standards/Standards.Model.rb,
lib/openstudio-standards/weather/Weather.Model.rb,
lib/openstudio-standards/utilities/simulation.rb
Overview
Extend the class
Instance Method Summary collapse
-
#add_booster_swh_end_uses(standard, swh_booster_loop, peak_flowrate, flowrate_schedule, water_use_temperature, building_type = nil) ⇒ OpenStudio::Model::WaterUseEquipment
Creates water fixtures and attaches them to the supplied booster water loop.
-
#add_cav(standard, sys_name, hot_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_efficiency, fan_motor_efficiency, fan_pressure_rise, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a packaged VAV system and adds it to the model.
-
#add_chw_loop(standard, chw_pumping_type, chiller_cooling_type, chiller_condenser_type, chiller_compressor_type, chiller_capacity_guess_tons, condenser_water_loop = nil, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a chilled water loop and adds it to the model.
-
#add_construction(construction_name, construction_props = nil) ⇒ Object
Create a construction from the openstudio standards dataset.
-
#add_construction_set(building_vintage, clim, building_type, spc_type, is_residential) ⇒ Object
Create a construction set from the openstudio standards dataset.
-
#add_constructions(building_type, building_vintage, climate_zone) ⇒ Bool
Adds code-minimum constructions based on the building type as defined in the OpenStudio_Standards_construction_sets.json file.
- #add_curve(curve_name) ⇒ Object
-
#add_cw_loop(number_cooling_towers = 1) ⇒ OpenStudio::Model::PlantLoop
Creates a condenser water loop and adds it to the model.
-
#add_data_center_hvac(standard, sys_name, hot_water_loop, heat_pump_loop, thermal_zones, hvac_op_sch, oa_damper_sch, main_data_center = false) ⇒ Array<OpenStudio::Model::AirLoopHVAC>
Creates a data center PSZ-AC system for each zone.
-
#add_data_center_load(space, dc_watts_per_area) ⇒ Bool
Adds a data center load to a given space.
-
#add_daylighting_controls(building_vintage) ⇒ Object
Add the daylighting controls for lobby, cafe, dinning and banquet.
- #add_debugging_variables(type) ⇒ Object
-
#add_design_days_and_weather_file(building_type, building_vintage, climate_zone) ⇒ Object
Helper method to set the weather file, import the design days, set water mains temperature, and set ground temperature.
-
#add_doas(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_max_flow_rate, economizer_control_type, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a DOAS system with fan coil units for each zone.
-
#add_door_infiltration(building_vintage, climate_zone) ⇒ Object
add extra infiltration for ground floor corridor.
-
#add_elevator(standard, space, number_of_elevators, elevator_type, elevator_schedule, elevator_fan_schedule, elevator_lights_schedule, building_type = nil) ⇒ OpenStudio::Model::ElectricEquipment
Add an elevator the the specified space.
-
#add_exhaust_fan(availability_sch_name, flow_rate, flow_fraction_schedule_name, balanced_exhaust_fraction_schedule_name, thermal_zones) ⇒ Array<OpenStudio::Model::FanZoneExhaust>
Adds an exhaust fan to each zone.
-
#add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input) ⇒ Bool
Adds exterior lights to the building, as specified in OpenStudio_Standards_prototype_inputs.
-
#add_extra_equip_corridor(building_vintage) ⇒ Object
add elevator and lights&fans for the ground floor corridor.
- #add_extra_equip_elevator_pump_room(building_vintage) ⇒ Object
-
#add_extra_equip_kitchen(building_vintage) ⇒ Object
add extra equipment for kitchen.
-
#add_high_temp_radiant(standard, sys_name, thermal_zones, heating_type, combustion_efficiency, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACHighTemperatureRadiant>
Creates a high temp radiant heater for each zone and adds it to the model.
-
#add_hp_loop(building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a heat pump loop which has a boiler and fluid cooler for supplemental heating/cooling and adds it to the model.
- #add_hvac(building_type, building_vintage, climate_zone, prototype_input) ⇒ Object
-
#add_hw_loop(boiler_fuel_type, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a hot water loop with one boiler and add it to the model.
-
#add_loads(building_vintage, climate_zone) ⇒ Bool
Adds the loads and associated schedules for each space type as defined in the OpenStudio_Standards_space_types.json file.
-
#add_material(material_name) ⇒ Object
Create a material from the openstudio standards dataset.
-
#add_occupancy_sensors(building_type, building_vintage, climate_zone) ⇒ Bool
Adds occupancy sensors to certain space types per the PNNL documentation.
-
#add_performance_rating_method_baseline_system(standard, system_type, zones) ⇒ Object
Add the specified baseline system type to the specified zons based on the specified standard.
-
#add_performance_rating_method_construction_set(building_vintage, category) ⇒ OpenStudio::Model::DefaultConstructionSet
Creates a construction set with the construction types specified in the Performance Rating Method (aka Appendix G aka LEED) and adds it to the model.
-
#add_psz_ac(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_location, fan_type, heating_type, supplemental_heating_type, cooling_type, building_type = nil) ⇒ Array<OpenStudio::Model::AirLoopHVAC>
Creates a PSZ-AC system for each zone and adds it to the model.
-
#add_ptac(standard, sys_name, hot_water_loop, thermal_zones, fan_type, heating_type, cooling_type, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner>
Creates a PTAC system for each zone and adds it to the model.
-
#add_pthp(standard, sys_name, thermal_zones, fan_type, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner>
Creates a PTHP system for each zone and adds it to the model.
-
#add_pvav(standard, sys_name, thermal_zones, hvac_op_sch, oa_damper_sch, hot_water_loop = nil, return_plenum = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a packaged VAV system and adds it to the model.
-
#add_refrigeration(standard, case_type, cooling_capacity_per_length, length, evaporator_fan_pwr_per_length, lighting_per_length, lighting_sch_name, defrost_pwr_per_length, restocking_sch_name, cop, cop_f_of_t_curve_name, condenser_fan_pwr, condenser_fan_pwr_curve_name, thermal_zone) ⇒ Object
Adds a single refrigerated case connected to a rack composed of a single compressor and a single air-cooled condenser.
-
#add_schedule(schedule_name) ⇒ ScheduleRuleset
Create a schedule from the openstudio standards dataset and add it to the model.
-
#add_split_AC(standard, sys_name, thermal_zones, hvac_op_sch, alt_hvac_op_sch, oa_damper_sch, fan_type, heating_type, supplemental_heating_type, cooling_type, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a split DX AC system for each zone and adds it to the model.
- #add_swh(building_type, building_vintage, climate_zone, prototype_input, hvac_standards) ⇒ Object
-
#add_swh_booster(standard, main_service_water_loop, water_heater_capacity, water_heater_volume, water_heater_fuel, booster_water_temperature, parasitic_fuel_consumption_rate, booster_water_heater_thermal_zone, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a booster water heater and attaches it to the supplied service water heating loop.
-
#add_swh_end_uses(standard, use_name, swh_loop, peak_flowrate, flowrate_schedule, water_use_temperature, space_name, building_type = nil) ⇒ OpenStudio::Model::WaterUseEquipment
Creates water fixtures and attaches them to the supplied service water loop.
- #add_swh_end_uses_by_space(building_type, building_vintage, climate_zone, swh_loop, space_type_name, space_name, space_multiplier = nil) ⇒ Object
-
#add_swh_loop(standard, sys_name, water_heater_thermal_zone, service_water_temperature, service_water_pump_head, service_water_pump_motor_efficiency, water_heater_capacity, water_heater_volume, water_heater_fuel, parasitic_fuel_consumption_rate, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a service water heating loop.
-
#add_unitheater(standard, sys_name, thermal_zones, hvac_op_sch, fan_control_type, fan_pressure_rise, heating_type, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACUnitHeater>
Creates a unit heater for each zone and adds it to the model.
-
#add_vals_to_sch(day_sch, sch_type, values) ⇒ Object
Helper method to fill in hourly values.
-
#add_vav_pfp_boxes(standard, sys_name, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, vav_fan_efficiency, vav_fan_motor_efficiency, vav_fan_pressure_rise, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a VAV system with parallel fan powered boxes and adds it to the model.
-
#add_vav_reheat(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, vav_fan_efficiency, vav_fan_motor_efficiency, vav_fan_pressure_rise, return_plenum, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a VAV system and adds it to the model.
-
#add_water_heater(standard, water_heater_capacity, water_heater_volume, water_heater_fuel, service_water_temperature, parasitic_fuel_consumption_rate, swh_temp_sch, set_peak_use_flowrate, peak_flowrate, flowrate_schedule, water_heater_thermal_zone, building_type = nil) ⇒ OpenStudio::Model::WaterHeaterMixed
Creates a water heater and attaches it to the supplied service water heating loop.
- #add_zone_mixing(building_vintage) ⇒ Object
-
#addDaylightingControls(building_vintage) ⇒ Object
Applies daylighting controls to each space in the model per the standard.
- #adjust_clg_setpoint(building_vintage, climate_zone) ⇒ Object
-
#apply_infiltration_standard(building_vintage) ⇒ Bool
Apply the air leakage requirements to the model, as described in PNNL section 5.2.1.6.
-
#apply_multizone_vav_outdoor_air_sizing(building_vintage) ⇒ Object
Applies the multi-zone VAV outdoor air sizing requirements to all applicable air loops in the model.
-
#apply_performance_rating_method_baseline_skylight_to_roof_ratio(template) ⇒ Object
Reduces the SRR to the values specified by the PRM.
-
#apply_performance_rating_method_baseline_window_to_wall_ratio(template) ⇒ Object
Reduces the WWR to the values specified by the PRM.
-
#apply_performance_rating_method_construction_types(template) ⇒ Bool
Go through the default construction sets and hard-assigned constructions.
-
#apply_standard_constructions(template, climate_zone) ⇒ Bool
Apply the standard construction to each surface in the model, based on the construction type currently assigned.
-
#applyHVACEfficiencyStandard(building_vintage, climate_zone) ⇒ Object
Applies the HVAC parts of the standard to all objects in the model using the the template/standard specified in the model.
- #applyPrototypeHVACAssumptions(building_type, building_vintage, climate_zone) ⇒ Object
-
#applySizingValues ⇒ Object
Takes the values calculated by the EnergyPlus sizing routines and puts them into all objects model in place of the autosized fields.
- #assign_building_story(building_type, building_vintage, climate_zone, building_story_map) ⇒ Object
-
#assign_space_type_stubs(building_type, building_vintage, space_type_map) ⇒ Bool
Reads in a mapping between names of space types and names of spaces in the model, creates an empty OpenStudio::Model::SpaceType (no loads, occupants, schedules, etc.) for each space type, and assigns this space type to the list of spaces named.
-
#assign_spaces_to_stories ⇒ Bool
Assign each space in the model to a building story based on common z (height) values.
-
#autosize ⇒ Object
Changes all hard-sized HVAC values to Autosized.
-
#coil_cooling_fuels(cooling_coil) ⇒ Object
Get the cooling fuel type of a cooling coil.
-
#coil_heating_fuels(heating_coil) ⇒ Object
Get the heating fuel type of a heating coil.
-
#create_performance_rating_method_baseline_building(building_type, building_vintage, climate_zone, sizing_run_dir = Dir.pwd, debug = false) ⇒ Bool
Creates a Performance Rating Method (aka Appendix G aka LEED) baseline building model based on the inputs currently in the model.
-
#create_prototype_building(building_type, building_vintage, climate_zone, sizing_run_dir = Dir.pwd, debug = false) ⇒ Bool
Creates a DOE prototype building model and replaces the current model with this model.
-
#create_thermal_zones(building_type, building_vintage, climate_zone) ⇒ Bool
Creates thermal zones to contain each space, as defined for each building in the system_to_space_map inside the Prototype.building_name e.g.
- #custom_hvac_tweaks(building_type, building_vintage, climate_zone, prototype_input) ⇒ Object
- #custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input) ⇒ Object
- #define_building_story_map(building_type, building_vintage, climate_zone) ⇒ Object
- #define_hvac_system_map(building_type, building_vintage, climate_zone) ⇒ Object
- #define_space_multiplier ⇒ Object
-
#define_space_type_map(building_type, building_vintage, climate_zone) ⇒ Object
TODO: The ElectricEquipment schedules are wrong in OpenStudio Standards…
-
#differentiate_primary_secondary_thermal_zones(zones) ⇒ Hash
Determine which of the zones should be served by the primary HVAC system.
-
#find_and_add_construction(building_vintage, climate_zone_set, intended_surface_type, standards_construction_type, building_category) ⇒ Object
Helper method to find a particular construction and add it to the model after modifying the insulation value if necessary.
-
#find_ashrae_hot_water_demand ⇒ Array
Returns average daily hot water consumption by building type recommendations from 2011 ASHRAE Handobook - HVAC Applications Table 7 section 60.14 Not all building types are included in lookup some recommendations have multiple values based on number of units.
-
#find_climate_zone_set(clim, building_vintage) ⇒ Object
Helper method to find out which climate zone set contains a specific climate zone.
-
#find_conditioned_space_names(building_type, building_vintage, climate_zone) ⇒ Array<String>
Get the list of all conditioned spaces, as defined for each building in the system_to_space_map inside the Prototype.building_name e.g.
-
#find_constructions(boundary_condition, type) ⇒ Object
Get a unique list of constructions with given boundary condition and a given type of surface.
-
#find_icc_iecc_2015_hot_water_demand(units_per_bldg, bedrooms_per_unit) ⇒ Double
Returns average daily hot water consumption for residential buildings gal/day from ICC IECC 2015 Residential Standard Reference Design from Table R405.5.2(1).
-
#find_icc_iecc_2015_internal_loads(units_per_bldg, bedrooms_per_unit) ⇒ Hash
Returns average daily internal loads for residential buildings from Table R405.5.2(1).
-
#find_object(hash_of_objects, search_criteria, capacity = nil) ⇒ Hash
Method to search through a hash for an object that meets the desired search criteria, as passed via a hash.
-
#find_objects(hash_of_objects, search_criteria, capacity = nil) ⇒ Array
Method to search through a hash for the objects that meets the desired search criteria, as passed via a hash.
-
#find_prototype_floor_area(building_type) ⇒ Double
Keep track of floor area for prototype buildings.
-
#find_target_eui(template) ⇒ Double
user needs to pass in building_vintage as string.
-
#find_target_eui_by_end_use(template) ⇒ Hash
user needs to pass in building_vintage as string.
-
#get_baseline_system_type_by_zone(building_vintage, climate_zone) ⇒ Hash
Looks through the model and creates an hash of what the baseline system type should be for each zone.
-
#get_building_climate_zone_and_building_type(remap_office = true) ⇒ hash
this is used by other methods to get the clinzte aone and building type from a model.
-
#get_construction_properties(template, intended_surface_type, standards_construction_type, building_category = 'Nonresidential') ⇒ hash
Returns standards data for selected construction.
-
#get_full_weather_file_path ⇒ OpenStudio::OptionalPath
Get the full path to the weather file that is specified in the model.
-
#get_lookup_name(building_type) ⇒ String
Get the name of the building type used in lookups.
-
#get_story_for_nominal_z_coordinate(minz) ⇒ OpenStudio::Model::BuildingStory
Helper method to get the story object that cooresponds to a specific minimum z value.
-
#getAutosizedValue(object, value_name, units) ⇒ Object
A helper method to get component sizes from the model returns the autosized value as an optional double.
-
#getAutosizedValueFromEquipmentSummary(object, table_name, value_name, units) ⇒ Object
A helper method to get component sizes from the Equipment Summary of the TabularDataWithStrings Report returns the autosized value as an optional double.
-
#group_zones_by_story(zones) ⇒ Array<Array<OpenStudio::Model::ThermalZone>>
Group an array of zones into multiple arrays, one for each story in the building.
-
#load_building_type_methods(building_type, building_vintage, climate_zone) ⇒ Bool
Loads the library of methods specific to this building type.
-
#load_geometry(building_type, building_vintage, climate_zone) ⇒ Bool
Loads a geometry-only .osm as a starting point.
-
#make_name(building_vintage, clim, building_type, spc_type) ⇒ Object
Helper method to make a shortened version of a name that will be readable in a GUI.
-
#modify_infiltration_coefficients(building_type, building_vintage, climate_zone) ⇒ Bool
Changes the infiltration coefficients for the prototype vintages.
-
#modify_surface_convection_algorithm(building_vintage) ⇒ Bool
Sets the inside and outside convection algorithms for different vintages.
-
#output_fan_report(csv_path = nil) ⇒ Array of Hash
Helper function to output the fan power for each fan in the model Todo: output actual bhp and allowable bhp for systems 3-4 and 5-8 Todo: remove maybe later?.
-
#performance_rating_method_baseline_system_groups(standard) ⇒ Array<Hash>
Determine the dominant and exceptional areas of the building based on fuel types and occupancy types.
-
#performance_rating_method_baseline_system_type(standard, climate_zone, area_type, heating_fuel_type, area_ft2, num_stories) ⇒ String
Determine the baseline system type given the inputs.
-
#plant_loop_cooling_fuels(plant_loop) ⇒ Object
Get the cooling fuel type of a plant loop Do not search for the fuel used for heat rejection on the condenser loop.
-
#plant_loop_heating_fuels(plant_loop) ⇒ Object
Get the heating fuel type of a plant loop.
-
#process_results_for_datapoint(climate_zone, building_type, template) ⇒ Hash
Method to gather prototype simulation results for a specific climate zone, building type, and template.
-
#replace_model(path_to_osm) ⇒ Bool
Replaces all objects in the current model with the objects in the .osm.
- #request_timeseries_outputs ⇒ Object
-
#reset_kitchen_OA(building_vintage) ⇒ Object
In order to provide sufficient OSA to replace exhaust flow through kitchen hoods (3,300 cfm), modeled OSA to kitchen is different from OSA determined based on ASHRAE 62.1.
-
#residential_and_nonresidential_floor_areas(standard) ⇒ Hash
Determine the residential and nonresidential floor areas based on the space type properties for each space.
-
#residential_and_nonresidential_story_counts(standard) ⇒ Hash
Determine the number of residential and nonresidential stories.
- #run(run_dir = "#{Dir.pwd}/Run") ⇒ Object
- #run_simulation_and_log_errors(run_dir = "#{Dir.pwd}/Run") ⇒ Object
-
#runSizingRun(sizing_run_dir = "#{Dir.pwd}/SizingRun") ⇒ Object
A helper method to run a sizing run and pull any values calculated during autosizing back into the self.
-
#set_sizing_parameters(building_type, building_vintage) ⇒ Bool
Changes the infiltration coefficients for the prototype vintages.
- #update_exhaust_fan_efficiency(building_vintage) ⇒ Object
- #update_fan_efficiency ⇒ Object
- #update_sizing_zone(building_vintage) ⇒ Object
-
#update_waterheater_loss_coefficient(building_vintage) ⇒ Object
add hvac.
-
#zone_airloop_cooling_fuels(zone) ⇒ Object
Get the cooling fuels for a zones airloop.
-
#zone_airloop_heating_fuels(zone) ⇒ Object
Get the heating fuels for a zones airloop.
-
#zone_equipment_cooling_fuels(zone) ⇒ Object
Get the cooling fuels for a zone.
-
#zone_equipment_heating_fuels(zone) ⇒ Object
Get the heating fuels for a zone @ return [Array<String>] an array of fuels.
Instance Method Details
#add_booster_swh_end_uses(standard, swh_booster_loop, peak_flowrate, flowrate_schedule, water_use_temperature, building_type = nil) ⇒ OpenStudio::Model::WaterUseEquipment
Creates water fixtures and attaches them to the supplied booster water loop.
90.1-2007, 90.1-2010, 90.1-2013 the booster water loop to add water fixtures to. the resulting water fixture.
3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3757 def add_booster_swh_end_uses(standard, swh_booster_loop, peak_flowrate, flowrate_schedule, water_use_temperature, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding water fixture to #{swh_booster_loop.name}.") # Water use connection swh_connection = OpenStudio::Model::WaterUseConnections.new(self) # Water fixture definition water_fixture_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(self) rated_flow_rate_m3_per_s = peak_flowrate rated_flow_rate_gal_per_min = OpenStudio.convert(rated_flow_rate_m3_per_s,'m^3/s','gal/min').get water_fixture_def.setName("Water Fixture Def - #{rated_flow_rate_gal_per_min} gal/min") water_fixture_def.setPeakFlowRate(rated_flow_rate_m3_per_s) # Target mixed water temperature mixed_water_temp_f = OpenStudio.convert(water_use_temperature,'F','C').get mixed_water_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) mixed_water_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),OpenStudio.convert(mixed_water_temp_f,'F','C').get) water_fixture_def.setTargetTemperatureSchedule(mixed_water_temp_sch) # Water use equipment water_fixture = OpenStudio::Model::WaterUseEquipment.new(water_fixture_def) water_fixture.setName("Booster Water Fixture - #{rated_flow_rate_gal_per_min} gal/min at #{mixed_water_temp_f}F") schedule = self.add_schedule(flowrate_schedule) water_fixture.setFlowRateFractionSchedule(schedule) swh_connection.addWaterUseEquipment(water_fixture) # Connect the water use connection to the SWH loop swh_booster_loop.addDemandBranchForComponent(swh_connection) return water_fixture end |
#add_cav(standard, sys_name, hot_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_efficiency, fan_motor_efficiency, fan_pressure_rise, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a packaged VAV system and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 1051 def add_cav(standard, sys_name, hot_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_efficiency, fan_motor_efficiency, fan_pressure_rise, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding CAV for #{thermal_zones.size} zones.") thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Debug, 'openstudio.Model.Model', "---#{zone.name}") end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # Hot water loop control temperatures hw_temp_f = 152.6 #HW setpoint 152.6F hw_delta_t_r = 20 #20F delta-T hw_temp_c = OpenStudio.convert(hw_temp_f,'F','C').get hw_delta_t_k = OpenStudio.convert(hw_delta_t_r,'R','K').get # Air handler control temperatures clg_sa_temp_f = 55.04 # Central deck clg temp 55F prehtg_sa_temp_f = 44.6 # Preheat to 44.6F preclg_sa_temp_f = 55.04 # Precool to 55F htg_sa_temp_f = 62.06 # Central deck htg temp 62.06F rht_sa_temp_f = 122 # VAV box reheat to 104F zone_htg_sa_temp_f = 122 # Zone heating design supply air temperature to 122F clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f,'F','C').get prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f,'F','C').get preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f,'F','C').get htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f,'F','C').get rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f,'F','C').get zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f,'F','C').get # Air handler air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? air_loop.setName("#{thermal_zones.size} Zone CAV") else air_loop.setName(sys_name) end air_loop.setAvailabilitySchedule(hvac_op_sch) # Air handler supply air setpoint sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F") sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default") sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),clg_sa_temp_c) sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,sa_temp_sch) sa_stpt_manager.setName("#{air_loop.name} supply air setpoint manager") sa_stpt_manager.addToNode(air_loop.supplyOutletNode) # Air handler sizing sizing_system = air_loop.sizingSystem sizing_system.setPreheatDesignTemperature(prehtg_sa_temp_c) sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c) sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c) sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c) sizing_system.setSizingOption('Coincident') sizing_system.setAllOutdoorAirinCooling(false) sizing_system.setAllOutdoorAirinHeating(false) sizing_system.setSystemOutdoorAirMethod('ZoneSum') # Fan fan = OpenStudio::Model::FanConstantVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{air_loop.name} Fan") fan.setFanEfficiency(fan_efficiency) fan.setMotorEfficiency(fan_motor_efficiency) fan.setPressureRise(fan_pressure_rise) fan.addToNode(air_loop.supplyInletNode) fan.setEndUseSubcategory("CAV system Fans") # Air handler heating coil htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) htg_coil.addToNode(air_loop.supplyInletNode) hot_water_loop.addDemandBranchForComponent(htg_coil) htg_coil.setName("#{air_loop.name} Main Htg Coil") htg_coil.controllerWaterCoil.get.setName("#{air_loop.name} Main Htg Coil Controller") htg_coil.setRatedInletWaterTemperature(hw_temp_c) htg_coil.setRatedInletAirTemperature(prehtg_sa_temp_c) htg_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) htg_coil.setRatedOutletAirTemperature(htg_sa_temp_c) # Air handler cooling coil clg_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(self) clg_coil.setName("#{air_loop.name} Clg Coil") clg_coil.addToNode(air_loop.supplyInletNode) # Outdoor air intake system oa_intake_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_intake_controller.setName("#{air_loop.name} OA Controller") oa_intake_controller.setMinimumLimitType('FixedMinimum') #oa_intake_controller.setMinimumOutdoorAirSchedule(motorized_oa_damper_sch) oa_intake_controller.setMinimumFractionofOutdoorAirSchedule(oa_damper_sch) oa_intake_controller.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum') controller_mv = oa_intake_controller.controllerMechanicalVentilation controller_mv.setName("#{air_loop.name} Vent Controller") controller_mv.setSystemOutdoorAirMethod('ZoneSum') oa_intake = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self, oa_intake_controller) oa_intake.setName("#{air_loop.name} OA Sys") oa_intake.addToNode(air_loop.supplyInletNode) # The oa system needs to be added before setting the night cycle control air_loop.setNightCycleControlType('CycleOnAny') # Connect the CAV system to each zone thermal_zones.each do |zone| # Reheat coil rht_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) rht_coil.setName("#{zone.name} Rht Coil") rht_coil.setRatedInletWaterTemperature(hw_temp_c) rht_coil.setRatedInletAirTemperature(htg_sa_temp_c) rht_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) rht_coil.setRatedOutletAirTemperature(rht_sa_temp_c) hot_water_loop.addDemandBranchForComponent(rht_coil) # VAV terminal terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(self,self.alwaysOnDiscreteSchedule,rht_coil) terminal.setName("#{zone.name} VAV Term") terminal.setZoneMinimumAirFlowMethod('Constant') terminal.set_initial_prototype_damper_position(standard, zone.outdoor_airflow_rate_per_area) terminal.setMaximumFlowPerZoneFloorAreaDuringReheat(0.0) terminal.setMaximumFlowFractionDuringReheat(0.5) terminal.setMaximumReheatAirTemperature(rht_sa_temp_c) air_loop.addBranchForZone(zone,terminal.to_StraightComponent) # Zone sizing # TODO Create general logic for cooling airflow method. # Large hotel uses design day with limit, school uses design day. sizing_zone = zone.sizingZone if building_type == 'SecondarySchool' sizing_zone.setCoolingDesignAirFlowMethod('DesignDay') else sizing_zone.setCoolingDesignAirFlowMethod("DesignDayWithLimit") end sizing_zone.setHeatingDesignAirFlowMethod("DesignDay") sizing_zone.setZoneCoolingDesignSupplyAirTemperature(clg_sa_temp_c) #sizing_zone.setZoneHeatingDesignSupplyAirTemperature(rht_sa_temp_c) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(zone_htg_sa_temp_c) end # Set the damper action based on the template. air_loop.set_vav_damper_action(standard) return true end |
#add_chw_loop(standard, chw_pumping_type, chiller_cooling_type, chiller_condenser_type, chiller_compressor_type, chiller_capacity_guess_tons, condenser_water_loop = nil, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a chilled water loop and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013
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 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 116 def add_chw_loop(standard, chw_pumping_type, chiller_cooling_type, chiller_condenser_type, chiller_compressor_type, chiller_capacity_guess_tons, condenser_water_loop = nil, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding chilled water loop.") # Chilled water loop chilled_water_loop = OpenStudio::Model::PlantLoop.new(self) chilled_water_loop.setName('Chilled Water Loop') chilled_water_loop.setMaximumLoopTemperature(98) chilled_water_loop.setMinimumLoopTemperature(1) # Chilled water loop controls chw_temp_f = 44 #CHW setpoint 44F chw_delta_t_r = 10.1 #10.1F delta-T # TODO: Yixing check the CHW Setpoint from standards # TODO: Should be a OutdoorAirReset, see the changes I've made in Standards.PlantLoop.apply_performance_rating_method_baseline_temperatures if building_type == 'LargeHotel' chw_temp_f = 45 #CHW setpoint 45F chw_delta_t_r = 12 #12F delta-T end chw_temp_c = OpenStudio.convert(chw_temp_f,'F','C').get chw_delta_t_k = OpenStudio.convert(chw_delta_t_r,'R','K').get chw_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) chw_temp_sch.setName("Chilled Water Loop Temp - #{chw_temp_f}F") chw_temp_sch.defaultDaySchedule.setName("Chilled Water Loop Temp - #{chw_temp_f}F Default") chw_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),chw_temp_c) chw_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,chw_temp_sch) chw_stpt_manager.setName("Chilled water loop setpoint manager") chw_stpt_manager.addToNode(chilled_water_loop.supplyOutletNode) sizing_plant = chilled_water_loop.sizingPlant sizing_plant.setLoopType('Cooling') sizing_plant.setDesignLoopExitTemperature(chw_temp_c) sizing_plant.setLoopDesignTemperatureDifference(chw_delta_t_k) # Chilled water pumps if chw_pumping_type == 'const_pri' # Primary chilled water pump pri_chw_pump = OpenStudio::Model::PumpVariableSpeed.new(self) pri_chw_pump.setName('Chilled Water Loop Pump') pri_chw_pump_head_ft_h2o = 60.0 pri_chw_pump_head_press_pa = OpenStudio.convert(pri_chw_pump_head_ft_h2o, 'ftH_{2}O','Pa').get pri_chw_pump.setRatedPumpHead(pri_chw_pump_head_press_pa) pri_chw_pump.setMotorEfficiency(0.9) # Flat pump curve makes it behave as a constant speed pump pri_chw_pump.setFractionofMotorInefficienciestoFluidStream(0) pri_chw_pump.setCoefficient1ofthePartLoadPerformanceCurve(0) pri_chw_pump.setCoefficient2ofthePartLoadPerformanceCurve(1) pri_chw_pump.setCoefficient3ofthePartLoadPerformanceCurve(0) pri_chw_pump.setCoefficient4ofthePartLoadPerformanceCurve(0) pri_chw_pump.setPumpControlType('Intermittent') pri_chw_pump.addToNode(chilled_water_loop.supplyInletNode) elsif chw_pumping_type == 'const_pri_var_sec' # Primary chilled water pump pri_chw_pump = OpenStudio::Model::PumpConstantSpeed.new(self) pri_chw_pump.setName('Chilled Water Loop Primary Pump') pri_chw_pump_head_ft_h2o = 15 pri_chw_pump_head_press_pa = OpenStudio.convert(pri_chw_pump_head_ft_h2o, 'ftH_{2}O','Pa').get pri_chw_pump.setRatedPumpHead(pri_chw_pump_head_press_pa) pri_chw_pump.setMotorEfficiency(0.9) pri_chw_pump.setPumpControlType('Intermittent') pri_chw_pump.addToNode(chilled_water_loop.supplyInletNode) # Secondary chilled water pump sec_chw_pump = OpenStudio::Model::PumpVariableSpeed.new(self) sec_chw_pump.setName('Chilled Water Loop Secondary Pump') sec_chw_pump_head_ft_h2o = 45 sec_chw_pump_head_press_pa = OpenStudio.convert(sec_chw_pump_head_ft_h2o, 'ftH_{2}O','Pa').get sec_chw_pump.setRatedPumpHead(sec_chw_pump_head_press_pa) sec_chw_pump.setMotorEfficiency(0.9) # Curve makes it perform like variable speed pump sec_chw_pump.setFractionofMotorInefficienciestoFluidStream(0) sec_chw_pump.setCoefficient1ofthePartLoadPerformanceCurve(0) sec_chw_pump.setCoefficient2ofthePartLoadPerformanceCurve(0.0205) sec_chw_pump.setCoefficient3ofthePartLoadPerformanceCurve(0.4101) sec_chw_pump.setCoefficient4ofthePartLoadPerformanceCurve(0.5753) sec_chw_pump.setPumpControlType('Intermittent') sec_chw_pump.addToNode(chilled_water_loop.demandInletNode) # Change the chilled water loop to have a two-way common pipes chilled_water_loop.setCommonPipeSimulation('CommonPipe') end # Make the correct type of chiller based these properties chiller = OpenStudio::Model::ChillerElectricEIR.new(self) chiller.setName("#{standard} #{chiller_cooling_type} #{chiller_condenser_type} #{chiller_compressor_type} Chiller") chilled_water_loop.addSupplyBranchForComponent(chiller) chiller.setReferenceLeavingChilledWaterTemperature(chw_temp_c) ref_cond_wtr_temp_f = 95 ref_cond_wtr_temp_c = OpenStudio.convert(ref_cond_wtr_temp_f,'F','C').get chiller.setReferenceEnteringCondenserFluidTemperature(ref_cond_wtr_temp_c) chiller.setMinimumPartLoadRatio(0.15) chiller.setMaximumPartLoadRatio(1.0) chiller.setOptimumPartLoadRatio(1.0) chiller.setMinimumUnloadingRatio(0.25) chiller.setCondenserType('AirCooled') chiller.setLeavingChilledWaterLowerTemperatureLimit(OpenStudio.convert(36,'F','C').get) chiller.setChillerFlowMode('ConstantFlow') #if building_type == "LargeHotel" # TODO: Yixing. Add the temperature setpoint and change the flow mode will cost the simulation with # thousands of Severe Errors. Need to figure this out later. #chiller.setChillerFlowMode('LeavingSetpointModulated') #chiller_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,chw_temp_sch) #chiller_stpt_manager.setName("chiller outlet setpoint manager") #chiller_stpt_manager.addToNode(chiller.supplyOutletModelObject.get.to_Node.get) #end # Connect the chiller to the condenser loop if # one was supplied. if condenser_water_loop condenser_water_loop.addDemandBranchForComponent(chiller) chiller.setCondenserType('WaterCooled') end #chilled water loop pipes chiller_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) chilled_water_loop.addSupplyBranchForComponent(chiller_bypass_pipe) coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) chilled_water_loop.addDemandBranchForComponent(coil_bypass_pipe) supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_outlet_pipe.addToNode(chilled_water_loop.supplyOutletNode) demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_inlet_pipe.addToNode(chilled_water_loop.demandInletNode) demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_outlet_pipe.addToNode(chilled_water_loop.demandOutletNode) return chilled_water_loop end |
#add_construction(construction_name, construction_props = nil) ⇒ Object
make return an OptionalConstruction
Create a construction from the openstudio standards dataset. If construction_props are specified, modifies the insulation layer accordingly.
2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2032 def add_construction(construction_name, construction_props = nil) # First check model and return construction if it already exists self.getConstructions.each do |construction| if construction.name.get.to_s == construction_name OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "Already added construction: #{construction_name}") return construction end end OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "Adding construction: #{construction_name}") # Get the object data data = self.find_object($os_standards['constructions'], {'name'=>construction_name}) if !data OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Cannot find data for construction: #{construction_name}, will not be created.") return OpenStudio::Model::OptionalConstruction.new end # Make a new construction and set the standards details construction = OpenStudio::Model::Construction.new(self) construction.setName(construction_name) standards_info = construction.standardsInformation intended_surface_type = data['intended_surface_type'] unless intended_surface_type intended_surface_type = '' end standards_info.setIntendedSurfaceType(intended_surface_type) standards_construction_type = data['standards_construction_type'] unless standards_construction_type standards_construction_type = '' end standards_info.setStandardsConstructionType(standards_construction_type) # TODO: could put construction rendering color in the spreadsheet # Add the material layers to the construction layers = OpenStudio::Model::MaterialVector.new data['materials'].each do |material_name| material = add_material(material_name) if material layers << material end end construction.setLayers(layers) # Modify the R value of the insulation to hit the specified U-value, C-Factor, or F-Factor. # Doesn't currently operate on glazing constructions if construction_props # Determine the target U-value, C-factor, and F-factor target_u_value_ip = construction_props['assembly_maximum_u_value'] target_f_factor_ip = construction_props['assembly_maximum_f_factor'] target_c_factor_ip = construction_props['assembly_maximum_c_factor'] OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "#{data['intended_surface_type']} u_val #{target_u_value_ip} f_fac #{target_f_factor_ip} c_fac #{target_c_factor_ip}") if target_u_value_ip && !(data['intended_surface_type'] == 'ExteriorWindow' || data['intended_surface_type'] == 'Skylight') # Set the U-Value construction.set_u_value(target_u_value_ip.to_f, data['insulation_layer'], data['intended_surface_type'], true) elsif target_f_factor_ip && data['intended_surface_type'] == 'GroundContactFloor' # Set the F-Factor (only applies to slabs on grade) # TODO figure out what the prototype buildings did about ground heat transfer #construction.set_slab_f_factor(target_f_factor_ip.to_f, data['insulation_layer']) construction.set_u_value(0.0, data['insulation_layer'], data['intended_surface_type'], true) elsif target_c_factor_ip && data['intended_surface_type'] == 'GroundContactWall' # Set the C-Factor (only applies to underground walls) # TODO figure out what the prototype buildings did about ground heat transfer #construction.set_underground_wall_c_factor(target_c_factor_ip.to_f, data['insulation_layer']) construction.set_u_value(0.0, data['insulation_layer'], data['intended_surface_type'], true) end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Adding construction #{construction.name}.") return construction end |
#add_construction_set(building_vintage, clim, building_type, spc_type, is_residential) ⇒ Object
Create a construction set from the openstudio standards dataset. Returns an Optional DefaultConstructionSet
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2160 def add_construction_set(building_vintage, clim, building_type, spc_type, is_residential) construction_set = OpenStudio::Model::OptionalDefaultConstructionSet.new # Find the climate zone set that this climate zone falls into climate_zone_set = find_climate_zone_set(clim, building_vintage) if !climate_zone_set return construction_set end # Get the object data data = self.find_object($os_standards['construction_sets'], {'template'=>building_vintage, 'climate_zone_set'=> climate_zone_set, 'building_type'=>building_type, 'space_type'=>spc_type, 'is_residential'=>is_residential}) if !data data = self.find_object($os_standards['construction_sets'], {'template'=>building_vintage, 'climate_zone_set'=> climate_zone_set, 'building_type'=>building_type, 'space_type'=>spc_type}) if !data return construction_set end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Adding construction set: #{building_vintage}-#{clim}-#{building_type}-#{spc_type}-is_residential#{is_residential}") name = make_name(building_vintage, clim, building_type, spc_type) # Create a new construction set and name it construction_set = OpenStudio::Model::DefaultConstructionSet.new(self) construction_set.setName(name) # Exterior surfaces constructions exterior_surfaces = OpenStudio::Model::DefaultSurfaceConstructions.new(self) construction_set.setDefaultExteriorSurfaceConstructions(exterior_surfaces) if data['exterior_floor_standards_construction_type'] && data['exterior_floor_building_category'] exterior_surfaces.setFloorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorFloor', data['exterior_floor_standards_construction_type'], data['exterior_floor_building_category'])) end if data['exterior_wall_standards_construction_type'] && data['exterior_wall_building_category'] exterior_surfaces.setWallConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorWall', data['exterior_wall_standards_construction_type'], data['exterior_wall_building_category'])) end if data['exterior_roof_standards_construction_type'] && data['exterior_roof_building_category'] exterior_surfaces.setRoofCeilingConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorRoof', data['exterior_roof_standards_construction_type'], data['exterior_roof_building_category'])) end # Interior surfaces constructions interior_surfaces = OpenStudio::Model::DefaultSurfaceConstructions.new(self) construction_set.setDefaultInteriorSurfaceConstructions(interior_surfaces) construction_name = data['interior_floors'] if construction_name != nil interior_surfaces.setFloorConstruction(add_construction(construction_name)) end construction_name = data['interior_walls'] if construction_name != nil interior_surfaces.setWallConstruction(add_construction(construction_name)) end construction_name = data['interior_ceilings'] if construction_name != nil interior_surfaces.setRoofCeilingConstruction(add_construction(construction_name)) end # Ground contact surfaces constructions ground_surfaces = OpenStudio::Model::DefaultSurfaceConstructions.new(self) construction_set.setDefaultGroundContactSurfaceConstructions(ground_surfaces) if data['ground_contact_floor_standards_construction_type'] && data['ground_contact_floor_building_category'] ground_surfaces.setFloorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'GroundContactFloor', data['ground_contact_floor_standards_construction_type'], data['ground_contact_floor_building_category'])) end if data['ground_contact_wall_standards_construction_type'] && data['ground_contact_wall_building_category'] ground_surfaces.setWallConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'GroundContactWall', data['ground_contact_wall_standards_construction_type'], data['ground_contact_wall_building_category'])) end if data['ground_contact_ceiling_standards_construction_type'] && data['ground_contact_ceiling_building_category'] ground_surfaces.setRoofCeilingConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'GroundContactRoof', data['ground_contact_ceiling_standards_construction_type'], data['ground_contact_ceiling_building_category'])) end # Exterior sub surfaces constructions exterior_subsurfaces = OpenStudio::Model::DefaultSubSurfaceConstructions.new(self) construction_set.setDefaultExteriorSubSurfaceConstructions(exterior_subsurfaces) if data['exterior_fixed_window_standards_construction_type'] && data['exterior_fixed_window_building_category'] exterior_subsurfaces.setFixedWindowConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorWindow', data['exterior_fixed_window_standards_construction_type'], data['exterior_fixed_window_building_category'])) end if data['exterior_operable_window_standards_construction_type'] && data['exterior_operable_window_building_category'] exterior_subsurfaces.setOperableWindowConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorWindow', data['exterior_operable_window_standards_construction_type'], data['exterior_operable_window_building_category'])) end if data['exterior_door_standards_construction_type'] && data['exterior_door_building_category'] exterior_subsurfaces.setDoorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorDoor', data['exterior_door_standards_construction_type'], data['exterior_door_building_category'])) end construction_name = data['exterior_glass_doors'] if construction_name != nil exterior_subsurfaces.setGlassDoorConstruction(add_construction(construction_name)) end if data['exterior_overhead_door_standards_construction_type'] && data['exterior_overhead_door_building_category'] exterior_subsurfaces.setOverheadDoorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorDoor', data['exterior_overhead_door_standards_construction_type'], data['exterior_overhead_door_building_category'])) end if data['exterior_skylight_standards_construction_type'] && data['exterior_skylight_building_category'] exterior_subsurfaces.setSkylightConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'Skylight', data['exterior_skylight_standards_construction_type'], data['exterior_skylight_building_category'])) end if construction_name = data['tubular_daylight_domes'] exterior_subsurfaces.setTubularDaylightDomeConstruction(add_construction(construction_name)) end if construction_name = data['tubular_daylight_diffusers'] exterior_subsurfaces.setTubularDaylightDiffuserConstruction(add_construction(construction_name)) end # Interior sub surfaces constructions interior_subsurfaces = OpenStudio::Model::DefaultSubSurfaceConstructions.new(self) construction_set.setDefaultInteriorSubSurfaceConstructions(interior_subsurfaces) if construction_name = data['interior_fixed_windows'] interior_subsurfaces.setFixedWindowConstruction(add_construction(construction_name)) end if construction_name = data['interior_operable_windows'] interior_subsurfaces.setOperableWindowConstruction(add_construction(construction_name)) end if construction_name = data['interior_doors'] interior_subsurfaces.setDoorConstruction(add_construction(construction_name)) end # Other constructions if construction_name = data['interior_partitions'] construction_set.setInteriorPartitionConstruction(add_construction(construction_name)) end if construction_name = data['space_shading'] construction_set.setSpaceShadingConstruction(add_construction(construction_name)) end if construction_name = data['building_shading'] construction_set.setBuildingShadingConstruction(add_construction(construction_name)) end if construction_name = data['site_shading'] construction_set.setSiteShadingConstruction(add_construction(construction_name)) end # componentize the construction set #construction_set_component = construction_set.createComponent # Return the construction set return OpenStudio::Model::OptionalDefaultConstructionSet.new(construction_set) end |
#add_constructions(building_type, building_vintage, climate_zone) ⇒ Bool
Adds code-minimum constructions based on the building type as defined in the OpenStudio_Standards_construction_sets.json file. Where there is a separate construction set specified for the individual space type, this construction set will be created and applied to this space type, overriding the whole-building construction set.
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 447 def add_constructions(building_type, building_vintage, climate_zone) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying constructions') is_residential = "No" #default is nonresidential for building level # Assign construction to adiabatic construction # Assign a material to all internal mass objects cp02_carpet_pad = OpenStudio::Model::MasslessOpaqueMaterial.new(self) cp02_carpet_pad.setName('CP02 CARPET PAD') cp02_carpet_pad.setRoughness("VeryRough") cp02_carpet_pad.setThermalResistance(0.21648) cp02_carpet_pad.setThermalAbsorptance(0.9) cp02_carpet_pad.setSolarAbsorptance(0.7) cp02_carpet_pad.setVisibleAbsorptance(0.8) normalweight_concrete_floor = OpenStudio::Model::StandardOpaqueMaterial.new(self) normalweight_concrete_floor.setName('100mm Normalweight concrete floor') normalweight_concrete_floor.setRoughness('MediumSmooth') normalweight_concrete_floor.setThickness(0.1016) normalweight_concrete_floor.setConductivity(2.31) normalweight_concrete_floor.setDensity(2322) normalweight_concrete_floor.setSpecificHeat(832) nonres_floor_insulation = OpenStudio::Model::MasslessOpaqueMaterial.new(self) nonres_floor_insulation.setName('Nonres_Floor_Insulation') nonres_floor_insulation.setRoughness("MediumSmooth") nonres_floor_insulation.setThermalResistance(2.88291975297193) nonres_floor_insulation.setThermalAbsorptance(0.9) nonres_floor_insulation.setSolarAbsorptance(0.7) nonres_floor_insulation.setVisibleAbsorptance(0.7) floor_adiabatic_construction = OpenStudio::Model::Construction.new(self) floor_adiabatic_construction.setName('Floor Adiabatic construction') floor_layers = OpenStudio::Model::MaterialVector.new floor_layers << cp02_carpet_pad floor_layers << normalweight_concrete_floor floor_layers << nonres_floor_insulation floor_adiabatic_construction.setLayers(floor_layers) g01_13mm_gypsum_board = OpenStudio::Model::StandardOpaqueMaterial.new(self) g01_13mm_gypsum_board.setName('G01 13mm gypsum board') g01_13mm_gypsum_board.setRoughness('Smooth') g01_13mm_gypsum_board.setThickness(0.0127) g01_13mm_gypsum_board.setConductivity(0.1600) g01_13mm_gypsum_board.setDensity(800) g01_13mm_gypsum_board.setSpecificHeat(1090) g01_13mm_gypsum_board.setThermalAbsorptance(0.9) g01_13mm_gypsum_board.setSolarAbsorptance(0.7) g01_13mm_gypsum_board.setVisibleAbsorptance(0.5) wall_adiabatic_construction = OpenStudio::Model::Construction.new(self) wall_adiabatic_construction.setName('Wall Adiabatic construction') wall_layers = OpenStudio::Model::MaterialVector.new wall_layers << g01_13mm_gypsum_board wall_layers << g01_13mm_gypsum_board wall_adiabatic_construction.setLayers(wall_layers) m10_200mm_concrete_block_basement_wall= OpenStudio::Model::StandardOpaqueMaterial.new(self) m10_200mm_concrete_block_basement_wall.setName('M10 200mm concrete block basement wall') m10_200mm_concrete_block_basement_wall.setRoughness('MediumRough') m10_200mm_concrete_block_basement_wall.setThickness(0.2032) m10_200mm_concrete_block_basement_wall.setConductivity(1.326) m10_200mm_concrete_block_basement_wall.setDensity(1842) m10_200mm_concrete_block_basement_wall.setSpecificHeat(912) basement_wall_construction = OpenStudio::Model::Construction.new(self) basement_wall_construction.setName('Basement Wall construction') basement_wall_layers = OpenStudio::Model::MaterialVector.new basement_wall_layers << m10_200mm_concrete_block_basement_wall basement_wall_construction.setLayers(basement_wall_layers) basement_floor_construction = OpenStudio::Model::Construction.new(self) basement_floor_construction.setName('Basement Floor construction') basement_floor_layers = OpenStudio::Model::MaterialVector.new basement_floor_layers << m10_200mm_concrete_block_basement_wall basement_floor_layers << cp02_carpet_pad basement_floor_construction.setLayers(basement_floor_layers) self.getSurfaces.each do |surface| if surface.outsideBoundaryCondition.to_s == "Adiabatic" if surface.surfaceType.to_s == "Wall" surface.setConstruction(wall_adiabatic_construction) else surface.setConstruction(floor_adiabatic_construction) end elsif surface.outsideBoundaryCondition.to_s == "OtherSideCoefficients" # Ground if surface.surfaceType.to_s == "Wall" surface.setOutsideBoundaryCondition("Ground") surface.setConstruction(basement_wall_construction) else surface.setOutsideBoundaryCondition("Ground") surface.setConstruction(basement_floor_construction) end end end # Make the default construction set for the building bldg_def_const_set = self.add_construction_set(building_vintage, climate_zone, building_type, nil, is_residential) if bldg_def_const_set.is_initialized self.getBuilding.setDefaultConstructionSet(bldg_def_const_set.get) else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'Could not create default construction set for the building.') return false end # Make a construction set for each space type, if one is specified self.getSpaceTypes.each do |space_type| # Get the standards building type stds_building_type = nil if space_type.standardsBuildingType.is_initialized stds_building_type = space_type.standardsBuildingType.get else OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Space type called '#{space_type.name}' has no standards building type.") end # Get the standards space type stds_spc_type = nil if space_type.standardsSpaceType.is_initialized stds_spc_type = space_type.standardsSpaceType.get else OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Space type called '#{space_type.name}' has no standards space type.") end # If the standards space type is Attic, # the building type should be blank. if stds_spc_type == 'Attic' stds_building_type = '' end # Attempt to make a construction set for this space type # and assign it if it can be created. spc_type_const_set = self.add_construction_set(building_vintage, climate_zone, stds_building_type, stds_spc_type, is_residential) if spc_type_const_set.is_initialized space_type.setDefaultConstructionSet(spc_type_const_set.get) end end # Add construction from story level, especially for the case when there are residential and nonresidential construction in the same building if building_type == 'SmallHotel' self.getBuildingStorys.each do |story| next if story.name.get == 'AtticStory' puts "story = #{story.name}" is_residential = "No" #default for building story level exterior_spaces_area = 0 story_exterior_residential_area = 0 # calculate the propotion of residential area in exterior spaces, see if this story is residential or not story::spaces.each do |space| next if space.exteriorWallArea == 0 space_type = space.spaceType.get if space_type.standardsSpaceType.is_initialized space_type_name = space_type.standardsSpaceType.get end data = self.find_object($os_standards['space_types'], {'template'=>building_vintage, 'building_type'=>building_type, 'space_type'=>space_type_name}) exterior_spaces_area += space.floorArea story_exterior_residential_area += space.floorArea if data['is_residential'] == "Yes" # "Yes" is residential, "No" or nil is nonresidential end is_residential = "Yes" if story_exterior_residential_area/exterior_spaces_area >= 0.5 next if is_residential == "No" # if the story is identified as residential, assign residential construction set to the spaces on this story. building_story_const_set = self.add_construction_set(building_vintage, climate_zone, building_type, nil, is_residential) if building_story_const_set.is_initialized story::spaces.each do |space| space.setDefaultConstructionSet(building_story_const_set.get) end end end # Standars: For whole buildings or floors where 50% or more of the spaces adjacent to exterior walls are used primarily for living and sleeping quarters end # Make skylights have the same construction as fixed windows # sub_surface = self.getBuilding.defaultConstructionSet.get.defaultExteriorSubSurfaceConstructions.get # window_construction = sub_surface.fixedWindowConstruction.get # sub_surface.setSkylightConstruction(window_construction) # Assign a material to all internal mass objects material = OpenStudio::Model::StandardOpaqueMaterial.new(self) material.setName('Std Wood 6inch') material.setRoughness('MediumSmooth') material.setThickness(0.15) material.setConductivity(0.12) material.setDensity(540) material.setSpecificHeat(1210) material.setThermalAbsorptance(0.9) material.setSolarAbsorptance(0.7) material.setVisibleAbsorptance(0.7) construction = OpenStudio::Model::Construction.new(self) construction.setName('InteriorFurnishings') layers = OpenStudio::Model::MaterialVector.new layers << material construction.setLayers(layers) # Assign the internal mass construction to existing internal mass objects self.getSpaces.each do |space| internal_masses = space.internalMass internal_masses.each do |internal_mass| internal_mass.internalMassDefinition.setConstruction(construction) end end # get all the space types that are conditioned conditioned_space_names = find_conditioned_space_names(building_type, building_vintage, climate_zone) # add internal mass unless (building_type == 'SmallHotel') && (building_vintage == '90.1-2004' or building_vintage == '90.1-2007' or building_vintage == '90.1-2010' or building_vintage == '90.1-2013') internal_mass_def = OpenStudio::Model::InternalMassDefinition.new(self) internal_mass_def.setSurfaceAreaperSpaceFloorArea(2.0) internal_mass_def.setConstruction(construction) conditioned_space_names.each do |conditioned_space_name| space = self.getSpaceByName(conditioned_space_name) if space.is_initialized space = space.get internal_mass = OpenStudio::Model::InternalMass.new(internal_mass_def) internal_mass.setName("#{space.name} Mass") internal_mass.setSpace(space) end end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying constructions') return true end |
#add_curve(curve_name) ⇒ Object
2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2337 def add_curve(curve_name) #OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.addCurve", "Adding curve '#{curve_name}' to the model.") success = false curve_biquadratics = $os_standards["curve_biquadratics"] curve_quadratics = $os_standards["curve_quadratics"] curve_bicubics = $os_standards["curve_bicubics"] curve_cubics = $os_standards["curve_cubics"] # Make biquadratic curves curve_data = self.find_object(curve_biquadratics, {"name"=>curve_name}) if curve_data curve = OpenStudio::Model::CurveBiquadratic.new(self) curve.setName(curve_data["name"]) curve.setCoefficient1Constant(curve_data["coeff_1"]) curve.setCoefficient2x(curve_data["coeff_2"]) curve.setCoefficient3xPOW2(curve_data["coeff_3"]) curve.setCoefficient4y(curve_data["coeff_4"]) curve.setCoefficient5yPOW2(curve_data["coeff_5"]) curve.setCoefficient6xTIMESY(curve_data["coeff_6"]) curve.setMinimumValueofx(curve_data["min_x"]) curve.setMaximumValueofx(curve_data["max_x"]) curve.setMinimumValueofy(curve_data["min_y"]) curve.setMaximumValueofy(curve_data["max_y"]) if curve_data["min_out"] curve.setMinimumCurveOutput(curve_data["min_out"]) end if curve_data["max_out"] curve.setMaximumCurveOutput(curve_data["max_out"]) end success = true return curve end # Make quadratic curves curve_data = self.find_object(curve_quadratics, {"name"=>curve_name}) if curve_data curve = OpenStudio::Model::CurveQuadratic.new(self) curve.setName(curve_data["name"]) curve.setCoefficient1Constant(curve_data["coeff_1"]) curve.setCoefficient2x(curve_data["coeff_2"]) curve.setCoefficient3xPOW2(curve_data["coeff_3"]) curve.setMinimumValueofx(curve_data["min_x"]) curve.setMaximumValueofx(curve_data["max_x"]) if curve_data["min_out"] curve.setMinimumCurveOutput(curve_data["min_out"]) end if curve_data["max_out"] curve.setMaximumCurveOutput(curve_data["max_out"]) end success = true return curve end # Make cubic curves curve_data = self.find_object(curve_cubics, {"name"=>curve_name}) if curve_data curve = OpenStudio::Model::CurveCubic.new(self) curve.setName(curve_data["name"]) curve.setCoefficient1Constant(curve_data["coeff_1"]) curve.setCoefficient2x(curve_data["coeff_2"]) curve.setCoefficient3xPOW2(curve_data["coeff_3"]) curve.setCoefficient4xPOW3(curve_data["coeff_4"]) curve.setMinimumValueofx(curve_data["min_x"]) curve.setMaximumValueofx(curve_data["max_x"]) if curve_data["min_out"] curve.setMinimumCurveOutput(curve_data["min_out"]) end if curve_data["max_out"] curve.setMaximumCurveOutput(curve_data["max_out"]) end success = true return curve end # Make bicubic curves curve_data = self.find_object(curve_bicubics, {"name"=>curve_name}) if curve_data curve = OpenStudio::Model::CurveBicubic.new(self) curve.setName(curve_data["name"]) curve.setCoefficient1Constant(curve_data["coeff_1"]) curve.setCoefficient2x(curve_data["coeff_2"]) curve.setCoefficient3xPOW2(curve_data["coeff_3"]) curve.setCoefficient4y(curve_data["coeff_4"]) curve.setCoefficient5yPOW2(curve_data["coeff_5"]) curve.setCoefficient6xTIMESY(curve_data["coeff_6"]) curve.setCoefficient7xPOW3(curve_data["coeff_7"]) curve.setCoefficient8yPOW3(curve_data["coeff_8"]) curve.setCoefficient9xPOW2TIMESY(curve_data["coeff_9"]) curve.setCoefficient10xTIMESYPOW2(curve_data["coeff_10"]) curve.setMinimumValueofx(curve_data["min_x"]) curve.setMaximumValueofx(curve_data["max_x"]) curve.setMinimumValueofy(curve_data["min_y"]) curve.setMaximumValueofy(curve_data["max_y"]) if curve_data["min_out"] curve.setMinimumCurveOutput(curve_data["min_out"]) end if curve_data["max_out"] curve.setMaximumCurveOutput(curve_data["max_out"]) end success = true return curve end # Return false if the curve was not created if success == false #OpenStudio::logFree(OpenStudio::Warn, "openstudio.prototype.addCurve", "Could not find a curve called '#{curve_name}' in the standards.") return nil end end |
#add_cw_loop(number_cooling_towers = 1) ⇒ OpenStudio::Model::PlantLoop
Creates a condenser water loop and adds it to the model.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 255 def add_cw_loop(number_cooling_towers = 1) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding condenser water loop.") # Condenser water loop condenser_water_loop = OpenStudio::Model::PlantLoop.new(self) condenser_water_loop.setName('Condenser Water Loop') condenser_water_loop.setMaximumLoopTemperature(80) condenser_water_loop.setMinimumLoopTemperature(5) # Condenser water loop controls cw_temp_f = 70 #CW setpoint 70F cw_temp_sizing_f = 85 #CW sized to deliver 85F cw_delta_t_r = 10 #10F delta-T cw_approach_delta_t_r = 7 #7F approach cw_temp_c = OpenStudio.convert(cw_temp_f,'F','C').get cw_temp_sizing_c = OpenStudio.convert(cw_temp_sizing_f,'F','C').get cw_delta_t_k = OpenStudio.convert(cw_delta_t_r,'R','K').get cw_approach_delta_t_k = OpenStudio.convert(cw_approach_delta_t_r,'R','K').get cw_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) cw_temp_sch.setName("Condenser Water Loop Temp - #{cw_temp_f}F") cw_temp_sch.defaultDaySchedule.setName("Condenser Water Loop Temp - #{cw_temp_f}F Default") cw_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),cw_temp_c) cw_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,cw_temp_sch) cw_stpt_manager.addToNode(condenser_water_loop.supplyOutletNode) sizing_plant = condenser_water_loop.sizingPlant sizing_plant.setLoopType('Condenser') sizing_plant.setDesignLoopExitTemperature(cw_temp_sizing_c) sizing_plant.setLoopDesignTemperatureDifference(cw_delta_t_k) # Condenser water pump #TODO make this into a HeaderedPump:VariableSpeed cw_pump = OpenStudio::Model::PumpVariableSpeed.new(self) cw_pump.setName('Condenser Water Loop Pump') cw_pump_head_ft_h2o = 49.7 cw_pump_head_press_pa = OpenStudio.convert(cw_pump_head_ft_h2o, 'ftH_{2}O','Pa').get cw_pump.setRatedPumpHead(cw_pump_head_press_pa) # Curve makes it perform like variable speed pump cw_pump.setFractionofMotorInefficienciestoFluidStream(0) cw_pump.setCoefficient1ofthePartLoadPerformanceCurve(0) cw_pump.setCoefficient2ofthePartLoadPerformanceCurve(0.0216) cw_pump.setCoefficient3ofthePartLoadPerformanceCurve(-0.0325) cw_pump.setCoefficient4ofthePartLoadPerformanceCurve(1.0095) cw_pump.setPumpControlType('Intermittent') cw_pump.addToNode(condenser_water_loop.supplyInletNode) # TODO move cooling tower curve to lookup from spreadsheet cooling_tower_fan_curve = OpenStudio::Model::CurveCubic.new(self) cooling_tower_fan_curve.setName('Cooling Tower Fan Curve') cooling_tower_fan_curve.setCoefficient1Constant(0) cooling_tower_fan_curve.setCoefficient2x(0) cooling_tower_fan_curve.setCoefficient3xPOW2(0) cooling_tower_fan_curve.setCoefficient4xPOW3(1) cooling_tower_fan_curve.setMinimumValueofx(0) cooling_tower_fan_curve.setMaximumValueofx(1) # Cooling towers number_cooling_towers.times do |i| cooling_tower = OpenStudio::Model::CoolingTowerVariableSpeed.new(self) cooling_tower.setName("#{condenser_water_loop.name} Cooling Tower #{i}") cooling_tower.setDesignApproachTemperature(cw_approach_delta_t_k) cooling_tower.setDesignRangeTemperature(cw_delta_t_k) cooling_tower.setFanPowerRatioFunctionofAirFlowRateRatioCurve(cooling_tower_fan_curve) cooling_tower.setMinimumAirFlowRateRatio(0.2) cooling_tower.(0.125) cooling_tower.setNumberofCells(2) cooling_tower.setCellControl('MaximalCell') condenser_water_loop.addSupplyBranchForComponent(cooling_tower) end # Condenser water loop pipes cooling_tower_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) condenser_water_loop.addSupplyBranchForComponent(cooling_tower_bypass_pipe) chiller_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) condenser_water_loop.addDemandBranchForComponent(chiller_bypass_pipe) supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_outlet_pipe.addToNode(condenser_water_loop.supplyOutletNode) demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_inlet_pipe.addToNode(condenser_water_loop.demandInletNode) demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_outlet_pipe.addToNode(condenser_water_loop.demandOutletNode) return condenser_water_loop end |
#add_data_center_hvac(standard, sys_name, hot_water_loop, heat_pump_loop, thermal_zones, hvac_op_sch, oa_damper_sch, main_data_center = false) ⇒ Array<OpenStudio::Model::AirLoopHVAC>
Creates a data center PSZ-AC system for each zone.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open center in the building.
1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 1895 def add_data_center_hvac(standard, sys_name, hot_water_loop, heat_pump_loop, thermal_zones, hvac_op_sch, oa_damper_sch, main_data_center = false) thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding data center HVAC for #{zone.name}.") end hw_temp_f = 180 #HW setpoint 180F hw_delta_t_r = 20 #20F delta-T hw_temp_c = OpenStudio.convert(hw_temp_f,'F','C').get hw_delta_t_k = OpenStudio.convert(hw_delta_t_r,'R','K').get # control temps used across all air handlers clg_sa_temp_f = 55 # Central deck clg temp 55F prehtg_sa_temp_f = 44.6 # Preheat to 44.6F htg_sa_temp_f = 55 # Central deck htg temp 55F rht_sa_temp_f = 104 # VAV box reheat to 104F clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f,'F','C').get prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f,'F','C').get htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f,'F','C').get rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f,'F','C').get # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # Make a PSZ-AC for each zone air_loops = [] thermal_zones.each do |zone| air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? air_loop.setName("#{zone.name} PSZ-AC Data Center") else air_loop.setName("#{zone.name} #{sys_name}") end air_loops << air_loop air_loop.setAvailabilitySchedule(hvac_op_sch) # When an air_loop is contructed, its constructor creates a sizing:system object # the default sizing:system contstructor makes a system:sizing object # appropriate for a multizone VAV system # this systems is a constant volume system with no VAV terminals, # and therfore needs different default settings air_loop_sizing = air_loop.sizingSystem # TODO units air_loop_sizing.setTypeofLoadtoSizeOn('Sensible') air_loop_sizing.autosizeDesignOutdoorAirFlowRate air_loop_sizing.setMinimumSystemAirFlowRatio(1.0) air_loop_sizing.setPreheatDesignTemperature(7.0) air_loop_sizing.setPreheatDesignHumidityRatio(0.008) air_loop_sizing.setPrecoolDesignTemperature(12.8) air_loop_sizing.setPrecoolDesignHumidityRatio(0.008) air_loop_sizing.setCentralCoolingDesignSupplyAirTemperature(12.8) air_loop_sizing.setCentralHeatingDesignSupplyAirTemperature(40.0) air_loop_sizing.setSizingOption('Coincident') air_loop_sizing.setAllOutdoorAirinCooling(false) air_loop_sizing.setAllOutdoorAirinHeating(false) air_loop_sizing.setCentralCoolingDesignSupplyAirHumidityRatio(0.0085) air_loop_sizing.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080) air_loop_sizing.setCoolingDesignAirFlowMethod('DesignDay') air_loop_sizing.setCoolingDesignAirFlowRate(0.0) air_loop_sizing.setHeatingDesignAirFlowMethod('DesignDay') air_loop_sizing.setHeatingDesignAirFlowRate(0.0) air_loop_sizing.setSystemOutdoorAirMethod('ZoneSum') # Zone sizing sizing_zone = zone.sizingZone sizing_zone.setZoneCoolingDesignSupplyAirTemperature(12.8) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(40.0) # Add a setpoint manager single zone reheat to control the # supply air temperature based on the needs of this zone setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(self) setpoint_mgr_single_zone_reheat.setControlZone(zone) fan = OpenStudio::Model::FanOnOff.new(self,hvac_op_sch) # Set fan op sch manually since fwd translator doesn't fan.setName("#{air_loop.name} Fan") fan_static_pressure_in_h2o = 2.5 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, 'inH_{2}O','Pa').get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.54) fan.setMotorEfficiency(0.90) htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(self) htg_coil.setName("#{air_loop.name} Water-to-Air HP Htg Coil") htg_coil.setRatedHeatingCoefficientofPerformance(4.2) # TODO add this to standards htg_coil.setHeatingCapacityCoefficient1(0.237847462869254) htg_coil.setHeatingCapacityCoefficient2(-3.35823796081626) htg_coil.setHeatingCapacityCoefficient3(3.80640467406376) htg_coil.setHeatingCapacityCoefficient4(0.179200417311554) htg_coil.setHeatingCapacityCoefficient5(0.12860719846082) htg_coil.setHeatingPowerConsumptionCoefficient1(-3.79175529243238) htg_coil.setHeatingPowerConsumptionCoefficient2(3.38799239505527) htg_coil.setHeatingPowerConsumptionCoefficient3(1.5022612076303) htg_coil.setHeatingPowerConsumptionCoefficient4(-0.177653510577989) htg_coil.setHeatingPowerConsumptionCoefficient5(-0.103079864171839) heat_pump_loop.addDemandBranchForComponent(htg_coil) clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(self) clg_coil.setName("#{air_loop.name} Water-to-Air HP Clg Coil") clg_coil.setRatedCoolingCoefficientofPerformance(3.4) # TODO add this to standards clg_coil.setTotalCoolingCapacityCoefficient1(-4.30266987344639) clg_coil.setTotalCoolingCapacityCoefficient2(7.18536990534372) clg_coil.setTotalCoolingCapacityCoefficient3(-2.23946714486189) clg_coil.setTotalCoolingCapacityCoefficient4(0.139995928440879) clg_coil.setTotalCoolingCapacityCoefficient5(0.102660179888915) clg_coil.setSensibleCoolingCapacityCoefficient1(6.0019444814887) clg_coil.setSensibleCoolingCapacityCoefficient2(22.6300677244073) clg_coil.setSensibleCoolingCapacityCoefficient3(-26.7960783730934) clg_coil.setSensibleCoolingCapacityCoefficient4(-1.72374720346819) clg_coil.setSensibleCoolingCapacityCoefficient5(0.490644802367817) clg_coil.setSensibleCoolingCapacityCoefficient6(0.0693119353468141) clg_coil.setCoolingPowerConsumptionCoefficient1(-5.67775976415698) clg_coil.setCoolingPowerConsumptionCoefficient2(0.438988156976704) clg_coil.setCoolingPowerConsumptionCoefficient3(5.845277342193) clg_coil.setCoolingPowerConsumptionCoefficient4(0.141605667000125) clg_coil.setCoolingPowerConsumptionCoefficient5(-0.168727936032429) heat_pump_loop.addDemandBranchForComponent(clg_coil) supplemental_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) supplemental_htg_coil.setName("#{air_loop.name} Electric Backup Htg Coil") oa_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_controller.setName("#{air_loop.name} OA Sys Controller") oa_controller.setMinimumOutdoorAirSchedule(oa_damper_sch) oa_system = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self,oa_controller) oa_system.setName("#{air_loop.name} OA Sys") # Add the components to the air loop # in order from closest to zone to furthest from zone supply_inlet_node = air_loop.supplyInletNode if main_data_center humidifier = OpenStudio::Model::HumidifierSteamElectric.new(self) humidifier.setRatedCapacity(3.72E-5) humidifier.setRatedPower(100000) humidifier.setName("#{air_loop.name} Electric Steam Humidifier") extra_elec_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) extra_elec_htg_coil.setName("#{air_loop.name} Electric Htg Coil") extra_water_htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) extra_water_htg_coil.setName("#{air_loop.name} Water Htg Coil") extra_water_htg_coil.setRatedInletWaterTemperature(hw_temp_c) extra_water_htg_coil.setRatedInletAirTemperature(prehtg_sa_temp_c) extra_water_htg_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) extra_water_htg_coil.setRatedOutletAirTemperature(htg_sa_temp_c) hot_water_loop.addDemandBranchForComponent(extra_water_htg_coil) extra_water_htg_coil.addToNode(supply_inlet_node) extra_elec_htg_coil.addToNode(supply_inlet_node) humidifier.addToNode(supply_inlet_node) humidity_spm = OpenStudio::Model::SetpointManagerSingleZoneHumidityMinimum.new(self) humidity_spm.setControlZone(zone) humidity_spm.addToNode(humidifier.outletModelObject().get.to_Node.get) humidistat = OpenStudio::Model::ZoneControlHumidistat.new(self) humidistat.(self.add_schedule('OfficeLarge DC_MinRelHumSetSch')) zone.setZoneControlHumidistat(humidistat) end unitary_system = OpenStudio::Model::AirLoopHVACUnitarySystem.new(self) unitary_system.setSupplyFan(fan) unitary_system.setHeatingCoil(htg_coil) unitary_system.setCoolingCoil(clg_coil) unitary_system.setSupplementalHeatingCoil(supplemental_htg_coil) unitary_system.setName("#{zone.name} Unitary HP") unitary_system.setControllingZoneorThermostatLocation(zone) unitary_system.setMaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation(OpenStudio.convert(40,'F','C').get) unitary_system.setFanPlacement('BlowThrough') unitary_system.(hvac_op_sch) unitary_system.(self.alwaysOnDiscreteSchedule) unitary_system.addToNode(supply_inlet_node) setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(55,'F','C').get) setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(104,'F','C').get) # Add the OA system oa_system.addToNode(supply_inlet_node) # Attach the nightcycle manager to the supply outlet node setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode) air_loop.setNightCycleControlType('CycleOnAny') # Create a diffuser and attach the zone/diffuser pair to the air loop diffuser = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(self,self.alwaysOnDiscreteSchedule) diffuser.setName("#{air_loop.name} Diffuser") air_loop.addBranchForZone(zone,diffuser.to_StraightComponent) end return air_loops end |
#add_data_center_load(space, dc_watts_per_area) ⇒ Bool
Adds a data center load to a given space.
1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 1863 def add_data_center_load(space, dc_watts_per_area) # Data center load data_center_definition = OpenStudio::Model::ElectricEquipmentDefinition.new(self) data_center_definition.setName('Data Center Load') data_center_definition.setWattsperSpaceFloorArea(dc_watts_per_area) data_center_equipment = OpenStudio::Model::ElectricEquipment.new(data_center_definition) data_center_equipment.setName('Data Center Load') data_center_sch = self.alwaysOnDiscreteSchedule data_center_equipment.setSchedule(data_center_sch) data_center_equipment.setSpace(space) return true end |
#add_daylighting_controls(building_vintage) ⇒ Object
Add the daylighting controls for lobby, cafe, dinning and banquet
194 195 196 197 198 199 200 |
# File 'lib/openstudio-standards/prototypes/Prototype.large_hotel.rb', line 194 def add_daylighting_controls(building_vintage) space_names = ['Banquet_Flr_6','Dining_Flr_6','Cafe_Flr_1','Lobby_Flr_1'] space_names.each do |space_name| space = self.getSpaceByName(space_name).get space.addDaylightingControls(building_vintage, false, false) end end |
#add_debugging_variables(type) ⇒ Object
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 1137 def add_debugging_variables(type) # 'detailed' # 'timestep' # 'hourly' # 'daily' # 'monthly' vars = [] case type when 'service_water_heating' var_names << ['Water Heater Water Volume Flow Rate','timestep'] var_names << ['Water Use Equipment Hot Water Volume Flow Rate','timestep'] var_names << ['Water Use Equipment Cold Water Volume Flow Rate','timestep'] var_names << ['Water Use Equipment Hot Water Temperature','timestep'] var_names << ['Water Use Equipment Cold Water Temperature','timestep'] var_names << ['Water Use Equipment Mains Water Volume','timestep'] var_names << ['Water Use Equipment Target Water Temperature','timestep'] var_names << ['Water Use Equipment Mixed Water Temperature','timestep'] var_names << ['Water Heater Tank Temperature','timestep'] var_names << ['Water Heater Use Side Mass Flow Rate','timestep'] var_names << ['Water Heater Heating Rate','timestep'] var_names << ['Water Heater Water Volume Flow Rate','timestep'] var_names << ['Water Heater Water Volume','timestep'] end var_names.each do |var_name, reporting_frequency| outputVariable = OpenStudio::Model::OutputVariable.new(var_name,self) outputVariable.setReportingFrequency(reporting_frequency) end end |
#add_design_days_and_weather_file(building_type, building_vintage, climate_zone) ⇒ Object
Helper method to set the weather file, import the design days, set water mains temperature, and set ground temperature. Based on ChangeBuildingLocation measure by Nicholas Long
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 |
# File 'lib/openstudio-standards/weather/Weather.Model.rb', line 8 def add_design_days_and_weather_file(building_type, building_vintage, climate_zone) require_relative 'Weather.stat_file' OpenStudio::logFree(OpenStudio::Info, 'openstudio.weather.Model', "Started adding weather file for climate zone: #{climate_zone}.") # Define the weather file for each climate zone climate_zone_weather_file_map = { 'ASHRAE 169-2006-1A' => 'USA_FL_Miami.Intl.AP.722020_TMY3.epw', 'ASHRAE 169-2006-1B' => 'SAU_Riyadh.404380_IWEC.epw', 'ASHRAE 169-2006-2A' => 'USA_TX_Houston-Bush.Intercontinental.AP.722430_TMY3.epw', 'ASHRAE 169-2006-2B' => 'USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw', 'ASHRAE 169-2006-3A' => 'USA_TN_Memphis.Intl.AP.723340_TMY3.epw', 'ASHRAE 169-2006-3B' => 'USA_TX_El.Paso.Intl.AP.722700_TMY3.epw', 'ASHRAE 169-2006-3C' => 'USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw', 'ASHRAE 169-2006-4A' => 'USA_MD_Baltimore-Washington.Intl.AP.724060_TMY3.epw', 'ASHRAE 169-2006-4B' => 'USA_NM_Albuquerque.Intl.AP.723650_TMY3.epw', 'ASHRAE 169-2006-4C' => 'USA_OR_Salem-McNary.Field.726940_TMY3.epw', 'ASHRAE 169-2006-5A' => 'USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw', 'ASHRAE 169-2006-5B' => 'USA_ID_Boise.Air.Terminal.726810_TMY3.epw', 'ASHRAE 169-2006-5C' => 'CAN_BC_Vancouver.718920_CWEC.epw', 'ASHRAE 169-2006-6A' => 'USA_VT_Burlington.Intl.AP.726170_TMY3.epw', 'ASHRAE 169-2006-6B' => 'USA_MT_Helena.Rgnl.AP.727720_TMY3.epw', 'ASHRAE 169-2006-7A' => 'USA_MN_Duluth.Intl.AP.727450_TMY3.epw', 'ASHRAE 169-2006-7B' => 'USA_MN_Duluth.Intl.AP.727450_TMY3.epw', 'ASHRAE 169-2006-8A' => 'USA_AK_Fairbanks.Intl.AP.702610_TMY3.epw', 'ASHRAE 169-2006-8B' => 'USA_AK_Fairbanks.Intl.AP.702610_TMY3.epw' } # Define where the weather files live top_dir = File.( '../../..',File.dirname(__FILE__)) weather_dir = "#{top_dir}/data/weather" # Get the weather file name from the hash weather_file_name = climate_zone_weather_file_map[climate_zone] if weather_file_name.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.weather.Model', "Could not determine the weather file for climate zone: #{climate_zone}.") return false end # Add Weather File unless (Pathname.new weather_dir).absolute? weather_dir = File.(File.join(File.dirname(__FILE__), weather_dir)) end weather_file = File.join(weather_dir, weather_file_name) epw_file = OpenStudio::EpwFile.new(weather_file) OpenStudio::Model::WeatherFile.setWeatherFile(self, epw_file).get weather_name = "#{epw_file.city}_#{epw_file.stateProvinceRegion}_#{epw_file.country}" weather_lat = epw_file.latitude weather_lon = epw_file.longitude weather_time = epw_file.timeZone weather_elev = epw_file.elevation # Add or update site data site = self.getSite site.setName(weather_name) site.setLatitude(weather_lat) site.setLongitude(weather_lon) site.setTimeZone(weather_time) site.setElevation(weather_elev) #Add or update ground temperature data ground_temp_vals = self.find_object($os_standards["ground_temperatures"], {'template'=>building_vintage, 'climate_zone'=>climate_zone, 'building_type'=>building_type}) if ground_temp_vals && ground_temp_vals['jan'] groundTemp = self.getSiteGroundTemperatureBuildingSurface groundTemp.setJanuaryGroundTemperature(ground_temp_vals['jan']) groundTemp.setFebruaryGroundTemperature(ground_temp_vals['feb']) groundTemp.setMarchGroundTemperature(ground_temp_vals['mar']) groundTemp.setAprilGroundTemperature(ground_temp_vals['apr']) groundTemp.setMayGroundTemperature(ground_temp_vals['may']) groundTemp.setJuneGroundTemperature(ground_temp_vals['jun']) groundTemp.setJulyGroundTemperature(ground_temp_vals['jul']) groundTemp.setAugustGroundTemperature(ground_temp_vals['aug']) groundTemp.setSeptemberGroundTemperature(ground_temp_vals['sep']) groundTemp.setOctoberGroundTemperature(ground_temp_vals['oct']) groundTemp.setNovemberGroundTemperature(ground_temp_vals['nov']) groundTemp.setDecemberGroundTemperature(ground_temp_vals['dec']) else OpenStudio::logFree(OpenStudio::Warn, 'openstudio.weather.Model', "Could not find ground temperatures; will use generic temperatures, which will skew results.") groundTemp = self.getSiteGroundTemperatureBuildingSurface groundTemp.setJanuaryGroundTemperature(19.527) groundTemp.setFebruaryGroundTemperature(19.502) groundTemp.setMarchGroundTemperature(19.536) groundTemp.setAprilGroundTemperature(19.598) groundTemp.setMayGroundTemperature(20.002) groundTemp.setJuneGroundTemperature(21.640) groundTemp.setJulyGroundTemperature(22.225) groundTemp.setAugustGroundTemperature(22.375) groundTemp.setSeptemberGroundTemperature(21.449) groundTemp.setOctoberGroundTemperature(20.121) groundTemp.setNovemberGroundTemperature(19.802) groundTemp.setDecemberGroundTemperature(19.633) end # Add SiteWaterMainsTemperature -- via parsing of STAT file. stat_filename = "#{File.join(File.dirname(weather_file), File.basename(weather_file, '.*'))}.stat" if File.exist? stat_filename stat_file = EnergyPlus::StatFile.new(stat_filename) water_temp = self.getSiteWaterMainsTemperature water_temp.setAnnualAverageOutdoorAirTemperature(stat_file.mean_dry_bulb) water_temp.setMaximumDifferenceInMonthlyAverageOutdoorAirTemperatures(stat_file.delta_dry_bulb) #OpenStudio::logFree(OpenStudio::Info, "openstudio.weather.Model", "Mean dry bulb is #{stat_file.mean_dry_bulb}") #OpenStudio::logFree(OpenStudio::Info, "openstudio.weather.Model", "Delta dry bulb is #{stat_file.delta_dry_bulb}") else OpenStudio::logFree(OpenStudio::Error, 'openstudio.weather.Model', "Could not find .stat file for: #{stat_filename}.") return false end # Remove any existing Design Day objects that are in the file self.getDesignDays.each { |d| d.remove } # Load in the ddy file based on convention that it is in # the same directory and has the same basename as the epw file. ddy_file = "#{File.join(File.dirname(weather_file), File.basename(weather_file, '.*'))}.ddy" if File.exist? ddy_file ddy_model = OpenStudio::EnergyPlus.loadAndTranslateIdf(ddy_file).get ddy_model.getObjectsByType('OS:SizingPeriod:DesignDay'.to_IddObjectType).each do |d| # Import the 99.6% Heating and 0.4% Cooling design days ddy_list = /(Htg 99.6. Condns DB)|(Clg .4% Condns DB=>MWB)/ if d.name.get =~ ddy_list self.addObject(d.clone) #OpenStudio::logFree(OpenStudio::Info, 'openstudio.weather.Model', "Added #{d.name} design day.") end end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.weather.Model', "Could not find .stat file for: #{stat_filename}.") return false end OpenStudio::logFree(OpenStudio::Info, 'openstudio.weather.Model', "Finished adding weather file for climate zone: #{climate_zone}.") return true end |
#add_doas(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_max_flow_rate, economizer_control_type, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a DOAS system with fan coil units for each zone.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open if nil, this value will be autosized. FixedDryBulb,
3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3816 def add_doas(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_max_flow_rate, economizer_control_type, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding DOAS system for #{thermal_zones.size} zones.") thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Debug, 'openstudio.Model.Model', "---#{zone.name}") end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # DOAS air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? air_loop.setName("#{thermal_zones.size} DOAS Air Loop HVAC") else air_loop.setName("DOAS Air Loop HVAC") end air_loop.setNightCycleControlType('CycleOnAny') # modify system sizing properties sizing_system = air_loop.sizingSystem # set central heating and cooling temperatures for sizing sizing_system.setCentralCoolingDesignSupplyAirTemperature(12.8) sizing_system.setCentralHeatingDesignSupplyAirTemperature(16.7) #ML OS default is 16.7 sizing_system.setSizingOption("Coincident") # load specification sizing_system.setSystemOutdoorAirMethod("ZoneSum") #ML OS default is ZoneSum sizing_system.setTypeofLoadtoSizeOn("Sensible") # DOAS sizing_system.setAllOutdoorAirinCooling(true) # DOAS sizing_system.setAllOutdoorAirinHeating(true) # DOAS sizing_system.setMinimumSystemAirFlowRatio(0.3) # No DCV # set availability schedule air_loop.setAvailabilitySchedule(hvac_op_sch) airloop_supply_inlet = air_loop.supplyInletNode # create air loop fan # constant speed fan fan = OpenStudio::Model::FanConstantVolume.new(self, self.alwaysOnDiscreteSchedule) fan.setName("DOAS fan") fan.setFanEfficiency(0.58175) fan.setPressureRise(622.5) #Pa if fan_max_flow_rate != nil fan.setMaximumFlowRate(fan_max_flow_rate) else fan.autosizeMaximumFlowRate end fan.setMotorEfficiency(0.895) fan.setMotorInAirstreamFraction(1.0) fan.setEndUseSubcategory("DOAS Fans") fan.addToNode(airloop_supply_inlet) # create heating coil # water coil heating_coil = OpenStudio::Model::CoilHeatingWater.new(self, self.alwaysOnDiscreteSchedule) hot_water_loop.addDemandBranchForComponent(heating_coil) heating_coil.controllerWaterCoil.get.setMinimumActuatedFlow(0) heating_coil.addToNode(airloop_supply_inlet) heating_coil.controllerWaterCoil.get.setControllerConvergenceTolerance(0.0001) # create cooling coil # water coil cooling_coil = OpenStudio::Model::CoilCoolingWater.new(self, self.alwaysOnDiscreteSchedule) chilled_water_loop.addDemandBranchForComponent(cooling_coil) cooling_coil.controllerWaterCoil.get.setMinimumActuatedFlow(0) cooling_coil.addToNode(airloop_supply_inlet) # create controller outdoor air controller_OA = OpenStudio::Model::ControllerOutdoorAir.new(self) controller_OA.setName("DOAS OA Controller") controller_OA.setEconomizerControlType(economizer_control_type) controller_OA.setMinimumLimitType('FixedMinimum') controller_OA.setMinimumOutdoorAirSchedule(oa_damper_sch) controller_OA.resetEconomizerMaximumLimitDryBulbTemperature # TODO: Yixing read the schedule from the Prototype Input if building_type == "LargeHotel" controller_OA.setMinimumFractionofOutdoorAirSchedule(self.add_schedule("HotelLarge FLR_3_DOAS_OAminOAFracSchedule")) end controller_OA.resetEconomizerMaximumLimitEnthalpy controller_OA.resetMaximumFractionofOutdoorAirSchedule controller_OA.resetEconomizerMinimumLimitDryBulbTemperature # create ventilation schedules and assign to OA controller controller_OA.setHeatRecoveryBypassControlType("BypassWhenWithinEconomizerLimits") # create outdoor air system system_OA = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self, controller_OA) system_OA.addToNode(airloop_supply_inlet) # create scheduled setpoint manager for airloop # DOAS or VAV for cooling and not ventilation setpoint_manager = OpenStudio::Model::SetpointManagerOutdoorAirReset.new(self) setpoint_manager.setControlVariable('Temperature') setpoint_manager.setSetpointatOutdoorLowTemperature(15.5) setpoint_manager.setOutdoorLowTemperature(15.5) setpoint_manager.setSetpointatOutdoorHighTemperature(12.8) setpoint_manager.setOutdoorHighTemperature(21) # connect components to airloop # find the supply inlet node of the airloop # add setpoint manager to supply equipment outlet node setpoint_manager.addToNode(air_loop.supplyOutletNode) # add thermal zones to airloop thermal_zones.each do |zone| zone_name = zone.name.to_s zone_sizing = zone.sizingZone zone_sizing.setZoneCoolingDesignSupplyAirTemperature(12.8) zone_sizing.setZoneHeatingDesignSupplyAirTemperature(40) zone_sizing.setCoolingDesignAirFlowMethod("DesignDayWithLimit") zone_sizing.setHeatingDesignAirFlowMethod("DesignDay") # make an air terminal for the zone air_terminal = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(self, self.alwaysOnDiscreteSchedule) air_terminal.setName(zone_name + "Air Terminal") fan_coil_cooling_coil = OpenStudio::Model::CoilCoolingWater.new(self, self.alwaysOnDiscreteSchedule) fan_coil_cooling_coil.setName(zone_name + "FCU Cooling Coil") chilled_water_loop.addDemandBranchForComponent(fan_coil_cooling_coil) fan_coil_cooling_coil.controllerWaterCoil.get.setMinimumActuatedFlow(0) fan_coil_heating_coil = OpenStudio::Model::CoilHeatingWater.new(self, self.alwaysOnDiscreteSchedule) fan_coil_heating_coil.setName(zone_name + "FCU Heating Coil") hot_water_loop.addDemandBranchForComponent(fan_coil_heating_coil) fan_coil_heating_coil.controllerWaterCoil.get.setMinimumActuatedFlow(0) fan_coil_fan = OpenStudio::Model::FanOnOff.new(self, self.alwaysOnDiscreteSchedule) fan_coil_fan.setName(zone_name + " Fan Coil fan") fan_coil_fan.setFanEfficiency(0.16) fan_coil_fan.setPressureRise(270.9) #Pa fan_coil_fan.autosizeMaximumFlowRate fan_coil_fan.setMotorEfficiency(0.29) fan_coil_fan.setMotorInAirstreamFraction(1.0) fan_coil_fan.setEndUseSubcategory("FCU Fans") fan_coil = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(self, self.alwaysOnDiscreteSchedule, fan_coil_fan, fan_coil_cooling_coil, fan_coil_heating_coil) fan_coil.setName(zone_name + "FCU") fan_coil.setCapacityControlMethod("CyclingFan") fan_coil.autosizeMaximumSupplyAirFlowRate fan_coil.setMaximumOutdoorAirFlowRate(0) fan_coil.addToThermalZone(zone) # attach new terminal to the zone and to the airloop air_loop.addBranchForZone(zone, air_terminal.to_StraightComponent) end return air_loop end |
#add_door_infiltration(building_vintage, climate_zone) ⇒ Object
add extra infiltration for ground floor corridor
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/openstudio-standards/prototypes/Prototype.full_service_restaurant.rb', line 469 def add_door_infiltration(building_vintage,climate_zone) # add extra infiltration for dining room door and attic (there is no attic in 'DOE Ref Pre-1980') unless building_vintage == 'DOE Ref 1980-2004' or building_vintage == 'DOE Ref Pre-1980' dining_space = self.getSpaceByName('Dining').get attic_space = self.getSpaceByName('Attic').get infiltration_diningdoor = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self) infiltration_attic = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self) infiltration_diningdoor.setName("Dining door Infiltration") infiltration_per_zone_diningdoor = 0 infiltration_per_zone_attic = 0.0729 if building_vintage == '90.1-2004' infiltration_per_zone_diningdoor = 0.902834611 infiltration_diningdoor.setSchedule(add_schedule('RestaurantFastFood DOOR_INFIL_SCH')) elsif building_vintage == '90.1-2007' case climate_zone when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-3A', 'ASHRAE 169-2006-3B', 'ASHRAE 169-2006-3C', 'ASHRAE 169-2006-4A', 'ASHRAE 169-2006-4B', 'ASHRAE 169-2006-4C' infiltration_per_zone_diningdoor = 0.902834611 infiltration_diningdoor.setSchedule(add_schedule('RestaurantFastFood DOOR_INFIL_SCH')) else infiltration_per_zone_diningdoor = 0.583798439 infiltration_diningdoor.setSchedule(add_schedule('RestaurantFastFood VESTIBULE_DOOR_INFIL_SCH')) end elsif building_vintage == '90.1-2010' or '90.1-2013' case climate_zone when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-3A', 'ASHRAE 169-2006-3B', 'ASHRAE 169-2006-3C' infiltration_per_zone_diningdoor = 0.902834611 infiltration_diningdoor.setSchedule(add_schedule('RestaurantFastFood DOOR_INFIL_SCH')) else infiltration_per_zone_diningdoor = 0.583798439 infiltration_diningdoor.setSchedule(add_schedule('RestaurantFastFood VESTIBULE_DOOR_INFIL_SCH')) end end infiltration_diningdoor.setDesignFlowRate(infiltration_per_zone_diningdoor) infiltration_diningdoor.setSpace(dining_space) infiltration_attic.setDesignFlowRate(infiltration_per_zone_attic) infiltration_attic.setSchedule(add_schedule('Always On')) infiltration_attic.setSpace(attic_space) end end |
#add_elevator(standard, space, number_of_elevators, elevator_type, elevator_schedule, elevator_fan_schedule, elevator_lights_schedule, building_type = nil) ⇒ OpenStudio::Model::ElectricEquipment
Add an elevator the the specified space
DOE Ref Pre-1980, DOE Ref 1980-2004, 90.1-2004, 90.1-2007, 90.1-2010, 90.1-2013, to assign the elevators to. Traction, Hydraulic
4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 4003 def add_elevator(standard, space, number_of_elevators, elevator_type, elevator_schedule, elevator_fan_schedule, elevator_lights_schedule, building_type=nil) # Lift motor assumptions lift_pwr_w = nil case standard when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' if elevator_type == 'Traction' lift_pwr_w = 18537.0 elsif elevator_type == 'Hydraulic' if building_type == 'MidriseApartment' lift_pwr_w = 16055.0 else lift_pwr_w = 14610.0 end else lift_pwr_w = 14610.0 OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "Elevator type '#{elevator_type}', not recognized, will assume Hydraulic elevator, #{lift_pwr_w} W.") end when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' if elevator_type == 'Traction' lift_pwr_w = 20370.0 elsif elevator_type == 'Hydraulic' lift_pwr_w = 16055.0 else lift_pwr_w = 16055.0 OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "Elevator type '#{elevator_type}', not recognized, will assume Hydraulic elevator, #{lift_pwr_w} W.") end end # Size assumptions length_ft = 6.66 width_ft = 4.25 height_ft = 8.0 area_ft2 = length_ft * width_ft volume_ft3 = area_ft2 * height_ft # Ventilation assumptions vent_rate_acm = 1 # air changes per minute vent_rate_cfm = volume_ft3 / vent_rate_acm vent_pwr_per_flow_w_per_cfm = 0.33 vent_pwr_w = vent_pwr_per_flow_w_per_cfm * vent_rate_cfm # Lighting assumptions design_ltg_lm_per_ft2 = 30 light_loss_factor = 0.75 pct_incandescent = 0.7 pct_led = 0.3 incandescent_efficacy_lm_per_w = 10.0 led_efficacy_lm_per_w = 35.0 target_ltg_lm_per_ft2 = design_ltg_lm_per_ft2 / light_loss_factor #40 target_ltg_lm = target_ltg_lm_per_ft2 * area_ft2 #1132.2 lm_incandescent = target_ltg_lm * pct_incandescent #792.54 lm_led = target_ltg_lm * pct_led #339.66 w_incandescent = lm_incandescent / incandescent_efficacy_lm_per_w #79.254 w_led = lm_led / led_efficacy_lm_per_w #9.7 lighting_pwr_w = w_incandescent + w_led # Elevator lift motor elevator_definition = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elevator_definition.setName('Elevator Lift Motor') elevator_definition.setDesignLevel(lift_pwr_w) elevator_equipment = OpenStudio::Model::ElectricEquipment.new(elevator_definition) elevator_equipment.setName("#{number_of_elevators.round} Elevator Lift Motors") elevator_sch = self.add_schedule(elevator_schedule) elevator_equipment.setSchedule(elevator_sch) elevator_equipment.setSpace(space) elevator_equipment.setMultiplier(number_of_elevators) # Pre-1980 and 1980-2004 don't have lights or fans return elevator_equipment if standard == 'DOE Ref Pre-1980' || standard == 'DOE Ref 1980-2004' # Elevator fan elevator_fan_definition = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elevator_fan_definition.setName('Elevator Fan') elevator_fan_definition.setDesignLevel(vent_pwr_w) elevator_fan_equipment = OpenStudio::Model::ElectricEquipment.new(elevator_fan_definition) elevator_fan_equipment.setName("#{number_of_elevators.round} Elevator Fans") elevator_fan_sch = self.add_schedule(elevator_fan_schedule) elevator_fan_equipment.setSchedule(elevator_fan_sch) elevator_fan_equipment.setSpace(space) elevator_fan_equipment.setMultiplier(number_of_elevators) # Elevator lights elevator_lights_definition = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elevator_lights_definition.setName('Elevator Lights') elevator_lights_definition.setDesignLevel(lighting_pwr_w) elevator_lights_equipment = OpenStudio::Model::ElectricEquipment.new(elevator_lights_definition) elevator_lights_equipment.setName("#{number_of_elevators.round} Elevator Lights") elevator_lights_sch = self.add_schedule(elevator_lights_schedule) elevator_lights_equipment.setSchedule(elevator_lights_sch) elevator_lights_equipment.setSpace(space) elevator_lights_equipment.setMultiplier(number_of_elevators) return elevator_equipment end |
#add_exhaust_fan(availability_sch_name, flow_rate, flow_fraction_schedule_name, balanced_exhaust_fraction_schedule_name, thermal_zones) ⇒ Array<OpenStudio::Model::FanZoneExhaust>
Adds an exhaust fan to each zone.
of the balanced exhaust fraction schedule.
4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 4118 def add_exhaust_fan(availability_sch_name, flow_rate, flow_fraction_schedule_name, balanced_exhaust_fraction_schedule_name, thermal_zones) # Make an exhaust fan for each zone fans = [] thermal_zones.each do |zone| fan = OpenStudio::Model::FanZoneExhaust.new(self) fan.setName("#{zone.name} Exhaust Fan") fan.setAvailabilitySchedule(self.add_schedule(availability_sch_name)) fan.setMaximumFlowRate(flow_rate) unless flow_fraction_schedule_name.nil? fan.setFlowFractionSchedule(self.add_schedule(flow_fraction_schedule_name)) end fan.setSystemAvailabilityManagerCouplingMode('Decoupled') unless balanced_exhaust_fraction_schedule_name.nil? fan.setBalancedExhaustFractionSchedule(self.add_schedule(balanced_exhaust_fraction_schedule_name)) end fan.addToThermalZone(zone) fans << fan end return fans end |
#add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input) ⇒ Bool
translate w/linear foot of facade, door, parking, etc into lookup table and implement that way instead of hard-coding as inputs in the spreadsheet.
Adds exterior lights to the building, as specified in OpenStudio_Standards_prototype_inputs
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 875 def add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input) # TODO Standards - translate w/linear foot of facade, door, parking, etc # into lookup table and implement that way instead of hard-coding as # inputs in the spreadsheet. OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding exterior lights') # Occupancy Sensing Exterior Lights # which reduce to 70% power when no one is around. unless prototype_input['occ_sensing_exterior_lighting_power'].nil? occ_sens_ext_lts_power = prototype_input['occ_sensing_exterior_lighting_power'] occ_sens_ext_lts_sch_name = prototype_input['occ_sensing_exterior_lighting_schedule'] occ_sens_ext_lts_name = 'Occ Sensing Exterior Lights' occ_sens_ext_lts_def = OpenStudio::Model::ExteriorLightsDefinition.new(self) occ_sens_ext_lts_def.setName("#{occ_sens_ext_lts_name} Def") occ_sens_ext_lts_def.setDesignLevel(occ_sens_ext_lts_power) occ_sens_ext_lts_sch = self.add_schedule(occ_sens_ext_lts_sch_name) occ_sens_ext_lts = OpenStudio::Model::ExteriorLights.new(occ_sens_ext_lts_def, occ_sens_ext_lts_sch) occ_sens_ext_lts.setName("#{occ_sens_ext_lts_name} Def") occ_sens_ext_lts.setControlOption('AstronomicalClock') end # Building Facade and Landscape Lights # that don't dim at all at night. unless prototype_input['nondimming_exterior_lighting_power'].nil? nondimming_ext_lts_power = prototype_input['nondimming_exterior_lighting_power'] nondimming_ext_lts_sch_name = prototype_input['nondimming_exterior_lighting_schedule'] nondimming_ext_lts_name = 'NonDimming Exterior Lights' nondimming_ext_lts_def = OpenStudio::Model::ExteriorLightsDefinition.new(self) nondimming_ext_lts_def.setName("#{nondimming_ext_lts_name} Def") nondimming_ext_lts_def.setDesignLevel(nondimming_ext_lts_power) nondimming_ext_lts_sch = self.add_schedule(nondimming_ext_lts_sch_name) nondimming_ext_lts = OpenStudio::Model::ExteriorLights.new(nondimming_ext_lts_def, nondimming_ext_lts_sch) nondimming_ext_lts.setName("#{nondimming_ext_lts_name} Def") nondimming_ext_lts.setControlOption('AstronomicalClock') end # Fuel Equipment, As Exterior:FuelEquipment is not supported by OpenStudio yet, # temporarily use Exterior:Lights and set the control option to ScheduleNameOnly # todo: change it to Exterior:FuelEquipment when OpenStudio supported it. unless prototype_input['exterior_fuel_equipment1_power'].nil? fuel_ext_power = prototype_input['exterior_fuel_equipment1_power'] fuel_ext_sch_name = prototype_input['exterior_fuel_equipment1_schedule'] fuel_ext_name = 'Fuel equipment 1' fuel_ext_def = OpenStudio::Model::ExteriorLightsDefinition.new(self) fuel_ext_def.setName("#{fuel_ext_name} Def") fuel_ext_def.setDesignLevel(fuel_ext_power) fuel_ext_sch = self.add_schedule(fuel_ext_sch_name) fuel_ext_lts = OpenStudio::Model::ExteriorLights.new(fuel_ext_def, fuel_ext_sch) fuel_ext_lts.setName("#{fuel_ext_name}") fuel_ext_lts.setControlOption('ScheduleNameOnly') end unless prototype_input['exterior_fuel_equipment2_power'].nil? fuel_ext_power = prototype_input['exterior_fuel_equipment2_power'] fuel_ext_sch_name = prototype_input['exterior_fuel_equipment2_schedule'] fuel_ext_name = 'Fuel equipment 2' fuel_ext_def = OpenStudio::Model::ExteriorLightsDefinition.new(self) fuel_ext_def.setName("#{fuel_ext_name} Def") fuel_ext_def.setDesignLevel(fuel_ext_power) fuel_ext_sch = self.add_schedule(fuel_ext_sch_name) fuel_ext_lts = OpenStudio::Model::ExteriorLights.new(fuel_ext_def, fuel_ext_sch) fuel_ext_lts.setName("#{fuel_ext_name}") fuel_ext_lts.setControlOption('ScheduleNameOnly') end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding exterior lights') return true end |
#add_extra_equip_corridor(building_vintage) ⇒ Object
add elevator and lights&fans for the ground floor corridor
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb', line 281 def add_extra_equip_corridor(building_vintage) corridor_top_space = self.getSpaceByName('T Corridor').get elec_equip_def1 = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elec_equip_def2 = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elec_equip_def1.setName("T Corridor Electric Equipment Definition1") elec_equip_def2.setName("T Corridor Electric Equipment Definition2") elec_equip_def1.setFractionLatent(0) elec_equip_def1.setFractionRadiant(0) elec_equip_def1.setFractionLost(0.95) elec_equip_def2.setFractionLatent(0) elec_equip_def2.setFractionRadiant(0) elec_equip_def2.setFractionLost(0.95) elec_equip_def1.setDesignLevel(20370) case building_vintage when '90.1-2013' elec_equip_def2.setDesignLevel(63) when '90.1-2010' elec_equip_def2.setDesignLevel(105.9) when '90.1-2004', '90.1-2007' elec_equip_def2.setDesignLevel(161.9) end # Create the electric equipment instance and hook it up to the space type elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1) elec_equip2 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def2) elec_equip1.setName("T Corridor_Elevators_Equip") elec_equip2.setName("Elevators_Lights_Fan") elec_equip1.setSpace(corridor_top_space) elec_equip2.setSpace(corridor_top_space) elec_equip1.setSchedule(add_schedule("ApartmentMidRise BLDG_ELEVATORS")) case building_vintage when '90.1-2004', '90.1-2007' elec_equip2.setSchedule(add_schedule("ApartmentMidRise ELEV_LIGHT_FAN_SCH_24_7")) when '90.1-2010', '90.1-2013' elec_equip2.setSchedule(add_schedule("ApartmentMidRise ELEV_LIGHT_FAN_SCH_ADD_DF")) end end |
#add_extra_equip_elevator_pump_room(building_vintage) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/openstudio-standards/prototypes/Prototype.outpatient.rb', line 165 def add_extra_equip_elevator_pump_room(building_vintage) elevator_pump_room = self.getSpaceByName('Floor 1 Elevator Pump Room').get elec_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elec_equip_def.setName("Elevator Pump Room Electric Equipment Definition") elec_equip_def.setFractionLatent(0) elec_equip_def.setFractionRadiant(0.1) elec_equip_def.setFractionLost(0.9) elec_equip_def.setDesignLevel(48165) elec_equip = OpenStudio::Model::ElectricEquipment.new(elec_equip_def) elec_equip.setName("Elevator Pump Room Elevator Equipment") elec_equip.setSpace(elevator_pump_room) case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' elec_equip.setSchedule(add_schedule("OutPatientHealthCare BLDG_ELEVATORS")) when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' elec_equip.setSchedule(add_schedule("OutPatientHealthCare BLDG_ELEVATORS_Pre2004")) end end |
#add_extra_equip_kitchen(building_vintage) ⇒ Object
add extra equipment for kitchen
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 372 def add_extra_equip_kitchen(building_vintage) kitchen_space = self.getSpaceByName('Kitchen') kitchen_space = kitchen_space.get kitchen_space_type = kitchen_space.spaceType.get elec_equip_def1 = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elec_equip_def2 = OpenStudio::Model::ElectricEquipmentDefinition.new(self) elec_equip_def1.setName("Kitchen Electric Equipment Definition1") elec_equip_def2.setName("Kitchen Electric Equipment Definition2") case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' elec_equip_def1.setFractionLatent(0) elec_equip_def1.setFractionRadiant(0.25) elec_equip_def1.setFractionLost(0) elec_equip_def2.setFractionLatent(0) elec_equip_def2.setFractionRadiant(0.25) elec_equip_def2.setFractionLost(0) if building_vintage == '90.1-2013' elec_equip_def1.setDesignLevel(457.5) elec_equip_def2.setDesignLevel(570) else elec_equip_def1.setDesignLevel(515.917) elec_equip_def2.setDesignLevel(851.67) end # Create the electric equipment instance and hook it up to the space type elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1) elec_equip2 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def2) elec_equip1.setName("Kitchen_Reach-in-Freezer") elec_equip2.setName("Kitchen_Reach-in-Refrigerator") elec_equip1.setSpaceType(kitchen_space_type) elec_equip2.setSpaceType(kitchen_space_type) elec_equip1.setSchedule(add_schedule("RestaurantFastFood ALWAYS_ON")) elec_equip2.setSchedule(add_schedule("RestaurantFastFood ALWAYS_ON")) when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' elec_equip_def1.setDesignLevel(577) elec_equip_def1.setFractionLatent(0) elec_equip_def1.setFractionRadiant(0) elec_equip_def1.setFractionLost(1) # Create the electric equipment instance and hook it up to the space type elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1) elec_equip1.setName("Kitchen_ExhFan_Equip") elec_equip1.setSpaceType(kitchen_space_type) elec_equip1.setSchedule(add_schedule("RestaurantFastFood Kitchen_Exhaust_SCH")) end end |
#add_high_temp_radiant(standard, sys_name, thermal_zones, heating_type, combustion_efficiency, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACHighTemperatureRadiant>
Creates a high temp radiant heater for each zone and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 Gas, Electric
array of the resulting radiant heaters.
3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3162 def add_high_temp_radiant(standard, sys_name, thermal_zones, heating_type, combustion_efficiency, building_type=nil) # Make a high temp radiant heater for each zone rad_heaters = [] thermal_zones.each do |zone| high_temp_radiant = OpenStudio::Model::ZoneHVACHighTemperatureRadiant.new(self) high_temp_radiant.setName("#{zone.name} High Temp Radiant") high_temp_radiant.setFuelType(heating_type) high_temp_radiant.setCombustionEfficiency(combustion_efficiency) high_temp_radiant.setTemperatureControlType(control_type) high_temp_radiant.setFractionofInputConvertedtoRadiantEnergy(0.8) high_temp_radiant.setHeatingThrottlingRange(2) high_temp_radiant.addToThermalZone(zone) rad_heaters << high_temp_radiant end return rad_heaters end |
#add_hp_loop(building_type = nil) ⇒ OpenStudio::Model::PlantLoop
replace cooling tower with fluid cooler once added to OS 1.9.0
Creates a heat pump loop which has a boiler and fluid cooler
for supplemental heating/cooling and adds it to the model.
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 345 def add_hp_loop(building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding heat pump loop.") # Heat Pump loop heat_pump_water_loop = OpenStudio::Model::PlantLoop.new(self) heat_pump_water_loop.setName('Heat Pump Loop') heat_pump_water_loop.setMaximumLoopTemperature(80) heat_pump_water_loop.setMinimumLoopTemperature(5) # Heat Pump loop controls hp_high_temp_f = 65 # Supplemental heat below 65F hp_low_temp_f = 41 # Supplemental cooling below 41F hp_temp_sizing_f = 102.2 #CW sized to deliver 102.2F hp_delta_t_r = 19.8 #19.8F delta-T boiler_hw_temp_f = 86 #Boiler makes 86F water hp_high_temp_c = OpenStudio.convert(hp_high_temp_f,'F','C').get hp_low_temp_c = OpenStudio.convert(hp_low_temp_f,'F','C').get hp_temp_sizing_c = OpenStudio.convert(hp_temp_sizing_f,'F','C').get hp_delta_t_k = OpenStudio.convert(hp_delta_t_r,'R','K').get boiler_hw_temp_c = OpenStudio.convert(boiler_hw_temp_f,'F','C').get hp_high_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) hp_high_temp_sch.setName("Heat Pump Loop High Temp - #{hp_high_temp_f}F") hp_high_temp_sch.defaultDaySchedule.setName("Heat Pump Loop High Temp - #{hp_high_temp_f}F Default") hp_high_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),hp_high_temp_c) hp_low_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) hp_low_temp_sch.setName("Heat Pump Loop Low Temp - #{hp_low_temp_f}F") hp_low_temp_sch.defaultDaySchedule.setName("Heat Pump Loop Low Temp - #{hp_low_temp_f}F Default") hp_low_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),hp_low_temp_c) hp_stpt_manager = OpenStudio::Model::SetpointManagerScheduledDualSetpoint.new(self) hp_stpt_manager.setHighSetpointSchedule(hp_high_temp_sch) hp_stpt_manager.setLowSetpointSchedule(hp_low_temp_sch) hp_stpt_manager.addToNode(heat_pump_water_loop.supplyOutletNode) sizing_plant = heat_pump_water_loop.sizingPlant sizing_plant.setLoopType('Heating') sizing_plant.setDesignLoopExitTemperature(hp_temp_sizing_c) sizing_plant.setLoopDesignTemperatureDifference(hp_delta_t_k) # Heat Pump loop pump hp_pump = OpenStudio::Model::PumpConstantSpeed.new(self) hp_pump.setName('Heat Pump Loop Pump') hp_pump_head_ft_h2o = 60 hp_pump_head_press_pa = OpenStudio.convert(hp_pump_head_ft_h2o, 'ftH_{2}O','Pa').get hp_pump.setRatedPumpHead(hp_pump_head_press_pa) hp_pump.setPumpControlType('Intermittent') hp_pump.addToNode(heat_pump_water_loop.supplyInletNode) # Cooling towers if building_type == 'LargeOffice' # TODO: For some reason the FluidCoolorTwoSpeed is causing simulation failures. # might need to look into the defaults # cooling_tower = OpenStudio::Model::FluidCoolerTwoSpeed.new(self) cooling_tower = OpenStudio::Model::CoolingTowerTwoSpeed.new(self) cooling_tower.setName("#{heat_pump_water_loop.name} Central Tower") heat_pump_water_loop.addSupplyBranchForComponent(cooling_tower) #### Add SPM Scheduled Dual Setpoint to outlet of Fluid Cooler so correct Plant Operation Scheme is generated hp_stpt_manager_2 = OpenStudio::Model::SetpointManagerScheduledDualSetpoint.new(self) hp_stpt_manager_2.setHighSetpointSchedule(hp_high_temp_sch) hp_stpt_manager_2.setLowSetpointSchedule(hp_low_temp_sch) hp_stpt_manager_2.addToNode(cooling_tower.outletModelObject.get.to_Node.get) else # TODO replace with FluidCooler:TwoSpeed when available # cooling_tower = OpenStudio::Model::CoolingTowerTwoSpeed.new(self) # cooling_tower.setName("#{heat_pump_water_loop.name} Sup Cooling Tower") # heat_pump_water_loop.addSupplyBranchForComponent(cooling_tower) fluid_cooler = OpenStudio::Model::EvaporativeFluidCoolerSingleSpeed.new(self) fluid_cooler.setName("#{heat_pump_water_loop.name} Sup Cooling Tower") fluid_cooler.setDesignSprayWaterFlowRate(0.002208) # Based on HighRiseApartment fluid_cooler.setPerformanceInputMethod("UFactorTimesAreaAndDesignWaterFlowRate") heat_pump_water_loop.addSupplyBranchForComponent(fluid_cooler) end # Boiler boiler = OpenStudio::Model::BoilerHotWater.new(self) boiler.setName("#{heat_pump_water_loop.name} Sup Boiler") boiler.setFuelType('Gas') boiler.setDesignWaterOutletTemperature(boiler_hw_temp_c) boiler.setMinimumPartLoadRatio(0) boiler.setMaximumPartLoadRatio(1.2) boiler.setOptimumPartLoadRatio(1) boiler.setBoilerFlowMode('ConstantFlow') heat_pump_water_loop.addSupplyBranchForComponent(boiler) #### Add SPM Scheduled Dual Setpoint to outlet of Boiler so correct Plant Operation Scheme is generated hp_stpt_manager_3 = OpenStudio::Model::SetpointManagerScheduledDualSetpoint.new(self) hp_stpt_manager_3.setHighSetpointSchedule(hp_high_temp_sch) hp_stpt_manager_3.setLowSetpointSchedule(hp_low_temp_sch) hp_stpt_manager_3.addToNode(boiler.outletModelObject.get.to_Node.get) # Heat Pump water loop pipes supply_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_bypass_pipe.setName("#{heat_pump_water_loop.name} Supply Bypass") heat_pump_water_loop.addSupplyBranchForComponent(supply_bypass_pipe) demand_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_bypass_pipe.setName("#{heat_pump_water_loop.name} Demand Bypass") heat_pump_water_loop.addDemandBranchForComponent(demand_bypass_pipe) supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_outlet_pipe.setName("#{heat_pump_water_loop.name} Supply Outlet") supply_outlet_pipe.addToNode(heat_pump_water_loop.supplyOutletNode) demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_inlet_pipe.setName("#{heat_pump_water_loop.name} Demand Inlet") demand_inlet_pipe.addToNode(heat_pump_water_loop.demandInletNode) demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_outlet_pipe.setName("#{heat_pump_water_loop.name} Demand Outlet") demand_outlet_pipe.addToNode(heat_pump_water_loop.demandOutletNode) return heat_pump_water_loop end |
#add_hvac(building_type, building_vintage, climate_zone, prototype_input) ⇒ Object
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 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb', line 5 def add_hvac(building_type, building_vintage, climate_zone, prototype_input) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding HVAC') # Get the list of HVAC systems, as defined # for each building in the Prototype.building_name files. system_to_space_map = define_hvac_system_map(building_type, building_vintage, climate_zone) # Add each HVAC system system_to_space_map.each do |system| thermal_zones = get_zones_from_spaces_on_system(system) return_plenum = get_return_plenum_from_system(system) # Add the HVAC systems case system['type'] when 'VAV' # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Retrieve the existing chilled water loop # or add a new one if necessary. chilled_water_loop = nil if self.getPlantLoopByName('Chilled Water Loop').is_initialized chilled_water_loop = self.getPlantLoopByName('Chilled Water Loop').get else condenser_water_loop = nil if prototype_input['chiller_condenser_type'] == 'WaterCooled' condenser_water_loop = self.add_cw_loop() end chilled_water_loop = self.add_chw_loop(building_vintage, prototype_input['chw_pumping_type'], prototype_input['chiller_cooling_type'], prototype_input['chiller_condenser_type'], prototype_input['chiller_compressor_type'], prototype_input['chiller_capacity_guess'], condenser_water_loop) end # Add the VAV self.add_vav_reheat(building_vintage, system['name'], hot_water_loop, chilled_water_loop, thermal_zones, prototype_input['vav_operation_schedule'], prototype_input['vav_oa_damper_schedule'], prototype_input['vav_fan_efficiency'], prototype_input['vav_fan_motor_efficiency'], prototype_input['vav_fan_pressure_rise'], return_plenum, building_type) when 'CAV' # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Add the CAV self.add_cav(building_vintage, system['name'], hot_water_loop, thermal_zones, prototype_input['vav_operation_schedule'], prototype_input['vav_oa_damper_schedule'], prototype_input['vav_fan_efficiency'], prototype_input['vav_fan_motor_efficiency'], prototype_input['vav_fan_pressure_rise'], building_type) when 'PSZ-AC' # Special logic to differentiate between operation schedules # that vary even inside of a system type for stripmall. hvac_op_sch = nil oa_sch = nil if system['hvac_op_sch_index'].nil? || system['hvac_op_sch_index'] == 1 hvac_op_sch = prototype_input['pszac_operation_schedule'] oa_sch = prototype_input['pszac_oa_damper_schedule'] elsif system['hvac_op_sch_index'] == 2 hvac_op_sch = prototype_input['pszac_operation_schedule_2'] oa_sch = prototype_input['pszac_oa_damper_schedule_2'] elsif system['hvac_op_sch_index'] == 3 hvac_op_sch = prototype_input['pszac_operation_schedule_3'] oa_sch = prototype_input['pszac_oa_damper_schedule_3'] end # Special logic to make unitary heat pumps all blow-through fan_position = 'DrawThrough' if prototype_input['pszac_heating_type'] == 'Single Speed Heat Pump' || prototype_input['pszac_heating_type'] == 'Water To Air Heat Pump' fan_position = 'BlowThrough' end # Special logic to make a heat pump loop if necessary heat_pump_loop = nil if prototype_input['pszac_heating_type'] == 'Water To Air Heat Pump' heat_pump_loop = add_hp_loop(prototype_input) end self.add_psz_ac(building_vintage, system['name'], heat_pump_loop, # Typically nil unless water source hp heat_pump_loop, # Typically nil unless water source hp thermal_zones, hvac_op_sch, oa_sch, fan_position, prototype_input['pszac_fan_type'], prototype_input['pszac_heating_type'], prototype_input['pszac_supplemental_heating_type'], prototype_input['pszac_cooling_type'], building_type) when 'PVAV' # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end self.add_pvav(building_vintage, system['name'], thermal_zones, prototype_input['vav_operation_schedule'], prototype_input['vav_oa_damper_schedule'], hot_water_loop, return_plenum) when 'DOAS' # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Retrieve the existing chilled water loop # or add a new one if necessary. chilled_water_loop = nil if self.getPlantLoopByName('Chilled Water Loop').is_initialized chilled_water_loop = self.getPlantLoopByName('Chilled Water Loop').get else condenser_water_loop = nil if prototype_input['chiller_condenser_type'] == 'WaterCooled' condenser_water_loop = self.add_cw_loop() end chilled_water_loop = self.add_chw_loop(building_vintage, prototype_input['chw_pumping_type'], prototype_input['chiller_cooling_type'], prototype_input['chiller_condenser_type'], prototype_input['chiller_compressor_type'], prototype_input['chiller_capacity_guess'], condenser_water_loop) end self.add_doas(building_vintage, system['name'], hot_water_loop, chilled_water_loop, thermal_zones, prototype_input['vav_operation_schedule'], prototype_input['doas_oa_damper_schedule'], prototype_input['doas_fan_maximum_flow_rate'], prototype_input['doas_economizer_control_type'], building_type) when 'DC' # Data Center # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Retrieve the existing heat pump loop # or add a new one if necessary. heat_pump_loop = nil if self.getPlantLoopByName('Heat Pump Loop').is_initialized heat_pump_loop = self.getPlantLoopByName('Heat Pump Loop').get else heat_pump_loop = self.add_hp_loop() end self.add_data_center_hvac(building_vintage, nil, hot_water_loop, heat_pump_loop, thermal_zones, prototype_input['flow_fraction_schedule_name'], prototype_input['flow_fraction_schedule_name'], system['main_data_center']) when 'SAC' self.add_split_AC(building_vintage, nil, thermal_zones, prototype_input['sac_operation_schedule'], prototype_input['sac_operation_schedule_meeting'], prototype_input['sac_oa_damper_schedule'], prototype_input['sac_fan_type'], prototype_input['sac_heating_type'], prototype_input['sac_heating_type'], prototype_input['sac_cooling_type'], building_type) when 'UnitHeater' self.add_unitheater(building_vintage, nil, thermal_zones, prototype_input['unitheater_operation_schedule'], prototype_input['unitheater_fan_control_type'], prototype_input['unitheater_fan_static_pressure'], prototype_input['unitheater_heating_type'], building_type) when 'PTAC' self.add_ptac(building_vintage, nil, nil, thermal_zones, prototype_input['ptac_fan_type'], prototype_input['ptac_heating_type'], prototype_input['ptac_cooling_type'], building_type) when 'Exhaust Fan' self.add_exhaust_fan(system['availability_sch_name'], system['flow_rate'], system['flow_fraction_schedule_name'], system['balanced_exhaust_fraction_schedule_name'], thermal_zones) when 'Refrigeration' self.add_refrigeration(building_vintage, system['case_type'], system['cooling_capacity_per_length'], system['length'], system['evaporator_fan_pwr_per_length'], system['lighting_per_length'], system['lighting_sch_name'], system['defrost_pwr_per_length'], system['restocking_sch_name'], system['cop'], system['cop_f_of_t_curve_name'], system['condenser_fan_pwr'], system['condenser_fan_pwr_curve_name'], thermal_zones[0]) else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "System type #{system['type']} is not recognized. This system will not be added.") end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding HVAC') return true end |
#add_hw_loop(boiler_fuel_type, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a hot water loop with one boiler and add it to the model.
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 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 12 def add_hw_loop(boiler_fuel_type, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding hot water loop.") #hot water loop hot_water_loop = OpenStudio::Model::PlantLoop.new(self) hot_water_loop.setName('Hot Water Loop') hot_water_loop.setMinimumLoopTemperature(10) #hot water loop controls # TODO: Yixing check other building types and add the parameter to the prototype input if more values comes out. if building_type == "LargeHotel" hw_temp_f = 140 #HW setpoint 140F else hw_temp_f = 180 #HW setpoint 180F end hw_delta_t_r = 20 #20F delta-T hw_temp_c = OpenStudio.convert(hw_temp_f,'F','C').get hw_delta_t_k = OpenStudio.convert(hw_delta_t_r,'R','K').get hw_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) hw_temp_sch.setName("Hot Water Loop Temp - #{hw_temp_f}F") hw_temp_sch.defaultDaySchedule.setName("Hot Water Loop Temp - #{hw_temp_f}F Default") hw_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),hw_temp_c) hw_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,hw_temp_sch) hw_stpt_manager.setName("Hot water loop setpoint manager") hw_stpt_manager.addToNode(hot_water_loop.supplyOutletNode) sizing_plant = hot_water_loop.sizingPlant sizing_plant.setLoopType('Heating') sizing_plant.setDesignLoopExitTemperature(hw_temp_c) sizing_plant.setLoopDesignTemperatureDifference(hw_delta_t_k) #hot water pump hw_pump = OpenStudio::Model::PumpVariableSpeed.new(self) hw_pump.setName('Hot Water Loop Pump') hw_pump_head_ft_h2o = 60.0 hw_pump_head_press_pa = OpenStudio.convert(hw_pump_head_ft_h2o, 'ftH_{2}O','Pa').get hw_pump.setRatedPumpHead(hw_pump_head_press_pa) hw_pump.setMotorEfficiency(0.9) hw_pump.setFractionofMotorInefficienciestoFluidStream(0) hw_pump.setCoefficient1ofthePartLoadPerformanceCurve(0) hw_pump.setCoefficient2ofthePartLoadPerformanceCurve(1) hw_pump.setCoefficient3ofthePartLoadPerformanceCurve(0) hw_pump.setCoefficient4ofthePartLoadPerformanceCurve(0) hw_pump.setPumpControlType('Intermittent') hw_pump.addToNode(hot_water_loop.supplyInletNode) #boiler boiler_max_t_f = 203 boiler_max_t_c = OpenStudio.convert(boiler_max_t_f,'F','C').get boiler = OpenStudio::Model::BoilerHotWater.new(self) boiler.setName('Hot Water Loop Boiler') boiler.setEfficiencyCurveTemperatureEvaluationVariable('LeavingBoiler') boiler.setFuelType(boiler_fuel_type) boiler.setDesignWaterOutletTemperature(hw_temp_c) boiler.setNominalThermalEfficiency(0.78) boiler.setMaximumPartLoadRatio(1.2) boiler.setWaterOutletUpperTemperatureLimit(boiler_max_t_c) boiler.setBoilerFlowMode('LeavingSetpointModulated') hot_water_loop.addSupplyBranchForComponent(boiler) if building_type == "LargeHotel" boiler.setEfficiencyCurveTemperatureEvaluationVariable("LeavingBoiler") boiler.setDesignWaterOutletTemperature(81) boiler.setMaximumPartLoadRatio(1.2) boiler.setSizingFactor(1.2) boiler.setWaterOutletUpperTemperatureLimit(95) end # TODO: Yixing. Add the temperature setpoint will cost the simulation with # thousands of Severe Errors. Need to figure this out later. #boiler_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,hw_temp_sch) #boiler_stpt_manager.setName("Boiler outlet setpoint manager") #boiler_stpt_manager.addToNode(boiler.outletModelObject.get.to_Node.get) #hot water loop pipes boiler_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) hot_water_loop.addSupplyBranchForComponent(boiler_bypass_pipe) coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) hot_water_loop.addDemandBranchForComponent(coil_bypass_pipe) supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_outlet_pipe.addToNode(hot_water_loop.supplyOutletNode) demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_inlet_pipe.addToNode(hot_water_loop.demandInletNode) demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_outlet_pipe.addToNode(hot_water_loop.demandOutletNode) return hot_water_loop end |
#add_loads(building_vintage, climate_zone) ⇒ Bool
Adds the loads and associated schedules for each space type as defined in the OpenStudio_Standards_space_types.json file. This includes lights, plug loads, occupants, ventilation rate requirements, infiltration, gas equipment (for kitchens, etc.) and typical schedules for each. Some loads are governed by the standard, others are typical values pulled from sources such as the DOE Reference and DOE Prototype Buildings.
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 412 def add_loads(building_vintage, climate_zone) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying space types (loads)') # Loop through all the space types currently in the model, # which are placeholders, and give them appropriate loads and schedules self.getSpaceTypes.sort.each do |space_type| # Rendering color space_type.set_rendering_color(building_vintage) # Loads space_type.set_internal_loads(building_vintage, true, true, true, true, true, true) # Schedules space_type.set_internal_load_schedules(building_vintage, true, true, true, true, true, true, true) end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying space types (loads)') return true end |
#add_material(material_name) ⇒ Object
make return an OptionalMaterial
Create a material from the openstudio standards dataset.
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1930 def add_material(material_name) # First check model and return material if it already exists self.getMaterials.each do |material| if material.name.get.to_s == material_name OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "Already added material: #{material_name}") return material end end #OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Adding material: #{material_name}") # Get the object data data = self.find_object($os_standards['materials'], {'name'=>material_name}) if !data OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Cannot find data for material: #{material_name}, will not be created.") return false #TODO change to return empty optional material end material = nil material_type = data['material_type'] if material_type == 'StandardOpaqueMaterial' material = OpenStudio::Model::StandardOpaqueMaterial.new(self) material.setName(material_name) material.setRoughness(data['roughness'].to_s) material.setThickness(OpenStudio.convert(data['thickness'].to_f, 'in', 'm').get) material.setConductivity(OpenStudio.convert(data['conductivity'].to_f, 'Btu*in/hr*ft^2*R', 'W/m*K').get) material.setDensity(OpenStudio.convert(data['density'].to_f, 'lb/ft^3', 'kg/m^3').get) material.setSpecificHeat(OpenStudio.convert(data['specific_heat'].to_f, 'Btu/lb*R', 'J/kg*K').get) material.setThermalAbsorptance(data['thermal_absorptance'].to_f) material.setSolarAbsorptance(data['solar_absorptance'].to_f) material.setVisibleAbsorptance(data['visible_absorptance'].to_f) elsif material_type == 'MasslessOpaqueMaterial' material = OpenStudio::Model::MasslessOpaqueMaterial.new(self) material.setName(material_name) material.setThermalResistance(OpenStudio.convert(data['resistance'].to_f, 'hr*ft^2*R/Btu', 'm^2*K/W').get) material.setConductivity(OpenStudio.convert(data['conductivity'].to_f, 'Btu*in/hr*ft^2*R', 'W/m*K').get) material.setDensity(OpenStudio.convert(data['density'].to_f, 'lb/ft^3', 'kg/m^3').get) material.setSpecificHeat(OpenStudio.convert(data['specific_heat'].to_f, 'Btu/lb*R', 'J/kg*K').get) material.setThermalAbsorptance(data['thermal_absorptance'].to_f) material.setSolarAbsorptance(data['solar_absorptance'].to_f) material.setVisibleAbsorptance(data['visible_absorptance'].to_f) elsif material_type == 'AirGap' material = OpenStudio::Model::AirGap.new(self) material.setName(material_name) material.setThermalResistance(OpenStudio.convert(data['resistance'].to_f, 'hr*ft^2*R/Btu*in', 'm*K/W').get) elsif material_type == 'Gas' material = OpenStudio::Model::Gas.new(self) material.setName(material_name) material.setThickness(OpenStudio.convert(data['thickness'].to_f, 'in', 'm').get) material.setGasType(data['gas_type'].to_s) elsif material_type == 'SimpleGlazing' material = OpenStudio::Model::SimpleGlazing.new(self) material.setName(material_name) material.setUFactor(OpenStudio.convert(data['u_factor'].to_f, 'Btu/hr*ft^2*R', 'W/m^2*K').get) material.setSolarHeatGainCoefficient(data['solar_heat_gain_coefficient'].to_f) material.setVisibleTransmittance(data['visible_transmittance'].to_f) elsif material_type == 'StandardGlazing' material = OpenStudio::Model::StandardGlazing.new(self) material.setName(material_name) material.setOpticalDataType(data['optical_data_type'].to_s) material.setThickness(OpenStudio.convert(data['thickness'].to_f, 'in', 'm').get) material.setSolarTransmittanceatNormalIncidence(data['solar_transmittance_at_normal_incidence'].to_f) material.setFrontSideSolarReflectanceatNormalIncidence(data['front_side_solar_reflectance_at_normal_incidence'].to_f) material.setBackSideSolarReflectanceatNormalIncidence(data['back_side_solar_reflectance_at_normal_incidence'].to_f) material.setVisibleTransmittanceatNormalIncidence(data['visible_transmittance_at_normal_incidence'].to_f) material.setFrontSideVisibleReflectanceatNormalIncidence(data['front_side_visible_reflectance_at_normal_incidence'].to_f) material.setBackSideVisibleReflectanceatNormalIncidence(data['back_side_visible_reflectance_at_normal_incidence'].to_f) material.setInfraredTransmittanceatNormalIncidence(data['infrared_transmittance_at_normal_incidence'].to_f) material.setFrontSideInfraredHemisphericalEmissivity(data['front_side_infrared_hemispherical_emissivity'].to_f) material.setBackSideInfraredHemisphericalEmissivity(data['back_side_infrared_hemispherical_emissivity'].to_f) material.setConductivity(OpenStudio.convert(data['conductivity'].to_f, 'Btu*in/hr*ft^2*R', 'W/m*K').get) material.setDirtCorrectionFactorforSolarandVisibleTransmittance(data['dirt_correction_factor_for_solar_and_visible_transmittance'].to_f) if /true/i.match(data['solar_diffusing'].to_s) material.setSolarDiffusing(true) else material.setSolarDiffusing(false) end else puts "Unknown material type #{material_type}" exit end return material end |
#add_occupancy_sensors(building_type, building_vintage, climate_zone) ⇒ Bool
genericize and move this method to Standards.Space
Adds occupancy sensors to certain space types per the PNNL documentation.
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 751 def add_occupancy_sensors(building_type, building_vintage, climate_zone) # Only add occupancy sensors for 90.1-2010 case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007' return true end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding Occupancy Sensors') space_type_reduction_map = { 'SecondarySchool' => {'Classroom' => 0.32, 'Restroom' => 0.34, 'Office' => 0.22}, 'PrimarySchool' => {'Classroom' => 0.32, 'Restroom' => 0.34, 'Office' => 0.22} } # Loop through all the space types and reduce lighting operation schedule fractions as-specified self.getSpaceTypes.each do |space_type| # Skip space types with no standards building type next if space_type.standardsBuildingType.empty? stds_bldg_type = space_type.standardsBuildingType.get # Skip space types with no standards space type next if space_type.standardsSpaceType.empty? stds_spc_type = space_type.standardsSpaceType.get # Skip building types and space types that aren't listed in the hash next unless space_type_reduction_map.has_key?(stds_bldg_type) next unless space_type_reduction_map[stds_bldg_type].has_key?(stds_spc_type) # Get the reduction fraction multiplier red_multiplier = 1 - space_type_reduction_map[stds_bldg_type][stds_spc_type] lights_sch_names = [] lights_schs = {} reduced_lights_schs = {} # Get all of the lights in this space type # and determine the list of schedules they use. space_type.lights.each do |light| # Skip lights that don't have a schedule next if light.schedule.empty? lights_sch = light.schedule.get lights_schs[lights_sch.name.to_s] = lights_sch lights_sch_names << lights_sch.name.to_s end # Loop through the unique list of lighting schedules, cloning # and reducing schedule fraction before and after the specified times lights_sch_names.uniq.each do |lights_sch_name| lights_sch = lights_schs[lights_sch_name] # Skip non-ruleset schedules next if lights_sch.to_ScheduleRuleset.empty? # Clone the schedule (so that we don't mess with lights in # other space types that might be using the same schedule). new_lights_sch = lights_sch.clone(self).to_ScheduleRuleset.get new_lights_sch.setName("#{lights_sch_name} OccSensor Reduction") reduced_lights_schs[lights_sch_name] = new_lights_sch # Method to multiply the values in a day schedule by a specified value # but only when the existing value is higher than a specified lower limit. # This limit prevents occupancy sensors from affecting unoccupied hours. def multiply_schedule(day_sch, multiplier, limit) # Record the original times and values times = day_sch.times values = day_sch.values # Remove the original times and values day_sch.clearValues # Create new values by using the multiplier on the original values new_values = [] for i in 0..(values.length - 1) if values[i] > limit new_values << values[i] * multiplier else new_values << values[i] end end # Add the revised time/value pairs to the schedule for i in 0..(new_values.length - 1) day_sch.addValue(times[i], new_values[i]) end end #end reduce schedule # Reduce default day schedule multiply_schedule(new_lights_sch.defaultDaySchedule, red_multiplier, 0.25) # Reduce all other rule schedules new_lights_sch.scheduleRules.each do |sch_rule| multiply_schedule(sch_rule.daySchedule, red_multiplier, 0.25) end end #end of lights_sch_names.uniq.each do # Loop through all lights instances, replacing old lights # schedules with the reduced schedules. space_type.lights.each do |light| # Skip lights that don't have a schedule next if light.schedule.empty? old_lights_sch_name = light.schedule.get.name.to_s if reduced_lights_schs[old_lights_sch_name] light.setSchedule(reduced_lights_schs[old_lights_sch_name]) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Occupancy sensor reduction added to '#{light.name}'") end end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished Adding Occupancy Sensors') return true end |
#add_performance_rating_method_baseline_system(standard, system_type, zones) ⇒ Object
add 90.1-2013 systems 11-13
Add the specified baseline system type to the specified zons based on the specified standard. For some multi-zone system types, the standards require identifying zones whose loads or schedules are outliers and putting these systems on separate single-zone systems. This method does that.
90.1-2007, 90.1-2010, 90.1-2013 nonresidential, and heatedonly electric and fossil PTHP, PTAC, PSZ_AC, PSZ_HP, PVAV_Reheat, PVAV_PFP_Boxes, VAV_Reheat, VAV_PFP_Boxes, Gas_Furnace, Electric_Furnace, which are also returned by the method OpenStudio::Model::Model.performance_rating_method_baseline_system_type.
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 633 def (standard, system_type, zones) case standard when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' case system_type when 'PTAC' # System 1 if zones.size > 0 # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Add a hot water PTAC to each zone self.add_ptac(standard, nil, hot_water_loop, zones, 'ConstantVolume', 'Water', 'Single Speed DX AC') end when 'PTHP' # System 2 if zones.size > 0 # Add an air-source packaged terminal # heat pump with electric supplemental heat # to each zone. self.add_pthp(standard, nil, zones, 'ConstantVolume') end when 'PSZ_AC' # System 3 if zones.size > 0 # Add a gas-fired PSZ-AC to each zone # hvac_op_sch=nil means always on # oa_damper_sch to nil means always open self.add_psz_ac(standard, sys_name=nil, hot_water_loop=nil, chilled_water_loop=nil, zones, hvac_op_sch=nil, oa_damper_sch=nil, fan_location='DrawThrough', fan_type='ConstantVolume', heating_type='Gas', supplemental_heating_type='Gas', # Should we really add supplemental heating here? cooling_type='Single Speed DX AC', building_type=nil) end when 'PSZ_HP' # System 4 if zones.size > 0 # Add an air-source packaged single zone # heat pump with electric supplemental heat # to each zone. self.add_psz_ac(standard, 'PSZ-HP', nil, nil, zones, nil, nil, 'DrawThrough', 'ConstantVolume', 'Single Speed Heat Pump', 'Electric', 'Single Speed Heat Pump', building_type=nil) end when 'PVAV_Reheat' # System 5 # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Group zones by story story_zone_lists = self.group_zones_by_story(zones) # For the array of zones on each story, # separate the primary zones from the secondary zones. # Add the baseline system type to the primary zones # and add the suplemental system type to the secondary zones. story_zone_lists.each do |zones| # Differentiate primary and secondary zones pri_sec_zone_lists = self.differentiate_primary_secondary_thermal_zones(zones) pri_zones = pri_sec_zone_lists['primary'] sec_zones = pri_sec_zone_lists['secondary'] # Add a PVAV with Reheat for the primary zones story_name = zones[0].spaces[0].buildingStory.get.name.get sys_name = "#{story_name} PVAV_Reheat (Sys5)" # If and only if there are primary zones to attach to the loop # counter example: floor with only one elevator machine room that get classified as sec_zones if pri_zones.size > 0 self.add_pvav(standard, sys_name, pri_zones, nil, nil, hot_water_loop) end # Add a PSZ_AC for each secondary zone if sec_zones.size > 0 self.(standard, 'PSZ_AC', sec_zones) end end when 'PVAV_PFP_Boxes' # System 6 when 'VAV_Reheat' # System 7 # Retrieve the existing hot water loop # or add a new one if necessary. hot_water_loop = nil if self.getPlantLoopByName('Hot Water Loop').is_initialized hot_water_loop = self.getPlantLoopByName('Hot Water Loop').get else hot_water_loop = self.add_hw_loop('NaturalGas') end # Retrieve the existing chilled water loop # or add a new one if necessary. chilled_water_loop = nil if self.getPlantLoopByName('Chilled Water Loop').is_initialized chilled_water_loop = self.getPlantLoopByName('Chilled Water Loop').get else condenser_water_loop = self.add_cw_loop() chilled_water_loop = self.add_chw_loop(standard, 'const_pri_var_sec', 'WaterCooled', nil, 'Rotary Screw', 175.0, condenser_water_loop) end # Group zones by story story_zone_lists = self.group_zones_by_story(zones) # For the array of zones on each story, # separate the primary zones from the secondary zones. # Add the baseline system type to the primary zones # and add the suplemental system type to the secondary zones. story_zone_lists.each do |zones| # The group_zones_by_story NO LONGER returns empty lists when a given floor doesn't have any of the zones # So NO need to filter it out otherwise you get an error undefined method `spaces' for nil:NilClass #next if zones.empty? # Differentiate primary and secondary zones pri_sec_zone_lists = self.differentiate_primary_secondary_thermal_zones(zones) pri_zones = pri_sec_zone_lists['primary'] sec_zones = pri_sec_zone_lists['secondary'] # Add a VAV for the primary zones story_name = zones[0].spaces[0].buildingStory.get.name.get sys_name = "#{story_name} VAV_Reheat (Sys7)" # If and only if there are primary zones to attach to the loop # counter example: floor with only one elevator machine room that get classified as sec_zones if pri_zones.size > 0 self.add_vav_reheat(standard, sys_name, hot_water_loop, chilled_water_loop, pri_zones, nil, nil, 0.62, 0.9, OpenStudio.convert(4.0, 'inH_{2}O', 'Pa').get, nil) end # Add a PSZ_AC for each secondary zone if sec_zones.size > 0 self.(standard, 'PSZ_AC', sec_zones) end end when 'VAV_PFP_Boxes' # System 8 # Retrieve the existing chilled water loop # or add a new one if necessary. chilled_water_loop = nil if self.getPlantLoopByName('Chilled Water Loop').is_initialized chilled_water_loop = self.getPlantLoopByName('Chilled Water Loop').get else condenser_water_loop = self.add_cw_loop() chilled_water_loop = self.add_chw_loop(standard, 'const_pri_var_sec', 'WaterCooled', nil, 'Rotary Screw', 175.0, condenser_water_loop) end # Group zones by story story_zone_lists = self.group_zones_by_story(zones) # For the array of zones on each story, # separate the primary zones from the secondary zones. # Add the baseline system type to the primary zones # and add the suplemental system type to the secondary zones. story_zone_lists.each do |zones| # Differentiate primary and secondary zones pri_sec_zone_lists = self.differentiate_primary_secondary_thermal_zones(zones) pri_zones = pri_sec_zone_lists['primary'] sec_zones = pri_sec_zone_lists['secondary'] # Add an VAV for the primary zones story_name = zones[0].spaces[0].buildingStory.get.name.get sys_name = "#{story_name} VAV_PFP_Boxes (Sys8)" # If and only if there are primary zones to attach to the loop if pri_zones.size > 0 self.add_vav_pfp_boxes(standard, sys_name, chilled_water_loop, pri_zones, nil, nil, 0.62, 0.9, OpenStudio.convert(4.0, 'inH_{2}O', 'Pa').get) end # Add a PSZ_HP for each secondary zone if sec_zones.size > 0 self.(standard, 'PSZ_HP', sec_zones) end end when 'Gas_Furnace' # System 9 if zones.size > 0 # Add a System 9 - Gas Unit Heater to each zone self.add_unitheater(standard, nil, zones, nil, 'ConstantVolume', OpenStudio::convert(0.2, "inH_{2}O", "Pa").get, 'Gas', nil) end when 'Electric_Furnace' # System 10 if zones.size > 0 # Add a System 10 - Electric Unit Heater to each zone self.add_unitheater(standard, nil, zones, nil, 'ConstantVolume', OpenStudio::convert(0.2, "inH_{2}O", "Pa").get, 'Electric', nil) end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "System type #{system_type} is not a valid choice, nothing will be added to the model.") end end end |
#add_performance_rating_method_construction_set(building_vintage, category) ⇒ OpenStudio::Model::DefaultConstructionSet
Creates a construction set with the construction types specified in the Performance Rating Method (aka Appendix G aka LEED) and adds it to the model. This method creates and adds the constructions and their materials as well.
Valid choices are Nonresidential, Residential, and Semiheated construction set populated with the specified constructions.
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1356 def (building_vintage, category) construction_set = OpenStudio::Model::OptionalDefaultConstructionSet.new # Find the climate zone set that this climate zone falls into climate_zone_set = find_climate_zone_set(clim, building_vintage) if !climate_zone_set return construction_set end # Get the object data data = self.find_object($os_standards['construction_sets'], {'template'=>building_vintage, 'climate_zone_set'=> climate_zone_set, 'building_type'=>building_type, 'space_type'=>spc_type, 'is_residential'=>is_residential}) if !data data = self.find_object($os_standards['construction_sets'], {'template'=>building_vintage, 'climate_zone_set'=> climate_zone_set, 'building_type'=>building_type, 'space_type'=>spc_type}) if !data return construction_set end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Adding construction set: #{building_vintage}-#{clim}-#{building_type}-#{spc_type}-is_residential#{is_residential}") name = make_name(building_vintage, clim, building_type, spc_type) # Create a new construction set and name it construction_set = OpenStudio::Model::DefaultConstructionSet.new(self) construction_set.setName(name) # Specify the types of constructions # Exterior surfaces constructions exterior_floor_standards_construction_type = 'SteelFramed' exterior_wall_standards_construction_type = 'SteelFramed' exterior_roof_standards_construction_type = 'IEAD' # Ground contact surfaces constructions ground_contact_floor_standards_construction_type = 'Unheated' ground_contact_wall_standards_construction_type = 'Mass' # Exterior sub surfaces constructions exterior_fixed_window_standards_construction_type = 'IEAD' exterior_operable_window_standards_construction_type = 'IEAD' exterior_door_standards_construction_type = 'IEAD' exterior_overhead_door_standards_construction_type = 'IEAD' exterior_skylight_standards_construction_type = 'IEAD' # Exterior surfaces constructions exterior_surfaces = OpenStudio::Model::DefaultSurfaceConstructions.new(self) construction_set.setDefaultExteriorSurfaceConstructions(exterior_surfaces) exterior_surfaces.setFloorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorFloor', exterior_floor_standards_construction_type, category)) exterior_surfaces.setWallConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorWall', exterior_wall_standards_construction_type, category)) exterior_surfaces.setRoofCeilingConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorRoof', exterior_roof_standards_construction_type, category)) # Interior surfaces constructions interior_surfaces = OpenStudio::Model::DefaultSurfaceConstructions.new(self) construction_set.setDefaultInteriorSurfaceConstructions(interior_surfaces) construction_name = interior_floors if construction_name != nil interior_surfaces.setFloorConstruction(add_construction(construction_name)) end construction_name = interior_walls if construction_name != nil interior_surfaces.setWallConstruction(add_construction(construction_name)) end construction_name = interior_ceilings if construction_name != nil interior_surfaces.setRoofCeilingConstruction(add_construction(construction_name)) end # Ground contact surfaces constructions ground_surfaces = OpenStudio::Model::DefaultSurfaceConstructions.new(self) construction_set.setDefaultGroundContactSurfaceConstructions(ground_surfaces) ground_surfaces.setFloorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'GroundContactFloor', ground_contact_floor_standards_construction_type, category)) ground_surfaces.setWallConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'GroundContactWall', ground_contact_wall_standards_construction_type, category)) # Exterior sub surfaces constructions exterior_subsurfaces = OpenStudio::Model::DefaultSubSurfaceConstructions.new(self) construction_set.setDefaultExteriorSubSurfaceConstructions(exterior_subsurfaces) if exterior_fixed_window_standards_construction_type && exterior_fixed_window_building_category exterior_subsurfaces.setFixedWindowConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorWindow', exterior_fixed_window_standards_construction_type, category)) end if exterior_operable_window_standards_construction_type && exterior_operable_window_building_category exterior_subsurfaces.setOperableWindowConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorWindow', exterior_operable_window_standards_construction_type, category)) end if exterior_door_standards_construction_type && exterior_door_building_category exterior_subsurfaces.setDoorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorDoor', exterior_door_standards_construction_type, category)) end construction_name = exterior_glass_doors if construction_name != nil exterior_subsurfaces.setGlassDoorConstruction(add_construction(construction_name)) end if exterior_overhead_door_standards_construction_type && exterior_overhead_door_building_category exterior_subsurfaces.setOverheadDoorConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'ExteriorDoor', exterior_overhead_door_standards_construction_type, category)) end if exterior_skylight_standards_construction_type && exterior_skylight_building_category exterior_subsurfaces.setSkylightConstruction(find_and_add_construction(building_vintage, climate_zone_set, 'Skylight', exterior_skylight_standards_construction_type, category)) end if construction_name = tubular_daylight_domes exterior_subsurfaces.setTubularDaylightDomeConstruction(add_construction(construction_name)) end if construction_name = tubular_daylight_diffusers exterior_subsurfaces.setTubularDaylightDiffuserConstruction(add_construction(construction_name)) end # Interior sub surfaces constructions interior_subsurfaces = OpenStudio::Model::DefaultSubSurfaceConstructions.new(self) construction_set.setDefaultInteriorSubSurfaceConstructions(interior_subsurfaces) if construction_name = interior_fixed_windows interior_subsurfaces.setFixedWindowConstruction(add_construction(construction_name)) end if construction_name = interior_operable_windows interior_subsurfaces.setOperableWindowConstruction(add_construction(construction_name)) end if construction_name = interior_doors interior_subsurfaces.setDoorConstruction(add_construction(construction_name)) end # Other constructions if construction_name = interior_partitions construction_set.setInteriorPartitionConstruction(add_construction(construction_name)) end if construction_name = space_shading construction_set.setSpaceShadingConstruction(add_construction(construction_name)) end if construction_name = building_shading construction_set.setBuildingShadingConstruction(add_construction(construction_name)) end if construction_name = site_shading construction_set.setSiteShadingConstruction(add_construction(construction_name)) end # componentize the construction set #construction_set_component = construction_set.createComponent # Return the construction set return OpenStudio::Model::OptionalDefaultConstructionSet.new(construction_set) # Create a constuction set that is all end |
#add_psz_ac(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_location, fan_type, heating_type, supplemental_heating_type, cooling_type, building_type = nil) ⇒ Array<OpenStudio::Model::AirLoopHVAC>
Creates a PSZ-AC system for each zone and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open Single Speed Heat Pump, Water To Air Heat Pump Single Speed DX AC, Single Speed Heat Pump, Water To Air Heat Pump Todo: clarify where these default curves coefficients are coming from Todo: I (jmarrec) believe it is the DOE Ref curves (“DOE Ref DX Clg Coil Cool-Cap-fT”)
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 1243 def add_psz_ac(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, fan_location, fan_type, heating_type, supplemental_heating_type, cooling_type, building_type=nil) unless hot_water_loop.nil? or chilled_water_loop.nil? hw_temp_f = 180 #HW setpoint 180F hw_delta_t_r = 20 #20F delta-T hw_temp_c = OpenStudio.convert(hw_temp_f,'F','C').get hw_delta_t_k = OpenStudio.convert(hw_delta_t_r,'R','K').get # control temps used across all air handlers clg_sa_temp_f = 55 # Central deck clg temp 55F prehtg_sa_temp_f = 44.6 # Preheat to 44.6F htg_sa_temp_f = 55 # Central deck htg temp 55F rht_sa_temp_f = 104 # VAV box reheat to 104F clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f,'F','C').get prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f,'F','C').get htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f,'F','C').get rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f,'F','C').get end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # Make a PSZ-AC for each zone air_loops = [] thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding PSZ-AC for #{zone.name}.") air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? air_loop.setName("#{zone.name} PSZ-AC") else air_loop.setName("#{zone.name} #{sys_name}") end air_loop.setAvailabilitySchedule(hvac_op_sch) air_loops << air_loop # When an air_loop is contructed, its constructor creates a sizing:system object # the default sizing:system contstructor makes a system:sizing object # appropriate for a multizone VAV system # this systems is a constant volume system with no VAV terminals, # and therfore needs different default settings air_loop_sizing = air_loop.sizingSystem # TODO units air_loop_sizing.setTypeofLoadtoSizeOn('Sensible') air_loop_sizing.autosizeDesignOutdoorAirFlowRate air_loop_sizing.setMinimumSystemAirFlowRatio(1.0) air_loop_sizing.setPreheatDesignTemperature(7.0) air_loop_sizing.setPreheatDesignHumidityRatio(0.008) air_loop_sizing.setPrecoolDesignTemperature(12.8) air_loop_sizing.setPrecoolDesignHumidityRatio(0.008) air_loop_sizing.setCentralCoolingDesignSupplyAirTemperature(12.8) air_loop_sizing.setCentralHeatingDesignSupplyAirTemperature(40.0) air_loop_sizing.setSizingOption('Coincident') air_loop_sizing.setAllOutdoorAirinCooling(false) air_loop_sizing.setAllOutdoorAirinHeating(false) air_loop_sizing.setCentralCoolingDesignSupplyAirHumidityRatio(0.0085) air_loop_sizing.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080) air_loop_sizing.setCoolingDesignAirFlowMethod('DesignDay') air_loop_sizing.setCoolingDesignAirFlowRate(0.0) air_loop_sizing.setHeatingDesignAirFlowMethod('DesignDay') air_loop_sizing.setHeatingDesignAirFlowRate(0.0) air_loop_sizing.setSystemOutdoorAirMethod('ZoneSum') # Zone sizing sizing_zone = zone.sizingZone if building_type == 'RetailStandalone' && (standard =='DOE Ref 1980-2004' || standard =='DOE Ref Pre-1980') sizing_zone.setZoneCoolingDesignSupplyAirTemperature(14) else sizing_zone.setZoneCoolingDesignSupplyAirTemperature(12.8) end sizing_zone.setZoneHeatingDesignSupplyAirTemperature(40.0) # Add a setpoint manager single zone reheat to control the # supply air temperature based on the needs of this zone setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(self) setpoint_mgr_single_zone_reheat.setControlZone(zone) fan = nil # ConstantVolume: Packaged Rooftop Single Zone Air conditioner; # Cycling: Unitary System; # CyclingHeatPump: Unitary Heat Pump system if fan_type == 'ConstantVolume' fan = OpenStudio::Model::FanConstantVolume.new(self,hvac_op_sch) fan.setName("#{air_loop.name} Fan") fan_static_pressure_in_h2o = 2.5 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, 'inH_{2}O','Pa').get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.54) fan.setMotorEfficiency(0.90) elsif fan_type == 'Cycling' fan = OpenStudio::Model::FanOnOff.new(self,hvac_op_sch) # Set fan op sch manually since fwd translator doesn't fan.setName("#{air_loop.name} Fan") fan_static_pressure_in_h2o = 2.5 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, 'inH_{2}O','Pa').get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.54) fan.setMotorEfficiency(0.90) else OpenStudio::logFree(OpenStudio::Error, 'openstudio.Model.Model', "Fan type '#{fan_type}' not recognized, cannot add PSZ-AC.") return [] end htg_coil = nil if heating_type == 'Gas' htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{air_loop.name} Gas Htg Coil") if standard =='DOE Ref Pre-1980' htg_coil.setGasBurnerEfficiency(0.78) end elsif heating_type == 'Water' if hot_water_loop.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'No hot water plant loop supplied') return false end htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{air_loop.name} Water Htg Coil") htg_coil.setRatedInletWaterTemperature(hw_temp_c) htg_coil.setRatedInletAirTemperature(prehtg_sa_temp_c) htg_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) htg_coil.setRatedOutletAirTemperature(htg_sa_temp_c) hot_water_loop.addDemandBranchForComponent(htg_coil) elsif heating_type == 'Single Speed Heat Pump' htg_cap_f_of_temp = OpenStudio::Model::CurveCubic.new(self) htg_cap_f_of_temp.setCoefficient1Constant(0.758746) htg_cap_f_of_temp.setCoefficient2x(0.027626) htg_cap_f_of_temp.setCoefficient3xPOW2(0.000148716) htg_cap_f_of_temp.setCoefficient4xPOW3(0.0000034992) htg_cap_f_of_temp.setMinimumValueofx(-20.0) htg_cap_f_of_temp.setMaximumValueofx(20.0) htg_cap_f_of_flow = OpenStudio::Model::CurveCubic.new(self) htg_cap_f_of_flow.setCoefficient1Constant(0.84) htg_cap_f_of_flow.setCoefficient2x(0.16) htg_cap_f_of_flow.setCoefficient3xPOW2(0.0) htg_cap_f_of_flow.setCoefficient4xPOW3(0.0) htg_cap_f_of_flow.setMinimumValueofx(0.5) htg_cap_f_of_flow.setMaximumValueofx(1.5) htg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveCubic.new(self) htg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.19248) htg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.0300438) htg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00103745) htg_energy_input_ratio_f_of_temp.setCoefficient4xPOW3(-0.000023328) htg_energy_input_ratio_f_of_temp.setMinimumValueofx(-20.0) htg_energy_input_ratio_f_of_temp.setMaximumValueofx(20.0) htg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) htg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.3824) htg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.4336) htg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0512) htg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.0) htg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.0) htg_part_load_fraction = OpenStudio::Model::CurveQuadratic.new(self) htg_part_load_fraction.setCoefficient1Constant(0.85) htg_part_load_fraction.setCoefficient2x(0.15) htg_part_load_fraction.setCoefficient3xPOW2(0.0) htg_part_load_fraction.setMinimumValueofx(0.0) htg_part_load_fraction.setMaximumValueofx(1.0) htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, htg_cap_f_of_temp, htg_cap_f_of_flow, htg_energy_input_ratio_f_of_temp, htg_energy_input_ratio_f_of_flow, htg_part_load_fraction) htg_coil.setName("#{air_loop.name} HP Htg Coil") htg_coil.setRatedCOP(3.3) # TODO add this to standards htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(-12.2) htg_coil.setMaximumOutdoorDryBulbTemperatureforDefrostOperation(1.67) htg_coil.setCrankcaseHeaterCapacity(50.0) htg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(4.4) htg_coil.setDefrostStrategy('ReverseCycle') htg_coil.setDefrostControl('OnDemand') def_eir_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) def_eir_f_of_temp.setCoefficient1Constant(0.297145) def_eir_f_of_temp.setCoefficient2x(0.0430933) def_eir_f_of_temp.setCoefficient3xPOW2(-0.000748766) def_eir_f_of_temp.setCoefficient4y(0.00597727) def_eir_f_of_temp.setCoefficient5yPOW2(0.000482112) def_eir_f_of_temp.setCoefficient6xTIMESY(-0.000956448) def_eir_f_of_temp.setMinimumValueofx(12.77778) def_eir_f_of_temp.setMaximumValueofx(23.88889) def_eir_f_of_temp.setMinimumValueofy(21.11111) def_eir_f_of_temp.setMaximumValueofy(46.11111) htg_coil.setDefrostEnergyInputRatioFunctionofTemperatureCurve(def_eir_f_of_temp) elsif heating_type == 'Water To Air Heat Pump' if hot_water_loop.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'No hot water plant loop supplied') return false end htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(self) htg_coil.setName("#{air_loop.name} Water-to-Air HP Htg Coil") htg_coil.setRatedHeatingCoefficientofPerformance(4.2) # TODO add this to standards htg_coil.setHeatingCapacityCoefficient1(0.237847462869254) htg_coil.setHeatingCapacityCoefficient2(-3.35823796081626) htg_coil.setHeatingCapacityCoefficient3(3.80640467406376) htg_coil.setHeatingCapacityCoefficient4(0.179200417311554) htg_coil.setHeatingCapacityCoefficient5(0.12860719846082) htg_coil.setHeatingPowerConsumptionCoefficient1(-3.79175529243238) htg_coil.setHeatingPowerConsumptionCoefficient2(3.38799239505527) htg_coil.setHeatingPowerConsumptionCoefficient3(1.5022612076303) htg_coil.setHeatingPowerConsumptionCoefficient4(-0.177653510577989) htg_coil.setHeatingPowerConsumptionCoefficient5(-0.103079864171839) hot_water_loop.addDemandBranchForComponent(htg_coil) end supplemental_htg_coil = nil if supplemental_heating_type == 'Electric' supplemental_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) supplemental_htg_coil.setName("#{air_loop.name} Electric Backup Htg Coil") elsif supplemental_heating_type == 'Gas' supplemental_htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) supplemental_htg_coil.setName("#{air_loop.name} Gas Backup Htg Coil") end clg_coil = nil if cooling_type == 'Water' if chilled_water_loop.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'No chilled water plant loop supplied') return false end clg_coil = OpenStudio::Model::CoilCoolingWater.new(self,self.alwaysOnDiscreteSchedule) clg_coil.setName("#{air_loop.name} Water Clg Coil") chilled_water_loop.addDemandBranchForComponent(clg_coil) elsif cooling_type == 'Two Speed DX AC' clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.42415) clg_cap_f_of_temp.setCoefficient2x(0.04426) clg_cap_f_of_temp.setCoefficient3xPOW2(-0.00042) clg_cap_f_of_temp.setCoefficient4y(0.00333) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.00008) clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.00021) clg_cap_f_of_temp.setMinimumValueofx(17.0) clg_cap_f_of_temp.setMaximumValueofx(22.0) clg_cap_f_of_temp.setMinimumValueofy(13.0) clg_cap_f_of_temp.setMaximumValueofy(46.0) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.77136) clg_cap_f_of_flow.setCoefficient2x(0.34053) clg_cap_f_of_flow.setCoefficient3xPOW2(-0.11088) clg_cap_f_of_flow.setMinimumValueofx(0.75918) clg_cap_f_of_flow.setMaximumValueofx(1.13877) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.23649) clg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.02431) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00057) clg_energy_input_ratio_f_of_temp.setCoefficient4y(-0.01434) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.00063) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.00038) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.20550) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.32953) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.12308) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.75918) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.13877) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.77100) clg_part_load_ratio.setCoefficient2x(0.22900) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_cap_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp_low_spd.setCoefficient1Constant(0.42415) clg_cap_f_of_temp_low_spd.setCoefficient2x(0.04426) clg_cap_f_of_temp_low_spd.setCoefficient3xPOW2(-0.00042) clg_cap_f_of_temp_low_spd.setCoefficient4y(0.00333) clg_cap_f_of_temp_low_spd.setCoefficient5yPOW2(-0.00008) clg_cap_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00021) clg_cap_f_of_temp_low_spd.setMinimumValueofx(17.0) clg_cap_f_of_temp_low_spd.setMaximumValueofx(22.0) clg_cap_f_of_temp_low_spd.setMinimumValueofy(13.0) clg_cap_f_of_temp_low_spd.setMaximumValueofy(46.0) clg_energy_input_ratio_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient1Constant(1.23649) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient2x(-0.02431) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient3xPOW2(0.00057) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient4y(-0.01434) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient5yPOW2(0.00063) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00038) clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofx(17.0) clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofx(22.0) clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofy(13.0) clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofy(46.0) clg_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio, clg_cap_f_of_temp_low_spd, clg_energy_input_ratio_f_of_temp_low_spd) clg_coil.setName("#{air_loop.name} 2spd DX AC Clg Coil") clg_coil.setRatedLowSpeedSensibleHeatRatio(OpenStudio::OptionalDouble.new(0.69)) clg_coil.setBasinHeaterCapacity(10) clg_coil.setBasinHeaterSetpointTemperature(2.0) elsif cooling_type == 'Single Speed DX AC' # Defaults to "DOE Ref DX Clg Coil Cool-Cap-fT" clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.9712123) clg_cap_f_of_temp.setCoefficient2x(-0.015275502) clg_cap_f_of_temp.setCoefficient3xPOW2(0.0014434524) clg_cap_f_of_temp.setCoefficient4y(-0.00039321) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.0000068364) clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.0002905956) clg_cap_f_of_temp.setMinimumValueofx(-100.0) clg_cap_f_of_temp.setMaximumValueofx(100.0) clg_cap_f_of_temp.setMinimumValueofy(-100.0) clg_cap_f_of_temp.setMaximumValueofy(100.0) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(1.0) clg_cap_f_of_flow.setCoefficient2x(0.0) clg_cap_f_of_flow.setCoefficient3xPOW2(0.0) clg_cap_f_of_flow.setMinimumValueofx(-100.0) clg_cap_f_of_flow.setMaximumValueofx(100.0) # "DOE Ref DX Clg Coil Cool-EIR-fT", clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.28687133) clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.023902164) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000810648) clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.013458546) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.0003389364) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.0004870044) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(-100.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(100.0) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(-100.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(100.0) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.0) clg_energy_input_ratio_f_of_flow.setCoefficient2x(0.0) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(-100.0) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(100.0) # "DOE Ref DX Clg Coil Cool-PLF-fPLR" clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.90949556) clg_part_load_ratio.setCoefficient2x(0.09864773) clg_part_load_ratio.setCoefficient3xPOW2(-0.00819488) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_part_load_ratio.setMinimumCurveOutput(0.7) clg_part_load_ratio.setMaximumCurveOutput(1.0) clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio) clg_coil.setName("#{air_loop.name} 1spd DX AC Clg Coil") elsif cooling_type == 'Single Speed Heat Pump' # "PSZ-AC_Unitary_PackagecoolCapFT" clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.766956) clg_cap_f_of_temp.setCoefficient2x(0.0107756) clg_cap_f_of_temp.setCoefficient3xPOW2(-0.0000414703) clg_cap_f_of_temp.setCoefficient4y(0.00134961) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.000261144) clg_cap_f_of_temp.setCoefficient6xTIMESY(0.000457488) clg_cap_f_of_temp.setMinimumValueofx(12.78) clg_cap_f_of_temp.setMaximumValueofx(23.89) clg_cap_f_of_temp.setMinimumValueofy(21.1) clg_cap_f_of_temp.setMaximumValueofy(46.1) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.8) clg_cap_f_of_flow.setCoefficient2x(0.2) clg_cap_f_of_flow.setCoefficient3xPOW2(0.0) clg_cap_f_of_flow.setMinimumValueofx(0.5) clg_cap_f_of_flow.setMaximumValueofx(1.5) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.297145) clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.0430933) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000748766) clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.00597727) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000482112) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000956448) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(12.78) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(23.89) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(21.1) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.1) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.156) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1816) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.85) clg_part_load_ratio.setCoefficient2x(0.15) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio) clg_coil.setName("#{air_loop.name} 1spd DX HP Clg Coil") #clg_coil.setMaximumOutdoorDryBulbTemperatureForCrankcaseHeaterOperation(OpenStudio::OptionalDouble.new(10.0)) #clg_coil.setRatedSensibleHeatRatio(0.69) #clg_coil.setBasinHeaterCapacity(10) #clg_coil.setBasinHeaterSetpointTemperature(2.0) elsif cooling_type == 'Water To Air Heat Pump' if chilled_water_loop.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'No chilled water plant loop supplied') return false end clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(self) clg_coil.setName("#{air_loop.name} Water-to-Air HP Clg Coil") clg_coil.setRatedCoolingCoefficientofPerformance(3.4) # TODO add this to standards clg_coil.setTotalCoolingCapacityCoefficient1(-4.30266987344639) clg_coil.setTotalCoolingCapacityCoefficient2(7.18536990534372) clg_coil.setTotalCoolingCapacityCoefficient3(-2.23946714486189) clg_coil.setTotalCoolingCapacityCoefficient4(0.139995928440879) clg_coil.setTotalCoolingCapacityCoefficient5(0.102660179888915) clg_coil.setSensibleCoolingCapacityCoefficient1(6.0019444814887) clg_coil.setSensibleCoolingCapacityCoefficient2(22.6300677244073) clg_coil.setSensibleCoolingCapacityCoefficient3(-26.7960783730934) clg_coil.setSensibleCoolingCapacityCoefficient4(-1.72374720346819) clg_coil.setSensibleCoolingCapacityCoefficient5(0.490644802367817) clg_coil.setSensibleCoolingCapacityCoefficient6(0.0693119353468141) clg_coil.setCoolingPowerConsumptionCoefficient1(-5.67775976415698) clg_coil.setCoolingPowerConsumptionCoefficient2(0.438988156976704) clg_coil.setCoolingPowerConsumptionCoefficient3(5.845277342193) clg_coil.setCoolingPowerConsumptionCoefficient4(0.141605667000125) clg_coil.setCoolingPowerConsumptionCoefficient5(-0.168727936032429) chilled_water_loop.addDemandBranchForComponent(clg_coil) end oa_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_controller.setName("#{air_loop.name} OA Sys Controller") oa_controller.setMinimumOutdoorAirSchedule(oa_damper_sch) oa_controller.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum') oa_system = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self,oa_controller) oa_system.setName("#{air_loop.name} OA Sys") # Add the components to the air loop # in order from closest to zone to furthest from zone supply_inlet_node = air_loop.supplyInletNode # Wrap coils in a unitary system or not, depending # on the system type. if fan_type == 'Cycling' if heating_type == 'Water To Air Heat Pump' unitary_system = OpenStudio::Model::AirLoopHVACUnitarySystem.new(self) unitary_system.setSupplyFan(fan) unitary_system.setHeatingCoil(htg_coil) unitary_system.setCoolingCoil(clg_coil) unitary_system.setSupplementalHeatingCoil(supplemental_htg_coil) unitary_system.setName("#{zone.name} Unitary HP") unitary_system.setControllingZoneorThermostatLocation(zone) unitary_system.setMaximumSupplyAirTemperature(50) unitary_system.setFanPlacement('BlowThrough') unitary_system.setSupplyAirFlowRateMethodDuringCoolingOperation("SupplyAirFlowRate") unitary_system.setSupplyAirFlowRateMethodDuringHeatingOperation("SupplyAirFlowRate") unitary_system.setSupplyAirFlowRateMethodWhenNoCoolingorHeatingisRequired("SupplyAirFlowRate") unitary_system.(self.alwaysOnDiscreteSchedule) unitary_system.addToNode(supply_inlet_node) setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(50) else unitary_system = OpenStudio::Model::AirLoopHVACUnitaryHeatPumpAirToAir.new(self, self.alwaysOnDiscreteSchedule, fan, htg_coil, clg_coil, supplemental_htg_coil) unitary_system.setName("#{air_loop.name} Unitary HP") unitary_system.setControllingZone(zone) unitary_system.setMaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation(OpenStudio.convert(40,'F','C').get) unitary_system.setFanPlacement(fan_location) unitary_system.(hvac_op_sch) unitary_system.addToNode(supply_inlet_node) setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(55,'F','C').get) setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(104,'F','C').get) end else if fan_location == 'DrawThrough' # Add the fan unless fan.nil? fan.addToNode(supply_inlet_node) end # Add the supplemental heating coil unless supplemental_htg_coil.nil? supplemental_htg_coil.addToNode(supply_inlet_node) end # Add the heating coil unless htg_coil.nil? htg_coil.addToNode(supply_inlet_node) end # Add the cooling coil unless clg_coil.nil? clg_coil.addToNode(supply_inlet_node) end elsif fan_location == 'BlowThrough' # Add the supplemental heating coil unless supplemental_htg_coil.nil? supplemental_htg_coil.addToNode(supply_inlet_node) end # Add the cooling coil unless clg_coil.nil? clg_coil.addToNode(supply_inlet_node) end # Add the heating coil unless htg_coil.nil? htg_coil.addToNode(supply_inlet_node) end # Add the fan unless fan.nil? fan.addToNode(supply_inlet_node) end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'Invalid fan location') return false end setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(50,'F','C').get) setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(122,'F','C').get) end # Add the OA system oa_system.addToNode(supply_inlet_node) # Attach the nightcycle manager to the supply outlet node setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode) air_loop.setNightCycleControlType('CycleOnAny') # Create a diffuser and attach the zone/diffuser pair to the air loop diffuser = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(self,self.alwaysOnDiscreteSchedule) diffuser.setName("#{air_loop.name} Diffuser") air_loop.addBranchForZone(zone,diffuser.to_StraightComponent) end return air_loops end |
#add_ptac(standard, sys_name, hot_water_loop, thermal_zones, fan_type, heating_type, cooling_type, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner>
Creates a PTAC system for each zone and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 Gas, Electric, Water Two Speed DX AC, Single Speed DX AC array of the resulting PTACs.
2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 2603 def add_ptac(standard, sys_name, hot_water_loop, thermal_zones, fan_type, heating_type, cooling_type, building_type=nil) thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding PTAC for #{zone.name}.") end # schedule: always off always_off = OpenStudio::Model::ScheduleRuleset.new(self) always_off.setName("ALWAYS_OFF") always_off.defaultDaySchedule.setName("ALWAYS_OFF day") always_off.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0.0) always_off.setSummerDesignDaySchedule(always_off.defaultDaySchedule) always_off.setWinterDesignDaySchedule(always_off.defaultDaySchedule) # Make a PTAC for each zone ptacs = [] thermal_zones.each do |zone| # Zone sizing sizing_zone = zone.sizingZone sizing_zone.setZoneCoolingDesignSupplyAirTemperature(14) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(50.0) sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008) sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008) # add fan fan = nil if fan_type == "ConstantVolume" fan = OpenStudio::Model::FanConstantVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{zone.name} PTAC Fan") fan_static_pressure_in_h2o = 1.33 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, "inH_{2}O","Pa").get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.52) fan.setMotorEfficiency(0.8) elsif fan_type == "Cycling" fan = OpenStudio::Model::FanOnOff.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{zone.name} PTAC Fan") fan_static_pressure_in_h2o = 1.33 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, "inH_{2}O","Pa").get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.52) fan.setMotorEfficiency(0.8) else OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "ptac_fan_type of #{fan_type} is not recognized.") end # add heating coil htg_coil = nil if heating_type == "Gas" htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{zone.name} PTAC Gas Htg Coil") elsif heating_type == "Electric" htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{zone.name} PTAC Electric Htg Coil") elsif heating_type == "Water" if hot_water_loop.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'No hot water plant loop supplied') return false end hw_sizing = hot_water_loop.sizingPlant hw_temp_c = hw_sizing.designLoopExitTemperature hw_delta_t_k = hw_sizing.loopDesignTemperatureDifference # Using openstudio defaults for now... prehtg_sa_temp_c = 16.6 htg_sa_temp_c = 32.2 htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{hot_water_loop.name} Water Htg Coil") # None of these temperatures are defined htg_coil.setRatedInletWaterTemperature(hw_temp_c) htg_coil.setRatedInletAirTemperature(prehtg_sa_temp_c) htg_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) htg_coil.setRatedOutletAirTemperature(htg_sa_temp_c) hot_water_loop.addDemandBranchForComponent(htg_coil) else OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "ptac_heating_type of #{heating_type} is not recognized.") end # add cooling coil clg_coil = nil if cooling_type == "Two Speed DX AC" clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.42415) clg_cap_f_of_temp.setCoefficient2x(0.04426) clg_cap_f_of_temp.setCoefficient3xPOW2(-0.00042) clg_cap_f_of_temp.setCoefficient4y(0.00333) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.00008) clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.00021) clg_cap_f_of_temp.setMinimumValueofx(17.0) clg_cap_f_of_temp.setMaximumValueofx(22.0) clg_cap_f_of_temp.setMinimumValueofy(13.0) clg_cap_f_of_temp.setMaximumValueofy(46.0) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.77136) clg_cap_f_of_flow.setCoefficient2x(0.34053) clg_cap_f_of_flow.setCoefficient3xPOW2(-0.11088) clg_cap_f_of_flow.setMinimumValueofx(0.75918) clg_cap_f_of_flow.setMaximumValueofx(1.13877) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.23649) clg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.02431) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00057) clg_energy_input_ratio_f_of_temp.setCoefficient4y(-0.01434) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.00063) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.00038) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.20550) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.32953) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.12308) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.75918) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.13877) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.77100) clg_part_load_ratio.setCoefficient2x(0.22900) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_cap_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp_low_spd.setCoefficient1Constant(0.42415) clg_cap_f_of_temp_low_spd.setCoefficient2x(0.04426) clg_cap_f_of_temp_low_spd.setCoefficient3xPOW2(-0.00042) clg_cap_f_of_temp_low_spd.setCoefficient4y(0.00333) clg_cap_f_of_temp_low_spd.setCoefficient5yPOW2(-0.00008) clg_cap_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00021) clg_cap_f_of_temp_low_spd.setMinimumValueofx(17.0) clg_cap_f_of_temp_low_spd.setMaximumValueofx(22.0) clg_cap_f_of_temp_low_spd.setMinimumValueofy(13.0) clg_cap_f_of_temp_low_spd.setMaximumValueofy(46.0) clg_energy_input_ratio_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient1Constant(1.23649) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient2x(-0.02431) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient3xPOW2(0.00057) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient4y(-0.01434) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient5yPOW2(0.00063) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00038) clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofx(17.0) clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofx(22.0) clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofy(13.0) clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofy(46.0) clg_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio, clg_cap_f_of_temp_low_spd, clg_energy_input_ratio_f_of_temp_low_spd) clg_coil.setName("#{zone.name} PTAC 2spd DX AC Clg Coil") clg_coil.setRatedLowSpeedSensibleHeatRatio(OpenStudio::OptionalDouble.new(0.69)) clg_coil.setBasinHeaterCapacity(10) clg_coil.setBasinHeaterSetpointTemperature(2.0) elsif cooling_type == "Single Speed DX AC" # for small hotel clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.942587793) clg_cap_f_of_temp.setCoefficient2x(0.009543347) clg_cap_f_of_temp.setCoefficient3xPOW2(0.000683770) clg_cap_f_of_temp.setCoefficient4y(-0.011042676) clg_cap_f_of_temp.setCoefficient5yPOW2(0.000005249) clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.000009720) clg_cap_f_of_temp.setMinimumValueofx(12.77778) clg_cap_f_of_temp.setMaximumValueofx(23.88889) clg_cap_f_of_temp.setMinimumValueofy(18.3) clg_cap_f_of_temp.setMaximumValueofy(46.11111) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.8) clg_cap_f_of_flow.setCoefficient2x(0.2) clg_cap_f_of_flow.setCoefficient3xPOW2(0.0) clg_cap_f_of_flow.setMinimumValueofx(0.5) clg_cap_f_of_flow.setMaximumValueofx(1.5) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.342414409) clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.034885008) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000623700) clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.004977216) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000437951) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000728028) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(12.77778) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(23.88889) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(18.3) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.11111) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.1552) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1808) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.85) clg_part_load_ratio.setCoefficient2x(0.15) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_part_load_ratio.setMinimumCurveOutput(0.7) clg_part_load_ratio.setMaximumCurveOutput(1.0) clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio) clg_coil.setName("#{zone.name} PTAC 1spd DX AC Clg Coil") else OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "ptac_cooling_type of #{heating_type} is not recognized.") end # Wrap coils in a PTAC system ptac_system = OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner.new(self, self.alwaysOnDiscreteSchedule, fan, htg_coil, clg_coil) ptac_system.setName("#{zone.name} PTAC") ptac_system.setFanPlacement("DrawThrough") if fan_type == "ConstantVolume" ptac_system.(self.alwaysOnDiscreteSchedule) elsif fan_type == "Cycling" ptac_system.(always_off) end ptac_system.addToThermalZone(zone) ptacs << ptac_system end return ptacs end |
#add_pthp(standard, sys_name, thermal_zones, fan_type, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner>
Creates a PTHP system for each zone and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 array of the resulting PTACs.
2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 2878 def add_pthp(standard, sys_name, thermal_zones, fan_type, building_type=nil) thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding PTHP for #{zone.name}.") end # schedule: always off always_off = OpenStudio::Model::ScheduleRuleset.new(self) always_off.setName("ALWAYS_OFF") always_off.defaultDaySchedule.setName("ALWAYS_OFF day") always_off.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0.0) always_off.setSummerDesignDaySchedule(always_off.defaultDaySchedule) always_off.setWinterDesignDaySchedule(always_off.defaultDaySchedule) # Make a PTHP for each zone pthps = [] thermal_zones.each do |zone| # Zone sizing sizing_zone = zone.sizingZone sizing_zone.setZoneCoolingDesignSupplyAirTemperature(14) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(50.0) sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008) sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008) # add fan fan = nil if fan_type == "ConstantVolume" fan = OpenStudio::Model::FanConstantVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{zone.name} PTAC Fan") fan_static_pressure_in_h2o = 1.33 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, "inH_{2}O","Pa").get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.52) fan.setMotorEfficiency(0.8) elsif fan_type == "Cycling" fan = OpenStudio::Model::FanOnOff.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{zone.name} PTAC Fan") fan_static_pressure_in_h2o = 1.33 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, "inH_{2}O","Pa").get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.52) fan.setMotorEfficiency(0.8) else OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "ptac_fan_type of #{fan_type} is not recognized.") end # add heating coil htg_cap_f_of_temp = OpenStudio::Model::CurveCubic.new(self) htg_cap_f_of_temp.setCoefficient1Constant(0.758746) htg_cap_f_of_temp.setCoefficient2x(0.027626) htg_cap_f_of_temp.setCoefficient3xPOW2(0.000148716) htg_cap_f_of_temp.setCoefficient4xPOW3(0.0000034992) htg_cap_f_of_temp.setMinimumValueofx(-20.0) htg_cap_f_of_temp.setMaximumValueofx(20.0) htg_cap_f_of_flow = OpenStudio::Model::CurveCubic.new(self) htg_cap_f_of_flow.setCoefficient1Constant(0.84) htg_cap_f_of_flow.setCoefficient2x(0.16) htg_cap_f_of_flow.setCoefficient3xPOW2(0.0) htg_cap_f_of_flow.setCoefficient4xPOW3(0.0) htg_cap_f_of_flow.setMinimumValueofx(0.5) htg_cap_f_of_flow.setMaximumValueofx(1.5) htg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveCubic.new(self) htg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.19248) htg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.0300438) htg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00103745) htg_energy_input_ratio_f_of_temp.setCoefficient4xPOW3(-0.000023328) htg_energy_input_ratio_f_of_temp.setMinimumValueofx(-20.0) htg_energy_input_ratio_f_of_temp.setMaximumValueofx(20.0) htg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) htg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.3824) htg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.4336) htg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0512) htg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.0) htg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.0) htg_part_load_fraction = OpenStudio::Model::CurveQuadratic.new(self) htg_part_load_fraction.setCoefficient1Constant(0.85) htg_part_load_fraction.setCoefficient2x(0.15) htg_part_load_fraction.setCoefficient3xPOW2(0.0) htg_part_load_fraction.setMinimumValueofx(0.0) htg_part_load_fraction.setMaximumValueofx(1.0) htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, htg_cap_f_of_temp, htg_cap_f_of_flow, htg_energy_input_ratio_f_of_temp, htg_energy_input_ratio_f_of_flow, htg_part_load_fraction) htg_coil.setName("#{zone.name} PTHP Htg Coil") # add cooling coil clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.766956) clg_cap_f_of_temp.setCoefficient2x(0.0107756) clg_cap_f_of_temp.setCoefficient3xPOW2(-0.0000414703) clg_cap_f_of_temp.setCoefficient4y(0.00134961) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.000261144) clg_cap_f_of_temp.setCoefficient6xTIMESY(0.000457488) clg_cap_f_of_temp.setMinimumValueofx(12.78) clg_cap_f_of_temp.setMaximumValueofx(23.89) clg_cap_f_of_temp.setMinimumValueofy(21.1) clg_cap_f_of_temp.setMaximumValueofy(46.1) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.8) clg_cap_f_of_flow.setCoefficient2x(0.2) clg_cap_f_of_flow.setCoefficient3xPOW2(0.0) clg_cap_f_of_flow.setMinimumValueofx(0.5) clg_cap_f_of_flow.setMaximumValueofx(1.5) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.297145) clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.0430933) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000748766) clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.00597727) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000482112) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000956448) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(12.78) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(23.89) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(21.1) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.1) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.156) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1816) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.85) clg_part_load_ratio.setCoefficient2x(0.15) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio) clg_coil.setName("#{zone.name} PTAC 1spd DX HP Clg Coil") #clg_coil.setRatedSensibleHeatRatio(0.69) #clg_coil.setBasinHeaterCapacity(10) #clg_coil.setBasinHeaterSetpointTemperature(2.0) # Supplemental heating coil supplemental_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) # Wrap coils in a PTHP system pthp_system = OpenStudio::Model::ZoneHVACPackagedTerminalHeatPump.new(self, self.alwaysOnDiscreteSchedule, fan, htg_coil, clg_coil, supplemental_htg_coil) pthp_system.setName("#{zone.name} PTHP") pthp_system.setFanPlacement("DrawThrough") if fan_type == "ConstantVolume" pthp_system.(self.alwaysOnDiscreteSchedule) elsif fan_type == "Cycling" pthp_system.(always_off) end pthp_system.addToThermalZone(zone) pthps << pthp_system end return pthps end |
#add_pvav(standard, sys_name, thermal_zones, hvac_op_sch, oa_damper_sch, hot_water_loop = nil, return_plenum = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a packaged VAV system and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 870 def add_pvav(standard, sys_name, thermal_zones, hvac_op_sch, oa_damper_sch, hot_water_loop = nil, return_plenum = nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding Packaged VAV for #{thermal_zones.size} zones.") thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Debug, 'openstudio.Model.Model', "---#{zone.name}") end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # Control temps for HW loop # will only be used when hot_water_loop is provided. hw_temp_f = 180 #HW setpoint 180F hw_delta_t_r = 20 #20F delta-T hw_temp_c = OpenStudio.convert(hw_temp_f,'F','C').get hw_delta_t_k = OpenStudio.convert(hw_delta_t_r,'R','K').get # Control temps used across all air handlers # TODO why aren't design and operational temps coordinated? sys_dsn_prhtg_temp_f = 44.6 # Design central deck to preheat to 44.6F sys_dsn_clg_sa_temp_f = 57.2 # Design central deck to cool to 57.2F sys_dsn_htg_sa_temp_f = 62 # Central heat to 62F zn_dsn_clg_sa_temp_f = 55 # Design VAV box for 55F from central deck zn_dsn_htg_sa_temp_f = 122 # Design VAV box to reheat to 122F rht_rated_air_in_temp_f = 62 # Reheat coils designed to receive 62F rht_rated_air_out_temp_f = 90 # Reheat coils designed to supply 90F...but zone expects 122F...? clg_sa_temp_f = 55 # Central deck clg temp operates at 55F sys_dsn_prhtg_temp_c = OpenStudio.convert(sys_dsn_prhtg_temp_f,'F','C').get sys_dsn_clg_sa_temp_c = OpenStudio.convert(sys_dsn_clg_sa_temp_f,'F','C').get sys_dsn_htg_sa_temp_c = OpenStudio.convert(sys_dsn_htg_sa_temp_f,'F','C').get zn_dsn_clg_sa_temp_c = OpenStudio.convert(zn_dsn_clg_sa_temp_f,'F','C').get zn_dsn_htg_sa_temp_c = OpenStudio.convert(zn_dsn_htg_sa_temp_f,'F','C').get rht_rated_air_in_temp_c = OpenStudio.convert(rht_rated_air_in_temp_f,'F','C').get rht_rated_air_out_temp_c = OpenStudio.convert(rht_rated_air_out_temp_f,'F','C').get clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f,'F','C').get sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F") sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default") sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),clg_sa_temp_c) # Air handler air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? sys_name = "#{thermal_zones.size} Zone PVAV" air_loop.setName(sys_name) else air_loop.setName(sys_name) end air_loop.setAvailabilitySchedule(hvac_op_sch) # Air handler controls stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,sa_temp_sch) stpt_manager.addToNode(air_loop.supplyOutletNode) sizing_system = air_loop.sizingSystem # sizing_system.setPreheatDesignTemperature(sys_dsn_prhtg_temp_c) # sizing_system.setCentralCoolingDesignSupplyAirTemperature(sys_dsn_clg_sa_temp_c) sizing_system.setCentralHeatingDesignSupplyAirTemperature(sys_dsn_htg_sa_temp_c) sizing_system.setSizingOption('Coincident') sizing_system.setAllOutdoorAirinCooling(false) sizing_system.setAllOutdoorAirinHeating(false) air_loop.setNightCycleControlType('CycleOnAny') # Fan fan = OpenStudio::Model::FanVariableVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{air_loop.name} Fan") fan.addToNode(air_loop.supplyInletNode) # Heating coil - depends on whether heating is hot water or electric, # which is determined by whether or not a hot water loop is provided. if hot_water_loop.nil? htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{air_loop.name} Main Htg Coil") htg_coil.addToNode(air_loop.supplyInletNode) else htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{air_loop.name} Main Htg Coil") htg_coil.setRatedInletWaterTemperature(hw_temp_c) htg_coil.setRatedInletAirTemperature(rht_rated_air_in_temp_c) htg_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) htg_coil.setRatedOutletAirTemperature(rht_rated_air_out_temp_c) htg_coil.addToNode(air_loop.supplyInletNode) hot_water_loop.addDemandBranchForComponent(htg_coil) end # Cooling coil clg_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(self) clg_coil.setName("#{air_loop.name} Clg Coil") clg_coil.addToNode(air_loop.supplyInletNode) # Outdoor air intake system oa_intake_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_intake = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self, oa_intake_controller) oa_intake.setName("#{air_loop.name} OA Sys") oa_intake_controller.setMinimumLimitType('FixedMinimum') oa_intake_controller.setMinimumOutdoorAirSchedule(oa_damper_sch) oa_intake.addToNode(air_loop.supplyInletNode) controller_mv = oa_intake_controller.controllerMechanicalVentilation controller_mv.setName("#{air_loop.name} Ventilation Controller") # Hook the VAV system to each zone thermal_zones.each do |zone| # Reheat coil rht_coil = nil # sys_name.include? "Outpatient F2 F3" is only for reheat coil of Outpatient Floor2&3 if hot_water_loop.nil? or sys_name.include? "Outpatient F2 F3" rht_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) rht_coil.setName("#{zone.name} Rht Coil") else rht_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) rht_coil.setName("#{zone.name} Rht Coil") rht_coil.setRatedInletWaterTemperature(hw_temp_c) rht_coil.setRatedInletAirTemperature(rht_rated_air_in_temp_c) rht_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) rht_coil.setRatedOutletAirTemperature(rht_rated_air_out_temp_c) hot_water_loop.addDemandBranchForComponent(rht_coil) end # VAV terminal terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(self,self.alwaysOnDiscreteSchedule,rht_coil) terminal.setName("#{zone.name} VAV Term") terminal.setZoneMinimumAirFlowMethod('Constant') terminal.set_initial_prototype_damper_position(standard, zone.outdoor_airflow_rate_per_area) air_loop.addBranchForZone(zone,terminal.to_StraightComponent) unless return_plenum.nil? zone.setReturnPlenum(return_plenum) end # Zone sizing sizing_zone = zone.sizingZone sizing_zone.setZoneCoolingDesignSupplyAirTemperature(zn_dsn_clg_sa_temp_c) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(zn_dsn_htg_sa_temp_c) end # Set the damper action based on the template. air_loop.set_vav_damper_action(standard) return true end |
#add_refrigeration(standard, case_type, cooling_capacity_per_length, length, evaporator_fan_pwr_per_length, lighting_per_length, lighting_sch_name, defrost_pwr_per_length, restocking_sch_name, cop, cop_f_of_t_curve_name, condenser_fan_pwr, condenser_fan_pwr_curve_name, thermal_zone) ⇒ Object
Set compressor properties since prototypes use simple
fix latent case credit curve setter
The legacy prototype IDF files use the simplified
Adds a single refrigerated case connected to a rack composed of a single compressor and a single air-cooled condenser.
Refreigeration:ComprssorRack object, but this object is not included in OpenStudio. Instead, a detailed rack with similar performance is added. refrigeration rack instead of detailed
4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 4156 def add_refrigeration(standard, case_type, cooling_capacity_per_length, length, evaporator_fan_pwr_per_length, lighting_per_length, lighting_sch_name, defrost_pwr_per_length, restocking_sch_name, cop, cop_f_of_t_curve_name, condenser_fan_pwr, condenser_fan_pwr_curve_name, thermal_zone) # Default properties based on the case type # case_type = 'Walkin Freezer', 'Display Case' case_temp = nil latent_heat_ratio = nil runtime_fraction = nil fraction_antisweat_to_case = nil under_case_return_air_fraction = nil latent_case_credit_curve_name = nil defrost_type = nil if case_type == 'Walkin Freezer' case_temp = OpenStudio.convert(-9.4,'F','C').get latent_heat_ratio = 0.1 runtime_fraction = 0.4 fraction_antisweat_to_case = 0.0 under_case_return_air_fraction = 0.0 case standard when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' latent_case_credit_curve_name = 'Single Shelf Horizontal Latent Energy Multiplier_After2004' when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' latent_case_credit_curve_name = 'Single Shelf Horizontal Latent Energy Multiplier_Pre2004' end defrost_type = 'Electric' elsif case_type == 'Display Case' case_temp = OpenStudio.convert(35.6,'F','C').get latent_heat_ratio = 0.08 runtime_fraction = 0.85 fraction_antisweat_to_case = 0.2 under_case_return_air_fraction = 0.05 latent_case_credit_curve_name = 'Multi Shelf Vertical Latent Energy Multiplier' defrost_type = 'None' end OpenStudio::logFree(OpenStudio::Info, "openstudio.model.Model", "Started Adding Refrigeration System") # Defrost schedule defrost_sch = OpenStudio::Model::ScheduleRuleset.new(self) defrost_sch.setName("Refrigeration Defrost Schedule") defrost_sch.defaultDaySchedule.setName("Refrigeration Defrost Schedule Default") if case_type == 'Walkin Freezer' defrost_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,11,0,0), 0) defrost_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,11,20,0), 1) defrost_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,23,0,0), 0) defrost_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,23,20,0), 1) defrost_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0) elsif case_type == 'Display Case' defrost_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,23,20,0), 0) end # Dripdown schedule defrost_dripdown_sch = OpenStudio::Model::ScheduleRuleset.new(self) defrost_dripdown_sch.setName("Refrigeration Defrost DripDown Schedule") defrost_dripdown_sch.defaultDaySchedule.setName("Refrigeration Defrost DripDown Schedule Default") defrost_dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,11,0,0), 0) defrost_dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,11,30,0), 1) defrost_dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,23,0,0), 0) defrost_dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,23,30,0), 1) defrost_dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0) # Case Credit Schedule case_credit_sch = OpenStudio::Model::ScheduleRuleset.new(self) case_credit_sch.setName("Refrigeration Case Credit Schedule") case_credit_sch.defaultDaySchedule.setName("Refrigeration Case Credit Schedule Default") case_credit_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,7,0,0), 0.2) case_credit_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,21,0,0), 0.4) case_credit_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0.2) # Case ref_case = OpenStudio::Model::RefrigerationCase.new(self, defrost_sch) ref_case.setName("#{thermal_zone.name} #{case_type}") ref_case.setAvailabilitySchedule(self.alwaysOnDiscreteSchedule) ref_case.setThermalZone(thermal_zone) ref_case.setRatedTotalCoolingCapacityperUnitLength(cooling_capacity_per_length) ref_case.setCaseLength(length) ref_case.(case_temp) ref_case.setStandardCaseFanPowerperUnitLength(evaporator_fan_pwr_per_length) ref_case.(evaporator_fan_pwr_per_length) ref_case.setStandardCaseLightingPowerperUnitLength(lighting_per_length) ref_case.resetInstalledCaseLightingPowerperUnitLength ref_case.setCaseLightingSchedule(self.add_schedule(lighting_sch_name)) ref_case.setHumidityatZeroAntiSweatHeaterEnergy(0) unless defrost_type == 'None' ref_case.setCaseDefrostType('Electric') ref_case.setCaseDefrostPowerperUnitLength(defrost_pwr_per_length) ref_case.setCaseDefrostDripDownSchedule(defrost_dripdown_sch) end ref_case.setUnderCaseHVACReturnAirFraction(under_case_return_air_fraction) ref_case.setFractionofAntiSweatHeaterEnergytoCase(fraction_antisweat_to_case) ref_case.resetDesignEvaporatorTemperatureorBrineInletTemperature ref_case.setRatedAmbientTemperature(OpenStudio.convert(75,'F','C').get) ref_case.setRatedLatentHeatRatio(latent_heat_ratio) ref_case.setRatedRuntimeFraction(runtime_fraction) #TODO enable ref_case.setLatentCaseCreditCurve(self.add_curve(latent_case_credit_curve_name)) ref_case.setLatentCaseCreditCurve(self.add_curve(latent_case_credit_curve_name)) ref_case.setCaseHeight(0) # TODO: setRefrigeratedCaseRestockingSchedule is not working ref_case.setRefrigeratedCaseRestockingSchedule(self.add_schedule(restocking_sch_name)) if case_type == 'Walkin Freezer' ref_case.setCaseCreditFractionSchedule(case_credit_sch) end # Compressor # TODO set compressor properties since prototypes use simple # refrigeration rack instead of detailed compressor = OpenStudio::Model::RefrigerationCompressor.new(self) # Condenser condenser = OpenStudio::Model::RefrigerationCondenserAirCooled.new(self) condenser.setRatedFanPower(condenser_fan_pwr) # Refrigeration system ref_sys = OpenStudio::Model::RefrigerationSystem.new(self) ref_sys.addCompressor(compressor) ref_sys.addCase(ref_case) ref_sys.setRefrigerationCondenser(condenser) ref_sys.setSuctionPipingZone(thermal_zone) OpenStudio::logFree(OpenStudio::Info, "openstudio.model.Model", "Finished adding Refrigeration System") return true end |
#add_schedule(schedule_name) ⇒ ScheduleRuleset
make return an OptionalScheduleRuleset
Create a schedule from the openstudio standards dataset and add it to the model.
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1802 def add_schedule(schedule_name) return nil if schedule_name == nil or schedule_name == "" # First check model and return schedule if it already exists self.getSchedules.each do |schedule| if schedule.name.get.to_s == schedule_name OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "Already added schedule: #{schedule_name}") return schedule end end require 'date' #OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Adding schedule: #{schedule_name}") # Find all the schedule rules that match the name rules = self.find_objects($os_standards['schedules'], {'name'=>schedule_name}) if rules.size == 0 OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Cannot find data for schedule: #{schedule_name}, will not be created.") return false #TODO change to return empty optional schedule:ruleset? end # Helper method to fill in hourly values def add_vals_to_sch(day_sch, sch_type, values) if sch_type == "Constant" day_sch.addValue(OpenStudio::Time.new(0, 24, 0, 0), values[0]) elsif sch_type == "Hourly" for i in 0..23 next if values[i] == values[i + 1] day_sch.addValue(OpenStudio::Time.new(0, i + 1, 0, 0), values[i]) end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Schedule type: #{sch_type} is not recognized. Valid choices are 'Constant' and 'Hourly'.") end end # Make a schedule ruleset sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(self) sch_ruleset.setName("#{schedule_name}") # Loop through the rules, making one for each row in the spreadsheet rules.each do |rule| day_types = rule['day_types'] start_date = DateTime.parse(rule['start_date']) end_date = DateTime.parse(rule['end_date']) sch_type = rule['type'] values = rule['values'] #Day Type choices: Wkdy, Wknd, Mon, Tue, Wed, Thu, Fri, Sat, Sun, WntrDsn, SmrDsn, Hol # Default if day_types.include?('Default') day_sch = sch_ruleset.defaultDaySchedule day_sch.setName("#{schedule_name} Default") add_vals_to_sch(day_sch, sch_type, values) end # Winter Design Day if day_types.include?('WntrDsn') day_sch = OpenStudio::Model::ScheduleDay.new(self) sch_ruleset.setWinterDesignDaySchedule(day_sch) day_sch = sch_ruleset.winterDesignDaySchedule day_sch.setName("#{schedule_name} Winter Design Day") add_vals_to_sch(day_sch, sch_type, values) end # Summer Design Day if day_types.include?('SmrDsn') day_sch = OpenStudio::Model::ScheduleDay.new(self) sch_ruleset.setSummerDesignDaySchedule(day_sch) day_sch = sch_ruleset.summerDesignDaySchedule day_sch.setName("#{schedule_name} Summer Design Day") add_vals_to_sch(day_sch, sch_type, values) end # Other days (weekdays, weekends, etc) if day_types.include?('Wknd') || day_types.include?('Wkdy') || day_types.include?('Sat') || day_types.include?('Sun') || day_types.include?('Mon') || day_types.include?('Tue') || day_types.include?('Wed') || day_types.include?('Thu') || day_types.include?('Fri') # Make the Rule sch_rule = OpenStudio::Model::ScheduleRule.new(sch_ruleset) day_sch = sch_rule.daySchedule day_sch.setName("#{schedule_name} #{day_types} Day") add_vals_to_sch(day_sch, sch_type, values) # Set the dates when the rule applies sch_rule.setStartDate(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(start_date.month.to_i), start_date.day.to_i)) sch_rule.setEndDate(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(end_date.month.to_i), end_date.day.to_i)) # Set the days when the rule applies # Weekends if day_types.include?('Wknd') sch_rule.setApplySaturday(true) sch_rule.setApplySunday(true) end # Weekdays if day_types.include?('Wkdy') sch_rule.setApplyMonday(true) sch_rule.setApplyTuesday(true) sch_rule.setApplyWednesday(true) sch_rule.setApplyThursday(true) sch_rule.setApplyFriday(true) end # Individual Days sch_rule.setApplyMonday(true) if day_types.include?('Mon') sch_rule.setApplyTuesday(true) if day_types.include?('Tue') sch_rule.setApplyWednesday(true) if day_types.include?('Wed') sch_rule.setApplyThursday(true) if day_types.include?('Thu') sch_rule.setApplyFriday(true) if day_types.include?('Fri') sch_rule.setApplySaturday(true) if day_types.include?('Sat') sch_rule.setApplySunday(true) if day_types.include?('Sun') end end # Next rule return sch_ruleset end |
#add_split_AC(standard, sys_name, thermal_zones, hvac_op_sch, alt_hvac_op_sch, oa_damper_sch, fan_type, heating_type, supplemental_heating_type, cooling_type, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a split DX AC system for each zone and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open Single Speed DX AC, Single Speed Heat Pump
2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 2131 def add_split_AC(standard, sys_name, thermal_zones, hvac_op_sch, alt_hvac_op_sch, oa_damper_sch, fan_type, heating_type, supplemental_heating_type, cooling_type, building_type=nil) thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding split DX AC for #{zone.name}.") end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # alternate hvac operation schedule if alt_hvac_op_sch.nil? alt_hvac_op_sch = self.alwaysOnDiscreteSchedule else alt_hvac_op_sch = self.add_schedule(alt_hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # OA_controller Maximum OA Fraction schedule econ_MaxOAFrac_Sch = self.add_schedule("HotelSmall SAC_Econ_MaxOAFrac_Sch") # Make a SAC for each group of thermal zones parts = [] space_type_names = [] thermal_zones.each do |zone| name = zone.name parts << name.get #get space types zone.spaces.each do |space| space_type_name = space.spaceType.get.standardsSpaceType.get space_type_names << space_type_name end # Zone sizing sizing_zone = zone.sizingZone sizing_zone.setZoneCoolingDesignSupplyAirTemperature(14) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(50.0) sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008) sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008) end thermal_zone_name = parts.join(' - ') # Meeting room cycling fan schedule if space_type_names.include? 'Meeting' hvac_op_sch = alt_hvac_op_sch end air_loop = OpenStudio::Model::AirLoopHVAC.new(self) air_loop.setName("#{thermal_zone_name} SAC") air_loop.setAvailabilitySchedule(hvac_op_sch) # When an air_loop is contructed, its constructor creates a sizing:system object # the default sizing:system contstructor makes a system:sizing object # appropriate for a multizone VAV system # this systems is a constant volume system with no VAV terminals, # and therfore needs different default settings air_loop_sizing = air_loop.sizingSystem # TODO units air_loop_sizing.setTypeofLoadtoSizeOn("Sensible") air_loop_sizing.autosizeDesignOutdoorAirFlowRate air_loop_sizing.setMinimumSystemAirFlowRatio(1.0) air_loop_sizing.setPreheatDesignTemperature(7.0) air_loop_sizing.setPreheatDesignHumidityRatio(0.008) air_loop_sizing.setPrecoolDesignTemperature(11) air_loop_sizing.setPrecoolDesignHumidityRatio(0.008) air_loop_sizing.setCentralCoolingDesignSupplyAirTemperature(12) air_loop_sizing.setCentralHeatingDesignSupplyAirTemperature(50) air_loop_sizing.setSizingOption("NonCoincident") air_loop_sizing.setAllOutdoorAirinCooling(false) air_loop_sizing.setAllOutdoorAirinHeating(false) air_loop_sizing.setCentralCoolingDesignSupplyAirHumidityRatio(0.008) air_loop_sizing.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080) air_loop_sizing.setCoolingDesignAirFlowMethod("DesignDay") air_loop_sizing.setCoolingDesignAirFlowRate(0.0) air_loop_sizing.setHeatingDesignAirFlowMethod("DesignDay") air_loop_sizing.setHeatingDesignAirFlowRate(0.0) air_loop_sizing.setSystemOutdoorAirMethod("ZoneSum") # Add a setpoint manager single zone reheat to control the # supply air temperature based on the needs of this zone controlzone = thermal_zones[0] setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(self) setpoint_mgr_single_zone_reheat.setControlZone(controlzone) # Fan fan = nil if fan_type == "ConstantVolume" fan = OpenStudio::Model::FanConstantVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{thermal_zone_name} SAC Fan") fan_static_pressure_in_h2o = 2.5 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, "inH_{2}O","Pa").get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.56) # get the average of four fans fan.setMotorEfficiency(0.86) # get the average of four fans elsif fan_type == "Cycling" fan = OpenStudio::Model::FanOnOff.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{thermal_zone_name} SAC Fan") fan_static_pressure_in_h2o = 2.5 fan_static_pressure_pa = OpenStudio.convert(fan_static_pressure_in_h2o, "inH_{2}O","Pa").get fan.setPressureRise(fan_static_pressure_pa) fan.setFanEfficiency(0.53625) fan.setMotorEfficiency(0.825) end # Heating Coil htg_coil = nil if heating_type == "Gas" htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{thermal_zone_name} SAC Gas Htg Coil") htg_coil.setGasBurnerEfficiency(0.8) htg_part_load_fraction_correlation = OpenStudio::Model::CurveCubic.new(self) htg_part_load_fraction_correlation.setCoefficient1Constant(0.8) htg_part_load_fraction_correlation.setCoefficient2x(0.2) htg_part_load_fraction_correlation.setCoefficient3xPOW2(0) htg_part_load_fraction_correlation.setCoefficient4xPOW3(0) htg_part_load_fraction_correlation.setMinimumValueofx(0) htg_part_load_fraction_correlation.setMaximumValueofx(1) htg_coil.setPartLoadFractionCorrelationCurve(htg_part_load_fraction_correlation) elsif heating_type == "Single Speed Heat Pump" htg_cap_f_of_temp = OpenStudio::Model::CurveCubic.new(self) htg_cap_f_of_temp.setCoefficient1Constant(0.758746) htg_cap_f_of_temp.setCoefficient2x(0.027626) htg_cap_f_of_temp.setCoefficient3xPOW2(0.000148716) htg_cap_f_of_temp.setCoefficient4xPOW3(0.0000034992) htg_cap_f_of_temp.setMinimumValueofx(-20.0) htg_cap_f_of_temp.setMaximumValueofx(20.0) htg_cap_f_of_flow = OpenStudio::Model::CurveCubic.new(self) htg_cap_f_of_flow.setCoefficient1Constant(0.84) htg_cap_f_of_flow.setCoefficient2x(0.16) htg_cap_f_of_flow.setCoefficient3xPOW2(0.0) htg_cap_f_of_flow.setCoefficient4xPOW3(0.0) htg_cap_f_of_flow.setMinimumValueofx(0.5) htg_cap_f_of_flow.setMaximumValueofx(1.5) htg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveCubic.new(self) htg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.19248) htg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.0300438) htg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00103745) htg_energy_input_ratio_f_of_temp.setCoefficient4xPOW3(-0.000023328) htg_energy_input_ratio_f_of_temp.setMinimumValueofx(-20.0) htg_energy_input_ratio_f_of_temp.setMaximumValueofx(20.0) htg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) htg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.3824) htg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.4336) htg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0512) htg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.0) htg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.0) htg_part_load_fraction = OpenStudio::Model::CurveQuadratic.new(self) htg_part_load_fraction.setCoefficient1Constant(0.85) htg_part_load_fraction.setCoefficient2x(0.15) htg_part_load_fraction.setCoefficient3xPOW2(0.0) htg_part_load_fraction.setMinimumValueofx(0.0) htg_part_load_fraction.setMaximumValueofx(1.0) htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, htg_cap_f_of_temp, htg_cap_f_of_flow, htg_energy_input_ratio_f_of_temp, htg_energy_input_ratio_f_of_flow, htg_part_load_fraction) htg_coil.setName("#{thermal_zone_name} SAC HP Htg Coil") end # Supplemental Heating Coil supplemental_htg_coil = nil if supplemental_heating_type == "Electric" supplemental_htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) supplemental_htg_coil.setName("#{thermal_zone_name} PSZ-AC Electric Backup Htg Coil") elsif supplemental_heating_type == "Gas" supplemental_htg_coil = OpenStudio::Model::CoilHeatingGas.new(self,self.alwaysOnDiscreteSchedule) supplemental_htg_coil.setName("#{thermal_zone_name} PSZ-AC Gas Backup Htg Coil") end # Cooling Coil clg_coil = nil if cooling_type == "Two Speed DX AC" clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.42415) clg_cap_f_of_temp.setCoefficient2x(0.04426) clg_cap_f_of_temp.setCoefficient3xPOW2(-0.00042) clg_cap_f_of_temp.setCoefficient4y(0.00333) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.00008) clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.00021) clg_cap_f_of_temp.setMinimumValueofx(17.0) clg_cap_f_of_temp.setMaximumValueofx(22.0) clg_cap_f_of_temp.setMinimumValueofy(13.0) clg_cap_f_of_temp.setMaximumValueofy(46.0) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.77136) clg_cap_f_of_flow.setCoefficient2x(0.34053) clg_cap_f_of_flow.setCoefficient3xPOW2(-0.11088) clg_cap_f_of_flow.setMinimumValueofx(0.75918) clg_cap_f_of_flow.setMaximumValueofx(1.13877) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.23649) clg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.02431) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00057) clg_energy_input_ratio_f_of_temp.setCoefficient4y(-0.01434) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.00063) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.00038) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.20550) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.32953) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.12308) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.75918) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.13877) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.77100) clg_part_load_ratio.setCoefficient2x(0.22900) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_cap_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp_low_spd.setCoefficient1Constant(0.42415) clg_cap_f_of_temp_low_spd.setCoefficient2x(0.04426) clg_cap_f_of_temp_low_spd.setCoefficient3xPOW2(-0.00042) clg_cap_f_of_temp_low_spd.setCoefficient4y(0.00333) clg_cap_f_of_temp_low_spd.setCoefficient5yPOW2(-0.00008) clg_cap_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00021) clg_cap_f_of_temp_low_spd.setMinimumValueofx(17.0) clg_cap_f_of_temp_low_spd.setMaximumValueofx(22.0) clg_cap_f_of_temp_low_spd.setMinimumValueofy(13.0) clg_cap_f_of_temp_low_spd.setMaximumValueofy(46.0) clg_energy_input_ratio_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient1Constant(1.23649) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient2x(-0.02431) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient3xPOW2(0.00057) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient4y(-0.01434) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient5yPOW2(0.00063) clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00038) clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofx(17.0) clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofx(22.0) clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofy(13.0) clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofy(46.0) clg_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio, clg_cap_f_of_temp_low_spd, clg_energy_input_ratio_f_of_temp_low_spd) clg_coil.setName("#{thermal_zone_name} SAC 2spd DX AC Clg Coil") clg_coil.setRatedLowSpeedSensibleHeatRatio(OpenStudio::OptionalDouble.new(0.69)) clg_coil.setBasinHeaterCapacity(10) clg_coil.setBasinHeaterSetpointTemperature(2.0) elsif cooling_type == "Single Speed DX AC" clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.942587793) clg_cap_f_of_temp.setCoefficient2x(0.009543347) clg_cap_f_of_temp.setCoefficient3xPOW2(0.00068377) clg_cap_f_of_temp.setCoefficient4y(-0.011042676) clg_cap_f_of_temp.setCoefficient5yPOW2(0.000005249) clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.00000972) clg_cap_f_of_temp.setMinimumValueofx(12.77778) clg_cap_f_of_temp.setMaximumValueofx(23.88889) clg_cap_f_of_temp.setMinimumValueofy(23.88889) clg_cap_f_of_temp.setMaximumValueofy(46.11111) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.8) clg_cap_f_of_flow.setCoefficient2x(0.2) clg_cap_f_of_flow.setCoefficient3xPOW2(0) clg_cap_f_of_flow.setMinimumValueofx(0.5) clg_cap_f_of_flow.setMaximumValueofx(1.5) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.342414409) clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.034885008) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.0006237) clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.004977216) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000437951) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000728028) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(12.77778) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(23.88889) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(23.88889) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.11111) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.1552) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1808) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.85) clg_part_load_ratio.setCoefficient2x(0.15) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_part_load_ratio.setMinimumCurveOutput(0.7) clg_part_load_ratio.setMaximumCurveOutput(1.0) clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio) clg_coil.setName("#{thermal_zone_name} SAC 1spd DX AC Clg Coil") elsif cooling_type == "Single Speed Heat Pump" clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_cap_f_of_temp.setCoefficient1Constant(0.766956) clg_cap_f_of_temp.setCoefficient2x(0.0107756) clg_cap_f_of_temp.setCoefficient3xPOW2(-0.0000414703) clg_cap_f_of_temp.setCoefficient4y(0.00134961) clg_cap_f_of_temp.setCoefficient5yPOW2(-0.000261144) clg_cap_f_of_temp.setCoefficient6xTIMESY(0.000457488) clg_cap_f_of_temp.setMinimumValueofx(12.78) clg_cap_f_of_temp.setMaximumValueofx(23.89) clg_cap_f_of_temp.setMinimumValueofy(21.1) clg_cap_f_of_temp.setMaximumValueofy(46.1) clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_cap_f_of_flow.setCoefficient1Constant(0.8) clg_cap_f_of_flow.setCoefficient2x(0.2) clg_cap_f_of_flow.setCoefficient3xPOW2(0.0) clg_cap_f_of_flow.setMinimumValueofx(0.5) clg_cap_f_of_flow.setMaximumValueofx(1.5) clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(self) clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.297145) clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.0430933) clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000748766) clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.00597727) clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000482112) clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000956448) clg_energy_input_ratio_f_of_temp.setMinimumValueofx(12.78) clg_energy_input_ratio_f_of_temp.setMaximumValueofx(23.89) clg_energy_input_ratio_f_of_temp.setMinimumValueofy(21.1) clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.1) clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(self) clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.156) clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1816) clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256) clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5) clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5) clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(self) clg_part_load_ratio.setCoefficient1Constant(0.85) clg_part_load_ratio.setCoefficient2x(0.15) clg_part_load_ratio.setCoefficient3xPOW2(0.0) clg_part_load_ratio.setMinimumValueofx(0.0) clg_part_load_ratio.setMaximumValueofx(1.0) clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(self, self.alwaysOnDiscreteSchedule, clg_cap_f_of_temp, clg_cap_f_of_flow, clg_energy_input_ratio_f_of_temp, clg_energy_input_ratio_f_of_flow, clg_part_load_ratio) clg_coil.setName("#{thermal_zone_name} SAC 1spd DX HP Clg Coil") #clg_coil.setRatedSensibleHeatRatio(0.69) #clg_coil.setBasinHeaterCapacity(10) #clg_coil.setBasinHeaterSetpointTemperature(2.0) end oa_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_controller.setName("#{thermal_zone_name} SAC OA Sys Controller") oa_controller.setMinimumOutdoorAirSchedule(oa_damper_sch) oa_controller.setMaximumFractionofOutdoorAirSchedule(econ_MaxOAFrac_Sch) oa_system = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self,oa_controller) oa_system.setName("#{thermal_zone_name} SAC OA Sys") # Add the components to the air loop # in order from closest to zone to furthest from zone supply_inlet_node = air_loop.supplyInletNode # Add the fan unless fan.nil? fan.addToNode(supply_inlet_node) end # Add the supplemental heating coil unless supplemental_htg_coil.nil? supplemental_htg_coil.addToNode(supply_inlet_node) end # Add the heating coil unless htg_coil.nil? htg_coil.addToNode(supply_inlet_node) end # Add the cooling coil unless clg_coil.nil? clg_coil.addToNode(supply_inlet_node) end setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(55.4,"F","C").get) setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(113,"F","C").get) setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode) # Add the OA system oa_system.addToNode(supply_inlet_node) # Create a diffuser and attach the zone/diffuser pair to the air loop thermal_zones.each do |zone| diffuser = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(self,self.alwaysOnDiscreteSchedule) diffuser.setName("#{zone.name} SAC Diffuser") air_loop.addBranchForZone(zone,diffuser.to_StraightComponent) end return air_loop end |
#add_swh(building_type, building_vintage, climate_zone, prototype_input, hvac_standards) ⇒ Object
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 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.swh.rb', line 5 def add_swh(building_type, building_vintage, climate_zone, prototype_input) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding Service Water Heating') # Add the main service water heating loop, if specified unless prototype_input['main_water_heater_volume'].nil? # Add the main service water loop main_swh_loop = self.add_swh_loop(building_vintage, 'Main Service Water Loop', nil, OpenStudio.convert(prototype_input['main_service_water_temperature'],'F','C').get, prototype_input['main_service_water_pump_head'], prototype_input['main_service_water_pump_motor_efficiency'], OpenStudio.convert(prototype_input['main_water_heater_capacity'],'Btu/hr','W').get, OpenStudio.convert(prototype_input['main_water_heater_volume'],'gal','m^3').get, prototype_input['main_water_heater_fuel'], OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'],'Btu/hr','W').get, building_type) unless building_type == 'RetailStripmall' # Attach the end uses if specified in prototype inputs # TODO remove special logic for large office SWH end uses # TODO remove special logic for stripmall SWH end uses and service water loops # TODO remove special logic for large hotel SWH end uses if building_type == 'LargeOffice' # Only the core spaces have service water ['Core_bottom', 'Core_mid', 'Core_top'].each do |space_name| self.add_swh_end_uses(building_vintage, 'Main', main_swh_loop, OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'],'gal/min','m^3/s').get, prototype_input['main_service_water_flowrate_schedule'], OpenStudio.convert(prototype_input['main_water_use_temperature'],'F','C').get, space_name, building_type) end elsif building_type == 'RetailStripmall' return true if building_vintage == "DOE Ref Pre-1980" || building_vintage == "DOE Ref 1980-2004" # Create a separate hot water loop & water heater for each space in the list swh_space_names = ["LGstore1","SMstore1","SMstore2","SMstore3","LGstore2","SMstore5","SMstore6"] swh_sch_names = ["RetailStripmall Type1_SWH_SCH","RetailStripmall Type1_SWH_SCH","RetailStripmall Type2_SWH_SCH", "RetailStripmall Type2_SWH_SCH","RetailStripmall Type3_SWH_SCH","RetailStripmall Type3_SWH_SCH", "RetailStripmall Type3_SWH_SCH"] rated_use_rate_gal_per_min = 0.03 # in gal/min rated_flow_rate_m3_per_s = OpenStudio.convert(rated_use_rate_gal_per_min,'gal/min','m^3/s').get # Loop through all spaces swh_space_names.zip(swh_sch_names).each do |swh_space_name, swh_sch_name| swh_thermal_zone = self.getSpaceByName(swh_space_name).get.thermalZone.get main_swh_loop = self.add_swh_loop(building_vintage, "#{swh_thermal_zone.name} Service Water Loop", swh_thermal_zone, OpenStudio.convert(prototype_input['main_service_water_temperature'],'F','C').get, prototype_input['main_service_water_pump_head'], prototype_input['main_service_water_pump_motor_efficiency'], OpenStudio.convert(prototype_input['main_water_heater_capacity'],'Btu/hr','W').get, OpenStudio.convert(prototype_input['main_water_heater_volume'],'gal','m^3').get, prototype_input['main_water_heater_fuel'], OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'],'Btu/hr','W').get, building_type) self.add_swh_end_uses(building_vintage, 'Main', main_swh_loop, rated_flow_rate_m3_per_s, swh_sch_name, OpenStudio.convert(prototype_input['main_water_use_temperature'],'F','C').get, swh_space_name, building_type) end elsif building_type == 'LargeHotel' # Add water use equipment to each space guess_room_water_use_schedule = "HotelLarge GuestRoom_SWH_Sch" kitchen_water_use_schedule = "HotelLarge BLDG_SWH_SCH" water_end_uses = [] space_type_map = self.define_space_type_map(building_type, building_vintage, climate_zone) space_multipliers = define_space_multiplier kitchen_space_types = ['Kitchen'] kitchen_space_use_rate = 2.22 # gal/min, from PNNL prototype building guess_room_water_use_rate = 0.020833333 # gal/min, Reference: NREL Reference building report 5.1.6 # Create a list of water use rates and associated room multipliers case building_vintage when "90.1-2004", "90.1-2007", "90.1-2010", "90.1-2013" guess_room_space_types =['GuestRoom','GuestRoom2','GuestRoom3','GuestRoom4'] else guess_room_space_types =['GuestRoom','GuestRoom3'] guess_room_space_types1 = ['GuestRoom2'] guess_room_space_types2 = ['GuestRoom4'] guess_room_water_use_rate1 = 0.395761032 # gal/min, Reference building guess_room_water_use_rate2 = 0.187465752 # gal/min, Reference building laundry_water_use_schedule = "HotelLarge LaundryRoom_Eqp_Elec_Sch" laundry_space_types = ['Laundry'] laundry_room_water_use_rate = 2.6108244 # gal/min, Reference building guess_room_space_types1.each do |space_type| space_names = space_type_map[space_type] space_names.each do |space_name| space_multiplier = 1 space_multiplier= space_multipliers[space_name].to_i if space_multipliers[space_name] != nil water_end_uses.push([space_name, guess_room_water_use_rate1 * space_multiplier,guess_room_water_use_schedule]) end end guess_room_space_types2.each do |space_type| space_names = space_type_map[space_type] space_names.each do |space_name| space_multiplier = 1 space_multiplier= space_multipliers[space_name].to_i if space_multipliers[space_name] != nil water_end_uses.push([space_name, guess_room_water_use_rate2 * space_multiplier,guess_room_water_use_schedule]) end end laundry_space_types.each do |space_type| space_names = space_type_map[space_type] space_names.each do |space_name| space_multiplier = 1 space_multiplier= space_multipliers[space_name].to_i if space_multipliers[space_name] != nil water_end_uses.push([space_name, laundry_room_water_use_rate * space_multiplier,laundry_water_use_schedule]) end end end guess_room_space_types.each do |space_type| space_names = space_type_map[space_type] space_names.each do |space_name| space_multiplier = 1 space_multiplier= space_multipliers[space_name].to_i if space_multipliers[space_name] != nil water_end_uses.push([space_name, guess_room_water_use_rate * space_multiplier,guess_room_water_use_schedule]) end end kitchen_space_types.each do |space_type| space_names = space_type_map[space_type] space_names.each do |space_name| space_multiplier = 1 space_multiplier= space_multipliers[space_name].to_i if space_multipliers[space_name] != nil water_end_uses.push([space_name, kitchen_space_use_rate * space_multiplier,kitchen_water_use_schedule]) end end # Connect the water use equipment to the loop water_end_uses.each do |water_end_use| space_name = water_end_use[0] use_rate = water_end_use[1] # in gal/min use_schedule = water_end_use[2] self.add_swh_end_uses(building_vintage, 'Main', main_swh_loop, OpenStudio.convert(use_rate,'gal/min','m^3/s').get, use_schedule, OpenStudio.convert(prototype_input['main_water_use_temperature'],'F','C').get, space_name, building_type) end elsif prototype_input['main_service_water_peak_flowrate'] # Attaches the end uses if specified as a lump value in the prototype_input self.add_swh_end_uses(building_vintage, 'Main', main_swh_loop, OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'],'gal/min','m^3/s').get, prototype_input['main_service_water_flowrate_schedule'], OpenStudio.convert(prototype_input['main_water_use_temperature'],'F','C').get, nil, building_type) else # Attaches the end uses if specified by space type space_type_map = self.define_space_type_map(building_type, building_vintage, climate_zone) space_type_map.each do |space_type_name, space_names| search_criteria = { 'template' => building_vintage, 'building_type' => building_type, 'space_type' => space_type_name } data = find_object($os_standards['space_types'],search_criteria) # Skip space types with no data next if data.nil? # Skip space types with no water use next if data['service_water_heating_peak_flow_rate'].nil? # Add a service water use for each space space_names.each do |space_name| space = self.getSpaceByName(space_name).get space_multiplier = space.multiplier self.add_swh_end_uses_by_space(building_type, building_vintage, climate_zone, main_swh_loop, space_type_name, space_name, space_multiplier) end end end end # Add the booster water heater, if specified unless prototype_input['booster_water_heater_volume'].nil? # Add the booster water loop swh_booster_loop = self.add_swh_booster(building_vintage, main_swh_loop, OpenStudio.convert(prototype_input['booster_water_heater_capacity'],'Btu/hr','W').get, OpenStudio.convert(prototype_input['booster_water_heater_volume'],'gal','m^3').get, prototype_input['booster_water_heater_fuel'], OpenStudio.convert(prototype_input['booster_water_temperature'],'F','C').get, 0, nil, building_type) # Attach the end uses self.add_booster_swh_end_uses(building_vintage, swh_booster_loop, OpenStudio.convert(prototype_input['booster_service_water_peak_flowrate'],'gal/min','m^3/s').get, prototype_input['booster_service_water_flowrate_schedule'], OpenStudio.convert(prototype_input['booster_water_use_temperature'],'F','C').get, building_type) end # Add the laundry water heater, if specified unless prototype_input['laundry_water_heater_volume'].nil? # Add the laundry service water heating loop laundry_swh_loop = self.add_swh_loop(building_vintage, 'Laundry Service Water Loop', nil, OpenStudio.convert(prototype_input['laundry_service_water_temperature'],'F','C').get, prototype_input['laundry_service_water_pump_head'], prototype_input['laundry_service_water_pump_motor_efficiency'], OpenStudio.convert(prototype_input['laundry_water_heater_capacity'],'Btu/hr','W').get, OpenStudio.convert(prototype_input['laundry_water_heater_volume'],'gal','m^3').get, prototype_input['laundry_water_heater_fuel'], OpenStudio.convert(prototype_input['laundry_service_water_parasitic_fuel_consumption_rate'],'Btu/hr','W').get, building_type) # Attach the end uses if specified in prototype inputs self.add_swh_end_uses(building_vintage, 'Laundry', laundry_swh_loop, OpenStudio.convert(prototype_input['laundry_service_water_peak_flowrate'],'gal/min','m^3/s').get, prototype_input['laundry_service_water_flowrate_schedule'], OpenStudio.convert(prototype_input['laundry_water_use_temperature'],'F','C').get, nil, building_type) end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding Service Water Heating') return true end |
#add_swh_booster(standard, main_service_water_loop, water_heater_capacity, water_heater_volume, water_heater_fuel, booster_water_temperature, parasitic_fuel_consumption_rate, booster_water_heater_thermal_zone, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a booster water heater and attaches it to the supplied service water heating loop.
90.1-2007, 90.1-2010, 90.1-2013 the main service water loop that this booster assists. Gas, Electric fuel consumption rate, in W zones to place water heater in. If nil, will be assumed in 70F air for heat loss.
the resulting booster water loop.
3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3459 def add_swh_booster(standard, main_service_water_loop, water_heater_capacity, water_heater_volume, water_heater_fuel, booster_water_temperature, parasitic_fuel_consumption_rate, booster_water_heater_thermal_zone, building_type = nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding booster water heater to #{main_service_water_loop.name}.") # Booster water heating loop booster_service_water_loop = OpenStudio::Model::PlantLoop.new(self) booster_service_water_loop.setName('Service Water Loop') # Temperature schedule type limits temp_sch_type_limits = OpenStudio::Model::ScheduleTypeLimits.new(self) temp_sch_type_limits.setName('Temperature Schedule Type Limits') temp_sch_type_limits.setLowerLimitValue(0.0) temp_sch_type_limits.setUpperLimitValue(100.0) temp_sch_type_limits.setNumericType('Continuous') temp_sch_type_limits.setUnitType('Temperature') # Service water heating loop controls swh_temp_c = booster_water_temperature swh_temp_f = OpenStudio.convert(swh_temp_c,'C','F').get swh_delta_t_r = 9 #9F delta-T swh_delta_t_k = OpenStudio.convert(swh_delta_t_r,'R','K').get swh_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) swh_temp_sch.setName("Service Water Booster Temp - #{swh_temp_f}F") swh_temp_sch.defaultDaySchedule().setName("Service Water Booster Temp - #{swh_temp_f}F Default") swh_temp_sch.defaultDaySchedule().addValue(OpenStudio::Time.new(0,24,0,0),swh_temp_c) swh_temp_sch.setScheduleTypeLimits(temp_sch_type_limits) swh_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,swh_temp_sch) swh_stpt_manager.setName("Hot water booster setpoint manager") swh_stpt_manager.addToNode(booster_service_water_loop.supplyOutletNode) sizing_plant = booster_service_water_loop.sizingPlant sizing_plant.setLoopType('Heating') sizing_plant.setDesignLoopExitTemperature(swh_temp_c) sizing_plant.setLoopDesignTemperatureDifference(swh_delta_t_k) # Booster water heating pump swh_pump = OpenStudio::Model::PumpConstantSpeed.new(self) swh_pump.setName('Booster Water Loop Pump') swh_pump_head_press_pa = 0.0 # As if there is no circulation pump swh_pump.setRatedPumpHead(swh_pump_head_press_pa) swh_pump.setMotorEfficiency(1) swh_pump.setPumpControlType('Intermittent') swh_pump.addToNode(booster_service_water_loop.supplyInletNode) # Water heater # TODO Standards - Change water heater methodology to follow # 'Model Enhancements Appendix A.' water_heater_capacity_btu_per_hr = OpenStudio.convert(water_heater_capacity, "W", "Btu/hr").get water_heater_capacity_kbtu_per_hr = OpenStudio.convert(water_heater_capacity_btu_per_hr, "Btu/hr", "kBtu/hr").get water_heater_vol_gal = OpenStudio.convert(water_heater_volume,'m^3','gal').get # Water heater depends on the fuel type water_heater = OpenStudio::Model::WaterHeaterMixed.new(self) water_heater.setName("#{water_heater_vol_gal}gal #{water_heater_fuel} Booster Water Heater - #{water_heater_capacity_kbtu_per_hr.round}kBtu/hr") water_heater.setTankVolume(OpenStudio.convert(water_heater_vol_gal,'gal','m^3').get) water_heater.setSetpointTemperatureSchedule(swh_temp_sch) if booster_water_heater_thermal_zone.nil? # Assume the water heater is indoors at 70F for now default_water_heater_ambient_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) default_water_heater_ambient_temp_sch.setName('Water Heater Ambient Temp Schedule - 70F') default_water_heater_ambient_temp_sch.defaultDaySchedule.setName('Water Heater Ambient Temp Schedule - 70F Default') default_water_heater_ambient_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),OpenStudio::convert(70,"F","C").get) default_water_heater_ambient_temp_sch.setScheduleTypeLimits(temp_sch_type_limits) water_heater.setAmbientTemperatureIndicator('Schedule') water_heater.setAmbientTemperatureSchedule(default_water_heater_ambient_temp_sch) else water_heater.setAmbientTemperatureIndicator('ThermalZone') water_heater.setAmbientTemperatureThermalZone booster_water_heater_thermal_zone end water_heater.setMaximumTemperatureLimit(OpenStudio::convert(180,'F','C').get) water_heater.setDeadbandTemperatureDifference(OpenStudio.convert(3.6,'R','K').get) water_heater.setHeaterControlType('Cycle') water_heater.setHeaterMaximumCapacity(OpenStudio.convert(water_heater_capacity_btu_per_hr,'Btu/hr','W').get) water_heater.setOffCycleParasiticHeatFractiontoTank(0.8) water_heater.setIndirectWaterHeatingRecoveryTime(1.5) # 1.5hrs if water_heater_fuel == 'Electricity' water_heater.setHeaterFuelType('Electricity') water_heater.setHeaterThermalEfficiency(1.0) water_heater.setOffCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOnCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOffCycleParasiticFuelType('Electricity') water_heater.setOnCycleParasiticFuelType('Electricity') water_heater.setOffCycleLossCoefficienttoAmbientTemperature(1.053) water_heater.setOnCycleLossCoefficienttoAmbientTemperature(1.053) elsif water_heater_fuel == 'Natural Gas' water_heater.setHeaterFuelType('Gas') water_heater.setHeaterThermalEfficiency(0.8) water_heater.setOffCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOnCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOffCycleParasiticFuelType('Gas') water_heater.setOnCycleParasiticFuelType('Gas') water_heater.setOffCycleLossCoefficienttoAmbientTemperature(6.0) water_heater.setOnCycleLossCoefficienttoAmbientTemperature(6.0) end if water_heater_fuel == 'Electricity' water_heater.setHeaterFuelType('Electricity') water_heater.setOffCycleParasiticFuelType('Electricity') water_heater.setOnCycleParasiticFuelType('Electricity') elsif water_heater_fuel == 'Natural Gas' water_heater.setHeaterFuelType('Gas') water_heater.setOffCycleParasiticFuelType('Gas') water_heater.setOnCycleParasiticFuelType('Gas') end booster_service_water_loop.addSupplyBranchForComponent(water_heater) # Service water heating loop bypass pipes water_heater_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) booster_service_water_loop.addSupplyBranchForComponent(water_heater_bypass_pipe) coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) booster_service_water_loop.addDemandBranchForComponent(coil_bypass_pipe) supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_outlet_pipe.addToNode(booster_service_water_loop.supplyOutletNode) demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_inlet_pipe.addToNode(booster_service_water_loop.demandInletNode) demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_outlet_pipe.addToNode(booster_service_water_loop.demandOutletNode) # Heat exchanger to supply the booster water heater # with normal hot water from the main service water loop. hx = OpenStudio::Model::HeatExchangerFluidToFluid.new(self) hx.setName("HX for Booster Water Heating") hx.setHeatExchangeModelType("Ideal") hx.setControlType("UncontrolledOn") hx.setHeatTransferMeteringEndUseType("LoopToLoop") # Add the HX to the supply side of the booster loop hx.addToNode(booster_service_water_loop.supplyInletNode) # Add the HX to the demand side of # the main service water loop. main_service_water_loop.addDemandBranchForComponent(hx) return booster_service_water_loop end |
#add_swh_end_uses(standard, use_name, swh_loop, peak_flowrate, flowrate_schedule, water_use_temperature, space_name, building_type = nil) ⇒ OpenStudio::Model::WaterUseEquipment
Creates water fixtures and attaches them to the supplied service water loop.
90.1-2007, 90.1-2010, 90.1-2013 to the newly created fixture. the main service water loop to add water fixtures to. or nil, in which case it will not be assigned to any particular space. the resulting water fixture.
3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3622 def add_swh_end_uses(standard, use_name, swh_loop, peak_flowrate, flowrate_schedule, water_use_temperature, space_name, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding water fixture to #{swh_loop.name}.") # Water use connection swh_connection = OpenStudio::Model::WaterUseConnections.new(self) # Water fixture definition water_fixture_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(self) rated_flow_rate_m3_per_s = peak_flowrate rated_flow_rate_gal_per_min = OpenStudio.convert(rated_flow_rate_m3_per_s,'m^3/s','gal/min').get frac_sensible = 0.2 frac_latent = 0.05 # water_use_sensible_frac_sch = OpenStudio::Model::ScheduleConstant.new(self) # water_use_sensible_frac_sch.setValue(0.2) # water_use_latent_frac_sch = OpenStudio::Model::ScheduleConstant.new(self) # water_use_latent_frac_sch.setValue(0.05) water_use_sensible_frac_sch = OpenStudio::Model::ScheduleRuleset.new(self) water_use_sensible_frac_sch.setName("Fraction Sensible - #{frac_sensible}") water_use_sensible_frac_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),frac_sensible) water_use_latent_frac_sch = OpenStudio::Model::ScheduleRuleset.new(self) water_use_latent_frac_sch.setName("Fraction Latent - #{frac_latent}") water_use_latent_frac_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),frac_latent) water_fixture_def.setSensibleFractionSchedule(water_use_sensible_frac_sch) water_fixture_def.setLatentFractionSchedule(water_use_latent_frac_sch) water_fixture_def.setPeakFlowRate(rated_flow_rate_m3_per_s) water_fixture_def.setName("#{use_name.capitalize} Service Water Use Def #{rated_flow_rate_gal_per_min.round(2)}gal/min") # Target mixed water temperature mixed_water_temp_f = OpenStudio.convert(water_use_temperature,'C','F').get mixed_water_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) mixed_water_temp_sch.setName("Mixed Water At Faucet Temp - #{mixed_water_temp_f.round}F") mixed_water_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),OpenStudio.convert(mixed_water_temp_f,'F','C').get) water_fixture_def.setTargetTemperatureSchedule(mixed_water_temp_sch) # Water use equipment water_fixture = OpenStudio::Model::WaterUseEquipment.new(water_fixture_def) schedule = self.add_schedule(flowrate_schedule) water_fixture.setFlowRateFractionSchedule(schedule) if space_name.nil? water_fixture.setName("#{use_name.capitalize} Service Water Use #{rated_flow_rate_gal_per_min.round(2)}gal/min") else water_fixture.setName("#{space_name.capitalize} Service Water Use #{rated_flow_rate_gal_per_min.round(2)}gal/min") end unless space_name.nil? space = self.getSpaceByName(space_name) space = space.get water_fixture.setSpace(space) end swh_connection.addWaterUseEquipment(water_fixture) # Connect the water use connection to the SWH loop swh_loop.addDemandBranchForComponent(swh_connection) return water_fixture end |
#add_swh_end_uses_by_space(building_type, building_vintage, climate_zone, swh_loop, space_type_name, space_name, space_multiplier = nil) ⇒ Object
3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3689 def add_swh_end_uses_by_space(building_type, building_vintage, climate_zone, swh_loop, space_type_name, space_name, space_multiplier = nil) # find the specific space_type properties from standard.json search_criteria = { 'template' => building_vintage, 'building_type' => building_type, 'space_type' => space_type_name } data = find_object($os_standards['space_types'],search_criteria) space = self.getSpaceByName(space_name) space = space.get space_area = OpenStudio.convert(space.floorArea,'m^2','ft^2').get # ft2 if space_multiplier.nil? space_multiplier = 1 end # Water use connection swh_connection = OpenStudio::Model::WaterUseConnections.new(self) # Water fixture definition water_fixture_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(self) rated_flow_rate_per_area = data['service_water_heating_peak_flow_per_area'].to_f # gal/h.ft2 rated_flow_rate_gal_per_hour = rated_flow_rate_per_area * space_area * space_multiplier # gal/h rated_flow_rate_gal_per_min = rated_flow_rate_gal_per_hour/60 # gal/h to gal/min rated_flow_rate_m3_per_s = OpenStudio.convert(rated_flow_rate_gal_per_min,'gal/min','m^3/s').get # water_use_sensible_frac_sch = OpenStudio::Model::ScheduleConstant.new(self) # water_use_sensible_frac_sch.setValue(0.2) # water_use_latent_frac_sch = OpenStudio::Model::ScheduleConstant.new(self) # water_use_latent_frac_sch.setValue(0.05) water_use_sensible_frac_sch = OpenStudio::Model::ScheduleRuleset.new(self) water_use_sensible_frac_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),0.2) water_use_latent_frac_sch = OpenStudio::Model::ScheduleRuleset.new(self) water_use_latent_frac_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),0.05) water_fixture_def.setSensibleFractionSchedule(water_use_sensible_frac_sch) water_fixture_def.setLatentFractionSchedule(water_use_latent_frac_sch) water_fixture_def.setPeakFlowRate(rated_flow_rate_m3_per_s) water_fixture_def.setName("#{space_name.capitalize} Service Water Use Def #{rated_flow_rate_gal_per_min.round(2)}gal/min") # Target mixed water temperature mixed_water_temp_c = data['service_water_heating_target_temperature'] mixed_water_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) mixed_water_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),mixed_water_temp_c) water_fixture_def.setTargetTemperatureSchedule(mixed_water_temp_sch) # Water use equipment water_fixture = OpenStudio::Model::WaterUseEquipment.new(water_fixture_def) schedule = self.add_schedule(data['service_water_heating_schedule']) water_fixture.setFlowRateFractionSchedule(schedule) water_fixture.setName("#{space_name.capitalize} Service Water Use #{rated_flow_rate_gal_per_min.round(2)}gal/min") swh_connection.addWaterUseEquipment(water_fixture) # Connect the water use connection to the SWH loop swh_loop.addDemandBranchForComponent(swh_connection) end |
#add_swh_loop(standard, sys_name, water_heater_thermal_zone, service_water_temperature, service_water_pump_head, service_water_pump_motor_efficiency, water_heater_capacity, water_heater_volume, water_heater_fuel, parasitic_fuel_consumption_rate, building_type = nil) ⇒ OpenStudio::Model::PlantLoop
Creates a service water heating loop.
90.1-2007, 90.1-2010, 90.1-2013 zones to place water heater in. If nil, will be assumed in 70F air for heat loss. service water pump motor efficiency, as decimal. Valid choices are Natural Gas, Electricity rate of the water heater, in W the resulting service water loop.
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3209 def add_swh_loop(standard, sys_name, water_heater_thermal_zone, service_water_temperature, service_water_pump_head, service_water_pump_motor_efficiency, water_heater_capacity, water_heater_volume, water_heater_fuel, parasitic_fuel_consumption_rate, building_type = nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding service water loop.") # Service water heating loop service_water_loop = OpenStudio::Model::PlantLoop.new(self) service_water_loop.setMinimumLoopTemperature(10) service_water_loop.setMaximumLoopTemperature(60) if sys_name.nil? service_water_loop.setName("Service Water Loop") else service_water_loop.setName(sys_name) end # Temperature schedule type limits temp_sch_type_limits = OpenStudio::Model::ScheduleTypeLimits.new(self) temp_sch_type_limits.setName('Temperature Schedule Type Limits') temp_sch_type_limits.setLowerLimitValue(0.0) temp_sch_type_limits.setUpperLimitValue(100.0) temp_sch_type_limits.setNumericType('Continuous') temp_sch_type_limits.setUnitType('Temperature') # Service water heating loop controls swh_temp_c = service_water_temperature swh_temp_f = OpenStudio.convert(swh_temp_c,'C','F').get swh_delta_t_r = 9 #9F delta-T swh_delta_t_k = OpenStudio.convert(swh_delta_t_r,'R','K').get swh_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) swh_temp_sch.setName("Service Water Loop Temp - #{swh_temp_f.round}F") swh_temp_sch.defaultDaySchedule().setName("Service Water Loop Temp - #{swh_temp_f.round}F Default") swh_temp_sch.defaultDaySchedule().addValue(OpenStudio::Time.new(0,24,0,0),swh_temp_c) swh_temp_sch.setScheduleTypeLimits(temp_sch_type_limits) swh_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,swh_temp_sch) swh_stpt_manager.setName("Service hot water setpoint manager") swh_stpt_manager.addToNode(service_water_loop.supplyOutletNode) sizing_plant = service_water_loop.sizingPlant sizing_plant.setLoopType('Heating') sizing_plant.setDesignLoopExitTemperature(swh_temp_c) sizing_plant.setLoopDesignTemperatureDifference(swh_delta_t_k) # Service water heating pump swh_pump_head_press_pa = service_water_pump_head swh_pump_motor_efficiency = service_water_pump_motor_efficiency if swh_pump_head_press_pa.nil? # As if there is no circulation pump swh_pump_head_press_pa = 0.001 swh_pump_motor_efficiency = 1 end if building_type.nil? && ( 'template' == 'DOE Ref 1980-2004' || 'template' == 'DOE Ref Pre-1980' ) if building_type == 'Medium Office' swh_pump = OpenStudio::Model::PumpConstantSpeed.new(self) else swh_pump = OpenStudio::Model::PumpVariableSpeed.new(self) end else swh_pump = OpenStudio::Model::PumpConstantSpeed.new(self) end swh_pump.setName('Service Water Loop Pump') swh_pump.setRatedPumpHead(swh_pump_head_press_pa.to_f) swh_pump.setMotorEfficiency(swh_pump_motor_efficiency) swh_pump.setPumpControlType('Intermittent') swh_pump.addToNode(service_water_loop.supplyInletNode) water_heater = add_water_heater(standard, water_heater_capacity, water_heater_volume, water_heater_fuel, service_water_temperature, parasitic_fuel_consumption_rate, swh_temp_sch, false, 0.0, nil, water_heater_thermal_zone, building_type) service_water_loop.addSupplyBranchForComponent(water_heater) # Service water heating loop bypass pipes water_heater_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) service_water_loop.addSupplyBranchForComponent(water_heater_bypass_pipe) coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self) service_water_loop.addDemandBranchForComponent(coil_bypass_pipe) supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) supply_outlet_pipe.addToNode(service_water_loop.supplyOutletNode) demand_inlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_inlet_pipe.addToNode(service_water_loop.demandInletNode) demand_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(self) demand_outlet_pipe.addToNode(service_water_loop.demandOutletNode) return service_water_loop end |
#add_unitheater(standard, sys_name, thermal_zones, hvac_op_sch, fan_control_type, fan_pressure_rise, heating_type, building_type = nil) ⇒ Array<OpenStudio::Model::ZoneHVACUnitHeater>
Creates a unit heater for each zone and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on
Gas, Electric array of the resulting unit heaters. Todo: to leverage this method for proposed model creation, might be useful to add ‘Water’ to heating type with an optional hot_water_loop to tie it to
3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3081 def add_unitheater(standard, sys_name, thermal_zones, hvac_op_sch, fan_control_type, fan_pressure_rise, heating_type, building_type=nil) thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding split unit heater for #{zone.name}.") end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # Make a unit heater for each zone unit_heaters = [] thermal_zones.each do |zone| # Zone sizing sizing_zone = zone.sizingZone if building_type == 'RetailStandalone' && standard != 'DOE Ref 1980-2004' && standard != 'DOE Ref Pre-1980' sizing_zone.setZoneCoolingDesignSupplyAirTemperature(12.8) else sizing_zone.setZoneCoolingDesignSupplyAirTemperature(14) end sizing_zone.setZoneHeatingDesignSupplyAirTemperature(50.0) sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008) sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008) # add fan fan = OpenStudio::Model::FanConstantVolume.new(self,hvac_op_sch) fan.setName("#{zone.name} UnitHeater Fan") fan.setPressureRise(fan_pressure_rise) fan.setFanEfficiency(0.53625) fan.setMotorEfficiency(0.825) # add heating coil htg_coil = nil if heating_type == "Gas" htg_coil = OpenStudio::Model::CoilHeatingGas.new(self, hvac_op_sch) htg_coil.setName("#{zone.name} UnitHeater Gas Htg Coil") elsif heating_type == "Electric" htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self, hvac_op_sch) htg_coil.setName("#{zone.name} UnitHeater Electric Htg Coil") else OpenStudio::logFree(OpenStudio::Error, 'openstudio.Model.Model', "No heating type was found when adding unit heater; no unit heater will be created.") return false end unit_heater = OpenStudio::Model::ZoneHVACUnitHeater.new(self, hvac_op_sch, fan, htg_coil) unit_heater.setName("#{zone.name} UnitHeater") unit_heater.setFanControlType(fan_control_type) unit_heater.addToThermalZone(zone) unit_heaters << unit_heater end return unit_heaters end |
#add_vals_to_sch(day_sch, sch_type, values) ⇒ Object
Helper method to fill in hourly values
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1824 def add_vals_to_sch(day_sch, sch_type, values) if sch_type == "Constant" day_sch.addValue(OpenStudio::Time.new(0, 24, 0, 0), values[0]) elsif sch_type == "Hourly" for i in 0..23 next if values[i] == values[i + 1] day_sch.addValue(OpenStudio::Time.new(0, i + 1, 0, 0), values[i]) end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Schedule type: #{sch_type} is not recognized. Valid choices are 'Constant' and 'Hourly'.") end end |
#add_vav_pfp_boxes(standard, sys_name, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, vav_fan_efficiency, vav_fan_motor_efficiency, vav_fan_pressure_rise, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a VAV system with parallel fan powered boxes and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 704 def add_vav_pfp_boxes(standard, sys_name, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, vav_fan_efficiency, vav_fan_motor_efficiency, vav_fan_pressure_rise, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding VAV with PFP Boxes and Reheat system for #{thermal_zones.size} zones.") thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Debug, 'openstudio.Model.Model', "---#{zone.name}") end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # control temps used across all air handlers clg_sa_temp_f = 55.04 # Central deck clg temp 55F prehtg_sa_temp_f = 44.6 # Preheat to 44.6F preclg_sa_temp_f = 55.04 # Precool to 55F htg_sa_temp_f = 55.04 # Central deck htg temp 55F rht_sa_temp_f = 104 # VAV box reheat to 104F zone_htg_sa_temp_f = 104 # Zone heating design supply air temperature to 104 F clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f,'F','C').get prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f,'F','C').get preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f,'F','C').get htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f,'F','C').get rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f,'F','C').get zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f,'F','C').get sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F") sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default") sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),clg_sa_temp_c) #air handler air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? air_loop.setName("#{thermal_zones.size} Zone VAV with PFP Boxes and Reheat") else air_loop.setName(sys_name) end air_loop.setAvailabilitySchedule(hvac_op_sch) sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,sa_temp_sch) sa_stpt_manager.setName("#{thermal_zones.size} Zone VAV supply air setpoint manager") sa_stpt_manager.addToNode(air_loop.supplyOutletNode) #air handler controls sizing_system = air_loop.sizingSystem sizing_system.setPreheatDesignTemperature(prehtg_sa_temp_c) sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c) sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c) sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c) sizing_system.setSizingOption('Coincident') sizing_system.setAllOutdoorAirinCooling(false) sizing_system.setAllOutdoorAirinHeating(false) sizing_system.setSystemOutdoorAirMethod('ZoneSum') #fan fan = OpenStudio::Model::FanVariableVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{air_loop.name} Fan") fan.setFanEfficiency(vav_fan_efficiency) fan.setMotorEfficiency(vav_fan_motor_efficiency) fan.setPressureRise(vav_fan_pressure_rise) fan.setFanPowerMinimumFlowRateInputMethod('fraction') fan.setFanPowerMinimumFlowFraction(0.25) fan.addToNode(air_loop.supplyInletNode) fan.setEndUseSubcategory("VAV system Fans") #heating coil htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) htg_coil.setName("#{air_loop.name} Htg Coil") htg_coil.addToNode(air_loop.supplyInletNode) #cooling coil clg_coil = OpenStudio::Model::CoilCoolingWater.new(self,self.alwaysOnDiscreteSchedule) clg_coil.setName("#{air_loop.name} Clg Coil") clg_coil.addToNode(air_loop.supplyInletNode) clg_coil.setHeatExchangerConfiguration("CrossFlow") chilled_water_loop.addDemandBranchForComponent(clg_coil) clg_coil.controllerWaterCoil.get.setName("#{air_loop.name} Clg Coil Controller") #outdoor air intake system oa_intake_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_intake_controller.setName("#{air_loop.name} OA Controller") oa_intake_controller.setMinimumLimitType('FixedMinimum') #oa_intake_controller.setMinimumOutdoorAirSchedule(oa_damper_sch) oa_intake_controller.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum') controller_mv = oa_intake_controller.controllerMechanicalVentilation controller_mv.setName("#{air_loop.name} Vent Controller") controller_mv.setSystemOutdoorAirMethod('VentilationRateProcedure') oa_intake = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self, oa_intake_controller) oa_intake.setName("#{air_loop.name} OA Sys") oa_intake.addToNode(air_loop.supplyInletNode) # The oa system need to be added before setting the night cycle control air_loop.setNightCycleControlType('CycleOnAny') #hook the VAV system to each zone thermal_zones.each do |zone| #reheat coil rht_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule) rht_coil.setName("#{zone.name} Rht Coil") # terminal fan pfp_fan = OpenStudio::Model::FanConstantVolume.new(self,self.alwaysOnDiscreteSchedule) pfp_fan.setName("#{zone.name} PFP Term Fan") pfp_fan.setPressureRise(300) #parallel fan powered terminal pfp_terminal = OpenStudio::Model::AirTerminalSingleDuctParallelPIUReheat.new(self, self.alwaysOnDiscreteSchedule, pfp_fan, rht_coil) pfp_terminal.setName("#{zone.name} PFP Term") air_loop.addBranchForZone(zone,pfp_terminal.to_StraightComponent) # Zone sizing # TODO Create general logic for cooling airflow method. # Large hotel uses design day with limit, school uses design day. sizing_zone = zone.sizingZone sizing_zone.setCoolingDesignAirFlowMethod('DesignDay') sizing_zone.setHeatingDesignAirFlowMethod('DesignDay') sizing_zone.setZoneCoolingDesignSupplyAirTemperature(clg_sa_temp_c) #sizing_zone.setZoneHeatingDesignSupplyAirTemperature(rht_sa_temp_c) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(zone_htg_sa_temp_c) end return air_loop end |
#add_vav_reheat(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, vav_fan_efficiency, vav_fan_motor_efficiency, vav_fan_pressure_rise, return_plenum, building_type = nil) ⇒ OpenStudio::Model::AirLoopHVAC
Creates a VAV system and adds it to the model.
90.1-2007, 90.1-2010, 90.1-2013 or nil in which case will be defaulted to always on or nil in which case will be defaulted to always open the supply plenum, or nil, in which case no return plenum will be used.
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 483 def add_vav_reheat(standard, sys_name, hot_water_loop, chilled_water_loop, thermal_zones, hvac_op_sch, oa_damper_sch, vav_fan_efficiency, vav_fan_motor_efficiency, vav_fan_pressure_rise, return_plenum, building_type=nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding VAV system for #{thermal_zones.size} zones.") thermal_zones.each do |zone| OpenStudio::logFree(OpenStudio::Debug, 'openstudio.Model.Model', "---#{zone.name}") end hw_temp_f = 180 #HW setpoint 180F hw_delta_t_r = 20 #20F delta-T hw_temp_c = OpenStudio.convert(hw_temp_f,'F','C').get hw_delta_t_k = OpenStudio.convert(hw_delta_t_r,'R','K').get if building_type == "LargeHotel" rht_sa_temp_f = 90 # VAV box reheat to 90F for large hotel zone_htg_sa_temp_f = 104 # Zone heating design supply air temperature to 104 F else rht_sa_temp_f = 104 # VAV box reheat to 104F zone_htg_sa_temp_f = 104 # Zone heating design supply air temperature to 104 F end # hvac operation schedule if hvac_op_sch.nil? hvac_op_sch = self.alwaysOnDiscreteSchedule else hvac_op_sch = self.add_schedule(hvac_op_sch) end # oa damper schedule if oa_damper_sch.nil? oa_damper_sch = self.alwaysOnDiscreteSchedule else oa_damper_sch = self.add_schedule(oa_damper_sch) end # control temps used across all air handlers clg_sa_temp_f = 55.04 # Central deck clg temp 55F prehtg_sa_temp_f = 44.6 # Preheat to 44.6F preclg_sa_temp_f = 55.04 # Precool to 55F htg_sa_temp_f = 55.04 # Central deck htg temp 55F if building_type == "LargeHotel" htg_sa_temp_f = 62 # Central deck htg temp 55F end rht_sa_temp_f = 104 # VAV box reheat to 104F clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f,'F','C').get prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f,'F','C').get preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f,'F','C').get htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f,'F','C').get rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f,'F','C').get zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f,'F','C').get sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F") sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default") sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),clg_sa_temp_c) #air handler air_loop = OpenStudio::Model::AirLoopHVAC.new(self) if sys_name.nil? air_loop.setName("#{thermal_zones.size} Zone VAV") else air_loop.setName(sys_name) end air_loop.setAvailabilitySchedule(hvac_op_sch) sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,sa_temp_sch) sa_stpt_manager.setName("#{thermal_zones.size} Zone VAV supply air setpoint manager") sa_stpt_manager.addToNode(air_loop.supplyOutletNode) #air handler controls sizing_system = air_loop.sizingSystem sizing_system.setPreheatDesignTemperature(prehtg_sa_temp_c) sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c) sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c) sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c) sizing_system.setSizingOption('Coincident') sizing_system.setAllOutdoorAirinCooling(false) sizing_system.setAllOutdoorAirinHeating(false) sizing_system.setSystemOutdoorAirMethod('ZoneSum') #fan fan = OpenStudio::Model::FanVariableVolume.new(self,self.alwaysOnDiscreteSchedule) fan.setName("#{air_loop.name} Fan") fan.setFanEfficiency(vav_fan_efficiency) fan.setMotorEfficiency(vav_fan_motor_efficiency) fan.setPressureRise(vav_fan_pressure_rise) fan.setFanPowerMinimumFlowRateInputMethod('fraction') fan.setFanPowerMinimumFlowFraction(0.25) fan.addToNode(air_loop.supplyInletNode) fan.setEndUseSubcategory("VAV system Fans") #heating coil htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) htg_coil.addToNode(air_loop.supplyInletNode) hot_water_loop.addDemandBranchForComponent(htg_coil) htg_coil.setName("#{air_loop.name} Main Htg Coil") htg_coil.controllerWaterCoil.get.setName("#{air_loop.name} Main Htg Coil Controller") htg_coil.setRatedInletWaterTemperature(hw_temp_c) htg_coil.setRatedInletAirTemperature(prehtg_sa_temp_c) htg_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) htg_coil.setRatedOutletAirTemperature(htg_sa_temp_c) if building_type == "LargeHotel" htg_coil.setRatedInletAirTemperature(htg_sa_temp_c) htg_coil.setRatedOutletAirTemperature(rht_sa_temp_c) else htg_coil.setRatedInletAirTemperature(prehtg_sa_temp_c) htg_coil.setRatedOutletAirTemperature(htg_sa_temp_c) end #cooling coil clg_coil = OpenStudio::Model::CoilCoolingWater.new(self,self.alwaysOnDiscreteSchedule) clg_coil.setName("#{air_loop.name} Clg Coil") clg_coil.addToNode(air_loop.supplyInletNode) clg_coil.setHeatExchangerConfiguration("CrossFlow") chilled_water_loop.addDemandBranchForComponent(clg_coil) clg_coil.controllerWaterCoil.get.setName("#{air_loop.name} Clg Coil Controller") #outdoor air intake system oa_intake_controller = OpenStudio::Model::ControllerOutdoorAir.new(self) oa_intake_controller.setName("#{air_loop.name} OA Controller") oa_intake_controller.setMinimumLimitType('FixedMinimum') #oa_intake_controller.setMinimumOutdoorAirSchedule(oa_damper_sch) oa_intake_controller.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum') controller_mv = oa_intake_controller.controllerMechanicalVentilation controller_mv.setName("#{air_loop.name} Vent Controller") controller_mv.setSystemOutdoorAirMethod('VentilationRateProcedure') if building_type == "LargeHotel" oa_intake_controller.setEconomizerControlType("DifferentialEnthalpy") oa_intake_controller.setHeatRecoveryBypassControlType("BypassWhenOAFlowGreaterThanMinimum") oa_intake_controller.resetMaximumFractionofOutdoorAirSchedule oa_intake_controller.resetMaximumFractionofOutdoorAirSchedule oa_intake_controller.resetEconomizerMinimumLimitDryBulbTemperature end oa_intake = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self, oa_intake_controller) oa_intake.setName("#{air_loop.name} OA Sys") oa_intake.addToNode(air_loop.supplyInletNode) # The oa system need to be added before setting the night cycle control air_loop.setNightCycleControlType('CycleOnAny') #hook the VAV system to each zone thermal_zones.each do |zone| #reheat coil rht_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule) rht_coil.setName("#{zone.name} Rht Coil") rht_coil.setRatedInletWaterTemperature(hw_temp_c) rht_coil.setRatedInletAirTemperature(htg_sa_temp_c) rht_coil.setRatedOutletWaterTemperature(hw_temp_c - hw_delta_t_k) rht_coil.setRatedOutletAirTemperature(rht_sa_temp_c) hot_water_loop.addDemandBranchForComponent(rht_coil) #vav terminal terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(self,self.alwaysOnDiscreteSchedule,rht_coil) terminal.setName("#{zone.name} VAV Term") terminal.setZoneMinimumAirFlowMethod('Constant') terminal.set_initial_prototype_damper_position(standard, zone.outdoor_airflow_rate_per_area) terminal.setMaximumFlowPerZoneFloorAreaDuringReheat(0.0) terminal.setMaximumFlowFractionDuringReheat(0.5) terminal.setMaximumReheatAirTemperature(rht_sa_temp_c) air_loop.addBranchForZone(zone,terminal.to_StraightComponent) # Zone sizing # TODO Create general logic for cooling airflow method. # Large hotel uses design day with limit, school uses design day. sizing_zone = zone.sizingZone if building_type == 'SecondarySchool' sizing_zone.setCoolingDesignAirFlowMethod('DesignDay') else sizing_zone.setCoolingDesignAirFlowMethod("DesignDayWithLimit") end sizing_zone.setHeatingDesignAirFlowMethod("DesignDay") sizing_zone.setZoneCoolingDesignSupplyAirTemperature(clg_sa_temp_c) #sizing_zone.setZoneHeatingDesignSupplyAirTemperature(rht_sa_temp_c) sizing_zone.setZoneHeatingDesignSupplyAirTemperature(zone_htg_sa_temp_c) unless return_plenum.nil? zone.setReturnPlenum(return_plenum) end end # Set the damper action based on the template. air_loop.set_vav_damper_action(standard) return air_loop end |
#add_water_heater(standard, water_heater_capacity, water_heater_volume, water_heater_fuel, service_water_temperature, parasitic_fuel_consumption_rate, swh_temp_sch, set_peak_use_flowrate, peak_flowrate, flowrate_schedule, water_heater_thermal_zone, building_type = nil) ⇒ OpenStudio::Model::WaterHeaterMixed
Creates a water heater and attaches it to the supplied service water heating loop.
90.1-2007, 90.1-2010, 90.1-2013 Natural Gas, Electricity fuel consumption rate, in W schedule. If nil, will be defaulted. and flow rate schedule will be set. zones to place water heater in. If nil, will be assumed in 70F air for heat loss.
the resulting water heater.
3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 |
# File 'lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb', line 3337 def add_water_heater(standard, water_heater_capacity, water_heater_volume, water_heater_fuel, service_water_temperature, parasitic_fuel_consumption_rate, swh_temp_sch, set_peak_use_flowrate, peak_flowrate, flowrate_schedule, water_heater_thermal_zone, building_type = nil) OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding water heater.") # Water heater # TODO Standards - Change water heater methodology to follow # 'Model Enhancements Appendix A.' water_heater_capacity_btu_per_hr = OpenStudio.convert(water_heater_capacity, "W", "Btu/hr").get water_heater_capacity_kbtu_per_hr = OpenStudio.convert(water_heater_capacity_btu_per_hr, "Btu/hr", "kBtu/hr").get water_heater_vol_gal = OpenStudio.convert(water_heater_volume, "m^3", "gal").get # Temperature schedule type limits temp_sch_type_limits = OpenStudio::Model::ScheduleTypeLimits.new(self) temp_sch_type_limits.setName('Temperature Schedule Type Limits') temp_sch_type_limits.setLowerLimitValue(0.0) temp_sch_type_limits.setUpperLimitValue(100.0) temp_sch_type_limits.setNumericType('Continuous') temp_sch_type_limits.setUnitType('Temperature') if swh_temp_sch.nil? # Service water heating loop controls swh_temp_c = service_water_temperature swh_temp_f = OpenStudio.convert(swh_temp_c,'C','F').get swh_delta_t_r = 9 #9F delta-T swh_temp_c = OpenStudio.convert(swh_temp_f,'F','C').get swh_delta_t_k = OpenStudio.convert(swh_delta_t_r,'R','K').get swh_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) swh_temp_sch.setName("Service Water Loop Temp - #{swh_temp_f.round}F") swh_temp_sch.defaultDaySchedule.setName("Service Water Loop Temp - #{swh_temp_f.round}F Default") swh_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),swh_temp_c) swh_temp_sch.setScheduleTypeLimits(temp_sch_type_limits) end # Water heater depends on the fuel type water_heater = OpenStudio::Model::WaterHeaterMixed.new(self) water_heater.setName("#{water_heater_vol_gal}gal #{water_heater_fuel} Water Heater - #{water_heater_capacity_kbtu_per_hr.round}kBtu/hr") water_heater.setTankVolume(OpenStudio.convert(water_heater_vol_gal,'gal','m^3').get) water_heater.setSetpointTemperatureSchedule(swh_temp_sch) if water_heater_thermal_zone.nil? # Assume the water heater is indoors at 70F for now default_water_heater_ambient_temp_sch = OpenStudio::Model::ScheduleRuleset.new(self) default_water_heater_ambient_temp_sch.setName('Water Heater Ambient Temp Schedule - 70F') default_water_heater_ambient_temp_sch.defaultDaySchedule.setName('Water Heater Ambient Temp Schedule - 70F Default') default_water_heater_ambient_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0),OpenStudio::convert(70,"F","C").get) default_water_heater_ambient_temp_sch.setScheduleTypeLimits(temp_sch_type_limits) water_heater.setAmbientTemperatureIndicator('Schedule') water_heater.setAmbientTemperatureSchedule(default_water_heater_ambient_temp_sch) else water_heater.setAmbientTemperatureIndicator('ThermalZone') water_heater.setAmbientTemperatureThermalZone water_heater_thermal_zone end water_heater.setMaximumTemperatureLimit(OpenStudio::convert(180,'F','C').get) water_heater.setDeadbandTemperatureDifference(OpenStudio.convert(3.6,'R','K').get) water_heater.setHeaterControlType('Cycle') water_heater.setHeaterMaximumCapacity(OpenStudio.convert(water_heater_capacity_btu_per_hr,'Btu/hr','W').get) water_heater.setOffCycleParasiticHeatFractiontoTank(0.8) water_heater.setIndirectWaterHeatingRecoveryTime(1.5) # 1.5hrs if water_heater_fuel == 'Electricity' water_heater.setHeaterFuelType('Electricity') water_heater.setHeaterThermalEfficiency(1.0) water_heater.setOffCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOnCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOffCycleParasiticFuelType('Electricity') water_heater.setOnCycleParasiticFuelType('Electricity') water_heater.setOffCycleLossCoefficienttoAmbientTemperature(1.053) water_heater.setOnCycleLossCoefficienttoAmbientTemperature(1.053) elsif water_heater_fuel == 'Natural Gas' water_heater.setHeaterFuelType('Gas') water_heater.setHeaterThermalEfficiency(0.78) water_heater.setOffCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOnCycleParasiticFuelConsumptionRate(parasitic_fuel_consumption_rate) water_heater.setOffCycleParasiticFuelType('Gas') water_heater.setOnCycleParasiticFuelType('Gas') water_heater.setOffCycleLossCoefficienttoAmbientTemperature(6.0) water_heater.setOnCycleLossCoefficienttoAmbientTemperature(6.0) end if set_peak_use_flowrate rated_flow_rate_m3_per_s = peak_flowrate rated_flow_rate_gal_per_min = OpenStudio.convert(rated_flow_rate_m3_per_s,'m^3/s','gal/min').get water_heater.setPeakUseFlowRate(rated_flow_rate_m3_per_s) schedule = self.add_schedule(flowrate_schedule) water_heater.setUseFlowRateFractionSchedule(schedule) end return water_heater end |
#add_zone_mixing(building_vintage) ⇒ Object
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 490 def add_zone_mixing(building_vintage) # add zone_mixing between kitchen and dining space_kitchen = self.getSpaceByName('Kitchen').get zone_kitchen = space_kitchen.thermalZone.get space_dining = self.getSpaceByName('Dining').get zone_dining = space_dining.thermalZone.get zone_mixing_kitchen = OpenStudio::Model::ZoneMixing.new(zone_kitchen) zone_mixing_kitchen.setSchedule(add_schedule('RestaurantFastFood Hours_of_operation')) case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' zone_mixing_kitchen.setDesignFlowRate(0.834532374) when '90.1-2007', '90.1-2010', '90.1-2013' zone_mixing_kitchen.setDesignFlowRate(0.416067345) when '90.1-2004' zone_mixing_kitchen.setDesignFlowRate(0.826232888) end zone_mixing_kitchen.setSourceZone(zone_dining) zone_mixing_kitchen.setDeltaTemperature(0) end |
#addDaylightingControls(building_vintage) ⇒ Object
Applies daylighting controls to each space in the model per the standard.
1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1604 def addDaylightingControls(building_vintage) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding daylighting controls.') # Add daylighting controls to each space self.getSpaces.sort.each do |space| added = space.addDaylightingControls(building_vintage, false, false) end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding daylighting controls.') end |
#adjust_clg_setpoint(building_vintage, climate_zone) ⇒ Object
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 436 def adjust_clg_setpoint(building_vintage,climate_zone) ['Dining','Kitchen'].each do |space_name| space_type_name = self.getSpaceByName(space_name).get.spaceType.get.name.get thermostat_name = space_type_name + ' Thermostat' thermostat = self.getThermostatSetpointDualSetpointByName(thermostat_name).get case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010' if climate_zone == 'ASHRAE 169-2006-2B' || climate_zone == 'ASHRAE 169-2006-1B' || climate_zone == 'ASHRAE 169-2006-3B' case space_name when 'Dining' thermostat.setCoolingSetpointTemperatureSchedule(add_schedule("RestaurantFastFood CLGSETP_SCH_NO_OPTIMUM")) when 'Kitchen' thermostat.setCoolingSetpointTemperatureSchedule(add_schedule("RestaurantFastFood CLGSETP_KITCHEN_SCH_NO_OPTIMUM")) end end end end end |
#apply_infiltration_standard(building_vintage) ⇒ Bool
This infiltration method is not used by the Reference
Apply the air leakage requirements to the model, as described in PNNL section 5.2.1.6.
base infiltration rates off of. buildings, fix this inconsistency.
1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1624 def apply_infiltration_standard(building_vintage) # Set the infiltration rate at each space self.getSpaces.sort.each do |space| space.set_infiltration_rate(building_vintage) end case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' #"For 'DOE Ref Pre-1980' and 'DOE Ref 1980-2004', infiltration rates are not defined using this method, no changes have been made to the model. else # Remove infiltration rates set at the space type self.getSpaceTypes.each do |space_type| space_type.spaceInfiltrationDesignFlowRates.each do |infil| infil.remove end end end end |
#apply_multizone_vav_outdoor_air_sizing(building_vintage) ⇒ Object
This must be performed before the sizing run because
Applies the multi-zone VAV outdoor air sizing requirements to all applicable air loops in the model.
it impacts component sizes, which in turn impact efficiencies.
1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1548 def apply_multizone_vav_outdoor_air_sizing(building_vintage) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying multizone vav OA sizing.') # Multi-zone VAV outdoor air sizing self.getAirLoopHVACs.sort.each {|obj| obj.apply_multizone_vav_outdoor_air_sizing(building_vintage)} OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying multizone vav OA sizing.') end |
#apply_performance_rating_method_baseline_skylight_to_roof_ratio(template) ⇒ Object
support semiheated spaces as a separate SRR category
add skylight frame area to calculation of SRR
Reduces the SRR to the values specified by the PRM. SRR reduction will be done by shrinking in the x direction toward the center.
3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3231 def (template) # Loop through all spaces in the model, and # per the PNNL PRM Reference Manual, find the areas # of each space conditioning category (res, nonres, semi-heated) # separately. Include space multipliers. nr_wall_m2 = 0.001 # Avoids divide by zero errors later nr_sky_m2 = 0 res_wall_m2 = 0.001 res_sky_m2 = 0 sh_wall_m2 = 0.001 sh_sky_m2 = 0 self.getSpaces.each do |space| # Loop through all surfaces in this space wall_area_m2 = 0 sky_area_m2 = 0 space.surfaces.sort.each do |surface| # Skip non-outdoor surfaces next unless surface.outsideBoundaryCondition == 'Outdoors' # Skip non-walls next unless surface.surfaceType == 'RoofCeiling' # This wall's gross area (including skylight area) wall_area_m2 += surface.grossArea * space.multiplier # Subsurfaces in this surface surface.subSurfaces.sort.each do |ss| next unless ss.subSurfaceType == 'Skylight' sky_area_m2 += ss.netArea * space.multiplier end end # Determine the space category cat = 'NonRes' if space.is_residential(template) cat = 'Res' end # if space.is_semiheated # cat = 'Semiheated' # end # Add to the correct category case cat when 'NonRes' nr_wall_m2 += wall_area_m2 nr_sky_m2 += sky_area_m2 when 'Res' res_wall_m2 += wall_area_m2 res_sky_m2 += sky_area_m2 when 'Semiheated' sh_wall_m2 += wall_area_m2 sh_sky_m2 += sky_area_m2 end end # Calculate the SRR of each category srr_nr = ((nr_sky_m2 / nr_wall_m2)*100).round(1) srr_res = ((res_sky_m2 / res_wall_m2)*100).round(1) srr_sh = ((sh_sky_m2 / sh_wall_m2)*100).round(1) OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "The skylight to roof ratios (SRRs) are: NonRes: #{srr_nr.round}%, Res: #{srr_res.round}%.") # SRR limit srr_lim = nil case template when '90.1-2004', '90.1-2007', '90.1-2010' srr_lim = 5.0 when '90.1-2013' srr_lim = 3.0 end # Check against SRR limit srr_nr > srr_lim ? red_nr = true : red_nr = false srr_res > srr_lim ? red_res = true : red_res = false srr_sh > srr_lim ? red_sh = true : red_sh = false # Stop here unless skylights need reducing return true unless red_nr || red_res || red_sh OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Reducing the size of all skylights equally down to the limit of #{srr_lim.round}%.") # Determine the factors by which to reduce the skylight area mult_nr_red = srr_lim / srr_nr mult_res_red = srr_lim / srr_res #mult_sh_red = srr_lim / srr_sh # Reduce the skylight area if any of the categories necessary self.getSpaces.each do |space| # Determine the space category cat = 'NonRes' if space.is_residential(template) cat = 'Res' end # if space.is_semiheated # cat = 'Semiheated' # end # Skip spaces whose skylights don't need to be reduced case cat when 'NonRes' next unless red_nr mult = mult_nr_red when 'Res' next unless red_res mult = mult_res_red when 'Semiheated' next unless red_sh # mult = mult_sh_red end # Loop through all surfaces in this space space.surfaces.sort.each do |surface| # Skip non-outdoor surfaces next unless surface.outsideBoundaryCondition == 'Outdoors' # Skip non-walls next unless surface.surfaceType == 'RoofCeiling' # Subsurfaces in this surface surface.subSurfaces.sort.each do |ss| next unless ss.subSurfaceType == 'Skylight' # Reduce the size of the skylight red = 1.0 - mult ss.reduce_area_by_percent_by_shrinking_x(red) end end end return true end |
#apply_performance_rating_method_baseline_window_to_wall_ratio(template) ⇒ Object
add proper support for 90.1-2013 with all those building
support 90.1-2004 requirement that windows be modeled as
support semiheated spaces as a separate WWR category
add window frame area to calculation of WWR
Reduces the WWR to the values specified by the PRM. WWR reduction will be done by raising sill height. This causes the least impact on the daylighting area calculations and controls placement.
type specific values horizontal bands. Currently just using existing window geometry, and shrinking vertically as necessary if WWR is above limit.
3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3101 def (template) # Loop through all spaces in the model, and # per the PNNL PRM Reference Manual, find the areas # of each space conditioning category (res, nonres, semi-heated) # separately. Include space multipliers. nr_wall_m2 = 0.001 # Avoids divide by zero errors later nr_wind_m2 = 0 res_wall_m2 = 0.001 res_wind_m2 = 0 sh_wall_m2 = 0.001 sh_wind_m2 = 0 self.getSpaces.each do |space| # Loop through all surfaces in this space wall_area_m2 = 0 wind_area_m2 = 0 space.surfaces.sort.each do |surface| # Skip non-outdoor surfaces next unless surface.outsideBoundaryCondition == 'Outdoors' # Skip non-walls next unless surface.surfaceType == 'Wall' # This wall's gross area (including window area) wall_area_m2 += surface.grossArea * space.multiplier # Subsurfaces in this surface surface.subSurfaces.sort.each do |ss| next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow' wind_area_m2 += ss.netArea * space.multiplier end end # Determine the space category cat = 'NonRes' if space.is_residential(template) cat = 'Res' end # if space.is_semiheated # cat = 'Semiheated' # end # Add to the correct category case cat when 'NonRes' nr_wall_m2 += wall_area_m2 nr_wind_m2 += wind_area_m2 when 'Res' res_wall_m2 += wall_area_m2 res_wind_m2 += wind_area_m2 when 'Semiheated' sh_wall_m2 += wall_area_m2 sh_wind_m2 += wind_area_m2 end end # Calculate the WWR of each category wwr_nr = ((nr_wind_m2 / nr_wall_m2)*100).round(1) wwr_res = ((res_wind_m2 / res_wall_m2)*100).round(1) wwr_sh = ((sh_wind_m2 / sh_wall_m2)*100).round(1) OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "The WWRs are: NonRes: #{wwr_nr.round}%, Res: #{wwr_res.round}%.") # WWR limit wwr_lim = 40.0 # Check against WWR limit wwr_nr > wwr_lim ? red_nr = true : red_nr = false wwr_res > wwr_lim ? red_res = true : red_res = false wwr_sh > wwr_lim ? red_sh = true : red_sh = false # Stop here unless windows need reducing return true unless red_nr || red_res || red_sh OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Reducing the size of all windows (by raising sill height) to reduce window area down to the limit of #{wwr_lim.round}%.") # Determine the factors by which to reduce the window area mult_nr_red = wwr_lim / wwr_nr mult_res_red = wwr_lim / wwr_res #mult_sh_red = wwr_lim / wwr_sh # Reduce the window area if any of the categories necessary self.getSpaces.each do |space| # Determine the space category cat = 'NonRes' if space.is_residential(template) cat = 'Res' end # if space.is_semiheated # cat = 'Semiheated' # end # Skip spaces whose windows don't need to be reduced case cat when 'NonRes' next unless red_nr mult = mult_nr_red when 'Res' next unless red_res mult = mult_res_red when 'Semiheated' next unless red_sh # mult = mult_sh_red end # Loop through all surfaces in this space space.surfaces.sort.each do |surface| # Skip non-outdoor surfaces next unless surface.outsideBoundaryCondition == 'Outdoors' # Skip non-walls next unless surface.surfaceType == 'Wall' # Subsurfaces in this surface surface.subSurfaces.sort.each do |ss| next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow' # Reduce the size of the window red = 1.0 - mult ss.reduce_area_by_percent_by_raising_sill(red) end end end return true end |
#apply_performance_rating_method_construction_types(template) ⇒ Bool
Go through the default construction sets and hard-assigned constructions. Clone the existing constructions and set their intended surface type and standards construction type per the PRM. For some standards, this will involve making modifications. For others, it will not.
90.1-2007, 90.1-2010, 90.1-2013
2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2890 def (template) types_to_modify = [] # Possible boundary conditions are # Adiabatic # Surface # Outdoors # Ground # Possible surface types are # AtticFloor # AtticWall # AtticRoof # DemisingFloor # DemisingWall # DemisingRoof # ExteriorFloor # ExteriorWall # ExteriorRoof # ExteriorWindow # ExteriorDoor # GlassDoor # GroundContactFloor # GroundContactWall # GroundContactRoof # InteriorFloor # InteriorWall # InteriorCeiling # InteriorPartition # InteriorWindow # InteriorDoor # OverheadDoor # Skylight # TubularDaylightDome # TubularDaylightDiffuser # Possible standards construction types # Mass # SteelFramed # WoodFramed # IEAD # View # Daylight # Swinging # NonSwinging # Heated # Unheated # RollUp # Sliding # Metal # Nonmetal framing (all) # Metal framing (curtainwall/storefront) # Metal framing (entrance door) # Metal framing (all other) # Metal Building # Attic and Other # Glass with Curb # Plastic with Curb # Without Curb # Create an array of types case template when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' types_to_modify << ['Outdoors', 'ExteriorWall', 'SteelFramed'] types_to_modify << ['Outdoors', 'ExteriorRoof', 'IEAD'] types_to_modify << ['Outdoors', 'ExteriorFloor', 'SteelFramed'] types_to_modify << ['Ground', 'GroundContactFloor', 'Unheated'] types_to_modify << ['Ground', 'GroundContactWall', 'Unheated'] end # Modify all constructions of each type types_to_modify.each do |boundary_cond, surf_type, const_type| constructions = self.find_constructions(boundary_cond, surf_type) constructions.sort.each do |const| standards_info = const.standardsInformation standards_info.setIntendedSurfaceType(surf_type) standards_info.setStandardsConstructionType(const_type) end end return true end |
#apply_standard_constructions(template, climate_zone) ⇒ Bool
Apply the standard construction to each surface in the model, based on the construction type currently assigned.
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2981 def apply_standard_constructions(template, climate_zone) types_to_modify = [] # Possible boundary conditions are # Adiabatic # Surface # Outdoors # Ground # Possible surface types are # Floor # Wall # RoofCeiling # FixedWindow # OperableWindow # Door # GlassDoor # OverheadDoor # Skylight # TubularDaylightDome # TubularDaylightDiffuser # Create an array of surface types # each standard applies to. case template when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' types_to_modify << ['Outdoors', 'Floor'] types_to_modify << ['Outdoors', 'Wall'] types_to_modify << ['Outdoors', 'RoofCeiling'] types_to_modify << ['Outdoors', 'FixedWindow'] types_to_modify << ['Outdoors', 'OperableWindow'] types_to_modify << ['Outdoors', 'Door'] types_to_modify << ['Outdoors', 'GlassDoor'] types_to_modify << ['Outdoors', 'OverheadDoor'] types_to_modify << ['Outdoors', 'Skylight'] types_to_modify << ['Ground', 'Floor'] types_to_modify << ['Ground', 'Wall'] end # Find just those surfaces surfaces_to_modify = [] types_to_modify.each do |boundary_condition, surface_type| # Surfaces self.getSurfaces.each do |surf| next unless surf.outsideBoundaryCondition == boundary_condition next unless surf.surfaceType == surface_type surfaces_to_modify << surf end # SubSurfaces self.getSubSurfaces.each do |surf| next unless surf.outsideBoundaryCondition == boundary_condition next unless surf.subSurfaceType == surface_type surfaces_to_modify << surf end end # Modify these surfaces prev_created_consts = {} surfaces_to_modify.sort.each do |surf| prev_created_consts = surf.apply_standard_construction(template, climate_zone, prev_created_consts) end # List the unique array of constructions OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Applying standard constructions") if prev_created_consts.size == 0 OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "None of the constructions in your proposed model have both Intended Surface Type and Standards Construction Type") else prev_created_consts.each do |surf_type, construction| OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "For #{surf_type.join(' ')}, applied #{construction.name}.") end end return true end |
#applyHVACEfficiencyStandard(building_vintage, climate_zone) ⇒ Object
Applies the HVAC parts of the standard to all objects in the model using the the template/standard specified in the model.
1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1561 def applyHVACEfficiencyStandard(building_vintage, climate_zone) sql_db_vars_map = Hash.new() OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying HVAC efficiency standards.') # Air Loop Controls self.getAirLoopHVACs.sort.each {|obj| obj.apply_standard_controls(building_vintage, climate_zone)} ##### Apply equipment efficiencies # Fans # self.getFanVariableVolumes.sort.each {|obj| obj.setStandardEfficiency(building_vintage)} # self.getFanConstantVolumes.sort.each {|obj| obj.setStandardEfficiency(building_vintage)} # self.getFanOnOffs.sort.each {|obj| obj.setStandardEfficiency(building_vintage)} # self.getFanZoneExhausts.sort.each {|obj| obj.setStandardEfficiency(building_vintage)} # Pumps #self.getPumpConstantSpeeds.sort.each {|obj| obj.set_standard_minimum_motor_efficiency(building_vintage)} #self.getPumpVariableSpeeds.sort.each {|obj| obj.set_standard_minimum_motor_efficiency(building_vintage)} # Unitary ACs self.getCoilCoolingDXTwoSpeeds.sort.each {|obj| obj.setStandardEfficiencyAndCurves(building_vintage)} self.getCoilCoolingDXSingleSpeeds.sort.each {|obj| sql_db_vars_map = obj.setStandardEfficiencyAndCurves(building_vintage, sql_db_vars_map)} # Unitary HPs self.getCoilHeatingDXSingleSpeeds.sort.each {|obj| sql_db_vars_map = obj.setStandardEfficiencyAndCurves(building_vintage, sql_db_vars_map)} # Chillers self.getChillerElectricEIRs.sort.each {|obj| obj.setStandardEfficiencyAndCurves(building_vintage)} # Boilers self.getBoilerHotWaters.sort.each {|obj| obj.setStandardEfficiencyAndCurves(building_vintage)} # Water Heaters self.getWaterHeaterMixeds.sort.each {|obj| obj.setStandardEfficiency(building_vintage)} OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying HVAC efficiency standards.') end |
#applyPrototypeHVACAssumptions(building_type, building_vintage, climate_zone) ⇒ Object
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 1047 def applyPrototypeHVACAssumptions(building_type, building_vintage, climate_zone) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying prototype HVAC assumptions.') ##### Apply equipment efficiencies # Fans self.getFanConstantVolumes.sort.each {|obj| obj.setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)} self.getFanVariableVolumes.sort.each {|obj| obj.setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)} self.getFanOnOffs.sort.each {|obj| obj.setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)} self.getFanZoneExhausts.sort.each {|obj| obj.setPrototypeFanPressureRise} ##### Add Economizers if (building_vintage != 'NECB 2011') then # Create an economizer maximum OA fraction of 70% # to reflect damper leakage per PNNL econ_max_70_pct_oa_sch = OpenStudio::Model::ScheduleRuleset.new(self) econ_max_70_pct_oa_sch.setName("Economizer Max OA Fraction 70 pct") econ_max_70_pct_oa_sch.defaultDaySchedule.setName("Economizer Max OA Fraction 70 pct Default") econ_max_70_pct_oa_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0.7) else # NECB 2011 prescribes ability to provide 100% OA (5.2.2.7-5.2.2.9) econ_max_100_pct_oa_sch = OpenStudio::Model::ScheduleRuleset.new(self) econ_max_100_pct_oa_sch.setName("Economizer Max OA Fraction 100 pct") econ_max_100_pct_oa_sch.defaultDaySchedule.setName("Economizer Max OA Fraction 100 pct Default") econ_max_100_pct_oa_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 1.0) end # Check each airloop self.getAirLoopHVACs.each do |air_loop| if air_loop.is_economizer_required(building_vintage, climate_zone) == true # If an economizer is required, determine the economizer type # in the prototype buildings, which depends on climate zone. economizer_type = nil case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007' economizer_type = 'DifferentialDryBulb' when '90.1-2010', '90.1-2013' case climate_zone when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-3A', 'ASHRAE 169-2006-4A' economizer_type = 'DifferentialEnthalpy' else economizer_type = 'DifferentialDryBulb' end when 'NECB 2011' # NECB 5.2.2.8 states that economizer can be controlled based on difference betweeen # return air temperature and outside air temperature OR return air enthalpy # and outside air enthalphy; latter chosen to be consistent with MNECB and CAN-QUEST implementation economizer_type = 'DifferentialEnthalpy' end # Set the economizer type # Get the OA system and OA controller oa_sys = air_loop.airLoopHVACOutdoorAirSystem if oa_sys.is_initialized oa_sys = oa_sys.get else OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "#{air_loop.name} is required to have an economizer, but it has no OA system.") next end oa_control = oa_sys.getControllerOutdoorAir oa_control.setEconomizerControlType(economizer_type) if (building_vintage != 'NECB 2011') then #oa_control.setMaximumFractionofOutdoorAirSchedule(econ_max_70_pct_oa_sch) else #oa_control.setMaximumFractionofOutdoorAirSchedule(econ_max_100_pct_oa_sch) end # Check that the economizer type set by the prototypes # is not prohibited by code. If it is, change to no economizer. unless air_loop.is_economizer_type_allowable(building_vintage, climate_zone) OpenStudio::logFree(OpenStudio::Warn, "openstudio.prototype.Model", "#{air_loop.name} is required to have an economizer, but the type chosen, #{economizer_type} is prohibited by code for #{building_vintage}, climate zone #{climate_zone}. Economizer type will be switched to No Economizer.") oa_control.setEconomizerControlType('NoEconomizer') end end end # TODO What is the logic behind hard-sizing # hot water coil convergence tolerances? self.getControllerWaterCoils.sort.each {|obj| obj.set_convergence_limits} OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying prototype HVAC assumptions.') end |
#applySizingValues ⇒ Object
Takes the values calculated by the EnergyPlus sizing routines and puts them into all objects model in place of the autosized fields. Must have previously completed a run with sql output for this to work.
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 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb', line 85 def applySizingValues # Ensure that the model has a sql file associated with it if self.sqlFile.empty? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'Failed to apply sizing values because model is missing sql file containing sizing results.') return false end # TODO Sizing methods for these types of equipment are # currently only stubs that need to be filled in. self.getAirConditionerVariableRefrigerantFlows.sort.each {|obj| obj.applySizingValues} self.getAirLoopHVACUnitaryHeatCoolVAVChangeoverBypasss.sort.each {|obj| obj.applySizingValues} self.getAirLoopHVACUnitarySystems.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctConstantVolumeCooledBeams.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctConstantVolumeFourPipeInductions.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctConstantVolumeReheats.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctSeriesPIUReheats.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctVAVHeatAndCoolNoReheats.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctVAVHeatAndCoolReheats.sort.each {|obj| obj.applySizingValues} self.getBoilerSteams.sort.each {|obj| obj.applySizingValues} self.getCoilCoolingDXMultiSpeeds.sort.each {|obj| obj.applySizingValues} self.getCoilCoolingDXVariableRefrigerantFlows.sort.each {|obj| obj.applySizingValues} self.getCoilCoolingWaterToAirHeatPumpEquationFits.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingWaterToAirHeatPumpEquationFits.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingGasMultiStages.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingDesuperheaters.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingDXVariableRefrigerantFlows.sort.each {|obj| obj.applySizingValues} self.getCoilWaterHeatingDesuperheaters.sort.each {|obj| obj.applySizingValues} self.getCoolingTowerTwoSpeeds.sort.each {|obj| obj.applySizingValues} self.getCoolingTowerVariableSpeeds.sort.each {|obj| obj.applySizingValues} self.getEvaporativeCoolerDirectResearchSpecials.sort.each {|obj| obj.applySizingValues} self.getEvaporativeCoolerIndirectResearchSpecials.sort.each {|obj| obj.applySizingValues} self.getEvaporativeFluidCoolerSingleSpeeds.sort.each {|obj| obj.applySizingValues} self.getHeatExchangerFluidToFluids.sort.each {|obj| obj.applySizingValues} self.getHumidifierSteamElectrics.sort.each {|obj| obj.applySizingValues} self.getZoneHVACBaseboardConvectiveElectrics.sort.each {|obj| obj.applySizingValues} self.getZoneHVACBaseboardConvectiveWaters.sort.each {|obj| obj.applySizingValues} self.getZoneHVACFourPipeFanCoils.sort.each {|obj| obj.applySizingValues} self.getZoneHVACHighTemperatureRadiants.sort.each {|obj| obj.applySizingValues} self.getZoneHVACIdealLoadsAirSystems.sort.each {|obj| obj.applySizingValues} self.getZoneHVACLowTemperatureRadiantElectrics.sort.each {|obj| obj.applySizingValues} self.getZoneHVACLowTempRadiantConstFlows.sort.each {|obj| obj.applySizingValues} self.getZoneHVACLowTempRadiantVarFlows.sort.each {|obj| obj.applySizingValues} self.getZoneHVACPackagedTerminalAirConditioners.sort.each {|obj| obj.applySizingValues} self.getZoneHVACPackagedTerminalHeatPumps.sort.each {|obj| obj.applySizingValues} self.getZoneHVACTerminalUnitVariableRefrigerantFlows.sort.each {|obj| obj.applySizingValues} self.getZoneHVACWaterToAirHeatPumps.sort.each {|obj| obj.applySizingValues} # Zone equipment # Air terminals self.getAirTerminalSingleDuctParallelPIUReheats.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctVAVReheats.sort.each {|obj| obj.applySizingValues} self.getAirTerminalSingleDuctUncontrolleds.sort.each {|obj| obj.applySizingValues} # AirLoopHVAC components self.getAirLoopHVACs.sort.each {|obj| obj.applySizingValues} self.getSizingSystems.sort.each {|obj| obj.applySizingValues} # Fans self.getFanConstantVolumes.sort.each {|obj| obj.applySizingValues} self.getFanVariableVolumes.sort.each {|obj| obj.applySizingValues} self.getFanOnOffs.sort.each {|obj| obj.applySizingValues} # Heating coils self.getCoilHeatingElectrics.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingGass.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingWaters.sort.each {|obj| obj.applySizingValues} self.getCoilHeatingDXSingleSpeeds.sort.each {|obj| obj.applySizingValues} # Cooling coils self.getCoilCoolingDXSingleSpeeds.sort.each {|obj| obj.applySizingValues} self.getCoilCoolingDXTwoSpeeds.sort.each {|obj| obj.applySizingValues} self.getCoilCoolingWaters.sort.each {|obj| obj.applySizingValues} # Outdoor air self.getControllerOutdoorAirs.sort.each {|obj| obj.applySizingValues} self.getHeatExchangerAirToAirSensibleAndLatents.sort.each {|obj| obj.applySizingValues} # PlantLoop components self.getPlantLoops.sort.each {|obj| obj.applySizingValues} # Pumps self.getPumpConstantSpeeds.sort.each {|obj| obj.applySizingValues} self.getPumpVariableSpeeds.sort.each {|obj| obj.applySizingValues} # Heating equipment self.getBoilerHotWaters.sort.each {|obj| obj.applySizingValues} # Cooling equipment self.getChillerElectricEIRs.sort.each {|obj| obj.applySizingValues} # Condenser equipment self.getCoolingTowerSingleSpeeds.sort.each {|obj| obj.applySizingValues} # Controls self.getControllerWaterCoils.sort.each {|obj| obj.applySizingValues} # VRF components # Refrigeration components return true end |
#assign_building_story(building_type, building_vintage, climate_zone, building_story_map) ⇒ Object
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 385 def assign_building_story(building_type, building_vintage, climate_zone, building_story_map) building_story_map.each do |building_story_name, space_names| stub_building_story = OpenStudio::Model::BuildingStory.new(self) stub_building_story.setName(building_story_name) space_names.each do |space_name| space = self.getSpaceByName(space_name) next if space.empty? space = space.get space.setBuildingStory(stub_building_story) end end return true end |
#assign_space_type_stubs(building_type, building_vintage, space_type_map) ⇒ Bool
Reads in a mapping between names of space types and names of spaces in the model, creates an empty OpenStudio::Model::SpaceType (no loads, occupants, schedules, etc.) for each space type, and assigns this space type to the list of spaces named. Later on, these empty space types can be used as keys in a lookup to add loads, schedules, and other inputs that are either typical or governed by a standard.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 362 def assign_space_type_stubs(building_type, building_vintage, space_type_map) space_type_map.each do |space_type_name, space_names| # Create a new space type stub_space_type = OpenStudio::Model::SpaceType.new(self) stub_space_type.setStandardsBuildingType(building_type) stub_space_type.setStandardsSpaceType(space_type_name) stub_space_type.setName("#{building_type} #{space_type_name}") stub_space_type.set_rendering_color(building_vintage) space_names.each do |space_name| space = self.getSpaceByName(space_name) next if space.empty? space = space.get space.setSpaceType(stub_space_type) #OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Setting #{space.name} to #{building_type}.#{space_type_name}") end end return true end |
#assign_spaces_to_stories ⇒ Bool
Assign each space in the model to a building story based on common z (height) values. If no story
object is found for a particular height, create a new one and assign it to the space. Does not assign a story to plenum spaces.
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1309 def assign_spaces_to_stories() # Make hash of spaces and minz values sorted_spaces = {} self.getSpaces.each do |space| # Skip plenum spaces next if space.is_plenum # loop through space surfaces to find min z value z_points = [] space.surfaces.each do |surface| surface.vertices.each do |vertex| z_points << vertex.z end end minz = z_points.min + space.zOrigin sorted_spaces[space] = minz end # Pre-sort spaces sorted_spaces = sorted_spaces.sort{|a,b| a[1]<=>b[1]} # Take the sorted list and assign/make stories sorted_spaces.each do |space| space_obj = space[0] space_minz = space[1] if space_obj.buildingStory.empty? story = get_story_for_nominal_z_coordinate(space_minz) space_obj.setBuildingStory(story) end end return true end |
#autosize ⇒ Object
Changes all hard-sized HVAC values to Autosized
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb', line 192 def autosize # TODO Sizing methods for these types of equipment are # currently only stubs that need to be filled in. self.getAirConditionerVariableRefrigerantFlows.sort.each {|obj| obj.autosize} self.getAirLoopHVACUnitaryHeatCoolVAVChangeoverBypasss.sort.each {|obj| obj.autosize} self.getAirLoopHVACUnitarySystems.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctConstantVolumeCooledBeams.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctConstantVolumeFourPipeInductions.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctConstantVolumeReheats.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctSeriesPIUReheats.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctVAVHeatAndCoolNoReheats.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctVAVHeatAndCoolReheats.sort.each {|obj| obj.autosize} self.getBoilerSteams.sort.each {|obj| obj.autosize} self.getCoilCoolingDXMultiSpeeds.sort.each {|obj| obj.autosize} self.getCoilCoolingDXVariableRefrigerantFlows.sort.each {|obj| obj.autosize} self.getCoilCoolingWaterToAirHeatPumpEquationFits.sort.each {|obj| obj.autosize} self.getCoilHeatingWaterToAirHeatPumpEquationFits.sort.each {|obj| obj.autosize} self.getCoilHeatingGasMultiStages.sort.each {|obj| obj.autosize} self.getCoilHeatingDesuperheaters.sort.each {|obj| obj.autosize} self.getCoilHeatingDXVariableRefrigerantFlows.sort.each {|obj| obj.autosize} self.getCoilWaterHeatingDesuperheaters.sort.each {|obj| obj.autosize} self.getCoolingTowerTwoSpeeds.sort.each {|obj| obj.autosize} self.getCoolingTowerVariableSpeeds.sort.each {|obj| obj.autosize} self.getEvaporativeCoolerDirectResearchSpecials.sort.each {|obj| obj.autosize} self.getEvaporativeCoolerIndirectResearchSpecials.sort.each {|obj| obj.autosize} self.getEvaporativeFluidCoolerSingleSpeeds.sort.each {|obj| obj.autosize} self.getHeatExchangerFluidToFluids.sort.each {|obj| obj.autosize} self.getHumidifierSteamElectrics.sort.each {|obj| obj.autosize} self.getZoneHVACBaseboardConvectiveElectrics.sort.each {|obj| obj.autosize} self.getZoneHVACBaseboardConvectiveWaters.sort.each {|obj| obj.autosize} self.getZoneHVACFourPipeFanCoils.sort.each {|obj| obj.autosize} self.getZoneHVACHighTemperatureRadiants.sort.each {|obj| obj.autosize} self.getZoneHVACIdealLoadsAirSystems.sort.each {|obj| obj.autosize} self.getZoneHVACLowTemperatureRadiantElectrics.sort.each {|obj| obj.autosize} self.getZoneHVACLowTempRadiantConstFlows.sort.each {|obj| obj.autosize} self.getZoneHVACLowTempRadiantVarFlows.sort.each {|obj| obj.autosize} self.getZoneHVACPackagedTerminalAirConditioners.sort.each {|obj| obj.autosize} self.getZoneHVACPackagedTerminalHeatPumps.sort.each {|obj| obj.autosize} self.getZoneHVACTerminalUnitVariableRefrigerantFlows.sort.each {|obj| obj.autosize} self.getZoneHVACWaterToAirHeatPumps.sort.each {|obj| obj.autosize} # Zone equipment # Air terminals self.getAirTerminalSingleDuctParallelPIUReheats.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctVAVReheats.sort.each {|obj| obj.autosize} self.getAirTerminalSingleDuctUncontrolleds.sort.each {|obj| obj.autosize} # AirLoopHVAC components self.getAirLoopHVACs.sort.each {|obj| obj.autosize} self.getSizingSystems.sort.each {|obj| obj.autosize} # Fans self.getFanConstantVolumes.sort.each {|obj| obj.autosize} self.getFanVariableVolumes.sort.each {|obj| obj.autosize} self.getFanOnOffs.sort.each {|obj| obj.autosize} # Heating coils self.getCoilHeatingElectrics.sort.each {|obj| obj.autosize} self.getCoilHeatingGass.sort.each {|obj| obj.autosize} self.getCoilHeatingWaters.sort.each {|obj| obj.autosize} self.getCoilHeatingDXSingleSpeeds.sort.each {|obj| obj.autosize} # Cooling coils self.getCoilCoolingDXSingleSpeeds.sort.each {|obj| obj.autosize} self.getCoilCoolingDXTwoSpeeds.sort.each {|obj| obj.autosize} self.getCoilCoolingWaters.sort.each {|obj| obj.autosize} # Outdoor air self.getControllerOutdoorAirs.sort.each {|obj| obj.autosize} self.getHeatExchangerAirToAirSensibleAndLatents.sort.each {|obj| obj.autosize} # PlantLoop components self.getPlantLoops.sort.each {|obj| obj.autosize} # Pumps self.getPumpConstantSpeeds.sort.each {|obj| obj.autosize} self.getPumpVariableSpeeds.sort.each {|obj| obj.autosize} # Heating equipment self.getBoilerHotWaters.sort.each {|obj| obj.autosize} # Cooling equipment self.getChillerElectricEIRs.sort.each {|obj| obj.autosize} # Condenser equipment self.getCoolingTowerSingleSpeeds.sort.each {|obj| obj.autosize} # Controls self.getControllerWaterCoils.sort.each {|obj| obj.autosize} # VRF components # Refrigeration components return true end |
#coil_cooling_fuels(cooling_coil) ⇒ Object
Get the cooling fuel type of a cooling coil
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 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 150 def coil_cooling_fuels(cooling_coil) fuels = [] # Get the object type obj_type = cooling_coil.iddObjectType.valueName.to_s case obj_type when 'OS_Coil_Cooling_DX_MultiSpeed' 'Electricity' when 'OS_Coil_Cooling_DX_SingleSpeed' fuels << 'Electricity' when 'OS_Coil_Cooling_DX_TwoSpeed' fuels << 'Electricity' when 'OS_Coil_Cooling_DX_TwoStageWithHumidityControlMode' fuels << 'Electricity' when 'OS_Coil_Cooling_DX_VariableRefrigerantFlow' fuels << 'Electricity' when 'OS_Coil_Cooling_DX_VariableSpeed' fuels << 'Electricity' when 'OS_Coil_Cooling_WaterToAirHeatPump_EquationFit' fuels << 'Electricity' when 'OS_Coil_Cooling_WaterToAirHeatPump_VariableSpeed_EquationFit' fuels << 'Electricity' when 'OS_CoilSystem_Cooling_DX_HeatExchangerAssisted' fuels << 'Electricity' when 'OS_CoilSystem_Cooling_Water_HeatExchangerAssisted' fuels << 'Electricity' when 'OS_HeatPump_WaterToWater_EquationFit_Cooling' fuels << 'Electricity' when 'OS_Refrigeration_AirChiller' fuels << 'Electricity' when 'OS_Coil_Cooling_CooledBeam' cooling_coil = cooling_coil.to_CoilCoolingCooledBeam.get if cooling_coil.plantLoop.is_initialized fuels += self.plant_loop_cooling_fuels(cooling_coil.plantLoop.get) end when 'OS_Coil_Cooling_LowTempRadiant_ConstFlow' cooling_coil = cooling_coil.to_CoilCoolingLowTempRadiantConstFlow.get if cooling_coil.plantLoop.is_initialized fuels += self.plant_loop_cooling_fuels(cooling_coil.plantLoop.get) end when 'OS_Coil_Cooling_LowTempRadiant_VarFlow' cooling_coil = cooling_coil.to_CoilCoolingLowTempRadiantVarFlow.get if cooling_coil.plantLoop.is_initialized fuels += self.plant_loop_cooling_fuels(cooling_coil.plantLoop.get) end when 'OS_Coil_Cooling_Water' cooling_coil = cooling_coil.to_CoilCoolingWater.get if cooling_coil.plantLoop.is_initialized fuels += self.plant_loop_cooling_fuels(cooling_coil.plantLoop.get) end else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No cooling fuel types found for #{obj_type}") end return fuels.uniq.sort end |
#coil_heating_fuels(heating_coil) ⇒ Object
Get the heating fuel type of a heating coil
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 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 102 def coil_heating_fuels(heating_coil) fuels = [] # Get the object type obj_type = heating_coil.iddObjectType.valueName.to_s case obj_type when 'OS_Coil_Heating_DX_MultiSpeed' fuels << 'Electricity' when 'OS_Coil_Heating_DX_SingleSpeed' fuels << 'Electricity' when 'OS_Coil_Heating_DX_VariableRefrigerantFlow' fuels << 'Electricity' when 'OS_Coil_Heating_DX_VariableSpeed' fuels << 'Electricity' when 'OS_Coil_Heating_Desuperheater' fuels << 'Electricity' when 'OS_Coil_Heating_Electric' fuels << 'Electricity' when 'OS_Coil_Heating_Gas' fuels << 'NaturalGas' when 'OS_Coil_Heating_Gas_MultiStage' fuels << 'NaturalGas' when 'OS_Coil_Heating_Water' heating_coil = heating_coil.to_CoilHeatingWater.get if heating_coil.plantLoop.is_initialized fuels += self.plant_loop_heating_fuels(heating_coil.plantLoop.get) end when 'OS_Coil_Heating_Water_BaseboardRadiant' heating_coil = heating_coil.to_CoilHeatingWaterBaseboardRadiant.get if heating_coil.plantLoop.is_initialized fuels += self.plant_loop_heating_fuels(heating_coil.plantLoop.get) end when 'OS_Coil_Heating_WaterToAirHeatPump_EquationFit' fuels << 'Electricity' when 'OS_Coil_Heating_WaterToAirHeatPump_VariableSpeedEquationFit' fuels << 'Electricity' when 'OS_Coil_WaterHeating_AirToWaterHeatPump' fuels << 'Electricity' when 'OS_Coil_WaterHeating_Desuperheater' fuels << 'Electricity' else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No heating fuel types found for #{obj_type}") end return fuels.uniq.sort end |
#create_performance_rating_method_baseline_building(building_type, building_vintage, climate_zone, sizing_run_dir = Dir.pwd, debug = false) ⇒ Bool
Per 90.1, the Performance Rating Method “does NOT offer an alternative
Creates a Performance Rating Method (aka Appendix G aka LEED) baseline building model based on the inputs currently in the model.
the current model with this model.
compliance path for minimum standard compliance.“ This means you can’t use this method for code compliance to get a permit.
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 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 97 def (building_type, building_vintage, climate_zone, sizing_run_dir = Dir.pwd, debug = false) lookup_building_type = self.get_lookup_name(building_type) self.getBuilding.setName("#{building_vintage}-#{building_type}-#{climate_zone} PRM baseline created: #{Time.new}") # Reduce the WWR and SRR, if necessary self.(building_vintage) self.(building_vintage) # Assign building stories to spaces in the building # where stories are not yet assigned. self.assign_spaces_to_stories # Modify the internal loads in each space type, # keeping user-defined schedules. OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Changing Lighting and Ventilation Rates") self.getSpaceTypes.sort.each do |space_type| space_type.set_internal_loads(building_vintage, false, true, false, false, true, false) end # Modify some of the construction types as necessary self.(building_vintage) # Set the construction properties of all the surfaces in the model self.apply_standard_constructions(building_vintage, climate_zone) # Get the groups of zones that define the # baseline HVAC systems for later use. # This must be done before removing the HVAC systems # because it requires knowledge of proposed HVAC fuels. sys_groups = self.(building_vintage) # Remove all HVAC from model BTAP::Resources::HVAC.clear_all_hvac_from_model(self) # Add ideal loads to every zone and run # a sizing run to determine heating/cooling loads, # which will impact which zones go onto secondary # HVAC systems. self.getThermalZones.each do |zone| ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(self) ideal_loads.addToThermalZone(zone) end # Run sizing run if self.runSizingRun("#{sizing_run_dir}/SizingRunIdeal") == false return false end # Remove ideal loads self.getZoneHVACIdealLoadsAirSystems.each do |ideal_loads| ideal_loads.remove end # Determine the baseline HVAC system type for each of # the groups of zones and add that system type. sys_groups.each do |sys_group| # Determine the primary baseline system type system_type = (building_vintage, climate_zone, sys_group['type'], sys_group['fuel'], sys_group['area_ft2'], sys_group['stories']) OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "System type is #{system_type} for #{sys_group['zones'].size} zones.") sys_group['zones'].each do |zone| OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "---#{zone.name}") end # Add the system type for these zones self.(building_vintage, system_type, sys_group['zones']) end # SAT reset, economizers self.getAirLoopHVACs.sort.each do |air_loop| air_loop.(building_vintage, climate_zone) end # Apply the minimum damper positions self.getAirLoopHVACs.sort.each do |air_loop| air_loop.set_minimum_vav_damper_positions(building_vintage) end # Apply the baseline system temperatures self.getPlantLoops.sort.each do |plant_loop| plant_loop.(building_vintage) end # Run sizing run with the HVAC equipment if self.runSizingRun("#{sizing_run_dir}/SizingRun1") == false return false end # If there are any multizone systems, set damper positions # and perform a second sizing run has_multizone_systems = false self.getAirLoopHVACs.sort.each do |air_loop| if air_loop.is_multizone_vav_system self.apply_multizone_vav_outdoor_air_sizing(building_vintage) if self.runSizingRun("#{sizing_run_dir}/SizingRun2") == false return false end break end end # Set the baseline fan power for all airloops self.getAirLoopHVACs.sort.each do |air_loop| air_loop.(building_vintage) end # Set the baseline pumping power for all plant loops # Set the baseline pump control type for all plant loops # Set the baseline number of boilers self.getPlantLoops.sort.each do |plant_loop| plant_loop.(building_vintage) plant_loop.(building_vintage) plant_loop.(building_vintage) plant_loop.(building_vintage) end # Run sizing run with the new chillers and boilers to determine capacities if self.runSizingRun("#{sizing_run_dir}/SizingRun3") == false return false end # Apply the HVAC efficiency standard self.applyHVACEfficiencyStandard(building_vintage, climate_zone) # Add daylighting controls to each space self.getSpaces.sort.each do |space| added = space.addDaylightingControls(building_vintage, false, false) end # Delete all the unused curves self.getCurves.sort.each do |curve| if curve.parent.empty? #OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "#{curve.name} is unused; it will be removed.") curve.remove end end # Todo: turn off self shading # Set Solar Distribution to MinimalShadowing... problem is when you also have detached shading such as surrounding buildings etc # It won't be taken into account, while it should: only self shading from the building itself should be turned off but to my knowledge there isn't a way to do this in E+ model_status = 'final' self.save(OpenStudio::Path.new("#{sizing_run_dir}/#{model_status}.osm"), true) # Translate to IDF and save for debugging forward_translator = OpenStudio::EnergyPlus::ForwardTranslator.new idf = forward_translator.translateModel(self) idf_path = OpenStudio::Path.new("#{sizing_run_dir}/#{model_status}.idf") idf.save(idf_path,true) return true end |
#create_prototype_building(building_type, building_vintage, climate_zone, sizing_run_dir = Dir.pwd, debug = false) ⇒ Bool
Creates a DOE prototype building model and replaces the current model with this model.
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 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 25 def create_prototype_building(building_type, building_vintage, climate_zone, sizing_run_dir = Dir.pwd, debug = false) lookup_building_type = self.get_lookup_name(building_type) # Retrieve the Prototype Inputs from JSON search_criteria = { 'template' => building_vintage, 'building_type' => building_type } prototype_input = self.find_object($os_standards['prototype_inputs'], search_criteria) if prototype_input.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Could not find prototype inputs for #{search_criteria}, cannot create model.") return false end self.load_building_type_methods(building_type, building_vintage, climate_zone) self.load_geometry(building_type, building_vintage, climate_zone) self.getBuilding.setName("#{building_vintage}-#{building_type}-#{climate_zone} created: #{Time.new}") space_type_map = self.define_space_type_map(building_type, building_vintage, climate_zone) self.assign_space_type_stubs(lookup_building_type, building_vintage, space_type_map) self.add_loads(building_vintage, climate_zone) self.apply_infiltration_standard(building_vintage) self.modify_infiltration_coefficients(building_type, building_vintage, climate_zone) self.modify_surface_convection_algorithm(building_vintage) self.add_constructions(lookup_building_type, building_vintage, climate_zone) self.create_thermal_zones(building_type,building_vintage, climate_zone) self.add_hvac(building_type, building_vintage, climate_zone, prototype_input) self.custom_hvac_tweaks(building_type, building_vintage, climate_zone, prototype_input) self.add_swh(building_type, building_vintage, climate_zone, prototype_input) self.custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input) self.add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input) self.add_occupancy_sensors(building_type, building_vintage, climate_zone) self.add_design_days_and_weather_file(building_type, building_vintage, climate_zone) self.set_sizing_parameters(building_type, building_vintage) self.yearDescription.get.setDayofWeekforStartDay('Sunday') # Perform a sizing run if self.runSizingRun("#{sizing_run_dir}/SizingRun1") == false return false end # If there are any multizone systems, set damper positions # and perform a second sizing run has_multizone_systems = false self.getAirLoopHVACs.sort.each do |air_loop| if air_loop.is_multizone_vav_system self.apply_multizone_vav_outdoor_air_sizing(building_vintage) if self.runSizingRun("#{sizing_run_dir}/SizingRun2") == false return false end break end end # Apply the prototype HVAC assumptions # which include sizing the fan pressure rises based # on the flow rate of the system. self.applyPrototypeHVACAssumptions(building_type, building_vintage, climate_zone) # Apply the HVAC efficiency standard self.applyHVACEfficiencyStandard(building_vintage, climate_zone) # Add daylighting controls per standard # only four zones in large hotel have daylighting controls # todo: YXC to merge to the main function if building_type != "LargeHotel" self.addDaylightingControls(building_vintage) else self.add_daylighting_controls(building_vintage) end if building_type == "QuickServiceRestaurant" || building_type == "FullServiceRestaurant" self.update_exhaust_fan_efficiency(building_vintage) end if building_type == "HighriseApartment" self.update_fan_efficiency end # Add output variables for debugging if debug self.request_timeseries_outputs end # Finished model_status = 'final' self.save(OpenStudio::Path.new("#{sizing_run_dir}/#{model_status}.osm"), true) return true end |
#create_thermal_zones(building_type, building_vintage, climate_zone) ⇒ Bool
Creates thermal zones to contain each space, as defined for each building in the system_to_space_map inside the Prototype.building_name e.g. (Prototype.secondary_school.rb) file.
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 703 def create_thermal_zones(building_type,building_vintage, climate_zone) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started creating thermal zones') # This map define the multipliers for spaces with multipliers not equals to 1 case building_type when 'LargeHotel', 'MidriseApartment','LargeOffice' space_multiplier_map = self.define_space_multiplier else space_multiplier_map ={} end # Create a thermal zone for each space in the self self.getSpaces.each do |space| zone = OpenStudio::Model::ThermalZone.new(self) zone.setName("#{space.name} ZN") if space_multiplier_map[space.name.to_s] != nil zone.setMultiplier(space_multiplier_map[space.name.to_s]) end space.setThermalZone(zone) # Skip thermostat for spaces with no space type next if space.spaceType.empty? # Add a thermostat space_type_name = space.spaceType.get.name.get thermostat_name = space_type_name + ' Thermostat' thermostat = self.getThermostatSetpointDualSetpointByName(thermostat_name) if thermostat.empty? OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "Thermostat #{thermostat_name} not found for space name: #{space.name}") else thermostatClone = thermostat.get.clone(self).to_ThermostatSetpointDualSetpoint.get zone.setThermostatSetpointDualSetpoint(thermostatClone) end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished creating thermal zones') return true end |
#custom_hvac_tweaks(building_type, building_vintage, climate_zone, prototype_input) ⇒ Object
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 307 def custom_hvac_tweaks(building_type, building_vintage, climate_zone, prototype_input) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started building type specific adjustments') # add extra equipment for kitchen self.add_extra_equip_kitchen(building_vintage) # add extra infiltration for dining room door and attic self.add_door_infiltration(building_vintage,climate_zone) # add zone_mixing between kitchen and dining self.add_zone_mixing(building_vintage) # Update Sizing Zone self.update_sizing_zone(building_vintage) # adjust the cooling setpoint self.adjust_clg_setpoint(building_vintage,climate_zone) # reset the design OA of kitchen self.reset_kitchen_OA(building_vintage) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished building type specific adjustments') return true end |
#custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input) ⇒ Object
520 521 522 523 524 525 526 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 520 def custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input) self.update_waterheater_loss_coefficient(building_vintage) return true end |
#define_building_story_map(building_type, building_vintage, climate_zone) ⇒ Object
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
# File 'lib/openstudio-standards/prototypes/Prototype.small_hotel.rb', line 483 def define_building_story_map(building_type, building_vintage, climate_zone) building_story_map = nil building_story_map = { 'BuildingStory1' => [ 'GuestRoom101','GuestRoom102','GuestRoom103','GuestRoom104','GuestRoom105', 'CorridorFlr1','ElevatorCoreFlr1','EmployeeLoungeFlr1','ExerciseCenterFlr1', 'FrontLoungeFlr1','FrontOfficeFlr1','FrontStairsFlr1','RearStairsFlr1', 'FrontStorageFlr1','RearStorageFlr1','LaundryRoomFlr1','MechanicalRoomFlr1', 'MeetingRoomFlr1','RestroomFlr1'], 'BuildingStory2' => [ 'GuestRoom201','GuestRoom202_205','GuestRoom206_208','GuestRoom209_212','GuestRoom213', 'GuestRoom214','GuestRoom215_218','GuestRoom219','GuestRoom220_223','GuestRoom224', 'CorridorFlr2','FrontStairsFlr2','RearStairsFlr2','FrontStorageFlr2','RearStorageFlr2','ElevatorCoreFlr2'], 'BuildingStory3' => [ 'GuestRoom301','GuestRoom302_305','GuestRoom306_308','GuestRoom309_312','GuestRoom313', 'GuestRoom314','GuestRoom315_318','GuestRoom319','GuestRoom320_323','GuestRoom324', 'CorridorFlr3','FrontStairsFlr3','RearStairsFlr3','FrontStorageFlr3','RearStorageFlr3','ElevatorCoreFlr3'], 'BuildingStory4' => [ 'GuestRoom401','GuestRoom402_405','GuestRoom406_408','GuestRoom409_412','GuestRoom413', 'GuestRoom414','GuestRoom415_418','GuestRoom419','GuestRoom420_423','GuestRoom424', 'CorridorFlr4','FrontStairsFlr4','RearStairsFlr4','FrontStorageFlr4','RearStorageFlr4','ElevatorCoreFlr4'] } # attic only applies to the two DOE vintages. if building_vintage == 'DOE Ref Pre-1980' or building_vintage == 'DOE Ref 1980-2004' building_story_map['AtticStory'] = ['Attic'] end return building_story_map end |
#define_hvac_system_map(building_type, building_vintage, climate_zone) ⇒ Object
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 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 23 def define_hvac_system_map(building_type, building_vintage, climate_zone) case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' system_to_space_map = [ { 'type' => 'PSZ-AC', 'space_names' => ['Dining', 'Kitchen'] }, { 'type' => 'Exhaust Fan', 'name' => 'Dining Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood HVACOperationSchd', 'flow_rate' => 0.834532374, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => nil, 'space_names' => [ 'Dining' ] }, { 'type' => 'Exhaust Fan', 'name' => 'Kitchen Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood HVACOperationSchd', 'flow_rate' => 0.722467626, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => nil, 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Walkin Freezer', 'cooling_capacity_per_length' => 688, 'length' => 2.44, 'evaporator_fan_pwr_per_length' => 74, 'lighting_per_length' => 33, 'lighting_sch_name' => 'QuickServiceRestaurant Bldg Light', 'defrost_pwr_per_length' => 1291.7, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:1_WALKINFREEZER_WalkInStockingSched', 'cop' => 1.5, 'cop_f_of_t_curve_name' => 'RACK1_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => 'RACK1_RackCondFanCurve2', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Display Case', 'cooling_capacity_per_length' => 734.0, 'length' => 3.05, 'evaporator_fan_pwr_per_length' => 66, 'lighting_per_length' => 33.0, 'lighting_sch_name' => 'QuickServiceRestaurant Bldg Light', 'defrost_pwr_per_length' => 0.0, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:2_SELFCONTAINEDDISPLAYCASE_CaseStockingSched', 'cop' => 3.0, 'cop_f_of_t_curve_name' => 'RACK2_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => nil, 'space_names' => [ 'Kitchen' ] } ] when '90.1-2004' system_to_space_map = [ { 'type' => 'PSZ-AC', 'space_names' => ['Dining', 'Kitchen'] }, { 'type' => 'Exhaust Fan', 'name' => 'Kitchen Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood Hours_of_operation', 'flow_rate' => 1.557427, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => 'RestaurantFastFood Kitchen Exhaust Fan Balanced Exhaust Fraction Schedule_2004', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Exhaust Fan', 'name' => 'Dining Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood Hours_of_operation', 'flow_rate' => 0.826233, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => nil, 'space_names' => [ 'Dining' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Walkin Freezer', 'cooling_capacity_per_length' => 688, 'length' => 2.44, 'evaporator_fan_pwr_per_length' => 74, 'lighting_per_length' => 33, 'lighting_sch_name' => 'RestaurantFastFood BLDG_LIGHT_DINING_SCH_2004_2007', 'defrost_pwr_per_length' => 1291.7, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:1_WALKINFREEZER_WalkInStockingSched', 'cop' => 1.5, 'cop_f_of_t_curve_name' => 'RACK1_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => 'RACK1_RackCondFanCurve2', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Display Case', 'cooling_capacity_per_length' => 734.0, 'length' => 3.05, 'evaporator_fan_pwr_per_length' => 66, 'lighting_per_length' => 33.0, 'lighting_sch_name' => 'RestaurantFastFood BLDG_LIGHT_DINING_SCH_2004_2007', 'defrost_pwr_per_length' => 0.0, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:2_SELFCONTAINEDDISPLAYCASE_CaseStockingSched', 'cop' => 3.0, 'cop_f_of_t_curve_name' => 'RACK2_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => nil, 'space_names' => [ 'Kitchen' ] } ] when '90.1-2007', '90.1-2010' system_to_space_map = [ { 'type' => 'PSZ-AC', 'space_names' => ['Dining', 'Kitchen'] }, { 'type' => 'Exhaust Fan', 'name' => 'Kitchen Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood Hours_of_operation', 'flow_rate' => 1.557427, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => 'RestaurantFastFood Kitchen Exhaust Fan Balanced Exhaust Fraction Schedule_2007_2010_2013', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Exhaust Fan', 'name' => 'Dining Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood Hours_of_operation', 'flow_rate' => 0.416, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => nil, 'space_names' => [ 'Dining' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Walkin Freezer', 'cooling_capacity_per_length' => 688, 'length' => 2.44, 'evaporator_fan_pwr_per_length' => 74, 'lighting_per_length' => 33, 'lighting_sch_name' => 'RestaurantFastFood BLDG_LIGHT_DINING_SCH_2004_2007', 'defrost_pwr_per_length' => 1291.7, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:1_WALKINFREEZER_WalkInStockingSched', 'cop' => 1.5, 'cop_f_of_t_curve_name' => 'RACK1_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => 'RACK1_RackCondFanCurve2', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Display Case', 'cooling_capacity_per_length' => 734.0, 'length' => 3.05, 'evaporator_fan_pwr_per_length' => 66, 'lighting_per_length' => 33.0, 'lighting_sch_name' => 'RestaurantFastFood BLDG_LIGHT_DINING_SCH_2004_2007', 'defrost_pwr_per_length' => 0.0, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:2_SELFCONTAINEDDISPLAYCASE_CaseStockingSched', 'cop' => 3.0, 'cop_f_of_t_curve_name' => 'RACK2_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => nil, 'space_names' => [ 'Kitchen' ] } ] when '90.1-2013' system_to_space_map = [ { 'type' => 'PSZ-AC', 'space_names' => ['Dining', 'Kitchen'] }, { 'type' => 'Exhaust Fan', 'name' => 'Kitchen Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood Hours_of_operation', 'flow_rate' => 1.557427, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => 'RestaurantFastFood Kitchen Exhaust Fan Balanced Exhaust Fraction Schedule_2007_2010_2013', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Exhaust Fan', 'name' => 'Dining Exhaust Fan', 'availability_sch_name' => 'RestaurantFastFood Hours_of_operation', 'flow_rate' => 0.416, 'flow_fraction_schedule_name' => nil, 'balanced_exhaust_fraction_schedule_name' => nil, 'space_names' => [ 'Dining' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Walkin Freezer', 'cooling_capacity_per_length' => 688, 'length' => 2.44, 'evaporator_fan_pwr_per_length' => 21.143, 'lighting_per_length' => 33, 'lighting_sch_name' => 'RestaurantFastFood walkin_occ_lght_SCH', 'defrost_pwr_per_length' => 1291.7, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:1_WALKINFREEZER_WalkInStockingSched', 'cop' => 1.5, 'cop_f_of_t_curve_name' => 'RACK1_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => 'RACK1_RackCondFanCurve2', 'space_names' => [ 'Kitchen' ] }, { 'type' => 'Refrigeration', 'case_type' => 'Display Case', 'cooling_capacity_per_length' => 734.0, 'length' => 3.05, 'evaporator_fan_pwr_per_length' => 18.857, 'lighting_per_length' => 33.0, 'lighting_sch_name' => 'RestaurantFastFood walkin_occ_lght_SCH', 'defrost_pwr_per_length' => 0.0, 'restocking_sch_name' => 'RestaurantFastFood Kitchen_Case:2_SELFCONTAINEDDISPLAYCASE_CaseStockingSched', 'cop' => 3.0, 'cop_f_of_t_curve_name' => 'RACK2_RackCOPfTCurve', 'condenser_fan_pwr' => 330, 'condenser_fan_pwr_curve_name' => nil, 'space_names' => [ 'Kitchen' ] } ] end return system_to_space_map end |
#define_space_multiplier ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/openstudio-standards/prototypes/Prototype.mid_rise_apartment.rb', line 140 def define_space_multiplier # This map define the multipliers for spaces with multipliers not equals to 1 space_multiplier_map = { 'M SW Apartment' => 2, 'M NW Apartment' => 2, 'M SE Apartment' => 2, 'M NE Apartment' => 2, 'M N1 Apartment' => 2, 'M N2 Apartment' => 2, 'M S1 Apartment' => 2, 'M S2 Apartment' => 2, 'M Corridor' => 2 } return space_multiplier_map end |
#define_space_type_map(building_type, building_vintage, climate_zone) ⇒ Object
TODO: The ElectricEquipment schedules are wrong in OpenStudio Standards… It needs to be ‘RetailStandalone BLDG_EQUIP_SCH’ for 90.1-2010 at least but probably all TODO: There is an OpenStudio bug where two heat exchangers are on the equipment list and it references the same single heat exchanger for both. This doubles the heat recovery energy. TODO: The HeatExchangerAirToAir is not calculating correctly. It does not equal the legacy IDF and has higher energy usage due to that. TODO: Need to determine if WaterHeater can be alone or if we need to ‘fake’ it.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/openstudio-standards/prototypes/Prototype.retail_standalone.rb', line 10 def define_space_type_map(building_type, building_vintage, climate_zone) space_type_map = nil case building_vintage when 'DOE Ref Pre-1980' space_type_map = { 'Dining' => ['Dining'], 'Kitchen' => ['Kitchen'] } when 'DOE Ref 1980-2004','90.1-2010','90.1-2007','90.1-2004','90.1-2013' space_type_map = { 'Dining' => ['Dining'], 'Kitchen' => ['Kitchen'], 'Attic' => ['attic'] } end return space_type_map end |
#differentiate_primary_secondary_thermal_zones(zones) ⇒ Hash
Improve load-based exception algorithm.
Determine which of the zones should be served by the primary HVAC system. First, eliminate zones that differ by more than 40 full load hours per week. In this case, lighting schedule is used as the proxy for operation instead of occupancy to avoid accidentally removing transition spaces. Second, eliminate zones whose heating or cooling loads differ from the area-weighted average of all other zones on the system by more than 10 Btu/hr*ft^2.
Current algorithm is faithful to 90.1, but can lead to nonsensical results in some cases. where the keys are ‘primary’ and ‘secondary’
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1068 def differentiate_primary_secondary_thermal_zones(zones) # Determine the operational hours (proxy is annual # full load lighting hours) for all zones zone_data_1 = [] zones.each do |zone| data = {} data['zone'] = zone # Get the area area_ft2 = OpenStudio.convert(zone.floorArea, 'm^2', 'ft^2').get data['area_ft2'] = area_ft2 #OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "#{zone.name}") zone.spaces.each do |space| #OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "***#{space.name}") # Get all lights from either the space # or the space type. all_lights = [] all_lights += space.lights if space.spaceType.is_initialized all_lights += space.spaceType.get.lights end # Base the annual operational hours # on the first lights schedule with hours # greater than zero. ann_op_hrs = 0 all_lights.sort.each do |lights| #OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "******#{lights.name}") # Get the fractional lighting schedule lights_sch = lights.schedule full_load_hrs = 0.0 # Skip lights with no schedule next if lights_sch.empty? lights_sch = lights_sch.get if lights_sch.to_ScheduleRuleset.is_initialized lights_sch = lights_sch.to_ScheduleRuleset.get full_load_hrs = lights_sch.annual_equivalent_full_load_hrs if full_load_hrs > 0 ann_op_hrs = full_load_hrs break # Stop after the first schedule with more than 0 hrs end elsif lights_sch.to_ScheduleConstant.is_initialized lights_sch = lights_sch.to_ScheduleConstant.get full_load_hrs = lights_sch.annual_equivalent_full_load_hrs if full_load_hrs > 0 ann_op_hrs = full_load_hrs break # Stop after the first schedule with more than 0 hrs end end end wk_op_hrs = ann_op_hrs / 52.0 data['wk_op_hrs'] = wk_op_hrs #OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "******wk_op_hrs = #{wk_op_hrs.round}") end zone_data_1 << data end # Filter out any zones that operate differently by more # than 40hrs/wk. This will be determined by a difference of more # than (40 hrs/wk * 52 wks/yr) = 2080 annual full load hrs. zones_same_hrs = [] zone_data_1.each_with_index do |data, i| # Eliminate the data from this zone other_zone_data_1 = Array.new(zone_data_1) other_zone_data_1.delete_at(i) # Calculate the area-weighted # average operating hours area_hrs = 1 tot_area = 1 other_zone_data_1.each do |other_data| area_hrs += other_data['area_ft2'] * other_data['wk_op_hrs'] tot_area += other_data['area_ft2'] end avg_wk_op_hrs = area_hrs / tot_area OpenStudio::logFree(OpenStudio::Debug, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name} weekly operating hours = #{data['wk_op_hrs'].round} hrs/wk, average of #{avg_wk_op_hrs.round} hrs/wk for other zones on the system.") # Compare avg to this zone wk_op_hrs = data['wk_op_hrs'] if wk_op_hrs < avg_wk_op_hrs - 40.0 OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, the weekly full load operating hrs of #{wk_op_hrs.round} hrs is more than 40 hrs lower than the average of #{avg_wk_op_hrs.round} hrs for other zones on the system, zone will not be attached to the primary system.") next elsif wk_op_hrs > avg_wk_op_hrs + 40.0 OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, the weekly full load operating hrs of #{wk_op_hrs.round} hrs is more than 40 hrs higher than the average of #{avg_wk_op_hrs.round} hrs for other zones on the system, zone will not be attached to the primary system.") next end # Operating hours are same zones_same_hrs << data['zone'] end # Get the heating and cooling loads and areas for # all remaining zones. zone_data_2 = [] zones_same_hrs.each do |zone| data = {} data['zone'] = zone # Get the area area_ft2 = OpenStudio.convert(zone.floorArea, 'm^2', 'ft^2').get data['area_ft2'] = area_ft2 # Get the heating load htg_load_w_per_m2 = zone.heatingDesignLoad if htg_load_w_per_m2.is_initialized htg_load_btu_per_ft2 = OpenStudio.convert(htg_load_w_per_m2.get,'W/m^2','Btu/hr*ft^2').get data['htg_load_btu_per_ft2'] = htg_load_btu_per_ft2 else OpenStudio::logFree(OpenStudio::Warn, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, could not determine the design heating load.") end # Get the cooling load clg_load_w_per_m2 = zone.coolingDesignLoad if clg_load_w_per_m2.is_initialized clg_load_btu_per_ft2 = OpenStudio.convert(clg_load_w_per_m2.get,'W/m^2','Btu/hr*ft^2').get data['clg_load_btu_per_ft2'] = clg_load_btu_per_ft2 else OpenStudio::logFree(OpenStudio::Warn, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, could not determine the design cooling load.") end zone_data_2 << data end # Filter out any zones that are +/- 10 Btu/hr*ft^2 from the # area-weighted average. primary_zones = [] zone_data_2.each_with_index do |data, i| # Eliminate the data from this zone other_zone_data_2 = Array.new(zone_data_2) other_zone_data_2.delete_at(i) # Calculate the area-weighted # average heating and cooling loads htg_load_hrs = 0 clg_load_hrs = 0 area_hrs = 1 htg_area = 1 clg_area = 1 other_zone_data_2.each do |other_data| # Don't include nil or zero loads in average unless other_data['htg_load_btu_per_ft2'].nil? || other_data['htg_load_btu_per_ft2'] == 0.0 htg_load_hrs += other_data['area_ft2'] * other_data['htg_load_btu_per_ft2'] htg_area += other_data['area_ft2'] end # Don't include nil or zero loads in average unless other_data['clg_load_btu_per_ft2'].nil? || other_data['clg_load_btu_per_ft2'] == 0.0 clg_load_hrs += other_data['area_ft2'] * other_data['clg_load_btu_per_ft2'] clg_area += other_data['area_ft2'] end end avg_htg_load_btu_per_ft2 = htg_load_hrs / htg_area avg_clg_load_btu_per_ft2 = clg_load_hrs / clg_area # This is throwing an error: undefined method `round' for nil:NilClass # So I'll assign zero if nil for now data['htg_load_btu_per_ft2'] ||= 0 data['clg_load_btu_per_ft2'] ||= 0 OpenStudio::logFree(OpenStudio::Debug, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name} heating = #{data['htg_load_btu_per_ft2'].round} Btu/hr*ft^2, average heating = #{avg_htg_load_btu_per_ft2.round} Btu/hr*ft^2 for other zones. Cooling = #{data['clg_load_btu_per_ft2'].round} Btu/hr*ft^2, average cooling = #{avg_clg_load_btu_per_ft2.round} Btu/hr*ft^2 for other zones.") # Filter on heating load htg_load_btu_per_ft2 = data['htg_load_btu_per_ft2'] if htg_load_btu_per_ft2 < avg_htg_load_btu_per_ft2 - 10.0 OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, the heating load of #{htg_load_btu_per_ft2.round} Btu/hr*ft^2 is more than 10 Btu/hr*ft^2 lower than the average of #{avg_htg_load_btu_per_ft2.round} Btu/hr*ft^2 for other zones on the system, zone will be assigned a secondary system.") next elsif htg_load_btu_per_ft2 > avg_htg_load_btu_per_ft2 + 10.0 OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, the heating load of #{htg_load_btu_per_ft2.round} Btu/hr*ft^2 is more than 10 Btu/hr*ft^2 higher than the average of #{avg_htg_load_btu_per_ft2.round} Btu/hr*ft^2 for other zones on the system, zone will be assigned a secondary system.") next end # Filter on cooling load clg_load_btu_per_ft2 = data['clg_load_btu_per_ft2'] if clg_load_btu_per_ft2 < avg_clg_load_btu_per_ft2 - 10.0 OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, the cooling load of #{clg_load_btu_per_ft2.round} Btu/hr*ft^2 is more than 10 Btu/hr*ft^2 lower than the average of #{avg_clg_load_btu_per_ft2.round} Btu/hr*ft^2 for other zones on the system, zone will be assigned a secondary system.") next elsif clg_load_btu_per_ft2 > avg_clg_load_btu_per_ft2 + 10.0 OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.BuildingStory", "For zone #{data['zone'].name}, the cooling load of #{clg_load_btu_per_ft2.round} Btu/hr*ft^2 is more than 10 Btu/hr*ft^2 higher than the average of #{avg_clg_load_btu_per_ft2.round} Btu/hr*ft^2 for other zones on the system, zone will be assigned a secondary system.") next end # It is a primary zone! primary_zones << data['zone'] end # Secondary zones are all other zones secondary_zones = [] zones.each do |zone| unless primary_zones.include?(zone) secondary_zones << zone end end return {'primary'=>primary_zones, 'secondary'=>secondary_zones} end |
#find_and_add_construction(building_vintage, climate_zone_set, intended_surface_type, standards_construction_type, building_category) ⇒ Object
Helper method to find a particular construction and add it to the model after modifying the insulation value if necessary.
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2121 def find_and_add_construction(building_vintage, climate_zone_set, intended_surface_type, standards_construction_type, building_category) # Get the construction properties, # which specifies properties by construction category by climate zone set. # AKA the info in Tables 5.5-1-5.5-8 props = self.find_object($os_standards['construction_properties'], {'template'=>building_vintage, 'climate_zone_set'=> climate_zone_set, 'intended_surface_type'=> intended_surface_type, 'standards_construction_type'=> standards_construction_type, 'building_category' => building_category }) if !props OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Could not find construction properties for: #{building_vintage}-#{climate_zone_set}-#{intended_surface_type}-#{standards_construction_type}-#{building_category}.") # Return an empty construction construction = OpenStudio::Model::Construction.new(self) construction.setName("Could not find construction properties") return construction else OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "Construction properties for: #{building_vintage}-#{climate_zone_set}-#{intended_surface_type}-#{standards_construction_type}-#{building_category} = #{props}.") end # Make sure that a construction is specified if props['construction'].nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No typical construction is specified for construction properties of: #{building_vintage}-#{climate_zone_set}-#{intended_surface_type}-#{standards_construction_type}-#{building_category}. Make sure it is entered in the spreadsheet.") # Return an empty construction construction = OpenStudio::Model::Construction.new(self) construction.setName("No typical construction was specified") return construction end # Add the construction, modifying properties as necessary construction = add_construction(props['construction'], props) return construction end |
#find_ashrae_hot_water_demand ⇒ Array
Returns average daily hot water consumption by building type recommendations from 2011 ASHRAE Handobook - HVAC Applications Table 7 section 60.14 Not all building types are included in lookup some recommendations have multiple values based on number of units. Will return an array of hashes. Many may have one array entry. all values other than block size are gallons.
specific to building type. Array will be empty for some building types.
3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3396 def find_ashrae_hot_water_demand() # todo - for types not in table use standards area normalized swh values # get building type building_data = self.get_building_climate_zone_and_building_type building_type = building_data['building_type'] result = [] if building_type == 'FullServiceRestaurant' result << {:units => 'meal',:block => nil, :max_hourly => 1.5, :max_daily => 11.0, :avg_day_unit => 2.4} elsif building_type == 'Hospital' OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.") elsif ['LargeHotel','SmallHotel'].include? building_type result << {:units => 'unit',:block => 20, :max_hourly => 6.0, :max_daily => 35.0, :avg_day_unit => 24.0} result << {:units => 'unit',:block => 60, :max_hourly => 5.0, :max_daily => 25.0, :avg_day_unit => 14.0} result << {:units => 'unit',:block => 100, :max_hourly => 4.0, :max_daily => 15.0, :avg_day_unit => 10.0} elsif building_type == 'MidriseApartment' result << {:units => 'unit',:block => 20, :max_hourly => 12.0, :max_daily => 80.0, :avg_day_unit => 42.0} result << {:units => 'unit',:block => 50, :max_hourly => 10.0, :max_daily => 73.0, :avg_day_unit => 40.0} result << {:units => 'unit',:block => 75, :max_hourly => 8.5, :max_daily => 66.0, :avg_day_unit => 38.0} result << {:units => 'unit',:block => 100, :max_hourly => 7.0, :max_daily => 60.0, :avg_day_unit => 37.0} result << {:units => 'unit',:block => 200, :max_hourly => 5.0, :max_daily => 50.0, :avg_day_unit => 35.0} elsif ['Office','LargeOffice','MediumOffice','SmallOffice'].include? building_type result << {:units => 'person',:block => nil, :max_hourly => 0.4, :max_daily => 2.0, :avg_day_unit => 1.0} elsif building_type == 'Outpatient' OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.") elsif building_type == 'PrimarySchool' result << {:units => 'student',:block => nil, :max_hourly => 0.6, :max_daily => 1.5, :avg_day_unit => 0.6} elsif building_type == 'QuickServiceRestaurant' result << {:units => 'meal',:block => nil, :max_hourly => 0.7, :max_daily => 6.0, :avg_day_unit => 0.7} elsif building_type == 'Retail' OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.") elsif building_type == 'SecondarySchool' result << {:units => 'student',:block => nil, :max_hourly => 1.0, :max_daily => 3.6, :avg_day_unit => 1.8} elsif building_type == 'StripMall' OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.") elsif building_type == 'SuperMarket' OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.") elsif building_type == 'Warehouse' OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.") else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Didn't find expected building type. As a result can't determine hot water demand recommendations") end return result end |
#find_climate_zone_set(clim, building_vintage) ⇒ Object
Helper method to find out which climate zone set contains a specific climate zone. Returns climate zone set name as String if success, nil if not found.
3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3564 def find_climate_zone_set(clim, building_vintage) result = nil possible_climate_zones = [] $os_standards['climate_zone_sets'].each do |climate_zone_set| if climate_zone_set['climate_zones'].include?(clim) possible_climate_zones << climate_zone_set['name'] end end # Check the results if possible_climate_zones.size == 0 OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find a climate zone set containing #{clim}") elsif possible_climate_zones.size > 2 OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Found more than 2 climate zone sets containing #{clim}; will return last matching cliimate zone set.") end # For Pre-1980 and 1980-2004, use the most specific climate zone set. # For example, 2A and 2 both contain 2A, so use 2A. # For 2004-2013, use least specific climate zone set. # For example, 2A and 2 both contain 2A, so use 2. case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' result = possible_climate_zones.sort.last when '90.1-2007', '90.1-2010', '90.1-2013' result = possible_climate_zones.sort.first when '90.1-2004' if possible_climate_zones.include? "ClimateZone 3" result = possible_climate_zones.sort.last else result = possible_climate_zones.sort.first end when 'ICC IECC 2015', 'OEESC 2014' result = possible_climate_zones.sort.first end # Check that a climate zone set was found if result.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find a climate zone set when #{building_vintage}") end return result end |
#find_conditioned_space_names(building_type, building_vintage, climate_zone) ⇒ Array<String>
Get the list of all conditioned spaces, as defined for each building in the system_to_space_map inside the Prototype.building_name e.g. (Prototype.secondary_school.rb) file.
686 687 688 689 690 691 692 693 694 695 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 686 def find_conditioned_space_names(building_type, building_vintage, climate_zone) system_to_space_map = define_hvac_system_map(building_type, building_vintage, climate_zone) conditioned_space_names = OpenStudio::StringVector.new system_to_space_map.each do |system| system['space_names'].each do |space_name| conditioned_space_names << space_name end end return conditioned_space_names end |
#find_constructions(boundary_condition, type) ⇒ Object
Get a unique list of constructions with given boundary condition and a given type of surface. Pulls from both default construction sets and hard-assigned constructions.
valid choices are: Adiabatic Surface Outdoors Ground valid choices are: AtticFloor AtticWall AtticRoof DemisingFloor DemisingWall DemisingRoof ExteriorFloor ExteriorWall ExteriorRoof ExteriorWindow ExteriorDoor GlassDoor GroundContactFloor GroundContactWall GroundContactRoof InteriorFloor InteriorWall InteriorCeiling InteriorPartition InteriorWindow InteriorDoor OverheadDoor Skylight TubularDaylightDome TubularDaylightDiffuser return [Array<OpenStudio::Model::ConstructionBase>] an array of all constructions.
2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2772 def find_constructions(boundary_condition, type) constructions = [] # From default construction sets self.getDefaultConstructionSets.each do |const_set| ext_surfs = const_set.defaultExteriorSurfaceConstructions int_surfs = const_set.defaultInteriorSurfaceConstructions gnd_surfs = const_set.defaultGroundContactSurfaceConstructions ext_subsurfs = const_set.defaultExteriorSubSurfaceConstructions int_subsurfs = const_set.defaultInteriorSubSurfaceConstructions # Can't handle incomplete construction sets if ext_surfs.empty? || int_surfs.empty? || gnd_surfs.empty? || ext_subsurfs.empty? || int_subsurfs.empty? OpenStudio::logFree(OpenStudio::Error, "openstudio.model.Space", "Default construction set #{const_set.name} is incomplete; contructions from this set will not be reported.") next end ext_surfs = ext_surfs.get int_surfs = int_surfs.get gnd_surfs = gnd_surfs.get ext_subsurfs = ext_subsurfs.get int_subsurfs = int_subsurfs.get case type # Exterior Surfaces when 'ExteriorWall', 'AtticWall' constructions << ext_surfs.wallConstruction when 'ExteriorFloor' constructions << ext_surfs.floorConstruction when 'ExteriorRoof', 'AtticRoof' constructions << ext_surfs.roofCeilingConstruction # Interior Surfaces when 'InteriorWall', 'DemisingWall', 'InteriorPartition' constructions << int_surfs.wallConstruction when 'InteriorFloor', 'AtticFloor', 'DemisingFloor' constructions << int_surfs.floorConstruction when 'InteriorCeiling', 'DemisingRoof' constructions << int_surfs.roofCeilingConstruction # Ground Contact Surfaces when 'GroundContactWall' constructions << gnd_surfs.wallConstruction when 'GroundContactFloor' constructions << gnd_surfs.floorConstruction when 'GroundContactRoof' constructions << gnd_surfs.roofCeilingConstruction # Exterior SubSurfaces when 'ExteriorWindow' constructions << ext_subsurfs.fixedWindowConstruction constructions << ext_subsurfs.operableWindowConstruction when 'ExteriorDoor' constructions << ext_subsurfs.doorConstruction when 'GlassDoor' constructions << ext_subsurfs.glassDoorConstruction when 'OverheadDoor' constructions << ext_subsurfs.overheadDoorConstruction when 'Skylight' constructions << ext_subsurfs.skylightConstruction when 'TubularDaylightDome' constructions << ext_subsurfs.tubularDaylightDomeConstruction when 'TubularDaylightDiffuser' constructions << ext_subsurfs.tubularDaylightDiffuserConstruction # Interior SubSurfaces when 'InteriorWindow' constructions << int_subsurfs.fixedWindowConstruction constructions << int_subsurfs.operableWindowConstruction when 'InteriorDoor' constructions << int_subsurfs.doorConstruction end end # Hard-assigned surfaces self.getSurfaces.each do |surf| next unless surf.outsideBoundaryCondition == boundary_condition next unless surf.surfaceType == type constructions << surf.construction end # Hard-assigned subsurfaces self.getSubSurfaces.each do |surf| next unless surf.outsideBoundaryCondition == boundary_condition next unless surf.subSurfaceType == type constructions << surf.construction end # Throw out the empty constructions all_constructions = [] constructions.uniq.each do |const| next if const.empty? all_constructions << const.get end # Only return the unique list (should already be uniq) all_constructions = all_constructions.uniq # ConstructionBase can be sorted all_constructions = all_constructions.sort return all_constructions end |
#find_icc_iecc_2015_hot_water_demand(units_per_bldg, bedrooms_per_unit) ⇒ Double
Returns average daily hot water consumption for residential buildings gal/day from ICC IECC 2015 Residential Standard Reference Design from Table R405.5.2(1)
3449 3450 3451 3452 3453 3454 3455 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3449 def find_icc_iecc_2015_hot_water_demand(units_per_bldg,bedrooms_per_unit) swh_gal_per_day = units_per_bldg * (30.0 + (10.0 * bedrooms_per_unit)) return swh_gal_per_day end |
#find_icc_iecc_2015_internal_loads(units_per_bldg, bedrooms_per_unit) ⇒ Hash
Returns average daily internal loads for residential buildings from Table R405.5.2(1)
3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3461 def find_icc_iecc_2015_internal_loads(units_per_bldg,bedrooms_per_unit) # get total and conditioned floor area total_floor_area = self.getBuilding.floorArea if self.getBuilding.conditionedFloorArea.is_initialized conditioned_floor_area = self.getBuilding.conditionedFloorArea.get else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find conditioned floor area, will use total floor area.") conditioned_floor_area = total_floor_area end # get climate zone value climate_zone_value = '' climateZones = self.getClimateZones climateZones.climateZones.each do |climateZone| if climateZone.institution == "ASHRAE" climate_zone_value = climateZone.value next end end internal_loads = {} internal_loads['mech_vent_cfm'] = units_per_bldg * (0.01 * conditioned_floor_area + 7.5 * (bedrooms_per_unit + 1.0)) if ['1A','1B','2A','2B'].include? climate_zone_value internal_loads['infiltration_ach'] = 5.0 else internal_loads['infiltration_ach'] = 3.0 end internal_loads['igain_btu_per_day'] = units_per_bldg * (17900.0 + 23.8 * conditioned_floor_area + 4104.0 * bedrooms_per_unit) internal_loads['internal_mass_lbs'] = total_floor_area * 8.0 return internal_loads end |
#find_object(hash_of_objects, search_criteria, capacity = nil) ⇒ Hash
Method to search through a hash for an object that meets the desired search criteria, as passed via a hash. If capacity is supplied, the object will only be returned if the specified capacity is between the minimum_capacity and maximum_capacity values.
1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1735 def find_object(hash_of_objects, search_criteria, capacity = nil) desired_object = nil search_criteria_matching_objects = [] matching_objects = [] # Compare each of the objects against the search criteria hash_of_objects.each do |object| meets_all_search_criteria = true search_criteria.each do |key, value| # Don't check non-existent search criteria next unless object.has_key?(key) # Stop as soon as one of the search criteria is not met if object[key] != value meets_all_search_criteria = false break end end # Skip objects that don't meet all search criteria next if !meets_all_search_criteria # If made it here, object matches all search criteria search_criteria_matching_objects << object end # If capacity was specified, narrow down the matching objects if capacity.nil? matching_objects = search_criteria_matching_objects else # Round up if capacity is an integer if capacity == capacity.round capacity = capacity + (capacity * 0.01) end search_criteria_matching_objects.each do |object| # Skip objects that don't have fields for minimum_capacity and maximum_capacity next if !object.has_key?('minimum_capacity') || !object.has_key?('maximum_capacity') # Skip objects that don't have values specified for minimum_capacity and maximum_capacity next if object['minimum_capacity'].nil? || object['maximum_capacity'].nil? # Skip objects whose the minimum capacity is below the specified capacity next if capacity <= object['minimum_capacity'].to_f # Skip objects whose max next if capacity > object['maximum_capacity'].to_f # Found a matching object matching_objects << object end end # Check the number of matching objects found if matching_objects.size == 0 desired_object = nil #OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Find object search criteria returned no results. Search criteria: #{search_criteria}, capacity = #{capacity}. Called from #{caller(0)[1]}") elsif matching_objects.size == 1 desired_object = matching_objects[0] else desired_object = matching_objects[0] OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Find object search criteria returned #{matching_objects.size} results, the first one will be returned. Called from #{caller(0)[1]}. \n Search criteria: \n #{search_criteria} \n All results: \n #{matching_objects.join("\n")}") end return desired_object end |
#find_objects(hash_of_objects, search_criteria, capacity = nil) ⇒ Array
Method to search through a hash for the objects that meets the desired search criteria, as passed via a hash. Returns an Array (empty if nothing found) of matching objects.
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1660 def find_objects(hash_of_objects, search_criteria, capacity = nil) desired_object = nil search_criteria_matching_objects = [] matching_objects = [] # Compare each of the objects against the search criteria hash_of_objects.each do |object| meets_all_search_criteria = true search_criteria.each do |key, value| # Don't check non-existent search criteria next unless object.has_key?(key) # Stop as soon as one of the search criteria is not met if object[key] != value meets_all_search_criteria = false break end end # Skip objects that don't meet all search criteria next if meets_all_search_criteria == false # If made it here, object matches all search criteria search_criteria_matching_objects << object end # If capacity was specified, narrow down the matching objects if capacity.nil? matching_objects = search_criteria_matching_objects else # Round up if capacity is an integer if capacity = capacity.round capacity = capacity + (capacity * 0.01) end search_criteria_matching_objects.each do |object| # Skip objects that don't have fields for minimum_capacity and maximum_capacity next if !object.has_key?('minimum_capacity') || !object.has_key?('maximum_capacity') # Skip objects that don't have values specified for minimum_capacity and maximum_capacity next if object['minimum_capacity'].nil? || object['maximum_capacity'].nil? # Skip objects whose the minimum capacity is below the specified capacity next if capacity <= object['minimum_capacity'] # Skip objects whose max next if capacity > object['maximum_capacity'] # Found a matching object matching_objects << object end end # Check the number of matching objects found if matching_objects.size == 0 desired_object = nil #OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Find objects search criteria returned no results. Search criteria: #{search_criteria}, capacity = #{capacity}. Called from #{caller(0)[1]}.") end return matching_objects end |
#find_prototype_floor_area(building_type) ⇒ Double
Keep track of floor area for prototype buildings. This is used to calculate EUI’s to compare against non prototype buildings Areas taken from scorecard Excel Files
2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2569 def find_prototype_floor_area(building_type) if building_type == 'FullServiceRestaurant' # 5502 ft^2 result = 511 elsif building_type == 'Hospital' # 241,410 ft^2 (including basement) result = 22422 elsif building_type == 'LargeHotel' # 122,132 ft^2 result = 11345 elsif building_type == 'LargeOffice' # 498,600 ft^2 result = 46320 elsif building_type == 'MediumOffice' # 53,600 ft^2 result = 4982 elsif building_type == 'MidriseApartment' # 33,700 ft^2 result = 3135 elsif building_type == 'Office' result = nil # todo - there shouldn't be a prototype building for this OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Measures calling this should choose between SmallOffice, MediumOffice, and LargeOffice") elsif building_type == 'Outpatient' #40.950 ft^2 result = 3804 elsif building_type == 'PrimarySchool' # 73,960 ft^2 result = 6871 elsif building_type == 'QuickServiceRestaurant' # 2500 ft^2 result = 232 elsif building_type == 'Retail' # 24,695 ft^2 result = 2294 elsif building_type == 'SecondarySchool' # 210,900 ft^2 result = 19592 elsif building_type == 'SmallHotel' # 43,200 ft^2 result = 4014 elsif building_type == 'SmallOffice' # 5500 ft^2 result = 511 elsif building_type == 'StripMall' # 22,500 ft^2 result = 2090 elsif building_type == 'SuperMarket' #45,002 ft2 (from legacy reference idf file) result = 4181 elsif building_type == 'Warehouse' # 49,495 ft^2 (legacy ref shows 52,045, but I wil calc using 49,495) result = 4595 else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Didn't find expected building type. As a result can't determine floor prototype floor area") result = nil end return result end |
#find_target_eui(template) ⇒ Double
user needs to pass in building_vintage as string. The building type and climate zone will come from the model. If the building type or ASHRAE climate zone is not set in the model this will return nil If the lookup doesn’t find matching simulation results this wil return nil
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2667 def find_target_eui(template) building_data = self.get_building_climate_zone_and_building_type climate_zone = building_data['climate_zone'] building_type = building_data['building_type'] # look up results target_consumption = process_results_for_datapoint(climate_zone, building_type, template) # lookup target floor area for prototype buildings target_floor_area = find_prototype_floor_area(building_type) if target_consumption['total_legacy_energy_val'] > 0 if target_floor_area > 0 result = target_consumption['total_legacy_energy_val']/target_floor_area else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find prototype building floor area") result = nil end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find target results for #{climate_zone},#{building_type},#{template}") result = nil # couldn't calculate EUI consumpiton lookup failed end return result end |
#find_target_eui_by_end_use(template) ⇒ Hash
user needs to pass in building_vintage as string. The building type and climate zone will come from the model. If the building type or ASHRAE climate zone is not set in the model this will return nil If the lookup doesn’t find matching simulation results this wil return nil
2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2701 def find_target_eui_by_end_use(template) building_data = self.get_building_climate_zone_and_building_type climate_zone = building_data['climate_zone'] building_type = building_data['building_type'] # look up results target_consumption = process_results_for_datapoint(climate_zone, building_type, template) # lookup target floor area for prototype buildings target_floor_area = find_prototype_floor_area(building_type) if target_consumption['total_legacy_energy_val'] > 0 if target_floor_area > 0 result = {} target_consumption['total_energy_by_end_use'].each do |end_use,consumption| result[end_use] = consumption/target_floor_area end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find prototype building floor area") result = nil end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find target results for #{climate_zone},#{building_type},#{template}") result = nil # couldn't calculate EUI consumpiton lookup failed end return result end |
#get_baseline_system_type_by_zone(building_vintage, climate_zone) ⇒ Hash
This method modifies the model by removing the existing
Looks through the model and creates an hash of what the baseline system type should be for each zone.
HVAC and adding ideal loads in order to perform a sizing run to determine primary vs. secondary zones. PTHP, PTAC, PSZ_AC, PSZ_HP, PVAV_Reheat, PVAV_PFP_Boxes, VAV_Reheat, VAV_PFP_Boxes, Gas_Furnace, Electric_Furnace
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 953 def get_baseline_system_type_by_zone(building_vintage, climate_zone) zone_to_sys_type = {} # Get the groups of zones that define the # baseline HVAC systems for later use. # This must be done before removing the HVAC systems # because it requires knowledge of proposed HVAC fuels. sys_groups = self.(building_vintage) # Remove all HVAC from model BTAP::Resources::HVAC.clear_all_hvac_from_model(self) # Add ideal loads to every zone and run # a sizing run to determine heating/cooling loads, # which will impact which zones go onto secondary # HVAC systems. self.getThermalZones.each do |zone| ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(self) ideal_loads.addToThermalZone(zone) end # Run sizing run if self.runSizingRun("#{Dir.pwd}/SizingRunIdeal") == false return false end # Remove ideal loads self.getZoneHVACIdealLoadsAirSystems.each do |ideal_loads| ideal_loads.remove end # Assign building stories to spaces in the building # where stories are not yet assigned. self.assign_spaces_to_stories # Determine the baseline HVAC system type for each of # the groups of zones and add that system type. sys_groups.each do |sys_group| # Determine the primary baseline system type pri_system_type = (building_vintage, climate_zone, sys_group['type'], sys_group['fuel'], sys_group['area_ft2'], sys_group['stories']) # Record the zone-by-zone system type assignments case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' case pri_system_type when 'PTAC', 'PTHP', 'PSZ_AC', 'PSZ_HP', 'Gas_Furnace', 'Electric_Furnace' sys_group['zones'].each do |zone| zone_to_sys_type[zone] = pri_system_type end when 'PVAV_Reheat', 'PVAV_PFP_Boxes', 'VAV_Reheat', 'VAV_PFP_Boxes' # Determine the secondary system type sec_system_type = nil case pri_system_type when 'PVAV_Reheat', 'VAV_Reheat' sec_system_type = 'PSZ_AC' when 'PVAV_PFP_Boxes', 'VAV_PFP_Boxes' sec_system_type = 'PSZ_HP' end # Group zones by story story_zone_lists = self.group_zones_by_story(sys_group['zones']) # For the array of zones on each story, # separate the primary zones from the secondary zones. # Add the baseline system type to the primary zones # and add the suplemental system type to the secondary zones. story_zone_lists.each do |zones| # Differentiate primary and secondary zones pri_sec_zone_lists = self.differentiate_primary_secondary_thermal_zones(zones) # Record the primary zone system types pri_sec_zone_lists['primary'].each do |zone| zone_to_sys_type[zone] = pri_system_type end # Record the secondary zone system types pri_sec_zone_lists['secondary'].each do |zone| zone_to_sys_type[zone] = sec_system_type end end end end end puts zone_to_sys_type return zone_to_sys_type end |
#get_building_climate_zone_and_building_type(remap_office = true) ⇒ hash
this is used by other methods to get the clinzte aone and building type from a model. it has logic to break office into small, medium or large based on building area that can be turned off
2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2619 def get_building_climate_zone_and_building_type(remap_office = true) # get climate zone from model # get ashrae climate zone from model climate_zone = '' climateZones = self.getClimateZones climateZones.climateZones.each do |climateZone| if climateZone.institution == "ASHRAE" climate_zone = "ASHRAE 169-2006-#{climateZone.value}" next end end # get building type from model building_type = '' if self.getBuilding.standardsBuildingType.is_initialized building_type = self.getBuilding.standardsBuildingType.get end # prototype small office approx 500 m^2 # prototype medium office approx 5000 m^2 # prototype large office approx 50,000 m^2 # map office building type to small medium or large if building_type == "Office" and remap_office open_studio_area = self.getBuilding.floorArea if open_studio_area < 2750 building_type = "SmallOffice" elsif open_studio_area < 25250 building_type = "MediumOffice" else building_type = "LargeOffice" end end results = {} results['climate_zone'] = climate_zone results['building_type'] = building_type return results end |
#get_construction_properties(template, intended_surface_type, standards_construction_type, building_category = 'Nonresidential') ⇒ hash
Returns standards data for selected construction
3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3068 def get_construction_properties(template,intended_surface_type,standards_construction_type,building_category = 'Nonresidential') # get climate_zone_set climate_zone = self.get_building_climate_zone_and_building_type['climate_zone'] climate_zone_set = self.find_climate_zone_set(climate_zone, template) # populate search hash search_criteria = { "template" => template, "climate_zone_set" => climate_zone_set, "intended_surface_type" => intended_surface_type, "standards_construction_type" => standards_construction_type, "building_category" => building_category, } # switch to use this but update test in standards and measures to load this outside of the method construction_properties = self.find_object($os_standards["construction_properties"], search_criteria) return construction_properties end |
#get_full_weather_file_path ⇒ OpenStudio::OptionalPath
Get the full path to the weather file that is specified in the model.
2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2454 def get_full_weather_file_path full_epw_path = OpenStudio::OptionalPath.new if self.weatherFile.is_initialized epw_path = self.weatherFile.get.path if epw_path.is_initialized if File.exist?(epw_path.get.to_s) full_epw_path = OpenStudio::OptionalPath.new(epw_path.get) else # If this is an always-run Measure, need to check a different path alt_weath_path = File.(File.join(File.dirname(__FILE__), "../../../resources")) alt_epw_path = File.(File.join(alt_weath_path, epw_path.get.to_s)) if File.exist?(alt_epw_path) full_epw_path = OpenStudio::OptionalPath.new(OpenStudio::Path.new(alt_epw_path)) else OpenStudio::logFree(OpenStudio::Error, "openstudio.standards.Model", "Model has been assigned a weather file, but the file is not in the specified location of '#{epw_path.get}'.") end end else OpenStudio::logFree(OpenStudio::Error, "openstudio.standards.Model", "Model has a weather file assigned, but the weather file path has been deleted.") end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', 'Model has not been assigned a weather file.') end return full_epw_path end |
#get_lookup_name(building_type) ⇒ String
Unify the lookup names and eliminate this method
Get the name of the building type used in lookups
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 123 def get_lookup_name(building_type) lookup_name = building_type case building_type when 'SmallOffice' lookup_name = 'Office' when 'MediumOffice' lookup_name = 'Office' when 'LargeOffice' lookup_name = 'Office' when 'RetailStandalone' lookup_name = 'Retail' when 'RetailStripmall' lookup_name = 'StripMall' end return lookup_name end |
#get_story_for_nominal_z_coordinate(minz) ⇒ OpenStudio::Model::BuildingStory
Helper method to get the story object that cooresponds to a specific minimum z value. Makes a new story if none found at this height.
desired story, in meters.
3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3369 def get_story_for_nominal_z_coordinate(minz) self.getBuildingStorys.each do |story| z = story.nominalZCoordinate if z.is_initialized if minz == z.get return story end end end story = OpenStudio::Model::BuildingStory.new(self) story.setNominalZCoordinate(minz) return story end |
#getAutosizedValue(object, value_name, units) ⇒ Object
A helper method to get component sizes from the model returns the autosized value as an optional double
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb', line 295 def getAutosizedValue(object, value_name, units) result = OpenStudio::OptionalDouble.new name = object.name.get.upcase object_type = object.iddObject.type.valueDescription.gsub('OS:','') sql = self.sqlFile if sql.is_initialized sql = sql.get #SELECT * FROM ComponentSizes WHERE CompType = 'Coil:Heating:Gas' AND CompName = "COIL HEATING GAS 3" AND Description = "Design Size Nominal Capacity" query = "SELECT Value FROM ComponentSizes WHERE CompType='#{object_type}' AND CompName='#{name}' AND Description='#{value_name}' AND Units='#{units}'" val = sql.execAndReturnFirstDouble(query) if val.is_initialized result = OpenStudio::OptionalDouble.new(val.get) else # TODO: comment following line (debugging new HVACsizing objects right now) # OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "QUERY ERROR: Data not found for query: #{query}") end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'Model has no sql file containing results, cannot lookup data.') end return result end |
#getAutosizedValueFromEquipmentSummary(object, table_name, value_name, units) ⇒ Object
A helper method to get component sizes from the Equipment Summary of the TabularDataWithStrings Report returns the autosized value as an optional double
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb', line 333 def getAutosizedValueFromEquipmentSummary(object, table_name, value_name, units) result = OpenStudio::OptionalDouble.new name = object.name.get.upcase sql = self.sqlFile if sql.is_initialized sql = sql.get #SELECT * FROM ComponentSizes WHERE CompType = 'Coil:Heating:Gas' AND CompName = "COIL HEATING GAS 3" AND Description = "Design Size Nominal Capacity" query = "Select Value FROM TabularDataWithStrings WHERE ReportName = 'EquipmentSummary' AND TableName = '#{table_name}' AND RowName = '#{name}' AND ColumnName = '#{value_name}' AND Units = '#{units}'" val = sql.execAndReturnFirstDouble(query) if val.is_initialized result = OpenStudio::OptionalDouble.new(val.get) else # TODO: comment following line (debugging new HVACsizing objects right now) # OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "QUERY ERROR: Data not found for query: #{query}") end else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'Model has no sql file containing results, cannot lookup data.') end return result end |
#group_zones_by_story(zones) ⇒ Array<Array<OpenStudio::Model::ThermalZone>>
Group an array of zones into multiple arrays, one for each story in the building. Removes empty array (when the story doesn’t contain any of the zones)
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 1268 def group_zones_by_story(zones) story_zone_lists = [] self.getBuildingStorys.each do |story| # Get all the spaces on this story spaces = story.spaces # Get all the thermal zones that serve these spaces all_zones_on_story = [] spaces.each do |space| if space.thermalZone.is_initialized all_zones_on_story << space.thermalZone.get else OpenStudio::logFree(OpenStudio::Warn, "openstudio.Standards.Model", "Space #{space.name} has no thermal zone, it is not included in the simulation.") end end # Find zones in the list that are on this story zones_on_story = [] zones.each do |zone| if all_zones_on_story.include?(zone) zones_on_story << zone end end story_zone_lists << zones_on_story end return story_zone_lists end |
#load_building_type_methods(building_type, building_vintage, climate_zone) ⇒ Bool
Loads the library of methods specific to this building type
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 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 151 def load_building_type_methods(building_type, building_vintage, climate_zone) building_methods = nil case building_type when 'SecondarySchool' building_methods = 'Prototype.secondary_school' when 'PrimarySchool' building_methods = 'Prototype.primary_school' when 'SmallOffice' building_methods = 'Prototype.small_office' when 'MediumOffice' building_methods = 'Prototype.medium_office' when 'LargeOffice' building_methods = 'Prototype.large_office' when 'SmallHotel' building_methods = 'Prototype.small_hotel' when 'LargeHotel' building_methods = 'Prototype.large_hotel' when 'Warehouse' building_methods = 'Prototype.warehouse' when 'RetailStandalone' building_methods = 'Prototype.retail_standalone' when 'RetailStripmall' building_methods = 'Prototype.retail_stripmall' when 'QuickServiceRestaurant' building_methods = 'Prototype.quick_service_restaurant' when 'FullServiceRestaurant' building_methods = 'Prototype.full_service_restaurant' when 'Hospital' building_methods = 'Prototype.hospital' when 'Outpatient' building_methods = 'Prototype.outpatient' when 'MidriseApartment' building_methods = 'Prototype.mid_rise_apartment' when 'HighriseApartment' building_methods = 'Prototype.high_rise_apartment' else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model',"Building Type = #{building_type} not recognized") return false end lib_dir = File.( '../../..',File.dirname(__FILE__)) require "#{lib_dir}/lib/openstudio-standards/prototypes/#{building_methods}" return true end |
#load_geometry(building_type, building_vintage, climate_zone) ⇒ Bool
Loads a geometry-only .osm as a starting point.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 206 def load_geometry(building_type, building_vintage, climate_zone) OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding geometry') # Determine which geometry file to use # based on building_type and template case building_type when 'SecondarySchool' if building_vintage == 'DOE Ref Pre-1980' || building_vintage == 'DOE Ref 1980-2004' geometry_file = 'Geometry.secondary_school_pre_1980_to_2004.osm' else geometry_file = 'Geometry.secondary_school.osm' end when 'PrimarySchool' if building_vintage == 'DOE Ref Pre-1980' || building_vintage == 'DOE Ref 1980-2004' geometry_file = 'Geometry.primary_school_pre_1980_to_2004.osm' else geometry_file = 'Geometry.primary_school.osm' end when 'SmallOffice' if building_vintage == 'DOE Ref Pre-1980' geometry_file = 'Geometry.small_office_pre_1980.osm' else geometry_file = 'Geometry.small_office.osm' end alt_search_name = 'Office' when 'MediumOffice' geometry_file = 'Geometry.medium_office.osm' alt_search_name = 'Office' when 'LargeOffice' alt_search_name = 'Office' case building_vintage when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004' geometry_file = 'Geometry.large_office_reference.osm' else geometry_file = 'Geometry.large_office_2010.osm' end when 'SmallHotel' case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' geometry_file = 'Geometry.small_hotel_doe.osm' when '90.1-2004' geometry_file = 'Geometry.small_hotel_pnnl2004.osm' when '90.1-2007' geometry_file = 'Geometry.small_hotel_pnnl2007.osm' when '90.1-2010' geometry_file = 'Geometry.small_hotel_pnnl2010.osm' when '90.1-2013' geometry_file = 'Geometry.small_hotel_pnnl2013.osm' end when 'LargeHotel' case building_vintage when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004' geometry_file = 'Geometry.large_hotel.doe.osm' when '90.1-2007','90.1-2004' geometry_file = 'Geometry.large_hotel.2004_2007.osm' when '90.1-2010' geometry_file = 'Geometry.large_hotel.2010.osm' else geometry_file = 'Geometry.large_hotel.2013.osm' end when 'Warehouse' case building_vintage when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004' geometry_file = 'Geometry.warehouse_pre_1980_to_2004.osm' else geometry_file = 'Geometry.warehouse.osm' end when 'RetailStandalone' case building_vintage when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004' geometry_file = 'Geometry.retail_standalone.pre1980_post1980.osm' when '90.1-2004','90.1-2007' geometry_file = 'Geometry.retail_standalone.2004_2007.osm' else #'90.1-2010', '90.1-2013' geometry_file = 'Geometry.retail_standalone.2010_2013.osm' end alt_search_name = 'Retail' when 'RetailStripmall' geometry_file = 'Geometry.retail_stripmall.osm' alt_search_name = 'StripMall' when 'QuickServiceRestaurant' case building_vintage when 'DOE Ref Pre-1980' geometry_file = 'Geometry.quick_service_restaurant_pre1980.osm' when 'DOE Ref 1980-2004','90.1-2010','90.1-2007','90.1-2004','90.1-2013' geometry_file = 'Geometry.quick_service_restaurant_allothers.osm' end when 'FullServiceRestaurant' case building_vintage when 'DOE Ref Pre-1980' geometry_file = 'Geometry.full_service_restaurant_pre1980.osm' when 'DOE Ref 1980-2004','90.1-2010','90.1-2007','90.1-2004','90.1-2013' geometry_file = 'Geometry.full_service_restaurant_allothers.osm' end when 'Hospital' geometry_file = 'Geometry.hospital.osm' when 'Outpatient' geometry_file = 'Geometry.outpatient.osm' when 'MidriseApartment' geometry_file = 'Geometry.mid_rise_apartment.osm' when 'HighriseApartment' geometry_file = 'Geometry.high_rise_apartment.osm' else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model',"Building Type = #{building_type} not recognized") return false end # Load the geometry .osm top_dir = File.( '../../..',File.dirname(__FILE__)) geom_dir = "#{top_dir}/data/geometry" self.replace_model("#{geom_dir}/#{geometry_file}") OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding geometry') return true end |
#make_name(building_vintage, clim, building_type, spc_type) ⇒ Object
Helper method to make a shortened version of a name that will be readable in a GUI.
3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 3498 def make_name(building_vintage, clim, building_type, spc_type) clim = clim.gsub('ClimateZone ', 'CZ') if clim == 'CZ1-8' clim = '' end if building_type == 'FullServiceRestaurant' building_type = 'FullSrvRest' elsif building_type == 'Hospital' building_type = 'Hospital' elsif building_type == 'LargeHotel' building_type = 'LrgHotel' elsif building_type == 'LargeOffice' building_type = 'LrgOffice' elsif building_type == 'MediumOffice' building_type = 'MedOffice' elsif building_type == 'MidriseApartment' building_type = 'MidApt' elsif building_type == 'HighriseApartment' building_type = 'HighApt' elsif building_type == 'Office' building_type = 'Office' elsif building_type == 'Outpatient' building_type = 'Outpatient' elsif building_type == 'PrimarySchool' building_type = 'PriSchl' elsif building_type == 'QuickServiceRestaurant' building_type = 'QckSrvRest' elsif building_type == 'Retail' building_type = 'Retail' elsif building_type == 'SecondarySchool' building_type = 'SecSchl' elsif building_type == 'SmallHotel' building_type = 'SmHotel' elsif building_type == 'SmallOffice' building_type = 'SmOffice' elsif building_type == 'StripMall' building_type = 'StMall' elsif building_type == 'SuperMarket' building_type = 'SpMarket' elsif building_type == 'Warehouse' building_type = 'Warehouse' end parts = [building_vintage] unless building_type.empty? parts << building_type end unless spc_type.nil? parts << spc_type end unless clim.empty? parts << clim end result = parts.join(' - ') return result end |
#modify_infiltration_coefficients(building_type, building_vintage, climate_zone) ⇒ Bool
Consistency - make prototype and reference vintages consistent
Add 90.1-2013?
Changes the infiltration coefficients for the prototype vintages.
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 951 def modify_infiltration_coefficients(building_type, building_vintage, climate_zone) # Select the terrain type, which # impacts wind speed, and in turn infiltration terrain = 'City' case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' case building_type when 'Warehouse' terrain = 'Urban' when 'SmallHotel' terrain = 'Suburbs' end end # Set the terrain type self.getSite.setTerrain(terrain) # modify the infiltration coefficients for 90.1-2004, 90.1-2007, 90.1-2010, 90.1-2013 return true unless building_vintage == '90.1-2004' or building_vintage == '90.1-2007' or building_vintage == '90.1-2010' or building_vintage == '90.1-2013' # The pre-1980 and 1980-2004 buildings have this: # 1.0000, !- Constant Term Coefficient # 0.0000, !- Temperature Term Coefficient # 0.0000, !- Velocity Term Coefficient # 0.0000; !- Velocity Squared Term Coefficient # The 90.1-2010 buildings have this: # 0.0000, !- Constant Term Coefficient # 0.0000, !- Temperature Term Coefficient # 0.224, !- Velocity Term Coefficient # 0.0000; !- Velocity Squared Term Coefficient self.getSpaceInfiltrationDesignFlowRates.each do |infiltration| infiltration.setConstantTermCoefficient(0.0) infiltration.setTemperatureTermCoefficient(0.0) infiltration.setVelocityTermCoefficient(0.224) infiltration.setVelocitySquaredTermCoefficient(0.0) end end |
#modify_surface_convection_algorithm(building_vintage) ⇒ Bool
Consistency - make prototype and reference vintages consistent
Sets the inside and outside convection algorithms for different vintages
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 993 def modify_surface_convection_algorithm(building_vintage) inside = self.getInsideSurfaceConvectionAlgorithm outside = self.getOutsideSurfaceConvectionAlgorithm case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' inside.setAlgorithm('TARP') outside.setAlgorithm('DOE-2') when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' inside.setAlgorithm('TARP') outside.setAlgorithm('TARP') end end |
#output_fan_report(csv_path = nil) ⇒ Array of Hash
Helper function to output the fan power for each fan in the model Todo: output actual bhp and allowable bhp for systems 3-4 and 5-8 Todo: remove maybe later?
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb', line 373 def output_fan_report(csv_path = nil) table = [] # Deal with all the constant volume fans self.getFanConstantVolumes.each do |fan| row = {:name=>fan.name.to_s, :type=>'Constant Volume', :rated_w_per_cfm=>fan.rated_w_per_cfm.round(2), :air_loop=>'', :hvac_component=>'', :zone_hvac_component=>''} if fan.airLoopHVAC.is_initialized row[:air_loop] = fan.airLoopHVAC.get.name.to_s elsif fan.containingHVACComponent.is_initialized row[:hvac_component] = fan.containingHVACComponent.get.name.to_s elsif fan.containingZoneHVACComponent.is_initialized row[:zone_hvac_component] = fan.containingZoneHVACComponent.get.name.to_s end # Add to table table << row end # Deal with all the constant volume fans self.getFanVariableVolumes.each do |fan| row = {:name=>fan.name.to_s, :type=>'Variable Volume', :rated_w_per_cfm=>fan.rated_w_per_cfm.round(2), :air_loop=>'', :hvac_component=>'', :zone_hvac_component=>''} if fan.airLoopHVAC.is_initialized row[:air_loop] = fan.airLoopHVAC.get.name.to_s elsif fan.containingHVACComponent.is_initialized row[:hvac_component] = fan.containingHVACComponent.get.name.to_s elsif fan.containingZoneHVACComponent.is_initialized row[:zone_hvac_component] = fan.containingZoneHVACComponent.get.name.to_s end # Add to table table << row end # Deal with all the constant volume fans self.getFanOnOffs.each do |fan| row = {:name=>fan.name.to_s, :type=>'On Off', :rated_w_per_cfm=>fan.rated_w_per_cfm.round(2), :air_loop=>'', :hvac_component=>'', :zone_hvac_component=>''} if fan.airLoopHVAC.is_initialized row[:air_loop] = fan.airLoopHVAC.get.name.to_s elsif fan.containingHVACComponent.is_initialized row[:hvac_component] = fan.containingHVACComponent.get.name.to_s elsif fan.containingZoneHVACComponent.is_initialized row[:zone_hvac_component] = fan.containingZoneHVACComponent.get.name.to_s end # Add to table table << row end # If a csv path is given, output if !csv_path.nil? CSV.open(csv_path, "wb") do |csv| csv << table.first.keys # adds the attributes name on the first line table.each do |hash| csv << hash.values end end end return table end |
#performance_rating_method_baseline_system_groups(standard) ⇒ Array<Hash>
Determine the dominant and exceptional areas of the building based on fuel types and occupancy types.
with keys area_ft2, type, fuel, and zones (an array of zones)
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 337 def (standard) # Get the residential and nonresidential # fossil and electric zones and their areas res_fossil = {'area_ft2'=>0, 'type'=>'residential', 'fuel'=>'fossil', 'zones'=>[]} res_elec = {'area_ft2'=>0, 'type'=>'residential', 'fuel'=>'electric', 'zones'=>[]} nonres_fossil = {'area_ft2'=>0, 'type'=>'nonresidential', 'fuel'=>'fossil', 'zones'=>[]} nonres_elec = {'area_ft2'=>0, 'type'=>'nonresidential', 'fuel'=>'electric', 'zones'=>[]} [res_fossil, res_elec, nonres_fossil, nonres_elec].each do |data| # If the zone meets the criteria, add it self.getThermalZones.each do |zone| area_m2 = zone.floorArea area_ft2 = OpenStudio.convert(area_m2, 'm^2', 'ft^2').get # Residential Fossil if data['type'] == 'residential' && data['fuel'] == 'fossil' if zone.is_residential(standard) && zone.is_fossil_hybrid_or_purchased_heat data['area_ft2'] += area_ft2 data['zones'] << zone end # Residential Electric elsif data['type'] == 'residential' && data['fuel'] == 'electric' if zone.is_residential(standard) && !zone.is_fossil_hybrid_or_purchased_heat data['area_ft2'] += area_ft2 data['zones'] << zone end # Nonresidential Fossil elsif data['type'] == 'nonresidential' && data['fuel'] == 'fossil' if !zone.is_residential(standard) && zone.is_fossil_hybrid_or_purchased_heat data['area_ft2'] += area_ft2 data['zones'] << zone end # Nonresidential Electric elsif data['type'] == 'nonresidential' && data['fuel'] == 'electric' if !zone.is_residential(standard) && !zone.is_fossil_hybrid_or_purchased_heat data['area_ft2'] += area_ft2 data['zones'] << zone end end end end # Determine the number of stories of each type stories = self.residential_and_nonresidential_story_counts(standard) res_stories = stories['residential'] nonres_stories = stories['nonresidential'] res_fossil['stories'] = res_stories res_elec['stories'] = res_stories nonres_fossil['stories'] = nonres_stories nonres_elec['stories'] = nonres_stories # Determine the dominant area type. # In the event of a tie, choose nonresidential. dom_type = nil if res_fossil['area_ft2'] + res_elec['area_ft2'] > nonres_fossil['area_ft2'] + nonres_elec['area_ft2'] dom_type = 'residential' else dom_type = 'nonresidential' end # Determine the dominant fuel type # in the dominant area type. # In the event of a tie, choose fossil. dom_fuel = nil if dom_type == 'residential' if res_elec['area_ft2'] > res_fossil['area_ft2'] dom_fuel = 'electric' else dom_fuel = 'fossil' end elsif dom_type == 'nonresidential' if nonres_elec['area_ft2'] > nonres_fossil['area_ft2'] dom_fuel = 'electric' else dom_fuel = 'fossil' end end # Categorize the hashes dom_type_dom_fuel = nil dom_type_sec_fuel = nil sec_type_dom_fuel = nil sec_type_sec_fuel = nil [res_fossil, res_elec, nonres_fossil, nonres_elec].each do |data| if data['type'] == dom_type && data['fuel'] == dom_fuel dom_type_dom_fuel = data elsif data['type'] == dom_type && data['fuel'] != dom_fuel dom_type_sec_fuel = data elsif data['type'] != dom_type && data['fuel'] == dom_fuel sec_type_dom_fuel = data elsif data['type'] != dom_type && data['fuel'] != dom_fuel sec_type_sec_fuel = data end end # Define the minimum area for the # exception that allows a different # system type in part of the building. # This is common across different versions # of 90.1 exception_min_area_ft2 = nil case standard when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' exception_min_area_ft2 = 20000 end # There are four possible categories of data # dom is the dominant zones, or zones that don't fall into an exception # exc_fuel is any group of zones that meet the fuel type exception # exc_occ is any group of zones that meet the occ type exception # exc_fuel_occ is any group of zones that meet both the fuel and occ typ exceptions dom = dom_type_dom_fuel exc_fuel = nil exc_occ = nil exc_fuel_occ = nil # Exception for fuel type if dom_type_sec_fuel['area_ft2'] > exception_min_area_ft2 exc_fuel = dom_type_sec_fuel else dom['area_ft2'] += dom_type_sec_fuel['area_ft2'] dom['zones'] += dom_type_sec_fuel['zones'] end # Exception for occupancy type if sec_type_dom_fuel['area_ft2'] > exception_min_area_ft2 exc_fuel = sec_type_dom_fuel else dom['area_ft2'] += sec_type_dom_fuel['area_ft2'] dom['zones'] += sec_type_dom_fuel['zones'] end # Exception for fuel type and occupancy type if sec_type_sec_fuel['area_ft2'] > exception_min_area_ft2 exc_fuel = sec_type_sec_fuel else dom['area_ft2'] += sec_type_sec_fuel['area_ft2'] dom['zones'] += sec_type_sec_fuel['zones'] end # Put all the non-nil groups into an array. # A group will be nil if the exception was not triggered. sys_groups = [] [dom, exc_fuel, exc_occ, exc_fuel_occ].each do |data| next if data.nil? sys_groups << data end return sys_groups end |
#performance_rating_method_baseline_system_type(standard, climate_zone, area_type, heating_fuel_type, area_ft2, num_stories) ⇒ String
add 90.1-2013 systems 11-13
Determine the baseline system type given the inputs. Logic is different for different standards.
90.1-2007, 90.1-2010, 90.1-2013 nonresidential, and heatedonly electric and fossil PTHP, PTAC, PSZ_AC, PSZ_HP, PVAV_Reheat, PVAV_PFP_Boxes, VAV_Reheat, VAV_PFP_Boxes, Gas_Furnace, Electric_Furnace
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 501 def (standard, climate_zone, area_type, heating_fuel_type, area_ft2, num_stories) system_type = nil case standard when '90.1-2004', '90.1-2007', '90.1-2010' # Set the limit differently for # different codes limit_ft2 = 25000 limit_ft2 = 75000 if standard == '90.1-2004' case area_type when 'residential' if heating_fuel_type == 'electric' system_type = 'PTHP' # sys 2 else system_type = 'PTAC' # sys 1 end when 'nonresidential' # nonresidential and 3 floors or less and <75,000 ft2 if num_stories <= 3 && area_ft2 < limit_ft2 if heating_fuel_type == 'electric' system_type = 'PSZ_HP' # sys 4 else system_type = 'PSZ_AC' # sys 3 end # nonresidential and 4 or 5 floors or 5 floors or less and 75,000 ft2 to 150,000 ft2 elsif ( ((num_stories == 4 || num_stories == 5) && area_ft2 < limit_ft2) || (num_stories <= 5 && (area_ft2 >= limit_ft2 && area_ft2 <= 150000)) ) if heating_fuel_type == 'electric' system_type = 'PVAV_PFP_Boxes' # sys 6 else system_type = 'PVAV_Reheat' # sys 5 end # nonresidential and more than 5 floors or >150,000 ft2 elsif (num_stories >= 5 || area_ft2 > 150000) if heating_fuel_type == 'electric' system_type = 'VAV_PFP_Boxes' # sys 8 else system_type = 'VAV_Reheat' # sys 7 end end when 'heatedonly' if heating_fuel_type == 'electric' system_type = 'Electric_Furnace' # sys 9 else system_type = 'Gas_Furnace' # sys 10 end end when '90.1-2013' limit_ft2 = 25000 # Fuel type is determined based on climate zone # for 90.1-2013 case climate_zone when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-3A' heating_fuel_type = 'electric' else heating_fuel_type = 'fossil' end OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Heating fuel is #{heating_fuel_type} for 90.1-2013, climate zone #{climate_zone}. This is independent of the heating fuel type in the proposed building, per G3.1.1-3. This is different than previous versions of 90.1.") case area_type when 'residential' if heating_fuel_type == 'electric' system_type = 'PTHP' # sys 2 else system_type = 'PTAC' # sys 1 end when 'nonresidential' # nonresidential and 3 floors or less and <75,000 ft2 if num_stories <= 3 && area_ft2 < limit_ft2 if heating_fuel_type == 'electric' system_type = 'PSZ_HP' # sys 4 else system_type = 'PSZ_AC' # sys 3 end # nonresidential and 4 or 5 floors or 5 floors or less and 75,000 ft2 to 150,000 ft2 elsif ( ((num_stories == 4 || num_stories == 5) && area_ft2 < limit_ft2) || (num_stories <= 5 && (area_ft2 >= limit_ft2 && area_ft2 <= 150000)) ) if heating_fuel_type == 'electric' system_type = 'PVAV_PFP_Boxes' # sys 6 else system_type = 'PVAV_Reheat' # sys 5 end # nonresidential and more than 5 floors or >150,000 ft2 elsif (num_stories >= 5 || area_ft2 > 150000) if heating_fuel_type == 'electric' system_type = 'VAV_PFP_Boxes' # sys 8 else system_type = 'VAV_Reheat' # sys 7 end end when 'heatedonly' if heating_fuel_type == 'electric' system_type = 'Electric_Furnace' # sys 9 else system_type = 'Gas_Furnace' # sys 10 end end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "System type is #{system_type} for #{standard}, #{area_type}, #{heating_fuel_type}, #{area_ft2.round} ft^2, #{num_stories} stories.") return system_type end |
#plant_loop_cooling_fuels(plant_loop) ⇒ Object
Get the cooling fuel type of a plant loop Do not search for the fuel used for heat rejection on the condenser loop.
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 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 58 def plant_loop_cooling_fuels(plant_loop) fuels = [] # Get the cooling fuels for all supply components # on this plant loop. plant_loop.supplyComponents.each do |component| # Get the object type obj_type = component.iddObjectType.valueName.to_s case obj_type when 'OS_Chiller_Absorption' fuels << 'NaturalGas' OpenStudio::logFree(OpenStudio::Warn, 'openstudio.sizing.Model', "Assuming NaturalGas as fuel for absorption chiller.") when 'OS_Chiller_Absorption_Indirect' fuels << 'NaturalGas' OpenStudio::logFree(OpenStudio::Warn, 'openstudio.sizing.Model', "Assuming NaturalGas as fuel for absorption chiller indirect.") when 'OS_Chiller_Electric_EIR' fuels << 'Electricity' when 'OS_CoolingTower_SingleSpeed' fuels << 'Electricity' when 'OS_CoolingTower_TwoSpeed' fuels << 'Electricity' when 'OS_CoolingTower_VariableSpeed' fuels << 'Electricity' when 'OS_DistrictCooling' fuels << 'DistrictCooling' when 'OS_EvaporativeFluidCooler_SingleSpeed' fuels << 'Electricity' when 'OS_EvaporativeFluidCooler_TwoSpeed' fuels << 'Electricity' when 'OS_FluidCooler_SingleSpeed' fuels << 'Electricity' when 'OS_FluidCooler_TwoSpeed' fuels << 'Electricity' when 'OS_Node', 'OS_Pump_ConstantSpeed', 'OS_Pump_VariableSpeed', 'OS_Connector_Splitter', 'OS_Connector_Mixer', 'OS_Pipe_Adiabatic' # To avoid extraneous debug messages else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No cooling fuel types found for #{obj_type}") end end return fuels.uniq.sort end |
#plant_loop_heating_fuels(plant_loop) ⇒ Object
Get the heating fuel type of a plant loop
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 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 14 def plant_loop_heating_fuels(plant_loop) fuels = [] # Get the heating fuels for all supply components # on this plant loop. plant_loop.supplyComponents.each do |component| # Get the object type obj_type = component.iddObjectType.valueName.to_s case obj_type when 'OS_Boiler_HotWater' component = component.to_BoilerHotWater.get fuels << component.fuelType when 'OS_Boiler_Steam' component = component.to_BoilerHotWater.get fuels << component.fuelType when 'OS_District_Heating' fuels << 'DistrictHeating' when 'OS_HeatPump_WaterToWater_EquationFit_Heating' fuels << 'Electricity' when 'OS_SolarCollector_FlatPlate_PhotovoltaicThermal' fuels << 'SolarEnergy' when 'OS_SolarCollector_FlatPlate_Water' fuels << 'SolarEnergy' when 'OS_SolarCollector_IntegralCollectorStorage' fuels << 'SolarEnergy' when 'OS_WaterHeater_HeatPump' fuels << 'Electricity' when 'OS_WaterHeater_Mixed' fuels << 'obj.fuelType' when 'OS_WaterHeater_Stratified' fuels << 'obj.fuelType' when 'OS_Node', 'OS_Pump_ConstantSpeed', 'OS_Pump_VariableSpeed', 'OS_Connector_Splitter', 'OS_Connector_Mixer', 'OS_Pipe_Adiabatic' # To avoid extraneous debug messages else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No heating fuel types found for #{obj_type}") end end return fuels.uniq.sort end |
#process_results_for_datapoint(climate_zone, building_type, template) ⇒ Hash
Method to gather prototype simulation results for a specific climate zone, building type, and template
2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 2490 def process_results_for_datapoint(climate_zone, building_type, template) # Combine the data from the JSON files into a single hash top_dir = File.( '../../..',File.dirname(__FILE__)) standards_data_dir = "#{top_dir}/data/standards" # Load the legacy idf results JSON file into a ruby hash temp = File.read("#{standards_data_dir}/legacy_idf_results.json") legacy_idf_results = JSON.parse(temp) # List of all fuel types fuel_types = ['Electricity', 'Natural Gas', 'Additional Fuel', 'District Cooling', 'District Heating', 'Water'] # List of all end uses end_uses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps', 'Heat Rejection','Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators'] # Get legacy idf results legacy_results_hash = {} legacy_results_hash['total_legacy_energy_val'] = 0 legacy_results_hash['total_legacy_water_val'] = 0 legacy_results_hash['total_energy_by_fuel'] = {} legacy_results_hash['total_energy_by_end_use'] = {} fuel_types.each do |fuel_type| end_uses.each do |end_use| next if end_use == 'Exterior Equipment' # Get the legacy results number legacy_val = legacy_idf_results.dig(building_type, template, climate_zone, fuel_type, end_use) # Combine the exterior lighting and exterior equipment if end_use == 'Exterior Lighting' legacy_exterior_equipment = legacy_idf_results.dig(building_type, template, climate_zone, fuel_type, 'Exterior Equipment') unless legacy_exterior_equipment.nil? legacy_val += legacy_exterior_equipment end end if legacy_val.nil? OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "#{fuel_type} #{end_use} legacy idf value not found") next end # Add the energy to the total if fuel_type == 'Water' legacy_results_hash['total_legacy_water_val'] += legacy_val else legacy_results_hash['total_legacy_energy_val'] += legacy_val # add to fuel specific total if legacy_results_hash['total_energy_by_fuel'][fuel_type] legacy_results_hash['total_energy_by_fuel'][fuel_type] += legacy_val # add to existing counter else legacy_results_hash['total_energy_by_fuel'][fuel_type] = legacy_val # start new counter end # add to end use specific total if legacy_results_hash['total_energy_by_end_use'][end_use] legacy_results_hash['total_energy_by_end_use'][end_use] += legacy_val # add to existing counter else legacy_results_hash['total_energy_by_end_use'][end_use] = legacy_val # start new counter end end end # Next end use end # Next fuel type return legacy_results_hash end |
#replace_model(path_to_osm) ⇒ Bool
Replaces all objects in the current model with the objects in the .osm. Typically used to load a model as a starting point.
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 331 def replace_model(path_to_osm) # Take the existing model and remove all the objects # (this is cheesy), but need to keep the same memory block handles = OpenStudio::UUIDVector.new self.objects.each {|o| handles << o.handle} self.removeObjects(handles) # Load geometry from the saved geometry.osm geom_model = safe_load_model(path_to_osm) # Add the objects from the geometry model to the working model self.addObjects(geom_model.toIdfFile.objects) return true end |
#request_timeseries_outputs ⇒ Object
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 1327 def request_timeseries_outputs # "detailed" # "timestep" # "hourly" # "daily" # "monthly" vars = [] # vars << ['Heating Coil Gas Rate', 'detailed'] # vars << ['Zone Thermostat Air Temperature', 'detailed'] # vars << ['Zone Thermostat Heating Setpoint Temperature', 'detailed'] # vars << ['Zone Thermostat Cooling Setpoint Temperature', 'detailed'] # vars << ['Zone Air System Sensible Heating Rate', 'detailed'] # vars << ['Zone Air System Sensible Cooling Rate', 'detailed'] # vars << ['Fan Electric Power', 'detailed'] # vars << ['Zone Mechanical Ventilation Standard Density Volume Flow Rate', 'detailed'] # vars << ['Air System Outdoor Air Mass Flow Rate', 'detailed'] # vars << ['Air System Outdoor Air Flow Fraction', 'detailed'] # vars << ['Air System Outdoor Air Minimum Flow Fraction', 'detailed'] # vars << ['Water Use Equipment Hot Water Volume Flow Rate', 'hourly'] # vars << ['Water Use Equipment Cold Water Volume Flow Rate', 'hourly'] # vars << ['Water Use Equipment Total Volume Flow Rate', 'hourly'] # vars << ['Water Use Equipment Hot Water Temperature', 'hourly'] # vars << ['Water Use Equipment Cold Water Temperature', 'hourly'] # vars << ['Water Use Equipment Target Water Temperature', 'hourly'] # vars << ['Water Use Equipment Mixed Water Temperature', 'hourly'] # vars << ['Water Use Connections Hot Water Volume Flow Rate', 'hourly'] # vars << ['Water Use Connections Cold Water Volume Flow Rate', 'hourly'] # vars << ['Water Use Connections Total Volume Flow Rate', 'hourly'] # vars << ['Water Use Connections Hot Water Temperature', 'hourly'] # vars << ['Water Use Connections Cold Water Temperature', 'hourly'] # vars << ['Water Use Connections Plant Hot Water Energy', 'hourly'] # vars << ['Water Use Connections Return Water Temperature', 'hourly'] # vars << ['Air System Outdoor Air Economizer Status','timestep'] # vars << ['Air System Outdoor Air Heat Recovery Bypass Status','timestep'] # vars << ['Air System Outdoor Air High Humidity Control Status','timestep'] # vars << ['Air System Outdoor Air Flow Fraction','timestep'] # vars << ['Air System Outdoor Air Minimum Flow Fraction','timestep'] # vars << ['Air System Outdoor Air Mass Flow Rate','timestep'] # vars << ['Air System Mixed Air Mass Flow Rate','timestep'] # vars << ['Heating Coil Gas Rate','timestep'] vars << ['Boiler Part Load Ratio','timestep'] vars << ['Boiler Gas Rate','timestep'] # vars << ['Boiler Gas Rate','timestep'] # vars << ['Fan Electric Power','timestep'] vars << ['Pump Electric Power','timestep'] vars << ['Pump Outlet Temperature','timestep'] vars << ['Pump Mass Flow Rate','timestep'] # vars << ['Zone Air Terminal VAV Damper Position','timestep'] # vars << ['Zone Air Terminal Minimum Air Flow Fraction','timestep'] # vars << ['Zone Air Terminal Outdoor Air Volume Flow Rate','timestep'] # vars << ['Zone Lights Electric Power','hourly'] # vars << ['Daylighting Lighting Power Multiplier','hourly'] # vars << ['Schedule Value','hourly'] vars.each do |var, freq| outputVariable = OpenStudio::Model::OutputVariable.new(var, self) outputVariable.setReportingFrequency(freq) end end |
#reset_kitchen_OA(building_vintage) ⇒ Object
In order to provide sufficient OSA to replace exhaust flow through kitchen hoods (3,300 cfm), modeled OSA to kitchen is different from OSA determined based on ASHRAE 62.1. It takes into account the available OSA in dining as transfer air.
459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 459 def reset_kitchen_OA(building_vintage) space_kitchen = self.getSpaceByName('Kitchen').get ventilation = space_kitchen.designSpecificationOutdoorAir.get ventilation.setOutdoorAirFlowperPerson(0) ventilation.setOutdoorAirFlowperFloorArea(0) case building_vintage when '90.1-2007', '90.1-2010', '90.1-2013' ventilation.setOutdoorAirFlowRate(1.14135966) when '90.1-2004', 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' ventilation.setOutdoorAirFlowRate(0.7312) end end |
#residential_and_nonresidential_floor_areas(standard) ⇒ Hash
Determine the residential and nonresidential floor areas based on the space type properties for each space. For spaces with no space type, assume nonresidential.
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 264 def residential_and_nonresidential_floor_areas(standard) res_area_m2 = 0 nonres_area_m2 = 0 self.getSpaces.each do |space| if space.is_residential(standard) res_area_m2 += space.floorArea else nonres_area_m2 += space.floorArea end end return {'residential' => res_area_m2, 'nonresidential' => nonres_area_m2} end |
#residential_and_nonresidential_story_counts(standard) ⇒ Hash
Determine the number of residential and nonresidential stories. If a story has both types, add it to both counts. Checks the zone multipliers to get the floor multiplier Ignores spaces that aren’t part of total floor area
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 286 def residential_and_nonresidential_story_counts(standard) res_stories = 0 nonres_stories = 0 self.getBuildingStorys.each do |story| has_res = false has_nonres = false zone_mults = [] story.spaces.each do |space| # Ignore spaces that aren't part of the total floor area next if !space.partofTotalFloorArea # Handle zone multipliers if !space.thermalZone.empty? zone_mults << space.thermalZone.get.multiplier end if space.is_residential(standard) has_res = true else has_nonres = true end end if zone_mults.size == 0 OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Story #{story.name} has no thermal zones!") else floor_mult = zone_mults.instance_eval { reduce(:+) / size.to_f }.to_i end res_stories += 1 * floor_mult if has_res nonres_stories += 1 * floor_mult if has_nonres if has_res && has_nonres OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "Story #{story.name} is mixed use (residential and nonresidential).") end end return {'residential' => res_stories, 'nonresidential' => nonres_stories} end |
#run(run_dir = "#{Dir.pwd}/Run") ⇒ Object
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 1171 def run(run_dir = "#{Dir.pwd}/Run") # If the run directory is not specified # run in the current working directory # Make the directory if it doesn't exist if !Dir.exists?(run_dir) Dir.mkdir(run_dir) end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Started simulation in '#{run_dir}'") # Change the simulation to only run the weather file # and not run the sizing day simulations sim_control = self.getSimulationControl sim_control.setRunSimulationforSizingPeriods(false) sim_control.setRunSimulationforWeatherFileRunPeriods(true) # Save the model to energyplus idf idf_name = 'in.idf' osm_name = 'in.osm' forward_translator = OpenStudio::EnergyPlus::ForwardTranslator.new idf = forward_translator.translateModel(self) idf_path = OpenStudio::Path.new("#{run_dir}/#{idf_name}") osm_path = OpenStudio::Path.new("#{run_dir}/#{osm_name}") idf.save(idf_path,true) self.save(osm_path,true) # Set up the sizing simulation # Find the weather file epw_path = nil if self.weatherFile.is_initialized epw_path = self.weatherFile.get.path if epw_path.is_initialized if File.exist?(epw_path.get.to_s) epw_path = epw_path.get else # If this is an always-run Measure, need to check a different path alt_weath_path = File.(File.join(File.dirname(__FILE__), "../../../resources")) alt_epw_path = File.(File.join(alt_weath_path, epw_path.get.to_s)) if File.exist?(alt_epw_path) epw_path = OpenStudio::Path.new(alt_epw_path) else OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "Model has been assigned a weather file, but the file is not in the specified location of '#{epw_path.get}'.") return false end end else OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "Model has a weather file assigned, but the weather file path has been deleted.") return false end else OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "Model has not been assigned a weather file.") return false end # If running on a regular desktop, use RunManager. # If running on OpenStudio Server, use WorkFlowMananger # to avoid slowdown from the sizing run. use_runmanager = true begin require 'openstudio-workflow' use_runmanager = false rescue LoadError use_runmanager = true end sql_path = nil if use_runmanager == true OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Running sizing run with RunManager.") # Find EnergyPlus ep_dir = OpenStudio.getEnergyPlusDirectory ep_path = OpenStudio.getEnergyPlusExecutable ep_tool = OpenStudio::Runmanager::ToolInfo.new(ep_path) idd_path = OpenStudio::Path.new(ep_dir.to_s + "/Energy+.idd") output_path = OpenStudio::Path.new("#{run_dir}/") # Make a run manager and queue up the sizing run run_manager_db_path = OpenStudio::Path.new("#{run_dir}/run.db") run_manager = OpenStudio::Runmanager::RunManager.new(run_manager_db_path, true, false, false, false) job = OpenStudio::Runmanager::JobFactory::createEnergyPlusJob(ep_tool, idd_path, idf_path, epw_path, output_path) run_manager.enqueue(job, true) # Start the sizing run and wait for it to finish. while run_manager.workPending sleep 1 OpenStudio::Application::instance.processEvents end sql_path = OpenStudio::Path.new("#{run_dir}/Energyplus/eplusout.sql") OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Finished sizing run in #{(Time.new - start_time).round}sec.") else # Use the openstudio-workflow gem OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Running sizing run with openstudio-workflow gem.") # Copy the weather file to this directory FileUtils.copy(epw_path.to_s, run_dir) # Run the simulation sim = OpenStudio::Workflow.run_energyplus('Local', run_dir) final_state = sim.run if final_state == :finished OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Finished sizing run in #{(Time.new - start_time).round}sec.") end sql_path = OpenStudio::Path.new("#{run_dir}/run/eplusout.sql") end # Load the sql file created by the sizing run sql_path = OpenStudio::Path.new("#{run_dir}/Energyplus/eplusout.sql") if OpenStudio::exists(sql_path) sql = OpenStudio::SqlFile.new(sql_path) # Check to make sure the sql file is readable, # which won't be true if EnergyPlus crashed during simulation. if !sql.connectionOpen OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed. Look at the eplusout.err file in #{File.dirname(sql_path.to_s)} to see the cause.") return false end # Attach the sql file from the run to the sizing model self.setSqlFile(sql) else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "Results for the sizing run couldn't be found here: #{sql_path}.") return false end # Check that the run finished without severe errors error_query = "SELECT ErrorMessage FROM Errors WHERE ErrorType='1'" errs = self.sqlFile.get.execAndReturnVectorOfString(error_query) if errs.is_initialized errs = errs.get if errs.size > 0 errs = errs.get OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed with the following severe errors: #{errs.join('\n')}.") return false end end OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Finished simulation in '#{run_dir}'") return true end |
#run_simulation_and_log_errors(run_dir = "#{Dir.pwd}/Run") ⇒ Object
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 |
# File 'lib/openstudio-standards/utilities/simulation.rb', line 5 def run_simulation_and_log_errors(run_dir = "#{Dir.pwd}/Run") # Make the directory if it doesn't exist if !Dir.exists?(run_dir) Dir.mkdir(run_dir) end # Save the model to energyplus idf idf_name = 'in.idf' osm_name = 'in.osm' OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Starting simulation here: #{run_dir}.") forward_translator = OpenStudio::EnergyPlus::ForwardTranslator.new idf = forward_translator.translateModel(self) idf_path = OpenStudio::Path.new("#{run_dir}/#{idf_name}") osm_path = OpenStudio::Path.new("#{run_dir}/#{osm_name}") idf.save(idf_path,true) self.save(osm_path,true) # Set up the simulation # Find the weather file epw_path = self.get_full_weather_file_path if epw_path.empty? return false end epw_path = epw_path.get # If running on a regular desktop, use RunManager. # If running on OpenStudio Server, use WorkFlowMananger # to avoid slowdown from the run. use_runmanager = true begin require 'openstudio-workflow' use_runmanager = false rescue LoadError use_runmanager = true end sql_path = nil if use_runmanager OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Running with RunManager.') # Find EnergyPlus ep_dir = OpenStudio.getEnergyPlusDirectory ep_path = OpenStudio.getEnergyPlusExecutable ep_tool = OpenStudio::Runmanager::ToolInfo.new(ep_path) idd_path = OpenStudio::Path.new(ep_dir.to_s + "/Energy+.idd") output_path = OpenStudio::Path.new("#{run_dir}/") # Make a run manager and queue up the run run_manager_db_path = OpenStudio::Path.new("#{run_dir}/run.db") # HACK: workaround for Mac with Qt 5.4, need to address in the future. OpenStudio::Application::instance().application(false) run_manager = OpenStudio::Runmanager::RunManager.new(run_manager_db_path, true, false, false, false) job = OpenStudio::Runmanager::JobFactory::createEnergyPlusJob(ep_tool, idd_path, idf_path, epw_path, output_path) run_manager.enqueue(job, true) # Start the run and wait for it to finish. while run_manager.workPending sleep 1 OpenStudio::Application::instance.processEvents end sql_path = OpenStudio::Path.new("#{run_dir}/EnergyPlus/eplusout.sql") OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished run.') else # Use the openstudio-workflow gem OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Running with openstudio-workflow gem.') # Copy the weather file to this directory FileUtils.copy(epw_path.to_s, run_dir) # Run the simulation sim = OpenStudio::Workflow.run_energyplus('Local', run_dir) final_state = sim.run if final_state == :finished OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished run.') end sql_path = OpenStudio::Path.new("#{run_dir}/run/eplusout.sql") end # TODO Delete the eplustbl.htm and other files created # by the run for cleanliness. if OpenStudio::exists(sql_path) sql = OpenStudio::SqlFile.new(sql_path) # Check to make sure the sql file is readable, # which won't be true if EnergyPlus crashed during simulation. if !sql.connectionOpen OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed, cannot create model. Look at the eplusout.err file in #{File.dirname(sql_path.to_s)} to see the cause.") return false end # Attach the sql file from the run to the model self.setSqlFile(sql) else OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "Results for the run couldn't be found here: #{sql_path}.") return false end # Report severe errors in the run error_query = "SELECT ErrorMessage FROM Errors WHERE ErrorType in(1,2)" errs = self.sqlFile.get.execAndReturnVectorOfString(error_query) if errs.is_initialized errs = errs.get end # Check that the run completed completed_query = "SELECT Completed FROM Simulations" completed = self.sqlFile.get.execAndReturnFirstDouble(completed_query) if completed.is_initialized completed = completed.get if completed == 0 OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run did not finish and had following errors: #{errs.join('\n')}") return false end end # Check that the run completed with no severe errors completed_successfully_query = "SELECT CompletedSuccessfully FROM Simulations" completed_successfully = self.sqlFile.get.execAndReturnFirstDouble(completed_successfully_query) if completed_successfully.is_initialized completed_successfully = completed_successfully.get if completed_successfully == 0 OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed with the following severe or fatal errors: #{errs.join('\n')}") return false end end # Log any severe errors that did not cause simulation to fail if errs.size > 0 OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', "The run completed but had the following severe errors: #{errs.join('\n')}") end return true end |
#runSizingRun(sizing_run_dir = "#{Dir.pwd}/SizingRun") ⇒ Object
A helper method to run a sizing run and pull any values calculated during autosizing back into the self.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb', line 64 def runSizingRun(sizing_run_dir = "#{Dir.pwd}/SizingRun") # Change the simulation to only run the sizing days sim_control = self.getSimulationControl sim_control.setRunSimulationforSizingPeriods(true) sim_control.setRunSimulationforWeatherFileRunPeriods(false) # Run the sizing run self.run_simulation_and_log_errors(sizing_run_dir) # Change the model back to running the weather file sim_control.setRunSimulationforSizingPeriods(false) sim_control.setRunSimulationforWeatherFileRunPeriods(true) return true end |
#set_sizing_parameters(building_type, building_vintage) ⇒ Bool
Consistency - make sizing factors consistent between building types, climate zones, and vintages?
Changes the infiltration coefficients for the prototype vintages.
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 |
# File 'lib/openstudio-standards/prototypes/Prototype.Model.rb', line 1016 def set_sizing_parameters(building_type, building_vintage) # Default unless otherwise specified clg = 1.2 htg = 1.2 case building_vintage when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' case building_type when 'PrimarySchool', 'SecondarySchool' clg = 1.5 htg = 1.5 when 'LargeHotel' clg = 1.33 htg = 1.33 end when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' case building_type when 'Hospital', 'LargeHotel', 'MediumOffice', 'LargeOffice', 'Outpatient', 'PrimarySchool' clg = 1.0 htg = 1.0 end end sizing_params = self.getSizingParameters sizing_params.setHeatingSizingFactor(htg) sizing_params.setCoolingSizingFactor(clg) OpenStudio::logFree(OpenStudio::Info, 'openstudio.prototype.Model', "Set sizing factors to #{htg} for heating and #{clg} for cooling.") end |
#update_exhaust_fan_efficiency(building_vintage) ⇒ Object
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 472 def update_exhaust_fan_efficiency(building_vintage) case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' self.getFanZoneExhausts.sort.each do |exhaust_fan| fan_name = exhaust_fan.name.to_s if fan_name.include? "Dining" exhaust_fan.setFanEfficiency(1) exhaust_fan.setPressureRise(0) end end when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004' self.getFanZoneExhausts.sort.each do |exhaust_fan| exhaust_fan.setFanEfficiency(1) exhaust_fan.setPressureRise(0.000001) end end end |
#update_fan_efficiency ⇒ Object
350 351 352 353 354 355 |
# File 'lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb', line 350 def update_fan_efficiency self.getFanOnOffs.sort.each do |fan_onoff| fan_onoff.setFanEfficiency(0.53625) fan_onoff.setMotorEfficiency(0.825) end end |
#update_sizing_zone(building_vintage) ⇒ Object
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb', line 417 def update_sizing_zone(building_vintage) case building_vintage when '90.1-2007', '90.1-2010', '90.1-2013' zone_sizing = self.getSpaceByName('Dining').get.thermalZone.get.sizingZone zone_sizing.setCoolingDesignAirFlowMethod('DesignDayWithLimit') zone_sizing.setCoolingMinimumAirFlowperZoneFloorArea(0.003581176) zone_sizing = self.getSpaceByName('Kitchen').get.thermalZone.get.sizingZone zone_sizing.setCoolingDesignAirFlowMethod('DesignDayWithLimit') zone_sizing.setCoolingMinimumAirFlowperZoneFloorArea(0) when '90.1-2004' zone_sizing = self.getSpaceByName('Dining').get.thermalZone.get.sizingZone zone_sizing.setCoolingDesignAirFlowMethod('DesignDayWithLimit') zone_sizing.setCoolingMinimumAirFlowperZoneFloorArea(0.007111554) zone_sizing = self.getSpaceByName('Kitchen').get.thermalZone.get.sizingZone zone_sizing.setCoolingDesignAirFlowMethod('DesignDayWithLimit') zone_sizing.setCoolingMinimumAirFlowperZoneFloorArea(0) end end |
#update_waterheater_loss_coefficient(building_vintage) ⇒ Object
add hvac
122 123 124 125 126 127 128 129 130 |
# File 'lib/openstudio-standards/prototypes/Prototype.retail_stripmall.rb', line 122 def update_waterheater_loss_coefficient(building_vintage) case building_vintage when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013' self.getWaterHeaterMixeds.sort.each do |water_heater| water_heater.setOffCycleLossCoefficienttoAmbientTemperature(7.561562668) water_heater.setOnCycleLossCoefficienttoAmbientTemperature(7.561562668) end end end |
#zone_airloop_cooling_fuels(zone) ⇒ Object
Get the cooling fuels for a zones airloop
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 390 def zone_airloop_cooling_fuels(zone) fuels = [] # Get the air loop that serves this zone air_loop = zone.airLoopHVAC if air_loop.empty? return fuels end air_loop = air_loop.get # Find fuel types of all equipment # on the supply side of this airloop. air_loop.supplyComponents.each do |component| # Get the object type obj_type = component.iddObjectType.valueName.to_s case obj_type when 'OS_AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypass' component = component.to_AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.get fuels += self.coil_cooling_fuels(component.coolingCoil) when 'OS_AirLoopHVAC_UnitaryHeatPump_AirToAir' component = component.to_AirLoopHVACUnitaryHeatPumpAirToAir.get fuels += self.coil_cooling_fuels(component.coolingCoil) when 'OS_AirLoopHVAC_UnitaryHeatPump_AirToAir_MultiSpeed' component = component.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.get fuels += self.coil_cooling_fuels(component.coolingCoil) when 'OS_AirLoopHVAC_UnitarySystem' component = component.to_AirLoopHVACUnitarySystem.get if component.coolingCoil.is_initialized fuels += self.coil_cooling_fuels(component.coolingCoil.get) end when 'OS_EvaporativeCooler_Direct_ResearchSpecial' fuels << 'Electricity' when 'OS_EvaporativeCooler_Indirect_ResearchSpecial' fuels << 'Electricity' when 'OS_Coil_Cooling_DX_MultiSpeed' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_DX_SingleSpeed' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_DX_TwoSpeed' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_DX_TwoStageWithHumidityControlMode' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_DX_VariableRefrigerantFlow' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_DX_VariableSpeed' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_WaterToAirHeatPump_EquationFit' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_WaterToAirHeatPump_VariableSpeed_EquationFit' fuels += self.coil_cooling_fuels(component) when 'OS_CoilSystem_Cooling_DX_HeatExchangerAssisted' fuels += self.coil_cooling_fuels(component) when 'OS_CoilSystem_Cooling_Water_HeatExchangerAssisted' fuels += self.coil_cooling_fuels(component) when 'OS_Coil_Cooling_Water' fuels += self.coil_cooling_fuels(component) when 'OS_HeatPump_WaterToWater_EquationFit_Cooling' fuels += self.coil_cooling_fuels(component) when 'OS_Node', 'OS_Fan_ConstantVolume', 'OS_Fan_VariableVolume', 'OS_AirLoopHVAC_OutdoorAirSystem' # To avoid extraneous debug messages else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No heating fuel types found for #{obj_type}") end end return fuels.uniq.sort end |
#zone_airloop_heating_fuels(zone) ⇒ Object
Get the heating fuels for a zones airloop
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 325 def zone_airloop_heating_fuels(zone) fuels = [] # Get the air loop that serves this zone air_loop = zone.airLoopHVAC if air_loop.empty? return fuels end air_loop = air_loop.get # Find fuel types of all equipment # on the supply side of this airloop. air_loop.supplyComponents.each do |component| # Get the object type obj_type = component.iddObjectType.valueName.to_s case obj_type when 'OS_AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypass' component = component.to_AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.get fuels += self.coil_heating_fuels(component.heatingCoil) when 'OS_AirLoopHVAC_UnitaryHeatPump_AirToAir' component = component.to_AirLoopHVACUnitaryHeatPumpAirToAir.get fuels += self.coil_heating_fuels(component.heatingCoil) when 'OS_AirLoopHVAC_UnitaryHeatPump_AirToAir_MultiSpeed' component = component.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.get fuels += self.coil_heating_fuels(component.heatingCoil) when 'OS_AirLoopHVAC_UnitarySystem' component = component.to_AirLoopHVACUnitarySystem.get if component.heatingCoil.is_initialized fuels += self.coil_heating_fuels(component.heatingCoil.get) end when 'OS_Coil_Heating_DX_MultiSpeed' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_DX_SingleSpeed' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_DX_VariableSpeed' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_Desuperheater' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_Electric' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_Gas' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_Gas_MultiStage' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_Water' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_WaterToAirHeatPump_EquationFit' fuels += self.coil_heating_fuels(component) when 'OS_Coil_Heating_WaterToAirHeatPump_VariableSpeed_EquationFit' fuels += self.coil_heating_fuels(component) when 'OS_Coil_WaterHeating_AirToWaterHeatPump' fuels += self.coil_heating_fuels(component) when 'OS_Coil_WaterHeating_Desuperheater' fuels += self.coil_heating_fuels(component) when 'OS_Node', 'OS_Fan_ConstantVolume', 'OS_Fan_VariableVolume', 'OS_AirLoopHVAC_OutdoorAirSystem' # To avoid extraneous debug messages else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No heating fuel types found for #{obj_type}") end end return fuels.uniq.sort end |
#zone_equipment_cooling_fuels(zone) ⇒ Object
Get the cooling fuels for a zone
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 290 def zone_equipment_cooling_fuels(zone) fuels = [] # Get the cooling fuels for all zone HVAC equipment zone.equipment.each do |equipment| # Get the object type obj_type = equipment.iddObjectType.valueName.to_s case obj_type when 'to_AirTerminal_SingleDuct_ConstantVolume_CooledBeam' equipment = equipment.to_AirTerminalSingleDuctConstantVolumeCooledBeam.get fuels += self.coil_cooling_fuels(equipment.coilCoolingCooledBeam) when 'to_AirTerminal_SingleDuct_ConstantVolume_FourPipeInduction' equipment = equipment.to_AirTerminalSingleDuctConstantVolumeFourPipeInduction.get if equipment.coolingCoil.is_initialized fuels += self.coil_heating_fuels(equipment.coolingCoil.get) end when 'OS_Refrigeration_AirChiller' fuels << 'Electricity' when 'OS_ZoneHVAC_IdealLoadsAirSystem' fuels << 'DistrictCooling' when 'OS_ZoneHVAC_PackagedTerminalAirConditioner' fuels << 'Electricity' when 'OS_ZoneHVAC_PackagedTerminalHeatPump' fuels << 'Electricity' when 'OS_ZoneHVAC_TerminalUnit_VariableRefrigerantFlow' fuels << 'Electricity' else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No cooling fuel types found for #{obj_type}") end end return fuels.uniq.sort end |
#zone_equipment_heating_fuels(zone) ⇒ Object
Get the heating fuels for a zone @ return [Array<String>] an array of fuels
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/openstudio-standards/hvac_sizing/HVACSizing.HeatingCoolingFuels.rb', line 209 def zone_equipment_heating_fuels(zone) fuels = [] # Get the heating fuels for all zone HVAC equipment zone.equipment.each do |equipment| # Get the object type obj_type = equipment.iddObjectType.valueName.to_s case obj_type when 'OS_AirTerminal_SingleDuct_ConstantVolume_FourPipeInduction' equipment = equipment.to_AirTerminalSingleDuctConstantVolumeFourPipeInduction.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_AirTerminal_SingleDuct_ConstantVolume_Reheat' equipment = equipment.to_AirTerminalSingleDuctConstantVolumeReheat.get fuels += self.coil_heating_fuels(equipment.reheatCoil) when 'OS_AirTerminal_SingleDuct_InletSideMixer' # TODO when 'OS_AirTerminal_SingleDuct_ParallelPIUReheat' equipment = equipment.to_AirTerminalSingleDuctParallelPIUReheat.get fuels += self.coil_heating_fuels(equipment.reheatCoil) when 'OS_AirTerminal_SingleDuct_SeriesPIUReheat' equipment = equipment.to_AirTerminalSingleDuctSeriesPIUReheat.get fuels += self.coil_heating_fuels(equipment.reheatCoil) when 'OS_AirTerminal_SingleDuct_VAVHeatAndCool_Reheat' equipment = equipment.to_AirTerminalSingleDuctVAVHeatAndCoolReheat.get fuels += self.coil_heating_fuels(equipment.reheatCoil) when 'OS_AirTerminal_SingleDuct_VAV_Reheat' equipment = equipment.to_AirTerminalSingleDuctVAVReheat.get fuels += self.coil_heating_fuels(equipment.reheatCoil) when 'OS_ZoneHVAC_Baseboard_Convective_Water' equipment = equipment.to_ZoneHVACBaseboardConvectiveWater.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_Baseboard_RadiantConvective_Water' equipment = equipment.to_ZoneHVACBaseboardRadiantConvectiveWater.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_FourPipeFanCoil' equipment = equipment.to_ZoneHVACFourPipeFanCoil.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_LowTempRadiant_ConstFlow' equipment = equipment.to_ZoneHVACLowTempRadiantConstFlow.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_LowTempRadiant_VarFlow' equipment = equipment.to_ZoneHVACLowTempRadiantVarFlow.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_UnitHeater' equipment = equipment.to_ZoneHVACUnitHeater.get fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_UnitVentilator' equipment = equipment.to_ZoneHVACUnitVentilator.get if equipment.heatingCoil.is_initialized fuels += self.coil_heating_fuels(equipment.heatingCoil.get) end when 'OS_ZoneHVAC_Baseboard_Convective_Electric' fuels << 'Electricity' when 'OS_ZoneHVAC_Baseboard_RadiantConvective_Electric' fuels << 'Electricity' when 'OS_ZoneHVAC_HighTemperatureRadiant' equipment = equipment.to_ZoneHVACHighTemperatureRadiant.get fuels << equipment.fuelType when 'OS_ZoneHVAC_IdealLoadsAirSystem' fuels << 'DistrictHeating' when 'OS_ZoneHVAC_LowTemperatureRadiant_Electric' fuels << 'Electricity' when 'OS_ZoneHVAC_PackagedTerminalAirConditioner' equipment = equipment.to_ZoneHVACPackagedTerminalAirConditioner.get fuel_coil = self.coil_heating_fuels(equipment.heatingCoil) fuels += self.coil_heating_fuels(equipment.heatingCoil) when 'OS_ZoneHVAC_PackagedTerminalHeatPump' fuels << 'Electricity' when 'OS_ZoneHVAC_TerminalUnit_VariableRefrigerantFlow' fuels << 'Electricity' when 'OS_ZoneHVAC_WaterToAirHeatPump' fuels << 'Electricity' else #OpenStudio::logFree(OpenStudio::Debug, 'openstudio.sizing.Model', "No heating fuel types found for #{obj_type}") end end return fuels.uniq.sort end |