@@ -4,6 +4,7 @@ using LinearAlgebra
4
4
using Tracker
5
5
using ReverseDiff
6
6
using RecursiveArrayTools
7
+ using Logging
7
8
8
9
@inline function calcgibbs (ph:: U ,T:: W ) where {U<: IdealPhase ,W<: Real }
9
10
return getGibbs .(getfield .(ph. species,:thermo ),T)
50
51
51
52
export makespcsvector
52
53
53
- @inline function getkf (rxn:: ElementaryReaction ,ph,T,P,C,ns,V,phi)
54
+ @inline function getkf (rxn:: ElementaryReaction ,ph,T,P,C,ns,V,phi,dGrxn,d )
54
55
if isdefined (rxn. kinetics,:efficiencies ) && length (rxn. kinetics. efficiencies) > 0
55
56
@views @inbounds @fastmath C += sum ([ns[i]* val for (i,val) in rxn. kinetics. efficiencies])/ V
56
57
end
57
- return rxn. kinetics (T= T,P= P,C= C,phi= phi)
58
+ return rxn. kinetics (T= T,P= P,C= C,phi= phi,dGrxn = dGrxn,d = d )
58
59
end
59
60
export getkf
60
61
61
- @inline function getkfs (ph:: U ,T:: W1 ,P:: W2 ,C:: W3 ,ns:: Q ,V:: W4 ,phi) where {U,W1,W2,W3,W4<: Real ,Q<: AbstractArray }
62
+ @inline function getkfs (ph:: U ,T:: W1 ,P:: W2 ,C:: W3 ,ns:: Q ,V:: W4 ,phi,dGrxns,d ) where {U,W1,W2,W3,W4<: Real ,Q<: AbstractArray }
62
63
kfs = similar (ns,length (ph. reactions))
63
64
i = 1
64
65
oldind = 1
@@ -70,7 +71,7 @@ export getkf
70
71
i += 1
71
72
end
72
73
@simd for i in ind+ 1 : length (ph. reactions)
73
- @inbounds kfs[i] = getkf (ph. reactions[i],ph,T,P,C,ns,V,phi)
74
+ @inbounds kfs[i] = getkf (ph. reactions[i],ph,T,P,C,ns,V,phi,dGrxns[i],d )
74
75
end
75
76
return kfs
76
77
end
@@ -84,13 +85,13 @@ for 2 spc calculates using the Smolchowski equation
84
85
for >2 spc calculates using the Generalized Smolchowski equation
85
86
Equations from Flegg 2016
86
87
"""
87
- @inline function getDiffusiveRate (spcs:: Q ,diffs:: Array{W,1} ) where {Q<: AbstractArray ,W<: Real }
88
+ @inline function getDiffusiveRate (spcs:: Q ,spcsinds :: Q2 , diffs:: Array{W,1} ) where {Q<: AbstractArray ,W<: Real ,Q2 <: AbstractArray }
88
89
if length (spcs) == 1
89
90
return Inf
90
91
elseif length (spcs) == 2
91
- @fastmath @inbounds kf = 4.0 * Base. pi * (diffs[spcs [1 ]. index ]+ diffs[spcs [2 ]. index ])* (spcs[1 ]. radius+ spcs[2 ]. radius)* Na
92
+ @fastmath @inbounds kf = 4.0 * Base. pi * (diffs[spcsinds [1 ]]+ diffs[spcsinds [2 ]])* (spcs[1 ]. radius+ spcs[2 ]. radius)* Na
92
93
else
93
- @views @inbounds diffusivity = diffs[getfield .(spcs, :index ) ]
94
+ @views @inbounds diffusivity = diffs[spcsinds ]
94
95
N = length (spcs)
95
96
@fastmath a = (3.0 * length (spcs)- 5.0 )/ 2.0
96
97
@fastmath Dinv = 1.0 ./ diffusivity
@@ -103,76 +104,26 @@ Equations from Flegg 2016
103
104
end
104
105
export getDiffusiveRate
105
106
106
- @inline function getKc (rxn:: ElementaryReaction ,ph:: U ,T:: Z ,Gs :: Q ,phi:: V = 0.0 ) where {U<: AbstractPhase ,V,Q,Z<: Real }
107
+ @inline function getKc (rxn:: ElementaryReaction ,ph:: U ,T:: Z ,dGrxn :: Q ,phi:: V = 0.0 ) where {U<: AbstractPhase ,V,Q,Z<: Real }
107
108
Nreact = length (rxn. reactantinds)
108
109
Nprod = length (rxn. productinds)
109
- dGrxn = 0.0
110
- if Nreact == 1
111
- @fastmath @inbounds dGrxn -= Gs[rxn. reactantinds[1 ]]
112
- elseif Nreact == 2
113
- @fastmath @inbounds dGrxn -= Gs[rxn. reactantinds[1 ]]+ Gs[rxn. reactantinds[2 ]]
114
- elseif Nreact == 3
115
- @fastmath @inbounds dGrxn -= Gs[rxn. reactantinds[1 ]]+ Gs[rxn. reactantinds[2 ]]+ Gs[rxn. reactantinds[3 ]]
116
- elseif Nreact == 4
117
- @fastmath @inbounds dGrxn -= Gs[rxn. reactantinds[1 ]]+ Gs[rxn. reactantinds[2 ]]+ Gs[rxn. reactantinds[3 ]]+ Gs[rxn. reactantinds[4 ]]
118
- end
119
- if Nprod == 1
120
- @fastmath @inbounds dGrxn += Gs[rxn. productinds[1 ]]
121
- elseif Nprod == 2
122
- @fastmath @inbounds dGrxn += Gs[rxn. productinds[1 ]]+ Gs[rxn. productinds[2 ]]
123
- elseif Nprod == 3
124
- @fastmath @inbounds dGrxn += Gs[rxn. productinds[1 ]]+ Gs[rxn. productinds[2 ]]+ Gs[rxn. productinds[3 ]]
125
- elseif Nprod == 4
126
- @fastmath @inbounds dGrxn += Gs[rxn. productinds[1 ]]+ Gs[rxn. productinds[2 ]]+ Gs[rxn. productinds[3 ]]+ Gs[rxn. productinds[4 ]]
127
- end
128
- return @inbounds @fastmath exp (- (dGrxn+ rxn. electronchange* phi)/ (R* T))* (getC0 (ph,T))^ (Nprod- Nreact)
110
+ return @inbounds @fastmath exp ((dGrxn+ rxn. electronchange* (phi* F))/ (- R* T))* (getC0 (ph,T))^ (Nprod- Nreact)
129
111
end
130
112
131
- @inline function getKc (rxn:: ElementaryReaction ,phase1,phase2,Gs1,Gs2,T,phi= 0.0 ) # for constant k interfaces
132
- dGrxn = 0.0
133
- dN1 = 0
134
- dN2 = 0
135
- for r in rxn. reactants
136
- isfirst = true
137
- ind = findfirst (isequal (r),phase1. species)
138
- if ind === nothing
139
- isfirst = false
140
- ind = findfirst (isequal (r),phase2. species)
141
- dGrxn -= Gs2[ind]
142
- dN2 -= 1
143
- else
144
- dGrxn -= Gs1[ind]
145
- dN1 -= 1
146
- end
147
- end
148
- for r in rxn. products
149
- isfirst = true
150
- ind = findfirst (isequal (r),phase1. species)
151
- if ind === nothing
152
- isfirst = false
153
- ind = findfirst (isequal (r),phase2. species)
154
- dGrxn += Gs2[ind]
155
- dN2 += 1
156
- else
157
- dGrxn += Gs1[ind]
158
- dN1 += 1
159
- end
160
- end
161
- return @inbounds @fastmath exp (- (dGrxn+ rxn. electronchange* phi)/ (R* T))* getC0 (phase1,T)^ dN1* getC0 (phase2,T)^ dN2
113
+ @inline function getKcs (ph:: U ,T:: Z ,dGrxns:: Q ) where {U<: AbstractPhase ,Q,Z<: Real }
114
+ return @fastmath @inbounds exp .(dGrxns./ (- R* T) .+ ph. Nrp.* log (getC0 (ph,T)));
162
115
end
163
- export getKc
164
116
165
- @inline function getKcs (ph:: U ,T:: Z ,Gs :: Q ) where {U<: AbstractPhase ,Q,Z<: Real }
166
- return @fastmath @inbounds exp .(ph . stoichmatrix * (Gs ./ ( R* T) ) .+ ph. Nrp.* log (getC0 (ph,T)));
117
+ @inline function getKcs (ph:: U ,T:: Z ,dGrxns :: Q ,phi :: V ) where {U<: AbstractPhase ,Q,Z<: Real ,V <: Real }
118
+ return @fastmath @inbounds exp .(dGrxns ./ ( - R* T) .+ ph. Nrp.* log (getC0 (ph,T)));
167
119
end
168
120
169
- @inline function getKcs (ph:: U ,T :: Z ,Gs :: Q ,phi :: V ) where {U <: AbstractPhase ,Q,Z <: Real ,V <: Real }
170
- return @fastmath @inbounds exp .(ph . stoichmatrix * (Gs ./ ( R* T)) . + ph. electronchange .* (phi / (R * T)) .+ ph. Nrp .* log (getC0 (ph,T)));
121
+ @inline function getKcs (ph,T,Gs1,Gs2,dGrxns)
122
+ return @fastmath @inbounds exp .(dGrxns ./ ( - R* T) .+ ph. Nrp1 .* log ( getC0 (ph . domain1 . phase, T)) .+ ph. Nrp2 .* log (getC0 (ph. domain2 . phase ,T)));
171
123
end
172
124
173
- @inline function getKcs (ph,T,Gs1,Gs2)
174
- Gpart = ArrayPartition (Gs1,Gs2)
175
- return @fastmath @inbounds exp .(ph. stoichmatrix* (Gpart./ (R* T)) .+ ph. Nrp1.* log (getC0 (ph. domain1. phase,T)) .+ ph. Nrp2.* log (getC0 (ph. domain2. phase,T)));
125
+ @inline function getKcs (ph1,ph2,T,Nrp1,Nrp2,dGrxns)
126
+ return @fastmath @inbounds exp .(dGrxns./ (- R* T) .+ Nrp1.* log (getC0 (ph1,T)) .+ Nrp2.* log (getC0 (ph2,T)));
176
127
end
177
128
178
129
export getKcs
@@ -181,30 +132,30 @@ export getKcs
181
132
Calculates the forward and reverse rate coefficients for a given reaction, phase and state
182
133
Maintains diffusion limitations if the phase has diffusionlimited=true
183
134
"""
184
- @inline function getkfkrev (rxn:: ElementaryReaction ,ph:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs :: Q2 ,diffs:: Q3 ,V:: W5 ,phi:: W8 ;kf:: W6 = - 1.0 ,f:: W7 = - 1.0 ) where {U<: AbstractPhase ,W8,W6,W7,W5,W4,W1,W2,W3<: Real ,Q1,Q2,Q3<: AbstractArray }
185
- if signbit (kf)
135
+ @inline function getkfkrev (rxn:: ElementaryReaction ,ph:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,dGrxn :: Q2 ,diffs:: Q3 ,V:: W5 ,phi:: W8 ,d ;kf:: W6 = - 1.0 ,f:: W7 = - 1.0 ) where {U<: AbstractPhase ,W8,W6,W7,W5,W4,W1,W2,W3<: Real ,Q1,Q2,Q3<: AbstractArray }
136
+ if signbit (kf)
186
137
if signbit (f)
187
- kf = getkf (rxn,ph,T,P,C,ns,V,phi)
138
+ kf = getkf (rxn,ph,T,P,C,ns,V,phi,dGrxn,d )
188
139
else
189
- kf = getkf (rxn,ph,T,P,C,ns,V,phi)* f
140
+ kf = getkf (rxn,ph,T,P,C,ns,V,phi,dGrxn,d )* f
190
141
end
191
142
end
192
- Kc = getKc (rxn,ph,T,Gs ,phi)
143
+ Kc = getKc (rxn,ph,T,dGrxn ,phi)
193
144
@fastmath krev = kf/ Kc
194
145
if ph. diffusionlimited
195
146
if length (rxn. reactants) == 1
196
147
if length (rxn. products) > 1
197
- krevdiff = getDiffusiveRate (rxn. products,diffs)
148
+ krevdiff = getDiffusiveRate (rxn. products,rxn . productinds, diffs)
198
149
@fastmath krev = krev* krevdiff/ (krev+ krevdiff)
199
150
@fastmath kf = Kc* krev
200
151
end
201
152
elseif length (rxn. products) == 1
202
- kfdiff = getDiffusiveRate (rxn. reactants,diffs)
153
+ kfdiff = getDiffusiveRate (rxn. reactants,rxn . reactantinds, diffs)
203
154
@fastmath kf = kf* kfdiff/ (kf+ kfdiff)
204
155
@fastmath krev = kf/ Kc
205
156
elseif length (rxn. products) == length (rxn. reactants)
206
- kfdiff = getDiffusiveRate (rxn. reactants,diffs)
207
- krevdiff = getDiffusiveRate (rxn. products,diffs)
157
+ kfdiff = getDiffusiveRate (rxn. reactants,rxn . reactantinds, diffs)
158
+ krevdiff = getDiffusiveRate (rxn. products,rxn . productinds, diffs)
208
159
@fastmath kff = kf* kfdiff/ (kf+ kfdiff)
209
160
@fastmath krevr = krev* krevdiff/ (krev+ krevdiff)
210
161
@fastmath kfr = Kc* krevr
@@ -223,98 +174,101 @@ Maintains diffusion limitations if the phase has diffusionlimited=true
223
174
end
224
175
export getkfkrev
225
176
226
- @inline function getkfkrevs (phase:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs:: Q2 ,diffs:: Q3 ,V:: W5 ,phi:: W7 ;kfs:: W6 = nothing ) where {U,W7,W6,W5<: Real ,W1<: Real ,W2<: Real ,W3,W4,Q1<: AbstractArray ,Q2,Q3<: AbstractArray }
177
+ @inline function getkfkrevs (phase:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs:: Q2 ,diffs:: Q3 ,V:: W5 ,phi:: W7 ,d;kfs:: W6 = nothing ) where {U,W7,W6,W5<: Real ,W1<: Real ,W2<: Real ,W3,W4,Q1<: AbstractArray ,Q2,Q3<: AbstractArray }
178
+ dGrxns = - (phase. stoichmatrix* Gs). + phase. electronchange.* (phi* F)
227
179
if ! phase. diffusionlimited && kfs === nothing
228
- kfs = getkfs (phase,T,P,C,ns,V,phi)
180
+ kfs = getkfs (phase,T,P,C,ns,V,phi,dGrxns,d )
229
181
if phi == 0.0
230
- krev = @fastmath kfs./ getKcs (phase,T,Gs )
182
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns )
231
183
else
232
- krev = @fastmath kfs./ getKcs (phase,T,Gs ,phi)
184
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns ,phi)
233
185
end
234
186
elseif ! phase. diffusionlimited && ! (kfs === nothing )
235
187
if phi == 0.0
236
- krev = @fastmath kfs./ getKcs (phase,T,Gs )
188
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns )
237
189
else
238
- krev = @fastmath kfs./ getKcs (phase,T,Gs ,phi)
190
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns ,phi)
239
191
end
240
192
elseif phase. diffusionlimited && ! (kfs === nothing )
241
193
len = length (phase. reactions)
242
194
krev = zeros (typeof (N),len)
243
195
@simd for i = 1 : len
244
- @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,Gs ,diffs,V,phi;kf= kfs[i])
196
+ @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,dGrxns[i] ,diffs,V,phi,d ;kf= kfs[i])
245
197
end
246
198
else
247
199
len = length (phase. reactions)
248
200
kfs = zeros (typeof (N),len)
249
201
krev = zeros (typeof (N),len)
250
202
@simd for i = 1 : len
251
- @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,Gs ,diffs,V,phi)
203
+ @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,dGrxns[i] ,diffs,V,phi,d )
252
204
end
253
205
end
254
206
kfs .*= phase. forwardability
255
207
krev .*= phase. reversibility
256
208
return kfs,krev
257
209
end
258
210
259
- @inline function getkfkrevs (phase:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs:: Q2 ,diffs:: Q3 ,V:: W5 ,phi:: W7 ;kfs:: W6 = nothing ) where {U,W7,W6,W5<: Real ,W1<: Real ,W2<: Real ,W3,W4,Q1<: AbstractArray ,Q2<: Union{ReverseDiff.TrackedArray,Tracker.TrackedArray} ,Q3<: AbstractArray } # autodiff p
211
+ @inline function getkfkrevs (phase:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs:: Q2 ,diffs:: Q3 ,V:: W5 ,phi:: W7 ,d;kfs:: W6 = nothing ) where {U,W7,W6,W5<: Real ,W1<: Real ,W2<: Real ,W3,W4,Q1<: AbstractArray ,Q2<: Union{ReverseDiff.TrackedArray,Tracker.TrackedArray} ,Q3<: AbstractArray } # autodiff p
212
+ dGrxns = - (phase. stoichmatrix* Gs). + phase. electronchange.* (phi* F)
260
213
if ! phase. diffusionlimited && kfs === nothing
261
- kfs = getkfs (phase,T,P,C,ns,V,phi)
214
+ kfs = getkfs (phase,T,P,C,ns,V,phi,dGrxns,d )
262
215
if phi == 0.0
263
- krev = @fastmath kfs./ getKcs (phase,T,Gs )
216
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns )
264
217
else
265
- krev = @fastmath kfs./ getKcs (phase,T,Gs ,phi)
218
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns ,phi)
266
219
end
267
220
elseif ! phase. diffusionlimited && ! (kfs === nothing )
268
221
if phi == 0.0
269
- krev = @fastmath kfs./ getKcs (phase,T,Gs )
222
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns )
270
223
else
271
- krev = @fastmath kfs./ getKcs (phase,T,Gs ,phi)
224
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns ,phi)
272
225
end
273
226
elseif phase. diffusionlimited && ! (kfs === nothing )
274
227
len = length (phase. reactions)
275
228
krev = similar (kfs)
276
229
kfsdiff = similar (kfs)
277
230
@simd for i = 1 : len
278
- @fastmath @inbounds kfsdiff[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,Gs ,diffs,V,phi;kf= kfs[i])
231
+ @fastmath @inbounds kfsdiff[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,dGrxns[i] ,diffs,V,phi,d ;kf= kfs[i])
279
232
end
280
233
return kfsdiff, krev
281
234
else
282
235
len = length (phase. reactions)
283
- kfs = zeros (typeof (Gs[1 ]),len)
236
+ kfs = zeros (typeof (Gs[1 ]),len)ss
284
237
krev = zeros (typeof (Gs[1 ]),len)
285
238
@simd for i = 1 : len
286
- @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,Gs ,diffs,V,phi)
239
+ @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,dGrxns[i] ,diffs,V,phi,d )
287
240
end
288
241
end
289
242
return kfs,krev
290
243
end
291
244
292
- @inline function getkfkrevs (phase:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs:: Array{Q2,1} ,diffs:: Q3 ,V:: W5 ,phi:: W7 ;kfs:: W6 = nothing ) where {U,W7,W6,W5<: Real ,W1<: Real ,W2<: Real ,W3,W4,Q1<: AbstractArray ,Q2<: ForwardDiff.Dual ,Q3<: AbstractArray } # autodiff p
245
+ @inline function getkfkrevs (phase:: U ,T:: W1 ,P:: W2 ,C:: W3 ,N:: W4 ,ns:: Q1 ,Gs:: Array{Q2,1} ,diffs:: Q3 ,V:: W5 ,phi:: W7 ,d;kfs:: W6 = nothing ) where {U,W7,W6,W5<: Real ,W1<: Real ,W2<: Real ,W3,W4,Q1<: AbstractArray ,Q2<: ForwardDiff.Dual ,Q3<: AbstractArray } # autodiff p
246
+ dGrxns = - (phase. stoichmatrix* Gs). + phase. electronchange.* (phi* F)
293
247
if ! phase. diffusionlimited && kfs === nothing
294
- kfs = getkfs (phase,T,P,C,ns,V,phi)
248
+ kfs = getkfs (phase,T,P,C,ns,V,phi,dGrxns,d )
295
249
if phi == 0.0
296
- krev = @fastmath kfs./ getKcs (phase,T,Gs )
250
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns )
297
251
else
298
- krev = @fastmath kfs./ getKcs (phase,T,Gs ,phi)
252
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns ,phi)
299
253
end
300
254
elseif ! phase. diffusionlimited && ! (kfs === nothing )
301
255
if phi == 0.0
302
- krev = @fastmath kfs./ getKcs (phase,T,Gs )
256
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns )
303
257
else
304
- krev = @fastmath kfs./ getKcs (phase,T,Gs ,phi)
258
+ krev = @fastmath kfs./ getKcs (phase,T,dGrxns ,phi)
305
259
end
306
260
elseif phase. diffusionlimited && ! (kfs === nothing )
307
261
len = length (phase. reactions)
308
262
krev = similar (kfs)
309
263
@simd for i = 1 : len
310
- @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,Gs ,diffs,V,phi;kf= kfs[i])
264
+ @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,dGrxns[i] ,diffs,V,phi,d ;kf= kfs[i])
311
265
end
312
266
else
313
267
len = length (phase. reactions)
314
268
kfs = zeros (typeof (Gs[1 ]),len)
315
269
krev = zeros (typeof (Gs[1 ]),len)
316
270
@simd for i = 1 : len
317
- @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,Gs ,diffs,V,phi)
271
+ @fastmath @inbounds kfs[i],krev[i] = getkfkrev (phase. reactions[i],phase,T,P,C,N,ns,dGrxns[i] ,diffs,V,phi,d )
318
272
end
319
273
end
320
274
kfs .*= phase. forwardability
0 commit comments