Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comstock Standards Fixes #1798

Merged
merged 18 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ Naming/FileName:
Enabled: false

Style/FrozenStringLiteralComment:
Enabled: false
Enabled: false

Style/HashSyntax:
EnforcedShorthandSyntax: either
4 changes: 2 additions & 2 deletions lib/openstudio-standards/create_typical/create_typical.rb
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@ def self.create_typical_building_from_model(model,

# adjust F factor constructions to avoid simulation errors
model.getFFactorGroundFloorConstructions.each do |cons|
# Rfilm_in = 0.135, Rfilm_out = 0.03, Rcons for 6" heavy concrete = 0.15m / 1.95 W/mK
if cons.area <= (0.135 + 0.03 + (0.15 / 1.95)) * cons.perimeterExposed * cons.fFactor
# Rfilm_in = 0.135, Rfilm_out = 0.03, Rcons for 6" heavy concrete = 0.15m / 1.95 W/mK, 0.001 minimum resistance of Rfic resistive layer
if cons.area <= (0.135 + 0.03 + (0.15 / 1.95) + 0.001) * cons.perimeterExposed * cons.fFactor
# set minimum Rfic to ~ R1 = 0.18 m^2K/W
new_area = 0.422 * cons.perimeterExposed * cons.fFactor
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CreateTypical', "F-factor fictitious resistance for #{cons.name.get} with Area=#{cons.area.round(2)}, Exposed Perimeter=#{cons.perimeterExposed.round(2)}, and F-factor=#{cons.fFactor.round(2)} will result in a negative value and a failed simulation. Construction area is adjusted to be #{new_area.round(2)} m2.")
Expand Down
22 changes: 13 additions & 9 deletions lib/openstudio-standards/hvac/cbecs_hvac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,11 @@ def self.add_cbecs_hvac_system(model, standard, hvac_system_type, zones)
zone_equipment_ventilation: false)

when 'DOAS with VRF'
standard.model_add_hvac_system(model, 'DOAS', ht = 'Electricity', znht = nil, cl = 'Electricity', zones,
standard.model_add_hvac_system(model, 'DOAS', ht = 'Electricity', znht = nil, cl = 'Electricity', system_zones,
air_loop_heating_type: 'DX',
air_loop_cooling_type: 'DX')
standard.model_add_hvac_system(model, 'VRF', ht = 'Electricity', znht = nil, cl = 'Electricity', zones)
standard.model_add_hvac_system(model, 'VRF', ht = 'Electricity', znht = nil, cl = 'Electricity', system_zones)
standard.model_add_hvac_system(self, 'Baseboards', ht = 'Electricity', znht = nil, cl = nil, heated_only_zones)

when 'DOAS with water source heat pumps fluid cooler with boiler'
standard.model_add_hvac_system(model, 'DOAS', ht = 'NaturalGas', znht = nil, cl = 'Electricity', zones)
Expand Down Expand Up @@ -312,8 +313,8 @@ def self.add_cbecs_hvac_system(model, standard, hvac_system_type, zones)
# default to have no ventilation air
standard.model_add_hvac_system(model, 'PTAC', ht = nil, znht = 'NaturalGas', cl = 'Electricity', system_zones,
zone_equipment_ventilation: false)
# use 'Baseboard electric' for heated only zones
standard.model_add_hvac_system(model, 'Baseboards', ht = 'Electricity', znht = nil, cl = nil, heated_only_zones)
# use gas unit heaters for heated only zones
standard.model_add_hvac_system(model, 'Unit Heaters', ht = 'NaturalGas', znht = nil, cl = nil, heated_only_zones)

when 'PTAC with gas boiler'
# default to have no ventilation air
Expand Down Expand Up @@ -371,8 +372,8 @@ def self.add_cbecs_hvac_system(model, standard, hvac_system_type, zones)

when 'PSZ-AC with gas coil'
standard.model_add_hvac_system(model, 'PSZ-AC', ht = nil, znht = 'NaturalGas', cl = 'Electricity', system_zones)
# use 'Baseboard electric' for heated only zones
standard.model_add_hvac_system(model, 'Baseboards', ht = 'Electricity', znht = nil, cl = nil, heated_only_zones)
# use gas unit heaters for heated only zones
standard.model_add_hvac_system(model, 'Unit Heaters', ht = 'NaturalGas', znht = nil, cl = nil, heated_only_zones)

when 'PSZ-AC with gas boiler'
standard.model_add_hvac_system(model, 'PSZ-AC', ht = 'NaturalGas', znht = nil, cl = 'Electricity', system_zones)
Expand Down Expand Up @@ -443,7 +444,8 @@ def self.add_cbecs_hvac_system(model, standard, hvac_system_type, zones)

# PVAV systems by default use a DX coil for cooling
when 'PVAV with gas boiler reheat', 'Packaged VAV Air Loop with Boiler' # second enumeration for backwards compatibility with Tenant Star project
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'NaturalGas', znht = 'NaturalGas', cl = 'Electricity', zones)
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'NaturalGas', znht = 'NaturalGas', cl = 'Electricity', system_zones)
standard.model_add_hvac_system(model, 'Baseboards', ht = 'NaturalGas', znht = nil, cl = nil, heated_only_zones)

