Skip to content

Commit d214bc6

Browse files
committed
Updated documentation
1 parent 39ba4d2 commit d214bc6

6 files changed

Lines changed: 317 additions & 242 deletions

File tree

oscps-lib/src/blocks.rs

Lines changed: 135 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,182 +1,195 @@
11
//! # Blocks
22
//!
3-
//! This file contains traits which describe the traits that will be
4-
//! implemented by various structs to represent different unit operations.
3+
//! This file contains traits implemented by various structs to represent
4+
//! different unit operations.
55
//!
66
//! For example, if a block is a simple mixer, then it will implement the
77
//! MassBalance trait but not the EnergyBalance.
8-
//!
98
9+
use crate::connector;
10+
use once_cell::sync::Lazy;
11+
use uom::si::energy::joule;
1012
use uom::si::f64::Energy;
1113
use uom::si::f64::Mass;
1214
use uom::si::mass::kilogram;
13-
use uom::si::energy::joule;
14-
use crate::connector;
15-
use once_cell::sync::Lazy;
1615

17-
//Initiallizing a global variable for the tolerance for the energy balance
1816
#[allow(dead_code)]
19-
static TOLERENCE_ENERGY: Lazy<Energy> = Lazy::new(|| Energy::new::<joule>(5.0));
17+
/// Minimum error allowed for energy difference. TODO: Change this to a
18+
/// relative scale instead of an absolute scale.
19+
pub static TOLERENCE_ENERGY: Lazy<Energy> =
20+
Lazy::new(|| Energy::new::<joule>(5.0));
2021

21-
//Initiallizing a global variable for the tolerance for the mass balance
2222
#[allow(dead_code)]
23-
static TOLERENCE_MASS: Lazy<Mass> = Lazy::new(|| Mass::new::<kilogram>(5.0));
24-
25-
//Initiallizing a global variable for the tolerance for the element balance
23+
/// Minimum error allowed for mass difference. TODO: Change this to a relative
24+
/// scale instead of an absolute scale.
25+
pub static TOLERENCE_MASS: Lazy<Mass> =
26+
Lazy::new(|| Mass::new::<kilogram>(5.0));
2627

