tbd 3.1.1 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/pull_request.yml +16 -0
- data/LICENSE.md +1 -1
- data/README.md +3 -7
- data/Rakefile +8 -7
- data/lib/measures/tbd/LICENSE.md +1 -1
- data/lib/measures/tbd/README.md +8 -0
- data/lib/measures/tbd/measure.rb +44 -2
- data/lib/measures/tbd/measure.xml +38 -29
- data/lib/measures/tbd/resources/geo.rb +56 -16
- data/lib/measures/tbd/resources/model.rb +0 -6
- data/lib/measures/tbd/resources/oslog.rb +17 -7
- data/lib/measures/tbd/resources/psi.rb +117 -10
- data/lib/measures/tbd/resources/tbd.rb +1 -1
- data/lib/measures/tbd/resources/ua.rb +36 -69
- data/lib/measures/tbd/resources/utils.rb +86 -28
- data/lib/measures/tbd/resources/version.rb +1 -1
- data/lib/measures/tbd/tests/tbd_tests.rb +117 -87
- data/lib/tbd/geo.rb +56 -16
- data/lib/tbd/psi.rb +117 -10
- data/lib/tbd/ua.rb +36 -69
- data/lib/tbd/version.rb +2 -2
- data/lib/tbd.rb +9 -9
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a5a9002ff406325bc226c157ed29ffc22ccb60ac46b9c6bf29358f04aa9d6a3
|
4
|
+
data.tar.gz: 60b0a52d46be3a91a2119cb5d3875826e7b278ca9ce78a230e9575263dbb4c89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df24c1565b802fd84c8f067d78662adf23d5fb2059145b6b22da98b8c06f70b49283ef7f28613e91c1258e3c7b865d17e81df93c2340aec431483597d8ddb847
|
7
|
+
data.tar.gz: 34ea2406564f08b36a54987ab08fd5d2cb24e49bfb02640169278f1138f65f36ac2c9279abb7e8be83e1c2aec4cca639b8735ab13f54f0470fe0a8470977be86
|
@@ -70,3 +70,19 @@ jobs:
|
|
70
70
|
docker exec -t test bundle update
|
71
71
|
docker exec -t test bundle exec rake
|
72
72
|
docker kill test
|
73
|
+
test_351x:
|
74
|
+
runs-on: ubuntu-22.04
|
75
|
+
steps:
|
76
|
+
- name: Check out repository
|
77
|
+
uses: actions/checkout@v2
|
78
|
+
- name: Run Tests
|
79
|
+
run: |
|
80
|
+
echo $(pwd)
|
81
|
+
echo $(ls)
|
82
|
+
docker pull nrel/openstudio:3.5.1
|
83
|
+
docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.5.1
|
84
|
+
docker exec -t test pwd
|
85
|
+
docker exec -t test ls
|
86
|
+
docker exec -t test bundle update
|
87
|
+
docker exec -t test bundle exec rake
|
88
|
+
docker kill test
|
data/LICENSE.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2020-
|
3
|
+
Copyright (c) 2020-2023 Denis Bourgeois & Dan Macumber
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -32,9 +32,7 @@ TBD is systematically tested against updated OpenStudio versions (since v3.0.0).
|
|
32
32
|
|
33
33
|
### Windows Installation
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
From the command line, check that the ruby installation returns the correct Ruby version:
|
35
|
+
Either install Ruby using the [RubyInstaller](https://rubyinstaller.org/downloads/archives/) for [Ruby 2.7.2 (x64)](https://github.com/oneclick/rubyinstaller2/releases/tag/RubyInstaller-2.7.2-1/rubyinstaller-2.7.2-1-x64.exe), or preferably under [WSL2](https://gist.github.com/brgix/0d968d8f32c41f13300dc6769414df79). Run the following steps if going down the _RubyInstaller_ route. From the command line, check that the ruby installation returns the correct Ruby version:
|
38
36
|
```
|
39
37
|
ruby -v
|
40
38
|
```
|
@@ -57,9 +55,6 @@ Verify your OpenStudio and Ruby configuration:
|
|
57
55
|
ruby -e "require 'openstudio'" -e "puts OpenStudio::Model::Model.new"
|
58
56
|
```
|
59
57
|
|
60
|
-
`git clone` the TBD repo, then run basic tests to ensure the measure operates properly (see end of this README).
|
61
|
-
|
62
|
-
|
63
58
|
### MacOS Installation
|
64
59
|
|
65
60
|
MacOS already comes with Ruby, but likely not the right Ruby version for the desired OpenStudio measure development [environment](https://github.com/NREL/OpenStudio/wiki/OpenStudio-SDK-Version-Compatibility-Matrix). Instructions here show how to install Ruby v2.7.2 alongside MacOS's own Ruby version. Although no longer officially supported, instructions for an OpenStudio v2.9.1 setup is described [here](https://github.com/rd2/tbd/blob/master/v291_MacOS.md).
|
@@ -117,8 +112,9 @@ cd ~/Documents/sandbox340
|
|
117
112
|
ruby -e "require 'openstudio'" -e "puts OpenStudio::Model::Model.new"
|
118
113
|
```
|
119
114
|
|
120
|
-
|
115
|
+
## Clone TBD
|
121
116
|
|
117
|
+
Once done with either the Windows or MacOS setup, install the latest version of _git_ (e.g. through Homebrew), then ```git clone``` the TBD repo, e.g. under "sandbox340". Run the basic tests below to ensure the measure operates as expected.
|
122
118
|
|
123
119
|
## Complete list of test commands
|
124
120
|
|
data/Rakefile
CHANGED
@@ -2,28 +2,29 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
5
|
-
|
5
|
+
t.rspec_opts = "--exclude-pattern \'spec/**/*suite_spec.rb\'"
|
6
6
|
end
|
7
7
|
|
8
8
|
task default: :spec
|
9
9
|
|
10
10
|
desc "Update Library Files"
|
11
11
|
task :libraries do
|
12
|
-
puts "Updating Library Files"
|
12
|
+
# puts "Updating Library Files"
|
13
13
|
|
14
14
|
require "fileutils"
|
15
15
|
|
16
16
|
libs = ["topolys", "osut", "oslg", "tbd"]
|
17
17
|
files = {}
|
18
|
-
|
18
|
+
|
19
19
|
$:.each do |path|
|
20
20
|
libs.each do |l|
|
21
21
|
next unless path.include?(l)
|
22
|
+
|
22
23
|
files[l] = Dir.glob(File.join(path, "#{l}/*.rb"))
|
23
24
|
files[l].delete_if { |f| f.include?("version.rb") } unless l == "topolys"
|
24
|
-
puts "#{l} lib files:"
|
25
|
-
files[l].each { |lf| puts "... #{lf}" }
|
26
|
-
puts
|
25
|
+
# puts "#{l} lib files:"
|
26
|
+
# files[l].each { |lf| puts "... #{lf}" }
|
27
|
+
# puts
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
@@ -38,7 +39,7 @@ end
|
|
38
39
|
|
39
40
|
desc "Update Measure"
|
40
41
|
task measure: [:libraries] do
|
41
|
-
puts "Updating Measure"
|
42
|
+
# puts "Updating Measure"
|
42
43
|
|
43
44
|
require "openstudio"
|
44
45
|
require "open3"
|
data/lib/measures/tbd/LICENSE.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2020-
|
3
|
+
Copyright (c) 2020-2023 Denis Bourgeois & Dan Macumber
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/lib/measures/tbd/README.md
CHANGED
@@ -27,6 +27,14 @@ For EnergyPlus simulations, leave CHECKED. For iterative exploration with Apply
|
|
27
27
|
**Required:** false,
|
28
28
|
**Model Dependent:** false
|
29
29
|
|
30
|
+
### Proximity tolerance (m)
|
31
|
+
Proximity tolerance (e.g. 0.100 m) between subsurface edges, e.g. between near-adjacent window jambs.
|
32
|
+
**Name:** sub_tol,
|
33
|
+
**Type:** Double,
|
34
|
+
**Units:** ,
|
35
|
+
**Required:** false,
|
36
|
+
**Model Dependent:** false
|
37
|
+
|
30
38
|
### Load 'tbd.json'
|
31
39
|
Loads existing 'tbd.json' file (under '/files'), may override 'default thermal bridge' set.
|
32
40
|
**Name:** load_tbd_json,
|
data/lib/measures/tbd/measure.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# MIT License
|
2
2
|
#
|
3
|
-
# Copyright (c) 2020-
|
3
|
+
# Copyright (c) 2020-2023 Denis Bourgeois & Dan Macumber
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -48,6 +48,15 @@ class TBDMeasure < OpenStudio::Measure::ModelMeasure
|
|
48
48
|
alter.setDefaultValue(true)
|
49
49
|
args << alter
|
50
50
|
|
51
|
+
arg = "sub_tol"
|
52
|
+
dsc = "Proximity tolerance (e.g. 0.100 m) between subsurface edges, e.g. " \
|
53
|
+
"between near-adjacent window jambs."
|
54
|
+
sub_tol = OpenStudio::Measure::OSArgument.makeDoubleArgument(arg, false)
|
55
|
+
sub_tol.setDisplayName("Proximity tolerance (m)")
|
56
|
+
sub_tol.setDescription(dsc)
|
57
|
+
sub_tol.setDefaultValue(TBD::TOL)
|
58
|
+
args << sub_tol
|
59
|
+
|
51
60
|
arg = "load_tbd_json"
|
52
61
|
dsc = "Loads existing 'tbd.json' file (under '/files'), may override " \
|
53
62
|
"'default thermal bridge' set."
|
@@ -225,6 +234,7 @@ class TBDMeasure < OpenStudio::Measure::ModelMeasure
|
|
225
234
|
|
226
235
|
argh = {}
|
227
236
|
argh[:alter ] = runner.getBoolArgumentValue("alter_model", args)
|
237
|
+
argh[:sub_tol ] = runner.getDoubleArgumentValue("sub_tol", args)
|
228
238
|
argh[:load_tbd ] = runner.getBoolArgumentValue("load_tbd_json", args)
|
229
239
|
argh[:option ] = runner.getStringArgumentValue("option", args)
|
230
240
|
argh[:write_tbd ] = runner.getBoolArgumentValue("write_tbd_json", args)
|
@@ -286,6 +296,38 @@ class TBDMeasure < OpenStudio::Measure::ModelMeasure
|
|
286
296
|
end
|
287
297
|
end
|
288
298
|
|
299
|
+
# Pre-validate ground-facing constructions for KIVA.
|
300
|
+
if argh[:kiva_force] || argh[:gen_kiva]
|
301
|
+
kva = true
|
302
|
+
|
303
|
+
mdl.getSurfaces.each do |s|
|
304
|
+
id = s.nameString
|
305
|
+
construction = s.construction
|
306
|
+
next unless s.isGroundSurface
|
307
|
+
|
308
|
+
if construction.empty?
|
309
|
+
runner.registerError("Invalid construction for KIVA (#{id})")
|
310
|
+
kva = false if kva
|
311
|
+
else
|
312
|
+
construction = construction.get.to_LayeredConstruction
|
313
|
+
|
314
|
+
if construction.empty?
|
315
|
+
runner.registerError("KIVA requires layered constructions (#{id})")
|
316
|
+
kva = false if kva
|
317
|
+
else
|
318
|
+
construction = construction.get
|
319
|
+
|
320
|
+
unless TBD.standardOpaqueLayers?(construction)
|
321
|
+
runner.registerError("KIVA requires standard materials (#{id})")
|
322
|
+
kva = false if kva
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
return false unless kva
|
329
|
+
end
|
330
|
+
|
289
331
|
# Process all ground-facing surfaces as foundation-facing.
|
290
332
|
if argh[:kiva_force]
|
291
333
|
argh[:gen_kiva] = true
|
@@ -313,7 +355,7 @@ class TBDMeasure < OpenStudio::Measure::ModelMeasure
|
|
313
355
|
|
314
356
|
argh[:version ] = model.getVersion.versionIdentifier
|
315
357
|
tbd = TBD.process(model, argh)
|
316
|
-
argh[:io ] = tbd[:io]
|
358
|
+
argh[:io ] = tbd[:io ]
|
317
359
|
argh[:surfaces] = tbd[:surfaces]
|
318
360
|
setpoints = TBD.heatingTemperatureSetpoints?(model)
|
319
361
|
setpoints = TBD.coolingTemperatureSetpoints?(model) || setpoints
|
@@ -3,8 +3,8 @@
|
|
3
3
|
<schema_version>3.0</schema_version>
|
4
4
|
<name>tbd_measure</name>
|
5
5
|
<uid>8890787b-8c25-4dc8-8641-b6be1b6c2357</uid>
|
6
|
-
<version_id>
|
7
|
-
<version_modified>
|
6
|
+
<version_id>2fc42e1d-2010-44ae-9837-6390512c41d4</version_id>
|
7
|
+
<version_modified>20230214T105829Z</version_modified>
|
8
8
|
<xml_checksum>99772807</xml_checksum>
|
9
9
|
<class_name>TBDMeasure</class_name>
|
10
10
|
<display_name>Thermal Bridging and Derating - TBD</display_name>
|
@@ -30,6 +30,15 @@
|
|
30
30
|
</choice>
|
31
31
|
</choices>
|
32
32
|
</argument>
|
33
|
+
<argument>
|
34
|
+
<name>sub_tol</name>
|
35
|
+
<display_name>Proximity tolerance (m)</display_name>
|
36
|
+
<description>Proximity tolerance (e.g. 0.100 m) between subsurface edges, e.g. between near-adjacent window jambs.</description>
|
37
|
+
<type>Double</type>
|
38
|
+
<required>false</required>
|
39
|
+
<model_dependent>false</model_dependent>
|
40
|
+
<default_value>0.01</default_value>
|
41
|
+
</argument>
|
33
42
|
<argument>
|
34
43
|
<name>load_tbd_json</name>
|
35
44
|
<display_name>Load 'tbd.json'</display_name>
|
@@ -373,12 +382,6 @@
|
|
373
382
|
<usage_type>doc</usage_type>
|
374
383
|
<checksum>32D70693</checksum>
|
375
384
|
</file>
|
376
|
-
<file>
|
377
|
-
<filename>LICENSE.md</filename>
|
378
|
-
<filetype>md</filetype>
|
379
|
-
<usage_type>license</usage_type>
|
380
|
-
<checksum>CB393A2B</checksum>
|
381
|
-
</file>
|
382
385
|
<file>
|
383
386
|
<filename>geometry.rb</filename>
|
384
387
|
<filetype>rb</filetype>
|
@@ -386,34 +389,28 @@
|
|
386
389
|
<checksum>D80E9AE6</checksum>
|
387
390
|
</file>
|
388
391
|
<file>
|
389
|
-
<filename>
|
390
|
-
<filetype>
|
391
|
-
<usage_type>
|
392
|
-
<checksum>
|
393
|
-
</file>
|
394
|
-
<file>
|
395
|
-
<filename>version.rb</filename>
|
396
|
-
<filetype>rb</filetype>
|
397
|
-
<usage_type>resource</usage_type>
|
398
|
-
<checksum>05CC939E</checksum>
|
392
|
+
<filename>LICENSE.md</filename>
|
393
|
+
<filetype>md</filetype>
|
394
|
+
<usage_type>license</usage_type>
|
395
|
+
<checksum>A91E64A0</checksum>
|
399
396
|
</file>
|
400
397
|
<file>
|
401
398
|
<filename>oslog.rb</filename>
|
402
399
|
<filetype>rb</filetype>
|
403
400
|
<usage_type>resource</usage_type>
|
404
|
-
<checksum>
|
401
|
+
<checksum>E97617E3</checksum>
|
405
402
|
</file>
|
406
403
|
<file>
|
407
404
|
<filename>tbd.rb</filename>
|
408
405
|
<filetype>rb</filetype>
|
409
406
|
<usage_type>resource</usage_type>
|
410
|
-
<checksum>
|
407
|
+
<checksum>A4E8433C</checksum>
|
411
408
|
</file>
|
412
409
|
<file>
|
413
410
|
<filename>utils.rb</filename>
|
414
411
|
<filetype>rb</filetype>
|
415
412
|
<usage_type>resource</usage_type>
|
416
|
-
<checksum>
|
413
|
+
<checksum>283C976C</checksum>
|
417
414
|
</file>
|
418
415
|
<file>
|
419
416
|
<version>
|
@@ -424,37 +421,49 @@
|
|
424
421
|
<filename>measure.rb</filename>
|
425
422
|
<filetype>rb</filetype>
|
426
423
|
<usage_type>script</usage_type>
|
427
|
-
<checksum>
|
424
|
+
<checksum>44B11139</checksum>
|
428
425
|
</file>
|
429
426
|
<file>
|
430
427
|
<filename>tbd_tests.rb</filename>
|
431
428
|
<filetype>rb</filetype>
|
432
429
|
<usage_type>test</usage_type>
|
433
|
-
<checksum>
|
430
|
+
<checksum>58ED6635</checksum>
|
431
|
+
</file>
|
432
|
+
<file>
|
433
|
+
<filename>geo.rb</filename>
|
434
|
+
<filetype>rb</filetype>
|
435
|
+
<usage_type>resource</usage_type>
|
436
|
+
<checksum>F447D8CE</checksum>
|
434
437
|
</file>
|
435
438
|
<file>
|
436
439
|
<filename>README.md</filename>
|
437
440
|
<filetype>md</filetype>
|
438
441
|
<usage_type>readme</usage_type>
|
439
|
-
<checksum>
|
442
|
+
<checksum>B836C43A</checksum>
|
440
443
|
</file>
|
441
444
|
<file>
|
442
|
-
<filename>
|
445
|
+
<filename>ua.rb</filename>
|
443
446
|
<filetype>rb</filetype>
|
444
447
|
<usage_type>resource</usage_type>
|
445
|
-
<checksum>
|
448
|
+
<checksum>19193778</checksum>
|
446
449
|
</file>
|
447
450
|
<file>
|
448
451
|
<filename>psi.rb</filename>
|
449
452
|
<filetype>rb</filetype>
|
450
453
|
<usage_type>resource</usage_type>
|
451
|
-
<checksum>
|
454
|
+
<checksum>1045EF38</checksum>
|
452
455
|
</file>
|
453
456
|
<file>
|
454
|
-
<filename>
|
457
|
+
<filename>model.rb</filename>
|
458
|
+
<filetype>rb</filetype>
|
459
|
+
<usage_type>resource</usage_type>
|
460
|
+
<checksum>8E9A76C7</checksum>
|
461
|
+
</file>
|
462
|
+
<file>
|
463
|
+
<filename>version.rb</filename>
|
455
464
|
<filetype>rb</filetype>
|
456
465
|
<usage_type>resource</usage_type>
|
457
|
-
<checksum>
|
466
|
+
<checksum>A3BB982A</checksum>
|
458
467
|
</file>
|
459
468
|
</files>
|
460
469
|
</measure>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# MIT License
|
2
2
|
#
|
3
|
-
# Copyright (c) 2020-
|
3
|
+
# Copyright (c) 2020-2023 Denis Bourgeois & Dan Macumber
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -22,24 +22,27 @@
|
|
22
22
|
|
23
23
|
module TBD
|
24
24
|
##
|
25
|
-
# Check for matching Topolys vertex pairs between edges
|
25
|
+
# Check for matching Topolys vertex pairs between edges.
|
26
26
|
#
|
27
27
|
# @param e1 [Hash] first edge
|
28
28
|
# @param e2 [Hash] second edge
|
29
|
+
# @param tol [Float] user-set tolerance (> TOL) in m
|
29
30
|
#
|
30
31
|
# @return [Bool] true if edges share vertex pairs
|
31
32
|
# @return [Bool] false if invalid input
|
32
|
-
def matches?(e1 = {}, e2 = {})
|
33
|
+
def matches?(e1 = {}, e2 = {}, tol = TOL)
|
33
34
|
mth = "TBD::#{__callee__}"
|
34
35
|
cl = Topolys::Point3D
|
35
36
|
a = false
|
36
37
|
|
37
38
|
return mismatch("e1", e1, Hash, mth, DBG, a) unless e1.is_a?(Hash)
|
38
39
|
return mismatch("e2", e2, Hash, mth, DBG, a) unless e2.is_a?(Hash)
|
40
|
+
|
39
41
|
return hashkey("e1", e1, :v0, mth, DBG, a) unless e1.key?(:v0)
|
40
42
|
return hashkey("e1", e1, :v1, mth, DBG, a) unless e1.key?(:v1)
|
41
43
|
return hashkey("e2", e2, :v0, mth, DBG, a) unless e2.key?(:v0)
|
42
44
|
return hashkey("e2", e2, :v1, mth, DBG, a) unless e2.key?(:v1)
|
45
|
+
|
43
46
|
return mismatch("e1 :v0", e1[:v0], cl, mth, DBG, a) unless e1[:v0].is_a?(cl)
|
44
47
|
return mismatch("e1 :v1", e1[:v1], cl, mth, DBG, a) unless e1[:v1].is_a?(cl)
|
45
48
|
return mismatch("e2 :v0", e2[:v0], cl, mth, DBG, a) unless e2[:v0].is_a?(cl)
|
@@ -51,26 +54,29 @@ module TBD
|
|
51
54
|
return zero("e1", mth, DBG, a) if e1_vector.magnitude < TOL
|
52
55
|
return zero("e2", mth, DBG, a) if e2_vector.magnitude < TOL
|
53
56
|
|
57
|
+
return mismatch("e1", e1, Hash, mth, DBG, a) unless tol.is_a?(Numeric)
|
58
|
+
return zero("tol", mth, DBG, a) if tol < TOL
|
59
|
+
|
54
60
|
return true if
|
55
61
|
(
|
56
62
|
(
|
57
|
-
( (e1[:v0].x - e2[:v0].x).abs <
|
58
|
-
(e1[:v0].y - e2[:v0].y).abs <
|
59
|
-
(e1[:v0].z - e2[:v0].z).abs <
|
63
|
+
( (e1[:v0].x - e2[:v0].x).abs < tol &&
|
64
|
+
(e1[:v0].y - e2[:v0].y).abs < tol &&
|
65
|
+
(e1[:v0].z - e2[:v0].z).abs < tol
|
60
66
|
) ||
|
61
|
-
( (e1[:v0].x - e2[:v1].x).abs <
|
62
|
-
(e1[:v0].y - e2[:v1].y).abs <
|
63
|
-
(e1[:v0].z - e2[:v1].z).abs <
|
67
|
+
( (e1[:v0].x - e2[:v1].x).abs < tol &&
|
68
|
+
(e1[:v0].y - e2[:v1].y).abs < tol &&
|
69
|
+
(e1[:v0].z - e2[:v1].z).abs < tol
|
64
70
|
)
|
65
71
|
) &&
|
66
72
|
(
|
67
|
-
( (e1[:v1].x - e2[:v0].x).abs <
|
68
|
-
(e1[:v1].y - e2[:v0].y).abs <
|
69
|
-
(e1[:v1].z - e2[:v0].z).abs <
|
73
|
+
( (e1[:v1].x - e2[:v0].x).abs < tol &&
|
74
|
+
(e1[:v1].y - e2[:v0].y).abs < tol &&
|
75
|
+
(e1[:v1].z - e2[:v0].z).abs < tol
|
70
76
|
) ||
|
71
|
-
( (e1[:v1].x - e2[:v1].x).abs <
|
72
|
-
(e1[:v1].y - e2[:v1].y).abs <
|
73
|
-
(e1[:v1].z - e2[:v1].z).abs <
|
77
|
+
( (e1[:v1].x - e2[:v1].x).abs < tol &&
|
78
|
+
(e1[:v1].y - e2[:v1].y).abs < tol &&
|
79
|
+
(e1[:v1].z - e2[:v1].z).abs < tol
|
74
80
|
)
|
75
81
|
)
|
76
82
|
)
|
@@ -354,6 +360,7 @@ module TBD
|
|
354
360
|
next unless valid
|
355
361
|
vec = s.vertices
|
356
362
|
area = s.grossArea
|
363
|
+
mult = s.multiplier
|
357
364
|
typ = s.subSurfaceType.downcase
|
358
365
|
type = :skylight
|
359
366
|
type = :window if typ.include?("window" )
|
@@ -442,6 +449,7 @@ module TBD
|
|
442
449
|
n: n,
|
443
450
|
gross: s.grossArea,
|
444
451
|
area: area,
|
452
|
+
mult: mult,
|
445
453
|
type: type,
|
446
454
|
u: u,
|
447
455
|
unhinged: unhinged }
|
@@ -478,7 +486,9 @@ module TBD
|
|
478
486
|
end
|
479
487
|
|
480
488
|
subarea = 0
|
481
|
-
|
489
|
+
|
490
|
+
subs.values.each { |sub| subarea += sub[:area] * sub[:mult] }
|
491
|
+
|
482
492
|
surf[:net] = surf[:gross] - subarea
|
483
493
|
|
484
494
|
# Tranform final Point 3D sets, and store.
|
@@ -604,6 +614,36 @@ module TBD
|
|
604
614
|
return mismatch("floors", floors, cl2, mth, DBG, a) unless floors.is_a?(cl2)
|
605
615
|
return mismatch("edges", edges, cl2, mth, DBG, a) unless edges.is_a?(cl2)
|
606
616
|
|
617
|
+
kva = true
|
618
|
+
|
619
|
+
# Pre-validate foundation-facing constructions.
|
620
|
+
model.getSurfaces.each do |s|
|
621
|
+
id = s.nameString
|
622
|
+
construction = s.construction
|
623
|
+
next unless s.outsideBoundaryCondition.downcase == "foundation"
|
624
|
+
|
625
|
+
if construction.empty?
|
626
|
+
log(ERR, "Invalid construction for KIVA (see #{id})")
|
627
|
+
kva = false if kva
|
628
|
+
else
|
629
|
+
construction = construction.get.to_LayeredConstruction
|
630
|
+
|
631
|
+
if construction.empty?
|
632
|
+
log(ERR, "KIVA requires layered constructions (see #{id})")
|
633
|
+
kva = false if kva
|
634
|
+
else
|
635
|
+
construction = construction.get
|
636
|
+
|
637
|
+
unless standardOpaqueLayers?(construction)
|
638
|
+
log(ERR, "KIVA requires standard materials (see #{id})")
|
639
|
+
kva = false if kva
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
return a unless kva
|
646
|
+
|
607
647
|
# Strictly relying on Kiva's total exposed perimeter approach.
|
608
648
|
arg = "TotalExposedPerimeter"
|
609
649
|
kiva = true
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# BSD 3-Clause License
|
2
2
|
#
|
3
|
-
# Copyright (c) 2022, Denis Bourgeois
|
3
|
+
# Copyright (c) 2022-2023, Denis Bourgeois
|
4
4
|
# All rights reserved.
|
5
5
|
#
|
6
6
|
# Redistribution and use in source and binary forms, with or without
|
@@ -127,6 +127,7 @@ module OSlg
|
|
127
127
|
# @return [String] "DEBUG", "INFO", "WARN", "ERROR" or "FATAL"
|
128
128
|
def tag(level)
|
129
129
|
return @@tag[level] if level >= DEBUG && level <= FATAL
|
130
|
+
|
130
131
|
""
|
131
132
|
end
|
132
133
|
|
@@ -138,6 +139,7 @@ module OSlg
|
|
138
139
|
# @return [String] preset OSlg message
|
139
140
|
def msg(status)
|
140
141
|
return @@msg[status] if status >= DEBUG && status <= FATAL
|
142
|
+
|
141
143
|
""
|
142
144
|
end
|
143
145
|
|
@@ -163,6 +165,7 @@ module OSlg
|
|
163
165
|
@@logs << {level: level, message: message}
|
164
166
|
@@status = level if level > @@status
|
165
167
|
end
|
168
|
+
|
166
169
|
@@status
|
167
170
|
end
|
168
171
|
|
@@ -194,10 +197,11 @@ module OSlg
|
|
194
197
|
mth = mth[0...60] + " ..." if mth.length > 60
|
195
198
|
return res if mth.empty?
|
196
199
|
|
197
|
-
msg
|
200
|
+
msg = "Invalid '#{id}' "
|
198
201
|
msg += "arg ##{ord} " if ord > 0
|
199
202
|
msg += "(#{mth})"
|
200
203
|
log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
|
204
|
+
|
201
205
|
res
|
202
206
|
end
|
203
207
|
|
@@ -232,6 +236,7 @@ module OSlg
|
|
232
236
|
|
233
237
|
msg = "'#{id}' #{obj.class}? expecting #{cl} (#{mth})"
|
234
238
|
log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
|
239
|
+
|
235
240
|
res
|
236
241
|
end
|
237
242
|
|
@@ -264,8 +269,9 @@ module OSlg
|
|
264
269
|
mth = mth[0...60] + " ..." if mth.length > 60
|
265
270
|
return res if mth.empty?
|
266
271
|
|
267
|
-
msg
|
272
|
+
msg = "Missing '#{key}' key in '#{id}' Hash (#{mth})"
|
268
273
|
log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
|
274
|
+
|
269
275
|
res
|
270
276
|
end
|
271
277
|
|
@@ -294,8 +300,9 @@ module OSlg
|
|
294
300
|
mth = mth[0...60] + " ..." if mth.length > 60
|
295
301
|
return res if mth.empty?
|
296
302
|
|
297
|
-
msg
|
303
|
+
msg = "Empty '#{id}' (#{mth})"
|
298
304
|
log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
|
305
|
+
|
299
306
|
res
|
300
307
|
end
|
301
308
|
|
@@ -325,8 +332,9 @@ module OSlg
|
|
325
332
|
mth = mth[0...60] + " ..." if mth.length > 60
|
326
333
|
return res if mth.empty?
|
327
334
|
|
328
|
-
msg
|
335
|
+
msg = "Zero '#{id}' (#{mth})"
|
329
336
|
log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
|
337
|
+
|
330
338
|
res
|
331
339
|
end
|
332
340
|
|
@@ -355,9 +363,10 @@ module OSlg
|
|
355
363
|
|
356
364
|
mth = mth[0...60] + " ..." if mth.length > 60
|
357
365
|
return res if mth.empty?
|
358
|
-
|
359
|
-
msg
|
366
|
+
|
367
|
+
msg = "Negative '#{id}' (#{mth})"
|
360
368
|
log(lvl, msg) if lvl >= DEBUG && lvl <= FATAL
|
369
|
+
|
361
370
|
res
|
362
371
|
end
|
363
372
|
|
@@ -368,6 +377,7 @@ module OSlg
|
|
368
377
|
def clean!
|
369
378
|
@@status = 0
|
370
379
|
@@logs = []
|
380
|
+
|
371
381
|
@@level
|
372
382
|
end
|
373
383
|
|