def test_recompute_Q_from_QvibQrot_Dunham_Evib123_Erot(verbose=True, warnings=True, *args, **kwargs): """Calculate vibrational and rotational partition functions: - with Dunham expansions. Evib, Erot = (Evib1+Evib2+Evib3, Erot) - under nonequilibrium Calculate total rovibrational partition function, and compare Test if partition function can be recomputed correctly from vibrational populations and rotational partition function (note that we are in a coupled case so partition function is not simply the product of Qvib, Qrot) """ iso = 1 Tvib = 1500 Trot = 300 S = Molecules["CO2"][iso]["X"] Qf = PartFunc_Dunham( S, use_cached=True, group_energy_modes_in_2T_model={ "CO2": (["Evib1", "Evib2", "Evib3"], ["Erot"]) }, ) Q = Qf.at_noneq(Tvib, Trot) _, Qvib, dfQrot = Qf.at_noneq(Tvib, Trot, returnQvibQrot=True) if verbose: printm("Q", Q) if verbose: printm("Qvib", Qvib) # 1) Test Q vs Q recomputed from Qrot, Qvib # Recompute Qtot df = dfQrot Q2 = ((df.gvib * exp(-df.Evib * hc_k / Tvib)) * df.Qrot).sum() # Todo: non Boltzmann case assert np.isclose(Q, Q2) if verbose: printm("Tested Q vs recomputed from (Qvib, Qrot) are the same: OK") return True
def test_Q_1Tvib_vs_Q_3Tvib(T=1500, verbose=True, warnings=True, *args, **kwargs): """Test if partition function calculated in 1-Tvib mode returns the same result as partition function calculated in 3-Tvib mode """ b = True # input M = "CO2" I = 1 # isotope S = Molecules[M][I]["X"] Qf = PartFunc_Dunham(S, use_cached=True) df = Qf.df # First make sure energies match if not (df.Evib == df.Evib1 + df.Evib2 + df.Evib3).all(): b *= False if warnings: printm( "WARNING in test_Q_1Tvib_vs_Q_3Tvib: Evib != Evib1 + Evib2 + Evib3" ) # Then calculate Q vs Q3T Q = Qf.at_noneq(T, T) if verbose: printm("Q", Q) Q3T = Qf.at_noneq_3Tvib((T, T, T), T) if verbose: printm("Q3T", Q3T) assert np.isclose(Q, Q3T) if verbose: printm( "Tested Q in 1-Tvib vs Q in 3-Tvib modes (T={0:.0f}K): OK".format( T)) return True