use crate::{
consolidation_settlement::model::SettlementResult,
models::{foundation::Foundation, soil_profile::SoilProfile},
validation::{validate_field, ValidationError},
};
use super::reduction_factors::interpolate_if;
pub fn validate_input(
soil_profile: &SoilProfile,
foundation: &Foundation,
foundation_pressure: f64,
) -> Result<(), ValidationError> {
soil_profile.validate(&[
"thickness",
"dry_unit_weight",
"saturated_unit_weight",
"elastic_modulus",
"poissons_ratio",
])?;
foundation.validate(&["foundation_depth", "foundation_width", "foundation_length"])?;
validate_field(
"foundation_pressure",
Some(foundation_pressure),
Some(0.0),
None,
"loads",
)?;
Ok(())
}
pub fn calc_ip(h: f64, b: f64, l: f64, u: f64) -> f64 {
let m = l / b;
let n = 2.0 * h / b;
let m2 = m * m;
let n2 = n * n;
let a0 = m
* ((1.0 + (1.0 + m2).sqrt()) * (m2 + n2).sqrt() / (m * (1.0 + (1.0 + m2 + n2).sqrt())))
.ln();
let a1 = ((m + (1.0 + m2).sqrt()) * (1.0 + n2).sqrt() / (m + (1.0 + m2 + n2).sqrt())).ln();
let a2 = m / (n * (1.0 + m2 + n2).sqrt());
let f1 = (a0 + a1) / std::f64::consts::PI;
let f2 = 0.5 * (n / std::f64::consts::PI) * a2.atan();
f1 + ((1.0 - 2.0 * u) / (1.0 - u)) * f2
}
pub fn single_layer_settlement(h: f64, u: f64, e: f64, l: f64, b: f64, df: f64, q_net: f64) -> f64 {
let lb = l / b;
let db = df / b;
let ip = calc_ip(h, b, l, u);
let if_value = interpolate_if(u, db, lb);
100.0 * q_net * 4.0 * b * if_value * ip * (1.0 - u.powi(2)) * 0.5 / e
}
pub fn calc_elastic_settlement(
soil_profile: &mut SoilProfile,
foundation: &Foundation,
foundation_pressure: f64,
) -> Result<SettlementResult, ValidationError> {
validate_input(soil_profile, foundation, foundation_pressure)?;
soil_profile.calc_layer_depths();
let mut settlements = vec![];
let df = foundation.foundation_depth.unwrap();
let width = foundation.foundation_width.unwrap();
let length = foundation.foundation_length.unwrap();
let q_net = foundation_pressure - soil_profile.calc_normal_stress(df);
let df_index = soil_profile.get_layer_index(df);
for i in 0..soil_profile.layers.len() {
let layer = &soil_profile.layers[i];
let h = layer.depth.unwrap() - df;
let u = layer.poissons_ratio.unwrap();
let e = layer.elastic_modulus.unwrap();
if i < df_index {
settlements.push(0.0);
} else {
let settlement_all = single_layer_settlement(h, u, e, length, width, df, q_net);
if i == 0 {
settlements.push(settlement_all.max(0.));
} else {
let h0 = soil_profile.layers[i - 1].depth.unwrap() - df;
let settlement_prevlayer =
single_layer_settlement(h0, u, e, length, width, df, q_net);
settlements.push((settlement_all - settlement_prevlayer).max(0.));
}
}
}
Ok(SettlementResult {
settlement_per_layer: settlements.clone(),
total_settlement: settlements.iter().sum(),
qnet: q_net,
})
}