lib/openstudio-standards/standards/Standards.Model.rb in openstudio-standards-0.2.10 vs lib/openstudio-standards/standards/Standards.Model.rb in openstudio-standards-0.2.11.rc1
- old
+ new
@@ -1,9 +1,7 @@
require 'csv'
-
-
class Standard
attr_accessor :space_multiplier_map
attr_accessor :standards_data
def define_space_multiplier
@@ -88,10 +86,13 @@
sys_groups = model_prm_baseline_system_groups(model, custom)
# Remove all HVAC from model, excluding service water heating
model_remove_prm_hvac(model)
+ # Remove all EMS objects from the model
+ model_remove_prm_ems_objects(model)
+
# Modify the service water heating loops per the baseline rules
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', '*** Cleaning up Service Water Heating Loops ***')
model_apply_baseline_swh_loops(model, building_type)
# Determine the baseline HVAC system type for each of the groups of zones and add that system type.
@@ -1243,11 +1244,11 @@
array_of_zones.delete_at(biggest_delta_i)
# Call method recursively if something was eliminated
array_of_zones = model_eliminate_outlier_zones(model, array_of_zones, key_to_inspect, tolerance, field_name, units)
else
zn_name = array_of_zones[biggest_delta_i]['zone'].name.get.to_s
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "For zone #{zn_name}, the #{field_name} #{worst.round(2)} #{units} - average #{field_name} #{avg.round(2)} #{units} = #{biggest_delta.round(2)} #{units} < tolerance of #{tolerance} #{units}, stopping elimination process.")
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "For zone #{zn_name}, the #{field_name} #{worst.round(2)} #{units} - average #{field_name} #{avg.round(2)} #{units} = #{biggest_delta.round(2)} #{units} less than the tolerance of #{tolerance} #{units}, stopping elimination process.")
end
return array_of_zones
end
@@ -1259,11 +1260,11 @@
# on the system by more than 10 Btu/hr*ft^2.
#
# @return [Hash] A hash of two arrays of ThermalZones,
# where the keys are 'primary' and 'secondary'
def model_differentiate_primary_secondary_thermal_zones(model, zones)
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', 'Determining which zones are served by the primary vs. secondary HVAC system.')
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', 'Determining which zones are served by the primary vs. secondary HVAC system.')
# Determine the operational hours (proxy is annual
# full load lighting hours) for all zones
zone_data_1 = []
zones.each do |zone|
@@ -1363,14 +1364,14 @@
end
end
# Report out the primary vs. secondary zones
unless pri_zone_names.empty?
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "Primary system zones = #{pri_zone_names.join(', ')}.")
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Primary system zones = #{pri_zone_names.join(', ')}.")
end
unless sec_zone_names.empty?
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "Secondary system zones = #{sec_zone_names.join(', ')}.")
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Secondary system zones = #{sec_zone_names.join(', ')}.")
end
return { 'primary' => pri_zones, 'secondary' => sec_zones }
end
@@ -1389,11 +1390,11 @@
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.")
+ 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 = []
@@ -1447,11 +1448,11 @@
space_obj = space[0]
space_minz = space[1]
if space_obj.buildingStory.empty?
story = model_get_story_for_nominal_z_coordinate(model, space_minz)
space_obj.setBuildingStory(story)
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "Space #{space[0].name} was not assigned to a story by the user. It has been assigned to #{story.name}.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Model', "Space #{space[0].name} was not assigned to a story by the user. It has been assigned to #{story.name}.")
end
end
return true
end
@@ -1471,11 +1472,11 @@
# Applies the HVAC parts of the template to all objects in the model using the the template specified in the model.
def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true)
sql_db_vars_map = {}
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying HVAC efficiency standards.')
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Started applying HVAC efficiency standards for #{template} template.")
# Air Loop Controls
if apply_controls.nil? || apply_controls == true
model.getAirLoopHVACs.sort.each { |obj| air_loop_hvac_apply_standard_controls(obj, climate_zone) }
end
@@ -1501,11 +1502,11 @@
model.getHeaderedPumpsConstantSpeeds.sort.each { |obj| pump_apply_standard_minimum_motor_efficiency(obj) }
model.getHeaderedPumpsVariableSpeeds.sort.each { |obj| pump_apply_standard_minimum_motor_efficiency(obj) }
# Unitary HPs
# set DX HP coils before DX clg coils because when DX HP coils need to first
- # pull the capacities of their paried DX clg coils, and this does not work
+ # pull the capacities of their paired DX clg coils, and this does not work
# correctly if the DX clg coil efficiencies have been set because they are renamed.
model.getCoilHeatingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = coil_heating_dx_single_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
# Unitary ACs
model.getCoilCoolingDXTwoSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_two_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
@@ -3158,11 +3159,11 @@
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.")
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Space', "Default construction set #{const_set.name} is incomplete; constructions from this set will not be reported.")
next
end
ext_surfs = ext_surfs.get
int_surfs = int_surfs.get
@@ -3776,10 +3777,30 @@
model.getAirConditionerVariableRefrigerantFlows.each(&:remove)
return true
end
+ # Remove EMS objects that may be orphaned from removing HVAC
+ #
+ # @return [Bool] true if successful, false if not
+ def model_remove_prm_ems_objects(model)
+ model.getEnergyManagementSystemActuators(&:remove)
+ model.getEnergyManagementSystemConstructionIndexVariables(&:remove)
+ model.getEnergyManagementSystemCurveOrTableIndexVariables(&:remove)
+ model.getEnergyManagementSystemGlobalVariables(&:remove)
+ model.getEnergyManagementSystemInternalVariables(&:remove)
+ model.getEnergyManagementSystemMeteredOutputVariables(&:remove)
+ model.getEnergyManagementSystemOutputVariables(&:remove)
+ model.getEnergyManagementSystemPrograms(&:remove)
+ model.getEnergyManagementSystemProgramCallingManagers(&:remove)
+ model.getEnergyManagementSystemSensors(&:remove)
+ model.getEnergyManagementSystemSubroutines(&:remove)
+ model.getEnergyManagementSystemTrendVariables(&:remove)
+
+ return true
+ end
+
# Remove external shading devices. Site shading will not be impacted.
# @return [Bool] returns true if successful, false if not.
def model_remove_external_shading_devices(model)
shading_surfaces_removed = 0
model.getShadingSurfaceGroups.sort.each do |shade_group|
@@ -4015,21 +4036,21 @@
end
end
# Check the results
if possible_climate_zone_sets.size.zero?
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find a climate zone set containing #{clim}")
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find a climate zone set containing #{clim}. Make sure to use ASHRAE standards with ASHRAE climate zones and DEER or CA Title 24 standards with CEC climate zones.")
elsif possible_climate_zone_sets.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.")
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Found more than 2 climate zone sets containing #{clim}; will return last matching climate zone set.")
end
# Get the climate zone from the possible set
climate_zone_set = model_get_climate_zone_set_from_list(model, possible_climate_zone_sets)
# Check that a climate zone set was found
if climate_zone_set.nil?
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find a climate zone set when #{template}")
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find a climate zone set in standard #{template}")
end
return climate_zone_set
end
@@ -4286,11 +4307,11 @@
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "For #{space_type.name}, number of students = #{num_students}.") unless num_students == 0.0
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "For #{space_type.name}, number of beds = #{num_beds}.") unless num_beds == 0.0
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "For #{space_type.name}, number of meals = #{num_meals}.") unless num_meals.nil?
else
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Cannot identify standards buidling type and space type for #{space_type.name}, it won't be added to space_type_hash.")
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Cannot identify standards building type and space type for #{space_type.name}, it won't be added to space_type_hash.")
end
end
return space_type_hash.sort.to_h
end
@@ -4501,11 +4522,11 @@
model.getSpaces.sort.each do |space|
@space_multiplier_map[space.name.get] = space.multiplier if space.multiplier > 1
end
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding geometry')
unless @space_multiplier_map.empty?
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Found mulitpliers for space #{@space_multiplier_map}")
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Found multipliers for space #{@space_multiplier_map}")
end
return is_valid
end
# Determines how ventilation for the standard is specified.
@@ -4895,11 +4916,11 @@
model.getScheduleRulesets.sort.each do |sch|
if !sch.hasAdditionalProperties or !sch.additionalProperties.hasFeature("param_sch_ver")
# for now don't look at schedules without targets, in future can alter these by looking at building level hours of operation
next if not sch.directUseCount > 0 # won't catch if used for space type load instance, but that space type isn't used
# todo - address schedules that fall into this category, if they are used in the model
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.ScheduleRuleset', "For #{sch.sources.first.name}, #{sch.name} is not setup as parametric schedule. It has #{sch.sources.size} sources.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Model', "For #{sch.sources.first.name}, #{sch.name} is not setup as parametric schedule. It has #{sch.sources.size} sources.")
next
end
# apply parametric inputs
schedule_apply_parametric_inputs(sch,ramp_frequency,infer_hoo_for_non_assigned_objects,error_on_out_of_order,parametric_inputs)
@@ -5368,10 +5389,10 @@
daily_flh = day_schedule_equivalent_full_load_hrs(schedule_day)
percent_change = ((daily_flh - est_daily_flh)/daily_flh) * 100.0
if percent_change.abs > 0.05
# todo - this estimation can have flaws. Fix or remove it, make sure to update for secondary logic (if we implement that here)
# post application checks compares against actual instead of estimated values
- OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ScheduleRuleset', "For day schedule #{schedule_day.name} in #{sch.name} there was a #{percent_change.round(4)}% change. Expected full load hours is #{daily_flh.round(4)}, but estimated value is #{est_daily_flh.round(4)}")
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Model', "For day schedule #{schedule_day.name} in #{sch.name} there was a #{percent_change.round(4)}% change. Expected full load hours is #{daily_flh.round(4)}, but estimated value is #{est_daily_flh.round(4)}")
end
raw_string = []
par_val_time_hash.sort.each do |time,value_array|