-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathRatevec.jl
More file actions
216 lines (201 loc) · 7.18 KB
/
Ratevec.jl
File metadata and controls
216 lines (201 loc) · 7.18 KB
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
using Parameters
using ReverseDiff
using ForwardDiff
abstract type AbstractRatevec end
export AbstractRatevec
@with_kw struct Arrheniusvec{N<:Array,K<:Array,Q<:Array} <: AbstractRatevec
A::N
n::K
Ea::Q
end
function Arrheniusvec(arrs::T) where {T<:AbstractArray}
A = zeros(length(arrs))
n = zeros(length(arrs))
Ea = zeros(length(arrs))
for (i,aval) in enumerate(arrs)
A[i] = aval.A
n[i] = aval.n
Ea[i] = aval.Ea
end
return Arrheniusvec(A=A,n=n,Ea=Ea)
end
@inline (arr::Arrheniusvec)(;T::Q,P::N=0.0,C::S=0.0,phi=0.0,dGrxns=0.0) where {Q<:Real,N<:Real,S<:Real} = @fastmath @inbounds arr.A.*exp.(arr.n.*log(T).-arr.Ea.*(1.0/(R*T)))
@inline (arr::Arrheniusvec)(T::Q;P::N=0.0,C::S=0.0,phi=0.0) where {Q<:Real,N<:Real,S<:Real} = @fastmath @inbounds arr.A.*exp.(arr.n.*log(T).-arr.Ea.*(1.0/(R*T)))
export Arrheniusvec
@with_kw struct Chebyshevvec{T<:AbstractArray,Q<:Real,S<:Real,V<:Real,B<:Real} <: AbstractRate
coefs::T
Tmin::Q
Tmax::S
Pmin::V
Pmax::B
end
function Chebyshevvec(chevs::T) where {T<:AbstractArray}
coefs = zeros(length(chevs),size(chevs[1].coefs)[1],size(chevs[1].coefs)[2])
for k in 1:size(chevs[1].coefs)[2]
for j in 1:size(chevs[1].coefs)[1]
for i in 1:length(chevs)
coefs[i,j,k] = chevs[i].coefs[j,k]
end
end
end
return Chebyshevvec(coefs=coefs,Tmin=chevs[1].Tmin,Tmax=chevs[1].Tmax,Pmin=chevs[1].Pmin,Pmax=chevs[1].Pmax)
end
export Chebyshevvec
@inline function evalChebyshevPolynomial(ch::Chebyshevvec,n::N,x::Q) where {N<:Integer,Q<:Real}
"""
evaluate the nth order Chebyshev Polynomial at x
"""
if n==0
return 1.0
elseif n == 1
return x
else
T = 0.0
T0 = 1.0
T1 = x
for i in 1:(n-1)
@fastmath T = 2*x*T1-T0
T0 = T1
T1 = T
end
return T
end
end
export evalChebyshevPolynomial
@inline function getredtemp(ch::Chebyshevvec,T::N) where {N<:Real}
"""
return a reduced temperature corresponding to the given tempeprature
for the Chebyshev polynomial, maps the inverse of temperautre onto [-1,1]
"""
return @fastmath (2.0/T-1.0/ch.Tmin-1.0/ch.Tmax)/(1.0/ch.Tmax-1.0/ch.Tmin)
end
export getredtemp
@inline function getredpress(ch::Chebyshevvec,P::N) where {N<:Real}
"""
return a reduced pressure corresponding to the given temperature
for the Chebyshev polynomial maps the logarithm of pressure onto [-1,1]
"""
return @fastmath (2.0*log10(P)-log10(ch.Pmin)-log10(ch.Pmax))/(log10(ch.Pmax)-log10(ch.Pmin))
end
export getredpress
@inline function (ch::Chebyshevvec)(;T::N,P::Q=0.0,C::B=0.0,phi=0.0,dGrxns=0.0) where {N<:Real,B<:Real,Q<:Real}
k = zeros(N,size(ch.coefs)[1])
Tred = getredtemp(ch,T)
Pred = getredpress(ch,P)
klen,Tlen,Plen = size(ch.coefs)
@simd for j = 1:Plen
@simd for i = 1:Tlen
@fastmath @inbounds k .+= ch.coefs[:,i,j].*(evalChebyshevPolynomial(ch,i-1,Tred)*evalChebyshevPolynomial(ch,j-1,Pred))
end
end
return @fastmath 10.0.^k
end
@with_kw struct Troevec{P<:AbstractArray,Q<:AbstractArray,F<:AbstractArray,L<:AbstractArray,N<:Integer,K<:AbstractFloat,R<:AbstractRateUncertainty} <: AbstractFalloffRate
arrhigh::Arrheniusvec
arrlow::Arrheniusvec
a::P
T3::Q
T1::F
T2::L
efficiencies::Array{Dict{N,K},1}
unc::R = EmptyRateUncertainty()
end
function Troevec(troes::T) where {T<:AbstractArray}
Ahigh = zeros(length(troes))
nhigh = zeros(length(troes))
Ehigh = zeros(length(troes))
Alow = zeros(length(troes))
nlow = zeros(length(troes))
Elow = zeros(length(troes))
a = zeros(length(troes))
T3 = zeros(length(troes))
T1 = zeros(length(troes))
T2 = zeros(length(troes))
efficiencies = [Dict{Int64,Float64}() for x in troes]
for (i,falloff) in enumerate(troes)
if isa(falloff, ThirdBody)
Alow[i] = falloff.arr.A
nlow[i] = falloff.arr.n
Elow[i] = falloff.arr.Ea
Ahigh[i] = 1e20 #very high limited by energy transfer process
T3[i] = Inf
T1[i] = Inf
if length(efficiencies) > 0
efficiencies[i] = falloff.efficiencies
end
elseif isa(falloff,Lindemann)
Alow[i] = falloff.arrlow.A
nlow[i] = falloff.arrlow.n
Elow[i] = falloff.arrlow.Ea
Ahigh[i] = falloff.arrhigh.A
nhigh[i] = falloff.arrhigh.n
Ehigh[i] = falloff.arrhigh.Ea
T3[i] = Inf
T1[i] = Inf
if length(efficiencies) > 0
efficiencies[i] = falloff.efficiencies
end
elseif isa(falloff,Troe)
Alow[i] = falloff.arrlow.A
nlow[i] = falloff.arrlow.n
Elow[i] = falloff.arrlow.Ea
Ahigh[i] = falloff.arrhigh.A
nhigh[i] = falloff.arrhigh.n
Ehigh[i] = falloff.arrhigh.Ea
a[i] = falloff.a
T3[i] = falloff.T3
T1[i] = falloff.T1
T2[i] = falloff.T2
if length(efficiencies) > 0
efficiencies[i] = falloff.efficiencies
end
else
val = typeof(falloff)
error("could not process type $val in Troevec creation")
end
end
return Troevec(arrhigh=Arrheniusvec(Ahigh,nhigh,Ehigh),arrlow=Arrheniusvec(Alow,nlow,Elow),
a=a,T3=T3,T1=T1,T2=T2,efficiencies=efficiencies)
end
export Troevec
@inline function (tr::Troevec)(;T::Q=nothing,P::R=0.0,C::S=nothing,phi=0.0,dGrxns=0.0) where {Q<:Real,R<:Real,S<:Real}
k0 = tr.arrlow(T=T)
kinf = tr.arrhigh(T=T)
@fastmath Pr = k0.*C./kinf
@fastmath log10Pr = log10.(Pr)
@fastmath log10Fcent = log10.((1.0.-tr.a).*exp.(-T./tr.T3).+tr.a.*exp.(-T./tr.T1).+exp.(-tr.T2./T))
d = 0.14
@fastmath n = 0.75.-1.27.*log10Fcent
@fastmath c = -0.4.-0.67.*log10Fcent
F = 10.0.^((.!isinf.(tr.T1)) .* @fastmath (log10Fcent./(1.0.+((log10Pr.+c)./(n.-d.*(log10Pr))).^2)))
return @fastmath ((k0.*C)./(1.0.+Pr)).*F
end
@with_kw struct PdepArrheniusvec{T<:Real,Q<:AbstractRateUncertainty,Z<:Arrheniusvec} <: AbstractRate
Ps::Array{T,1}
arrvecs::Array{Z,1}
unc::Q = EmptyRateUncertainty()
end
function PdepArrheniusvec(pdeparrs::T) where {T<:AbstractArray}
Ps = pdeparrs[1].Ps
arrs = [Array{Arrhenius,1}() for i = 1:length(Ps)]
for ind in 1:length(pdeparrs)
for i =1:length(Ps)
push!(arrs[i],pdeparrs[ind].arrs[i])
end
end
return PdepArrheniusvec(;Ps=Ps,arrvecs=Arrheniusvec.(arrs))
end
export PdepArrheniusvec
@inline function (parr::PdepArrheniusvec)(;T::Q=nothing,P::V=nothing,C::S=0.0,phi=0.0,dGrxns=0.0) where {Q<:Real,V<:Real,S<:Real}
inds = getBoundingIndsSorted(P,parr.Ps)::Tuple{Int64,Int64}
if inds[2] == -1
return @inbounds parr.arrvecs[inds[1]](T=T)
else
@inbounds highk = parr.arrvecs[inds[2]](T=T)
@inbounds lowk = parr.arrvecs[inds[1]](T=T)
@inbounds Plow = parr.Ps[inds[1]]
@inbounds Phigh = parr.Ps[inds[2]]
return @inbounds @fastmath lowk.*10.0.^(log10.(P./Plow)/log10.(Phigh./Plow)*log10.(highk./lowk))
end
end
export PdepArrheniusvec