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

Speed up weather processing #1941

Merged
merged 7 commits into from
Mar 3, 2025
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
49 changes: 23 additions & 26 deletions BuildResidentialHPXML/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3654,21 +3654,6 @@ def run(model, runner, user_arguments)
return false
end

epw_path = args[:weather_station_epw_filepath]
if epw_path.nil?
# Get EPW path from zip code
epw_path = Defaults.lookup_weather_data_from_zipcode(args[:site_zip_code])[:station_filename]
end

# Create EpwFile object
if not File.exist? epw_path
epw_path = File.join(File.expand_path(File.join(File.dirname(__FILE__), '..', 'weather')), epw_path) # a filename was entered for weather_station_epw_filepath
end
if not File.exist? epw_path
runner.registerError("Could not find EPW file at '#{epw_path}'.")
return false
end

# Create HPXML file
hpxml_path = args[:hpxml_path]
unless (Pathname.new hpxml_path).absolute?
Expand All @@ -3683,7 +3668,7 @@ def run(model, runner, user_arguments)
end
end

hpxml_doc = HPXMLFile.create(runner, model, args, epw_path, hpxml_path, existing_hpxml_path)
hpxml_doc = HPXMLFile.create(runner, model, args, hpxml_path, existing_hpxml_path)
if not hpxml_doc
runner.registerError('Unsuccessful creation of HPXML file.')
return false
Expand Down Expand Up @@ -3965,14 +3950,11 @@ module HPXMLFile
# @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings
# @param model [OpenStudio::Model::Model] OpenStudio Model object
# @param args [Hash] Map of :argument_name => value
# @param epw_path [String] Path to the EPW weather file
# @param hpxml_path [String] Path to the created HPXML file
# @param existing_hpxml_path [String] Path to the existing HPXML file
# @return [Oga::XML::Element] Root XML element of the updated HPXML document
def self.create(runner, model, args, epw_path, hpxml_path, existing_hpxml_path)
if need_weather_based_on_args(args)
weather = WeatherFile.new(epw_path: epw_path, runner: nil)
end
def self.create(runner, model, args, hpxml_path, existing_hpxml_path)
weather = get_weather_if_needed(args)

success = create_geometry_envelope(runner, model, args)
return false if not success
Expand Down Expand Up @@ -4072,21 +4054,36 @@ def self.create(runner, model, args, epw_path, hpxml_path, existing_hpxml_path)
return hpxml_doc
end

# Determines if we need to process the weather; we avoid this if we can because it has a runtime performance impact
# Returns the WeatherFile object if we determine we need it for subsequent processing.
#
# @param args [Hash] Map of :argument_name => value
# @return [Boolean] True if we need to process the weather file
def self.need_weather_based_on_args(args)
# @return [WeatherFile] Weather object containing EPW information
def self.get_weather_if_needed(args)
if (args[:hvac_control_heating_season_period].to_s == Constants::BuildingAmerica) ||
(args[:hvac_control_cooling_season_period].to_s == Constants::BuildingAmerica) ||
(args[:solar_thermal_system_type] != Constants::None && args[:solar_thermal_collector_tilt].start_with?('latitude')) ||
(args[:pv_system_present] && args[:pv_system_array_tilt].start_with?('latitude')) ||
(args[:pv_system_2_present] && args[:pv_system_2_array_tilt].start_with?('latitude')) ||
(args[:apply_defaults])
return true
epw_path = args[:weather_station_epw_filepath]
if epw_path.nil?
# Get EPW path from zip code
epw_path = Defaults.lookup_weather_data_from_zipcode(args[:site_zip_code])[:station_filename]
end

# Error-checking
if not File.exist? epw_path
epw_path = File.join(File.expand_path(File.join(File.dirname(__FILE__), '..', 'weather')), epw_path) # a filename was entered for weather_station_epw_filepath
end
if not File.exist? epw_path
runner.registerError("Could not find EPW file at '#{epw_path}'.")
return false
end

return WeatherFile.new(epw_path: epw_path, runner: nil)
end

return false
return
end

