NREL / openstudio-standards

Other
79 stars 57 forks source link

Validate Geometry for all Archetypes #255

Closed phylroy closed 7 years ago

phylroy commented 7 years ago

Review all the archetype geometry files used by NECB and...

Also ensure the that model contains

image

Addition 1: This method adds the BuildingStories to the model for Small Hotel. Eliminate the need for this method by creating this information into the geo files directly for the different vintages. Create new osms if required. https://github.com/NREL/openstudio-standards/blob/nrcan/openstudio-standards/lib/openstudio-standards/prototypes/Prototype.small_hotel.rb#L473


  def self.define_building_story_map(building_type, template, climate_zone)
    building_story_map = nil

    building_story_map = {
      'BuildingStory1' => ['GuestRoom101', 'GuestRoom102', 'GuestRoom103', 'GuestRoom104', 'GuestRoom105', 'CorridorFlr1', 'ElevatorCoreFlr1', 'EmployeeLoungeFlr1', 'ExerciseCenterFlr1', 'FrontLoungeFlr1', 'FrontOfficeFlr1', 'FrontStairsFlr1', 'RearStairsFlr1', 'FrontStorageFlr1', 'RearStorageFlr1', 'LaundryRoomFlr1', 'MechanicalRoomFlr1', 'MeetingRoomFlr1', 'RestroomFlr1'],
      'BuildingStory2' => ['GuestRoom201', 'GuestRoom202_205', 'GuestRoom206_208', 'GuestRoom209_212', 'GuestRoom213', 'GuestRoom214', 'GuestRoom215_218', 'GuestRoom219', 'GuestRoom220_223', 'GuestRoom224', 'CorridorFlr2', 'FrontStairsFlr2', 'RearStairsFlr2', 'FrontStorageFlr2', 'RearStorageFlr2', 'ElevatorCoreFlr2'],
      'BuildingStory3' => ['GuestRoom301', 'GuestRoom302_305', 'GuestRoom306_308', 'GuestRoom309_312', 'GuestRoom313', 'GuestRoom314', 'GuestRoom315_318', 'GuestRoom319', 'GuestRoom320_323', 'GuestRoom324', 'CorridorFlr3', 'FrontStairsFlr3', 'RearStairsFlr3', 'FrontStorageFlr3', 'RearStorageFlr3', 'ElevatorCoreFlr3'],
      'BuildingStory4' => ['GuestRoom401', 'GuestRoom402_405', 'GuestRoom406_408', 'GuestRoom409_412', 'GuestRoom413', 'GuestRoom414', 'GuestRoom415_418', 'GuestRoom419', 'GuestRoom420_423', 'GuestRoom424', 'CorridorFlr4', 'FrontStairsFlr4', 'RearStairsFlr4', 'FrontStorageFlr4', 'RearStorageFlr4', 'ElevatorCoreFlr4']
    }

    # attic only applies to the two DOE vintages.
    if template == 'DOE Ref Pre-1980' || template == 'DOE Ref 1980-2004'
      building_story_map['AtticStory'] = ['Attic']
    end
    return building_story_map
  end