when 'PVAV with central air source heat pump reheat'
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'AirSourceHeatPump', znht = 'AirSourceHeatPump', cl = 'Electricity', zones)
Expand All @@ -452,11 +454,13 @@ def self.add_cbecs_hvac_system(model, standard, hvac_system_type, zones)
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'DistrictHeating', znht = 'DistrictHeating', cl = 'Electricity', zones)

when 'PVAV with PFP boxes'
standard.model_add_hvac_system(model, 'PVAV PFP Boxes', ht = 'Electricity', znht = 'Electricity', cl = 'Electricity', zones)
standard.model_add_hvac_system(model, 'PVAV PFP Boxes', ht = 'Electricity', znht = 'Electricity', cl = 'Electricity', system_zones)
standard.model_add_hvac_system(model, 'Baseboards', ht = 'Electricity', znht = nil, cl = nil, heated_only_zones)

when 'PVAV with gas heat with electric reheat', 'PVAV with gas coil heat with electric reheat'
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'Gas', znht = 'Electricity', cl = 'Electricity', zones,
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'Gas', znht = 'Electricity', cl = 'Electricity', system_zones,
air_loop_heating_type: 'Gas')
standard.model_add_hvac_system(model, 'Baseboards', ht = 'Electricity', znht = nil, cl = nil, heated_only_zones)

when 'PVAV with gas boiler heat with electric reheat'
standard.model_add_hvac_system(model, 'PVAV Reheat', ht = 'Gas', znht = 'Electricity', cl = 'Electricity', zones)
Expand Down
35 changes: 19 additions & 16 deletions lib/openstudio-standards/schedules/parametric.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ def self.model_setup_parametric_schedules(model,
thermostat = zone.thermostatSetpointDualSetpoint.get
if thermostat.heatingSetpointTemperatureSchedule.is_initialized && thermostat.heatingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
schedule = thermostat.heatingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method: 'tstat')
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'tstat')
end
if thermostat.coolingSetpointTemperatureSchedule.is_initialized && thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
schedule = thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method: 'tstat')
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'tstat')
end
end
end
Expand All @@ -231,7 +231,7 @@ def self.model_setup_parametric_schedules(model,
air_loop_hash[air_loop] = hours_of_operation
if air_loop.availabilitySchedule.to_ScheduleRuleset.is_initialized
schedule = air_loop.availabilitySchedule.to_ScheduleRuleset.get
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, air_loop, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method:)
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, air_loop, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
end
avail_mgrs = air_loop.availabilityManagers
avail_mgrs.sort.each do |avail_mgr|
Expand All @@ -241,7 +241,7 @@ def self.model_setup_parametric_schedules(model,
resources.sort.each do |resource|
if resource.to_ScheduleRuleset.is_initialized
schedule = resource.to_ScheduleRuleset.get
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, avail_mgr, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method:)
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, avail_mgr, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
end
end
end
Expand Down Expand Up @@ -299,7 +299,7 @@ def self.model_setup_parametric_schedules(model,
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Parametric.Model', "Cannot identify where #{component.name.get} is in system. Will not gather parametric inputs for #{schedule.name.get}")
next
end
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, component, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method:)
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, component, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
end
end

