From f4cb039db995a2d17962d885f3e86cb93a86cd29 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sat, 29 Mar 2025 20:10:02 -0400 Subject: [PATCH 01/21] starting basic structure of the properties databases --- oscps-lib/src/component.rs | 163 ------------------ oscps-lib/src/lib.rs | 2 +- oscps-lib/src/properties.rs | 163 ++++++++++++++++++ .../src/properties/pure_species_properties.rs | 8 + 4 files changed, 172 insertions(+), 164 deletions(-) delete mode 100644 oscps-lib/src/component.rs create mode 100644 oscps-lib/src/properties.rs create mode 100644 oscps-lib/src/properties/pure_species_properties.rs diff --git a/oscps-lib/src/component.rs b/oscps-lib/src/component.rs deleted file mode 100644 index a4581cd..0000000 --- a/oscps-lib/src/component.rs +++ /dev/null @@ -1,163 +0,0 @@ -//! # Component -//! -//! Contains chemical properties for components in the simulation. - -extern crate uom; - -extern crate pubchem; -use anyhow::Result; -use std::{thread,time::Duration}; - - -#[allow(dead_code)] -/// This will hold the list of chemicals used within the simulation -pub struct ChemicalList { - chemical_list: Vec, -} - -#[allow(dead_code)] -/// A struct to store information regarding the chemical properties of a -/// particular substance. The "Chemical" struct is a wrapper for the -/// pubchem::Compound object -pub struct Chemical { - /// The (PubChem)[] CID of a compound. - pub pubchem_obj: pubchem::Compound, - /// Physical properties of a compound. - pub properties: ChemicalProperties, -} - -#[allow(dead_code)] -/// Used by the "Chemical" struct to create the pubchem::Compound obj based on -/// either the chemical name or the pubchem id of the chemical -pub enum ChemicalIdentifier { - /// The PubChem ID of the component. - PubchemID(u32), - /// The actual name of the component. - CompoundName(String), -} - -#[allow(dead_code)] -/// Implementation of the chemical of interest. -impl Chemical { - /// Constructs a new chemical. - pub fn new(identifier: ChemicalIdentifier) -> Result { - let pubchem_chemical_object = match identifier { - ChemicalIdentifier::PubchemID(id) => pubchem::Compound::new(id), - ChemicalIdentifier::CompoundName(name) => pubchem::Compound::with_name(name.as_str()), - }; - let mut request_counter = 0; - let mut cid_vec = None; - while request_counter <= 10 { - match pubchem_chemical_object.cids(){ - Ok(cid_list) => { - cid_vec = Some(cid_list); - break; - }, - _ => { - request_counter += 1; - thread::sleep(Duration::from_secs(10)); - } - }; - } - - // let cid_vec = pubchem_chemical_object.cids().unwrap(); - let cid: i32 = cid_vec.unwrap()[0]; - let prop = ChemicalProperties::new(cid).unwrap(); - Ok(Chemical { - pubchem_obj: pubchem_chemical_object, - properties: prop, - }) - } - /// Returns the pubchem object for the compound. - pub fn get_pubchem_obj(&self) -> &pubchem::Compound { - &self.pubchem_obj - } - - /// Returns the "ChemicalProperties" object for the "Chemical" object. - pub fn get_properties(&self) -> &ChemicalProperties { - &self.properties - } -} - -#[allow(dead_code)] -/// Struct containing properties of a chemical -pub struct ChemicalProperties { - /// Contains the molar mass of a compound. - pub molar_mass: f64, // kg/mol - /// Critial temperature of a compoound. - pub critical_temp: f64, // K - /// The critical pressure of a compound. - pub critical_pressure: f64, // Pa - /// Acentric factor of a compound. - pub acentric_factor: f64, - ///Heat capacity Coefficient A - pub const_a: f64, - ///Heat capacity Coefficient B - pub const_b: f64, - ///Heat capacity Coefficient C - pub const_c: f64, - ///Heat capacity Coefficient D - pub const_d: f64 -} - -/// Implementation of the ChemicalProperties struct. -impl ChemicalProperties { - /// Constructor for the ChemicalProperties struct. - pub fn new(cid: i32) -> Result { - println!("Recieving information for compound/element {cid}"); - Ok(ChemicalProperties { - molar_mass: 0.0, // kg/mol - critical_temp: 0.0, // K - critical_pressure: 0.0, // Pa - acentric_factor: 0.0, - const_a: 0.0, - const_b: 0.0, - const_c: 0.0, - const_d: 0.0 - }) - } -} - -#[cfg(test)] -mod chemical_species_tests { - use crate::component::{Chemical, ChemicalIdentifier}; - use std::{thread,time::Duration}; - - #[test] - fn test_create_chemical_from_pubchem_id() { - // Using a known PubChem ID, e.g., 7732 (water) - let identifier = ChemicalIdentifier::PubchemID(7732); - - let chemical = Chemical::new(identifier); - thread::sleep(Duration::from_secs(10)); - - assert!( - chemical.is_ok(), - "Failed to create chemical from PubChem ID" - ); - let chemical = chemical.unwrap(); - - // Verify that the Chemical object contains the expected PubChem object - assert_eq!(chemical.get_pubchem_obj().cids().unwrap()[0], 7732); - - // Optionally, verify that the ChemicalProperties object has been initialized - // assert_eq!(chemical.get_properties().molar_mass, 0.0); // Example check for default values - } - - #[test] - fn test_create_chemical_from_name() { - let identifier = ChemicalIdentifier::CompoundName(String::from("Water")); - - let chemical = Chemical::new(identifier); - thread::sleep(Duration::from_secs(10)); - - - assert!(chemical.is_ok(), "Failed to create chemical from name"); - let chemical = chemical.unwrap(); - - // Verify that the Chemical object contains a valid name - assert_eq!(chemical.get_pubchem_obj().cids().unwrap()[0], 962); - assert_eq!(chemical.pubchem_obj.title().unwrap(), "Water"); - // assert_eq!(chemical.get_properties().molar_mass, 0.0); // Example check for default values - } -} diff --git a/oscps-lib/src/lib.rs b/oscps-lib/src/lib.rs index e81652e..9d05b9f 100644 --- a/oscps-lib/src/lib.rs +++ b/oscps-lib/src/lib.rs @@ -6,7 +6,7 @@ #![warn(missing_docs)] pub mod blocks; -pub mod component; +pub mod properties; pub mod connector; pub mod simulation; pub mod thermodynamics; diff --git a/oscps-lib/src/properties.rs b/oscps-lib/src/properties.rs new file mode 100644 index 0000000..03578dd --- /dev/null +++ b/oscps-lib/src/properties.rs @@ -0,0 +1,163 @@ +//! # Properties +//! +//! Contains chemical properties for species in the simulation. + +extern crate uom; +extern crate pubchem; +pub mod pure_species_properties; + +use anyhow::Result; +use uom::si::f64::*; +use std::{thread,time::Duration}; +use serde::{Serialize, Deserialize}; + +#[allow(dead_code)] +/// This will hold the list of chemicals used within the simulation +pub struct ChemicalList { + chemical_list: Vec, +} + +#[allow(dead_code)] +/// A struct to store information regarding the chemical properties of a +/// particular substance. The "Chemical" struct is a wrapper for the +/// pubchem::Compound object +pub struct Chemical { + /// The (PubChem)[] CID of a compound. + pub pubchem_obj: pubchem::Compound, + /// Physical properties of a compound. + pub properties: ChemicalProperties, +} + +#[allow(dead_code)] +/// Used by the "Chemical" struct to create the pubchem::Compound obj based on +/// either the chemical name or the pubchem id of the chemical +pub enum ChemicalIdentifier { + /// The PubChem ID of the component. + PubchemID(u32), + /// The actual name of the component. + CompoundName(String), +} + +#[allow(dead_code)] +/// Implementation of the chemical of interest. +impl Chemical { + /// Constructs a new chemical. + pub fn new(identifier: ChemicalIdentifier) -> Result { + let pubchem_chemical_object = match identifier { + ChemicalIdentifier::PubchemID(id) => pubchem::Compound::new(id), + ChemicalIdentifier::CompoundName(name) => pubchem::Compound::with_name(name.as_str()), + }; + let mut request_counter = 0; + let mut cid_vec = None; + while request_counter <= 10 { + match pubchem_chemical_object.cids(){ + Ok(cid_list) => { + cid_vec = Some(cid_list); + break; + }, + _ => { + request_counter += 1; + thread::sleep(Duration::from_secs(10)); + } + }; + } + + // let cid_vec = pubchem_chemical_object.cids().unwrap(); + let cid: i32 = cid_vec.unwrap()[0]; + let prop = ChemicalProperties::new(cid).unwrap(); + Ok(Chemical { + pubchem_obj: pubchem_chemical_object, + properties: prop, + }) + } + /// Returns the pubchem object for the compound. + pub fn get_pubchem_obj(&self) -> &pubchem::Compound { + &self.pubchem_obj + } + + /// Returns the "ChemicalProperties" object for the "Chemical" object. + pub fn get_properties(&self) -> &ChemicalProperties { + &self.properties + } +} + +#[allow(dead_code)] +/// Struct containing properties of a chemical +pub struct ChemicalProperties { + /// Molecular weight (kg/mol) + pub molar_mass: MolarMass, + + /// Critical properties (optional since not all compounds have them) + pub critical: Option, + + /// Heat capacity coefficients (optional, stored as an array) + pub heat_capacity: Option, + + /// Transport properties (optional, could include viscosity, etc.) + pub transport: Option, + + /// Additional chemical property categories + pub other_properties: Option>, +} + +/// Implementation of the ChemicalProperties struct. +impl ChemicalProperties { + // /// Constructor for the ChemicalProperties struct. + // pub fn new(cid: i32) -> Result { + // println!("Recieving information for compound/element {cid}"); + // Ok(ChemicalProperties { + // molar_mass: 0.0, // kg/mol + // critical_temp: 0.0, // K + // critical_pressure: 0.0, // Pa + // acentric_factor: 0.0, + // const_a: 0.0, + // const_b: 0.0, + // const_c: 0.0, + // const_d: 0.0 + // }) + // } +} + +#[cfg(test)] +mod chemical_species_tests { + // use crate::component::{Chemical, ChemicalIdentifier}; + // use std::{thread,time::Duration}; + + // #[test] + // fn test_create_chemical_from_pubchem_id() { + // // Using a known PubChem ID, e.g., 7732 (water) + // let identifier = ChemicalIdentifier::PubchemID(7732); + + // let chemical = Chemical::new(identifier); + // thread::sleep(Duration::from_secs(10)); + // + // assert!( + // chemical.is_ok(), + // "Failed to create chemical from PubChem ID" + // ); + // let chemical = chemical.unwrap(); + + // // Verify that the Chemical object contains the expected PubChem object + // assert_eq!(chemical.get_pubchem_obj().cids().unwrap()[0], 7732); + + // // Optionally, verify that the ChemicalProperties object has been initialized + // // assert_eq!(chemical.get_properties().molar_mass, 0.0); // Example check for default values + // } + + // #[test] + // fn test_create_chemical_from_name() { + // let identifier = ChemicalIdentifier::CompoundName(String::from("Water")); + + // let chemical = Chemical::new(identifier); + // thread::sleep(Duration::from_secs(10)); + + + // assert!(chemical.is_ok(), "Failed to create chemical from name"); + // let chemical = chemical.unwrap(); + + // // Verify that the Chemical object contains a valid name + // assert_eq!(chemical.get_pubchem_obj().cids().unwrap()[0], 962); + // assert_eq!(chemical.pubchem_obj.title().unwrap(), "Water"); + // // assert_eq!(chemical.get_properties().molar_mass, 0.0); // Example check for default values + // } +} diff --git a/oscps-lib/src/properties/pure_species_properties.rs b/oscps-lib/src/properties/pure_species_properties.rs new file mode 100644 index 0000000..d897bae --- /dev/null +++ b/oscps-lib/src/properties/pure_species_properties.rs @@ -0,0 +1,8 @@ +///# Pure Species Properties +/// This sub-module will contain the information regarding the cheracteristic properties of pure +/// species. This would include the molar mass (molecular weight), accentric factor, critical +/// temperature, critical pressure, critical compressibility, critical molar volume, and normal +/// boiling point. + + +use crate::properties::*; From c68dfd43ede5b369cab605f00a4afb82a53ca8e3 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sat, 29 Mar 2025 20:27:19 -0400 Subject: [PATCH 02/21] updating the cargo.toml file for the oscps-lib library module removed unnecessary external imports --- oscps-lib/Cargo.toml | 1 - oscps-lib/src/thermodynamics.rs | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index a0326c6..33065e4 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" uom = "0.36.0" once_cell = "1.17.1" pubchem = "0.1.1" -reqwest = { version = "0.11", features = ["json"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tokio = { version = "1", features = ["full"] } diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index 47e969c..e6a611d 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -7,8 +7,11 @@ pub mod ideal_gas_package; ///Importing SRK Package pub mod srk_package; -use crate::component::Chemical; +/// Importing chemical properties +use crate::properties::Chemical; + +///Importing External Packages use uom::si::f64::*; use uom::si::mass; use uom::si::pressure; From 2dafbdd0cdf00792eb67adf8bfcea0aaae67a958 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sat, 29 Mar 2025 20:54:57 -0400 Subject: [PATCH 03/21] cleaning up the properties.rs file --- oscps-lib/src/properties.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/oscps-lib/src/properties.rs b/oscps-lib/src/properties.rs index 03578dd..2cdb4eb 100644 --- a/oscps-lib/src/properties.rs +++ b/oscps-lib/src/properties.rs @@ -4,6 +4,7 @@ extern crate uom; extern crate pubchem; +///Importing pure species properties pub mod pure_species_properties; use anyhow::Result; @@ -12,11 +13,16 @@ use std::{thread,time::Duration}; use serde::{Serialize, Deserialize}; #[allow(dead_code)] -/// This will hold the list of chemicals used within the simulation -pub struct ChemicalList { - chemical_list: Vec, +/// Used by the "Chemical" struct to create the pubchem::Compound obj based on +/// either the chemical name or the pubchem id of the chemical +pub enum ChemicalIdentifier { + /// The PubChem ID of the component. + PubchemID(u32), + /// The actual name of the component. + CompoundName(String), } + #[allow(dead_code)] /// A struct to store information regarding the chemical properties of a /// particular substance. The "Chemical" struct is a wrapper for the @@ -28,16 +34,6 @@ pub struct Chemical { pub properties: ChemicalProperties, } -#[allow(dead_code)] -/// Used by the "Chemical" struct to create the pubchem::Compound obj based on -/// either the chemical name or the pubchem id of the chemical -pub enum ChemicalIdentifier { - /// The PubChem ID of the component. - PubchemID(u32), - /// The actual name of the component. - CompoundName(String), -} - #[allow(dead_code)] /// Implementation of the chemical of interest. impl Chemical { From f5894272b90cee1a58478126da9ef47c02a4ebcf Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 30 Mar 2025 12:19:33 -0400 Subject: [PATCH 04/21] adding a new library crate for postgresql db management --- Cargo.toml | 2 +- oscps-db/Cargo.toml | 6 ++++++ oscps-db/src/lib.rs | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 oscps-db/Cargo.toml create mode 100644 oscps-db/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 7ca18e5..d1ca24f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = [ "oscps-gui", +members = [ "oscps-db", "oscps-gui", "oscps-lib", ] diff --git a/oscps-db/Cargo.toml b/oscps-db/Cargo.toml new file mode 100644 index 0000000..567612e --- /dev/null +++ b/oscps-db/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "oscps-db" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/oscps-db/src/lib.rs b/oscps-db/src/lib.rs new file mode 100644 index 0000000..b93cf3f --- /dev/null +++ b/oscps-db/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} From cf3db48369259b02c765eb768b7e0e5e895d0399 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Wed, 2 Apr 2025 18:29:28 -0400 Subject: [PATCH 05/21] updating branch with some minor additions --- oscps-lib/src/properties.rs | 6 ++---- oscps-lib/src/properties/pure_species_properties.rs | 7 +++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/oscps-lib/src/properties.rs b/oscps-lib/src/properties.rs index 2cdb4eb..4764a09 100644 --- a/oscps-lib/src/properties.rs +++ b/oscps-lib/src/properties.rs @@ -80,10 +80,7 @@ impl Chemical { #[allow(dead_code)] /// Struct containing properties of a chemical pub struct ChemicalProperties { - /// Molecular weight (kg/mol) - pub molar_mass: MolarMass, - - /// Critical properties (optional since not all compounds have them) + /// Pure species properties pub critical: Option, /// Heat capacity coefficients (optional, stored as an array) @@ -93,6 +90,7 @@ pub struct ChemicalProperties { pub transport: Option, /// Additional chemical property categories + // Here we might add properties related to binary interactions, etc... pub other_properties: Option>, } diff --git a/oscps-lib/src/properties/pure_species_properties.rs b/oscps-lib/src/properties/pure_species_properties.rs index d897bae..9078f70 100644 --- a/oscps-lib/src/properties/pure_species_properties.rs +++ b/oscps-lib/src/properties/pure_species_properties.rs @@ -6,3 +6,10 @@ use crate::properties::*; + +///#PureSpeciesProperties +/// +///This will contain all the important properties for pure species +pub struct PureSpeciesProperties { + +} From baa861881413379f94af955ad0e42b4e10ef302d Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Thu, 3 Apr 2025 21:00:39 -0400 Subject: [PATCH 06/21] adding properties of the 'PureSpeciesProperties' struct --- oscps-lib/Cargo.toml | 1 + oscps-lib/src/properties/pure_species_properties.rs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index 33065e4..4856d92 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -11,3 +11,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tokio = { version = "1", features = ["full"] } anyhow = "1.0" +oscps-db = { path = "../oscps-db" } diff --git a/oscps-lib/src/properties/pure_species_properties.rs b/oscps-lib/src/properties/pure_species_properties.rs index 9078f70..9fa6288 100644 --- a/oscps-lib/src/properties/pure_species_properties.rs +++ b/oscps-lib/src/properties/pure_species_properties.rs @@ -6,10 +6,20 @@ use crate::properties::*; +use uom::si::f64; +use std::sync::Arc; +use oscps_db::*; ///#PureSpeciesProperties /// ///This will contain all the important properties for pure species pub struct PureSpeciesProperties { - + pub species_obj_id: Arc, + pub antoine_equation_constants: Vec, + pub critical_temperature: f64::ThermodynamicTemperature, + pub molar_mass: f64::MolarMass, + pub normal_boiling_point: f64::ThermodynamicTemperature, + pub critical_molar_volume: f64::Volume, + pub accentric_factor: f64::Ratio, + pub compressibility_factor: f64::Ratio } From b14841d0c613da2429a5a71557f7200a93fe5788 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Thu, 3 Apr 2025 21:08:18 -0400 Subject: [PATCH 07/21] adding a workflow that would update the documentation on github pages from updates to the rust doc-strings --- .github/workflows/create-doc-pages.yml | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/create-doc-pages.yml diff --git a/.github/workflows/create-doc-pages.yml b/.github/workflows/create-doc-pages.yml new file mode 100644 index 0000000..d5ffed1 --- /dev/null +++ b/.github/workflows/create-doc-pages.yml @@ -0,0 +1,28 @@ +name: Generate and Deploy Rust Docs + +on: + pull_request: + branches: + - main + +jobs: + rust-docs: + name: Generate Rust Documentation + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Generate documentation + run: cargo doc --no-deps + + - name: Deploy to GitHub Pages + if: github.ref == 'refs/heads/main' + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./target/doc From 16238406d7606462a70cfe057941a6df77402e0f Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Thu, 3 Apr 2025 21:11:37 -0400 Subject: [PATCH 08/21] added warning flag --- oscps-lib/src/properties/pure_species_properties.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oscps-lib/src/properties/pure_species_properties.rs b/oscps-lib/src/properties/pure_species_properties.rs index 9fa6288..9606197 100644 --- a/oscps-lib/src/properties/pure_species_properties.rs +++ b/oscps-lib/src/properties/pure_species_properties.rs @@ -4,7 +4,7 @@ /// temperature, critical pressure, critical compressibility, critical molar volume, and normal /// boiling point. - +#[warn(unused_imports)] use crate::properties::*; use uom::si::f64; use std::sync::Arc; From a441fd067c8f90065a0add6f40698c847aa23ecf Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sat, 10 May 2025 16:45:37 -0400 Subject: [PATCH 09/21] starting to implement ability to retrieve information about chemical properties --- oscps-db/src/lib.rs | 21 +++---- oscps-db/src/postgres_db.rs | 4 ++ oscps-lib/src/properties.rs | 62 ++----------------- .../src/properties/pure_species_properties.rs | 7 +++ 4 files changed, 26 insertions(+), 68 deletions(-) create mode 100644 oscps-db/src/postgres_db.rs diff --git a/oscps-db/src/lib.rs b/oscps-db/src/lib.rs index b93cf3f..e629600 100644 --- a/oscps-db/src/lib.rs +++ b/oscps-db/src/lib.rs @@ -1,14 +1,11 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} +///#OSCPS-db +/// +///Main library folder for the OSCPS-db library crate +/// +///will hold the methods to pull information from the POSTGRES database and from relevant APIs +/// +///Will hold property information for chemcial property calculation +///Will hold information about the user's simulation -#[cfg(test)] -mod tests { - use super::*; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub mod postgres_db; diff --git a/oscps-db/src/postgres_db.rs b/oscps-db/src/postgres_db.rs new file mode 100644 index 0000000..00d086a --- /dev/null +++ b/oscps-db/src/postgres_db.rs @@ -0,0 +1,4 @@ +/// #PostgresDb +/// +/// Will provide methods to connect to a postgres database to pull relevant property and/or +/// simulation information diff --git a/oscps-lib/src/properties.rs b/oscps-lib/src/properties.rs index 4764a09..73b9720 100644 --- a/oscps-lib/src/properties.rs +++ b/oscps-lib/src/properties.rs @@ -94,64 +94,14 @@ pub struct ChemicalProperties { pub other_properties: Option>, } -/// Implementation of the ChemicalProperties struct. -impl ChemicalProperties { - // /// Constructor for the ChemicalProperties struct. - // pub fn new(cid: i32) -> Result { - // println!("Recieving information for compound/element {cid}"); - // Ok(ChemicalProperties { - // molar_mass: 0.0, // kg/mol - // critical_temp: 0.0, // K - // critical_pressure: 0.0, // Pa - // acentric_factor: 0.0, - // const_a: 0.0, - // const_b: 0.0, - // const_c: 0.0, - // const_d: 0.0 - // }) - // } +/// Trait to group all property libraries +trait PropertyLibrary { + /// default function for connecting the database to pull relevant property information + fn oscps_db_connection(&self) -> &db_connection; } -#[cfg(test)] -mod chemical_species_tests { - // use crate::component::{Chemical, ChemicalIdentifier}; - // use std::{thread,time::Duration}; - - // #[test] - // fn test_create_chemical_from_pubchem_id() { - // // Using a known PubChem ID, e.g., 7732 (water) - // let identifier = ChemicalIdentifier::PubchemID(7732); - - // let chemical = Chemical::new(identifier); - // thread::sleep(Duration::from_secs(10)); - // - // assert!( - // chemical.is_ok(), - // "Failed to create chemical from PubChem ID" - // ); - // let chemical = chemical.unwrap(); - - // // Verify that the Chemical object contains the expected PubChem object - // assert_eq!(chemical.get_pubchem_obj().cids().unwrap()[0], 7732); - - // // Optionally, verify that the ChemicalProperties object has been initialized - // // assert_eq!(chemical.get_properties().molar_mass, 0.0); // Example check for default values - // } - // #[test] - // fn test_create_chemical_from_name() { - // let identifier = ChemicalIdentifier::CompoundName(String::from("Water")); - // let chemical = Chemical::new(identifier); - // thread::sleep(Duration::from_secs(10)); - - - // assert!(chemical.is_ok(), "Failed to create chemical from name"); - // let chemical = chemical.unwrap(); - - // // Verify that the Chemical object contains a valid name - // assert_eq!(chemical.get_pubchem_obj().cids().unwrap()[0], 962); - // assert_eq!(chemical.pubchem_obj.title().unwrap(), "Water"); - // // assert_eq!(chemical.get_properties().molar_mass, 0.0); // Example check for default values - // } +#[cfg(test)] +mod chemical_species_tests { } diff --git a/oscps-lib/src/properties/pure_species_properties.rs b/oscps-lib/src/properties/pure_species_properties.rs index 9606197..a8c7b45 100644 --- a/oscps-lib/src/properties/pure_species_properties.rs +++ b/oscps-lib/src/properties/pure_species_properties.rs @@ -23,3 +23,10 @@ pub struct PureSpeciesProperties { pub accentric_factor: f64::Ratio, pub compressibility_factor: f64::Ratio } + +///Functions to pull pure species properties from the database + // Database will need to handle API calls to external sources for information currently in the + // database. +impl PureSpeciesProperties { + +} From 1dd5192e29b476a1ad35da4197dca9d6e06df9b9 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sat, 10 May 2025 17:02:54 -0400 Subject: [PATCH 10/21] updating oscps-db --- oscps-db/src/lib.rs | 2 ++ oscps-db/src/postgres_db.rs | 7 ++++++- oscps-db/src/properties_db.rs | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 oscps-db/src/properties_db.rs diff --git a/oscps-db/src/lib.rs b/oscps-db/src/lib.rs index e629600..d8f2f31 100644 --- a/oscps-db/src/lib.rs +++ b/oscps-db/src/lib.rs @@ -9,3 +9,5 @@ pub mod postgres_db; +pub mod properties_db; + diff --git a/oscps-db/src/postgres_db.rs b/oscps-db/src/postgres_db.rs index 00d086a..9dcbf50 100644 --- a/oscps-db/src/postgres_db.rs +++ b/oscps-db/src/postgres_db.rs @@ -1,4 +1,9 @@ -/// #PostgresDb +/// #PostgresDB /// /// Will provide methods to connect to a postgres database to pull relevant property and/or /// simulation information + + +// Will need the following: +// 1. PostgresDB --> will send queries and return results and handle exceptions +// 2. PropertiesDB --> will formulate the right queries required for 'DBConnector' diff --git a/oscps-db/src/properties_db.rs b/oscps-db/src/properties_db.rs new file mode 100644 index 0000000..7de179b --- /dev/null +++ b/oscps-db/src/properties_db.rs @@ -0,0 +1,3 @@ +///# PropertiesDB +/// +///Will formulate the right queries required for 'DBConnector' From 3f402303c11a8ac9f8cc945db62b0427e7c91b87 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sat, 10 May 2025 17:49:33 -0400 Subject: [PATCH 11/21] updating branch --- oscps-db/src/postgres_db.rs | 25 ++++++++++++++++++++++--- oscps-db/src/properties_db.rs | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/oscps-db/src/postgres_db.rs b/oscps-db/src/postgres_db.rs index 9dcbf50..7bdd500 100644 --- a/oscps-db/src/postgres_db.rs +++ b/oscps-db/src/postgres_db.rs @@ -2,8 +2,27 @@ /// /// Will provide methods to connect to a postgres database to pull relevant property and/or /// simulation information +/// +/// properties: +/// 1. db_name +/// 2. query +/// 3. status +/// 4. connection_key +use sqlx::PgPool; +use uuid::Uuid; -// Will need the following: -// 1. PostgresDB --> will send queries and return results and handle exceptions -// 2. PropertiesDB --> will formulate the right queries required for 'DBConnector' + +enum DBStatus { + Successful, + Failure, + InProgress +} + +pub struct PostgresDB { + pub db_name: String, + pub input_query: String, + pub request_status: DBStatus, + db_key: Uuid, + db_pool: PgPool, +} diff --git a/oscps-db/src/properties_db.rs b/oscps-db/src/properties_db.rs index 7de179b..b011aa2 100644 --- a/oscps-db/src/properties_db.rs +++ b/oscps-db/src/properties_db.rs @@ -1,3 +1,4 @@ ///# PropertiesDB /// ///Will formulate the right queries required for 'DBConnector' +/// From 9062fd527593ab1d9598a3950d87ddc8164c7e2d Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 25 May 2025 13:58:59 -0400 Subject: [PATCH 12/21] changed 'ThermoState' to 'StreamThermoState' for more specificity I made the change as I to make sure that it is understood that the ThermoState struct is used by the Streams within the flow diagram and not by the blocks. The blocks (reactors, separators, etc) will contain their own calculations. On the other hand, the ThermoPackage may be used by both streams and blocks --- oscps-lib/src/connector.rs | 4 ++-- oscps-lib/src/thermodynamics.rs | 35 ++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/oscps-lib/src/connector.rs b/oscps-lib/src/connector.rs index fa67621..9eb9c68 100644 --- a/oscps-lib/src/connector.rs +++ b/oscps-lib/src/connector.rs @@ -1,7 +1,7 @@ //! # Connector //! -use crate::thermodynamics::ThermoState; +use crate::thermodynamics::StreamThermoState; /// # Stream /// @@ -13,7 +13,7 @@ pub struct Stream { /// ID of the stream. pub s_id : String, /// Instance of ThermoState struct that holds thermodynamic information. - pub thermo : Option, + pub thermo : Option, // TODO: Change these from strings to integers, or better yet, // references to the source and destination blocks, to minimize // computation time spent on looking for sources and destinations. diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index e6a611d..0afc273 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -72,11 +72,11 @@ pub struct ComponentData { } #[allow(dead_code)] -/// # ThermoState -/// Returns a thermodynamic state, including pressure, temperature, and -/// mole fractions. -/// This struct will be used for streams in the flow diagram -pub struct ThermoState { +/// # StreamThermoState +/// +/// This struct will be used for performing thermodynamic calculations for the streams in the flow +/// diagram. +pub struct StreamThermoState { /// Pressure of the state. pub pressure: Option, // pressure /// Temperature of the state. @@ -95,12 +95,12 @@ pub struct ThermoState { #[allow(dead_code)] -/// Implementation of ThermoState +/// Implementation of StreamThermoState /// This struct holds the functionality to perform thermodynamic calculations for streams -impl ThermoState { - /// Constructor for creating a ThermoState +impl StreamThermoState { + /// Constructor for creating a StreamThermoState pub fn new() -> Self { - ThermoState { + StreamThermoState { pressure : None, temperature : None, mass_list : vec![], @@ -110,6 +110,9 @@ impl ThermoState { thermodynamic_package : None } } + /// Public function to execute the calculations for determining the thermodynamic state for the + /// stream. Dependence on the Thermodynamic Packages. + pub fn execute_thermo_calcs(&mut self) -> Self {} /// this function will return the total mass for an individual stream fn calc_total_mass(&mut self) -> Mass { let mut mass_sum = 0.0; @@ -137,7 +140,7 @@ impl ThermoState { ///#ThermoPackage ///Will be a common trait for all the thermodynamic packages ///Will include functions common to thermodynamic packages -///Will also enable to user to switch between thermodynamic packages within the ThermoState struct +///Will also enable to user to switch between thermodynamic packages within the StreamThermoState struct ///(the thermodynamic packages will be structs) pub trait ThermoPackage{ ///Calculating the Enthalpy @@ -173,7 +176,7 @@ mod thermo_tests { // use std::{thread,time::Duration}; // #[test] - // ///Test case generates an instance of the 'ThermoState' struct + // ///Test case generates an instance of the 'StreamThermoState' struct // fn test_create_thermo_state() { // // Create some test data for ThermoMoleFrac (mole fractions) // let water = Chemical { @@ -196,14 +199,14 @@ mod thermo_tests { // const_d: 0.0 // }; - // // Create ThermoState - // let thermo_state = ThermoState::new( + // // Create StreamThermoState + // let thermo_state = StreamThermoState::new( // 101325.0, // pressure in Pascals (1 atm) // 298.15, // temperature in Kelvin (25°C) // vec![water_species_pair], // Example with one chemical // ); - // // Validate ThermoState + // // Validate StreamThermoState // assert_eq!(thermo_state.pressure.get::(), 101325.0); // assert_eq!(thermo_state.temperature.get::(), 298.15); // assert_eq!(thermo_state.mass_list.len(), 1); // Should contain one mole fraction entry @@ -222,7 +225,7 @@ mod thermo_tests { // } // #[test] - // ///Tests the mass fraction function within the 'ThermoState struct' + // ///Tests the mass fraction function within the 'StreamThermoState struct' // fn test_mass_fraction_calculation() { // let water = Chemical { // pubchem_obj: pubchem::Compound::new(962), @@ -258,7 +261,7 @@ mod thermo_tests { // mass_quantity: anisidine_mass, // }; - // let therm_obj = ThermoState::new( + // let therm_obj = StreamThermoState::new( // 101325.0, // 298.15, // vec![water_species_pair, anisidine_species_pair], From c0e3703bf13ac1ebc4dbcff3cdae9bd2d4a18d60 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 25 May 2025 14:07:22 -0400 Subject: [PATCH 13/21] added some more comments for better understanding of the struct's purpose --- oscps-lib/src/thermodynamics.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index 0afc273..51f0e3e 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -138,10 +138,15 @@ impl StreamThermoState { ///Thermodynamic Packages. /// ///#ThermoPackage -///Will be a common trait for all the thermodynamic packages -///Will include functions common to thermodynamic packages -///Will also enable to user to switch between thermodynamic packages within the StreamThermoState struct ///(the thermodynamic packages will be structs) +/// +///Will be a common trait for all the thermodynamic packages and will include common functions. +///Will also enable to user to switch between thermodynamic packages within the StreamThermoState struct +/// +///The thermodynamic pacakges can be used by the blocks for any relevant calculations +/// +///For calculations, the thermodynamic packages will call upon the property struct for relevant +///info. pub trait ThermoPackage{ ///Calculating the Enthalpy fn enthalpy(&self) -> MolarEnergy; From 9211a7348b4daa85f84a986d32f19740a18f938e Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 25 May 2025 14:41:11 -0400 Subject: [PATCH 14/21] renaming connector to stream --- oscps-lib/src/{connector.rs => stream.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename oscps-lib/src/{connector.rs => stream.rs} (100%) diff --git a/oscps-lib/src/connector.rs b/oscps-lib/src/stream.rs similarity index 100% rename from oscps-lib/src/connector.rs rename to oscps-lib/src/stream.rs From 2a8864115e4af86c358922d09f2fd29eb85daf21 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 25 May 2025 14:41:47 -0400 Subject: [PATCH 15/21] updating the main lib.rs file --- oscps-lib/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oscps-lib/src/lib.rs b/oscps-lib/src/lib.rs index 9d05b9f..d645347 100644 --- a/oscps-lib/src/lib.rs +++ b/oscps-lib/src/lib.rs @@ -7,7 +7,7 @@ pub mod blocks; pub mod properties; -pub mod connector; +pub mod stream; pub mod simulation; pub mod thermodynamics; From f2369aa30d6aac1258600784148fd51a8f84a407 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 25 May 2025 14:45:56 -0400 Subject: [PATCH 16/21] added author and edition information :) --- Cargo.toml | 3 ++- oscps-db/Cargo.toml | 3 ++- oscps-gui/Cargo.toml | 4 ++-- oscps-lib/Cargo.toml | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d1ca24f..a138b1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" - +authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2024" members = [ "oscps-db", "oscps-gui", "oscps-lib", ] diff --git a/oscps-db/Cargo.toml b/oscps-db/Cargo.toml index 567612e..224940b 100644 --- a/oscps-db/Cargo.toml +++ b/oscps-db/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "oscps-db" version = "0.1.0" -edition = "2021" +authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2025" [dependencies] diff --git a/oscps-gui/Cargo.toml b/oscps-gui/Cargo.toml index 0822647..4c2f3fd 100644 --- a/oscps-gui/Cargo.toml +++ b/oscps-gui/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "oscps-gui" version = "0.1.0" -authors = ["Nathaniel Thomas ", "Bhargav Akula "] -edition = "2021" +authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2024" [dependencies] env_logger = "0.11.6" diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index 4856d92..e144d1a 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "oscps-lib" version = "0.1.0" -edition = "2021" +authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2024" [dependencies] uom = "0.36.0" From a252056496c8f8064d7a9a31a00c9072db897a74 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Wed, 4 Jun 2025 08:02:16 -0400 Subject: [PATCH 17/21] updating repo and attempting to add autodiff for thermo module --- oscps-db/Cargo.toml | 1 - oscps-gui/Cargo.toml | 1 - oscps-lib/Cargo.toml | 1 - oscps-lib/src/stream.rs | 84 ++++++- oscps-lib/src/thermodynamics.rs | 207 +----------------- .../{srk_package.rs => eos_models.rs} | 12 +- .../src/thermodynamics/ideal_gas_package.rs | 179 --------------- 7 files changed, 99 insertions(+), 386 deletions(-) rename oscps-lib/src/thermodynamics/{srk_package.rs => eos_models.rs} (52%) delete mode 100644 oscps-lib/src/thermodynamics/ideal_gas_package.rs diff --git a/oscps-db/Cargo.toml b/oscps-db/Cargo.toml index 224940b..77a353c 100644 --- a/oscps-db/Cargo.toml +++ b/oscps-db/Cargo.toml @@ -2,6 +2,5 @@ name = "oscps-db" version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] -edition = "2025" [dependencies] diff --git a/oscps-gui/Cargo.toml b/oscps-gui/Cargo.toml index 4c2f3fd..64bdd4e 100644 --- a/oscps-gui/Cargo.toml +++ b/oscps-gui/Cargo.toml @@ -2,7 +2,6 @@ name = "oscps-gui" version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] -edition = "2024" [dependencies] env_logger = "0.11.6" diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index e144d1a..0b2deb7 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -2,7 +2,6 @@ name = "oscps-lib" version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] -edition = "2024" [dependencies] uom = "0.36.0" diff --git a/oscps-lib/src/stream.rs b/oscps-lib/src/stream.rs index 9eb9c68..109fccd 100644 --- a/oscps-lib/src/stream.rs +++ b/oscps-lib/src/stream.rs @@ -1,7 +1,7 @@ //! # Connector //! -use crate::thermodynamics::StreamThermoState; +use crate::thermodynamics::{ThermodynamicConstants, ThermoPackage}; /// # Stream /// @@ -35,3 +35,85 @@ impl Stream { } } } + +#[allow(dead_code)] +/// Species list +pub struct ComponentData { + /// Chemical species + pub chemical_species: Chemical, // will contain intrinsic properties of species + /// Mass quantity + pub mass_quantity: Mass, + /// Molar quantity + pub molar_quantity: AmountOfSubstance, + ///volumetric quantity + pub vol_quantity: Volume, + /// partial pressure + pub partial_pressure : Pressure, +} + +#[allow(dead_code)] +/// # StreamThermoState +/// +/// This struct will be used for performing thermodynamic calculations for the streams in the flow +/// diagram. +pub struct StreamThermoState { + /// Pressure of the state. + pub pressure: Option, // pressure + /// Temperature of the state. + pub temperature: Option, // temperature + /// List of mole fractions. + pub mass_list: Vec,//Information about each component within stream + /// Total Mass + pub total_mass : Option, // total mass in stream + /// Total Moles + pub total_mol : Option, // total moles in stream + /// Total Volume + pub total_volume : Option, // total volume in stream + ///Thermo Package + pub thermodynamic_package : Option> // thermodynamics package +} + + +#[allow(dead_code)] +/// Implementation of StreamThermoState +/// This struct holds the functionality to perform thermodynamic calculations for streams +impl StreamThermoState { + /// Constructor for creating a StreamThermoState + pub fn new() -> Self { + StreamThermoState { + pressure : None, + temperature : None, + mass_list : vec![], + total_mass : None, + total_mol : None, + total_volume : None, + thermodynamic_package : None + } + } + /// Public function to execute the calculations for determining the thermodynamic state for the + /// stream. Dependence on the Thermodynamic Packages. + pub fn execute_thermo_calcs(&mut self) -> Self { + + } + /// this function will return the total mass for an individual stream + fn calc_total_mass(&mut self) -> Mass { + let mut mass_sum = 0.0; + for chem in &self.mass_list { + mass_sum += chem.mass_quantity.get::(); + } + self.total_mass = Some(Mass::new::(mass_sum)); + + self.total_mass.unwrap() + } + /// this function will return the total moles for an individual stream + fn calc_total_moles(&mut self) -> AmountOfSubstance { + let mut mole_sum = 0.0; + for chem in &self.mass_list { + mole_sum += chem.molar_quantity.get::(); + } + self.total_mol = Some(AmountOfSubstance::new::(mole_sum)); + + self.total_mol.unwrap() + } +} + diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index 51f0e3e..5951931 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -3,10 +3,8 @@ //! This module will hold all the functions related to calculating //! themrodynamic properties for the blocks and chemical species. -///Importing Ideal Gas Package -pub mod ideal_gas_package; -///Importing SRK Package -pub mod srk_package; +///Importing EOSModels +pub mod eos_models; /// Importing chemical properties use crate::properties::Chemical; @@ -19,8 +17,9 @@ use uom::si::thermodynamic_temperature; use uom::si::energy; use uom::si::amount_of_substance; - #[allow(dead_code)] +/// #ThermodynamicConstants +/// /// Struct for storing physical constants for thermodynamics. /// TODO: Reimplement the use of uom for dimensional analysis. pub enum ThermodynamicConstants { @@ -56,89 +55,9 @@ impl ThermodynamicConstants { } } -#[allow(dead_code)] -/// Species list -pub struct ComponentData { - /// Chemical species - pub chemical_species: Chemical, // will contain intrinsic properties of species - /// Mass quantity - pub mass_quantity: Mass, - /// Molar quantity - pub molar_quantity: AmountOfSubstance, - ///volumetric quantity - pub vol_quantity: Volume, - /// partial pressure - pub partial_pressure : Pressure, -} - -#[allow(dead_code)] -/// # StreamThermoState -/// -/// This struct will be used for performing thermodynamic calculations for the streams in the flow -/// diagram. -pub struct StreamThermoState { - /// Pressure of the state. - pub pressure: Option, // pressure - /// Temperature of the state. - pub temperature: Option, // temperature - /// List of mole fractions. - pub mass_list: Vec,//Information about each component within stream - /// Total Mass - pub total_mass : Option, // total mass in stream - /// Total Moles - pub total_mol : Option, // total moles in stream - /// Total Volume - pub total_volume : Option, // total volume in stream - ///Thermo Package - pub thermodynamic_package : Option> // thermodynamics package -} - - -#[allow(dead_code)] -/// Implementation of StreamThermoState -/// This struct holds the functionality to perform thermodynamic calculations for streams -impl StreamThermoState { - /// Constructor for creating a StreamThermoState - pub fn new() -> Self { - StreamThermoState { - pressure : None, - temperature : None, - mass_list : vec![], - total_mass : None, - total_mol : None, - total_volume : None, - thermodynamic_package : None - } - } - /// Public function to execute the calculations for determining the thermodynamic state for the - /// stream. Dependence on the Thermodynamic Packages. - pub fn execute_thermo_calcs(&mut self) -> Self {} - /// this function will return the total mass for an individual stream - fn calc_total_mass(&mut self) -> Mass { - let mut mass_sum = 0.0; - for chem in &self.mass_list { - mass_sum += chem.mass_quantity.get::(); - } - self.total_mass = Some(Mass::new::(mass_sum)); - - self.total_mass.unwrap() - } - /// this function will return the total moles for an individual stream - fn calc_total_moles(&mut self) -> AmountOfSubstance { - let mut mole_sum = 0.0; - for chem in &self.mass_list { - mole_sum += chem.molar_quantity.get::(); - } - self.total_mol = Some(AmountOfSubstance::new::(mole_sum)); - - self.total_mol.unwrap() - } -} - ///Thermodynamic Packages. /// -///#ThermoPackage -///(the thermodynamic packages will be structs) +///#MaxwellRelations /// ///Will be a common trait for all the thermodynamic packages and will include common functions. ///Will also enable to user to switch between thermodynamic packages within the StreamThermoState struct @@ -147,7 +66,7 @@ impl StreamThermoState { /// ///For calculations, the thermodynamic packages will call upon the property struct for relevant ///info. -pub trait ThermoPackage{ +pub trait MaxwellRelations{ ///Calculating the Enthalpy fn enthalpy(&self) -> MolarEnergy; ///Calculating the Entropy @@ -168,117 +87,5 @@ pub trait ThermoPackage{ fn gibbs_free_energy(&self) -> Energy; } - - - #[cfg(test)] -mod thermo_tests { - // use super::*; - // use crate::component::{Chemical, ChemicalProperties}; - // use uom::si::mass::kilogram; - // use uom::si::pressure::pascal; - // use uom::si::thermodynamic_temperature::kelvin; - // use std::{thread,time::Duration}; - - // #[test] - // ///Test case generates an instance of the 'StreamThermoState' struct - // fn test_create_thermo_state() { - // // Create some test data for ThermoMoleFrac (mole fractions) - // let water = Chemical { - // pubchem_obj: pubchem::Compound::new(962), - // properties: ChemicalProperties { - // molar_mass: 0.01801528, // kg/mol for water - // critical_temp: 647.1, // K - // critical_pressure: 2206.0, // Pa - // acentric_factor: 0.344, // example - // }, - // }; - // thread::sleep(Duration::from_secs(10)); - // let water_mass = Mass::new::(2.0); - // let water_species_pair = SpeciesQuantityPair { - // chemical_species: water, - // mass_quantity: water_mass, - // const_a: 1.0, - // const_b: 1.0, - // const_c: 1.0, - // const_d: 0.0 - // }; - - // // Create StreamThermoState - // let thermo_state = StreamThermoState::new( - // 101325.0, // pressure in Pascals (1 atm) - // 298.15, // temperature in Kelvin (25°C) - // vec![water_species_pair], // Example with one chemical - // ); - - // // Validate StreamThermoState - // assert_eq!(thermo_state.pressure.get::(), 101325.0); - // assert_eq!(thermo_state.temperature.get::(), 298.15); - // assert_eq!(thermo_state.mass_list.len(), 1); // Should contain one mole fraction entry - - // - - // // Check that the mole fraction's chemical is correctly set - // assert_eq!( - // thermo_state.mass_list[0] - // .chemical_species - // .get_pubchem_obj() - // .cids() - // .unwrap()[0], - // 962 - // ); - // } - - // #[test] - // ///Tests the mass fraction function within the 'StreamThermoState struct' - // fn test_mass_fraction_calculation() { - // let water = Chemical { - // pubchem_obj: pubchem::Compound::new(962), - // properties: ChemicalProperties { - // molar_mass: 0.01801528, // kg/mol for water - // critical_temp: 647.1, // K - // critical_pressure: 2206.0, // Pa - // acentric_factor: 0.344, // example - // }, - // }; - // thread::sleep(Duration::from_secs(10)); - - // let anisdine = Chemical { - // pubchem_obj: pubchem::Compound::new(7732), - // properties: ChemicalProperties { - // molar_mass: 123.155, // g/mol, converting to kg/mol = 123.155 / 1000 - // critical_temp: 592.0, // K (approximated) - // critical_pressure: 2.6e6, // Pa (approximated) - // acentric_factor: 0.24, // (approximated) - // }, - // }; - // thread::sleep(Duration::from_secs(10)); - // - // let water_mass = Mass::new::(2.0); - // let water_species_pair = SpeciesQuantityPair { - // chemical_species: water, - // mass_quantity: water_mass, - // }; - - // let anisidine_mass = Mass::new::(8.0); - // let anisidine_species_pair = SpeciesQuantityPair { - // chemical_species: anisdine, - // mass_quantity: anisidine_mass, - // }; - - // let therm_obj = StreamThermoState::new( - // 101325.0, - // 298.15, - // vec![water_species_pair, anisidine_species_pair], - // ); - - // let mass_fraction = therm_obj - // .mass_frac(&therm_obj.mass_list[0].chemical_species) - // .unwrap(); - - // assert!( - // (mass_fraction - 0.2).abs() < 1e-6, - // "Mole fraction calculation failed" - // ); // Should be 0.2 - // } -} +mod thermo_tests {} diff --git a/oscps-lib/src/thermodynamics/srk_package.rs b/oscps-lib/src/thermodynamics/eos_models.rs similarity index 52% rename from oscps-lib/src/thermodynamics/srk_package.rs rename to oscps-lib/src/thermodynamics/eos_models.rs index 94a196a..c9fcd38 100644 --- a/oscps-lib/src/thermodynamics/srk_package.rs +++ b/oscps-lib/src/thermodynamics/eos_models.rs @@ -1,7 +1,6 @@ - -///#SRKPackage +///#EOSModel /// -///Will contain equations relating to the SRK Equation of state +///This struct will represent the different thermodynamic equations of state use crate::thermodynamics::*; @@ -15,3 +14,10 @@ use uom::si::energy; use uom::si::amount_of_substance; use uom::si::volume; use uom::si::ratio; + + +/// This struct will hold the chemical potential equation for each type of equation of state +/// Inspired by: https://github.com/ClapeyronThermo/Clapeyron.jl +pub struct EOSModel { + +} diff --git a/oscps-lib/src/thermodynamics/ideal_gas_package.rs b/oscps-lib/src/thermodynamics/ideal_gas_package.rs deleted file mode 100644 index d399335..0000000 --- a/oscps-lib/src/thermodynamics/ideal_gas_package.rs +++ /dev/null @@ -1,179 +0,0 @@ -///#IdealGasPackage -/// -///Will contain equations related to ideal gases - - -use crate::thermodynamics::*; -use std::sync::Arc; -use uom::si::f64::*; -use uom::si::molar_energy; -use uom::si::molar_heat_capacity; -use uom::si::pressure; -use uom::si::thermodynamic_temperature; -use uom::si::energy; -use uom::si::amount_of_substance; -use uom::si::volume; -use uom::si::ratio; - -///Creating the ideal gas thermodynamics package -pub struct IdealGasPackage { - ///Temperature - pub temperature : Arc, - /// Pressure - pub pressure : Arc, - ///List of Species - pub species_list : Vec>, - /// Mass - pub total_mass : Arc, - /// Volume - pub total_vol : Arc, - /// Moles - pub total_mol : Arc -} -///Implementing functions specific to the IdealGasPackage -impl IdealGasPackage { - ///Constructor - pub fn new( - temperature: Arc, - pressure : Arc, - species_list : Vec>, - total_mass : Arc, - total_vol : Arc, - total_mol : Arc) -> Self { - IdealGasPackage { - temperature, - pressure, - species_list, - total_mass, - total_vol, - total_mol - } - } -} -/// Implementing the ThermoPackage trait for the IdealGasPackage -impl ThermoPackage for IdealGasPackage { - ///Calculating enthalpy - // Need to run a for loop where I calculate the enthalpy of each species and then add it to - // the variable 'total_enthalpy' - // ASSUMPTIONS CURRENTLY MADE: - // No enthalpy from phase change - // when working with gases, assume that they are ideal gases - // Tref = 298 K & Pref = 101.325 kPa - // Href = 0 - fn enthalpy(&self) -> MolarEnergy { - let mut total_enthalpy = 0.0; - let t_ref = 298.15; //reference temperature - let h_ref = 0.0; //Reference enthalpy - let mut cp_ref; - let mut cp_t; - let r = ThermodynamicConstants::UniversalGasConstant.value().downcast::().unwrap(); - - for chem_object in &self.species_list { - let chem = &(*chem_object).chemical_species.properties; - if chem.const_c != 0.0 { - cp_ref = chem.const_a * t_ref + (1.0 / 2.0) * (chem.const_b / (10.0f64.powf(3.0))) * t_ref.powi(2); - cp_t = chem.const_a * self.temperature.get::() + (1.0 / 2.0) * (chem.const_b / (10.0f64.powf(3.0))) * self.temperature.get::().powf(2.0) + (1.0 / 3.0) * (chem.const_c / (10.0f64.powf(6.0))) * self.temperature.get::().powf(3.0); - } - else{ - cp_ref = chem.const_a * t_ref + (1.0 / 2.0) * (chem.const_b / (10.0f64.powf(3.0))) * t_ref.powi(2) + (-1.0) * (chem.const_d / (10.0f64.powf(-5.0))) * t_ref.powi(-1); - cp_t = chem.const_a * self.temperature.get::() + (1.0 / 2.0) * (chem.const_b / (10.0f64.powf(3.0))) * self.temperature.get::().powf(2.0) + (-1.0) * (chem.const_d / (10.0f64.powf(-5.0))) * self.temperature.get::().powf(-1.0); - } - let species_enthalpy = (chem_object.molar_quantity.get::()/self.total_mol.get::())*(h_ref + (cp_t - cp_ref)* r.get::()); - total_enthalpy += species_enthalpy; - } - - MolarEnergy::new::(total_enthalpy) - } - /// Determine ideal gas pressure - fn pressure(&self) -> Pressure { - let r = ThermodynamicConstants::UniversalGasConstant.value().downcast::().unwrap(); - let ideal_pressure = (self.total_mol.get::() * r.get::() * self.temperature.get::()) / (self.total_vol.get::()); - Pressure::new::(ideal_pressure) - } - ///Deterrmine entropy - // Will need to use equation (5.10) from the 'Introduction to Chemical Engineering - // Thermodynamics' - fn entropy(&self) -> MolarHeatCapacity { - let mut entropy_total = 0.0; - let t_ref = 298.15_f64; //reference temperature - let mut cp_ref; - let mut cp_t; - let r = ThermodynamicConstants::UniversalGasConstant.value().downcast::().unwrap(); - let p_o = 1.0_f64; // units atm - - for chem_object in &self.species_list { - let chem = &(*chem_object).chemical_species.properties; - if chem.const_c != 0.0 { - cp_ref = chem.const_a * t_ref.ln() + (chem.const_b / (10.0f64.powf(3.0))) * t_ref; - cp_t = chem.const_a * self.temperature.get::().ln() + (chem.const_b / (10.0f64.powf(3.0))) * self.temperature.get::() + (1.0 / 2.0) * (chem.const_c / (10.0f64.powf(6.0))) * self.temperature.get::().powf(2.0); - } - else{ - cp_ref = chem.const_a * t_ref.ln() + (chem.const_b / (10.0f64.powf(3.0))) * t_ref + (-1.0/2.0) * (chem.const_d / (10.0f64.powf(-5.0))) * t_ref.powi(-2); - cp_t = chem.const_a * self.temperature.get::().ln() + (chem.const_b / (10.0f64.powf(3.0))) * self.temperature.get::() + (-1.0/2.0) * (chem.const_d / (10.0f64.powf(-5.0))) * self.temperature.get::().powf(-2.0); - } - let integral_solve_species = cp_t - cp_ref; - let pressure_ratio = (*chem_object).partial_pressure.get::() / p_o; - - entropy_total += (chem_object.molar_quantity.get::()/self.total_mol.get::())*r.get::()*(integral_solve_species - pressure_ratio); - } - - MolarHeatCapacity::new::(entropy_total) - } - /// Determining vapor fraction - // In Ideal gas package, only will be used when components are all in gaseous state so - // vapor fraction will always be equal to 1 - fn vapor_fraction(&self) -> Ratio { - Ratio::new::(1.0) - } - /// Determining Cp (Heat capacity under constant pressure conditions) - fn heat_capacity_const_pressure(&self) -> MolarHeatCapacity { - let r = ThermodynamicConstants::UniversalGasConstant.value().downcast::().unwrap(); - let mut total_heat_capacity_const_pressure : f64 = 0.0; - let mut cp_t; - let t = self.temperature.get::(); - for chem_object in &self.species_list { - let chem = &(*chem_object).chemical_species.properties; - if chem.const_c != 0.0 { - cp_t = chem.const_a + (chem.const_b / (10.0f64.powf(3.0)))*t + (chem.const_c / (10.0f64.powf(6.0)))*t.powf(2.0); - } - else { - cp_t = chem.const_a + (chem.const_b / (10.0f64.powf(3.0)))*t + (chem.const_d / (10.0f64.powf(-5.0)))*t.powf(-2.0); - } - total_heat_capacity_const_pressure += cp_t* (chem_object.molar_quantity.get::()/self.total_mol.get::())*r.get::(); - } - MolarHeatCapacity::new::(total_heat_capacity_const_pressure) - } - ///Determining internal energy - //Need to figure out way to calculate Cv - fn internal_energy(&self) -> MolarEnergy { - MolarEnergy::new::(0.0) - } - ///Determining temperature - fn temperature(&self) -> ThermodynamicTemperature { - let r = ThermodynamicConstants::UniversalGasConstant.value().downcast::().unwrap().get::(); - //T = PV/nR - let p = self.pressure.get::(); - let v = self.total_vol.get::(); - let n = self.total_mol.get::(); - let ideal_temperature = (p*v)/(n*r); - ThermodynamicTemperature::new::(ideal_temperature) - } - ///Determining volume - fn volume(&self) -> Volume { - let r = ThermodynamicConstants::UniversalGasConstant.value().downcast::().unwrap().get::(); - // V = (nRT)/P - let n = self.total_mol.get::(); - let p = self.pressure.get::(); - let t = self.temperature.get::(); - let ideal_volume = (n*r*t)/(p); - Volume::new::(ideal_volume) - } - ///Determining the Gibbs free energy - fn gibbs_free_energy(&self) -> Energy { - let enthalpy = self.enthalpy().get::()*self.total_mol.get::(); - let entropy = self.entropy().get::()*self.total_mol.get::(); - let gibbs_free_energy_value = enthalpy - self.temperature.get::()*entropy; - Energy::new::(gibbs_free_energy_value) - } -} - From 479d71610cb563b3bd4f83a1dff8be0fa00fff83 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Wed, 4 Jun 2025 19:02:28 -0400 Subject: [PATCH 18/21] fixed some compiler issues --- oscps-lib/Cargo.toml | 2 +- oscps-lib/src/blocks.rs | 2 +- oscps-lib/src/lib.rs | 6 +++++- .../src/properties/pure_species_properties.rs | 2 +- oscps-lib/src/stream.rs | 18 ++++++++++++++---- oscps-lib/src/thermodynamics.rs | 2 ++ 6 files changed, 24 insertions(+), 8 deletions(-) diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index 0b2deb7..320625c 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] [dependencies] -uom = "0.36.0" +uom = "0.37.0" once_cell = "1.17.1" pubchem = "0.1.1" serde = { version = "1.0", features = ["derive"] } diff --git a/oscps-lib/src/blocks.rs b/oscps-lib/src/blocks.rs index ff99f2c..b40c738 100644 --- a/oscps-lib/src/blocks.rs +++ b/oscps-lib/src/blocks.rs @@ -6,7 +6,7 @@ //! For example, if a block is a simple mixer, then it will implement the //! MassBalance trait but not the EnergyBalance. -use crate::connector::Stream; +use crate::stream::Stream; use once_cell::sync::Lazy; use uom::si::energy::joule; use uom::si::f64::Energy; diff --git a/oscps-lib/src/lib.rs b/oscps-lib/src/lib.rs index d645347..befb911 100644 --- a/oscps-lib/src/lib.rs +++ b/oscps-lib/src/lib.rs @@ -5,9 +5,13 @@ #![warn(missing_docs)] +extern crate uom; +extern crate once_cell; +extern crate serde; +extern crate anyhow; + pub mod blocks; pub mod properties; pub mod stream; pub mod simulation; pub mod thermodynamics; - diff --git a/oscps-lib/src/properties/pure_species_properties.rs b/oscps-lib/src/properties/pure_species_properties.rs index a8c7b45..f9b4983 100644 --- a/oscps-lib/src/properties/pure_species_properties.rs +++ b/oscps-lib/src/properties/pure_species_properties.rs @@ -8,7 +8,7 @@ use crate::properties::*; use uom::si::f64; use std::sync::Arc; -use oscps_db::*; +// use oscps_db; ///#PureSpeciesProperties /// diff --git a/oscps-lib/src/stream.rs b/oscps-lib/src/stream.rs index 109fccd..855eba6 100644 --- a/oscps-lib/src/stream.rs +++ b/oscps-lib/src/stream.rs @@ -1,7 +1,15 @@ //! # Connector //! -use crate::thermodynamics::{ThermodynamicConstants, ThermoPackage}; +use crate::thermodynamics::{ThermodynamicConstants, MaxwellRelations}; +use crate::properties::Chemical; +///Importing External Packages +use uom::si::f64::*; +use uom::si::mass; +use uom::si::pressure; +use uom::si::thermodynamic_temperature; +use uom::si::energy; +use uom::si::amount_of_substance; /// # Stream /// @@ -23,7 +31,6 @@ pub struct Stream { pub to_block : String } - impl Stream { /// Constructor for 'Stream' struct pub fn new(id: String, from_blk_id : String, to_blk_id : String) -> Stream { @@ -36,8 +43,11 @@ impl Stream { } } + #[allow(dead_code)] -/// Species list +/// #ComponentData +/// +/// Species list for a stream pub struct ComponentData { /// Chemical species pub chemical_species: Chemical, // will contain intrinsic properties of species @@ -70,7 +80,7 @@ pub struct StreamThermoState { /// Total Volume pub total_volume : Option, // total volume in stream ///Thermo Package - pub thermodynamic_package : Option> // thermodynamics package + pub thermodynamic_package : Option> // thermodynamics package } diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index 5951931..0c902e4 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -17,6 +17,8 @@ use uom::si::thermodynamic_temperature; use uom::si::energy; use uom::si::amount_of_substance; +// use std::autodiff::*; + #[allow(dead_code)] /// #ThermodynamicConstants /// From c5a70b1215a963ba1a5cdbc9bd923c26ec2fe4b9 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Wed, 4 Jun 2025 21:48:53 -0400 Subject: [PATCH 19/21] updating comments and using third party autodiff package until experimental std::autodiff is implemented into rust --- oscps-lib/Cargo.toml | 1 + oscps-lib/src/thermodynamics.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index 320625c..03d3507 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -11,4 +11,5 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tokio = { version = "1", features = ["full"] } anyhow = "1.0" +autodiff = "0.7.0" oscps-db = { path = "../oscps-db" } diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index 0c902e4..1ae7d40 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -17,7 +17,6 @@ use uom::si::thermodynamic_temperature; use uom::si::energy; use uom::si::amount_of_substance; -// use std::autodiff::*; #[allow(dead_code)] /// #ThermodynamicConstants @@ -68,6 +67,10 @@ impl ThermodynamicConstants { /// ///For calculations, the thermodynamic packages will call upon the property struct for relevant ///info. +/// +///TODO: Currently the rust std::autodiff is still experimental. Need to wait for this release. In +///the meantime, we will either manually write out the derivatives or use a third party autdiff +///package (the third party is: https://crates.io/crates/autodiff) pub trait MaxwellRelations{ ///Calculating the Enthalpy fn enthalpy(&self) -> MolarEnergy; From cc786127adaa8c7ec12805c138804d8ef8565021 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 8 Jun 2025 14:58:48 -0400 Subject: [PATCH 20/21] made minor changes --- oscps-lib/Cargo.toml | 1 + oscps-lib/src/thermodynamics.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/oscps-lib/Cargo.toml b/oscps-lib/Cargo.toml index 03d3507..aef0dad 100644 --- a/oscps-lib/Cargo.toml +++ b/oscps-lib/Cargo.toml @@ -2,6 +2,7 @@ name = "oscps-lib" version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2021" [dependencies] uom = "0.37.0" diff --git a/oscps-lib/src/thermodynamics.rs b/oscps-lib/src/thermodynamics.rs index 1ae7d40..dce49bc 100644 --- a/oscps-lib/src/thermodynamics.rs +++ b/oscps-lib/src/thermodynamics.rs @@ -17,7 +17,6 @@ use uom::si::thermodynamic_temperature; use uom::si::energy; use uom::si::amount_of_substance; - #[allow(dead_code)] /// #ThermodynamicConstants /// From 19745d41064f0f2d1443ccf45951aa6b7ed92c59 Mon Sep 17 00:00:00 2001 From: Bhargav Akula Date: Sun, 8 Jun 2025 15:24:21 -0400 Subject: [PATCH 21/21] minor updates to branch fixed 'edition' for cargo.toml files --- oscps-db/Cargo.toml | 1 + oscps-gui/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/oscps-db/Cargo.toml b/oscps-db/Cargo.toml index 77a353c..522b655 100644 --- a/oscps-db/Cargo.toml +++ b/oscps-db/Cargo.toml @@ -2,5 +2,6 @@ name = "oscps-db" version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2021" [dependencies] diff --git a/oscps-gui/Cargo.toml b/oscps-gui/Cargo.toml index 64bdd4e..b98ca8e 100644 --- a/oscps-gui/Cargo.toml +++ b/oscps-gui/Cargo.toml @@ -2,6 +2,7 @@ name = "oscps-gui" version = "0.1.0" authors = ["Nathaniel Thomas ", "Bhargav Akula "] +edition = "2021" [dependencies] env_logger = "0.11.6"