urbanopt-scenario 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CONTRIBUTING.md +58 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  5. data/.github/pull_request_template.md +23 -0
  6. data/.gitignore +26 -0
  7. data/.rdoc_options +36 -0
  8. data/.rspec +3 -0
  9. data/.rubocop.yml +10 -0
  10. data/.travis.yml +23 -0
  11. data/CHANGELOG.md +19 -0
  12. data/Gemfile +43 -0
  13. data/Jenkinsfile +10 -0
  14. data/LICENSE.md +27 -0
  15. data/RDOC_MAIN.md +39 -0
  16. data/README.md +39 -0
  17. data/Rakefile +51 -0
  18. data/deploy_docs.sh +5 -0
  19. data/doc_templates/LICENSE.md +27 -0
  20. data/doc_templates/README.md.erb +42 -0
  21. data/doc_templates/copyright_erb.txt +31 -0
  22. data/doc_templates/copyright_js.txt +4 -0
  23. data/doc_templates/copyright_ruby.txt +29 -0
  24. data/docs/.gitignore +3 -0
  25. data/docs/.vuepress/components/InnerJsonSchema.vue +84 -0
  26. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  27. data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
  28. data/docs/.vuepress/components/StaticLink.vue +8 -0
  29. data/docs/.vuepress/config.js +15 -0
  30. data/docs/.vuepress/highlight.js +8 -0
  31. data/docs/.vuepress/public/custom_rdoc_styles.css +74 -0
  32. data/docs/.vuepress/utils.js +17 -0
  33. data/docs/README.md +39 -0
  34. data/docs/package-lock.json +11817 -0
  35. data/docs/package.json +26 -0
  36. data/docs/schemas/scenario-schema.md +3 -0
  37. data/lib/change_log.rb +147 -0
  38. data/lib/measures/.rubocop.yml +5 -0
  39. data/lib/measures/default_feature_reports/LICENSE.md +27 -0
  40. data/lib/measures/default_feature_reports/README.md +56 -0
  41. data/lib/measures/default_feature_reports/README.md.erb +42 -0
  42. data/lib/measures/default_feature_reports/measure.rb +742 -0
  43. data/lib/measures/default_feature_reports/measure.xml +139 -0
  44. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
  45. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +238 -0
  46. data/lib/measures/default_feature_reports/tests/example_model.osm +4378 -0
  47. data/lib/urbanopt-scenario.rb +31 -0
  48. data/lib/urbanopt/scenario.rb +45 -0
  49. data/lib/urbanopt/scenario/default_reports.rb +40 -0
  50. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +169 -0
  51. data/lib/urbanopt/scenario/default_reports/date.rb +97 -0
  52. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +187 -0
  53. data/lib/urbanopt/scenario/default_reports/end_use.rb +159 -0
  54. data/lib/urbanopt/scenario/default_reports/end_uses.rb +140 -0
  55. data/lib/urbanopt/scenario/default_reports/feature_report.rb +213 -0
  56. data/lib/urbanopt/scenario/default_reports/generator.rb +92 -0
  57. data/lib/urbanopt/scenario/default_reports/location.rb +99 -0
  58. data/lib/urbanopt/scenario/default_reports/logger.rb +44 -0
  59. data/lib/urbanopt/scenario/default_reports/program.rb +261 -0
  60. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +298 -0
  61. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +300 -0
  62. data/lib/urbanopt/scenario/default_reports/schema/README.md +34 -0
  63. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +13 -0
  64. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +830 -0
  65. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +92 -0
  66. data/lib/urbanopt/scenario/default_reports/storage.rb +105 -0
  67. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +258 -0
  68. data/lib/urbanopt/scenario/default_reports/validator.rb +97 -0
  69. data/lib/urbanopt/scenario/default_reports/wind.rb +92 -0
  70. data/lib/urbanopt/scenario/extension.rb +63 -0
  71. data/lib/urbanopt/scenario/logger.rb +42 -0
  72. data/lib/urbanopt/scenario/scenario_base.rb +79 -0
  73. data/lib/urbanopt/scenario/scenario_csv.rb +122 -0
  74. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +162 -0
  75. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +69 -0
  76. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +98 -0
  77. data/lib/urbanopt/scenario/scenario_runner_base.rb +63 -0
  78. data/lib/urbanopt/scenario/scenario_runner_osw.rb +158 -0
  79. data/lib/urbanopt/scenario/simulation_dir_base.rb +90 -0
  80. data/lib/urbanopt/scenario/simulation_dir_osw.rb +261 -0
  81. data/lib/urbanopt/scenario/simulation_mapper_base.rb +47 -0
  82. data/lib/urbanopt/scenario/version.rb +35 -0
  83. data/urbanopt-scenario-gem.gemspec +38 -0
  84. metadata +251 -0
