Class: URBANopt::REopt::REoptGHPAdapter
- Inherits:
-
Object
- Object
- URBANopt::REopt::REoptGHPAdapter
- Defined in:
- lib/urbanopt/reopt/reopt_ghp_adapter_ghp.rb
Overview
:nodoc:
Instance Method Summary collapse
- #create_reopt_input_building_bau(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, building_id, modelica_result) ⇒ Object
- #create_reopt_input_building_ghp(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, building_id, modelica_result) ⇒ Object
- #create_reopt_input_district_ghp(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, ghp_id, modelica_result) ⇒ Object
-
#initialize ⇒ REoptGHPAdapter
constructor
A new instance of REoptGHPAdapter.
Constructor Details
#initialize ⇒ REoptGHPAdapter
Returns a new instance of REoptGHPAdapter.
10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/urbanopt/reopt/reopt_ghp_adapter_ghp.rb', line 10 def initialize # initialize @@logger @@logger ||= URBANopt::REopt.reopt_logger # Define class variables @@hours_in_year = 8760 @@nat_gas_dollars_per_mmbtu = 13.5 @@year_of_simulation = 2023 @@year_of_simulation = 2023 @@small_multiplier = [0.00001] end |
Instance Method Details
#create_reopt_input_building_bau(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, building_id, modelica_result) ⇒ Object
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/urbanopt/reopt/reopt_ghp_adapter_ghp.rb', line 423 def create_reopt_input_building_bau(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, building_id, modelica_result) reopt_inputs_building_bau = {} if !reopt_ghp_assumptions_hash.nil? reopt_inputs_building_bau = reopt_ghp_assumptions_hash else @@logger.info('Using default REopt assumptions') # create a dictionary for REopt Inputs reopt_inputs_building_bau = { Site: {}, SpaceHeatingLoad: {}, DomesticHotWaterLoad: {}, ElectricLoad: {}, ElectricTariff: { urdb_label: "" }, ExistingBoiler: {} } end # The URDB label is required to be specified in the input assumption file if reopt_inputs_building_bau.nil? || reopt_inputs_building_bau[:ElectricTariff].nil? || reopt_inputs_building_bau[:ElectricTariff][:urdb_label].nil? || reopt_inputs_building_bau[:ElectricTariff][:urdb_label].empty? raise "Missing value for urdb_label - this is a required input" end scenario_json_path = File.join(run_dir, "default_scenario_report.json") if File.exist?(scenario_json_path) File.open(scenario_json_path, 'r') do |file| scenario_json_data = JSON.parse(file.read, symbolize_names: true) # update site location @latitude = scenario_json_data[:scenario_report][:location][:latitude_deg] @longitude = scenario_json_data[:scenario_report][:location][:longitude_deg] reopt_inputs_building_bau[:Site][:latitude] = @latitude reopt_inputs_building_bau[:Site][:longitude] = @longitude end end reopt_inputs_building_bau[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = [] # Read the default csv report default_feature_report_path = File.join(run_dir, building_id.to_s, "feature_reports", "default_feature_report.csv") if File.exist?(default_feature_report_path) timeseries_data = CSV.read(default_feature_report_path, headers: true) # Initialize the total kBtu sum heating_kbtu = 0.0 cooling_kbtu = 0.0 total_kwh_heating = 0.0 total_kwh_cooling = 0.0 # TODO : add other Heating Fuels if present (Heating:Propane(kBtu) etc.) # Convert each value in "Heating:NaturalGas(kBtu)" to MMBtu and store in the array timeseries_data.each do |row| if row['Heating:NaturalGas(kBtu)'] # Ensure the value exists heating_kBtu_value = row['Heating:NaturalGas(kBtu)'].to_f # Convert to float heating_kbtu += heating_kBtu_value # Sum kBtu values end if row.headers.include?('Cooling:NaturalGas(kBtu)') && row['Cooling:NaturalGas(kBtu)'] cooling_kBtu_value = row['Cooling:NaturalGas(kBtu)'].to_f # Convert to float cooling_kbtu += cooling_kBtu_value end if row['Heating:Electricity(kWh)'] heating_value = row['Heating:Electricity(kWh)'].to_f # Convert to float total_kwh_heating += heating_value # Sum heating values end if row['Cooling:Electricity(kWh)'] cooling_value = row['Cooling:Electricity(kWh)'].to_f # Convert to float total_kwh_cooling += cooling_value # Sum cooling values end end # Check if the heating kBtu is zero if heating_kbtu.zero? # If zero, populate with near zero hourly values to meet reopts formatting requirements reopt_inputs_building_bau[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year else # If not zero, convert and append to the array timeseries_data.each do |row| if row['Heating:NaturalGas(kBtu)'] # Ensure the value exists kBtu_value = row['Heating:NaturalGas(kBtu)'].to_f # Convert to float mMBtu_value = kBtu_value / 1000 # Convert kBtu to MMBtu reopt_inputs_building_bau[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] << mMBtu_value # Append to the array end end # Add fuel cost for existing boiler reopt_inputs_building_bau[:ExistingBoiler][:fuel_cost_per_mmbtu] = @@nat_gas_dollars_per_mmbtu end # if cooling_kbtu.zero? # # If zero, populate with near zero hourly values to meet reopts formatting requirements # reopt_inputs_building_bau[:CoolingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year # else # if there is cooling through natural gas it needs to be added to coolingload. If there is electricity based cooling, it is included in electric load if !cooling_kbtu.zero? # Add fuel load values for cooling reopt_inputs_building_bau[:CoolingLoad] = {} # If not zero, convert and append to the array timeseries_data.each do |row| if row['Cooling:NaturalGas(kBtu)'] # Ensure the value exists kBtu_value = row['Cooling:NaturalGas(kBtu)'].to_f # Convert to float ton_value = kBtu_value / 12 # Convert kBtu to ton reopt_inputs_building_bau[:CoolingLoad][:thermal_loads_ton] << ton_value # Append to the array end end # Add fuel cost for existing chiller reopt_inputs_building_bau[:ExistingChiller][:fuel_cost_per_mmbtu] = @@nat_gas_dollars_per_mmbtu end total_kwh_load = total_kwh_heating + total_kwh_cooling reopt_inputs_building_bau[:ElectricLoad][:year] = @@year_of_simulation # Check if the total kwh is zero if total_kwh_load.zero? # This is the total of heating and cooling electricity loads reopt_inputs_building_bau[:ElectricLoad][:loads_kw] = @@small_multiplier * @@hours_in_year else total_value_kwh = [] # Initialize the array timeseries_data.each do |row| heating_value_kwh = row['Heating:Electricity(kWh)'] ? row['Heating:Electricity(kWh)'].to_f : 0.0 cooling_value_kwh = row['Cooling:Electricity(kWh)'] ? row['Cooling:Electricity(kWh)'].to_f : 0.0 total = heating_value_kwh + cooling_value_kwh # Sum the values total_value_kwh << total # Append to the array reopt_inputs_building_bau[:ElectricLoad][:loads_kw] = total_value_kwh end end end #save output report in reopt_ghp directory reopt_ghp_dir = File.join(run_dir, "reopt_ghp", "reopt_ghp_inputs") json_file_path = File.join(reopt_ghp_dir, "BAU_building_#{building_id}.json") pretty_json = JSON.pretty_generate(reopt_inputs_building_bau) File.write(json_file_path, pretty_json) end |
#create_reopt_input_building_ghp(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, building_id, modelica_result) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/urbanopt/reopt/reopt_ghp_adapter_ghp.rb', line 22 def create_reopt_input_building_ghp(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, building_id, modelica_result) # Define variables reopt_inputs_building = {} if !reopt_ghp_assumptions_hash.nil? reopt_inputs_building = reopt_ghp_assumptions_hash else @@logger.info('Using default REopt assumptions') # create a dictionary for REopt Inputs reopt_inputs_building = { Site: {}, SpaceHeatingLoad: {}, DomesticHotWaterLoad: {}, ElectricLoad: {}, GHP: {}, ExistingBoiler: {} } end # The URDB label is required to be specified in the input assumption file if reopt_inputs_building[:ElectricTariff][:urdb_label].nil? || reopt_inputs_building[:ElectricTariff][:urdb_label].empty? raise "Missing value for urdb_label - this is a required input" end scenario_json_path = File.join(run_dir, "default_scenario_report.json") if File.exist?(scenario_json_path) File.open(scenario_json_path, 'r') do |file| scenario_json_data = JSON.parse(file.read, symbolize_names: true) # update site location @latitude = scenario_json_data[:scenario_report][:location][:latitude_deg] @longitude = scenario_json_data[:scenario_report][:location][:longitude_deg] reopt_inputs_building[:Site][:latitude] = @latitude reopt_inputs_building[:Site][:longitude] = @longitude end end reopt_inputs_building[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = [] reopt_inputs_building[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = [] # Read the default csv report default_feature_report_path = File.join(run_dir, building_id.to_s, "feature_reports", "default_feature_report.csv") if File.exist?(default_feature_report_path) timeseries_data = CSV.read(default_feature_report_path, headers: true) hours = timeseries_data.length timesteps_per_hour = if (hours % @@hours_in_year).zero? hours / @@hours_in_year else nil end heating_header = 'Heating:NaturalGas(kBtu)' if timesteps_per_hour.nil? || timesteps_per_hour.zero? reopt_inputs_building[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year puts "default_feature_report.csv has #{hours} rows (not a multiple of #{@@hours_in_year}); using near-zero placeholder SpaceHeatingLoad fuel load series for REopt input formatting." elsif timeseries_data.headers.include?(heating_header) heating_kbtu_series = timeseries_data.map { |row| row[heating_header].to_s.to_f } heating_mmbtu_series = if timesteps_per_hour == 1 heating_kbtu_series.map { |v| v / 1000.0 } else # Convert kBtu per timestep to equivalent kBtu/h, then reduce # to hourly resolution using the shared REopt utility pattern. heating_kbtu_per_hour = heating_kbtu_series.map { |v| v * timesteps_per_hour } convert_powerflow_resolution(heating_kbtu_per_hour, timesteps_per_hour, 1).map { |v| v / 1000.0 } end if heating_mmbtu_series.nil? || heating_mmbtu_series.sum.zero? # All-zero series: use near-zero placeholder to meet REopt formatting requirements reopt_inputs_building[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year else reopt_inputs_building[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = heating_mmbtu_series end else reopt_inputs_building[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year puts "#{heating_header} header not found in default_feature_report.csv; using near-zero placeholder SpaceHeatingLoad fuel load series for REopt input formatting." end else # populate with near zero hourly values to meet reopts formatting requirements reopt_inputs_building[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year puts "default_feature_report.csv not found; using near-zero placeholder SpaceHeatingLoad fuel load series for REopt input formatting." end # Add domestic hot water load if present in the default feature report if File.exist?(default_feature_report_path) # Re-use already loaded default_feature_report.csv when available timeseries_data ||= CSV.read(default_feature_report_path, headers: true) dhw_header = 'WaterSystems:NaturalGas(kBtu)' if timesteps_per_hour.nil? || timesteps_per_hour.zero? reopt_inputs_building[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year puts "default_feature_report.csv has #{hours} rows (not a multiple of #{@@hours_in_year}); using near-zero placeholder DomesticHotWaterLoad fuel load series for REopt input formatting." elsif timeseries_data.headers.include?(dhw_header) dhw_kbtu_series = timeseries_data.map { |row| row[dhw_header].to_s.to_f } dhw_mmbtu_series = if timesteps_per_hour == 1 dhw_kbtu_series.map { |v| v / 1000.0 } else # Convert kBtu per timestep to equivalent kBtu/h, then reduce # to hourly resolution using the shared REopt utility pattern. dhw_kbtu_per_hour = dhw_kbtu_series.map { |v| v * timesteps_per_hour } convert_powerflow_resolution(dhw_kbtu_per_hour, timesteps_per_hour, 1).map { |v| v / 1000.0 } end if dhw_mmbtu_series.nil? || dhw_mmbtu_series.sum.zero? reopt_inputs_building[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year else reopt_inputs_building[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = dhw_mmbtu_series end else reopt_inputs_building[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year puts "#{dhw_header} header not found in default_feature_report.csv; using near-zero placeholder DomesticHotWaterLoad fuel load series for REopt input formatting." end else # populate with near zero hourly values to meet reopts formatting requirements reopt_inputs_building[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier * @@hours_in_year puts "default_feature_report.csv not found; using near-zero placeholder DomesticHotWaterLoad fuel load series for REopt input formatting." end # read_modelica_result modelica_project = File.(modelica_result) project_name = File.basename(modelica_project) @modelica_csv = File.join( modelica_project, "#{project_name}.Districts.DistrictEnergySystem_results", "#{project_name}.Districts.DistrictEnergySystem_result.csv" ) if File.exist?(@modelica_csv) modelica_data = CSV.read(@modelica_csv, headers: true) heating_power_header = modelica_data.headers.select{ |h| h.to_s.start_with?("heating_electric_power") } prefix = "" if heating_power_header[0].split("_")[-1].include? ("B") prefix = "B" else prefix = "" end heating_power = "heating_electric_power_#{prefix}#{building_id}" cooling_power = "cooling_electric_power_#{prefix}#{building_id}" ets_pump_power = "ets_pump_power_#{prefix}#{building_id}" heating_system_capacity = "heating_system_capacity_#{prefix}#{building_id}" cooling_system_capacity = "cooling_system_capacity_#{prefix}#{building_id}" pump_power = "pump_power_#{building_id}" heating_power_values = cooling_power_values = pump_power_values = ets_pump_power_values = [] total_electric_load_building = [] # Ensure the column exists if modelica_data.headers.include?(heating_power) heating_power_values = modelica_data[heating_power] end if modelica_data.headers.include?(cooling_power) cooling_power_values = modelica_data[cooling_power] end if modelica_data.headers.include?(pump_power) pump_power_values = modelica_data[pump_power] end if modelica_data.headers.include?(ets_pump_power) ets_pump_power_values = modelica_data[ets_pump_power] end total_electric_load_building = heating_power_values.zip(cooling_power_values, pump_power_values, ets_pump_power_values).map do |elements| # Convert watts to kilowatts elements.map { |e| e.to_f / 1000 }.sum end peak_combined_heatpump_thermal_ton = 0 if modelica_data.headers.include?(heating_system_capacity) heating_system_capacity_value = modelica_data[heating_system_capacity][0] end if modelica_data.headers.include?(cooling_system_capacity) cooling_system_capacity_value = modelica_data[cooling_system_capacity][0] end watts_per_ton_cooling_capacity = 3517 peak_combined_heatpump_thermal_ton = ([heating_system_capacity_value.to_f.abs, cooling_system_capacity_value.to_f.abs].max) / watts_per_ton_cooling_capacity # Store the result in reopt_inputs_building ElectricLoad reopt_inputs_building[:ElectricLoad][:loads_kw] = total_electric_load_building reopt_inputs_building[:ElectricLoad][:year] = @@year_of_simulation # Add GHP Fields reopt_inputs_building[:GHP] = {} # Add avoided capital cost of all buildings if reopt_inputs_building[:features] && !reopt_inputs_building[:features].empty? # Find the feature matching this building_id matching_feature = reopt_inputs_building[:features].find { |feature| feature[:feature_id] == building_id.to_i} if matching_feature # Set avoided capex value into GHP block reopt_inputs_building[:GHP][:avoided_capex_by_ghp_present_value] = matching_feature[:avoided_capex_by_ghp_present_value] end end # REopt default reopt_inputs_building[:GHP][:require_ghp_purchase] = 1 reopt_inputs_building[:GHP][:om_cost_per_sqft_year] = 0 reopt_inputs_building[:GHP][:heatpump_capacity_sizing_factor_on_peak_load] = 1.0 # Add the floor area building_json_path = File.join(run_dir, building_id.to_s, "feature_reports", "default_feature_report.json") if File.exist?(building_json_path) puts building_json_path File.open(building_json_path, 'r') do |file| building_json_data = JSON.parse(file.read, symbolize_names: true) reopt_inputs_building[:GHP][:building_sqft] = building_json_data[:program][:footprint_area_sqft].to_f end else puts "File not found: #{building_json_path}" end # Add existing boiler fuel cost # TODO : Add this as optional user input # Cost of Natural Gas in $/mmbtu as per REopt Defaults reopt_inputs_building[:ExistingBoiler][:fuel_cost_per_mmbtu] = @@nat_gas_dollars_per_mmbtu # Add ghpghx_responses ghpghx_output = {} ghpghx_output[:outputs] = {} ghpghx_output[:inputs] = {} ghpghx_output[:outputs][:heat_pump_configuration] = "WSHP" # This is not used in REopt calculation but required for formatting. ghpghx_output[:outputs][:yearly_ghx_pump_electric_consumption_series_kw] = [0] * @@hours_in_year ghpghx_output[:outputs][:number_of_boreholes] = 0 ghpghx_output[:outputs][:length_boreholes_ft] = 0 ghpghx_output[:outputs][:peak_combined_heatpump_thermal_ton] = peak_combined_heatpump_thermal_ton ghpghx_output[:outputs][:yearly_total_electric_consumption_kwh] = total_electric_load_building.sum ghpghx_output[:outputs][:yearly_total_electric_consumption_series_kw] = total_electric_load_building ghpghx_output[:outputs][:yearly_heating_heatpump_electric_consumption_series_kw] = total_electric_load_building ghpghx_output[:outputs][:yearly_cooling_heatpump_electric_consumption_series_kw] = [0] * @@hours_in_year # This is not used in REopt calculation but required for formatting. # populate with near zero hourly values to meet reopts formatting requirements ghpghx_output[:inputs][:heating_thermal_load_mmbtu_per_hr] = @@small_multiplier * @@hours_in_year # This is not used in REopt calculation but required for formatting. ghpghx_output[:inputs][:cooling_thermal_load_ton] = [0] * @@hours_in_year ghpghx_output_all = [ghpghx_output] reopt_inputs_building[:GHP][:ghpghx_responses] = {} reopt_inputs_building[:GHP][:ghpghx_responses] = ghpghx_output_all end #save output report in reopt_ghp directory reopt_ghp_dir = File.join(run_dir, "reopt_ghp", "reopt_ghp_inputs") json_file_path = File.join(reopt_ghp_dir, "GHP_building_#{building_id}.json") pretty_json = JSON.pretty_generate(reopt_inputs_building) File.write(json_file_path, pretty_json) end |
#create_reopt_input_district_ghp(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, ghp_id, modelica_result) ⇒ Object
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/urbanopt/reopt/reopt_ghp_adapter_ghp.rb', line 272 def create_reopt_input_district_ghp(run_dir, system_parameter_hash, reopt_ghp_assumptions_hash, ghp_id, modelica_result) reopt_inputs_district = {} if !reopt_ghp_assumptions_hash.nil? reopt_inputs_district = reopt_ghp_assumptions_hash else @@logger.info('Using default REopt assumptions') # create a dictionary for REopt Inputs reopt_inputs_district = { Site: {}, SpaceHeatingLoad: {}, DomesticHotWaterLoad: {}, ElectricLoad: {}, ElectricTariff: { "urdb_label": "" }, GHP: {}, ExistingBoiler: {} } end reopt_inputs_district[:Site] = {} reopt_inputs_district[:Site][:latitude] = @latitude reopt_inputs_district[:Site][:longitude] = @longitude # The URDB label is required to be specified in the input assumption file if reopt_inputs_district[:ElectricTariff][:urdb_label].nil? || reopt_inputs_district[:ElectricTariff][:urdb_label].empty? raise "Missing value for urdb_label - this is a required input" end # populate with near zero hourly values to meet reopts formatting requirements # This is not used in REopt calculation but required for formatting. reopt_inputs_district[:SpaceHeatingLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier*@@hours_in_year # populate with near zero hourly values to meet reopts formatting requirements # This is not used in REopt calculation but required for formatting. reopt_inputs_district[:DomesticHotWaterLoad][:fuel_loads_mmbtu_per_hour] = @@small_multiplier*@@hours_in_year reopt_inputs_district[:ElectricLoad] = {} # populate with near zero hourly values to meet reopts formatting requirements # This is not used in REopt calculation but required for formatting. reopt_inputs_district[:ElectricLoad][:loads_kw] = @@small_multiplier*@@hours_in_year reopt_inputs_district[:ElectricLoad][:year] = @@year_of_simulation reopt_inputs_district[:ExistingBoiler] = {} reopt_inputs_district[:ExistingBoiler][:fuel_cost_per_mmbtu] = @@nat_gas_dollars_per_mmbtu # GHP inputs reopt_inputs_district[:GHP] = {} reopt_inputs_district[:GHP][:require_ghp_purchase] = 1 reopt_inputs_district[:GHP][:building_sqft] = format('%.8f', @@small_multiplier[0]).to_f reopt_inputs_district[:GHP][:om_cost_per_sqft_year] = 0 reopt_inputs_district[:GHP][:heatpump_capacity_sizing_factor_on_peak_load] = 1.0 # Add ghpghx outputs ghpghx_output = {} ghpghx_output[:outputs] = {} ghpghx_output[:inputs] = {} ghpghx_output[:inputs][:heating_thermal_load_mmbtu_per_hr] = [0]*@@hours_in_year ghpghx_output[:inputs][:cooling_thermal_load_ton] = [0] * @@hours_in_year # Read GHX sizes from system parameter hash ghe_specific_params = system_parameter_hash[:district_system][:fifth_generation][:ghe_parameters][:borefields] ghe_specific_params.each do |ghe| if ghe[:ghe_id] == ghp_id unless ghe[:pre_designed_borefield] if ghe[:autosized_rectangle_borefield] borefield = ghe[:autosized_rectangle_borefield] elsif ghe[:autosized_rectangle_constrained_borefield] borefield = ghe[:autosized_rectangle_constrained_borefield] elsif ghe[:autosized_birectangle_borefield] borefield = ghe[:autosized_birectangle_borefield] elsif ghe[:autosized_birectangle_constrained_borefield] borefield = ghe[:autosized_birectangle_constrained_borefield] elsif ghe[:autosized_bizoned_rectangle_borefield] borefield = ghe[:autosized_bizoned_rectangle_borefield] elsif ghe[:autosized_near_square_borefield] borefield = ghe[:autosized_near_square_borefield] elsif ghe[:autosized_rowwise_borefield] borefield = ghe[:autosized_rowwise_borefield] end end ghpghx_output[:outputs][:number_of_boreholes] = borefield[:number_of_boreholes] # convert meters to feet by multiplying with 3.28084 ghpghx_output[:outputs][:length_boreholes_ft] = (borefield[:borehole_length])*3.28084 end end if File.exist?(@modelica_csv) modelica_data = CSV.read(@modelica_csv, headers: true) electrical_power_consumed = modelica_data["electrical_power_consumed"] # Convert watts to kilowatts electrical_power_consumed_kw = electrical_power_consumed.map { |e| e.to_f / 1000 } # if ghp_id.include?('-') # # Note: For some reason when reading columns, '-' from the column headers are removed, whereas ghp_id has - # ghp_id_formatted = ghp_id.delete('-') # ghp_column = "electrical_power_consumed_#{ghp_id_formatted}".to_sym # else # # Note: For some reason when reading columns, '-' from the column headers are removed, whereas ghp_id has - # ghp_column = "electrical_power_consumed_#{ghp_id}".to_sym # end # # Ensure the column exists # unless modelica_data.headers.include?(ghp_column) # puts "Column #{ghp_column} does not exist in the CSV file." # end # # Access values from the column # column_values = modelica_data.by_col[ghp_column] ghpghx_output[:outputs][:yearly_ghx_pump_electric_consumption_series_kw] = electrical_power_consumed_kw else # populate with near zero hourly values to meet reopts formatting requirements # This is not used in REopt calculation but required for formatting. ghpghx_output[:outputs][:yearly_ghx_pump_electric_consumption_series_kw] = @@small_multiplier*@@hours_in_year end # This is not used in REopt calculation but required for formatting. ghpghx_output[:outputs][:peak_combined_heatpump_thermal_ton] = 0.000000001 ghpghx_output[:outputs][:heat_pump_configuration] = "WSHP" # populate with near zero hourly values to meet reopts formatting requirements # This is not used in REopt calculation but required for formatting. ghpghx_output[:outputs][:yearly_total_electric_consumption_series_kw] = @@small_multiplier * @@hours_in_year ghpghx_output[:outputs][:yearly_heating_heatpump_electric_consumption_series_kw] = [0] * @@hours_in_year ghpghx_output[:outputs][:yearly_cooling_heatpump_electric_consumption_series_kw] = [0] * @@hours_in_year ghpghx_output_all = [ghpghx_output, ghpghx_output] reopt_inputs_district[:GHP][:ghpghx_responses] = ghpghx_output_all #save output report in reopt_ghp directory reopt_ghp_dir = File.join(run_dir, "reopt_ghp", "reopt_ghp_inputs") json_file_path = File.join(reopt_ghp_dir, "GHX_#{ghp_id}.json") pretty_json = JSON.pretty_generate(reopt_inputs_district) File.write(json_file_path, pretty_json) end |