Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/NREL/ComStock into asparke2…
Browse files Browse the repository at this point in the history
…/utility_rates
  • Loading branch information
eringold committed Jan 22, 2024
2 parents bb9e025 + 24e17d1 commit 4cea7ef
Show file tree
Hide file tree
Showing 13 changed files with 76,967 additions and 37 deletions.
13 changes: 11 additions & 2 deletions postprocessing/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
'pyarrow',
'fsspec',
's3fs',
'kaleido==0.1.0post1',
'boto3',
'botocore',
'pyyaml',
Expand All @@ -69,6 +68,16 @@
'ipykernel',
# 'awscli',
# 'colorama==0.4.3'
]
],
':sys_platform == "win32"': [
'kaleido==0.1.0post1', # kaleido version for Windows
],
':sys_platform == "linux"': [
'kaleido==0.1.0', # kaleido version for Linux
],
':sys_platform == "darwin"': [
'kaleido==0.1.0', # kaleido version for MacOS
],

}
)
Original file line number Diff line number Diff line change
Expand Up @@ -2698,9 +2698,9 @@ def typical_building_from_model(model, runner, user_arguments)
# adjust F factor constructions to avoid simulation errors
model.getFFactorGroundFloorConstructions.each do |cons|
# Rfilm_in = 0.135, Rfilm_out = 0.03, Rcons = 0.15/1.95
if cons.area <= (0.135 + 0.03 + 0.15/1.95) * cons.perimeterExposed * cons.fFactor
if cons.area < (0.001 + 0.135 + 0.03 + 0.15/1.95) * cons.perimeterExposed * cons.fFactor
# set minimum Rfic to > 1e-3
new_area = 0.233 * cons.perimeterExposed * cons.fFactor
new_area = 0.243 * cons.perimeterExposed * cons.fFactor
runner.registerInfo("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)}.")
cons.setArea(new_area)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,6 @@ def run(model, runner, user_arguments)
next
end

is_unitary = false
air_loop_hvac.supplyComponents.each do |sc|
if sc.to_AirLoopHVACUnitarySystem.is_initialized
is_unitary = true
end
end

if is_unitary
runner.registerInfo("Air loop #{air_loop_hvac.name} is a unitary system cannot economize.")
next
end

sizing_system = air_loop_hvac.sizingSystem
type_of_load = sizing_system.typeofLoadtoSizeOn
if type_of_load == 'VentilationRequirement'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>fault_hvac_economizer_changeover_temperature</name>
<uid>ba9893ba-e0f1-427a-becc-9484ab739681</uid>
<version_id>8df6bb60-8f90-4b81-88ea-864183f142c1</version_id>
<version_modified>2023-10-16T20:24:55Z</version_modified>
<version_id>6a2d09c4-8b12-4015-8d90-eb487ef860fc</version_id>
<version_modified>2023-11-07T14:57:02Z</version_modified>
<xml_checksum>3166FFDC</xml_checksum>
<class_name>FaultHvacEconomizerChangeoverTemperature</class_name>
<display_name>fault hvac economizer changeover temperature</display_name>
Expand Down Expand Up @@ -166,7 +166,13 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>C2486816</checksum>
<checksum>08929401</checksum>
</file>
<file>
<filename>measure_test.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>8611FE49</checksum>
</file>
</files>
</measure>
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# ComStock™, Copyright (c) 2023 Alliance for Sustainable Energy, LLC. All rights reserved.
# See top level LICENSE.txt file for license terms.

# *******************************************************************************
# OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC.
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# (1) Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# (2) Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# (3) Neither the name of the copyright holder nor the names of any contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission from the respective party.
#
# (4) Other than as required in clauses (1) and (2), distributions in any form
# of modifications or other derivative works may not use the "OpenStudio"
# trademark, "OS", "os", or any other confusingly similar designation without
# specific prior written permission from Alliance for Sustainable Energy, LLC.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# *******************************************************************************

# dependencies
require 'openstudio'
require 'openstudio/measure/ShowRunnerOutput'
require 'fileutils'
require 'minitest/autorun'
require_relative '../measure.rb'

# only necessary to include here if annual simulation request and the measure doesn't require openstudio-standards
# require 'openstudio-standards'

