structuraid_core 0.1.3 → 0.2.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -9
- data/lib/structuraid_core/design_codes/aci_318_19/rc/footings/bending_reinforcement_ratio.rb +65 -0
- data/lib/structuraid_core/design_codes/aci_318_19/rc/footings/one_way_shear_capacity.rb +29 -0
- data/lib/structuraid_core/design_codes/aci_318_19/rc/footings/punching_critical_section_perimeter.rb +105 -0
- data/lib/structuraid_core/design_codes/aci_318_19/rc/minimum_steel_cover.rb +55 -0
- data/lib/structuraid_core/design_codes/aci_318_19/rc/reduction_factor.rb +88 -0
- data/lib/structuraid_core/design_codes/nsr_10/rc/footings/bending_reinforcement_ratio.rb +66 -0
- data/lib/structuraid_core/design_codes/nsr_10/rc/footings/one_way_shear_capacity.rb +31 -0
- data/lib/structuraid_core/design_codes/nsr_10/rc/footings/punching_critical_section_perimeter.rb +103 -0
- data/lib/structuraid_core/design_codes/nsr_10/rc/minimum_steel_cover.rb +57 -0
- data/lib/structuraid_core/design_codes/nsr_10/rc/reduction_factor.rb +82 -0
- data/lib/structuraid_core/design_codes/schemas/rc/footings/bending_reinforcement_ratio_schema.rb +24 -0
- data/lib/structuraid_core/design_codes/schemas/rc/footings/one_way_shear_capacity_schema.rb +22 -0
- data/lib/structuraid_core/design_codes/schemas/rc/footings/punching_critical_section_perimeter_schema.rb +23 -0
- data/lib/structuraid_core/design_codes/schemas/rc/minimum_steel_cover_schema.rb +32 -0
- data/lib/structuraid_core/design_codes/schemas/rc/reduction_factor_schema.rb +17 -0
- data/lib/structuraid_core/design_codes/utils/schema_definition.rb +38 -9
- data/lib/structuraid_core/elements/column/rectangular.rb +5 -4
- data/lib/structuraid_core/elements/footing.rb +69 -2
- data/lib/structuraid_core/engineering/analysis/footing/base.rb +17 -0
- data/lib/structuraid_core/engineering/analysis/footing/centric_combined_two_columns.rb +99 -0
- data/lib/structuraid_core/engineering/analysis/footing/centric_isolated.rb +1 -1
- data/lib/structuraid_core/engineering/analysis/footing/utils/basic_geometry.rb +36 -0
- data/lib/structuraid_core/engineering/analysis/footing/utils/centroid.rb +33 -0
- data/lib/structuraid_core/engineering/analysis/footing/utils/one_way_moment.rb +63 -0
- data/lib/structuraid_core/engineering/analysis/footing/utils/one_way_shear.rb +46 -0
- data/lib/structuraid_core/engineering/base.rb +1 -1
- data/lib/structuraid_core/engineering/locations/absolute.rb +4 -0
- data/lib/structuraid_core/engineering/locations/base.rb +1 -0
- data/lib/structuraid_core/engineering/locations/collection.rb +51 -0
- data/lib/structuraid_core/engineering/locations/coordinates_system.rb +19 -4
- data/lib/structuraid_core/engineering/locations/relative.rb +17 -4
- data/lib/structuraid_core/errors/engineering/locations/duplicate_label_error.rb +13 -0
- data/lib/structuraid_core/loads/point_load.rb +3 -2
- data/lib/structuraid_core/version.rb +1 -1
- metadata +67 -2
@@ -0,0 +1,82 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module DesignCodes
|
3
|
+
module NSR10
|
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
|
+
MIN_STRAIN_AFTER_TRANSITION = 0.005
|
22
|
+
|
23
|
+
CODE_REFERENCE = 'NSR-10 C.9.3.2'.freeze
|
24
|
+
|
25
|
+
def call
|
26
|
+
unless CONTROL_STRENGTH_CASES.include?(strength_controlling_behaviour)
|
27
|
+
raise UnrecognizedValueError.new(strength_controlling_behaviour, :strength_controlling_behaviour)
|
28
|
+
end
|
29
|
+
|
30
|
+
return tension_controlled_factor if strength_controlling_behaviour == :tension_controlled
|
31
|
+
return compression_controlled_factor if strength_controlling_behaviour == :compression_controlled
|
32
|
+
return crushing_controlled_factor if strength_controlling_behaviour == :crushing_controlled
|
33
|
+
if %i[
|
34
|
+
shear_nonseismic_controlled
|
35
|
+
torsion_controlled
|
36
|
+
corbel_bracket_controlled
|
37
|
+
strud_and_tie_controlled
|
38
|
+
].include?(strength_controlling_behaviour)
|
39
|
+
return shear_nonseismic_controlled_factor
|
40
|
+
end
|
41
|
+
|
42
|
+
transition_controlled_factor
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def shear_nonseismic_controlled_factor
|
48
|
+
0.75
|
49
|
+
end
|
50
|
+
|
51
|
+
def crushing_controlled_factor
|
52
|
+
0.65
|
53
|
+
end
|
54
|
+
|
55
|
+
def tension_controlled_factor
|
56
|
+
0.90
|
57
|
+
end
|
58
|
+
|
59
|
+
def compression_controlled_factor
|
60
|
+
return 0.75 if is_coil_rebar
|
61
|
+
|
62
|
+
0.65
|
63
|
+
end
|
64
|
+
|
65
|
+
def transition_controlled_factor
|
66
|
+
raise MissingParamError, :strain unless strain
|
67
|
+
|
68
|
+
transition_controlled_by_strain
|
69
|
+
end
|
70
|
+
|
71
|
+
def transition_controlled_by_strain
|
72
|
+
return compression_controlled_factor if strain < MAX_STRAIN_BEFORE_TRANSITION
|
73
|
+
return tension_controlled_factor if strain > MIN_STRAIN_AFTER_TRANSITION
|
74
|
+
|
75
|
+
transition_rate = is_coil_rebar ? 50 : 250 / 3
|
76
|
+
compression_controlled_factor + (strain - MAX_STRAIN_BEFORE_TRANSITION) * transition_rate
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/structuraid_core/design_codes/schemas/rc/footings/bending_reinforcement_ratio_schema.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module DesignCodes
|
3
|
+
module Schemas
|
4
|
+
module RC
|
5
|
+
module Footings
|
6
|
+
class BendingReinforcementRatioSchema
|
7
|
+
include DesignCodes::Utils::SchemaDefinition
|
8
|
+
|
9
|
+
required_params %i[
|
10
|
+
design_compression_strength
|
11
|
+
design_steel_yield_strength
|
12
|
+
width
|
13
|
+
effective_height
|
14
|
+
flexural_moment
|
15
|
+
capacity_reduction_factor
|
16
|
+
]
|
17
|
+
|
18
|
+
optional_params []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module DesignCodes
|
3
|
+
module Schemas
|
4
|
+
module RC
|
5
|
+
module Footings
|
6
|
+
class OneWayShearCapacitySchema
|
7
|
+
include DesignCodes::Utils::SchemaDefinition
|
8
|
+
|
9
|
+
required_params %i[
|
10
|
+
design_compression_strength
|
11
|
+
width
|
12
|
+
effective_height
|
13
|
+
light_concrete_modification_factor
|
14
|
+
]
|
15
|
+
|
16
|
+
optional_params []
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module DesignCodes
|
3
|
+
module Schemas
|
4
|
+
module RC
|
5
|
+
module Footings
|
6
|
+
class PunchingCriticalSectionPerimeterSchema
|
7
|
+
include DesignCodes::Utils::SchemaDefinition
|
8
|
+
|
9
|
+
required_params %i[
|
10
|
+
column_section_length_1
|
11
|
+
column_section_length_2
|
12
|
+
column_absolute_location
|
13
|
+
column_label
|
14
|
+
footing
|
15
|
+
]
|
16
|
+
|
17
|
+
optional_params []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module DesignCodes
|
3
|
+
module Schemas
|
4
|
+
module RC
|
5
|
+
class MinimumSteelCoverSchema
|
6
|
+
include DesignCodes::Utils::SchemaDefinition
|
7
|
+
|
8
|
+
required_params %i[
|
9
|
+
concrete_casting_against_soil
|
10
|
+
environment_exposure
|
11
|
+
]
|
12
|
+
|
13
|
+
optional_params %i[
|
14
|
+
maximum_rebar_diameter
|
15
|
+
structural_element
|
16
|
+
]
|
17
|
+
|
18
|
+
enum :structural_element, %i[
|
19
|
+
slab
|
20
|
+
wall
|
21
|
+
joist
|
22
|
+
beam
|
23
|
+
column
|
24
|
+
shell thin_shell
|
25
|
+
tensor_joint
|
26
|
+
pedestal
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module DesignCodes
|
3
|
+
module Schemas
|
4
|
+
module RC
|
5
|
+
class ReductionFactorSchema
|
6
|
+
include DesignCodes::Utils::SchemaDefinition
|
7
|
+
|
8
|
+
required_params %i[strength_controlling_behaviour]
|
9
|
+
optional_params %i[
|
10
|
+
strain
|
11
|
+
is_coil_rebar
|
12
|
+
]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -10,15 +10,9 @@ module StructuraidCore
|
|
10
10
|
|
11
11
|
module ClassMethods
|
12
12
|
def validate!(params)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
optional.each do |optional_param|
|
18
|
-
raise DesignCodes::MissingParamError, optional_param if params[optional_param].nil?
|
19
|
-
rescue DesignCodes::MissingParamError => e
|
20
|
-
Warning.warn(e.message)
|
21
|
-
end
|
13
|
+
validate_required_params!(params)
|
14
|
+
validate_optional_params!(params)
|
15
|
+
validate_enum_params!(params)
|
22
16
|
|
23
17
|
true
|
24
18
|
end
|
@@ -40,8 +34,38 @@ module StructuraidCore
|
|
40
34
|
@optional
|
41
35
|
end
|
42
36
|
|
37
|
+
def enum_params
|
38
|
+
@enum_params
|
39
|
+
end
|
40
|
+
|
43
41
|
private
|
44
42
|
|
43
|
+
def validate_required_params!(params)
|
44
|
+
required.each do |required_param|
|
45
|
+
raise DesignCodes::MissingParamError, required_param if params[required_param].nil?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def validate_optional_params!(params)
|
50
|
+
optional.each do |optional_param|
|
51
|
+
raise DesignCodes::MissingParamError, optional_param if params[optional_param].nil?
|
52
|
+
rescue DesignCodes::MissingParamError => e
|
53
|
+
Warning.warn(e.message)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate_enum_params!(params)
|
58
|
+
enum_params&.each do |enum_param|
|
59
|
+
param_name = enum_param[:name]
|
60
|
+
param_value = params[param_name]
|
61
|
+
next if param_value.nil? && optional.include?(param_name)
|
62
|
+
|
63
|
+
if enum_param[:values].none?(param_value)
|
64
|
+
raise DesignCodes::UnrecognizedValueError.new(param_name, param_value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
45
69
|
def required_params(params)
|
46
70
|
@required = params
|
47
71
|
end
|
@@ -49,6 +73,11 @@ module StructuraidCore
|
|
49
73
|
def optional_params(params)
|
50
74
|
@optional = params
|
51
75
|
end
|
76
|
+
|
77
|
+
def enum(param_name, values)
|
78
|
+
@enum_params = []
|
79
|
+
@enum_params << { name: param_name, values: }
|
80
|
+
end
|
52
81
|
end
|
53
82
|
end
|
54
83
|
end
|
@@ -2,13 +2,14 @@ module StructuraidCore
|
|
2
2
|
module Elements
|
3
3
|
module Column
|
4
4
|
class Rectangular < Base
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :length_1, :length_2, :height, :material, :label
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
7
|
+
def initialize(length_1:, length_2:, height:, material:, label: nil)
|
8
|
+
@length_1 = length_1.to_f
|
9
|
+
@length_2 = length_2.to_f
|
10
10
|
@height = height.to_f
|
11
11
|
@material = material
|
12
|
+
@label = label&.to_sym
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -1,14 +1,29 @@
|
|
1
1
|
module StructuraidCore
|
2
2
|
module Elements
|
3
|
+
# A footing is a structural element that transfers load from a column to the soil.
|
3
4
|
class Footing < Base
|
4
5
|
attr_accessor :length_1, :length_2, :height, :material, :cover_lateral, :cover_top, :cover_bottom
|
5
6
|
attr_reader :longitudinal_top_reinforcement_length_1,
|
6
7
|
:longitudinal_bottom_reinforcement_length_1,
|
7
8
|
:longitudinal_top_reinforcement_length_2,
|
8
|
-
:longitudinal_bottom_reinforcement_length_2
|
9
|
+
:longitudinal_bottom_reinforcement_length_2,
|
10
|
+
:coordinates_system
|
9
11
|
|
10
12
|
VALID_SECTIONS = %i[length_1 length_2].freeze
|
11
13
|
|
14
|
+
# @param length_1 [Float] The length of the footing in the direction of the main section
|
15
|
+
# @param length_2 [Float] The length of the footing in the direction perpendicular to the main section
|
16
|
+
# @param height [Float] The height of the footing
|
17
|
+
# @param material [Materials::Concrete] The material of the footing. It must be concrete
|
18
|
+
# @param cover_lateral [Float] The lateral cover of the footing
|
19
|
+
# @param cover_top [Float] The top cover of the footing
|
20
|
+
# @param cover_bottom [Float] The bottom cover of the footing
|
21
|
+
# @param longitudinal_top_reinforcement_length_1 [Reinforcement::StraightLongitudinal] The longitudinal reinforcement in the direction of the main section
|
22
|
+
# @param longitudinal_bottom_reinforcement_length_1 [Reinforcement::StraightLongitudinal] The longitudinal reinforcement in the direction of the main section
|
23
|
+
# @param longitudinal_top_reinforcement_length_2 [Reinforcement::StraightLongitudinal] The longitudinal reinforcement in the direction perpendicular to the main section
|
24
|
+
# @param longitudinal_bottom_reinforcement_length_2 [Reinforcement::StraightLongitudinal] The longitudinal reinforcement in the direction perpendicular to the main section
|
25
|
+
#
|
26
|
+
# @return [Footing] the footing
|
12
27
|
def initialize(
|
13
28
|
length_1:,
|
14
29
|
length_2:,
|
@@ -36,10 +51,16 @@ module StructuraidCore
|
|
36
51
|
@main_section = :length_1
|
37
52
|
end
|
38
53
|
|
54
|
+
# Computes the horizontal area of the footing
|
55
|
+
# @return [Float] The horizontal area of the footing
|
39
56
|
def horizontal_area
|
40
|
-
|
57
|
+
length_1 * length_2
|
41
58
|
end
|
42
59
|
|
60
|
+
# Computes the effective height of the footing for each direction and for either top or bottom reinforcement
|
61
|
+
# @param section_direction [Symbol] The direction of the section. See VALID_SECTIONS
|
62
|
+
# @param above_middle [Boolean] Whether the reinforcement is above the middle of the footing
|
63
|
+
# @return [Float] The effective height of the footing
|
43
64
|
def effective_height(section_direction:, above_middle:)
|
44
65
|
case section_direction
|
45
66
|
when :length_1
|
@@ -49,8 +70,54 @@ module StructuraidCore
|
|
49
70
|
end
|
50
71
|
end
|
51
72
|
|
73
|
+
# Sets the coordinates system of the footing
|
74
|
+
# @param coordinates_system [Engineering::Locations::CoordinatesSystem] A coordinates system instance
|
75
|
+
# @return [Engineering::Locations::CoordinatesSystem] The coordinates system of the footing
|
76
|
+
def add_coordinates_system(coordinates_system)
|
77
|
+
@coordinates_system = coordinates_system
|
78
|
+
end
|
79
|
+
|
80
|
+
# Adds a column's location to the footing. If the column's location is already in the footing's coordinates system, it returns the existing location.
|
81
|
+
# @param column_location [Engineering::Locations::Absolute] The column's absolute location
|
82
|
+
# @param column_label [String, Symbol] The column's label
|
83
|
+
# @return [Engineering::Locations::Relative] The column's relative location
|
84
|
+
def find_or_add_column_location(column_location, column_label)
|
85
|
+
label = "column_#{column_label}"
|
86
|
+
relative_location_vector = column_location.to_vector - coordinates_system.anchor_location.to_vector
|
87
|
+
coordinates_system.find_or_add_location_from_vector(relative_location_vector, label:)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Computes the vertices location of the footing's perimeter horizontally and adds them to the footing's coordinates system
|
91
|
+
def add_vertices_location
|
92
|
+
vertices_locations_vectors.each do |label, vector|
|
93
|
+
coordinates_system.find_or_add_location_from_vector(vector, label:)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Evaluates if a relative location is inside the footing's perimeter. It works only for horizontal locations (z = 0)
|
98
|
+
# @param location [Engineering::Locations::Relative] The relative location to evaluate
|
99
|
+
# @return [Boolean] Whether the location is inside the footing's perimeter
|
100
|
+
def inside_me?(location)
|
101
|
+
inside_axis_2 = location.value_2 >= -0.5 * length_2 && location.value_2 <= 0.5 * length_2
|
102
|
+
inside_axis_1 = location.value_1 >= -0.5 * length_1 && location.value_1 <= 0.5 * length_1
|
103
|
+
|
104
|
+
inside_axis_1 && inside_axis_2
|
105
|
+
end
|
106
|
+
|
52
107
|
private
|
53
108
|
|
109
|
+
def vertices_locations_vectors
|
110
|
+
half_length_1 = 0.5 * length_1
|
111
|
+
half_length_2 = 0.5 * length_2
|
112
|
+
|
113
|
+
{
|
114
|
+
'vertex_top_right' => Vector[half_length_1, half_length_2, 0],
|
115
|
+
'vertex_top_left' => Vector[-half_length_1, half_length_2, 0],
|
116
|
+
'vertex_bottom_left' => Vector[-half_length_1, -half_length_2, 0],
|
117
|
+
'vertex_bottom_right' => Vector[half_length_1, -half_length_2, 0]
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
54
121
|
def aspect_ratio
|
55
122
|
@length_1 / @length_2
|
56
123
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module Engineering
|
3
|
+
module Analysis
|
4
|
+
module Footing
|
5
|
+
class Base
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require_relative 'utils/basic_geometry'
|
13
|
+
require_relative 'utils/centroid'
|
14
|
+
require_relative 'utils/one_way_shear'
|
15
|
+
require_relative 'utils/one_way_moment'
|
16
|
+
require_relative 'centric_isolated'
|
17
|
+
require_relative 'centric_combined_two_columns'
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'byebug'
|
2
|
+
|
3
|
+
module StructuraidCore
|
4
|
+
module Engineering
|
5
|
+
module Analysis
|
6
|
+
module Footing
|
7
|
+
class CentricCombinedTwoColumns < Base
|
8
|
+
include Utils::BasicGeometry
|
9
|
+
include Utils::Centroid
|
10
|
+
include Utils::OneWayShear
|
11
|
+
include Utils::OneWayMoment
|
12
|
+
|
13
|
+
def initialize(footing:, loads_from_columns:, section_direction:)
|
14
|
+
if ORTHOGONALITIES.none?(section_direction)
|
15
|
+
raise Engineering::Analysis::SectionDirectionError.new(section_direction, ORTHOGONALITIES)
|
16
|
+
end
|
17
|
+
|
18
|
+
@footing = footing
|
19
|
+
@loads_from_columns = loads_from_columns
|
20
|
+
@section_direction = section_direction
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_geometry
|
24
|
+
add_loads_to_coordinates_system
|
25
|
+
align_coordinates_system_with_loads
|
26
|
+
add_vertices_location_to_coordinates_system
|
27
|
+
end
|
28
|
+
|
29
|
+
def reaction_at_first_column
|
30
|
+
-(solicitation * @footing.horizontal_area + reaction_at_second_column)
|
31
|
+
end
|
32
|
+
|
33
|
+
def reaction_at_second_column
|
34
|
+
local_length_1 = length_border_to_first_column
|
35
|
+
local_length_2 = length_first_column_to_second_column
|
36
|
+
local_length_3 = length_second_column_to_border
|
37
|
+
|
38
|
+
(solicitation_load / 2 / local_length_2) * (local_length_1**2 - (local_length_2 + local_length_3)**2)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :footing, :section_direction, :loads_from_columns
|
44
|
+
|
45
|
+
def coordinates_system
|
46
|
+
footing.coordinates_system
|
47
|
+
end
|
48
|
+
|
49
|
+
def align_coordinates_system_with_loads
|
50
|
+
last_load_location_label = "load_#{loads_from_columns.last.label}"
|
51
|
+
aligner_vector = coordinates_system.find_location(last_load_location_label).to_vector
|
52
|
+
coordinates_system.align_axis_1_with(vector: aligner_vector)
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_loads_to_coordinates_system
|
56
|
+
centroid = absolute_centroid
|
57
|
+
|
58
|
+
loads_from_columns.each do |load_from_column|
|
59
|
+
coordinates_system.find_or_add_location_from_vector(
|
60
|
+
load_from_column.location.to_vector - centroid.to_vector,
|
61
|
+
label: "load_#{load_from_column.label}"
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_vertices_location_to_coordinates_system
|
67
|
+
footing.add_vertices_location
|
68
|
+
end
|
69
|
+
|
70
|
+
def length_border_to_first_column
|
71
|
+
load_location_label = "load_#{loads_from_columns.first.label}"
|
72
|
+
load_location_vector = coordinates_system.find_location(load_location_label).to_vector
|
73
|
+
vertex_location_vector = coordinates_system.find_location('vertex_top_left').to_vector
|
74
|
+
|
75
|
+
(load_location_vector - vertex_location_vector)[0].abs
|
76
|
+
end
|
77
|
+
|
78
|
+
def length_first_column_to_second_column
|
79
|
+
first_load_location_label = "load_#{loads_from_columns.first.label}"
|
80
|
+
first_load_location_vector = coordinates_system.find_location(first_load_location_label).to_vector
|
81
|
+
|
82
|
+
last_load_location_label = "load_#{loads_from_columns.last.label}"
|
83
|
+
last_load_location_vector = coordinates_system.find_location(last_load_location_label).to_vector
|
84
|
+
|
85
|
+
(last_load_location_vector - first_load_location_vector)[0].abs
|
86
|
+
end
|
87
|
+
|
88
|
+
def length_second_column_to_border
|
89
|
+
load_location_label = "load_#{loads_from_columns.last.label}"
|
90
|
+
load_location_vector = coordinates_system.find_location(load_location_label).to_vector
|
91
|
+
vertex_location_vector = coordinates_system.find_location('vertex_top_right').to_vector
|
92
|
+
|
93
|
+
(vertex_location_vector - load_location_vector)[0].abs
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module Engineering
|
3
|
+
module Analysis
|
4
|
+
module Footing
|
5
|
+
module Utils
|
6
|
+
module BasicGeometry
|
7
|
+
ORTHOGONALITIES = %i[length_1 length_2].freeze
|
8
|
+
|
9
|
+
def solicitation_load
|
10
|
+
solicitation * orthogonal_length
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def section_length
|
16
|
+
footing.public_send(section_direction)
|
17
|
+
end
|
18
|
+
|
19
|
+
def orthogonal_length
|
20
|
+
footing.public_send(orthogonal_direction)
|
21
|
+
end
|
22
|
+
|
23
|
+
def orthogonal_direction
|
24
|
+
orthogonal = ORTHOGONALITIES - [@cut_direction]
|
25
|
+
orthogonal.last
|
26
|
+
end
|
27
|
+
|
28
|
+
def solicitation
|
29
|
+
-loads_from_columns.sum(&:value) / @footing.horizontal_area
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module Engineering
|
3
|
+
module Analysis
|
4
|
+
module Footing
|
5
|
+
module Utils
|
6
|
+
module Centroid
|
7
|
+
def absolute_centroid
|
8
|
+
Engineering::Locations::Absolute.new(
|
9
|
+
value_x: moment_yy / total_load,
|
10
|
+
value_y: moment_xx / total_load,
|
11
|
+
value_z: loads_from_columns.first.location.value_z
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def moment_yy
|
18
|
+
loads_from_columns.sum { |load| load.value * load.location.value_x }
|
19
|
+
end
|
20
|
+
|
21
|
+
def moment_xx
|
22
|
+
loads_from_columns.sum { |load| load.value * load.location.value_y }
|
23
|
+
end
|
24
|
+
|
25
|
+
def total_load
|
26
|
+
loads_from_columns.sum(&:value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module StructuraidCore
|
2
|
+
module Engineering
|
3
|
+
module Analysis
|
4
|
+
module Footing
|
5
|
+
module Utils
|
6
|
+
module OneWayMoment
|
7
|
+
def moment_at(x_distance)
|
8
|
+
return [] if x_distance > section_length
|
9
|
+
|
10
|
+
moment = [
|
11
|
+
moment_stretch_1(x_distance),
|
12
|
+
moment_stretch_2(x_distance),
|
13
|
+
moment_stretch_3(x_distance)
|
14
|
+
].select(&:nonzero?)
|
15
|
+
return [0] if moment.empty?
|
16
|
+
|
17
|
+
moment
|
18
|
+
end
|
19
|
+
|
20
|
+
def maximum_moment
|
21
|
+
moment_at(moment_inflection_point)
|
22
|
+
end
|
23
|
+
|
24
|
+
def moment_inflection_point
|
25
|
+
-reaction_at_first_column / solicitation_load
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def moment_stretch_1(x_distance)
|
31
|
+
return 0.0 if x_distance > length_border_to_first_column
|
32
|
+
|
33
|
+
0.5 * solicitation_load * x_distance**2
|
34
|
+
end
|
35
|
+
|
36
|
+
def moment_stretch_2(x_distance)
|
37
|
+
local_length_1 = length_border_to_first_column
|
38
|
+
local_length_2 = length_first_column_to_second_column
|
39
|
+
return 0.0 if x_distance < local_length_1 || x_distance > local_length_1 + local_length_2
|
40
|
+
|
41
|
+
0.5 * solicitation_load * x_distance**2 + reaction_at_first_column * (x_distance - local_length_1)
|
42
|
+
end
|
43
|
+
|
44
|
+
def moment_stretch_3(x_distance)
|
45
|
+
return 0.0 if x_distance < length_border_to_first_column + length_first_column_to_second_column
|
46
|
+
|
47
|
+
0.5 * solicitation_load * x_distance**2 + reaction_1_moment(x_distance) + reaction_2_moment(x_distance)
|
48
|
+
end
|
49
|
+
|
50
|
+
def reaction_1_moment(x_distance)
|
51
|
+
reaction_at_first_column * (x_distance - length_border_to_first_column)
|
52
|
+
end
|
53
|
+
|
54
|
+
def reaction_2_moment(x_distance)
|
55
|
+
local_length_2 = length_first_column_to_second_column
|
56
|
+
reaction_at_second_column * (x_distance - length_border_to_first_column - local_length_2)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|