@@ -48,8 +48,10 @@ def setup_class(cls):
4848 chemkin_file = os .path .join (chem_dir , "chem_annotated.inp" )
4949 spc_dict = os .path .join (chem_dir , "species_dictionary.txt" )
5050
51- cls .uncertainty = Uncertainty (output_directory = "chemDir" )
51+ cls .uncertainty = Uncertainty (output_directory = os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ), "chemDir" )) )
5252 cls .uncertainty .load_model (chemkin_file , spc_dict )
53+ for i in range (len (cls .uncertainty .species_list )):
54+ cls .uncertainty .species_list [i ].index = i # local analysis depends on species being indexed
5355
5456 # load database properly
5557 cls .uncertainty .database = RMGDatabase ()
@@ -178,6 +180,117 @@ def test_uncertainty_assignment(self):
178180 rtol = 1e-4
179181 )
180182
183+ def test_local_analysis (self ):
184+ """
185+ Test to run uncorrelated and then correlated local_analysis and make sure the results are expected
186+ """
187+ # these are sorted by the name of the corresponding parameter
188+ expected_uncorrelated_total_variance = 1.8329056941266446
189+ expected_uncorrelated_thermo_variances = np .array ([0.09781627 , 0.00041446 , 9.953e-05 , 0.06186124 , 0.17092419 , 0.04856985 , 0.00306632 , 0.00391013 ])
190+ expected_uncorrelated_kinetics_variances = np .array ([0.00080811 , 0.01687337 , 0.02022449 , 0.15888459 , 0.085189 , 0.01588366 , 0.00012957 , 0.01605351 , 1.1311145 , 0.0010829 ])
191+ expected_correlated_total_variance = 3.006637059881831
192+ expected_correlated_thermo_variances = np .array ([0.04573167 , 0.00014685 , 3.263e-05 , 0.03236887 , 0.07672388 , 0.0013764 , 0.0001338 , 0.00143231 , 0.00028968 , 0.01098087 , 0.00031352 , 0.01747643 , 0.04856985 , 0.09145902 ])
193+ expected_correlated_kinetics_variances = np .array ([0.00011471 , 0.11981721 , 0.15516713 , 2.0212174 , 0.28939964 , 0.00193506 , 0.02838292 , 0.0161796 , 0.0040449 , 0.00136045 , 0.00168253 , 0.00253735 , 0.00253735 , 0.00136045 , 0.01687337 , 0.01605351 , 0.00080811 , 0.00012957 ])
194+ expected_uncorrelated_thermo_labels = {
195+ 'dln[C2H6(18)]/dG[C2H3(20)]' ,
196+ 'dln[C2H6(18)]/dG[C2H4(11)]' ,
197+ 'dln[C2H6(18)]/dG[C2H5(12)]' ,
198+ 'dln[C2H6(18)]/dG[C2H6(18)]' ,
199+ 'dln[C2H6(18)]/dG[CH(4)]' ,
200+ 'dln[C2H6(18)]/dG[CH2(5)]' ,
201+ 'dln[C2H6(18)]/dG[CH3(14)]' ,
202+ 'dln[C2H6(18)]/dG[CH4(16)]' ,
203+ }
204+ expected_uncorrelated_kinetics_labels = {
205+ 'k10: CH3(14)+C2H5(12)<=>CH4(16)+C2H4(11)' ,
206+ 'k1: O(0)+H2O2(3)<=>OH(1)+HO2(2)' ,
207+ 'k2: CH3(14)+PC3H7(15)<=>CH4(16)+CH2CH2CH2(17)' ,
208+ 'k3: C2H6(18)+PC3H7(15)<=>C2H5(12)+C3H8(19)' ,
209+ 'k4: C2H3(20)+C3H8(19)<=>C2H4(11)+PC3H7(15)' ,
210+ 'k5: CH3(14)+C3H8(19)<=>CH4(16)+PC3H7(15)' ,
211+ 'k6: CH3(14)+C2H6(18)<=>CH4(16)+C2H5(12)' ,
212+ 'k7: HCCO(10)(+M)<=>O(0)+C2H(8)(+M)' ,
213+ 'k8: C2H5(12)+CH3CHCH3(21)<=>C2H6(18)+C3H6(22)' ,
214+ 'k9: C3H5(24)+CH2CH2CH2(17)<=>C3H5(23)+C3H6(22)' ,
215+ }
216+ expected_correlated_thermo_labels = {
217+ 'Estimation C2H3(20)' ,
218+ 'Estimation C2H4(11)' ,
219+ 'Estimation C2H5(12)' ,
220+ 'Estimation C2H6(18)' ,
221+ 'Estimation CH(4)' ,
222+ 'Estimation CH3(14)' ,
223+ 'Group(group) Cds-CdsHH' ,
224+ 'Group(group) Cs-CsHHH' ,
225+ 'Group(other) R' ,
226+ 'Group(radical) CCJ' ,
227+ 'Group(radical) CH3' ,
228+ 'Group(radical) CJ3' ,
229+ 'Library CH2(5)' ,
230+ 'Library CH4(16)' ,
231+ }
232+ expected_correlated_kinetics_labels = {
233+ 'Disproportionation Root_Ext-1R!H-R_N-4R->O_N-Sp-5R!H=1R!H_Ext-4CHNS-R_N-6R!H->S_4CHNS->C_N-Sp-6BrBrBrCCCClClClFFFIIINNNOOOPPPSiSiSi#4C_6BrCClFINOPSi->C_N-1R!H-inRing_N-Sp-6C-4C' ,
234+ 'Disproportionation Root_Ext-2R!H-R_2R!H->C_4R->C' ,
235+ 'Estimation C2H3(20)+C3H8(19)<=>C2H4(11)+PC3H7(15)' ,
236+ 'Estimation C2H5(12)+CH3CHCH3(21)<=>C2H6(18)+C3H6(22)' ,
237+ 'Estimation C2H6(18)+PC3H7(15)<=>C2H5(12)+C3H8(19)' ,
238+ 'Estimation C3H5(24)+CH2CH2CH2(17)<=>C3H5(23)+C3H6(22)' ,
239+ 'Estimation CH3(14)+C3H8(19)<=>CH4(16)+PC3H7(15)' ,
240+ 'Estimation CH3(14)+PC3H7(15)<=>CH4(16)+CH2CH2CH2(17)' ,
241+ 'H_Abstraction C/H3/Cs;C_methyl' ,
242+ 'H_Abstraction C/H3/Cs\\ H2\\ Cs|O;Cd_Cd\\ H2_rad/Cs' ,
243+ 'H_Abstraction C/H3/Cs\\ H2\\ O;C_methyl' ,
244+ 'H_Abstraction C/H3/Cs\\ H3;C_rad/H2/Cs\\ H3' ,
245+ 'H_Abstraction C/H3/Cs\\ H3;C_rad/H2/Cs\\ H\\ Cs\\ Cs|O' ,
246+ 'H_Abstraction C/H3/Cs\\ H3;Cd_Cd\\ H2_pri_rad' ,
247+ 'Library O(0)+H2O2(3)<=>OH(1)+HO2(2)' ,
248+ 'PDep HCCO(10)(+M)<=>O(0)+C2H(8)(+M)' ,
249+ 'Training Disproportionation CH3(14)+C2H5(12)<=>CH4(16)+C2H4(11)' ,
250+ 'Training H_Abstraction CH3(14)+C2H6(18)<=>CH4(16)+C2H5(12)' ,
251+ }
252+
253+ sensitive_species = [self .uncertainty .species_list [18 ]]
254+
255+ # uncorrelated analysis first
256+ self .uncertainty .assign_parameter_uncertainties ()
257+ output = self .uncertainty .local_analysis (sensitive_species = sensitive_species )
258+ total_variance , kinetic_uncertainty , thermo_uncertainty = output [sensitive_species [0 ]]
259+ assert np .isclose (total_variance , expected_uncorrelated_total_variance )
260+
261+ # order of kinetic or thermo uncertainty is not guaranteed, this sorts by name
262+ kinetic_variances = [r [2 ] for r in kinetic_uncertainty ]
263+ kinetics_names = [r [0 ] for r in kinetic_uncertainty ]
264+ sorted_kinetic_variances = [x for _ , x in sorted (zip (kinetics_names , kinetic_variances ))]
265+ assert np .isclose (sorted_kinetic_variances , expected_uncorrelated_kinetics_variances ).all ()
266+ assert set (kinetics_names ) == expected_uncorrelated_kinetics_labels
267+
268+ thermo_variances = [s [2 ] for s in thermo_uncertainty ]
269+ thermo_names = [s [0 ] for s in thermo_uncertainty ]
270+ sorted_thermo_variances = [x for _ , x in sorted (zip (thermo_names , thermo_variances ))]
271+ assert np .isclose (sorted_thermo_variances , expected_uncorrelated_thermo_variances ).all ()
272+ assert set (thermo_names ) == expected_uncorrelated_thermo_labels
273+
274+ # now repeat for correlated analysis
275+ self .uncertainty .assign_parameter_uncertainties (correlated = True )
276+ output = self .uncertainty .local_analysis (sensitive_species = sensitive_species , correlated = True )
277+ total_variance , kinetic_uncertainty , thermo_uncertainty = output [sensitive_species [0 ]]
278+ assert np .isclose (total_variance , expected_correlated_total_variance )
279+
280+ # order of kinetic or thermo uncertainty is not guaranteed, this sorts by name
281+ kinetic_variances = [r [2 ] for r in kinetic_uncertainty ]
282+ kinetics_names = [r [0 ] for r in kinetic_uncertainty ]
283+ sorted_kinetic_variances = [x for _ , x in sorted (zip (kinetics_names , kinetic_variances ))]
284+ assert np .isclose (sorted_kinetic_variances , expected_correlated_kinetics_variances ).all ()
285+ assert set (kinetics_names ) == expected_correlated_kinetics_labels
286+
287+ thermo_variances = [s [2 ] for s in thermo_uncertainty ]
288+ thermo_names = [s [0 ] for s in thermo_uncertainty ]
289+ sorted_thermo_variances = [x for _ , x in sorted (zip (thermo_names , thermo_variances ))]
290+ assert np .isclose (sorted_thermo_variances , expected_correlated_thermo_variances ).all ()
291+ assert set (thermo_names ) == expected_correlated_thermo_labels
292+
293+
181294 def test_specific_species_uncertainties (self ):
182295 """
183296 Test uncertainties for a few specific examples
0 commit comments