diff --git a/src/bin/two_d.rs b/src/bin/two_d.rs index 03c18ac..08cbe56 100644 --- a/src/bin/two_d.rs +++ b/src/bin/two_d.rs @@ -2,15 +2,15 @@ use fea::two_d::beam_elements::*; use fea::two_d::*; fn main() { - let student_id_last_digit = 9 as f32; + let student_id_last_digit = 9_f32; let d = student_id_last_digit / 100.0; - let r = d/2.0; + let r = d / 2.0; let e = 210e9; - let p = (25.0 - student_id_last_digit)*1000.0; + let p = (25.0 - student_id_last_digit) * 1000.0; let theta = 30.0_f32.to_radians(); - let l = 2.0/theta.cos(); + let l = 2.0 / theta.cos(); - let p1 = Point{ + let p1 = Point { id: 1, pos: Vector(0.0, 0.0), bc: BoundaryCondition::Fixed, @@ -24,7 +24,7 @@ fn main() { beams: vec![], }; - let l_e3 = 2.0/theta.sin(); + let l_e3 = 2.0 / theta.sin(); println!("l_e3 {l_e3}"); let p3 = Point { @@ -38,32 +38,47 @@ fn main() { id: 4, pos: Vector(l * theta.cos(), l * theta.sin()), bc: BoundaryCondition::Force(Vector::from_mag_angle(p, 45_f32.to_radians())), - beams: vec![] + beams: vec![], }; let mut w = World::from(vec![p1, p2, p3, p4]); - w.link(1,4, NewBeam { - cross_section: CrossSection::Circular(r), - material: fea::Material { - yield_stress: 95e6, - youngs_modulus: e, - } - }).unwrap(); - w.link(2,4, NewBeam { - cross_section: CrossSection::Circular(r), - material: fea::Material { - yield_stress: 95e6, - youngs_modulus: e, - } - }).unwrap(); - w.link(3,4, NewBeam { - cross_section: CrossSection::Circular(r), - material: fea::Material { - yield_stress: 95e6, - youngs_modulus: e, - } - }).unwrap(); + w.link( + 1, + 4, + NewBeam { + cross_section: CrossSection::Circular(r), + material: fea::Material { + yield_stress: 95e6, + youngs_modulus: e, + }, + }, + ) + .unwrap(); + w.link( + 2, + 4, + NewBeam { + cross_section: CrossSection::Circular(r), + material: fea::Material { + yield_stress: 95e6, + youngs_modulus: e, + }, + }, + ) + .unwrap(); + w.link( + 3, + 4, + NewBeam { + cross_section: CrossSection::Circular(r), + material: fea::Material { + yield_stress: 95e6, + youngs_modulus: e, + }, + }, + ) + .unwrap(); println!("{:?}", w); println!("{:?}", w.stiffness_matrix().unwrap()); diff --git a/src/two_d.rs b/src/two_d.rs index e8b803c..428b482 100644 --- a/src/two_d.rs +++ b/src/two_d.rs @@ -1,14 +1,4 @@ pub mod beam_elements; +pub mod vector; -#[derive(Debug)] -pub struct Vector(pub f32, pub f32); - -impl Vector { - pub fn distance(&self, other: &Self) -> f32 { - ((self.0 - other.0).powi(2) + (self.1 - other.1).powi(2)).sqrt() - } - - pub fn from_mag_angle(magnitude: f32, angle: f32) -> Self { - Self (magnitude * angle.cos(), magnitude * angle.sin()) - } -} +pub use vector::*; diff --git a/src/two_d/beam_elements.rs b/src/two_d/beam_elements.rs index 7532466..a679a56 100644 --- a/src/two_d/beam_elements.rs +++ b/src/two_d/beam_elements.rs @@ -1,25 +1,11 @@ mod beam; +mod boundary_condition; mod cross_section; +mod point; mod world; pub use beam::*; +pub use boundary_condition::*; pub use cross_section::*; +pub use point::*; pub use world::*; - -use super::Vector; -use crate::Material; - -#[derive(Debug)] -pub struct Point { - pub id: usize, - pub pos: Vector, - pub bc: BoundaryCondition, - pub beams: Vec, -} - -#[derive(Debug)] -pub enum BoundaryCondition { - Free, - Fixed, - Force(Vector), -} diff --git a/src/two_d/beam_elements/beam.rs b/src/two_d/beam_elements/beam.rs index f88829c..7ead646 100644 --- a/src/two_d/beam_elements/beam.rs +++ b/src/two_d/beam_elements/beam.rs @@ -1,7 +1,8 @@ use super::*; +use crate::Material; #[derive(Debug)] -pub struct Beam{ +pub struct Beam { pub id: usize, pub points: (usize, usize), pub material: Material, @@ -15,14 +16,12 @@ pub struct NewBeam { impl Beam { pub fn new(p1: usize, p2: usize, props: NewBeam) -> Beam { - let b = Beam { + Beam { id: 0, points: (p1, p2), material: props.material, cross_section: props.cross_section, - }; - - return b; + } } fn get_points<'a>(&self, world: &'a World) -> (&'a Point, &'a Point) { @@ -33,21 +32,12 @@ impl Beam { } pub fn stiffness(&self, world: &World) -> f32 { - let s = self.cross_section.area() * self.material.youngs_modulus / self.length(world); - - println!("{:?} {}", self, s); - - s - + self.cross_section.area() * self.material.youngs_modulus / self.length(world) } pub fn length(&self, world: &World) -> f32 { let (p1, p2) = self.get_points(world); - let l = p1.pos.distance(&p2.pos); - - println!("{:?} {}", self, l); - - l + p1.pos.distance(&p2.pos) } pub fn angle(&self, world: &World) -> f32 { @@ -55,14 +45,14 @@ impl Beam { let dx = p1.pos.0 - p2.pos.0; let dy = p1.pos.1 - p2.pos.1; - (dy/dx).atan() + (dy / dx).atan() } pub fn other_point(&self, p: usize) -> usize { - if p == self.points.0{ - return self.points.1; + if p == self.points.0 { + self.points.1 } else { - return self.points.0; + self.points.0 } } } diff --git a/src/two_d/beam_elements/boundary_condition.rs b/src/two_d/beam_elements/boundary_condition.rs new file mode 100644 index 0000000..d5ee0a6 --- /dev/null +++ b/src/two_d/beam_elements/boundary_condition.rs @@ -0,0 +1,8 @@ +use crate::two_d::Vector; + +#[derive(Debug)] +pub enum BoundaryCondition { + Free, + Fixed, + Force(Vector), +} diff --git a/src/two_d/beam_elements/point.rs b/src/two_d/beam_elements/point.rs new file mode 100644 index 0000000..f3ef858 --- /dev/null +++ b/src/two_d/beam_elements/point.rs @@ -0,0 +1,10 @@ +use super::super::Vector; +use super::BoundaryCondition; + +#[derive(Debug)] +pub struct Point { + pub id: usize, + pub pos: Vector, + pub bc: BoundaryCondition, + pub beams: Vec, +} diff --git a/src/two_d/beam_elements/world.rs b/src/two_d/beam_elements/world.rs index 7549eda..0e8636d 100644 --- a/src/two_d/beam_elements/world.rs +++ b/src/two_d/beam_elements/world.rs @@ -19,34 +19,40 @@ impl World { let beam = self.beams.get(beam_id).unwrap(); let stiffness = beam.stiffness(self); let other_point = self.points.get(&beam.other_point(point.id)).unwrap(); - let ax = 2*(point.id-1); + let ax = 2 * (point.id - 1); let ay = ax + 1; - let bx = 2*(other_point.id-1); + let bx = 2 * (other_point.id - 1); let by = bx + 1; - + let angle = beam.angle(self); - println!("point: {} to point {} beam: {} beam_angle: {}", _point_id, other_point.id, beam.id, beam.angle(self).to_degrees()); + println!( + "point: {} to point {} beam: {} beam_angle: {}", + _point_id, + other_point.id, + beam.id, + beam.angle(self).to_degrees() + ); let c2 = angle.cos().powi(2); let s2 = angle.sin().powi(2); let cs = angle.cos() * angle.sin(); // F_AX += K_AB * c2 * (U_AX) - a[ax*dof + ax] += stiffness * c2; + a[ax * dof + ax] += stiffness * c2; // F_AX += K_AB * cs * U_AY - a[ax*dof + ay] += stiffness * cs; + a[ax * dof + ay] += stiffness * cs; // F_AY += K_AB * cs * U_AX - a[ay*dof + ax] += stiffness * cs; + a[ay * dof + ax] += stiffness * cs; // F_AY += K_AB * s^2 * U_AY - a[ay*dof + ay] += stiffness * s2; + a[ay * dof + ay] += stiffness * s2; // F_AX += K_AB -c^2 U_BX - a[ax*dof + bx] += stiffness * -c2; + a[ax * dof + bx] += stiffness * -c2; // F_AX += K_AB -cs U_BY - a[ax*dof + by] += stiffness * -cs; + a[ax * dof + by] += stiffness * -cs; // F_AY += K_AB -cs U_BX - a[ay*dof + bx] += stiffness * -cs; + a[ay * dof + bx] += stiffness * -cs; // F_AY += K_AB -s^2 U_BY - a[ay*dof + by] += stiffness * -s2; + a[ay * dof + by] += stiffness * -s2; } } @@ -56,7 +62,7 @@ impl World { } } - pub fn link(&mut self, id1: usize, id2: usize, new_beam: NewBeam) -> Result<(), &str>{ + pub fn link(&mut self, id1: usize, id2: usize, new_beam: NewBeam) -> Result<(), &str> { let b_id = self.beams.len(); let p1 = match self.points.get_mut(&id1) { Some(point) => point, @@ -86,7 +92,10 @@ impl From> for World { /// If this is not the case, then some points will be overriden. fn from(points: Vec) -> World { let mut points = points; - let mut w = World { points: HashMap::new(), beams: HashMap::new() }; + let mut w = World { + points: HashMap::new(), + beams: HashMap::new(), + }; while let Some(point) = points.pop() { w.points.insert(point.id, point); diff --git a/src/two_d/vector.rs b/src/two_d/vector.rs new file mode 100644 index 0000000..efe6e53 --- /dev/null +++ b/src/two_d/vector.rs @@ -0,0 +1,12 @@ +#[derive(Debug)] +pub struct Vector(pub f32, pub f32); + +impl Vector { + pub fn distance(&self, other: &Self) -> f32 { + ((self.0 - other.0).powi(2) + (self.1 - other.1).powi(2)).sqrt() + } + + pub fn from_mag_angle(magnitude: f32, angle: f32) -> Self { + Self(magnitude * angle.cos(), magnitude * angle.sin()) + } +}