use serde::{Serialize, Deserialize};
use serde_json;
pub mod single_wing;
use super::*;
use single_wing::WingBuilder;
use crate::error::Error;
use super::force_calculations::ForceCalculationSettings;
use corrections::circulation::CirculationCorrectionBuilder;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LineForceModelBuilder {
pub wing_builders: Vec<WingBuilder>,
pub nr_sections: usize,
#[serde(default = "LineForceModel::default_density")]
pub density: Float,
#[serde(default)]
pub circulation_correction: CirculationCorrectionBuilder,
#[serde(default)]
pub angle_of_attack_correction: AngleOfAttackCorrection,
#[serde(default)]
pub output_coordinate_system: CoordinateSystem,
#[serde(default)]
pub rotation_type: RotationType,
#[serde(default)]
pub local_wing_angles: Vec<Float>,
#[serde(default)]
pub rotation: SpatialVector,
#[serde(default)]
pub translation: SpatialVector,
#[serde(default)]
pub force_calculation_settings: ForceCalculationSettings
}
impl LineForceModelBuilder {
pub fn new(nr_sections: usize) -> Self {
LineForceModelBuilder {
wing_builders: Vec::new(),
nr_sections,
density: LineForceModel::default_density(),
circulation_correction: Default::default(),
angle_of_attack_correction: Default::default(),
output_coordinate_system: CoordinateSystem::Global,
rotation_type: RotationType::XYZ,
local_wing_angles: Vec::new(),
rotation: SpatialVector::from([0.0, 0.0, 0.0]),
translation: SpatialVector::from([0.0, 0.0, 0.0]),
force_calculation_settings: ForceCalculationSettings::default()
}
}
pub fn new_from_string(setup_string: &str) -> Result<Self, Error> {
let serde_res = serde_json::from_str(setup_string)?;
Ok(serde_res)
}
pub fn add_wing(&mut self, wing_builder: WingBuilder) {
self.wing_builders.push(wing_builder);
}
pub fn build(&self) -> LineForceModel {
self.build_with_nr_sections(self.nr_sections)
}
pub fn build_with_nr_sections(&self, nr_sections: usize) -> LineForceModel {
let mut line_force_model = LineForceModel::new(self.density);
for wing_builder in &self.wing_builders {
let wing = wing_builder.build(nr_sections);
line_force_model.add_wing(&wing);
}
let circulation_correction = self.circulation_correction.build(
&line_force_model
);
line_force_model.circulation_correction = circulation_correction;
line_force_model.angle_of_attack_correction = self.angle_of_attack_correction.clone();
line_force_model.output_coordinate_system = self.output_coordinate_system;
if self.local_wing_angles.len() > 0 {
if self.local_wing_angles.len() != line_force_model.nr_wings() {
panic!("The number of local wing angles does not match the number of wings.");
}
line_force_model.local_wing_angles = self.local_wing_angles.clone();
}
line_force_model.force_calculation_settings = self.force_calculation_settings.clone();
line_force_model.rigid_body_motion.translation = self.translation;
line_force_model.rigid_body_motion.rotation = self.rotation;
line_force_model.update_calculated_values_after_create();
line_force_model
}
}