Skip to content

Commit 1ee772b

Browse files
committed
Switch order of layers back to their original definition
1 parent 519133d commit 1ee772b

11 files changed

Lines changed: 270 additions & 203 deletions

File tree

gui/source/post/StressPlot.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,24 @@ void StressPlot::updateStresses() {
6060
this->graph(2*iLayer+1)->data()->clear();
6161

6262
for(size_t iLength = 0; iLength < common.limb.length.size(); ++iLength) {
63-
// Back
64-
this->graph(2*iLayer)->addData(
65-
quantity_length.getUnit().fromBase(common.limb.length[iLength]),
66-
quantity_stress.getUnit().fromBase(std::get<1>(states.layer_stress[index][iLayer][iLength]))
67-
);
68-
69-
// Belly
70-
this->graph(2*iLayer+1)->addData(
71-
quantity_length.getUnit().fromBase(common.limb.length[iLength]),
72-
quantity_stress.getUnit().fromBase(std::get<0>(states.layer_stress[index][iLayer][iLength]))
73-
);
63+
double stress_back = std::get<0>(states.layer_stress[index][iLayer][iLength]);
64+
double stress_belly = std::get<1>(states.layer_stress[index][iLayer][iLength]);
65+
66+
// Only plot stresses != 0. TODO: Find a solution to plot stresses over the domain of the layers instead.
67+
if(stress_back != 0.0) {
68+
this->graph(2*iLayer)->addData(
69+
quantity_length.getUnit().fromBase(common.limb.length[iLength]),
70+
quantity_stress.getUnit().fromBase(stress_back)
71+
);
72+
}
73+
74+
// Only plot stresses != 0. TODO: Find a solution to plot stresses over the domain of the layers instead.
75+
if(stress_belly != 0.0) {
76+
this->graph(2*iLayer+1)->addData(
77+
quantity_length.getUnit().fromBase(common.limb.length[iLength]),
78+
quantity_stress.getUnit().fromBase(stress_belly)
79+
);
80+
}
7481
}
7582
}
7683
}

gui/source/pre/views/limb3d/LimbMesh.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,46 @@ LimbMesh::LimbMesh(const BowModel& bow, const LimbInfo& geometry)
5050
points_l_next[j] = center_next - 0.5*w_next*normal_w_next + y_next[j]*normal_h_next;
5151
}
5252

53+
// Sides
54+
for(size_t iLayer = 0; iLayer < nLayers; ++iLayer) {
55+
// Only layers with height != 0
56+
if(y_prev[iLayer] != y_prev[iLayer+1] || y_next[iLayer] != y_next[iLayer+1]) {
57+
// Left
58+
addQuad(points_l_prev[iLayer], points_l_next[iLayer], points_l_next[iLayer+1], points_l_prev[iLayer+1], colors[iLayer]);
59+
60+
// Right
61+
addQuad(points_r_prev[iLayer], points_r_prev[iLayer+1], points_r_next[iLayer+1], points_r_next[iLayer], colors[iLayer]);
62+
63+
// Start
64+
if(iSegment == 0) {
65+
addQuad(points_r_prev[iLayer], points_l_prev[iLayer], points_l_prev[iLayer+1], points_r_prev[iLayer+1], colors[iLayer]);
66+
}
67+
// End
68+
if(iSegment == nSegments - 1) {
69+
addQuad(points_r_next[iLayer], points_r_next[iLayer+1], points_l_next[iLayer+1], points_l_next[iLayer], colors[iLayer]);
70+
}
71+
}
72+
}
73+
74+
// Back
75+
for(size_t iLayer = 0; iLayer < nLayers; ++iLayer) {
76+
// Find first layer with height != 0
77+
if(y_prev[iLayer] != y_prev[iLayer+1] || y_next[iLayer] != y_next[iLayer+1]) {
78+
addQuad(points_l_prev[iLayer], points_r_prev[iLayer], points_r_next[iLayer], points_l_next[iLayer], colors[iLayer]);
79+
break;
80+
}
81+
}
82+
83+
// Belly
84+
for(size_t iLayer = nLayers; iLayer > 0; --iLayer) {
85+
// Find first layer with height != 0
86+
if(y_prev[iLayer] != y_prev[iLayer-1] || y_next[iLayer] != y_next[iLayer-1]) {
87+
addQuad(points_l_prev[iLayer], points_l_next[iLayer], points_r_next[iLayer], points_r_prev[iLayer], colors[iLayer-1]);
88+
break;
89+
}
90+
}
91+
92+
/*
5393
// Sides
5494
for(size_t jLayer = 0; jLayer < nLayers; ++jLayer) {
5595
// Only layers with height != 0
@@ -89,6 +129,7 @@ LimbMesh::LimbMesh(const BowModel& bow, const LimbInfo& geometry)
89129
break;
90130
}
91131
}
132+
*/
92133
}
93134
}
94135

gui/source/solver/BowModel.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,18 @@ void to_json(nlohmann::json& obj, const ProfileSegment& input) {
7878
}
7979
}
8080

