LMRRfactory 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 TheBurkeLab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ from masterFitter import masterFitter
2
+
3
+ # 'method' is a function that is present in a file called 'file.py'
@@ -0,0 +1,3 @@
1
+ from cantera.build.python import cantera
2
+
3
+ # 'method' is a function that is present in a file called 'file.py'
@@ -0,0 +1,472 @@
1
+ """
2
+ Class that allows for fitting of rate constants at various temperatures and pressures (k(T,P))
3
+ """
4
+ from LMRRfactory.ext import cantera as ct
5
+ import numpy as np
6
+ from scipy.optimize import curve_fit
7
+ from scipy.optimize import least_squares
8
+ import yaml
9
+
10
+ class masterFitter:
11
+ def __init__(self, T_ls, P_ls, inputFile,n_P=7, n_T=7, M_only=False):
12
+ self.T_ls = T_ls
13
+ self.P_ls = P_ls
14
+ self.n_P=n_P
15
+ self.n_T=n_T
16
+ self.P_min = P_ls[0]
17
+ self.P_max = P_ls[-1]
18
+ self.T_min = T_ls[0]
19
+ self.T_max = T_ls[-1]
20
+ self.M_only=M_only
21
+
22
+ # self.input = self.openyaml(inputFile)
23
+ with open(inputFile) as f:
24
+ self.input = yaml.safe_load(f)
25
+ with open("data/thirdbodydefaults.yaml") as f:
26
+ self.defaults = yaml.safe_load(f)
27
+ self.mech = self.yaml_custom_load(self.input['chemical-mechanism'])
28
+
29
+ self.pDepReactionNames=[]
30
+ self.pDepReactions = []
31
+ for reaction in self.mech['reactions']:
32
+ if reaction.get('type') == 'falloff' and 'Troe' in reaction:
33
+ self.pDepReactions.append(reaction)
34
+ self.pDepReactionNames.append(reaction['equation'])
35
+ elif reaction.get('type') == 'pressure-dependent-Arrhenius':
36
+ self.pDepReactions.append(reaction)
37
+ self.pDepReactionNames.append(reaction['equation'])
38
+ elif reaction.get('type') == 'Chebyshev':
39
+ self.pDepReactions.append(reaction)
40
+ self.pDepReactionNames.append(reaction['equation'])
41
+
42
+ if len(self.pDepReactions)==0:
43
+ print("No pressure-dependent reactions found in mechanism. Please choose another mechanism.")
44
+ else:
45
+ self.shortMech = self.zippedMech()
46
+
47
+ def yaml_custom_load(self,fname):
48
+ with open(fname) as f:
49
+ data = yaml.safe_load(f)
50
+ newMolecList = []
51
+ for molec in data['phases'][0]['species']:
52
+ if str(molec).lower()=="false":
53
+ newMolecList.append("NO")
54
+ else:
55
+ newMolecList.append(molec)
56
+ data['phases'][0]['species'] = newMolecList
57
+ for species in data['species']:
58
+ name = str(species['name']).lower()
59
+ if name == "false":
60
+ species['name']="NO"
61
+ for reaction in data['reactions']:
62
+ effs = reaction.get('efficiencies')
63
+ if effs is not None:
64
+ for key in list(effs.keys()):
65
+ keyStr = str(key).lower()
66
+ if keyStr == "false":
67
+ reaction['efficiencies']["NO"] = reaction['efficiencies'].pop(key)
68
+ return data
69
+
70
+
71
+ def zippedMech(self):
72
+ blend=self.blendedInput()
73
+ shortMechanism={
74
+ 'units': self.mech['units'],
75
+ 'phases': self.mech['phases'],
76
+ 'species': self.mech['species'],
77
+ 'reactions': []
78
+ }
79
+ blendRxnNames = []
80
+ for rxn in blend['reactions']:
81
+ blendRxnNames.append(rxn['equation'])
82
+ for mech_rxn in self.mech['reactions']:
83
+ if mech_rxn['equation'] in blendRxnNames:
84
+ idx = blendRxnNames.index(mech_rxn['equation'])
85
+ colliderM = blend['reactions'][idx]['collider-list'][0]
86
+ colliderMlist=[]
87
+ if mech_rxn['type'] == 'falloff' and 'Troe' in mech_rxn:
88
+ colliderMlist.append({
89
+ 'collider': 'M',
90
+ 'eps': {'A': 1, 'b': 0, 'Ea': 0},
91
+ 'low-P-rate-constant': mech_rxn['low-P-rate-constant'],
92
+ 'high-P-rate-constant': mech_rxn['high-P-rate-constant'],
93
+ 'Troe': mech_rxn['Troe'],
94
+ })
95
+ elif mech_rxn['type'] == 'pressure-dependent-Arrhenius':
96
+ colliderMlist.append({
97
+ 'collider': 'M',
98
+ 'eps': {'A': 1, 'b': 0, 'Ea': 0},
99
+ 'rate-constants': mech_rxn['rate-constants'],
100
+ })
101
+ elif mech_rxn['type'] == 'Chebyshev':
102
+ colliderMlist.append({
103
+ 'collider': 'M',
104
+ 'eps': {'A': 1, 'b': 0, 'Ea': 0},
105
+ 'temperature-range': mech_rxn['temperature-range'],
106
+ 'pressure-range': mech_rxn['pressure-range'],
107
+ 'data': mech_rxn['data'],
108
+ })
109
+
110
+ # colliderList.append(blend['reactions'][idx]['collider-list'])
111
+ shortMechanism['reactions'].append({
112
+ 'equation': mech_rxn['equation'],
113
+ 'type': 'linear-burke',
114
+ 'reference-collider': blend['reactions'][idx]['reference-collider'],
115
+ 'collider-list': colliderMlist + blend['reactions'][idx]['collider-list']
116
+ })
117
+ else:
118
+ shortMechanism['reactions'].append(mech_rxn)
119
+ return shortMechanism
120
+
121
+ def blendedInput(self):
122
+ defaults2=self.deleteDuplicates()
123
+ blend = {'reactions': []}
124
+ speciesList = self.mech['phases'][0]['species']
125
+ defaultRxnNames = []
126
+ defaultColliderNames = []
127
+ for defaultRxn in defaults2['reactions']:
128
+ defaultRxnNames.append(defaultRxn['equation'])
129
+ for defaultCol in defaultRxn['collider-list']:
130
+ defaultColliderNames.append(defaultCol['collider'])
131
+ # first fill it with all of the default reactions and colliders (which have valid species)
132
+ for defaultRxn in defaults2['reactions']:
133
+ flag = True
134
+ for defaultCol in defaultRxn['collider-list']:
135
+ if defaultCol['collider'] not in speciesList:
136
+ flag = False
137
+ if flag == True:
138
+ blend['reactions'].append(defaultRxn)
139
+
140
+ blendRxnNames = []
141
+ for blendRxn in blend['reactions']:
142
+ blendRxnNames.append(blendRxn['equation'])
143
+
144
+ for inputRxn in self.input['reactions']:
145
+ if inputRxn['equation'] in blendRxnNames: #input reaction also exists in defaults file
146
+ idx = blendRxnNames.index(inputRxn['equation'])
147
+ # print(inputRxn['reference-collider'])
148
+ if inputRxn['reference-collider'] == blend['reactions'][idx]['reference-collider']: #no blending conflicts bc colliders have same ref
149
+ for inputCol in inputRxn['collider-list']:
150
+ if inputCol['collider'] in speciesList:
151
+ blend['reactions'][idx]['collider-list'].append(inputCol)
152
+ else: #blending conflict -> delete all default colliders and override with the user inputs
153
+ print(f"The user-provided reference collider for {inputRxn['equation']}, ({inputRxn['reference-collider']}) does not match the program default ({blend['reactions'][idx]['reference-collider']}).")
154
+ print(f"The default colliders have thus been deleted and the reaction has been completely overrided by (rather than blended with) the user's custom input values.")
155
+ blend['reactions'][idx]['collider-list'] = inputRxn['collider-list']
156
+ else:
157
+ flag = True
158
+ for inputCol in inputRxn['collider-list']:
159
+ if inputCol['collider'] not in speciesList:
160
+ flag = False
161
+ if flag == True:
162
+ blend['reactions'].append(inputRxn)
163
+ for reaction in blend['reactions']:
164
+ for col in reaction['collider-list']:
165
+ temperatures=np.array(col['temperatures'])
166
+ eps = np.array(col['eps'])
167
+ # epsLow=effs['epsLow']['A']
168
+ # epsHigh=effs['epsHigh']['A']
169
+ # rate_constants=np.array([epsLow,epsHigh])
170
+ def arrhenius_rate(T, A, beta, Ea):
171
+ # R = 8.314 # Gas constant in J/(mol K)
172
+ R = 1.987 # cal/molK
173
+ return A * T**beta * np.exp(-Ea / (R * T))
174
+ def fit_function(params, T, ln_rate_constants):
175
+ A, beta, Ea = params
176
+ return np.log(arrhenius_rate(T, A, beta, Ea)) - ln_rate_constants
177
+ initial_guess = [3, 0.5, 50.0]
178
+ result = least_squares(fit_function, initial_guess, args=(temperatures, np.log(eps)))
179
+ A_fit, beta_fit, Ea_fit = result.x
180
+ col['eps'] = {'A': round(float(A_fit),5),'b': round(float(beta_fit),5),'Ea': round(float(Ea_fit),5)}
181
+ del col['temperatures']
182
+ return blend
183
+
184
+
185
+
186
+ def deleteDuplicates(self):
187
+ # defaults2 = {'reactions': []}
188
+ # defaultRxnNames=[]
189
+ # for defaultRxn in self.defaults['reactions']:
190
+ # defaultRxnNames.append(defaultRxn['equation'])
191
+ # for inputRxn in self.input['reactions']:
192
+ # if inputRxn['equation'] in defaultRxnNames:
193
+ # defaultRxnNames.remove(inputRxn['equation'])
194
+ # newReactionList = []
195
+ # for defaultRxn in self.defaults['reactions']:
196
+ # if defaultRxn['equation'] in defaultRxnNames:
197
+ # newReactionList.append(defaultRxn)
198
+ defaults2 = {'reactions': []}
199
+ inputRxnNames=[]
200
+ inputColliderNames=[]
201
+ for inputRxn in self.input['reactions']:
202
+ inputRxnNames.append(inputRxn['equation'])
203
+ inputRxnColliderNames=[]
204
+ for inputCol in inputRxn['collider-list']:
205
+ inputRxnColliderNames.append(inputCol['collider'])
206
+ inputColliderNames.append(inputRxnColliderNames)
207
+ for defaultRxn in self.defaults['reactions']:
208
+ if defaultRxn['equation'] in inputRxnNames:
209
+ idx = inputRxnNames.index(defaultRxn['equation'])
210
+ defaultColliderNames=[]
211
+ for defaultCol in defaultRxn['collider-list']:
212
+ defaultColliderNames.append(defaultCol['collider'])
213
+ # print(defaultRxn['equation'])
214
+ for defaultCol in defaultRxn['collider-list']:
215
+ if defaultCol['collider'] in inputColliderNames[idx]:
216
+ defaultColliderNames.remove(defaultCol['collider'])
217
+ # print(inputColliderNames[idx])
218
+ # print(defaultColliderNames)
219
+ newColliderList=[] #only contains colliders that aren't already in the input
220
+ for defaultCol in defaultRxn['collider-list']:
221
+ if defaultCol['collider'] in defaultColliderNames:
222
+ newColliderList.append(defaultCol)
223
+ if len(newColliderList)>0:
224
+ defaults2['reactions'].append({
225
+ 'equation': defaultRxn['equation'],
226
+ 'reference-collider': defaultRxn['reference-collider'],
227
+ 'collider-list': newColliderList
228
+ })
229
+ else: # reaction isn't in input, so keep the entire default rxn
230
+ defaults2['reactions'].append(defaultRxn)
231
+ return defaults2
232
+
233
+
234
+
235
+ def get_Xvec(self,reaction):
236
+ Prange = self.P_ls
237
+ Xvec=[]
238
+ for i,P in enumerate(Prange):
239
+ for j,T in enumerate(self.T_ls):
240
+ Xvec.append([P,T])
241
+ Xvec=np.array(Xvec)
242
+ return Xvec.T
243
+
244
+ def get_Xdict(self,reaction):
245
+ Prange = self.P_ls
246
+ Xdict={}
247
+ for i,P in enumerate(Prange):
248
+ Xdict[P]=self.T_ls
249
+ return Xdict
250
+
251
+ def get_YAML_kTP(self,reaction,collider):
252
+ gas = ct.Solution("shortMech.yaml")
253
+ k_TP = []
254
+ for T in self.T_ls:
255
+ temp = []
256
+ for P in self.P_ls:
257
+ gas.TPX = T, P*ct.one_atm, {collider:1.0}
258
+ val=gas.forward_rate_constants[gas.reaction_equations().index(reaction['equation'])]
259
+ temp.append(val)
260
+ k_TP.append(temp)
261
+ return np.array(k_TP)
262
+
263
+ def first_cheby_poly(self, x, n):
264
+ '''Generate n-th order Chebyshev ploynominals of first kind.'''
265
+ if n == 0: return 1
266
+ elif n == 1: return x
267
+ result = 2. * x * self.first_cheby_poly(x, 1) - self.first_cheby_poly(x, 0)
268
+ m = 0
269
+ while n - m > 2:
270
+ result = 2. * x * result - self.first_cheby_poly(x, m+1)
271
+ m += 1
272
+ # print(result)
273
+ return result
274
+ def reduced_P(self,P):
275
+ '''Calculate the reduced pressure.'''
276
+ P_tilde = 2. * np.log10(P) - np.log10(self.P_min) - np.log10(self.P_max)
277
+ P_tilde /= (np.log10(self.P_max) - np.log10(self.P_min))
278
+ return P_tilde
279
+ def reduced_T(self,T):
280
+ '''Calculate the reduced temperature.'''
281
+ T_tilde = 2. * T ** (-1) - self.T_min ** (-1) - self.T_max ** (-1)
282
+ T_tilde /= (self.T_max ** (-1) - self.T_min ** (-1))
283
+ return T_tilde
284
+ def cheby_poly(self,reaction,collider):
285
+ '''Fit the Chebyshev polynominals to rate constants.
286
+ Input rate constants vector k should be arranged based on pressure.'''
287
+ k_TP = self.get_YAML_kTP(reaction,collider)
288
+ cheb_mat = np.zeros((len(k_TP.flatten()), self.n_T * self.n_P))
289
+ for m, T in enumerate(self.T_ls):
290
+ for n, P in enumerate(self.P_ls):
291
+ for i in range(self.n_T):
292
+ for j in range(self.n_P):
293
+ T_tilde = self.reduced_T(T)
294
+ P_tilde = self.reduced_P(P)
295
+ T_cheb = self.first_cheby_poly(T_tilde, i)
296
+ P_cheb = self.first_cheby_poly(P_tilde, j)
297
+ cheb_mat[m * len(self.P_ls) + n, i * self.n_P + j] = T_cheb * P_cheb
298
+ coef = np.linalg.lstsq(cheb_mat, np.log10(k_TP.flatten()),rcond=None)[0].reshape((self.n_T, self.n_P))
299
+ return coef
300
+ def get_cheb_table(self,reaction,collider,label,epsilon,kTP='off'):
301
+ coef = self.cheby_poly(reaction,collider)
302
+ if kTP=='on':
303
+ colDict = {
304
+ 'collider': label,
305
+ 'eps': epsilon,
306
+ 'temperature-range': [float(self.T_min), float(self.T_max)],
307
+ 'pressure-range': [f'{self.P_min:.3e} atm', f'{self.P_max:.3e} atm'],
308
+ 'data': []
309
+ }
310
+ for i in range(len(coef)):
311
+ row=[]
312
+ for j in range(len(coef[0])):
313
+ # row.append(f'{coef[i,j]:.4e}')
314
+ row.append(float(coef[i,j]))
315
+ colDict['data'].append(row)
316
+ else:
317
+ colDict = {
318
+ 'collider': label,
319
+ 'eps': epsilon,
320
+ }
321
+
322
+ return colDict
323
+
324
+ def get_PLOG_table(self,reaction,collider,label,epsilon,kTP='off'):
325
+ if kTP=='on':
326
+ colDict = {
327
+ 'collider': label,
328
+ 'eps': epsilon,
329
+ 'rate-constants': []
330
+ }
331
+ def arrhenius(T, A, n, Ea):
332
+ return np.log(A) + n*np.log(T)+ (-Ea/(1.987*T))
333
+ gas = ct.Solution('shortMech.yaml')
334
+ Xdict = self.get_Xdict(reaction)
335
+ for i,P in enumerate(Xdict.keys()):
336
+ k_list = []
337
+ for j,T in enumerate(Xdict[P]):
338
+ gas.TPX = T, P*ct.one_atm, {collider:1}
339
+ k_T = gas.forward_rate_constants[gas.reaction_equations().index(reaction['equation'])]
340
+ k_list.append(k_T)
341
+ k_list=np.array(k_list)
342
+ popt, pcov = curve_fit(arrhenius, self.T_ls, np.log(k_list),maxfev = 2000)
343
+ newDict = {
344
+ 'P': f'{P:.3e} atm',
345
+ 'A': float(popt[0]),
346
+ 'b': float(popt[1]),
347
+ 'Ea': float(popt[2]),
348
+ }
349
+ colDict['rate-constants'].append(newDict)
350
+ else:
351
+ colDict = {
352
+ 'collider': label,
353
+ 'eps': epsilon,
354
+ }
355
+
356
+ return colDict
357
+
358
+ def get_Troe_table(self,reaction,collider,label,epsilon,kTP='off'):
359
+ def f(X,a0,n0,ea0,ai,ni,eai,Fcent):
360
+ N= 0.75 - 1.27 * np.log10(Fcent)
361
+ c= -0.4 - 0.67 * np.log10(Fcent)
362
+ d=0.14
363
+ Rcal=1.987
364
+ Rjoule=8.3145
365
+ M = X[0]*ct.one_atm/Rjoule/X[1]/1000000.0
366
+ k0 = a0 * (X[1] ** n0) * np.exp(-ea0 / (Rcal * X[1]))
367
+ ki = ai * (X[1] ** ni) * np.exp(-eai / (Rcal * X[1]))
368
+ logps = np.log10(k0) + np.log10(M) - np.log10(ki)
369
+ den = logps + c
370
+ den = den / (N - d * den)
371
+ den = np.power(den, 2) + 1.0
372
+ logF = np.log10(Fcent) / den
373
+ logk_fit = np.log10(k0) + np.log10(M) + np.log10(ki) + logF - np.log10(ki + k0 * M)
374
+ return logk_fit
375
+ Xdict=self.get_Xdict(reaction)
376
+ gas = ct.Solution('shortMech.yaml')
377
+ logk_list=[]
378
+ for i,P in enumerate(Xdict.keys()):
379
+ for j,T in enumerate(Xdict[P]):
380
+ gas.TPX=T,P*ct.one_atm,{collider:1.0}
381
+ k_TP=gas.forward_rate_constants[gas.reaction_equations().index(reaction['equation'])]
382
+ logk_list.append(np.log10(k_TP))
383
+ # NEED TO GENERALIZE THE FOLLOWING LINES
384
+ # if "H + OH (+M)" in reaction:
385
+ k0_g = [4.5300E+21, -1.8100E+00, 4.9870E+02]
386
+ ki_g = [2.5100E+13, 0.234, -114.2]
387
+ # # elif "H + O2 (+M)" in reaction:
388
+ # k0_g = [6.366e+20, -1.72, 524.8]
389
+ # ki_g = [4.7e+12,0.44,0.0]
390
+ # # elif "H2O2 (+M)" in reaction:
391
+ # k0_g = [2.5e+24,-2.3, 4.8749e+04]
392
+ # ki_g = [2.0e+12,0.9,4.8749e+04]
393
+ # # elif "NH2 (+M)" in reaction:
394
+ # k0_g = [1.6e+34,-5.49,1987.0]
395
+ # ki_g = [5.6e+14,-0.414,66.0]
396
+ # # elif "NH3 <=>" in reaction:
397
+ # k0_g = [2.0e+16, 0.0, 9.315e+04]
398
+ # ki_g = [9.0e+16, -0.39, 1.103e+05]
399
+ # # elif "HNO" in reaction:
400
+ # k0_g = [2.4e+14, 0.206, -1550.0]
401
+ # ki_g = [1.5e+15, -0.41, 0.0]
402
+ guess = k0_g+ki_g+[1]
403
+ bounds = (
404
+ [1e-100, -np.inf, -np.inf, 1e-100, -np.inf, -np.inf, 1e-100], # Lower bounds
405
+ [np.inf, np.inf, np.inf, np.inf, np.inf, np.inf, 1] # Upper bounds
406
+ )
407
+ Xvec=self.get_Xvec(reaction)
408
+ popt, pcov = curve_fit(f,Xvec,logk_list,p0=guess,maxfev=1000000,bounds=bounds)
409
+ a0,n0,ea0,ai,ni,eai=popt[0],popt[1],popt[2],popt[3],popt[4],popt[5]
410
+ def numFmt(val):
411
+ return round(float(val),3)
412
+ if kTP=='on':
413
+ colDict = {
414
+ 'collider': label,
415
+ 'eps': epsilon,
416
+ 'low-P-rate-constant': {'A':numFmt(a0), 'b': numFmt(n0), 'Ea': numFmt(ea0)},
417
+ 'high-P-rate-constant': {'A': numFmt(ai), 'b': numFmt(ni), 'Ea': numFmt(eai)},
418
+ 'Troe': {'A': round(float(popt[6]),3), 'T3': 1.0e-30, 'T1': 1.0e+30}
419
+ }
420
+ else:
421
+ colDict = {
422
+ 'collider': label,
423
+ 'eps': epsilon,
424
+ }
425
+ return colDict
426
+
427
+
428
+ def final_yaml(self,foutName,fit_fxn): # returns PLOG in LMRR YAML format
429
+ newMechanism={
430
+ 'units': self.mech['units'],
431
+ 'phases': self.mech['phases'],
432
+ 'species': self.mech['species'],
433
+ 'reactions': []
434
+ }
435
+ for reaction in self.shortMech['reactions']:
436
+ if reaction.get('type')=='linear-burke':
437
+ colliderList=[]
438
+ for i, col in enumerate(reaction['collider-list']):
439
+ if i == 0:
440
+ colliderList.append(fit_fxn(reaction,reaction['reference-collider'],"M",col['eps'],kTP='on'))
441
+ elif len(list(reaction['collider-list'][i].keys()))>3:
442
+ colliderList.append(fit_fxn(reaction,col['collider'],col['collider'],col['eps'],kTP='on'))
443
+ else:
444
+ colliderList.append(fit_fxn(reaction,col['collider'],col['collider'],col['eps'],kTP='off'))
445
+ newMechanism['reactions'].append({
446
+ 'equation': reaction['equation'],
447
+ 'type': 'linear-burke',
448
+ 'reference-collider': reaction['reference-collider'],
449
+ 'collider-list': colliderList
450
+ })
451
+ else:
452
+ newMechanism['reactions'].append(reaction)
453
+ with open(foutName, 'w') as outfile:
454
+ yaml.dump(newMechanism, outfile, default_flow_style=None,sort_keys=False)
455
+
456
+ def Troe(self,foutName): # returns PLOG in LMRR YAML format
457
+ self.final_yaml(foutName,self.get_Troe_table)
458
+ def PLOG(self,foutName): # returns PLOG in LMRR YAML format
459
+ self.final_yaml(foutName,self.get_PLOG_table)
460
+ def cheb2D(self,foutName): # returns Chebyshev in LMRR YAML format
461
+ self.final_yaml(foutName,self.get_cheb_table)
462
+
463
+ # # INPUTS
464
+ T_list=np.linspace(200,2000,100)
465
+ # P_list=np.logspace(-12,12,num=120)
466
+ P_list=np.logspace(-1,2,num=5)
467
+
468
+ mF = masterFitter(T_list,P_list,"LMRR-generator//test//inputs//testinput.yaml",n_P=7,n_T=7,M_only=True)
469
+
470
+ mF.Troe("LMRtest_Troe_M")
471
+ mF.PLOG("LMRtest_PLOG_M")
472
+ mF.cheb2D("LMRtest_cheb_M")
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.1
2
+ Name: LMRRfactory
3
+ Version: 0.0.1
4
+ Summary: Auto-generate LMR-R reactions and mechanisms
5
+ Author: Patrick Singal
6
+ Author-email: p.singal@columbia.edu
7
+ Keywords: python,first package
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Education
10
+ Classifier: Programming Language :: Python :: 2
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: MacOS :: MacOS X
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ License-File: LICENSE
15
+ Requires-Dist: cantera
16
+ Requires-Dist: numpy
17
+ Requires-Dist: pyyaml
18
+ Requires-Dist: scipy
19
+
20
+ Auto-generates LMR-R reactions (and mechanisms) according to the user’s choice of Plog, Troe, or Chebyshev sub-formats
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ LMRRfactory/__init__.py
5
+ LMRRfactory/masterFitter.py
6
+ LMRRfactory.egg-info/PKG-INFO
7
+ LMRRfactory.egg-info/SOURCES.txt
8
+ LMRRfactory.egg-info/dependency_links.txt
9
+ LMRRfactory.egg-info/requires.txt
10
+ LMRRfactory.egg-info/top_level.txt
11
+ LMRRfactory/ext/__init__.py
@@ -0,0 +1,4 @@
1
+ cantera
2
+ numpy
3
+ pyyaml
4
+ scipy
@@ -0,0 +1 @@
1
+ LMRRfactory
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.1
2
+ Name: LMRRfactory
3
+ Version: 0.0.1
4
+ Summary: Auto-generate LMR-R reactions and mechanisms
5
+ Author: Patrick Singal
6
+ Author-email: p.singal@columbia.edu
7
+ Keywords: python,first package
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Education
10
+ Classifier: Programming Language :: Python :: 2
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: MacOS :: MacOS X
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ License-File: LICENSE
15
+ Requires-Dist: cantera
16
+ Requires-Dist: numpy
17
+ Requires-Dist: pyyaml
18
+ Requires-Dist: scipy
19
+
20
+ Auto-generates LMR-R reactions (and mechanisms) according to the user’s choice of Plog, Troe, or Chebyshev sub-formats
@@ -0,0 +1,2 @@
1
+ # LMRR-generator
2
+ Automatically generates LMR-R reactions (and mechanisms) according to the user’s choice of Plog, Troe, or Chebyshev sub-formats
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,28 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ VERSION = '0.0.1'
4
+ DESCRIPTION = 'Auto-generate LMR-R reactions and mechanisms'
5
+ LONG_DESCRIPTION = 'Auto-generates LMR-R reactions (and mechanisms) according to the user’s choice of Plog, Troe, or Chebyshev sub-formats'
6
+
7
+ # Setting up
8
+ setup(
9
+ # the name must match the folder name 'verysimplemodule'
10
+ name="LMRRfactory",
11
+ version=VERSION,
12
+ author="Patrick Singal",
13
+ author_email="p.singal@columbia.edu",
14
+ description=DESCRIPTION,
15
+ long_description=LONG_DESCRIPTION,
16
+ packages=find_packages(),
17
+ install_requires=['cantera','numpy','pyyaml','scipy'],
18
+
19
+ keywords=['python', 'first package'],
20
+ classifiers= [
21
+ "Development Status :: 3 - Alpha",
22
+ "Intended Audience :: Education",
23
+ "Programming Language :: Python :: 2",
24
+ "Programming Language :: Python :: 3",
25
+ "Operating System :: MacOS :: MacOS X",
26
+ "Operating System :: Microsoft :: Windows",
27
+ ]
28
+ )