structuraid_core 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -6
  3. data/lib/structuraid_core/design_codes/aci_318_19/rc/footings/bending_reinforcement_ratio.rb +65 -0
  4. data/lib/structuraid_core/design_codes/aci_318_19/rc/footings/one_way_shear_capacity.rb +29 -0
  5. data/lib/structuraid_core/design_codes/aci_318_19/rc/footings/punching_critical_section_perimeter.rb +105 -0
  6. data/lib/structuraid_core/design_codes/aci_318_19/rc/minimum_steel_cover.rb +55 -0
  7. data/lib/structuraid_core/design_codes/aci_318_19/rc/reduction_factor.rb +88 -0
  8. data/lib/structuraid_core/design_codes/nsr_10/rc/footings/bending_reinforcement_ratio.rb +66 -0
  9. data/lib/structuraid_core/design_codes/nsr_10/rc/footings/one_way_shear_capacity.rb +31 -0
  10. data/lib/structuraid_core/design_codes/nsr_10/rc/footings/punching_critical_section_perimeter.rb +103 -0
  11. data/lib/structuraid_core/design_codes/nsr_10/rc/minimum_steel_cover.rb +57 -0
  12. data/lib/structuraid_core/design_codes/nsr_10/rc/reduction_factor.rb +82 -0
  13. data/lib/structuraid_core/design_codes/schemas/rc/footings/bending_reinforcement_ratio_schema.rb +24 -0
  14. data/lib/structuraid_core/design_codes/schemas/rc/footings/one_way_shear_capacity_schema.rb +22 -0
  15. data/lib/structuraid_core/design_codes/schemas/rc/footings/punching_critical_section_perimeter_schema.rb +23 -0
  16. data/lib/structuraid_core/design_codes/schemas/rc/minimum_steel_cover_schema.rb +32 -0
  17. data/lib/structuraid_core/design_codes/schemas/rc/reduction_factor_schema.rb +17 -0
  18. data/lib/structuraid_core/design_codes/utils/schema_definition.rb +38 -9
  19. data/lib/structuraid_core/elements/column/rectangular.rb +5 -4
  20. data/lib/structuraid_core/elements/footing.rb +37 -1
  21. data/lib/structuraid_core/engineering/analysis/footing/base.rb +17 -0
  22. data/lib/structuraid_core/engineering/analysis/footing/centric_combined_two_columns.rb +99 -0
  23. data/lib/structuraid_core/engineering/analysis/footing/centric_isolated.rb +1 -1
  24. data/lib/structuraid_core/engineering/analysis/footing/utils/basic_geometry.rb +36 -0
  25. data/lib/structuraid_core/engineering/analysis/footing/utils/centroid.rb +33 -0
  26. data/lib/structuraid_core/engineering/analysis/footing/utils/one_way_moment.rb +63 -0
  27. data/lib/structuraid_core/engineering/analysis/footing/utils/one_way_shear.rb +46 -0
  28. data/lib/structuraid_core/engineering/base.rb +1 -1
  29. data/lib/structuraid_core/engineering/locations/absolute.rb +4 -0
  30. data/lib/structuraid_core/engineering/locations/base.rb +1 -0
  31. data/lib/structuraid_core/engineering/locations/collection.rb +51 -0
  32. data/lib/structuraid_core/engineering/locations/coordinates_system.rb +19 -4
  33. data/lib/structuraid_core/engineering/locations/relative.rb +17 -4
  34. data/lib/structuraid_core/errors/engineering/locations/duplicate_label_error.rb +13 -0
  35. data/lib/structuraid_core/loads/point_load.rb +3 -2
  36. data/lib/structuraid_core/version.rb +1 -1
  37. metadata +25 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6a3c25bdfad6f0af2c266ad01cf0321e74780e4366a9a0b941e37c108f6d152