81-
void from_json(const nlohmann::json& obj, ProfileSegment& input) {
81+
void from_json(const nlohmann::json& obj, ProfileSegment& output) {
8282
if(obj.at("type") == "line") {
83-
input = obj.at("parameters").get<Line>();
83+
output = obj.at("parameters").get<Line>();
8484
}
8585
else if(obj.at("type") == "arc") {
86-
input = obj.at("parameters").get<Arc>();
86+
output = obj.at("parameters").get<Arc>();
8787
}
8888
else if(obj.at("type") == "spiral") {
89-
input = obj.at("parameters").get<Spiral>();
89+
output = obj.at("parameters").get<Spiral>();
9090
}
9191
else if(obj.at("type") == "spline") {
92-
input = obj.at("parameters").get<Spline>();
92+
output = obj.at("parameters").get<Spline>();
9393
}
9494
else {
9595
throw std::runtime_error("Unknown segment type");
@@ -123,28 +123,28 @@ void to_json(nlohmann::json& obj, const LayerAlignment& input) {
123123
}
124124
}
125125

126-
void from_json(const nlohmann::json& obj, LayerAlignment& input) {
126+
void from_json(const nlohmann::json& obj, LayerAlignment& output) {
127127
if(obj.at("type") == "section_back") {
128-
input = SectionBack{};
128+
output = SectionBack{};
129129
}
130130
else if(obj.at("type") == "section_belly") {
131-
input = SectionBelly{};
131+
output = SectionBelly{};
132132
}
133133
else if(obj.at("type") == "section_center") {
134-
input = SectionCenter{};
134+
output = SectionCenter{};
135135
}
136136
else if(obj.at("type") == "layer_back") {
137-
input = LayerBack {
137+
output = LayerBack {
138138
.layer = obj.at("layer")
139139
};
140140
}
141141
else if(obj.at("type") == "layer_belly") {
142-
input = LayerBelly {
142+
output = LayerBelly {
143143
.layer = obj.at("layer")
144144
};
145145
}
146146
else if(obj.at("type") == "layer_center") {
147-
input = LayerCenter {
147+
output = LayerCenter {
148148
.layer = obj.at("layer")
149149
};
150150
}

gui/source/solver/BowModel.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
157157
using ProfileSegment = std::variant<Line, Arc, Spiral, Spline>;
158158

159159
void to_json(nlohmann::json& obj, const ProfileSegment& input);
160-
void from_json(const nlohmann::json& obj, ProfileSegment& input);
160+
void from_json(const nlohmann::json& obj, ProfileSegment& output);
161161

162162
struct Profile {
163163
std::list<ProfileSegment> segments; // List to keep references valid when swapping around elements
@@ -177,7 +177,7 @@ struct LayerCenter { std::string layer; };
177177
using LayerAlignment = std::variant<SectionBack, SectionBelly, SectionCenter, LayerBack, LayerBelly, LayerCenter>;
178178

179179
void to_json(nlohmann::json& obj, const LayerAlignment& input);
180-
void from_json(const nlohmann::json& obj, LayerAlignment& input);
180+
void from_json(const nlohmann::json& obj, LayerAlignment& output);
181181

182182
struct Material {
183183
std::string name;

rust/virtualbow/src/geometry.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ pub struct DiscreteLimbGeometry {
2222
pub n_nodes: Vec<f64>, // Relative lengths of the element nodes
2323
pub s_nodes: Vec<f64>, // Arc lengths of the element nodes
2424
pub p_nodes: Vec<SVector<f64, 3>>, // Positions (x, y, φ) of the element nodes
25-
pub y_nodes: Vec<DVector<f64>>, // Layer bounds at nodes (y in cross section coordinates)
26-
pub h_nodes: Vec<DVector<f64>>, // Layer heights at nodes
25+
pub y_nodes: Vec<DVector<f64>>, // Layer bounds (back to belly) at nodes (y in cross-section coordinates)
26+
pub h_nodes: Vec<DVector<f64>>, // Layer heights (back to belly) at nodes
2727

2828
pub p_control: Vec<SVector<f64, 3>>, // Positions (x, y, φ) of the control points
2929

3030
pub n_eval: Vec<f64>, // Relative lengths at which the limb quantities are evaluated
3131
pub s_eval: Vec<f64>, // Arc lengths at which the limb quantities are evaluated
3232
pub p_eval: Vec<SVector<f64, 3>>, // Positions (x, y, φ) of the evaluation points
33-
pub y_eval: Vec<DVector<f64>>, // Layer bounds at eval points (y in cross section coordinates)
33+
pub y_eval: Vec<DVector<f64>>, // Layer bounds at eval points (y in cross-section coordinates)
3434
pub h_eval: Vec<DVector<f64>>, // Layer heights at eval points
3535
pub w_eval: Vec<f64>, // Widths at eval points
3636

@@ -47,8 +47,8 @@ impl LimbGeometry {
4747
// First the eccentricity, i.e. the distance of the reference point from the profile curve at the root of the limb is calculated.
4848
// Then the starting point according to handle dimensions, eccentricity and limb root angle follows.
4949
let eccentricity = match input.dimensions.handle_reference {
50-
HandleReference::Back => section.section_bounds(0.0).1,
51-
HandleReference::Belly => section.section_bounds(0.0).0,
50+
HandleReference::Back => section.section_bounds(0.0).0,
51+
HandleReference::Belly => section.section_bounds(0.0).1,
5252
HandleReference::Profile => 0.0,
5353
};
5454
let start = CurvePoint::new(0.0, input.dimensions.handle_angle, vector![
@@ -61,7 +61,7 @@ impl LimbGeometry {
6161
// Since we can't check this analytically, we check for a fixed number of points along the length of the limb
6262
for s in lin_space(profile.length_start()..=profile.length_end(), 1000) { // TODO: Magic number
6363
let kappa = profile.curvature(s);
64-
let (y_belly, y_back) = section.section_bounds(profile.normalize(s));
64+
let (y_back, y_belly) = section.section_bounds(profile.normalize(s));
6565

6666
// Intersection at the back side happens when the curvature is positive, i.e. curved in the back direction and the y coordinate of the back is larger or equal to the radius of curvature
6767
// Intersection at the belly side happens when the curvature is negative, i.e. curved in the belly direction and the y coordinate of the belly is larger or equal to the radius of curvature

rust/virtualbow/src/input/versions/latest.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,11 @@ impl From<version3::BowModel> for BowModel {
160160
fn from(model: version3::BowModel) -> BowModel {
161161
let settings = Settings {
162162
num_limb_elements: model.settings.n_limb_elements,
163-
num_limb_eval_points: 100,
164163
min_draw_resolution: model.settings.n_draw_steps,
165164
max_draw_resolution: model.settings.n_draw_steps,
166165
arrow_clamp_force: model.settings.arrow_clamp_force,
167-
string_compression_factor: 1e-6,
168166
timespan_factor: model.settings.time_span_factor,
169-
timeout_factor: 5.0,
170-
min_timestep: 1e-6,
171-
max_timestep: 1e-4,
172-
steps_per_period: 250,
167+
.. Default::default()
173168
};
174169

175170
let dimensions = Dimensions {
@@ -181,22 +176,29 @@ impl From<version3::BowModel> for BowModel {
181176
handle_offset: model.dimensions.handle_setback,
182177
};
183178

184-
let materials = model.materials.iter().map(|material| Material {
185-
name: material.name.clone(),
186-
color: material.color.clone(),
187-
density: material.rho,
188-
youngs_modulus: material.E,
189-
shear_modulus: material.E/(2.0*(1.0 + 0.4)), // Shear modulus was newly added. Estimate for poisson ratio v = 0.4.
190-
tensile_strength: 0.0, // Field was newly introduced, value unknown.
191-
compressive_strength: 0.0, // Field was newly introduced, value unknown.
192-
safety_margin: 0.0 // Field was newly introduced, value unknown.
179+
let materials = model.materials.iter().map(|material| {
180+
let mut shear_modulus = material.E/(2.0*(1.0 + 0.4)); // Shear modulus was newly added. Estimate for poisson ratio v = 0.4
181+
let factor = 0.1*material.E;
182+
shear_modulus = (shear_modulus/factor).round()*factor; // Round to precision based on E
183+
shear_modulus = f64::max(shear_modulus, factor); // Minimum if rounded to zero
184+
185+
Material {
186+
name: material.name.clone(),
187+
color: material.color.clone(),
188+
density: material.rho,
189+
youngs_modulus: material.E,
190+
shear_modulus,
191+
tensile_strength: 0.0, // Field was newly introduced, value unknown.
192+
compressive_strength: 0.0, // Field was newly introduced, value unknown.
193+
safety_margin: 0.0 // Field was newly introduced, value unknown.
194+
}
193195
}).collect_vec();
194196

195197
let layers = model.layers.iter().map(|layer| Layer {
196198
name: layer.name.clone(),
197199
material: materials[layer.material].name.clone(),
198200
height: layer.height.clone(),
199-
}).rev().collect_vec(); // Layers were previously defined from back to belly, but are now from belly to back (direction of the y axis), so the old layers have to be reversed
201+
}).collect_vec();
200202

201203
let section = Section {
202204
alignment: LayerAlignment::SectionBack, // Field was newly introduced. Previously the profile curve was always aligned with the cross section's back.

rust/virtualbow/src/output/result.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ pub struct State {
136136
pub limb_strain: Vec<SVector<f64, 3>>, // epsilon, kappa, gamma
137137
pub limb_force: Vec<SVector<f64, 3>>, // N, Q, M
138138

139-
pub layer_strain: Vec<Vec<[f64; 2]>>, // layer, length, belly/back
140-
pub layer_stress: Vec<Vec<[f64; 2]>>, // layer, length, belly/back
139+
pub layer_strain: Vec<Vec<[f64; 2]>>, // layer, length, back/belly
140+
pub layer_stress: Vec<Vec<[f64; 2]>>, // layer, length, back/belly
141141

142142
pub arrow_pos: f64,
143143
pub arrow_vel: f64,

0 commit comments

Comments
 (0)