Expand All @@ -317,11 +317,11 @@ def self.model_setup_parametric_schedules(model,
if opt_space.is_initialized
space = space.get
hours_of_operation = OpenstudioStandards::Space.space_hours_of_operation(space)
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method:)
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
else
hours_of_operation = OpenstudioStandards::Space.spaces_hours_of_operation(model.getSpaces)
if !hours_of_operation.nil?
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method:)
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
end
end

Expand Down Expand Up @@ -440,7 +440,7 @@ def self.spaces_space_types_get_parametric_schedule_inputs(spaces_space_types, p
OpenstudioStandards::Space.space_load_instance_get_parametric_schedule_inputs(space_load_instance, parametric_inputs, hours_of_operation, gather_data_only)
if space_load_instance.activityLevelSchedule.is_initialized && space_load_instance.activityLevelSchedule.get.to_ScheduleRuleset.is_initialized
act_sch = space_load_instance.activityLevelSchedule.get.to_ScheduleRuleset.get
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(act_sch, space_load_instance, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method: 'hours')
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(act_sch, space_load_instance, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'hours')
end
end
space_type.spaceInfiltrationDesignFlowRates.each do |space_load_instance|
Expand Down Expand Up @@ -1056,7 +1056,7 @@ def self.schedule_ruleset_apply_parametric_inputs(schedule_ruleset, ramp_frequen
remainder = days_to_fill - value[:days_used]
day_for_rule = days_to_fill - remainder
if remainder.size < days_to_fill.size
autogen_rules[profile_index] = { days_to_fill: day_for_rule, hoo_start:, hoo_end: }
autogen_rules[profile_index] = { days_to_fill: day_for_rule, hoo_start: hoo_start, hoo_end: hoo_end}
end
days_to_fill = remainder
end
Expand Down Expand Up @@ -1162,6 +1162,8 @@ def self.schedule_day_adjust_from_parameters(schedule_day, hoo_start, hoo_end, v
vac = 24.0 - occ
range = val_clg - val_flr

timestep_minutes = (0..60).step(60 * ramp_frequency).to_a

OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Parametric.ScheduleDay', "Schedule #{schedule_day.name} has this formula hash: #{formula_hash}")

# apply variables and create updated hash with only numbers
Expand All @@ -1172,7 +1174,11 @@ def self.schedule_day_adjust_from_parameters(schedule_day, hoo_start, hoo_end, v
time = time.gsub('hoo_end', hoo_end.to_s)
time = time.gsub('occ', occ.to_s)
# can save special variables like lunch or break using this logic
time = time.gsub('mid', (hoo_start + (occ * 0.5)).to_s)
mid_start = hoo_start + (occ * 0.5)
mid_start_min = mid_start.modulo(1) * 60
mid_start_min_ts = timestep_minutes.min { |a, b| (a - mid_start_min).abs <=> (b - mid_start_min).abs }
mid_start_adjusted = mid_start.floor + (mid_start_min_ts / 60)
time = time.gsub('mid', mid_start_adjusted.to_s)
time = time.gsub('vac', vac.to_s)
begin
time_float = eval(time)
Expand Down Expand Up @@ -1255,18 +1261,15 @@ def self.schedule_day_adjust_from_parameters(schedule_day, hoo_start, hoo_end, v
updated_time = 0.0
last_buffer = 'NA'
else
# pick midpoint and put each time there. e.g. times of (2,7,9,8,11) would be changed to (2,7,8.5,8.5,11)
delta = last_time - time_value_pair[0]

# determine much space last item can move
if i < 2
last_buffer = time_value_pairs[i - 1][0] # can move down to 0 without any issues
else
last_buffer = time_value_pairs[i - 1][0] - time_value_pairs[i - 2][0]
end

# center if possible but don't exceed available buffer
updated_time = time_value_pairs[i - 1][0] - [delta / 2.0, last_buffer].min
# move to previous timestep but don't exceed available buffer
updated_time = time_value_pairs[i - 1][0] - [ramp_frequency, last_buffer].min
end

# update values in array
Expand Down Expand Up @@ -1342,7 +1345,7 @@ def self.schedule_day_adjust_from_parameters(schedule_day, hoo_start, hoo_end, v
time_value_pairs.rotate!(rotate_steps)

# add a 24 on the end of array that matches the first value
if time_value_pairs.last[0] != 24.0
if time_value_pairs.last[0].to_i != 24
time_value_pairs << [24.0, time_value_pairs.first[1]]
end

Expand Down
2 changes: 1 addition & 1 deletion lib/openstudio-standards/space/space.rb
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ def self.space_load_instance_get_parametric_schedule_inputs(space_load_instance,
return nil
end

OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(opt_sch.get.to_ScheduleRuleset.get, space_load_instance, parametric_inputs, hours_of_operation, gather_data_only:, hoo_var_method: 'hours')
OpenstudioStandards::Schedules.schedule_ruleset_get_parametric_inputs(opt_sch.get.to_ScheduleRuleset.get, space_load_instance, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'hours')

return parametric_inputs
end
Expand Down
6 changes: 6 additions & 0 deletions lib/openstudio-standards/standards/Standards.SpaceType.rb
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ def space_type_apply_internal_loads(space_type, set_people, set_lights, set_elec
definition.setWattsperSpaceFloorArea(OpenStudio.convert(elec_equip_per_area.to_f, 'W/ft^2', 'W/m^2').get)
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} set electric EPD to #{elec_equip_per_area} W/ft^2.")
end
definition.resetFractionLatent unless definition.isFractionLatentDefaulted
definition.resetFractionRadiant unless definition.isFractionRadiantDefaulted
definition.resetFractionLost unless definition.isFractionLostDefaulted
definition.setFractionLatent(elec_equip_frac_latent.to_f) if elec_equip_frac_latent
definition.setFractionRadiant(elec_equip_frac_radiant.to_f) if elec_equip_frac_radiant
definition.setFractionLost(elec_equip_frac_lost.to_f) if elec_equip_frac_lost
Expand Down Expand Up @@ -375,6 +378,9 @@ def space_type_apply_internal_loads(space_type, set_people, set_lights, set_elec
definition.setWattsperSpaceFloorArea(OpenStudio.convert(gas_equip_per_area.to_f, 'Btu/hr*ft^2', 'W/m^2').get)
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} set gas EPD to #{gas_equip_per_area} Btu/hr*ft^2.")
end
definition.resetFractionLatent unless definition.isFractionLatentDefaulted
definition.resetFractionRadiant unless definition.isFractionRadiantDefaulted
definition.resetFractionLost unless definition.isFractionLostDefaulted
definition.setFractionLatent(gas_equip_frac_latent.to_f) if gas_equip_frac_latent
definition.setFractionRadiant(gas_equip_frac_radiant.to_f) if gas_equip_frac_radiant
definition.setFractionLost(gas_equip_frac_lost.to_f) if gas_equip_frac_lost
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,33 @@
{
"template": "DOE Ref 1980-2004",
"fluid_type": "Hot Water",
"fuel_type": "Gas",
"condensing": null,
"condensing_control": null,
"fuel_type": "NaturalGas",
"draft_type": null,
"minimum_capacity": 0.0,
"maximum_capacity": 299999.0,
"maximum_capacity": 299999.99,
"start_date": "1919-09-09T00:00:00+00:00",
"end_date": "2999-09-09T00:00:00+00:00",
"minimum_annual_fuel_utilization_efficiency": 0.8,
"minimum_thermal_efficiency": null,
"minimum_combustion_efficiency": null,
"efffplr": "Boiler Constant Efficiency Curve",
"standby_mode_power": null,
"off_mode_power": null,
"notes": "From 90.1-1989"
},
{
"template": "DOE Ref 1980-2004",
"fluid_type": "Hot Water",
"fuel_type": "Gas",
"condensing": null,
"condensing_control": null,
"fuel_type": "NaturalGas",
"draft_type": null,
"minimum_capacity": 300000.0,
"maximum_capacity": 249999999.0,
"maximum_capacity": 9999999999.0,
"start_date": "1919-09-09T00:00:00+00:00",
"end_date": "2999-09-09T00:00:00+00:00",
"minimum_annual_fuel_utilization_efficiency": null,
"minimum_thermal_efficiency": null,
"minimum_combustion_efficiency": 0.8,
"efffplr": "Boiler Constant Efficiency Curve",
"standby_mode_power": null,
"off_mode_power": null,
"notes": "From 90.1-1989"
}
]
Expand Down
Loading