RatRod_rs/
lib.rs

1pub mod node;
2pub mod model;
3pub mod elements;
4pub mod material;
5pub mod section;
6
7#[cfg(test)]
8mod tests {
9    use sparse_matrix::vector::Vector;
10
11    use crate::{elements::ElementType, model::Model, node::Node, material::Material, section::Section};
12
13    use more_asserts::assert_le;
14
15    #[test]
16    fn spring_in_tension() {
17        let mut model = Model::new(2, 0.00000001);
18        model.add_node(Node {
19            x : 0.,
20            y : 0.,
21            z : 0.
22        }).add_node(Node {
23                x : 1.,
24                y : 0.,
25                z : 0.
26            }).add_material(Material {
27                e : 1.
28            }).add_section(Section {
29                s : 1.,
30                i : 1.
31            }).add_element(ElementType::Truss, vec![0,1], 0, 0)
32            .add_u_boundary_condition(0, 0, 0.)
33            .add_u_boundary_condition(0, 1, 0.)
34            .set_force(1, 0, 1.);
35
36        model.solve();
37
38        let u = model.u;
39        let f = model.f;
40        assert_eq!(u, Vector { values: vec![0.0, 0.0, 0.0, 1.0, 0.0, 0.0] });
41        assert_eq!(f, Vector { values: vec![-1.0, 0.0, 0.0, 1.0, 0.0, 0.0] });
42    }
43
44    #[test]
45    fn beam_in_flexion() {
46        let mut model = Model::new(2, 0.00000001);
47        model.add_node(Node {
48            x : 0.,
49            y : 0.,
50            z : 0.
51        }).add_node(Node {
52                x : 1.,
53                y : 0.,
54                z : 0.
55            }).add_material(Material {
56                e : 1.
57            }).add_section(Section {
58                s : 1.,
59                i : 1.
60            }).add_element(ElementType::Beam, vec![0,1], 0, 0)
61            .add_u_boundary_condition(0, 0, 0.)
62            .add_u_boundary_condition(0, 1, 0.)
63            .add_u_boundary_condition(0, 2, 0.)
64            .set_force(1, 1, 3.);
65
66        model.solve();
67
68        let u = model.u;
69        let f = model.f;
70        assert_le!((&(&u - &Vector { values: vec![0.0, 0.0, 0.0, 0.0, 1.0, 1.5] }).unwrap() * &(&u - &Vector { values: vec![0.0, 0.0, 0.0, 0.0, 1.0, 1.5] }).unwrap()).unwrap().sqrt(), 0.01);
71        assert_le!((&(&f - &Vector { values: vec![0.0, -3.0, -3.0, 0.0, 3.0, 0.0] }).unwrap() * &(&u - &Vector { values: vec![0.0, -3.0, -3.0, 0.0, 3.0, 0.0] }).unwrap()).unwrap().sqrt(), 0.01);
72    }
73
74    #[test]
75    fn multielement_beam_in_flexion() {
76        let mut model = Model::new(2, 0.00000001);
77        model.add_node(Node {
78            x : 0.,
79            y : 0.,
80            z : 0.
81        }).add_node(Node {
82                x : 0.5,
83                y : 0.,
84                z : 0.
85            }).add_node(Node {
86                x : 1.,
87                y : 0.,
88                z : 0.
89            }).add_material(Material {
90                e : 1.
91            }).add_section(Section {
92                s : 1.,
93                i : 1.
94            }).add_element(ElementType::Beam, vec![0,1], 0, 0)
95            .add_element(ElementType::Beam, vec![1,2], 0, 0)
96            .add_u_boundary_condition(0, 0, 0.)
97            .add_u_boundary_condition(0, 1, 0.)
98            .add_u_boundary_condition(0, 2, 0.)
99            .set_force(2, 1, 3.);
100
101        model.solve();
102
103        let u = model.u;
104        let f = model.f;
105        assert_le!((&(&u - &Vector { values: vec![0.0, 0.0, 0.0, 0.0, 15./48., 9./8., 0.0, 1.0, 1.5] }).unwrap() * &(&u - &Vector { values: vec![0.0, 0.0, 0.0, 0.0, 15./48., 9./8., 0.0, 1.0, 1.5] }).unwrap()).unwrap().sqrt(), 0.01);
106        assert_le!((&(&f - &Vector { values: vec![0.0, -3.0, -3.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0] }).unwrap() * &(&u - &Vector { values: vec![0.0, -3.0, -3.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0] }).unwrap()).unwrap().sqrt(), 0.01);
107    }
108    #[test]
109    fn save_model() {
110        let mut model = Model::new(2, 0.00000001);
111        model.add_node(Node {
112            x : 0.,
113            y : 0.,
114            z : 0.
115        }).add_node(Node {
116                x : 0.5,
117                y : 0.,
118                z : 0.
119            }).add_node(Node {
120                x : 1.,
121                y : 0.,
122                z : 0.
123            }).add_material(Material {
124                e : 1.
125            }).add_section(Section {
126                s : 1.,
127                i : 1.
128            }).add_element(ElementType::Beam, vec![0,1], 0, 0)
129            .add_element(ElementType::Beam, vec![1,2], 0, 0)
130            .add_u_boundary_condition(0, 0, 0.)
131            .add_u_boundary_condition(0, 1, 0.)
132            .add_u_boundary_condition(0, 2, 0.)
133            .set_force(2, 1, 3.);
134        model.save("model_test.json");
135    }
136
137    #[test]
138    fn load_model() {
139        let mut model = Model::new(2, 0.00000001);
140        model.add_node(Node {
141            x : 0.,
142            y : 0.,
143            z : 0.
144        }).add_node(Node {
145                x : 0.5,
146                y : 0.,
147                z : 0.
148            }).add_node(Node {
149                x : 1.,
150                y : 0.,
151                z : 0.
152            }).add_material(Material {
153                e : 1.
154            }).add_section(Section {
155                s : 1.,
156                i : 1.
157            }).add_element(ElementType::Beam, vec![0,1], 0, 0)
158            .add_element(ElementType::Beam, vec![1,2], 0, 0)
159            .add_u_boundary_condition(0, 0, 0.)
160            .add_u_boundary_condition(0, 1, 0.)
161            .add_u_boundary_condition(0, 2, 0.)
162            .set_force(2, 1, 3.);
163        model.save("model_test.json");
164        let test = Model::load("model_test.json");
165        assert_eq!(model, test);
166    }
167}
168
169