1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use data_sep::*;
use math::{ gcd };
use reaction::{ ElemReaction };
use trait_element::{ Element };
use trait_properties::{ Properties };
use trait_reaction::{ Reaction };
use types::*;
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct RedoxReaction<E: Element> {
pub reductor: ElemReaction<E>,
pub oxidator: ElemReaction<E>
}
impl<E: Element> Reaction<E> for RedoxReaction<E> {
fn equalise(&self) -> bool {
self.elem_reaction().equalise()
}
fn is_valid(&self) -> bool {
get_sep(&self.oxidator) > get_sep(&self.reductor) && self.elem_reaction().is_valid()
}
fn energy_cost(&self) -> Energy {
self.reductor.energy_cost() + self.oxidator.energy_cost()
}
fn elem_reaction(&self) -> ElemReaction<E> {
let red_charge;
let oxi_charge;
if let Some(red_elec_pos) = self.reductor.rhs.compounds.iter().position(|x|
x.element.get_molecule().unwrap()
.compounds.get(0).unwrap()
.atom.number == 0
) {
red_charge = self.reductor.rhs.compounds.get(red_elec_pos).unwrap().amount;
} else if let Some(red_elec_pos) = self.reductor.lhs.compounds.iter().position(|x|
x.element.get_molecule().unwrap()
.compounds.get(0).unwrap()
.atom.number == 0
) {
red_charge = self.reductor.lhs.compounds.get(red_elec_pos).unwrap().amount;
} else {
panic!("Reductor has no electrons!");
}
if let Some(oxi_elec_pos) = self.oxidator.lhs.compounds.iter().position(|x|
x.element.get_molecule().unwrap()
.compounds.get(0).unwrap()
.atom.number == 0
) {
oxi_charge = self.oxidator.lhs.compounds.get(oxi_elec_pos).unwrap().amount;
} else if let Some(oxi_elec_pos) = self.oxidator.rhs.compounds.iter().position(|x|
x.element.get_molecule().unwrap()
.compounds.get(0).unwrap()
.atom.number == 0
) {
oxi_charge = self.oxidator.rhs.compounds.get(oxi_elec_pos).unwrap().amount;
} else {
panic!("Oxidator has no electrons!");
}
let gcd = gcd(red_charge as i32, oxi_charge as i32) as u16;
let red_mult = oxi_charge / gcd;
let oxi_mult = red_charge / gcd;
ElemReaction {
lhs: self.reductor.lhs.clone() * red_mult + self.oxidator.lhs.clone() * oxi_mult,
rhs: self.reductor.rhs.clone() * red_mult + self.oxidator.rhs.clone() * oxi_mult,
is_equilibrium: true
}
}
}
impl<E: Element> Properties for RedoxReaction<E> {
fn symbol(&self) -> String {
let mut symbol = String::new();
symbol += "oxidator: ";
symbol += &self.oxidator.symbol();
symbol += "\n";
symbol += "reductor: ";
symbol += &self.reductor.symbol();
return symbol;
}
fn name(&self) -> String {
let mut name = String::new();
name += "oxidator: ";
name += &self.oxidator.name();
name += "\n";
name += "reductor: ";
name += &self.reductor.name();
return name;
}
fn mass(&self) -> AtomMass {
0.0
}
}