class FaultHvacEconomizerChangeoverTemperatureTest < Minitest::Test

# return file paths to test models in test directory
def models_for_tests
paths = Dir.glob(File.join(File.dirname(__FILE__), '../../../tests/models/*.osm'))
paths = paths.map { |path| File.expand_path(path) }
return paths
end

# return file paths to epw files in test directory
def epws_for_tests
paths = Dir.glob(File.join(File.dirname(__FILE__), '../../../tests/weather/*.epw'))
paths = paths.map { |path| File.expand_path(path) }
return paths
end

def load_model(osm_path)
translator = OpenStudio::OSVersion::VersionTranslator.new
model = translator.loadModel(OpenStudio::Path.new(osm_path))
assert(!model.empty?)
model = model.get
return model
end

def run_dir(test_name)
# always generate test output in specially named 'output' directory so result files are not made part of the measure
return "#{File.dirname(__FILE__)}/output/#{test_name}"
end

def model_output_path(test_name)
return "#{run_dir(test_name)}/#{test_name}.osm"
end

def sql_path(test_name)
return "#{run_dir(test_name)}/run/eplusout.sql"
end

def report_path(test_name)
return "#{run_dir(test_name)}/reports/eplustbl.html"
end

# applies the measure and then runs the model
def apply_measure_and_run(test_name, measure, argument_map, osm_path, epw_path, run_model: false)
assert(File.exist?(osm_path))
assert(File.exist?(epw_path))

# create run directory if it does not exist
if !File.exist?(run_dir(test_name))
FileUtils.mkdir_p(run_dir(test_name))
end
assert(File.exist?(run_dir(test_name)))

# change into run directory for tests
start_dir = Dir.pwd
Dir.chdir run_dir(test_name)

# remove prior runs if they exist
if File.exist?(model_output_path(test_name))
FileUtils.rm(model_output_path(test_name))
end
if File.exist?(report_path(test_name))
FileUtils.rm(report_path(test_name))
end

# copy the osm and epw to the test directory
new_osm_path = "#{run_dir(test_name)}/#{File.basename(osm_path)}"
FileUtils.cp(osm_path, new_osm_path)
new_epw_path = "#{run_dir(test_name)}/#{File.basename(epw_path)}"
FileUtils.cp(epw_path, new_epw_path)
# create an instance of a runner
runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)

# load the test model
model = load_model(new_osm_path)

# set model weather file
epw_file = OpenStudio::EpwFile.new(OpenStudio::Path.new(new_epw_path))
OpenStudio::Model::WeatherFile.setWeatherFile(model, epw_file)
assert(model.weatherFile.is_initialized)

# run the measure
puts "\nAPPLYING MEASURE..."
measure.run(model, runner, argument_map)
result = runner.result
result_success = result.value.valueName == 'Success'

# show the output
show_output(result)

# save model
model.save(model_output_path(test_name), true)

if run_model && result_success
puts "\nRUNNING MODEL..."

std = Standard.build('90.1-2013')
std.model_run_simulation_and_log_errors(model, run_dir(test_name))

# check that the model ran successfully
assert(File.exist?(sql_path(test_name)))
end

# change back directory
Dir.chdir(start_dir)

return result
end

def test_number_of_arguments_and_argument_names
# This test ensures that the current test is matched to the measure inputs
test_name = 'test_number_of_arguments_and_argument_names'
puts "\n######\nTEST:#{test_name}\n######\n"

# Create an instance of the measure
measure = FaultHvacEconomizerChangeoverTemperature.new

# Make an empty model
model = OpenStudio::Model::Model.new

# Get arguments and test that they are what we are expecting
arguments = measure.arguments(model)
assert_equal(3, arguments.size)
assert_equal('econ_choice', arguments[0].name)
assert_equal('changeovertemp', arguments[1].name)
assert_equal('apply_measure', arguments[2].name)
end

# create an array of hashes with model name, weather, and expected result
def models_to_test
test_sets = []

