1+ using YAML
2+ using Unitful
3+
14function convertchemkin2yml (chemkinpath;spcdictpath= " " ,output= " chem.rms" )
25 if spcdictpath != " "
36 spcs,rxns = chemkin. load_chemkin_file (chemkinpath,dictionary_path= spcdictpath)
47 else
58 spcs,rxns = chemkin. load_chemkin_file (chemkinpath)
69 end
7- writeyml (spcs,rxns;path= output)
10+ D = getmechdictfromchemkin (spcs,rxns)
11+ writeyml (D;path= output)
812end
913
10- function writeyml (spcs,rxns;path= " chem.rms" )
11- D = getmechdict (spcs,rxns)
12- yaml. dump (D,stream= pybuiltin (" open" )(path," w" ))
14+ function writeyml (D;path= " chem.rms" )
15+ YAML. write_file (path,D)
1316end
1417
15- function getmechdict (spcs,rxns)
18+ function getmechdictfromchemkin (spcs,rxns)
1619 names = [x. label for x in spcs]
1720 for (i,name) in enumerate (names)
1821 if count (names.== name) > 1
@@ -29,6 +32,74 @@ function getmechdict(spcs,rxns)
2932 return D
3033end
3134
35+ function convertcanterayml2rmsyml (path;output= " chem.rms" )
36+ canterayml = YAML. load_file (path)
37+ D = getmechdictfromcantera (canterayml)
38+ writeyml (D;path= output)
39+ end
40+
41+ function getmechdictfromcantera (canterayml)
42+ unsupportedphases = [
43+ " binary-solution-tabulated" ,
44+ " compound-lattice" ,
45+ " constant-density" ,
46+ " Debye-Huckel" ,
47+ " edge" ,
48+ " electron-cloud" ,
49+ " fixed-stoichiometry" ,
50+ " HMW-electrolyte" ,
51+ # "ideal-gas",
52+ " ideal-molal-solution" ,
53+ " ideal-condensed" ,
54+ " ideal-solution-VPSS" ,
55+ # "ideal-surface",
56+ " ions-from-neutral-molecule" ,
57+ " lattice" ,
58+ " liquid-water-IAPWS95" ,
59+ " Margules" ,
60+ " Maskell-solid-solution" ,
61+ " Peng-Robinson" ,
62+ " plasma" ,
63+ " pure-fluid" ,
64+ " Redlich-Kister" ,
65+ " Redlich-Kwong" ,
66+ ]
67+
68+ spcs = canterayml[" species" ]
69+ rxns = canterayml[" reactions" ]
70+ phases = canterayml[" phases" ]
71+ units = canterayml[" units" ] # user specified units
72+ units = Dict (key=> uparse (value) for (key,value) in units) # convert to Unitful units
73+
74+ # prevent duplicate names
75+ spc_names = [spc[" name" ] for spc in spcs]
76+ for (i,name) in enumerate (spc_names)
77+ if count (spc_names.== name) > 1
78+ k = 2
79+ new_name = name
80+ while new_name in spc_names
81+ new_name = string (name," -" ,k)
82+ end
83+ spc_names[i] = new_name
84+ end
85+ end
86+
87+ D = Dict ([])
88+ D[" Units" ] = Dict ([]) # will be converting all values to SI
89+ D[" Phases" ] = []
90+ for phase in phases
91+ if phase[" thermo" ] in unsupportedphases
92+ @error " Currently not supporting $(phase[" thermo" ]) "
93+ end
94+ phasedict = Dict ()
95+ phasedict[" name" ] = phase[" name" ]
96+ phasedict[" Species" ] = [canteradict2rmsdict (spc,spcs,spc_names,units,:species ) for spc in spcs if spc[" name" ] in phase[" species" ]]
97+ push! (D[" Phases" ],phasedict)
98+ end
99+ D[" Reactions" ] = [canteradict2rmsdict (rxn,spcs,spc_names,units,:reaction ) for rxn in rxns]
100+ return D
101+ end
102+
32103function getradicals (obj:: T ) where {T}
33104 sm = obj. molecule[1 ]. to_smiles ()
34105 if sm == " [O][O]"
@@ -140,3 +211,160 @@ function obj2dict(obj,spcs,names;label="solvent")
140211 end
141212 return D
142213end
214+
215+ function canteradict2rmsdict (canteradict,spcs,names,units,dict_type;numreactants= nothing ,polyindex= nothing )
216+ D = Dict ([])
217+ if dict_type == :species # species
218+ D[" name" ] = names[findall (x-> x== canteradict,spcs)[1 ]]
219+ D[" type" ] = " Species"
220+ D[" smiles" ] = " "
221+ D[" thermo" ] = canteradict2rmsdict (canteradict[" thermo" ],spcs,names,units,:thermo )
222+ if haskey (canteradict," equation-of-state" )
223+ model = canteradict[" equation-of-state" ][" model" ]
224+ @error " Currently not supporting $(model) thermo model"
225+ end
226+ elseif dict_type == :thermo
227+ if canteradict[" model" ] == " NASA7"
228+ D[" type" ] = " NASA"
229+ D[" polys" ] = [canteradict2rmsdict (canteradict,spcs,names,units,:NASApolynomial ;polyindex= i) for i in 1 : (length (canteradict[" temperature-ranges" ])- 1 )]
230+ else
231+ @error " Currently only support NASA7 thermo model from Cantera"
232+ end
233+ elseif dict_type == :NASApolynomial
234+ D[" type" ] = " NASApolynomial"
235+ D[" Tmax" ] = canteradict[" temperature-ranges" ][polyindex+ 1 ]
236+ D[" Tmin" ] = canteradict[" temperature-ranges" ][polyindex]
237+ D[" coefs" ] = canteradict[" data" ][polyindex,:][1 ]
238+ elseif dict_type == :reaction # reaction
239+ equation = canteradict[" equation" ]
240+ reversible = true
241+ if occursin (" <=> " ,equation) # reversible
242+ reactants, products = split (canteradict[" equation" ]," <=> " )
243+ elseif occursin (" => " ,equation) # irreversible
244+ reactants, products = split (canteradict[" equation" ]," => " )
245+ reversible = false
246+ end
247+ reactants = _interpretstoichstring (reactants,names)
248+ products = _interpretstoichstring (products,names)
249+ kinetics = canteradict2rmsdict (canteradict,spcs,names,units,:kinetics ,numreactants= length (reactants))
250+ D[" reactants" ] = reactants
251+ D[" products" ] = products
252+ D[" kinetics" ] = kinetics
253+ D[" reversible" ] = reversible
254+ D[" type" ] = " ElementaryReaction"
255+ elseif dict_type == :kinetics
256+ if haskey (canteradict," type" )
257+ kinetics_type = canteradict[" type" ]
258+ if kinetics_type == " three-body"
259+ D[" type" ] = " ThirdBody"
260+ D[" arr" ] = canteradict2rmsdict (canteradict[" rate-constant" ],spcs,names,units,:arrhenius ,numreactants= numreactants+ 1 )
261+ D[" efficiencies" ] = get (canteradict," efficiencies" ,Dict ([]))
262+ elseif kinetics_type == " falloff"
263+ if haskey (canteradict," Troe" )
264+ D[" type" ] = " Troe"
265+ D[" arrhigh" ] = canteradict2rmsdict (canteradict[" high-P-rate-constant" ],spcs,names,units,:arrhenius ,numreactants= numreactants)
266+ D[" arrlow" ] = canteradict2rmsdict (canteradict[" low-P-rate-constant" ],spcs,names,units,:arrhenius ,numreactants= numreactants+ 1 )
267+ D[" efficiencies" ] = get (canteradict," efficiencies" ,Dict ([]))
268+ D[" a" ] = canteradict[" Troe" ][" A" ]
269+ D[" T1" ] = canteradict[" Troe" ][" T1" ]
270+ if haskey (canteradict[" Troe" ]," T2" )
271+ D[" T2" ] = canteradict[" Troe" ][" T2" ]
272+ else
273+ D[" T2" ] = 0.0
274+ end
275+ D[" T3" ] = canteradict[" Troe" ][" T3" ]
276+ else # Lindemann
277+ D[" type" ] = " Lindemann"
278+ D[" arrhigh" ] = canteradict2rmsdict (canteradict[" high-P-rate-constant" ],spcs,names,units,:arrhenius ,numreactants= numreactants)
279+ D[" arrlow" ] = canteradict2rmsdict (canteradict[" low-P-rate-constant" ],spcs,names,units,:arrhenius ,numreactants= numreactants+ 1 )
280+ D[" efficiencies" ] = get (canteradict," efficiencies" ,Dict ([]))
281+ end
282+ elseif kinetics_type == " pressure-dependent-Arrhenius"
283+ D[" type" ] = " PdepArrhenius"
284+ D[" Ps" ] = [kinetics[" P" ] for kinetics in canteradict[" rate-constants" ]]
285+ D[" arrs" ] = [canteradict2rmsdict (kinetics,spcs,names,units,:arrhenius ,numreactants= numreactants) for kinetics in canteradict[" rate-constants" ]]
286+ elseif kinetics_type == " Chebyshev"
287+ D[" type" ] = " Chebyshev"
288+ D[" coefs" ] = [canteradict[" data" ][:,i] for i in 1 : size (canteradict[" data" ],2 )]
289+ D[" Tmin" ] = tosivalue (canteradict[" temperature-range" ][1 ],units= units,value_type= :temperature )
290+ D[" Tmax" ] = tosivalue (canteradict[" temperature-range" ][end ],units= units,value_type= :temperature )
291+ D[" Pmin" ] = tosivalue (canteradict[" pressure-range" ][1 ],units= units,value_type= :pressure )
292+ D[" Pmax" ] = tosivalue (canteradict[" pressure-range" ][end ],units= units,value_type= :pressure )
293+ else
294+ @error " Currently not supporting $(kinetics_type) "
295+ end
296+ elseif haskey (canteradict," sticking-coefficient" )
297+ D = canteradict2rmsdict (canteradict[" sticking-coefficient" ],spcs,names,units,:arrhenius ,numreactants= 0 )
298+ D[" type" ] = " StickingCoefficient"
299+ elseif haskey (canteradict," rate-constant" ) # arrhenius
300+ D = canteradict2rmsdict (canteradict[" rate-constant" ],spcs,names,units,:arrhenius ,numreactants= numreactants)
301+ else
302+ @error " Currently not supporting $(canteradict) type kinetics"
303+ end
304+ if haskey (canteradict," coverage-dependencies" )
305+ @error " Currently not supporting coverage dependencies"
306+ end
307+ elseif dict_type == :arrhenius
308+ D[" type" ] = " Arrhenius"
309+ D[" A" ] = tosivalue (canteradict[" A" ],units= units,value_type= :Afactor ,numreactants= numreactants)
310+ D[" Ea" ] = tosivalue (canteradict[" Ea" ],units= units,value_type= :activationenergy )
311+ D[" n" ] = canteradict[" b" ]
312+ end
313+ return D
314+ end
315+
316+ function _interpretstoichstring (spcs,names)
317+ spc_names = Vector {String} ()
318+
319+ spcs = split (spcs," " )
320+ for (ind,item) in enumerate (spcs)
321+ stoich = tryparse (Int64,item)
322+ if stoich != nothing
323+ spc = spcs[ind+ 1 ]
324+ append! (spc_names,[spc for i in 1 : (stoich- 1 )])
325+ else
326+ if item in names
327+ spc = item
328+ push! (spc_names,spc)
329+ end
330+ end
331+ end
332+ return spc_names
333+ end
334+
335+ function tosivalue (value;units= nothing ,value_type= nothing ,numreactants= nothing )
336+
337+ if value isa String # unit specified for this individual value
338+ value,unit = split (value," " )
339+ value = parse (Float64,value)
340+ unit = uparse (unit)
341+ else
342+ if value_type == :temperature
343+ unit = get (units," temperature" ,Unitful. K)
344+ elseif value_type == :pressure
345+ unit = get (units," pressure" ,Unitful. Pa)
346+ elseif value_type == :activationenergy
347+ unit = get (units," activation-energy" ,nothing )
348+ if unit == nothing
349+ quantity_unit = get (units," quantity" ,Unitful. mol)
350+ energy_unit = get (units," energy" ,Unitful. J)
351+ unit = (energy_unit)/ (quantity_unit)
352+ end
353+ elseif value_type == :Afactor
354+ time_unit = get (units," time" ,Unitful. s)
355+ length_unit = get (units," length" ,Unitful. m)
356+ quantity_unit = get (units," quantity" ,Unitful. mol)
357+ if numreactants == 1
358+ unit = time_unit^ (- 1 )
359+ elseif numreactants == 2
360+ unit = (length_unit)^ 3 / (quantity_unit* time_unit)
361+ elseif numreactants == 3
362+ unit = (length_unit)^ 6 / ((quantity_unit)^ 2 * (time_unit))
363+ elseif numreactants == 0
364+ return value
365+ end
366+ end
367+ end
368+ return upreferred (value* unit). val
369+ end
370+
0 commit comments