use eframe::egui;
use crate::Thermodynamics::DBhandlers::transport_api::{
LambdaUnit, TransportCalculator, ViscosityUnit, create_transport_calculator_by_name,
};
use crate::Thermodynamics::thermo_lib_api::ThermoData;
#[derive(Debug)]
pub struct TransportApp {
transport_data: ThermoData,
substance_input: String,
selected_library: String,
temperature: String,
pressure: String,
search_results: String,
available_substances: Vec<String>,
selected_substance: String,
calculated_lambda: Option<f64>,
calculated_viscosity: Option<f64>,
lambda_unit: LambdaUnit,
viscosity_unit: ViscosityUnit,
}
impl Default for TransportApp {
fn default() -> Self {
let transport_data = ThermoData::new();
let selected_library = if !transport_data.transport_libs.is_empty() {
transport_data.transport_libs[0].clone()
} else {
"Aramco_transport".to_string()
};
let available_substances = transport_data
.LibThermoData
.get(&selected_library)
.map(|lib_data| lib_data.keys().cloned().collect())
.unwrap_or_default();
Self {
transport_data,
substance_input: String::new(),
selected_library,
temperature: "298.15".to_string(),
pressure: "101325.0".to_string(),
search_results: "No search performed yet".to_string(),
available_substances,
selected_substance: String::new(),
calculated_lambda: None,
calculated_viscosity: None,
lambda_unit: LambdaUnit::MKWPerMK,
viscosity_unit: ViscosityUnit::MKPaS,
}
}
}
impl TransportApp {
pub fn new() -> Self {
Self::default()
}
fn update_substances_for_library(&mut self) {
self.available_substances = self
.transport_data
.LibThermoData
.get(&self.selected_library)
.map(|lib_data| lib_data.keys().cloned().collect())
.unwrap_or_default();
}
fn search_substance_by_name(&mut self, substance_name: &str) {
self.selected_substance = substance_name.to_string();
if let Some(lib_data) = self
.transport_data
.LibThermoData
.get(&self.selected_library)
{
if let Some(substance_data) = lib_data.get(substance_name) {
self.search_results = format!(
"Found '{}' in library '{}':\n\n{}",
substance_name,
self.selected_library,
serde_json::to_string_pretty(substance_data)
.unwrap_or("Error formatting data".to_string())
);
} else {
self.search_results = format!(
"Substance '{}' not found in library '{}'",
substance_name, self.selected_library
);
}
} else {
self.search_results = format!("Library '{}' not found", self.selected_library);
}
}
#[allow(dead_code)]
fn search_substance(&mut self) {
if self.substance_input.is_empty() {
self.search_results = "Please enter a substance name".to_string();
return;
}
if let Some(lib_data) = self
.transport_data
.LibThermoData
.get(&self.selected_library)
{
if let Some(substance_data) = lib_data.get(&self.substance_input) {
self.search_results = format!(
"Found '{}' in library '{}':\n\n{}",
self.substance_input,
self.selected_library,
serde_json::to_string_pretty(substance_data)
.unwrap_or("Error formatting data".to_string())
);
} else {
self.search_results = format!(
"Substance '{}' not found in library '{}'",
self.substance_input, self.selected_library
);
}
} else {
self.search_results = format!("Library '{}' not found", self.selected_library);
}
}
fn calculate_properties(&mut self) {
let temp_result = self.temperature.parse::<f64>();
let pres_result = self.pressure.parse::<f64>();
let substance_name = if !self.selected_substance.is_empty() {
&self.selected_substance
} else {
&self.substance_input
};
if substance_name.is_empty() {
self.search_results = "Please select a substance first".to_string();
return;
}
match (temp_result, pres_result) {
(Ok(t), Ok(_p)) => {
if let Some(lib_data) = self
.transport_data
.LibThermoData
.get(&self.selected_library)
{
if let Some(substance_data) = lib_data.get(substance_name) {
match self.perform_transport_calculation(substance_data, t) {
Ok((lambda, viscosity)) => {
self.calculated_lambda = Some(lambda);
self.calculated_viscosity = Some(viscosity);
let lambda_unit_str = match self.lambda_unit {
LambdaUnit::WPerMK => "W/m路K",
LambdaUnit::MWPerMK => "mW/m路K",
LambdaUnit::MKWPerMK => "渭W/m路K",
LambdaUnit::MKWPerSMK => "渭W/s路m路K",
};
let viscosity_unit_str = match self.viscosity_unit {
ViscosityUnit::KgPerMS => "kg/m路s",
ViscosityUnit::PaS => "Pa路s",
ViscosityUnit::MKPaS => "渭Pa路s",
};
self.search_results = format!(
"Transport properties for '{}' at T = {} K:\n\nThermal conductivity = {:.5} {}\nViscosity = {:.8} {}",
substance_name,
t,
lambda,
lambda_unit_str,
viscosity,
viscosity_unit_str
);
}
Err(e) => {
self.search_results = format!("Calculation error: {}", e);
}
}
} else {
self.search_results =
format!("Substance '{}' not found for calculations", substance_name);
}
} else {
self.search_results = format!(
"Library '{}' not available for calculations",
self.selected_library
);
}
}
_ => {
self.search_results = "Invalid temperature or pressure values".to_string();
}
}
}
fn perform_transport_calculation(
&self,
substance_data: &serde_json::Value,
temperature: f64,
) -> Result<(f64, f64), String> {
let mut transport_calc = create_transport_calculator_by_name(&self.selected_library);
transport_calc
.from_serde(substance_data.clone())
.map_err(|e| format!("Failed to load data: {}", e))?;
transport_calc
.set_lambda_unit(Some(self.lambda_unit))
.map_err(|e| format!("Failed to set lambda unit: {}", e))?;
transport_calc
.set_viscosity_unit(Some(self.viscosity_unit))
.map_err(|e| format!("Failed to set viscosity unit: {}", e))?;
transport_calc
.extract_coefficients(temperature)
.map_err(|e| format!("Failed to extract coefficients: {}", e))?;
let mut lambda: f64 = 0.0;
if self.selected_library == "CEA" {
lambda = transport_calc
.calculate_lambda(None, None, temperature)
.map_err(|e| format!("Failed to calculate thermal conductivity: {}", e))?;
} else {
};
let viscosity = transport_calc
.calculate_viscosity(temperature)
.map_err(|e| format!("Failed to calculate viscosity: {}", e))?;
Ok((lambda, viscosity))
}
pub fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
egui::Window::new("Transport Properties Analysis")
.open(open)
.default_size([1200.0, 800.0])
.show(ctx, |ui| {
ui.heading("Transport Properties and Calculations");
ui.separator();
ui.horizontal(|ui| {
ui.vertical(|ui| {
ui.set_width(200.0);
ui.set_min_height(600.0);
ui.heading("List of Substances");
ui.horizontal(|ui| {
ui.label("Search:");
ui.text_edit_singleline(&mut self.substance_input);
});
ui.separator();
egui::ScrollArea::vertical()
.max_height(1200.0)
.show(ui, |ui| {
for substance in &self.available_substances.clone() {
if self.substance_input.is_empty()
|| substance
.to_lowercase()
.contains(&self.substance_input.to_lowercase())
{
if ui.selectable_label(false, substance).clicked() {
self.search_substance_by_name(substance);
}
}
}
});
ui.separator();
egui::ComboBox::from_label("Library Source")
.selected_text(&self.selected_library)
.show_ui(ui, |ui| {
for library in &self.transport_data.transport_libs.clone() {
if ui
.selectable_value(
&mut self.selected_library,
library.clone(),
library,
)
.clicked()
{
self.update_substances_for_library();
}
}
});
});
ui.separator();
ui.vertical(|ui| {
ui.group(|ui| {
ui.label("Substance Information:");
egui::ScrollArea::vertical()
.id_salt("substance_info")
.max_height(300.0)
.show(ui, |ui| {
ui.text_edit_multiline(&mut self.search_results);
});
});
ui.add_space(10.0);
ui.group(|ui| {
ui.label("Calculation Parameters:");
ui.horizontal(|ui| {
ui.label("Temperature (K):");
ui.text_edit_singleline(&mut self.temperature);
ui.label("Pressure (Pa):");
ui.text_edit_singleline(&mut self.pressure);
if ui.button("馃М Calculate Properties").clicked() {
self.calculate_properties();
}
});
ui.horizontal(|ui| {
ui.label("Lambda Unit:");
ui.radio_value(&mut self.lambda_unit, LambdaUnit::WPerMK, "W/m路K");
ui.radio_value(
&mut self.lambda_unit,
LambdaUnit::MWPerMK,
"mW/m路K",
);
ui.radio_value(
&mut self.lambda_unit,
LambdaUnit::MKWPerMK,
"渭W/m路K",
);
});
ui.horizontal(|ui| {
ui.label("Viscosity Unit:");
ui.radio_value(
&mut self.viscosity_unit,
ViscosityUnit::PaS,
"Pa路s",
);
ui.radio_value(
&mut self.viscosity_unit,
ViscosityUnit::MKPaS,
"渭Pa路s",
);
});
});
ui.separator();
ui.horizontal(|ui| {
if ui.button("Clear Results").clicked() {
self.search_results = "Results cleared".to_string();
}
if ui.button("Export Data").clicked() {
self.search_results +=
"\n\nExport functionality not yet implemented";
}
if ui.button("Load from File").clicked() {
self.search_results +=
"\n\nFile loading functionality not yet implemented";
}
});
});
});
});
}
}