# test: building with no economizer
test_sets << {
model: '361_Small_Office_PSZ_Gas_3a',
weather: 'CA_LOS-ANGELES-DOWNTOWN-USC_722874S_16',
result: 'NA'
}
# test: building with economizers with fixed drybulb control only
test_sets << {
model: '361_Small_Office_PSZ_Gas_3a_economizer_allfdb',
weather: 'CA_LOS-ANGELES-DOWNTOWN-USC_722874S_16',
result: 'Success'
}
# test: building with economizers with some fixed drybulb control
test_sets << {
model: '361_Small_Office_PSZ_Gas_3a_economizer_notallfdb',
weather: 'CA_LOS-ANGELES-DOWNTOWN-USC_722874S_16',
result: 'Success'
}
# test: building with economizers with no fixed drybulb control
test_sets << {
model: '361_Small_Office_PSZ_Gas_3a_economizer_nofdb',
weather: 'CA_LOS-ANGELES-DOWNTOWN-USC_722874S_16',
result: 'NA'
}
return test_sets
end

def test_models
test_name = 'test_models'
puts "\n######\nTEST:#{test_name}\n######\n"

models_to_test.each do |set|
instance_test_name = set[:model]
puts "instance test name: #{instance_test_name}"
osm_path = models_for_tests.select { |x| set[:model] == File.basename(x, '.osm') }
epw_path = epws_for_tests.select { |x| set[:weather] == File.basename(x, '.epw') }
assert(!osm_path.empty?)
assert(!epw_path.empty?)
osm_path = osm_path[0]
epw_path = epw_path[0]

# create an instance of the measure
measure = FaultHvacEconomizerChangeoverTemperature.new

# load the model; only used here for populating arguments
model = load_model(osm_path)

# set arguments here; will vary by measure
arguments = measure.arguments(model)
argument_map = OpenStudio::Measure::OSArgumentMap.new

# set arguments: choice of economizer
econ_choice = arguments[0].clone
assert(econ_choice.setValue('all available economizer'))
argument_map['econ_choice'] = econ_choice

# set arguments: changeover temperature C
changeovertemp = arguments[1].clone
assert(changeovertemp.setValue(10.88))
argument_map['changeovertemp'] = changeovertemp

# set arguments: apply measure
apply_measure = arguments[2].clone
assert(apply_measure.setValue(true))
argument_map['apply_measure'] = apply_measure

# apply the measure to the model and optionally run the model
result = apply_measure_and_run(instance_test_name, measure, argument_map, osm_path, epw_path, run_model: false)

# check the measure result; result values will equal Success, Fail, or Not Applicable (NA)
# also check the amount of warnings, info, and error messages
# use if or case statements to change expected assertion depending on model characteristics
assert(result.value.valueName == set[:result])

# to check that something changed in the model, load the model and the check the objects match expected new value
model = load_model(model_output_path(instance_test_name))

end
end
end
12 changes: 0 additions & 12 deletions resources/measures/fault_hvac_economizer_damper_stuck/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,6 @@ def run(model, runner, user_arguments)
next
end

is_unitary = false
air_loop_hvac.supplyComponents.each do |sc|
if sc.to_AirLoopHVACUnitarySystem.is_initialized
is_unitary = true
end
end

if is_unitary
runner.registerInfo("Air loop #{air_loop_hvac.name} is a unitary system cannot economize.")
next
end

sizing_system = air_loop_hvac.sizingSystem
type_of_load = sizing_system.typeofLoadtoSizeOn
if type_of_load == 'VentilationRequirement'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>fault_hvac_economizer_damper_stuck</name>
<uid>790eeac7-3689-4d63-ab6c-16ddb473905e</uid>
<version_id>c90702c6-0758-4a8f-b0d8-1ef8079f64da</version_id>
<version_modified>2023-10-16T20:24:55Z</version_modified>
<version_id>206bc2e6-fe36-4d3e-ad89-a0c1254622c3</version_id>
<version_modified>2023-11-07T15:08:08Z</version_modified>
<xml_checksum>D881B814</xml_checksum>
<class_name>FaultHvacEconomizerDamperStuck</class_name>
<display_name>fault hvac economizer damper stuck</display_name>
Expand Down Expand Up @@ -135,7 +135,13 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>1400E685</checksum>
<checksum>0BE829E9</checksum>
</file>
<file>
<filename>measure_test.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>D4A56848</checksum>
</file>
</files>
</measure>
Loading

0 comments on commit 4cea7ef

Please sign in to comment.