4
- data.tar.gz: 60afe6f91b70f5acd7ac3d12b1e0c33282afed9620f2c55ee2c29ada6fe3295f
3
+ metadata.gz: 39b0943343ece08b91c2884a16e133ad77e663c71c8416db4d65248a20871b67
4
+ data.tar.gz: e9ead6c46af568fd4f7d7fda9cfdd73996f93cff85afdf602161b01caef091f7
5
5
  SHA512:
6
- metadata.gz: fc6983c21cb7278bb90e9b2b3d4a68e6c873e1fd7de57205724344385200e4674c05fceb61c02342a4329c5ce1515636c614ec8c55d5dba6952f08cd595a309b
7
- data.tar.gz: da91f2acb4102987f40c8d05b314727349782e0ac170859423460e131aa6b5793c4761066c583b0c6836d1db0392f47b574911faf75368fef61ebf4b4485497e
6
+ metadata.gz: b48678b5b1131cf438cfaf5db1d8c2dac8ba1dc89c2d8ee77f580b7c1386f64c7081fbdd1980c7ea6d8373e93fccb7b414bc4555a1ce4c64461e83e1fd40f780
7
+ data.tar.gz: d986996199861f01fa6d495bf13b87119d0039d9b23146e545da8e063aab47c8b6ef199a3c232e80a569f0350aec37dcfad856557217830b13a0abdac162ade2
data/.rubocop.yml CHANGED
@@ -25,12 +25,6 @@ RSpec/MultipleMemoizedHelpers:
25
25
  RSpec/NestedGroups:
26
26
  Enabled: false
27
27
 
28
- RSpec/ContainExactly:
29
- Enabled: false
30
-
31
- RSpec/MatchArray:
32
- Enabled: false
33
-
34
28
  Lint/MissingSuper:
35
29
  Enabled: false
36
30
 