28+
#[allow(dead_code)]
2729
/// Trait for ensuring the overall mass balance is maintained in a flowsheet.
2830
///
29-
/// This trait can be implemented by any block that needs to ensure mass conservation.
30-
#[allow(dead_code)]
31+
/// This trait can be implemented by any block that needs to ensure mass
32+
/// conservation.
3133
pub trait MassBalance {
32-
// total mass in - total mass out < tolerance
33-
fn mass_balance_check(&self, mass_in : Mass, mass_out : Mass) -> bool {
34+
/// Perform a mass balance check on object by comparing inlet and outlet
35+
/// mass. TODO: Compare mass flow rates, not mass and check for relative
36+
/// error instead of absolute, perhaps error should be less than 1e-6
37+
/// fraction of the total inlet mass. This can be an adjustable parameter.
38+
/// Smaller takes longer to converge, but is more
39+
fn mass_balance_check(&self, mass_in: Mass, mass_out: Mass) -> bool {
3440
let mass_in_kg = mass_in.get::<kilogram>();
3541
let mass_out_kg = mass_out.get::<kilogram>();
36-
3742
let mass_difference = mass_in_kg - mass_out_kg;
38-
3943
return mass_difference <= TOLERENCE_MASS.get::<kilogram>();
4044
}
4145
}
4246

47+
#[allow(dead_code)]
4348
/// # EnergyBalance
4449
///
45-
/// This trait ensures that blocks in the flowsheet adhere to energy conservation principles.
46-
///
47-
/// This is useful for distinguishing between "dynamic" and "steady state" simulations.
48-
#[allow(dead_code)]
50+
/// This trait ensures that blocks in the flowsheet adhere to energy
51+
/// conservation principles.
4952
pub trait EnergyBalance {
50-
51-
// total energy in - total energy out < tolerance
52-
fn energy_balance_check(&self, energy_in : Energy, energy_out : Energy) -> bool {
53-
// Convert both energy_in and energy_out to joules
53+
/// Perform an energy balance on a block. Checks all input and output
54+
/// streams and ensures that energy stays the same. TODO: Ensure that
55+
/// energy loss is accounted for. For example, a mixer may not be entirely
56+
/// adiabatic, and therefor some energy will be lost to the environment.
57+
/// Also implement changes in issue #19.
58+
fn energy_balance_check(&self, energy_in: Energy, energy_out: Energy) ->
59+
bool {
5460
let energy_in_joules = energy_in.get::<joule>();
5561
let energy_out_joules = energy_out.get::<joule>();
56-
57-
// Calculate the difference between energy_in and energy_out in joules
5862
let energy_difference = energy_in_joules - energy_out_joules;
59-
60-
// Check if the energy difference is less than the global threshold
61-
let within_threshold = energy_difference <= TOLERENCE_ENERGY.get::<joule>();
62-
63+
let within_threshold = energy_difference <=
64+
TOLERENCE_ENERGY.get::<joule>();
6365
return within_threshold;
64-
6566
}
6667
}
6768

68-
/// # Mixer Block
69-
///
70-
/// A block used for simple stream mixing operations.
71-
///
72-
/// This struct requires the implementation of both EnergyBalance and MassBalance traits to ensure proper conservation principles are followed.
7369
#[allow(dead_code)]
70+
/// # Mixer
71+
///
72+
/// A block used for simple stream mixing operations.
7473
pub struct Mixer {
75-
pub block_id : String,
76-
pub x_cord : i32,
77-
pub y_cord : i32,
78-
pub input_streams_mass : Vec<connector::Mconnector>,
79-
pub input_streams_energy : Vec<connector::Econnector>,
80-
pub outlet_stream_energy : Option<connector::Econnector>,
74+
/// The ID of the block.
75+
pub block_id: String,
76+
/// The x-coordiante on a flowsheet of the block.
77+
pub x_cord: i32,
78+
/// The y-coordinate on a flowsheet of the block.
79+
pub y_cord: i32,
80+
/// All mass input streams for the block.
81+
pub input_streams_mass: Vec<connector::Mconnector>,
82+
/// All energy input streams for the block.
83+
pub input_streams_energy: Vec<connector::Econnector>,
84+
/// All mass output streams for the block.
8185
pub outlet_stream_mass: Option<connector::Mconnector>,
82-
86+
/// All energy output streams for the block
87+
pub outlet_stream_energy: Option<connector::Econnector>,
8388
}
8489

85-
// Applying mass balance trait to Mixer Block
90+
/// Applying mass balance trait to Mixer Block
8691
impl MassBalance for Mixer {}
8792

88-
// Applying the energy balance trait to the Mixer Block
93+
/// Applying the energy balance trait to the Mixer Block
8994
impl EnergyBalance for Mixer {}
9095

9196
#[allow(dead_code)]
97+
/// Implementations of the mixer block.
9298
impl Mixer {
93-
pub fn new(id : String, x_cord : i32, y_cord : i32, in_streams_mass : Vec<connector::Mconnector>, in_streams_energy : Vec<connector::Econnector>) -> Mixer {
99+
/// Create a new mixer block.
100+
pub fn new(
101+
id: String,
102+
x_cord: i32,
103+
y_cord: i32,
104+
in_streams_mass: Vec<connector::Mconnector>,
105+
in_streams_energy: Vec<connector::Econnector>,
106+
) -> Mixer {
94107
return Mixer {
95-
block_id : id,
108+
block_id: id,
96109
x_cord,
97110
y_cord,
98-
input_streams_mass : in_streams_mass,
99-
input_streams_energy : in_streams_energy,
100-
outlet_stream_mass : None,
101-
outlet_stream_energy : None
111+
input_streams_mass: in_streams_mass,
112+
input_streams_energy: in_streams_energy,
113+
outlet_stream_mass: None,
114+
outlet_stream_energy: None,
102115
};
103116
}
104117

118+
/// Execute the mixer block (calculate balances, output streams, etc)
119+
/// TODO: This block should calculate the new state of external connectors.
105120
pub fn execute_block(&mut self) {
106-
107-
// Calculating total Energy and Mass leaving the system (Assuming Steady State...)
108-
self.outlet_stream_mass = Some(connector::Mconnector{
109-
m_conn_id : String::from("Mass_Outlet"),
110-
m_flow_total : self.compute_total_outlet_mass_flow().unwrap()
121+
self.outlet_stream_mass = Some(connector::Mconnector {
122+
m_conn_id: String::from("Mass_Outlet"),
123+
m_flow_total: self.compute_total_outlet_mass_flow().unwrap(),
124+
});
125+
self.outlet_stream_energy = Some(connector::Econnector {
126+
e_conn_id: String::from("Energy Outlet"),
127+
energy_flow_total: self.compute_outlet_energy_flows().unwrap(),
111128
});
112-
self.outlet_stream_energy = Some(connector::Econnector { e_conn_id: String::from("Energy Outlet"), energy_flow_total: self.compute_outlet_energy_flows().unwrap()});
113129
}
114-
130+
115131
/// This private method will compute the outlet mass flows for the mixer block
116-
///
132+
///
117133
/// # Returns
118-
///
134+
///
119135
/// A Mass quantity (uom object) that holds the outlet mass flow
120136
fn compute_total_outlet_mass_flow(&self) -> Option<f64> {
121-
// TODO: steps to implement function:
137+
// TODO: steps to implement function:
122138
// Need to loop through each of the connector structures and add up the mass flows
123-
// During this process, need to make sure that all the mass flows are in the same units
124-
// Use the UOM package to help with this part...
125-
let mut mass_flow_sum : f64 = 0.0;
126-
139+
// During this process, need to make sure that all the mass flows are in the same units
140+
// Use the UOM package to help with this part...
141+
let mut mass_flow_sum: f64 = 0.0;
142+
127143
for stream in &self.input_streams_mass {
128-
mass_flow_sum = mass_flow_sum + stream.m_flow_total;
129-
}
144+
mass_flow_sum = mass_flow_sum + stream.m_flow_total;
145+
}
130146
return Some(mass_flow_sum);
131147
}
132148

133-
149+
/// Determines the total energy flowing through the block
134150
fn compute_outlet_energy_flows(&self) -> Option<f64> {
151+
let mut energy_flow_sum: f64 = 0.0;
135152

136-
let mut energy_flow_sum : f64 = 0.0;
137-
138153
for stream in &self.input_streams_energy {
139-
energy_flow_sum = energy_flow_sum + stream.energy_flow_total;
140-
}
154+
energy_flow_sum = energy_flow_sum + stream.energy_flow_total;
155+
}
141156
return Some(energy_flow_sum);
142157
}
143158

144-
fn compute_outlet_phase_fractions(&self) {
145-
146-
}
147-
148-
fn compute_outlet_temperature(&self) {
149-
150-
}
151-
152-
fn compute_outlet_pressure(&self) {
153-
154-
}
159+
/// Determines the phase fractions of the output using thermodynamics.
160+
/// TODO: Implement this function
161+
fn compute_outlet_phase_fractions(&self) {}
155162

163+
/// Computes the outlet temperature of the mixer (assumes no chemical
164+
/// reactions) TODO: Implement this function
165+
fn compute_outlet_temperature(&self) {}
166+
167+
/// Computes the mixer outlet pressure.
168+
/// TODO: Implement this function
169+
fn compute_outlet_pressure(&self) {}
156170
}
157171

158172
#[cfg(test)]
159173
mod block_tests {
160-
use crate::connector::{Mconnector, Econnector};
174+
use crate::connector::{Econnector, Mconnector};
161175

162176
use super::*;
163-
// use std::io;
164-
use uom::si::f64::Energy;
165177
use uom::si::energy::kilojoule;
178+
use uom::si::f64::Energy;
166179
use uom::si::mass::pound;
167-
180+
168181
#[test]
169182
fn test_mass_balance_check_steady_state_for_mixer() {
170183
// here you will need to check that the mass into the mixer = mass out of mixer
171-
184+
172185
let mixer_test_obj = Mixer {
173-
block_id : String::from("Test Mixer"),
174-
x_cord : 0,
175-
y_cord : 0,
176-
input_streams_mass : Vec::new(),
177-
input_streams_energy : Vec::new(),
178-
outlet_stream_mass : None,
179-
outlet_stream_energy : None
186+
block_id: String::from("Test Mixer"),
187+
x_cord: 0,
188+
y_cord: 0,
189+
input_streams_mass: Vec::new(),
190+
input_streams_energy: Vec::new(),
191+
outlet_stream_mass: None,
192+
outlet_stream_energy: None,
180193
};
181194
let mass_in = Mass::new::<pound>(100.0);
182195
let mass_out = Mass::new::<pound>(95.0);
@@ -187,13 +200,13 @@ mod block_tests {
187200
fn test_energy_balance_check_steady_state_for_mixer() {
188201
// energy into mixer = energy out of mixer
189202
let mixer_test_obj = Mixer {
190-
block_id : String::from("Test Mixer"),
191-
x_cord : 0,
192-
y_cord : 0,
193-
input_streams_mass : Vec::new(),
194-
input_streams_energy : Vec::new(),
195-
outlet_stream_mass : None,
196-
outlet_stream_energy : None
203+
block_id: String::from("Test Mixer"),
204+
x_cord: 0,
205+
y_cord: 0,
206+
input_streams_mass: Vec::new(),
207+
input_streams_energy: Vec::new(),
208+
outlet_stream_mass: None,
209+
outlet_stream_energy: None,
197210
};
198211
let energy_in = Energy::new::<kilojoule>(10.0);
199212
let energy_out = Energy::new::<kilojoule>(95.0);
@@ -203,36 +216,34 @@ mod block_tests {
203216
#[test]
204217
fn test_compute_total_outlet_mass_flow() {
205218
let in_streams_mass = vec![
206-
Mconnector { m_conn_id: String::from("Mass1"), m_flow_total: 3.0 },
207-
Mconnector { m_conn_id: String::from("Mass2"), m_flow_total: 7.0 },
219+
Mconnector {
220+
m_conn_id: String::from("Mass1"),
221+
m_flow_total: 3.0,
222+
},
223+
Mconnector {
224+
m_conn_id: String::from("Mass2"),
225+
m_flow_total: 7.0,
226+
},
208227
];
209-
let mixer = Mixer::new(
210-
String::from("Mixer3"),
211-
0,
212-
0,
213-
in_streams_mass,
214-
vec![],
215-
);
228+
let mixer = Mixer::new(String::from("Mixer3"), 0, 0, in_streams_mass, vec![]);
216229

217230
assert_eq!(mixer.compute_total_outlet_mass_flow(), Some(10.0));
218231
}
219232

220-
221233
#[test]
222234
fn test_compute_outlet_energy_flows() {
223235
let in_streams_energy = vec![
224-
Econnector { e_conn_id: String::from("Energy1"), energy_flow_total: 100.0 },
225-
Econnector { e_conn_id: String::from("Energy2"), energy_flow_total: 200.0 },
236+
Econnector {
237+
e_conn_id: String::from("Energy1"),
238+
energy_flow_total: 100.0,
239+
},
240+
Econnector {
241+
e_conn_id: String::from("Energy2"),
242+
energy_flow_total: 200.0,
243+
},
226244
];
227-
let mixer = Mixer::new(
228-
String::from("Mixer5"),
229-
0,
230-
0,
231-
vec![],
232-
in_streams_energy,
233-
);
245+
let mixer = Mixer::new(String::from("Mixer5"), 0, 0, vec![], in_streams_energy);
234246

235247
assert_eq!(mixer.compute_outlet_energy_flows(), Some(300.0));
236248
}
237-
238249
}

0 commit comments

Comments
 (0)