mirror of
https://github.com/alvierahman90/fea.git
synced 2024-12-15 02:51:59 +00:00
use rc, refcell to keep track of references
This commit is contained in:
parent
70d19a2f26
commit
ab3f353457
@ -1,10 +1,12 @@
|
||||
use super::*;
|
||||
use crate::Material;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Beam {
|
||||
pub id: usize,
|
||||
pub points: (usize, usize),
|
||||
pub points: (Weak<RefCell<Point>>, Weak<RefCell<Point>>),
|
||||
pub material: Material,
|
||||
pub cross_section: CrossSection,
|
||||
}
|
||||
@ -15,7 +17,7 @@ pub struct NewBeam {
|
||||
}
|
||||
|
||||
impl Beam {
|
||||
pub fn new(p1: usize, p2: usize, props: NewBeam) -> Beam {
|
||||
pub fn new(p1: Weak<RefCell<Point>>, p2: Weak<RefCell<Point>>, props: NewBeam) -> Beam {
|
||||
Beam {
|
||||
id: 0,
|
||||
points: (p1, p2),
|
||||
@ -24,35 +26,38 @@ impl Beam {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_points<'a>(&self, world: &'a World) -> (&'a Point, &'a Point) {
|
||||
let p1 = world.points.get(&self.points.0).unwrap();
|
||||
let p2 = world.points.get(&self.points.1).unwrap();
|
||||
|
||||
(p1, p2)
|
||||
fn get_points(&self) -> (Rc<RefCell<Point>>, Rc<RefCell<Point>>) {
|
||||
(
|
||||
self.points.0.upgrade().unwrap(),
|
||||
self.points.1.upgrade().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn stiffness(&self, world: &World) -> f32 {
|
||||
self.cross_section.area() * self.material.youngs_modulus / self.length(world)
|
||||
pub fn stiffness(&self) -> f32 {
|
||||
self.cross_section.area() * self.material.youngs_modulus / self.length()
|
||||
}
|
||||
|
||||
pub fn length(&self, world: &World) -> f32 {
|
||||
let (p1, p2) = self.get_points(world);
|
||||
pub fn length(&self) -> f32 {
|
||||
let (p1, p2) = self.get_points();
|
||||
let (p1, p2) = (p1.borrow(), p2.borrow());
|
||||
p1.pos.distance(&p2.pos)
|
||||
}
|
||||
|
||||
pub fn angle(&self, world: &World) -> f32 {
|
||||
let (p1, p2) = self.get_points(world);
|
||||
pub fn angle(&self) -> f32 {
|
||||
let (p1, p2) = self.get_points();
|
||||
let (p1, p2) = (p1.borrow(), p2.borrow());
|
||||
let dx = p1.pos.0 - p2.pos.0;
|
||||
let dy = p1.pos.1 - p2.pos.1;
|
||||
|
||||
(dy / dx).atan()
|
||||
}
|
||||
|
||||
pub fn other_point(&self, p: usize) -> usize {
|
||||
if p == self.points.0 {
|
||||
self.points.1
|
||||
pub fn other_point(&self, p: &Point) -> Option<Rc<RefCell<Point>>> {
|
||||
let (p0, _) = self.get_points();
|
||||
if p.id == p0.borrow().id {
|
||||
self.points.1.upgrade()
|
||||
} else {
|
||||
self.points.0
|
||||
self.points.0.upgrade()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,10 @@ pub enum CrossSection {
|
||||
|
||||
impl CrossSection {
|
||||
pub fn area(&self) -> f32 {
|
||||
let a = match self {
|
||||
match self {
|
||||
Self::Area(a) => *a,
|
||||
Self::Circular(r) => PI * r.powi(2),
|
||||
Self::Rectangular(l1, l2) => l1 * l2,
|
||||
};
|
||||
println!("{:?} {}", self, a);
|
||||
|
||||
a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
use super::super::Vector;
|
||||
use super::BoundaryCondition;
|
||||
use super::{Beam, BoundaryCondition};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Weak;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Point {
|
||||
pub id: usize,
|
||||
pub pos: Vector,
|
||||
pub bc: BoundaryCondition,
|
||||
pub beams: Vec<usize>,
|
||||
pub beams: Vec<Weak<RefCell<Beam>>>,
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
use super::*;
|
||||
use ndarray::prelude::*;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct World {
|
||||
pub points: HashMap<usize, Point>,
|
||||
pub beams: HashMap<usize, Beam>,
|
||||
pub points: HashMap<usize, Rc<RefCell<Point>>>,
|
||||
pub beams: HashMap<usize, Rc<RefCell<Beam>>>,
|
||||
}
|
||||
|
||||
impl World {
|
||||
@ -13,28 +15,23 @@ impl World {
|
||||
let dof = self.points.len() * 2;
|
||||
let mut a: Vec<f32> = vec![0.0; dof.pow(2)];
|
||||
|
||||
// set up forces exerted by displacements of other beams
|
||||
for (_point_id, point) in &self.points {
|
||||
for beam_id in &point.beams {
|
||||
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();
|
||||
for point in self.points.values() {
|
||||
let point = point.borrow();
|
||||
for beam in &point.beams {
|
||||
let beam = beam.upgrade().unwrap();
|
||||
let beam = beam.borrow();
|
||||
let other_point = beam.other_point(&point).unwrap();
|
||||
let other_point = other_point.borrow();
|
||||
let ax = 2 * (point.id - 1);
|
||||
let ay = ax + 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()
|
||||
);
|
||||
let angle = beam.angle();
|
||||
let c2 = angle.cos().powi(2);
|
||||
let s2 = angle.sin().powi(2);
|
||||
let cs = angle.cos() * angle.sin();
|
||||
let stiffness = beam.stiffness();
|
||||
|
||||
// F_AX += K_AB * c2 * (U_AX)
|
||||
a[ax * dof + ax] += stiffness * c2;
|
||||
@ -64,22 +61,28 @@ impl World {
|
||||
|
||||
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) {
|
||||
let p1 = match self.points.get(&id1) {
|
||||
Some(point) => point,
|
||||
None => return Err("Point with id1 not found"),
|
||||
};
|
||||
p1.beams.push(b_id);
|
||||
let p1_id = p1.id;
|
||||
|
||||
let p2 = match self.points.get_mut(&id2) {
|
||||
let p2 = match self.points.get(&id2) {
|
||||
Some(point) => point,
|
||||
None => return Err("Point with id1 not found"),
|
||||
};
|
||||
let p2_id = p2.id;
|
||||
p2.beams.push(b_id);
|
||||
|
||||
let mut b = Beam::new(p1_id, p2_id, new_beam);
|
||||
b.id = b_id;
|
||||
let b = Rc::new(RefCell::new(Beam::new(
|
||||
Rc::downgrade(p1),
|
||||
Rc::downgrade(p2),
|
||||
new_beam,
|
||||
)));
|
||||
|
||||
{
|
||||
b.borrow_mut().id = b_id;
|
||||
}
|
||||
|
||||
p1.borrow_mut().beams.push(Rc::downgrade(&b));
|
||||
p2.borrow_mut().beams.push(Rc::downgrade(&b));
|
||||
|
||||
self.beams.insert(b_id, b);
|
||||
|
||||
Ok(())
|
||||
@ -98,7 +101,7 @@ impl From<Vec<Point>> for World {
|
||||
};
|
||||
|
||||
while let Some(point) = points.pop() {
|
||||
w.points.insert(point.id, point);
|
||||
w.points.insert(point.id, Rc::new(RefCell::new(point)));
|
||||
}
|
||||
|
||||
w
|
||||
|
Loading…
Reference in New Issue
Block a user