lib/openstudio-standards/standards/Standards.Model.rb in openstudio-standards-0.3.0 vs lib/openstudio-standards/standards/Standards.Model.rb in openstudio-standards-0.3.1.rc1

- old
+ new

@@ -206,11 +206,11 @@ # Add or remove daylighting controls to each space # Add daylighting controls for 90.1-2013 and prior # Remove daylighting control for 90.1-PRM-2019 and onward model.getSpaces.sort.each do |space| - space_set_baseline_daylighting_controls(space, false, false) + space_set_baseline_daylighting_controls(space, true, false) end OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', '*** Applying Baseline Constructions ***') # Modify some of the construction types as necessary @@ -453,70 +453,65 @@ # Check unmet load hours if unmet_load_hours_check nb_adjustments = 0 loop do - model_run_simulation_and_log_errors(model, "#{sizing_run_dir}/final#{degs}") == false - # If UMLH are greater than the threshold allowed by Appendix G, - # increase zone air flow and load as per the recommendation in - # the PRM-RM; Note that the PRM-RM only suggest to increase - # air zone air flow, but the zone sizing factor in EnergyPlus - # increase both air flow and load. - if model_get_unmet_load_hours(model) > 300 - # Limit the number of zone sizing factor adjustment to 8 - unless nb_adjustments < 8 - OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "After 8 rounds of zone sizing factor adjustments the unmet load hours for the baseline model (#{degs} degree of rotation) still exceed 300 hours. Please open an issue on GitHub (https://github.com/NREL/openstudio-standards/issues) and share your user model with the developers.") - break - end - model.getThermalZones.each do |thermal_zone| - # Cooling adjustments - clg_umlh = thermal_zone_get_unmet_load_hours(thermal_zone, 'Cooling') - if clg_umlh > 50 - # Get zone cooling sizing factor - if thermal_zone.sizingZone.zoneCoolingSizingFactor.is_initialized - sizing_factor = thermal_zone.sizingZone.zoneCoolingSizingFactor.get - else - sizing_factor = 1.0 - end + # Loop break condition: Limit the number of zone sizing factor adjustment to 3 + unless nb_adjustments < 3 + OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "After 3 rounds of zone sizing factor adjustments the unmet load hours for the baseline model (#{degs} degree of rotation) still exceed 300 hours. Please open an issue on GitHub (https://github.com/NREL/openstudio-standards/issues) and share your user model with the developers.") + break + end + # Close the previous SQL session if open to prevent EnergyPlus from overloading the same session + sql = model.sqlFile.get + if sql.connectionOpen + sql.close + end - # Make adjustment to zone cooling sizing factor - # Do not adjust factors greater or equal to 2 - if sizing_factor < 2.0 - if clg_umlh > 150 - sizing_factor *= 1.1 - elsif clg_umlh > 50 - sizing_factor *= 1.05 + if model_run_simulation_and_log_errors(model, "#{sizing_run_dir}/final#{degs}") + # If UMLH are greater than the threshold allowed by Appendix G, + # increase zone air flow and load as per the recommendation in + # the PRM-RM; Note that the PRM-RM only suggest to increase + # air zone air flow, but the zone sizing factor in EnergyPlus + # increase both air flow and load. + if model_get_unmet_load_hours(model) > 300 + model.getThermalZones.each do |thermal_zone| + # Cooling adjustments + clg_umlh = thermal_zone_get_unmet_load_hours(thermal_zone, 'Cooling') + if clg_umlh > 50 + sizing_factor = 1.0 + if thermal_zone.sizingZone.zoneCoolingSizingFactor.is_initialized + sizing_factor = thermal_zone.sizingZone.zoneCoolingSizingFactor.get end + # Make adjustment to zone cooling sizing factor + # Do not adjust factors greater or equal to 2 + clg_umlh > 150 ? sizing_factor = [2.0, sizing_factor * 1.1].min : sizing_factor = [2.0, sizing_factor * 1.05].min thermal_zone.sizingZone.setZoneCoolingSizingFactor(sizing_factor) end - end - # Heating adjustments - htg_umlh = thermal_zone_get_unmet_load_hours(thermal_zone, 'Heating') - if htg_umlh > 50 - # Get zone cooling sizing factor - if thermal_zone.sizingZone.zoneHeatingSizingFactor.is_initialized - sizing_factor = thermal_zone.sizingZone.zoneHeatingSizingFactor.get - else + # Heating adjustments + # Reset sizing factor + htg_umlh = thermal_zone_get_unmet_load_hours(thermal_zone, 'Heating') + if htg_umlh > 50 sizing_factor = 1.0 - end - - # Make adjustment to zone heating sizing factor - # Do not adjust factors greater or equal to 2 - if sizing_factor < 2.0 - if htg_umlh > 150 - sizing_factor *= 1.1 - elsif htg_umlh > 50 - sizing_factor *= 1.05 + if thermal_zone.sizingZone.zoneHeatingSizingFactor.is_initialized + # Get zone heating sizing factor + sizing_factor = thermal_zone.sizingZone.zoneHeatingSizingFactor.get end + + # Make adjustment to zone heating sizing factor + # Do not adjust factors greater or equal to 2 + htg_umlh > 150 ? sizing_factor = [2.0, sizing_factor * 1.1].min : sizing_factor = [2.0, sizing_factor * 1.05].min thermal_zone.sizingZone.setZoneHeatingSizingFactor(sizing_factor) end end end else - break + # simulation failure, raise the exception. + # OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'OpenStudio simulation failed.') + raise('OpenStudio simulation failed.') end + nb_adjustments += 1 end end end if debug @@ -2263,12 +2258,13 @@ # # @param model [OpenStudio::Model::Model] OpenStudio model object # @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A' # @param apply_controls [Bool] toggle whether to apply air loop and plant loop controls # @param sql_db_vars_map [Hash] hash map + # @param necb_ref_hp [Bool] for compatability with NECB ruleset only. # @return [Bool] returns true if successful, false if not - def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true, sql_db_vars_map: nil) + def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true, sql_db_vars_map: nil, necb_ref_hp: false) sql_db_vars_map = {} if sql_db_vars_map.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Started applying HVAC efficiency standards for #{template} template.") # Air Loop Controls @@ -2300,15 +2296,15 @@ # Unitary HPs # set DX HP coils before DX clg coils because when DX HP coils need to first # 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) } + model.getCoilHeatingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = coil_heating_dx_single_speed_apply_efficiency_and_curves(obj, sql_db_vars_map, necb_ref_hp) } # 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) } - model.getCoilCoolingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_single_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) } + model.getCoilCoolingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_single_speed_apply_efficiency_and_curves(obj, sql_db_vars_map, necb_ref_hp) } model.getCoilCoolingDXMultiSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_multi_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) } # WSHPs # set WSHP heating coils before cooling coils to get cooling coil capacities before they are renamed model.getCoilHeatingWaterToAirHeatPumpEquationFits.sort.each { |obj| sql_db_vars_map = coil_heating_water_to_air_heat_pump_apply_efficiency_and_curves(obj, sql_db_vars_map) } @@ -2353,11 +2349,11 @@ def model_add_daylighting_controls(model) OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding daylighting controls.') # Add daylighting controls to each space model.getSpaces.sort.each do |space| - added = space_add_daylighting_controls(space, false, false) + added = space_add_daylighting_controls(space, true, false) end OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding daylighting controls.') return true end @@ -3585,10 +3581,11 @@ existing_curves += model.getCurveLinears existing_curves += model.getCurveCubics existing_curves += model.getCurveQuadratics existing_curves += model.getCurveBicubics existing_curves += model.getCurveBiquadratics + existing_curves += model.getCurveQuadLinears existing_curves.sort.each do |curve| if curve.name.get.to_s == curve_name OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Model', "Already added curve: #{curve_name}") return curve end @@ -3684,9 +3681,28 @@ curve.setMaximumValueofx(data['maximum_independent_variable_1']) if data['maximum_independent_variable_1'] curve.setMinimumValueofy(data['minimum_independent_variable_2']) if data['minimum_independent_variable_2'] curve.setMaximumValueofy(data['maximum_independent_variable_2']) if data['maximum_independent_variable_2'] curve.setMinimumCurveOutput(data['minimum_dependent_variable_output']) if data['minimum_dependent_variable_output'] curve.setMaximumCurveOutput(data['maximum_dependent_variable_output']) if data['maximum_dependent_variable_output'] + return curve + when 'QuadLinear' + curve = OpenStudio::Model::CurveQuadLinear.new(model) + curve.setName(data['name']) + curve.setCoefficient1Constant(data['coeff_1']) + curve.setCoefficient2w(data['coeff_2']) + curve.setCoefficient3x(data['coeff_3']) + curve.setCoefficient4y(data['coeff_4']) + curve.setCoefficient5z(data['coeff_5']) + curve.setMinimumValueofw(data['minimum_independent_variable_w']) + curve.setMaximumValueofw(data['maximum_independent_variable_w']) + curve.setMinimumValueofx(data['minimum_independent_variable_x']) + curve.setMaximumValueofx(data['maximum_independent_variable_x']) + curve.setMinimumValueofy(data['minimum_independent_variable_y']) + curve.setMaximumValueofy(data['maximum_independent_variable_y']) + curve.setMinimumValueofz(data['minimum_independent_variable_z']) + curve.setMaximumValueofz(data['maximum_independent_variable_z']) + curve.setMinimumCurveOutput(data['minimum_dependent_variable_output']) + curve.setMaximumCurveOutput(data['maximum_dependent_variable_output']) return curve when 'MultiVariableLookupTable' num_ind_var = data['number_independent_variables'].to_i table = OpenStudio::Model::TableMultiVariableLookup.new(model, num_ind_var) table.setName(data['name'])