@@ -0,0 +1,162 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+ #
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+ #
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ module URBANopt
32
+ module Scenario
33
+ class ScenarioDatapoint
34
+ attr_reader :scenario, :feature_id, :feature_name, :mapper_class #:nodoc:#
35
+
36
+ ##
37
+ # ScenarioDatapoint is an agnostic description of the simulation of a Feature in a Scenario
38
+ # A Simulation Mapper will map the
39
+ ##
40
+ # [parameters:]
41
+ # +scenario+ - _ScenarioBase_ - Scenario containing this ScenarioDatapoint.
42
+ # +feature_id+ - _String_ - Unique id of the feature for this ScenarioDatapoint.
43
+ # +feature_name+ - _String_ - Human readable name of the feature for this ScenarioDatapoint.
44
+ # +mapper_class+ - _String_ - Name of Ruby class used to translate feature to simulation OSW.
45
+ def initialize(scenario, feature_id, feature_name, mapper_class)
46
+ @scenario = scenario
47
+ @feature_id = feature_id
48
+ @feature_name = feature_name
49
+ @feature = scenario.feature_file.get_feature_by_id(feature_id)
50
+ @mapper_class = mapper_class
51
+ end
52
+
53
+ attr_reader :feature #:nodoc:
54
+
55
+ ##
56
+ # Gets the type of a feature
57
+ ##
58
+ def feature_type
59
+ @feature.feature_type
60
+ end
61
+
62
+ ##
63
+ # Return the directory that this datapoint will run in.
64
+ ##
65
+ # [return:] _String_ - Directory that this datapoint will run in.
66
+ def run_dir
67
+ raise 'Feature ID not set' if @feature_id.nil?
68
+ raise 'Scenario run dir not set' if @scenario.run_dir.nil?
69
+ return File.join(@scenario.run_dir, @feature_id + '/')
70
+ end
71
+
72
+ ##
73
+ # Return the directory that this datapoint will run in.
74
+ def clear
75
+ dir = run_dir
76
+ FileUtils.rm_rf(dir) if File.exist?(dir)
77
+ FileUtils.mkdir_p(dir) if !File.exist?(dir)
78
+ end
79
+
80
+ # rubocop: disable Security/Eval #:nodoc:
81
+ # rubocop: disable Style/EvalWithLocation #:nodoc:
82
+ # Disable Sceurity/Eval since there is no user input #:nodoc:
83
+
84
+ ##
85
+ # Create run directory and generate simulation OSW, all previous contents of directory are removed
86
+ # The simulation OSW is created by evaluating the mapper_class's create_osw method
87
+ ##
88
+ # [return:] _String_ - Path to the simulation OSW.
89
+ ##
90
+ def create_osw
91
+ osw = eval("#{@mapper_class}.new.create_osw(@scenario, @feature_id, @feature_name)")
92
+ dir = run_dir
93
+ FileUtils.rm_rf(dir) if File.exist?(dir)
94
+ FileUtils.mkdir_p(dir) if !File.exist?(dir)
95
+ osw_path = File.join(dir, 'in.osw')
96
+ File.open(osw_path, 'w') do |f|
97
+ f << JSON.pretty_generate(osw)
98
+ # make sure data is written to the disk one way or the other
99
+ begin
100
+ f.fsync
101
+ rescue StandardError
102
+ f.flush
103
+ end
104
+ end
105
+ return osw_path
106
+ end
107
+ # rubocop: enable Security/Eval #:nodoc:
108
+ # rubocop: enable Style/EvalWithLocation #:nodoc:
109
+
110
+ ##
111
+ # Return true if the datapoint is out of date, false otherwise. Non-existant files are out of date.
112
+ ##
113
+ # [return:] _Boolean_ - True if the datapoint is out of date, false otherwise.
114
+ def out_of_date?
115
+ dir = run_dir
116
+ if !File.exist?(dir)
117
+ return true
118
+ end
119
+
120
+ out_osw = File.join(dir, 'out.osw')
121
+ if !File.exist?(out_osw)
122
+ return true
123
+ end
124
+ out_osw_time = File.mtime(out_osw)
125
+
126
+ # array of files that this datapoint depends on
127
+ dependencies = []
128
+
129
+ # depends on the feature file
130
+ dependencies << scenario.feature_file.path
131
+
132
+ # depends on the csv file
133
+ dependencies << scenario.csv_file
134
+
135
+ # depends on the mapper classes
136
+ Dir.glob(File.join(scenario.mapper_files_dir, '*')).each do |f|
137
+ dependencies << f
138
+ end
139
+
140
+ # depends on the root gemfile
141
+ dependencies << File.join(scenario.root_dir, 'Gemfile')
142
+ dependencies << File.join(scenario.root_dir, 'Gemfile.lock')
143
+
144
+ # todo, depends on all the measures?
145
+
146
+ # check if out of date
147
+ dependencies.each do |f|
148
+ if File.exist?(f)
149
+ if File.mtime(f) > out_osw_time
150
+ puts "File '#{f}' is newer than '#{out_osw}', datapoint out of date"
151
+ return true
152
+ end
153
+ else
154
+ puts "Dependency file '#{f}' does not exist"
155
+ end
156
+ end
157
+
158
+ return false
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,69 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+ #
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+ #
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ module URBANopt
32
+ module Scenario
33
+ class ScenarioPostProcessorBase
34
+ ##
35
+ # ScenarioPostProcessorBase post-processes a Scenario to create scenario level results.
36
+ ##
37
+ # [parameters:]
38
+ # +scenario_base+ - _ScenarioBase_ - An object of ScenarioBase class.
39
+ def initialize(scenario_base)
40
+ @scenario_base = scenario_base
41
+ end
42
+
43
+ attr_reader :scenario_base
44
+
45
+ ##
46
+ # Run the post processor on this Scenario.
47
+ ##
48
+ def run
49
+ raise 'run not implemented for ScenarioPostProcessorBase, override in your class'
50
+ end
51
+
52
+ ##
53
+ # Add results from a simulation_dir to this result.
54
+ ##
55
+ # [parameters:]
56
+ # +simulation_dir+ - _SimulationDirOSW_ - An object on SimulationDirOSW class.
57
+ def add_simulation_dir(simulation_dir)
58
+ raise 'add_simulation_dir not implemented for ScenarioPostProcessorBase, override in your class'
59
+ end
60
+
61
+ ##
62
+ # Save scenario result.
63
+ ##
64
+ def save
65
+ raise 'save not implemented for ScenarioPostProcessorBase, override in your class'
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,98 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+ #
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+ #
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ require 'urbanopt/scenario/scenario_post_processor_base'
32
+ require 'urbanopt/scenario/default_reports'
33
+ require 'urbanopt/scenario/default_reports/logger'
34
+
35
+ require 'csv'
36
+ require 'json'
37
+ require 'fileutils'
38
+
39
+ module URBANopt
40
+ module Scenario
41
+ class ScenarioDefaultPostProcessor < ScenarioPostProcessorBase
42
+ ##
43
+ # ScenarioPostProcessorBase post-processes a scenario to create scenario level results
44
+ ##
45
+ # [parameters:]
46
+ # +scenario_base+ - _ScenarioBase_ - An object of ScenarioBase class.
47
+ def initialize(scenario_base)
48
+ super(scenario_base)
49
+
50
+ initialization_hash = { directory_name: scenario_base.run_dir, name: scenario_base.name, id: scenario_base.name }
51
+ @scenario_result = URBANopt::Scenario::DefaultReports::ScenarioReport.new(initialization_hash)
52
+
53
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
54
+ end
55
+
56
+ ##
57
+ # Run the post processor on this Scenario.This will add all the simulation_dirs.
58
+ ##
59
+ def run
60
+ # this run method adds all the simulation_dirs, you can extend it to do more custom stuff
61
+ @scenario_base.simulation_dirs.each do |simulation_dir|
62
+ add_simulation_dir(simulation_dir)
63
+ end
64
+ return @scenario_result
65
+ end
66
+
67
+ ##
68
+ # Add results from a simulation_dir to this result.
69
+ ##
70
+ # [parameters:]
71
+ # +simulation_dir+ - _SimulationDirOSW_ - An object on SimulationDirOSW class.
72
+ def add_simulation_dir(simulation_dir)
73
+ feature_reports = URBANopt::Scenario::DefaultReports::FeatureReport.from_simulation_dir(simulation_dir)
74
+
75
+ feature_reports.each do |feature_report|
76
+ if feature_report.to_hash[:simulation_status] == 'Complete'
77
+ @scenario_result.add_feature_report(feature_report)
78
+ else
79
+ @@logger.error("Feature #{feature_report.id} failed to run!")
80
+ end
81
+ end
82
+
83
+ return feature_reports
84
+ end
85
+
86
+ ##
87
+ # Save scenario result
88
+ ##
89
+ # [parameters:]
90
+ # +file_name+ - _String_ - Assign a name to the saved scenario results file
91
+ def save(file_name = 'default_scenario_report')
92
+ @scenario_result.save
93
+
94
+ return @scenario_result
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,63 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+ #
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+ #
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ module URBANopt
32
+ module Scenario
33
+ class ScenarioRunnerBase
34
+ ##
35
+ # ScenarioRunnerBase is the agnostic interface for a class which can create and run SimulationFiles.
36
+ ##
37
+ def initialize; end
38
+
39
+ ##
40
+ # Create all SimulationDirs for Scenario.
41
+ ##
42
+ # [parameters:]
43
+ # +scenario+ - _ScenarioBase_ - Scenario to create simulation input files for scenario.
44
+ # +force_clear+ - _Bool_ - Clear Scenario before creating simulation input files
45
+ # [return:] _Array_ Returns an array of all SimulationDirs, even those created previously, for Scenario.
46
+ def create_simulation_files(scenario, force_clear = false)
47
+ raise 'create_input_files is not implemented for ScenarioRunnerBase, override in your class'
48
+ end
49
+
50
+ ##
51
+ # Create and run all SimulationFiles for Scenario.
52
+ ##
53
+ # [parameters:]
54
+ # +scenario+ - _ScenarioBase_ - Scenario to create and run simulation input files for.
55
+ # +force_clear+ - _Bool_ - Clear Scenario before creating Simulation input files.
56
+ #
57
+ # [return:] _Array_ Returns an array of all SimulationDirs, even those created previously, for Scenario.
58
+ def run(scenario, force_clear = false)
59
+ raise 'run is not implemented for ScenarioRunnerBase, override in your class'
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,158 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+ #
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+ #
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ require 'urbanopt/scenario/scenario_runner_base'
32
+ require 'json'
33
+
34
+ require 'fileutils'
35
+ # require 'hash_parser'
36
+
37
+ module URBANopt
38
+ module Scenario
39
+ class ScenarioRunnerOSW < ScenarioRunnerBase
40
+ ##
41
+ # ScenarioRunnerOSW is a class to create and run SimulationFileOSWs
42
+ ##
43
+ def initialize; end
44
+
45
+ ##
46
+ # Create all OSWs for Scenario.
47
+ ##
48
+ # [parameters:]
49
+ # +scenario+ - _ScenarioBase_ - Scenario to create simulation input files for.
50
+ # +force_clear+ - _Bool_ - Clear Scenario before creating simulation input files.
51
+ # [return:] _Array_ Returns array of all SimulationDirs, even those created previously, for Scenario.
52
+ def create_simulation_files(scenario, force_clear = false)
53
+ if force_clear
54
+ scenario.clear
55
+ end
56
+
57
+ FileUtils.mkdir_p(scenario.run_dir) if !File.exist?(scenario.run_dir)
58
+
59
+ simulation_dirs = scenario.simulation_dirs
60
+
61
+ simulation_dirs.each do |simulation_dir|
62
+ if simulation_dir.out_of_date?
63
+ puts "simulation_dir #{simulation_dir.run_dir} is out of date, regenerating input files"
64
+ simulation_dir.create_input_files
65
+ end
66
+ end
67
+ return simulation_dirs
68
+ end
69
+
70
+ ##
71
+ # Create and run all SimulationFileOSW for Scenario.
72
+ # A staged runner is implented to run buildings, then transformers then district systems.
73
+ # - instantiate openstudio runner to run .osw files.
74
+ # - create simulation files for this scenario.
75
+ # - get feature_type value from in.osw files
76
+ # - cretae 3 groups to store .osw files (+building_osws+ , +transformer_osws+ , +district_system_osws+)
77
+ # - add each osw file to its corresponding group id +simulation_dir+ is out_of_date
78
+ # - Run osw file groups in order and store simulation failure in a array.
79
+ ##
80
+ # [parameters:]
81
+ # +scenario+ - _ScenarioBase_ - Scenario to create and run SimulationFiles for.
82
+ # +force_clear+ - _Bool_ - Clear Scenario before creating SimulationFiles.
83
+ # [return:] _Array_ Returns array of all SimulationFiles, even those created previously, for Scenario.
84
+ def run(scenario, force_clear = false)
85
+ # instantiate openstudio runner - use the defaults for now. If need to change then create
86
+ # the runner.conf file (i.e. run `rake openstudio:runner:init`)
87
+ runner = OpenStudio::Extension::Runner.new(scenario.root_dir)
88
+
89
+ # create simulation files
90
+ simulation_dirs = create_simulation_files(scenario, force_clear)
91
+
92
+ # osws = []
93
+ # simulation_dirs.each do |simulation_dir|
94
+ # if !simulation_dir.is_a?(SimulationDirOSW)
95
+ # raise "ScenarioRunnerOSW does not know how to run #{simulation_dir.class}"
96
+ # end
97
+ # if simulation_dir.out_of_date?
98
+ # osws << simulation_dir.in_osw_path
99
+ # end
100
+ # end
101
+
102
+ # cretae 3 groups to store .osw files (+building_osws+ , +transformer_osws+ , +district_system_osws+)
103
+ building_osws = []
104
+ transformer_osws = []
105
+ district_system_osws = []
106
+
107
+ simulation_dirs.each do |simulation_dir|
108
+ in_osw = File.read(simulation_dir.in_osw_path)
109
+ in_osw_hash = JSON.parse(in_osw, symbolize_names: true)
110
+
111
+ if !simulation_dir.is_a?(SimulationDirOSW)
112
+ raise "ScenarioRunnerOSW does not know how to run #{simulation_dir.class}"
113
+ end
114
+
115
+ # get feature_type value from in.osw files
116
+ feature_type = nil
117
+ in_osw_hash[:steps].each { |x| feature_type = x[:arguments][:feature_type] if x[:arguments][:feature_type] }
118
+
119
+ # add each osw file to its corresponding group id +simulation_dir+ is out_of_date
120
+ if simulation_dir.out_of_date?
121
+
122
+ if feature_type == 'Building'
123
+ building_osws << simulation_dir.in_osw_path
124
+ elsif feature_type == 'District System'
125
+ district_system_osws << simulation_dir.in_osw_path
126
+ elsif feature_type == 'Transformer'
127
+ transformer_osws << simulation_dir.in_osw_path
128
+ else
129
+ raise "ScenarioRunnerOSW does not know how to run a #{feature_type} feature"
130
+ end
131
+
132
+ end
133
+ end
134
+
135
+ # Run osw groups in order and store simulation failure in a array.
136
+ # Return simulation_dirs after running all simulations.
137
+
138
+ # failures
139
+ failures = []
140
+ # run building_osws
141
+ # building_failures = runner.run_osws(building_osws, num_parallel = Extension::NUM_PARALLEL, max_to_run = Extension::MAX_DATAPOINTS)
142
+ building_failures = runner.run_osws(building_osws)
143
+ failures << building_failures
144
+ # run district_system_osws
145
+ # district_system_failures = runner.run_osws(district_system_osws, num_parallel = Extension::NUM_PARALLEL, max_to_run = Extension::MAX_DATAPOINTS)
146
+ district_system_failures = runner.run_osws(district_system_osws)
147
+ failures << district_system_failures
148
+ # run transformer_osws
149
+ # transformer_failures = runner.run_osws(transformer_osws, num_parallel = Extension::NUM_PARALLEL, max_to_run = Extension::MAX_DATAPOINTS)
150
+ transformer_failures = runner.run_osws(transformer_osws)
151
+ failures << transformer_failures
152
+
153
+ # puts "failures = #{failures}"
154
+ return simulation_dirs
155
+ end
156
+ end
157
+ end
158
+ end