# Check for errors in hpxml, and validate hpxml_doc against hpxml_path
Expand Down
6 changes: 3 additions & 3 deletions BuildResidentialHPXML/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>build_residential_hpxml</name>
<uid>a13a8983-2b01-4930-8af2-42030b6e4233</uid>
<version_id>ff0d59bb-d91a-4541-b946-afe4c5d3ab43</version_id>
<version_modified>2025-02-17T19:20:53Z</version_modified>
<version_id>e2cc5ff7-44e1-4751-a0d3-1354a9611c20</version_id>
<version_modified>2025-03-01T19:56:47Z</version_modified>
<xml_checksum>2C38F48B</xml_checksum>
<class_name>BuildResidentialHPXML</class_name>
<display_name>HPXML Builder</display_name>
Expand Down Expand Up @@ -7699,7 +7699,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>88B90FC6</checksum>
<checksum>EAEA0FE1</checksum>
</file>
<file>
<filename>constants.rb</filename>
Expand Down
2 changes: 1 addition & 1 deletion BuildResidentialScheduleFile/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def run(model, runner, user_arguments)

if epw_path.nil?
epw_path = Location.get_epw_path(hpxml_bldg, hpxml_path)
weather = WeatherFile.new(epw_path: epw_path, runner: runner, hpxml: hpxml)
weather = WeatherFile.new(epw_path: epw_path, runner: runner)
end
# deterministically vary schedules across building units
args[:random_seed] *= (i + 1)
Expand Down
6 changes: 3 additions & 3 deletions BuildResidentialScheduleFile/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>build_residential_schedule_file</name>
<uid>f770b2db-1a9f-4e99-99a7-7f3161a594b1</uid>
<version_id>acfa3ed7-ca05-472e-832b-19f86cabf04b</version_id>
<version_modified>2025-02-18T03:57:10Z</version_modified>
<version_id>c0a857c5-fe4e-4ce4-aaa7-43fc053e4f56</version_id>
<version_modified>2025-03-01T23:19:33Z</version_modified>
<xml_checksum>03F02484</xml_checksum>
<class_name>BuildResidentialScheduleFile</class_name>
<display_name>Schedule File Builder</display_name>
Expand Down Expand Up @@ -133,7 +133,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>9163B41C</checksum>
<checksum>5EB9E0D7</checksum>
</file>
<file>
<filename>README.md</filename>
Expand Down
21 changes: 10 additions & 11 deletions HPXMLtoOpenStudio/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def run(model, runner, user_arguments)
return false unless hpxml.errors.empty?

# Do these once upfront for the entire HPXML object
epw_path, weather = process_weather(runner, hpxml, args)
weather = process_weather(runner, hpxml, args)
process_whole_sfa_mf_inputs(hpxml)
hpxml_sch_map, design_loads_results_out = process_defaults_schedules_emissions_files(runner, weather, hpxml, args)

Expand All @@ -133,10 +133,10 @@ def run(model, runner, user_arguments)
# If we're running a whole SFA/MF building, all the unit models will be merged later
if hpxml.buildings.size > 1
unit_model = OpenStudio::Model::Model.new
create_unit_model(hpxml, hpxml_bldg, runner, unit_model, epw_path, weather, hpxml_sch_map[hpxml_bldg])
create_unit_model(hpxml, hpxml_bldg, runner, unit_model, weather, hpxml_sch_map[hpxml_bldg])
hpxml_osm_map[hpxml_bldg] = unit_model
else
create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, weather, hpxml_sch_map[hpxml_bldg])
create_unit_model(hpxml, hpxml_bldg, runner, model, weather, hpxml_sch_map[hpxml_bldg])
hpxml_osm_map[hpxml_bldg] = model
end
end
Expand All @@ -154,7 +154,7 @@ def run(model, runner, user_arguments)
# Outputs.apply_ems_debug_output(model) # Uncomment to debug EMS

# Write output files
Outputs.write_debug_files(runner, model, args[:debug], args[:output_dir], epw_path)
Outputs.write_debug_files(runner, model, weather, args[:debug], args[:output_dir])

# Write annual results output file
# This is helpful if the user wants to get these results right away (e.g.,
Expand Down Expand Up @@ -229,23 +229,23 @@ def create_hpxml_object(runner, args)
return hpxml
end

