structuraid_core 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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