-
Notifications
You must be signed in to change notification settings - Fork 19
/
reactions.py
executable file
·167 lines (144 loc) · 6.89 KB
/
reactions.py
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import unittest
import cmf
t = cmf.Time()
def setup():
p = cmf.project('A B C')
S = p.NewStorage('S')
S.volume = 1.0
return p, S
class ReactionObjects(unittest.TestCase):
def test_Reaction_01_access(self):
"""Test if the reactions behave like a list"""
p, S = setup()
A = p.solutes[0]
self.assertEqual(len(S[A].reactions), 0)
def test_Reaction_02_constant(self):
"""Test a cmf.SoluteConstantFluxReaction"""
p, S = setup()
A = p.solutes[0]
reaction = cmf.SoluteConstantFluxReaction(1.0)
S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), 1.0, 'Change rate of solute does not equal reaction')
reaction.flux = 2.0
self.assertEqual(S[A].dxdt(t), 2.0, 'Change rate of solute does not react to parameter change of parent')
def test_Reaction_02_rate_zero_order(self):
"""Test a cmf.SoluteRateReaction as constant source"""
p, S = setup()
A = p.solutes[0]
reaction = cmf.SoluteRateReaction.constant_source(A, 1.0)
S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), 1.0, 'Change rate of solute does not equal reaction')
S[A].conc = 30.0
self.assertEqual(S[A].dxdt(t), 1.0, 'Change rate of solute not independent of concentration')
def test_Reaction_03_decay(self):
"""Test cmf.SoluteDecayReaction"""
p, S = setup()
A = p.solutes[0]
reaction = cmf.SoluteDecayReaction(1.0)
S[A].state = 1.0
S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'Change rate of solute does not equal reaction')
S[A].state = 0.5
self.assertEqual(S[A].dxdt(t), -0.5, 'Change rate of solute does not react to state change')
reaction.decay = 2.0
self.assertEqual(S[A].dxdt(t), -1.0, 'Change rate of solute does not react to parameter change of parent')
def test_Reaction_03_rate_decay(self):
"""Test cmf.SoluteRateReaction as linear decay"""
p, S = setup()
A = p.solutes[0]
reaction = cmf.SoluteRateReaction.decay(A, 1.0)
S[A].state = 1.0
S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'Change rate of solute does not equal reaction')
S[A].state = 0.5
self.assertEqual(S[A].dxdt(t), -0.5, 'Change rate of solute does not react to state change')
reaction.k_forward = 2.0
self.assertEqual(S[A].dxdt(t), -1.0, 'Change rate of solute does not react to parameter change of parent')
def test_Reaction_04_Equilibrium(self):
"""Test cmf.SoluteEquilibriumReaction"""
p, S = setup()
A, B = list(p.solutes)[:2]
reaction = cmf.SoluteEquilibriumReaction(A, B, 1.0, 1.0)
S[A].state = 1.0
S[B].state = 0.0
S[B].reactions = S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'dA/dt: Change rate of solute does not equal reaction')
self.assertEqual(S[B].dxdt(t), 1.0, 'dB/dt: Change rate of solute does not equal other Solute')
S[B].state = 1.0
self.assertEqual(S[A].dxdt(t), 0.0, 'Change rate of solute not zero for equilibrium')
def test_Reaction_04_Rate_Equilibrium(self):
"""Test cmf.SoluteEquilibriumReaction"""
p, S = setup()
A, B = list(p.solutes)[:2]
reaction = cmf.SoluteRateReaction(1.0, 1.0).update({A: -1, B: +1})
S.volume = 1.0
S[A].state = 1.0
S[B].state = 0.0
S[B].reactions = S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'dA/dt: Change rate of solute does not equal reaction')
self.assertEqual(S[B].dxdt(t), 1.0, 'dB/dt: Change rate of solute does not equal other Solute')
S[B].state = 1.0
self.assertEqual(S[A].dxdt(t), 0.0, 'Change rate of solute not zero for equilibrium')
def test_Reaction_05_1st_order(self):
"""Test cmf.Solute1stOrderReaction"""
p, S = setup()
A, B = p.solutes[:2]
reaction = cmf.Solute1stOrderReaction(A, B, 1.0)
S.volume = 1.0
S[A].state = 1.0
S[B].state = 0.0
S[B].reactions = S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'dA/dt: Change rate of solute does not equal reaction')
self.assertEqual(S[B].dxdt(t), 1.0, 'dB/dt: Change rate of solute does not equal other Solute')
S[B].state = 1.0
self.assertEqual(S[A].dxdt(t), -1.0, 'Change rate of solute is changed by concentration of product')
def test_Reaction_06_2nd_order(self):
"""Test cmf.Solute2ndOrderReaction"""
p, S = setup()
A, B, C = p.solutes[:]
reaction = cmf.Solute2ndOrderReaction(A, B, C, 1.0)
S.volume = 1.0
S[A].state = 0.5
S[B].state = 2.0
for X in p.solutes:
S[X].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'dA/dt: Change rate of solute does not equal reaction')
self.assertEqual(S[B].dxdt(t), -1.0, 'dB/dt: Change rate of solute does not equal other Solute')
self.assertEqual(S[C].dxdt(t), 1.0, 'Change rate of solute is changed by concentration of product')
def test_Reaction_06_rate_2nd_order(self):
"""Test cmf.Solute2ndOrderReaction"""
p, S = setup()
A, B, C = p.solutes[:]
reaction = cmf.SoluteRateReaction.multi({A: -1, B: -1, C: 2}, 1.0)
S.volume = 1.0
S[A].state = 0.5
S[B].state = 2.0
cmf.attach_reactions_to_waterstorage(S, [reaction])
self.assertEqual(S[A].dxdt(t), -1.0, 'dA/dt: Change rate of solute does not equal reaction')
self.assertEqual(S[B].dxdt(t), -1.0, 'dB/dt: Change rate of solute does not equal other Solute')
self.assertEqual(S[C].dxdt(t), 2.0, 'Change rate of solute is changed by concentration of product')
def test_Reaction_05_rate_1st_order(self):
"""Test cmf.SoluteRateReaction as 1st order reaction"""
p, S = setup()
A, B = p.solutes[:2]
reaction = cmf.SoluteRateReaction(1.0).update({A: -1, B: 1})
S.volume = 1.0
S[A].state = 1.0
S[B].state = 0.0
S[B].reactions = S[A].reactions = [reaction]
self.assertEqual(S[A].dxdt(t), -1.0, 'dA/dt: Change rate of solute does not equal reaction')
self.assertEqual(S[B].dxdt(t), 1.0, 'dB/dt: Change rate of solute does not equal other Solute')
S[B].state = 1.0
self.assertEqual(S[A].dxdt(t), -1.0, 'Change rate of solute is changed by concentration of product')
def test_Reaction_10_director(self):
"""Test cmf.SoluteReaction in a Python implementation"""
p, S = setup()
A = p.solutes[0]
class R(cmf.SoluteReaction):
def get_flux(self, solstor, t):
return 1.0
r = R()
S[A].reactions = [r]
self.assertEqual(S[A].dxdt(t), 1.0, 'Change rate of solute does not equal reaction')
if __name__ == '__main__':
unittest.main(verbosity=2)