# Returns the EPW file path and the WeatherFile object.
# Returns the WeatherFile object.
#
# @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings
# @param hpxml [HPXML] HPXML object
# @param args [Hash] Map of :argument_name => value
# @return [Array<String, WeatherFile>] Path to the EPW weather file, Weather object containing EPW information
# @return [WeatherFile> Weather object containing EPW information
def process_weather(runner, hpxml, args)
epw_path = Location.get_epw_path(hpxml.buildings[0], args[:hpxml_path])
weather = WeatherFile.new(epw_path: epw_path, runner: runner, hpxml: hpxml)
weather = WeatherFile.new(epw_path: epw_path, runner: runner)
hpxml.buildings.each_with_index do |hpxml_bldg, i|
next if i == 0
next if Location.get_epw_path(hpxml_bldg, args[:hpxml_path]) == epw_path

fail 'Weather station EPW filepath has different values across dwelling units.'
end

return epw_path, weather
return weather
end

# Performs error-checking on the inputs for whole SFA/MF building simulations.
Expand Down Expand Up @@ -316,14 +316,13 @@ def process_defaults_schedules_emissions_files(runner, weather, hpxml, args)
# @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit
# @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings
# @param model [OpenStudio::Model::Model] OpenStudio Model object
# @param epw_path [String] Path to the EPW weather file
# @param weather [WeatherFile] Weather object containing EPW information
# @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files
# @return [nil]
def create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, weather, schedules_file)
def create_unit_model(hpxml, hpxml_bldg, runner, model, weather, schedules_file)
init(model, hpxml_bldg, hpxml.header)
SimControls.apply(model, hpxml.header)
Location.apply(model, weather, hpxml_bldg, hpxml.header, epw_path)
Location.apply(model, weather, hpxml_bldg, hpxml.header)

# Conditioned space & setpoints
spaces = {} # Map of HPXML locations => OpenStudio Space objects
Expand Down
20 changes: 10 additions & 10 deletions HPXMLtoOpenStudio/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>hpxm_lto_openstudio</name>
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
<version_id>b8d6c50d-c548-4e6b-a650-c9cb0de46fd2</version_id>
<version_modified>2025-02-28T01:26:30Z</version_modified>
<version_id>1efb99e6-bee6-4766-b58d-8c201261d3b2</version_id>
<version_modified>2025-03-03T05:41:52Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -183,7 +183,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>34B61ECA</checksum>
<checksum>5629CCEC</checksum>
</file>
<file>
<filename>airflow.rb</filename>
Expand Down Expand Up @@ -219,7 +219,7 @@
<filename>data/Xing_okstate_0664D_13659_Table_A-3.csv</filename>
<filetype>csv</filetype>
<usage_type>resource</usage_type>
<checksum>50B7055C</checksum>
<checksum>63D2B9F2</checksum>
</file>
<file>
<filename>data/cambium/LRMER_95DecarbBy2035.csv</filename>
Expand Down Expand Up @@ -327,7 +327,7 @@
<filename>defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>7F6189F3</checksum>
<checksum>C60070DF</checksum>
</file>
<file>
<filename>energyplus.rb</filename>
Expand Down Expand Up @@ -411,7 +411,7 @@
<filename>location.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>E5CD0079</checksum>
<checksum>3FF22771</checksum>
</file>
<file>
<filename>materials.rb</filename>
Expand Down Expand Up @@ -453,7 +453,7 @@
<filename>output.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>2824DDC1</checksum>
<checksum>F1DAFE41</checksum>
</file>
<file>
<filename>psychrometrics.rb</filename>
Expand Down Expand Up @@ -669,7 +669,7 @@
<filename>weather.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>70BF0986</checksum>
<checksum>AA8843CC</checksum>
</file>
<file>
<filename>xmlhelper.rb</filename>
Expand Down Expand Up @@ -741,7 +741,7 @@
<filename>test_location.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>733BB792</checksum>
<checksum>48836AFF</checksum>
</file>
<file>
<filename>test_miscloads.rb</filename>
Expand Down Expand Up @@ -789,7 +789,7 @@
<filename>test_weather.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>AD9AB5EC</checksum>
<checksum>6D80EFBE</checksum>
</file>
<file>
<filename>util.rb</filename>
Expand Down
Loading