```ruby
padmassun commented 7 years ago

NOTE: Task 1 I am using NECB 2011's space mapping as the default value for

FullServiceRestaurant
LargeOffice
MidriseApartment
QuickServiceRestaurant

This is mainly because other templates has its space type mapping been explicitly defined (i.e. there was no else case for the space type mapping).

padmassun commented 7 years ago

There were some issues with LargeOffice and PrimarySchool as per CircleCI. Working on fixing it...

padmassun commented 7 years ago

The following geometry files has problems loading in SketchUp.

Geometry.hospital.osm

Related to #253

Warning:  A surface was subdivided because of connected geometry.
Added new surface Surface 1
You should check your geometry carefully for mistakes.

Warning:  A surface was subdivided because of connected geometry.
Added new surface Surface 2
You should check your geometry carefully for mistakes.

Removed duplicate drawing interface for object Lab_Flr_3_Wall_West
  Potential duplicate of object Surface 1

Removed duplicate drawing interface for object Office2_Mult5_Flr_5_Floor
  Potential duplicate of object Surface 2

Geometry.warehouse_pre_1980_to_2004.osm

Warning:  BulkStorage_Wall_East_Door_3
This sub surface was not in the same plane as its base surface.
It has been automatically fixed.

Warning:  BulkStorage_Wall_East_Door_2
This sub surface was not in the same plane as its base surface.
It has been automatically fixed.

Warning:  FineStorage_Wall_East_Door_1
This sub surface was not in the same plane as its base surface.
It has been automatically fixed.

Warning:  BulkStorage_Wall_East_Door_1
This sub surface was not in the same plane as its base surface.
It has been automatically fixed.
padmassun commented 7 years ago

I am having some issues checking if surfaces are intersected properly. Related to https://github.com/NREL/OpenStudio/issues/2681 (SketchUp issue)

padmassun commented 7 years ago

Redoing Task 1 to consolidate duplicate values. Will be using the following format for spacetype_to_space.json

{
  "FullServiceRestaurant": [
    {
      "template": ["",""],
      "space_type_map" : {    }
    },
    {
      "template": ["",""],
      "space_type_map" : {   }
    }
  ],
  ...
}
padmassun commented 7 years ago

While waiting for CircleCI, I will be working on manually setting the number of stories in the osm file (using sketchUp), based on geometry.json file

padmassun commented 7 years ago

Script that changed the number of stories

require 'openstudio'
require_relative '../../lib/openstudio-standards/btap/btap'
require_relative '../../lib/openstudio-standards/btap/fileio'
require 'json'
require 'fileutils'

stories_data =  JSON.parse(File.read("./geometry.json"))
geom_file = JSON.parse(File.read("./template_building_type_to_geometry_file.json"))
modified_files = []
output_folder = "./output"
FileUtils.mkdir_p(File.absolute_path(output_folder))

geom_file.keys.each { |archetype|
  next if archetype == 'Office'
  puts "archetype: #{archetype}"
  geom_file[archetype].keys.each { |template|
    next unless template == "NECB 2011"
    next if modified_files.include?(geom_file[archetype][template])
    modified_files << geom_file[archetype][template]
    osm_infile_name = geom_file[archetype][template]
    puts "\tosm_infile_name: #{osm_infile_name}"
    model = BTAP::FileIO.safe_load_model(osm_infile_name)
    stories_above_ground = stories_data["NECB 2011"][archetype]["above_ground_floors"]
    stories_below_ground = stories_data["NECB 2011"][archetype]["below_ground_floors"]
    puts "\t\tstories_above_ground: #{stories_above_ground}"
    puts "\t\tstories_below_ground: #{stories_below_ground}"

    total = stories_above_ground + stories_below_ground

    puts "\t\tVALIDATION"
    puts "\t\tBEFORE"
    puts "\t\t\tStandardsNumberOfStories: [#{model.building.get.standardsNumberOfStories}]"
    puts "\t\t\tStandardsNumberOfAboveGroundStories: [#{model.building.get.standardsNumberOfAboveGroundStories}]"

    model.building.get.setStandardsNumberOfStories(total)
    model.building.get.setStandardsNumberOfAboveGroundStories(stories_above_ground)

    osm_path = OpenStudio::Path.new("./output/#{osm_infile_name}")
    model.save(osm_path, true)

    model = BTAP::FileIO.safe_load_model(osm_path)
    puts "\t\tAFTER"
    puts "\t\t\tStandardsNumberOfStories: [#{model.building.get.standardsNumberOfStories}]"
    puts "\t\t\tStandardsNumberOfAboveGroundStories: [#{model.building.get.standardsNumberOfAboveGroundStories}]"
  }
}

output

rchetype: SecondarySchool
    osm_infile_name: Geometry.secondary_school.osm
        stories_above_ground: 2
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [2]
            StandardsNumberOfAboveGroundStories: [2]
archetype: PrimarySchool
    osm_infile_name: Geometry.primary_school.osm
        stories_above_ground: 1
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [1]
            StandardsNumberOfAboveGroundStories: [1]
archetype: SmallOffice
    osm_infile_name: Geometry.small_office.osm
        stories_above_ground: 2
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [2]
            StandardsNumberOfAboveGroundStories: [2]
archetype: MediumOffice
    osm_infile_name: Geometry.medium_office.osm
        stories_above_ground: 3
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [3]
            StandardsNumberOfAboveGroundStories: [3]
archetype: LargeOffice
    osm_infile_name: Geometry.large_office_2010.osm
        stories_above_ground: 12
        stories_below_ground: 1
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [13]
            StandardsNumberOfAboveGroundStories: [12]
archetype: SmallHotel
    osm_infile_name: Geometry.small_hotel_pnnl2013.osm
        stories_above_ground: 4
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [4]
            StandardsNumberOfAboveGroundStories: [4]
archetype: LargeHotel
    osm_infile_name: Geometry.large_hotel.2013.osm
        stories_above_ground: 6
        stories_below_ground: 1
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [7]
            StandardsNumberOfAboveGroundStories: [6]
archetype: Warehouse
    osm_infile_name: Geometry.warehouse.osm
        stories_above_ground: 1
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [1]
            StandardsNumberOfAboveGroundStories: [1]
archetype: RetailStandalone
    osm_infile_name: Geometry.retail_standalone.2010_2013.osm
        stories_above_ground: 1
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [1]
            StandardsNumberOfAboveGroundStories: [1]
archetype: RetailStripmall
    osm_infile_name: Geometry.retail_stripmall.osm
        stories_above_ground: 1
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [1]
            StandardsNumberOfAboveGroundStories: [1]
archetype: QuickServiceRestaurant
    osm_infile_name: Geometry.quick_service_restaurant_allothers.osm
        stories_above_ground: 2
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [2]
            StandardsNumberOfAboveGroundStories: [2]
archetype: FullServiceRestaurant
    osm_infile_name: Geometry.full_service_restaurant_allothers.osm
        stories_above_ground: 2
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [2]
            StandardsNumberOfAboveGroundStories: [2]
archetype: Hospital
    osm_infile_name: Geometry.hospital_new.osm
        stories_above_ground: 5
        stories_below_ground: 1
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [6]
            StandardsNumberOfAboveGroundStories: [5]
archetype: Outpatient
    osm_infile_name: Geometry.outpatient.osm
        stories_above_ground: 3
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [3]
            StandardsNumberOfAboveGroundStories: [3]
archetype: MidriseApartment
    osm_infile_name: Geometry.mid_rise_apartment.osm
        stories_above_ground: 4
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [4]
            StandardsNumberOfAboveGroundStories: [4]
archetype: HighriseApartment
    osm_infile_name: Geometry.high_rise_apartment.osm
        stories_above_ground: 10
        stories_below_ground: 0
        VALIDATION
        BEFORE
            StandardsNumberOfStories: []
            StandardsNumberOfAboveGroundStories: []
        AFTER
            StandardsNumberOfStories: [10]
            StandardsNumberOfAboveGroundStories: [10]
padmassun commented 7 years ago

Now I will be working on mapping the BuildingStories to space in the geometry model for Small Hotel

padmassun commented 7 years ago

Script used to change SmallHotel Geometry

require 'openstudio'
require_relative '../../lib/openstudio-standards/btap/btap'
require_relative '../../lib/openstudio-standards/btap/fileio'
require 'json'
require 'fileutils'

small_hotel_geom_files = JSON.parse(File.read("./template_building_type_to_geometry_file.json"))["SmallHotel"]
output_folder = "./output"
FileUtils.mkdir_p(File.absolute_path(output_folder))

small_hotel_geom_files.keys.each { |template|

  building_story_map = {
    'BuildingStory1' => ['GuestRoom101', 'GuestRoom102', 'GuestRoom103', 'GuestRoom104', 'GuestRoom105', 'CorridorFlr1', 'ElevatorCoreFlr1', 'EmployeeLoungeFlr1', 'ExerciseCenterFlr1', 'FrontLoungeFlr1', 'FrontOfficeFlr1', 'FrontStairsFlr1', 'RearStairsFlr1', 'FrontStorageFlr1', 'RearStorageFlr1', 'LaundryRoomFlr1', 'MechanicalRoomFlr1', 'MeetingRoomFlr1', 'RestroomFlr1'],
    'BuildingStory2' => ['GuestRoom201', 'GuestRoom202_205', 'GuestRoom206_208', 'GuestRoom209_212', 'GuestRoom213', 'GuestRoom214', 'GuestRoom215_218', 'GuestRoom219', 'GuestRoom220_223', 'GuestRoom224', 'CorridorFlr2', 'FrontStairsFlr2', 'RearStairsFlr2', 'FrontStorageFlr2', 'RearStorageFlr2', 'ElevatorCoreFlr2'],
    'BuildingStory3' => ['GuestRoom301', 'GuestRoom302_305', 'GuestRoom306_308', 'GuestRoom309_312', 'GuestRoom313', 'GuestRoom314', 'GuestRoom315_318', 'GuestRoom319', 'GuestRoom320_323', 'GuestRoom324', 'CorridorFlr3', 'FrontStairsFlr3', 'RearStairsFlr3', 'FrontStorageFlr3', 'RearStorageFlr3', 'ElevatorCoreFlr3'],
    'BuildingStory4' => ['GuestRoom401', 'GuestRoom402_405', 'GuestRoom406_408', 'GuestRoom409_412', 'GuestRoom413', 'GuestRoom414', 'GuestRoom415_418', 'GuestRoom419', 'GuestRoom420_423', 'GuestRoom424', 'CorridorFlr4', 'FrontStairsFlr4', 'RearStairsFlr4', 'FrontStorageFlr4', 'RearStorageFlr4', 'ElevatorCoreFlr4']
  }

  # attic only applies to the two DOE vintages.
  if template == 'DOE Ref Pre-1980' || template == 'DOE Ref 1980-2004'
    building_story_map['AtticStory'] = ['Attic']
  end

  osm_infile_name = small_hotel_geom_files[template]
  puts "\tosm_infile_name: #{osm_infile_name}"
  model = BTAP::FileIO.safe_load_model(osm_infile_name)
  #remove existing building storey information
  model.getBuildingStorys.each {|iobj| iobj.remove}

  building_story_map.each do |building_story_name, space_names|
    stub_building_story = OpenStudio::Model::BuildingStory.new(model)
    stub_building_story.setName(building_story_name)

    space_names.each do |space_name|
      space = model.getSpaceByName(space_name)
      next if space.empty?
      space = space.get
      space.setBuildingStory(stub_building_story)
    end
  end
  osm_path = OpenStudio::Path.new("./output/#{osm_infile_name}")
  model.save(osm_path, true)
}
padmassun commented 7 years ago

Complete Addition 1 task: https://github.com/NREL/openstudio-standards/commit/362d689b018e0dcdef8cef074f099fd27e2f32af

padmassun commented 7 years ago

Code used to split and merge geometry and space-type mapping:

require 'json'
require 'fileutils'

geom_map = JSON.parse(File.read("./template_building_type_to_geometry_file.json"))
space_type_map_file = JSON.parse(File.read("./spacetype_to_space.json"))
output_folder = "./archetypes"
FileUtils.mkdir_p(File.absolute_path(output_folder))

geom_map.keys.each { |archetype|
  next if archetype == 'Office'
  out_json = {}
  out_json[archetype] = {}
  out_json[archetype]['geometry'] = geom_map[archetype]
  out_json[archetype]['space_map'] = space_type_map_file[archetype]
  File.open("#{output_folder}/#{archetype}.json", 'w'){|f| f.write(JSON.pretty_generate(out_json)) }
}
padmassun commented 7 years ago

The name of the space Office1_Mult4_Flr_1 seems to be wrong... the multiplier is 5 (programmed correctly), but space name states a multiplier of 4 image

padmassun commented 7 years ago

Need to eliminate the default option for space_type and geometry mapping

padmassun commented 7 years ago

Script used to eliminate default key:

require 'json'
require 'fileutils'

Dir.glob("./*.json") { |json_file|
  puts json_file
  json = JSON.parse(File.read(json_file))
  archetype = json.keys[0]
  puts archetype
  out_json = json
  all_templates = ['90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013','DOE Ref 1980-2004', 'DOE Ref Pre-1980', 'NECB 2011']
  all_templates.each { |template|
    unless json[archetype]["geometry"].has_key? template
      out_json[archetype]["geometry"][template] = json[archetype]["geometry"]["default"]
    end
    space_map_templates = []
    json[archetype]["space_map"].each { |item|
      item["template"].each { |tmpl8|
        space_map_templates << tmpl8
      }
    }
    unless space_map_templates.include?(template)
      json[archetype]["space_map"].each_with_index { |item , index|
        item["template"].each { |tmpl8|
          if tmpl8 == 'default'
            puts "\t#{item["template"]}"
            out_json[archetype]["space_map"][index]["template"] << template
          end
        }
      }
    end
  }
  json[archetype]["space_map"].each_with_index { |item , index|
    if item["template"].include?('default')
      out_json[archetype]["space_map"][index]["template"].delete('default')
    end
  }
  out_json[archetype]["geometry"].delete('default')
  FileUtils.mkdir_p(File.absolute_path("./output"))
  File.open("./output/#{archetype}.json", 'w'){|f| f.write(JSON.pretty_generate(out_json)) }
}
padmassun commented 7 years ago

Please see https://github.com/NREL/OpenStudio/issues/2681#issuecomment-313168566 regarding surface divide and intersection...

I am having issues running this measure on a geometry file... I have tried running test_necb_bldg_hospital to generate an osm file which was used to run this measure, and tried running delete_all_objs_except_geo.rb , Not all extra information was removed... Will attempt later on next week and try to resolve this issue...

padmassun commented 7 years ago

I will try (next week) to run this as using openstudio cli as an osw.

padmassun commented 7 years ago

All of the tasks has been completed except reviewing of whether the surfaces are intersected properly. There are some sketchup issues and the measurtes cannot be applied to the geometry file on openstudio (because there are no systems and constructions assigned to it...)

The NECB 2011 QAQC runs properly. There are no severe issues. I will put the reviewing of whether the surfaces are intersected properly on hold.

padmassun commented 7 years ago

The new geometry of this hospital has to be reviewed.

The NECB 2011 QAQC runs properly. There are no severe issues. I will put the reviewing of whether the surfaces are intersected properly on hold.