11use iter_num_tools:: lin_space;
22use itertools:: Itertools ;
33use nalgebra:: { DMatrix , DVector , SVector , vector} ;
4+ use serde:: { Deserialize , Serialize } ;
45use crate :: errors:: ModelError ;
56use crate :: input:: { BowModel , HandleReference } ;
67use crate :: profile:: profile:: { CurvePoint , ProfileCurve } ;
@@ -13,6 +14,26 @@ pub struct LimbGeometry {
1314 pub section : LayeredCrossSection , // Limb cross sections
1415}
1516
17+ // TODO: Return values s_nodes, u_node might not be needed if the evaluation works properly
18+ #[ derive( Serialize , Deserialize , Default , PartialEq , Debug , Clone ) ]
19+ pub struct DiscreteLimbGeometry {
20+ pub segments : Vec < LinearBeamSegment > , // Linear beam segment properties
21+ pub n_nodes : Vec < f64 > , // Relative lengths of the element nodes
22+ pub s_nodes : Vec < f64 > , // Arc lengths of the element nodes
23+ pub p_nodes : Vec < SVector < f64 , 3 > > , // Positions (x, y, φ) of the element nodes
24+ pub y_nodes : Vec < DVector < f64 > > , // Layer bounds at nodes (y in cross section coordinates)
25+
26+ pub n_eval : Vec < f64 > , // Relative lengths at which the limb quantities are evaluated
27+ pub s_eval : Vec < f64 > , // Arc lengths at which the limb quantities are evaluated
28+ pub p_eval : Vec < SVector < f64 , 3 > > , // Positions (x, y, φ) of the evaluation points
29+ pub y_eval : Vec < DVector < f64 > > , // Layer bounds at eval points (y in cross section coordinates)
30+ pub w_eval : Vec < f64 > , // Widths at eval points
31+ pub h_eval : Vec < f64 > , // Total heights at eval points
32+
33+ pub strain_eval : Vec < DMatrix < f64 > > , // Strain evaluation matrices for each evaluation point
34+ pub stress_eval : Vec < DMatrix < f64 > > , // Stress evaluation matrices for each evaluation point
35+ }
36+
1637impl LimbGeometry {
1738 pub fn new ( input : & BowModel ) -> Result < Self , ModelError > {
1839 // Section properties according to layers, materials and alignment to the profile curve
@@ -59,14 +80,14 @@ impl LimbGeometry {
5980 pub fn discretize ( & self , n_eval_points : usize , n_elements : usize ) -> DiscreteLimbGeometry {
6081 // Arc lengths and normalized positions along the profile where the element nodes are placed
6182 let s_nodes = lin_space ( self . profile . s_start ( ) ..=self . profile . s_end ( ) , n_elements + 1 ) . collect_vec ( ) ;
62- let p_nodes = s_nodes. iter ( ) . map ( |& s| self . profile . normalize ( s) ) . collect_vec ( ) ;
63- let u_nodes = s_nodes. iter ( ) . map ( |& s| self . profile . point ( s) ) . collect_vec ( ) ;
64- let y_nodes = p_nodes . iter ( ) . map ( |& p | self . section . layer_bounds ( p ) . 0 ) . collect_vec ( ) ;
83+ let n_nodes = s_nodes. iter ( ) . map ( |& s| self . profile . normalize ( s) ) . collect_vec ( ) ;
84+ let p_nodes = s_nodes. iter ( ) . map ( |& s| self . profile . point ( s) ) . collect_vec ( ) ;
85+ let y_nodes = n_nodes . iter ( ) . map ( |& n | self . section . layer_bounds ( n ) . 0 ) . collect_vec ( ) ;
6586
6687 // Equidistant evaluation points along the length of the limb
6788 let s_eval = lin_space ( self . profile . s_start ( ) ..=self . profile . s_end ( ) , n_eval_points) . collect_vec ( ) ;
68- let p_eval = s_eval. iter ( ) . map ( |& s| self . profile . normalize ( s) ) . collect_vec ( ) ;
69- let y_eval = p_eval . iter ( ) . map ( |& p | self . section . layer_bounds ( p ) . 0 ) . collect_vec ( ) ;
89+ let n_eval = s_eval. iter ( ) . map ( |& s| self . profile . normalize ( s) ) . collect_vec ( ) ;
90+ let y_eval = n_eval . iter ( ) . map ( |& n | self . section . layer_bounds ( n ) . 0 ) . collect_vec ( ) ;
7091
7192 let segments = s_nodes. iter ( ) . tuple_windows ( ) . enumerate ( ) . map ( |( i, ( & s0, & s1) ) | {
7293 // TODO: Better solution for numerical issues?
@@ -86,45 +107,47 @@ impl LimbGeometry {
86107 LinearBeamSegment :: new ( & self . profile , & self . section , s0, s1, & s_eval)
87108 } ) . collect ( ) ;
88109
89- let strain_eval = p_eval. iter ( ) . map ( |& p| self . section . strain_eval ( p) ) . collect ( ) ;
90- let stress_eval = p_eval. iter ( ) . map ( |& p| self . section . stress_eval ( p) ) . collect ( ) ;
110+ let p_eval = s_eval. iter ( ) . map ( |& s| self . profile . point ( s) ) . collect ( ) ;
111+ let w_eval = n_eval. iter ( ) . map ( |& n| self . section . width ( n) ) . collect ( ) ;
112+ let h_eval = n_eval. iter ( ) . map ( |& n| self . section . height ( n) ) . collect ( ) ;
91113
92- let position = s_eval. iter ( ) . map ( |& s| self . profile . point ( s) ) . collect ( ) ;
93- let width = p_eval. iter ( ) . map ( |& p| self . section . width ( p) ) . collect ( ) ;
94- let height = p_eval. iter ( ) . map ( |& p| self . section . height ( p) ) . collect ( ) ;
114+ let strain_eval = n_eval. iter ( ) . map ( |& n| self . section . strain_eval ( n) ) . collect ( ) ;
115+ let stress_eval = n_eval. iter ( ) . map ( |& n| self . section . stress_eval ( n) ) . collect ( ) ;
95116
96117 DiscreteLimbGeometry {
97118 segments,
119+ n_nodes,
98120 s_nodes,
99- u_nodes ,
121+ p_nodes ,
100122 y_nodes,
123+ n_eval,
101124 s_eval,
102125 y_eval,
103126 strain_eval,
104127 stress_eval,
105- position ,
106- width ,
107- height
128+ p_eval ,
129+ w_eval ,
130+ h_eval
108131 }
109132 }
110133}
111134
112- // TODO: Return values s_nodes, u_node might not be needed if the evaluation works properly
113- pub struct DiscreteLimbGeometry {
114- pub segments : Vec < LinearBeamSegment > , // Linear beam segment properties
115- pub s_nodes : Vec < f64 > , // Arc lengths of the element nodes
116- pub u_nodes : Vec < SVector < f64 , 3 > > , // Positions (x, y, φ) of the element nodes
117- pub y_nodes : Vec < DVector < f64 > > , // Layer bounds at nodes (y in cross section coordinates)
135+ impl TryInto < Vec < u8 > > for DiscreteLimbGeometry {
136+ type Error = ModelError ;
118137
119- pub s_eval : Vec < f64 > , // Arc lengths at which the limb quantities are evaluated (positions, forces, ...)
120- pub y_eval : Vec < DVector < f64 > > , // Layer bounds at eval points (y in cross section coordinates)
121- pub strain_eval : Vec < DMatrix < f64 > > , // Strain evaluation matrices for each evaluation point
122- pub stress_eval : Vec < DMatrix < f64 > > , // Stress evaluation matrices for each evaluation point
138+ // Conversion into MsgPack byte array
139+ fn try_into ( self ) -> Result < Vec < u8 > , Self :: Error > {
140+ rmp_serde:: to_vec_named ( & self ) . map_err ( ModelError :: OutputEncodeMsgPackError ) // TODO: Bett error type?
141+ }
142+ }
143+
144+ impl TryFrom < & [ u8 ] > for DiscreteLimbGeometry {
145+ type Error = ModelError ;
123146
124- // TODO: Unify with rest
125- pub position : Vec < SVector < f64 , 3 > > ,
126- pub width : Vec < f64 > ,
127- pub height : Vec < f64 >
147+ // Conversion from MsgPack byte array
148+ fn try_from ( value : & [ u8 ] ) -> Result < Self , Self :: Error > {
149+ rmp_serde :: from_slice ( value ) . map_err ( ModelError :: OutputDecodeMsgPackError )
150+ }
128151}
129152
130153#[ cfg( test) ]
0 commit comments