soilrust/bearing_capacity/
point_load_test.rs1use serde::Serialize;
2
3use crate::{
4 models::{foundation::Foundation, point_load_test::PointLoadTest},
5 validation::{validate_field, ValidationError},
6};
7
8#[derive(Debug, Serialize)]
10pub struct Output {
11 pub is50: f64,
13
14 pub ucs: f64,
16
17 pub c: f64,
19
20 pub d: f64,
22
23 pub allowable_bearing_capacity: f64,
25
26 pub qmax: f64,
28
29 pub df: f64,
31
32 pub is_safe: bool,
34
35 pub safety_factor: f64,
37}
38
39pub fn validate_input(
40 point_load_test: &PointLoadTest,
41 foundation: &Foundation,
42 foundation_pressure: f64,
43 safety_factor: f64,
44) -> Result<(), ValidationError> {
45 point_load_test.validate(&["is50", "d"])?;
46 foundation.validate(&["foundation_depth"])?;
47 validate_field(
48 "foundation_pressure",
49 Some(foundation_pressure),
50 Some(0.0),
51 None,
52 "loads",
53 )?;
54 validate_field(
55 "safety_factor",
56 Some(safety_factor),
57 Some(1.),
58 None,
59 "safety_factor",
60 )?;
61 Ok(())
62}
63pub fn get_generalized_c_value(d: f64) -> f64 {
73 let diameters = [
75 (20., 17.5),
76 (30., 19.),
77 (40., 21.),
78 (50., 23.),
79 (54., 24.),
80 (60., 24.5),
81 ];
82
83 if d <= diameters[0].0 {
84 return diameters[0].1;
85 }
86
87 if d >= diameters.last().unwrap().0 {
88 return diameters.last().unwrap().1;
89 }
90
91 for i in 0..diameters.len() - 1 {
93 let (d_lower, c_lower) = diameters[i];
94 let (d_upper, c_upper) = diameters[i + 1];
95
96 if d >= d_lower && d <= d_upper {
97 let fraction = (d - d_lower) / (d_upper - d_lower);
98 return c_lower + fraction * (c_upper - c_lower);
99 }
100 }
101 unreachable!()
102}
103
104pub fn calc_bearing_capacity(
115 point_load_test: PointLoadTest,
116 foundation: Foundation,
117 foundation_pressure: f64,
118 safety_factor: f64,
119) -> Result<Output, ValidationError> {
120 validate_input(
121 &point_load_test,
122 &foundation,
123 foundation_pressure,
124 safety_factor,
125 )?;
126 let df = foundation.foundation_depth.unwrap();
127 let point_load_test_exp = point_load_test.get_idealized_exp("idealized".to_string());
128 const MPA_TO_TON: f64 = 101.97162; let sample = point_load_test_exp.get_sample_at_depth(df);
130
131 let is50 = sample.is50.unwrap();
132 let d = sample.d.unwrap();
133 let c = get_generalized_c_value(d);
134
135 let ucs = is50 * c * MPA_TO_TON;
136
137 let allowable_bearing_capacity = ucs / safety_factor;
138 let is_safe = allowable_bearing_capacity >= foundation_pressure;
139
140 Ok(Output {
141 is50,
142 ucs,
143 c,
144 d,
145 allowable_bearing_capacity,
146 is_safe,
147 safety_factor,
148 qmax: foundation_pressure,
149 df,
150 })
151}