diff --git a/BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 b/BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 new file mode 100644 index 000000000..38741b7ef Binary files /dev/null and b/BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 differ diff --git a/BOLSIGChemistry_NominalRates/3BdyRecomb_Ground.h5 b/BOLSIGChemistry_NominalRates/3BdyRecomb_Ground.h5 new file mode 100644 index 000000000..a92f093ce Binary files /dev/null and b/BOLSIGChemistry_NominalRates/3BdyRecomb_Ground.h5 differ diff --git a/BOLSIGChemistry_NominalRates/3BdyRecomb_Metastable.h5 b/BOLSIGChemistry_NominalRates/3BdyRecomb_Metastable.h5 new file mode 100644 index 000000000..7b3192331 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/3BdyRecomb_Metastable.h5 differ diff --git a/BOLSIGChemistry_NominalRates/3BdyRecomb_Resonant.h5 b/BOLSIGChemistry_NominalRates/3BdyRecomb_Resonant.h5 new file mode 100644 index 000000000..fcc11aabf Binary files /dev/null and b/BOLSIGChemistry_NominalRates/3BdyRecomb_Resonant.h5 differ diff --git a/BOLSIGChemistry_NominalRates/DeExcitation_4p.h5 b/BOLSIGChemistry_NominalRates/DeExcitation_4p.h5 new file mode 100644 index 000000000..54e6ace87 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/DeExcitation_4p.h5 differ diff --git a/BOLSIGChemistry_NominalRates/DeExcitation_Metastable.h5 b/BOLSIGChemistry_NominalRates/DeExcitation_Metastable.h5 new file mode 100644 index 000000000..e436c6660 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/DeExcitation_Metastable.h5 differ diff --git a/BOLSIGChemistry_NominalRates/DeExcitation_Resonant.h5 b/BOLSIGChemistry_NominalRates/DeExcitation_Resonant.h5 new file mode 100644 index 000000000..bcf78ca74 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/DeExcitation_Resonant.h5 differ diff --git a/BOLSIGChemistry_NominalRates/Excitation_4p.h5 b/BOLSIGChemistry_NominalRates/Excitation_4p.h5 new file mode 100644 index 000000000..5e1358d5c Binary files /dev/null and b/BOLSIGChemistry_NominalRates/Excitation_4p.h5 differ diff --git a/BOLSIGChemistry_NominalRates/Excitation_Metastable.h5 b/BOLSIGChemistry_NominalRates/Excitation_Metastable.h5 new file mode 100644 index 000000000..3cfec52c6 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/Excitation_Metastable.h5 differ diff --git a/BOLSIGChemistry_NominalRates/Excitation_Resonant.h5 b/BOLSIGChemistry_NominalRates/Excitation_Resonant.h5 new file mode 100644 index 000000000..f4b6fff0d Binary files /dev/null and b/BOLSIGChemistry_NominalRates/Excitation_Resonant.h5 differ diff --git a/BOLSIGChemistry_NominalRates/Ionization.h5 b/BOLSIGChemistry_NominalRates/Ionization.h5 new file mode 100644 index 000000000..b0cb3e61d Binary files /dev/null and b/BOLSIGChemistry_NominalRates/Ionization.h5 differ diff --git a/BOLSIGChemistry_NominalRates/StepExcitation.h5 b/BOLSIGChemistry_NominalRates/StepExcitation.h5 new file mode 100644 index 000000000..f24fecab9 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/StepExcitation.h5 differ diff --git a/BOLSIGChemistry_NominalRates/StepIonization_4p.h5 b/BOLSIGChemistry_NominalRates/StepIonization_4p.h5 new file mode 100644 index 000000000..c9ae36f79 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/StepIonization_4p.h5 differ diff --git a/BOLSIGChemistry_NominalRates/StepIonization_Metastable.h5 b/BOLSIGChemistry_NominalRates/StepIonization_Metastable.h5 new file mode 100644 index 000000000..9cd0f8f0d Binary files /dev/null and b/BOLSIGChemistry_NominalRates/StepIonization_Metastable.h5 differ diff --git a/BOLSIGChemistry_NominalRates/StepIonization_Resonant.h5 b/BOLSIGChemistry_NominalRates/StepIonization_Resonant.h5 new file mode 100644 index 000000000..4014ea28b Binary files /dev/null and b/BOLSIGChemistry_NominalRates/StepIonization_Resonant.h5 differ diff --git a/BOLSIGChemistry_NominalRates/detailed_balance.py b/BOLSIGChemistry_NominalRates/detailed_balance.py new file mode 100644 index 000000000..24f58fc64 --- /dev/null +++ b/BOLSIGChemistry_NominalRates/detailed_balance.py @@ -0,0 +1,135 @@ +import numpy as np +import h5py as h5 +from matplotlib import pyplot as plt + +E_lvl_m = 11.548 +E_lvl_r = 11.624 +E_lvl_4p = 12.907 +E_lvl_i = 15.76 +g_m = 5.0 +g_r = 3.0 +g_4p = 3.0 +g_i = 4.0 +n_e = 3.7e15 + +rates14 = [] +rates21 = [] +rates26 = [] +rates29 = [] +rates35 = [] +data10 = h5.File('./1s-metastable.h5', 'r')["table"] +data11 = h5.File('./1s-resonance.h5', 'r')["table"] +data12 = h5.File('./2p-lumped.h5', 'r')["table"] +data13 = h5.File('./Ionization.h5', 'r')["table"] +data15 = h5.File('./StepIonization.h5', 'r')["table"] + +Te = data10[:,0] +rates10 = data10[:,1] +rates11 = data11[:,1] +rates12 = data12[:,1] +rates13 = data13[:,1] +rates15 = data15[:,1] + +for j in range(len(Te)): + rates14.append(rates10[j] * (1 / g_m) * np.exp(E_lvl_m / (Te[j] / 11604))) + rates21.append(rates11[j] * (1 / g_r) * np.exp(E_lvl_r / (Te[j] / 11604))) + rates26.append(rates15[j] * (g_m / g_i) * np.exp((E_lvl_i - E_lvl_m) / (Te[j] / 11604)) / n_e * 6.022e23) + rates29.append(rates13[j] * (1 / g_i) * np.exp(E_lvl_i / (Te[j] / 11604)) / n_e * 6.022e23) + rates35.append(rates12[j] * (1 / g_4p) * np.exp(E_lvl_4p / (Te[j] / 11604))) + + +data14 = np.empty(shape = (len(Te), 2)) +data21 = np.empty(shape = (len(Te), 2)) +data26 = np.empty(shape = (len(Te), 2)) +data29 = np.empty(shape = (len(Te), 2)) +data35 = np.empty(shape = (len(Te), 2)) + +data14[:,0] = Te +data14[:,1] = rates14 +data21[:,0] = Te +data21[:,1] = rates21 +data26[:,0] = Te +data26[:,1] = rates26 +data29[:,0] = Te +data29[:,1] = rates29 +data35[:,0] = Te +data35[:,1] = rates35 + +with h5.File('./Deexci-metastable.h5', 'w') as f: + dataset = f.create_dataset("table", data = data14) + +with h5.File('./Deexci-resonance.h5', 'w') as g: + dataset = g.create_dataset("table", data = data21) + +with h5.File('./3BdyRecomb-ground.h5', 'w') as h: + dataset = h.create_dataset("table", data = data29) + +with h5.File('./3BdyRecomb-metastable.h5', 'w') as x: + dataset = x.create_dataset("table", data = data26) + +with h5.File('./Deexci-2p.h5', 'w') as y: + dataset = y.create_dataset("table", data = data35) + +#rxn10 = h5.File("./BOLSIGChemistry_6SpeciesRates/lumped.metastable.h5", 'r') +#rxn11 = h5.File("./BOLSIGChemistry_6SpeciesRates/lumped.resonance.h5", 'r') + +#data10 = rxn10["table"] +#data11 = rxn11["table"] + +#Te = data10[:,0] +#Te /= 11604 +#rates10 = data10[:,1] +#rates11 = data11[:,1] +#rates10 /= 6.022e23 +#rates11 /= 6.022e23 + +#rates14 = [] +#rates21 = [] + +#for i in range(len(rates10)): +# rates14.append(rates10[i] * (1 / g_m) * np.exp(E_lvl_m / Te[i])) +# rates21.append(rates11[i] * (1 / g_r) * np.exp(E_lvl_r / Te[i])) + + +#arrh_14 = [] +#arrh_21 = [] + +#for j in range(len(Te)): +# arrh_14.append(4.3e-16 * Te[j]**0.74) +# arrh_21.append(4.3e-16 * Te[j]**0.74) + + +#fig,ax = plt.subplots() +#ax.set_xscale('log') +#ax.set_yscale('log') +#ax.plot(Te, rates14, color = 'darkblue', label = 'CRSC - 14') +#ax.plot(Te, arrh_14, color = 'cyan', label = 'Arrhenius - 14') +#ax.plot(Te, rates21, color = 'darkred', label = 'CRSC - 21') +#ax.plot(Te, arrh_21, color = 'orange', label = 'Arrhenius - 21') +#ax.legend() +#ax.set_xlabel('Te [eV]') +#ax.set_ylabel('Rate [# / m3-s]') +#plt.savefig('RatesComparison.png') + + +#for i in range(len(rates14)): +# rates14[i] *= 6.022e23 +# rates21[i] *= 6.022e23 +# Te[i] *= 11604 + +#data14 = np.empty(shape = (len(Te), 2)) +#data21 = np.empty(shape = (len(Te), 2)) + +#data14[:,0] = Te +#data21[:,0] = Te +#data14[:,1] = rates14 +#data21[:,1] = rates21 + +#with h5.File('./BOLSIGChemistry_6SpeciesRates/deexci.metastable.h5', 'w') as f: +# dataset = f.create_dataset("table", data = data14) + +#with h5.File('./BOLSIGChemistry_6SpeciesRates/deexci.resonance.h5', 'w') as g: +# dataset = g.create_dataset("table", data = data21) + + + diff --git a/BOLSIGChemistry_NominalRates/nominal_transport.h5 b/BOLSIGChemistry_NominalRates/nominal_transport.h5 new file mode 100644 index 000000000..47b16dc12 Binary files /dev/null and b/BOLSIGChemistry_NominalRates/nominal_transport.h5 differ diff --git a/BOLSIGChemistry_NominalRates/plot_rates.py b/BOLSIGChemistry_NominalRates/plot_rates.py new file mode 100644 index 000000000..355e3cde0 --- /dev/null +++ b/BOLSIGChemistry_NominalRates/plot_rates.py @@ -0,0 +1,157 @@ +import numpy as np +import csv +from matplotlib import pyplot as plt +from scipy.interpolate import CubicSpline +import matplotlib.colors as mcolors + +tau = (1./13.56e6) +nAr = 3.22e22 +np0 = 8e16 +Nr = 9 +iSample = 0 + +reactionExpressionTypelist = np.array([True,True,True,False,False,False,False,False,False]) + +reactionsList = [] + # import h5py as h5 + # rxnName = ["Ionization", ...] <- dictionary containing reaction name root string + # for r in range(Nr): + # if reactionExpressionTypeList[r]: + # fileName = "{0:s}.{1:08d}.h5".format(rxnName[r], iSample) + # f = h5.File(filename, "r") + # D = f["table"] + +for i in range(Nr): + if reactionExpressionTypelist[i]: + Nsample = 1 + N300 = 200 + + root_dir = "./" + rate_file = open("{0:s}reaction300K_{1:d}.txt".format(root_dir, i), 'r', encoding='utf-8-sig') + temp_file = open('reaction300K_Te.txt', 'r', encoding='utf-8-sig') + + rateCoeff = np.genfromtxt(rate_file, dtype='float') + rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] + rate_file.close() + + Te = np.genfromtxt(temp_file, dtype='float') + print(Te) + Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] + print(Te) + temp_file.close() + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + # Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + lastFalse = np.where(indices==False)[-1][-1] + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + #if i < 2: + # rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + #else: + # rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + #reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + # rxnBolsig = reactionExpressionTypelist[i], + # kf_log = reactionExpressionsLog, + # kf_T_log = reactionTExpressionsLog) + #reactionsList.append(reaction) + + + # rxn = eval("lambda energy :" + reactionExpressionslist[i]) + # rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + # setting the axes at the centre + fig ,ax = plt.subplots(figsize=(9, 6)) + ax.spines["top"].set_visible(True) + ax.spines["right"].set_visible(True) + ax.set_yscale('log') + ax.set_xscale('log') + + # plot the function + #plt.plot(rateCoeffXFiner, np.exp(reactionExpressions_cubicSplineDerivative_log(rateCoeffXFiner)), + # color='salmon', linestyle='--', label='interBolsig') + #plt.plot(rateCoeffXFine, np.exp(reactionExpressions_cubicSpline_log(rateCoeffXFine)), + # color='lightgreen', linestyle='--', label='interBolsig') + #plt.plot(Te[:,0], reactionTExpressionsLogFiltered(TeLog[:]) * np.exp(reactionExpressionsLog(TeLog[:])) / Te[:,0], + # color='blue', linestyle='-', label='interBolsig') + plt.plot(Te, np.exp(reactionExpressionsLog(TeLog[:])), + color='green', linestyle='-', label='Bolsig') + #plt.plot(Te, rxn(Te), + # color='salmon', linestyle='--', label='Liu') + #plt.plot(Te[:,0], rxn_T(Te[:,0]), + # color='red', linestyle='--', label='interBolsig') + plt.xlim((0.05,100)) + plt.ylim((1e-50,300)) + plt.legend() + plt.savefig("./PlotRates_%s.pdf" %str(i), dpi=300) + #plt.xlim((-0.0001,0.0255)) + plt.show() + + # Export rates to CSV Files + header = ['Te', 'kf'] + row_temp = [] + data = [] + for j in range(len(Te)): + row_temp.append(Te[j]) + row_temp.append(np.exp(reactionExpressionsLog(TeLog[j]))) + data.append(row_temp) + row_temp = [] + + f = open("./PlotRates_Rxn%s.csv" %str(i), 'w') + writer = csv.writer(f) + writer.writerow(header) + writer.writerows(data) + f.close() diff --git a/BOLSIGChemistry_NominalRates/plot_rates_h5.py b/BOLSIGChemistry_NominalRates/plot_rates_h5.py new file mode 100644 index 000000000..4716e11d7 --- /dev/null +++ b/BOLSIGChemistry_NominalRates/plot_rates_h5.py @@ -0,0 +1,110 @@ +import numpy as np +import csv +from matplotlib import pyplot as plt +from scipy.interpolate import CubicSpline +import matplotlib.colors as mcolors +import h5py as h5 + +Nr = 34 + +reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-34 + +rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "1s-metastable", + 9: "1s-resonance", + 10: "2p-lumped", + 11: "Ionization", + 12: "Deexci-metastable", + 13: "StepIonization", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "Deexci-resonance", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb-metastable", + 25: "3BdyRecomb-metastable", + 26: "3BdyRecomb-metastable", + 27: "3BdyRecomb-ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization", + 33: "Deexci-2p"} + +for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("{0:s}.h5".format(rxnNameDict[i]), 'r') + data = f["table"] + else: + f = h5.File("StepwiseExcitations.nominal.h5", 'r') + data = f[rxnNameDict[i]] + + Te = data[:,0] + Te /= 11604 + rateCoeff = data[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + row_temp = [] + data = [] + header = ["", "Te(eV)", "", "kf(m3/s)", ""] + for j in range(len(Te)): + row_temp.append('(') + row_temp.append(Te[j]) + row_temp.append(',') + row_temp.append(rateCoeff[j]) + row_temp.append(')') + data.append(row_temp) + row_temp = [] + + g = open("./CSVs/RateProfile_{}.csv".format(i + 1), 'w') + writer = csv.writer(g) + writer.writerow(header) + writer.writerows(data) + g.close() + else: + continue + +row_temp = [] +data = [] + +h = h5.File('../BOLSIGChemistry_Transport/nominal_transport.h5', 'r') +Nmu = h["mobility"] +Te_trans = Nmu[:,0] +Te_trans /= 11604 +mobility = Nmu[:,1] + +header = ["", "Te(eV)", "", "Nmu(VMS)", ""] +for k in range(len(Te_trans)): + row_temp.append('(') + row_temp.append(Te_trans[k]) + row_temp.append(',') + row_temp.append(mobility[k]) + row_temp.append(')') + data.append(row_temp) + row_temp = [] + +z = open("./CSVs/Transport.csv", 'w') +writer = csv.writer(z) +writer.writerow(header) +writer.writerows(data) +z.close() + diff --git a/BOLSIGChemistry_Transport/nominal_transport.h5 b/BOLSIGChemistry_Transport/nominal_transport.h5 new file mode 100644 index 000000000..1e1557ecf Binary files /dev/null and b/BOLSIGChemistry_Transport/nominal_transport.h5 differ diff --git a/chebSolver.py b/chebSolver.py index 6e654858f..2e0e8b0b6 100644 --- a/chebSolver.py +++ b/chebSolver.py @@ -3,17 +3,8 @@ import time from Liu2014Properties import setLiu2014Properties -from psaapProperties import setPsaapProperties from psaapPropertiesTestArm import setPsaapPropertiesTestArm from psaapPropertiesTestArmInterpTrans import setPsaapPropertiesTestArmInterpTrans -from psaapPropertiesCurrentTestCase import setPsaapPropertiesCurrentTestCase -from psaapPropertiesCurrentTestCase100mTorr import setPsaapPropertiesCurrentTestCase100mTorr -from psaapPropertiesWithSampling import setPsaapPropertiesWithSampling -from psaapPropertiesTestJP import setPsaapPropertiesTestJP -from psaapPropertiesTestJP_Nominal import setPsaapPropertiesTestJP_Nominal -from psaapPropertiesTestJP_Arrhenius import setPsaapPropertiesTestJP_Arrhenius -from psaapProperties_6Species import setPsaapProperties_6Species -from psaapProperties_6Species_Sampling import setPsaapProperties_6Species_Sampling from psaapProperties_6Species_Nominal import setPsaapProperties_6Species_Nominal class modelClosures: @@ -197,16 +188,6 @@ def diffusivity(self, i, energy, mu, nb, EinsteinForm): V0 = self.qStar * 1.0 # V0 = qStar * 1eV DEf = 2.0 / 3.0 * np.multiply(energy[:,[i]], mu[:,[i]]) / V0 - # Einstein for electrons only (for testing purposes) - # if EinsteinForm: - # #V0 = self.qStar * 1.0 # V0 = qStar * 1eV - # #DEf = 2.0 / 3.0 * np.multiply(energy[:,[i]], mu[:,[i]]) / V0 - # if self.Z[i] == -1: ## Added this to use Einstein Relation only with electrons and constant values for heavies - # V0 = self.qStar * 1.0 - # DEf = 2.0 / 3.0 * np.multiply(energy[:,[i]], mu[:,[i]]) / V0 - # else: - # DEf[:,0] = self.D[i] / nb - else: DEf[:,0] = self.D[i] / nb @@ -228,19 +209,13 @@ def diffusivity_U(self, i, j, energy, energy_U, mu, D, nb, EinsteinForm): D_U_tmp = D_ee * np.diag(energy_U[i,j,:,:]) D_U[:,:] = np.diag(D_U_tmp) - elif EinsteinForm: + elif EinsteinForm and self.Z[i] == -1: V0 = self.qStar * 1.0 # V0 = qStar * 1eV D_U = 2.0 / 3.0 * np.multiply(mu[:,[i]], energy_U[i,j,:,:]) / V0 if (j == self.Ns - 1): D_U[:,:] -= np.diag(D[:,i] / nb) - # Einstein for electrons only (for testing purposes) - # if EinsteinForm: - # if self.Z[i] == -1: - # V0 = self.qStar * 1.0 # V0 = qStar * 1eV - # D_U = 2.0 / 3.0 * np.multiply(mu[:,[i]], energy_U[i,j,:,:]) / V0 - return D_U @@ -427,21 +402,27 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, elif(scenario==3): Nr = 8 elif(scenario==4): - Nr = 8 + Nr = 9 elif(scenario==5): Nr = 7 elif(scenario==6): - Nr = 9 + Nr = 23 elif(scenario==7): - Nr = 9 + Nr = 23 elif(scenario==8): - Nr = 9 + Nr = 23 elif(scenario==9): Nr = 23 elif(scenario==10): - Nr = 23 + Nr = 34 elif(scenario==12): Nr = 23 + elif(scenario==13): + Nr = 23 + elif(scenario==14): + Nr = 23 + elif(scenario==16): + Nr = 23 elif(scenario==21): Nr = 8 else: @@ -463,21 +444,29 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, elif(scenario==3): setPsaapPropertiesCurrentTestCase(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==4): - setPsaapPropertiesCurrentTestCase100mTorr(gam, V0, VDC, self.params, Nr, iSample) + setPsaapProperties_4Species_Nominal(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==5): setPsaapPropertiesWithSampling(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==6): - setPsaapPropertiesTestJP(gam, V0, VDC, self.params, Nr, iSample) + setPsaapProperties_6Species_Sampling(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==7): - setPsaapPropertiesTestJP_Nominal(gam, V0, VDC, self.params, Nr, iSample) + setPsaapProperties_6Species_Sampling_250mTorr(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==8): - setPsaapPropertiesTestJP_Arrhenius(gam, V0, VDC, self.params, Nr, iSample) + setPsaapProperties_6Species_Sampling_500mTorr(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==9): setPsaapProperties_6Species(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==10): - setPsaapProperties_6Species_Sampling(gam, V0, VDC, self.params, Nr, iSample) + setPsaapProperties_6Species_100mTorr_Expanded(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==12): setPsaapProperties_6Species_Nominal(gam, V0, VDC, self.params, Nr, iSample) + elif(scenario==13): + setPsaapProperties_6Species_500mTorr(gam, V0, VDC, self.params, Nr, iSample) + elif(scenario==14): + setPsaapProperties_6Species_1Torr_Expanded(gam, V0, VDC, self.params, Nr, iSample) + elif(scenario==15): + setPsaapProperties_6Species_Sampling_1Torr_Expanded(gam, V0, VDC, self.params, Nr, iSample) + elif(scenario==16): + setPsaapProperties_6Species_5Torr(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==21): setPsaapPropertiesTestArmInterpTrans(gam, V0, VDC, self.params, Nr, iSample) @@ -1865,6 +1854,7 @@ def plot(self, col, create=True): action='store_true', help="Activate Einstein's form for diffusion coefficient.") parser.add_argument('--iSample', metavar='iSample', default=0, type=int, help='Sample index, if BOLSIG chemistry is used.') + parser.add_argument('--gam', metavar='gam', default=0.01, type=float, help='Secondary Electron Emission Coefficient') args = parser.parse_args() # Dump inputs to the screen for posterity @@ -1907,26 +1897,34 @@ def plot(self, col, create=True): print("# Running scenario = 3 (4 species, 8 rxn, Liu 2017)") Ns = 4 elif(args.scenario==4): - print("# Running scenario = 4 (4 species, 8 rxn, Liu 2017)") + print('# Running scenario = 4 (4 species, 9 rxn, 1Torr, Nominal)') Ns = 4 elif(args.scenario==5): - print("# Running scenario = 5 (4 species, 7 rxn, Bolsing and Lay, Moss et al, 2003)") + print('# Running scenario = 5 (4 species, 9 rxn, 1Torr, Sampling)') Ns = 4 elif(args.scenario==6): - print("# Running scenario = 6 (4 species, 9 rxn, Juan's mechanism)") - Ns = 4 + print('# Running scenario = 6 (6 species, 23 rxn, 1Torr, 100V, Sampling)') + Ns = 6 elif(args.scenario==7): - print("# Running scenario = 7 (4 species, 9 rxn, Nominal reaction rates)") - Ns = 4 + print('# Running scenario = 7 (6 species, 23 rxn, 250mTorr, 100V, Sampling)') + Ns = 6 elif(args.scenario==8): - Ns = 4 + print('# Running scenario = 8 (6 species, 23 rxn, 500mTorr, 100V, Sampling)') + Ns = 6 elif(args.scenario==9): print("# Running scenario = 9 (6 species, 23 rxn)") Ns = 6 elif(args.scenario==10): + print('# Running scenario = 10 (6species, 34 rxn, 100mTorr, Nominal)') Ns = 6 elif(args.scenario==12): + print('# Running scenario = 12 (6 species, 23 rxn, 1Torr, 100V, Nominal)') + Ns = 6 + elif(args.scenario==13): + print('# Running scenario = 13 (6 species, 23 rxn, 500mTorr, 100V, Nominal)') Ns = 6 + elif(args.scenario==14): + print('# Running scenario = 14 (6 species, 34 rxn, 1Torr, Nominal)') elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") Ns = 4 @@ -1970,7 +1968,7 @@ def plot(self, col, create=True): # Instantiate solver class tds = timeDomainCollocationSolver(Ns, 1, args.Np, elasticCollisionActivationFactor, backgroundSpecieActivationFactor, EinsteinForm, - gam=0.01, V0 = args.V0, VDC = args.VDC, + gam=args.gam, V0 = args.V0, VDC = args.VDC, scenario=args.scenario, scheme=args.tscheme, iSample = args.iSample) diff --git a/fullRun.sh b/fullRun.sh deleted file mode 100755 index e0dc2d977..000000000 --- a/fullRun.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -error_exit() -{ - echo "$1" 1>&2 - exit 1 -} - -EXE="python3 ./chebSolver.py" -#Np=150 -#Nt=32000 -#dt=0.015625 - -# Liu 3 species case -Np=150 -Nt=64000 -dt=0.0078125 -baseFile='restart_3spec_Np150_' - -baseCmd="$EXE --Np $Np --Nt $Nt --dt $dt" -screenOut="fullRun.out" -rm -f $screenOut - -# Run Chebyshev time domain solver out to 4000 periods -$baseCmd --t0 0.0 --outfile "${baseFile}T0500.npy" > $screenOut || error_exit "First run failed" -$baseCmd --t0 500.0 --restart "${baseFile}T0500.npy" \ - --outfile "${baseFile}T1000.npy" >> $screenOut || error_exit "Second run failed" -$baseCmd --t0 1000.0 --restart "${baseFile}T1000.npy" \ - --outfile "${baseFile}T1500.npy" >> $screenOut || error_exit "Third run failed" -$baseCmd --t0 1500.0 --restart "${baseFile}T1500.npy" \ - --outfile "${baseFile}T2000.npy" >> $screenOut || error_exit "Fourth run failed" -$baseCmd --t0 2000.0 --restart "${baseFile}T2000.npy" \ - --outfile "${baseFile}T2500.npy" >> $screenOut || error_exit "Fifth run failed" -$baseCmd --t0 2500.0 --restart "${baseFile}T2500.npy" \ - --outfile "${baseFile}T3000.npy" >> $screenOut || error_exit "Sixth run failed" -$baseCmd --t0 3000.0 --restart "${baseFile}T3000.npy" \ - --outfile "${baseFile}T3500.npy" >> $screenOut || error_exit "Seventh run failed" -$baseCmd --t0 3500.0 --restart "${baseFile}T3500.npy" \ - --outfile "${baseFile}T4000.npy" >> $screenOut || error_exit "Eighth run failed" diff --git a/generate_sample.py b/generate_sample.py index 4c33dc885..e0ce02f3c 100644 --- a/generate_sample.py +++ b/generate_sample.py @@ -47,7 +47,7 @@ def getNumberOfReactants(equation): # Take the nominal value from the input file coeffs0 = np.array(rxn['arrhenius']['coefficients'], dtype = np.double) # Add a relative error - coeffs0[0] *= (1.0 + error) ** np.random.normal() + coeffs0[0] *= (1.0 + error) ** np.random.normal(0, 1./3) # Create a dataset for the reaction dset = f.create_dataset(rxn['equation'], (3,), data = coeffs0) dset.attrs['rate_unit'] = rateUnit diff --git a/plotSampleRun.ipynb b/plotSampleRun.ipynb deleted file mode 100644 index be328070d..000000000 --- a/plotSampleRun.ipynb +++ /dev/null @@ -1,207 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Plot sample results\n", - "This notebook shows plots from the run conducted in fullRun.sh or sampleRun.sh, depending on what is available. You need to run one of those scripts prior to using this notebook in order to generate the data files used here.\n", - "\n", - "Two sets of plots are generated. The first shows the time histories of $\\min(n_e)$, $\\max(n_e)$, $\\min(T_e)$ and $\\max(T_e)$. This data is dumped to the screen for every time step, which is captured in run.out (for sampleRun.sh) or fullRun.out (for fullRun.sh). The second set of plots shows $n_e$, $n_i$, and $T_e$ as a function of $x$ for the snapshots stored in the restart files." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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IiIi8ielHKQ/CUw2s+Myhi0BVuUYd1UqLXO8re7eMYZ8hk2buid94WjpOaY9xsxqD5CemfcxQEWqTCIiIiIiIiLDlGyQ7u7dwB3A9WZWbWYvAV4P3Jpj9FuAS83sRDNrBD4BfHOM+dwJnGRmF5lZJfBJ4BF3X52R90fMbLaZzQI+mpH3k8BDwKfMrNLM3gicQrwCDuA24HVmdnYq+L8euONAD40TERERERGRo1fJPt0d/vR+828ArwA6gKvc/dtmNg94DDjR3Z9LjfsRhr8n/b1Z70kfkU/GfM4H/gWYT/o96WtTaQZ8nvR70r/GyPekf5P0e9L/V473pH8OaAZ+Afzlwd6TbmbbgXXjWlmHXwvxFHyRYlI9lFKhuiilQPVQSoHqoZSKUq+L8919Wq6Ekg7SpXSZ2YrRXhkgcrioHkqpUF2UUqB6KKVA9VBKxUSuiyV7ubuIiIiIiIjI0UZBuoiIiIiIiEiJUJAuz9fNxS6ACKqHUjpUF6UUqB5KKVA9lFIxYeui7kkXERERERERKRFqSRcREREREREpEQrSRUREREREREqEgnQRERERERGREqEgXURERERERKREKEgXERERERERKREK0kVERERERERKhIJ0ERERERERkRKhIF1ERERERESkRChIFxERERERESkRCtJFRERERERESoSCdBEREREREZESoSBdREREREREpEQoSBcREREREREpEQrSRUREREREREqEgnQRERERERGREjG52AWQkVpaWrytra3YxTig7u5uqquri10MOcqpHkqpUF2UUqB6KKVA9VBKRanXxZUrV+5w92m50hSkl6C2tjZWrFhR7GIc0PLly1m2bFmxiyFHOdVDKRWqi1IKVA+lFKgeSqko9bpoZutGS9Pl7iIiIiIiIiIlQkG6iIiIiIiISInQ5e4iIiIiIiJSEgYHobsburrSXeb3np7ourvT/ZldMvzP/qyOEr7a/YAUpIuIiIiIiMi4DAykA+fOznQwnQTUY+3PDsL37RtfOaZMgalTobo6PqdOhaoqGBycuBeNK0gXERERERE5gg0NDW+ZToLqXN/H0j/eYHrSpAiiq6uhpibdX18Pc+akhydpo/VndkkwPnmUiHb58t35WXlFoCBdRERERESkRLhDX186MM7sMoeNJ8ju6Rn7/CsqIiiurU0HyLW1MGNG7uFJf3YwndlfUQFmhVtnRxoF6SIiIiIiIoegry8C4r17h3eZw7ID69FaqLu64lLysZg0KQLl7MC5ufnAAfWBAu3y8sKuKzk4BekiIiIiInLUGRqKe6GTQDpXkD3Wrr//4PMzG9nqXFMD06fDMceMHJ4Ez5lBeHb/lClqoT4SKUgXEREREZEJIbkUfM+e3C3W2S3XBxrW2Rn5HUxFBdTVRVdfH5/z5kWQXF8fn0l60mUPq62Ne6jLJu6zzOQwUpAuIiIiIiKHRX9/BNi7d0d3sP4kGM8MyvfvP/h8yspGBssNDengOjstc1gSiCffKyoKv15EMilIFxERERGRgxocTAfM2YF00v/HPy7kttuGD89MP9gTwc0iSG5oiM/6epg7FxYvHt6SnavLDLqrqnQZuExcCtJFRERERI4Cg4PDW6t37crdn3zPDsI7Ow8+j8rKWTQ2poPsxkZoa0sH3EkAnnSZAXlDQ9xrrUvC5WinIF1EREREZAJwh97eCKCToDrpz/yeK+jevTtawQ+krCwC5cbGdNC8aNHIADvXZ9L99re/YdmyZYdlfYgcqRSki4iIiIgcJu7xzuqdO6GjIz6zA+7Rgu9duw5+P3ZtbTrQbmiABQuGt1wnw3P119ToEnGRUqAgXURERERknNzjfdY7d6YD7aQ/MwDP1X+g13VNmjQ8cG5sjIedJf2Zw7P7Gxpgsv7di0x42oxFRERE5KjlHvdbJwF00mUG3LkC8V27YGBg9HyrqqCpKbrm5rhsPPN70t/UNDzQrq1Va7bI0U5BuoiIiIgcEYaG4tLwHTtG7zID8SQYHxwcPc/6+nQg3dQUTxrP/J4ZaCefzc0RpIuIPB8K0kVERESk5LjH08QPFHDnCsCHhnLnV1ERwXPSLV48/HuuTpePi0gxaLcjIiIiIgXX0zO+gHvHjtEfkjZ5MrS0pLvFi4d/z9VNnarLyEVkYlCQLiIiIiLj0tcXrdbjCbh7e3PnZRat1kkwvXAhnHHGgQPuujoF3CJy5FKQLiIiInKU6+6Gbdtg+/boMvuT75kBd2fn6Hk1NKSD6dmzYcmSAwfcDQ3xRHMREQkK0kVERESOML29EVgnwXZ2f3YwPlord2UlTJuW7hYtOnDA3dQE5eWHd1lFRI40CtKzmNmZwKuAM4FZQBWwA3gCuBv4vrvvGkd+FcCNwPlAE/AU8Hfu/v/yXHQRERE5Qg0NxSu/tm6NwDr5zOxfs2Yp+/ZFf1dX7nySoHv69Pg84YR0f9Jlfq+p0WXlIiKHm4L0FDO7GPhrYDGwF3gEWAP0EsH1GcA7gRvM7D+A69z92TFkPRlYD5wDPAe8GvgPMzvZ3dfmezlERERkYujvj4B6y5YItLdsSfdnt3rv2JH7NWFlZenAurJyiCVLoLU1viddZvCtoFtEpPQpSAfM7GFgOnAL8C7gIXf3HOPVA68F3g6sMrO/dPfbD5S3u3cD12YM+rGZPQucDqzNywKIiIhISdi3LwLtpJU7CbK3bh0eiG/ZEu/nzqWuLgLtadPiIWpnnhn9SfCd+dnUlL6fe/nyh1m2bNlhW1YRESkMyxGLHnXM7ErgJnffN45plgAz3P2n45xXK7AOONXdV2cMvwK4AqC1tfX07373u+PJ9rDr6uqipqam2MWQo5zqoZQK1cUjmzvs3TuZXbumsHNnusv83tExhY6OCvbuzX1DdmXlIE1N/TQ29g/7zO5vatrPlCmjvOj7IFQPpRSoHkqpKPW6eO6556509/ZcaQrSDyMzKwf+H/C0u79ntPHa29t9xYoVh69gz8Py5ct1tl6KTvVQSoXq4sTjHvdtZ7ZsZ7d0J9+3bs39vu6KCpgxI1q0Z82KbubM6DIvOZ82DaqrC79MqodSClQPpVSUel00s1GDdF3uPkZm9mripMZdz3P6MuBWoB/4QD7LJiIiIsE93t+9aRNs3jx6t2UL9PSMnH7SpAisZ8yI7uSTI+BOvidB+YwZUF+v+7tFRCT/FKSPgZndCLQBxwN3mdliYKG7/3CM0xvwdaAVeLW75zgfLyIiIqMZGoqHp23alO4yg+7k+5YtuVu96+vTrdxnnhlBdtLinRmANzfHw9hERESKRUH62Jzj7ovN7MHU9zVE0D2mIB34KnACcL67j/ImUhERkaNTZyds3BiBduZn0p8E4LmC7+bmdPB9wgnp/pkz05efz5gBU6ce/uUSERF5PhSkj82w96K7e7+ZTRnLhGY2H3gP0AdssfR1ce9x99vyWkoREZESMjAQLdtJwJ0ZeGf2d3aOnLauDmbPjkB72bL4TL4nAfiMGXFfuIiIyJFEQfrYPGhmFwIOYGbVQO1YJnT3dYDuWBMRkSPK3r0jg+/sbuvWuEw9U3l5+iFrJ58MF1wQwXcSgCefJfxAXhERkYJSkD42VwPfARaY2f8Gzgee1wPkRERESllfH2zYMPJ+7+wW8K6ukdM2NMCcORFon3JKOvjO7FpadM+3iIjIgShIHwN37wJeZ2YvA9qBzwD/WdxSiYiIjI877NkDzz0X3fr18bluHaxdG93mzSOnS1q/Z8+O1u9XvWpk8D1rlu77FhERyQcF6aMwswp378sc5u6/Bn5dpCKJiIgcUNIKngTfmYF40mW3gJeXw9y50NYWwXdbW3zPfOe3nnguIiJy+ChIz2Jmy4BvAXPMbC/wCPAA8GDq8zF3Hxo9BxERkfwbGoLt24cH3NnB+JYtI6ebPh3mzYNFi+AVr4j+uXPjc968eAWZAnAREZHSoSB9pBuAHuADQAuwFHgD8KFU+j5AF/SJiEhedXamg+5cLeHr10N///Bppk5NB9tLlgwPvufOjfvDq6qKszwiIiLy/ChIH2kB8GZ3H/ZgODNrAE4DTi1KqUREZMLavz8eunagy9B37x4+TVlZ3Os9bx688IVw0UXDA/B586CxEUzvDxERETmiKEgfaTVQnj3Q3XcDv0x1IiIiQPIwtsk8+ODol6Fv2jTyVWRNTRFsz58PZ5898jL0mTNhso7SIiIiRx0d/kf6EnAZ8P1iF0RERIpv377Rg++kv7f3pcOmqahIB9znnz/yMvS5c/UecBEREclNQfpILwNOMLPbgU+6+xPFLpCIiBTO4GA8Ef3ZZ9PdM8+k+3O9kmzmzAi4Tz4ZXvMa6Otbw8tfftyfAvFp03QZuoiIiDw/CtJHegkwj7g3/c/NbAOwkniy+0rgAXffWsTyiYjIOGS+FzxXt3FjBOqJsrJo6V6wIF5JtmBBXJI+f34E4LNnw5Qpw+exfPlGli077vAumIiIiByRFKRncffFZlYBnEw82f3U1OfHgGrAgUnFK6GIiGQaGopAe82a4d0zz0QQvnfv8PEnT05ffn7OOfE5f34E4wsWxPfyEU8mERERETk8FKTn4O59wIpUB4CZGbAIWFKscomIHI0GB+P937lawZ9+Orp9+9LjV1TAscfCwoVw7rnpe8Ez3ws+SadaRUREpEQpSB8jd3fiye+ri10WEZEjTX9/tHw/+SQ88UR0a9ZEIL5hAwwMDB+/vj5aw489Ni5JP+646D/uuHg3eFlZcZZDRERE5FApSBcRkYIbGkq3hidPRX/mGXjqqejWrRt+X/j06XD88fDSl458N/jcuRGki4iIiByJFKQDZvYD4Fp3f3CM41cC7wd63P2mghZORGSC6O+PgPvxx+Gxx6JVPPPhbPv3Dx+/sTEuSX/Ri+Av/gIWLYru+OOhoaE4yyAiIiJSbArSw3PA783sIeA24B7gEXf/0wWWZjYLeBHwOuBNwEbg3UUoq4hIUbjDtm3pwHvduvhcuxZWr44APbM1fO5caGuDl7xkeEt40q9AXERERGQkBemAu3/QzL4MXAlcC9QDbmZ7gT6gESgHDPhDarxb3X2oOCUWESmM3t5oCV+1Kt4RngTiyWdf3/Dxa2riyegnnggXXQQnnBDdokWRJiIiIiLjoyA9xd2fBj5oZh8FXgycAcwCKoEO4oFxv3b3dcUrpYhIfvT2pi9Nf/xxePTR6J56Ku4fT8ycGS3fS5fC61+ffld48tnQAGbFWw4RERGRI42C9Czu3g/cnepERCacjo54ONvmzbBpU3QbNgzvdu5Mj28W94affDK85S3xefLJ8c7wioriLYeIiIjI0UhBehYze5+7f3WUtArgS+7+vw5zsUREhnGH3bsjGF+7Fh56CB54ILr160eOP21avJps/vy4R3zOnLhf/MQT40FtU6ce7iUQERERkVwUpI/0L2b2SuBSd/9TW5OZnQR8F5gPKEgXkYLq6YlgO+mSV5dldl1d6fHN0q8sW7oUjjkGZs2Ky9VnzIDKyuIti4iIiIiMnYL0kS4EvgU8bGbvdPflZvZXwOeAx4HTi1o6ETnidHTAypXRrVgRn+tyPP2itTWein7CCfDKV0Z/8sT0xYuhtvbwl11ERERE8ktBehZ3/5mZLQFuAX5hZg8DS4CvAFe5+/4DZiAikpJckp7cF75p0/D7xJN7xTMvT1+4EM48Ey6/fPjrymbP1v3hIiIiIkcDBek5uPs2M/tH4BxgKbAS+LQCdBEZzc6d0Qp+//3x+cgjEYTv2zdy3Pr6uBR91ixYtgxOOgna2+G00/TucBEREZGjnYL0LGY2Cfg08LfAT4FbgS8DD5nZO9z9nmKWT0SKo6sLtm2DrVuHd48/HoH500+nxz3uOHjhC6MFPAnGk27mTD2kTURERERGpyB9pN8Rl7f/tbt/GcDMlhP3qf/KzD7j7p8qYvlEpAB6e+G++6IVfN26uAQ9Mxjv6ck93dy5EZBfdll8nn66WsNFRERE5PlTkD5SHXCmuz+UDHD3LcAFZvZR4O8BBekiE1hPTzys7amn4Fe/iu4Pf4D+/kivq4t7wWfMiHvEp0+Ph7YlXfJ9+nSYMqW4yyIiIiIiRxYF6SOd7u4528zc/Ytm9j/jyczMPgBcApwMfMfdLznkEopIThs3xr3g69fHA9p27Eh3HR3p/t7e9DRlZXEv+F/9FZxzDrz4xdDcXLxlEBEREZGjm4L0LKMF6BnpDx0oPYdNROv7BUDV8y2XiIzU21vGD34Ad90FP/vZyNeWNTZGwN3SEk9HP+WU6G9pieGzZ8NZZ+nydBEREREpHQrSR5F6DdsioDI7zd1vGWs+7n5HKr92YE7eCihyhNq5E9auhb17obMzuj17YNeueJ3Zrl3RPfUU/PGPL2VwMN4Pfv75cOWV8ZT0+fPjAW2TtYcTERERkQnG3L3YZSgpZtYA3AWcmQxKff5pRbn7pOeR798Dc0a73N3MrgCuAGhtbT39u9/97nhncVh1dXVRU1NT7GLIEaCzczL339/Evfc2s2JFI7t3j36T95Qpg9TWDlBTM0Br6z7mz9/JmWd2c/LJeygv175Mikf7RCkFqodSClQPpVSUel0899xzV7p7e640tTON9BmgGXgZ8BvgjcAe4N3Ai4G3FmKm7n4zcDNAe3u7L1u2rBCzyZvly5dT6mWU4hsaioe0dXVFi3hXV7SGP/ccrFkTD2y77z4YHIxL0F/7Wli6FNra4lL12lqoqYnL0RsaoLJyEjAJqACqWb78UdVDKQnaJ0opUD2UUqB6KKViItdFBekjXQBcB/w+9X2Du68ElpvZV4EPAe8qVuFEStH27fDDH8Ly5bB6dTzArbMTurthtIt1zOLS9Kuvhle/Gl70Ipg07mtURERERESOLArSR5oJPOPug2a2D6jNSLsDKO3r0EUOg6EhePpp+PGP4fvfh3vuiWEzZ8LJJ8OSJfEas9radGt40tXVxbvF586FyhFPfBARERERObopSB9pC5A863kdcYn78tT3Y8ebmZlNJtbzJGCSmVUCA+4+cOhFFcmfri548EFYtSpaxnfvjoe3dXWlu+SS9fXr4zJ2gJNOgo9/HN74Rjj11GghFxERERGR50dB+kj3EIH5j4FbgU+ZWRswAFwM/HCc+X0C+FTG93cQl9Nfe4jlFDlkPT3RGv7d78JPfgJ9fem06up0a3jSCt7aCgsXwqteBSeeCOedF99FRERERCQ/FKSPdB0wK9X/j8RD5N4CTCUC9A+OJzN3vxYF5FIE7hGEZ77KLOnWro1L1H/84xhnxgx4z3vgggvicvUZM6C8vNhLICIiIiJy9FGQnsXdnwaeTvXvBz6a6kRK1oYN0Rp+771xufqOHfEu8aGh0adpbYV3vhPe8hZ42cv00DYRERERkVKgIH0UZjYXmAuMeLSVu//y8JdIZLju7nho27e+Bb/4RbScH3dcuiW8sXH4w9syu9mz4yFvun9cRERERKS0KEjPYmbHALcBL0oGpT491e/EQ+BECqK3Fzo60pem790breJJt3NntJbffXc8xG3+fLjmGnjXu3R/uIiIiIjIRKcgfaSvAfOAK4HVQH9xiyNHgwcfhP/7f+PhbevWHXjc8nJYtAje9jb4i7+IS9XLyg5POUVEREREpLAUpI/0QuASd/9esQsiR7bOTvjOd+Dmm2HlSqiogNe+Ft797rgUPbk0va4uLl1vbISGBpg6VZepi4iIiIgcqRSkj7QBtZ5LHrjDnj1x6frOnfHZ0REt5Q88EK3mvb3xnvGvfAXe8Q5oaip2qUVEREREpJgUpI/0GeBjZvZLd+8udmFkYujthX//d/jpT4c/XX1wMPf48+bBX/5lPF39jDPUMi4iIiIiIkFBehZ3v9XMXgCsNbPfA7tGjuIXF6FoUoJ27oSvfhX+6Z9g2zZoa4NTT42nqzc1QXPz8K6pCWbNisvYRUREREREsilIz2JmlwBXA4PAaYy89N0Pd5mktAwOwuOPx4Pevv71eBXahRfC3/4tnHOOWsVFREREROT5U5A+0nXAncCl7r672IWRw6+vD7Zsgc2bYePG6NauhaeegjVr4JlnoL8/nrL+1rfCX/81nHJKsUstIiIiIiJHAgXpIzUDNypAP7o8/ng8Zf1nP4PHHhuZXlUFxx4LJ5wAf/ZncNxx8LrXQWvr4S+riIiIiIgcuRSkj3QPcALwP8UuiBTe5s3wsY/BrbfClClw3nnw5jfDnDnxGrTZs6NradFl7CIiIiIiUngK0kf6EPAfZrYL+G9GPjgOdx867KWSvOrrg5tugmuuif6rroKPfASmTSt2yURERERE5GimIH2kx1Oft4yS7mi9TSjucV/5Y4/F69FWrICf/xy2b4cLLoB//ue4fF1ERERERKTYFGyOdD16gvuE1dERQfiqVemg/LHHYO/e9DgzZ8K558Lll8fl7bqMXURERERESoWC9Czufm2xyyDjMzgI3/sefOUrcO+90XIOcen6iSfCO94Rn4sXR6dL2kVEREREpFQpSJcJbdUquOwy+P3v45L1a6+Fs8+Gk05SMC4iIiIiIhOPgnSZcDo64IEH4LvfhVtugfp6+Na3osW8rKzYpRMREREREXn+FKRLyXvqqQjI77sPHn4Y1q+P4dXVcOml8OlPq9VcRERERESODArSpWT19sInPwlf+lLcZ37CCfDSl8LSpbBkCZx1FtTUFLuUIiIiIiIi+aMgXQrCHT7zGbjoInjBC8Y33erV8Yq0f/7naEW//HL41Kdg9uzClVdERERERKQUKEiXgti5Ez7xCbj5Zli37sDjuseD3/793+FHP0pfzn7KKfCzn8ErXlH48oqIiIiIiJQCBelSEMl7yZ97bvRx/ud/4MYb4Y9/hCefhKoq13qu1QAAIABJREFUeNWrIrh/5Suhre2wFFVERERERKRkKEiXgkiC9NEMDsIb3gBdXXD66fCNb8Sl8XV1h6d8IiIiIiIipUhBuhREZ2e63z0+n3gC7r03ntL+859HgP6Wt8Btt8GkScUpp4iIiIiISClRkC7Py+BgtHxffnlcop4tsyX9wgvh0Udh06b4XlcHZ58Nn/0svPnNYHZ4yiwiIiIiIlLqFKTL87J9eyV33AF33JFuKc+U2ZK+fHlc2n7eeRGcH388lJUdtqKKiIiIiIhMGArS5XnZsqXiT/1f+Uq8t3z+fJg5Eyor0y3pd98d7zOfrJomIiIiIiJyUAqdCszMmoCvA68EdgBXu/u3i1uqQ7d1a+Wf+q+8cnja2WdDeXn0n3rq/2fvzuNsqv8/gL/e9mVIGHvWLCFjmUpSiJIWFL6JEipt30q0qIj2aFeUrcRXSpIUSYukn7axxUQkW2Uf28ww233//njf0zl3Ge4w09zJ6/l43MfMve9zPudzzj33nPP+fM7CBJ2IiIiIiChSTJ/y3jgA6QAqA2gOYL6IrFbVxPyt1onLzAQ2biwDESAlBdi3D1i3zp5vvnkz8Pbb7rPOY2Lyt65EREREREQFCZP0PCQipQH0ANBUVZMBfCsi8wDcAGBYvlbuJJx9NrB+fQ3Ex9uzzWvUsJfj0UeBd9+1/3ntORERERERUeREw931i3KFiLQAsExVS3o+uw9AO1W9KmjYQQAGAUDlypVbvetkuVFowYIqOHw4Ax06JKNSpbT8rg6dwpKTkxHD0zUoCnBdpGjA9ZCiAddDihbRvi526NBhuarGh4uxJz1vxQA4GPTZQQBlggdU1YkAJgJAfHy8tm/fPs8rd6Latwe+/vprRHMd6dTA9ZCiBddFigZcDykacD2kaFGQ10WejJy3kgGUDfqsLIDDYYYlIiIiIiKiUxyT9Ly1AUAREanv+SwOQIG9aRwRERERERHlHSbpeUhVUwDMAfC4iJQWkQsAdAMwPX9rRkRERERERNGIN47LY/7npL8J4BIA+wAMO95z0kVkD4Ct/0D1TkZF2HPfifIT10OKFlwXKRpwPaRowPWQokW0r4u1VDU2XIBJOp0QEUnI7m6ERP8UrocULbguUjTgekjRgOshRYuCvC7ydHciIiIiIiKiKMEknYiIiIiIiChKMEmnEzUxvytABK6HFD24LlI04HpI0YDrIUWLArsu8pp0IiIiIiIioijBnnQiIiIiIiKiKMEknYiIiIiIiChKMEknIiIiIiIiihJM0omIiIiIiIiiBJN0IiIiIiIioijBJJ2IiIiIiIgoSjBJJyIiIiIiIooSTNKJiIiIiIiIogSTdCIiIiIiIqIowSSdiIiIiIiIKEowSSciIiIiIiKKEkzSiYiIiIiIiKJEvibpIlJeRD4UkRQR2SoifY4x7L0islNEDorImyJSPNJyRKSjiKwXkVQRWSwitTwxEZHRIrLP/xojIuKJPyEia0QkU0RGhalXH/80U0RkroiU98SK++t6yF/3ISexuIiIiIiIiOhfLr970scBSAdQGUBfAK+LSJPggUSkM4BhADoCqA2gLoDHIilHRCoCmANgBIDyABIAvOcZdxCA7gDiADQDcCWAWz3x3wA8AGB+mHo1ATABwA3+aacCGO8ZZBSA+gBqAegA4AERuexYC4SIiIiIiIhOXaKq+TNhkdIA9gNoqqob/J9NB/Cnqg4LGvYdAFtU9WH/+44AZqhqleOVIyKDAPRX1Tae6e4F0EJV14vIMgBTVXWiP34TgFtUtXVQHf4H4DdVHeX57GkAtVW1j/99PQDrAFRQ1cMi8ieAAaq6yB9/AkB9Ve2dO0uRiIiIiIiI/k2K5OO0GwDIchJrv9UA2oUZtgmAj4KGqywiFQDUPE45TfzvAQCqmiIim/yfrw+O+/8P6c3PRhMAyzxlbxKRdAANROR3ANXClN09XEH+xoRBAFC6dOlWjRo1irAK/7y9e4GtW4FmzYCiRfO7NkRERERERAXL8uXL96pqbLhYfibpMQAOBn12EECZCIZ1/i8TQTkxAPYcJx5cdoyIiB7/NINjTTsmqK7B0w3g78mfCADx8fGakJBwnEnnn0mTgEGDgAULgOrV87s2REREREREBYuIbM0ulp/XpCcDKBv0WVkAhyMY1vn/cATl5DReFkByBAn68cpODqpr8HSJiIiIiIiIAuRnkr4BQBERqe/5LA5AYphhE/0x73C7VHVfBOUEjOu/Jr1edvFj1CGc4LLrAigOYIOq7gew4yTKJiIiIiIiolNMviXpqpoCu+v64yJSWkQuANANwPQwg08DcJOINBaR0wEMBzA1wnI+BNBURHqISAkAjwL4WVXXe8oeIiLVRaQagKFO2QAgIkX94xWCNQaUEJHC/vAMAFeJyIX+5P9xAHNU9bCn7OEicrqINAJwi7fsgi6f7jlIRERERET0r5Xfj2C7A0BJALsBzARwu6omikhNEUkWkZoAoKoLAYwBsBjAVv9r5PHK8Y+7B0APAE/B7gJ/HgDv3dUnAPgYwBoAa2GPWpvgiU8CcATAdQAe8f9/g7/sRAC3wZL13bDrze/wjDsSwCZ/fZcAeM4/LwWa+xR5IiIiIiIiyk359gg2yl603zhu8mTglluA7duBGjXyuzZEREREREQFi4gsV9X4cLH87kknIiIiIiIiIj8m6XTCeBIGERERERFR7mKSTjnGa9KJiIiIiIjyBpN0IiIiIiIioijBJJ2IiIiIiIgoSjBJpxPGa9KJiIiIiIhyF5N0yjFek05ERERERJQ3mKQTERERERERRQkm6URERERERERRgkk6nTBek05ERERERJS7mKRTjvGadCIiIiIiorzBJJ2IiIiIiIgoSjBJJyIiIiIiIooSTNLphPGadCIiIiIiotzFJJ1yzLkmnUk6ERERERFR7mKSTjnGJJ2IiIiIiChv5GuSLiLlReRDEUkRka0i0ucYw94rIjtF5KCIvCkixSMtR0Q6ish6EUkVkcUiUssTExEZLSL7/K8xIu79y0Wktn+cVH8ZnTyxh0Uk2fM6IiI+Eanoj08VkfSgYQrn1vLLL0zSiYiIiIiI8kZ+96SPA5AOoDKAvgBeF5EmwQOJSGcAwwB0BFAbQF0Aj0VSjj9hngNgBIDyABIAvOcZdxCA7gDiADQDcCWAWz3xmQBWAqgA4BEAs0UkFgBU9WlVjXFeAEYD+FpV93rGH+MdRlWzcraIog+TdCIiIiIioryRb0m6iJQG0APACFVNVtVvAcwDcEOYwW8EMEVVE1V1P4AnAPSPsJxrACSq6vuqehTAKABxItLIU/YLqvqHqv4J4AVP2Q0AtAQwUlWPqOoHANb4pxc8P+Kf5tsnsVgKBCbpREREREREeSNHSbqItBaRUSKyUER+FpGNIvKd/7TuASJyeg6KawAgS1U3eD5bDSCkJ93/2eqg4SqLSIUIygkYV1VTAGzKLh5m3N9V9XAEdbwQ1pP/QdDnd4hIkogsF5GQ5N4hIoNEJEFEEvbs2ZPdYFHBvRiAiIiIiIiIclNESbqI3CgiawAsAzAYQCkAGwH8AGA/gPMATAbwpz9hrxNBsTEADgZ9dhBAmQiGdf4vE0E5OY0fBBDj7xnPSR1vBDBbVZM9n40FUB9AJdjp9lNF5IIw40JVJ6pqvKrGx8bGhhsk6rAnnYiIiIiIKHcVOd4AIrIalmROA9APwCrV0PRMRE6DXc/dF0CiiAxQ1feCh/NIBlA26LOyAA5HMKzz/+EIyslpvCyAZFVVEYmojiJSEkAvAN28n6vqCs/bBSIyA3b6/f+hAOPp7kRERERERHkjkp70twDUUdUHVXVluAQdAFT1oKrOUNXLAZwP4MBxyt0AoIiI1Pd8FgcgMcywif6Yd7hdqrovgnICxvVfw14vu3iYceuKSJls4o5rACQB+DpM3b0UQIE/WZxJOhERERERUd44bpKuqi/7b7gWMVVdraqfHWeYFNhd1x8XkdL+08C7AZgeZvBpAG4Skcb+696HA5gaYTkfAmgqIj1EpASARwH8rKrrPWUPEZHqIlINwFBP2RsArAIwUkRKiMjVsDvAB193fiOAacENGCLSU0RiRKSQiFwK4HrYTe0KNCbpREREREREeSNX7u4uIpeLyBUnMOodAEoC2A171NntqpooIjX9zxSvCQCquhDAGACLAWz1v0Yerxz/uHtgd2N/Cu718709404A8DHsru1rAcz3f+boDSDeP+6zAHr6y3TmvTqAi2HJfrB7APwJO6vgOQC3qOrXkS+e6MQknYiIiIiIKG9INmevR16AyHjYs8sbqOqZ/ueT11PVAt9jnF/i4+M1ISEhv6uRrVmzgGuvBdauBZqEu889ERERERERZUtElqtqfLhYbvSkt/Nfh+7cTG0jgIdzoVyKUnwEGxERERERUd7IjSR9v/eNqqYDKJYL5VKU4+nuREREREREuSs3kvSVItIFdudy5+7p4Z4jTv8SvCadiIiIiIgobxz3OekReAh2s7Y6IvI8gE6wm6/RvxSTdCIiIiIiorxx3J50EfnYuct6OKqarKpXwR579heApwHcm3tVpGjDJJ2IiIiIiChvRNKTfgWAJwBsO9ZAqvoNgG9yo1IU3ZikExERERER5Y1ceU46nVqYpBMREREREeUNJumUY3wEGxERERERUd6INEnvICKNRJiekYs96URERERERLkr0ru7P+1/HRWRtQBWA1jl/7taVZPzqH4UhXi6OxERERERUd6INEm/G4AAaA4gDsD1AG6G+2z0zbCkfZWqPpkH9aQowiSdiIiIiIgob0SapP+kqj86b0SkEIBGcJP25gDaArgaAJP0fzkm6URERERERHkj0iQ9gKr6APzif73jfC4ilXOpXhTFmKQTERERERHljVy9u7uq7srN8ig6MUknIiIiIiLKG5H0pJ8FYGdeV4QKDt7jn4iIiIiIKG8cN0lX1V//iYpQwcOedCIiIiIiotx13NPdReQjEWkRaYEiUkJEhojIbSdXNYpWPN2diIiIiIgob0RyTfo2AN+LyA8icreItBSRgB54EakmIt1FZAqAHQAGAlhxvIJFpLyIfCgiKSKyVUT6HGPYe0Vkp4gcFJE3RaR4pOWISEcRWS8iqSKyWERqeWIiIqNFZJ//NUbEPaFbRGr7x0n1l9HJE2svIj4RSfa8bvTEi/vreshf9yHHWyYFAZN0IiIiIiKivHHcJF1V7wLQGMCPAEYB+AnAURFJEpEdInIUwHYAcwA0ATAYQDPvI9uOYRyAdACVAfQF8LqINAkeSEQ6AxgGoCOA2gDqAngsknJEpKK/biMAlAeQAOA9z7iDAHSHPUquGYArAdzqic8EsBJABQCPAJgtIrGe+F+qGuN5ve2JjQJQH0AtAB0APCAil0WwXKIak3QiIiIiIqK8EdHd3VV1kz9ZrwLgYgAPA5gG4CMALwDoD6COqrZW1bf9j2g7JhEpDaAHgBGqmqyq3wKYB+CGMIPfCGCKqiaq6n4AT/inGUk51wBIVNX3VfUoLHGOE5FGnrJfUNU/VPVPz/xARBoAaAlgpKoeUdUPAKzxTy8S/QA8oar7VXUdgElO2QUZk3QiIiIiIqK8kaPnpKtqOoAl/tfJagAgS1U3eD5bDaBdmGGbwBoEvMNVFpEKAGoep5wm/vcAAFVNEZFN/s/XB8f9/zfxjPu7qh7OJg4AlURkF4BUAHMBDPdP43QA1cKU3T3M/EFEBsF69VGzZs1wg0QNJulERERERER5I1efk55DMQAOBn12EECZCIZ1/i8TQTk5jR8EEOO/Lv14464H0BxAVdgZBq0AvOgp11vX4HEDqOpEVY1X1fjY2Nhwg0QNJulERERERER5I0c96QDgvzHadbAe7BJBYVXVehEWlQygbNBnZQEcjmBY5//DEZST03hZAMmqqiJyzHFVdSfcZ8hvFpEHAMyHXdOe7Bn+6HHmr0Dhc9KJiIiIiIjyRo560kVkBIC3YKdxr4J76rvz+iYHxW0AUERE6ns+iwOQGGbYRH/MO9wuVd0XQTkB4/qvYa+XXTzMuHVFpEw28WAKQADAf+38jmOUXeCxJ52IiIiIiCh35bQn/SYAr6jqvSc7Yf9123MAPC4iN8NOG+8GoE2YwacBmCoiM2CJ73AAUyMs50MAz4lID1gv96MAflbV9Z6yh4jIAliSPRTAq/6yN4jIKgAjRWQ4gC6wO8D3AOwRbAB+h93dvgaAZxF47fw0AMNFJAF25/lbAAw4oQUWRXi6OxERERERUd7I6TXpFQB8nIvTvwNASQC7YY86u11VE0Wkpv+Z4zUBQFUXAhgDYDGArf7XyOOV4x93DyypfgrAfgDnAejtGXeCf57WAFgLS+QneOK9AcT7x30WQE9/mYDd+f07ACkAlvnHv9sz7kgAm/z1XQLgOf+8FGhM0omIiIiIiPKGaA4yLRH5BMCXqvpS3lWJ4uPjNSEhIb+rka0lS4D27YEvvwQuvji/a0NERERERFSwiMhyVY0PF8vp6e6DAcwRkX0AFgBICh4gkmekU8HGnnQiIiIiIqK8kdMk3XkW+VvZxPUEyqQChkk6ERERERFR3shpQv04LBGnUxgfwUZERERERJQ3cpSkq+qoPKoHFUDsSSciIiIiIspdOb27OxFPdyciIiIiIsojTNIpx5ikExERERER5Y3jJukikiUi5/r/9/nfZ/fKzPsqU35jkk5ERERERJQ3Irkm/XEAf3j+Z2p2imOSTkRERERElDeOm6Sr6mOe/0flaW2oQGCSTkRERERElDdO6JnmInIGgDMAlAiOqepXJ1spim58BBsREREREVHeyFGSLiJ1AcwAcK7zkf+v+v9XAIVzrXYU1diTTkRERERElLty2pM+GUBNAIMBrAeQnus1oqjH092JiIiIiIjyRk6T9HMA9FfVD/KiMlQwMEknIiIiIiLKGzl9TvofYO/5KY9JOhERERERUd7IaZL+NIAHRaR0XlSGCoZ/OkmfNQuIjQWqVQNef52NA0RERERE9O+Vo9PdVXW6iDQCsEVEvgewP3QQvTHXakdR6Z9M0n/7DejXD2jaFChTBrjjDiAtDRg8OHC4zz8Hvv/ehq1VK+/rRURERERElBdy1JMuIv0BPASgHICWAC4M88pJeeVF5EMRSRGRrSLS5xjD3isiO0XkoIi8KSLFIy1HRDqKyHoRSRWRxSJSyxMTERktIvv8rzEi7kPGRKS2f5xUfxmdPLErRORbETngr9skESnjiU8VkXQRSfa8Cvzd73P7EWwZGZZkf/GF/e/14ovWGDBvHvDll0DLlsDs2YHDjB0LXHop8OijQPPmwKJFgfH0dGDoUKBmTWDYMODIkdytPxERERERUW7J6enujwH4EECsqlZX1TpBr7o5LG8c7Br3ygD6AnhdRJoEDyQinQEMA9ARQG0Adf11OW45IlIRwBwAIwCUB5AA4D3PuIMAdAcQB6AZgCsB3OqJzwSwEkAFAI8AmC0isf7YaQCeBFANwFkAagB4Lqj6Y1Q1xvPKimTBFAS50ZN+6BDQrp0l2ZdcArRoAWzaZLHMTODdd4FevexU90KFgCpVrCfdsXIlMGQI0K0bkJgInH46cNddbtznA3r2tGS/alVg9Gh7H+yPP4CPPrL6EBERERER5ZecJukVAIxX1QMnO2H/de09AIxQ1WRV/RbAPAA3hBn8RgBTVDVRVfcDeAJA/wjLuQZAoqq+r6pHAYwCEOc/bd8p+wVV/UNV/wTwgqfsBrAzBkaq6hH/Xe3X+KcHVX1HVReqaqq/XpMAXHCyyyba5ebp7sOGAT/8AEyZArz3niXar71mse+/B/bvtwTcUaIEcPSo+/7JJ4HTTgPeegto3Bi46ipg9243Pn068PHHwEsv2XRuvx1YsADI8jSVfPopUL8+0L07EB8PrF9/8vNFRERERER0InKapH8L6zHODQ0AZKnqBs9nqwGE9KT7P1sdNFxlEakQQTkB46pqCoBN2cXDjPu7qh6OoI4AcBGAxKDP7hCRJBFZLiI9shmvQMmtJH3nTmDyZODWW4GBA4H//AeoXBlITbX4okXWe37JJe443iT9r7+s9/umm6wHHQDKlQMOHrQe9PR0YNQooFUr4J57LF6vnv1NSbG/O3YAvXsDjRoB77wDHDgAdOhg4zqSkqxutWoBnTvbdfJERERERER5IafPSb8HwCwR2Q9gIUJvHAdV9UVYVgyAg0GfHQRQJoJhnf/LRFBODIA9x4kHlx3jvy49u7KrB1dQRC6B9cqf5/l4LICh/nEuBfCeiOxU1f8LM/4g2Kn3qFmzZnA4quRWkv6//9k16N6bwBUt6l6XnpBgvePlyrlxb5L+5pvWIz5okBsvV87qdfgwMGcOsGULMH68W+eYGPubnAyULQs88ICVN2uW9aYfOGA3p/vrL6B2bUv2+/a16+GvuQZYuNCS/s2bgfLl3elu2QKsWmWNDOeff3LLhYiIiIiITl057UlfB+BsANMA7AaQEfTKyTPUkwGUDfqsLIDDEQzr/H84gnJyGi8LIFlVNdI6ikhrAO8A6Ont0VfVFaq6T1UzVXUBgBmw0+9DqOpEVY1X1fjY2Nhwg0SN3ErSP/0UOPtsoEED9zMnSVcFli+3hNjLSdKzsqwXvmNH4Mwz3XilSvZ3+XLgmWfsGvfLLnPjTpJ+6BDwzTfWUHD//ZagA3btOwDs22d/X33VEvOXX7br46dOtXE3bnTL/OQTm4errwbatAEGDLDr6cNJTs7RIiIiIiIiolNMTnvSHweQWw/e2gCgiIjUV1Un5YlD6Oni8H8WB2CWZ7hdqrpPRI4ep5xEWA83gL+vYa8XFI8D8GM249YVkTKeU97jYAm5U14L2DXwA1X1y+PMswLI5Xuj//NyI0lPTQWWLnVPQ3c4Sfpff9m15cFJerVqlkC//jqwdSswZkxg/KqrrDe7Y0d7v2BB4N3oz/JfrDFtmp0qX7Mm8PDDbrxiRfu7bZvV5YEHrMzbb7fPq1a1v3v32t8VK4AePYAmTYAJE4CZMy2h793bTo0HrDGgTx/r3T90yOZpwQK3QQGwZZmWZr3xLVsCxYpFviyJiIiIiOjfI6fPSR+VWxNW1RQRmQPgcRG5GUBzAN0AtAkz+DQAU0VkBoAdAIYDmBphOR8CeM5/Pfh8AI8C+FlV13vKHiIiC2BJ9FAAr/rL3iAiqwCMFJHhALrA7gDfAwBEpCnstP+7VPXj4EqLSE9/PBVAJwDXA7jqBBZXVMmNR7CtXm3J+IVBD+1zkvQVK+x9y5aB8euuA55+2u7g3qCB3ezNq2xZS4Afe8zuGN+lS2C8RQs7bf2ZZ+z9p58CpUq58Vat7A7yDz5oveHly9tN7Zx5dk5y2LnTEu5rr7Vk+4svgAoVbPiXXwZ27bLhNm+26ZUuDdxwg13rPmmS3czuppvcZXHZZZb4Z2ZaQ8GiRVZXx8aN1gv/009WRs+eVs9gR45Ygl+4wD/oj4iIiIjo1JTT091z2x0ASsJOnZ8J4HZVTRSRmv5nitcEAFVdCGAMgMUAtvpfI49Xjn/cPbCk+inYNfTnAejtGXcCgI9hd21fC0vkJ3jivQHE+8d9FnZKu3ON+1AAsQCmeJ6D7j0T4B4AfwI4AHs02y2q+vUJLKeodDI96dkl4U6Svny5JcbNmwfG69a108/vusuenR6ux7llS+slv/PO0JgIMGOGXaf+xReBp8IDdjr9O+8Ae/bY9emzZ7uJOQCccYa9xoyxm8n9/rsNX6GCxStXtr+//mo959262an5n39ud60fP94S6M2bbbg//7Se+pQUu4Heq6/aHe3nzHGn+fzz1iDRsqUNc9ddgWcQ7N5t89G1q91Ar2xZe+Sc19q1tkyeeQa44go7E8HrwAFL8FessMsIVq9GCFWblyVLrLEgOxkZgXfPD5aZ6d64j4goO6mp2V86FIldu+yMq2M5ciT72Lp1wNy52cdVrQE1u33hmjXAyJHuzVDDjb9ggd2cNLvxb7nFfSxpuPFfew347rvw8S1b7DKsTz7Jfh7eeAMYNy587NAha1x+9dXspz96NNCvn3svGS+fzy4nGzw4+2X04ov2GFbvU1m8Zs+2p8B4H73qNWeONfavWRM+/vvv1nCe3aVmq1bZvnPx4vBxZ5+Xns3FnIcPA/feaw3r2TneOvzRR3bG3Yk6cMC+a6KC4nj5w8nGMzJs+1PgqSpfUfZq1aqVRrNfflEFVGfOPPEyBg5UjY1V9fkCPz/nHNXLLlPt2lW1UaOTq+fJOHrUXuEsWaJaurQtg5dfDo1feaVqsWKqTZuqFi6s+tlngfHatW3+9u9XjYtTjYlRXbnSjdesqXrDDfb/7Nk2nSuvtP9XrVKtW1f1uussnpxsywxQrVRJ9dJLVc84w/46Xn/d4t5XkyZufN061QoV3HkCVKtXD1wW99xj9XbiRYuqHjniDvPii6q33qr6n/9YPDZW9eBBN75+veqDD9p0CxVSLVJEde1aN75pk+q0aaqrV6v27at6/vmqv/3mxn0+1aVLVW++2abRsKHqwoVuPCvLxvX5VKdPt+WzdGngcj94UPWpp1T/+1/Vq65S/fDDwPjhwzb+r79aXefM0RBff606darqiBGqEycGxpx1eedO1WefVX3jjdDxk5JUV6yweX355dD1X1U1I0N1xgzVF15QTUsLjft8qgkJVv7hw6FxVdXvv1d99VWrSzhJSTaNbdvCx//8U3XSJPuth5Oerjpvns1LONu3q86apfp//xc+7vOpLlumOn9++Hhyso3/6afh46q23s6aFf53mpam+v77qnPnBq6nXjt22DL8/ffw9Zs1S/Wdd1T37Ak//s6dquPGqX71Vei4qjb9yZNt3Q4nKcnGHz8+8POsLKvz/PmqI0eq/vhj+PFTUuw7Hjo08LfmzNuXX9pv6aOPVDMzQ8dPTbXfw6232nbFa9Mm1UWLVFuyuoEzAAAgAElEQVS2tPUwuHynng8/rHr99aH7gt9/t+1Vgwaqd98dfhn4fBbr1MnK8Tp0SPWll2ybFhdn29xw0x8zRrVePdWePQPrmJGh+sorqiVL2jZ40iT7zOuPP1Qfe8y2R+3aha7Lr79u23FAdcAA1d27A+MbNqjedZfF69e3dcXrgw9Uixe3+Lnnqi5fHhj/9VfVQYMsXrKk6qOPBsYTE1XLlLF41ar2e/Xas0f16qvdbfJ11wX+FlJTA7fZDz5ov1tHerotNyfesWPob6FvXzferZvNs9c997jxBg1Cv6c33nDjVauqLlgQGH/rLTd++um2TfFavz5wv3X//YHxLVvs+wVsWT3zTGDc51M96yx3/C5dAteTrCzbnzrx++6z35XXI4+48XPOUf3uu8D4f//rxm+5RXXz5sD4hg1Wt6JFbfzXXguML13qjt+3r+o33wTGMzNtPbnwQtW2bW0Yr9RU2+c768D06Rri++/t99S3r+rZZ9vvy+vxx21dGTFC9cknQ7cXGRm2rIcMUa1Rw8rz2rxZ9c47bZv58MP22wpn+nTVOnVsu+fl86l++639Rh55JPzvXdXiTZuGLgOnjKNHVZ94IrR8x4EDtu9v0iT8vjUjQ3XsWDvO8P5WHFlZto5UqZL9vnHePNUrrgg8fvEaO9Z+C+G+J1U7junSxbYf4Xz1lR0b33ln+Pj69TaPQ4aEzpuq6saNqhdfbNMIJynJtgstWwZuTw4ftve7dtn8VaoU+D1nZNh3kJpq28WmTQOP8ZxxMzPtd1K6tOonn7jxzExbL30+1eHDbdv5yiuB8R9+sPh996mWKmXrq9e6dfb3hRdURey4uSAAkKDZ5IP5npDyVfCS9HXrbM0JPijJzuTJtmPo2tX9EXXsaIlYsDZtLFazppuIRqOkJNWtW8PH9u2zjUOdOuEbMoYMseVXtqztuL3JpqrNf2yse5DZunVgotG6te1kdu60jWWhQnYg7rj8ctvAqqp+/LHFO3e2pGjTJtvhx8ZafPNmS8iLF1e95ho76BowwA58fD7bKTmJ98UX247hggvsvTP/L7wQeCBVrpz9dQ78f/zRPdg880xLsAFLYpw61KkTWAZgB9aqtnG/8kr38xIl9O8DKlWr45136t8Has5wN93kLpNp00LLv+giN/7hh3ZAftZZqqedZvGGDd34xo2qzZoFjl+smJuQ/fGHauPGqvHxqpUru8McOODOw513ugeUzuvnny2ekWENV82bq7Zv78a9SerUqXag5h3f21AwdarV8Y473PjIkW48IUG1e3fVVq1sBwao9u/vxleutNhDD9kO2PnOHfv22c71uuvcg8J69dz4/v3WwNavn3vgGxNj34+qLatXXrGDuEsucevo3dGPHq3aoYO7jgF20OL49FPVYcNsvpy4dzs0c6bVyVu+dxmtXGkH1bNnq1asqH8fWDu2b7cDoIsucse/8UY3npFhieHMmfa7CV4GGRn2+6ta1R2/fn03nplpy/eVVwLncccOdxn16WONWE5MJLCxZfp01dtuU+3d2x3mvffc+OTJoev63LlufMsW+0137uzGb7vNja9aFTh9wBoCHAcP2jbKu542buzG09LcZeNNbrz69VOtVStwmH373LizzXFehQsHNkg99ljob+njj934hAmhy2DRIjf+8ceh8QcfdOOrV7vbqxYt7P/hw934jh22bfaOf+GFgd9zpUq2Hb7/fou3bRu4DM491z4vXtzWoaJFA5OjW2+1aTz3nDsN737ASZCvvNL2l0BgQ4DTOPvMM24D7OLFbvyDD9zvvksX+3/s2MB5LFpU9dprbbsEBDYk/PWXfdavnzuPvXu78YwM2x41buyua95llJ5u892qlerTT1u8Th03npVlv72iRQPXNSfZ8PncRpLhw924tzFl1iz7zNmeAdbQ6hg7Vv9ObsOtR+vXuw0tzuvxx934smX2WdOm7m9m2DA3npys2qNH4PidOrnxzZttGTi/c8AajBz797vHC96Xs03du9d+i8FxZz3y+Ww/G/xb+eEHi2dmWkNd8PjLlrl1mD8/cPkDtk463n7b3ec7rzFj3PjixdYY56yjgB0LOr77zo4FveNffrkbT0xUHTzYEjInftppbnzNGtVevVSrVQssw9k3JyVZ0v3557Z/cuJOg9Phw9bQOGBA4PjOb8nns9/i5MlupwlgDUyOkSNtv/bgg278xRfd+FNP2XqwYoUbv/lmNz51qv2O161z56NHDzf+ySfWCPbbb+5y9O53li61/daaNXYMAtjxiWPjRuuIeestW1ZOHZzjk6QkK3fcuMCGt8REi2dk2Da9c2f3tw64jW4+n+23L7vMGqGcuLcB2jmGe/ddN/7II2586FD3WNaJX3tt4DIErLHJibdv78ad7dnLL7vr++mna4HAJL2AvaI9SXdat4Nb9sOZM8eGbdlStXx527j+8osd+IRr5Wrf3nbqgB2w/xtlZlpi27NnaC+cqm3InYP8pk1De0MnTXJ36IAdjHk5By7XXWcJbXx84AGuc9DXtatteE8/PTARcpLuTz6xBCZ4pzx/vn12xx2qDzxg//fqZa2gSUnWCg7Yd5+QYOXXqWM7EFWbH8B2isuW2c6hXDmb7rRplrgCdiCemupu3IcNs4OSrCwbp1Mnizt1bNJE9fbbbefYrJnbUuwsr2bNbHo7dtiyr1HDdj7z59uBYNmydoB0zTU2zbJlbfy1a+37KFbM6vTpp27vye7dVp7T8FC5su08b7jB3q9daz0zzkFqu3aWoDk783nzbH1whncO1pwDuwkTbAf4zDP2vmRJO6B46CF3majaTt57gNGihe3wnCR8yRK3ASMuzk1incRh1Sr7fXoPgho0sO/O57PvLC7OYqVKWfJStqz+fdCclOQeHDjz4PRgbdliwzi9hs4rJsb+Llpky2Do0MC4czDhJOHvvBMYd5I8p7FmxozAg9FOnQLjK1fa/DhxJ3Fp2dIShhUrAnseGze29bZNGxs/JcUaxbx1qF/fpvnbb7aMOnRwY3Xr2gF04cJuL8PNNweO37Wr+xs+etSSEu/4Ti+ec9A8Y0bg+H362Pd8zTU2D+PGuclC69Z2EOUcuKjad9GkiTt+z57WIFGrlq3L33zjLqPu3e23WLWqDecsg6uucsdv08YSpMKF7ayJbdvc9WDAANtX9OljB4iqtgzGjHHHj4uz7YxzUJuS4v6ee/Wy9WrKFHvv9Fx98ok7j+3a2TQLF7YEMTPT7b1t1sy2FVu3ur8lVevBdg6Eb7/dDlTj4my5pKaqfvGFxYoUcbe9NWu6vXcHDrgNLK++anW+9VZbn7dvt2Vcv77FZ82ycQYOtERR1b4npyFt1ChbJm++ae+/+cbq0L+/ve/Xz8ZxDmxXrbLhx42z9//5j8WXL7f3b7xh8WefdbdHPp+7z3Z675xteLVqtsyysmz7dscd7vbC+Y6cs7wqV7b5ULX9hZO8Otv1tm2t4cFZzxo0CNyP9+5tjXvB25OXXrL4fffZMs/MtOTWOUugQweLO40Oq1fbMnJ+K05jq5NALV9u0xg92p2HgwfdhpcnnrBp3HuvG09OtsZCwE0sPvzQjc+da+tf1ao2veRka/xz4p99Zg0oZ51lvxtVG97ZRvXqZdv6bt1s27pihSWNzvg332zraffutl9StV5Hby//Cy+4CfuLL1oZjRoFfk+33Wb/b9tmjWWDB7vxCy+0ZBmwJHj5cpueE3/+eXc/9L//uY2q3u3NZZfZMqhd234n3oTt3HPdxh4nAV28OHD8EiUsIS9e3H7X48eHbk9jYuz3lplp65a3gcWZDmDHHh984DaqB7/WrrWGpOBGDGe97NLFOkhatw6MOw0Oo0fbb91Zps6rUiWrf9Om9h0OHBg6bRE7m3HTptBOjEKFbFtTvrzV/8knw9e/cmVrTJk+PTTmdGqMH2/7BG/nhDMuYEn5woWB+zVn3wJYQr5okc2LN16jhv29/no7I6tNm8C4s42//HLbZnXrFhhv1Mi+x6ZNrdHLux4C1klUvboNt3hx4NkqgG2LLrrI9tETJthxV/DybdfOpvHJJ6HHP4DbiP3AA6FnjkQbJukF7BXtSfqvv+rfG/JjycqyhCUuzg5MfvpJ/z6QqFXLPQDx8p5el90pT6eC5GTbiYY7JUvVeqdHjgyf5Ccl2bI97TRLKoJP00xLs41i5cqWoHhPtVe1HaN3x/fww4GnZaelBX5PAwYEnkq6Y4d7ACdi37X3NEqfL7AXsGLF0FNBndZi52A6uCHC6TnPro5Ogteqlf3t3NkO7BwvvuhOW8R6ipKS3PjLL1u8dWvbAVapEnjqlnOAVbmy7WxLlQo8vd5Z1+vXt1ehQnZQ4ti1yxoGypVzG6WeeMJimZm2jEuXtp2Zc5DRp0/gKXhnnWXJidPre8kl7sFmZqZ9XqKEfVfFi9sOcft2d3wnaW7b1qZVo4Ylm+vWWWOIcwDVt6/t5EuVCrx0w0kczjzTdrjFitkOef1620Y4B/rdurnz8PDDdprurl1WzxIlbEfrHGzecYf1Lv34ox30ith83H23u2P+5RdbZ5OT3WTJaRBo184OjL77zpZVw4Z2Fs9LL9n3dMYZVq+PP7beBWc9qFrVvo8aNWzcxESbfv/+9h1Nm2YHJiKWZM6daw1QP/9svxVnPpyDz7Q0S7qdA/kpU9yk4qGHrLdg9mybRtu2GnBw6CRuPp+tc4Alwi+9ZN93hw52YPTOOzaPzkGe0+hxxRXuKb0+n82Xc3lHlSpW3zlzLGlISbHTTIsXd3uG69Wz9dfRvr0d1C1ZYr8HEUtOExJs/L17LV64sK0DpUtb0un8Hp0Gps8/t7NbAPt97t9v242sLLfxw5mHwYPd046d04FHjrQD50KFbJ/iPZPJOYhzlmGHDpYoOr+nwoVtGUybZo0QFSsG9qg6PesVKtjfhg0DT81u187Wjffes3WtSJHAXud162y+y5Wz30mpUtYQ52wXnYTx1VetLMASGadn3OnJKl3abaDt1s09y8RZD3r0cHt927d3T6nNzLSzFYoWdX8LtWq5Zw8kJ9t306SJfQcitt3x7j+cbfp559kyLlvWergdl1xi63nv3rauVKli37Pj8cdt/DZt3LPEevVye+uchoWWLW27VqiQJYXOAbSTZLdq5SYVsbFur++mTbYtLlfOXUYdO9q2RtW2CyK2vXUSOcA9vTwry224cxokzzzTvewpI8PqXbFi4FkmV1/tbncnTbLPnMbAOnVsvXR6rp3LB7p0cc/4atjQ7bXdsMGWmzcZGjjQbQxyfssXXWTzXrSo7WOcY6309MCzysqXt0T7yy8t7iTFdeoEJvjes4XGjnUbuYoVs2Xo9HynpNhnRYu62+RixWzdcuq4bFngmUIdO1ojlbP/dNZvZ/oVKtjwc+bY2TI7dwb2nJ97rrtN865HMTG2jlSsaN/p3Xfb7yA9PbCx88wzbXk/+aTtV777zo2JWP1r1rTh7rnHjofGjnWPUcqVs/Wwa1f7zW/bZsN6jy86drTvqls32w4uWOBua5xG0ubNrQ5LloSe/XDxxbYMmja19TExMXAa11xjDett2tj28qOP3G2hs4w6drTvu0cPW4bOcgasQXLAAPfSn19+sd+Zdz174AFbHg0b2vGY98yBSpVs+ZYr51764+1Rj4mxfbNzLLRsmW3TnPWoaFHrHDr9dJvWzJm2f3F+Z4UK2Xpev767/5g3L7BxoXdvm3ahQtZgv2VLYMP/5Ze7+48BA+w41Xs2VosWbrxTJ9u2Ou+Pl6vkNybpBewV7Un6hg225mR3TY3DSWScnrBdu+y9c0DlPYXSMXOm/r1zDndNEP0zDhyw0+ScA6RwNm92D5CC/fKLJRYjRoS/Ltq5Bu3NN229CLZunfVWX311+OuWfT47sL7//vDxHTusp+SCC6wOweuSz2cHDTfcYPHga7uPHLHTq+LjbQca7tKG+fOtfj17Bp6J4Jg61ZKac84Jf231//2fjdu2rSUPwb76yg5e6tSxBN45xdGxcaPt+Fq2tB51byOEqn0HV15pBzm9eoVeW33woJ2+es45duAffH364cO24yxd2hLd4OsQfT77vXbqZL0GwdefZ2XZb7xMGTv4DW5ocerYr58lHOGWwejRNq6IJbnB85iSYgdGnTrZMgpu1Jo61e3xj4sLf53gJ5/Ygc8994Sui4sXuwca5coFnjbu2LbNemQHDAhsyFG1Aw3ngFbEfhPB9yFIS7Oez+uvD7305ehRt8cRsOUcrlfgww9t+UycGHo9qbe3rE6d0DqqWg/trbfatjm4fG+PZOnS4a+V3LXLfov33BN6XfOPP7rXdotYI0Xwunz0qE1n4MDQxtmDBwN7grp1C/29+nx22u3111vvUXD53tOZmzULf438okW2vo8aFVr+tGnuAWnVqoGnjTtWrrSGtJtvDl0G3tNUy5SxugbbvNkahbp1c5MuR1aWbatELLkYMSJ0HvfutQPpDh3cHnWvWbOskapoUatj8LXXKSl2IH/eedarHXwfgj/+sG1hpUr2e3Eu0XBkZNhvsUUL6+HfuDEw7pwBEB9vDSbOpT7e+IQJtj1r1y58A/SaNbaMu3UL/x3MmWMJYPPm4ZfB0aPWY3z99bZ/C44vXWq9xQ0aWCNLuPtZLF1qSdiUKaH3Odiwwda1s86y7Vq4a7N377bGwddfD13P9u+3ZOnccy1pDG5AV7Xvfe5cGz+4Ad7ns/lr3962Fd5T971++cXqH+538NlnNg+dO1ujRPB6pmoJ+bvvhr8nyebNtn726GHbteTk0GEyMmxbt3hx+O3hjBnWg/3oo9nfE2T5ckuWw31HP/9s25Phw0PXQ8fWrZYo7t0bGktOtjo89pg1RoaTlGTLN7trz9ets8b+L78Mf++ZtDRbBj/+GD6+d68ll/PmBV7i4XCOob74InQ9VLX9wOLFtm9wfuvB+4aff7YGgXD3HFG19eOjj9xLkY4cCVwftm+3xjWn8T94Pg4dsjzAObZISwvcvxw4YL9Z59JIny9wH+7cf2f9evf9rl3udI4cseXz5ZduvYLXt+XLw6/D0eRYSbpYnKJJfHy8JiQk5Hc1svXbb0D9+sD06cD112c/3D332OPGkpLsrulJSXYX9K5d7c7s8+cDl18eOI6qxerVA5o2zdv5IKK8l5kJFCpkrxORlmavsmVPbPwjR+yRibVqnVgdjhwBNmwAzjzTHqWYU+np9rSK6tWBmjVzPn5WFvDDD/bki/j4nD8C0+ezpzYkJdldsEuWzHkdfvnFlsH557tPsMiJv/6yeWjcGGjYMOfjp6QAy5YBp50GnHNOzpeBqi2DI0eA1q2BIjl6+KzZtcvuoH322YGP7YxUVpbtO6tXB2Jicj4+YHdbL1LkxKYPuH17J/pbJCKi3CUiy1U1PmyMSXr0KShJ+rRp9niW7Jx9NlC1qvtokkOH3IOsn34CEhPtoI2IiIiIiOhUcqwkne2plGNOL8ax2neSkuzZ3O3bu585vRd//WV/K1XKk+oREREREREVWEzSKcciSdJXrrS/55zjfuYk6Tt22Ol25cvnTf2IiIiIiIgKKibplGM5SdJbtHA/c5J0nw+oWJHXxREREREREQVjmkQ5FkmSvmoVUKOGJeOOQoXccXmqOxERERERUSgm6ZRjRYva38zM7IdZvRpo3jz088KF7S+TdCIiIiIiolBM0inHnCQ9PT37YfbvD/+oHueU99jY3K8XERERERFRQccknXLMSdIzMrIfJjMz/LNomaQTERERERFlj0k65VixYvb3eEm6c2q7l89nf8P1shMREREREZ3qmKRTjp1MT3pqqv3lNelEREREREShmKRTjkVyTXp2SbqDSToREREREVEoJumUYyKWgB+rJz0ri0k6ERERERFRTuVrki4i5UXkQxFJEZGtItLnGMPeKyI7ReSgiLwpIsUjLUdEOorIehFJFZHFIlLLExMRGS0i+/yvMSLO07wBEantHyfVX0anoLL7+KeZIiJzRaS8J1bcX9dD/roPOdllFi2KFj2x090dVarkfp2IiIiIiIgKuvzuSR8HIB1AZQB9AbwuIk2CBxKRzgCGAegIoDaAugAei6QcEakIYA6AEQDKA0gA8J5n3EEAugOIA9AMwJUAbvXEZwJYCaACgEcAzBaRWH/ZTQBMAHCDf9qpAMZ7xh0FoD6AWgA6AHhARC6LbNFEt2LFgLS08DHV4yfptWplHyMiIiIiIjpVHSONylsiUhpADwBNVTUZwLciMg+W8A4LGvxGAFNUNdE/7hMAZgAYFkE51wBIVNX3/eOOArBXRBqp6np/2S+o6h/++AsAbgHwhog0ANASwKWqegTAByIy2D+9N2ANAh+r6jf+cUcAWCciZVT1MIB+AAao6n4A+0VkEoD+ABbm3pLMH9WqAZMnA8nJoTEneS9RIjR2113Apk3h7/xORERERER0qsu3JB1AAwBZqrrB89lqAO3CDNsEwEdBw1UWkQoAah6nnCb+9wAAVU0RkU3+z9cHx/3/N/GM+7s/4c4uvsxT9iYRSQfQQER+B1AtTNndw8wfRGQQrFcfAJJF5Ndww0WRigD2vvlm9gM8/LC9wnEvKCA6KRUB7M3vShCB6yJFB66HFA24HlK0iPZ1Mdtzi/MzSY8BcDDos4MAykQwrPN/mQjKiQGw5zjx4LJj/NelZ1d29QjmISaorsHTDaCqEwFMDBeLRiKSoKrx+V0POrVxPaRowXWRogHXQ4oGXA8pWhTkdTE/r0lPBlA26LOyAA5HMKzz/+EIyslpvCyAZFXVkyw72fM+3LhEREREREREAfIzSd8AoIiI1Pd8FgcgMcywif6Yd7hdqrovgnICxvVfw14vu3iYceuKSJljxL1l1wVQHMAG/3XoO45RNhEREREREVGAfEvSVTUFdtf1x0WktIhcAKAbgOlhBp8G4CYRaSwipwMYDmBqhOV8CKCpiPQQkRIAHgXws/+mcU7ZQ0SkuohUAzDUU/YGAKsAjBSREiJyNewO8B/4x50B4CoRudCf/D8OYI7nGvZpAIaLyOki0gh2Q7qpJ7HYokmBOTWf/tW4HlK04LpI0YDrIUUDrocULQrsuih2Vnc+TdyeKf4mgEsA7AMwTFXfEZGaAH4B0FhVt/mHHQLgQQAlYUnybaqadqxyPNPpBOA12MX5PwDor6pb/DEBMBrAzf7BJwN40H+6O0SkNiyxPg/ANgB3quoXnrL7AHgW9oi2L2B3c0/yx4oDeB1ATwBHAIxW1RdPfskRERERERHRv1G+JulERERERERE5MrPa9KJiIiIiIiIyINJOhEREREREVGUYJJOREREREREFCWYpBMRERERERFFCSbpRERERERERFGCSToRERERERFRlGCSTkRERERERBQlmKQTERERERERRQkm6URERERERERRgkk6ERERERERUZRgkk5EREREREQUJZikExEREREREUUJJulEREREREREUYJJOhEREREREVGUKJLfFTgViEhtAOMBnA8gDcBsAINVNTPc8BUrVtTatWv/U9UjIiIiIiKif9Dy5cv3qmpsuBiT9H/GeAC7AVQFUA7A5wDuADA23MC1a9dGQkLCP1c7IiIiIiIi+seIyNbsYjzd/Z9RB8AsVT2qqjsBLATQJJ/rRERERERERFGGSfo/4xUAvUWklIhUB9AFlqgTERERERER/Y1J+j9jCazn/BCAPwAkAJjrHUBEBolIgogk7NmzJx+qSEREREREFB18PmDtWmDXrvDx3buBSZOA994DMjL+2brlNSbpeUxECgH4DMAcAKUBVARwOoDR3uFUdaKqxqtqfGxs2PsHEBERERERRYVDh4CEBCAtLTSmasnznXcC77xj771SU4Fhw4BmzYA+fSzh9tq4EYiLA84+GzjjDGD8+MD4d98BjRoBgwYBvXsDl18OJCe78aSk3JnH/MIkPe+VB3AGgNdUNU1V9wF4C8Dl+VstIiIiIiL6N/L5gKVLgUWLgKys0Pj+/cDzzwP33w+sWxcaX7wYaNECKFMGuP320ER88mSgalXgnHOABg2ANWvcmCowcKAlz1OmAH37Anff7SbqWVlAt27AmDFAxYrA3LlA27bAtm0WT0kBuncHduwAJkwALr3Ukv1x4yy+dy/QqxdQvjywYoX1pi9eDHTuDBw4YHWpVQuYM+fkl2N+YZKex1R1L4DNAG4XkSIiUg7AjQBW52/NiIiIiIgoP2RkAD/+CPz1V/j4F18A/ftbEr13b2DM5wNeftmS48aNgfnzA+OHDwPt2gEXXWSJ60UXAQcPuvHt2y0Bv/9+K+eccyyZd6xcCXTp4ibLb7xhCbdzSvnChcAttwAXXAC8/TaQmWnT++kni0+cCEydCjz0kJUxdCjw2ms2PVXgqads/iZOBL76yv7fvRu48ELgt9+sUWDdOuDdd62nfM4cS+r/+1/gmWes533vXuD9920+br4ZmDXLpn/hhcDVVwOlStn/BZaq8pXHLwDNAXwNYD+AvQDeB1Apu+FbtWqlRERERESUP7ZtU/38c9Xk5NCYz6f60UeqDz2kumhRaHz7dtUrrlAtXly1bVvVjRsD4z/9pFqrliqgWqSI6htvBMZnzLBY+fIWr19fdedON/7IIxZv1061SRPVQoVU337brdt//qNauLCVO3myldG2rWpKimp6umqbNqoxMarLlqn+9ZdqXJxqsWKq8+apHjigWq+eavXqqrt3W5mvvmrT69NHdfNm1YoVVZs1U01Ntfjvv6vWqaNapozqM89YWZ07q2ZluXX673+tjI4dVUVUb7jBPncsX65aoYINA6g+/njgMklLU+3e3Y2/+Wbocl+wQLVUKdWyZVW/+SY0Hm0AJGh2+WN2Ab7y78UknYiIiIgoe2lp9gonKUn1hRdUH33Uku1ga9eq9uqleu65lsh6k0VV1aeftsQXUK1RQ3XNGsMQnW4AACAASURBVDfm86n27esmi4DqE0+48dRU1RYtVEuXVr31Vks8zzjDkltV1R07VCtXtiR9xgzVLl2sjBdftPjq1aolS6peeKHqkSOqS5da4tmkiSXNCxdakjtwoNUlOVn14ovts8mTVV9+2cobPdqt03vvWbxzZ9UBAyz+zjtufN8+1XPOsWS+YUP7++23gcvkmWfc+T3tNNX16wPjf/yh2qiRxevXV92zJzCelaU6eLBq0aLWgOEk+F6Jiao9e6qOGRP6nahaA8OsWbZMsnPokDVGFARM0gvYi0k6ERERERVkTi9qOGlpqkuWqP76a/j4//6n2qGDardulrh5paer3n+/Ja7Fi6s++WRgQrdrl9tLDaiWK6e6cqUb//lnS6DLl1dt3tyGufdet76zZ9tnvXqpzpmjWq2aapUqquvWWfy55yw+cqQlg/362fsRI6we/fvb+08+seFXrrQ61KmjummTJdQlS7qJf3q6JaaA6pAhqnXr2jR37HDr/OWXqiVKuL3VTZsGJqKpqZaAO/PcvXvo8p840XrXAdWhQ0OX+YEDqpddZvM6c2b472X6dNWbb7YzAcI5cMDtjc9OuOT7VMUkvYC9mKQTERERUX45fNiS2fT08PGffrJkNdwpxTt2qF55pfXGxsVZz7DXihWBSbST3DomTrTPGza0RLpcucAyBg+2eN++qldfbf/feaclpRkZltyXKGG9rRs3Wi92pUqW7B84YL28VapYz29Wlupdd1kZ/frZPJcpYz3sR4/a9H75xcavUsV654sUUe3Rw61zVpbqTTdZGfHx9vfRR0OX12mnufPsnJruyMhQ7d3bYmXKqH73Xehy/fxzq/u556pu2RIaP3rUevSffDJ8L7WqNRL8+CMT5WjBJL2AvZikExEREdGJ8PlUf/jBejTDJWuHD6s+/7zqLbeofvFFaPz9992Esn59S1K9hg93k00gsCf76FHV1q2tp/jOO1WrVrXTvZ0ydu+2a51r1LDTlm+80cr4738t2f3hB7ue+dJLLXHdssWGj421nud337Xh777bndehQ92k/bbb7P+pU936rl9vCXalSqrnn2+9yUuWBC6vxx5z56dSpdBT5Neutc8B1bPPDu0pzsqyelSqZEl/Zmbocl292ubz3XdDY049fvghsAed/t2YpBewF5N0IiIiolPTgQOqU6aoTpvm9uZ6LV9uN93q3j302tzMTDtN20k4zzrLbmLmSEqyzwC7cZiI6tixgWWXKKF63nmqEybYtdPVq7vXUzs3NOvf33qir7/eTZqzslRvv93ez5plw2/caGVUrmw96JdcYqeor1hhcZ9P9b77bJyuXe0071q1VPfudev066/2eZkylsC3aRN4LbrPZw0FzjwPHhy6zNatU23QwBoPpkwJv9z/9z/rEQ8+vd6xd6/qp5+Gv5Ec0Ylgkl7AXkzSiYiIiAqm1avtztQzZoReF5yVZadzt21rN89auzYwvn27JaROwtmmTWDCumiR3Xjr9NOtd7hoUbspmMO56/fIkXZtdZkydjOvXbts2ldcYeMsXGi97M7dsh9+2IapWdNOD9+1y8r7+Wc73bxmTbseuVQpu6GZcxp8VpZdzw2oNm5sf++/P3Ce1q0LnKfgJNnns9O0RawnOvj0eFVL9rt3V73uusC7nHt9843d3Tu7U7l9vuxP3yfKD8dK0sXiFE3i4+M1ISEhv6tBREREdEpRBebNA777DujUyV5ehw4Bo0bZM6WbNbNnTFeq5MbnzbNnNPt89r5nT2D6dKBECXt///3A888DcXHAn3/a86UXLADOPx84etSeZ71unX22fTswcCBQv75NLyMDaNkSqFoVWLIEKFQI6NoV+PZbYNw4IDYW6NULuOkmYNIkQAT45ht7TnatWkDbtsCUKfa86jvvtPpkZtr/EycCJUva/H/7LdCqlTtPK1cCl15qz6WuUcOeRV2lSuAye/FFWxZduwJjxwKFCwcut23bgDfftGV2zTXhl/3evUBMjLusiP7tRGS5qsaHjTFJjz5M0omIiIhy7uhR4N13gS1bgOuuAxo2DIz//jvwyCPAmjWWUD72GFC0qBt/6CHg2Wfd9yNH2ksESEuzJDohAbj4Yktma9YEPvsMqF0bSEwEWrcGGjUCFi4Epk4F7rsPaNcO+Ogj+6x3b+D22y2p3rbNGgF27ADeew+YOROYMQOYOxfo1s2m/9VXVs/YWEte//zTpt+ggcWPHAGuvRb4+GN7f/75No430V261Mrbvx+47TZg/HibH4eqJdiLFwNDhgDt24cu1927rWHg4ouBChVO7LshokBM0gsYJulERER0Kjp0CJg923qN+/a1nlWvn37C/7d35/E21msfxz8/Q0RkqDSgAUkSRZPqUFSG0lxKpUmOIkqnNA+iedCgEnWUBpKQjkgSTTRqkDRI5pTInPg9f3z3etaesLfsvdbm+3699ste973ue//2ft3PebrWdf2ui969YfFi6No1a1b277+hVSt46y29LlsWhgzRMYBZs6BRIwXbjRopKD3xRAX1ZcsqQD7vPGWi+/RRhnngQOjQQYFtp07Qv7/Wd/rp8P77ur50aXjqKejeHZYtUxBdtap+5ksvQfv2sMcesHChMuHjx8N22+n8ggXKUn/1lV7feac+RMjso48UqK9Zo2C+RYus59euVdD/xx8KsnfcMeffddkyfRiQCO7NLPUcpBcxDtLNzMysKPrzTxg3TiXZRxyR8/w77yjQLVtWWeu9906e++EHOOYYmDNHr+vWVcC9227Ja48/HipVgooV4bvv4N57VUIOCtofeUQBdZs2+po6VQH0ueeq3PvHH2HyZGXYn3xSgXijRgpu27eHww7Tz9xu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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from os import path\n", - "\n", - "## check what result is available\n", - "#if (path.isfile('fullRun.out')):\n", - "# # if we have a long run, plot that\n", - "# D = np.loadtxt('fullRun.out')\n", - "#elif (path.isfile('run.out')):\n", - "# # otherwise, try short run\n", - "# D = np.loadtxt('run.out')\n", - "#else:\n", - "# print(\"Don't have any data! Plotting will fail.\")\n", - "\n", - " \n", - "D = np.loadtxt('run.out')\n", - "\n", - "plt.figure(figsize=(16,9))\n", - "ax0 = plt.subplot(4,1,1)\n", - "ax0.plot(D[:,0], D[:,1], 'b-')\n", - "plt.setp(ax0.get_xticklabels(),visible=False)\n", - "plt.setp(ax0.get_yticklabels(),fontsize=12)\n", - "ax0.set_ylabel(r'$\\min(n_e)$', fontsize=16)\n", - "\n", - "ax1 = plt.subplot(4,1,2,sharex=ax0)\n", - "ax1.plot(D[:,0], D[:,2], 'b-')\n", - "#ax1.set_ylim(0.85,1.1)\n", - "ax1.grid()\n", - "plt.setp(ax1.get_xticklabels(),visible=False)\n", - "plt.setp(ax1.get_yticklabels(),fontsize=12)\n", - "ax1.set_ylabel(r'$\\max(n_e)$', fontsize=16)\n", - "\n", - "ax2 = plt.subplot(4,1,3,sharex=ax0)\n", - "ax2.plot(D[:,0], D[:,3], 'b-')\n", - "plt.ylim(0,1e-5)\n", - "plt.setp(ax2.get_xticklabels(),visible=False)\n", - "plt.setp(ax2.get_yticklabels(),fontsize=12)\n", - "ax2.set_ylabel(r'$\\min(T_e)$', fontsize=16)\n", - "\n", - "ax3 = plt.subplot(4,1,4,sharex=ax0)\n", - "ax3.plot(D[:,0], D[:,4], 'b-')\n", - "#plt.ylim(0,1e-5)\n", - "plt.setp(ax3.get_xticklabels(),fontsize=12)\n", - "plt.setp(ax3.get_yticklabels(),fontsize=12)\n", - "ax3.set_ylabel(r'$\\max(T_e)$', fontsize=16)\n", - "ax3.set_xlabel(r'$t$', fontsize=16)\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "# The non-dimensional transport and chemstry properties are\n", - "# De = 3.536159e-01\n", - "# Di = 1.896334e-05\n", - "# mue = 8.849558e+01\n", - "# mui = 4.259880e-01\n", - "# Ck = 2.932670e+02\n", - "# A = 2.803050e+01\n", - "# dH = 1.570000e+01\n", - "# qStar = 1.000000e+03\n", - "# alpha = 3.611738e+01\n", - "# ks = 1.755162e+00\n", - "# gam = 1.000000e-02\n", - "['restart_psaap_Np250_T10.npy', 'restart_psaap_Np250_T20.npy', 'restart_psaap_Np250_T30.npy', 'restart_psaap_Np250_T40.npy', 'restart_psaap_Np250_T50.npy']\n" - ] - }, - { - "data": { - "image/png": "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4+7+KYnEtCeTv3KC6T1Ol2ZXMNIsL53O6bxsut+LtN8w7f5/7f1MILtXzsz584JjAm80kAwUvae9MHDh/u4ARKXTnwcc4/QitiwFMvH/cF2YxkREREQyFcPALX8eitTKQ5FaFf+8v5PSZzDnk9nHxPLnXR4u0zQTgF1As3t2NQO2pXNYCNDQMIxs9/T/HTj1sGsUERERERGRzC/DA2+KL4CehmH0MQyjsmEYE4DiwBQAwzA+Mwxjfar+84GbwGzDMJ4wDKMD8D7whdbhFRERERERkbQ45GFA0zT/ZxhGQWAYUAw4CLQyTfN0SpdigE+q/tcMw2iGbWqwMOAqtvV3v8jQwkVERERERCTTcNjsN6ZpTgYmp7OvZxptB4BGj7gsERERERERcRGOuqVZRERERERE5JFS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JMM0TUfX8EgZhnEJOO3oOv6ENxDt6CLkLhoT56RxcT4aE+ekcXE+GhPnozFxThoX55MZxqSMaZqF0trh8oE3MzAMI8w0TV9H1yF3aEyck8bF+WhMnJPGxfloTJyPxsQ5aVycT2YfE93SLCIiIiIiIi5JgVdERERERERckgKvc5jm6ALkPhoT56RxcT4aE+ekcXE+GhPnozFxThoX55Opx0TP8IqIiIiIiIhL0hVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JAVeERERERERcUkKvCIiIiIiIuKSFHhFRERERETEJSnwioiIiIiIiEtS4BURERERERGXpMArIiIiIiIiLkmBV0RERERERFySAq+IiIiIiIi4JHdHF/CoeXt7m2XLlnV0GQ9048YNcubM6egyJBWNiXPSuDgfjYlz0rg4H42J89GYOCeNi/PJDGOya9euaNM0C6W1z+UDb9myZQkLC3N0GQ8UHByMn5+fo8uQVDQmzknj4nw0Js5J4+J8NCbOR2PinDQuziczjIlhGKfT26dbmkVERERERMQlKfCKiIiIiIiIS1LgFREREREREZekwCsiIiIiIiIuSYFXREREREREXJICr4iIiIiIiLgkBV4RERERERFxSQq8IiIiIiIi4pIyPPAahjHAMIz9hmHEpnyFGIbR+gH9yxqGYabx1SIj6xYREREREZHMxd0B73kWGAocwxa4A4ClhmHUNE1z/wOOawHsS7V95dGVKCIiIiIiIpldhgde0zSX3dP0b8MwXgPqAQ8KvJdN04x6dJWJiIiIiIiIK3HoM7yGYbgZhvESkAvY9ifdlxiGcdEwjK2GYXTKgPJEREREREQkEzNM08z4NzWMJ4EQIBsQB3QzTXNFOn29sd32vBVIAtoC/wYCTNMMTOeYfkA/gCJFitRcsGDBQz+HhykuLo5cuXI5ugxJRWPinDQuzkdj4pw0Ls5HY+J8NCbOSePifDLDmDRp0mSXaZq+ae1zVOD1BEoD+YCOQF/AzzTNg3/x+MnAM6ZpPvVnfX19fc2wsLB/Uu4jFxwcjJ+fn6PLkFQ0Js5J4+J8NCbOSePifDQmzkdj4pw0Ls4nM4yJYRjpBl6H3NJsmmaCaZoRpmmGmab5AbAXeOtvvEQoUOHRVCciIiIiIiKuwFnW4bUAXn+j/9PA+UdUi4iIiIiIiLiADJ+l2TCMscAK4AyQG+gK+AGtU/Z/BtQ2TbNpynYAkAjsAazA88AAbEsbiYiIZCnx8fEcPnyY8PBwIiMjiYyM5PLly1y9epW4uDiSk5OJiYmhUKFC5MqVizx58lCsWDFKlChB2bJlqVSpEhUqVMDT09PRpyIiIvLIOWId3qJAYMqf17AtRdTSNM01KfuLAT73HDMMKAMkA+FAr/QmrBIREXElERERbNy4kS1btrB9+3bCw8OxWq1/etzhw4fT3efm5saTTz5JnTp1qF+/Pv7+/hQvXvxhli0iIuIUHLEOb8+/s980zTnAnEdYkoiIiNNITk5m8+bNLFmyhFWrVhEREfFI3mPv3r3s3buXqVOnAlC1alXatGlDp06dqFmzJoZhPPT3FRERyWiOuMIrIiIi9zh06BAzZ85kwYIFnD+f/jQVhmHg4+NDlSpVKFu2LKVLl6ZIkSLky5eP3Llz4+7uzp49e6hatSpxcXHExMTw+++/c/bsWSIiIjhy5AinTp1K8/0PHTrEuHHjKFu2LAEBAfTs2ZOyZcs+upMWERF5xBR4RUREHCQpKYkffviBSZMmsXXr1jT75MiRgyZNmtCwYUMaNGhA9erVyZkz5wNfNzEx8YFLSFy7do2dO3eyfft2fv31V7Zu3UpCQoJ9/6lTpxg1ahSjRo2iefPmDB48mObNm+uqr4iIZDoKvCIiIhns5s2bTJ8+nS+++ILIyMj79hcqVIhOnTrRoUMHGjZsiJfX31nI4M/lzZsXf39//P39GTZsGDdu3GD9+vUsXryY5cuXExMTY++7Zs0a1qxZQ+XKlXn//ffp2rUr7u76+CAiIpmDsyxLJCIi4vLi4+OZMGEC5cqVY/DgwXeFXXd3dzp16sTq1av5/fffmTx5Mv7+/g897KYlZ86ctG3bljlz5hAVFcWiRYto2bLlXVd0Dx8+TEBAAJUqVWL27NkkJyc/8rpERET+KQVeERGRR8w0Tb7//nsef/xxBg8ezIULF+z7vL29GTFiBGfOnGHRokU0b97coVdQvby86NSpEytXriQiIoLBgweTO3du+/7jx4/z6quvUr16dVavXo1pmg6rVURE5M8o8IqIiDxCu3fvpkGDBnTt2vWuK7olSpRg0qRJnD59mpEjR1K0aFEHVpm2cuXK8eWXX3LmzBlGjx5N/vz57fsOHDhAy5YtadOmDSdOnHBglSIiIulT4BUREXkErl+/zuDBg6lVqxYhISH29kKFCjFhwgQiIiIYMGAAOXLkcGCVf03evHkZNmwYp06dYuTIkXdNmrVy5UqqVq3K6NGj75r4SkRExBko8IqIiDxka9eupWrVqkyYMAGr1QqAp6cn7777LseOHWPQoEFky5bNwVX+fXny5GHEiBEcO3aMvn372p/xjY+PZ/jw4dSqVYvdu3c7uEoREZE7FHhFREQekri4OF577TWaN2/OmTNn7O3+/v4cPHiQzz//nLx58zqwwoejWLFiTJs2jdDQUGrWrGlv379/P7Vr12bEiBEkJSU5sEIREREbBV4REZGHYM+ePdSsWZMpU6bY2woWLEhgYCBr166lQoUKDqzu0ahVqxahoaF8+eWXZM+eHYDk5GQ+/vhjGjVqxMmTJx1coYiIZHUKvCIiIv+AaZpMmjSJunXrEh4ebm9v164dhw4dolu3bnct7+Nq3NzcGDx4MPv376dhw4b29pCQEJ5++mmWL1/uwOpERCSrU+AVERH5f4qPj6dnz54MHDjQPmFTzpw5mT17NkuWLKFIkSIOrjDjlC9fng0bNvDJJ5/g5uYGQGxsLC+88AKjRo2yP8ssIiKSkRR4RURE/h9+//13GjduzNy5c+1t1atXZ/fu3QQEBLj0Vd30uLm58eGHH7Jt2zbKlCljbx85ciQdOnQgNjbWgdWJiEhWpMArIiLyN4WGhuLr68uOHTvsbb169SIkJISKFSs6sDLnULt2bcLCwnj22WftbcuWLaNOnTocPXrUgZWJiEhWo8ArIiLyN8ydO5fGjRtz/vx5wHZVc8KECcyYMQMvLy8HV+c8vL29WbNmDW+//ba97ciRI9SuXZv169c7sDIREclKFHhFRET+AtM0+eSTTwgICOD27dsA5M+fnzVr1jBo0KAseQvzn3F3d+e///0vQUFB9lmcY2NjadWqFYsWLXJwdSIikhUo8IqIiPwJq9XKO++8w7BhfB2pIwAAIABJREFUw+xtVatWZefOnTRt2tSBlWUOXbt2ZevWrZQoUQKAhIQEXnzxRSZPnuzgykRExNUp8IqIiDxAUlISvXv35ssvv7S3NW3alJCQEHx8fBxYWeZSvXp1tm3bRqVKlQDbFfMBAwYwcuRITNN0cHUiIuKqFHhFRETSER8fT+fOnZk9e7a9rUOHDqxYsYLcuXM7rrBMqnTp0mzevJnatWvb20aNGsXrr79OcnKyAysTERFXpcArIiKShri4OFq1asXSpUvtbb1792bhwoWanOof8Pb2Zv369TRv3tzeNmXKFHr37q21ekVE5KFT4BUREbnHzZs3ef7559mwYYO97b333mP69Om4ubk5sDLXkCtXLpYvX87LL79sb5szZw79+/dX6BURkYdKgVdERCSV27dv0759e4KDg+1tY8eOZdy4cZqJ+SHy9PQkMDCQPn362NtmzJjBG2+8oWd6RUTkoVHgFRERSZGYmEiXLl1Yu3atve3zzz9n6NChDqzKdVksFqZOnUpAQIC97dtvv+Wtt95S6BURkYdCgVdERATbbMzdu3dn+fLl9rZRo0bx7rvvOrAq12exWJg5cyZdu3a1t02YMIH33ntPoVdERP4xBV4REcnyrFYrvXr1YuHChfa2oUOH8tFHHzmwqqzDzc2NOXPm0LlzZ3vbf/7zH0aPHu3AqkRExBUo8IqISJb3zjvvMG/ePPv2oEGD+Oyzz/TMbgZyd3cnKCiIdu3a2dtGjBjBrFmzHFiViIhkdgq8IiKSpU2cOJGvvvrKvt2vXz+++uorhV0H8PDw4H//+x/NmjWzt/Xt25c1a9Y4sCoREcnMFHhFRCTLWrp0KYMHD7Zvd+zYkcmTJyvsOpCnpyc//PAD1apVAyA5OZlOnTqxe/duB1cmIiKZkQKviIhkSaGhoXTt2tU+MVK9evWYN2+e1tl1Anny5GHlypWUKlUKgLi4OFq3bs2pU6ccW5iIiGQ6CrwiIpLlHD9+nOeff55bt24B4OPjw7Jly8iePbuDK5M/FC9enNWrV5MvXz4AoqKiaNmyJVeuXHFwZSIikpko8IqISJZy5coVWrVqxaVLlwAoWLAgq1atolChQg6uTO5VpUoVli1bhqenJwBHjhyhc+fOJCUlObgyERHJLBR4RUQky0hKSqJLly6Eh4cD4OXlxfLly6lQoYKDK5P0NGrU6K4ZtH/99Vfee+89B1YkIiKZiQKviIhkGR9++CHr16+3b8+bN4/69es7sCL5K7p06cKoUaPs219++eVdIVhERCQ9CrwiIpIlLFy4kPHjx9u3hw8fTufOnR1Ykfwdw4YNu2uN3r59+xIWFubAikREJDNQ4BUREZd34MABXn31Vft2mzZtGDFihAMrkr/LYrEwd+5cqlSpAsDt27dp3749Fy5ccHBlIiLizBR4RUTEpV29epV27dpx8+ZNACpUqMC8efOwWPRPYGaTO3duli5dSt68eQE4e/YsnTt3JjEx0cGViYiIs9K/9iIi4rKSk5Pp1q0bJ06cACBnzpz8+OOP9qVuJPOpUKEC33//PYZhALB582aGDBni4KpERMRZKfCKiIjLGj16NKtWrbJvz5kzh6pVqzqwInkYWrZsyaeffmrfnjhxIkuXLnVgRSIi4qwUeEVExCVt3LiR0aNH27fff/99Onbs6MCK5GEaOnQoL7zwgn27V69eREZGOrAiERFxRgq8IiLici5fvky3bt2wWq0A+Pn5MWbMGAdXJQ+TYRh89913lC5dGrA9q/3yyy/reV4REbmLAq+IiLgU0zR59dVXOXfuHAAFCxYkMDAQNzc3B1cmD1uBAgX4/vvv7WO7bds2zb4tIiJ3UeAVERGXMmnSJH766Sf79uzZsylRooQDK5JHqX79+nfduj527FjWrVvnwIpERMSZKPCKiIjL2LNnz10z9r755pu0adPGgRVJRhg6dCjNmjUDbFf4u3fvTlRUlIOrEhERZ6DAKyIiLiEuLo6XXnqJhIQEAKpXr864ceMcXJVkBIvFwrx58yhatCgAFy9eJCAgANM0HVyZiIg4mgKviIi4hLfeeovw8HDAtt7uggUL8PLycnBVklGKFClCYGCgfX3etWvXMnXqVAdXJSIijqbAKyIimd7KlSuZMWOGfXvy5MlUrFjRgRWJIzRt2pS3337bvj1kyBCOHz/uwIpERMTRFHhFRCRTu3LlCn369LFvd+7cmVdeecWBFYkjjRkzhipVqgBw48YNAgICSE5OdnBVIiLiKBkeeA3DGGAYxn7DMGJTvkIMw2j9J8c8aRjGRsMwbhmGcc4wjOHGH/csiYhIljZo0CDOnz8PQOHChZk8ebKDKxJHypYtG3PnzsXd3R2ArVu38sUXXzi4KhERcRRHXOE9CwwFagC+wK/AUsMwnkqrs2EYeYB1wAWgFjAIeBd4O63+IiKSdSxZsoSgoCD79rRp0/D29nZgReIMatasybBhw+zbw4YN4+DBgw6sSEREHCXDA69pmstM01xlmmaEaZrhpmn+G7gO1EvnkG5ADiDANM2DpmkuBsYBb+sqr4hI1nXx4kX+9a9/2bdfeeUVXnjhBQdWJM7kww8/pGbNmgAkJCTQo0cP+wzeIiKSdTj0GV7DMNwMw3gJyAVsS6dbPWCzaZq3UrWtAYoDZR9thSIi4oxM0+S1117j0qVLAJQoUYIJEyY4uCpxJh4eHsydO9c+U/fevXsZM2aMg6sSEZGMZjhijTrDMJ4EQoBsQBzQzTTNFen0XQucNU2zV6q20sBpoL5pmiFpHNMP6AdQpEiRmgsWLHj4J/EQxcXFkStXLkeXIaloTJyTxsX5OGpMfvnlFz755BP79rhx46hdu3aG1+Gs9LNyx8KFC/n2228BcHNzY9q0aZQrVy7D69CYOB+NiXPSuDifzDAmTZo02WWapm9a+xwVeD2B0kA+oCPQF/AzTfO+B2xSAu8Z0zR7p2orA5wC6pmmuf1B7+Xr62uGhYU9xOofvuDgYPz8/BxdhqSiMXFOGhfn44gxiY6OpnLlykRHRwPQv39/pkyZkqE1ODv9rNxhtVpp1KgRW7duBaBOnTps3boVNze3DK1DY+J8NCbOSePifDLDmBiGkW7gdcgtzaZpJqQ8wxtmmuYHwF7grXS6RwFF72krnPLnhUdVo4iIOKchQ4bYw27p0qUZP368gysSZ2axWJg2bRoeHh4AhIaG2q/4ioiI63OWdXgtgFc6+0KAhoZhZEvV1gz4HdtVXhERySJ+/fVX5syZY9+ePHkyuXPndmBFkhlUqVKFDz/80L79wQcfcObMGQdWJCIiGcUR6/CONQyjoWEYZVPW1/0M8AOCUvZ/ZhjG+lSHzAduArMNw3jCMIwOwPvAF6Yj7scWERGHuHXrFv3797dvd+nShdatH7iMu4jdBx98QOXKlQHb82gDBgxAHyNERFyfI67wFgUCgaPAemxr67Y0TXNVyv5igM8fnU3TvIbtim5xIAz4BvgvoFXkRUSykDFjxhAREQFA3rx5NSuz/C1eXl5MmzbNvv3TTz/xww8/OLAiERHJCI5Yh7enaZplTNP0Mk2zsGma/qZprrlnf9l7jjlgmmYj0zSzmaZZzDTNUbq6KyKSdRw8eJDPP//cvv35559TtOi90zuIPNgzzzxz19rNAwcO5OrVqw6sSEREHjVneYZXREQkTVarlb59+5KUlATYQkufPn0cXJVkVmPHjqVYsWIAXLhwgaFDhzq4IhEReZQUeEVExKlNnTqV7dttK9B5eHgwbdo0LBb98yX/P3nz5mXSpEn27RkzZrBjxw4HViQiIo+SPjGIiIjTunTp0n2z6/4x8ZDI/1eHDh1o06YNAKZp8sYbb2C1Wh1clYiIPAoKvCIi4rQ+/PBDYmJiAChfvjwffPCBgyuS/2PvzsOiKtsHjn/PDLvsiIi4g4Ko4G6UmVbma9pmaplpZa9ltpeVtm/vW1lWr5VmqWlamtavsqxcKrMy9w1REQEFFQTZd5iZ8/tjpgOkCOrAGeD+XBeX8xzOmXPnYMM9z/Pcd1Px7rvv4upq7Yi4fft2Fi1apHNEQggh6oMkvEIIIRzSjh07WLhwoTZ+9913cXNzO8cVQtRdaGgoTz75pDaeMWMG2dnZOkYkhBCiPkjCK4QQwuFYLBYeeOABrU/qqFGjpOeusLsZM2bQoUMHALKysnj++ed1jkgIIYS9ScIrhBDC4SxZsoStW7cC4OLiwjvvvKNzRKIp8vDwqPazNW/ePPbs2aNjREIIIexNEl4hhBAOJS8vjxkzZmjj6dOnExYWpmNEoim78cYbueaaawDryoL7779fW1kghBCi8ZOEVwghhEN58cUXycjIAKBt27bVqjQLYW+KojBnzhycnZ0B2Lx5M0uXLtU5KiGEEPYiCa8QQgiHsX//ft577z1tPHv2bFq0aKFjRKI5CA8P57HHHtPGM2bMoLCwUMeIhBBC2IskvEIIIRyCqqo8+uijmM1mAIYOHcrYsWN1jko0F88++yxt2rQBIC0tjbfeekvniIQQQtiDJLxCCCEcwk8//cSGDRsAMBqNzJkzB0VRdI5KNBeenp68+uqr2njWrFmcOHFCx4iEEELYgyS8QgghdGcymZg+fbo2njJlCj169NAxItEcTZo0iejoaABKSkp49tlndY5ICCHExZKEVwghhO4WLVrEgQMHAOtM24svvqhvQKJZMhqNzJ49WxsvWbJE2hQJIUQjJwmvEEIIXRUUFPD8889r45kzZxIUFKRjRKI5u+qqqxg1ahRg3Vf++OOPS5siIYRoxCThFUIIoatZs2Zx6tQpwNqG6JFHHtE5ItHcvfnmmxiNRgB++eUXvv/+e50jEkIIcaEk4RVCCKGb48ePV1tC+p///AcPDw8dIxICIiIiuPfee7XxE088QUVFhY4RCSGEuFCS8AohhNDNc889R0lJCQC9e/fm9ttv1zkiIaxefPFFvL29AYiPj2f+/Pk6RySEEOJCSMIrhBBCF3v27GHJkiXaePbs2RgM8rYkHENgYCBPP/20Nn755ZcpKCjQMSIhhBAXQn6zEEIIoYsnn3xSKwZ03XXXMXToUJ0jEqK6hx9+mPbt2wOQmZnJu+++q3NEQgghzpckvEIIIRrcr7/+yvr16wEwGAy88cYbOkckxJnc3Nyqtch66623yMrK0i8gIYQQ500SXiGEEA1KVdVqS0XvvPNOunXrpmNEQtRs4sSJREREAJCfn8/rr7+uc0RCCCHOhyS8QgghGtT333/Pli1bAHBxceGFF17QOSIhaubk5MSrr76qjd977z2OHz+uY0RCCCHOhyS8QgghGozFYuGZZ57Rxvfdd5+2R1IIRzV69Gj69esHQFlZGS+//LLOEQkhhKgrSXiFEEI0mBUrVhAbGwtAixYtqi1tFsJRKYrCf//7X228aNEiDh8+rGNEQggh6koSXiGEEA2ioqKC559/Xhs/+uijtGrVSseIhKi7q6++miuvvBIAs9lc7WdZCCGE45KEVwghRINYtGgRiYmJAPj5+TF9+nSdIxKi7v45y/vFF1+we/duHSMSQghRF5LwCiGEqHclJSXV9j3OmDEDHx8fHSMS4vwNHDiQG2+8URs/++yzOkYjhBCiLiThFUIIUe8++OADTp48CUBwcDAPPPCAzhEJcWFeffVVFEUB4IcffmDbtm06RySEEOJcJOEVQghRr4qKipg1a5Y2fu655/Dw8NAxIiEuXPfu3bn11lu18UsvvaRjNEIIIWojCa8QQoh6NW/ePDIzMwFo3749d999t84RCXFxnnvuOZnlFUKIRkISXiGEEPXmn7O7zzzzDC4uLjpGJMTF69atm8zyCiFEIyEJrxBCiHrz4YcfVpvdvfPOO/UNSAg7kVleIYRoHCThFUIIUS+Ki4urze7OnDlTZndFkyGzvEII0ThIwiuEEKJefPjhh2RkZADQrl077rrrLp0jEsK+ZJZXCCEcnyS8Qggh7K64uJg33nhDG8+cORNXV1cdIxLC/mSWVwghHJ8kvEIIIexu/vz52uxu27ZtmTx5ss4RCVE/ZJZXCCEcmyS8Qggh7KqkpOSMvbsyu9swVFXFZLFQBpgsFr3DaRb+Ocv78ssv6xiNEEKIf3LSOwAhhBBNy/z580lPTwcgJCRE+u7aQZnFQlxREXsLC0ksKSG5tJQTZWVkVFSQWVFBidlMuapSoaqVF23ahKui4OXkRKCzM0EuLrR3dSXCw4NwDw8iPDwIdXfH1SCffV+s5557jhUrVqCqKmvWrGHv3r1ER0frHZYQQggk4RVCCGFHZWVlvPXWW9pYZnfPn6qqHCou5tfcXHYVFLCrsJD9RUXVk9k6KlNVyioqOF1RwcHi4jO+bwDCPTy43MeHwb6+DPbxoZ2bmx3+K5qXbt26MXr0aL766isAXn/9dZYvX65zVEIIIUASXiGEEHa0dOlSTpw4AUBQUJDM7tZRgcnEzzk5/JSdzU/Z2RwrK7vg5zIARsAE1JYiW4CDxcUcLC7mo7Q0ADq5uTHE15ebWrbkGn9/mQGuo5kzZ2oJ78qVK3nllVcICwvTOSohhBCS8AohhLALs9lcbe/uY489hpvMFtao1Gzmu6wslqSnszYnB1MtM7ihbm709vIiwsODTm5udHBzI8jZmUAXF1oYDDgbDDgrCgZFYePGjVxxxRWUWCzkmUxkVFRwqrycxJIS4ouLOVRcTHxJCcdKS89IipNLS0lOT+eT9HS8jEauDwhgTGAgw/39cTca6+8vpJHr27cv11xzDevWrcNisTBr1iw++ugjvcMSQohmTxJeIYQQdvHVV1+RkJAAgK+vL1OnTtU5Isejqipb8/NZcuoUKzIyyDWZznqet9HIVX5+DPLxoY+nJ708PfF1dj6veymKgofRiIfRSHANy8qLzWa2FxSwKTeX33Jz2ZyfT0mVYlcFZjOfZWTwWUYGnkYjE4OCuD8khO4tWpxXLM3F008/zbp16wBYvHgxL7zwAiEhITpHJYQQzZskvEIIIS6aqqq89tpr2viBBx7A29tbx4gcS4XFwoqMDN5MTSW2qOis5/Ty9ORf/v6M8Pcnxtsb5wZYSuxhNHKFry9X+PryHFBusbCzoIBvT59mVWYmSaWl2rmFZjPzTp5k3smTXOHjw/0hIdzYsmWDxNlYDB48mJiYGP766y8qKip4++23mT17tt5hCSFEsyYJrxBCiIu2du1a9uzZA4C7uzsPPfSQzhE5hgKTiY/T0nj3+HFSz7Ivt5ObG5OCgpjUujWd3d11iLA6F4OBGB8fYnx8eK1zZ/YWFrIqM5NVmZkklJRo5/2Wl8dveXm0cXHhsXbtuK9NGzxkuTOKovD0009z3XXXAdaK5U8//TQBAQE6RyaEEM2XfCwrhBDiov33v//VHk+ZMoXAwEAdo9FfvsnEc8nJtPvrLx5PTKyW7HoYDExu3ZrfevXiyMCBvNipk0Mku/+kKAq9vLz4T+fOxA8YwK/R0YwJDKRqWnuyvJzpiYl03rKFd1NTKTGbdYvXUYwcOZKoqCgAioqKeO+993SOSAghmrcGT3gVRZmpKMp2RVHyFUXJVBTlO0VRetRyTUdFUdSzfP2roeIWQghxdn/++Se///47AE5OTjz++OM6R6SfcouF948fJ3TrVl49doy8KglgK2dnXu3UidSYGBZGRDDY1xeDougYbd0pisIQPz9Wde/OsZgYnu/QgdYuLtr3T1VU8GhiIqFbt/Le8eOUVdkH3NwoisKMGTO08Zw5cygoKNAxIiGEaN70mOEdAswFLgWuxNo5YYOiKP51uPZfQHCVr1/qKUYhhBB1VHXv7sSJE2nfvr2O0ehDVVW+zMig+/btPHjkCKcrKrTvdXV3Z37Xrhy75BKe6dAB//MsPuVoQlxdealTJ45ecgkfdOlCSJXEN628nIeOHKHH9u38kJWlY5T6Gjt2LKGhoQDk5OQwf/58nSMSQojmq8ETXlVVh6uq+omqqvtVVY0FJgKBwGV1uDxLVdX0Kl/l9RutEEKIc0lMTGTNmjWAdWbrqaee0jmihhdbWMig3bsZe+AAR6rsc+3g6sqybt04MGAA97Rpg1sT2+PqajAwLSSEIwMHMicsjOAqie+RkhJGxsZyfWwsSVX+TpoLJycnnnzySW387rvvUlHlQxAhhBANxxH28HphjSOnDuf+n6IoGYqi/Kkoyph6jksIIUQtVqxYoT0ePXo04eHhOkbTsErNZp5NSqLPzp1szs/Xjvs6OfFWaCiHBgxgQlAQxkaybPlCuRmNPNi2LYkDB/J2aCi+TpX1ML/LyiJy2zZeSE6muJnt773jjjto3bo1ACdOnODXX3/VOSIhhGieFLWWRvf1HoCirAS6AP1UVT3ru6GiKC2BO4A/sS6Bvh54BrhDVdVlZzn/HuAegKCgoL5VfyFzRIWFhXh6euodhqhCXhPHJK+LY8nIyGD8+PFYbPs1P/zww2aT8O4B3gZSqxxzAkYDEwC9GzLp+W8lB1gA/PCP422BmUBkg0ekn2XLlrFw4UIAOnbsyKJFi1Ca+AcgjYm8pzgmeV0cT2N4TYYOHbpTVdV+Z/uergmvoihvA7cCg1RVTTrPa+faros613n9+vVTd+zYcRFR1r+NGzcyZMgQvcMQVchr4pjkdXEsTzzxBG+99RYAQ4YMaRYzWAUmE9MTE/koLa3a8cu8vfk4PJxuLVroFFl1jvBvZVt+PvcnJLCjSsEmA/BU+/a80LEjrs2gf292djbt2rWjuLgYgPXr13P11VfrHJX4myP8OxFnktfF8TSG10RRlBoTXt3ebRRFeQcYD1x5vsmuzVasM8NCCCEaWH5+Ph999JE2bg6VmXcWFNB3585qya630ci8Ll3Y1Lu3wyS7jmKAtzdb+/RhfteueNn2L1uA11JSGLBzJ3sLC/UNsAH4+/szefJkbfz3B0RCCCEaji4Jr6Io/wNuw5rsHrrAp+kFpNV6lhBCCLtbsGAB+bZ9q+Hh4Vx77bU6R1R/LKrK26mpxOzaRUKVAkw3tWzJgQEDmBoS0mjaCzU0g6JwT5s2xPbvz1BfX+34vqIi+u/cyayUFCw6b62qb4888ggG22z22rVr2bdvn84RCSFE86JHH94PgLuwzu7mKIrS2vblWeWc1xRF+bnK+A5FUW5TFKWboijhiqJMB+4HpJu7EEI0sIqKCt59911t/Pjjj2u/0Dc1p8rLGRkby+OJiVTYEjNPo5GlERH8X48ehLi66hxh49DBzY0N0dHMCQvDzfazUqGqPJWUxE3795PbhCsYh4aGMnr0aG389ttv6xiNEEI0P3r8hjINa2Xmn7HO0P79Nb3KOcFA6D+uexbYAWzHuu93sqqq79R7tEIIIar58ssvSU21lmvy9fVl4sSJOkdUP/7IzSV6+3Z+ys7WjvX38mJPv37cbqu+K+rOoCg82LYte/r1Y4CXl3Z8dVYWfXfuZE+Vvb5NzfTplb/ifP7555w4cULHaIQQonnRow+vUsPXi1XOuVNV1Y5VxktUVY1UVbWFqqreqqr2O1t1ZiGEEPVLVdVq+xBvvPFG3NzcdIyofnx08iRX7t3LqSozj0+2a8cfvXsT6u6uY2SNX7iHB3/07s1jbdtqx5JKS4nZvZtP0prmTqWBAwfSo0cPwLpC4r33ZIGaEEI0lKa5Bk0IIUS9+O2339i1axcAbm5u3HDDDTpHZF8VFgv3Hz7MvYcPa0uYA52dWRsVxRuhobg00aXbDc3ZYGB2WBirIiPxtBW0KrVYmBwfz73x8VTYWl01Jbfccov2+MMPP6SgCc9oCyGEI5F3biGEEHVWdXb3zjvvxLdKIaLG7nR5Odfs28fckye1Y709PdnRty/X+PvrGFnTNaZVK3b07Uukh4d27KO0NK6NjSXPZNIxMvuLiYmhSxdrc4m8vDytP68QQoj6JQmvEEKIOjl48CBr1qwBQFEUHn30UZ0jsp8DRUX037WLjbm52rFxgYH80bs37Zvgkm1HEu7hwdY+fRjfqpV2bENODpft2sWx0lIdI7Mvo9HIY489po3nzJmD2WzWMSIhhGgeJOEVQghRJ1UrM19//fV07dpVx2js56+8PAbt3s1RW3KlAP/p1IkVkZF42Jbbivrl6eTEZ9268VLHjtqxuOJiLtm1ix229ldNwaRJk/Dz8wMgOTmZ77//XueIhBCi6ZOEVwghRK2ys7NZunSpNq46U9WYfX/6NFft3UuObflsC4OBb3r04OkOHVCkt26DUhSF5zt2ZGlEBM62v/v08nIG79nDt6dP6xydfXh4eDBlyhRt/L///U/HaIQQonmQhFcIIUStFixYQElJCQC9evXi8ssv1zmii7c4LY0b9++nxFYgKdDZmY29enF9y5Y6R9a83d66Neujo/FzcgKgxGJh9P79fJqernNk9nH//fdjtK0c+PXXX4mNjdU5IiGEaNqc9A5ACCGEYzOZTLz//vva+KGHHmrUs5+qqjIrNZUZSUnasY5ubqyLiqJLleJJjqgip4LSo6WUJpdSnl6OucCMqcCEucCMucCMpdSC4qJAFiT8XwIGVwMGdwMuwS64tnHFJcQF1xBXXFq5oBgd9zW8wteXv/r04dp9+0gqLcUC3HHoEEVmM/eFhOgd3kVp3749N910E19++SVg3cv78ccf6xyVEEI0XZLwCiGEOKdvv/2W1NRUAFq2bMn48eN1jujCqarKM8nJvJaSoh2LatGCn6KiCHZ11TGy6sxFZgp2FVCwrYCCHQUUHyqmJLkEc17dixyd4ESN31OcFNzD3fGM9sQzypMW0S3wjPLEtY3j/B2Ee3jwV58+DNu7l31FRQBMS0igyGxmevv2Okd3cR5++GEt4V22bBmvvfYaLWVlgRBC1AtJeIUQQpxT1X2G9957L26NtGqxqqo8nZzM61WS3St8fPi2Z098nPR9OzTlmcjZkEP22mzy/8qn6EAR1GMrWtWkUhxXTHFfUteQAAAgAElEQVRcMRmfZ2jH3Tq64XulL35X+uF7pS+uwfomwK1cXPi1Vy9G7NvHNlvf2ieSkig0m3mhY8dGu9Lgsssuo0+fPuzatYvS0lIWLFjAjBkz9A5LCCGaJEl4hRBC1Gj37t38/vvvADg5OXHffffpHNGFOVuyO9Lfny+7d8dNh0rMqqpSFFtE1possn/MJm9zHtRh8tbgbsCtoxtundxwDXHFyccJo5cRo5cRJ28nDG4GLOUW4mPjCesQhqXMgrnQTHlaOWUnyrQvU9bZe9yWHi0lfVE66Yus+2U9unkQMDKAwHGBePXz0iXB9Hd2ZkN0NNfFxvJbXh4ALx07RqHZzJuhoY0y6VUUhYceeog777wTgA8++IDHH38cZ2dnfQMTQogmSBJeIYQQNZozZ472eMyYMYQ0wv2TqqoyMymJN2zLsgGuCwhgVffuuBoatnZjaWoppz47xamlpyg+UFzziQZrsund3xuv/l549vbEvbM7zq2c65TgxW+Mp+2QtjV+31Rgomh/EYV7CynaZ/2zcE8hluLq08rFB4spPlhM6lupuHVyI3BcIK3GtcKzt2eDJppeTk78EBXFzXFx/JSdDcDs48dxUhRe69y5USa9t956K08++SQZGRkcP36cr7/+mnHjxukdlhBCNDmS8AohhDirjIwMPv/8c2388MMP6xjNhXGEZNdcYiZzZSbpn6aT+2suqGc/z7OvJwEjAvC72g/Pvp44edbfW7STlxM+MT74xPhoxywVFgq2F5Dzcw65v+SStzkPtbwy2NLkUlLfSCX1jVQ8unnQ5r42tJ7UGiefhvlVwsNo5JsePbjtwAH+z9am6I3UVFoYjTxXpX9vY+Hq6srUqVN5+eWXAevWAUl4hRDC/iThFUIIcVYfffQR5eXlAPTv35+BAwfqHNH5e+HoUd2S3bL0Mk7OPcnJeSepOF1xxvcNHgZaXt8S/2v98R/uj0srl3qP6VwMzgZ8LvXB51IfeM6aqOduzCVzZSaZX2dWK5hVfLCYIw8dIWlmEkG3BxEyLQTPKM96j9HVYGBFZCRj4uJYnZUFwPNHj+JhNPJ4u3b1fn97mzp1Kq+99hoVFRVs3ryZHTt20K9fP73DEkKIJkX68AohhDhDRUUFc+fO1cYPP/xwo1s2Ouf4cV45dkwbXxcQwJcNkOwW7ivk0F2H2NJhC8deOVY92TWA3zA/Ij6N4NJTlxK5PJLWE1vrnuyejdHdSMCIACI+ieCyU5fR47seBN0ehNGzcs+zpchC2vw0dkTvYPeQ3WRvyEZVa5jCthNng4EvIiO5xs9POzY9MZF5J2quSu2ogoODq83qvvfeezpGI4QQTZMkvEIIIc7w1VdfkZaWBkDr1q0ZO3aszhGdn89OneLhI0e08b9sBapc6jHZLYwtJPaGWHZE7yB9cXq15cCuHVzp/EZnYlJjiF4XTeuJret1ybK9GVwNtBzVkm5LuxFzMoYuc7vg0b16z+K83/LYN2wfuwftJntd/Sa+bkYjX/fowWCfyiXZ0xISWJKeXm/3rC8PPfSQ9viLL74gyzZzLYQQwj4k4RVCCHGGDz74QHs8depUXFwcbwayJj9mZXHnoUPaOMbbu16T3eIjxRyYcIAd0TvIWl09WfGO8SZyVSQDjwyk/ZPtHarP7YVy8nIi5L4Q+sf2p9dvvQi8JRDFqXL2P39zPvuG72P3pbvJXlt/ia+H0cj3PXsy0MtLOzb50CFW2/b3NhYDBgzQljGXlZXxySef6ByREEI0LZLwCiGEqGbfvn388ccfgLUV0T333KNzRHX3V14eN8fFYbIlWd09PPi+Z09a1EProbK0MuLvjWdbxDZrL9sqeV3gmEB6/9WbPpv70GpMKwxOTe/tVlEUfAf70n1FdwYeGUibqW1QnKskvlvy2fevfewbsc/aV7geeDk58WNUFL08rfuHLcCtBw6wLT+/Xu5XX6ZNm6Y9njdvHhZLPTZhFkKIZqbpvQMLIYS4KPPmzdMejx49muDgYB2jqbu4oiJGxsZSYksWOri6sjY6Gn879za1VFhIfSeVbeHbSPsorVr/3IDrAui3px/dV3XH5xKfmp+kiXHr4EbXeV0ZmDiQNtPaoLhUJr45a3PYHrWdhIcSqMg+s3jXxfJzdmZtVBSd3dwAKLFYGBUby5Hic7R9cjC33HILfrY9yUlJSaxbt07niIQQoumQhFcIIYQmPz+fpUuXauOqM0+O7FR5OSP37SPHZAIg0NmZ9dHRhLjadwlx7u+57Oy7k8THEjEXVGa6vkN96f1Xb3qu7olndP1XK3ZUbu3c6PpBVy5JuoTge4Irf8sww4n3TrC1y1ZOfHAC1WzfZc6tXFz4MSqKACfrvujMigpGxMaSaasy7ug8PDy46667tHHVLQVCCCEujiS8QgghNEuXLqWoyLr8NDIyksGDB+scUe1KzGZu3L+fY2VlAHgajfwUFUUXD49arqy78oxyDt5xkD2D91AUW7k81yPCg6h1UfT6pVezmtGtjWuIK+Hzw+m3ux++Q32146ZsEwkPJLB70G6KDtp3mXNXDw++69kTN9te7SMlJVwXG0ux2VzLlY5h6tSp2uM1a9Zw9OhR/YIRQogmRBJeIYQQAKiqWm0587Rp0xy+FZGqqkyOj2eLbc+mAfgiMpI+VQoZXazMrzPZ3n07pz49pR0zeBjo/Hpn+u3th/8wf7vdq6nxjPIk+udoun/VHbdObtrx/C357Oi1g2OvHcNSYb/9qjE+PnzerRt//9RuLSjgtgMHMNdzqyR76NKlC8OHDwesP9fz58/XOSIhhGgaJOEVQggBwO+//05cXBwALVq0YOLEiTpHVLsXjx5lRUaGNn4nLIxrAwLs8twVuRUcvOMgcaPjqvXSbXlzSwYcHED7p9pjcJG30dooikLg6ED6H+hPx5c6aoWt1HKV5KeT2XXJLgr3FtrtfjcFBjInLEwbf5uVxTNJSXZ7/vpUdQvBggULKLOtWhBCCHHh5J1aCCEEAHPnztUeT5w4EW9vbx2jqd2y9HRePnZMG09r04YHQ0Ls8tzZG7LZ0XNHtVldlxAXev7Qkx5f9sCtvds5rhZnY3Qz0vH5jvTd1Rev/pUz8IW7CtnZbycps1JQLfaZiX2gbVumt2unjd9ITeXzU6fOcYVjGDlyJO3btwfg9OnTfPnllzpHJIQQjZ8kvEIIIUhPT+err77Sxvfdd5+O0dRuc14ed8fHa+Phfn78LyzsopdgW8otHHnsCPuG7aPseOXsWtDtQfSP7U/ACPvMHjdnnj086b25N51ndUZxtc32mlSSnkpi37X7KM+wT6Gp1zt3ZqR/5XLzu+Pj2eHg7YqMRiP33nuvNq76IZQQQogLIwmvEEIIFixYgMlW4XjQoEFERUXpHFHN0srKuDkujnLbvsxIDw++6N4dJ8PFvaWVHi9lz5A9HH/nuHbMKcCJ7l92p9vSbjj72be9UXNmcDLQ/on29N/bH+9LKlcS5KzNYUf0DnJ+ybnoexgVhc8iI4mwFS8rtVi4cf9+0h18mfDdd9+Ns62V1ubNm9mzZ4/OEQkhROMmCa8QQjRzJpOpWoEcR25FVG6xMDYujnRbu5mWzs5837MnPrZ2NBcqe0M2O3vvJP+vyhnAgFEB9N/fn8CbAy/quUXNPMI96LWpF+2eqlx+XJ5ezt6r95L8XDIW08UVtPJxcuLbHj3wMRoBOFFezs1xcZRZ7Fcoy96CgoIYO3asNpbiVUIIcXEk4RVCiGZuzZo1HD9undUMDAxk9OjROkdUs+mJifz5j4rMndzdL/j5VIvK0VeOsu+afZWFqYzQ+c3O9FjdA9fW9u3jK85kcDYQ+nooUT9F4Rxom0VX4dirx4i9NpaKnIpzP0EtutpWAPz9C8/m/HzuP3wY1YErN1dtUfTZZ59RWGi/ol5CCNHcSMIrhBDN3EcffaQ9vvvuu3F1dcwkb1l6Ou+dOKGNX+vcmSv9/C74+UwFJvbfsJ+jzx8FW+7j0tqFXr/0ov309g7fkqmp8R/uT7+9/fC9qrJvb876HHYN2HXRPXuH+/szKzRUGy9MT2dBWtpFPWd9GjRoEBEREQAUFBTwxRdf6ByREEI0XpLwCiFEM5aSksKPP/6ojadMmaJjNDXbW1jIPYcPa+ObW7bkiSpVeM9XaWopuwftJuv7LO2YzxU+9N3dF9/Bvue4UtQn12BXotdG0+H5DtqxkiMl7LpkF1k/ZJ3jyto91rYtE4OCtPGDCQnsLii4qOesL4qicM8992jjqh9KCSGEOD+S8AohRDO2cOFCbWnnsGHD6Ny5s84RnSmnooLR+/dTYtt3GeHhwScRERc8A5u/I986a7ivctaw3RPtiN4QLUuYHYBiVOj0UiciV0Vi8LD+mmLONxM7KpaUN1MueCmyoih82LUrPVu0AKBMVRkbF0eerVibo5k0aRIuLi4AbNu2TYpXCSHEBZKEVwghmimTycTChQu1cdUZJUehqip3HjpEUmkpAF5GI193747XBRapyvwmkz2D91Cebi16pTgphC8KJ3RWKAYneUt0JK3GtKL3n71xbW/7EEKFpCeTiJ8Sf8HFrDyMRr7s3h1PWxGrxNJS7j50yCH38wYEBDBmzBht/PHHH+sYjRBCNF7y7i6EEM3UTz/9xAnbntjAwECuv/56nSM60/snTrA6q3Ip6+KICCJsM3TnK/XtVOJGx2EpsSZLTr5ORK2LIviuYLvEKuzPq5cXfbf3xfuyytZF6QvTibs5DnOx+YKes6uHBwvCw7XxV6dPV9sb7kiqfgi1bNkyiooubi+zEEI0R5LwCiFEM1V1X+Bdd92lLZ90FLsLCpiemKiNH2nbltGB598iSFVVkmYmkfh4olacyi3UjT5b+uA39MKLXomG4dLKWkgsaFLl/tus1VnsHbaXiuwLq+B8S6tW3N+mjTaenpjI1vz8c1yhj8GDB9O1a1cA8vPzWblypc4RCSFE4yMJrxBCNEPHjx9nzZo12vjf//63jtGcqdBk4pYDByi3LTXt4+nJ6xewv1i1qCRMSyDl9RTtmPdl3vTZ0gePcA+7xSvql8HFQMTiiGr9evM357P78t2UppZe0HPODgujn5cXABW2/bzZFRfXAsnepHiVEEJcPEl4hRCiGVq0aBEWWxGoK6+8ki5duugcUXUPJCSQUFICgKfRyIrISFwN5/eWZamwcHDiQU5+eFI7FjAqgOj10bi0dKzZbFE7RVEIfT2U0Hcq2wsVHyhm96W7L6htkavBwMrISHxt+8FTy8q41wH7895xxx3a6ostW7awb98+nSMSQojGRRJeIYRoZsxmc7ViVY7WimhpejpLTp3SxvO6dKGLx/nNxppLzcSNiSPj8wztWKvxrej+f90xuhvtFqtoeO0eaUe3z7uhOFurdJcdL2PPkD0U7i887+fq5O7OYlu/W4AvMzNZkp5ut1jtoWXLlowePVobS/EqIYQ4P5LwCiFEM7Nu3TpSUqxLfAMCArjpppt0jqjS4eJi7qvSb/eOoCBub936vJ7DXGwmdmQsWasri121mdqGbku7YXCWt72mIGh8ED3X9MToaf3woiKjgr1D91K47/yT3htatuTe4MrCZQ8eOUKibXWBo6i6rHnp0qUUFxfrGI0QQjQu8s4vhBDNTNV9gHfeeSeuro7Re9ZksXD7wYMU2ZZad3V35/3zXGptLjWz/4b95P6Sqx1r91Q7usztgmK8sL69wjH5D/Mnam0URi9b0nu6gj1X7qFgT8F5P9fssDDC3d0BKDSbmXDgABWWC2t9VB+GDBlCWFgYAHl5eaxatUrniIQQovGQhFcIIZqRtLQ0vvvuO23sSMWqXktJYXuBNVlxVhRWREbieR79di1lFuJGx5GzIUc71uk/nQh9PRRFkWS3KfK51IeodVEYva1JrynLxN6r9lKw6/yS3hZGI59FRuJk+znZWlDAq8eO2T3eC6UoSrWtB4sWLdIxGiGEaFwk4RVCiGbk008/xWy29i+9/PLLiaiyf1FPOwsKeLlKgvFKp070tlXQrQtLuYW4sXFk/5itHev0aic6PN3BrnEKx+NziQ/R66Mx+tiS3mxb0rvz/JLevl5evNqpkzZ+9dgx/szLs2usF2PSpEkYjdb/xk2bNpGQkKBzREII0ThIwiuEEM2EqqrVZoYcpVhVqdnMpIMHMdmq417q7c30du1quaqSxWThwG0HyPqucs9uh+c60OEZSXabC+8B3kRviMbJ17oiwJRrYu/wveddvXl6u3Zc4eMDgAW4/eBB8k0me4d7QVq3bs3IkSO18eLFi/ULRgghGhFJeIUQopnYvHkzh20Foby8vLj55pt1jsjq2eRkDtiK8LQwGPi0WzeMdVyCrJpVDk06xOmvTmvH2j3Vjo4vdayHSIUj8+7nTfTP0Tj52ZLeLBN7h+2l5GjdC1AZFYWl3bpprYqOlpbyRGJivcR7ISZPnqw9Xrx4MSYHScaFEMKRScIrhBDNRNXZ3fHjx+Nxnq1+6sNvubm8ffy4Np4dFkaorXhQbVRV5cgjR8hYXtl6qO2jben8Wudms2fXZDFRWF5IVnEWJwtOkpqXSkZRBkWmIsrN5Q7XU7a+efXxIurHKAwtrL/elJ8oZ9+wfZSfKq/zc7Rzc2NelWJpH6WlsT47+xxXNJxrr72WoKAgAE6ePMm6det0jkgIIRxf3auBCCGEaLQKCwv54osvtHHVmSK9FJhM3HnoEH+nZP/y9+eeKu1hapPyegon3j+hjdtMa0Po7KZRoKrcXE5SThKHsw5zOOswKXkpZBRlcKroFKcKT3Gq6BS5pblY1HNUEv4TFBQ8nD0IbBFIUIsggjyDCGoRRLBnMKH+oYQHhBPeMhxfN9+G+4+rZ94Dven5bU/2XbsPtVyl5EgJe4fvpdfGXjj7OtfpOW5p1YpVmZn832nryoF/x8cT278/3udRRK0+ODs7M2nSJN58803A+iHWtddeq2tMQgjh6CThFUKIZmDVqlUUFVn3M0ZGRjJgwACdI4LpiYkcLS0FwM/JiQXh4XVOVtM+SSP56WRtHDgukC7vdWmUyW5OSQ47Tu5g24ltbD+5nbjMOJJzkjGr5ot+bhWVoooiinKLOJp7tMbzAj0CCW8ZTu/WvRkQMoABIQMI8w/DoDTOhWB+V/kRuSKSuDFxYIGivUXEjoolel00Rg9jrdcrisLcrl35LTeXLJOJlLIynkhMZH54eANEf2533XWXlvCuXr2azMxMAgMDdY5KCCEclyS8QgjRDFRdzjx58mTdE8ONOTl8lJamjT/o0oWQOvYDzlqTRfyUeG3se6Uv3T7thmJoHMluemE6G5I2sD5pPVuOb+Fw1uELfi6DYsDNyQ1XoyuuTq4YFSPl5nKKyoqoUCuosFTU6XkyizPJTMnkj5Q/tGO+br70b9OfwR0Gc03oNfQN7ovRUHuy6CgCbwokfGE48XdZf1by/8wnblwcPb7pgcGp9kQ+yMWF97t0YfzBg4B1afPYwECu9vev17hr061bN2JiYvjrr7+oqKhg2bJlPProo7rGJIQQjkwSXiGEaOIOHz7MH39YExknJyduv/12XeMpMZuZcrgyybupZUvG2/Yl1iZ/az5xY+PANvnZIroFPb7ugcHVcWciK8wVbDq2ibWJa1mXuI69p/bW6br2Pu3pGtCVrv5d6ezXWVuO/Pef/u7+OBvPvkR348aNDBkyBLPFTGF5YbXl0OmF6ZwoOKEtl07ITqDUVHrGc+SW5rI+aT3rk9bz3K/P4efmx1Wdr+KaztcwossI2nq3vai/l4YQfGcwplwTiY9aC09lr8nmyCNH6rwa4JZWrViZmcnXtqXNd8fHs79/f7x0Xto8efJk/vrrLwAWLlzII488ovuHWEII4aga/P/YiqLMBEYD4UAZsAWYqarq/lqu6wm8DwwAsoH5wCtqc6vIIYQQ5+mTTz7RHo8aNUoreqOXF48e5UiJtXKuj9HI+1UKBJ1LSWIJ+0buw1Ji3bfq1tGNqB+jcPJ2vM9uzRYzG49uZGXcSr46+BVZJVk1nutkcCI6KFpbSty7dW+6BHTBw/nii4oZDUZ83HzwcfOhS8DZ/54tqoWUvBTiMuKsS6tPbmPr8a1nxJxTmsOXB77kywNfAnBpu0sZFzmOMZFjCPEOuehY60u7R9pRcaqClNdTADj5wUncw9xp90jtra8URWGebWlzdpWlzR/qvLT5lltu4eGHH6a4uJi4uDh27NhB//79dY1JCCEclR6/JQwB5gLbAQV4GdigKEqkqqpnLYOoKIo3sB7YBPTHmiwvBoqA2fUfshBCNE4mk4klS5ZoY72LVe0sKOCt1FRt/FZoKG3qsJTZlGci9rpYTFnWNizOLZ2JWhuFa3DdlkE3lJ0nd7Jo9yK+PPglGUUZZz3HyeDEpe0u5ZrO1zC001D6BPfBzcmtgSOtZFAMdPTtSEffjozsau3zqqoqybnJbE7dzIakDaxLXEdaYVq16zanbmZz6mYeWfsIl7W7jPE9xjMhaoJDFsDq9J9OlCSVkLkyE4DExxJx6+hG4I217339e2nzbbalzfPT0rilVSuG+vnVa8zn4uXlxbhx47RevIsWLZKEVwghatDgCa+qqsOrjhVFmQjkAZcB39Vw2QTAA7hDVdUSYL+iKN2AxxRFeVtmeYUQ4uzWrl1Lmm2vbOvWrRkxYoRusVRYLNx96BB/1xUe6uvL3XWoymwxWThw6wGKD1p79SquCj2+64FHV/3bKgEUlheyYv8KPtzxITvTdp71nBCvEG6MuJHhocMZ0nEIXq5eDRzl+VEUhc5+nens15nbo25HVVXiMuNYn7ieH478wK/Jv1YrqvVn6p/8mfonT6x/glt63MI9fe7hkraXOMwyW8WgELE4grLUMvL/ygcVDt52ENdNrnj38671+lttVZv/Xto89fBh9vbrh5tRvz3NkydP1hLezz//nNmzZztEqzEhhHA0jrDpyQtrHDnnOCcG+N2W7P5tLdAG6Fh/oQkhRONWtVjVpEmTcNJx7+FbqanstVWKdjcY+Khr1zolRElPJJH9U+UCoIhFEfhc4lNvcdbVodOHmLZmGm1mt2HKd1POSHZbe7bmwQEP8vtdv5PyaArvX/s+14Vf5/DJ7tkoikKPVj14NOZR1k9cT9rjacwfNZ+rO19drZJziamExXsWc+miS4n6MIoPtn1AUXmRjpFXMrob6fFtD9w6W2fTLSUWYkfFUnrszP3L/6QoCu936YK3LcE9XFLCaykp9RpvbQYNGkQX23aA/Px8vvnmG13jEUIIR6XoPTmqKMpKoAvQT1XP3oNBUZR1wHFVVSdXOdYeOAZcqqrqX/84/x7gHoCgoKC+K1asqK/w7aKwsBBPT0+9wxBVyGvimOR1OT+5ubmMGTMGs9n6v9YlS5bQvn17u96jrq9JCvBv4O+awVOBW+pyg++pvnHlduDu84vR3g7lH+Lz1M/54/QfqFR/D3VWnBnSagjXtr6Wnj49MSr6zAA25L+VnPIcNmZu5Pu070kqSjrj+95O3twUchM3hdyEj7P+H1SQAjwAFNjGnbFWCHGv/dJvgP/ZHjsBC4AOdbxtfbwmy5YtY+HChQD069dPa1ck6kbeUxyTvC6OpzG8JkOHDt2pqmq/s31P14RXUZS3gVuBQaqqnvkuWXneOiBVVdW7qxzrABwFYlRV3VLTtf369VN37Nhhv6Drwd/VNIXjkNfEMcnrcn7mzJnDww8/DEBMTAybN2+2+z3q8pqoqsqVe/eyMTcXgL6enmzp0wcnw7kXGeVszGHfsH2oJuv7VMvRLem+qrsu7YdUVeXn5J95/Y/X+Tn55zO+Hx4Qzr1972VS9CQCPAIaPL5/0uPfiqqqbD+5nY93fszy/cspqqg+s+vu5M7dve/msZjH6OTXqUFj+6fcTbnsHbYXtdz6sxU4LpDIFZG1rjiwqCqX7trF1gJrtny5jw8be/XCUIeVCvXxmqSkpNCxY0dUVcVgMJCSkkJIiOMWEHM08p7imOR1cTyN4TVRFKXGhFe3Jc2KorwDjAeuPFeya5MOtP7HsVa2P0/ZOzYhhGgKqharuuOOO3SL47NTp7Rk1wgsjIioNdktOVpC3M1xWrLr2dtTt167f6b8yaBPBjFs6bAzkt2RXUbyy6RfOHj/QR6NedQhkl29KIrCgJABfHz9x5x8/CTvj3ifTr6ViW2JqYT3t79P1/e7MvX7qZwsOKlbrL6Dfek6t6s2zlyZSeqbqee4wsqgKHwUHo6TLcH9PS+PT9LT6y3O2rRv356hQ4cCYLFYWLZsmW6xCCGEo9Il4VUU5X/AbViT3UN1uOQv4HJFUaqWsRwGnMQ6yyuEEKKK/fv3s2vXLgBcXV0ZN26cLnHkVlQwPTFRGz/Sti3RtSyLMpeaiRsThynbVpE5yJke3/bA2KJhlwcfyDzADStuYNAng9icWjk7blSMTOg5gb1T9/L9bd8ztNNQhynO5Ci8Xb25f8D9HH7wMMtvXk7v1r2175ksJubvnE/YnDCeWv8U2SVnbdBQ74LvDqbNfW20cdLMJLLX1R5LlKcnj7et7EH8RGIiGeXl9RJjXVT9MGvJkiXovVVNCCEcTYMnvIqifADchXV2N0dRlNa2L88q57ymKErVj9E/B4qBxYqi9FAUZTQwA5AKzUIIcRaffvqp9vj666/HT6cWKs8dPcqpCuvO3RAXF17o2LHWa448eITCnYUAKM4KPb7ugVu7hmvbc7LgJP9e/W96zuvJ6vjV2nFngzP39buPhAcTWDZ6GVFBUQ0WU2PlZHDi1h63svOenay7fR1XdLhC+16JqYRZm2fR+X+d+e/v/6WkouQcz1Q/wt4Nw2eQbV+xBQ7ceoCSxNrjeL5jRzq5WX8mc0wmHjtypD7DPKfRo0fTokULAA4ePIijb+MSQoiGpscM7zSslZl/BtKqfE2vck4wEPr3QFXVPKwzuiEDPDIAACAASURBVG2AHcAHWMuYvN0wIQshRONhNpurLW3UaznzzoIC5p44oY3fDQvDq5Yq0WmL0khbUNnvNfTtUHxiGqbQkcli4p2/3iH8/XAW7l6IRbVo35vQcwLxD8Qzd+Rc3fefNkaKojAsdBi/3vEra29fS9/gvtr38sryeOaXZ+g+tzvfxdfUnbB+GFwMRK6KxCXEBQBTjon9N+3HXHTWGpoaD6ORubYKyQCfZWTwS865mk3UH09PT8aMGaONq37YJYQQQoeEV1VVpYavF6ucc6eqqh3/cV2sqqqDVVV1U1U1WFXVl2R2VwghzrRhwwat926rVq0YPnx4LVfYn1lVue/wYa3n7nA/P24ODDznNQW7C0i4P0Ebt7qtFSH3N0wBns2pm+n7UV8eW/cYheWF2vFrQq9h1z27WDZ6mSS6dqAoCteEXsP2KdtZNXYVXQMq99Em5yZz/YrrGfX5KBKzE8/xLPbl2tqVHl/1QHGxLksvii0i/t/xtS4N/ldAALe2aqWNH0xIoMJiOccV9afqh1rLly+nXMcl1kII4WgcoQ+vEEIIO6o6wzNhwgRdeu8uSEtju62SrYui8F6XLufc51qRU0HczXFYSq0Jg0d3D8I/Cq/3vbFZxVlMWT2FyxZdxr5T+7Tj3Vp2Y93t61h7+1p6B/c+xzOIC6EoCmMixxA3LY55I+fh7+6vfW9Nwhq6z+3O878+T6mp9h659uA90Juu8yqT74wVGaR9lHaOK6xmh4biaevNe6C4mPerrGhoSFdccYXWciwrK4s1a9boEocQQjgiSXiFEKIJyc/P5+uvv9bGeixnziwvZ2ZSZfH9Ge3b08XDo8bzVYvKwYkHKU22JjdGLyM9/q/+i1Stjl9N5NxIFuxeoB1zd3Ln9ateZ8/UPQwLHVav9xfWPb5T+03l8AOHuafPPShYP+AoM5fxyqZX6DO/D9tObGuQWIInBxN8T7A2Tng4gcK9hee4Atq4uvJCh8pOvC8cPUp6WVm9xVgTg8HAxIkTtXHVCu1CCNHcScIrhBBNyKpVqygpsRbdiYqKIjo6usFjmJmURI7JWmG5s5sbM2wzTzU5/s5xstdUVseNWByBR9eaE+SLlVeax13f3sUNK24goyhDO35D+A0cvP8gTw16ChejS73dX5wpwCOA+dfNZ+u/t9K/TX/t+MHTB4lZGMOMDTMaZLY37N0wWkRZC0CpZSpxY+MwFZjOec1DbdsS7u4OQIHZzFNJtXVarB+TJk3SHq9Zs4bMzExd4hBCCEcjCa8QQjQhVZcz6zG7u7OggEVV+pK+16UL7saaZ2oLdhaQNLMyQWj7eFsCR597r+/F+CX5F6I+jGLxnsXasWDPYL699Vu+ufUbOvh2qPliUe/6h/Rny7+3MPfaubRwtiaeFtXCG3++0SCzvUZ3I91XdsfQwvrrUUlCCYfvPXzO/bwuBgNzqhSw+vTUKTbn5dVrnGfTtWtXYmJiADCZTCxfvrzBYxBCCEckCa8QQjQRycnJbNq0CQCj0chtt93WoPdXVZWHExL4OzUYFRDAtQEBNZ5vKjBx4NYDqBXWK7z6e9H5v53rJbZyczmP/vQoV316FSl5Kdrx8T3Gs3/afq4Pv75e7ivOn0ExcF//+9g/bT9XdrpSO/73bO9LG1/CbDl3FeWL4RHuQfj8cG2csTyjWuXws7nG35/RLVtq4wcSEjDrUFfznz15hRBCSMIrhBBNxtKlS7XHw4cPp3Xr1g16/y8yMvgzPx8AZ0VhdmjoOc9PeDCBkiPW5ddGLyORyyMxuNj/belY7jEu/+Ry3t36rnYswD2AlWNW8vnNn1crmCQcR0ffjqyfuJ4Prv2g2mzvi7+9yLClwzhZcLLe7h00IYjgf1fZz/tg7ft53w4Lw81g/fndXVjIxyfrL76ajBs3DldXVwB27drFgQMHGjwGIYRwNJLwCiFEE6Cqqq7LmYvNZp6ssnfx4bZt6XqOQlWnPjvFqSWntHHXeV1xD3W3e1zfH/6e3vN7V1sKO7LLSPZP28/Y7mPtfj9hXwbFwLT+04i9L5bBHQZrx389+iu9PuzFT0d+qrd7h80Jo0XPyv28B249gLm45pnlDm5uPF1lv/ozyclkVVTUW3xn4+fnx3XXXaeNP/vsswa9vxBCOCJJeIUQognYunUriYnW3qU+Pj5cf33DLtF9MzWVVFt12kBnZ57tUPNe2JKkEg7fd1gbB00MImhCkF3jMVlMzNgwg+uWX0dOaQ5grQj8zvB3+G78d7T2bNjZb3FxOvl14pdJv/DCFS9olZwzizMZ8dkInlr/FBVm+yeWRncjkSsjtf28xYeKSXrq3AWpnmjXjk5ubgBkm0y8cvSo3eOqzYQJE7THn3/+ea39hIUQoqmThFcIIZqAqjM5Y8aMwc32S3dDSC0t5Y2Uyn2x/+3UCZ8aev9aKiwcGH8Ac4F1psw9zJ0uH3Q567kX6nTxaa7+9Gre+PMN7Vhb77ZsunMTj1zySL339hX1w2gw8uKQF/l50s8Ee1YuN561eRbDlg4js8j+VYlbRLQg7N0wbXzi/RNk/ZhV4/luRmO1pfwfnDxJfHGx3eM6lxEjRuDr6wvA0aNH2bx5c4PeXwghHI0kvEII0chVVFTwxRdfaOOGLlb1VFISJRYLAL09PbkrOLjGc1NeS6FgWwEAipNCt+XdcPI6e3J8IQ5kHmDAxwP47dhv2rERYSPYfe9uYtrF2O0+Qj9DOw1lz9Q9DA8drh377dhv9P+4P3vT99r9fsF3BxNwfWXxtfjJ8ZSfLq/x/BtbtuQKHx8ATKrKk7aVFw3F1dWVsWMrl+vLsmYhRHMnCa8QQjRyGzZs0HputmnThiuuuKLB7h0LLM+o7GX7v7AwjDXMoBbsLODYK8e0cadXO+Hdz9tusfyY8CMxC2NIzk0GQEHhlaGv8P1t39PSo2UtV4vGpFWLVvww4QdeHfqqtsT5WN4xLl10KV8d+Mqu91IUhfAF4TgHOQNQnl7O4Sk1typSFIW3w8L4+1/B6qwsfsnJsWtMtan6odfKlSupaOC9xEII4Ugk4RVCiEau6gzO+PHjMZ6j7609qarK3CrjcYGBXG5bSvlP5lIzB+84iGqyJgnel3nTbno7u8Xxvy3/Y9TyUeSXWatEt3Buwde3fM2zg5/FoMhbXVNkUAw8M/gZvr31W7xcvAAorihmzKoxPP/r81hUi93u5RLoQsSiCG18+pvTpH+SXuP5fby8mBRUuS/98cRE6q+R0pkGDx5M27ZtAcjKymLt2rUNeHchhHAs8luAEEI0YkVFRXzzzTfauGrBmvr2ZWYmh2yPXRWFWedoQ3T0haMUx1n3Mho8DEQsjkAxXvxeWpPFxH1r7uORtY9oCU4773b8OflPboi44aKfXzi+68KvY8u/txDqV/nz98qmV7j1y1spNZXa7T4B1wbQZlobbZzwUAIliSU1nv+fzp1xt7Up2lNYyDq7RVI7g8HA+PHjtbEsaxZCNGeS8AohRCO2evVqioqKAOjWrRu9evVqkPuWWyzMrNKG6KG2belQQ6GsvD/zSH0zVRuHvhmKR1jNLYvqqtRUythVY5m/c7527JK2l7BtyjaiW0df9POLxiMyMJJtU7YxrPMw7diqA6v417J/kVuaa7f7hL4Zinu4tX2WpcjCwUkHUc1nX9oc4urKk+0qVzEsBApNJrvFUpuqH359++23FBQUNNi9hRDCkUjCK4QQjVjVmZsJEyY0WAXi+SdPklhqnT3zc3JiZpX+o1WZi6xLmbHlBH5X+9Fmapuznns+8svyGfHZCL45VDm7Pb7HeH6941dpOdRM+bv788OEH3ig/wPasd+O/cbln1zO8fzjdrmH0cNI5GeRKE7Wf2f5m/M5/l7Nz/1E+/YEu7gAkIW1fVdDiYqKonv37gCUlJRUWwkihBDNiSS8QgjRSJ0+fbra3ryGqs6cZzLx8rHK4lPPduiAn7PzWc9NfCqR0kRrYmz0NhK+KBzFcHFJ+anCUwxZPISNRzdqxx6PeZxlo5fh5tRw7ZiE43EyODFnxBxmXT1LO7Y/Yz8xC2OIy4izyz28+nrR/unKD3iSn06m+MjZWw+1MBr5b6dO2vjN1FRO2PpV1zdFUarN8sqyZiFEcyUJrxBCNFIrV67EZFsiGRMTQ6cqv1jXp1kpKZy2VX1tDdwfEnLW83J/y+XkBye1cZc5XXBrd3EJaXJOMoM+GcTu9N3asTeufoO3rnlLilMJwJroPXHZEyy9aSlOBmvLq+P5xxn0ySD+SPnDLvfo8EwHWvRsAYClxEL83fGolrMvbZ7UujW9PT0BKLFYeOnoUbvEUBdVPwRbv349p06darB7CyGEoziv3w4URfnZ9ueziqKMUBQlqLZrhBBC1I9/LmduCMdLS3n7eOUSzrsBV8OZbyXmEjPxU+K1ccD1AQRNuri3jPjT8Qz6ZBBHso8A1iq9C69fyJOXPXlRzyuaptujbueH237A08WabOaW5jJ82XB+Tvr5op/b4GIg4pMIsBVEz9uUx8l5J89+rqLwRufO2nhRWhrxxWefEba3Dh06MGjQIAAsFku1ft1CCNFcnO/H4Tfb/nQG7gf2KIpyXFGUbxVFecG+oQkhhKhJcnIymzdvBsBoNDJu3LgGue8LR49SarFWQ+7j6cmVNZx37JVjlCRYK9gavY10ndf1ovYXx5+OZ+iSoZwssCYVrkZXvhr3FZN7T77g5xRN37DQYWy6cxNBLawfthRXFDNq+Sh+OvLTRT+3V18v2j9ZubQ58alESo6evWrzMH9/+tgem4FnqhR8q2+yrFkI0dydV8Krqmqu7c8XVFUdpapqMDAQa/FBWUsmhBANZPny5drj4cOHExgYWO/33F9YyOL0yt6jb4aGnvV//AV7CkiZlaKNQ98MxbWN6wXf9+9kN60wDQAPZw9+nPAjN0bceMHPKZqP3sG92XTXJkK8rEvvS02l3LDiBlbHr77o5+7wfAc8ulkrjluKLByechhVPfvS5nuqPP7q9Gm25edf9P3rYuzYsTg5WZd2b9u2jYSEhAa5rxBCOIo6J6mKopz1txVVVU+oqrpaVVWZ4RVCiAagqqouy5mfTk7GYns8wt+fK/38zjjHYrIQ/+946zQW/8/efcc3Vb0PHP/cNG3ppoPulj0VBAQFBwIOBPQHyHILouhXQBBUXKgg+BUXLhQXbmXJ3qAgQ0VRHKB8QSgUuoHSvXN/f5z0JqGDjqQt+Lxfr7ySk5x77q0lNU+ec54DAb0CiLgnosbnrCjY7dO8T43HFP8+bYLbsG30NpoGNAWgsKSQoYuGsuSvJbUa162Rm5rabP00lb45naQPksrt2xYYbvfF1GOHD1cYHDtTcHAw/fv3N9pffvmly88phBANyVkDXk3TemuadhTI1TQtXdO07zRNm6Np2p2apl2oaVIlRAgh6tLvv//OX3/9BYCPjw+DBg1y+Tl/zMhg1cmTAGjAC3ZrEu0lvJ5A9i/Zqp+nRtv3a16VuaJgt1fTXjUaT/y7tQhswbbR22gZ2BKAYksxNy+5mQV7F9RqXP9L/YmZbNtv99AjhyhILr8S88zmzUuX/bLl9Gk2pqfX6txVdea05roItIUQoqGoSrA6F8gFxgOvoraSGwx8DPwBZLvq4oQQQpRln90dPHgwPj4+Lj/nk3FxxuNbQkPpZK06ay/vcB5x02z9mj3TDO823jU63+H0wxLsCqeLDYhl2+httA1uC0CJXsLtS29nxf4VtRq32YxmeLXyUmNmlHDooUPl9mvj7c09EbYZD1MPHcJSB8HnjTfeiK/1PXvw4EF2797t8nMKIURDUZWAtznwsK7r7+i6/pyu6zfput4cCAKuAZ5y6RUKIYQwlJSUOKzfrYu9d79JT+fb06cBVZR2erNmZfrous6B+w5gyVOTnn06+RDzcEyZflWRlJXEtZ9dK8GucIlIv0i+G/UdFzS5AFBB74glI9h0aFONx3TzcqP1O62NduqCVE5tOFVu36ebNcPLWtn895wcFqSm1vi8VeXt7c1NN91ktKV4lRDi36QqAe9+VFVmB7qun9Z1/Vtd1191/mUJIYQoz7Zt20hISAAgJCSEa6+91qXn03XdoaLs3RERtPIum7VN/SqV9M3W6ZkmaPtBW0zu1V/xkp6XTr/P+3E4XZ2zkbkRa29dK8GucKow3zA23bGJVkGtALWmd/DCwbXapzfomiDCbrdtvXXggQOU5JWU6Rfp6cmk6GijPS0ujkKLpUw/Z7Of1rxgwQJjD28hhDjfVeXTyKvAPa6+ECGEEGdnX3Bm5MiRuLuX+T7SqVadPMmurCwAPDSNaU2blulTnFHMoSm2KZzRD0bj392/2ufKLcrlxq9u5M/UPwFw09xYNGwRVzW7qoZXL0TFIvwi2HzHZmL81UyE3KJcBn45kF8Sf6nxmC1faYk5UFVEzj+cz9GZR8vt92hMDIHWysmH8/Mdqp+7St++fQkLUwF5SkoKW7Zscfk5hRCiIahKwNsLaK9p2kJN09q6+oKEEEKUr6CggCVLbFVlXV2d2aLrPGW3dveBqChiGjUq0y/umTgKkwsB8IjwoNn0ZtU+V1FJEcMXD2fnsZ3Gc/MHzefGtjdWeywhqqpp46Z8c+c3xj69mQWZ9Pu8H/tS99VoPI9QD1q8aCvoduzFY+TsyynTr7G7O1NjbXv4zjx6lAIXZ3nNZjM333yz0V64cKFLzyeEEA1FVQLey4FYYDjwl6ZpRzVNW6pp2lOapvXXNC3sLMcLIYRwgvXr13Paupa2efPm9OjRw6XnW5iayp856sO6j8nE43Yf0A3/QMKbCUaz5astMfubq3Uei25h9IrRrD241nhuTr853HnRnTW7cCGqoXVwazbdsYkgryAATuadpN/n/TieebxG40XcHUHAFQEA6MU6/7vvf+iWsoWpxkdFEWqdoXGsoID3ExNr+BNU3ciRI43HS5cupbCw0OXnFEKI+nbWgFfX9QsAX+AS4H5gNRAOTAXWAK7/Cy2EEMIhI3PLLbegaTXb7qcqiiwWnj5yxGhPio4m1MPDoY9u0eE1KN2ct3HfxoSODK32uaZ9O40v/rQV0XnqyqeY1GNSTS5biBrpGNaR9betx8/DD4CErAQGfDGAjPyMao+lmTTavNsGzV29PzN3ZpI0v+zevD5ubjxm9yXS8/Hx5JWUXfPrTJdeeikxMWoKd3p6Ot98841LzyeEEA1BlSqK6LpeoOv6bl3X39d1fZyu65cB/kAHwPUlQoUQ4l8uNzeXlStXGm37TI0rfJqSwj95eQA0Npt5OKZsxeXkT5LBOvNTc9doPbd1tYPwj/Z8xPM7njfa9118HzP6zKj5hQtRQ92jurNs5DLMJjVD4c/UP7lp0U0UllQ/C+rTwYeYR2zvmcOPHYbMsv3uj4wk0vpFUlJhIfNcnOU1mUyMGDHCaMu0ZiHEv0H1S2ha6cp+Xdflr6UQQrjYmjVryLFOL27Xrh0dO3Z02bmKLBZmHrUV23kkJobGZxTHKjpVxOFHbdWbYx6Owadd9fYD3hK3hbGrxxrtAa0H8NaAt1yauRaiMle3uJr5/zffaH8b9y1jVo5Br8FeuU2fakqjZmrNe/HJYphfto+XmxtP2BWCeyE+nhwXZ3ntvyxbvnw5BQUFLj2fEELUtxoHvEIIIeqOfSZm5MiRLg0KP0tJ4Uh+PgDBZjMToqLK9Dn8xGGKThQB4BnrSdMny1Zvrsz+E/u5adFNFFvU1iidwjqxYOgCI7smRH2546I7mNlnptH+/I/Peerbp6o9jpuXGy3ntLQ9sQqyf88u0++eiAhiPD0BSC0q4q2EhDJ9nKlbt240b94cgIyMDDZu3OjS8wkhRH2TgFcIIRq4rKws1qxZY7RdOZ35zOzulJgY/MyOQWjWniyS3rOtSWz1eivcfNyqfI4TuScY+OVATuerAlwRvhGsvmU1fp5+tbx6IZzjiSuf4N6u9xrt53c8z3u/vFftcUIGhRB4XaBqWODghINlssWeJhNP2WV5X4yPJ9OFe+RqmibTmoUQ/yoS8AohRAO3cuVK8q0Z106dOtG+fXuXnevzlBTirOcKMpsZf0Z2V9d1/pn4D5R+Zr9UfaivqoLiAgYvGMzhdDUd2tvdm1W3rCImoOwaYSHqi6ZpvD3wbQa0HmA8N27tOL478l21x2n1eis0s5qRkbE9g9SvUsv0Gx0eTnPrll+niot543jNKkRXlf2XZitWrCDPul5fCCHORxLwCiFEA3fmdGZXqUp2N21JGhnbVeVazazBA1RrevXE9RONvXY1NL646QsujrzYCVcvhHOZTWYWDltI14iuABRbihm6aChx6XFnOdKRTzsfoidFG+1DjxyiOMsxg+tuMvG0XZb3lePHyXBhlrdz5860atUKgOzsbNavX++ycwkhRH2TgFcIIRqw06dPO3wYdWXA+0VKCocrye6W5JVw6JFDRjtqfJTapb2KPvj1A9795V2jPfua2QxuN7h2Fy2EC/l6+LJ85HLCfMIAtUfvoAWDyC4suxa3Mk2nNYVg9bgwsZCjM4+W6XN7WBitvbwAOF1c7NK1vJqmOfwtWbRokcvOJYQQ9U2qgwghRAO2fPlyiopUcahu3brRsmXLsxxRM8VnZHcnx8Tgf0Z29/irxyk4qiq6moPNNH26Kcd/r9rUy13HdzFu7TijffOFN/PwZQ874crPM0VFkJkJWVmQnW27z8tTrxUVQWGhutd1MJvVzd3d9thsJvCvv9RzAQHQuLG69/UFqYBdbTEBMSwbuYzen/SmsKSQP1P/5M5ld7JkxBJMWtXyBmZ/M9wHWHfgOj7nOBF3R+Dd1tvWx2TiyaZNGbV/PwBzjh1jYlQUvmbXfFQbOXIks2bNAmDVqlXk5ubi7e19lqOEEOLcIwGvEEI0YAsWLDAeuzS7m5rKIWt2N7CcyswFiQUc/a8tIG7+XHPcAx23KqpISnYKQxcNNfYz7RTWiQ9u/ODftf1QYSEcPw7x8ep27Ji6T0mBtDTb7fRpp5zuovKeNJlU4BsQAIGBEBYG4eHqFhGh7ps1gxYtIDhYgmM7PWN6Mm/gPO5eeTcAy/YvY/rW6UzvM73qg1wD/t/5k7kzE71I558p/9BpdSeHLreGhjL9yBHi8vM5WVzMO4mJPBJbjWkU1XDhhRfSrl079u/fT05ODmvWrGH48OEuOZcQQtQnCXiFEKKBOnHiBJs3bzba9pVVnanYYuG5I0eM9uTo6DLZ3cOPH8aSYwHA50IfIu6NqNLYRSVFDF88nIQsNT0zsFEgS0csxcejenv2njNOn4bff4f9++F//7PdHzkCFkv9XpvFAunp6mb3+y6Xn58KfO1vrVrBBRdAZOS/Mhge3WU0f6T8wWu7XgNgxrYZdAzryLAOw6o2gAat32zNLxf/AjqcWnOKU5tPEXRNkNHF3WTi8dhYxh44AMDLx44xLioKb7eqV0GvqtJpzdOnq6B90aJFEvAKIc5LEvAKIUQDtXTpUkpKSgDo2bMnsS7K9Hx1ZnY3Otrh9cyfMkn5NMVot3qtFSZz1aZyPrzxYbbHbwdUkaovh35JyyDXTMuuc6dOwY8/wq+/wp496hZXvYJGZWiaysD6+dluvr7g7a2mKNvfNA1KStT05uJidbM+PpWaSpC7uwrAMzLULTe36teRlaUC999/L/taYCB07AgXXgidOsHFF6u2dS/Z89lL173EvrR9bDq8CYDRK0bTMbQjbUPaVul4vy5+hI8OJ3l+MgCHphwi8NdANDfbFwh3hYfz3NGjHCsoILWoiPcSE5kU45oq5iNGjDAC3jVr1pCdnY2vr69LziWEEPVFAl4hhGig7Ksz33zzzS45h0XX+W98vNGeFB1NgF12V9d1/nnoH6MdPCiYwKsDqzT24n2LeeOnN4z2rL6zuL7V9U646noSHw/bt6vbjh2wb1/Vj9U0lRmNjYWYGNt9ZCQ0aWK7BQWBE7J5f2zdSu/evR2fLCpSge/p0yrLm5xsuyUlQWKiCtgPHYKcnIoHT0+HbdvUrZSHhwp+u3dXtyuuUBnh8ywTXFq5ufv73TmUfojswmyGLhrKrnt2VXnWQvPnmpO6IBVLroWcP3JI/jiZiDG2GRMeJhNTY2MZf/AgAC8eO8b9kZE0ckGWt0OHDlx44YXs3buXvLw8Vq1axS233OL08wghRH2SgFcIIRqg5ORktm7dCqiph8OGVXHaZDWtOHGCv62ZPz83tzJrd08sPUHm95nqOtw1Wr5ctezs4fTD3LPqHqM9pN0QHrviMSdddR3JzYXvvoN162D9erAGIJVyd1fTfi+8ENq2td1atwZrBd564+4OISHqVhldhxMnVOB7+LC6HTqkpmbv3auyv2cqLITdu9XtnXfUcxER0KsXXHWVuu/Q4bwIgAO9AlkyYgk9P+xJfnE++9L28Z81/+GTwZ9UaV26Z6QnsVNjOfLMEQDinoqjycgmmH1tH8nGhIcz6+hRkgoLSSosZH5yMg+c8d50lpEjR7J3715ATWuWgFcIcb6RgFcIIRqgJUuWYLGu+ezVqxeRkZFOP4eu6zxvl919IDKSQHdbISpLkYXDjx022lETovBudfYqroUlhYxcMpLMAhUoN2/cnI8GfXRuFKlKSYGlS2H5chXsFhRU3NfNDbp2hUsvhS5d1O2CC1S281ymabaMc48ejq/puiq4tXevuu3ZAz//rALiMyUlwcKF6gYqm3399ep27bWqevQ5qnN4Z+YOmMuYlWMA+OyPz7gy9kruvfjeKh0fMyWGxPcSKUwopDC5kGMvHqP5jObG643c3HgkJobJ1v+uL8THc09EBB4m5+8mOWLECKZNmwbAunXryMzMxN/f3+nnEUKI+iIBrxBCNED205ldVZ15c3o6u63ZukYmEw+dsU4w6b0k8v7JA8Dc2EzTJ5tWadzHNj/G7sTdALib3Fk4bCEBjQKceOVOVhrkLl6sJKkOtAAAIABJREFUgtyKikt5ecHll6vpuldeqQJdn/O0+FZFNE1Nx46NhQEDbM+fOqWyuz//DN9/r6Z8Z2Y6HpuYCPPnq5ubmwqmBw2CoUNVUaxzzN1d7mZH/A4++u0jACasm0C3yG50iehy1mPdfNxoMasF+0epLYiOvXyMiLERNIpuZPS5LzKSF+LjSS0q4lhBAZ8kJ3OvC774atOmDZ07d+a3336joKCAlStXcvvttzv9PEIIUV+c/1WhEEKIWjl+/Dg7duwAwM3NjaFDh7rkPPbZ3THh4YTZZSaLs4o5Mv2I0Y59Ihb3oLNvQ7TyfyuZ8+Mco/3itS/SPaq7cy7YmQoKVIB7/fUq8/jAA7BlS9lgt0MHmDwZNm5UQd2mTfDMM9C3778v2K1MUBBcdx08+SSsWaP+W/36K8yZA0OGqEJX9kpKYOdOePRRaNlSZcqffx6s1YnPFW8NeIuOoR0BKCgpYNjiYZzOr9rWUmF3hOHbVRWIsuRZiHvSseCZt5sbU+y+hPpvfDzFLqr0bf+lmv2XbUIIcT6QgFcIIRqYRYsWGY/79u1LaGio08/xfUYGW617vpo1rcxen8deOkZRWhEAnrGeRE04+/rB+Ix4Ri0fZbRvbHMjEy+d6LyLdoZ9+1QAGx0NI0bAhg2OQa6mqfWmb74JR4+q/q+8oqbgNmpU8bjCkZubmuI9aZLKnqemqszvtGmqqNWZ09v37FHBctu2Kvh94w21jriB83b3ZsmIJfh5+AFq7fqYlWPQdf2sx2omjZav2NbEp3yaQuZux6z4fyIjCbIWkYvLz2dJWpoTr97GfsuzDRs2kJ6e7pLzCCFEfajzgFfTtF6apq3UNC1B0zRd07RRZ+nfzNrvzNs5XOpTCCEqVhfTmZ8/etR4fFtoKE3tgrmCxAKOvXLMaDd/rjlujSqvEFtsKebWr28lPV99UI72j24463ZLStSa3F69VDGpOXMcgyn7IDchQU1rHj9eTdsVzmE2Q8+eMGMG/PSTmkb+0Udwww1l1zzv2QMTJ6rM+5AhsGKFqjDdQLUJbsP8QfON9tK/l/LBrx9U6djA3oEEDwo22oenHnYIlv3MZodCci/Ex1cpmK6uFi1a0K1bNwCKiopYvny5088hhBD1pT4yvL7AXmAikFeN464HIuxu3zr/0oQQon7FxcXx008/AWA2mxkyZIjTz/FbVhZrTp0CQAOmnhHYHXn2CJZclfX0uciHsNvCzjrm7B2z2XlsJwBumhtfDf2KYO/gsxzlYrm5qmJw+/YqcNq+3fH1mBg1PTkuzhbkRkSUP5ZwriZNYNQoWLVKZX8//xwGD3bcy7eoSH1RMXgwNG0K06erLZQaoGEdhvFAtweM9qQNk9h/Yn+Vjm35Ykuwfp90+tvTpG9yzK6Oj4rC21qs6vecHDZY37vOZv/l2tdff+2ScwghRH2o84BX1/W1uq4/oev6EqA6i1FO6rqebHcrdNU1CiFEfVm8eLHx+LrrriMoKMjp53jBbu3uTSEhtLdbi5rzVw5JHyYZ7ZYvtkRzqzxL+0viLzz73bNG+9nez3JF7BXOu+DqyshQwVFsrFqba7+dkNkMw4apbYbi4uDZZ1UwJepPQADcdhssW6YC2nnzVDbYXlKS+l3Fxqq+P/6oKkY3IC9f9zIdmnQAILcol1u/vpWC4kqqfFt5t/Em4h7bFy2HHzuMbrH9bCEeHtxr90WM/fvXmexrBWzatInMM4uOCSHEOepcWsO7VNO0VE3Tdmqa5poNKYUQop7ZB7z26+qc5WBuLovt1gE+cUawd/jxw8ZXkYHXBhJ0XeUBd0FJAbcvu51iSzEAl8VcVn/77WZnq8JHzZur4OjkSdtrAQGqQFJcnCpW1a+fWmcqGpbGjeG++9R63/374YknHLPuRUXw5ZcqIO7ZE1aurLiqdh3zcvfiq6Ff4emmstR7kvfw1LdPVenYZk83w+SlPpJl78kmdVGqw+uTY2IwW5cHfJeRwQ8ZGU68cqV58+Z06aIqTBcWFrJ69Wqnn0MIIerDuRDwZgMPAyOAAcA3wEJN06RmvhDivHLkyBF277Zu5+PuzqBBg5x+jleOHTOm1vQLDKSrn5/xWsaPGZxcaQsSW8w++1Yx78W9Z0zd9HH34dPBn2I21fGOd7m5qrBU8+aq8JF9wZ3mzeH11+H4cZg9WxWrEueGtm1h1ixVPGzBArUllL1du9S2Rp07q9dLSurnOu10CuvEi9e+aLRf/uFlNh3adNbjPCM9iZ5o+7cZ91QclkJbIB/bqBG32RWvm10HWV6Z1iyEOF9orih+UOWTa1o2MF7X9Y+redzbwBW6rneq4PWxwFiAsLCwixcsWFDbS3Wp7OxsfH196/syhB35nTRM5/vvZeHChcybNw+ASy+9lBdeeMGp458CbgZKy/+8CjjsGDoZ2GN93BeYVvl4u0/t5pE/HzHaU9pM4YaIG5xzsVWh64R++y0t583D84yKvnmRkRy56y5Sr74a/V+YyT1f3yu+Bw4QtWwZYd98g+mMQla5UVHE3347yddeW6/Ze13XeXzv4+w6tQuAYI9gPrj4A8yF5sp/J9nArUCWtT0RGGx7+Qgw2q77R0Az5102APHx8dx1110AeHp6smzZMry8vJx8lobjfH2fnOvk99LwnAu/kz59+vyi63q38l47VwPeu4B5uq6f9a9wt27d9NKMSUO1detWevfuXd+XIezI76RhOt9/Lz169GDXLvUhef78+YwePfosR1TPtLg4ZlqrM3fz8+Onrl2NKsrp36Tz+zW/q45ucMnfl+Dd2rvCsdLz0un4TkcSshIAuKHNDay8eWXdVWXeswcefBCs+xUbYmPh6afhzjvB/ez7Bp+vzvf3CklJKqs/bx7k5Di+dsEF8MILMHBg2e2P6khKdgqd5nUiNUdNTR7SbggTQifQp0+fSo+Lfymew48eBsA9zJ1L/7kUs69txsTgP/9khXWq/l1hYXzcvr3Tr/3CCy9k3759gFpiMWzY+buK7Lx/n5yj5PfS8JwLvxNN0yoMeM+FKc3l6QwknbWXEEKcI+Lj441g12w2O306c05JCW8nJBjtR2JijOBU13UOP3nYeC18VHilwS7AuLXjjGA3xDuED278oG6C3bQ0GDsWLr7YMdgNC4O5c+HAARgz5l8d7P4rRETAyy+r6c5PP63W/pbatw9uvBF691bFrepBmG8YHw/62Ggv27+Mzambz3pc1PgoPKPVGuCilCISXk9weP0xu4rqX6SmEp+f75wLtiPTmoUQ55v62IfXV9O0zpqmdbaeP9bajrW+/l9N076x63+Xpmm3aprWXtO0tpqmPQyMA96s62sXQghXWbJkifH46quvdnp15vlJSZwqVoWlmjdqxE0hIcZrJ1efJGuXmkepeWg0e7pZpWMt+3sZX+39ymi/f+P7hPmefeuiWtF1tXVNu3bw/vu2Cr1mMzz8sAp0H3jAcVsbcf4LDlYVuY8eVff2U+62bVOFrUaMgGPHKh7DRfq37s/9F99vtN/45w0SsxIrPcbNy41mzzYz2vEvxlN00jZ1u0dAAFcFBABQrOu84oKfyz7gXb16NfkuCKqFEKIu1UeGtxtqldgewAuYbn08w/p6BNDyjGOeAnYDP6OWoN2t6/qcOrlaIYSoA/YB7/Dhw506drHFwqvHjxvtKTExmK37euoWnbin4ozXIu+PpFFsowrHSs9L54G1tv1G+4X1Y3C7wRX2d4rjx1XG7o47wH4P0uuvh7174aWXwN/ftdcgGjZ/f5XpPXRI7adstiuctnix+qJk9mworNsdDV+67iWaNW4GQHZxNmNXjeVsS8nC7grDu52aYVGSWUL8C44FquyzvB8mJZF+xlrm2urYsSOtWrVS15ydzaZNZy+6JYQQDVl97MO7Vdd1rZzbKOvro3Rdb2bX/xNd1zvouu6j67q/ruvddF3/vK6vWwghXOXYsWP88MMPALi5uTF4sHMDyCVpaRyxZmmCzWZGh4cbr6UtTiPnD7UG0uRtoukTle9JO3njZJKzkwEI9w1nXMtxTr1WB7oOH3yg1mSuWWN7vmlTWLUK1q5VlXyFKBUaCm++CX//DSNH2p7PzYXHHlMVnbdsqbPL8fXw5aNBHxntNQfX8PFvH1d6jMlsovms5kY7YW4CBcm2/Xz7BQXR0bp3do7FwruJlWeNq0vTNJnWLIQ4r5yra3iFEOK8sXTpUuNx3759CQ4OdtrYuq7zkt20x/FRUXhbK9haii3EPW3L7kY/GI1HmEeFY234Z4PDh/V3Br6Dn7tfhf1rJSlJ7ZV7772QmWl7fvx4ldW94YZ6K0gkzgGtWqmtirZvh052Gzr8/Tf07Qu33QZnVPZ2ld7NevPgJQ8a7UkbJnEso/KpyCFDQvDtoqZnW/IsDlleTdOYbLe91psJCRQ6eS9i+4B35cqVFDk5iyyEEHVJAl4hhKhnixcvNh47ezrzt6dP82t2NgCNTCbGRUUZr6V8mkLegTwA3ALciHkkpsJxsgqyGLt6rNEeccEI101lXr8eLroI7KdStmql1mS++abjOk0hKnPFFfDLLzBnDtjtOc2XX6qZAytW1MllPH/180R5qfdeZkEmY1aOqXRqs6ZpNJvRzGgnzkukIMGW5b0lLIxwD/XlVGJhIQtSU516vd26dSPWOnU6PT2dLXWYFRdCCGeTgFcIIepRQkICO3fuBFwznfmleFtm6O7wcJpYPyRbCi0cfe6o8VrMwzG4B1Vc2fixzY8Rn6HGCvYK5s3+LqgbWFQEU6dC//6qGjOoLO6UKfD773Dllc4/pzj/mc0waRLs3w+33GJ7PjUVBg9WW1ilp7v0Enw8fJjadioaalbCpsObeP/X9ys9JnhgMH6XqCBdL9A5+rzt/eppMjHB7surV44dO+va4OrQNI2bbrrJaNvXGBBCiHONBLxCCFGP7Kcz9+7dmyZNmjht7D+zs9lg/SBvAibH2DK4yZ8mk39Eres1B5uJnhhd3hAAbDu6jbd3v2203+j/BqE+oU67TgDi4lRA++KLtufCw2HzZrX9jHfl2yQJcVaRkSqzu3q12tao1GefwYUXwrp1Lj19x4COTO452Wg/sumRSqs2a5pG8xm2tbxJ7yeRf9RWMfn+yEi8rcXn/sjJ4RsnB+32++8uX76ckpISp44vhBB1RQJeIYSoR/bTme0/YDrD63aVmYeEhNDSywsAS5GF+Fm2zG/MwzGY/cxljgfIL87nnpX3GO0b2tzALRfeUm7fGtu4Ebp2Bes+xICqwPz772q9pRDONHCgWgd+++225xITYcAANZvAhZWcn+vzHK2DWgNqavOEdRMq7R94XSD+l6sK5HqRztFZtixvkLu7QwG6l528RVHPnj2JsH4xkJaWxvbt2506vhBC1BUJeIUQop4kJSWxY8cOAEwmk8MUwtpKLSzk85QUo/2QXXY35dMUh+xu1LioMseXmr1jNgdPHQTA39OfeQPnoTmrWJSuw6uvqinMp0+r58xmtc3QmjWq4q4QrhAUpDK7S5c6/jt79VXo1Uvt6+sCXu5evHvDu0Z76d9LWb5/eYX9z8zyJn+UTN7hPKP9UEwMpe/GDenp7LWu13cGk8nksMRiRR2tdxZCCGeTgFcIIerJ0qVLjXV3V111FaFODPDeTUykwDp2dz8/LrPuU2spsjhkiSrL7h48eZDndzxvtF+4+gWi/CsOjqslPx9Gj1YZtdIKs1FRsGMHPPwwmOR/T6IODBliq/pdatcutX2RiwK8Ps37cHfnu432+LXjySzIrLB/YN9AGvduDIBerHNkxhHjtZZeXgwJCTHa9vttO8OZAa8z1wkLIURdkU8UQghRT+wLwThzOnOBxcLchASjPSk62sjKpnyWQn6cNbsbVHF2V9d1xq0dR2GJmt7ZPbI7Yy8eW27faktKgt694ZNPbM/17Am7d8OllzrnHEJUVZMmsHKlWitutn75c/q0Kmg1eTIUFzv9lC9d95KxDj4hK4Envnmi0v72FZtTPksh90Cu0Z5iN3vji5QUkgsKcJbevXvjb/2yLC4ujj///NNpYwshRF2RgFcIIepBSkoK27ZtA8pWRK2thamppFj3zYz08GC4tRBWdbK7C/ctZNNhtS2QSTMx74Z5uJncan9xe/dC9+6O63VHj4YtW1SRKiHqQ2k18O3bwbodD6C2M+rf3+lVnIO8gnj9+teN9ts/v80Px36osH/jKxsTeG2galhwqNh8WUAAPaxBaaGu85bdl1215eHhwYABA4z28uUVT78WQoiGSgJeIYSoB0uXLsVincp75ZVXEu6kYE/XdebYTWscHxWFu3V6cMrnKeQftsvuji8/u5uRn8FDGx4y2hMumUDXiK61v7gdO1Ql5tIP5CYTvPYafPgheHrWfnwhaqtHD9izB2680fbc5s1q5sH+/U491cgLRjKgtQomdXTuXXWvMaOiPM2ebWY8Tvk8xWEt75RoW5X1d5OSyHdiRWVZxyuEONdJwCuEEPXAfjrz8OHDnTbutowMfrMWrvEymRgbGQmApfiM7O6UirO7T337FMnZyQBE+kUyo8+M2l/YypVw7bW24lR+fmobmIkTVXZNiIYiKEit351h9+/+4EEVDG/Y4LTTaJrGOwPfwcfdB4B9aft4aedLFfYPuCyAxn3VWl5KIP4FW6X1wSEhxFq/NDpRVMRXqalOu87+/fvj7q726P7111+Jt9vbWwghzgUS8AohRB1LTU1l69atgPOnM79ml929MyyMYOsH1ZTPU8g/ZM3uBlac3d2duJu5P8+1jdfvNfw9/Wt3UR9+qIoD5Vv3EA0Lg+++g+uuq924QriKpsG0abB4MVi38yIjQ21d9PrrqsK4E8QGxDKr7yyjPWv7LI6errhCdNNpTY3HyR8nkx9vfU+bTIyPsr2nXz9+3GkFpvz9/elrtz3YypUrnTKuEELUFQl4hRCiji1fvtyYznz55ZcTac3C1tahvDxWnDhhtCdapznqJTrxz9vtuzslBrN/2eyuRbfwnzX/QUd9UL6+1fUM61DLYlovvAD33GOrxNyiBezcCV261G5cIerCsGHq32vplGGLBSZNUpXES/9N19K4S8bRObwzAHnFeQ7LCc7U+KrGBFwRAKh9eeNftL2vx0RE4GVdvvB7Tg7bMjKccn3gOK1Z1vEKIc41EvAKIUQdW7x4sfHYmdOZ3zx+nNKczvVBQbT3UVMl05akkXdQrfczNzYTNaH87O5Hez5id+JuADzdPHmr/1u123P32Wfh8cdt7S5d4PvvoWXLmo8pRF3r0gV+/llNaS716qtw111gLQ5XG2aTmbkDbLMqlu1fxrqD68rtq2maQ5Y36YMkCpJUVeYgd3fuDAszXnvDiVsU/d///Z/xeOvWraQ7uYiXEEK4kgS8QghRh06cOMGWLVuMtrOmM2cUF/NhcrLRnlSa3dV1h4quUROiys3uZuRn8MS3tq1Rpl4+lZZBtQhMn30Wpk+3tfv2ha1b1XRmIc414eGqkviQIbbnPv8cBg2CnJxaD39ZzGWM7jzaaE9YN4H84vxy+wZeG4hfdz8A9AKdYy8dM1570K541fITJziSl1fm+JqIjIzkkksuAaCkpIS1a9c6ZVwhhKgLEvAKIUQdWr58OSXWCqqXXXYZ0XYfUGtjflIS2dZx23t7c12g2sLk5OqT5PyhPpCbvE1EPVh+dnfGdzNIzVGFbmL8Y5h6xdSaX8yZwW6/frBmDfjXci2wEPWpUSO1pnes3X7U69bBNdfAyZO1Hv6Fa16gcSNVlOpQ+iFe/v7lcvudmeVNnJdIYaqq7tzBx4drrO99C/B2YmKtr6vUoEGDjMcyrVkIcS6RgFcIIeqQ/XTmYcNquT7WqkTXecNu781J0dFomqayu3aVmSPvj8QjxKPM8X+n/c0bP71htF+69iW83b2rfyG6Ds884xjsXn89LF+uggUhznVubjBvnipoVerHH9V2W0lJtRo61Ce0TAGrI6ePlNs3+IZgfDv7AmDJs3DsVVuWd6Jd8ar3k5LIcdIWRfbreNetW0d+fvkZaCGEaGgk4BVCiDpy8uRJvvnmG6PtrIB3xYkTHLF++Awym7ndOm349JbTZO3KAkDz0IiZElPmWF3XeWjDQxRbigHo1bQXIy4YUbMLefZZx61c+veHZcsk2BXnF01T/87ffNO2pdbff0OfPrUOeu+7+D66hKuCbvnF+UxaP6mCS9Bo+pRdlnduIkUn1XriAcHBtLS+504XF/OZ3VKH2mjfvj2tW7cGICcnh2+//dYp4wohhKtJwCuEEHVkxYoVxnTmHj16EBNTNgCtiTl2xWnuj4zE280NwCG7G3F3BJ6RnmWOXX1gNRsOqb1FTZqJN65/o2aFql591THYHTAAli6VYFecv8aPhy+/VFlfgP/9r9ZBr5vJzaGA1Yr/raiwgFXIkBC8L1AzMUqyS0iYq2Z5mDSNCXZLJd5ISHDKFkWapsm0ZiHEOUkCXiGEqCNLliwxHjsru/tLVhY7rNuPmDWNB6zTGTN+zOD0t6dVJzeIebRscF1QXOCwBcrYrmO5KPyi6l/EZ5/BlCm2dv/+8PXXEuyK89/NN8PChY5Bb+/eUIu1sz1jenJ357uN9uSNkykqKVsNWjNpxD4Wa7SPv3Gckhz1hdro8HD8rNf0d24um51UVdl+WvPKlSuN7dWEEKIhk4BXCCHqQHp6Ops3bzbazgp437TL7o5o0oQoT5XFtd93N+zWMLyae5U5ds6PcziUfgiAwEaBPNf3uWqfP+iHH2C0rbosV1whwa74dxk6VAW9Zmv18wMHVKa3FkHvf6/5L/6eqsjb/hP7mbd7Xrn9QkeG4tlUveeLTxaTNF9ll/3NZkaHhxv95tqt8a+NHj16EBoaCkBKSgq7du1yyrhCCOFKEvAKIUQdWLlyJUXWPTu7d+9O06ZNz3LE2aUVFrIgNdVoT7ROY8z+I5uTq6xVYzWIfTy2zLEp2SnM2m4rkDOjzwxCvEOqdwE7d3LB9OlQWhSnY0dYtQq8ygbXQpzXKgp6U1JqNFyoTyhPXfmU0X5m6zOcyjtVpp/J3eSwNv/YK8ewFKms6wN2xatWnTxJvBOKTLm5uXHjjTcabZnWLIQ4F0jAK4QQdcB+OvPw4cOdMuaHSUkUWNfmdffz4xLrtj/xs23Z3ZAhIfi09ylz7PTvppNdmA1AhyYduL/b/dU7+d69cMMNuBUUqHazZrBhAzRuXP0fRIjzwU03lQ16+/cH65KD6nrw0gdpEdgCgPT8dKZvnV5uv4gxEbiHuANQcLSA1IXqS7C23t4OWxS966QtiuynNUvAK4Q4F0jAK4QQLpaRkcHGjRuN9tChQ2s9ZrHFwjt2H2DHW7M5eUfyjA+8UH529++0v3nvl/eM9kvXvoTZZK76yRMS1HZDp61rhENDYeNGiIio5k8hxHmmNOg1WT9e7dkDgwZBDbKrnmZPXrr2JaP99u632X9if5l+bt5uRE2wZXOPzT5mFKl6IDLSeP6DpCQKnLDm9uqrr8bHR32JduDAAfbvL3tNQgjRkEjAK4QQLrZq1SoKCwsB6Nq1Ky1atKj1mKtPniTeml0NcXdnRJMmAByfcxysM4wb922Mfzf/MsdO3TyVEl11urr51fRv1b/qJ87NVR/grWsCi729Yd06sG5XIsS/3k03wfvv29rffQe33IJWg/1wh7QbwlVNrwKg2FLMwxsfLrdf1LgoTD7qI13O3hxOrVXTn28MDibauq4/taiIpWlp1b6GM3l5edGvXz+jLVleIURDJwGvEEK42OLFi43HzprO/KZdEZp7IyJo5OZG0ckikj6wbYkS+2jZ7O6WuC2sOrAKAA2Nl697uerbEFkscOed8Msvqu3mxr4ZM6Br15r/IEKcj+6+G2bPtrWXL6fNK69ANbcH0jSNOf3moKHeo2sOrmHDPxvK9HMPdifyXls2t3RZg9lk4j67mRdvy7RmIcS/kAS8QgjhQpmZmWzYYPuA6ozqzH/l5PCtdTqxCbX3LkDC2wlYctWURZ9OPgReF+hwnEW38PAmW4bozovupHN456qf+OmnVQXmUm+9RfrFF9fshxDifPfoo/Cw7f0WsW4dPPZYtYfpEtGF0Z1tldAnb5xMsaW4TL/oydFoZhUYZ2zPION7tXb4nogIzNYvtXZkZPBHdna1r+FMAwcOxM267dGuXbtIqsXew0II4WoS8AohhAutWbOGAuvU486dO9OqVataj2m/xcigkBBiGzWiJK+EhDdtz8c+Glsmc/vFH1/wa9KvAHiZvZjZd2bVT/r55zDLVtWZBx+E+6tZ6EqIf5sXX4RRoxzb88rfYqgyM/vOxNfDF4C/0v7iw18/LNOnUUwjwm4PM9qlWd5wT0+GhtgqsL/thC2KgoKC6NWrl9FetWpVrccUQghXkYBXCCFcyH46szOyuxnFxXySnGy0S4tVJX+STFGa2vbIM8aTJiOaOByXV5THE98+YbSn9JxCtH901U76/fcwZoytff318MorNfwJhPgX0TS1nvf//s/23PjxsGlTtYaJ8Ivg8SseN9rPfvcsOYU5ZfrFPGrboujkypPk7Fd97Lco+jwlhYzishni6vo/u59pzZo1tR5PCCFcRQJeIYRwkezsbNatW2e0nRHwfpqcTI610moHb2/6NG6MXqJz7OVjRp/oydGY3B3/vL/242sczzwOqD0+H7380aqdMDERhgwBa9EtOnSABQtsW68IISpnNsNXX5HVpo1ql5TA8OHw99/VGmZSj0lE+qnlC8nZybz242tl+vi09yH4xmCjffw19Z6/MiCAC7y9AcixWPjU7kuzmho4cKDxePPmzeQ7YZ9fIYRwBQl4hRDCRdauXWt8COzYsSNt27at1XgWXectu+mI46Oi0DSNtGVp5B9S5zEHmom4x3F7oJO5J3lh5wtGe0bvGfh5+p39hEVFMGIEpFq3OQoJgdWrISD0WtlpAAAgAElEQVSgVj+HEP863t78OWsWlGZaMzJg4ECoRtVkb3dvpve27cU7e+dsTuSeKNMvZooty5vySQqFaYVomuaQ5X07MdHYuqimWrduTRtrEJ+bm8vWrVtrNZ4QQriKBLxCCOEizp7O/E16Ogfy8gDwd3PjjrAwdF3n2Iu27G7kA5GYfR2zr7N3ziazIBOANsFtGNN1DFXy6KOwc6d6bDLBokXQvHmtfw4h/o0KQ0Jg1SqwZlqJi1NbGFnX+FfFqM6jaBfSDoCswixmbZtVpk9ArwB8u6r1vpZ8C4nzVGXmO8LC8LUWmtqfm8vW0n20a+GGG24wHq9evbrW4wkhhCtIwCuEEC6Qk5PD2rVrjbYzAl777O6o8HB8zWYytmWQ9XMWAJqnRvQEx3W5xzOP8+ZPbxrtWX1nYTZVYTryokXwmt2Uyeefhz59avcDCPFv16ULfPmlWtsLsGMH3HtvlbcrMpvM/Pfq/xrtuT/PJS49zqGPpmkOWd6EtxIoyS/Bz2zmjjBbUav3nFBZ2X5a85o1a2qdNRZCCFeQgFcIIVxg3bp15ObmAtChQwc6dOhQq/GO5OWx6uRJo106PTH+xXjjufC7wvEI83A4bsZ3M8gvVtOdL464mKHth579ZH//rfYRLTV4sMr2CiFqb9AgVa251GefwZtvVtz/zMPbDqJndE8AiixFPL316TJ9mgxvgkeU+ltQlFpE6ldqWcJ9kba9epempZFWuja/hq644gr8/f0BOHLkCH/99VetxhNCCFeQgFcIIVxgyZIlxmNnZHffTkykNHdyXWAgbb29yf4zm1NrT6knNce1ewAHTh5g/p75RvuFa14os1VRGVlZappljrUCbKtW8PHHtoyUEKL2pkxxrHw+ZYrK9laBpmnMvma20f7ijy/4Lfk3hz4mdxPRD9pmexx/9Ti6rnORry+X+Kn1+4W6zqcpKbX4IcDDw4PrrrvOaMu0ZiFEQyQBrxBCOFleXp7DB7/hw4fXarzckhI+sJt+WLoVkX1l5pAhIXi38XY4btqWaZToJQBc3fxqrmlxTeUn0nUYOxb271dtLy/4+mspUiWEs2kazJ0L3burdnGxqtxcxWnGVza9khvb3AiAjs7j3zxepk/E2AhMPupjXs7eHNI3pQMw1i7L+54TilfZr+OV7YmEEA2RBLxCCOFk69evJ8eaIW3bti0XXHBBrcZbkJpKunXfzGaNGjEgOJj8Y/mkfplq9Il9NNbhmF8Sf2HRvkVG237dX4U+/lhtOVTq3XehU6daXbsQogKenrBkCQRbtxFKToaRI1V19Cp4/urnMWnqY9z6f9az9chWh9fdG7sTMcZWsf3Yq+oLspFNmuBnLV51IC+PbRkZtfox+vfvb8wc2blzJ6dOnarVeEII4WwS8AohhJOdOZ35rNOIK6HrOnPtilX9JzISN03j+GvH0YtVZibgygD8L/V3OO6Jb58wHt/U/ia6R3Wv/EQHDsCECbb2PffAHXfU+LqFEFUQG6u+ZDJZP45t3w5Tp1bp0AtDL+TOi+402tO2TCuTrY2eGG180kvfkE723mx8zWZusy9elZhYqx8hNDSUSy65BACLxcL69etrNZ4QQjibBLxCCOFE+fn5rFq1ymjXdjrzrsxMfs3OBqCRycSYiAiKM4tJet829THmUce1u1vitrDx0EYATJqJmX1mVn6SwkK49Vbbut127RwrNAshXOeaa2Cm3Xt0zhxYuLBKhz5z1TO4m9wB2BG/g02HNzm87tXCi5AhIUb7+KvHARgbYcv8LklL42QVs8oVkWnNQoiGTAJeIYRwoo0bN5KVpbYJatWqFZ1qOSX4bbvsy82hoQS7u5P0YRIlWWptrnc7b4IHBBt9dF3nqS1PGe1RF42ifZP2lZ/kqafgl1/UYw8PtW2Kj0+trlsIUQ1Tp6rqzaXuuQf++eeshzVr3IwxXWzFr8rL8sZMtn0hlvJlCoVphXTx86ObffGq5ORaXb59wLtu3TqKrUswhBCiIZCAVwghnMiZ05nTCgtZmGpbpzsuMhJLsYXjrx83not+KBrNZDvHxkMb+f7Y9wC4m9x5pvczlZ9k82Z46SVb+4UX1F6hQoi6YzLBJ5+oqugA2dlwyy1q9sVZPNnrSTzdPAH4KeEn1hx0zLAGXBaA3yUquNULdGN2yH12Wd73kpJqVbzqoosuIspaTC89PZ0ff/yxxmMJIYSzScArhBBOUlBQwIoVK4x2baczz09OptD6IbS7nx/d/P05sewEBUcLADAHmwm7w7YWT9d1pm2ZZrTv7XovsQGOxawcpKU5rtPt1w8mTqzVNQshaiggQE1ldldTlNm9G6ZNq/wYINo/mvsuvs9oP73l6TLBa9SEKONx4juJWIos3Bwaiq+1eNX+3Fx21KJ4laZpDBw40GjL9kRCiIZEAl4hhHCSzZs3k5mZCUDz5s3pUotMaYmu845dsapx1uxJ6Ro8gKgHonDzcjPaaw6u4efEnwHwdPPkiStthavK0HW4915VGRYgNFRlmEzyvwUh6k3XrvBfu4rqL76oZmGcxeNXPo6X2QuAPcl7WLZ/mcProcNDcQ9VgXTB8QJOLD+hileFhhp93qvilkgVkYBXCNFQyScbIYRwEvvpzMOHD6/VdOa1J09ytEBlcoPMZkY2aULGDxlk/qgCas1DI/IB236auq7z9Janjfb93e4nyj+KCn3+Odhlo/noI7Cr3CqEqCcPPQTXXWdr33GHmo1RiXDfcMZfMt5oP7P1GSy6xWibPE1E3m/7e5HwpvoyzX5P3sWpqZyqRfGqq6++Gk9PNbV63759HDlypMZjCSGEM0nAK4QQTlBYWMjy5cuN9rBhw2o1nn2xqjERETRyc+P4HFt2N+zWMDzDPY32iv+tYE/yHgC8zF48dsVjFQ+ekOC4BdF//gMDBtTqeoUQTlK6nrc0+5qcDKNHq1kZlXj08kfx9fAFYG/qXod9uAEi74tEM6sv4TK2Z5D1WxZd/fzo6quOKdB1vrKrGVBdPj4+9O3b12hLtWYhREMhAa8QQjjBt99+y+nTpwFo2rQp3bp1q/FY/+Tmsv7UKQA04P7ISPKO5JH2tS3LE/1QtPHYolt4ZqutONUD3R8g3De8/MFLpzKXrtdr0UJNmxRCNBzh4fDxx7b2mjXw1luVHhLiHcLES21r8J/Z+gwllhKj7RnpSZPhTYx2aZZ3jF3xqg9lWrMQ4jwkAa8QQjiBM6szv2OX3e0fFEQLLy8S3kgA6wzFwGsC8e3ka/RZ+vdS/kj5AwBvd28evfzRigefPx/WrbO1P/oIfH0r7i+EqB/9+6vpzaUefRT+979KD5nScwoBngEAHDh5oEyW1754VcoXKRSeKOSW0FA8rX+v9mRns8e6rVpN2Ae8W7ZsIad0b28hhKhHdR7waprWS9O0lZqmJWiapmuaNqoKx3TUNO07TdPyrMc9rdXm06QQQjhRUVERy5bZisTUZjpzbkkJH9ntiTkuKorizGKSPrBlXqIn27K7JZYSh+zuhEsmEOpjK0TjID7e8QP0xInQq1eNr7W+6TpkZsKRI/Dbb/Djj7B1K2zYoJYnL16sbl9/DUuXwrJlsHIlbNoEO3fCnj0qfjh2DE6cgNzcs84aFaJu/fe/cNFF6nF+PowaBSUlFXYP9Ap0yPLO2j7LYS2vfw9//LrZbVH0QRKB7u4MbWLL/H5Uiz15mzVrxoUXXgioqvXffPNNjccSQghnMdfDOX2BvcCn1lulNE3zBzYB24DuQFvgYyAHeMVlVymEEFW0ZcsWTlmnIEdHR3PJJZfUeKwFqamkFxcD0LxRI64PCiLhteOUZKkPud7tvQnqF2T0X7RvEX+l/QWAr4cvj1z2SPkD6zqMGQOl2ZvWreH552t8nXUhLU0FpEeOwNGjtvuEBDh5Ek6dglrU2CmXmxsEBqpbUJDj46AgtawyLEzdwsPVvb8/yFewwiU8PdV63u7d1T/2H3+EV1+FRyp4nwMTe0zk1R9fJbswm31p+1i+fzk3tb8JUNsHRU2IYv9d+wFIfDuRmIdjuDsigi+t63c/T0nhxRYtaOTmVuE5KjNw4ED27t0LqHW8//d//1ejcYQQwlnqPODVdX0tsBZA07SPq3DIbYA3cJeu63nAXk3T2gOTNU17Va/NTulCCOEECxcuNB4PGzYMUw239tF1nbl2WxH9JzISSnSOv24rVhX9UDSaSUVXxZZinv3uWeO1SZdOItg7uPzB33vPtr2Jpqn1gd7eNbpOZ9N1OHgQfvoJ/vhD3X7/3bZjUl0qKVHZ3hMnqn6Mp6ct+LUPhMt77OcnwbGoposugqeftu3JO20aDBwIHTqU2z3IK4hx3ccxe+dsAGZum8mQdkOMZRahI0M59MghilKLKDhWwMkVJ+lzUwjNGjXiSH4+6cXFrDh5kpGhFcwUOYsbbriB2bPVuVevXo2u67Va4iGEELVVHxne6uoJbLcGu6U2AM8BzYC4+rgoIYQAVZ156dKlRnvkyJE1HuunrCx+zc4GoJHJxN0REZxYdoKCo2p7IvcQd8Jut20d9NWfX3Hg5AEA/D39mdxzcvkDJyQ4ZoSmTIHLLqvxddaWrsPff8N339luNQ1uvb0hOBgaNwYvL2jUyHZzd7edz2JR9yUlkJenpi/n5jo+zskB605Q1VJQoDLPR4+evW+jRmUD4bAwx8xx6ePAQAmOhdXUqbB8Ofzyi/oHN2oUfP89mMv/GDe552Te2PUGecV57Enew9qDaxnYRq2vNXmaiBwbydGZ6h9swlsJNBnahNHh4Txj3UpoflJSjQPeHj16EBgYSHp6OomJifz222+12pNcCCFqS6vPBKmmadnAeF3XP66kz0bguK7rd9s9FwscBS7Tdf2Hco4ZC4wFCAsLu3jBggXOvnSnys7OxleKxjQo8jtpmBri7+WHH37giSeeACAsLIyvvvqqxtmM51HrNwCuB6YCjAP+sj55B2D9S1iil3DnT3eSmK8KXI1qOoq7mt1V7rgXPP00TbZvByA3JobdH3yAxcOjRtd4pqr+TkpKYO/eALZta8L27SGkpTU66zGeniU0a5ZDeHg+4eH5hIXlEx5eQJMm+TRuXIS/fzEeHpazjlMdRUUaWVlmsrLcz7g3k5npTnq6B+np6v7UKQ/S0z3Iz6/Z1M+zcXOzEBhYRGBgIY0bq/vAwEICAtTP7uen7v39i4zHnp7qv0dDfK/829X2d+ITF8fF992HyTqP//A99xB/220V9p/7z1yWJKhieu392jO3y1zb36Y04GaMQnh8DMlN4VZAR1WH/wqo6c7cM2fONNbv3n333dxxxx01HMm15H3SMMnvpeE5F34nffr0+UXX9XK3yDgXMryg/v7a0yp4Xj2p6+8B7wF069ZN7927t+uuzAm2bt1KQ7/Gfxv5nTRMDfH3Mn/+fOPxnXfeSZ8+fWo0zonCQr774QejatKMrl1ps09nz19qb13NQ6PHiz2MvXc/2vOREew2btSY125+jYBGAWUHXrYMrMEugPdnn9HrqqtqdI3lqex3ouuwbRt89ZW6jMq2+AwIgCuugC5d1AzOTp2gZUs33Nz8AX+nXa8rZGerDHVKirpV9jgv7+zjlSopMXHihCcnTnievbOVl5daa+zpmU1UlC/+/moadem9/ePSe19flXkuzZCfeV/DGfriDLX++9W7t/qH9PjjALT45BNaPPggdOxYbvfWXVuz8o2VFJYU8nfW35Q0LeGaFtcYr+/9ai8nlqm5+1G/RtH7rtbM//13NqWnowP/a9aMkc2a1ehSk5KSjIB33759De7vdqmG+P8UIb+Xhuhc/52cCwFvMnDmhpKl82xS6vhahBDCkJ+fz/Lly412baYzf5icTKE12O3u50d3f3/2zdlnvB52W5gR7BaVFPHctueM1x7u+XD5wW5GBowbZ2vfcw84MdityKlT8Omn8O67sH9/+X0aN1aX0ru3uu/USRWMOhf5+kKrVupWGV1XwfGZgXBqquN96ePMzOpfS16emsEOvhw+XJOfpix3dxX8enqqGbRubure/nF5z535uv3NZCr7XGXPe3o6Tle3v3l5qX9PAQHqvnR6+3k5Hfzhh9W3Rz/9pIpY3X23KmRVzpsnyj+KMV3G8M7udwC1ltc+4I18INIIeJM/TqbF8y0YExHBpvR0QFVrfqppU0w1+A/Zr18/TCYTFouFn376idTUVEJrOEVaCCFq61wIeH8AZmua1kjX9Xzrc9cCicCRersqIcS/3vr168myVj1u2bIlXbt2rdE4JbrOPLu9d8dFRZF3JI+0r9OM56Ifsm1F9OWfXxJ3WpUvCPIK4sFLHyx/4McegyTrdkZhYfDiizW6vqr65Rd4801YuFDtoHKm0FAYMgSGDlWBbuka238LTbNlWc8WHIMKXtPSygbDp07ZqlSfee/sqtWgxnTFuK5kNtuC35AQiIhwvMXEQMuWEBt7jv07NJtVwbkuXdRa3t274Z13YPz4crtPvXwq7//6PsWWYr47+h3bj27nyqZXAhDYNxCv1l7kHcyjJLOElK9SGDQ6jECzmfTiYo7k57P19Gn6BgZW+zKDgoK4/PLL2b59O7qus27dOu66q/wlF0II4Wp1HvBqmuYLlP6v3gTEaprWGTil63q8pmn/BS7Rdf1qa58vgWeAjzVNmwm0AR4DpkuFZiFEfbKvzjxy5Mgar91dd/IkR6wRYpDZzIgmTUh4JM5YXxd4bSC+HdXamWJLMbO2zzKOndxjMn6efmUH3bED5s2ztd94Q1VBcoGff4bp02HNmrKv+fnBbbfBrbeqOlnnaha3Pnh5qYAsNrZq/UszyKdOwYYNu2nTphuZmWonqqwsyn2cmWkr3pWfX/79uai42FZt+59/Ku7n5gZNm6rgt107NdPgoovgggsaTBHzstq3hyefVJWbAZ54Qn2TFBVVpmvTxk25s9OdzP9NLb2YuX0mG5puAEAzaUTeH8mhKYcASHwnkYgxEdwWFsZb1mrxHyYl1SjgBVWtebt1OcXq1asl4BVC1Jv6yPB2A7bYtadbb58Ao4AIoGXpi7quZ2iadi0wF9gNpKP23321jq5XCCHKyM3NZdWqVUa7NtOZ59pld8dEROCeo5P0QZLxXPRkW3Z34d6FHDx1EFBrd8dfUk5mp6AAxo61tW+4AYYPr/H1VeSnn+Cxxzqya1fZ17p0gf/8B265RU35Fa5nn0Fu0yYbZyy30nUoLFSBb0GBKj5WXKxupY+r81zpzWJxbJ/t+cJCFYCXd8vJUbP3T5+23apabbukBA4fVrdNm2zPm0xqq+pu3dTa8iuvVHFmg1nP/Oij8MUXaqPqrCyYOBGWLCm36+NXPs7Hv3+MRbew8dBG9iTtoUuEqpocPiqcuCfjsORbyP41m6yfs7i7fbgR8C49cYKM4mICKqgGXZmBAwcydepUADZu3EhhYSEeTiqWJ4QQ1VEf+/BuxVZ0qrzXR5Xz3J9AL9ddlRBCVM+aNWvIyckBoF27dnSsoHDM2RzKy2P9qVOA+sN4f2QkSfOSKMkqAcC7vTdB/YIAKLGUMHP7TOPYiZdOLH/t7ksv/T979x0fRbUFcPw3m0pCSEhIQhK6dBHpXQQUFEWw0KRXAamCgApSVBAEohQRpaOggCAiKg+QJiV0kY40KWmEhISQnsz7425mdqlJAGnn+/nk8/bOzszukJd1zp57z1F9f0BFm9On39UFjadOwcCB8PPPAGbfX02Dli1V16MqVR7RNZSPGU1T62ddsl4364GQlKSC4JgYNR08LEytmw4Lg9BQOHMGTp5Uj28kI0PFkseOqbgSVDGw2rWhQQN45RWVFb5vXFzUIvnMbzWWLYNVq9SXW9co7l2cFmVbsPiQmpHy2bbP+P6N7wFw8nbCt5UvEfNVSZTQr0KpOLc0T7u7s//qVZIyMvjx4kW6BgRk+y2WLVuWIkWKcObMGeLi4tiyZQsNGjTI2fUKIcQdeFC+qxRCiIfK3ZrO/JU1kwLQ2NubIk4unJ983thW4J0CxrmXHVnG0ShVBcrD2YP+1ftff8LTp2GMOeWZMWPUgsW7IDERRo2CsmUzg11F01Qm9+BB+OEHqFpVgl1xf2X2Oy5dGurWhVatVBJ03DhVUG3zZlXc6+pVOHRI/f95zBj1hU2pUjfO5EZHwy+/wDvvqDXYZcuq9rhbtqhM8X/u2Wehc2dz3Lu3uqAbGFJ7iPF4yaElnIoxK5oF9TKnQkf+EElqdCod8pu1QhfksEm2pmk0sQnAV61alaPzCCHEnZKAVwghsunKlSv8arNgNafTmRPT05ljczPZOyiIqJ+iSP5Xzcd0yueEfzvVCTNDz7CrzNyvej/y5rrB2rp+/cyKUZUq2VdpziFdh5Ur1brG0aPtp4s2aBDBoUOwaJEKAIR4mLi5qf/fNm2qlsIuXqwqi1+5ooofBwer5bH58l1/7JEjqg7cM89AgQIweLAKnv9TEyaYb+7sWfWN1A1UCqhkVGjO0DMI3m6uCvOo5kHuimrdQUZSBuHzw2nj50fmcvvNsbGczuFi7pdfftl4/OuNFvkLIcR/QAJeIYTIplWrVpFkDSqfeuopypQpk6Pz/BAZSUxaGgBFXV150dub88FmdjewVyAOudRt54qjKzgYeRAAdyd33qnxzvUnXLlSTWsElWKdPv2Oq0SFh8Orr0KzZip5nKlKFdixAz788Ag5vHwhHlhublC9usrmLl+upkUfOaIKIjdpojLItsLDYeJEKFcOqlVTf3rW7j73lo+PeuFMn38Of/11w12H1h5qPJ6zbw4Xr6oq8JqmEdgr0HgudEYo/s7OvODtbWz7NiJnXSDr1auHm7X61/Hjxzl+/HiOziOEEHdCAl4hhMima6cz54Su63xpM525V2AgV7bHEReimq9qzhpBvYOMfW2zu72r9sbHzcf+hAkJKrubqXt3dcd+BxYvVlndlSvNbd7eaulgSIi6sRficaBpanp0z55qWvOlS+rvont3NXXa1q5damJFgQLqT/LMmXv85jp0MNfypqerF79BE4vnij5HpQDVOi0xLZFpO6cZz/m38cchj/pyLPF4IjF/xFw3rTknjTFcXV15/nmz969keYUQ94MEvEIIkQ0xMTH8/vvvxjinAe+uK1fYEx8PgIum0SUggHPB54zn/dv54+yvKpquOr6Kv8JV1iaXYy4G1Rp0/QnHjIF//1WPfXxg7NgcvS9QsXPXrtC6tVq3mKl7dzh+XBWAlvZC4nHm5qYKV33zDZw/r1pytWgBtkWIExJUX+rixdUa9+PH71G5ck1TLcgyGwpv26bWGFy3m8aQWuZa3mm7pnE1Ra35dXB3IH8HM8ANmxlGUx8fPK1/6CeTktgWF5ejt2e7jlcCXiHE/SABrxBCZMOyZctISUkBoHLlyhQvXvw2R9yYbXa3tZ8fbufSiPopythWcKAqNKXrOh9t/sjY3qtKL/zc/exPduyYWsuXafx4FfTmwLFjUKMGzJljbitUCNatUzf3OTytEI8sR0d46SVYskRVgf7yS9XPN1N6uirm1qNHFV58EfbvvwdvolQpVZUr05AhqinzNd4o+wbF8hYDIDoxmll7ZxnPBfQwKzFH/RSFQ3Q6Lf3Mz5r5OSxe9dJLLxmPN23aRFwOA2chhMgpCXiFECIbFtlkTtq2bZujc0SlpLA4MtIY9w4K4vyU85ChxnlfyIv7k+4ArD6xmt2huwFwdXTl3Vrv2p9M16FPH0hNVeOaNe0rt2bD4sVqbe6BA+a2tm3V+LnncnRKIR4r3t7w9ttqGe3//gc2s3kBta1iRfUnev78jc+RYx9+aM6vDg2FTz+9bhdHiyODapozRIJDgklNV58ducvlJk+NPADoqToRCyLoaDOteUlkJIk5KEcdFBRExYqq729aWhprbRseCyHEf0ACXiGEyKILFy6wceNGACwWC61bt87ReeaEh5NsXQ9X1cODChm5CJ9tZk9ult3tXqk7AR7X9MNctkylX9WbUtVybtRT5RZSU1XM3Lq1mRRycVEZ3W+/hTx5snmBQjzmNA0aNYK1a2HvXjWl2WJRf/O6DvPmQcmSMGwY3LWEZ548qu9SpkmTVNPsa3Su0BlfN18AzsaeNfrzAgR0Mz9fQmeGUtPDgyesFbpi09NZeelSjt6atCcSQtxPEvAKIUQWff/990bhlgYNGhAQEHCbI66Xrut8FRpqjN8ODCRsZhjp8Spz4l7OnbwNVbuhP07/Qcj5EACcHZztemkCapHgIJv1vH36QIUK2Xo/sbFqOuaXX5rbihdXRam6d5d+ukLcqYoV1ZLaWbN2YdOlh8REtdS+TBlVCOuu6NDBrCaXnGz/+WCVyykXfav1NcaTtk8yPtd8W/nikNtavOpYInHb4u5KT17bgPe3334jIyMjR+cRQoickIBXCCGyaOHChcbjNm3a5Ogcq6OjOWNtaeTt6EiLvPm4MMVcz1tgYAE0TUPXdUZvGm1s71qxKwXyFLA/2YQJqvcmgK+vapKbDefOqR6imQligObNYffubMfNQojbKFo0gVWr4I8/VBCcKTRU9QFu2xaiom5+fJZYLDBlijlescL+D9zq7apvk8sxFwB/hf/Fn2f/BMAxtyN+bcx1u2Ezw2hvU4b6f9HRhNs24s6iKlWq4GddDxwZGcnu3buzfQ4hhMgpCXiFECILDh8+zF/W/pYuLi68/vrrOTqPbbGqrgEBxC+PJvm8uoF08nfCv426udz07ya2nN0CqHV3tj00ARXojh9vjseMAS+vLL+PfftU1yLb9boffaQK73h6ZvOihBBZ1qCB+lJpwQKwqQnFokVQtqz6G8xBByBT9eoq05upf39zjb+Vj5sP7cu3N8aTd0w2Hgd0N2euXFx6kQLJjtS1fiikA4ts6g9klcVisSteJdOahRD/JQl4hRAiC2yLVTVp0gTPHESFJxMTWW3t86MBPQICODfJbEUU1CZZvjEAACAASURBVDsIi4v6WLbtu9vp6U4U9ipsf7LBg9WcSFDpoi5dsvw+fv8d6tZVFWVBdTNZsEDVvJEpzELcexYLtG8Phw+r/8108SK0aqV+Ll++gxcYNw5yW9sgHT6smmdfo191s2/3iqMrOHP5DAAelT1wf1oVzctIzCByUaTdtOacVmt+2WY+t7QnEkL8lyTgFUKI29B1/a5UZ54RGkpm4qaxtzc+u1OI36uqRFlcLQT2DARgy9ktrD+9HgAHzYH3n3nf/kSbNqk0UKbJk7PcGHfJEtU/NLM4laenqhxre9MthPhv+PioL5tWrYKgIHP70qXqe6ydO3N44oAAGD7cHH/00XXVsZ70e5Lni6ky0hl6Bl/uVAv5NU0jsHugsV/YzDCa58uHq7UY3t9Xr7L/Bi2PbqdRo0Y4OjoCsHfvXi7YzHYRQoh7SQJeIYS4jZCQEE6fPg2Ap6en3dS8rEpMT2dOZkoV1YroXLCZ3fXv6I+zrzNgn91t/3R7o28moJp62vbbbN1aLcTNgkWLVLXYzM4ihQvDtm1Qv362L0cIcRe9/DIcOgTdupnbzpyB2rVVQbkcTXHu31810QaVOrbt1Z25S3Xzs2TWvllcTbkKgF9bPyy51C1i/F/xaPsTeS1fPmPfnBSvypMnD88++6wx/u2337J9DiGEyAkJeIUQ4jZsi1U1b94cFxeXbJ9jcWQk0WlpABR1deWZS65cWmm2+CgwQBWk2nF+B2tOrgHAoln4oM4H9ieaNQv271ePc+WCzz7L0usvWKCyuJnFUcuUge3b1ZpBIcT95+kJM2fCjz+a6+jT0lTx9a5dwVrrLutcXeGTT8xxcLCqkGXjpRIvUdy7OACXky6zYP8CAJy8nPBt4WvsFzYrzK4n78KICNJyUGlZpjULIe4HCXiFEOIWUlNTWbzY7FOZ0+nMX9rcaPYKDCRs8gUy5zd7v+yNe2m1Zs42u/tmuTcp4VPCPElMjGrcmen996Fgwdu+9pw50KmTGeyWKwcbNqhZj0KIB8sbb6iicpUrm9vmzlXFri5ezObJ2raFp59WjxMSYNQou6ctmsWuRdGUnVPI0NUHhW1P3shFkdRz8iDAWc1CiUhNZU1MTDbfjH17orVr15KU7SheCCGyTwJeIYS4hbVr1xJl7RUSFBRE3bp1s32OnXFx7L5yBQAXTaO9az7C55pTAgsOVEHrntA9/PqPynpoaAx7Zpj9iUaNgkvWrHCRIvDuu7d97W++UdmhzCmR5cvD+vVg02lECPGAKVoU/vzTvtjy9u1QowYcO5aNE1ks9lOZZ89WRaxsdKrQCQ9nDwCORh1l7cm1AHjW8cSttBsA6VfSiV4aRTubD46cFK8qUaIEJUuWBCAhIYGNGzdm+xxCCJFdEvAKIcQtfPfdd8bj1q1b45DF4lC2ptsUZ2nt50fy7ItkJKosivvT7njVV+2EbLO7LZ9sSRnfMuZJDh1Si/kyTZyopjTfwsKF0KOHOa5YUQW7vr43P0YI8WDIlQvmzYPPPzerp586BTVrqrX3WdawofoBNc3jffsieHlc8tClolnl/YsdXwCqeJVtljdsZhgdbALen6OiuHxNu6OssJ3W/Msvv2T7eCGEyC4JeIUQ4iYuX77MTz/9ZIzbtWuX7XNEpaTwg03fyl5+gVyYagbABQcVRNM09ofv5+djPxvb7bK7ug4DBpjVpurXh9v0Af79dzWNOVOVKvDHH6oqrBDi4aBp6k9/xQpwU8lWYmJU/Pq//2XjROPHm1HzypWwebPd032r9UVDPb/6xGqORh0FwL+DP5qT2h4XEkeRM1DJ2u4oWddZku051vDKK68Yj3/55Rf0O2o6LIQQtycBrxBC3MTixYuNNWYVKlSgQoUK2T7HzLAwkq03dFU8PCj8ayIpYSkAOAc449fKD7DP7r5e5nWe8n/KPMnPP8O6deqxxaLaEN2iYe62bWodoLVGFk8+qW6O8+bN9tsXQjwAmjZVMWrm7IyEBNVe7Mcfs3iCihXB9gu7IUPsSj8/4f0Er5QyA9GpO6YC4OzrTL5XzerMYbPC7Hry5qRac506dYw+5ufOnePAgQPZPocQQmSHBLxCCHET8+bNMx537tw528enZmQwzWY6c79rWhEF9Q3C4mzhQMQBlh1ZZmwf/oxN/8zkZBg0yBz36gVP2QTD1zhwQLU4SUxU48KFVbDr7Z3tty+EeIBUrgxbtpidhlJTVVcy25bct/Txx5BZYX7HDpU2tmHbomj+/vlcTroMQEB3c1pzxLcRtPT0wdH6hdvWuDhOJCRk6zqcnJxo3LixMZZpzUKIe00CXiGEuIGjR48SEhICqBu0Nm3aZPscP168SGiKyubmd3am0SEnru5XfS4tbhYCewQC8NHmj4xjmpVqRsWAiuZJJk9WC/dApWhHj77p650+DS+8AJfVfSq+vrB2LQQFZfutCyEeQCVLwtatUKqUGqenQ5s2YFNI/uYKF1Y9jjJ99JFdlrd+kfqU8ysHwNXUq8zeOxuAvM/lxbWoKwBp0WlYVsXR2OYbtG8jIrJ9HddOaxZCiHtJAl4hhLiB+fPnG4+bNGlCvnz5brH39XRd5/Pz541x78BAIoLNbG/+zvlx8nbiQMQBfjxszksc+exI8yQREfZ9NEePvuki3OhoFeyGhamxh4fK7JYoccPdhRAPqQIFYONG1UsbVNDbtq1a+XBbQ4aYi4H/+svuIE3T7LK803ZNIz0jHc2iEdDVvniVbU/eBRERZGRzHe6LL75oFADcuXMnETkImoUQIqsk4BVCiGukp6ezYMECY9zJtvpTFoXExbHLphVR21hPon+LVk9qUKB/AeA22d1hw8B6DsqUgZ49b/haKSlqze4//6ixi4uqS1Ox4g13F0I85PLnVxXXbYPeli1VYbpb8vOD3r3N8ejRdlnetk+1xSeX+lLtzOUzrDy2Ur1ep/zGHePlDZdpcDkXeR0d1X5JSfwZG5ut9+/t7U3t2rUB9eXgr7/+mq3jhRAiOyTgFUKIa6xbt47Q0FAA/Pz87NabZdUXNtnddv7+JE0yi7vkey0fbiXcOBh58ObZ3X37YM4ccxwcDE5O172OrqtlvbbtLL/9FurVy/ZbFkI8RDKD3uLF1TglBZo1g507b3Pgu+/aZ3lt1vLmcsrFW5XfMsaTd0wGwCXIBZ+Xzdkl0bMjaO3nZ4xzUrxKpjULIf4rEvAKIcQ1bItVtWvXDqcbBJq3cjYpiWU27Tp6OvoR+b3ZmqjQUFV15qNNZna3aammZnY3sw1RZublpZfgxRdv+FqTJtnHxWPGQIsW2Xq7QoiHVP789uv0r15VFZ3//fcWB90oy5uRYQzfrvo2Dpqabrzp3038Ff4XYF+8KnxeOO3ymQHv0osXSchsm5ZFtgHvmjVrjIr4Qghxt0nAK4QQNmJiYux673bs2DHb5/jywgUyb/2e8/LCc9ol9DQVvHrV8yJPtTwcjDzI0sNLjWPssrvLlpl9Mh0dVXb3BlasUEvyMnXoAO+/n+23K4R4iBUpooLezDpSERHQpAnExd3ioMGDzSzv/v12a3kL5ClA87LNjfGUHVMA8G7sjXOgMwCpEakU35RCyVy5ALiSns5PUVHZet+lSpWihLXIQEJCAhs2bMjW8UIIkVUS8AohhI3FixeTnJwMQKVKlShfvny2jr+ans43mZWjgD6eAYTNNMcFhxYErs/uVgqopAZJSepm1DhBH7Mkq419+1ShmswkcJ068M03t2zPK4R4RJUpAz/9ZK56OHgQWrUye3Ffx9fXvmLzNVle2+JViw4sIvJqJBZHC/k7m8WqwmeG2xevkmnNQogHlAS8Qghhw3Y6c06KVS0ID+ey9S6zeK5clP82gYwEdSPp/rQ73i9433rt7uefw5kz6rGPD4wYcd1rXLyo1upltr8sVkzd7Ga22BRCPH7q1oVZs8zx6tXQv79dTSp7tmt5r8ny1ihQg6qBVQFITk/m691fA9hVa45eHU2LdC8yv2NbFxPDBeuXhVllG/CuWrUKPZvVnoUQIisk4BVCCKvDhw+zY8cOIGe9dzN03a5YVV+/QMKmhhrjQkMKoWkaH2/+GB11Y2eX3Q0LU4twM330keq9ayMtDVq3hnPn1NjTE1atgmx2TRJCPII6dIDhw83x9OkwdepNdr5FllfTNAbUGGCeZ/d0UtJTyFU0F3kbWj+TdHD6NoYGXl4AZADfZbO9UO3atfGyHn/u3Dn279+freOFECIrJOAVQgirGTNmGI+bNWuGz0163t7MyqgojicmAuDp4ECj33VSo1IBcCnsgm9LX7V295C5dndEXZsM7gcfqKozAOXKwVtmtdRM772nKrOCmr68cKHZmkQIIUaPVtOZM73zjurJfUO3yPI2L9ucgNwqoxseH258btkWrwqbHUZ7P39jPD88PFtZWicnJ7sq+DKtWQhxL0jAK4QQwNWrV+167/a8Sc/bm9F1nfGZaVegZ0AglyeY2d2CgwpicbTYZXdfKfkKlQMrqx127wab6dQEB6uCVTZ++EFVZc40ahS8/HK23qYQ4hFnscDcuVCjhhpnZEC7dmAz+cR0iyyvs4Mzb1d923hq8o7J6LpOvmb5cMqnFgsnn0um3n4H3C3qdvJIQgK7M3uHZ1GTJk2MxxLwCiHuBQl4hRACVawqNjYWgBIlSlC/fv1sHb81NpYQa1lUZ02jzW4Xks6oNhuOPo4EdAngUOQhu+yusXY3sw1RpldegYYN7c7/99/Qtas5btrUfuqiEEJkypVLVXEPDFTjqCi1FCI19QY7X5vltenL26NyD1wcVHGAXaG7CDkfgsXZgn9HM6t7ZWYkzX19jfH8bBavaty4MQ4Oqg3Srl27uHDhQraOF0KI25GAVwghsJ/O3KNHDyyW7H08fmaT3W3v70/SJ2Z2t0DfAji4O/DR5o9unN1dsgS2blWPnZzs07hATAy89ppZpKpkSViwQGVyhBDiRvz94fvvwRpLsnUrDBt2gx1vkeX1dfelzVNmLYPJOyYDENDNnNZ86ZdLvOlsLv/4PjKSFJuKz7eTN29e6tWrZ4xX2ATcQghxN8jtkhDisbdnzx527doFgIuLS7Z77x66epVfLl0CQAO6HslNwiEVnTrkdiCoTxD7w/ez5NAS4xgju5uYaN9Mt18/sPamBJX87dgRTp1S49y5VUVmT89sXqQQ4rFTt659HbwJE2Dlyhvs+O674O6uHv/9t12W17ZF0Y+Hf+R83HncS7vj+Yz6ENLTdEouTaCQtUx8dFoav1o/D7Pq9ddfNx4vX748W8cKIcTtSMArhHjsff3118bjFi1akC+bJY8n2mR3m/n44Dja7Lsb1CcIJx8nhm8w5x83LdXUzO5OnAhnz6rH+fJdN0950iSwXdY2bx6ULZuttyeEeIwNHmy/1r9jR7PzmeEWWd6n8z/Ns4WfBSBdT2f6rumAffGqiFnhtLumeFV2vPrqq8bjTZs2ERUVla3jhRDiViTgFUI81mJjY1m0aJExzm6xqvNJSSy0acXx1llPru5XlZYtbhYKDCzAtnPbWHV8FQAaGp/U/0TtfOECjBtnnuyTT8DaogPUFMT33jOfHjgQ3ngjW29PCPGYs1hg/nwoVEiNL1+Gli0hJeWaHQcNylKW95s935CYmohvc18cvVRhvaSTSbz6r5uxz6/R0Vy87gVuLjAwkJo1awKQnp4uxauEEHeVBLxCiMfawoULuWptBVSuXDlq1aqVreMnX7hAqrUNR508efAbddF4LrBnIE75nPjgjw+MbW2easNT/k+pwfvvmwtzy5eHbt2M/aKiVGuR9HQ1rlHDPjYWQois8vFRpQKcVHFldu1SSVw7t8jyNi3VlCJeRQC4lHiJhQcW4pDLAf92ZlbXfWY0NfPkASBN1/k+MjJb71GmNQsh7hUJeIUQjy1d1+2KVfXq1QtN07J8/OXUVL4ONYtT9YzKy5XdqiWH5qJR8N2CrDu1jk3/bgLA0eLIqHqj1M47dsC335on++ILo7pMRga0b68SwADe3rB4sXmzKoQQ2VW9Oowfb47HjYPt26/Z6SZZXgeLA32qmsFwZosi22nNF5dfpG1ucznIgmxOa7YNeNesWcOVbLY3EkKIm5GAVwjx2Nq2bRsHDhwAwN3dnXbt2mXr+BmhoVyxpmDLuLlRanS08VzgW4E453fmg/VmdrdLhS4U9y5+fRuiV18FmzZI48bB6tXm099+a05HFEKInOrfHxo0UI8zMqBDB7BOcFFukeXtWqkr7k4qGD4YeZANZzaQu3xuPKp5AKCn6NRdnYGL9UvDPfHxHLI7+a0VK1aMChUqAJCSksJvv/2Ww6sUQgh7EvAKIR5bX331lfG4TZs25LFOx8uK+LQ0Jp0/b4zfjvchfps1u+usUXBIQX4+9jO7Q3cD4OLgwofPfqh2XrQIQkLUY2dnVbjKatMm+PBD83WGDoWXXsrulQkhxPUsFpg7FzI/6k6cUEWt7Fyb5f3pJwC8XL3oVKGTsdsXIV8A9sWrEmdE0tSm6F92i1fJtGYhxL0gAa8Q4rF04cIFFi9ebIyzW6zqq9BQolJTASjs4kK1MbHGc/k758cp0Inh682Ky72r9qZAngIQF6dagGQaMACeeAKAiAh4800jocIzz6g6VkIIcbcUKgRTp5rjr76C//3PZodbZHn7VutrbF51fBUno0/i19oPh9xqOUbCkQSaR3sY+3wXEUFaNnry2ga8v/76K0lJSVk+VgghbkYCXiHEY2nq1KmkpaUB8Mwzz1CpUqUsH3s1PZ0JNq2IBiT7krA+DgDNUaPQe4VYdGARhy4eAiC3c27eq2Mttzx6NGRmPQICjDZE6enQti2EWTsa+frC99+Do+OdXKUQQlyvfXt47TVz3LkzREfb7GDbl/fAASPLWypfKRoXbwyAjs7UnVNxzO2I35t+xqFl5sTjby04EJaSwtqYmCy/r7Jly1KyZEkArl69ytq1a3NwdUIIYU8CXiHEYyc+Pt6u9+6gQYOydfyM0FAuWrO7hVxcqDnCzO76d/CHIOz67g6sMRBfd184dAgmTzZPNHEieKhsyJgx8McfarOmwXffQVBQdq9MCCFuT9Pg66/BzxqnhoVB7942O+TLB33NbK5tlte2RdGcfXOIS44joJs5rTlmcRRtvHyN8awwsy/57d+XJtOahRB3nQS8QojHzpw5c7h8+TIAxYsXp0mTJlk+NiE9nc/OnjXGfeN8SPzTunbXSaPIiCJM2TGFs7FqH183XwbVGqQKVfXta/YZevZZNX8Z2LABRo0yX2PYMGjU6A4uUAghbsPXF775xhz/8AOsXGmzg+1aXpssb6MnGlE6X2kArqRcYd5f8/Co6oF7ebVvRmIGTbebJeVXXrpEeHJylt+XbcC7cuVKUq1fLgohRE5JwCuEeKykp6fzxRdfGON33nkHB2s7oKz4JjSUSOsNWAFnF2p+cNl4LrBnIFfyXWHslrHGtlH1RpHHJY9qgrlhg9ro4ADTpoGmEREBbdqoeBigXj374FcIIe6VZs2gY0dz3Ls3GN2AbpLl1TSNftX6GZun7pyKjn2LotxfXqKOTU/eedkoXlWlShUKFCgAQHR0NJs3b87+hQkhhI37FvBqmva2pmmnNU1L0jRtj6Zpz9xi3yKapuk3+Hnxv3zPQoiH34oVKzh9+jQA3t7edLS927uNxPR0xtus3e190YvUvQkAWNwsFB5WmI83f0xcslrPW8qnFN0rdYf4eJUtydS3L5QrR3o6tGtnLun19YWFC412vEIIcc9NmqRiW4Dz5+2rxN8sy9vh6Q54uXoBcCL6BL8e/xX/dv5YXNVtZfxf8bRN9DJOMyssjIzMb/Vu49ppzUuXLs3hlQkhhHJfAl5N01oBk4GxQEVgG/C7pmm36zT5IhBg87P+Xr5PIcSjZ9KkScbjnj174p55M5cFM8PCCE9JASDQ2Zla75lrdwsMKMAZxzN8tdtsdfRZw89wcnCCjz+GCxfURn9/I4X76aewbp3anLluNzAwhxcmhBA54OMDn39ujqdMgV27rIObZHndnd3Vl3lWk7ZPwsnLya54VbVvEvGyVt07mZTExsvmbJjbad68ufH4xx9/lGnNQog7cr8yvAOBebquz9R1/Yiu632BMKDXbY67pOt6uM1Pyr1/q0KIR8X27dvZvn07AM7OzvSxbb1xG0np6Yy3Wbvb64InGUdVywxHL0cKvluQ99a9R1qGqvxct3BdXin5Chw+bH83OWECeHqyaROMHGlu/uADWbcrhLg/2raFhg3VY12H7t3BiDFvkuXtW60vjhYV0G76dxN7QvcQ1MestHfl+yje9DB78n4TGprl91O7dm1jWvOlS5ekWrMQ4o785wGvpmnOQGVgzTVPrQFq3ebw5ZqmRWqatlXTtOa32VcIIezYZnfbtGlDQEDALfa2N+3CBUKt2d0AJ2fqDDWzuwWHFCQkLoSfjv5kbJvYcCKarkOPHuadY+3a0K4dkZFq3a5tv11ZtyuEuF80DWbMgFy51Hj/fjBKHVyb5R01CjIyKOhZkFZPtjI2T9o+CY9KHuSppdbu6qk6r/xh3mb+FBXFxZSs5SksFgutW7c2xt9//32OrksIIeD+ZHjzAQ5AxDXbI4D8NzkmHngXaAm8BPwBLNY0rd29epNCiEfLqVOn+OknMyAdOHBglo+NSU1lrG1293QeOK1u3Jz8nQjqG8S7a981nm/zVBuqBlWF2bNhyxa10dERZswgQ9do3x4ykx358km/XSHE/VesmP2sk5EjwVruQGV5c+dWjw8eBGu7oEE1zdoESw4t4WzsWbssr2dwFNVzq9ZrKbrOgohrb/1u7k1rFXtQtRcSEhKyeUVCCKFoehaLCNy1F9S0QOACUFfX9T9tto8E3tR1vXQWzzMdqKPrevkbPPcW8BaAv79/5R9++OGuvPd7JT4+ntyZ/yERDwT5nTyY7uT3MnHiRH799VdAVQGdMGFClo+dASy2Pg7MgHktwemSdUM/WFNrDZ8e/RQAJ82JBdUWUCjBmaodO+IUHw/Av23acLp7dxYuLMSsWcWMc48f/zfVqkXn6JoeBPK38mCS38uD52H4naSlafToUZlTp9T7rFo1mvHj/0bToOjMmRRetAiA+KJF2T1rFlgsDNw/kH2X9wHQokAL3i70NrQCYtQ5f/0KJlrv7AoC8wEtC+9F13U6duzIOWuhwBEjRlC/fv27d7E8HL+Tx5H8Xh48D8PvpH79+nt0Xa9ywyd1Xf9PfwBnIA1occ32L4FN2ThPRyDxdvtVrlxZf9Bt2LDhfr8FcQ35nTyYcvp7+ffff3UnJycd0AF9/fr1WT82MVF32bhRZ8MGnQ0b9MkT9usb2KBvYIO+vch2PfpytO4/wV9nFDqj0IesGaIObNVK19VyOF1/4gldT0jQ//xT1x0czM3vvZejy3mgyN/Kg0l+Lw+eh+V3smOHrmua+Tm1cKH1iYsXdT13bvOJpUt1Xdf1VcdWGZ9/HmM99MuJl/VTI04Zn5Nbnt+je2zebHyGboqJyfJ7GTVqlPG53axZs7t+rQ/L7+RxI7+XB8/D8DsBdus3iQf/8ynNuio0tQdoeM1TDVHVmrOqAqrQlRBC3NKECROMKp+1a9emXr16WT52xOnTJFtnwlR2cqf8+2Y2ttiEYny0/SMirqppeoEegQyvOxx+/x0WLzZPMmMGUVdz0bo1pKdjfR+qeLMQQjxIqlUD23p+AwZAdDQ3rdjcuERjSudTKdwrKVeYtXcWgT0C0RxVHjd1XRwtHL2Nw2aGZf3WzXZa82+//UZUVFTOLkoI8Vi7X1Wag4FOmqZ10zStjKZpk4FA1MxBNE37VNO0PzJ31jSto6Zpbaz7ltI07V2gNzD1vrx7IcRDIywsjJkzZxrjDz/8EE3LyoQ6+Ds+3m7NWa/vLGp+CuD5jCfhdcKZutP8GApuFIxHmgV62RScb9eOjAbP06GD2ZnI21vW7QohHlxjxoC1SDIXL8LgwdYnBg60X8u7eDEWzWK3lnfyjslY/C3ke92s0PzSz+byuaWRkURlsXhVyZIlqVGjBgCpqaksXLgw5xclhHhs3ZeAV9f1xcAAYDjwF1AHeEnX9X+tuwQAT1xz2HBgN7ALaA100XX9c4QQ4hY+++wzkpOTAahatSqNstH7571Tp8i8TWuY7sETM66ogQZPfPEEfX7vQ7quUrYNijag5ZMtVQXTf60fZd7eEBzMxIkq6ZtpwQIoWPAOL0wIIe4RDw+YNs0cz5kDGzeisrwDBphPjBwJaWm0K98OP3fVg/dc3Dl+PPyjXfEq36nRVMqlWhsl6zqzspHl7dy5s/F47ty5OboeIcTj7X5leNF1fbqu60V0XXfRdb2yruubbZ7rpOt6EZvxfF3Xy+q67q7reh5d16vouv7dfXnjQoiHxrlz55g+fboxHjFiRJazuxtiYvg9Wk1f1oCO41KN5/J3yc9Kx5X8eVbV3XO0ODK18VS0HTsgONg8ycSJ/HnUlw8+MDcNHgwvv5zzaxJCiP9Cs2bw+uvmuEcPSEpCVWz28lIb//kH5s/H1dGV3lV7G/tO3D6RPLXz4F5eBbkZCRm0O+JuPP9laChpmX3ZbqNVq1bksvZL2r9/P/v27buzCxNCPHbuW8ArhBD32scff0yKdepc9erVeTmLkWa6rjP45Elj/EaMB0HrkgBw8HDAd4Qvg9cONp4fUH0AZd2LQMeOZnPdBg0Ie6ETLVua63Zr1FBTBYUQ4mEwZYrK9gIcPw6ffooKdgebn3989BEkJ9OrSi9cHV0B2Bu2l3Wn19lleSt9chk/JycAzicnsyKL63E9PT153SbyliyvECK7JOAVQjyS/vnnH+bMmWOMx44dm+Xs7pywMPZY2wm5aBqth5r9HwsPK8yYI2MIjw8HVKGqEc+OgGHD1B0hgIcHqV/PoWUrjXC1G/nywZIlYL3fE0KIB15QTMhNAAAAIABJREFUEIwbZ44//RQOHwb69QM/NYWZs2dh5kx83X3pWrGrse+YP8fg39Yfp3zqQ08/mUK7aE/j+SmZRQ2ywHZa88KFC41lKkIIkRUS8AohHkkjR44k3ZpabdCgAQ0aNMjScTGpqXxw+rQx7nrQHZ9/1Hlci7kS2jyUyTsmG89PajQJj5C9MNncRnAwQ74szJYtamixwA8/yLpdIcTDp2dPqFlTPU5Nhbfeggy33PD+++ZOY8ZAQgJDag/B0aKq8W3+dzPbLm4jqK+Z5W04MQFH6xePf8bGsvfKlSy9h/r161O4cGEAoqOjWbp06V24MiHE40ICXiHEI2fnzp18//33xnhMNuYRjzxzhihrC6MCOPHKu/HGc4XGF6LL6i5k6Gra8nNFn6NV4Zehc2fVmRKgcWMW5+7KF1+Y5xwzBp577g4uSAgh7hOLBb75xqwqv3UrzJqFioSDrMFseDhMm0Yhz0J0KN/BOHbMn2MIfDsQSy51u+m6OYFX080s74Rz57L4Hiz06NHDGE+zraglhBC3IQGvEOKRous6gwaZLTJef/11o63F7fx15QrTbabZ9Z5jwVUt3cX7ZW+meU3jSNQRANyd3JnVdBbakCGQmRH28uLY4Fl07WZOnX71VRg69A4vSggh7qNy5WDIEHM8ZAiExbjChx+aG8ePh9hY3qvzHhZN3V7+7+T/+Cv5LwK6Bhi7vTE7zXi8JDKSk4mJWXoP3bp1w9nZGYAdO3awa9euO7giIcTjRAJeIcQjZfny5WyxziV2cnJi/PjxWTouXdd56/hxrPWlqBXnSvVv1ToxSy4LSR8m8dm2z4z9P2v4GUV2HocZM4xtV8dN5ZUegVy9qsYlSsC8eZDFpcNCCPHAGj4cihdXj2NjoX9/oEsXKFZMbYyOhuBgSviUoNWTrYzjRmwYQYGBBYw7zvyL4nnOoiphZQATs5jl9fX1pXXr1sb4yy+/vNNLEkI8JiTgFUI8MpKSkhhqk07t06cPxTPv0G5j+oUL7LKuJ3NGo9egZDLj1AIjCtB1b1ej5269IvXoGdQM2rc3js9o9hqvLm3LP/+osZsbLF8Onp4IIcRDL1cuu+/3WLoUlv/ipHrxZpo4ES5c4MO6H9pleXdbduPfxt/YrfV3uvF4blgY4VksQtWnTx/j8Q8//MDFixdzeDVCiMeJBLxCiEfGhAkTOGltJ5Q3b16GDx+epePOJyUxzKZQVef1zhQ4oW7I3Mu7M6/SPA5GHgTAzcmN2S9/g6Vde4iMVAf4+zPMZwbr/jBTufPnq2mAQgjxqHjuOejUyRy//TZcerEtlC+vNiQkwPDhlPEtQ7vy7Yz9hq0fRqFhhYy7zidmxlNZcwMgWdcJPn8+S69ftWpVqlWrpo5LTpYsrxAiSyTgFUI8Ek6fPs3YsWON8SeffIK3t/dtj9N1nR7Hj3PFWtH5iSQnXh9nzTY4AJ/B2BDzvOOeG0exLxfBhg1qg6bxS+uFjJvjZ+wzejQ0b37n1ySEEA+a4GAIsC7JjYiAAYMcYNIkc4f582HfPkY+O9Ko2Pzn2T/Z6rTVyPJqQNsfzS8Ip124kOUs74ABA4zHU6ZMIS4u7s4uSAjxyJOAVwjxSOjXrx9JSarCVOXKle0qet7KvPBwfouONsb9R6ThrIo0EzAkgPb/tDemMj9T6Bl6Xy2rIlqr0+0+5LVpZgnmli3t67gIIcSjJG9e+Pprc/zdd7Aq6Xlo0kRt0HUYOJBiXkXpVrGbsd+QtUMoMMxcy/v0l1cphysAiRkZjD17Nkuv36JFC2OpSkxMDF999dWdX5QQ4pEmAa8Q4qG3bNkyVq1aBYCmaUyfPh0HB4fbHncuKYkBJ04Y49Z/OvHULjWV2e1JNyZVnsSxS8cAVZV5dq3xWNq2M1oQJVSvR9VfRmBNDlO5MsydK0WqhBCPtldegbZtzXGPHhD34QTI/NzduBEWL2Z43eHkcswFwP6I/SxJWIJ/W5XltejQdZ75Yfl1aChnrV9a3oqjoyPvvfeeMQ4ODiYhIeHOL0oI8ciSgFcI8VC7ePEivXr1Msbdu3c31njdSrqu0+noUeKs0WrhBEc6jlGpXc1J49yoc8w8ONPY/8sXp1Ki70jVbxJI9/HlubCFXLqsbvACAuDnn1WxKiGEeNRNngx+1pUcoaEwYEZp6NvX3OGddwjSczO0tllIcNj6YeT7IB+aswp0n56fSOUUFRCn6Dqjz5zJ0mu3b9+eggULAhAZGck333xz5xckhHhkScArhHio9enTx6jUGRQUlOU2ROPPnmX95cuAWk82aGgartYlZLmH5abTP52Mfds81YYOS4/B2rUA6JpGH8/vCDkbCICrK6xYAUFBd+eahBDiQefjA9Onm+O5c2FtndHmAt/wcBgxgndrvUuQh/pwjLgaQfD5YAr0LwCoz96On5t9eeeFh7PPWi3/VpydnRli0xj4k08+4bL181wIIa4lAa8Q4qG1ZMkSlixZYoxnzpyJl5fXbY/bFhvLCJuqzB2WW3hKFWHGo54HHbw7EJ8SD0CxvMX46mp9tHFmIP1dwQ+YcaoRoGbwLVkCWUgqCyHEI+WNN6BFC3PcoU8e4kZ/bm6YNg33v48w7vlxxqbgkGCS3krC0UcVtHpqdSp1L6ssbwbQ559/0HWzbdHNdOvWjcKFCwNw6dIlxowZc+cXJIR4JEnAK4R4KJ08eZLu3bsb4y5dutC4cePbHncxJYU3Dx/GuuyWCv860P7LDACcfJ2Y1noah6MPA+Dq6MryJz8iz1vmNL3d+V+m01mzaNXMmWo9mxBCPI6mTTOnNoeHQ5sVLdEbNlQbMjKgY0falHid6kHVAUhJT6HH5h4UGVXEOEf3wUk4WTufb4uL47uIiNu+rqurq92MnilTphht6YQQwpYEvEKIh05ycjKtWrUy2lEULVqU4ODg2x6XmpFBy8OHOWttf5EnRWPo0HQcMgAL7HpvF/PC5xn7f13tY55+8x2wFlIJ8yrNc+ELyUCt2x03Djp3vrvXJoQQDxM/P9WJKNOvv2nMr/6VWdDg8GEso0bzzSvfGG2Ktp7bysrKK8ldITcABU7otNnmbJxj8MmTXE5Nve1rt2zZkpo1awKQkpLC4MGD79JVCSEeJRLwCiEeOgMHDmTPnj0AODk5sWTJEjw9PW973LsnT7Ixc92uDu+N1MlvTSTE9onlnSvvGPv2LteFDm9/Ddb1wVddval7eSVxqNd55x2wWUImhBCPrRdfhIEDzfFb45/gVK8J5oaJEyl/Mp73apvVlYduHEqez/MYd6ItP0nGP00FxBGpqfS3qaB/M5qm2X3Z+dNPP9ktcxFCCJCAVwjxkPnyyy+ZblMpZcKECVSpUuX2x124wJQLF4xxl7lQM0Q91l/QaeXTyniuUaEGfD7+L7DecKU4uNIw6RdOUAJQ7TgmTpT2Q0IIkWnsWKhUST1OTYVnFvYk+Znn1YaMDHjzTYaX60XpfKUBiE+Jp9PJTgT2U8X/3BKh96QM43wLIiJYbv3C8VZq1KhB165djfHbb79NRBamRAshHh8S8AohHhq7du2if//+xrhFixb069fvtsf9GBlJ33/+McZ1t0Lbb9Vj7WmN5jWak6yrac5P+pRhydwrOO3aC0AGGq3SF7GdWtbXVNVILfLpKYQQBhcXWLYMvL3VODTcQpvE2eiZs2/OnsWlc3fmvjIbB00tC9l+fjsLGizAtagrAM+szqDxPkfjnD2OHyfcugTlViZNmmS0Kbp06RI9evTIUuErIcTjQW7ZhBAPhe3btzNy5EjSrX1zq1Spwrx589Buk2b9IyaGdkeOkHnrU/YYvPeJaoehBWp0atKJaC0agKDcgfz6iweef+4yju/B16zgNUAFuwsXgpPTXb88IYR46BUpAosXm18ILt9diM8rLDB3+O03any7gU8afGJsGrN3DLHjY9Ec1Wf52x+m4Z+oAuKo1FRaHT5MSoaZ+b0RT09P5syZY4x//vlnJk6ceHcuSgjx0JOAVwjxwNu9ezcvvvgiiYmJgOq3u3LlStwyi6LcxJroaJocOECy9Zv+gqEwdgjkSgJ8oHfr3pxxOgNAPlcf1v2Sl8JrdhrH92Eqs1CVoNu2lWBXCCFu5/nnVUG/TIM2NWVjNZuCB8OHM+RCERoWa2hsanmyJbmGqdZEua/C4OHpaNZvKTfHxtLPZobOzV/3efr06WOMhw4dyu+//35nFyOEeCRIwCuEeKBt2bKFRo0aGRWZfX19WbNmDQEBAbc87peoKJoeOECSNTPgGwWfDQTPONDz6PRt3ZdDeQ4B4Onkwf9+9qD0pkPG8QOZxJeom6d+/WDBAgl2hRAiK959F3r2NMfP7xzDuWLPGmNLh458m78XQR5BAMQlx9HCowXuL7gDUHkvdDMTtnwdFsbU8+dv+7qTJk2iTp06AOi6TuvWrdm/f/9duCIhxMNMAl4hxANr+fLlPP/888TExACQJ08e1q1bR9myZW953NTz53n14EEjs+sfAV/0g/wRkO6RTv9W/TnoexCAfE6erP/OgUrbzwBqzW53vuFzVMnRsWPhiy9kza4QQmSVpqn+vM2aqXE6jjx9ajmXfFXBKlJS8G/RmV+fHk9uZ9Wa6Gz8Wfo16odLGRcA3vwOnt9kLlnpd+IEs8PCbvm6zs7OLFu2zFjPGxcXx3PPPcfff/99l69QCPEwkVs4IcQDJz09nVGjRtG8eXOSrQVL/Pz8mDBhAuXLl7/pcckZGfQ+fpx+J06QueIrIBS+6A+BYZCUN4m32r7FgaADAARpnmyeEk+lI6pVUTLOtOYHZtEdNzdVgOX996UasxBCZJeDAyxaBHXrqnEM3lS++DtXcudXG2Jjefq1XiwpM9IoYhVyJYTBbQfjGOCIBrw7VqfsMfOc3Y8dY+5tgl4/Pz9WrlxptKq7dOkSDRo0MFrZCSEePxLwCiEeKKGhoTRu3JjRo0cbVTZLlCjB9u3bKVmy5E2P+ychgVp79zI9NNTYVvoITOujMrsX/S7StX1XTuU/BUCFhDxsC46lTIQqghWBH/XZwFJaUrQobNkCr79+Dy9UCCEecW5u8NtvUL++Gv9LEerEr+aKi4/acOUKjduOZE7hfmiobxa3pm1lRMcRaJ4aLikwfhCUsi7h1YEux47x0Zkzt6zCXKFCBdasWWMX9D7zzDMsXrz4Xl2qEOIBJgGvEOKBoOs6s2fPpmzZsqxdu9bYXr9+fbZu3UqxYsVueFy6rjP5/Hkq7t7N3vh4Y/uzG+Hzd8A7BnaX2E2Xzl0I9VbB8BsnnNnyeRyFYtW+e6lIVXaxnVq89hrs3QsVK96zSxVCiMeGuzusWgUNrTWq/uZpaiZv5JKTv9qQkECHzl/wnUMLI9O7wXUD/Tv1R/fRyX0VPhsExW3qVo08c4a2R44Qn5Z209etVq0aa9aswcvLC4DExERat27NoEGDSEpKuifXKoR4MEnAK4S477Zt20bt2rXp1q0bsbGxxvbhw4ezdu1afH19b3jc9thYau3dy4ATJ7hqLU7llAJ9psLI0eCcksGCugsY+uZQ4nPF45yhEbwalixMwT1VnSOYd6jJdmJyF+Lrr9U0Zuv9kRBCiLvAzU0FvZ07q/EhylEj9U/OWgqrDbpOmw+XsPhkRVwc1Bre/Xn306lNJ5L8kshzBYIHQuXd5jm/j4zk6d272W7z34xrVatWjZCQELvZQcHBwVSsWJGQkJC7fp1CiAeTBLxCiPsmJCSEZs2aUbt2bbZv325sf+KJJ1i/fj0ff/wxDg4O1x13MD6e5gcPUmvfPnZeuWJsL3wGpvaFN5ZDmFco/Tv1Z26DuWRYMigbCSHf6LwTAhYdzlKQF/mdQQRTr5ELBw/CW2/Jel0hhLgXnJ1h9mz49FP1OXuCElTO2MUm6hr7vLFgN39+70qgY14AzvqcpU37NpwocQKPeBj3HjT92TznqaQk6uzbR99//iE6NfWGr1uqVCl27NjBSy+9ZGw7evQoNWvWZMyYMZw9e/beXLAQ4oEhAa8Q4j8VHx/P3LlzqVOnDjVr1mTlypXGc87OzgwZMoS///6b+pmLvqwydJ09wCsHDvDU7t0si4oynnNKgc5zYGZ3eOJEGotrLqZbr24cLHwQ11QY8wfs+xoqhkM6Fj5nAGU5zLEiL7J8OaxeDYUL/1f/AkII8XjSNHjvPVi3DgIDIQpfnmcdU+hr7FP1cCy7x8Xw7GU11SbGI4aerXuypOYSHNNhwBfwwRhwt65gyQCmXbhAiR07mHTuHFfT0697XS8vL1atWsWMGTNwd3c3tq9bt47ixYvTrVs3jh07dt1xQohHgwS8Qoh7LiMjg23bttG9e3cCAgLo0qULW7dutdundevWHD16lPHjx+Pm5mZsP52YyMjTpykWEsK7wKpLl+yOa/AHzOsEHb6FvUV20L1nd2a8MINEl0Ta/A2HpsMHf4JzOvxCE8rzN+P8Pufj4NwcPgyvvSZZXSGE+C81aAB//w0tWkAaTvRnCo34H+coAEBAPKyffJkvVoNrhoV0h3S+euErBnQcQJh3KA3Xweyu9lOco9PSePfkSYqEhPDxmTOEWyv8Z9I0jR49enDgwAFet6lImJqayuzZsyldujQNGjTg+++/5+rVq//Jv4MQ4r/heL/fgBDi0ZSQkMC6detYuXIlq1atIiIi4rp9HB0dadOmDUOHDjV66+q6zvHERH6JimLlpUv8eYP1WVoG1NkCbRdCqeOwp+gePu08j4OFD6Lp8NoR+HCTyugC/M6LjOUDzhZ6hv79oUcPVUhFCCHE/eHjA0uWwO+/Q58+sPZUI57iAB8xgreZjqOeTv8QePl4Bu82gp9Lw/6i++nSswtttrShxfYWTBiciy114KteEBaozhuVmsqIM2f46N9/aebjQ1t/fxp7e+NqXR5TtGhRli1bxubNm+nduzcHDx403tOGDRvYsGEDbm5uvPzyyzRp0oSGDRsSEBBwP/6JhBB3iQS8Qoi7IikpiR07drBx40Y2bdrE9u3bb1oJs1SpUnTt2pUOHTrg7+9PdGoqK6OiWB8Tw69RlziRfOPj8sTC8+ug6UrIH5rMxic3MqHHUk4GnMQrEXrtgv4hUOoSxOHB17zJTEtP/F+sSL9OKpvrKJ96QgjxwGjcGA4dghkzYOxYL/pfnMJX9GI8Q2nKLxSPhhU/wPqiMKwBhBRMZm6DuaysspL2m9vTeHtjqu9wZvWLsKgNRFjb/KbpOsuiolgWFYWHgwPP583Li97evODtTWFXV+rWrcvUqVNxdHRkwoQJrFq1igxr8cOEhASWLl3K0qVLAXjqqado1KgR9evXp2bNmnh7e9+vfy4hRA7IrZ8QIttSU1M5fPgwe/bsYc+ePezevZv9+/eTfM0UMlu+vr40bdqU9h074lOxIvvi4/koNpbNJ//lYErCTY+zpEPVXdD4d6i+PYPDQX/xQ8W1bG6zmSTnBF44CWOXQtNj4JoGG3mWT+jKifJv0LKTG6vehPz578W/ghBCiLvB1RUGDIBu3eDrr2HKlDI0O7uS8uznfT6lOT/S4HQ622bDpiLwWW1YXfwSXzT5gvnPzuf1na/z8h8v89JvedlYD1Y2hQPlzfNfSU/np6gofrLWfiidKxfPennhBXSqWJGfVqwg9MIF5s2bx6JFizhy5Ijd+ztw4AAHDhxg0qRJ6vjSpalVqxY1atSgYsWKlCtXDldX1//k30oIkX3arRp3PwqqVKmi7969+/Y73kcbN26kXr169/ttCBvyO1EyMjI4e/YsR48e5ciRIxw5coT9+/ffNrjNVLpsWaq/8AIB9eoR/URx9sVc5WBKAomWW3/u5EqAKruh5naovCuVc3n+ZkeJHWx8ciNX3C7y3Gl4+Tg0OwY+V5zZQH1WOzThUq1XqPx6YRo3hlKl7ta/grgV+Vt5MMnv5cEjv5OsS0uDFStgzhz43/8gf8YFujKbLsyhCP8CcMYLZlWChU/BmbzgmOZIzeM1abS/EdVOVCO0gDN/PAfrG0Bo0K1fz1NzoLpXHmrkyUO1PHnIdfYsO1avZu3atWzZsoXUm1SAzuTg4ECZMmWoWLGi8VOmTBn8/PzQpEhEtsnfyoPnYfidaJq2R9f1Kjd6TjK8QgguX77MqVOnOHnyJMeOHTOC22PHjpGQcPPs67X8nniCfBUqo5ctz6WyT3I0vxdHM5+8GKn+9wal8hzSoNQxKP83VNoLXufPcLjAfrYU38nUt/ZSIiaJuv/C3FVQ/wycTC3HFq0uU4o/h2PnhlR/3oMxDWRdrhBCPAocHaF5c/UTGgrLlgWxfPkIxm4aTjU9hNb8QOPLv/PJ+hN8vB52BsHPpdNY88SffPjmn7gluVH9n+pU3VuV4B8rk+Tlx66qsLMa7H8aUlzsXy9WT2dNTAxrYmKMbXlr1qF8wxfp5mTB6cABLoaE8M+uXezft++6ADg9PZ2DBw9y8OBBvv32W2O7p6cnpUqVomTJkpQqVcr4KVGiBLly5bqn/4ZCCJMEvEI8BtLS0jh37hynTp2y+zl58iSnTp0ixuY/8lnl4pcfS4lSJJUqjl6qJJQqRaSnJ5FZONY3Ekr8AyWPQ/GjiThHn+Ck3yEOFDrA1poHKR4XR9UL8P5eKLciD6eSanLKqxLbgp7in6FNqPCcDx2rgU0xZyGEEI+gwEDo21f9xMRY2LSpFn/8UYuv10Pi4VM0Yg0vXPgfgy9sZOwfl7noBuuKJbD2iQ2srL2Bz5pBwUsFqXyqMi/Nf5reUaWIKhDAkTJwpAwcLguX817/ujGksyk+lk0ABQoYEbhfUjr+Z87gcuIIyUePEnXkCGGnTt3wvcfGxvJ/9u47vqr68P/469yd5GYnBILsrYKAIIqj0h/WbSlii7bOIi4UHLirQp1VcaFMFWlt1aJ1oF+lQ7RFEURBpoqywkwISW6Su+/5/XHDNUGWmuTcXN7Px+M8zv2cc5O8wwcN75y1aNEiFi1a1GC7YRi0bduWDh060KFDBzp27Njgdfv27VWIRRqRCq9IC2eaJpWVlWzcuLHBsmnTpsTrzZs3E93LswkPSnZ2/CG17dvH1x06QPfuBLOzD/ih9ggcVgId18cLbuHmCqj+mm0Zq1nbei2fe9eyo8s2+nlNfrEVLllViK/6WDa3OpqaHv3ZObI/JUM7MbCvwc8zd59Sk//jvg8REWnRcnNh2LD4ArB1a2c+/vhKFi2+kmcWxahY9BVHVC/kuBUfM3bFQqazkmpPlMXFm1jUdhOfHPU6U9pCiBx6bulJj3/24KxZPcmLHk5JpyxWHQ5fd4NvO0ONd+8Zdnjs7OjZBXp2gbPOim+srYW135D11Te4v/2WyLpvqNm0gdA+Hm9kmiYlJSWUlJR87xF9uxUWFlJcXExxcTFt2rRpsN79unXr1jidzp/6xyqS8lR4RZKYaZrs2rWLLVu2sHXrVrZs2UJJScn3Cq3P5/tpX8jlgjZt4r9Kb9u2Ybk9iGKbtxPabIV2m6DN5jDpu8rAv4Fq82t2ZG/AcG6iNrIJu81P+7Cbo749jHPWHEko5/fEuvUg7fietDq+O136Z1FQoOfiiojIgbVpA8OHxxewEYv15JtvevLFF5fw2hdw3+cBAp+tIv/bZfT9dik3spSj+Jyq7AqWt1rIF0UL+eIoWN4KytwFdCjtzBFvdebMHZ3IjfYgkNOWjR0drO0K6zrBlmKI7K1fpqdDn95U9en93TbThPJy2LQJNm6ETZuwbyzBtmkT4e1boe6O0PtSWlpKaWkpy5Yt2+/7CgsLKSwspKCgIPF6X0tBQYEKshySVHhFLBCLxSgvL2fr1q2JIru39datWw/q5lAHJT8//q+D3cV297q4GPLy9tsyvb54oW29DVpti5JeVYmjppRoqIRweB2GsRmXbSvZkW3k1frJqi7CG+qA196DDE7D2bUT3iM7UjCgI21755GZpUYrIiKNy2aDbt3iy7nnAniA/vh8/VmxAlasgLlfmpQv3Yjx5RoyF6zmJPNLrmA1neyr2VW4iNUFi/gqH5blw9pcOz5bW/K+bMexH7Wl7a72pNMJM6MYX14OJYfB5rZQchhsaw0xe70whhH/uZufD337AhCtWwiHYccO2L4dtm2Lr+u/3rHjgIV4t93F+GDl5ORQUFBAQUEBubm5B71kZGToBlzSYqnwijSCQCDAzp07Ez94ysrKEq/3Ni4vL088769RuN3QqhUUFcXX9V8XFUFhYfwo7l5kVEPBBigshbyyCGm+Gly1FRAsw+7fSnrtRtJDJbjMchwxP2lRF1m0IdvdgYKsruR1OJ2Mrm3J7lVMfu9istt6dYRWRESSRmYmHHdcfAED6AB04F//8tC+/Ti+/BLeWAc7vtxFePVa2LCe7ovXcULtOjryLZkZ3xDIX8TWnDDrc2BDNmxxe6jd2RrXjtYc82FrCnxtcNvbY3e2JppeQE22lx2tYHsRiXXiZllOZ/xsqrb7uH10NBo/OlxeDmVlsHPn3pddu+JHkn+AiooKKioqWLt27Q/6OIfD8b0SnJ2dTVZWFllZWWRmZh7Ua4dD1UOan/7WySHPNE0CgQA+nw+fz0dVVRWff/455eXlVFRUsGvXLnbt2pV4vXu9c+cudlVUUFmxi1CokY7C7k16evw3xHl58XVBQcMy26oVZGV97witPQJ55fEle1MUb2UNab5qXDUVeGrKSKvZSqZvM+7ILnD4cTqjeN1e8tKKaZ3dibadu5HX8Sgyu7Um54i2OApydK6xiIikDIfDpHt36N5995ZcYGDdAjU18bOR16+HDetiVK/dhvubdXTbvJnDd2whbdcWMms248rYQCzncwLZO6j0+tlqQm3MibeyEOfXBRTH8nGG8siIFeO0t8buKCTmySWU7qUmy8POfCjPiy878yGQZo//orqwcP/P2ItGoaLiu6WyMr7UH+9+XVUVH//IX7ZHIpEffDR5b9LS0hoU4czNaw1KAAAgAElEQVTMTLxeL+np6WRkZJCens7OnTuZP38+6enpDbYf6LXKtOyL/mZIi7G7mNbW1lJbW4vf72+wrq6uparKz65d1eza5aOiwkdFZd1SVUVVVSXVvgpqayrx+30Eg7WEgjWEQ35MsxGPth6sjIx4iS0o2Pc6Px/2uFNjVmW8xOaWm2SWhPCs8eOqLcHt34W7tgyPvxRvbSkZ4Uo8rhhpXhc5WQW0zm9P246dadelJ7ndW+NoWxS/PlclVkRE5HsyMqBXr/gSf6Zecd3ynVgsfiB269b4GcmuddWkr91Kp5ItGNu2Yisvw1FRhq12O0FjPUHXQkLeUsLpFYTSq/G5DdrY8ggauYTJJhbLJmLPJ+JqhcOej+HIAWcWMbeXkCedYLobX5aNymyoyrJTmZ1PVft8Il0O4huKxcDn+64YV1fHxz7fgV830uVVfr8fv9/P9u3bG+Xz1edwOklLT8ftduPxeOKL201aWhppdeP6+xq87wDjfe1zu904nU5cLhculwun04nNtpfnL4qlVHjlB4tEIgQCAYLBIIFAIPG6tjaAzxfA5wvWrQNUVweoqvZTWe2nuqKKKl8lNT4ffn8N/kANwaCfQMhPKOQnFAkSDgcJR4JEIyEikRDRekssErL6W983hyN+zlR2NuTkHNza4cDjh+xKyKoyyaiO4qkJ4vYHcG2owb2mEk+gBE+gkvRQNd5IDXkxP1mZLrILM2l9WCsO69Gedh064m3dG6OgYK9HekVERKRp2Gzx308XFEDv3gBeoFvd8n2mGb+pc3l53VnJm2up2VBGaEsZsdKdmDvLMSsqMXdVUBvcTq35JX5zJwH7LsL2KkL2akybCTYnps1J1EgjZHgJOnMJunMJObOJuLKJOLMwHBmYzgxizjQiLg9ht4ugJ4NAejY1GVDdGmq6QE0G1B7oOfah0Hflt6oq/rqmJv7N7F72HO/e5vd/t+8HnoL9Q0TCYXyVlfzE23j+ZDabHYfTGV8cTpx1RdhRrxi73C6cLidutxu3y4XLGX/tcbkajHeX6MTH7TH+KfvqL3a7/cDfWAumwpukTNMkGo0SCoUOevH7Q9TWhqipCVHtC1BZFaCqohpflQ9fdTW1NTXUBvz4A7UEgwECoWC8ZEZChHcXzFiESCRMJBomFosQjYSJRSPEomFikTCxaPhHnw6T1JzO+JHU9PT44vXGl8zM+LJ7vMc2t8OLFy/pURdp/hgefwSPP4w7EMIZDOIO+nGGavFs9uNZ7yM9thOvESLbHqPIY1CQn05+21yKOhSRV9iG7ILuuPIK458/xf/nIyIicqgxjPiR44wMaNcO6JsOtK9bDl4wWNc7ywLUbK3Cv72KcEUN4cpaIlU1RKqqqa3eRbWvjECggkC4kmC4imC0inDUTzQSwoxFicXiBTSGnbDDTdiVRtiVTsSdQciRTtiVQdiZTsSRTtSVRsTpJuosIOpoQ9TpIpLlIFzgIOi2EfLYCHhshFwQdMeX3a9NG/GyGwh8vwgHAvElGPzu9d7Ge27bc38TlukfIhaLEgpGCQUDVkc5eIaBzWbHZndgszuw2+11awd2R/zO3q1aH8aaZR9bHPTHUeG10GHdj6Z0yzfEYlEwTcxYFNOMYcZimHXbZA9OJ3g88Zs07V72Nk5PTxRYuysdp92Dw5mOy+nB6fDgtHtwOdy4bC48OEiLGrhCYZyhCO5wCEc4iDsWwW2GSDOjpNtieA3IitnIizopiEGhyyCn0ElWUSaZOa3IyG2Fw5sV/3WviIiISBNxu3df5uuBXh6gVaN+/mgU/L4I/rIaAuW1hH0BQr4gkeoAgaoa/DVV1Nb4CPh9+MurCQR9BIM1BIM1hINBIqEQ0XCEaDhMNBojiknIcBC2x5eIw1m3uIg43EQdLiKOTKLOAiIOF1Gvi0iOk6jDRdThJOK0E3E6iDjsxBx2onY7UbtB1GEj6rARtkOECJFoiBBhwmaIsBkiYoaJxELEYqH4Uer6Szi87/HB7AsGIRKJL+Fw/A8tHG7UeWg2pll3gCuyz7dUmvvel+xUeC1UFvUTqqm0OsYPZxjx/9M6nfE7/7pce39dtzacLmx2J3Z73drmxO6oW9scOOwuHHVrp92Jw+bAaXPgsjtw2Ry4bHbcNgduux034DJjeIwYHkzSbJDuMMhw2fCm2cnw2MnMcJPtTSc7O53c3Gwy8nNIL8glPTMPh2Pvdyre0/z58zn55JOb9I9RREREJBnZ7eDNceDNyQaym/Vrz58/n5N/9jPMUJhwTei7pTZMpDZEuCaIv6YWf20NAX8tAX8VAZ+fYNBPMFBL0B8gHAgSCYaIBMNEQmFC4QjhqEkICGMSxiCCQdiwEbWlE7ZlErXZ40u6I762O4jaHEQdDqJ2BzF7vbXDTtRhJ2azE7PZiNnrSrjNIGqYRMwYMWJEzSiRWJQoMaJEiZoRombdOlb3mgjRWLhuX5hYLIoZDX9XpncX6r29PtC4fhHf23uj0fj6IA6yGS34zEMVXgsZBzoSaLfHS6PDEV/vOd7f2uHAsDux2RzYbY742nBgM+w47PFticJp2HHY7Dhtdhw4cNhsOA07Lpsdl2HDZXfgsdlx222k2Z24HQZpdoM0hw2P00aGx47XHS+aGekuMtM8eLMyyM5MJzMnE29eLp7sLNyuND3DTURERET2zzAw3PFrXV15Voc5CKYZv+SvrlCaoTCxUISIP0zIHyLo9xMMBAn6/fj9AYKBAKFQgKA/RMgfIOQPEQ4ECQcjhMNhwqEwwUiEYCRGKBIjYpoEMeNHsm0mUZdB2ISoES/uUQyiNhsRw0bMsBG12Yga8SIeM+xEbTZidhvR3QXdZqtX1m3xjyf+daKY8bJO/HXUjBIzY6T5m/CJJE3MssJrGMbVwHigDbASGGea5n/38/7ewGTgGKAcmAb80TRb7nm/p51wAZU/d2IzwY4NB/EJcdgMnDZwGjYcBjhs4LIZuBwGLqcdt8OOx+Mg3eMkPcOFN8NNTpaH7Ox0srMyyMrJIisni3RvDk6nRyVTRERERKSpGEb8wFTdUVADsNctbiDTwmiNoaWf+WhJ4TUM4zfAE8DVwP/q1v9nGMbhpmlu3Mv7s4B/Ah8SfzhaD2AWUAM82kyxG90/nr8daPl/iURERERERJKRVXfXuQGYZZrmDNM0V5umeS2wFbhqH+//LZAOXGya5grTNF8FHgJuMHT4UkRERERERPai2QuvYRgu4Ghg3h675gGD9/FhxwH/NU3TX2/be8Sf/t2xsTOKiIiIiIhIy2c09yWwhmEUA5uBn5mm+WG97XcBvzVNs8dePmYeUGKa5mX1trUHNgCDTdP8eI/3jwZGAxQVFR390ksvNcn30liqq6vxer1Wx5B6NCfJSfOSfDQnyUnzknw0J8lHc5KcNC/JpyXMyZAhQ5aYpjlgb/usvEvznk3b2Mu2A71/b9sxTXM6MB1gwIABZrJfH6treJOP5iQ5aV6Sj+YkOWleko/mJPloTpKT5iX5tPQ5seIa3jIgCrTeY3srYPs+PmbbPt7Pfj5GREREREREDmHNXnhN0wwBS4BT9th1CvDRPj7sY+BEwzA8e7x/C7C+sTOKiIiIiIhIy2fVXZonAZcYhjHKMIxehmE8QfwGVFMBDMN4wDCMf9d7/1+BWmCWYRhHGoYxHLgVmNSSn8MrIiIiIiIiTceSa3hN03zZMIx84E6gDbACOMM0zQ11b2kDdKn3/krDME4BngY+BXYRf/7upGYNLiIiIiIiIi2GZTetMk3zGeCZfey7ZC/blgMnNXEsERERERERSRFWndIsIiIiIiIi0qRUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSYZpmlZnaFKGYZQCG6zOcQAFQJnVIaQBzUly0rwkH81JctK8JB/NSfLRnCQnzUvyaQlz0sE0zcK97Uj5wtsSGIbxqWmaA6zOId/RnCQnzUvy0ZwkJ81L8tGcJB/NSXLSvCSflj4nOqVZREREREREUpIKr4iIiIiIiKQkFd7kMN3qAPI9mpPkpHlJPpqT5KR5ST6ak+SjOUlOmpfk06LnRNfwioiIiIiISErSEV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiIiIhISlLhFRERERERkZSkwisiIiIiIiIpSYVXREREREREUpIKr4iIiIiIiKQkFV4RERERERFJSSq8IiIiIiIikpJUeEVERERERCQlqfCKiIiI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v57TTjuNiy++mNLS0sT2n//853z22We8+OKLdO3a1cKEP55hGJxyyiksWrSIv//973Tu3Dmxb/ny5Rx//PHcdNNN+P1+C1OKiIj8NCq8IiIiezBNk5kzZ3LkkUcyb968xPZ27drx97//nX/961/069fPwoSNxzAMRowYwcqVK7n//vvJyMgAIBaL8eijj9K3b18WLFhgcUoREZEfR4VXRESkntLSUn71q19x+eWXU1NTA8RL4bhx41i1ahUjRoxolrstNzePx8Ntt93GypUrGTp0aGL7V199xYknnsi4ceMaPN9XRESkJVDhFRERqbNw4UL69u3b4KZUPXv25KOPPuKxxx5r8GifVNWhQwfmzZvHjBkzyMzMBOJHvJ944gmOPfZYvvrqK4sTioiIHDwVXhEROeSZpsmUKVM46aST2LJlS2L7mDFjWLJkCccee6yF6ZqfYRiMGjWKlStXctpppyW2L1++nAEDBvDqq69amE5EROTgqfCKiMghze/3c+mll3L11VcTDocByM3N5e233+app54iPT3d4oTWadeuHe+88w5Tp07F7XYD4PP5GDFiBDfccEPiz0tERCRZqfCKiMgha926dQwePJgXXnghsa1fv34sWbKEM844w8JkycMwDK644go++ugjOnXqlNj+2GOPcfLJJ7N582YL04mIiOyfCq+IiBySFi1axDHHHMPSpUsT2y655BIWLFjQoNhJXP/+/VmyZAnnnHNOYttHH33EoEGD+OKLLyxMJiIism8qvCIicsh5++23GTJkCGVlZQA4nU6mTp3Kc889R1pamsXpkldubi6vv/46f/rTn7Db7QBs3ryZE044ocHjm0RERJKFCq+IiBxSnn32WX75y18mHrGTn5/PBx98wBVXXJGSjxtqbIZhMH78eN59912ysrKA+HW9Z5xxBs8995zF6URERBpS4RURkUOCaZpMnDiRUaNGEY1GAejYsSMfffQRxx13nMXpWp6hQ4fyv//9j3bt2gEQjUb5/e9/z5133olpmhanExERiVPhFRGRlBeLxbj66qu5++67E9v69evHxx9/TPfu3S1M1rL17t078ezi3e677z4uu+yyxC8VRERErKTCKyIiKS0Wi3HFFVcwderUxLZTTjmFDz74gNatW1uYLDUUFxfz4Ycfcvrppye2zZo1i4suuohIJGJhMhERERVeERFJ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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import os, fnmatch\n", - "import chebSolver as cs\n", - "\n", - "tds = cs.timeDomainCollocationSolver(2,1,250)\n", - "\n", - "#files = fnmatch.filter(os.listdir('.'), 'restart_Np150_*.npy')\n", - "files = fnmatch.filter(os.listdir('.'), 'restart_psaap_Np250_*.npy')\n", - "files.sort()\n", - "print(files)\n", - "cols = ['b-', 'r-', 'g-', 'm-', 'c-', 'k-', 'b--', 'r--', 'g--']\n", - "\n", - "files.append('newton_psaap_Np250.npy')\n", - "\n", - "#or file, col in zip(files, cols):\n", - "# print(\"Plotting {0:s} with {1:s}\".format(file,col),flush=True)\n", - "\n", - "create = True\n", - "for file, col in zip(files, cols):\n", - " tds.U2 = np.load(file)\n", - " tds.plot(col,create)\n", - " create = False\n", - " \n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "tds.U2 = np.load('newton_psaap_Np250.npy')\n", - "\n", - "ne = tds.U2[0:tds.Np]\n", - "ni = tds.U2[tds.Np:2*tds.Np]\n", - "nT = tds.U2[2*tds.Np:]\n", - "Te = nT/ne\n", - "\n", - "plt.figure(figsize=(16,9))\n", - "plt.plot(tds.xp, Te, 'b-')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/psaapProperties.py b/psaapProperties.py deleted file mode 100644 index 549ce9335..000000000 --- a/psaapProperties.py +++ /dev/null @@ -1,233 +0,0 @@ -import numpy as np -from scipy.interpolate import CubicSpline - - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapProperties(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=1Torr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [m^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - p = 133.3224 * 1.5 # [J/m^3] *1.5 to convert it to energy - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.6e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] - - # reaction parameters (NB: k_i = Ck*exp(-A/Te)) - Ck = 1.235e-7 # ionization rate pre-exponential factor [cm^3/s] - A = 18.687 # activation temperature [eV] - dH = 15.7 # energy lost per electron due to ionization rxn [eV] - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck *= 1e-6 # m^3/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - mue = nmue/nAr - mui = nmui/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - Ck = Ck*tau*nAr - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - dEps = np.array([0.0,15.7,0.0]) - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - params.beta = np.array([[2],[1],[0]], dtype=np.int64) - params.alfa = np.array([[1],[0],[1]], dtype=np.int64) - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.mu[0] = mue - params.mu[1] = mui - params.A[0] = Ck - params.B[0] = 0.0 - params.C[0] = A - params.dH[0] = dH - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)"] - - reactionExpressionTypelist = [False] - - reactionsList = [] - for i in range(Nr): - if reactionExpressionTypelist[i]: - Nsample = 72 - N300 = 200 - - rateCoeff = np.fromfile('./BOLSIGChemistry/reaction300K_%s.dat' %str(i)) - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - Te = np.fromfile('./BOLSIGChemistry/reaction300K.Te.dat') - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - # Nondimensionalization of mean energy and transformation to log scale. - # Te *= 1.5 - TeLog = np.log(Te) - - # Find first non-zero value of the coefficient rate. - I = np.nonzero(rateCoeff) - - # Compute the slope of the rate coefficient between its first two non-zero values. - # Finite differences are used. - dydx = (rateCoeff[I[0][0] + 1] - rateCoeff[I[0][0]]) \ - / (Te[I[0][0] + 1] - Te[I[0][0]]) - - # Arrhenius form: kf = A * exp(-C / Te) - # C = (dkf/dTe) / kf * Te**2.0 - # A = kf / exp(-C / Te) - C = Te[I[0][0]]**2.0*dydx / rateCoeff[I[0][0]] - # A = rateCoeff[I[0][0]] / np.exp(-C/Te[I[0][0]]) - - # Compute pre-exponential coefficient, A, in log scale. - ALog = np.log(rateCoeff[I[0][0]]) + C / Te[I[0][0]] - - # Transform rate coefficient in log scale. - rateCoeffLog = np.zeros(rateCoeff.shape) - rateCoeffLog[I[0][0]:] = np.log(rateCoeff[I[0][0]:]) - # For the troublesome values, we use the Arrhenius form. - rateCoeffLog[0:I[0][0]] = ALog - C / Te[0:I[0][0]] - # Nondimensionalization in log scale. - if i < 2: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - else: - rateCoeffLog += - np.log(1.0/tau) + np.log(np0) - # Nondimensionalization of the original rate, used for the plot and comparison. - rateCoeff *= tau * nAr - - # Interpolation in log scale. - reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) - # Gradient in log scale - reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) - - reaction = Reaction(rxnAlfa = params.alfa, rxnBeta = params.beta, - rxnBolsig = reactionExpressionTypelist[i], - kf_log = reactionExpressionsLog, - kf_T_log = reactionTExpressionsLog) - reactionsList.append(reaction) - - else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa, rxnBeta = params.beta, - rxnBolsig = reactionExpressionTypelist[i], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - - # 5) Dump to screen - params.print() diff --git a/psaapPropertiesCurrentTestCase.py b/psaapPropertiesCurrentTestCase.py deleted file mode 100644 index b372b994b..000000000 --- a/psaapPropertiesCurrentTestCase.py +++ /dev/null @@ -1,235 +0,0 @@ -import numpy as np - - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapPropertiesCurrentTestCase(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 1.6102e21 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [m^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - # p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - p = 1 * 6.6661185 * 1.5 # [J/m^3] *1.5 to convert it to energy (50 mTorr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - # tau = (1./13.6e6) # period of driving voltage [s] - tau = (1./27.1e6) # period of driving voltage [s] - L = 2.00*0.005 #1*0.005 # half-gap-width [m] (gap width is 1cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 4.83e20 # argon number density times electron mobility [1/(V*cm*s)] - nmui = 2.33e18 # argon number density times ion mobility [1/(V*cm*s)] - nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nDe = 1.93e21 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 1.04e17 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 1.21e17 # argon number density times metastable diffusivity [1/(cm*s)] - - # reaction parameters (NB: k_i = Ck*exp(-A/Te)) - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56,0.0]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,0.0,0.0,0.0,0.0]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - - # nominal - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - # slow excitation rate - #Ck = np.array([1.235e-7,0.5*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - ## fast excitation rate - #Ck = np.array([1.235e-7,2.0*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - A = np.array([18.687,15.06,4.95,2.14,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.7,11.56,4.14,-11.56,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.7,11.56,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck *= 1e-6 # m^3/s - Ck[7] *= 1e-6 # Ck[7] is now in m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - #Ck[2:5] = Ck[2:5]*tau*np0 - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - Ck[7] *= tau*nAr*nAr - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - - params.A[:] = Ck[:] - params.B[:] = 0.0 - params.C[:] = A[:] - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)"] - - reactionsList = [] - for i in range(Nr): - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - #params.Nr = 1 - - # 5) Dump to screen - params.print() diff --git a/psaapPropertiesCurrentTestCase100mTorr.py b/psaapPropertiesCurrentTestCase100mTorr.py deleted file mode 100644 index 60bf77c14..000000000 --- a/psaapPropertiesCurrentTestCase100mTorr.py +++ /dev/null @@ -1,235 +0,0 @@ -import numpy as np - - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapPropertiesCurrentTestCase100mTorr(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e21 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [m^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - # p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - p = 2 * 6.6661185 * 1.5 # [J/m^3] *1.5 to convert it to energy (50 mTorr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - # tau = (1./13.6e6) # period of driving voltage [s] - tau = (1./27.1e6) # period of driving voltage [s] - L = 2.00*0.005 #1*0.005 # half-gap-width [m] (gap width is 1cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e20 # argon number density times electron mobility [1/(V*cm*s)] - nmui = 4.65e18 # argon number density times ion mobility [1/(V*cm*s)] - nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nDe = 3.86e21 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e17 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 2.42e17 # argon number density times metastable diffusivity [1/(cm*s)] - - # reaction parameters (NB: k_i = Ck*exp(-A/Te)) - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56,0.0]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,0.0,0.0,0.0,0.0]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - - # nominal - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - # slow excitation rate - #Ck = np.array([1.235e-7,0.5*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - ## fast excitation rate - #Ck = np.array([1.235e-7,2.0*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - A = np.array([18.687,15.06,4.95,2.14,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.7,11.56,4.14,-11.56,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.7,11.56,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck *= 1e-6 # m^3/s - Ck[7] *= 1e-6 # Ck[7] is now in m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - #Ck[2:5] = Ck[2:5]*tau*np0 - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - Ck[7] *= tau*nAr*nAr - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*0.144 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - - params.A[:] = Ck[:] - params.B[:] = 0.0 - params.C[:] = A[:] - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)"] - - reactionsList = [] - for i in range(Nr): - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - #params.Nr = 1 - - # 5) Dump to screen - params.print() diff --git a/psaapPropertiesTestArmInterpTrans.py b/psaapPropertiesTestArmInterpTrans.py index c1c6f0626..22684fc3a 100644 --- a/psaapPropertiesTestArmInterpTrans.py +++ b/psaapPropertiesTestArmInterpTrans.py @@ -308,15 +308,6 @@ def setPsaapPropertiesTestArmInterpTrans(gam, inputV0, inputVDC, params, Nr, iSa diffList.append(diffusivity) Tplt = np.linspace(-0.5, 5, 1025) - import matplotlib.pyplot as plt - - plt.figure() - plt.plot(Tplt, De_spline(Tplt), 'b-') - plt.plot(Tplt, De * np.ones(Tplt.shape), 'k--') - plt.plot(Te, De_interp, 'rx') - #plt.plot(Tplt, De_Te_spline(Tplt), 'g--') - plt.xlim(-1, 5) - plt.show() Ns = 4 for i in range(1, Ns): diff --git a/psaapPropertiesTestJP.py b/psaapPropertiesTestJP.py deleted file mode 100644 index c826f9b0d..000000000 --- a/psaapPropertiesTestJP.py +++ /dev/null @@ -1,396 +0,0 @@ -import numpy as np -from scipy.interpolate import CubicSpline - -import matplotlib.pyplot as plt -import matplotlib.colors as mcolors - -import logging - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapPropertiesTestJP(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [A^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.6e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2.54cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - #nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - # / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nmum = 0.0 - nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - - # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) - # Ee = 3/2*Te (Te in eV) - # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] - # nominal - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,4.0e-13,5.0e-10,4.3e-10,2.1e-15,10.0,5.0e-27]) # pre-exponential factors [cm^3/s] - B = np.array([0.0,0.0,0.0,-0.5,0,0.74,0,0,-4.5]) - A = np.array([18.687,15.06,4.95,0.0,0.0,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.76,11.56,4.2,0.0,-7.36,-11.56,-11.56,0.0,-4.2]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.56,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck[0:7] *= 1e-6 # m^3/s - Ck[7] *= 1 # 1/s - Ck[8] *= 1e-12 # m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - #Ck[2:5] = Ck[2:5]*tau*np0 - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - Ck[7] *= tau - Ck[8] *= tau*np0*np0 - # Ck[7] *= tau*nAr*nAr - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - # params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - # params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - params.beta = np.array([[2,1,2,0,1,1,0,0,1],[1,0,1,0,1,0,0,0,0],[0,1,0,1,0,0,0,0,1],[0,0,0,0,1,1,2,1,0]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,0,1,0,0,2],[0,0,0,1,0,0,0,0,1],[0,0,1,0,2,1,1,1,0],[1,1,0,0,0,0,1,0,0]], dtype=np.int64) - # Rxn1: E + AR -> 2E + AR+ - # Rxn2: E + AR -> E + AR* - # Rxn3: E + AR* -> 2E + AR+ - # Rxn4: E + AR+ -> AR* - # Rxn5: 2AR* -> E + AR+ + AR - # Rxn6: E + AR* -> E + AR - # Rxn7: AR* + AR -> 2AR - # Rxn8: AR* -> AR - # Rxn9: 2E + AR+ -> E + AR* - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - - params.A[:] = Ck[:] - params.B[:] = B[:] - params.C[:] = A[:] - - # Account for the 2/3 term to convert from electron temperature to electron energy - for i in range(len(params.A)): - params.A[i] *= (2/3)**(params.B[i]) - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - # reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - # f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - # f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - # f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - # f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - # f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - # f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - # f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)"] - - # reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - # f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - # f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - # f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - # f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - # f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - # f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - # f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)"] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", - f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", - f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)"] - - reactionExpressionTypelist = np.array([True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - # import h5py as h5 - # rxnName = ["Ionization", ...] <- dictionary containing reaction name root string - # for r in range(Nr): - # if reactionExpressionTypeList[r]: - # fileName = "{0:s}.{1:08d}.h5".format(rxnName[r], iSample) - # f = h5.File(filename, "r") - # D = f["table"] - - for i in range(Nr): - if reactionExpressionTypelist[i]: - Nsample = 72 - N300 = 200 - - root_dir = "/g/g92/jbarbere/glowDischarge/toyProblems/timeDomain" - rate_file = "{0:s}/BOLSIGChemistry/reaction300K_{1:d}.dat".format(root_dir, i) - temp_file = "{0:s}/BOLSIGChemistry/reaction300K.Te.dat".format(root_dir) - - #rateCoeff = np.fromfile('/usr/workspace/violetak/BOLSIGSamples/glowDischarge/toyProblems/timeDomain/BOLSIGChemistry/reaction300K_%s.dat' %str(i)) - rateCoeff = np.fromfile(rate_file) - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - #Te = np.fromfile('/usr/workspace/violetak/BOLSIGSamples/glowDischarge/toyProblems/timeDomain/BOLSIGChemistry/reaction300K.Te.dat') - Te = np.fromfile(temp_file) - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - # Sorting mean energy array and rate coefficient array based on - # the mean energy array. - Teinds = Te.argsort() - rateCoeff = rateCoeff[Teinds] - Te = Te[Teinds] - - # Find duplicates - TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) - TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) - rateCoeff = rateCoeff[TeDuplicateinds] - Te = Te[TeDuplicateinds] - - # Nondimensionalization of mean energy. - # Te *= 1.5 - - # Find first non-zero value of the coefficient rate. - I = np.nonzero(rateCoeff) - - diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] - diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] - - Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) - Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) - - Nan = np.isnan(Monotonicity) - Inf = np.isinf(Monotonicity) - indexPositive = np.where(Monotonicity>0.0) - Positive = np.full(Monotonicity.shape, False, dtype=bool) - Positive[indexPositive] = True - - indices = Nan + Inf + Positive - - lastFalse = np.where(indices==False)[-1][-1] + 2 - - # Transformation to log scale. - TeLog = np.log(Te) - - # Compute the slope of the rate coefficient between its first two non-zero values. - # Finite differences are used. - dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ - / (Te[lastFalse + 1] - Te[lastFalse]) - - # Arrhenius form: kf = A * exp(-C / Te) - C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] - - # Compute pre-exponential coefficient, A, in log scale. - ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] - - # Transform rate coefficient in log scale. - rateCoeffLog = np.zeros(rateCoeff.shape) - rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) - # For the troublesome values, we use the Arrhenius form. - rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] - # Nondimensionalization in log scale. - if i < 2: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - else: - rateCoeffLog += - np.log(1.0/tau) + np.log(np0) - - # Interpolation in log scale. - reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) - # Gradient in log scale - reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf_log = reactionExpressionsLog, - kf_T_log = reactionTExpressionsLog) - reactionsList.append(reaction) - - logging.basicConfig(filename=LOGFilename) - logging.warning('Interpolation info (Reaction %s):', i) - logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) - logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) - logging.warning('Position of possible duplicates in mean energy array: %s', - TeDuplicateindsForLog[0]) - - # rxn = eval("lambda energy :" + reactionExpressionslist[i]) - # rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - # # setting the axes at the centre - # fig ,ax = plt.subplots(figsize=(9, 6)) - # ax.spines["top"].set_visible(True) - # ax.spines["right"].set_visible(True) - # ax.set_yscale('log') - # ax.set_xscale('log') - - # # plot the function - # # plt.plot(rateCoeffXFiner, np.exp(reactionExpressions_cubicSplineDerivative_log(rateCoeffXFiner)), - # # color='salmon', linestyle='--', label='interBolsig') - # # plt.plot(rateCoeffXFine, np.exp(reactionExpressions_cubicSpline_log(rateCoeffXFine)), - # # color='lightgreen', linestyle='--', label='interBolsig') - # # plt.plot(Te[:,0], reactionTExpressionsLogFiltered(TeLog[:]) * np.exp(reactionExpressionsLog(TeLog[:])) / Te[:,0], - # # color='blue', linestyle='-', label='interBolsig') - # plt.plot(Te, np.exp(reactionExpressionsLog(TeLog[:])), - # color='green', linestyle='-', label='Bolsig') - # plt.plot(Te, rxn(Te), - # color='salmon', linestyle='--', label='Liu') - # # plt.plot(Te[:,0], rxn_T(Te[:,0]), - # # color='red', linestyle='--', label='interBolsig') - # plt.xlim((0.05,100)) - # plt.ylim((1e-50,300)) - # plt.legend() - # plt.savefig("./Rates_%s.pdf" %str(i), dpi=300) - # # plt.xlim((-0.0001,0.0255)) - # plt.show() - else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - #params.Nr = 1 - - # 5) Dump to screen - params.print() diff --git a/psaapPropertiesTestJP_Arrhenius.py b/psaapPropertiesTestJP_Arrhenius.py deleted file mode 100755 index 84b12f6e5..000000000 --- a/psaapPropertiesTestJP_Arrhenius.py +++ /dev/null @@ -1,373 +0,0 @@ -import numpy as np -from scipy.interpolate import CubicSpline -import csv -import matplotlib.pyplot as plt -import matplotlib.colors as mcolors - -import logging - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapPropertiesTestJP_Arrhenius(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [A^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.56e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - #nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - #nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - # / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nmum = 0.0 - nmui = 8.0e19 - #nmum = 9.35e19 - nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - #nDm = 3.914e20 - - # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) - # Ee = 3/2*Te (Te in eV) - # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] - # nominal - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,4.0e-13,5.0e-10,4.3e-10,2.1e-15,10.0,5.0e-27]) # pre-exponential factors [cm^3/s] - B = np.array([0.0,0.0,0.0,-0.5,0.0,0.74,0.0,0.0,-4.5]) - A = np.array([18.687,15.06,4.95,0.0,0.0,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.76,11.56,4.2,0.0,-7.56,-11.56,-11.56,0.0,-4.2]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.56,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck[0:7] *= 1e-6 # m^3/s - Ck[7] *= 1 # 1/s - Ck[8] *= 1e-12 # m^6/s - # Ck[7] *= 1e-6 # Ck[7] is now in m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - #Ck[2:5] = Ck[2:5]*tau*np0 - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - Ck[7] *= tau - Ck[8] *= tau*np0*np0 - # Ck[7] *= tau*nAr*nAr - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - # params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - # params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - params.beta = np.array([[2,1,2,0,1,1,0,0,1],[1,0,1,0,1,0,0,0,0],[0,1,0,1,0,0,0,0,1],[0,0,0,0,1,1,2,1,0]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,0,1,0,0,2],[0,0,0,1,0,0,0,0,1],[0,0,1,0,2,1,1,1,0],[1,1,0,0,0,0,1,0,0]], dtype=np.int64) - # Rxn1: E + AR -> 2E + AR+ - # Rxn2: E + AR -> E + AR* - # Rxn3: E + AR* -> 2E + AR+ - # Rxn4: E + AR+ -> AR* - # Rxn5: 2AR* -> E + AR+ + AR - # Rxn6: E + AR* -> E + AR - # Rxn7: AR* + AR -> 2AR - # Rxn8: AR* -> AR - # Rxn9: 2E + AR+ -> E + AR* - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - - params.A[:] = Ck[:] - params.B[:] = B[:] - params.C[:] = A[:] - - # Account for the 2/3 term to convert from electron temperature to electron energy - for i in range(len(params.A)): - params.A[i] *= (2/3)**(params.B[i]) - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - # reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - # f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - # f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - # f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - # f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - # f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - # f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - # f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)"] - - # reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - # f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - # f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - # f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - # f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - # f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - # f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - # f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)"] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", - f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", - f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)"] - - reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - # import h5py as h5 - # rxnName = ["Ionization", ...] <- dictionary containing reaction name root string - # for r in range(Nr): - # if reactionExpressionTypeList[r]: - # fileName = "{0:s}.{1:08d}.h5".format(rxnName[r], iSample) - # f = h5.File(filename, "r") - # D = f["table"] - - for i in range(Nr): - if reactionExpressionTypelist[i]: - Nsample = 1 - N300 = 200 - - root_dir = ".." - rate_file = open("{0:s}/BOLSIGChemistry_NominalRates/reaction300K_{1:d}.txt".format(root_dir, i), 'r') - temp_file = open("{0:s}/BOLSIGChemistry_NominalRates/reaction300K_Te.txt".format(root_dir), 'r') - - #rateCoeff = np.fromfile(rate_file) - rateCoeff = np.genfromtxt(rate_file) - rate_file.close() - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - #Te = np.fromfile(temp_file) - Te = np.genfromtxt(temp_file) - temp_file.close() - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - # Sorting mean energy array and rate coefficient array based on - # the mean energy array. - Teinds = Te.argsort() - rateCoeff = rateCoeff[Teinds] - Te = Te[Teinds] - - # Find duplicates - TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) - TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) - rateCoeff = rateCoeff[TeDuplicateinds] - Te = Te[TeDuplicateinds] - - # Nondimensionalization of mean energy. - Te *= 1.5 - - # Find first non-zero value of the coefficient rate. - I = np.nonzero(rateCoeff) - - diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] - diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] - - Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) - Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) - - Nan = np.isnan(Monotonicity) - Inf = np.isinf(Monotonicity) - indexPositive = np.where(Monotonicity>0.0) - Positive = np.full(Monotonicity.shape, False, dtype=bool) - Positive[indexPositive] = True - - indices = Nan + Inf + Positive - - lastFalse = np.where(indices==False)[-1][-1] + 2 - - # Transformation to log scale. - TeLog = np.log(Te) - - # Compute the slope of the rate coefficient between its first two non-zero values. - # Finite differences are used. - dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ - / (Te[lastFalse + 1] - Te[lastFalse]) - - # Arrhenius form: kf = A * exp(-C / Te) - C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] - - # Compute pre-exponential coefficient, A, in log scale. - ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] - - # Transform rate coefficient in log scale. - rateCoeffLog = np.zeros(rateCoeff.shape) - rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) - # For the troublesome values, we use the Arrhenius form. - rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] - # Nondimensionalization in log scale. - if i < 2: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - else: - rateCoeffLog += - np.log(1.0/tau) + np.log(np0) - - # Interpolation in log scale. - reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) - # Gradient in log scale - reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf_log = reactionExpressionsLog, - kf_T_log = reactionTExpressionsLog) - reactionsList.append(reaction) - - logging.basicConfig(filename=LOGFilename) - logging.warning('Interpolation info (Reaction %s):', i) - logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) - logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) - logging.warning('Position of possible duplicates in mean energy array: %s', - TeDuplicateindsForLog[0]) - - else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - - # 5) Dump to screen - params.print() diff --git a/psaapPropertiesTestJP_Nominal.py b/psaapPropertiesTestJP_Nominal.py deleted file mode 100755 index 8b8ce532b..000000000 --- a/psaapPropertiesTestJP_Nominal.py +++ /dev/null @@ -1,371 +0,0 @@ -import numpy as np -from scipy.interpolate import CubicSpline -import csv -import matplotlib.pyplot as plt -import matplotlib.colors as mcolors - -import logging - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapPropertiesTestJP_Nominal(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [A^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.56e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - #nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - #nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - # / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nmum = 0.0 - nmui = 8.0e19 - #nmum = 9.35e19 - nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - #nDm = 3.914e20 - - # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) - # Ee = 3/2*Te (Te in eV) - # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] - # nominal - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,4.0e-13,5.0e-10,4.3e-10,2.1e-15,10.0,5.0e-27]) # pre-exponential factors [cm^3/s] - B = np.array([0.0,0.0,0.0,-0.5,0.0,0.74,0.0,0.0,-4.5]) - A = np.array([18.687,15.06,4.95,0.0,0.0,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.76,11.56,4.2,0.0,-7.56,-11.56,-11.56,0.0,-4.2]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.56,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck[0:7] *= 1e-6 # m^3/s - Ck[7] *= 1 # 1/s - Ck[8] *= 1e-12 # m^6/s - # Ck[7] *= 1e-6 # Ck[7] is now in m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - Ck[7] *= tau - Ck[8] *= tau*np0*np0 - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - # params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - # params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - params.beta = np.array([[2,1,2,0,1,1,0,0,1],[1,0,1,0,1,0,0,0,0],[0,1,0,1,0,0,0,0,1],[0,0,0,0,1,1,2,1,0]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,0,1,0,0,2],[0,0,0,1,0,0,0,0,1],[0,0,1,0,2,1,1,1,0],[1,1,0,0,0,0,1,0,0]], dtype=np.int64) - # Rxn1: E + AR -> 2E + AR+ - # Rxn2: E + AR -> E + AR* - # Rxn3: E + AR* -> 2E + AR+ - # Rxn4: E + AR+ -> AR* - # Rxn5: 2AR* -> E + AR+ + AR - # Rxn6: E + AR* -> E + AR - # Rxn7: AR* + AR -> 2AR - # Rxn8: AR* -> AR - # Rxn9: 2E + AR+ -> E + AR* - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - - params.A[:] = Ck[:] - params.B[:] = B[:] - params.C[:] = A[:] - - # Account for the 2/3 term to convert from electron temperature to electron energy - for i in range(len(params.A)): - params.A[i] *= (2/3)**(params.B[i]) - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - # reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - # f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - # f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - # f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - # f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - # f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - # f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - # f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)"] - - # reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - # f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - # f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - # f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - # f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - # f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - # f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - # f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)"] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", - f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", - f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)"] - - reactionExpressionTypelist = np.array([True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - # import h5py as h5 - # rxnName = ["Ionization", ...] <- dictionary containing reaction name root string - # for r in range(Nr): - # if reactionExpressionTypeList[r]: - # fileName = "{0:s}.{1:08d}.h5".format(rxnName[r], iSample) - # f = h5.File(filename, "r") - # D = f["table"] - - for i in range(Nr): - if reactionExpressionTypelist[i]: - Nsample = 1 - N300 = 200 - - root_dir = ".." - rate_file = open("{0:s}/BOLSIGChemistry_NominalRates/reaction300K_{1:d}.txt".format(root_dir, i), 'r') - temp_file = open("{0:s}/BOLSIGChemistry_NominalRates/reaction300K_Te.txt".format(root_dir), 'r') - - #rateCoeff = np.fromfile(rate_file) - rateCoeff = np.genfromtxt(rate_file) - rate_file.close() - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - #Te = np.fromfile(temp_file) - Te = np.genfromtxt(temp_file) - temp_file.close() - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - # Sorting mean energy array and rate coefficient array based on - # the mean energy array. - Teinds = Te.argsort() - rateCoeff = rateCoeff[Teinds] - Te = Te[Teinds] - - # Find duplicates - TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) - TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) - rateCoeff = rateCoeff[TeDuplicateinds] - Te = Te[TeDuplicateinds] - - # Nondimensionalization of mean energy. - #Te *= 1.5 - - # Find first non-zero value of the coefficient rate. - I = np.nonzero(rateCoeff) - - diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] - diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] - - Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) - Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) - - Nan = np.isnan(Monotonicity) - Inf = np.isinf(Monotonicity) - indexPositive = np.where(Monotonicity>0.0) - Positive = np.full(Monotonicity.shape, False, dtype=bool) - Positive[indexPositive] = True - - indices = Nan + Inf + Positive - - lastFalse = np.where(indices==False)[-1][-1] + 2 - - # Transformation to log scale. - TeLog = np.log(Te) - - # Compute the slope of the rate coefficient between its first two non-zero values. - # Finite differences are used. - dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ - / (Te[lastFalse + 1] - Te[lastFalse]) - - # Arrhenius form: kf = A * exp(-C / Te) - C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] - - # Compute pre-exponential coefficient, A, in log scale. - ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] - - # Transform rate coefficient in log scale. - rateCoeffLog = np.zeros(rateCoeff.shape) - rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) - # For the troublesome values, we use the Arrhenius form. - rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] - # Nondimensionalization in log scale. - if i < 2: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - else: - rateCoeffLog += - np.log(1.0/tau) + np.log(np0) - - # Interpolation in log scale. - reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) - # Gradient in log scale - reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf_log = reactionExpressionsLog, - kf_T_log = reactionTExpressionsLog) - reactionsList.append(reaction) - - logging.basicConfig(filename=LOGFilename) - logging.warning('Interpolation info (Reaction %s):', i) - logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) - logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) - logging.warning('Position of possible duplicates in mean energy array: %s', - TeDuplicateindsForLog[0]) - - else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - - # 5) Dump to screen - params.print() diff --git a/psaapPropertiesWithSampling.py b/psaapPropertiesWithSampling.py deleted file mode 100644 index ce6a6977f..000000000 --- a/psaapPropertiesWithSampling.py +++ /dev/null @@ -1,382 +0,0 @@ -import numpy as np -from scipy.interpolate import CubicSpline - -#import matplotlib.pyplot as plt -#import matplotlib.colors as mcolors - -import logging - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapPropertiesWithSampling(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [m^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.6e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2.54cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - - # reaction parameters (NB: k_i = Ck*exp(-A/Te)) - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56,0.0]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,0.0,0.0,0.0,0.0]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - - # nominal - # Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,4.0e-13,2e-7,5.0e-10,2.5e-15]) # pre-exponential factors [cm^3/s] - - # slow excitation rate - #Ck = np.array([1.235e-7,0.5*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - ## fast excitation rate - #Ck = np.array([1.235e-7,2.0*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - # A = np.array([18.687,15.06,4.95,2.14,0.0,0.0,0.0,0.0]) # activation temperature [eV] - # dH = np.array([15.7,11.56,4.14,-11.56,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - # dEps = np.array([0.0,15.7,11.56,0.0]) - - A = np.array([18.687,15.06,4.95,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.76,11.56,4.2,0.0,-11.56,-7.56,-11.56]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.56,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e−5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck *= 1e-6 # m^3/s - # Ck[7] *= 1e-6 # Ck[7] is now in m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - #Ck[2:5] = Ck[2:5]*tau*np0 - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - # Ck[7] *= tau*nAr*nAr - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - # params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - # params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - params.beta = np.array([[2,1,2,0,1,1,0],[1,0,1,0,0,1,0],[0,1,0,1,0,0,0],[0,0,0,0,1,1,2]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,1,0,0],[0,0,0,1,0,0,0],[0,0,1,0,1,2,1],[1,1,0,0,0,0,1]], dtype=np.int64) - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - - params.A[:] = Ck[:] - params.B[:] = 0.0 - params.C[:] = A[:] - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**({params.B[3]}-0.5)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-0.5-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]}-0.5 + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)"] - - reactionExpressionTypelist = np.array([True,True,True,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - for i in range(Nr): - if reactionExpressionTypelist[i]: - Nsample = 7200 - N300 = 200 - - #rateCoeff = np.fromfile("/g/g92/jbarbere/glowDischarge/toyProblems/timeDomain/BOLSIGChemistryZeroIonDeg7200Samples/reaction300K_%s.dat" %str(i)) - #rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - #Te = np.fromfile("/g/92/jbarbere/glowDischarge/toyProblems/timeDomain/BOLSIGChemistryZeroIonDeg7200Samples/reaction300K.Te.dat") - #Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - root_dir = "/g/g92/jbarbere/glowDischarge/toyProblems/timeDomain" - rate_file = "{0:s}/BOLSIGChemistryZeroIonDeg7200Samples/reaction300K_{1:d}.dat".format(root_dir, i) - temp_file = "{0:s}/BOLSIGChemistryZeroIonDeg7200Samples/reaction300K.Te.dat".format(root_dir) - - rateCoeff = np.fromfile(rate_file) - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - Te = np.fromfile(temp_file) - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - # Sorting mean energy array and rate coefficient array based on - # the mean energy array. - Teinds = Te.argsort() - rateCoeff = rateCoeff[Teinds] - Te = Te[Teinds] - - # Find duplicates - TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) - TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) - rateCoeff = rateCoeff[TeDuplicateinds] - Te = Te[TeDuplicateinds] - - # Nondimensionalization of mean energy. - Te *= 1.5 - - # Find first non-zero value of the coefficient rate. - I = np.nonzero(rateCoeff) - - diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] - diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] - - Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) - Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) - - Nan = np.isnan(Monotonicity) - Inf = np.isinf(Monotonicity) - indexPositive = np.where(Monotonicity>0.0) - Positive = np.full(Monotonicity.shape, False, dtype=bool) - Positive[indexPositive] = True - - indices = Nan + Inf + Positive - - lastFalse = np.where(indices==False)[-1][-1] + 1 - - # Transformation to log scale. - TeLog = np.log(Te) - - # Find first non-zero value of the coefficient rate. - # I = np.nonzero(rateCoeff) - - # Compute the slope of the rate coefficient between its first two non-zero values. - # Finite differences are used. - dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ - / (Te[lastFalse + 1] - Te[lastFalse]) - - # Arrhenius form: kf = A * exp(-C / Te) - # C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] - C = (np.log(rateCoeff[lastFalse + 1]) - np.log(rateCoeff[lastFalse])) \ - / (1.0 / Te[lastFalse] - 1.0 / Te[lastFalse + 1]) - - # Compute pre-exponential coefficient, A, in log scale. - ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] - - # Transform rate coefficient in log scale. - rateCoeffLog = np.zeros(rateCoeff.shape) - rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) - # For the troublesome values, we use the Arrhenius form. - rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] - # Nondimensionalization in log scale. - if i < 2: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - else: - rateCoeffLog += - np.log(1.0/tau) + np.log(np0) - - # Interpolation in log scale. - reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) - # Gradient in log scale - reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf_log = reactionExpressionsLog, - kf_T_log = reactionTExpressionsLog) - reactionsList.append(reaction) - - logging.basicConfig(filename=LOGFilename) - logging.warning('Interpolation info (Reaction %s):', i) - logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) - logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) - logging.warning('Position of possible duplicates in mean energy array: %s', - TeDuplicateindsForLog[0]) - - # rxn = eval("lambda energy :" + reactionExpressionslist[i]) - # rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - # # setting the axes at the centre - # fig ,ax = plt.subplots(figsize=(9, 6)) - # ax.spines["top"].set_visible(True) - # ax.spines["right"].set_visible(True) - # ax.set_yscale('log') - # ax.set_xscale('log') - - # TeFinerResolution = np.linspace(5.0e-4, 100, 20000) - # TeFinerResolutionLog = np.log(TeFinerResolution) - - # # plot the function - # # plt.plot(rateCoeffXFiner, np.exp(reactionExpressions_cubicSplineDerivative_log(rateCoeffXFiner)), - # # color='salmon', linestyle='--', label='interBolsig') - # plt.plot(TeFinerResolution, np.exp(reactionExpressionsLog(TeFinerResolutionLog)), - # color='lightgreen', linestyle='--', label='interBolsig') - # # plt.plot(Te[:,0], reactionTExpressionsLogFiltered(TeLog[:]) * np.exp(reactionExpressionsLog(TeLog[:])) / Te[:,0], - # # color='blue', linestyle='-', label='interBolsig') - # plt.plot(Te, np.exp(reactionExpressionsLog(TeLog[:])), - # color='green', linestyle='-', label='Bolsig') - # plt.plot(Te, rxn(Te), - # color='salmon', linestyle='--', label='Liu') - # # plt.plot(Te[:,0], rxn_T(Te[:,0]), - # # color='red', linestyle='--', label='interBolsig') - # plt.xlim((0.05,100)) - # plt.ylim((1e-50,300)) - # plt.legend() - # plt.savefig("./Rates_%s.pdf" %str(i), dpi=300) - # # plt.xlim((-0.0001,0.0255)) - # plt.show() - else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - #params.Nr = 1 - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_4plus2Species.py b/psaapProperties_4plus2Species.py deleted file mode 100755 index e9f41a1b5..000000000 --- a/psaapProperties_4plus2Species.py +++ /dev/null @@ -1,374 +0,0 @@ -import numpy as np -from scipy.interpolate import CubicSpline -import csv -import matplotlib.pyplot as plt -import matplotlib.colors as mcolors - -import logging - -class Reaction(object): - def __init__(self, *initial_data, **kwargs): - for dictionary in initial_data: - for key in dictionary: - setattr(self, key, dictionary[key]) - for key in kwargs: - setattr(self, key, kwargs[key]) - -def setPsaapProperties_4plus2Species(gam, inputV0, inputVDC, params, Nr, iSample): - """Sets non-dimensional properties corresponding to Liu 2014 paper. - - Inputs: - gam : Secondary electron emission coefficient - params : chebSolver.modelParams class - - Outputs: None - params data is overwritten using values from Liu 2014. - """ - ################################################################### - # User specified parameters (you may change these if you wish to - # run a different scenario from Liu 2014) - ################################################################### - - # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) - np0 = 8e16 # "nominal" electron density [1/m^3] - - # masses - # me = 9.10938356e-31 # mass of an electron [kg] - # me = 5.489e-4 # mass of an electron [u] - me = 0.511e6 # mass of an electron [eV/c2] - # mAr = 39.948 # mass of an argon atom [u] - # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] - mAr = 37.2158e9 # mass of an electron [eV/c2] - # u = 931.4941e6 # eV/c2 - c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [A^2] - - # nominal electron energy - e0 = 1.0 # [eV] - - # pressure - p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) - - # gas energy at the wall - Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot - - # characteristics of driving voltage - V0 = inputV0 # amplitude of driving voltage [V] - verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.56e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) - electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) - - # transport parameters - nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - #nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - #nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - # / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) - nmum = 0.0 - nmur = 0.0 - nmu4p = 0.0 - nmui = 8.0e19 - nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] - nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] - nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - nDr = 2.42e18 - nD4p = 2.42e18 - #nDm = 3.914e20 - - # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) - # Ee = 3/2*Te (Te in eV) - # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] - # nominal - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,4.0e-13,5.0e-10,4.3e-10,2.1e-15,10.0,5.0e-27]) # pre-exponential factors [cm^3/s] - B = np.array([0.0,0.0,0.0,-0.5,0.0,0.74,0.0,0.0,-4.5]) - A = np.array([18.687,15.06,4.95,0.0,0.0,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.76,11.56,4.2,0.0,-7.56,-11.56,-11.56,0.0,-4.2]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.56,0.0,0.0,0.0]) - - # BC parameters - # ks = 1.19e7 # electron recombination rate [cm/s] - ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] - - ################################################################### - # Constants of nature (probably shouldn't change unless you have - # root privileges on universe) - ################################################################### - qe = 1.6e-19 # unit charge [C] - eps0 = 8.86e-12 # permittivity of free space [F/m] - kB = 1.38e-23 # Boltzmann constant [J/K] - # kB = 8.62e-5 # Boltzmann constant [eV/K] - - - ################################################################### - # Calculate non-dimensional parameters - ################################################################### - - # 1) Convert input units to base SI (except eV) - nDe *= 100. # 1/(m*s) - nDi *= 100. # 1/(m*s) - nDm *= 100. - nDr *= 100. - nD4p *= 100. - nmue *= 100. # 1/(V*m*s) - nmui *= 100. # 1/(V*m*s) - Ck[0:7] *= 1e-6 # m^3/s - Ck[7] *= 1 # 1/s - Ck[8] *= 1e-12 # m^6/s - ks *= 0.01 # m/s - se *= 1.0e-20 # m^2 - - # 2) Compute "raw" transport parameters - De = nDe/nAr - Di = nDi/nAr - Dm = nDm/nAr - Dr = nDr/nAr - D4p = nD4p/nAr - - mue = nmue/nAr - mui = nmui/nAr - mum = nmum/nAr - mur = nmur/nAr - mu4p = nmu4p/nAr - - # 3) Compute non-dimensional properties required by solver - De = De*tau/(L*L) - Di = Di*tau/(L*L) - Dm = Dm*tau/(L*L) - Dr = Dr*tau/(L*L) - D4p = D4p*tau/(L*L) - - mue = mue*V0*tau/(L*L) - mui = mui*V0*tau/(L*L) - mum = mum*V0*tau/(L*L) - mur = mur*V0*tau/(L*L) - mu4p = mu4p*V0*tau/(L*L) - - Ck[0:2] = Ck[0:2]*tau*nAr - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - Ck[7] *= tau - Ck[8] *= tau*np0*np0 - A = A*1.5/e0 # 1.5 to convert from temperature to energy - dH = dH/e0 - qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V - alpha = qe*np0*L*L/(V0*eps0) - ks = ks*tau/L - p0 = p/qe/np0 - kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie - # (2/3)*tau/L**2*Kb/np0/kB, - # where Kb is the thermal conductivity of background specie - - params.beta = np.array([[2,1,2,0,1,1,0,0,1], - [1,0,1,0,1,0,0,0,0], - [0,1,0,1,0,0,0,0,1], - [0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0], - [0,0,0,0,1,1,2,1,0]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,0,1,0,0,2], - [0,0,0,1,0,0,0,0,1], - [0,0,1,0,2,1,1,1,0], - [0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0], - [1,1,0,0,0,0,1,0,0]], dtype=np.int64) - # Rxn1: E + AR -> 2E + AR+ - # Rxn2: E + AR -> E + AR* - # Rxn3: E + AR* -> 2E + AR+ - # Rxn4: E + AR+ -> AR* - # Rxn5: 2AR* -> E + AR+ + AR - # Rxn6: E + AR* -> E + AR - # Rxn7: AR* + AR -> 2AR - # Rxn8: AR* -> AR - # Rxn9: 2E + AR+ -> E + AR* - - # 4) Set values in params class - params.D[0] = De - params.D[1] = Di - params.D[2] = Dm - params.D[3] = Dr - params.D[4] = D4p - - params.mu[0] = mue - params.mu[1] = mui - params.mu[2] = mum - params.mu[3] = mur - params.mu[4] = mu4p - - params.A[:] = Ck[:] - params.B[:] = B[:] - params.C[:] = A[:] - - # Account for the 2/3 term to convert from electron temperature to electron energy - for i in range(len(params.A)): - params.A[i] *= (2/3)**(params.B[i]) - - params.dH[:] = dH[:] - params.dEps[:] = dEps[:] - params.qStar = qStar - params.alpha = alpha - params.ks = ks - params.gam = gam - params.kappaB = kappaB - params.nAronp0 = nAr / np0 - params.p0 = p0 - params.Tg0 = Tg0 - params.EC = 2.0 * me / mAr \ - * np.sqrt(16.0 * (me + mAr) * e0 * c**2 - / (3.0 * np.pi * me * mAr)) * se * nAr * tau - # params.EC = 2.0 * me / mAr * 3.8e9 * tau - - params.verticalShift = verticalShift / V0 - - # Parameters needed to compute the current with dimensions - params.V0Ltau = V0 / (L * tau) - params.V0L = V0 / L - params.LLV0tau = (L*L) / (V0*tau) - params.tauL = L / tau - params.np0 = np0 # "nominal" electron density [1/m^3] - params.qe = qe # unit charge [C] - params.eps0 = eps0 # unit charge [C] - params.eArea = electrodeArea # electrode area [m^2] - - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", - f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", - f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)"] - - reactionExpressionTypelist = np.array([True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - # import h5py as h5 - # rxnName = ["Ionization", ...] <- dictionary containing reaction name root string - # for r in range(Nr): - # if reactionExpressionTypeList[r]: - # fileName = "{0:s}.{1:08d}.h5".format(rxnName[r], iSample) - # f = h5.File(filename, "r") - # D = f["table"] - - for i in range(Nr): - if reactionExpressionTypelist[i]: - Nsample = 1 - N300 = 200 - - root_dir = ".." - rate_file = open("{0:s}/BOLSIGChemistry_NominalRates/reaction300K_{1:d}.txt".format(root_dir, i), 'r') - temp_file = open("{0:s}/BOLSIGChemistry_NominalRates/reaction300K_Te.txt".format(root_dir), 'r') - - #rateCoeff = np.fromfile(rate_file) - rateCoeff = np.genfromtxt(rate_file) - rate_file.close() - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - #Te = np.fromfile(temp_file) - Te = np.genfromtxt(temp_file) - temp_file.close() - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - - # Sorting mean energy array and rate coefficient array based on - # the mean energy array. - Teinds = Te.argsort() - rateCoeff = rateCoeff[Teinds] - Te = Te[Teinds] - - # Find duplicates - TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) - TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) - rateCoeff = rateCoeff[TeDuplicateinds] - Te = Te[TeDuplicateinds] - - # Nondimensionalization of mean energy. - Te *= 1.5 - - # Find first non-zero value of the coefficient rate. - I = np.nonzero(rateCoeff) - - diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] - diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] - - Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) - Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) - - Nan = np.isnan(Monotonicity) - Inf = np.isinf(Monotonicity) - indexPositive = np.where(Monotonicity>0.0) - Positive = np.full(Monotonicity.shape, False, dtype=bool) - Positive[indexPositive] = True - - indices = Nan + Inf + Positive - - lastFalse = np.where(indices==False)[-1][-1] + 2 - - # Transformation to log scale. - TeLog = np.log(Te) - - # Compute the slope of the rate coefficient between its first two non-zero values. - # Finite differences are used. - dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ - / (Te[lastFalse + 1] - Te[lastFalse]) - - # Arrhenius form: kf = A * exp(-C / Te) - C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] - - # Compute pre-exponential coefficient, A, in log scale. - ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] - - # Transform rate coefficient in log scale. - rateCoeffLog = np.zeros(rateCoeff.shape) - rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) - # For the troublesome values, we use the Arrhenius form. - rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] - # Nondimensionalization in log scale. - if i < 2: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - else: - rateCoeffLog += - np.log(1.0/tau) + np.log(np0) - - # Interpolation in log scale. - reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) - # Gradient in log scale - reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf_log = reactionExpressionsLog, - kf_T_log = reactionTExpressionsLog) - reactionsList.append(reaction) - - logging.basicConfig(filename=LOGFilename) - logging.warning('Interpolation info (Reaction %s):', i) - logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) - logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) - logging.warning('Position of possible duplicates in mean energy array: %s', - TeDuplicateindsForLog[0]) - - else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], - rxnBolsig = reactionExpressionTypelist[i], - kf = rxn, kf_T = rxn_T) - reactionsList.append(reaction) - - params.reactionsList = reactionsList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_6Species.py b/psaapProperties_6Species_100mTorr.py similarity index 83% rename from psaapProperties_6Species.py rename to psaapProperties_6Species_100mTorr.py index e02c158af..925628450 100755 --- a/psaapProperties_6Species.py +++ b/psaapProperties_6Species_100mTorr.py @@ -1,8 +1,9 @@ import numpy as np from scipy.interpolate import CubicSpline import csv -import matplotlib.pyplot as plt -import matplotlib.colors as mcolors +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 import logging @@ -14,7 +15,24 @@ def __init__(self, *initial_data, **kwargs): for key in kwargs: setattr(self, key, kwargs[key]) -def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_100mTorr(gam, inputV0, inputVDC, params, Nr, iSample): """Sets non-dimensional properties corresponding to Liu 2014 paper. Inputs: @@ -30,7 +48,7 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): ################################################################### # densities - nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + nAr = 3.22e21 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) np0 = 8e16 # "nominal" electron density [1/m^3] # masses @@ -48,7 +66,7 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): e0 = 1.0 # [eV] # pressure - p = 133.3224*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + p = 13.33*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) # gas energy at the wall Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot @@ -62,20 +80,15 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): # transport parameters nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - #nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - #nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - # / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) nmum = 0.0 nmur = 0.0 nmu4p = 0.0 nmui = 8.0e19 - #nmum = 9.35e19 nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] nDr = 2.42e18 nD4p = 2.42e18 - #nDm = 3.914e20 # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) # Ee = 3/2*Te (Te in eV) @@ -115,7 +128,7 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): nmui *= 100. # 1/(V*m*s) Ck[0:5] *= 1e-6 # m^3/s Ck[5:9] *= 1 # 1/s - Ck[9:22] *= 1e-6 # m^3/s + Ck[9:] *= 1e-6 # m^3/s ks *= 0.01 # m/s se *= 1.0e-20 # m^2 @@ -197,6 +210,30 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): # Rxn22: E + AR(r) -> E + AR(m) # Rxn23: E + AR(r) -> E + AR(4p) + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "lumped.metastable", + 10: "lumped.resonance", + 11: "lumped.2p", + 12: "ionization", + 13: "E + Ar(m) => E + Ar", + 14: "step_ionization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => 2E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + # 4) Set values in params class params.D[0] = De params.D[1] = Di @@ -277,8 +314,8 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", - f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", @@ -296,37 +333,25 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, - True,True,True,True,False,True,False,False,False,False,False,False,False,False]) + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) + LOGFilename = 'interpolationSample.log' f = open(LOGFilename, 'w') - # import h5py as h5 - # rxnName = ["Ionization", ...] <- dictionary containing reaction name root string - # for r in range(Nr): - # if reactionExpressionTypeList[r]: - # fileName = "{0:s}.{1:08d}.h5".format(rxnName[r], iSample) - # f = h5.File(filename, "r") - # D = f["table"] for i in range(Nr): if reactionExpressionTypelist[i]: - Nsample = 1 - N300 = 200 - - root_dir = ".." - rate_file = open("{0:s}/BOLSIGChemistry_6SpeciesRates/reaction300K_{1:d}.txt".format(root_dir, i), 'r') - temp_file = open("{0:s}/BOLSIGChemistry_6SpeciesRates/reaction300K_Te.txt".format(root_dir), 'r') - - #rateCoeff = np.fromfile(rate_file) - rateCoeff = np.genfromtxt(rate_file) - rate_file.close() - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] + if (i < 15): + f = h5.File("../BOLSIGChemistry_6SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../BOLSIGChemistry_6SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] - #Te = np.fromfile(temp_file) - Te = np.genfromtxt(temp_file) - temp_file.close() - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 # Sorting mean energy array and rate coefficient array based on # the mean energy array. @@ -386,13 +411,7 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): # For the troublesome values, we use the Arrhenius form. rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] # Nondimensionalization in log scale. - if i == 9: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i == 10: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i == 11: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i == 12: + if (i < 13): rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) else: rateCoeffLog += - np.log(1.0/tau) + np.log(np0) @@ -426,5 +445,39 @@ def setPsaapProperties_6Species(gam, inputV0, inputVDC, params, Nr, iSample): params.reactionsList = reactionsList + ## Electron Transport Data + diffList = [] + transport = h5.File("../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + # 5) Dump to screen params.print() diff --git a/psaapProperties_6Species_100mTorr_Expanded.py b/psaapProperties_6Species_100mTorr_Expanded.py new file mode 100755 index 000000000..237ec31f8 --- /dev/null +++ b/psaapProperties_6Species_100mTorr_Expanded.py @@ -0,0 +1,549 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_100mTorr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e21 # background number density of Ar [1/m^3] (corresponds to p = 100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 13.3*1.5 # [J/m^3] *1.5 to convert it to energy (100 mTorr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_10Torr_Expanded.py b/psaapProperties_6Species_10Torr_Expanded.py new file mode 100755 index 000000000..9e6dc8be6 --- /dev/null +++ b/psaapProperties_6Species_10Torr_Expanded.py @@ -0,0 +1,547 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_10Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e23 # background number density of Ar [1/m^3] (corresponds to p = 10 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 1333.3*1.5 # [J/m^3] *1.5 to convert it to energy (10 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_1Torr_Expanded.py b/psaapProperties_6Species_1Torr_Expanded.py new file mode 100755 index 000000000..192237450 --- /dev/null +++ b/psaapProperties_6Species_1Torr_Expanded.py @@ -0,0 +1,552 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_1Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p = 1 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 133.3*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + print("RXN {}:".format(i+1)) + print(Monotonicity) + print("") + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + #lastFalse = np.nonzero(rateCoeff)[0][0] + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_1Torr_Old.py b/psaapProperties_6Species_1Torr_Old.py new file mode 100755 index 000000000..79b313a1b --- /dev/null +++ b/psaapProperties_6Species_1Torr_Old.py @@ -0,0 +1,542 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_1Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p = 1 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 133.3*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "1s-metastable", + 9: "1s-resonance", + 10: "2p-lumped", + 11: "Ionization", + 12: "Deexci-metastable", + 13: "StepIonization", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "Deexci-resonance", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb-metastable", + 25: "3BdyRecomb-metastable", + 26: "3BdyRecomb-metastable", + 27: "3BdyRecomb-ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization", + 33: "Deexci-2p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BackupRates_Nominal/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BackupRates_Nominal/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + #lastFalse = np.nonzero(rateCoeff)[0][0] + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_250mTorr.py b/psaapProperties_6Species_250mTorr.py new file mode 100755 index 000000000..466192108 --- /dev/null +++ b/psaapProperties_6Species_250mTorr.py @@ -0,0 +1,533 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_250mTorr(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 8.05e21 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 33.33*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,0.0,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0.74,0,0,0.51,0.61,0.51,0.51,0.74,0,0.51]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.59,2.61,0,0,0,0,1.59]) # activation temperature [eV] + dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:] *= 1e-6 # m^3/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + # Rxn7: AR(4p) -> AR + # Rxn8: AR(4p) -> AR(m) + # Rxn9: AR(4p) -> AR(r) + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "lumped.metastable", + 10: "lumped.resonance", + 11: "lumped.2p", + 12: "ionization", + 13: "E + Ar(m) => E + Ar", + 14: "step_ionization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => 2E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)"] + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if (i < 15): + f = h5.File("../BOLSIGChemistry_6SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../BOLSIGChemistry_6SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 13): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + #NDe_v_Te = np.array([ [-0.05, 1.8e25], [0.0, 1.8e25], [0.05, 1.8e25], [0.1, 1.8e25], + # [0.2103718, 1.8e25], [0.2244455, 1.8e25], [0.2390528, 1.8e25], [0.2544605, 1.8e25], + # [0.2710021, 1.8e25], [0.2886776, 1.8e25], [0.3078205, 1.8e25], [0.3286309, 1.8e25], + # [0.3513089, 1.8e25], [0.3760546, 1.8e25], [0.4032682, 1.8e25], [0.4331498, 1.8e25], + # [0.4659662, 1.8e25], [0.5021843, 1.8e25], [0.5424044, 1.8e25], [0.5868266, 1.8e25], + # [0.6359845, 1.8e25], [0.690345, 1.8e25], [0.749041, 1.8e25], [0.813073, 1.8e25], + # [1.217942, 1.46E+25], [1.319326, 1.39E+25], [1.430048, 1.32E+25], [1.550108, 1.26E+25], + # [1.681507, 1.20E+25], [1.823578, 1.15E+25], [1.977655, 1.09E+25], [2.143071, 1.05E+25], + # [2.319826, 9.98E+24], [2.508587, 9.54E+24], [2.709354, 9.13E+24], [2.916124, 8.75E+24], + # [3.112889, 8.45E+24], [3.272969, 8.24E+24], [3.383691, 8.14E+24], [3.456394, 8.09E+24], + # [3.505085, 8.07E+24], [3.544438, 8.05E+24], [3.579789, 8.03E+24], [3.616474, 8.01E+24], + # [3.656494, 7.97E+24], [3.701183, 7.93E+24], [3.751875, 7.87E+24], [3.807903, 7.81E+24], + # [3.871268, 7.75E+24], [3.941303, 7.68E+24], [4.018675, 7.61E+24], [4.102717, 7.53E+24], + # [4.193429, 7.5E+24], [4.290811, 7.5E+24], [4.39553, 7.5E+24], [4.507586, 7.5E+24], + # [5., 7.5E+24], [6., 7.5E+24], [7., 7.5E+24], [8., 7.5E+24], + # [9., 7.5E+24], [10., 7.5E+24], [11., 7.5E+24], [12., 7.5E+24]]) + + transport = h5.File("../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + #Nmue_v_Te = np.array([[0.02846756, 1.289e+26], [0.02975487, 1.33e+26], [0.03173586, 1.383e+26], [0.03477738,1.448e+26], + # [0.03937968, 1.523e+26], [0.04614973, 1.604e+26], [0.05561446, 1.679e+26], [0.0681674,1.735e+26], + # [0.0835084, 1.749e+26], [0.1008504, 1.718e+26], [0.1187927, 1.639e+26], [0.1363348,1.522e+26], + # [0.1528764, 1.386e+26], [0.1682841, 1.245e+26], [0.1826913, 1.108e+26], [0.1965649,9.809e+25], + # [0.2103718, 8.662e+25], [0.2244455, 7.641e+25], [0.2390528, 6.74e+25], [0.2544605,5.947e+25], + # [0.2710021, 5.249e+25], [0.2886776, 4.636e+25], [0.3078205, 4.097e+25], [0.3286309,3.623e+25], + # [0.3513089, 3.206e+25], [0.3760546, 2.839e+25], [0.4032682, 2.517e+25], [0.4331498,2.232e+25], + # [0.4659662, 1.981e+25], [0.5021843, 1.76e+25], [0.5424044, 1.565e+25], [0.5868266,1.392e+25], + # [0.6359845, 1.239e+25], [0.690345, 1.103e+25], [0.749041, 9.8e+24], [0.813073,8.699e+24], + # [0.882441, 7.711e+24], [0.957145, 6.828e+24], [1.037185, 6.04e+24], [1.123895,5.344e+24], + # [1.217942, 4.729e+24], [1.319326, 4.186e+24], [1.430048, 3.707e+24], [1.550108,3.283e+24], + # [1.681507, 2.907e+24], [1.823578, 2.574e+24], [1.977655, 2.278e+24], [2.143071,2.015e+24], + # [2.319826, 1.779e+24], [2.508587, 1.569e+24], [2.709354, 1.384e+24], [2.916124,1.228e+24], + # [3.112889, 1.115e+24], [3.272969, 1.055e+24], [3.383691, 1.038e+24], [3.456394,1.044e+24], + # [3.505085, 1.054e+24], [3.544438, 1.062e+24], [3.579789, 1.064e+24], [3.616474, 1.059e+24], + # [3.656494, 1.048e+24], [3.701183, 1.033e+24], [3.751875, 1.014e+24], [3.807903, 9.928e+23], + # [3.871268, 9.697e+23], [3.941303, 9.459e+23], [4.018675, 9.22e+23], [4.102717, 8.991e+23], + # [4.193429, 8.773e+23], [4.290811, 8.57e+23], [4.39553, 8.383e+23], [4.507586, 8.21e+23], + # [4.627646, 8.051e+23], [4.757711, 7.901e+23], [4.899115, 7.757e+23], [5.054526, 7.617e+23], + # [5.227946, 7.479e+23], [5.423377, 7.339e+23], [5.646822, 7.198e+23], [5.905618, 7.056e+23], + # [6.20977, 6.91e+23], [6.571284, 6.757e+23], [7.01017, 6.607e+23], [7.54377, 6.458e+23], + # [8.19743, 6.303e+23], [9.01117, 6.155e+23], [10.02501, 6e+23], [11.30565, 5.843e+23], + # [12.89978, 5.677e+23], [14.91412, 5.51e+23], [17.41537, 5.326e+23], [20.57028, 5.149e+23], + # [24.51225, 4.968e+23], [29.45472, 4.784e+23], [35.6845, 4.602e+23], [43.58845, 4.421e+23], + # [53.86692, 4.269e+23], [67.367, 4.134e+23], [85.4427, 4.026e+23], [100.0, 4.026e+23]]) + + Nmue_v_Te = transport["mobility"] + #Te = Nmue_v_Te[:,0] + #Te /= 11604 + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_250mTorr_Expanded.py b/psaapProperties_6Species_250mTorr_Expanded.py new file mode 100755 index 000000000..6a0f13a40 --- /dev/null +++ b/psaapProperties_6Species_250mTorr_Expanded.py @@ -0,0 +1,547 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_250mTorr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 8.05e21 # background number density of Ar [1/m^3] (corresponds to p = 250 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 33.3*1.5 # [J/m^3] *1.5 to convert it to energy (250 mTorr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_2Torr_Expanded.py b/psaapProperties_6Species_2Torr_Expanded.py new file mode 100755 index 000000000..15233db2a --- /dev/null +++ b/psaapProperties_6Species_2Torr_Expanded.py @@ -0,0 +1,549 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_2Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 8.05e22 # background number density of Ar [1/m^3] (corresponds to p = 2.5 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 333.3*1.5 # [J/m^3] *1.5 to convert it to energy (2.5 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Delete BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + rateCoeff = np.delete(rateCoeff, fail_inds) + Te = np.delete(Te, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_500mTorr.py b/psaapProperties_6Species_500mTorr.py new file mode 100755 index 000000000..99fa3b14d --- /dev/null +++ b/psaapProperties_6Species_500mTorr.py @@ -0,0 +1,533 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_500mTorr(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 66.6*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,0.0,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0.74,0,0,0.51,0.61,0.51,0.51,0.74,0,0.51]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.59,2.61,0,0,0,0,1.59]) # activation temperature [eV] + dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:] *= 1e-6 # m^3/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + # Rxn7: AR(4p) -> AR + # Rxn8: AR(4p) -> AR(m) + # Rxn9: AR(4p) -> AR(r) + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "lumped.metastable", + 10: "lumped.resonance", + 11: "lumped.2p", + 12: "ionization", + 13: "E + Ar(m) => E + Ar", + 14: "step_ionization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => 2E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)"] + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if (i < 15): + f = h5.File("../BOLSIGChemistry_6SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../BOLSIGChemistry_6SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 13): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + #NDe_v_Te = np.array([ [-0.05, 1.8e25], [0.0, 1.8e25], [0.05, 1.8e25], [0.1, 1.8e25], + # [0.2103718, 1.8e25], [0.2244455, 1.8e25], [0.2390528, 1.8e25], [0.2544605, 1.8e25], + # [0.2710021, 1.8e25], [0.2886776, 1.8e25], [0.3078205, 1.8e25], [0.3286309, 1.8e25], + # [0.3513089, 1.8e25], [0.3760546, 1.8e25], [0.4032682, 1.8e25], [0.4331498, 1.8e25], + # [0.4659662, 1.8e25], [0.5021843, 1.8e25], [0.5424044, 1.8e25], [0.5868266, 1.8e25], + # [0.6359845, 1.8e25], [0.690345, 1.8e25], [0.749041, 1.8e25], [0.813073, 1.8e25], + # [1.217942, 1.46E+25], [1.319326, 1.39E+25], [1.430048, 1.32E+25], [1.550108, 1.26E+25], + # [1.681507, 1.20E+25], [1.823578, 1.15E+25], [1.977655, 1.09E+25], [2.143071, 1.05E+25], + # [2.319826, 9.98E+24], [2.508587, 9.54E+24], [2.709354, 9.13E+24], [2.916124, 8.75E+24], + # [3.112889, 8.45E+24], [3.272969, 8.24E+24], [3.383691, 8.14E+24], [3.456394, 8.09E+24], + # [3.505085, 8.07E+24], [3.544438, 8.05E+24], [3.579789, 8.03E+24], [3.616474, 8.01E+24], + # [3.656494, 7.97E+24], [3.701183, 7.93E+24], [3.751875, 7.87E+24], [3.807903, 7.81E+24], + # [3.871268, 7.75E+24], [3.941303, 7.68E+24], [4.018675, 7.61E+24], [4.102717, 7.53E+24], + # [4.193429, 7.5E+24], [4.290811, 7.5E+24], [4.39553, 7.5E+24], [4.507586, 7.5E+24], + # [5., 7.5E+24], [6., 7.5E+24], [7., 7.5E+24], [8., 7.5E+24], + # [9., 7.5E+24], [10., 7.5E+24], [11., 7.5E+24], [12., 7.5E+24]]) + + transport = h5.File("../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + #Nmue_v_Te = np.array([[0.02846756, 1.289e+26], [0.02975487, 1.33e+26], [0.03173586, 1.383e+26], [0.03477738,1.448e+26], + # [0.03937968, 1.523e+26], [0.04614973, 1.604e+26], [0.05561446, 1.679e+26], [0.0681674,1.735e+26], + # [0.0835084, 1.749e+26], [0.1008504, 1.718e+26], [0.1187927, 1.639e+26], [0.1363348,1.522e+26], + # [0.1528764, 1.386e+26], [0.1682841, 1.245e+26], [0.1826913, 1.108e+26], [0.1965649,9.809e+25], + # [0.2103718, 8.662e+25], [0.2244455, 7.641e+25], [0.2390528, 6.74e+25], [0.2544605,5.947e+25], + # [0.2710021, 5.249e+25], [0.2886776, 4.636e+25], [0.3078205, 4.097e+25], [0.3286309,3.623e+25], + # [0.3513089, 3.206e+25], [0.3760546, 2.839e+25], [0.4032682, 2.517e+25], [0.4331498,2.232e+25], + # [0.4659662, 1.981e+25], [0.5021843, 1.76e+25], [0.5424044, 1.565e+25], [0.5868266,1.392e+25], + # [0.6359845, 1.239e+25], [0.690345, 1.103e+25], [0.749041, 9.8e+24], [0.813073,8.699e+24], + # [0.882441, 7.711e+24], [0.957145, 6.828e+24], [1.037185, 6.04e+24], [1.123895,5.344e+24], + # [1.217942, 4.729e+24], [1.319326, 4.186e+24], [1.430048, 3.707e+24], [1.550108,3.283e+24], + # [1.681507, 2.907e+24], [1.823578, 2.574e+24], [1.977655, 2.278e+24], [2.143071,2.015e+24], + # [2.319826, 1.779e+24], [2.508587, 1.569e+24], [2.709354, 1.384e+24], [2.916124,1.228e+24], + # [3.112889, 1.115e+24], [3.272969, 1.055e+24], [3.383691, 1.038e+24], [3.456394,1.044e+24], + # [3.505085, 1.054e+24], [3.544438, 1.062e+24], [3.579789, 1.064e+24], [3.616474, 1.059e+24], + # [3.656494, 1.048e+24], [3.701183, 1.033e+24], [3.751875, 1.014e+24], [3.807903, 9.928e+23], + # [3.871268, 9.697e+23], [3.941303, 9.459e+23], [4.018675, 9.22e+23], [4.102717, 8.991e+23], + # [4.193429, 8.773e+23], [4.290811, 8.57e+23], [4.39553, 8.383e+23], [4.507586, 8.21e+23], + # [4.627646, 8.051e+23], [4.757711, 7.901e+23], [4.899115, 7.757e+23], [5.054526, 7.617e+23], + # [5.227946, 7.479e+23], [5.423377, 7.339e+23], [5.646822, 7.198e+23], [5.905618, 7.056e+23], + # [6.20977, 6.91e+23], [6.571284, 6.757e+23], [7.01017, 6.607e+23], [7.54377, 6.458e+23], + # [8.19743, 6.303e+23], [9.01117, 6.155e+23], [10.02501, 6e+23], [11.30565, 5.843e+23], + # [12.89978, 5.677e+23], [14.91412, 5.51e+23], [17.41537, 5.326e+23], [20.57028, 5.149e+23], + # [24.51225, 4.968e+23], [29.45472, 4.784e+23], [35.6845, 4.602e+23], [43.58845, 4.421e+23], + # [53.86692, 4.269e+23], [67.367, 4.134e+23], [85.4427, 4.026e+23], [100.0, 4.026e+23]]) + + Nmue_v_Te = transport["mobility"] + #Te = Nmue_v_Te[:,0] + #Te /= 11604 + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_500mTorr_Expanded.py b/psaapProperties_6Species_500mTorr_Expanded.py new file mode 100755 index 000000000..0b4f723a6 --- /dev/null +++ b/psaapProperties_6Species_500mTorr_Expanded.py @@ -0,0 +1,549 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_500mTorr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e22 # background number density of Ar [1/m^3] (corresponds to p = 500 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 66.6*1.5 # [J/m^3] *1.5 to convert it to energy (500m Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_5Torr.py b/psaapProperties_6Species_5Torr.py new file mode 100755 index 000000000..ea5a015d5 --- /dev/null +++ b/psaapProperties_6Species_5Torr.py @@ -0,0 +1,533 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_5Torr(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e23 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 666.65*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,0.0,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0.74,0,0,0.51,0.61,0.51,0.51,0.74,0,0.51]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.59,2.61,0,0,0,0,1.59]) # activation temperature [eV] + dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:] *= 1e-6 # m^3/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + # Rxn7: AR(4p) -> AR + # Rxn8: AR(4p) -> AR(m) + # Rxn9: AR(4p) -> AR(r) + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "lumped.metastable", + 10: "lumped.resonance", + 11: "lumped.2p", + 12: "ionization", + 13: "E + Ar(m) => E + Ar", + 14: "step_ionization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => 2E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)"] + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if (i < 15): + f = h5.File("../BOLSIGChemistry_6SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../BOLSIGChemistry_6SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 13): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + #NDe_v_Te = np.array([ [-0.05, 1.8e25], [0.0, 1.8e25], [0.05, 1.8e25], [0.1, 1.8e25], + # [0.2103718, 1.8e25], [0.2244455, 1.8e25], [0.2390528, 1.8e25], [0.2544605, 1.8e25], + # [0.2710021, 1.8e25], [0.2886776, 1.8e25], [0.3078205, 1.8e25], [0.3286309, 1.8e25], + # [0.3513089, 1.8e25], [0.3760546, 1.8e25], [0.4032682, 1.8e25], [0.4331498, 1.8e25], + # [0.4659662, 1.8e25], [0.5021843, 1.8e25], [0.5424044, 1.8e25], [0.5868266, 1.8e25], + # [0.6359845, 1.8e25], [0.690345, 1.8e25], [0.749041, 1.8e25], [0.813073, 1.8e25], + # [1.217942, 1.46E+25], [1.319326, 1.39E+25], [1.430048, 1.32E+25], [1.550108, 1.26E+25], + # [1.681507, 1.20E+25], [1.823578, 1.15E+25], [1.977655, 1.09E+25], [2.143071, 1.05E+25], + # [2.319826, 9.98E+24], [2.508587, 9.54E+24], [2.709354, 9.13E+24], [2.916124, 8.75E+24], + # [3.112889, 8.45E+24], [3.272969, 8.24E+24], [3.383691, 8.14E+24], [3.456394, 8.09E+24], + # [3.505085, 8.07E+24], [3.544438, 8.05E+24], [3.579789, 8.03E+24], [3.616474, 8.01E+24], + # [3.656494, 7.97E+24], [3.701183, 7.93E+24], [3.751875, 7.87E+24], [3.807903, 7.81E+24], + # [3.871268, 7.75E+24], [3.941303, 7.68E+24], [4.018675, 7.61E+24], [4.102717, 7.53E+24], + # [4.193429, 7.5E+24], [4.290811, 7.5E+24], [4.39553, 7.5E+24], [4.507586, 7.5E+24], + # [5., 7.5E+24], [6., 7.5E+24], [7., 7.5E+24], [8., 7.5E+24], + # [9., 7.5E+24], [10., 7.5E+24], [11., 7.5E+24], [12., 7.5E+24]]) + + transport = h5.File("../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + #Nmue_v_Te = np.array([[0.02846756, 1.289e+26], [0.02975487, 1.33e+26], [0.03173586, 1.383e+26], [0.03477738,1.448e+26], + # [0.03937968, 1.523e+26], [0.04614973, 1.604e+26], [0.05561446, 1.679e+26], [0.0681674,1.735e+26], + # [0.0835084, 1.749e+26], [0.1008504, 1.718e+26], [0.1187927, 1.639e+26], [0.1363348,1.522e+26], + # [0.1528764, 1.386e+26], [0.1682841, 1.245e+26], [0.1826913, 1.108e+26], [0.1965649,9.809e+25], + # [0.2103718, 8.662e+25], [0.2244455, 7.641e+25], [0.2390528, 6.74e+25], [0.2544605,5.947e+25], + # [0.2710021, 5.249e+25], [0.2886776, 4.636e+25], [0.3078205, 4.097e+25], [0.3286309,3.623e+25], + # [0.3513089, 3.206e+25], [0.3760546, 2.839e+25], [0.4032682, 2.517e+25], [0.4331498,2.232e+25], + # [0.4659662, 1.981e+25], [0.5021843, 1.76e+25], [0.5424044, 1.565e+25], [0.5868266,1.392e+25], + # [0.6359845, 1.239e+25], [0.690345, 1.103e+25], [0.749041, 9.8e+24], [0.813073,8.699e+24], + # [0.882441, 7.711e+24], [0.957145, 6.828e+24], [1.037185, 6.04e+24], [1.123895,5.344e+24], + # [1.217942, 4.729e+24], [1.319326, 4.186e+24], [1.430048, 3.707e+24], [1.550108,3.283e+24], + # [1.681507, 2.907e+24], [1.823578, 2.574e+24], [1.977655, 2.278e+24], [2.143071,2.015e+24], + # [2.319826, 1.779e+24], [2.508587, 1.569e+24], [2.709354, 1.384e+24], [2.916124,1.228e+24], + # [3.112889, 1.115e+24], [3.272969, 1.055e+24], [3.383691, 1.038e+24], [3.456394,1.044e+24], + # [3.505085, 1.054e+24], [3.544438, 1.062e+24], [3.579789, 1.064e+24], [3.616474, 1.059e+24], + # [3.656494, 1.048e+24], [3.701183, 1.033e+24], [3.751875, 1.014e+24], [3.807903, 9.928e+23], + # [3.871268, 9.697e+23], [3.941303, 9.459e+23], [4.018675, 9.22e+23], [4.102717, 8.991e+23], + # [4.193429, 8.773e+23], [4.290811, 8.57e+23], [4.39553, 8.383e+23], [4.507586, 8.21e+23], + # [4.627646, 8.051e+23], [4.757711, 7.901e+23], [4.899115, 7.757e+23], [5.054526, 7.617e+23], + # [5.227946, 7.479e+23], [5.423377, 7.339e+23], [5.646822, 7.198e+23], [5.905618, 7.056e+23], + # [6.20977, 6.91e+23], [6.571284, 6.757e+23], [7.01017, 6.607e+23], [7.54377, 6.458e+23], + # [8.19743, 6.303e+23], [9.01117, 6.155e+23], [10.02501, 6e+23], [11.30565, 5.843e+23], + # [12.89978, 5.677e+23], [14.91412, 5.51e+23], [17.41537, 5.326e+23], [20.57028, 5.149e+23], + # [24.51225, 4.968e+23], [29.45472, 4.784e+23], [35.6845, 4.602e+23], [43.58845, 4.421e+23], + # [53.86692, 4.269e+23], [67.367, 4.134e+23], [85.4427, 4.026e+23], [100.0, 4.026e+23]]) + + Nmue_v_Te = transport["mobility"] + #Te = Nmue_v_Te[:,0] + #Te /= 11604 + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_5Torr_Expanded.py b/psaapProperties_6Species_5Torr_Expanded.py new file mode 100755 index 000000000..b6ec32c71 --- /dev/null +++ b/psaapProperties_6Species_5Torr_Expanded.py @@ -0,0 +1,549 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_5Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e23 # background number density of Ar [1/m^3] (corresponds to p = 5 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 666.6*1.5 # [J/m^3] *1.5 to convert it to energy (5 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) # Temperature Power + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, # Rxns 1-8 + True,True,True,True,True,True,True,True,True,True,True,True,True,True, # Rxns 9-21 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 22-34 + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepExcitation.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 12): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_NominalRates/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Expanded.py b/psaapProperties_6Species_Expanded.py new file mode 100755 index 000000000..c5535dace --- /dev/null +++ b/psaapProperties_6Species_Expanded.py @@ -0,0 +1,539 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 133.3*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7,5e-12,0.0,4e-13,0.0,0.0,5.0e-27,7.17e-27,2.5e-11,2.5e-11,1.0e-9,1.0e-9,0.0,0.0]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0.74,0,0,0.0,0.61,0.0,0.0,0.74,0,0.0,0.0,0.0,-0.5,0.0,0.0,-4.5,-4.5,0.0,0.0,0.0,0.0,0.0,0.0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.0,2.61,0,0,0,0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]) # activation temperature [eV] + dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,1.283,0.0,0.0,0.0,-4.212,-4.136,-2.853,-15.76,-1.359,-1.283,-8.695,-8.771,4.136,-12.907]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:8] *= 1 # 1/s + Ck[8:25] *= 1e-6 # m^3/s + Ck[25:29] *= 1e-12 # m^6/s + Ck[29:] *= 1e-6 # m^3/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:25] *= tau*np0 + Ck[25:29] *= tau*np0*np0 + Ck[29:31] *= tau*nAr + Ck[31:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(r) + hv + # Rxn25: E + AR+ -> AR(4p) + hv + # Rxn26: 2E + AR+ -> E + AR(m) + # Rxn27: 2E + AR+ -> E + AR(r) + # Rxn28: 2E + AR+ -> E + AR(4p) + # Rxn29: 2E + AR+ -> E + AR + # Rxn30: AR + AR(4p) -> AR + AR(m) + # Rxn31: AR + AR(4p) -> AR + AR(r) + # Rxn32: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn33: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn34: E + AR(r) -> 2E + AR+ + # Rxn35: E + AR(4p) -> E + AR + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "1s-metastable", + 9: "1s-resonance", + 10: "2p-lumped", + 11: "Ionization", + 12: "Deexci-metastable", + 13: "StepIonization", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "Deexci-resonance", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(r)", + 24: "E + Ar+ => Ar(4p)", + 25: "3BdyRecomb-metastable", + 26: "3BdyRecomb-metastable", + 27: "3BdyRecomb-metastable", + 28: "3BdyRecomb-ground", + 29: "Ar + Ar(4p) => Ar + Ar(m)", + 30: "Ar + Ar(4p) => Ar + Ar(r)", + 31: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 32: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 33: "StepIonization", + 34: "Deexci-2p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)", + f"{params.A[23]} * energy**{params.B[23]} * np.exp(-{params.C[23]} / energy)", + f"{params.A[24]} * energy**{params.B[24]} * np.exp(-{params.C[24]} / energy)", + f"{params.A[25]} * energy**{params.B[25]} * np.exp(-{params.C[25]} / energy)", + f"{params.A[26]} * energy**{params.B[26]} * np.exp(-{params.C[26]} / energy)", + f"{params.A[27]} * energy**{params.B[27]} * np.exp(-{params.C[27]} / energy)", + f"{params.A[28]} * energy**{params.B[28]} * np.exp(-{params.C[28]} / energy)", + f"{params.A[29]} * energy**{params.B[29]} * np.exp(-{params.C[29]} / energy)", + f"{params.A[30]} * energy**{params.B[30]} * np.exp(-{params.C[30]} / energy)", + f"{params.A[31]} * energy**{params.B[31]} * np.exp(-{params.C[31]} / energy)", + f"{params.A[32]} * energy**{params.B[32]} * np.exp(-{params.C[32]} / energy)", + f"{params.A[33]} * energy**{params.B[33]} * np.exp(-{params.C[33]} / energy)", + f"{params.A[34]} * energy**{params.B[34]} * np.exp(-{params.C[34]} / energy)"] + + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)", + f"{params.A[23]} * (energy**({params.B[23]}-1)) * np.exp(-{params.C[23]}/energy) * ({params.B[23]} + {params.C[23]}/energy)", + f"{params.A[24]} * (energy**({params.B[24]}-1)) * np.exp(-{params.C[24]}/energy) * ({params.B[24]} + {params.C[24]}/energy)", + f"{params.A[25]} * (energy**({params.B[25]}-1)) * np.exp(-{params.C[25]}/energy) * ({params.B[25]} + {params.C[25]}/energy)", + f"{params.A[26]} * (energy**({params.B[26]}-1)) * np.exp(-{params.C[26]}/energy) * ({params.B[26]} + {params.C[26]}/energy)", + f"{params.A[27]} * (energy**({params.B[27]}-1)) * np.exp(-{params.C[27]}/energy) * ({params.B[27]} + {params.C[27]}/energy)", + f"{params.A[28]} * (energy**({params.B[28]}-1)) * np.exp(-{params.C[28]}/energy) * ({params.B[28]} + {params.C[28]}/energy)", + f"{params.A[29]} * (energy**({params.B[29]}-1)) * np.exp(-{params.C[29]}/energy) * ({params.B[29]} + {params.C[29]}/energy)", + f"{params.A[30]} * (energy**({params.B[30]}-1)) * np.exp(-{params.C[30]}/energy) * ({params.B[30]} + {params.C[30]}/energy)", + f"{params.A[31]} * (energy**({params.B[31]}-1)) * np.exp(-{params.C[31]}/energy) * ({params.B[31]} + {params.C[31]}/energy)", + f"{params.A[32]} * (energy**({params.B[32]}-1)) * np.exp(-{params.C[32]}/energy) * ({params.B[32]} + {params.C[32]}/energy)", + f"{params.A[33]} * (energy**({params.B[33]}-1)) * np.exp(-{params.C[33]}/energy) * ({params.B[33]} + {params.C[33]}/energy)", + f"{params.A[34]} * (energy**({params.B[34]}-1)) * np.exp(-{params.C[34]}/energy) * ({params.B[34]} + {params.C[34]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False, False, False, True, True, True, True, False, False, False, False, + True, True]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i == 25 or i == 26 or i == 27 or i == 28 or i > 32: + f = h5.File("../../../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_NominalRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 13): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + ## Electron Transport Data + diffList = [] + transport = h5.File("../../../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_ModTrans.py b/psaapProperties_6Species_ModTrans.py new file mode 100755 index 000000000..05abf8348 --- /dev/null +++ b/psaapProperties_6Species_ModTrans.py @@ -0,0 +1,533 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +#import matplotlib.pyplot as plt +#import matplotlib.colors as mcolors +import h5py as h5 + +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Nominal(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an argon atom [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 133.3*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmur = 0.0 + nmu4p = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times AR(m) diffusivity [1/(cm*s)] + nDr = 2.42e18 + nD4p = 2.42e18 + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.0e5,3.2e7,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0.74,0,0,0.51,0.61,0.51,0.51,0.74,0,0.51]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.59,2.61,0,0,0,0,1.59]) # activation temperature [eV] + dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # E, AR+, AR(m), AR(r), AR(4p), AR + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e-5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nDr *= 100. + nD4p *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:] *= 1e-6 # m^3/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + Dr = nDr/nAr + D4p = nD4p/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + mur = nmur/nAr + mu4p = nmu4p/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + Dr = Dr*tau/(L*L) + D4p = D4p*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + mur = mur*V0*tau/(L*L) + mu4p = mu4p*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + # Rxn7: AR(4p) -> AR + # Rxn8: AR(4p) -> AR(m) + # Rxn9: AR(4p) -> AR(r) + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + + rxnNameDict = { 0: "2Ar(m) => 2Ar", + 1: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 2: "2Ar(4p) => E + Ar+ + Ar", + 3: "2Ar(m) => E + Ar+ + Ar", + 4: "Ar(m) + Ar => 2Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "lumped.metastable", + 10: "lumped.resonance", + 11: "lumped.2p", + 12: "ionization", + 13: "E + Ar(m) => E + Ar", + 14: "step_ionization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => 2E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + params.D[3] = Dr + params.D[4] = D4p + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + params.mu[3] = mur + params.mu[4] = mu4p + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", + f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", + f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", + f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", + f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", + f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", + f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", + f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)", + f"{params.A[8]} * energy**{params.B[8]} * np.exp(-{params.C[8]} / energy)", + f"{params.A[9]} * energy**{params.B[9]} * np.exp(-{params.C[9]} / energy)", + f"{params.A[10]} * energy**{params.B[10]} * np.exp(-{params.C[10]} / energy)", + f"{params.A[11]} * energy**{params.B[11]} * np.exp(-{params.C[11]} / energy)", + f"{params.A[12]} * energy**{params.B[12]} * np.exp(-{params.C[12]} / energy)", + f"{params.A[13]} * energy**{params.B[13]} * np.exp(-{params.C[13]} / energy)", + f"{params.A[14]} * energy**{params.B[14]} * np.exp(-{params.C[14]} / energy)", + f"{params.A[15]} * energy**{params.B[15]} * np.exp(-{params.C[15]} / energy)", + f"{params.A[16]} * energy**{params.B[16]} * np.exp(-{params.C[16]} / energy)", + f"{params.A[17]} * energy**{params.B[17]} * np.exp(-{params.C[17]} / energy)", + f"{params.A[18]} * energy**{params.B[18]} * np.exp(-{params.C[18]} / energy)", + f"{params.A[19]} * energy**{params.B[19]} * np.exp(-{params.C[19]} / energy)", + f"{params.A[20]} * energy**{params.B[20]} * np.exp(-{params.C[20]} / energy)", + f"{params.A[21]} * energy**{params.B[21]} * np.exp(-{params.C[21]} / energy)", + f"{params.A[22]} * energy**{params.B[22]} * np.exp(-{params.C[22]} / energy)"] + + reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", + f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", + f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", + f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", + f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", + f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", + f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", + f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)", + f"{params.A[8]} * (energy**({params.B[8]}-1)) * np.exp(-{params.C[8]}/energy) * ({params.B[8]} + {params.C[8]}/energy)", + f"{params.A[9]} * (energy**({params.B[9]}-1)) * np.exp(-{params.C[9]}/energy) * ({params.B[9]} + {params.C[9]}/energy)", + f"{params.A[10]} * (energy**({params.B[10]}-1)) * np.exp(-{params.C[10]}/energy) * ({params.B[10]} + {params.C[10]}/energy)", + f"{params.A[11]} * (energy**({params.B[11]}-1)) * np.exp(-{params.C[11]}/energy) * ({params.B[11]} + {params.C[11]}/energy)", + f"{params.A[12]} * (energy**({params.B[12]}-1)) * np.exp(-{params.C[12]}/energy) * ({params.B[12]} + {params.C[12]}/energy)", + f"{params.A[13]} * (energy**({params.B[13]}-1)) * np.exp(-{params.C[13]}/energy) * ({params.B[13]} + {params.C[13]}/energy)", + f"{params.A[14]} * (energy**({params.B[14]}-1)) * np.exp(-{params.C[14]}/energy) * ({params.B[14]} + {params.C[14]}/energy)", + f"{params.A[15]} * (energy**({params.B[15]}-1)) * np.exp(-{params.C[15]}/energy) * ({params.B[15]} + {params.C[15]}/energy)", + f"{params.A[16]} * (energy**({params.B[16]}-1)) * np.exp(-{params.C[16]}/energy) * ({params.B[16]} + {params.C[16]}/energy)", + f"{params.A[17]} * (energy**({params.B[17]}-1)) * np.exp(-{params.C[17]}/energy) * ({params.B[17]} + {params.C[17]}/energy)", + f"{params.A[18]} * (energy**({params.B[18]}-1)) * np.exp(-{params.C[18]}/energy) * ({params.B[18]} + {params.C[18]}/energy)", + f"{params.A[19]} * (energy**({params.B[19]}-1)) * np.exp(-{params.C[19]}/energy) * ({params.B[19]} + {params.C[19]}/energy)", + f"{params.A[20]} * (energy**({params.B[20]}-1)) * np.exp(-{params.C[20]}/energy) * ({params.B[20]} + {params.C[20]}/energy)", + f"{params.A[21]} * (energy**({params.B[21]}-1)) * np.exp(-{params.C[21]}/energy) * ({params.B[21]} + {params.C[21]}/energy)", + f"{params.A[22]} * (energy**({params.B[22]}-1)) * np.exp(-{params.C[22]}/energy) * ({params.B[22]} + {params.C[22]}/energy)"] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if (i < 15): + f = h5.File("../BOLSIGChemistry_6SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../BOLSIGChemistry_6SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if Te[k] < 4.5 and indices[k] == False: + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if (i < 13): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i + 1) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + rxn = eval("lambda energy :" + reactionExpressionslist[i]) + rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + #NDe_v_Te = np.array([ [-0.05, 1.8e25], [0.0, 1.8e25], [0.05, 1.8e25], [0.1, 1.8e25], + # [0.2103718, 1.8e25], [0.2244455, 1.8e25], [0.2390528, 1.8e25], [0.2544605, 1.8e25], + # [0.2710021, 1.8e25], [0.2886776, 1.8e25], [0.3078205, 1.8e25], [0.3286309, 1.8e25], + # [0.3513089, 1.8e25], [0.3760546, 1.8e25], [0.4032682, 1.8e25], [0.4331498, 1.8e25], + # [0.4659662, 1.8e25], [0.5021843, 1.8e25], [0.5424044, 1.8e25], [0.5868266, 1.8e25], + # [0.6359845, 1.8e25], [0.690345, 1.8e25], [0.749041, 1.8e25], [0.813073, 1.8e25], + # [1.217942, 1.46E+25], [1.319326, 1.39E+25], [1.430048, 1.32E+25], [1.550108, 1.26E+25], + # [1.681507, 1.20E+25], [1.823578, 1.15E+25], [1.977655, 1.09E+25], [2.143071, 1.05E+25], + # [2.319826, 9.98E+24], [2.508587, 9.54E+24], [2.709354, 9.13E+24], [2.916124, 8.75E+24], + # [3.112889, 8.45E+24], [3.272969, 8.24E+24], [3.383691, 8.14E+24], [3.456394, 8.09E+24], + # [3.505085, 8.07E+24], [3.544438, 8.05E+24], [3.579789, 8.03E+24], [3.616474, 8.01E+24], + # [3.656494, 7.97E+24], [3.701183, 7.93E+24], [3.751875, 7.87E+24], [3.807903, 7.81E+24], + # [3.871268, 7.75E+24], [3.941303, 7.68E+24], [4.018675, 7.61E+24], [4.102717, 7.53E+24], + # [4.193429, 7.5E+24], [4.290811, 7.5E+24], [4.39553, 7.5E+24], [4.507586, 7.5E+24], + # [5., 7.5E+24], [6., 7.5E+24], [7., 7.5E+24], [8., 7.5E+24], + # [9., 7.5E+24], [10., 7.5E+24], [11., 7.5E+24], [12., 7.5E+24]]) + + transport = h5.File("../BOLSIGChemistry_Transport/nominal_transport.h5", 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + #Nmue_v_Te = np.array([[0.02846756, 1.289e+26], [0.02975487, 1.33e+26], [0.03173586, 1.383e+26], [0.03477738,1.448e+26], + # [0.03937968, 1.523e+26], [0.04614973, 1.604e+26], [0.05561446, 1.679e+26], [0.0681674,1.735e+26], + # [0.0835084, 1.749e+26], [0.1008504, 1.718e+26], [0.1187927, 1.639e+26], [0.1363348,1.522e+26], + # [0.1528764, 1.386e+26], [0.1682841, 1.245e+26], [0.1826913, 1.108e+26], [0.1965649,9.809e+25], + # [0.2103718, 8.662e+25], [0.2244455, 7.641e+25], [0.2390528, 6.74e+25], [0.2544605,5.947e+25], + # [0.2710021, 5.249e+25], [0.2886776, 4.636e+25], [0.3078205, 4.097e+25], [0.3286309,3.623e+25], + # [0.3513089, 3.206e+25], [0.3760546, 2.839e+25], [0.4032682, 2.517e+25], [0.4331498,2.232e+25], + # [0.4659662, 1.981e+25], [0.5021843, 1.76e+25], [0.5424044, 1.565e+25], [0.5868266,1.392e+25], + # [0.6359845, 1.239e+25], [0.690345, 1.103e+25], [0.749041, 9.8e+24], [0.813073,8.699e+24], + # [0.882441, 7.711e+24], [0.957145, 6.828e+24], [1.037185, 6.04e+24], [1.123895,5.344e+24], + # [1.217942, 4.729e+24], [1.319326, 4.186e+24], [1.430048, 3.707e+24], [1.550108,3.283e+24], + # [1.681507, 2.907e+24], [1.823578, 2.574e+24], [1.977655, 2.278e+24], [2.143071,2.015e+24], + # [2.319826, 1.779e+24], [2.508587, 1.569e+24], [2.709354, 1.384e+24], [2.916124,1.228e+24], + # [3.112889, 1.115e+24], [3.272969, 1.055e+24], [3.383691, 1.038e+24], [3.456394,1.044e+24], + # [3.505085, 1.054e+24], [3.544438, 1.062e+24], [3.579789, 1.064e+24], [3.616474, 1.059e+24], + # [3.656494, 1.048e+24], [3.701183, 1.033e+24], [3.751875, 1.014e+24], [3.807903, 9.928e+23], + # [3.871268, 9.697e+23], [3.941303, 9.459e+23], [4.018675, 9.22e+23], [4.102717, 8.991e+23], + # [4.193429, 8.773e+23], [4.290811, 8.57e+23], [4.39553, 8.383e+23], [4.507586, 8.21e+23], + # [4.627646, 8.051e+23], [4.757711, 7.901e+23], [4.899115, 7.757e+23], [5.054526, 7.617e+23], + # [5.227946, 7.479e+23], [5.423377, 7.339e+23], [5.646822, 7.198e+23], [5.905618, 7.056e+23], + # [6.20977, 6.91e+23], [6.571284, 6.757e+23], [7.01017, 6.607e+23], [7.54377, 6.458e+23], + # [8.19743, 6.303e+23], [9.01117, 6.155e+23], [10.02501, 6e+23], [11.30565, 5.843e+23], + # [12.89978, 5.677e+23], [14.91412, 5.51e+23], [17.41537, 5.326e+23], [20.57028, 5.149e+23], + # [24.51225, 4.968e+23], [29.45472, 4.784e+23], [35.6845, 4.602e+23], [43.58845, 4.421e+23], + # [53.86692, 4.269e+23], [67.367, 4.134e+23], [85.4427, 4.026e+23], [100.0, 4.026e+23]]) + + Nmue_v_Te = transport["mobility"] + #Te = Nmue_v_Te[:,0] + #Te /= 11604 + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling.py b/psaapProperties_6Species_Sampling.py index 9abed73e7..79cdd27e6 100755 --- a/psaapProperties_6Species_Sampling.py +++ b/psaapProperties_6Species_Sampling.py @@ -14,6 +14,23 @@ def __init__(self, *initial_data, **kwargs): for key in kwargs: setattr(self, key, kwargs[key]) +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSample): """Sets non-dimensional properties corresponding to Liu 2014 paper. @@ -62,25 +79,20 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa # transport parameters nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - #nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - #nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - # / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) nmum = 0.0 nmui = 8.0e19 - #nmum = 9.35e19 nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - #nDm = 3.914e20 # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) # Ee = 3/2*Te (Te in eV) # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] # nominal - Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.0e-5,3.2e7,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,3.2e7,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] B = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.74,0.0,0.0,0.51,0.61,0.51,0.51,0.74,0.0,0.51]) A = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.59,2.61,0.0,0.0,0.0,0.0,1.59]) # activation temperature [eV] - dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dH = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # BC parameters @@ -109,7 +121,7 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa nmui *= 100. # 1/(V*m*s) Ck[0:5] *= 1e-6 # m^3/s Ck[5:9] *= 1 # 1/s - Ck[9:22] *= 1e-6 # m^6/s + Ck[9:] *= 1e-6 # m^6/s ks *= 0.01 # m/s se *= 1.0e-20 # m^2 @@ -183,29 +195,31 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa # Rxn22: E + AR(r) -> E + AR(m) # Rxn23: E + AR(r) -> E + AR(4p) - rxnNameDict = {0: "2AR(m) => 2AR", - 1: "AR(m) + AR(r) => E + AR+ + AR", - 2: "2AR(4p) => E + AR+ + AR", - 3: "2AR(m) => E + AR+ + AR", - 4: "AR(m) + AR => 2AR", - 5: "AR(r) => AR", - 6: "AR(4p) => AR", - 7: "AR(4p) => AR(m)", - 8: "Ar(4p) => AR(r)", + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", 9: "1s-metastable", 10: "1s-resonance", 11: "2p-lumped", 12: "Ionization", - 13: "E + AR(m) => E + AR", + 13: "E + Ar(m) => E + Ar", + #13: "deexci-metastable", 14: "StepIonization", - 15: "E + AR(m) => E + AR(r)", - 16: "E + AR(m) => E + AR(4p)", - 17: "E + AR(4p) => 2E + AR+", - 18: "E + AR(4p) => E + AR(r)", - 19: "E + AR(4p) => E + AR(m)", - 20: "E + AR(r) => E + AR", - 21: "E + AR(r) => E + AR(m)", - 22: "E + AR(r) => E + AR(4p)"} + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => E + E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + #20: "deexci-resonance", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} # 4) Set values in params class params.D[0] = De @@ -252,36 +266,31 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa params.eArea = electrodeArea # electrode area [m^2] - reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, - True,True,True,True,False,True,False,False,False,False,False,False,False,False]) + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) reactionsList = [] LOGFilename = 'interpolationSample%s.log'%str(iSample) f = open(LOGFilename, 'w') for i in range(Nr): - Nsample = 20 - N300 = 200 - sample_root_dir = "../6species_SampleFiles" + sample_root_dir = "../BOLSIGChemistry_6SpeciesRates_Original" if reactionExpressionTypelist[i]: - #Nsample = 1 - #N300 = 200 - fileString = sample_root_dir + "/" + rxnNameDict[i] - fileName = "%s.%08d.h5" % (fileString, iSample) - f = h5.File(fileName, 'r') - dataset = f["table"] + if i < 15 or i == 20: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] - #rateCoeff = np.fromfile(rate_file) rateCoeff = dataset[:,1] rateCoeff /= 6.022e23 - #rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - #rateCoeff = np.reshape(rateCoeff,[1, N300]).T[:,1] - - #Te = np.fromfile(temp_file) Te = dataset[:,0] Te /= 11604. - #Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] - #Te = np.reshape(Te,[1, N300]).T[:,1] # Sorting mean energy array and rate coefficient array based on # the mean energy array. @@ -318,7 +327,7 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa #lastFalse = np.where(indices==False)[-1][-1] + 2 for k in range(len(Te)): if (Te[k] < 4.5 and indices[k] == False): - lasFalse = k + 2 + lastFalse = k + 2 # Transformation to log scale. TeLog = np.log(Te) @@ -384,22 +393,19 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa A *= tau*nAr elif (i > 4 and i < 9): A *= tau - elif (i > 8 and i < 13): - A /= 6.022e23 - A *= tau*nAr + #elif (i > 8 and i < 13): + # A /= 6.022e23 + # A *= tau*nAr else: A /= 6.022e23 A *= tau*np0 - A *= 11604**B - C = C*1.5/e0 + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") - #rxn = eval("lambda energy :" + reactionExpressionslist[i]) - #rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], rxnBolsig = reactionExpressionTypelist[i], kf = rxn, kf_T = rxn_T) @@ -407,5 +413,45 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa params.reactionsList = reactionsList + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../BOLSIGChemistry_6SpeciesRates_Original/Transport.%08d.h5" % (iSample), 'r') + #Te = NDe_v_Te[:,0] + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + # 5) Dump to screen params.print() diff --git a/psaapProperties_6Species_Sampling_100mTorr_Expanded.py b/psaapProperties_6Species_Sampling_100mTorr_Expanded.py new file mode 100755 index 000000000..4824dfcd5 --- /dev/null +++ b/psaapProperties_6Species_Sampling_100mTorr_Expanded.py @@ -0,0 +1,494 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_100mTorr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e21 # background number density of Ar [1/m^3] (corresponds to p = 100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 13.3*1.5 # [J/m^3] *1.5 to convert it to energy (100 mTorr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_10Torr_Expanded.py b/psaapProperties_6Species_Sampling_10Torr_Expanded.py new file mode 100755 index 000000000..f85cb08ca --- /dev/null +++ b/psaapProperties_6Species_Sampling_10Torr_Expanded.py @@ -0,0 +1,494 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_10Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e23 # background number density of Ar [1/m^3] (corresponds to p = 10 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 1333.3*1.5 # [J/m^3] *1.5 to convert it to energy (10 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_1Torr_Expanded.py b/psaapProperties_6Species_Sampling_1Torr_Expanded.py new file mode 100755 index 000000000..e3301d381 --- /dev/null +++ b/psaapProperties_6Species_Sampling_1Torr_Expanded.py @@ -0,0 +1,495 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_1Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 3.22e22 # background number density of Ar [1/m^3] (corresponds to p = 1 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 133.3*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_250mTorr.py b/psaapProperties_6Species_Sampling_250mTorr.py new file mode 100755 index 000000000..ab608c9de --- /dev/null +++ b/psaapProperties_6Species_Sampling_250mTorr.py @@ -0,0 +1,499 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_250mTorr(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 8.05e21 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 33.33*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,0.0,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + B = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.74,0.0,0.0,0.51,0.61,0.51,0.51,0.74,0.0,0.51]) + A = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.59,2.61,0.0,0.0,0.0,0.0,1.59]) # activation temperature [eV] + dH = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:] *= 1e-6 # m^6/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + # Rxn7: AR(4p) -> AR + # Rxn8: AR(4p) -> AR(m) + # Rxn9: AR(4p) -> AR(r) + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "1s-metastable", + 10: "1s-resonance", + 11: "2p-lumped", + 12: "Ionization", + 13: "E + Ar(m) => E + Ar", + 14: "StepIonization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => E + E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) + + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if (i < 15): + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i == 9: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 10: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 11: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if (i < 4): + A /= 6.022e23 + A *= tau*np0 + elif (i == 4): + A /= 6.022e23 + A *= tau*nAr + elif (i > 4 and i < 9): + A *= tau + #elif (i > 8 and i < 13): + # A /= 6.022e23 + # A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + #NDe_v_Te = np.array([ [-0.05, 1.8e25], [0.0, 1.8e25], [0.05, 1.8e25], [0.1, 1.8e25], + # [0.2103718, 1.8e25], [0.2244455, 1.8e25], [0.2390528, 1.8e25], [0.2544605, 1.8e25], + # [0.2710021, 1.8e25], [0.2886776, 1.8e25], [0.3078205, 1.8e25], [0.3286309, 1.8e25], + # [0.3513089, 1.8e25], [0.3760546, 1.8e25], [0.4032682, 1.8e25], [0.4331498, 1.8e25], + # [0.4659662, 1.8e25], [0.5021843, 1.8e25], [0.5424044, 1.8e25], [0.5868266, 1.8e25], + # [0.6359845, 1.8e25], [0.690345, 1.8e25], [0.749041, 1.8e25], [0.813073, 1.8e25], + # [1.217942, 1.46E+25], [1.319326, 1.39E+25], [1.430048, 1.32E+25], [1.550108, 1.26E+25], + # [1.681507, 1.20E+25], [1.823578, 1.15E+25], [1.977655, 1.09E+25], [2.143071, 1.05E+25], + # [2.319826, 9.98E+24], [2.508587, 9.54E+24], [2.709354, 9.13E+24], [2.916124, 8.75E+24], + # [3.112889, 8.45E+24], [3.272969, 8.24E+24], [3.383691, 8.14E+24], [3.456394, 8.09E+24], + # [3.505085, 8.07E+24], [3.544438, 8.05E+24], [3.579789, 8.03E+24], [3.616474, 8.01E+24], + # [3.656494, 7.97E+24], [3.701183, 7.93E+24], [3.751875, 7.87E+24], [3.807903, 7.81E+24], + # [3.871268, 7.75E+24], [3.941303, 7.68E+24], [4.018675, 7.61E+24], [4.102717, 7.53E+24], + # [4.193429, 7.5E+24], [4.290811, 7.5E+24], [4.39553, 7.5E+24], [4.507586, 7.5E+24], + # [5., 7.5E+24], [6., 7.5E+24], [7., 7.5E+24], [8., 7.5E+24], + # [9., 7.5E+24], [10., 7.5E+24], [11., 7.5E+24], [12., 7.5E+24]]) + + transport = h5.File("../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + #Te = NDe_v_Te[:,0] + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + #Nmue_v_Te = np.array([[0.02846756, 1.289e+26], [0.02975487, 1.33e+26], [0.03173586, 1.383e+26], [0.03477738,1.448e+26], + # [0.03937968, 1.523e+26], [0.04614973, 1.604e+26], [0.05561446, 1.679e+26], [0.0681674,1.735e+26], + # [0.0835084, 1.749e+26], [0.1008504, 1.718e+26], [0.1187927, 1.639e+26], [0.1363348,1.522e+26], + # [0.1528764, 1.386e+26], [0.1682841, 1.245e+26], [0.1826913, 1.108e+26], [0.1965649,9.809e+25], + # [0.2103718, 8.662e+25], [0.2244455, 7.641e+25], [0.2390528, 6.74e+25], [0.2544605,5.947e+25], + # [0.2710021, 5.249e+25], [0.2886776, 4.636e+25], [0.3078205, 4.097e+25], [0.3286309,3.623e+25], + # [0.3513089, 3.206e+25], [0.3760546, 2.839e+25], [0.4032682, 2.517e+25], [0.4331498,2.232e+25], + # [0.4659662, 1.981e+25], [0.5021843, 1.76e+25], [0.5424044, 1.565e+25], [0.5868266,1.392e+25], + # [0.6359845, 1.239e+25], [0.690345, 1.103e+25], [0.749041, 9.8e+24], [0.813073,8.699e+24], + # [0.882441, 7.711e+24], [0.957145, 6.828e+24], [1.037185, 6.04e+24], [1.123895,5.344e+24], + # [1.217942, 4.729e+24], [1.319326, 4.186e+24], [1.430048, 3.707e+24], [1.550108,3.283e+24], + # [1.681507, 2.907e+24], [1.823578, 2.574e+24], [1.977655, 2.278e+24], [2.143071,2.015e+24], + # [2.319826, 1.779e+24], [2.508587, 1.569e+24], [2.709354, 1.384e+24], [2.916124,1.228e+24], + # [3.112889, 1.115e+24], [3.272969, 1.055e+24], [3.383691, 1.038e+24], [3.456394,1.044e+24], + # [3.505085, 1.054e+24], [3.544438, 1.062e+24], [3.579789, 1.064e+24], [3.616474, 1.059e+24], + # [3.656494, 1.048e+24], [3.701183, 1.033e+24], [3.751875, 1.014e+24], [3.807903, 9.928e+23], + # [3.871268, 9.697e+23], [3.941303, 9.459e+23], [4.018675, 9.22e+23], [4.102717, 8.991e+23], + # [4.193429, 8.773e+23], [4.290811, 8.57e+23], [4.39553, 8.383e+23], [4.507586, 8.21e+23], + # [4.627646, 8.051e+23], [4.757711, 7.901e+23], [4.899115, 7.757e+23], [5.054526, 7.617e+23], + # [5.227946, 7.479e+23], [5.423377, 7.339e+23], [5.646822, 7.198e+23], [5.905618, 7.056e+23], + # [6.20977, 6.91e+23], [6.571284, 6.757e+23], [7.01017, 6.607e+23], [7.54377, 6.458e+23], + # [8.19743, 6.303e+23], [9.01117, 6.155e+23], [10.02501, 6e+23], [11.30565, 5.843e+23], + # [12.89978, 5.677e+23], [14.91412, 5.51e+23], [17.41537, 5.326e+23], [20.57028, 5.149e+23], + # [24.51225, 4.968e+23], [29.45472, 4.784e+23], [35.6845, 4.602e+23], [43.58845, 4.421e+23], + # [53.86692, 4.269e+23], [67.367, 4.134e+23], [85.4427, 4.026e+23], [100.0, 4.026e+23]]) + + #Te = Nmue_v_Te[:,0] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_250mTorr_Expanded.py b/psaapProperties_6Species_Sampling_250mTorr_Expanded.py new file mode 100755 index 000000000..710dc7193 --- /dev/null +++ b/psaapProperties_6Species_Sampling_250mTorr_Expanded.py @@ -0,0 +1,494 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_250mTorr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 8.05e21 # background number density of Ar [1/m^3] (corresponds to p = 250 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 33.3*1.5 # [J/m^3] *1.5 to convert it to energy (250 mTorr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_2Torr_Expanded.py b/psaapProperties_6Species_Sampling_2Torr_Expanded.py new file mode 100755 index 000000000..67b190b8d --- /dev/null +++ b/psaapProperties_6Species_Sampling_2Torr_Expanded.py @@ -0,0 +1,494 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_2Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 8.05e22 # background number density of Ar [1/m^3] (corresponds to p = 2.5 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 333.3*1.5 # [J/m^3] *1.5 to convert it to energy (2.5 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_500mTorr.py b/psaapProperties_6Species_Sampling_500mTorr.py new file mode 100755 index 000000000..71f69200d --- /dev/null +++ b/psaapProperties_6Species_Sampling_500mTorr.py @@ -0,0 +1,499 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_500mTorr(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 66.67*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,0.0,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7]) # pre-exponential factors [cm^3/s] + B = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.74,0.0,0.0,0.51,0.61,0.51,0.51,0.74,0.0,0.51]) + A = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.59,2.61,0.0,0.0,0.0,0.0,1.59]) # activation temperature [eV] + dH = np.array([0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,0.983]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:] *= 1e-6 # m^6/s + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + # Rxn7: AR(4p) -> AR + # Rxn8: AR(4p) -> AR(m) + # Rxn9: AR(4p) -> AR(r) + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "1s-metastable", + 10: "1s-resonance", + 11: "2p-lumped", + 12: "Ionization", + 13: "E + Ar(m) => E + Ar", + 14: "StepIonization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => E + E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True]) + + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if (i < 15): + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + indexPositive = np.where(Monotonicity>0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i == 9: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 10: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 11: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if (i < 4): + A /= 6.022e23 + A *= tau*np0 + elif (i == 4): + A /= 6.022e23 + A *= tau*nAr + elif (i > 4 and i < 9): + A *= tau + #elif (i > 8 and i < 13): + # A /= 6.022e23 + # A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + #NDe_v_Te = np.array([ [-0.05, 1.8e25], [0.0, 1.8e25], [0.05, 1.8e25], [0.1, 1.8e25], + # [0.2103718, 1.8e25], [0.2244455, 1.8e25], [0.2390528, 1.8e25], [0.2544605, 1.8e25], + # [0.2710021, 1.8e25], [0.2886776, 1.8e25], [0.3078205, 1.8e25], [0.3286309, 1.8e25], + # [0.3513089, 1.8e25], [0.3760546, 1.8e25], [0.4032682, 1.8e25], [0.4331498, 1.8e25], + # [0.4659662, 1.8e25], [0.5021843, 1.8e25], [0.5424044, 1.8e25], [0.5868266, 1.8e25], + # [0.6359845, 1.8e25], [0.690345, 1.8e25], [0.749041, 1.8e25], [0.813073, 1.8e25], + # [1.217942, 1.46E+25], [1.319326, 1.39E+25], [1.430048, 1.32E+25], [1.550108, 1.26E+25], + # [1.681507, 1.20E+25], [1.823578, 1.15E+25], [1.977655, 1.09E+25], [2.143071, 1.05E+25], + # [2.319826, 9.98E+24], [2.508587, 9.54E+24], [2.709354, 9.13E+24], [2.916124, 8.75E+24], + # [3.112889, 8.45E+24], [3.272969, 8.24E+24], [3.383691, 8.14E+24], [3.456394, 8.09E+24], + # [3.505085, 8.07E+24], [3.544438, 8.05E+24], [3.579789, 8.03E+24], [3.616474, 8.01E+24], + # [3.656494, 7.97E+24], [3.701183, 7.93E+24], [3.751875, 7.87E+24], [3.807903, 7.81E+24], + # [3.871268, 7.75E+24], [3.941303, 7.68E+24], [4.018675, 7.61E+24], [4.102717, 7.53E+24], + # [4.193429, 7.5E+24], [4.290811, 7.5E+24], [4.39553, 7.5E+24], [4.507586, 7.5E+24], + # [5., 7.5E+24], [6., 7.5E+24], [7., 7.5E+24], [8., 7.5E+24], + # [9., 7.5E+24], [10., 7.5E+24], [11., 7.5E+24], [12., 7.5E+24]]) + + transport = h5.File("../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + #Te = NDe_v_Te[:,0] + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + #Nmue_v_Te = np.array([[0.02846756, 1.289e+26], [0.02975487, 1.33e+26], [0.03173586, 1.383e+26], [0.03477738,1.448e+26], + # [0.03937968, 1.523e+26], [0.04614973, 1.604e+26], [0.05561446, 1.679e+26], [0.0681674,1.735e+26], + # [0.0835084, 1.749e+26], [0.1008504, 1.718e+26], [0.1187927, 1.639e+26], [0.1363348,1.522e+26], + # [0.1528764, 1.386e+26], [0.1682841, 1.245e+26], [0.1826913, 1.108e+26], [0.1965649,9.809e+25], + # [0.2103718, 8.662e+25], [0.2244455, 7.641e+25], [0.2390528, 6.74e+25], [0.2544605,5.947e+25], + # [0.2710021, 5.249e+25], [0.2886776, 4.636e+25], [0.3078205, 4.097e+25], [0.3286309,3.623e+25], + # [0.3513089, 3.206e+25], [0.3760546, 2.839e+25], [0.4032682, 2.517e+25], [0.4331498,2.232e+25], + # [0.4659662, 1.981e+25], [0.5021843, 1.76e+25], [0.5424044, 1.565e+25], [0.5868266,1.392e+25], + # [0.6359845, 1.239e+25], [0.690345, 1.103e+25], [0.749041, 9.8e+24], [0.813073,8.699e+24], + # [0.882441, 7.711e+24], [0.957145, 6.828e+24], [1.037185, 6.04e+24], [1.123895,5.344e+24], + # [1.217942, 4.729e+24], [1.319326, 4.186e+24], [1.430048, 3.707e+24], [1.550108,3.283e+24], + # [1.681507, 2.907e+24], [1.823578, 2.574e+24], [1.977655, 2.278e+24], [2.143071,2.015e+24], + # [2.319826, 1.779e+24], [2.508587, 1.569e+24], [2.709354, 1.384e+24], [2.916124,1.228e+24], + # [3.112889, 1.115e+24], [3.272969, 1.055e+24], [3.383691, 1.038e+24], [3.456394,1.044e+24], + # [3.505085, 1.054e+24], [3.544438, 1.062e+24], [3.579789, 1.064e+24], [3.616474, 1.059e+24], + # [3.656494, 1.048e+24], [3.701183, 1.033e+24], [3.751875, 1.014e+24], [3.807903, 9.928e+23], + # [3.871268, 9.697e+23], [3.941303, 9.459e+23], [4.018675, 9.22e+23], [4.102717, 8.991e+23], + # [4.193429, 8.773e+23], [4.290811, 8.57e+23], [4.39553, 8.383e+23], [4.507586, 8.21e+23], + # [4.627646, 8.051e+23], [4.757711, 7.901e+23], [4.899115, 7.757e+23], [5.054526, 7.617e+23], + # [5.227946, 7.479e+23], [5.423377, 7.339e+23], [5.646822, 7.198e+23], [5.905618, 7.056e+23], + # [6.20977, 6.91e+23], [6.571284, 6.757e+23], [7.01017, 6.607e+23], [7.54377, 6.458e+23], + # [8.19743, 6.303e+23], [9.01117, 6.155e+23], [10.02501, 6e+23], [11.30565, 5.843e+23], + # [12.89978, 5.677e+23], [14.91412, 5.51e+23], [17.41537, 5.326e+23], [20.57028, 5.149e+23], + # [24.51225, 4.968e+23], [29.45472, 4.784e+23], [35.6845, 4.602e+23], [43.58845, 4.421e+23], + # [53.86692, 4.269e+23], [67.367, 4.134e+23], [85.4427, 4.026e+23], [100.0, 4.026e+23]]) + + #Te = Nmue_v_Te[:,0] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_500mTorr_Expanded.py b/psaapProperties_6Species_Sampling_500mTorr_Expanded.py new file mode 100755 index 000000000..23f0c1b0a --- /dev/null +++ b/psaapProperties_6Species_Sampling_500mTorr_Expanded.py @@ -0,0 +1,494 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_500mTorr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e22 # background number density of Ar [1/m^3] (corresponds to p = 500 mTorr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 66.6*1.5 # [J/m^3] *1.5 to convert it to energy (500 mTorr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_6Species_Sampling_5Torr_Expanded.py b/psaapProperties_6Species_Sampling_5Torr_Expanded.py new file mode 100755 index 000000000..6c9f7b16a --- /dev/null +++ b/psaapProperties_6Species_Sampling_5Torr_Expanded.py @@ -0,0 +1,494 @@ +import numpy as np +from scipy.interpolate import CubicSpline +import csv +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import h5py as h5 +import logging + +class Reaction(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Diffusivity(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + +class Mobility(object): + def __init__(self, *initial_data, **kwargs): + for dictionary in initial_data: + for key in dictionary: + setattr(self, key, dictionary[key]) + for key in kwargs: + setattr(self, key, kwargs[key]) + + +def setPsaapProperties_6Species_Sampling_5Torr_Expanded(gam, inputV0, inputVDC, params, Nr, iSample): + """Sets non-dimensional properties corresponding to Liu 2014 paper. + + Inputs: + gam : Secondary electron emission coefficient + params : chebSolver.modelParams class + + Outputs: None + params data is overwritten using values from Liu 2014. + """ + ################################################################### + # User specified parameters (you may change these if you wish to + # run a different scenario from Liu 2014) + ################################################################### + + # densities + nAr = 1.61e23 # background number density of Ar [1/m^3] (corresponds to p = 5 Torr) + np0 = 8e16 # "nominal" electron density [1/m^3] + + # masses + # me = 9.10938356e-31 # mass of an electron [kg] + # me = 5.489e-4 # mass of an electron [u] + me = 0.511e6 # mass of an electron [eV/c2] + # mAr = 39.948 # mass of an argon atom [u] + # mAr = 39.948 * 1.66054e-27 # mass of an argon atom [kg] + mAr = 37.2158e9 # mass of an electron [eV/c2] + # u = 931.4941e6 # eV/c2 + c = 299792458 # speed of light [m/s] + se = 40 # momentum cross section [A^2] + + # nominal electron energy + e0 = 1.0 # [eV] + + # pressure + p = 666.6*1.5 # [J/m^3] *1.5 to convert it to energy (5 Torr) + + # gas energy at the wall + Tg0 = 0.038778 # 3/2*300K*kB ~ (p0 - nT[:,0])/ntot + + # characteristics of driving voltage + V0 = inputV0 # amplitude of driving voltage [V] + verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) + electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) + + # Add voltage uncertainty + V0 += h5.File('../../../BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (iSample), 'r')["V_Err"][0] + + # transport parameters + nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] + nmum = 0.0 + nmui = 8.0e19 + nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] + nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] + nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] + + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([2.0e-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.72e7,1.50e7,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-18,4.0e-19,0.0,0.0,0.0,0.0,2.5e-17,2.5e-17,1.0e-15,1.0e-15,0.0,0.0]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.5,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([0.0,-7.541,-10.577,-7.393,0.0,0.0,0.0,0.0,11.577,11.725,13.168,15.76,-11.577,4.183,0.148,1.592,2.592,-1.444,-1.592,-11.725,-0.148,1.444,0.0,0.0,-4.183,-4.035,-2.592,-15.76,0.0,0.0,-8.985,-9.133,4.035,-13.168]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.577,11.725,13.168,0.0]) + + # BC parameters + # ks = 1.19e7 # electron recombination rate [cm/s] + ks = 1.366109824889323e7 # electron recombination rate [cm/s/eV] + + ################################################################### + # Constants of nature (probably shouldn't change unless you have + # root privileges on universe) + ################################################################### + qe = 1.6e-19 # unit charge [C] + eps0 = 8.86e-12 # permittivity of free space [F/m] + kB = 1.38e-23 # Boltzmann constant [J/K] + # kB = 8.62e−5 # Boltzmann constant [eV/K] + + + ################################################################### + # Calculate non-dimensional parameters + ################################################################### + + # 1) Convert input units to base SI (except eV) + nDe *= 100. # 1/(m*s) + nDi *= 100. # 1/(m*s) + nDm *= 100. + nmue *= 100. # 1/(V*m*s) + nmui *= 100. # 1/(V*m*s) + ks *= 0.01 # m/s + se *= 1.0e-20 # m^2 + + # 2) Compute "raw" transport parameters + De = nDe/nAr + Di = nDi/nAr + Dm = nDm/nAr + + mue = nmue/nAr + mui = nmui/nAr + mum = nmum/nAr + + # 3) Compute non-dimensional properties required by solver + De = De*tau/(L*L) + Di = Di*tau/(L*L) + Dm = Dm*tau/(L*L) + + mue = mue*V0*tau/(L*L) + mui = mui*V0*tau/(L*L) + mum = mum*V0*tau/(L*L) + + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:8] *= tau + Ck[8:12] *= tau*nAr + Ck[12:24] *= tau*np0 + Ck[24:28] *= tau*np0*np0 + Ck[28:30] *= tau*nAr + Ck[30:] *= tau*np0 + A = A*1.5/e0 # 1.5 to convert from temperature to energy + dH = dH/e0 + qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V + alpha = qe*np0*L*L/(V0*eps0) + ks = ks*tau/L + p0 = p/qe/np0 + kappaB = 4.878171165833662*1.6129 # non-dimensional thermal conductivity of background specie + # (2/3)*tau/L**2*Kb/np0/kB, + # where Kb is the thermal conductivity of background specie + + params.beta = np.array([[0,1,1,1,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,2,1], # E + [0,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0], # AR+ + [0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0], # AR(m) + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0,1,1], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0], # AR(r) + [0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1], # AR(4p) + [0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0]], dtype=np.int64) # AR + + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR(m) + hv + # Rxn8: AR(4p) -> AR(r) + hv + # Rxn9: E + AR -> E + AR(m) + # Rxn10: E + AR -> E + AR(r) + # Rxn11: E + AR -> E + AR(4p) + # Rxn12: E + AR -> 2E + AR+ + # Rxn13: E + AR(m) -> E + AR + # Rxn14: E + AR(m) -> 2E + AR+ + # Rxn15: E + AR(m) -> E + AR(r) + # Rxn16: E + AR(m) -> E + AR(4p) + # Rxn17: E + AR(4p) -> 2E + AR+ + # Rxn18: E + AR(4p) -> E + AR(r) + # Rxn19: E + AR(4p) -> E + AR(m) + # Rxn20: E + AR(r) -> E + AR + # Rxn21: E + AR(r) -> E + AR(m) + # Rxn22: E + AR(r) -> E + AR(4p) + # Rxn23: E + AR+ -> AR(m) + hv + # Rxn24: E + AR+ -> AR(4p) + hv + # Rxn25: 2E + AR+ -> E + AR(m) + # Rxn26: 2E + AR+ -> E + AR(r) + # Rxn27: 2E + AR+ -> E + AR(4p) + # Rxn28: 2E + AR+ -> E + AR + # Rxn29: AR + AR(4p) -> AR + AR(m) + # Rxn30: AR + AR(4p) -> AR + AR(r) + # Rxn31: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn32: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn33: E + AR(r) -> 2E + AR+ + # Rxn34: E + AR(4p) -> E + AR + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar(m)", + 7: "Ar(4p) => Ar(r)", + 8: "Excitation_Metastable", + 9: "Excitation_Resonant", + 10: "Excitation_4p", + 11: "Ionization", + 12: "DeExcitation_Metastable", + 13: "StepIonization_Metastable", + 14: "E + Ar(m) => E + Ar(r)", + 15: "E + Ar(m) => E + Ar(4p)", + 16: "StepIonization_4p", + 17: "E + Ar(4p) => E + Ar(r)", + 18: "E + Ar(4p) => E + Ar(m)", + 19: "DeExcitation_Resonant", + 20: "E + Ar(r) => E + Ar(m)", + 21: "E + Ar(r) => E + Ar(4p)", + 22: "E + Ar+ => Ar(m)", + 23: "E + Ar+ => Ar(4p)", + 24: "3BdyRecomb_Metastable", + 25: "3BdyRecomb_Resonant", + 26: "3BdyRecomb_4p", + 27: "3BdyRecomb_Ground", + 28: "Ar + Ar(4p) => Ar + Ar(m)", + 29: "Ar + Ar(4p) => Ar + Ar(r)", + 30: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 31: "Ar(r) + Ar(4p) => E + Ar+ + Ar", + 32: "StepIonization_Resonant", + 33: "DeExcitation_4p"} + + # 4) Set values in params class + params.D[0] = De + params.D[1] = Di + params.D[2] = Dm + + params.mu[0] = mue + params.mu[1] = mui + params.mu[2] = mum + + params.A[:] = Ck[:] + params.B[:] = B[:] + params.C[:] = A[:] + + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + + params.dH[:] = dH[:] + params.dEps[:] = dEps[:] + params.qStar = qStar + params.alpha = alpha + params.ks = ks + params.gam = gam + params.kappaB = kappaB + params.nAronp0 = nAr / np0 + params.p0 = p0 + params.Tg0 = Tg0 + params.EC = 2.0 * me / mAr \ + * np.sqrt(16.0 * (me + mAr) * e0 * c**2 + / (3.0 * np.pi * me * mAr)) * se * nAr * tau + # params.EC = 2.0 * me / mAr * 3.8e9 * tau + + params.verticalShift = verticalShift / V0 + + # Parameters needed to compute the current with dimensions + params.V0Ltau = V0 / (L * tau) + params.V0L = V0 / L + params.LLV0tau = (L*L) / (V0*tau) + params.tauL = L / tau + params.np0 = np0 # "nominal" electron density [1/m^3] + params.qe = qe # unit charge [C] + params.eps0 = eps0 # unit charge [C] + params.eArea = electrodeArea # electrode area [m^2] + + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False, + True,True,True,True,True,True,True,True,True,True,True,True,True,True, + False,False,True,True,True,True,False,False,False,False,True,True]) + + thresholded_rxn = np.array([False, False, False, False, False, False, False, False, + True, True, True, True, False, True, True, True, True, False, False, False, False, + True, False, False, False, False, False, False, False, False, False, False, True, + False]) + reactionsList = [] + LOGFilename = 'interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../../../BOLSIGChemistry_6SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 14 or i == 16 or i == 19 or i > 23: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. + + ## Removing BOLSIG failures + fail_inds = [] + for j in range(len(rateCoeff)): + if rateCoeff[j] == 0.0 and j > np.nonzero(rateCoeff)[0][0]: + fail_inds.append(j) + + Te = np.delete(Te, fail_inds) + rateCoeff = np.delete(rateCoeff, fail_inds) + + # Sorting mean energy array and rate coefficient array based on + # the mean energy array. + Teinds = Te.argsort() + rateCoeff = rateCoeff[Teinds] + Te = Te[Teinds] + + # Find duplicates + TeDuplicateinds = np.where(np.abs(np.diff(Te, axis=0)) > 0.0) + TeDuplicateindsForLog = np.where(np.abs(np.diff(Te, axis=0)) == 0.0) + rateCoeff = rateCoeff[TeDuplicateinds] + Te = Te[TeDuplicateinds] + + # Nondimensionalization of mean energy. + Te *= 1.5 + + # Find first non-zero value of the coefficient rate. + I = np.nonzero(rateCoeff) + + diffRateCoeff = [j-i for i, j in zip(rateCoeff[:-1], rateCoeff[1:])] + diffTe = [j-i for i, j in zip(Te[:-1], Te[1:])] + + Monotonicity = np.asarray([j/i for i, j in zip(diffTe, diffRateCoeff)]) + Monotonicity = np.insert(Monotonicity, 0, 0.0, axis=0) + + Nan = np.isnan(Monotonicity) + Inf = np.isinf(Monotonicity) + if thresholded_rxn[i] == True: + indexPositive = np.where(Monotonicity>0.0) + else: + indexPositive = np.where(Monotonicity<0.0) + Positive = np.full(Monotonicity.shape, False, dtype=bool) + Positive[indexPositive] = True + + indices = Nan + Inf + Positive + + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 + + # Transformation to log scale. + TeLog = np.log(Te) + + # Compute the slope of the rate coefficient between its first two non-zero values. + # Finite differences are used. + dydx = (rateCoeff[lastFalse + 1] - rateCoeff[lastFalse]) \ + / (Te[lastFalse + 1] - Te[lastFalse]) + + # Arrhenius form: kf = A * exp(-C / Te) + C = Te[lastFalse]**2.0*dydx / rateCoeff[lastFalse] + + # Compute pre-exponential coefficient, A, in log scale. + ALog = np.log(rateCoeff[lastFalse]) + C / Te[lastFalse] + + # Transform rate coefficient in log scale. + rateCoeffLog = np.zeros(rateCoeff.shape) + rateCoeffLog[lastFalse:] = np.log(rateCoeff[lastFalse:]) + # For the troublesome values, we use the Arrhenius form. + rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] + # Nondimensionalization in log scale. + if i < 12: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 23 and i < 28: + rateCoeffLog += - np.log(1.0/tau) + 2*np.log(np0) + else: + rateCoeffLog += - np.log(1.0/tau) + np.log(np0) + + # Interpolation in log scale. + reactionExpressionsLog = CubicSpline(TeLog, rateCoeffLog) + # Gradient in log scale + reactionTExpressionsLog = CubicSpline.derivative(reactionExpressionsLog) + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf_log = reactionExpressionsLog, + kf_T_log = reactionTExpressionsLog) + reactionsList.append(reaction) + + logging.basicConfig(filename=LOGFilename) + logging.warning('Interpolation info (Reaction %s):', i) + logging.warning('First non-zero entry in the rate coefficient: %s', I[0][0]) + logging.warning('Monotonicity of the rate coefficient start from entry: %s', lastFalse) + logging.warning('Position of possible duplicates in mean energy array: %s', + TeDuplicateindsForLog[0]) + + else: + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 8: + A *= tau + elif i > 27 and i < 30: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") + + reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], + rxnBolsig = reactionExpressionTypelist[i], + kf = rxn, kf_T = rxn_T) + reactionsList.append(reaction) + + params.reactionsList = reactionsList + + diffList = [] + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../../../BOLSIGChemistry_6SpeciesRates/Transport.%08d.h5" % (iSample), 'r') + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) + diffList.append(diffusivity) + + Ns = 6 + for i in range(1, Ns): + diffList.append(Diffusivity(interpolate = False)) + + params.diffusivityList = diffList + + muList = [] + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) + mue_Te_spline = CubicSpline.derivative(mue_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + muList.append(mobility) + + Ns = 6 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapPropertiesTestArmVioleta.py b/psaapProperties_6Species_Sampling_Expanded_NewRates.py old mode 100644 new mode 100755 similarity index 50% rename from psaapPropertiesTestArmVioleta.py rename to psaapProperties_6Species_Sampling_Expanded_NewRates.py index 9c3d55670..3b61bfab1 --- a/psaapPropertiesTestArmVioleta.py +++ b/psaapProperties_6Species_Sampling_Expanded_NewRates.py @@ -1,8 +1,9 @@ import numpy as np from scipy.interpolate import CubicSpline - +import csv import matplotlib.pyplot as plt import matplotlib.colors as mcolors +import h5py as h5 import logging class Reaction(object): @@ -29,7 +30,8 @@ def __init__(self, *initial_data, **kwargs): for key in kwargs: setattr(self, key, kwargs[key]) -def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): + +def setPsaapProperties_6Species_Sampling_Expanded_NewRates(gam, inputV0, inputVDC, params, Nr, iSample): """Sets non-dimensional properties corresponding to Liu 2014 paper. Inputs: @@ -57,7 +59,7 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): mAr = 37.2158e9 # mass of an electron [eV/c2] # u = 931.4941e6 # eV/c2 c = 299792458 # speed of light [m/s] - se = 40 # momentum cross section [m^2] + se = 40 # momentum cross section [A^2] # nominal electron energy e0 = 1.0 # [eV] @@ -71,49 +73,27 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): # characteristics of driving voltage V0 = inputV0 # amplitude of driving voltage [V] verticalShift = inputVDC # DC voltage (vertical shift in driving voltage) - tau = (1./13.6e6) # period of driving voltage [s] - L = 2.00*0.005 # half-gap-width [m] (gap width is 2.54cm) + tau = (1./13.56e6) # period of driving voltage [s] + L = 2.00*0.005 # half-gap-width [m] (gap width is 2 cm) electrodeArea = np.pi*0.05**2 # electrode area [m^2] (electrode diameter = 0.1 m) # transport parameters nmue = 9.66e21 # argon number density times electron mobility [1/(V*cm*s)] - nmui = 4.65e19 # argon number density times ion mobility [1/(V*cm*s)] - nmum = 1 / (np.sqrt(16.0 * (mAr + mAr) * 300 * 8.62e-5 * c**2 - / (3.0 * np.pi * mAr * mAr)) * se * mAr * 1.6e-19 / c**2) + nmum = 0.0 + nmui = 8.0e19 nDe = 3.86e22 # argon number density times electron diffusivity [1/(cm*s)] nDi = 2.07e18 # argon number density times ion diffusivity [1/(cm*s)] nDm = 2.42e18 # argon number density times metastable diffusivity [1/(cm*s)] - # reaction parameters (NB: k_i = Ck*exp(-A/Te)) - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56,0.0]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14]) # activation temperature [eV] - #dH = np.array([15.7,11.56,4.14,-11.56]) # energy lost per electron due to ionization rxn [eV] - - #Ck = np.array([1.235e-7,0.0,0.0,0.0,0.0]) # pre-exponential factors [cm^3/s] - #A = np.array([18.687,15.06,4.95,2.14,0.0]) # activation temperature [eV] - #dH = np.array([15.7,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - + # reaction parameters (NB: k_i = Ck*Ee^B*exp(-A/Ee)) + # Ee = 3/2*Te (Te in eV) + # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] # nominal - # Ck = np.array([1.235e-7,3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - Ck = np.array([1.235e-7,3.712e-8,2.05e-7,4.0e-13,2e-7,5.0e-10,2.5e-15]) # pre-exponential factors [cm^3/s] - - # slow excitation rate - #Ck = np.array([1.235e-7,0.5*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - ## fast excitation rate - #Ck = np.array([1.235e-7,2.0*3.712e-8,2.05e-7,1.818e-9,2e-7,6.2e-10,3.0e-15,1.1e-31]) # pre-exponential factors [cm^3/s] - - # A = np.array([18.687,15.06,4.95,2.14,0.0,0.0,0.0,0.0]) # activation temperature [eV] - # dH = np.array([15.7,11.56,4.14,-11.56,0.0,0.0,0.0,0.0]) # energy lost per electron due to ionization rxn [eV] - # dEps = np.array([0.0,15.7,11.56,0.0]) - - A = np.array([18.687,15.06,4.95,0.0,0.0,0.0,0.0]) # activation temperature [eV] - dH = np.array([15.76,11.56,4.2,0.0,-11.56,-7.56,-11.56]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.56,0.0]) + Ck = np.array([2.0e-7,2.1e-9,5.0e-10,6.4e-10,2.1e-15,1.32e8,0.0,3.0e7,3.0e7,0.0,0.0,0.0,0.0,4.3e-10,0.0,3.7e-8,8.9e-7,1.8e-7,3.0e-7,3.0e-7,4.3e-10,9.1e-7,8.9e-7,5e-12,0.0,4e-13,0.0,0.0,5.0e-27,7.17e-27,2.5e-11,2.5e-11,1.0e-9,1.0e-9]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0.74,0,0,0.0,0.61,0.0,0.0,0.74,0,0.0,0.0,0.0,-0.5,0.0,0.0,-4.5,-4.5,0.0,0.0,0.0,0.0]) + A = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.0,2.61,0,0,0,0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]) # activation temperature [eV] + dH = np.array([0.0,-7.412,-10.054,-7.336,0.0,0.0,0.0,0.0,0.0,11.548,11.624,12.907,15.76,-11.548,4.212,0.076,1.359,2.853,-1.283,-1.359,-11.624,-0.076,1.283,0.0,0.0,0.0,-4.212,-4.136,-2.853,-15.76,-1.359,-1.283,-8.695,-8.771]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,11.624,12.907,0.0]) # BC parameters # ks = 1.19e7 # electron recombination rate [cm/s] @@ -139,8 +119,11 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): nDm *= 100. nmue *= 100. # 1/(V*m*s) nmui *= 100. # 1/(V*m*s) - Ck *= 1e-6 # m^3/s - # Ck[7] *= 1e-6 # Ck[7] is now in m^6/s + Ck[0:5] *= 1e-6 # m^3/s + Ck[5:9] *= 1 # 1/s + Ck[9:26] *= 1e-6 # m^3/s + Ck[26:30] *= 1e-12 # m^6/s + Ck[30:] *= 1e-6 # m^3/s ks *= 0.01 # m/s se *= 1.0e-20 # m^2 @@ -162,11 +145,14 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): mui = mui*V0*tau/(L*L) mum = mum*V0*tau/(L*L) - Ck[0:2] = Ck[0:2]*tau*nAr - #Ck[2:5] = Ck[2:5]*tau*np0 - Ck[2:6] = Ck[2:6]*tau*np0 - Ck[6] *= tau*nAr - # Ck[7] *= tau*nAr*nAr + Ck[0:4] *= tau*np0 + Ck[4] *= tau*nAr + Ck[5:9] *= tau + Ck[9:13] *= tau*nAr + Ck[13:26] *= tau*np0 + Ck[26:30] *= tau*np0*np0 + Ck[30:32] *= tau*nAr + Ck[32:] *= tau*np0 A = A*1.5/e0 # 1.5 to convert from temperature to energy dH = dH/e0 qStar = V0/e0 # qe*V0/e0, since e0 in eV, need qe*V0 in eV, which is just V0 in V @@ -177,14 +163,91 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): # (2/3)*tau/L**2*Kb/np0/kB, # where Kb is the thermal conductivity of background specie - #params.beta = np.array([[2,2,2,1,1],[1,0,1,0,0],[0,1,0,0,0],[0,0,0,1,1]]) - #params.alfa = np.array([[1,1,1,1,1],[0,0,0,0,0],[0,0,1,1,1],[1,1,0,0,0]]) - #params.beta = np.array([[2,1,2,1],[1,0,1,0],[0,1,0,0],[0,0,0,1]], dtype=np.int) - #params.alfa = np.array([[1,1,1,1],[0,0,0,0],[0,0,1,1],[1,1,0,0]], dtype=np.int) - # params.beta = np.array([[2,1,2,1,1,1,0,0],[1,0,1,0,0,1,0,0],[0,1,0,0,0,0,0,0],[0,0,0,1,0,1,2,1]], dtype=np.int64) - # params.alfa = np.array([[1,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0],[0,0,1,1,1,2,1,1],[1,1,0,0,0,0,1,2]], dtype=np.int64) - params.beta = np.array([[2,1,2,0,1,1,0],[1,0,1,0,0,1,0],[0,1,0,1,0,0,0],[0,0,0,0,1,1,2]], dtype=np.int64) - params.alfa = np.array([[1,1,1,1,1,0,0],[0,0,0,1,0,0,0],[0,0,1,0,1,2,1],[1,1,0,0,0,0,1]], dtype=np.int64) + params.beta = np.array([[0,1,1,1,0,0,0,0,0,1,1,1,2,1,2,1,1,2,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1], # E + [0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], # AR+ + [0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0], # AR(m) + [0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0], # AR(r) + [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0], # AR(4p) + [2,1,1,1,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1]], dtype=np.int64) # AR + + params.alfa = np.array([[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,0], # E + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0], # AR+ + [2,1,0,2,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1], # AR(r) + [0,0,2,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1], # AR(4p) + [0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0]], dtype=np.int64) # AR + # Rxn1: 2AR(m) -> 2AR + # Rxn2: AR(m) + AR(r) -> E + AR+ + AR + # Rxn3: 2AR(4p) -> E + AR+ + AR + # Rxn4: 2AR(m) -> E + AR+ + AR + # Rxn5: AR(m) + AR -> 2AR + # Rxn6: AR(r) -> AR + hv + # Rxn7: AR(4p) -> AR + hv + # Rxn8: AR(4p) -> AR(m) + hv + # Rxn9: AR(4p) -> AR(r) + hv + # Rxn10: E + AR -> E + AR(m) + # Rxn11: E + AR -> E + AR(r) + # Rxn12: E + AR -> E + AR(4p) + # Rxn13: E + AR -> 2E + AR+ + # Rxn14: E + AR(m) -> E + AR + # Rxn15: E + AR(m) -> 2E + AR+ + # Rxn16: E + AR(m) -> E + AR(r) + # Rxn17: E + AR(m) -> E + AR(4p) + # Rxn18: E + AR(4p) -> 2E + AR+ + # Rxn19: E + AR(4p) -> E + AR(r) + # Rxn20: E + AR(4p) -> E + AR(m) + # Rxn21: E + AR(r) -> E + AR + # Rxn22: E + AR(r) -> E + AR(m) + # Rxn23: E + AR(r) -> E + AR(4p) + # Rxn24: E + AR+ -> AR(m) + hv + # Rxn25: E + AR+ -> AR(r) + hv + # Rxn26: E + AR+ -> AR(4p) + hv + # Rxn27: 2E + AR+ -> E + AR(m) + # Rxn28: 2E + AR+ -> E + AR(r) + # Rxn29: 2E + AR+ -> E + AR(4p) + # Rxn30: 2E + AR+ -> E + AR + # Rxn31: AR + AR(4p) -> AR + AR(m) + # Rxn32: AR + AR(4p) -> AR + AR(r) + # Rxn33: AR(m) + AR(4p) -> E + AR+ + AR + # Rxn34: AR(r) + AR(4p) -> E + AR+ + AR + # Rxn35: E + AR(r) -> 2E + AR+ (not considered here) + + rxnNameDict = {0: "Ar(m) + Ar(m) => Ar + Ar", + 1: "Ar(m) + Ar(r) => E + Ar + Ar+", + 2: "Ar(4p) + Ar(4p) => E + Ar + Ar+", + 3: "Ar(m) + Ar(m) => E + Ar + Ar+", + 4: "Ar + Ar(m) => Ar + Ar", + 5: "Ar(r) => Ar", + 6: "Ar(4p) => Ar", + 7: "Ar(4p) => Ar(m)", + 8: "Ar(4p) => Ar(r)", + 9: "1s-metastable", + 10: "1s-resonance", + 11: "2p-lumped", + 12: "Ionization", + 13: "E + Ar(m) => E + Ar", + #13: "deexci-metastable", + 14: "StepIonization", + 15: "E + Ar(m) => E + Ar(r)", + 16: "E + Ar(m) => E + Ar(4p)", + 17: "E + Ar(4p) => E + E + Ar+", + 18: "E + Ar(4p) => E + Ar(r)", + 19: "E + Ar(4p) => E + Ar(m)", + 20: "E + Ar(r) => E + Ar", + #20: "deexci-resonance", + 21: "E + Ar(r) => E + Ar(m)", + 22: "E + Ar(r) => E + Ar(4p)", + 23: "E + Ar+ => Ar(m)", + 24: "E + Ar+ => Ar(r)", + 25: "E + Ar+ => Ar(4p)", + 26: "2E + Ar+ => E + Ar(m)", + 27: "2E + Ar+ => E + Ar(r)", + 28: "2E + Ar+ => E + Ar(4p)", + 29: "2E + Ar+ => E + Ar", + 30: "Ar + Ar(4p) => Ar + Ar(m)", + 31: "Ar + Ar(4p) => Ar + Ar(r)", + 32: "Ar(m) + Ar(4p) => E + Ar+ + Ar", + 33: "Ar(r) + Ar(4p) => E + Ar+ + Ar"} # 4) Set values in params class params.D[0] = De @@ -196,9 +259,13 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): params.mu[2] = mum params.A[:] = Ck[:] - params.B[:] = 0.0 + params.B[:] = B[:] params.C[:] = A[:] + # Account for the 2/3 term to convert from electron temperature to electron energy + for i in range(len(params.A)): + params.A[i] *= (2/3)**(params.B[i]) + params.dH[:] = dH[:] params.dEps[:] = dEps[:] params.qStar = qStar @@ -226,61 +293,33 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): params.eps0 = eps0 # unit charge [C] params.eArea = electrodeArea # electrode area [m^2] - # reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - # f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - # f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - # f"{params.A[3]} * energy**{params.B[3]} * np.exp(-{params.C[3]} / energy)", - # f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - # f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - # f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)", - # f"{params.A[7]} * energy**{params.B[7]} * np.exp(-{params.C[7]} / energy)"] - - # reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - # f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - # f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - # f"{params.A[3]} * (energy**({params.B[3]}-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]} + {params.C[3]}/energy)", - # f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - # f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - # f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)", - # f"{params.A[7]} * (energy**({params.B[7]}-1)) * np.exp(-{params.C[7]}/energy) * ({params.B[7]} + {params.C[7]}/energy)"] - - reactionExpressionslist = [f"{params.A[0]} * energy**{params.B[0]} * np.exp(-{params.C[0]} / energy)", - f"{params.A[1]} * energy**{params.B[1]} * np.exp(-{params.C[1]} / energy)", - f"{params.A[2]} * energy**{params.B[2]} * np.exp(-{params.C[2]} / energy)", - f"{params.A[3]} * energy**({params.B[3]}-0.5)", - f"{params.A[4]} * energy**{params.B[4]} * np.exp(-{params.C[4]} / energy)", - f"{params.A[5]} * energy**{params.B[5]} * np.exp(-{params.C[5]} / energy)", - f"{params.A[6]} * energy**{params.B[6]} * np.exp(-{params.C[6]} / energy)"] - - reactionTExpressionslist = [f"{params.A[0]} * (energy**({params.B[0]}-1)) * np.exp(-{params.C[0]}/energy) * ({params.B[0]} + {params.C[0]}/energy)", - f"{params.A[1]} * (energy**({params.B[1]}-1)) * np.exp(-{params.C[1]}/energy) * ({params.B[1]} + {params.C[1]}/energy)", - f"{params.A[2]} * (energy**({params.B[2]}-1)) * np.exp(-{params.C[2]}/energy) * ({params.B[2]} + {params.C[2]}/energy)", - f"{params.A[3]} * (energy**({params.B[3]}-0.5-1)) * np.exp(-{params.C[3]}/energy) * ({params.B[3]}-0.5 + {params.C[3]}/energy)", - f"{params.A[4]} * (energy**({params.B[4]}-1)) * np.exp(-{params.C[4]}/energy) * ({params.B[4]} + {params.C[4]}/energy)", - f"{params.A[5]} * (energy**({params.B[5]}-1)) * np.exp(-{params.C[5]}/energy) * ({params.B[5]} + {params.C[5]}/energy)", - f"{params.A[6]} * (energy**({params.B[6]}-1)) * np.exp(-{params.C[6]}/energy) * ({params.B[6]} + {params.C[6]}/energy)"] - - reactionExpressionTypelist = np.array([True,True,True,False,False,False,False]) + + reactionExpressionTypelist = np.array([False,False,False,False,False,False,False,False,False, + True,True,True,True,False,True,True,True,False,True,True,False,True,True, + False,False,False,False,False,False,False,False,False,False,False]) reactionsList = [] LOGFilename = 'interpolationSample%s.log'%str(iSample) f = open(LOGFilename, 'w') + for i in range(Nr): + sample_root_dir = "../BOLSIGChemistry_6SpeciesRates_New" if reactionExpressionTypelist[i]: - Nsample = 72 - N300 = 200 - - root_dir = "/g/g92/jbarbere/glowDischarge/toyProblems/timeDomain" - rate_file = "{0:s}/BOLSIGChemistry/reaction300K_{1:d}.dat".format(root_dir, i) - temp_file = "{0:s}/BOLSIGChemistry/reaction300K.Te.dat".format(root_dir) - - #rateCoeff = np.fromfile('/usr/workspace/violetak/BOLSIGSamples/glowDischarge/toyProblems/timeDomain/BOLSIGChemistry/reaction300K_%s.dat' %str(i)) - rateCoeff = np.fromfile(rate_file) - rateCoeff = np.reshape(rateCoeff,[Nsample, N300]).T[:,iSample] - - #Te = np.fromfile('/usr/workspace/violetak/BOLSIGSamples/glowDischarge/toyProblems/timeDomain/BOLSIGChemistry/reaction300K.Te.dat') - Te = np.fromfile(temp_file) - Te = np.reshape(Te,[Nsample, N300]).T[:,iSample] + if i < 15 or i == 20: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + else: + fileString = sample_root_dir + "/" + "StepwiseExcitations" + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f[rxnNameDict[i]] + + rateCoeff = dataset[:,1] + rateCoeff /= 6.022e23 + Te = dataset[:,0] + Te /= 11604. # Sorting mean energy array and rate coefficient array based on # the mean energy array. @@ -295,7 +334,7 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): Te = Te[TeDuplicateinds] # Nondimensionalization of mean energy. - # Te *= 1.5 + Te *= 1.5 # Find first non-zero value of the coefficient rate. I = np.nonzero(rateCoeff) @@ -314,7 +353,10 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): indices = Nan + Inf + Positive - lastFalse = np.where(indices==False)[-1][-1] + 2 + #lastFalse = np.where(indices==False)[-1][-1] + 2 + for k in range(len(Te)): + if (Te[k] < 4.5 and indices[k] == False): + lastFalse = k + 2 # Transformation to log scale. TeLog = np.log(Te) @@ -336,7 +378,13 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): # For the troublesome values, we use the Arrhenius form. rateCoeffLog[0:lastFalse] = ALog - C / Te[0:lastFalse] # Nondimensionalization in log scale. - if i < 2: + if i == 9: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 10: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 11: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i == 12: rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) else: rateCoeffLog += - np.log(1.0/tau) + np.log(np0) @@ -359,37 +407,36 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): logging.warning('Position of possible duplicates in mean energy array: %s', TeDuplicateindsForLog[0]) - # rxn = eval("lambda energy :" + reactionExpressionslist[i]) - # rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) - # # setting the axes at the centre - # fig ,ax = plt.subplots(figsize=(9, 6)) - # ax.spines["top"].set_visible(True) - # ax.spines["right"].set_visible(True) - # ax.set_yscale('log') - # ax.set_xscale('log') - - # # plot the function - # # plt.plot(rateCoeffXFiner, np.exp(reactionExpressions_cubicSplineDerivative_log(rateCoeffXFiner)), - # # color='salmon', linestyle='--', label='interBolsig') - # # plt.plot(rateCoeffXFine, np.exp(reactionExpressions_cubicSpline_log(rateCoeffXFine)), - # # color='lightgreen', linestyle='--', label='interBolsig') - # # plt.plot(Te[:,0], reactionTExpressionsLogFiltered(TeLog[:]) * np.exp(reactionExpressionsLog(TeLog[:])) / Te[:,0], - # # color='blue', linestyle='-', label='interBolsig') - # plt.plot(Te, np.exp(reactionExpressionsLog(TeLog[:])), - # color='green', linestyle='-', label='Bolsig') - # plt.plot(Te, rxn(Te), - # color='salmon', linestyle='--', label='Liu') - # # plt.plot(Te[:,0], rxn_T(Te[:,0]), - # # color='red', linestyle='--', label='interBolsig') - # plt.xlim((0.05,100)) - # plt.ylim((1e-50,300)) - # plt.legend() - # plt.savefig("./Rates_%s.pdf" %str(i), dpi=300) - # # plt.xlim((-0.0001,0.0255)) - # plt.show() else: - rxn = eval("lambda energy :" + reactionExpressionslist[i]) - rxn_T = eval("lambda energy :" + reactionTExpressionslist[i]) + fileName = "%s/Arrhenius.%08d.h5" % (sample_root_dir, iSample) + f = h5.File(fileName, 'r') + arrh_Coeffs = f[rxnNameDict[i]][...] + A, B, C = arrh_Coeffs + + # Non-dimensionalize the coefficients + if i < 4: + A /= 6.022e23 + A *= tau*np0 + elif i == 4: + A /= 6.022e23 + A *= tau*nAr + elif i > 4 and i < 9: + A *= tau + elif i > 25 and i < 30: + A /= (6.022e23)**2 + A *= tau*np0*np0 + elif i > 29 and i < 32: + A /= 6.022e23 + A *= tau*nAr + else: + A /= 6.022e23 + A *= tau*np0 + + A *= ((2./3.)*11604)**B + C *= 1.5/(e0*11604) + + rxn = eval("lambda energy :" + f"{A} * energy**{B} * np.exp(-{C} / energy)") + rxn_T = eval("lambda energy :" + f"{A} * energy**({B}-1) * np.exp(-{C} / energy) * ({B} + {C} / energy)") reaction = Reaction(rxnAlfa = params.alfa[:,[i]], rxnBeta = params.beta[:,[i]], rxnBolsig = reactionExpressionTypelist[i], @@ -397,31 +444,42 @@ def setPsaapPropertiesTestArm(gam, inputV0, inputVDC, params, Nr, iSample): reactionsList.append(reaction) params.reactionsList = reactionsList - #params.Nr = 1 diffList = [] - Te = np.linspace(0, 1000, 10) - De_interp = params.D[0]*np.ones(10) - De_spline = CubicSpline(Te, De_interp) + # Data from BOLSIG + # Te in [eV] + # De * N in [1/(m*s)] + transport = h5.File("../BOLSIGChemistry_6SpeciesRates_New/Transport.%08d.h5" % (iSample), 'r') + #Te = NDe_v_Te[:,0] + NDe_v_Te = transport["diffusivity"] + Te_trans = NDe_v_Te[:,0] + Te_trans /= 11604 + print("Te_min = {0:.6e}".format(NDe_v_Te[0,0])) + print("Te_max = {0:.6e}".format(NDe_v_Te[-1,0])) + De_interp = (NDe_v_Te[:,1]/nAr)*tau/(L*L) + De_spline = CubicSpline(Te_trans, De_interp) De_Te_spline = CubicSpline.derivative(De_spline) - diffusivity = Diffusivity(interpolate = False, D_expression = De_spline, D_T_expression = De_Te_spline) + diffusivity = Diffusivity(interpolate = True, D_expression = De_spline, D_T_expression = De_Te_spline) diffList.append(diffusivity) - Ns = 4 + Ns = 6 for i in range(1, Ns): diffList.append(Diffusivity(interpolate = False)) params.diffusivityList = diffList muList = [] - Te = np.linspace(0, 1000, 10) - mue_interp = params.mu[0]*np.ones(10) - mue_spline = CubicSpline(Te, mue_interp) + # Data from BOLSIG + # Te in [eV] + # Mue * N in [1/(V*m*s)] + Nmue_v_Te = transport["mobility"] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te_trans, mue_interp) mue_Te_spline = CubicSpline.derivative(mue_spline) - mobility = Mobility(interpolate = False, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) + mobility = Mobility(interpolate = True, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) muList.append(mobility) - Ns = 4 + Ns = 6 for i in range(1, Ns): muList.append(Mobility(interpolate = False)) diff --git a/sampleRun.sh b/sampleRun.sh deleted file mode 100755 index af1297760..000000000 --- a/sampleRun.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash - -error_exit() -{ - echo "$1" 1>&2 - exit 1 -} - -module load python/3.8.2 -EXE="python3 ../chebSolver.py" -NEWTEXE="python3 ../timePeriodicSolver.py" - -# psaap 2 species case -#Np=250 -#Nt=2560 -#dt=0.00390625 -#baseFile='restart_psaap_Np250_' - -# Liu 3 species case -#Np=250 -#Nt=25600 -#Nt1=128 -#dt=0.0078125 -#scenario=0 -#baseFile="restart_3spec_Np${Np}_" -#newtFile="newton_3spec_Np${Np}.npy" -#saveFile="newton_3spec_Np${Np}_fullsoln.npy" - -# Liu 4 species case -Np=150 -Nt=25600 -Nt1=128 -dt=0.0078125 -scenario=6 -baseFile="restart_4spec_Np${Np}_" -newtFile="newton_4spec_Np${Np}.npy" -saveFile="newton_4spec_Np${Np}_fullsoln.npy" - -baseCmd="$EXE --Np $Np --Nt $Nt --dt $dt --scenario $scenario" -newtCmd="$NEWTEXE --Np $Np --Nt $Nt1 --Nn 10 --scenario $scenario" -saveCmd="$EXE --Np $Np --Nt $Nt1 --dt $dt --scenario $scenario" - -# Activation of background specie and elastic collisions. -#baseCmd="$EXE --Np $Np --Nt $Nt --dt $dt --scenario $scenario --elasticCollisionActivation --backgroundSpecieActivation" -#newtCmd="$NEWTEXE --Np $Np --Nt $Nt1 --Nn 10 --scenario $scenario --elasticCollisionActivation --backgroundSpecieActivation" -#saveCmd="$EXE --Np $Np --Nt $Nt1 --dt $dt --scenario $scenario --elasticCollisionActivation --backgroundSpecieActivation" - -screenOut="run.out" -rm -f $screenOut - -# Run an example case of the Chebyshev time domain solver -echo "Run 0 to 200...${baseFile}T200.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 0.0 --outfile "${baseFile}T200.npy" > $screenOut || error_exit "First run failed" -echo "Run 200 to 400...${baseFile}T400.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 200.0 --restart "${baseFile}T200.npy" \ - --outfile "${baseFile}T400.npy" >> $screenOut || error_exit "Second run failed" -echo "Run 400 to 600...${baseFile}T600.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 400.0 --restart "${baseFile}T400.npy" \ - --outfile "${baseFile}T600.npy" >> $screenOut || error_exit "Second run failed" - -echo "Run time domain shooting...${newtFile}" -$newtCmd --V0 100 --VDC 0.0 --gam 0.01 --rtol 1e-8 --restart "${baseFile}T600.npy" \ - --outfile $newtFile >> $screenOut || error_exit "Shooting failed" - -echo "Saving one period...${saveFile}" -$saveCmd --V0 100 --VDC 0.0 --rtol 1e-8 --restart $newtFile --savedata $saveFile --outfile discard.npy >> $screenOut diff --git a/sampleRunCN.sh b/sampleRunCN.sh deleted file mode 100755 index fb6a9f314..000000000 --- a/sampleRunCN.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -error_exit() -{ - echo "$1" 1>&2 - exit 1 -} - -module load python/3.8.2 -EXE="python3 ./chebSolver.py" -NEWTEXE="python3 ./timePeriodicSolver.py" - -# psaap 2 species case -#Np=250 -#Nt=2560 -#dt=0.00390625 -#baseFile='restart_psaap_Np250_' - -# Liu 3 species case -#Np=300 -#Nt=25600 -#Nt1=128 -#dt=0.0078125 -#scenario=0 -#baseFile="restart_3spec_CN_Np${Np}_" -#newtFile="newton_3spec_CN_Np${Np}.npy" -#saveFile="newton_3spec_CN_Np${Np}_fullsoln.npy" - -# Liu 4 species case -Np=150 -Nt=25600 -Nt1=128 -dt=0.0078125 -scenario=6 -baseFile="restart_4spec_CN_Np${Np}_" -newtFile="newton_4spec_CN_Np${Np}.npy" -saveFile="newton_4spec_CN_Np${Np}_fullsoln.npy" - -baseCmd="$EXE --Np $Np --Nt $Nt --dt $dt --scenario $scenario" -#newtCmd="$NEWTEXE --Np $Np --Nt $Nt1 --Nn 10 --scenario $scenario --tscheme CN" -newtCmd="$NEWTEXE --Np $Np --Nt $Nt1 --Nn 20 --scenario $scenario --tscheme CN --alpha0 0.1 --increaseFac 1.5" -saveCmd="$EXE --Np $Np --Nt $Nt1 --dt $dt --scenario $scenario --tscheme CN" - -# Activation of background specie and elastic collisions. -#baseCmd="$EXE --Np $Np --Nt $Nt --dt $dt --scenario $scenario --elasticCollisionActivation --backgroundSpecieActivation" -#newtCmd="$NEWTEXE --Np $Np --Nt $Nt1 --Nn 10 --scenario $scenario --tscheme CN --elasticCollisionActivation --backgroundSpecieActivation" -#saveCmd="$EXE --Np $Np --Nt $Nt1 --dt $dt --scenario $scenario --tscheme CN --elasticCollisionActivation --backgroundSpecieActivation" - -screenOut="runCN.out" -rm -f $screenOut - -# Run an example case of the Chebyshev time domain solver -echo "Run 0 to 200...${baseFile}T200.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 0.0 --outfile "${baseFile}T200.npy" > $screenOut || error_exit "First run failed" -echo "Run 200 to 400...${baseFile}T400.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 200.0 --restart "${baseFile}T200.npy" \ - --outfile "${baseFile}T400.npy" >> $screenOut || error_exit "Second run failed" -echo "Run 400 to 600...${baseFile}T600.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 400.0 --restart "${baseFile}T400.npy" \ - --outfile "${baseFile}T600.npy" >> $screenOut || error_exit "Second run failed" -echo "Run 600 to 800...${baseFile}T800.npy" -$baseCmd --V0 100 --VDC 0.0 --t0 600.0 --restart "${baseFile}T600.npy" \ - --outfile "${baseFile}T800.npy" >> $screenOut || error_exit "Second run failed" - -echo "Run time domain shooting...${newtFile}" -$newtCmd --V0 100 --VDC 0.0 --gam 0.01 --rtol 1e-8 --restart "${baseFile}T800.npy" \ - --outfile $newtFile >> $screenOut || error_exit "Shooting failed" - -echo "Saving one period...${saveFile}" -$saveCmd --V0 100 --VDC 0.0 --rtol 1e-8 --restart $newtFile --savedata $saveFile --outfile discard.npy >> $screenOut diff --git a/timePeriodicSolver.py b/timePeriodicSolver.py index cb239002d..46a0454b3 100644 --- a/timePeriodicSolver.py +++ b/timePeriodicSolver.py @@ -23,7 +23,7 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, else: # Default initial guess. This should be overwritten # by reading restart if you want this to work. - self.tds.U1[0:self.tds.Np] = 1e-4 + self.tds.U1[0:self.tds.Np] = 1e-3 self.tds.U1[self.tds.Np:2*self.tds.Np] = 1e-4 self.tds.U1[2*self.tds.Np:] = 0.75 @@ -180,25 +180,58 @@ def solveNewtonStep(self, Uic, Nt): print("# Running scenario = 3 (4 species, 8 rxn, Liu 2017)") Ns = 4 elif(args.scenario==4): - print("# Running scenario = 4 (4 species, 8 rxn, Liu 2017)") + print('# Running scenario = 4 (4 species, 9 rxn, 1Torr, Nominal)') Ns = 4 elif(args.scenario==5): - print("# Running scenario = 5 (4 species, 7 rxn, Bolsing and Lay, Moss et al, 2003)") + print('# Running scenario = 5 (4 species, 9 rxn, 1Torr, Sampling)') Ns = 4 elif(args.scenario==6): - print("# Running scenario = 6 (4 species, 9 rxn, Juan's Mechanism)") - Ns = 4 + print('# Running scenario = 6 (6 species, 23 rxn, 1Torr, 100V, Sampling)') + Ns = 6 elif(args.scenario==7): - print("# Running scenario = 7 (4 species, 9 rxn, Nominal Reaction Rates)") - Ns = 4 + print('# Running scenario = 7 (6 species, 23 rxn, 250mTorr, 100V, Sampling)') + Ns = 6 elif(args.scenario==8): - Ns = 4 + print("# Running scenario = 9 (6 species, 23 rxn, 500mTorr, 100V, Sampling)") + Ns = 6 elif(args.scenario==9): print("# Running scenario = 9 (6 species, 23 rxn)") Ns = 6 elif(args.scenario==10): + print("# Running scenario = 10 (6 species, 23 rxn, 100mTorr, Nominal)") + Ns = 6 + elif(args.scenario==12): + print('# Running scenario = 12 (6 species, 23 rxn, 1Torr, 100V, Nominal)') + Ns = 6 + elif(args.scenario==13): + print('# Running scenario = 13 (6 species, 23 rxn, 500mTorr, 100V, Nominal)') + Ns = 6 + elif(args.scenario==14): + print('# Running scenario = 14 (6 species, 34 rxn, 1Torr, Nominal)') + Ns = 6 + elif(args.scenario==7): + print('# Running scenario = 7 (6 species, 34 rxn, 1Torr, Nominal)') + Ns = 6 + elif(args.scenario==8): + print('# Running scenario = 8 (6 species, 34 rxn, 1Torr, Sampling)') + Ns = 6 + elif(args.scenario==9): + print('# Running scenario = 9 (6 species, 34 rxn, 2Torr, Nominal)') + Ns = 6 + elif(args.scenario==10): + print('# Running scenario = 10 (6 species, 34 rxn, 2Torr, Sampling)') + Ns = 6 + elif(args.scenario==11): + print('# Running scenario = 11 (6 species, 34 rxn, 5Torr, Nominal)') Ns = 6 elif(args.scenario==12): + print('# Running scenario = 12 (6 species, 34 rxn, 5Torr, Sampling)') + Ns = 6 + elif(args.scenario==13): + print('# Running scenario = 13 (6 species, 34 rxn, 10Torr, Nominal)') + Ns = 6 + elif(args.scenario==14): + print('# Running scenario = 14 (6 species, 34 rxn, 10Torr, Sampling)') Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") @@ -207,6 +240,7 @@ def solveNewtonStep(self, Uic, Nt): print("ERROR: Scenario = {0:d} not recognized. Exiting.".format(args.scenario)) exit(-1) + print("#") elasticCollisionActivationFactor = 1.0 diff --git a/voltage_sample_gen.py b/voltage_sample_gen.py new file mode 100644 index 000000000..0a6cd91d8 --- /dev/null +++ b/voltage_sample_gen.py @@ -0,0 +1,17 @@ +import numpy as np +import h5py as h5 +import argparse + +voltage_uncert = 1./3. #Volts, given as standard deviation, assuming a normal distribution +#parser = argparse.ArgumentParser(description="") +#parser.add_argument( + +for i in range(7200): + factor = np.random.normal(0, voltage_uncert) + with h5.File('./BOLSIGChemistry_Voltage/Voltage.%08d.h5' % (i), 'w') as f: + f.create_dataset('V_Err', data = [factor]) + + if (i % 100) == 0: + print('{}-th sample generated'.format(i)) + +print('Done!')