@@ -0,0 +1,65 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module ACI31819
4
+ module RC
5
+ module Footings
6
+ class BendingReinforcementRatio
7
+ MINIMUM_RATIO = 0.0025
8
+ CODE_REFERENCE = 'ACI 318-19'.freeze
9
+
10
+ include DesignCodes::Utils::CodeRequirement
11
+ use_schema DesignCodes::Schemas::RC::Footings::BendingReinforcementRatioSchema
12
+
13
+ def call
14
+ [
15
+ solve_cuadratic_equation_for_steel_reinforcement_ratio,
16
+ MINIMUM_RATIO
17
+ ].max
18
+ end
19
+
20
+ private
21
+
22
+ ## the target is to solve [(1 - sqrt(1 - 4ac))/2a, (1 + sqrt(1 - 4ac))/2a]
23
+
24
+ def solve_cuadratic_equation_for_steel_reinforcement_ratio
25
+ [
26
+ equation_solver_option_1.negative? ? Float::INFINITY : equation_solver_option_1,
27
+ equation_solver_option_2
28
+ ].min
29
+ end
30
+
31
+ def equation_solver_option_1
32
+ (1 - equation_component_root) / (2 * equation_component_a)
33
+ end
34
+
35
+ def equation_solver_option_2
36
+ (1 + equation_component_root) / (2 * equation_component_a)
37
+ end
38
+
39
+ def equation_component_a
40
+ 0.59 * design_steel_yield_strength / design_compression_strength
41
+ end
42
+
43
+ def equation_component_c
44
+ section_area = width * effective_height # mm**2
45
+ reduced_steel_strength = capacity_reduction_factor * design_steel_yield_strength # N/(mm**2)
46
+ flexural_moment / (reduced_steel_strength * section_area * effective_height) # N/(mm**2)
47
+ end
48
+
49
+ def equation_component_root
50
+ unless 4 * equation_component_a * equation_component_c < 1
51
+ raise RequirementNotFulfilledError.new(
52
+ :flexural_moment,
53
+ "Moment #{flexural_moment} is too hight for this element",
54
+ CODE_REFERENCE
55
+ )
56
+ end
57
+
58
+ Math.sqrt(1 - 4 * equation_component_a * equation_component_c)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,29 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module ACI31819
4
+ module RC
5
+ module Footings
6
+ class OneWayShearCapacity
7
+ CODE_REFERENCE = 'ACI 318-19'.freeze
8
+
9
+ include DesignCodes::Utils::CodeRequirement
10
+ use_schema DesignCodes::Schemas::RC::Footings::OneWayShearCapacitySchema
11
+
12
+ def call
13
+ compute_concrete_shear_capacity
14
+ end
15
+
16
+ private
17
+
18
+ def compute_concrete_shear_capacity
19
+ effective_area = effective_height * width
20
+ concrete_strength = light_concrete_modification_factor * Math.sqrt(design_compression_strength)
21
+
22
+ 0.17 * concrete_strength * effective_area
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,105 @@
1
+ require 'byebug'
2
+
3
+ module StructuraidCore
4
+ module DesignCodes
5
+ module ACI31819
6
+ module RC
7
+ module Footings
8
+ class PunchingCriticalSectionPerimeter
9
+ include DesignCodes::Utils::CodeRequirement
10
+ use_schema DesignCodes::Schemas::RC::Footings::PunchingCriticalSectionPerimeterSchema
11
+
12
+ EDGES_INDEXES = {
13
+ top: { from: :top_right, to: :top_left },
14
+ left: { from: :top_left, to: :bottom_left },
15
+ bottom: { from: :bottom_left, to: :bottom_right },
16
+ right: { from: :bottom_right, to: :top_right }
17
+ }.freeze
18
+
19
+ def call
20
+ column_location = footing.find_or_add_column_location(column_absolute_location, column_label)
21
+ perimeter_vertices = build_initial_perimeter(column_location)
22
+
23
+ edges_indexes = EDGES_INDEXES
24
+ edges_indexes = select_edges_indexes_into_the_footing(edges_indexes, perimeter_vertices)
25
+ edges_indexes = update_edges_indexes_vertices(edges_indexes, perimeter_vertices)
26
+ compute_perimeter(edges_indexes, perimeter_vertices)
27
+ end
28
+
29
+ private
30
+
31
+ def update_edges_indexes_vertices(edges_indexes, perimeter_vertices)
32
+ edges_indexes.each do |_edge_name, edge|
33
+ update_location_to_limit(perimeter_vertices[edge[:from]])
34
+ update_location_to_limit(perimeter_vertices[edge[:to]])
35
+ end
36
+ end
37
+
38
+ def select_edges_indexes_into_the_footing(edges_indexes, perimeter_vertices)
39
+ edges_indexes.select do |_edge_name, edge|
40
+ start_vertex_inside_footing = footing.inside_me?(perimeter_vertices[edge[:from]])
41
+ end_vertex_inside_footing = footing.inside_me?(perimeter_vertices[edge[:to]])
42
+
43
+ start_vertex_inside_footing || end_vertex_inside_footing
44
+ end
45
+ end
46
+
47
+ def build_initial_perimeter(column_location)
48
+ perimeter_vertices_relative_to_column_location.map do |label, perimeter_vertex|
49
+ location = local_coordinates_system.find_or_add_location_from_vector(
50
+ perimeter_vertex + column_location.to_vector,
51
+ label: "column_#{column_label}_punching_#{label}"
52
+ )
53
+ [label, location]
54
+ end.to_h
55
+ end
56
+
57
+ def update_location_to_limit(location)
58
+ location.value_1 = update_to_constraint(location.value_1, 0.5 * footing.length_1)
59
+ location.value_2 = update_to_constraint(location.value_2, 0.5 * footing.length_2)
60
+ end
61
+
62
+ def update_to_constraint(initial_value, constraint_value)
63
+ if initial_value > constraint_value
64
+ constraint_value
65
+ elsif initial_value < -constraint_value
66
+ -constraint_value
67
+ else
68
+ initial_value
69
+ end
70
+ end
71
+
72
+ def perimeter_vertices_relative_to_column_location
73
+ {
74
+ top_right: perimeter_vertices_relative_to_column_location_with(way_1: 1, way_2: 1),
75
+ top_left: perimeter_vertices_relative_to_column_location_with(way_1: -1, way_2: 1),
76
+ bottom_left: perimeter_vertices_relative_to_column_location_with(way_1: -1, way_2: -1),
77
+ bottom_right: perimeter_vertices_relative_to_column_location_with(way_1: 1, way_2: -1)
78
+ }
79
+ end
80
+
81
+ def perimeter_vertices_relative_to_column_location_with(way_1:, way_2:)
82
+ Vector[
83
+ way_1 * 0.5 * (column_section_length_1 + footing.effective_height),
84
+ way_2 * 0.5 * (column_section_length_2 + footing.effective_height),
85
+ 0.0
86
+ ]
87
+ end
88
+
89
+ def local_coordinates_system
90
+ footing.coordinates_system
91
+ end
92
+
93
+ def compute_perimeter(edges_indexes, perimeter_vertices)
94
+ edges_indexes.map do |_edge_name, edge|
95
+ vector_from = perimeter_vertices[edge[:from]].to_vector
96
+ vector_to = perimeter_vertices[edge[:to]].to_vector
97
+ (vector_to - vector_from).magnitude
98
+ end.sum
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,55 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module ACI31819
4
+ module RC
5
+ class MinimumSteelCover
6
+ include DesignCodes::Utils::CodeRequirement
7
+ use_schema DesignCodes::Schemas::RC::MinimumSteelCoverSchema
8
+
9
+ CODE_REFERENCE = 'ACI 318-19 21.5.1.3.1'.freeze
10
+
11
+ def call
12
+ compute_cover
13
+ end
14
+
15
+ private
16
+
17
+ # Table 20.5.1.3.1
18
+ def compute_cover
19
+ return 75 if concrete_casting_against_soil
20
+ return expossed_to_environment_or_soil if !concrete_casting_against_soil && environment_exposure
21
+ return 50 unless structural_element
22
+
23
+ non_expossed_to_environment_or_soil
24
+ end
25
+
26
+ def expossed_to_environment_or_soil
27
+ return 40 if maximum_rebar_diameter&.<= 16
28
+
29
+ 50
30
+ end
31
+
32
+ def non_expossed_to_environment_or_soil
33
+ if %i[slab wall joist].include?(structural_element)
34
+ slab_wall_joist_minimum_cover
35
+ elsif %i[beam column tensor_joint pedestal].include?(structural_element)
36
+ 40
37
+ end
38
+ end
39
+
40
+ def slab_wall_joist_minimum_cover
41
+ return 20 if maximum_rebar_diameter&.<= 36
42
+
43
+ 40
44
+ end
45
+
46
+ def shell_minimum_cover
47
+ return 13 if maximum_rebar_diameter&.<= 16
48
+
49
+ 20
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,88 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module ACI31819
4
+ module RC
5
+ class ReductionFactor
6
+ include DesignCodes::Utils::CodeRequirement
7
+ use_schema DesignCodes::Schemas::RC::ReductionFactorSchema
8
+
9
+ CONTROL_STRENGTH_CASES = %i[
10
+ compression_controlled
11
+ tension_controlled
12
+ transition_controlled
13
+ crushing_controlled
14
+ shear_nonseismic_controlled
15
+ torsion_controlled
16
+ corbel_bracket_controlled
17
+ strud_and_tie_controlled
18
+ ].freeze
19
+
20
+ MAX_STRAIN_BEFORE_TRANSITION = 0.002 # 21.2.2.1 - 21.2.2.2
21
+ MIN_STRAIN_AFTER_TRANSITION = 0.005 # 21.2.2.1 - 21.2.2.2
22
+
23
+ CODE_REFERENCE = 'ACI 318-19 21.2'.freeze
24
+
25
+ # ACI 318-19 21.2
26
+ def call
27
+ unless CONTROL_STRENGTH_CASES.include?(strength_controlling_behaviour)
28
+ raise UnrecognizedValueError.new(strength_controlling_behaviour, :strength_controlling_behaviour)
29
+ end
30
+
31
+ # Table 21.2.1 (a) (h)
32
+ return tension_controlled_factor if strength_controlling_behaviour == :tension_controlled
33
+ # Table 21.2.1 (a)
34
+ return compression_controlled_factor if strength_controlling_behaviour == :compression_controlled
35
+ # Table 21.2.1 (d)
36
+ return crushing_controlled_factor if strength_controlling_behaviour == :crushing_controlled
37
+ # Table 21.2.1 (b) (c) (f) (g)
38
+ if %i[
39
+ shear_nonseismic_controlled
40
+ torsion_controlled
41
+ corbel_bracket_controlled
42
+ strud_and_tie_controlled
43
+ ].include?(strength_controlling_behaviour)
44
+ return shear_nonseismic_controlled_factor
45
+ end
46
+
47
+ # Table 21.2.1 (a)
48
+ transition_controlled_factor
49
+ end
50
+
51
+ private
52
+
53
+ def shear_nonseismic_controlled_factor
54
+ 0.75
55
+ end
56
+
57
+ def crushing_controlled_factor
58
+ 0.65
59
+ end
60
+
61
+ def tension_controlled_factor
62
+ 0.90
63
+ end
64
+
65
+ def compression_controlled_factor
66
+ return 0.75 if is_coil_rebar
67
+
68
+ 0.65
69
+ end
70
+
71
+ def transition_controlled_factor
72
+ raise MissingParamError, :strain unless strain
73
+
74
+ transition_controlled_by_strain
75
+ end
76
+
77
+ def transition_controlled_by_strain
78
+ return compression_controlled_factor if strain < MAX_STRAIN_BEFORE_TRANSITION
79
+ return tension_controlled_factor if strain > MIN_STRAIN_AFTER_TRANSITION
80
+
81
+ transition_rate = is_coil_rebar ? 50 : 250 / 3
82
+ compression_controlled_factor + (strain - MAX_STRAIN_BEFORE_TRANSITION) * transition_rate
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,66 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module NSR10
4
+ module RC
5
+ module Footings
6
+ class BendingReinforcementRatio
7
+ MINIMUM_RATIO = 0.0025
8
+ CODE_REFERENCE = 'NSR-10 C.15'.freeze
9
+
10
+ include DesignCodes::Utils::CodeRequirement
11
+ use_schema DesignCodes::Schemas::RC::Footings::BendingReinforcementRatioSchema
12
+
13
+ # NSR-10 C.15
14
+ def call
15
+ [
16
+ solve_cuadratic_equation_for_steel_reinforcement_ratio,
17
+ MINIMUM_RATIO
18
+ ].max
19
+ end
20
+
21
+ private
22
+
23
+ ## the target is to solve [(1 - sqrt(1 - 4ac))/2a, (1 + sqrt(1 - 4ac))/2a]
24
+
25
+ def solve_cuadratic_equation_for_steel_reinforcement_ratio
26
+ [
27
+ equation_solver_option_1.negative? ? Float::INFINITY : equation_solver_option_1,
28
+ equation_solver_option_2
29
+ ].min
30
+ end
31
+
32
+ def equation_solver_option_1
33
+ (1 - equation_component_root) / (2 * equation_component_a)
34
+ end
35
+
36
+ def equation_solver_option_2
37
+ (1 + equation_component_root) / (2 * equation_component_a)
38
+ end
39
+
40
+ def equation_component_a
41
+ 0.59 * design_steel_yield_strength / design_compression_strength
42
+ end
43
+
44
+ def equation_component_c
45
+ section_area = width * effective_height # mm**2
46
+ reduced_steel_strength = capacity_reduction_factor * design_steel_yield_strength # N/(mm**2)
47
+ flexural_moment / (reduced_steel_strength * section_area * effective_height) # N/(mm**2)
48
+ end
49
+
50
+ def equation_component_root
51
+ unless 4 * equation_component_a * equation_component_c < 1
52
+ raise RequirementNotFulfilledError.new(
53
+ :flexural_moment,
54
+ "Moment #{flexural_moment} is too hight for this element",
55
+ CODE_REFERENCE
56
+ )
57
+ end
58
+
59
+ Math.sqrt(1 - 4 * equation_component_a * equation_component_c)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,31 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module NSR10
4
+ module RC
5
+ module Footings
6
+ class OneWayShearCapacity
7
+ CODE_REFERENCE = 'NSR-10 C.11.11'.freeze
8
+
9
+ include DesignCodes::Utils::CodeRequirement
10
+ use_schema DesignCodes::Schemas::RC::Footings::OneWayShearCapacitySchema
11
+
12
+ # NSR-10 C.11.11
13
+
14
+ def call
15
+ compute_concrete_shear_capacity
16
+ end
17
+
18
+ private
19
+
20
+ def compute_concrete_shear_capacity
21
+ effective_area = effective_height * width
22
+ concrete_strength = light_concrete_modification_factor * Math.sqrt(design_compression_strength)
23
+
24
+ 0.17 * concrete_strength * effective_area
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,103 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module NSR10
4
+ module RC
5
+ module Footings
6
+ class PunchingCriticalSectionPerimeter
7
+ include DesignCodes::Utils::CodeRequirement
8
+ use_schema DesignCodes::Schemas::RC::Footings::PunchingCriticalSectionPerimeterSchema
9
+
10
+ EDGES_INDEXES = {
11
+ top: { from: :top_right, to: :top_left },
12
+ left: { from: :top_left, to: :bottom_left },
13
+ bottom: { from: :bottom_left, to: :bottom_right },
14
+ right: { from: :bottom_right, to: :top_right }
15
+ }.freeze
16
+
17
+ def call
18
+ column_location = footing.find_or_add_column_location(column_absolute_location, column_label)
19
+ perimeter_vertices = build_initial_perimeter(column_location)
20
+
21
+ edges_indexes = EDGES_INDEXES
22
+ edges_indexes = select_edges_indexes_into_the_footing(edges_indexes, perimeter_vertices)
23
+ edges_indexes = update_edges_indexes_vertices(edges_indexes, perimeter_vertices)
24
+ compute_perimeter(edges_indexes, perimeter_vertices)
25
+ end
26
+
27
+ private
28
+
29
+ def update_edges_indexes_vertices(edges_indexes, perimeter_vertices)
30
+ edges_indexes.each do |_edge_name, edge|
31
+ update_location_to_limit(perimeter_vertices[edge[:from]])
32
+ update_location_to_limit(perimeter_vertices[edge[:to]])
33
+ end
34
+ end
35
+
36
+ def select_edges_indexes_into_the_footing(edges_indexes, perimeter_vertices)
37
+ edges_indexes.select do |_edge_name, edge|
38
+ start_vertex_inside_footing = footing.inside_me?(perimeter_vertices[edge[:from]])
39
+ end_vertex_inside_footing = footing.inside_me?(perimeter_vertices[edge[:to]])
40
+
41
+ start_vertex_inside_footing || end_vertex_inside_footing
42
+ end
43
+ end
44
+
45
+ def build_initial_perimeter(column_location)
46
+ perimeter_vertices_relative_to_column_location.map do |label, perimeter_vertex|
47
+ location = local_coordinates_system.find_or_add_location_from_vector(
48
+ perimeter_vertex + column_location.to_vector,
49
+ label: "column_#{column_label}_punching_#{label}"
50
+ )
51
+ [label, location]
52
+ end.to_h
53
+ end
54
+
55
+ def update_location_to_limit(location)
56
+ location.value_1 = update_to_constraint(location.value_1, 0.5 * footing.length_1)
57
+ location.value_2 = update_to_constraint(location.value_2, 0.5 * footing.length_2)
58
+ end
59
+
60
+ def update_to_constraint(initial_value, constraint_value)
61
+ if initial_value > constraint_value
62
+ constraint_value
63
+ elsif initial_value < -constraint_value
64
+ -constraint_value
65
+ else
66
+ initial_value
67
+ end
68
+ end
69
+
70
+ def perimeter_vertices_relative_to_column_location
71
+ {
72
+ top_right: perimeter_vertices_relative_to_column_location_with(way_1: 1, way_2: 1),
73
+ top_left: perimeter_vertices_relative_to_column_location_with(way_1: -1, way_2: 1),
74
+ bottom_left: perimeter_vertices_relative_to_column_location_with(way_1: -1, way_2: -1),
75
+ bottom_right: perimeter_vertices_relative_to_column_location_with(way_1: 1, way_2: -1)
76
+ }
77
+ end
78
+
79
+ def perimeter_vertices_relative_to_column_location_with(way_1:, way_2:)
80
+ Vector[
81
+ way_1 * 0.5 * (column_section_length_1 + footing.effective_height),
82
+ way_2 * 0.5 * (column_section_length_2 + footing.effective_height),
83
+ 0.0
84
+ ]
85
+ end
86
+
87
+ def local_coordinates_system
88
+ footing.coordinates_system
89
+ end
90
+
91
+ def compute_perimeter(edges_indexes, perimeter_vertices)
92
+ edges_indexes.map do |_edge_name, edge|
93
+ vector_from = perimeter_vertices[edge[:from]].to_vector
94
+ vector_to = perimeter_vertices[edge[:to]].to_vector
95
+ (vector_to - vector_from).magnitude
96
+ end.sum
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,57 @@
1
+ module StructuraidCore
2
+ module DesignCodes
3
+ module NSR10
4
+ module RC
5
+ class MinimumSteelCover
6
+ include DesignCodes::Utils::CodeRequirement
7
+ use_schema DesignCodes::Schemas::RC::MinimumSteelCoverSchema
8
+
9
+ CODE_REFERENCE = 'NSR-10 C.7.7.1'.freeze
10
+
11
+ def call
12
+ compute_cover
13
+ end
14
+
15
+ private
16
+
17
+ def compute_cover
18
+ return 75 if concrete_casting_against_soil # c.7.7.1.a
19
+ return expossed_to_environment_or_soil if !concrete_casting_against_soil && environment_exposure # c.7.7.1.b
20
+ return 50 unless structural_element
21
+
22
+ non_expossed_to_environment_or_soil
23
+ end
24
+
25
+ def expossed_to_environment_or_soil
26
+ return 40 if maximum_rebar_diameter&.<= 16
27
+
28
+ 50
29
+ end
30
+
31
+ # c.7.7.1.c
32
+ def non_expossed_to_environment_or_soil
33
+ if %i[slab wall joist].include?(structural_element)
34
+ slab_wall_joist_minimum_cover
35
+ elsif %i[beam column].include?(structural_element)
36
+ 40
37
+ elsif %i[shell thin_shell].include?(structural_element)
38
+ shell_minimum_cover
39
+ end
40
+ end
41
+
42
+ def slab_wall_joist_minimum_cover
43
+ return 20 if maximum_rebar_diameter&.<= 36
44
+
45
+ 40
46
+ end
47
+
48
+ def shell_minimum_cover
49
+ return 13 if maximum_rebar_diameter&.<= 16
50
+
51
+ 20
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end