From 06f7d25b077457ec312637711c329e28b04b7947 Mon Sep 17 00:00:00 2001 From: "Todd A. Oliver" Date: Tue, 24 Jun 2025 15:55:03 -0500 Subject: [PATCH 01/10] Keep 6 species regression test input deck unchanged Adding modified version here for posterity --- .../nominal_transport.h5 | Bin 0 -> 12720 bytes chebSolver.py | 7 + psaapPropertiesTestArmInterpTrans.py | 9 - psaapProperties_6Species_500mTorr.py | 533 ++++++++++++++++++ psaapProperties_6Species_ModTrans.py | 533 ++++++++++++++++++ timePeriodicSolver.py | 2 + 6 files changed, 1075 insertions(+), 9 deletions(-) create mode 100644 BOLSIGChemistry_Transport/nominal_transport.h5 create mode 100755 psaapProperties_6Species_500mTorr.py create mode 100755 psaapProperties_6Species_ModTrans.py diff --git a/BOLSIGChemistry_Transport/nominal_transport.h5 b/BOLSIGChemistry_Transport/nominal_transport.h5 new file mode 100644 index 0000000000000000000000000000000000000000..1e1557ecff143d48ba5bc6b8115d5b0beb76b58a GIT binary patch literal 12720 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 NXQY30IQxy^e*wA*hKK+F literal 0 HcmV?d00001 diff --git a/chebSolver.py b/chebSolver.py index 6e654858f..ec126abd3 100644 --- a/chebSolver.py +++ b/chebSolver.py @@ -15,6 +15,7 @@ from psaapProperties_6Species import setPsaapProperties_6Species from psaapProperties_6Species_Sampling import setPsaapProperties_6Species_Sampling from psaapProperties_6Species_Nominal import setPsaapProperties_6Species_Nominal +from psaapProperties_6Species_500mTorr import setPsaapProperties_6Species_500mTorr class modelClosures: """Class providing model parameters.""" @@ -442,6 +443,8 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, Nr = 23 elif(scenario==12): Nr = 23 + elif(scenario==13): + Nr = 23 elif(scenario==21): Nr = 8 else: @@ -478,6 +481,8 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, setPsaapProperties_6Species_Sampling(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==21): setPsaapPropertiesTestArmInterpTrans(gam, V0, VDC, self.params, Nr, iSample) @@ -1927,6 +1932,8 @@ def plot(self, col, create=True): Ns = 6 elif(args.scenario==12): Ns = 6 + elif(args.scenario==13): + Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") Ns = 4 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/psaapProperties_6Species_500mTorr.py b/psaapProperties_6Species_500mTorr.py new file mode 100755 index 000000000..cd39b409d --- /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 = 2.415e22 # 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 = 99.99*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_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/timePeriodicSolver.py b/timePeriodicSolver.py index cb239002d..c9804a029 100644 --- a/timePeriodicSolver.py +++ b/timePeriodicSolver.py @@ -200,6 +200,8 @@ def solveNewtonStep(self, Uic, Nt): Ns = 6 elif(args.scenario==12): Ns = 6 + elif(args.scenario==13): + Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") Ns = 4 From 57998d472149ca62ea5dcaa703e925af259208c3 Mon Sep 17 00:00:00 2001 From: Juan Barberena Date: Mon, 19 Dec 2022 12:34:35 -0600 Subject: [PATCH 02/10] Added 4-Species Files --- 4Species_Test/sampleRunCN.sh | 47 ++ BOLSIGChemistry_4SpeciesRates/ionization.h5 | Bin 0 -> 9344 bytes .../lumped_1s.excite.h5 | Bin 0 -> 9344 bytes .../step_ionization.h5 | Bin 0 -> 9344 bytes psaapProperties_4Species_Nominal.py | 444 ++++++++++++++++++ 5 files changed, 491 insertions(+) create mode 100755 4Species_Test/sampleRunCN.sh create mode 100644 BOLSIGChemistry_4SpeciesRates/ionization.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/lumped_1s.excite.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/step_ionization.h5 create mode 100644 psaapProperties_4Species_Nominal.py diff --git a/4Species_Test/sampleRunCN.sh b/4Species_Test/sampleRunCN.sh new file mode 100755 index 000000000..03a2f5a0b --- /dev/null +++ b/4Species_Test/sampleRunCN.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +error_exit() +{ + echo "$1" 1>&2 + exit 1 +} + +EXE="python3 ../chebSolver.py" +NEWTEXE="python3 ../timePeriodicSolver.py" + +# 4 species + 9 rxn - Nominal Rates case +Np=150 +Nt=25600 +Nt1=128 +dt=0.0078125 +scenario=7 +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 --elasticCollisionActivation --backgroundSpecieActivation" +#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 --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}T200.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/BOLSIGChemistry_4SpeciesRates/ionization.h5 b/BOLSIGChemistry_4SpeciesRates/ionization.h5 new file mode 100644 index 0000000000000000000000000000000000000000..1468ca181ea1453f2c1c703727c65ace0df1dd03 GIT binary patch literal 9344 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/lumped_1s.excite.h5 b/BOLSIGChemistry_4SpeciesRates/lumped_1s.excite.h5 new file mode 100644 index 0000000000000000000000000000000000000000..7b7a1eb168dd0bcf89f803cef8dd70dc5a916e04 GIT binary patch literal 9344 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 z k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([0.0,0.0,0.0,4.0e-13,3.24e-9,8.6e-10,2.1e-15,3.21e7,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([0.0,0.0,0.0,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. # 1/(m*s) + 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] *= tau*nAr + 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], # E + [1,0,1,0,1,0,0,0,0], # AR+ + [0,1,0,1,0,0,0,0,1], # AR* + [0,0,0,0,1,1,2,1,0]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,0,1,0,0,2], # E + [0,0,0,1,0,0,0,0,1], # AR+ + [0,0,1,0,2,1,1,1,0], # AR* + [1,1,0,0,0,0,1,0,0]], dtype=np.int64) # AR + # 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* + + rxnNameDict = {0: "ionization", + 1: "lumped_1s.excite", + 2: "step_ionization", + 3: "Ar+ + E => Ar*", + 4: "Ar* + Ar* => Ar + Ar+ + E", + 5: "Ar* + e => Ar + E", + 6: "Ar* + Ar => Ar + Ar", + 7: "Ar* => Ar", + 8: "Ar+ + E + E => Ar* + E"} + + # 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)", + 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.log' + f = open(LOGFilename, 'w') + for i in range(Nr): + if reactionExpressionTypelist[i]: + f = h5.File("../BOLSIGChemistry_4SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + + 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 < 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 + + 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") + 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 = 4 + 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"] + 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 = 4 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() From e3ca86cd703d6281034ed923be83f075fa99f7dd Mon Sep 17 00:00:00 2001 From: "Todd A. Oliver" Date: Tue, 24 Jun 2025 16:19:12 -0500 Subject: [PATCH 03/10] Fixing chebSolver imports --- .../plot_rates_h5.py | 37 ++ chebSolver.py | 77 +-- fullRun.sh | 39 -- plotSampleRun.ipynb | 207 -------- psaapProperties.py | 233 -------- psaapPropertiesCurrentTestCase.py | 235 --------- psaapPropertiesCurrentTestCase100mTorr.py | 235 --------- psaapPropertiesTestArmVioleta.py | 431 --------------- psaapPropertiesTestJP.py | 396 -------------- psaapPropertiesTestJP_Arrhenius.py | 373 ------------- psaapPropertiesTestJP_Nominal.py | 371 ------------- psaapPropertiesWithSampling.py | 382 -------------- psaapProperties_4plus2Species.py | 374 ------------- psaapProperties_6Species.py | 430 --------------- psaapProperties_6Species_Sampling_500mTorr.py | 499 ++++++++++++++++++ timePeriodicSolver.py | 19 +- 16 files changed, 589 insertions(+), 3749 deletions(-) create mode 100644 BOLSIGChemistry_4SpeciesRates/plot_rates_h5.py delete mode 100755 fullRun.sh delete mode 100644 plotSampleRun.ipynb delete mode 100644 psaapProperties.py delete mode 100644 psaapPropertiesCurrentTestCase.py delete mode 100644 psaapPropertiesCurrentTestCase100mTorr.py delete mode 100644 psaapPropertiesTestArmVioleta.py delete mode 100644 psaapPropertiesTestJP.py delete mode 100755 psaapPropertiesTestJP_Arrhenius.py delete mode 100755 psaapPropertiesTestJP_Nominal.py delete mode 100644 psaapPropertiesWithSampling.py delete mode 100755 psaapProperties_4plus2Species.py delete mode 100755 psaapProperties_6Species.py create mode 100755 psaapProperties_6Species_Sampling_500mTorr.py diff --git a/BOLSIGChemistry_4SpeciesRates/plot_rates_h5.py b/BOLSIGChemistry_4SpeciesRates/plot_rates_h5.py new file mode 100644 index 000000000..6f33cc29d --- /dev/null +++ b/BOLSIGChemistry_4SpeciesRates/plot_rates_h5.py @@ -0,0 +1,37 @@ +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 = 3 +reactionExpressionTypelist = np.array([True, True, True]) +rxnNameDict = {0: "ionization", + 1: "lumped_1s.excite", + 2: "step_ionization"} + +for i in range(Nr): + if reactionExpressionTypelist[i]: + f = h5.File("{0:s}.h5".format(rxnNameDict[i]), 'r') + data = f["table"] + + Te = data[:,0] + rateCoeff = data[:,1] + rateCoeff /= 6.022e23 + + row_temp = [] + data = [] + header = ["Te(K)", "kf(m3/s)"] + for j in range(len(Te)): + row_temp.append(Te[j]) + row_temp.append(rateCoeff[j]) + data.append(row_temp) + row_temp = [] + + g = open("./RateProfile_{0:s}.csv".format(rxnNameDict[i]), 'w') + writer = csv.writer(g) + writer.writerow(header) + writer.writerows(data) + g.close() + diff --git a/chebSolver.py b/chebSolver.py index ec126abd3..ec4ec9ce0 100644 --- a/chebSolver.py +++ b/chebSolver.py @@ -2,20 +2,15 @@ import numpy.polynomial.chebyshev as cheb 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_4Species_Nominal import setPsaapProperties_4Species_Nominal from psaapProperties_6Species_Nominal import setPsaapProperties_6Species_Nominal -from psaapProperties_6Species_500mTorr import setPsaapProperties_6Species_500mTorr +from psaapProperties_6Species_Sampling import setPsaapProperties_6Species_Sampling +from psaapProperties_6Species_Sampling_500mTorr import setPsaapProperties_6Species_Sampling_500mTorr class modelClosures: """Class providing model parameters.""" @@ -198,16 +193,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 @@ -229,19 +214,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 @@ -432,11 +411,11 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, 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): @@ -445,6 +424,12 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, Nr = 23 elif(scenario==13): Nr = 23 + elif(scenario==14): + Nr = 23 + elif(scenario==15): + Nr = 23 + elif(scenario==16): + Nr = 23 elif(scenario==21): Nr = 8 else: @@ -457,6 +442,7 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, self.params = modelClosures(self.Ns, Nr) + if(scenario==0): setLiu2014Properties(gam, V0, VDC, self.params, Nr, iSample) elif(scenario==1): @@ -470,11 +456,11 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, 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): @@ -483,6 +469,12 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, 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_100mTorr(gam, V0, VDC, self.params, Nr, iSample) + elif(scenario==15): + setPsaapProperties_6Species_250mTorr(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) @@ -1918,21 +1910,30 @@ def plot(self, col, create=True): print("# Running scenario = 5 (4 species, 7 rxn, Bolsing and Lay, Moss et al, 2003)") 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): 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): + Ns = 6 + elif(args.scenario==15): + Ns = 6 + elif(args.scenario==16): Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") 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/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/CsqIiiurU0HyLW1MGNG7uFJf3Ywndlf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VZ94IrR8x4EDtu9v0iT8vjUjQ3XsWDvO8P5WHFlZto5UqZL9vnHePNUrrgg8fvEaO9Z+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/wOOawHsS7V95dGVKCIiIiIiIpldhgde0zSX3dP0b8MwXgPqAQ8KvJdN04x6dJWJiIiIiIiIK3HoM7yGYbgZhvESkAvY9ifdlxiGcdEwjK2GYXTKgPJEREREREQkEzNM08z4NzWMJ4EQIBsQB3QzTXNFOn29sd32vBVI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f/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+yyxC8VRERErKTCKyIiKS0Wi3HFFVcwderUxLZTTjmFDz74gNatW1uYLDUUFxfz4Ycfcvrppye2zZo1i4suuohIJGJhMhERERVeERFJYbFYjCuvvJKZM2cmtl1wwQXMnTuXzMxMC5OllszMTN58801+//vfJ7b99a9/5fzzz9ezekVExFIqvCIikpJ2n8Y8Y8aMxLaLLrqI2bNn43K5LEyWmhwOB9OnT+fqq69ObJszZw7nnXcewWDQwmQiInIoU+EVEZGUY5om11xzDdOmTUtsu/DCC3nuuecSj9ORxmez2Zg8eTLjxo1LbHvjjTcYPnw4gUDAwmQiInKoUuEVEZGUYpom1157bYNrdn/3u9/x/PPPq+w2A8MwmDRpEjfffHNi2zvvvMOwYcMIhUIWJhMRkUORCq+IiKSUCRMm8PTTTyfGv/3tb5k1a5bKbjMyDIMHH3yQP/zhD4lt7733HhdeeKHu3iwiIs1KhVdERFLG9OnTmTBhQmJ8/vnn88ILL6jsWsAwDCZOnMhdd92V2PbKK69w9dVX6zm9IiLSbFR4RUQkJbzxxhtcddVVifGpp56qspsE7rnnHq677rrEePr06dxxxx0WJhIRkUOJCq+IiLR4H330ESNHjiQWiwFw9NFHM2fOHJxOp8XJxDAMHnvsMX73u98ltj3wwAM88sgjFqYSEZFDhQqviIi0aKtXr+ass85K3AW4S5cuvP3223i9XouTyW42m43nnnuOs88+O7Ft/PjxPPfccxamEhGRQ4EKr4iItFjbt2/ntNNOY9euXQAUFhby7rvvUlRUZHEy2ZPT6eTll1/mpJNOSmwbPXo0//znPy1MJSIiqU6FV0REWqRQKMSIESPYuHEjABkZGbzzzjt07drV4mSyL2lpabz55pv069cPgGg0ynnnncfq1astTiYiIqlKhVdERFqc3c/a/d///gfErxN9+eWXGTBggMXJ5ECys7N5++23OeywwwCorKzkzDPPpLS01OJkIiKSilR4RUSkxZk6dSrTp09PjB988EHOPPNMCxPJD9GmTRveeustMjIyAFi3bh2/+tWvCAaDFicTEZFUo8IrIiItygcffNDgMTcXXHAB48ePtzCR/Bh9+/blb3/7G4ZhALBgwQJGjRqlZ/SKiEijUuEVEZEWY8OGDYwYMYJIJAJA//79mTlzZqI0Scty9tlnN3g80V/+8hfuvfdeCxOJiEiqUeEVEZEWwe/3M2zYMMrKygBo1aoVr7/+OmlpaRYnk5/i+uuvZ/To0YnxXXfdxdy5cy1MJCIiqUSFV0REWoSxY8eydOlSIP6Im9dee4127dpZnEp+KsMwmDx5Mv/v//2/xLYLL7yQb775xsJUIiKSKlR4RUQk6f3tb39jxowZifGTTz7J8ccfb2EiaUxOp5OXXnqJ9u3bA1BRUcG5555LbW2txclERKSlU+EVEZGk9vXXXzc45XXkyJFcccUVFiaSplBQUMCcOXNwuVwALFu2jKuuuko3sRIRkZ9EhVdERJJWIBDg17/+NdXV1QB07dqVadOm6SZVKWrgwIE89dRTifHs2bOZNm2ahYlERKSlU+EVEZGkddNNNyWu23W5XLzyyitkZWVZnEqa0uWXX84ll1ySGF933XV88skn1gUSEZEWTYVXRESS0pw5c3j66acT40mTJtGvXz8LE0lzMAyDZ555hr59+wIQDocZMWIEO3futDiZiIi0RCq8IiKSdDZu3MioUaMS4+HDh3P11VdbmEiaU1paGq+++io5OTkAlJSUMGrUKF3PKyIiP5gKr4iIJJVYLMYll1xCZWUlAB07duTZZ5/VdbuHmM6dO/PCCy8kxq+//rqu5xURkR9MhVdERJLK5MmTef/99wGw2Wy8+OKLiSN9cmg555xzuOaaaxLj66+/nlWrVlmYSEREWhoVXhERSRpr1qzhlltuSYxvueUWBg8ebGEisdrDDz/MkUceCcTv2j1y5EgCgYDFqUREpKVQ4RURkaQQiUS46KKLEmXmqKOO4p577rE2lFguLS2Nl156CY/HA8Dy5cu5+eabLU4lIiIthQqviIgkhQceeIDFixcD8UcQzZ49G5fLZXEqSQZHHHEEkyZNSoyfeuop5s6da2EiERFpKVR4RUTEckuWLGHixImJ8cSJE+nTp4+FiSTZXHnllQwbNiwxvvTSS9m2bZuFiUREpCVQ4RUREUsFAgEuuugiIpEIAIMHD+amm26yOJUkG8MwmDlzJsXFxQCUlZVx5ZVX6lFFIiKyXyq8IiJiqfvvvz9x592MjAxmz56N3W63OJUko/z8/AaPKnrjjTf461//amEiERFJdiq8IiJimZUrV/Lggw8mxg899BBdunSxMJEku6FDh3LVVVclxmPGjGHLli0WJhIRkWSmwisiIpaIxWJcfvnlhMNhIH4qc/0iI7Ivf/rTn+jYsSMAFRUVjB49Wqc2i4jIXqnwioiIJaZMmcLHH38MgNPpZMaMGdhs+rEkB+b1enn++VDAmigAACAASURBVOcT47fffptZs2ZZF0hERJKW/mUhIiLNrqSkhNtuuy0xvu222zj88MMtTCQtzcknn8x1112XGI8bN45NmzZZmEhERJKRCq+IiDQr0zQZM2YMPp8PgB49ejQovyIH6/7776dr164AVFVVMWrUKJ3aLCIiDajwiohIs3rttdd44403EuMZM2bg8XgsTCQtVUZGBrNmzcIwDADmzZvX4C7OIiIiKrwiItJsKisrufbaaxPj0aNHc+KJJ1qYSFq6448/nuuvvz4xvvHGGyktLbUwkYiIJBMVXhERaTYTJkxg69atALRp04aHHnrI4kSSCiZOnJi4a3N5eTk33HCDtYFERCRpqPCKiEizWLlyJU8++WRiPGnSJHJycixMJKkiIyODKVOmJMZ/+ctfmDdvnoWJREQkWajwiohIkzNNk+uuu45oNArE77D7m9/8xuJUkkpOO+00zj///MT4yiuvpLa21sJEIiKSDFR4RUSkyc2ZM4f//Oc/ANjtdp588snEjYZEGstjjz1Gbm4uAOvWrWPixIkWJxIREaup8IqISJOqqanhxhtvTIyvueYaevfubWEiSVVFRUU8/PDDifEjjzzCsmXLLEwkIiJWU+EVEZEm9cADD7Bp0yYACgsLmTBhgsWJJJVddtll/OxnPwMgGo1y+eWXJ06lFxGRQ48Kr4iINJm1a9c2OOL24IMP6kZV0qQMw2DatGm4XC4AFi9ezIwZMyxOJSIiVlHhFRGRJnP99dcTCoUAOOaYY7jkkkusDSSHhB49enD77bcnxnfccQc7d+60MJGIiFhFhVdERJrEvHnzmDt3LhA/6jZ58mRsNv3YkeZxyy230LlzZyD+bN477rjD4kQiImIF/ctDREQaXTQaZfz48YnxpZdeysCBAy1MJIcaj8fD448/nhhPnz6dJUuWWJhIRESs0CIKr2EYdsMw/mgYxjrDMAJ163sNw3BYnU1ERL5v9uzZfPHFFwCkp6dz7733WpxIDkVnnXUWZ5xxBhB/FvSYMWOIxWIWpxIRkebUIgovcAtwDXAd0BMYWze+zcpQIiLyfTU1Ndx5552J8c0330ybNm0sTCSHKsMwePzxxxM3sFq4cCGzZ8+2OJWIiDSnllJ4BwNvmab5lmma603TfBN4ExhkcS4REdnDpEmT2LJlCwCtW7du8AxekebWrVs3brrppsT4lltuoaKiwsJEIiLSnFpK4f0fMMQwjJ4AhmEcDvwceMfSVCIi0sC2bdt46KGHEuM//vGPeL1eCxOJwO23385hhx0GwI4dO7j77rstTiQiIs3FME3T6gwHZBiGAdxL/BTmKOAA7jNN8859vH80MBqgqKjo6Jdeeqm5ov4o1dXV+gdhktGcJCfNS/LZc04mTZrEW2+9BUCnTp2YMWMGdrvdqniHLP238n3z589nwoQJANhsNmbOnEmnTp2a7etrTpKP5iQ5aV6ST0uYkyFDhiwxTXPA3va1lMI7EngYGA+sBPoCTwDjTdN8dn8fO2DAAPPTTz9t+pA/wfz58zn55JOtjiH1aE6Sk+Yl+dSfk1WrVtG7d+/ETYHeeecdTj/9dAvTHbr038r3mabJKaecwr///W8ATj31VN59991m+/qak+SjOUlOmpfk0xLmxDCMfRbelnJK88PAI6ZpvmSa5nLTNP8MTEI3rRIRSRq33HJLouwOHTqU0047zeJEIt8xDIPHHnss8Szo9957r1kLr4iIWKOlFN504qcy1xel5eQXEUlp//3vf5k7dy4QLxYPP/ww8atRRJJH7969GTVqVGJ84403EolELEwkIiJNraUUxreAWw3DONMwjI6GYfwKuAH4h8W5REQOeaZpcscddyTGF154IX379rUwkci+TZw4MXEt2qpVq3j22f1eGSUiIi1cSym81wJzgGeA1cCjwAzgjv19kIiINL158+bx3//+FwCn08k999xjbSCR/SgqKuK22767IuoPf/gDVVVVFiYSEZGm1CIKr2maPtM0x5mm2cE0zTTTNDubpnm7aZoBq7OJiBzKTNPkzju/u2H+qFGjmvXOtyI/xvXXX0+7du0AKC0t5YEHHrA4kYiINJUWUXhFRCQ5LViwgN13wvd4PA1ObRZJVmlpaQ1K7mOPPcb69eutCyQiIk1GhVdERH6UaDTKc889lxhfffXVtG3b1sJEIgfv/PPPZ+DAgQAEg0Fuv/12ixOJiEhTcFgdQEREWqaXX36ZdevWAeD1ern11lstTpT8fJEIX/n9rA8EWB8IsC0UojQUYmckQm00ij8WI2Ka2ACbYZBht5Npt5PncNDe46Gd2/3d2u3GY7db/S21WDabjUmTJnHiiScC8Le//Y2xY8cyaNAgi5OJiEhjUuEVEZEfLBwOc/fddyfG48aNo7Cw0MJEyacqEmFhVRWfVFWxyOdjeXU1G4LBRvv8NuCIjAyOzsxkQN3SJyODNJXgg3bCCSdw7rnn8uqrrwJw66238p///EeP1BIRSSEqvCIi8oO98MILrF27FoCcnBxuvPFGixNZzzRNlvh8vLFzJ//atYvFVVXfe4B8Y4oBy2tqWF5Tw6xt2wBwGgYnZWfTHSiqqaFnerrK2wHcf//9vP7660SjUebPn8+8efM49dRTrY4lIiKNRIVXRER+kGAwyMSJExPjm2++mZycHAsTWcc0TRb5fPx9xw7mlJYe8AiuwzDolpZGl7Q0Ono8tHW5KHS5yHc48NrtpNntOAwD0zSJmCY1sRi+SIQd4TCbgkE2BgKJ9cZgEHOPzx82Tf5dUcG/gSmLF9PR4+GMvDxGtmrFCdnZKr970b17d0aNGsW0adMAuO222zjllFOw2XSbExGRVKDCKyIiP8gLL7zApk2bgPjR3WuvvdbiRM1vSzDItC1beH7bNjbto+QawFFeL4OzshiUlUV/r5fu6em4GqlI+SIRPq+uZonPx6c+H4t9Pr72+xu8Z30gwDNbtvDMli108Xi4uHVrLmrdmg4eT6NkSBV33XUXs2fPxu/38/nnn/PKK68wcuRIq2OJiEgjUOEVEZGDFg6HGzzOZeTIkXi9XgsTNR/TNPlfZSWTN2/mtbIyIuaex1ch227nlwUFnJ2fz5DcXPKdzibLk+lwcFJODifVO7q+ORjk/3buZPZXX7HUbscX/e6k6m8CAe5av5671q9nSE4OVxUXM7ywELuO+lJcXMzYsWN58MEHAbjzzjs599xzcTbh/ImISPPQ+ToiInLQXnzxxcTzSvPz8znnnHOsDdQMoqbJX7Zto++nn3LS0qW8UlraoOzmORxc1ro17/TuzY7jj+eFXr0Y0apVk5bdfWnrdjOquJiJQNnxx/Pvo47iijZtyN7jRlbvV1Tw61Wr6PHJJzyzeTO10aa82rhluOWWW8jNzQXgm2++YebMmRYnEhGRxqDCKyIiByUajXL//fcnxjfccANpaWkWJmpaMdNkzo4d9F68mAvXrOGLmpoG+0/KzuaVww9n2+DBPNuzJ6fn5zfa6cqNwWWz8fPcXKb26MHWwYN56fDDOS0vr8EP/m8CAa75+ms6LFzIhPXr2RkOW5bXajk5OQ0erTVx4kRq9phzERFpeZLnJ7OIiCS1l19+ma+//hqIl4MxY8ZYnKhpmKbJW2VlHL1kCeetWsXq2trEvnSbjdFt2rBswAA+6NeP81q1wplEJXdf0ux2ftOqFf/Xpw8bjzuOOzt0INfx3VVNZeEw96xfT+eFC3lwwwb8h+gR32uvvZbi4mIAtm3bxhNPPGFxIhER+amS/6e0iIhYLhaLcd999yXGY8eOJSsry8JETWNFdTU/W7qUc1asYGl1dWJ7pt3OXR06UHLccUzr0YM+Lfi65bZuN3/s1ImNxx7L41270t7tTuyrika5bd06un3yCc9v3Up0L9cpp7K0tDTuueeexPihhx5i586d1gUSEZGfTIVXREQO6LXXXmPVqlUAZGZmMnbsWIsTNa7qSITx33xD308/5b+VlYntaTYbt7Rrx7pjj2VCp07kptBNjLwOB2MPO4y1gwbxl1696F7v9PTNoRCXffklfT/9lPfKyy1M2fwuvfRSunfvDkBVVRWPPvqoxYlEROSnUOEVEZH9Mk2Te++9NzEeM2ZM4uY+LZ1pmrxaWkqvxYt5ZNMmdp/I6zAMrmvblm8HDeLBLl0suQFVc3HabPy2qIgVAwcypVs3iup9rytqajjtiy8YuXIl2w7wjOFU4XA4+OMf/5gYP/nkk5SWllqYSEREfgoVXhER2a+33nqLZcuWAZCens71119vcaLGsT0U4pcrVjBi5UpK6pW5n2Vns2zAAJ7o1o3W9U73TXVOm40r27Zl7aBB3NOxIxn1rk1+ue6XAtO3bCF2CJzmPGLECHr37g1ATU0NDz/8sMWJRETkx1LhFRGRfdrz6O5VV11FYWGhhYkax9yyMnovXsxb9a7PbOV0MrtnT97v25fDMzIsTGctr8PB3R07snbQIH5XVJTYXhGJcMVXX/GzpUtZleJ3L7bZbA2u5Z08eTLbt2+3LpCIiPxoKrwiIrJP77//PosXLwbA7XZz0003WZzop6mNRrnqq684e8UKSus9gueq4mLWHHMMF7ZujWEYFiZMHq3dbv7cqxfz+vShi8eT2P6/ykr6f/opT5SUYKbw0d5hw4bRt29fAPx+Pw899JDFiURE5MdQ4RURkX3605/+lHh92WWX0bp1awvT/DSf+Xz0//RTpm7ZktjWxuViXp8+PNO9e0rdkKoxnZKXx/KBA7m9fXscdb8MCJom49au5Yzly1P22l6bzcaECRMS4ylTprCl3t8dERFpGVR4RURkr5YtW8Z7770HxP/xf8MNN1ic6Md7futWjvvsM770+xPbhhcUsHzgQE7Jy7MwWcuQZrdzX+fOfH700fSr90imd8vL6fPpp7ydoo/uOfvsszn66KMBCAQCPPjggxYnEhGRH0qFV0RE9qr+jXrOPfdcunbtamGaHycci3Hd119z2ZdfEqo7/TbDZuPZHj2Yc8QRKX335aZwpNfLx/37c1O7doltpeEwZy1fzrVff00wFrMwXeMzDIOJEycmxtOmTaOkpMTCRCIi8kOp8IqIyPds2LCBl156KTEeP368hWl+nNJQiFOWLeOpzZsT245IT+fzAQO4rE0bXav7I7ltNh7u0oV/9ulDG5crsX3y5s0MWbqULSl2ivPpp5/OoEGDAAiFQtx///0WJxIRkR9ChVdERL7n8ccfJxqNP5V2yJAhDBw40OJEP8xnPh8Dlizhg8rKxLbhBQUs7N+fbunpFiZLHUPz8vhiwAB+mZ+f2PZxVRVHL1nCR/X+3Fu6PY/yzpw5kw0bNliYSEREfggVXhERaaC8vJwZM2YkxjfffLOFaX64d3bu5MTPP2dj3ZFGA7i3UyfmHHEEXofD2nAppsDl4h9HHsmjXbok/kGxLRTi5KVLmZZCN3g65ZRTOP744wEIh8MNbuYmIiLJTYVXREQamDJlCjV1z1nt3bs3p556qsWJDt4L27ZxzvLl1NZdS5plt/NW797c0aGDTmFuIoZhcEO7dsw76ijy636hEDZNrvzqKy7/8ktCKXBdr2EY3H333Ynxs88+qzs2i4i0EPpVt4iIJPj9fp588snE+Oabb24RRdE0TR7etIlbvv02sa2D2827ffrQMyPDwmRgxkwC6wIENgQIlgS/WzYHiVZFiQVjxAKx+DoYw7Ab2DPtODId2DPt2DPtOPOdeDp58HTykNYpDU8nD46s5PoR/v9yc/n06KP51cqVLK2uBmDm1q2s8/t59cgjyW7hR9eHDh3KMcccw6JFiwgGgzz66KM8+uijVscSEZEDaNk/fUREpFHNnj2bHTt2ANCuXTt+85vfWJzowGKmyY3ffMPj9e6e2ycjg//r04dit7tZs5gxk+ovqqn+rJrqz6vxfe6jZlkN0epoo38tZ6GTzKMzyRxYtwzIxN2meb/fPXVMS2NBv36M/vJLXqz7e/TvigpO+vxz3unTh7bNPB+NyTAM7rzzTs455xwApk6dyq233kphYaHFyUREZH9UeEVEBIBYLNbgiNUNN9yAM8kf2xOJxbhkzZpEuQI4KTubN448kpxmyh4oCbDrn7sof6+cXf/aRWRnpFm+brg0TPm75ZS/W57Y5m7nJndoLrSHcN8wzpzmn790u50/9+pFz/R0/rB+PQBf1NRw3Gef8X99+nCExUfcf4qzzjqLo446imXLllFbW8vjjz/OfffdZ3UsERHZDxVeEREB4J133uHrr78GICcnh9///vcWJ9q/SCzG71av5uXS0sS24QUFvNirFx67vUm/du1XtWx/cTulc0qpXVV7wPc7WzlJ756Ou50bd1s37sPcuNq6cOY5sblt2Dw2DLeBzW3DjJpEfdHEEvFFCG0LEfg2QGBdAP86P4H1Acyg+b2vE9wUZNvz2wBYcO8Cso7NIv/0fArPKyS9e/PdndowDO7s2JHD3G4u/+orIqbJpmCQ4z/7jDd69+ZnOTnNlqUx7T7Ke9555wHw1FNPcdNNN5Gbm2txMhER2RcVXhERAeCJJ55IvL788svJzMy0MM3+RWIxLlyzpkHZvaJNG57u3h17E11zHNoeYsfLO9j+l+34Fvv2+T5nKyfZJ2Tj7ecls18m3n5eXG1cjXottBkz8X/jx7fYh2+xj6rFVVR/Vk3MX+8GUVGoWlBF1YIq1t25jsxjMin6XRGtRrbCVeja9ydvRJe0aUOx2825K1dSHY1SGY3yi2XLePnwwxnWQk8FHj58OL169WL16tX4fD4mT57MH/7wB6tjiYjIPqjwiogIK1as4F//+hcANpuNa665xuJE+xY1TS5es4aX6p3GPKZtW57s2rVJbrBV+XElJZNKKP1HKezlUlzDbZBzYg65v8gl7xd5ZPTOwLA17Y2+DJtBerd00rulU3RBEQCxSAzfYh/l75az4ZUN8CVQ7yCwb5EP3yIfa69fS95peRRfXkz+WfkY9qbN+ou8PD7s25czli9nWyhEyDQZsXIlLx5+OL9p1apJv3ZTsNls3H777Vx44YVA/JnV48aNS+pfEImIHMr0WCIREWlwZ+bhw4fToUMHC9PsW9Q0uXj1av5ar+xeXVzc6GU3Fomx45UdLDl2CZ8P/pzSOQ3LruE0KBhWwOF/P5wTyk/gqH8eRfvx7fEe5W3ysrsvNoeN7OOy6TShE0yBwdsH0+svvSgYVoDhrJcpCuVvl7Ni2Ao+6f4JJU+UEKlq2uuO+2VmsrB/f7qlpe2OwAWrVjF727Ym/bpNZeTIkXTu3BmIP7d6ypQpFicSEZF9UeEVETnElZWV8ec//zkxHjt2rIVp9i1mmly2xw2qriouZnK3bo1WdmOhGJuf2cwnXT9h1W9W4fuk4anLWcdn0X1qdwZvG8yR/ziSViNaYU9v2uuFfyxXoYui3xZx5D+OZPC2wXSf2p2s47P+P3v3HR5F9TVw/Dub3ggJqQQICQFCCYQiIAqCiAiIgBQBAaUoAmIX7OVne+2NoiIoIEVpKkUUK4pK7yQkIQRCOqSTnp33jwmziYQQyG7q+TzPPuydnZl7QwLZs/fec8qckxedR9QjUfzT7B8iH4kkNybXYuPxt7fnj9BQ2jtqe4mNwL3h4Syug/Vsra2tefrpp/X2u+++S07OlfdyCyGEqH4S8AohRAO3ePFi8vLyAOjWrRs33HBDDY/oUqqq8lhUFMuTkvRjD5gx2FWNKkmrktjdbjeRsyPJP52vv6bYKvhM8aH74e50/asrTWc0xca9dmev/i8bdxuazmhK17+60vNkT5rPa461m2lXU3FWMXEfxrG7zW4iZkaQdzbPIuPwtbPj99BQOpdkalaB+yMimF+qpFRdMXnyZJo1awZAcnIyX3zxRQ2PSAghRHkk4BVCiAassLCQBQsW6O2HH37YIvtgq+rt2Fg+jIvT2/f7+rKgdWsMVRyrqqqc33aefd32EXZ3GHnRpkDPuok1/s/70+t0L4KXBuMc4lylvmoLh0AHWv1fK66PvZ42n7TBMdiUvVktVIn/JJ5dQbuIfCSS/MT8Cu50bTxtbfk1NJRuzqa/zzlRUXxUx4JeW1tbnnzySb39zjvvUFRUPSWphBBCVJ4EvEII0YCtX7+euJJA0tvbm7Fjx9bwiC61PDGRedHRenu0pycL27SpcrCbE5XD4UGHOTL4CNkHs/Xj1m7WBL4VyPVnrifgfwHY+dhVqZ/aysrJiqYzmnLdsevotK0Trn1c9dfUfJW4D+PYFbiL6GeiKco2byDnbmPDL6GhXN/ItMT64agoliYkmLUfS5s2bRpNmjQBICYmhrVr19bwiIQQQvyXBLxCCNGAffDBB/rzWbNmYWdXu4K7befPM+3ECb19k6srK4KDq1R6yFhgJObVGPZ03EPa9jT9uMHBQItnWtAzuictnmxRa/fmmptiUHAf5E7oH6F0+rETLj1M2YaNuUbOvHGG3cG7SVqdhKpeWvv3WrlaW/Njp070LhX03nfiBF+X2qNd2zk5OfHggw/q7TfffNOsf0dCCCGqTgJeIYRooP7991927doFaMszZ8yYUcMjKmt3Ziajjh2jqCSA6OTkxHchIdhbXXsgmv5nOntD9xLzfAxqfklgYoCmDzSl58meBL4WiE3jurU/11wURcH9Vne6/tuVjps64hxqWnJcEFdA2IQwDt50kOxD2RXc5eq4WFuzJSSELiXLm43AxLAwNp07Z7Y+LO3BBx/EoST79KFDh/jpp59qeERCCCFKk4BXCCEaqA8//FB/PmHCBLy9vWtwNGWdys1l6JEj5BiNAPjb2fFDp064Wl9b+fjiC8WcmHGCg30PkhNmyqbr3M2Zbnu60WZRG+x8a9fsdk1RFAWP2z3otq8bwcuCsfE2fQCQ8WcGe7vuJXJOpNmWOTe2seHHTp1oV5K9uUhVGXPsGL+kpV3hytrBw8OD6dOn6+0333yzBkcjhBDivyTgFUKIBigxMZH169fr7dpUiiirqIg7jh7lXGEhAE2srfmxc2eaXuNy66z9WeztupeEz0z7Q62crQj6MIhuu7rh0tWlgqsbLsWg4DPZh54RPWn2eDMU65Jl5EaImx/H3pC9pP1qnqDU09aWnzt3JtDeHoB8VWX4kSP8m5Fhlvtb2mOPPYZVycqD3377jT179tTwiIQQQlwkAa8QQjRAS5YsobAkoLzhhhsIDQ2t4RFpjKrKpLAwjl64AICtovB9SAhtHR2vcOWlVKPKmXfOsL/XfnIjTPVlPUZ4cF3YdTR7qBmKVe3LSF3bWDeyJuidILof7o7bQDf9eF5MHocGHCJiVgRFWVWf7W1qZ8cvnTvjZ2sLwAWjkduPHCGyDtS3bdmyJePGjdPbMssrhBC1hwS8QgjRwBQVFfHpp5/q7VmzZtXgaMp6MSaG786f19uftW1Lb1fXCq4oX358PocHHSb6yWjUQm2vrpWzFcHLgumwoQP2zezNNuaGwqmdE51+7ES7r9qVqeEbvyiePSF7SPul6rO9LR0c+CU0FA8bbRn1+aIiBh8+THJBQZXvbWlz587Vn2/YsIGIiIgaHI0QQoiLJOAVQogGZsuWLcTGxgLg6enJqFGjanhEmq+Tk3n19Gm9/VizZtzj43PV90n/K529XfaS9rMpAHO5zoVuB7rhM9mnVtYZrisURcH7bm+uO34dTYY30Y/nn87n0C2HiH46GmOhsUp9tHV0ZHNICA4G7S3Kybw8hh05Qk5xcZXua2mdOnVi8ODBgFbf+Z133qnhEQkhhAAJeIUQosFZtGiR/nzatGm1ohTR/qwspoSH6+1Bbm68GRh41feJ/yyeQzcfojBZW66NAi2ebkGXnV1wDLr6ZdGifHY+dnTc2JF2K9th7W6a7T3zf2c42O8geWfyqnT/no0asbp9e/1Nyu6sLMYfP05xLS/5M2/ePP35smXLSKhjdYWFEKI+koBXCCEakKioKH788UdAm62rDaWIUgoKGH70KLklGZnbODiwpn17rA2V/xVlLDQSMSuCiBkR+hJmG08bOv/cmcDXAzHYyK87c1MUBe8J3lx37DrcBpn29mb+ncne0L2c+75qpYWGe3jwUevWevv78+d5KDKyVte57du3Lz179gSgoKCABQsW1PCIhBBCyDsAIYRoQD755BP9+ZAhQ2jZsmXNDQZTkqqz+fkAuFpZ8X1ICI1tKl8LtyClgEO3HCJ+Ubx+zDlUKzfkdrNbBVcKc7DzsaPT1k4E/l8glJRILkor4ujwo0Q9GlWlJc6z/fyY27y53l4YH897Z89WdcgWoygKTzzxhN5etGgROXUg6ZYQQtRnEvAKIUQDkZubyxdffKG3a0OyqjfOnOHHUvVWV7Vvf1UZmXMictjfYz8ZO0zlazzv8qTLzi7Y+0tiquqiGBRazGtBlx1dsGtuWiJ/9oOzHL71MAXnrj3p1BuBgYzz8tLbc0+e5IdSic1qm5EjRxIQEABAamoqy5cvr+ERCSFEwyYBrxBCNBDffPMNqampAAQEBDBo0KAaHc/vaWm8cOqU3n6qRQuGNGlSwRVlZe7N5MANB8iLKdkvqkDAGwG0X90eK0crcw9XVIJrb1e6H+xOkztM38f039PZf91+so9kX9M9DYrCl8HB3FiSrdsIjDt+nPCS0lW1jZWVVZm61u+//z5GY9USeQkhhLh2EvAKIUQDsXDhQv35jBkzsLKquaAwqaCA8WFhXAwD+ri68spVLK9O/TmVQ/0PUXhOS05lcDTQ8fuO+D/lL1mYa5iNuw0dv+1IwGsBUPKtyIvJY//1+0n5NuWa7mlnMLC+QwealyRYyywuZvjRo6SX1JKubaZOnYprSYAeERHBli1banhEQgjRcEnAK4QQDcC+ffvYvXs3ALa2tkydOrXGxlKsqkwMCyOxpLaqp40Nq68iSVXy18kcGXKE4mytTI21uzWdf+mMx+0eFhuzuDqKouD/jD8dv+2IUZ+tFQAAIABJREFUlbP2wYrxgpFjI48R80rMNSWe8rK15buOHfVyRRG5uYyrpZmbXVxcuP/++/X2e++9V4OjEUKIhk0CXiGEaABKJ6saO3Ysnp6eNTaW106f5ueSfbsK8FW7dvhVsjRS3II4jo8/rmditmtmR5e/uuDay9VSwxVV4HGHB13/7Yp9oGk/dcwLMYRPCb+mZFZdXFz4MjhYb/+Ylsa8kyfNMlZzmzNnjr6K4vfffyciIqKGRySEEA2TBLxCCFHPZWVlsXr1ar39wAMP1NhY/kpP5+WYGL39rL8/t7q7V+ra2A9iiXwwEkom9ByDHenydxec2jlZYKTCXJw6ONFtdzca39xYP5a0LImjw49SfKH4qu831suL5/z99fa7Z8+yIjHRLGM1p+bNmzN27Fi9vXbt2hocjRBCNFwS8AohRD23Zs0aLpQk+Gnfvj29e/eukXFkFhUxKTxc37fbr3FjXqrkvt2z889y8lHTTJ5LTxe6/NUF++aSibkusGliQ6dtnfCZ5qMfS/0hlYP9D1KQcvUZnF9u2ZLhpRKczYiI4Ej2tSXFsqTHHntMf/7bb79xthaXVBJCiPpKAl4hhKjnPv/8c/35fffdV2NJnR6JiiImT8uo3NjamhXBwVhVYixxi+KImhOltxvd0IjO2ztj06TytXpFzTPYGGi7uC3+z5tmZ7P2ZHGg9wFyo3Ov7l6Kwop27WhXUsIq12hk1LFjZBYVmXXMVdW9e3f69u0LQHFxMfPnz6/hEQkhRMMjAa8QQtRjhw8fLpOsauLEiTUyjo0pKXxRatnpotataWZ/5dnZ+M/iiZwVqbcbXd+ITls7Ye1ibZFxCstSFIWA/wXQelFr/R1IblQu+3vvJ/vQ1c3Qulhbs75DB5xKklhF5uYy7cSJa0qIZUmlZ3k//fRTsmvhTLQQQtRnEvAKIUQ9Vnp2d+TIkXh4VH8m48T8fO4vlbBnvJcX47y9r3hdwpIEImaYrnPp4UKnHzph3UiC3brO7wE/OqzrgGKnzfAXJhVysP9BsvZlXdV92jk5sbhtW729LiWFj+LizDrWqrr99tsJCgoCID09neXLl9fwiIQQomGRgFcIIeqp3NxcVqxYobfvu+++ah+DqqpMP3GCcyX1UpvZ2bGgdesrXpe8NpkT953Q2y7dXej0YyesXSXYrS88R3rS+efOWLlqmYyL0oo4OOAgmbsyr+o+4729md20qd5+4uRJ/snIMOtYq8LKyoqHHnpIb3/88ccYjVefoVoIIcS1kXcOQghRT23cuJH09HQAAgIC6N+/f7WP4bOEBLakpurtL4ODcbOpeO9t+h/phE0M07MxO3d1ptNPnbBpXPf27GYXZBOfFU98VjxZ+VnkFOaQU5hDblEuOYU5ANhZ2WFnbaf/2ciuEd5O3ng7e+Pl5IWtlW0NfxWW0/jGxoT+EsqhWw9RlFpEcUYxhwYeImRrCI1vbHzlG5R4NyiI3VlZ7MnKokhVGXv8OPu7dcPTtnb83d1zzz089dRT5OTkEB4ezs8//8ytt95a08MSQogGQQJeIYSopxYvXqw/nz59OgZD9S7qOZWby2NRpmRTjzRrxgA3twqvyT6SzZHhR1ALtGjXoY0DnX7shI1b7Q12swuyOZ5ynCNJRziafJTj544TmxFLXFYcmflXN1tZHjd7N/wa+dGmSRvaNmlL2yZtadOkDe0829HYvvJBYW3l0s2F0F9DOXTLIQrPFVKcVczh2w4TsjkEt34V/7xcZGcwsLZDB7rs3UtaURFn8/OZHB7OlpAQDDWUpK20Ro0aMXjwYNavXw/ARx99JAGvEEJUEwl4hRCiHoqMjOT3338HwGAwcO+991Zr/6qqcn9EBDklSzfbOzryekBAhdfkxeZxePBhijO02qy2PrZ0+rETth61Y5YOtK8rKjWKP07/wY7TO9gZu5PotGiL9pmWl0ZaXhpHk49e8lpr99b08OtBT7+e9PDrQahPKHbWdhYdjyU4d3Ym9PdQDg44SGFSIcYLRo4MOaIFvTdXLuj1t7fnq3btGHrkCADbUlP56OxZHmne3JJDr7SRI0eyYcMGVFVly5YtREZG0roSy/uFEEJUjQS8QghRDy1dulR/PnToUJqW2uNYHZYlJvJzWhqgJYv4MjgYByury55fmFrI4dsOUxCn1WS1crEi5IcQHFo6VMdwK5Sam8rmiM1sidzCjtM7SMxOvPJFJWytbGnq0pSmLk1xs3fD0cZRfzhYa19bfnE++UX52p/F+aTlppF0IYmk7CRSclIwqpff7xmZGklkaiQrj6zU+7uxxY0EEYRrgiudfTpjUOpGug6nDk6E/h7KoZsPUZBQgDHXyJE7jtB5e2dcr3et1D2GNGnCk82b83ZsLADzoqPp17gxoS4ulhx6pfj5+TFkyBC2bNkCwIIFC/jggw9qeFRCCFH/ScArhBD1TGFhIV988YXeru5kVUkFBTx28qTefqRZM65r1Oiy5xvzjRwdcZSc49qeVsVGoePGjriE1lyQEpcZx7fh37IxfCO/x/xOsVp82XOtFCvaerSlo1dHOnp2pINXB1q5taKpS1M8HD2qVPe42FjM+dzzxKTHcOLcCU6cP0HE+QhOnD9BWEoYhcbCMucXFBfw66lf+ZVf+eyzz/B09GRgq4GMaDuCIa2H4GTrdM1jqQ5OwU6E7gjlYL+DFMQVYLxg5PDgw4T+FopLl8r9PLwaEMCvaWnsy86mQFUZHxbG3m7dcKrgA5fq8tBDD+kB79KlS3nllVdwqQXBuBBC1GcS8AohRD2zZcsWkpKSAPD19WXw4MHV2v+cyEjSiooACLC3538VLGVWVZWImRFk/GnKqhu8LBi3AZVbxmpOeUV5bAzbyOL9i/kt5rfLnudq50of/z7c5H8Tff370tm7s8WWEVsZrPBy8sLLyYsefj0uGe/BxIPsjtvN7rjd7IrbRVRqVJlzUnJSWHVkFauOrMLRxpEhrYcwpv0YhrYeWmuDX8cgRzr/3JmDfQ9SmFJIcUYxh289TOiOUJzaXXnMtgYDq9q3p+vevVwwGgnPyeGxqCg+LVW+qKYMHDiQ4OBgwsPDycrKYtmyZTz44IM1PSwhhKjXJOAVQoh6pvTs7pQpU7C2rr7/6r87d461KSl6+7M2bSqcWYv7KI7EL0xLhAPfDsR7/JVr9JrT8ZTjLN63mOWHl5Oam1ruOT39ejIyeCSDggYR4hWClaHmZwvtre3p1awXvZr10o/FZcaxPXo7X/3zFYezD5OSY/pe5BTmsO74OtYdX4eDtQN3truT+7reR1//vlWahbYEp2AnOv3UiUP9D1GUXkThuUIO3XKILn92wSHwysvc2zg68nHr1kw9oZW2+iwhgUHu7tzp6WnpoVdIURTmzJnD7NmzAa1E0axZs6o9oZwQQjQk8j+sEELUI8nJyWzdulVvT5kypdr6zigqYlZEhKlvHx9ucXe/7PmpP6cS9bhpRtL7Hm+aP149CYZUVeXn6J8ZsHwAHRZ24INdH5QJdg2KgQEBA5g/eD5nHz3Lv9P/Zd6N8wj1Ca0Vwe7l+DXy497Qe3mu3XMkPpHIvvv38eJNL9Les32Z83KLcll5ZCX9lvWj7fy2vLXzLZKyk2po1OVzCXUh5IcQDE7aW5WC+AIO3XKI/Lj8Sl1/r48PY0sFuNNPnCA2L88iY70akydPxtVV25McERHBTz/9VMMjEkKI+k0CXiGEqEdWrVpFUcly4htvvJGgoKBq63vuyZPEF2hJp7xtbHi3VavLnpsTlcPxscehZGusS08X2nzSxuIzjUbVyLfh39Lz854MXDGQX0/9WuZ1f1d/Xun/CmceOcPPk39mdo/Z+DXys+iYLMWgGOjq25WX+r3EsVnHODbrGC/d9NIlwW9kaiTzfp5Hs/ebMW7dOPbG762hEV/KtZcrIZtCMNhrb1fyTuVx+LbDFGUUXfFaRVH4tE0bWthpy83Tioq4Jzwco6padMxX4uzszLRp0/T2hx9+WIOjEUKI+k8CXiGEqEe+/PJL/fk999xTbf3+nZHBZwkJent+69a42ZRfO7cos4ijw49SlKYFLbZNbem4sSNW9pabOVVVlTVH1xCyKISRX49kT/we/TUrxYpR7Uax7e5tRD8czXN9n6uzQW5F2nu258V+L3Js1jH23b+Pmd1n0sjOlEysyFjE18e+5rrF19Hvy35sjthcYYbo6uLW340O6zugWGsfhlw4eoGjI49iLLjy2Brb2LCyXTv9zc5v6eksiIuz4GgrZ/bs2fqHO9u2bSOi1MoIIYQQ5iUBrxBC1BMHDx7k0KFDANjb2zNmzJhq6bdYVZkdGam3hzdpwqjL7JVUjSphk8JMGZntFDp+2xE7X8vVjt15Zie9lvRi/PrxHE85rh+3s7JjVvdZRM6JZN3YdQwKGlRnSvhUVVffriwcupCExxP4cviX3ND8hjKv/3H6D4atHkaHhR344sAXFBmvPKNqSU2GNKHtUlPSqfTf0gmfEo5qvPJs7Y2NGzOvRQu9PS86msicHIuMs7ICAwO5/fbb9fYnn3xSg6MRQoj6rWH8ZhdCiAZg2bJl+vM777xT3ydoaZ/Ex3MwOxsAB4OBD1u3vuzS5Ni3Yzn//Xm93fbztjS67vIli6riZOpJxqwdw41f3MjuuN36cWdbZ+b2nkvMIzEsGLqAALfLZ5Gu7xxtHLkn9B7+mvoXB2YcYGKniVgbTEnOws+FM/X7qbRb0I6vDn9FsfHy5ZkszWeSDwGvmb5XyauSiX4mulLXvtiyJSFOWobnXKORe8LDKa7hpc0XE1eBlmgup4aDcCGEqK8k4BVCiHqgsLCQlStX6u3qWs6cBjwbbQo6nvX3x9/evtxz0/9KJ/pZ07nNHm+Gz0Qfs48ppzCHedvn0W5BO9YdX6cft7WyZW7vuZx55AxvDnwTH2fz912XhfqEsmLkCqIfiuaJ65/AxdZUHzYqNYpJGycRsiiEtcfW1thS5xZPt8B3hq/ejn0zlrgFV16ibGcwsDw4GOuSD2L+yczk3dhYi42zMgYOHKjvsU9PT2f16tU1Oh4hhKiv6kzAqyiKr6IoyxRFSVEUJU9RlOOKotxU0+MSQoja4IcffiClpByQn58fAwYMqJZ+PwMyirVZvyAHB55oXn6W5YJzBRwfZ0pS1ah3IwLfCDT7eH479RudFnXirb/fotBYqB8f13EcJx48wZsD38TNofpr/NYlzV2b8/atbxP7aCyv9n+VxvaN9dfCzoUxdt1Yun/WnR2nd1T72BRFofX81jQZ1kQ/FjknknPfnbvitaEuLrzo76+3nz91iqMlKxNqgsFgYObMmXp7wYIFqDU86yyEEPVRnQh4FUVpDOwEFGAo0A6YAyTX5LiEEKK2KL2cedKkSVhVUPvWXP7JyGBbqfbHQUHYlVNPVDWqhN8TTkGclsHZ2t2a9mvaY7Ax36+g9Lx07t90Pzcvv5mTaSf149c3u55/pv3D6lGradm4pdn6awhc7V15tu+znHr4FC/0faHMjO+BxAPc9OVNjFk7hpj0mGodl8HaQPvV7XHpUTIeFY7ffZzsw1cOXp9q0YLrXLTrClSVyeHhFBprLjHXvffei33JiogDBw6wa9euGhuLEELUV3Ui4AXmAgmqqk5WVXW3qqqnVFX9RVXVsJoemBBC1LTz58+zadMmvV0dy5mLVZVZpRJVjfDw4LYmTco9N/adWFK3mmrctlveDvvm5S97vhabTmyiw8IOLN6/WD/maufKkjuWsHPqTno162W2vhqixvaNebn/y5x6+BTzbpiHg7WD/tq64+sInh/Mc78+R3ZB9c2WWjlZEbIpBPtA7efIeMHIkTuOUJBSUOF11gYDy4KDsStZ2nwgO5vXTp+2+Hgvx93dnfHjx+vthQsX1thYhBCivqorAe8IYJeiKF8ripKsKMpBRVEeVCxdsFEIIeqA1atXU1ioLd/t2bMnwcHBFu/zv4mq3r9Mzd2MvzPKJBZq/mRzmgwtPzC+WnlFeczZOoc71txBfFa8fnxE8AiOzz7O1C5TLV7XtyFp4tiE/7vl/zjx4AnGdzQFafnF+bz252sEzw/m2/Bvq208tl62hHwfgpWLtpoh/3Q+x0Ydu2K5onZOTrweaFpO//qZMzW6tLl08qqvv/6ac+euvDxbCCFE5Sl1Yb+Ioih5JU/fB74BQoGPgadUVZ1fzvn3A/cDeHt7d1uzZk11DfWaZGdn4+zsXNPDEKXI96R2ku9L+WbMmKHX8XzkkUcYPny4RfvLACYCF0OEqcCk8k7MAqZj2nzSAfgAsC7v5KtzNucs/wv7H5HZpllmNxs3Hm79MH09+jb4QLc6/q0czTjK/JPzOZF1oszxPh59eCjoITzsPCzav+4f4Fng4tuZIcATaJugLqMYeBg4VtJuh/amwpIbASr6nsycOZPw8HAA7r///jKzvsJy5HdK7STfl9qnLnxP+vfvv09V1e7lvVZXAt4CYK+qqr1LHXsdGKmqaruKru3evbu6d+9eSw+xSn7//Xf69etX08MQpcj3pHaS78uljh07RseOHQGwtbUlMTERNzfLJmV6KDKSj+O0zLhNgZN9+mBfzp7h43cfJ3mVFu1au1vT/UB37FtUfSnzqiOrmLF5RpkltCOCR7DkjiW4O7hX+f71QXX9WzGqRlYcWsHcn+eSfMGUVsPVzpW3Br7F9K7Tq6W28Zm3zhA9z7SSIOiDIJo93KzCa8IuXCB0714KSt4HfRAUxMPNKr6mKir6nixfvlzfitCyZUuioqKqZR9+Qye/U2on+b7UPnXhe6IoymUD3rqypDkBOP6fY2FAi3LOFUKIBmPFihX68+HDh1s82I3IyWFRvGn58EwoN9hN/iZZD3YB2i5pW+VgN78on/u+v4+7N9ytB7u2VrZ8PPhjNozdIMFuDTAoBu4JvYew2WFMDZ2qH8/Iz2DG5hn0X9afU2mnLD6O5k82x3uSt96OeiyK1J9SK7hCW9r8XKmszc9ERxOTm2uxMVZk7NixuLtrP78xMTFs27btClcIIYSorLoS8O4E2v7nWBug5jJNCCFEDTMajaxatUpvT5pU7sJis5p78iRFJTNifV1duaGcc/Lj84mYGaG3fab44DnCs0r9plxIYcDyAXx+4HP9WJB7EP9O+5cHezzY4Jcw1zR3B3eWDF/Cr5N/Jcg9SD++4/QOOn3SiS8OfGHRkjuKotDmsza49CzJ3GyE4+OPk3c6r8Lr5rVoQUcnJwByjEZmRETUSGkge3t7pk2bprcXLFhQ7WMQQoj6qq4EvO8DvRRFeVZRlCBFUcYADwHyG0EI0WD9+eefxMbGAlq210GDBlm0v9/T0vju/Hm9/W6rVpdsk1RVlRPTT1CUWgSAnb8dQR8EURVHk4/S4/Me7IzdqR+bEDKB/ffvp4tvlyrdW5hX/4D+HH7gME/f+DRWijbzn12QzdTvpzJ67WjO5VguIZOVvRUdN3bEtqktAEWpRRwbfYzivOLLXmNrMPB527b6z/FPaWl8lZRksTFW5IEHHtA/uNm2bRunTll+ZlwIIRqCOhHwqqq6By1T81jgKPAa8Dwg+fuFEA3WypUr9edjx47F1tbWYn0ZVZXHT5rq207y9qZ7o0aXnBf/aTypP5QsJVWg3bJ2WDe69ixVWyK2cP2S6/VarwoK7976Ll+N/AoXO5eKLxY1wsHGgdcHvM4/0/6hTZM2+vENYRsIWRTCtijLLde187Wjw9oOKNZa4Ji1N4uoR6IqvKZno0Y85Oentx+JiiK5oOLyRpYQGBjIbbfdBmgfHC1ZsqTaxyCEEPVRnQh4AVRV3aKqamdVVe1VVW2jqupHal3IuCWEEBaQn5/P2rVr9fbEiRMt2t9XSUnsLyndYm8w8FpAwCXn5ETlcPJxU1Dc7NFmNL6p8TX3+f4/7zNs9TB9v66zrTPfj/+ex65/TJYw1wHX+V3H/vv3M7P7TP1YYnYig1cOZu72uRQZiyzSr2tvV1q9ayqTlfBpAonLEiu85tWAAPzt7ABILSrikaiKg2RLuf/++/XnS5Ys0cuNCSGEuHZ1JuAVQghh8sMPP5Ceng5oWV179+59hSuuXU5xMc9EmzLgPt6sGc3tyyagUotVwieHY8zRaqA6dnAk4LVLg+LKUFWVp35+isd+egy1pNaMv6s/f0/9m9vb3H6NX4WoCU62TiwcupDN4zfj5eSlH3/777cZsHwACVkJFunXb44fXuNM/UU8EEH2ocvX2nW2tubTtqZUIauTk/k5teKkV5YwdOhQfH19AUhMTGTz5s3VPgYhhKhvJOAVQog6qPRy5gkTJlh0xvO92FjiSpZ4etvYMK/FpQny4+bHkflPJgCKtUK7Fe2wsr/6sirFxmJmbpnJmzvf1I/1bt6b3fftJsQ75Bq/AlHThrYZytGZRxkcNFg/tuP0Drp82oXfTv1m9v4URaHN4jY4tncEwJhn5OiooxSmX37GdJC7O+O9TEHy7MhI8o1Gs4+tIjY2Nkydasp2/dlnn1Vr/0IIUR9JwCuEEHVMRkYGmzZt0tt33323xfpKKSjgzZLEWAD/CwjAxbrsnty803lEP2uaAfZ/3h+XLle/v7awuJCJGyfy6b5P9WPD2w7nl8m/lJkdFHWTp5Mnmyds5tX+r+q1eZMuJHHLilt44883MKrmDS6tna3psL4DVs7aBy95J/M4MeVEhVmY323VikYlZbYicnN5+8wZs46pMqZPn65/gPXjjz8SExNT7WMQQoj6RAJeIYSoYzZs2EB+fj4AoaGhtG/f3mJ9vXHmDNnFWpbbDo6OTPXxKXuCChEzIzBeMC1lbvHU1ZdIzynMYcTXI1hzdI1+bGKniawdsxZ766rV7xW1h0Ex8GzfZ/lp4k94OmqlqoyqkWd+fYaxa8dyoeCCWftzCnai7Rempcrnvj1H/KL4y57va2fHq6X2p7925gzR1Vybt2XLlnrGdVVV+fzzz69whRBCiIpIwCuEEHVM6eXMlpzdjc3LY2FcnN5+LTAQa8N/fm38SpmszG0Xt8Vge3W/Wi4UXGDIyiFsjdyqH5t93WyWjViGjZXNNY9f1F4DAgdwYMYBbmhuquS8Pmw9fb7ow9nMs2bty2u0F35zTFmYox6LIvvw5ffzzvLzo4uzMwB5RiNzIiOrvTZv6eRVS5culeRVQghRBRLwCiFEHRIfH8+vv/4KaPsUx48fb7G+Xjl9mvySN/o9XFy4o0mTMq8Xni+E+aa232w/XK93vao+8oryGL5mOH+c/kM/9myfZ/l48Mf6sldRP/k18uO3e35jTo85+rEDiQe4bvF17Dq7y6x9Bb4ViFNnJwDUfJXj445TfKH8+rxWisInbdrotXm3pqby7TnL1Q8uz+23345PyWqKhIQEtmzZUq39CyFEfSLvJoQQog5Zs2aNPtvUr18//ErVDzWnyJwcliaYMui+Hhh4SWKsqMejQEsUjV0zOwJev7qszAXFBYz+ZjS/nPpFP/bWLW/x6s2vStmhBsLGyoaPBn/EJ0M/wdqg7Q1PzE7kpi9vYvWR1Wbrx8reivZr2mNw1N725ITlVFift0ejRsxo2lRvPxQVRXaRZcoolcfGxoZp06bpbUleJYQQ104CXiGEqEO++uor/bkla+++GBPDxfmvmxs3ZoCbW5nXU7enkrQsSW+3XtQaa5eyyawqUmQsYsL6CWyJNM1cvXbzazx5w5NVGreom2Z0n8FPE3/CzV77OcsvzmfChgm88scrZltO7BTsROuPW+vthM8TSP46+bLnvx4QgKeNtqT+bH4+/zt92izjqKxp06bpH/xs27ZNklcJIcQ1koBXCCHqiPDwcA4cOACAnZ0do0aNskg/h7KzWZ1sCgReCyg7c1ucW0zEAxF623OsJx63e1T6/kbVyJTvprA+bL1+7Nk+z/JMn2eqMGpR1/UP6M/u+3YT7BGsH3vh9xeYvXU2xcbylx9fLZ8pPmXq8564/wS5p8pPSuVmY8PbrVrp7ffPnuVETo5ZxlEZAQEB3HrrrYCWvGrJkiXV1rcQQtQnEvAKIUQdsWaNKYPx0KFDcXW9uv2ylfX8qVP68zuaNKHXf/qJfTuWvOg8reEMQR8GVfreqqoyc/NMvjpsmql+tNejvNL/laoNWtQLQe5B/DPtHwYEDNCPLdq7iLHrxpJXlFfl+yuKQptP2mAfoGX+Ls4sJuzuMNTi8meRJ3t7c0OjRgAUqSqPRl1+GbQllE5etWTJEoqqcVm1EELUFxLwCiFEHaCqKl9//bXeHjdunEX6+Scjg03nzwOgAK/8Z3Y3NyaXM2+Uqk16H9j52FX6/q/ueJXP9pv2I87oNoN3b31X9uwKXWP7xmy9eyvjO5oSsm0I28CgrwaRnpde5ftbu1rTfk17FGvtZy7zn0zOvFV+vV1FUfiodWs9gdUPqalsKfn3UR2GDRtWJnnV5s2bq61vIYSoLyTgFUKIOuDIkSOEh4cD4OTkxNChQy3Sz3OlZnfHe3nRqaQ8y0UnHz+JMU+ruevc1RmuYhgrDq3ghd9f0NuTOk1i4dCFEuyKS9ha2fLVnV/xaK9H9WM7Tu+gzxd9iMuMq+DKymnUoxH+L/rr7ZgXY8g6mFXuuV1dXJjm66u3H42KosBorPIYKsPGxoapU6fqbUleJYQQV08CXiGEqANKL2ceNmwYjo6OZu/jz/R0fk3XZtCsgJdbtizzeupPqZzbYCrP0vrj1tqJlfDbqd+Y9r0p6+zAwIEsuWOJlB4Sl2VQDLw36D3eHvi2fuxo8lH6ftmX0+lVTyDV4qkWNOqlLVdWC1XCJ4VTnFf+XuHXAgJwtdJ+2CNzc/nwrHlrBVdk+vTp+vNt27ZxupqTZwkhRF0n7zSEEKKWq67lzK+UeiN9j48PQaWCamOBkciHIvW29z3euPau3B7i4ynHGfn1SAqNhQCEeIWwdsxabKxszDRyUZ890fsJVoxcoZctik6Lpu+uOP/cAAAgAElEQVSXfTmZerJK9zVYGwheHqyXKrpw9AIxz8eUe66XrS0vlfoA6JXTp0nMz69S/5UlyauEEKJqJOAVQohabt++fURHRwPQqFEjbrvtNrP38U9GBtvT0gDtF8PTLVqUef3sR2fJPaFls7VysSLw/wIrdd/E7ESGrBxCRn4GAL7OvmyZsAVXe8sk3BL108ROE9kwdgO2VrYAnMk4w01f3sSJcyeqdF/H1o60etuUiTn23VjS/yh/n/BsPz/alXwIlFVczNOllv9b2owZM/TnkrxKCCGujgS8QghRy5We3R0xYgR2dpVPElVZpWd37/b2LjO7mx+fz+mXTa+3fLllpRJV5RbmMmz1ME5naNc62TixZcIWmrs2N9/ARYMxrO0wvh/3PfbWWobluKw4bvryJo4lH6vSfZvObIrboJI60yqE3xtOUealAaWNwcAHQaaM5F8mJrI7M7NKfVfWsGHD8Pb2BiA+Pp4tW7Zc4QohhBAXScArhBC1mNFoLBPw3nXXXWbvY29mJj+kpgJaZuZn/f3LvB49L5ribG1vo2N7R/we9LviPVVVZeaWmeyN3wto+zG/GfMNXXy7mHfwokEZFDSIrRO24mTjBEDShST6LevHocRD13xPRVEIXhqMtZu2ZDovJo+ox8ovP3Sruzt3NGmitx+OikJVyy9pZE42NjZMmTJFb3/xxRcW71MIIeoLCXiFEKIW+/fff4mNjQXA3d2dW265xex9lJ7dHeflRdtSs7uZuzNJ+ipJb7f+uDUGmyv/6vhk7ycsO7RMb39424cMaT3ETCMWDVn/gP78OPFHXGxdADiXc45bVtzC8ZTj13xPu6Z2tFnURm8nLkkkdXtquee+FxSEbUlm8X8zM1mbknLN/V6N0tmaN2/eTGJiYrX0K4QQdZ0EvEIIUYuVnt298847sbW1Nev9D2Rl8X2purulZ3dVVeXkE6bEQB53euB2s9sV7/l37N88vO1hvX1v6L3Mvm62+QYtGrwbWtzAz5N/prF9Y6Ak6F1+C1Gp5c/MVobXXV54jvHU2yfuO0FR9qVLm1s5ODDHz7TK4anoaPKroUxR69at6dOnDwDFxcV89dVXFu9TCCHqAwl4hRCiliouLuabb77R25ZYzvxqqdndUZ6edHBy0tvnvz9Pxp9asinFWiHwzSsnqkrMTmT0N6P1jMxdfbuycIjU2hXm18OvR5mZ3oTsBAYsH1ClkkWtP26NdRNtaXP+6XxOPV1+Yqpn/f1xt9bOO5WXx/y4qtcGrozSs7xLly6tluXUQghR10nAK4QQtdSff/6pL1v09PSkX79+Zr3/kexsNpwz1dV9rtTsrrHQyMl5ptndprOa4hhUce3fwuJCxqwdQ0J2AgBNHJqwYewGHGwczDpuIS7q4deDLRO24GCt/YydyTjDgOUDiM+Kv6b72Xrb0vrD1no7bn4c6X9emrXZzcaGF0qVKXr19GnOFxZeU59XY/To0Tg7OwMQFhbGrl27LN6nEELUdRLwCiFELVV6OfOYMWOwLplRMpfXSs3ujvDwoHPJG2mAhMUJpjJEjazwf97/kuv/64mfnuCvM38BWpKq1aNW49/4ytcJURV9/Pvw3bjv9JJFJ9NOMmD5AJIvJF/T/bwmeOE+1F1vn5h2guLc4kvOm9m0KUEOWqCdXlTEKzEx19Tf1XB2di6z0mPp0qUW71MIIeo6CXiFEKIWKioqYv369Xrb3MuZT+bmlkm2U3p2tyiziJiXYvS2/zP+2HpUvHd4Y9hGPtr9kd5+7ebXGNhqoPkGLEQFBrYayLox67A2aB8KhZ8LZ/DKwWTlZ131vRRFoc0nbbBqZAVAbmQuMS/GXHKercHAW4GmZf4L4uOJzMm5ti/gKpRe1rxmzRouXLhg8T6FEKIuk4BXCCFqoR07dpBSEpD6+vpy4403mvX+78bGcjHNziA3N7q5uOivnXnrDIUp2vJMu+Z2+D1UcRmis5lnmb5put4eGTySeTfMM+t4hbiSYW2HserOVRgU7a3N/oT9jPpmFAXFBVd9L/tm9rR6p5Xejn03lszdl9bcHeHhQR9XVwCKVJWnoqOvcfSVd/3119O2bVsAsrKyynwwJoQQ4lLmXR8nhBDCLNatW6c/HzVqFAaD+T6fTC4o4ItSJU3mtmihP887m8fZd8/q7YDXA7BysLrsvYrVYiZumEhqrlbCpYVrC5bcsaRuJqlKS4PoaO1x5gykpMD583DunPZIS4PcXMjPh4IC058GA9jYlH04O4Orq/Zo3Fj709MTfH3Bx0f709cXmjYFM2febsjGdBhDRn4G9226D4Dt0duZ+t1Ulo9crgfCleU73Zfkr5NJ/yUdjNrS5m77u5Upy6UoCu+0akXP/fsB2HDuHH+mp9OncWPzfVH/oSgKU6dOZd487UOlpUuXMnnyZIv1J4QQdZ0EvEIIUcsUFxezYcMGvT169Giz3v/juDjySsqodHdxoX+pN+cxz8dgzNNec+7qjPcE7wrvtfrMav44/Qeg7dv9auRXuDlcuXRRjcrIgIMH4cAB7XH0qBbkpl+anMjiDAZo1gwCAyEgQPszKAjat4c2bcDevvrHVMdN7zqdhKwEXvj9BQBWHlmJr7Mvb9/69lXdR1EU2i5uy56OezDmGLlw9AJn3z9Li7ktypzXo1Ejxnt5sTpZ2zP85MmT/NO1q0U/9Jk0aRLPPPMMxcXF/PHHH0RFRREUFGSx/oQQoi6TgFcIIWqZnTt3kpSUBIC3t7dZlzNnFxWxoFQJlbnNm+tvzC+EXSBxuWnmt9XbrVAMl3/T/u/Zf/ki5gu9/Vyf5+jj38dsYzWb2Fj49Vf45RfYuVMLbmsLo1GbTT5zBn7/vexrBgO0aqUFvx07Qteu0L07NG8OdXEGvRo91/c54rPi+WTfJwC88887+Lr48tj1j13VfRwCHGj5ckuin9R+ZmJeisFzrCcOLctmHn8jMJD1KSkUqCq7srL49tw5Rnp6lnNH8/D19WXIkCFs2rQJgC+//JJXX33VYv0JIURdJgGvEELUMqWXM995551YWV1+SfHV+jwhgbSiIgBa2dtzZ6k35TEvxnBxY6/bIDfcbr78TG1GXgYT1k/AWHJB7+a9ef6m5802zirJy4OffoKtW7UgNyqqctc5OGgzrIGB0LIleHuDhwc0aaL96e4Ojo5gZ6c9bG21h9EIhYXao6hIW+aclaXNJGdkaDPH6emQnAwJCZc+LldL1WiEyEjt8d13puMeHlrg262b9ujeXZslliBYpygK84fMJ/FCIt+GfwvA4z89TlOXpozrOO6q7tXs4WYkrUjiwuELGHONRM6OJGRzSJkZXH97e2b7+fH+WW07wLOnTjGsSROszbgV4b+mTp1aJuB9+eWXzfp/hRBC1BcS8AohRC1iNBrLJKEx53LmQqOR986a9uc+0bw5ViVv2rMOZpGy1pS1OeDVgArvNXvrbE6lnwLA1c6VlXeu1DPk1oiLQe7atfD995B5aYIhnbU1dOgAXbpos6ahodryYS+v6g8a8/Ph9Gk4dUqbeT55EiIi4PhxrV1eMHzuHGzbpj0u8vODvn1Nj8sF0Q2IlcGKVXeu4tavbtXLZd377b34u/pzffPrK30fg42BNp+24UDvA6BC6tZUUtan4DXaq8x5z7RowecJCWQVFxOWk8PypCSm+vqa9WsqbejQoXh5eZGcnExcXBzbt2/ntttus1h/QghRV5nt3YmiKEMARVXVLea6pxBCNDT//vsv8fHxAHh4eNC3b1+z3XtNcjKx+fkAeNnYcI+Pj/5azAsx+nOPER406t7osvfZELaBlUdW6u1Pb/+Ulo1bmm2cV2XvXli0CNatu3yQa28PN94IAwZA//5agGtnV73jvBw7Oy3YbtPm0tdyc+HECTh2DA4d0r7WffvK/zrj4mD1au0B9HZ11b7eiwFw587aEukGxsHGge/Hfc8NS28g7FwY+cX5jPh6BLum77qqn1nXXq40faAp8Yu0f5tRD0XhPtAda1fT2ygPW1uebN6cF0rq8b4YE8N4Ly8cLDTramNjw6RJk3j33XcBLXmVBLxCCHEps/z2UxRlIfAg8GFJu4OiKHeY495CCNGQlF7OPHLkSKytzfO5pKqqvBUbq7cfatZMfyOeuSuT85vOay8o0PJ/LS97n/M555m5ZabevtX7Vu7qaN4awVeUmwtffgk9esB118HSpZcGgYGBMG8e/Pabtpx4+3Z46ino2bP2BLtX4uCgBed33w1vvaXtQ05L02aAV6+Gxx+Hfv20jND/YZuRARs2wCOPaLPYvr4webJ23fnz1f+11CA3Bzc2T9iMh6MHAMkXkhm2ehiZ+RWsAihHwOsB2PpoGbULEgo49dypS855tFkzvG1sADibn8/Ckg+vLGXKlCn682+//ZZz585ZtD8hhKiLzPVx702qqg4BLlZ4jwSeMdO9hRCiQVBVtUzAa87lzD+kpnL0wgUAnAwGZjVtqr926nnTG3evu7xwDrk0gLro4W0Pk3xBy0bb1KUpc4LmmG2MV5SSogWtfn4wZQrs2VP29cBA7fV9+7R9u//3f1pAWFcC3MowGKB1axg3Dt55Rwvo09K0r/m992DECG2v8X8lJ8OKFTBhgrZ0u3dveOUVbdbYaLz0/Hom0C2QjXdtxNZKC1iPJh9l3LpxFBmLKn0Pm8Y2BH1gyoQctyCOzD1lg2Zna2ueb9lSb79++jQZRZXv42p16NCBnj17AlBYWMiqVass1pcQQtRV5gp400o3VFUtAKSwoBBCXIU9e/YQWzIL6+bmRv/+/c1273dKze7e37QpbiWzUOl/pJO2veS/cAO0fKnlZe/x/YnvL1nK7Gx9+eDYbFJStNnali3hzTe1AO8iW1uYNAn+/lsLct94Q5vRbEgJnKytta/50Udh40ZISWH30qWwYAGMHasluSrNaIR//oEXXtBmyJs2hVmztBlkCwZnNe3GFjeyeNhivf1D1A888dMTV3UPz7GeuA0qSeamQsQDEajFZfdL3+frS2BJOanUoiLePnOmagO/gqlTp+rPlyxZgir7t4UQogxzBbwHFEUZDKgAiqI4AS5murcQQjQIpWd3R4wYgU1JUFpVh7Kz+a2kxqwV8EizZoA2o1x6dtdnsg+ObR3LvUdabhoPbH5Ab0/qNInb29xulvFd1rlz2oxtQIC2pDcnx/RaQIAW/J49C8uXw/XXN6wgtyIGAzkBAVoQ+/XXkJQEu3fDSy9pS7r/+/eUlKTtgx4wQAt+Z8zQloAXFtbI8C1pcufJPHOjaQHah7s+5NO9n1b6ekVRaLOwDQZ77e1T9v5sEpYklDnH1mDglQBT0rf3z54loWTvvCXcddddODhoZZIOHz7MgQMHLNaXEELURZUKeBVF2aQoSosKTnkamAUEKIryDrATkORVQghRSZZczvxhqczMoz09aVEy+5S2PY2MPzMAUGwU/F/0v+w9Hv3xURKytTf2Ps4+fHDbB2Yb3yWKiuCjjyAoSAtqS5ZiAxASomVijoyEuXPBgrVO6w2DQZvJffFF+PdfbXnzypUwceKls78pKfDZZ3Drrdq+3+nT4eefobi4ZsZuAa/c/Aqj2o3S23N+mMPfsX9X+nqHQAdaPGV6SxT9dDSF58t+ODDOy4vQkr3VOUYjr54+XcVRX56rq2uZ/y+WLl1qsb6EEKIuquwM71DA53IvqqqararqMGA4EA+8Djxa9eEJIUTDcODAAU6dKinz4+rKgAEDzHLf5IICViYl6e0ys7svmGZ3faf74tDSodx7bInYwrJDy/T2oqGLcHcoZ5+oOezYoS3PffhhrYbtRSEhWibmgwdh9GiQeqPXzsND28u7YgUkJsLvv8ODD2oBbmnnz8OSJTBwIPj7a7Ptx47VyJDNyaAYWD5yOV18ugBQaCxk9DejSchKuMKVJs3nNse+pfbBUVFqUZmVElofCm+UmuVdnJBAohnGfjmlk1etXr2afAvOKAshRF1j1hoFqqruUFX1PVVVv1FlE4kQQlRa6dndO+64AzszJVr6JD6egpL/jnu6uNDL1RWAtF/SyNql5RlU7BT8ny1/djcrP4sHtpiWMo/vOJ4RwSPMMrYyEhK0GcebboIjR0zHW7c2BbqjRjXI0joWZWWl/Z1//LG2PPzPP7UPG/z8yp4XF6fNtnfsCN27w/z5WvbrOsrRxpGNd22kiUMTABKyExizdgwFxQWVut7KwapMAqv4T+LJ2p9V5pxB7u7cWPLvrVBVWWGmsZfnpptuokULbdY5NTWVrVu3WrA3IYSoW+SdgxBC1DBVVVm/fr3eHjVqVAVnV16+0cjCuDi9fXF2F+D0q6Yllr7TfLHzKz/AfvmPlzmbqS2J9nT05KPBH5llbGWsWgXt2mnLbC9ydNQSUB05IoFudTEYtHrFH3wAZ85oia0efvjSZeP79sGcOdp+3ylTtPPq4Gfc/o39WTN6DQZF+9naGbuTx358rNLXN7mjCe63lax0UCHywUhUo+nvQVEUXimVsXkbEFV6H7oZGQwGJk2apLeXL19ukX6EEKIuupp3EP0VRQlWFMkKIoQQ5hQWFkZERAQATk5ODBo0yCz3XZOcTFJJ4iE/W1tGlQQu6X+mk/FHyd5da4UWc8tP0XAk6Qgf/Gvaq/v+oPf1WqZmkZYG48drdWZLL18eOxbCw7UltPWppFBdYjBAr15a8BsXB5s2wZgxZb8fF+sh9+4NnTtria+ys2tsyNfilsBbeGPAG3p7wZ4FLDu4rIIrTBRFIejDIBQb7W1R5j+ZJK1IKnNOPzc3bm7cGAAj8LIF9/JOnjxZf75lyxapySuEECWuJuB9HTgGZCuKsktRlM8URZmlKMoNiqJUQ10KIYSonzZu3Kg/Hzx4MPYlSaWqQlVVPiiVrOpBPz9sSmZJT79metPtPdkbe/9L+zOqRmZumUmxqiUr6teyHxNCJlR5XLpffoFOnWDNGtOxwEAtQdLXX0Pz5ubrS1SNjQ3cfjt884229HzhQggNLXvOkSNaVuhmzeDJJ8GCgZ25Pdn7SUa3NyV9emDLA+yL31epax3bONL8cdPP6sm5JynKKFvaqXTG5pVJSYSVTsJmRm3atKFXr16AVpN3Tel/W0II0YBdTcD7EPAwsLrkuonAfGAHkKEoSpSiKOsURXnO/MMUQoj6q3TAO3LkSLPcc0dGBgdLZtscDAbub9oUgMw9maT9aKq7WzrbbGnLDy1nZ+xOAKwN1iwcshCzLPApKIDHH4dbbtH2jF40daq2T9dMybqEhbi5wcyZsH8/7NoF06Zpy88vysiAd97RPrwYPRr++qvmxlpJiqKw9I6ltPdsD0BeUR6j144mPa9ye5RbPNsCWz9bAAqTC4l5KabM671dXRnsri19VoGXYsq+bk6lZ3llWbMQQmiuJuDdo6rqfFVVp6uqeh3gDHQEJgHvACeBG4GXzT9MIYSon86cOcO+fdpsko2NDUOHDjXLfUvP7t7j44N7SU3f0rO7XuO8cGx9ad3d1NxUntz+pN5+4vonaOfZruqDio+Hm2+G994zHfPwgI0btWzALlK+vc5QFOjRAz7/XPu+fvyxlmDsIqMR1q+HPn20x9attXqfr4udC9/e9S2N7BoBEJMew7Tvp1GZ/JvWztYEvWtKYBU3P46cE2X36v6v1F7eb1JSOGShpd933XUXtrZa8L1nzx7CwsIs0o8QQtQl15wFRFVVo6qqx1VVXaWq6jxVVQepquoDNDXj+IQQol779ttv9ec333wzriVZXasiOjeX70rt33uoJONu9uFszn93Xj/u/0z5mZmf+eUZzuVo17dwbcFzfc2wcGfnTq3c0M6dpmODB2tLYUdYIOuzqD6urlpZo/Bw2LxZm70v7a+/YOhQ6NJFW65eS2v6tm7SmqV3mGrYbgjbwII9Cyp1redYT1z7av921SKVk0+eLPN690aNuKFU+8VTZcsYmYu7uzvDhg3T2zLLK4QQFsjSrKpq0pXPEkIIAWWXM48wU+A3Py6Oi/NSt7m7087JCYDTr5tmdz3u9MCpg9Ml1+46u4vP9n2mtz+67SOcbC8976osX67N7F6sB2wwaCVutmwBn8uWeBd1jcGgBbbbt2sfZEydqu3/vejQIRg3zpSRuxYGvqPaj2L2dbP19uM/PV6p/byKohD0XhCUrPo/v+k8qT+nljlnSqnn350/z97MTHMM+RKllzWvWLGC4lr49yyEENWpsgFvO+CEJQcihBANzblz59ixYwegvWEePnx4le+ZU1zMF4mJevvi7G7OiRxSvknRj5dXd9eoGpm9dTZqSbh8e5vbuaPtHdc+GKMRnnkG7rlH27sL2hLm7dth7lxtWayonzp21JapR0fDI4+U3ecbGanVXO7cGTZsqHVLnd+59R26+HQBoKC4gLHrxpKRl3GFq8Clmws+95g+wDn52EnUYtPX1goYW6rE04sW2ss7ePBgPDy0bOpxcXH89ttvFulHCCHqikoFvKqqnlBV9cr/2wshhKi0TZs2YTQaAejVqxe+vr5Vvufq5GTSi7Qssa3s7RlUkiznzP+d4eK0r/sQd1y6Xrpfdvmh5exL0Gaz7K3t+ei2j649UVVBAUyerNXSvahjR9izR5vtFQ1Ds2bw/vta1ubnn4eSEj0AHDum1Vju3h1++KHWBL721vZ8M+YbXGy1fyPRadFM3zS9Uvt5A14LwOCkvbW6cOQCCUsSyrz+UsuWFyeB2ZqaapFZXhsbGyZMMGVUl2XNQoiGzuxLmoUQQlSOubMzq6rKgrg4vT3Tzw+DopAfl0/SStNuk/Jmd7MLsnnml2f09pO9nyTALeCS8yolK0srY7NypenY0KHw999QKnmPaEA8POB//4NTp7TA17lUNcP9+2HIEBg4UFv2XAsEuQexeNhivb3u+DoW7V10xevsmtqVyXx+6rlTZcoUtXNy4i4vL739PwuVbyq9rHn9+vVkZWVZpB8hhKgLJOAVQogakJ2dzU8//aS3zRHw7srM5EBJ9ld7g4EpJftjz354FrVQm51qdEMjXHtfmhjr7Z1vk5CtzUb5Ovsy94a51zaItDQtadH27aZjM2bAd99JFmahzfBeDHyffBIcHEyv/fKLlthq2jSt3m8Nu6vjXTzQ7QG9/fhPj3M85fgVr2v+eHPsmtsBUJhSWGbvPMBz/v76LO+m8+fZb4FgtGvXrnTo0AGAnJwcNmzYYPY+hBCirpCAVwghasC2bdvIz88HoGPHjgQFBV3hiitbEB+vPx/v5YW7jQ1FmUXEf2o63uLJS+vuns08y9t/v623X7v5NZxtnS8574pSUrTlyrt3m47973+waBFYWV39/UT95eEBb70FJ09qdX0v/nyoKixdqpU4euUVyM2t0WG+f9v7hHiFAFp93rs33E1+UX6F11g5WBH4ZqDePvvBWXKjTV9HBycnRpfay/uKBWZ5FUWRmrxCCFFCAl4hhKgBpcsRmWN2N6WggG+Sk/X27JJkVQmLEyjO1LK0OrR1oMmwJpdc+/QvT5NbpL0h/3/27js8iqoL4PBvN9l0kpCeEAIIiChNUaogRRREegdFBbHQFBAbFgTEAgIWEJUmotJBsCEfSpEmAiK9CiGFJJCQkN72++NuZnZJAtkkQALnfZ487p2dmZ2QZJ2z99xz7g66mycaPGH/BcTGQqtW8M8/+raZM1X6qhSnEoUJDoZZs+Dff1Vac56UFHjrLbXu+5dfbtjluTi68F2P73B2UDO2/5z7hzf/ePOqxwX0DcCzierpa840c+qVUzbPv1lFX1aw+vz5a9KXd8CAARiN6jbvjz/+IDw8vNRfQwghygMJeIUQ4jrLzMzkxx9/1MalEfDOjY4m01JUp1GFCjSsUIHcrFwiZkRo+1QeUxmD0Tb43BW5i0X/LtLG0x6ehtFg5/8azp+Htm3hkCXd02iE+fNh6NDifTPi1nPnnapN1bp1KsjNc+qUCoR79oSzZ2/IpdUJqMOH7T7UxlO3TeWP/65c+dhgMFB9enVtHLc8Dqyyoet6eNDdUkkZYMI1qNhcqVIlHrT0RDabzSxatOgqRwghxM1JAl4hhLjONm7cSGKiKnxfpUoVGjRoUKLz5ZjNzLZKZ86b3Y1dHEtGhEq/NAWaCHw80OY4s9nMqHWjtHHXO7rSqmoru17bMSlJrdk9cEBtMBph0SJ48kn7vxEhHnpIZQl8/rltRecVK1T/3qlTITu78OOvkRGNRvBw9YcBMGNm4OqBJKQlXPEYryZe+PfWU5f5AptKz29ZFXBbef48+6/BLO/lac1FqTQthBA3Gwl4hRDiOru8OnOxW/9Y/HzhAmcs64F9HR3p7e+P2Wzm7BR9Rix0RCgOLrbraJcfWs7Ws1sBMBlNfPjgh9glLY26r7+uV9Y1GGDhQujXr/jfjBAODvDcc3D0qOrhnCclRRW6atIE9u+/rpdkMBiY32U+fm5qVjYiKYLnfnruqgFktXerYXC0/H3/Cxd+vKA9V9/Dg65Ws7zXYi1v165d8bBUxD569Ch/Wa+vF0KIW4QEvEIIcR3l5ubyww8/aOPSSGe2bkU0ODgYFwcHEn5LIGV/CgBGdyMhz4fYHJOVk8VrG17TxsMbDaemb82iv2h2NvTrh9fBg2psMKg05gEDiv+NCGEtIAAWLIBNm8BScRiA3buhYUOYNAmysq7b5QRXCGZOpznaeOnBpTbLAQriVsPN5m/v1CunyM3O1cbWa3mXx8VxMCWlFK8Y3N3d6dWrlzaW4lVCiFuRBLxCCHEd7dy5k2hLyxV/f3+aN29eovOdSE1lXYJKrTQAz4Wom+vwKXqBmuDBwZh8TDbHzd07l5MJJwGo6FKRN1tevRCPxmyG4cNVq6E806fbzsYJUVpatoS9e+G998BZFY8iK0sVRGvSRBW8uk663NGFIfcM0cYjfhlBRFLEFY6AKm9WwaGCyq5IPZzKuQXntOfuqVCBTr6qkA5ZCnsAACAASURBVJwZmHwNZnmt05oXL15MZmZmqb+GEEKUZRLwCiHEdWSdzty5c2ccStiu50urfqWP+PhQzdWVS3sucXHDRbXRAUJHhdock5aVxoRNE7TxK81foaJrxaK/6Lvvwhdf6OOxY+GFF4p1/UIUickEr76qAt/GjfXte/bAvffC++9Dbm7hx5ei6Q9Pp4aPaiOWmJHIkLVDrpja7OTvRNgrejuw02+dJiclRxtbz/Iujo3lVCm3YmrZsiVhYer14+Pj+fXXX0v1/EIIUdZJwCuEENeJ2WzOt363JDJzc1lwTp8tetYyuxsxXZ9xCugVgGtVV5vjPvvrM6KTVaAc7BHMiMYjiv6i8+apmTWLmAcfVMGGENdD7dqwdavq4Ws92/vaa9CuHVgVb7tW3J3cmd9lPgbU2txfT/zK/H/mX/GY0BdDwdIRLDM606Z6+n2enjxYUX3glAt8WMrtg4xGI/2s1tV/++23pXp+IYQo6yTgFUKI6+TgwYOcOHECAA8PD9q2bVui8/1w/jxxljWMoc7OdPDxISM6g9glej/e0DG2s7uJ6Ym8v1UPUN9s+SZuJreiveBvv8Ezz+jjBx/kyMsvq8rMQlwvDg4qq+Cff2xne3//HerVg7Vrr/kl3B92Py82eVEbj1o3irOJhbdNcnB3gKf0cfgH4WTG6anFr4fpM8Dzz50j2lKErrQMsFpbv2bNGpKSkkr1/EIIUZbJXYoQQlwn1rO7jzzyCC4uLiU6n3U68+CgIByNRqJmR2HOUumVns088bzX0+aYj7Z/RHxaPADVvKsx+J7BRXuxkyehTx/IsaRiNmgAK1ZgNpmufJwQ18odd8CWLTBunCqaBnDhAnTurNaYl3Jq8OUmtZlETR9V6C0pI4mn1z595arN7cHtTvXhUs6lHM5M1NfrtvL2pnGFCgBkms1Mi7jyumB71a1bl7p16wKQnp5u814khBA3Owl4hRDiOinNdOaTaWn8z1KsyggMCg4mNyOXqNl6SmfoC7azu7EpsUzbPk0bT2g9AScHp6u/WEoKdOsGFy3rgitVgp9/Bk/PKx8nxLVmMqlqzb//rn4v88ycCc2bw3//XbOXdjO5saDrAi21+beTvzFnz5zCD3CA296/TRtGfRFF+pl0QLU9es1qLe/sqCgSSrkCtfUsr6Q1CyFuJRLwCiHEdRAeHs7evXsBMJlMPPLIIyU63xyr2d0OPj6EubgQuziWrFh1k+wc6oxfNz+bYyZvmUxKlmp7UiegDv3qFKFfrtkMgwfrfU+dnGDlSggOLtH1C1GqWrVS/aC7dtW37d2rClqtW3fNXrZZ5WaMbjpaG4/+bTRnLhZeadn3UV88m6kPisyZZk6/c1p7rpOvL3e5qRng5JwcPrNqN1YarNfxbtiwgXNW6/+FEOJmJgGvEEJcB9a9d9u0aYNnCWZHM3NzmWcV8D4TEoLZbCbiYz0NMmRYCEaT/hYfnhjO539/ro3fbfMuDsYiVIj+6CNYskQff/45NGpU7GsX4prx9VUfxsycqWZ+AeLjoUMHNQt8jao4T2w9kVq+tQBIzky+YtVmg8HAbZP1Wd5zX58j5YilX7bBwKtWa3k/joggJScn3zmKKywsjJYtWwKqH/gS679rIYS4iUnAK4QQ14F1wNvVehaqGNZeuECsJd0xxMmJR3x8SPwzkeS9yQAYXY2EDAmxOWbipolk5qgiOU1Cm9Dp9k5Xf6H16+GVV/Tx88/DoEElunYhrimDAYYOhU2bwFK1HLNZVRbv0kVPyy9FriZXFnRdgNGgbqnWn1rPon8XFbq/9wPeVHzI0gYsV7UpytM3IICqlrX9F7Kz+aqUq05LWrMQ4lYkAa8QQlxjCQkJbNy4URt37ty5ROf70uomeHBwMI5Go83sbuBjgZh89WJSpy+eZsG+Bdr43TbvYsgr8lOY06ehb199Vqx5c5gxo0TXLcR107Sp6tHbqpW+7ccf1faTJ0v95ZqENmFko5HaeNS6UcSlxBW6f7V3q2mP45bFcWnPJQAcjUZerlxZe27q2bNklOLMdM+ePTFZZr937drF8ePHS+3cQghRVknAK4QQ19jPP/9MjiU1sVGjRoSEhFzliML9l5bGekuxKgMq4E0/k875Vee1fSqNrGRzzPt/vk92bjYAD1R5gDbV2lz5RbKzYcAAlQ4KaqZs+XK1fleI8iIwUGUpvPSSvu3IEdXK6M8/S/3lJraZSBUvVXjqQtoFRq0bVei+nvd64tddX2P/3zi9uNZTQUEEWoLSyMxMFsXElNo1+vj42NQPkFleIcStQAJeIYS4xlavXq097tKlS4nONTc6mrzVge19fKji4kLkzEiwTAJ5t/XGo46Htn94Yjjz9s7Txm898NbVX2TSJNi2TT12cFDBblBQia5biBvC0RGmTIHvvwdnZ7XtwgVo2xYWFZ52XBweTh583lFfJ//t/m9Zd6LwglnVJlbT7sLif43n4maVbu3i4MBoq1neD8LDyblSuyM7XZ7WfMVWSkIIcROQgFcIIa6h9PR0fv31V21ckvW7Wbm5zLOqrPpMcDA5KTlEf6UXsLq8FdEHf35AVq5a79u8cnNaV2195RfZuhUmTtTHEyaoNFAhyrO+fWHjRggIUOPMTHj8cXj7bbXGt5R0qNnBpvr5cz89R0pmSoH7ut/pTuDjgdr4v3H/acHncyEheDs6AnA8LY0VcYWnR9vr0UcfpYKl5++JEyfYtWtXqZ1bCCHKIgl4hRDiGvr9999JTlbFpGrUqEHt2rWLfa5f4uOJzlSFp4KdnOjo60vMtzFkX1Tpyi7VXfDt6KvtH5kUyZy9el/Qtx5468prdy9eVKnMeWsGH3jAtmiVEOVZkyawcyfcdZe+bcIEGDgQSrHn7Yz2M/Bx9QHU+vm3/ig8q6Lq21UxmNTfZOKficT/opYReDo6Msxq6cN74eGlNhPr6upKjx49tLGkNQshbnblMuA1GAyvGwwGs8Fg+OxGX4sQQlzJ5dWZr1os6gqsWxE9ERSEo8Gg0pktKg2vhMGon//DrR/aVGZud1u7wk9uNqsqzGcsPUQrVoRvvlEpzULcLKpWVVkMDz2kb1u0SPXvTU0tlZcIcA9g2kPTtPGMnTP4O+rvAvd1reZK8DN6T+v/3tJneV8IDcXVqG7T/klO5te8NfWlwDqtefHixWRnZ5fauYUQoqwpdwGvwWBoAgwB/r3R1yKEEFeSm5vLmjVrtHFJ1u/GZGbyk9UN76CgIJK2JZHyr6WHp6uRoCf1dbbRl6L5cs+X2vitlleZ3f3mG1i8WB9/+SVYrSMU4qbh5QU//QTPPKNv+/lnaNcOLAXhSmpg/YE8eNuDAOSac3n2x2fJMRfcU7fKuCoYXdTtWPLuZC6svQCAv5MTQ4L1YPi98PBSuTaA1q1bE2w5d2xsLBs2bCi1cwshRFlTrgJeg8HgBXwLDAZK5/9KQghxjfz111+cs6y59ff3p2kJ1sIuiokh2zLzc7+XFzXd3Iicpc/uBg4IxOSttyKasm0K6dnpANwbci/ta7Qv/OSnTsGwYfp48GDo2bPY1ypEmefoCLNnwxtv6Nu2bYOWLaEUet8aDAZmd5yNi6Pqqbsneg9rotYUuK9zsDMhz+vpy6fHn9ZmeV+qXBlHywdVWxIT2ZmUVOJrA3BwcKBv377aWNKahRA3s3IV8AJfAsvNZvPvN/pChBDiaqyrM3fq1AmHYqYHm81mm3TmQUFBZMZmErdML2QTMky/YY5JjmH237O18RVnd81mGDIELOuMuf126bcrbg0GgyrQ9vHH+rYDB1TP6RMnSnz66j7Vef3+17Xx3P/mEpNccIuhsFfCMLpaZnn3JnP+B9VmrLKLC/3yCm0BH509W+LrymOd1rxq1SpSSymlWwghyppyE/AaDIYhQA3gzRt9LUIIURSXr98trr8uXeKQ5WbU3Wikl78/0XOjMWepWSDPpp5UaFBB23/6jumkZacBcHfQ3Tx6+6OFn3zuXPjd8hmi0ajWM3p4FL6/EDebkSPV772lKjKnT6uZ3qNHS3zqsc3HUtOnJgApOSmMXT+2wP2cAp0IGWo1y/v2acy56u97jNXSghVxcfyXllbi6wK45557qFWrFgDJyck2yy+EEOJmYigP/dcMBkMt4E+ghdlsPmLZthE4YDabhxew/zPAMwCBgYENF1uvSyuDkpOT8ZAbzDJFfiZlU3n6uYSHh/PEE08A4OLiwurVq3HO6wNqp2nAWsvj9sArOcAAIG+y6HXAUo8qOTuZvjv6kpKj1vZOuGsCLfxaFHhep7g4Gj31FI4pat/wPn049dxzdl1befqZ3Erk52I/nx07uGv8eBwyMgDI8PVl37RppIaFlei8u+J38fL+l7Xx9PrTaeDdIP+OCUB/IN0yHg88oB6OBfLKXnUHRpToinQLFy5k/vz5ADRt2pTJkyeX0pnLB/k7KZvk51L2lIefSevWrXebzeZ7C3quvAS8TwLzAeuKDw6AGcgF3M1mc0ZBx957773mv/8uuDpiWbFx40ZatWp1oy9DWJGfSdlUnn4uH374Ia9YWvp069aNlStXFus8qTk5BG/bRlKOevvb0qABd2zO5kCXAwCY/Ew0OdsEBxeVLv3Bnx/w6oZXAbjD7w4ODj2I0VBAMo/ZDF26wFpLKF2jBuzbB25udl1fefqZ3Erk51JMmzfDI4+A5UMggoJUBkQJ2okB9F7Wm2WHlgFwp/+d/PPsP5gcTPn2O/nKSc5+qNKW3eu4c+++ezEYDfwWH8/D/6pane5GI2ebNqWiKf/x9jp58iQ1atQAwNHRkXPnzuHr63uVo24e8ndSNsnPpewpDz8Tg8FQaMBbXlKaVwN1gQZWX38Diy2PM2/cpQkhRH7W6cwlqc68Mi5OC3ZrurrS3MvLplhV8NPBWrCbnp3O9B3TtedebvZywcEuwJIlerALKrXZzmBXiJtOy5bwyy/g7q7G585B69Zw6FCJTjvt4Wm4GFUBq0Nxh5ixo+B18pXHVsborv5mUw6kELdcrdNvV7EidS3XlJKbyxelUFgLoHr16jRp0gSA7OzsYn8wJ4QQZVm5CHjNZvNFs9l8wPoLSAHiLeOyP00thLhlxMTEsH37dgCMRiOPPnqFNbRXMd9S5RngqaAg0k6kkbDOUqTeAMHP6m1LFu5bSEyKynOuVKESA+oNoEDnz8MIq6TI559XN/pCCGjRAn79VV/LHhMDrVqpglbFFOoZylNVn9LG4zeN52xi/gJUTn5OhI4M1can3zmNOceMwWCwWcv7SWQkGbm5xb4ea9bVmsv6EjAhhCiOchHwCiFEebJ27VqtrUiLFi2KnSL4X1oav1+8CKg364FBQUTN1md2fDv64lrVFYCc3BymbJuiPTe66WicHJwKPvELL6igF1Sv3fffL9b1CXHTuv9+WLcOKliKwcXFqT69Jaje3L1Sd+oE1AEgNSuVMb+NKXC/ymMq41BBZW2kHkoldlksAP0CAghxUn/T0ZmZfB9TcMVne/Xq1Uur4v7HH38QbVURXgghbgblNuA1m82tCipYJYQQN5p1O6KSVGdeYDW7+7CPD0G5jpybr2+zruq68vBKTsSrm3FvF2+G3DOk4JP+9ht8950+nj0bPD2LfY1C3LSaNbMNes+dU0FvZOSVjyuEo9GRWY/M0sbLDi1j0+lN+fYz+ZqoNLKSNg5/Nxxzrhkno5GRofrs70cREZRGgltISAgPPKCqY5nNZpYvX17icwohRFlSbgNeIYQoi5KTk/nf//6njYu7fjfXbLYJeAcFBRG3NI7shGwAXG5zwedhH0DdpH6w9QNt3+H3DaeCcwXyyciwTWUeMEAV6BFCFKxpU/jpJ3BR6285fVoFvXkZEnZqUaUF/er008Yv/PoCObk5+farPMp2Le/5Ner1ngkOxt2oth9ISeG3hIRiXcflJK1ZCHEzk4BXCCFK0bp168iwtDWpV68e1apVK9Z5fk9IINxyHl9HRzr5+RH1pZ7OHPJsCAajSkPc8N8GdkfvBsDF0YURjQtpWjJ9Ohw7ph57ecFHHxXr2oS4pbRoAStW6H16Dx+G9u0hKalYp/uw3Ye4mVSBuH0x+5izZ06+fUy+JioNvWyW12ymosnE08H6uv2pZ/OvAy6OHj164OCg0qi3bdvGmTNnSuW8QghRFkjAK4QQpai0qjPPs5rdHRAYSNahVJK2qRtsg8lA0JNB2vPWs7uD7x5MgHtA/hNGRMDEifp4wgQIDCz29QlxS3nkEVi0CCxrXdm9Gzp3hrQ0u08V6hnKq81f1cbjfh9HQlr+mdrQ0aEYXdRt2qW/L5Hwm9rnxdBQ7ebtfwkJ/HPpkt3XcDk/Pz/atWunjZcuXVricwohRFkhAa8QQpSSrKwsfvzxR21c3IA3ISuLlXFx2nhQcDDRX+mFZPy6+uEUoIrX7I7azf9OqRRqB4MDY5oWXAiHMWMgNVU9rlsXhg4t1rUJccvq0we++EIfb9oEfftCTv6U5Kt5qdlLVPWuCsCFtAuM3zg+3z7OQc4ED9Fnc09PPI3ZbKaqqyu9/P217dMiIux+/YJIWrMQ4mYlAa8QQpSSP//8kwTLmrrQ0FDuueeeYp1ncWwsGZZiNPd4eFDHwZWYhXpF1uBn9JvgaTumaY9739WbahULSKHesAGsZ2w++0xPzxRCFN2QIfDhh/p4zRoYNQrsLB7lanJlarup2njmrpkcisvf67fy2MoYTGpWOWlrEombEwFsWhR9HxtLRHq6Xa9fkK5du+JkqQK9Z88ejh8/XuJzCiFEWSB3PEIIUUqsqzN36dJFa/Vhr3mX9d6NWx5H9kW9WFXFNhUBOJt4lqUH9UD2pWYv5T9ZVpZtoar+/W9oz92EBDh0SC0lDg9XXwkJajmk9ReAyaR/OTmpZcf+/uorIED9t3JluO029ZXXNlWIa2rsWIiNhamWgPXTT6FaNRX42qF77e60rtqaP07/QY45hxd/fZF1j62zed9wqexC0BNBRM9RGR5nJp3B+wFv7vP0pKWXF5sTE8k2m/kkMpIPq1cv0bfl5eVFhw4dtGUZS5Ys4Y033ijROYUQoiyQgFcIIUqB2Wy2Wb9b3HZEB5KT+duyJs/JYKB/YCBnvjygPR88JFgrVvXZX5+RnasC4VZVW3FPcAEzyp98oorsgIoIp0zJv881kpUFu3bB5s2wcyf89RdERV39uOIKCIDq1aFWLZW1Xbcu1KsnS5XFNfDBB3DmDCxbpsZjxkBYGPToUeRTGAwGZrSfwd1f3E2uOZf1p9az9thaOtfqbLNf2KthRM+LhlxI+F8CSTuT8GzsyUuVK7M5Uc34fhEVxRtVquBZwsyNvn37au9jixcvloBXCHFTkJRmIYQoBfv27dMqm3p5eWl9Le0132p2t6ufH87HM0n8U93UGhz1YlXJmcl8sVtfTzi6yej8J4uJgXfe0cfjx0NISP79SlFCAnz9NXTtCr6+0Lw5vPYarF59bYNdUJNu27fDggUq/njoIQgKUoHwQw/BG2+oDFSrf2IhisdohIUL1S84qJTmxx5Tv4B2qBdYj+caPqeNx64fS1ZOls0+rtVdCeyvf2pz5l31PtPR15darq4AJOXk2LQxK65OnTrh5qYqSB88eJADBw5c5QghhCj7ZIZXCCFKgfXsbseOHTGZTHafIys3l0Ux+lrdp4KCiJ6kF6vy7eKLc5AzAPP3zicxQwXCNX1q0vH2jvlPOH485FVwrV0bRo60+5qKdN1Z8PPPMHcu/PILZGcXvq+zs7qUO+6AqlXVpJi/P3h66l8VKqhiuFlZ+ldmpgqm4+L0r5gYNcl28qRqj5qVVfBrxsXB+vXqK0/lytC4seo406KFmgm2dGURomhcXOCHH1Sv3uPHIT1dVW7evh1q1CjyaSa0nsC3+78lMSORYxeO8cXuLxjeaLjNPmGvhRHzbQyY4cLaC1z65xIVGlTgxdBQnrestf00MpLhlSphLOZSCgB3d3c6derEkiVLADXLO2nSpGKfTwghygIJeIUQohRcvn63ONbFxxNridpCnJxo4+bFX18f1p4PeUbNzubk5jBj5wxt+6gmozAaLkvYOXwYvvpKH0+dqhbDlqILF+Cbb6rQr1/hs6ZhYfDgg9CsmQowa9e+NoFlTo7qvHTiBBw8CPv3q68DByAlJf/+Z8+qr+XL1djTU11jy5YqAL7vPhWcC3FFvr7qU54mTeD8efXVqZPK4ff0LNop3Hx5o+UbjF0/FoDxG8fzeL3H8XLx0vZxv9Md/x7+xC1X1dvDJ4dz19K7eDwoiNf++4+L2dmcSEvjl/h4Ovr6luhb6tu3r03AO3HixGLXIxBCiLJAUpqFEKKEzpw5wz///AOAk5MT7du3L9Z5rFMSHw8MJGHlBbITLMWqqrpQ8UFVrOqHoz9wKuEUAD6uPgysPzD/yV55RW+X0rYtdOhQrGsqyLlz8MILapZ03rxq+YLdRo3UEscjR9TM69y5MHgw1Klz7WZRHRygShX1rY4cqWL9HTtUAawTJ2DxYhg9Gu6/HywZmzaSkuDXX+H111XA6+UFbdrA5MkqdrnSrLW4xVWvDmvXqhlfUL/4AwZAbm6RTzG80XCbNkWTt0zOt0/YuDDtcdzyOFIOp+Du4MDTwXrV9o9LoUVR+/bt8bQE6ydPnmT37t0lPqcQQtxIEvAKIUQJWaczt2nTRrtZtMeFrCzWXLigjZ8ICiLqS33Rq3Wxqmnb9VZEzzV8Dncnd9uTbdyobsBB5QZPmaL+W0KJifDqq6oi8iefQFqa/lxwsFqre/y4ChBfflkVj7rRE0NGo4pH+vSBjz6CLVvU9/HPP6o7U58+6tovl5EBf/wB48apyTs/P+jWTR1z5IjdXWjEza5JE/XJTp4ff4Q33yzy4S6OLrzf9n1t/PHOjzl98bTNPhUaVMD3UcvsrRnC3wsHYFhIiHYztz4hgUMFpTTYwcXFhW7dumlj6ckrhCjvJOAVQogSKo3qzN/HxJBliaIaVahA2Fm0npsGRwNBg1Sxqp0RO9l6disAJqOJYY2G2Z4oNxdesmpP9PjjcPfdxbom61POnw+3365mbq0D3Zo1L7FokVpLO3myXUsXbxhHR6hfH4YNUzO/kZFqFnj+fBg0CGrWzH9MYqIqvDVihErLDg2FJ55QdYsiI6//9yDKoP791Sc9eSZPBktqcFH0vqs3jSs1BiAjJ4PXN7yebx/rWd6Y72JIO5VGVVdXuvj5ads/LYVfyD59+miPlyxZQq4ds9VCCFHWSMArhBAlEB8fz6ZNm7Rxp06dinUe63TmJ4OCiP7KqlhVZ71Y1fQd07Xt/er2I6TCZVWXv/8e8lIQXVyghAVnjh5V61oHDVJVkPM0aKAmsb74YjcDBpT68uDrymBQs8BPPqkm6Y4dU+uBFy6EgQMLLmwdFaWef+IJFfzWrq2C4R9+UMGxuEVNngzWSxqeekqlExSBwWDgo4c+0sbfH/ievyL/stnHq4kX3m291SAHwj9Qs7wvhIZq+yw8d46Ewiq4FdGDDz6Ij48PABEREWzbtq1E5xNCiBtJAl4hhCiBn3/+mRzLWtnGjRsTUoy2PweSk9mdnAyo3ru9vHw597UeAOcVqwpPDGf5oeXa9nytiNLT1SLUPKNGqYW2xZCTo+pcNWgAW7fq20ND4bvvVEzdseONT1m+VipVUpPjX3+tgt/Dh+HTT1W7JS+v/PsfOaLSnfPaMTVtqjJaN21S6dHiFuHgoD50yksTSEuDLl1UqfAiaB7WnB619V6+Y34bg/my/Pkqb1TRHp9bcI6Mcxm09PKivrta2pCam8vc6GhKwmQy0bNnT228xI6ZaiGEKGsk4BVCiBKwTmcubnXmr61aEXX18yNnTSLZF1SVJOcqzlRsp4pVzdo1ixyzCq7bVGtD/aD6tif65BMIVzM++PmpwlXFEB0NDz8MY8eqGBpUGvDrr6vArl8/tTb2VmEwqDZKw4fDqlWqEO/OnfDuu6qwlZOT7f45Oapg1qRJ0KoV+PiommEffQT79tlVy0iUR97equFz3lr+8HC1WDyviNxVvP/g+zgaVRONP8P/ZPWR1TbPez/gTYXGFQAwZ5qJ/CQSg8HASKtZ3s8iI8ku4S9a3759tcdLly4lWyq3CSHKqVvolkUIIUpXeno6v/zyizYuzvrd7Nxcvrksndm6WFXIkBAMRgNpWWl8tUdvM/RC4xdsT5SQoNIp84wfX/BU5FX8739qfeuGDfq2u++Gv/9WAZ67e+HH3iocHVUl6tdfV/9OCQnw22/q84WGDfPPeqemqgrQL72kZsyDg9Vyz3nz9M8nxE3mjjtUKkTeL8Mff1D166+LdGgNnxoMu09fm//676+TnasHmwaDgbCX9bW8UZ9HkX0pm/4BAfhZ1hacyciwKYJXHC1btiQoSNUOiI2NtVm6IYQQ5YkEvEIIUUy///47KZaKqDVr1uSOO+6w+xzrEhKIsay3C3JyonmcC4mbLItAHSDoKXXD+d3+74hPiwegmnc1OtbsaHuiqVP1xaM1a8Izz9h1HWYzTJumZnbzsi8NBlWleOdOFQSLgrm5Qbt28P776oOBuDhYtgyefVatDb5cbKzKeh08WLVSuv12GDoUli4Fq8l+Ud517GhTqbnqN9+oTz6K4I2Wb+DprGaIj5w/wsJ9C22e9+vih2tNVwCyL2YTPScaFwcHnrUqOf5JCVsUOTg40KtXL228YsWKEp1PCCFuFAl4hRCimFav1lMNu3btiqEYC1ov770bN1cf+z7qi3OIM2azmU/++kTbPuy+YTgYrRraxsbCxx/r4wkT7KoilZGhCjaNGaOn2wYFqdneSZPKd0GqG8HXF3r2hNmzVfXnU6dUX+A+fVSm+eWOH4fPP1fPBwWpycFnn1UThFIBupx76y148EF9/NhjcPbsVQ/zc/NjbLOx2vjtjW+TlqWXRzc4GKj8kr4+P2JaBLlZuTxf2OK+aQAAIABJREFUqRKOlvehTYmJ/HPpUoku33od78qVK7V6BUIIUZ5IwCuEEMWQm5vLmjVrtHFx1u/GZ2Wx5vx5bfy4b0CBxao2n9nMvzH/AuBmcmPQ3YNsT/Tee5DXe7NePejdu8jXkJio1pcutJpAatoU9u5V61NFyVWrBk8/rVogxcSof9spU9Rsuqtr/v2PHoUvv4QBA1SRsBo11GzwwoWq/ZMoRxwc4Ntv9VLfFy6ov8/MzKse+mKTFwl0DwQgIimCmbtm2jwfODAQU4D6NCojIoPYxbFUcnamp7+/ts8nJfzEpHnz5gQGqmuIiYlhq3UFOyGEKCck4BVCiGLYuXMnMZb804CAAJo0aWL3ORbHxpJpqcB6X4UKBK5PIytOpTc7hzrj87BqC/LpX59qxwysN5CKrhX1k0REqOnBPBMnFrmiVFSUajn0xx/6tqeeUmPL0j1RyoxGtY73pZdUdmtCgvr3fuMNaNEifwEsgJMn1XrfJ56AqlVVENyrl0pB375dqkCXeQEBsHgx5ry/yx074NVXr3qYh5MHb7bUU6Inb5nMxfSL2tjBxYHQkXqhqrNTzmI2mxlZqZK27buYGOKKEFwXxsHBge7du2vj5cuXX2FvIYQomyTgFUKIYrCuztypUyccHByusHfBrtR7N2hQEAYHA+GJ4aw6skrbPqLxCNuTTJyoRzyNGkER+wCHh6tg999/9W3vvqv60Do72/2tiGJydlaVnCdOhM2b4eJFFQCPHw+tW6tWypeLjITly1UKerNmqhhwkyaqC9XSpSpj9rJONuJGa9GCU08/rY+nT1clv69iSMMh3FbxNgAS0hOYsnWKzfMhz4dgdFe3cin7U4hfF08TT0/uq6CqOGeYzXxZwhZF1mnNK1asIFfKjAshyhkJeIUQohguX79rr4MpKeyyrK9zMhjokuZJwvoE9aQBggep4jOzds0i16xuMNtWa8ud/nfqJ8mb+svz7rtFaoz7338q2D15Uo0dHGD+fFV1+Gbtq1teuLqqAPjtt+H331UAvGWLWkvdrl3BVbIzM1VhsRkz1DrgsDDo3bsp3bur437+Gaw+WxE3yNk+fWw/kBo8WGVoXIGTgxMTW0/UxjN2ziD6kh7AmnxMhAzRe3+f/fAsBoOBF6xaFM2KjCSrBEFqy5Yt8bMsPo+KimL79u3FPpcQQtwIEvAKIYSdjhw5wtGjRwFwc3Ojbdu2dp/ja6sIpLOfH5lf62t5fR72waWKS75WRCMbj7Q9yfjxkNcbs1UrKMJ1nD4NDzygrwV1coKVK1XRKlH2ODvD/feratm//aYC4L17YdYsGDhQFeQuyPnzzqxapYoEd+yoWiGFhOiFg1etUr8DMhN8HRmN8PXX6hMJUPnsAwdetTFz3zp9qR+oyqSnZqUycfNEm+dDXwwFS4LJxT8ukrQriV7+/gRZ8uOjMjNZkVd6vRgcHR3p1q2bNpa0ZiFEeSMBrxBC2Mk6nbl9+/a4FlR56Aqyc3NZZNV/ZqB/ANHz9Fmb4CFqdveKrYgOHlTFcPJMmnTV6dmoKBUT5xWJdXaGH36Azp3tunxxAzk6qjXAzz+vYqdjx1QbpLVr1Qx9mzbg4VHwsdHRarZ30iTo3l2tB/bzU78TL7ygKklv26Z3txLXQMWK8M03+jr7P/5QLcWuwGgw8l7b97TxV3u+4kT8CW3sUsWFgL4B2vjslLM4GY08H6LP/M6K0nt7F4d1WvPy5cslrVkIUa5IwCuEEHayDniLU515fUIC0ZZCMoEmE/fthMwoNTYFmPDt5JuvFdHwRsNtWxG9/bY+PdehAzRvfsXXPH9epcSeOqXGzs4qSGrf3u7LF2WMnx88+qjKaN+wQc0Cz5mzi3nzYMQI9avh5lbwsfHxKnX6k09U6+bmzcHbGypXVr9WY8fCggWqv3BeIXBRQi1bwmuv6eNx42D37ise0r5Ge1pWaQlAdm4272x6x+b5sLFh2uO4FXGknUzjmeBgrUXRlsRE9icnF/uSW7duTcWKqlheREQEu3btKva5hBDiepOAVwgh7HDu3Dl27NgBqAqmHTt2vMoR+dn03g0KIm6OPg56MgijyXjlVkT798OKFfp40qQrvl5qqgqIDh3Cct2wbJkKgMXNx8EBqldP4amnVCD755+QlASHD6ukgDFjVEEsL6/CzxERoapIT52qKnffd5+aOa5cWc0IP/+8qrv0009qljkr6/p9fzeFt9+Gxo3V4+xs6N//ip8oGAwGJreZrI2//fdbDscd1sYe9T2o+LClensunJ12liBnZ7pbNX7+vASzvCaTyaZWgaQ1CyHKEwl4hRDCDmvXrsVsmVlt0aIFvr6+dh2fkJXFaqveu/2MPlz46YI2Dn5apTNf3orI28VbP8lEqzV8XbrAPfcU+no5OepeeudONTYYVEZlEYs5i5uEgwPccYf6XZg6Vc3qJiSowmWrV6vPTPr1g7p1wWQq/DwREerY2bNh9Gj1QUqtWqrY1u23q/Ho0er5339X6fOS/VoAk0l9+pCXf37smCqzfQXNw5rTvoZKyTBjZvym8TbPW8/ynpt3jsy4TIZatSj6JiaGpLw1/8VweVqzWRaACyHKCccbfQFCCFGelLQ6s3Xv3YYeHvh+l0RSjnrOu5U3bjXdrtyK6OBB1ZMmz1tvXfH1Ro1S63TzfPyxCmyEMBjgttvUl3VmflYWnDihftUOHFD/3b9fBceFxUs5OXD8uPr66Sfb51xdVXGt22/P/2Xn50U3l+rV4bPP9IpxX30FjzwCV3hfmdBqAr+e+BWApQeXMq7FOOoF1gPAu403Hvd4kLwnmdz0XCI/i6Tl+Krc6ebGodRUknNyWBQTYxME2+PBBx/Ey8uLxMRETp8+zZ49e2jYsGGxziWEENeTzPAKIUQRXbp0iQ0bNmjj4qzfta7O/ERgENFz8xersm5F9OBtD9q2Ipo4UV+726nTFWd3P/8cPtUnihkzRq3pFOJKTCaoXRt69lSFwJctgyNHVGr8sWPw448wbRo895wqkmXVAadAaWmq3/Py5TB5sorvmjVTa4/9/NTjp56C995TmfoHDkB6+vX4TsuAgQNVL6k8zz6rFtwX4r5K99G5ll5l7u2Nb2uPDQYDYS/rs7yRn0WSm5ZrE+DOiows9sysk5OTzXuepDULIcoLmeEVQogiWrduHRkZGQDUr1+fqlWr2nX84ZQUdlp675oMBjocdSLiP3Vn71jREb/ufvlaEY1oZBWhHj4MS5fq47f1m93LbdwII626GPXqBR9+aNflCmHDZFIztTVrqvZG1lJS1KzwsWNqlvfYMf3rwoWCzwfque3b1Zc1gwGqVNFngu+8U6Vb16mjimrdNAwG9cnUn39CZCTExsLw4bB4caGHTGg1gTVH1wCw+shqdkftpmGImmn16+GHSzUX0v9LJzs+m5hvYnh8cCCvnDxJSm4uB1NT2ZKYSMti/iP27NmThQsXAirgnTx5MgZp3i2EKOMk4BVCiCIqaXVmm967vr5kTNR7YwY+HoiDiwPf7blCK6JJk/TZ3Y4doZB0wtOn1excXvppw4aq0q5RcnrENeLuDvXrq6/LXbigB8FHj9oGxGlpBZ/PbFa/x6dPq/7D1ipXVoFv3br61113qZZN5VLFino6M8CSJdCjh/qUqgD1g+rT886eLD+kZljf2vgWP/VXeeRGRyOVRlbi5KiTAETMiOC+IcE8HhTEbEvRqlmRkcUOeNu1a0eFChW4dOkSJ06c4N9//6V+QT90IYQoQ8rr/x6EEOK6ysrK4scff9TG9q7fzTGb+caq9+4ANz/OrzqqjYOHBOdrRTTsvmF6K6KjR21nfQpZu5uRoe6T82bVAgNVUaLC2tIIca35+qqvJk1st+fmqknNvEA4Lwg+elQFuoUVuzp7Vn398ou+zdVVZfc3bgyNGqmvqlWv2pq67OjQAQYPhrlz1XjoUHjgAQgIKHD38Q+MZ8WhFZgx8/Pxn9l+djtNKzcFIHhQMKffOk3OpRxSj6SSsD6B55uHaAHvivPnOZeRQZCzs92X6eLiQqdOnfjuu+8ANcsrAa8QoqyTz/uFEKIINm/ezMWLFwEICwujQYMGdh2/Pj6eKEvv3QCTifqrMjFnqdlazyaeeNTxYEv4lsJbEU2apEcA7durO/oCvPyy6pkKKgV11aqrr7EU4kYwGvU2R0OHwowZ8PPPqjhWaqpqo7VqlVrbO2AA1KtXeAXptDTYulWtLe7bVxXiCghQk6aTJqnnLH9+ZddHH6l/EFDreIcO1TM6LnNXwF30r9tfG7+1Uf8AzNHTkaBBQdr47PSz1PPw4H5LH6pss5k50XrtAHtZV2tetmyZVGsWQpR5EvAKIUQRWBdo6dKli93r1r62nt0NDOS8Ve/dvGJV1q2IHqv7GBVdLX01jx0Dy4wKUOja3ZUrVd/VPFOmQNOmdl2mEGWCs7MqnNW1K7z6KixaBPv2qbXCBw+qZIdx46BzZz1GvNz582oW+M034f77Vebwww/D+++rD4XKXLskLy+YM0cfr1ih0psL8fYDb+NgUBkg/zv1P7ac2aI9FzoyFCxvUQnrEkg5lMLQkBDt+S+io8ku5j9A+/btcXd3B+Do0aMcymvwLYQQZZQEvEIIcRU5OTmsXLlSG/cqZG1dYS5mZbEqTl+v2z3andQjqQA4eDjg39ufs4lnWXVYb0U0vNFw/QTvvaffnT/0UP7cUODUKRhkNSHctatt0SohbgYmkypg1aePmrn94QcID4eoKPV43Dho107FjpdLTVXrgV97De67DypVUlnEq1aBpZbcjffQQ/DMM/p42DCwWvtvraZvTQbWH6iNJ27W+3O73uaKXxc/bRzxSQTd/f0JsEyRR2Rk8OOVqoldgaurKx2tqpZJtWYhRFknAa8QQlzF1q1biY2NBSAoKIhmzZrZdfySuDgyLGl/93h44DvnovZcQP8AHD0cmf33bHLMqiFvq6qtqBtYV+1w+jR8841+sgLW7mZkQO/ekJioxlWrwrx55Wj9ohAlFBysZnsnTVJBbXy8Wgv89deq5VG1avmPOXdO/Z10767aI3XooPZPSrr+129j6lRVohrUN/LCC4XuOq7FOG2Wd/2p9Ww/q5e7Dn1RX8sQszAGY0IOTwcHa9tmWdb0Fod1WrMEvEKIsk4CXiGEuArrG7ru3bvj4OBg1/ELrGZoHvfyJ26ZPtsbPCSY9Ox0vtzzpbbNphXRBx9AjgqEad0amjfPd/6xY2H3bvXYZFJZkBUr2nWJQtxUjEbVzmjgQBXUnjqlPjtasAAef1wFuNYyM+HXX1WP4IAAVSR5+fLCq0hfUxUq6MWrQLUisyqYZ626T3UG1Bugja1neb1aeuHRwAOA3LRcor6K4pmQEO3Gb31CAsdSU4t1iR06dMDV1RWAAwcOcOTIkWKdRwghrgcJeIUQ4gpyc3NZsWKFNrae2SiKo6mp7LBMGZkMBtpuMJCbptKTPRp4UKFhBZYcWML51PMAVPasTOdandXBkZHqbj3PG2/kO/+aNfCpvvSXKVMKrWclxC2tShV44glYuFDN7m7frlKgLy8ynJGh1sP36gUhIfDii6oF9nXVtq2KvvMMHQrJyQXu+vr9r2M0qNu5X078wq7IXQAYDAZCR+mzvJGfRVLZwYlHfX21bbOLOcvr4eFBhw4dtLHM8gohyjIJeIUQ4gp27NhBlOWm0N/fnxYtWth1vHXv3Ud9fUmfrRevKqhY1dD7huJotHSMmzpVLy3btKma4bVy/rztcj9ZtytE0Tg4qKXwkybBP/+o2d8PPoDLi69fvAgff6zWDbdurbInrlu156lT9anos2dV9a0C1PKrRd86fbXxhM0TtMcBfQIwBap1u5mRmcQtj2NopUra8/PPnSM1L4PETpLWLIQoLyTgFUKIK7C+kevWrRuOjkVvX55jNrPQKuDtnexJyr4UAIyuRgL6B7AjYge7o1U+srODM0/f87TaOTYWvvhCP9kbb+RblDtsGOQVfw4KUlmQsm5XCPtVqaJaeu3dq9ohvfWWam1kbeNG1fKoShUVi17zQle+vjB9uj7+5BPYtavAXce1GIfBUpb5x2M/sid6DwBGZyOVhuoBbsT0CB709qa6iwsAF7OzWWypT2Cvjh074mzp5btv3z6OHz9erPMIIcS1JgGvEEIUwmw22wS89qYzb0hIINIyHeRvMlFngb5ezr+XPyZvk83sbv+6/fFzs8zoTJ+uLyC8+25VUcfKkiVqaV+eOXPAx8euyxNCFKB2bXjnHTh+XBXA6t5dzQjnOXdOrZuvUgXGj4diFjsumgEDVNlpUJXahwyBrKx8u93pfye97tKrx1uv5Q15LgSDswqGL+26RPLOSzxvNctb3LRmT09PHn74YW1svfRDCCHKEgl4hRCiELt27eLs2bMA+Pj40KpVK7uOty5W1d/Hn4RvbYtVRV+KZtmhZdo2rVhVfDx89pl+ostmd6Oj1ZK+PIMGgVWXECFEKTAaVay5YgWcOaOCYKsixyQkqG15s8MJCdfgIgwGmD0bLAWi2LcPZswocNc3Wuhr/FcfWc2+c/sAcApwInBAoPZcxIwIngwKwsnynrLr0iX+KeZ0taQ1CyHKAwl4hRCiENY3cF27dsVk6WFZFInZ2aw6f14bd9ptIidZrZVzu8MNr+ZefLH7C7JzswFoXrk5dwffrXb+9FO9QM2dd6rFuRZms1q3Gx+vxmFhtlmPQojSV6mSSnP+7z/48kuoXl1/LiVFFYurXl39LWZklPKL33abmkrO8/bb6kIuUzewLt1rd9fGk7ZM0h6HvqAXr4pbEYd7dA49/P21bV9FRxfr0jp16qS9L+7evZv/CrguIYS40STgFUKIAlyeztyjRw+7jl8aG0t6rqrG3MDDg4oz9emf4KeDycrN4ovd+hpdbXY3KUlVyckzbpyaarJYsMC2Q8m8eeDpadelCSGKydlZZRUfOQLffQd16+rPJSTA6NHqM6ply9SHU6Vm1Ci9nHRamiodXYA3W+qFrZYfWs7hOFVe2qOeB95tvNUTOapi8zNW09WLYmKKVbzK29ubdnkp10hasxCibJKAVwghCrB3715ttsLLy4u2bdvadbx1OnM/c0WSdqjWRAaTgcCBgSw/tJxzyWqfkAoh+szM55/ruZE1akDv3tp5IiJs73OHD1fdS4QQ15ejI/TrpzKMly2znfE9dUr92d5/Pxw8WEovaDLZFrFbswZ+/jnfbg2CGtDp9k7a+IOtH2iPQ1/UZ3mjv4qmuaMHNS2p0kk5OSwtZvGqXr30tcOS1iyEKIsk4BVCiAJY37h17txZq0ZaFMdSU9lm6b3raDDwwFK9yIxfNz+c/J1silU91/A5TA4mSE2Fjz7ST/Taa+rO2mLECDUBDCoWfv99e78rIURpMhigZ09V2XnGDNvCcdu2qXpz48eXUppz48ZqwX6ekSMhPT3fbq+3eF17/O3+bzlz8QwAvh19ca2hAtzsi9nEfhvL01azvMVNa+7cubNWvX7nzp2Eh4cX6zxCCHGtSMArhBCXMZvNLFumF5Oytzqzde/djt4+ZM3V1/IGDwnm76i/2RGxAwAnByeeaWhppvvVVxBnKWwVFgaPPaYdt2oVrF6tv8acOeDubtdlCSGuEScneOEFOHECXnpJTciCKqj8zjsq8D1woBTWHrz/PnhbUpNPnrT9gMyiSWgTWlVtBUB2bjZTt00FwGA0UGmEXp05amYUTwQGYrIUr9qWlMTBlBS7L8nHx8cmA2blypV2n0MIIa4lCXiFEOIyu3fv5sSJE4BqvfHQQw8V+dgcs5mFec1xgW4nXclOUIWpXKq5ULFNRZvZ3d539SbQI1BNAX34oX6iV15Rd9GoWd0RI/Snnn4aHnigON+ZEOJaqlhRFbDauxeaNNG3Hz4MI0feXdikbNH5+8MkvRgV776rSkhf5rX7X9Mez9k7h5hk9Z4U9EQQRnd165dyIAXnnWl08fPT9v2qmC2KpFqzEKIsk4BXCCEu8/3332uPu3XrhouLS5GP/SMhgQhL/qKfycSdM/V2H8GDg4lLi2PxgcXaNq1Y1YIFkHezGRRkk7o4bhxERqrHAQG2cbEQouy56y74809VcN3DQ20zmw18+qnKTD5ypAQnf/ZZ2wJWo0fn26Xdbe1oGNwQgPTsdD7eqQrhOXo5EviY3qIocqZt8aqFMTGkF6N4VdeuXXGwNCveunUrkXlvWEIIUQZIwCuEEFZycnJYvFgPSPv162fX8dbFqno7+ZDye6IaOEDQU0F8tfsrMnMyAWhUqRGNKjVSeY/WC3LHjgVLkL1jB8ycqT/18cdqFkkIUbY5OKjCcgcPwiOP6Nv//RcaNlSfcRWrkrOjo+2bwsqV8NtvNrsYDAabWd6Zu2aSmK7eiyoN09Oaz688z/3pblSzvN8kZGezwqqdWlH5+fnZ9ClftWqV3ecQQohrRQJeIYSwsmXLFqIsM63+/v52VWdOyMqyuVlsb3UP6tvRF2Ogkc///lzbps3ufvcdnD5t2dFXzeCg4uAhQ/Sb4vbtoU8f+78nIcSNExamWom9+OIx8mrfpabCU0/BwIFw6dKVjy9Q8+bq4DwjRkBmps0u3Wp3o5ZvLQCSMpKYtWsWAB51PfBq4QWAOdtMzFfnbItXSVqzEOImIwGvEEJYsU5n7t27t1Z9tCi+jYnRe++6u+Pzabz2XPCQYFYfWU3kJZXqF+AeQK87e0FODkyerJ9k9GitGtVHH8GBA2qzmxvMmqWqwgohyheDAbp0ieKvv+COO/TtixZBo0aq2JXdPvxQb8J97JjtrC9gNBh59f5XtfH0HdNJzUoFbGd5o76I4gm/ABws402JiRxNTbX7crp164bB8ga1efNmzllluwghxI0kAa8QQlhkZmbazEzYk85sNpv50qqtR/9YT7JiVDsipxAnfNr72BSrerbhszg7OsPy5epmFcDLC4YNA1QdmgkT9PO/8w5Uq1ac70oIUVbUqwd//61md/McOaLW9W7aZOfJAgNVz6M8EybAhQs2u/Sv25/KnpUBiEuNY97eeYClPVqQKoqXGZ2J6edLPOrrqx03pxgtigIDA2nZsiWg3g8lrVkIUVZIwCuEEBbr168nPl7NyoaFhdG0adMiH7szKYn9lpYebkYjzT5P054LHhTM/vP72RK+BQBHoyPP3fsc5ObaVlwdOVIFvcCoUaoeDaj6NC++WJLvTAhRVri7w7x58M032lJ94uOhXTu13S7Dhqmm3AAXL9oGwKi2Zy81e0kbT902lezcbIxORoKf0dOYI2dG8kxIiDZecO4cGZZsFXtIWrMQoiySgFcIISys05n79u2L0Vj0t0jr2d1eLr5k/XRRDYwQ/HSwzexuj9o9CKkQAmvX6jnL7u6qkSewbp3qu5tn1ixVp0YIcfN47DE1qxtoKZqclQWDB8PLL6uVDkXi5KT6IOX5/PN8JaCfvudp/NxU66EziWdYfkgFoiHPhJCXx5y4KZHmUU5UtiwyPp+VxQ/FKF7VvXt37fHGjRuJy+srLoQQN5AEvEIIAaSmprJ69WptbE86c2J2NotjY7Vxp1/0hba+j/qS4p/Ct/u/1baNaDRCVaKynt0dOhR8fcnIsO25+8QT0KyZnd+MEKJcaNQI/vpL7zIEKn7t3Vu15i6SLl0gr0JyTg689JLN024mN4bdN0w//7YpmM1mnCs549/NX9se83k0g62KV31ZjOJVISEhNG/eHIDc3Fyb91QhhLhRJOAVQghg7dq1pFhSkmvXrk196zvQq/g2JoY0S/pffVd3/KfrMyOVhlVi7t65pGenA3B30N00q9xMtRH5+2+1k4uL1ktz+nQ4flxt9vKCDz4o6XcmhCjLwsJUz97OnfVtK1eqOLZItaMMBpg2Ta9o99NPsH69zS5D7xuKi6PKn94TvYdNZ9SC4ZBhehpzzDcxDPTw124MN1y8yMm0NOwlac1CiLJGAl4hhMA2nblfv35atdGrMZvNfGE1E9L7jDu5iSr4da3pimcbT60dCKjZXQPAxIn6SYYMgaAgzp613Txhgp7uKIS4eXl4qCB31Ch927p10KFDEdsW3X03PPmkPh492iYvOsA9gCfqP6GNp26bCoD3A9643eUGQE5yDqbFCXTw8dH2m1uM4lXWac0bNmzgwmWFtIQQ4nqTgFcIccu7ePEiv/zyiza2J51516VL/GuZGXY1GmkyPVl7LuT5ENYcX8OZxDMA+Lr60rdOX9i8GbZuVTuZTDB2LABjxugzOnXrqixnIcStwcFBtSKzrju1ebMqZpWQUIQTTJqktTTjwAGYO9fm6VFNRmFQH7fx0/GfOBR3CIPBQKWhVi2KZkXZ9OSdFx1Nlp3Fq8LCwmjcuDEAOTk5rFmzxq7jhRCitEnAK4S45a1YsYLMzEwA7r33XmrkVT0tAut1bt3wxrhDRaxGVyNBTwbx0faPtOefbfgsriZX27W7Tz4JlSuzYQMsW6Zv/uwzKVQlxK3GYIC337atQ7VzJ7RpA1et/xQSAq+8oo/ffNNmeriWXy0619LzpqdtnwZA4OOBOFRQ1atSD6fSfL8DwU6qZVFMVhY/FmOGtlevXtpjSWsWQtxoEvAKIW55CxYs0B7379+/yMclXVasquMqs/Y4cEAgu1N2s+3sNgBMRhPDGw2HHTvgf/9TOzk4wKuvkplpW6hqwACwtLMUQtyCXnoJZs7Ux//8o4Leq870jhkDoaHqcWysWttrfV6rFkXf/PsN55LP4VjBkcCB+tqJmJlRDAoK0sZfFiOtuUePHtrj9evXc/HiRbvPIYQQpUUCXiHELe348eP8+eefADg6OjJgwIAiH/tdTAwplnS/u5zdCJmp342GDAuxmd3tX7c/wRWC4d139RP07w+33cYnn8Dhw2pThQq2sztCiFvT0KEwfz7kdUc7cAA6dgTLCoqCubnZFgKYOhViYrRh88rNaVxJpRudhln6AAAgAElEQVRn5mTy2V+fAdikNZ//4TyPGfR1vOvi4zmTnm7XtVetWpV7770XgKysLNauXWvX8UIIUZok4BVC3NKsZ3c7duxIQEBAkY4zm83MtEpn7nnYBbLUY8+mnpyvcp6Vh1dqz49uOhr27oUff1QbDAZ47TWiouCdd/Tzjh8PVkvohBC3sCefBKu3KLZvhx49wLICo2CPPw533aUeJyfbLKEwGAyMbTZWG8/aNYuUzBTc73THu7W32pgDzvMSeKhiRQDMFK94lVRrFkKUFRLwCiFuWTk5OXz99dfa+KmnnirysZsTEzlgmWpxMxpp9qFerKrSsErM2DGDXLOa/W13WzvqBdaDyZP1E/TsCbVrM3asuicFuPNO29RmIYR4/HH4+GN9vG4dDBxoU4TZloMDvP++Pp49G06e1IZd7+jKbRVvAyAhPYH5/8wH1PtWnqivohjsr6c1z4uOJtvO4lXWac3r1q0jKSnJruOFEKK0SMArhLhlrV+/nsjISAACAgJ45JFHinzspxER2uNeqV44HVVTLiZ/E44dHZm7V6+QOqbpGDh0CFas0E8wbhybN8N33+mbPvtMFW0WQghrI0eqYlZ5liyB4cPBbC7kgI4doUUL9Tg7WxWwsnAwOjC6yWhtPG37NHJyc/Dt4otTJVWsKismi6abzARY3pAiMzP5NT7ermuuUaMGDRo0ACAjI4OffvrJruOFEKK0SMArhLhlzZ8/X3v82GOPYSpitHk2PZ3V589r445f6vmFwc8EM+fAHFKy1OxvnYA6PFT9IXjvPf3utFMnsu+qz/Dh+jn79IHWrUvwzQghbmpvv43Ne8bs2bbLIWwYDPDBB/r4++9hzx5t+GSDJ/FxVet0/7v4H6uOrMLoaCTk2RBtn7iZUTxZwuJV1mnNy6zL0AshxHUkAa8Q4pYUHx/P6tWrtbE96cyfR0WRl03Y0lgB/1UquDWYDAQ8F8Anf32i7Tu6yWgMp07ZTuWOG8fnn8P+/Wro7q5qywghRGEMBpXabF1X75131GxvgZo2hW7d9PGrr2oP3Z3cGXqv3uh7yrYpmM1mgocEYzCpXr1JW5Pol+il7fPThQtEZmTYdc3WAe8vv/zCJas2SUIIcb1IwCuEuCV9//33Nr1369SpU6Tj0nNy+MpqpqPHzwbtcUC/AFZdWEXUJVXMKsgjiP51+6v1dHnr39q1I7ZaY+sMQ958U+8kIoQQhTEaVeXmhx7Stz35JPz9dyEHTJ6sl3lev15viQYMbzQcJweVwvxX5F9sPbsV5yBn/Hv4a/u4zr5Aa29VzCoXtZbXHrVq1aJevXoApKen82Ne0T4hhLiOykXAazAYXjMYDLsMBkOSwWCIMxgMaw0GQ9HuToUQogDW6cz2zO4ujo3lfJYqxxzm6MRd0/RCLKEvhtq0Ihp+33Cco2LAqjAWb7zBa69BYqIa1qwJL75YzG9CCHHLMZnUrG6tWmqcng5duoBV0XjdHXfAoEH6+NVXtaUVgR6BDKw3UHtqyjbVDy1kmJ7WHPNtDE956ZXr50ZHk1PowuGC9e7dW3u8dOlSu44VQojSUC4CXqAVMAtoBrQBsoH/GQxWjeKEEKKI9u/fz+7duwFwdnamX79+RTrObDbzqaXIFUCf/a44WFoRebfxZovHFvbF7APAzeTGc/c+p5rqWgJkWrRgp3NL5s3Tz/nJJ+DsXPLvSQhx6/D2hjVr1H9BBbtdu0JaWgE7jx8PLi7q8e7dYLWUY3RTvXjVmqNrOHr+KF7NvXCv5w7wf/buO76m8w/g+OfkZiJmiL1rq1mzVtWo1ii1a7RmjLZqb2pTe1eNGjVLtdr+qJq1SWwSYiYiRILsm9x7fn+c69wbDQlChu/79crLfZ7znPHkuDfne5+FOcJMtd9iyGZvD8DN6Gj+fsHJq1q3bq2//uuvv2S2ZiHEG5cqAl5VVRupqrpSVdXzqqqeAzoB2YGayXxpQohUyLZ1t0WLFmSxrDeZkKOPH+NpWUPIWbGj9iTreLS8A/Iy6eAkPd2zYk+yPY6BZcv0PNOwkfTtaz1e8+bQuPHL1kII8TYrVgw2bdJWIQI4cQK6d49n5uY8eeLOdjV6tL6mUcnsJfmk2Cf6pllHZqEoSpwlioIX3qWTu7ueXvaC3ZqLFStGuXLlAG225t9///2F9hdCiFeVKgLeeLiiXXtIcl+IECJ1MRqNrF27Vk+/SHdm29bd5kHpyeCvjct1Ke7C+VLnOXz7MACOBkcG1RgEs2bBk0leKldmhV9DLA3LODnB7NmvWBkhxFutQQOYM8ea/vnnZ0yAN2QIZMigvb5wQYuULQZVH6S//unMT9wLv4d7R3cMmbRIOvJKJG2up9fL/PbgAXdfcPIq6dYshEhOivqCYzFSAkVRNgHvAJVVVf3P0uuKovQEegK4u7tX2rBhwxu+whcTFhZGhid/iESKIPckZUqK+7Jnzx4mTJgAQPbs2Vm/fj2GJ00kz/EAaAv67MzLhkHRY5bEABhUYBCnHmrR7Ce5PmGoe3eqt2uHISoKgOMjJtNgwSAeP9aWPurS5QZdu954pbqkBPJeSZnkvqQ8r+ueqCrMmlWMHTu0sbd2dipz5nhRtmzcrsMFV6yg4Jo1AETkzcuJVatQDQZUVcXDywPvUG8AOhfozBcFv4AFwJOlw2vAV5PAMrE8PYAOL3CNfn5+dOrUCQAHBwe2bt2aIv5/yvskZZL7kvKkhntSr169U6qqVo5vW6oLeBVFmQW0A95XVfVaQuUrV66snnzm9IUpw759+6hbt25yX4awIfckZUqK+1KnTh0OHDgAwPjx4xkzZkyi9hvq68v027cBqBqTjqkNIwCwz2qPwzEHqq2rBoCdYodPPx+KzFyhzZAKULYs/d4/zcLFWqeaggXh4kVwcXmlqqQI8l5JmeS+pDyv854YjVC3Lhw5oqXz5oXTpyFbNptCDx9CoULavwArVoClh8vG8xtp90s7ALK5ZOPWgFtwHY4XP66VtYNrZ4rQLcgXgCLOzvhUrYqdopBYFStWxMvLC4A1a9bw+eefv3R9k4q8T1ImuS8pT2q4J4qiPDPgTVVdmhVFmQ20Bz5ITLArhBC2Lly4oAe7BoOB7t27J2q/R7GxLLGZArX1BusXhbk9cjP55GQ93b5Me4oY08fpZ3i9w0gWL7V+3M6enTaCXSFEyuDoCBs2wJPpCPz8oEsX62pogDbD1eDB1vT48fqQi1alWlEgUwEAHkQ+4KfTP5GuWDqyNLAc0AzV1keT2TJ5lW9UFHufBM6JJN2ahRDJJdUEvIqizEXrQfOBqqqXk/t6hBCpz5IlS/TXn376Kblz535OaavF/v48tkzy8o7qRIWV2lSoioNCaJtQfvP+TS87/P3hMHEiRGgtwGq5cnT6rbX+4NmokTZZlRBCJKX8+eOugPbHH9o0AnF89RW4uWmvb96E5csBsLezZ0C1AXqxWUdnYTKb4kxeFfJDIB2zWdfoXRbvOkjPZjtb886dO3n4ggGzEEK8rFQR8CqKshD4Aq11N0RRlJyWn5TdmVwIkWKEhYWxevVqPe3h4ZGo/aJMJub4+enpjr/ZYWdp4M3ZNSfTrkzTt7Uo0YLSYS6wdKmet+fDKRw6on3UOjjA3LnwAr0AhRAi0Zo2hYEDrelhw+DwYZsCGTLA8OHW9MSJ+lpG3Sp2I7Ozts7R1eCr/Ob9G9k+yYZTfm3dtJigGFqdsa6htjUoiHtGY6KvrUiRIlSsWBHQJg/87bffEthDCCGSRqoIeIE+aDMz/wME2PwMet5OQgjxxNq1a/X1H4sXL069evUStd9PgYEEWtbRzY0DNRZYFro0gNpbZeOFjXrZkbVGwpgxEBsLQGzN2nRcY1136NtvoXjxpKiNEELEb8oUqKZNKYDJBO3awYMHNgU8PCBXLu11QAAsXgxABscMeFS2fhH4/ZHvUQwKuXtbe8JknPOAahkzAhCjqqy6e/eFrk26NQshkkOqCHhVVVWe8TMuua9NCJHymc1m5s6dq6f79OmDkohmVpOqMuPWLT3d/h97HLRYFvfP3Zl2expmVeur3LBIQyrfd9DWBbFYnG8Kgfe08+TODaNGJUVthBDi2Rwc4o7nvX1bi3H1OUpdXOJ+GE2ZApb1xftX6Y+DnTaT/OHbhzl8+zC5uudCcdQ+x0KPhdLFmFXfdemdO5hfYPJT227Nu3btkm7NQog3IlUEvEII8Sp27drF5cva0P+MGTMmeu3dX+7fx9eyrFAmDHww09K6awcxvWNYfcbaRXpkrZEwcqT+VPm4XjMGbK6hb58507oMphBCvE4FCsCqVdb05s2wfr1Nge7dtUIAQUEwbx4AuVxz8fm71tmTZx6ZiWN2R3K0yaHnVfsxUp+86lpUFP+EhCT6ugoXLkzlytokqjExMWzduvXFKiaEEC9BAl4hRJo3x2bG5G7duuHq6prgPqqqMs2mdbftUUfSWeLdHG1zMP7WeL11t1GRRtS+pWizxACqotD/0SQs81xRpw60bZtElRFCiERo1kyLa5/o21ebvRnQpnUeO9a6ccYMfbmigdWtg4C3XdrG1eCr5Olnnbzq0dp7fJ7ROnnVkhecvKqtzYfhunXrXmhfIYR4GRLwCiHStIsXL7Jz504A7Ozs6N+/f6L2+yckBE9LNz9nFBpPi9S3hXYPZesla8vEpHoT40wEc6VaJ1Z7lgHA3h4WLJCJqoQQb96sWdrSu6DFs198YbNUUadO8M471o0zZwJQOkdpPir6EQAqKrOPzMa1iiuulbUvCtVolRZ7rI+P24OCuGNZ3igx2rdvrw8p2bt3L/7+/q9QQyGESJgEvEKINM22dbd58+YUevL0l4ApNq27Lc45kcUy1MytlRuj/Ufr2z4r9RmVjt2CQ4cAUB0c+Oz8eH374MFQpsyr1EAIIV6Oq6u2VNGTL9x274ZFiywb7e21tXifmDMH7t8HYFAN65ygK0+v5EHkA/J8ZW3lTTcziNoZMwFgAlYEBCT6mvLkycMHH3wAaD1p1sfpay2EEElPAl4hRJp1584dfrJZmHLAgAHPKW21/+FD9li699kBTadG6dvud73P39f+1rYpdkyoPjLOOiB/FezDudCCABQpAqOtsbEQQrxxtWrBIJs1LYYMAW9vS6JtW+s3cmFhMH06APUK1qNCzgoARMZGsujEInK0yYFDDm1Cq2i/aNr7WScl+CEgANMLTF71+efWccJr1659iVoJIUTiScArhEiz5syZg9GyTmSNGjV4//33E9xHVVXGXL+up5tddiK3ZYha1k+yMiJwhL6ta7mulFi1A27cAMCYMRsdr1jHxS1dqk2IKoQQyWnCBGtcGxkJnTtbVk+zs4PvvrMWXLgQAgJQFCVOK++C4wuItosmd0/rEkUV5oTi5qAFwLejo/lfcHCir6dly5Y4OzsDcObMGc6dO/fylRNCiARIwCuESJNCQkJYbFlfEmDYsGGJWopo78OHHHj0CAB7oPV31rFpt7rc4qjfUQAcDY6MLd5TW9LDYrxhAg/R1gLp0gXq10+KmgghxKtxcoI1a7QliwCOH9fG9wLQogVUrKi9jozUP9Nal2pNvoz5ALgfcZ+fzvxE7t65Uey1z9HIvY/paLAuUfQik1dlzJiRZs2a6WmZvEoI8TpJwCuESJMWLVpEmGXSqVKlSvHxxx8nuM9/Wne9HMltGZqWrWU2ht+3TkzlUdmD/N/NhYgIAO64vcvUkJ5a2Wzw/fdJVRMhhHh15cvDuHHW9NixcOUK2gDfCROsG5YuhVu3cDA4MKCadRjI94e/xz6XPW4t3fS8JhvN+us/HzzgVpR1+EdCbLs1r1u3DrPZ/JzSQgjx8iTgFUKkOaGhocyePVtPDx06FDu7hD/u/gwO5tDjxwA4qAptpmrdobGD0x1Pc/7eeQDSO6RnhGP9OAtbdnwwDzMGAGbPBjc3hBAiRRk8WAt8AaKioGdPy9LhH30E1atrG4xGmDgRgB6VepDFWeu14hviyy+XfiFPf+vkVc5LHlA/gzZ5lRlY9gKTVzVq1Ihs2bIB4Ofnx4EDB16tckII8QwS8Aoh0pz58+fz4MEDAAoWLEj79u0T3CfWbGaIr6+ebnHYHvd72utsnbMx+NpgfdvAagPIMcg6VvfPDK3Zp9YB4MMPwabhQgghUgwHB1i+HAzad3Ps2wc//ojWymsJcgFYsQKuXiWDYwb6vtdXz552aBoZa2QkQwVtwipzlJnPvJz07T/cuUN0IltqHR0d46zJK5NXCSFeFwl4hRBpyuPHj/nepj/x6NGjcXgycO05fgoM5KKle3J6sx3tv48BQHFS+KXBLwSGBwKQxzUPQ664g5cXAEaDMx5hMwBtCZBly2TNXSFEylWxYpyJ5Rk8GO7cAT74AOrV0zJNJn0yq/5V++Nsr00w5RngyZ4be+K08pae+pC8jlrQey8mho337iX6Wmy7NW/ZsoWoF+gSLYQQiSUBrxAiTZk7dy4hISEAFClShE6dOiW4T7jJFGfsbvtfFH3dXde+rky5Zp2YalrVUaQfZV27crJpKLcoYDk3FCyYBJUQQojXaNw4KFpUe/3oEfTpY+nabDuWd+1auHiRHOlz8GX5L/XsaYemkaNdDuyz2QNgumaka0gmfftcPz/URC5RVK1aNQoXLmy5jkf88ccfr1QvIYSIjwS8Qog0Izg4mFn61KOJb92defs2dyzLF2WPNtByhQkAx5yOfFf6O4wmbVu1vNXosPQQBAUB4GfIz3SGANCsGXTtmpS1EUKI18PFReuN8sT27bBlC1CzJjRurGWqqj7L1cAaA7FTtEfG3dd2czrkdJwliurNisDZMk+CZ1gYhy1zISREURQ6duyop6VbsxDidZCAVwiRZkyaNImHD7Wm2XfeeSfOg9Sz3IyKYsqtW3q681IzLpZedcH9gtl+ezsACgpzM7dHWWN9IOtpWkwk6cieXboyCyFSl7p1oUcPa7pfPwgOJm4r7+bNcPo0hbMUpk3pNnr29MPTydM/D4qj9qFntyeMNmpmfftcP79EX4ft5/Qff/zB/fv3X7guQgjxPBLwCiHShGvXrjF//nw9PWXKFOzt7RPcb+DVq0RZJlkpEWjgo+1aV7x0FdLR26m3Xq53uW5UGTxHT6+nHX/RBNBW8ciRI0mqIYQQb8z06ZArl/b63j3L2N7KlbW1eZ8YMwaAITWG6FlbLm7Bz8kP98/d9bxmP5n011vv3+d2IsfjFi9enGrVqgEQExPDmjVrXrI2QggRPwl4hRBpwogRI4iJ0SaaqlGjBi1btkxwn39CQvjF0j0ZoM9EEwYzoMBfnf7CP9wfgBzpczB5twqWcb4hSha+QQt+u3SBTz9N4soIIcQbkDkzLFpkTa9aBX//jTZh1ZMuK7//DsePUyFXBRoWaQiAWTXz/eHvyTcon75vtpWPqO3oCoAJWHTnTqKvo3v37vrrH3/8MdFjgIUQIjEk4BVCpHpHjhxh48aNenrGjBkoCfQvjjKZ6OPjo6cb/WtHWW2ZXew62DH+sXViqlm5vyDzwuV6+ht1NvdwJ39+baIqIYRIrVq0gM8+s6Z79oTwwmWhjbULM6NHAzC05lA9a+XplTzM85Bsn2TT89r+be1V88OdO0SYrK2+z9OmTRvSp08PwKVLlzh69OjLVEUIIeIlAa8QIlWLjY3Fw8NDT7dq1YoaNWokuN/EmzfxiYwEIH2MQvc5Wrdm++z2fP3u16hoLQwN839Ah6HWcbu/0pzVdMbeHjZsgEyZ/ntsIYRITebPhyxZtNc3blji23HjwDIRFbt2wd691CtYjyp5qgAQbYpm2qFp5BtsbeUtMS2Egg7aEkXBsbGsCwxM1PldXV1p166dnv7xxx9ftUpCCKGTgFcIkaotWrSIM2fOAODi4hJnDd5nORsWxrTbt/V0z/kqbg+01ye6nOB05GkAXB1dWfZPOhQ/rWvzfdzoxVJAYcoUqF49aesihBDJIWdOsJngnrlz4fjjEmC7rNuQISiqyrg64/SsH079QFi5MFyraF2Z7SKhwwUXffs8f/9Ed0+27da8YcMGHidypmchhEiIBLxCiFQrICCA0ZaudgCjRo2iYAIL4caYzXT39ibW8hBWzkfhkx3aNvUDlYHpB+plZ7m0IP+6HXq6N0u4hzsffwzffpt09RBCiOTWpQs0aKC9NpuhWzcwjvoOnLQWW06ehE2baFy08X9beW3G8r7/XSjpLS3D58PD2WOZOT8hVatWpXTp0gBERESwbt26JKqZEOJtJwGvECJVUlWVfv366a0AxYsXZ+DAgQnsBZNu3uREaCgADib4dqKKnQp2me3oW7MvqmLpypyjBt2Gb9L3W0pPttKKIkVgzRprTz8hhEgLFEWbcT5dOi19/jxMW58fvvnGWmjECBSjMW4rr+cPGD804lzYGQAXfxOf3XPVt0+3Wfbt+edX6NWrl55euHChTF4lhEgS8sgmhEiVNmzYwNatW/X0woULcXrSEvEMRx49YuLNm3q663LIb+nZvKPDDi4ZLgGQ3cWNVUsDUaKiAThHGb5hDunTw/bt1rFuQgiRlhQqBBMnWtMTJsCl5sMga1Yt4/p1WLyYxkUbUzVPVQCMJiPTjkwj37fWVt6Pp0XqD5i7QkLwtHzJmJDOnTvrk1dduHCB/fv3v3KdhBBCAl4hRKoTEBBA37599XTPnj2pX7/+c/d5HBtLp0uXeDJnaLnz0NYysXNwvWBmZJ+hl111thC5zvgCEIELbdlIFC6sXg2WHndCCJEmffUVVNViWWJioOs3mTGPtA4dYcIElEePGFd3nJ71g+cPmFqZsM+mzdKc/aSRpmHWVt5piWzlzZQpE51sxg0vXLjw5SsihBAWEvAKIVIVs9lM9+7dCQkJAaBAgQIJTlSlqipfXL6Mb1QUAOkjYdhEMJhBzavStVpXsKxiNMBUhSbrTuj7fskKLlGKqVMhEUv7CiFEqmYwwPLl4OiopY8fh3kxHlrzL0BwMEyZQqMijaiWtxqgtfJO95wep5W35cxo/fWW+/e5EhGRqPPbfpm5bds2/P39X7FGQoi3nQS8QohUZebMmfz55596evny5bi6uj5nD5h5+zZbg4L09IDvIWcgYA9Dmw8l1EnrblfT6R2mTj6ul5vGEDbSjl69YMiQpK2HEEKkVKVL60vvAjB8nBMB/SdbM+bORbl9O85Y3mWey1A6K9hn0Vp58+8zUi9S655sBqbbzIz/PGXKlKFOnToAmEwmFi9e/Ep1EUIICXiFEKnG+fPnGT58uJ4eNGhQgl2Z/wkJYei1a3r6061Qf4/2elPzTZzIrrXm5nbIxpap13C09Hn+H40YwWQ+/hgWLNAmdBFCiLfF0KFQvrz2OioK2m1tg/ree1pGdDSMGkXDIg3jtPJOOT2FvAPy6sdovTBGf73q7l2uW9Y+T0i/fv3014sWLSIsLOwVayOEeJtJwCuESBUCAgIYP348JpMWkVarVo3Jkyc/d5+L4eG0On8esyVd+gJ4WBoLPGt6sriMlnC0c2DryghyPtKOfYZ3actG6tQzsHkz2Nu/lioJIUSK5eAAK1ZoXZwBDvxrx6/Vp1sLrFmDcvw44+uO17OWeS4jsmMk9pm1D80SfxipFqWtyxurqkyymTTweVq0aEHhwoUBCAkJYcWKFUlQIyHE20oCXiFEihcZGUnz5s0JsnRLzpIlCxs2bMDBweGZ+9yNjqbJ2bM8sgTIbkEwdhw4xELAOwEMqzdMH7e7eocDVa9qLQ+3yMdH/EXJqpnYvh1cXF5r1YQQIsWqUAGGDbOmOy2vS0SD5taM/v1pULA+HxT6AACTamLkiZF6K68CfD47Vi++6u5driWildfe3j7OMnOzZs0iNjb2OXsIIcSzScArhEjRzGYzX3zxBSdOaF2PDQYDGzZsoECBAs/cJzgmho/OneNmtDZpikskTBkG2YPgkfsj+jbrS4y91tXu+wMutD2uTaYSRDYa8z8K1cjNzp2QwNBgIYRI80aPhpIltdfh4dDt0SzUJ0vAnTiB8tNPTP/Q2vK77fI2/D7zwyG79oVk6V0xVA/V1ug1QaJbebt27YqbmxsAN2/eZPPmzUlTISHEW0cCXiFEiqWqKv3792fjxo163ty5c2nYsOEz93kUG0ujs2c5bRnzZTBpLbtFfSEiUwR92vQhxFWb4fnbk44M3KO1NjwgK/X5B/e6pdi5EzJlen31EkKI1MLJCVauBDvLE+OG44U5XGOwtcCwYVRKV4QOZTvoWYOPDCb/yPx6uuMM61jen+7e5VJ4eILnTZcuXZyxvFOnTsVsNj9nDyGEiJ8EvEKIFGvkyJEsWrRIT3/66adxlqx4WnBMDI3PnuVkqDbrsmKGQTOg6nGIdonmm7bfcCfbHQD6nTDw/Q4jACFkpgF/U7hFOf78EzJkeI2VEkKIVKZq1bizNn90YDjR7pYliO7fh2HDmPTBJBwN2lpGR/2Osq/GPpwLai27pQ+aqPnA2so7zGYiwefp27cv6dKlA+Ds2bNs27YtaSokhHirSMArhEhxVFVlxIgRTJkyRc9r167dc4Nd/+hoant5cfTxYz1vwGxovBMiXSL5puM3XMl9BQCPEzDvDxMKcIdc1GE/tb+uyJYtMmZXCCHiM2oUVNMmZCbUlI6BymzrxqVLKXjBnwHVBuhZg/cPxn20u57uOta6Lu9vDx5w4OHDBM/p5uYWp5V37Nix+sSFQgiRWBLwCiFSFLPZzFdffRUn2P3kk09YvXo1hifThT7lfFgYNT09uRARoed9PQea7oBwl3C++fwbLue9DMCIA7DwD20ylSsUpY7hEL0XvsucOdbZSIUQQsRlbw/r1ll7wCy825Iz+ZtaC/TsyahqQ8jtmhuAwPBAFuZeSIZK2g5FL6h84u2kFx/k64tZVRM87+DBg8lgOemFCxfYtGlTEtVICPG2kIBXCJFiREZG0r59exYsWKDnfYjfajkAACAASURBVPzxx2zevPmZMzJvDwqiupeXPkGVIRZGTIIW2+F+pvv069oPnzw+KCrM+xMm7dGC3f3U5tMch/npQCH69HkTtRNCiNStcGFtXXKNQtNbC4h1Tq8lL14kw6wFzGw4Uy8/98RcDOOs3yR2HBuNk6pNj38iNJSfAwMTPKebmxtff/21nh43bpzM2CyEeCES8AohUoSAgADq1q0b59v7tm3bsm3bNpydnf9TPsZsZsS1a7Q4f54wSxc3lwiYOAoa7AZfd1/6dOvDDfcbuEbD9vXQ/7i27xJ6MbPR3/xzNjs1aryR6gkhRJrQuTO0aaO9vk1+xthNtG6cMIG20e9Qp0AdAGLNsXjc9SB7h+wA5AyEtrutC5sP8vXlYYx1QqtnGThwIBkzZgTAx8eHpUuXJlFthBBvAwl4hRDJbu/evVSoUIHjx4/ref369WPdunXxtuxej4ykzunTTLl1S8/LdQcW9oVqx2BfqX30/7I/QRmDeOcBHFsGTX0gjPR0d/iJ2PlL2P6XI+7u/zm0EEKI51AUWLIE8mpL7TItoj9nM1TXErGxKF26sOjD2foEVsf8j7G37V7s0muPnG1nx5AzWmv1DYyJYfSNGwmeM0uWLAyzWRB4zJgxBAcHJ12lhBBpmgS8QohkYzQaGTt2LB9++CGBlq5tBoOBBQsWMH/+/P+M2TUDC/z8KHviBEdsJqeqfAIWe0D+myaWNFjC+NbjiXSKpPNpOLUUSgbBSSrRr7onIy53pl8/7aFNCCHEi8uSBX7+WZv3wIyBVmE/EW2vzabMhQuUmvszo2qN0ssPOTeEjEO1Ftp0kdD7e+vEU4v8/fG0zKz/PAMGDKBQoUIABAcHM378+CSskRAiLZOAVwiRLDw9PXnvvff47rvv9LUVc+TIwc6dO+Odjfn448f0B/pfvUq4pbwhFnouhWlDIdTej/7d+rOx5kYyR8HaX+CnX8HR6Mj0zJO5svooKw8Vo3DhN1lLIYRIm2rVgunTtddXeYcBsTOsG7//nqHh5SmboywAkbGRfJ3razJU1iafqr0bql3RujabgS8vX8aYwBq7zs7OzJhhPcfChQu5cOFC0lVICJFmScArhHijoqOjGTVqFFWqVOHs2bN6fu3atfHy8qJ+/fpxyvtHR9P50iWqenpy0Sa/4HVY0A/abDSxvfI2evTqwaW8l2h5ES4thI7nYJd9E9YNPsNXAcNp38leWnWFECIJDRhgHc+7GA92Ko30bY5dvmR5tckYFK2nzgH/A+zrvQ/FXkEB+o6PxcmsfSifCQ/nu0R0bW7ZsiV16mjjg00mE927d5dlioQQCZKAVwjxxvz9999UqFCBSZMm6Q8pLi4uzJo1iz179pA7d2697OPYWL67cYNix46xxmYmTwcjdFoNS3uBOewiHj08mPfxPAo9juKPdfDLJngQXpolLXdSOfAPvpxegnjmvBJCCPGKFAWWL4cyZQAUOqmrCVAsn+NBQbz31TTG2nRtHuo/FDy013n9oftS67JEU27d4pjNUJX4z6ewYMECfW6Ho0ePMm/evKSskhAiDZKAVwjx2nl7e9O0aVMaNmzIpUuX9PxatWpx5swZBgwYoI/XfRgTw3c3blDg6FHG3rhBhE03t1oHYOUX0GrDI+Y2nkG/bv14mOkKi3fA2cVQ6ao7vzdZTHa/0/T+pSFZs77xqgohxFslQwbYsQPc3eE+OWirrsf05PHy338ZsSWQ2gVqA2BWzXTN3xXnStq3kC03QwVvrawZ6HTpEo8TWHKoTJkyjBplDaJHjhzJ1atXk75iQog0QwJeIcRrExwczLfffkuZMmXYsWOHnp8+fXrmzZvHvn37eOeddwC4bzQy+vp1PdB9aPPQU9gXZg2A4RMj2V/oZzr378yBMn8y7JDK1XnQ5HQh/m29iAz3rtP0j97kyG3/n2sRQgjxehQoAL/9Bs7OcJDajMK6VJFh0RLWPvqQLM5ZALgRfoMpradgl8EOOxUGjzOTzqh1bb4SGckXly+jqmq853li2LBhvPvuu4C2fnvHjh0xGo2vqXZCiNROAl4hRJILDw9n8uTJFC5cmNmzZxNrCV4VReHLL7/kypUr9O/fHzs7Oy6Eh9PD25t8R44w8eZNHtuMx8rjB0Onwrw+Ufi4bKTD1x3YVmMZQ4485tZs6HWyLDcHrCNvuA91N3iQ3s0luaoshBBvtSpVYMMGbebmqQxjA231bfm+Hcfa/N+gjd6F36J+43CPwwDkugvfTrMGuFuDgpjl5/fcczk6OrJixQrs7bUvN48fP87QoUOTukpCiDRCAl4hRJKJiYlhyZIlFC1alJEjR/Lo0SN9W61atTh58iTLly/HPWdO/vfgAY3OnKHMiRP8GBBAtM03+vluwYhJsLBnGI8eb6RT/w7srLKE7w485Ooce1qGtUfZuJ8CIWcoO6UDdo7SoiuEEMmteXNYsQJA4QtWcpz3tA1mM026TWVKkV562eGZhnOvxT0A6u+BT7dZjzPU15e/Hjx47rkqVarEtGnT9PScOXPYunVrUlVFCJGGSMArhHhlZrOZTZs2Ubp0aTw8PLh7966+rVixYmzZsoX9+/dTslw5frhzhzLHj/PRuXPsCgmJc5xi3jD6O5j6zV28DQv4/Ku23CmwhJ+3h3B8dSFq5O9DJj9/Snr+TOZmtWUxXSGESGE6d4b58yEKF5qznZvk1zZERjKk7zra57HO5NyxTEciK0UC4LEISlmmeDABrS9c4GQCk1gNGDCA5s2b25y7M56enklaHyFE6icBrxDilezevZsqVarQtm1brly5oufnzp2bH374gQsXLlDzk08Ye+MG+Q8doZePD5ciI/VyilmbjGpef+gz+SwH3MYxuGtHShp/4eQKe5bH9KLRqkO4PfAltG9ryJEjOaophBAikfr1gwUL4C65+JDd3MUdAOVxKMuHH6NOlgoAxNrH0qF+B0x5TDjEwnejwF1r9CXcbObjc+e4GhHxzPMoisLKlSspVKiQtk94OB9//DE3b958vRUUQqQqEvAKIV7KyZMnadCgAQ0aNODUqVN6fubMmZk6dSpXrlyhavv29LhyhQKHjzLh5k2CzNaJqFwioNUWWNElmmq//sm8mj3YUedrPC4exNPzY8Z7bKH47Xu4bVmCUrOGtOYKIUQq0revtmSRr/IODfibYLRJq1yCHrJ9nDcV0hcF4GG6h3zZ8ktMWU1kC4Zpg8E1TDvGvZgY6p4+jc9zgt4sWbKwY8cOMmfODMDdu3f56KOPCLRZzk4I8XaTgFcI8UJ8fHxo06YN7733Hrt379bznZ2dGTp0KFd9fXm3e3eaXfah3MmTrAoMxKhYx+e639W6ri3oHoiD91ImN2uDQ5YZbPVMx84qC2i7LxD3fb9h17oVODklRxWFEEIkgS+/hK1bwdelLB+ym/u4AZApJIK/Jt2khEMuAG5lu0WvNr0wZTBR4BZMGg6O0dox/I1G6p4+zaXw8Geep1SpUvz66684OjoCcOnSJerWrUtAQMDrraAQIlWQgFcIkSh37tyhd+/elCpVis2bN+v5BoOBHj16cNnHhxJff03Vcz40OXeOfx4/jLN/yYswdhwMHOnJeWU02+p0oFXYbi5k7sukRZcpe/wMdv36gpvbG66ZEEKI16VFCzhwAAJyVqQWB/EjDwDuD2PYPzmAcqbsAPjm9KV/2/4Y0xspex6mDAfnKO0YAUYjNb282PfUvA+26tSpw5o1a7Cz0x5tL1++TJ06dbh+/frrraAQIsWTgFcI8Vzh4eGMGjWKokWLsnTpUkw2ywa1atUKr7NnqTpuPDUu+/GFtze+apS+3c4EdfbBzK+jabziN3bl+4LwwsNZ55qb33v9w2eHAnGYNBmKF0+GmgkhhHgTKleGEycgW40S1OQQ5ygDQI5w2DvjPtUeuQJwKd8l+nTqQ1jGMCp6wZRh4GyZ8iEkNpaGZ8+y/Dmttm3atGHDhg0YDAYAbWhN1aocPnz49VZQCJGiScArhIiXqqr8+uuvlCxZkkmTJhFpM9FUvXr1OHz0KB/OnM8HNx/S3cebOw7R+vZ04fDZZpjZJ5CchxdxoshnNMyzi4MNxjHu12Dy/bgR6tYFO/kIEkKIt0HevLBvH7QeWIAaHGY7zQDIEgV75ofS9rIDoLX09urSi7vZ7lL+DMweAFktKxTFqCrdvb3pcukSYbGx8Z6ndevWbNq0Se/efP/+ferVq8fSpUtRbZa/E0K8PeRpUwjxH9euXaNp06Z8+umn3L59W8+vUKEC//vf//BYtYlWgeBx3ZsgF6O+PeMj6PYjDBvqRUjgCG4V+4KppdOzfsJRGm8/j6FzF0ifPjmqJIQQIpk5OMD338PWXa58lXcbYxiPCTtcYmH9hhgm/gOKCney3aFH9x6cKHKCEt6wqA8U9rUeZ3VgIJVOneKQzVrvtlq2bMmePXtwswyRMRqN9O7dm9atWxMcHPwmqiqESEEk4BVC6EwmEzNnzqR06dL88ccfer6bmxsrV65k+q978QjNTptr5wnIaG3xzfgIui+Dr8ccxcfci4yFJrOtXmtmbbhPwdkroXTp5KiOEEKIFKhBAzh3wY57vcZQhwPcoAAKMPIg/PMT5HkMYS5hDOs4jHXvryP7fTML+kGj/1mP4RMZyfteXvTx8SEkJuY/56hZsybHjx+nbNmyet4vv/xCqVKl2Lhxo7T2CvEWkYBXCAFoE3y8//77DBo0iKgobRyuoij07t2bf06cZ5FjNRpc9eK622N9H5cI+GIF9B97iCtqD/KVWsHuNpP5ensgrn0HSGuuEEKIeGXMCEuWwNyTNelW+SwL6IsZhXo34MxiaHsezHZmfvzwR77t8i2PnO4ybBoMn6z97Xli8Z07FD12jHl+fhjN5jjnKFSoEMeOHaNPnz56XmBgIO3ataNx48b4+voihEj7JOAV4i1nMpmYMWMG5cuX5+jRo3p+uXLl2H/wMKF1R1P5nA8nct/VPzHsTND8Vxg+7Dw3jb0pVupndvf6gR7rfXBs0UrG5gohhEiUSpVg9/GM5NqygPYFjnCSSmSLhA1b4I91UOAhnCl4hu4e3dn23jY+/NvMqq5Q3WYequDYWL6+epVix46x9M4dom0CXxcXFxYuXMj27dvJnTu3nr9r1y569OhBly5duHjx4hussRDiTZOnUiHeYteuXaNOnToMGTKE6Ght0ikHBwe+++47uk/ZSxNvA+vcfYhxtc7MXO0ITPjWj8jbw8lcbj5/eSyi888XsK9TL7mqIYQQIhVTFGjVCtZdrYr36uMMy7eOGxSgyRW4uBBtbK8SzryP5+HR04N7TueZNBLGjYVcd6zHuRkdTW8fHwocOcLo69e5HWVdNaBZs2ZcvHiRvn376ksXqarK6tWrKV26NE2bNuXgwYPS1VmINEgCXiHeQqqqsmLFCsqVK8ehQ4f0/IoVK7Ll12P87NSBrxzOEFY4XN+W6w6MHBdBngOziS4xhM09htF/jTeOdT5IjioIIYRIY+ztoWMnO6bc7IDP7z4srPAjATGFGXkQfOfBwMPg5+ZD/279Gd1uFAUu3WBVV+i9GDLZLP0eGBPDxJs3KXj0KJ+eP8+u4GBMqkqmTJlYsGABZ86coUmTJnHOvWPHDmrXrk316tVZsWIFoaGhb7byQojXRgJeId4y9+7d49NPP6Vbt26EhYUBYDAYGD16POU67qRNUBSXq9xGtdfKOxihyypoPfdPruf8glmf1WH8z7fJ2Lh58lVCCCFEmqUo0PATR/p6diP9bW+2dNrOJXNjpu9SuDEHRh8An3yH+NLjS8a2Hs47JzxZ314LfLMFWY9jBn4NCqLR2bPkPXSY/leucOjRI0pZJmacP38+LVq0QFEUfZ9jx47RrVs3cubMSadOnfjnn3/irD8vhEh9JOAV4i2yY8cOypYty/bt2/W84sWL8930gyw0tWVl+fNE57eup/vuGRg17DoBkX1o0tifdSuuk7/bt2AwJMflCyGEeMvkzGvPZ6ubUSvsLzw3XuVcqSF8vd+NW7Nh1XYVF4ejDOwykP5du5PJ+3+s7mhk3Fio4Bn3OHdjY1jg78/7Xl7k//cIX125QkSZMqzfsoWLFy/SvXt3fe1egIiICNauXcuHH36oB7/r16/nwYMHb/g3IIR4VRLwCvEWCAsLo1evXjRt2pR79+7p+Z069SVDnb+ZkNtMcIMA/RPBJQL6zjNS8o8F2Jefzm8TttBo/DpIly6ZaiCEEOJtZmcHldsU5oMT08gaeYdbs3dSku5sXZuVG7Phiwu+bK09jXbffMapjLPoOvcsq7pAy18gy1NL7/qbjMz392cokPXAvwwOj6by+PHsv3yZGTNmUKZMmTjlg4KCWLt2LR06dCBHjhzUqFGDiRMn4unpifmpmaGFECmPfXJfgBDi9Tp69CidOnXi6tWrel6uXLmo3fgHtuYsSHjDuMsyVD0KtX49QWD+BUzrMYoCn23W+pcJIYQQKYDi6ECxfg2hX0OIWQRb99Bm+W90+2kn/ul92V7id5Y3+Z17Tjmpf64+E7fVItK9OPvqwoHa8DiT9ViRisqO0BB2hIYAkLdidep9+BFt7vlz/ddf+XPrVgIDA/XyZrOZI0eOcOTIEUaPHk3OnDlp3LgxTZo0oUGDBmTOnPkN/zaEEAmRgFeINComJoYJEyYwadKkON9Av/9+K666TeDXpveJzmId7JTxEXT58TG3+Z5a9d1pNvKStOgKIYRI2RwcyNy2EZnbNgLA3fca+dbupOu2XUT7/82uIuv4X+11XMjiRmnv6gz5oyaGjBU59Z4DR6uBX764h/Ozi2HNw/vg6Aht2lC4ZQc+fRCIo9cJfPfv59SxY3Fmcr579y6rVq1i1apVGAwGatasSZMmTfjoo48oW7ZsnPHBQojkIQGvEGmQt7c3n3/+OSdPntTzXF0zUqT8bLzqlye8TmCc8vX+USn6759kyPc7a4euJ33pCm/6koUQQohXphQpTI6xHuQY6wExMZQ8epQvft9P6K6D3Ar+hyN5f+ffPI4EBZemwY/lyRNZlaCCRTldwcCZchD51Pe81+xjueaeDRo3hsaNKR4SRcGrF4g6fpRze/cSbDOm12QyceDAAQ4cOMCwYcPIkycPTZo0oUmTJtSvXx9XV9c3/NsQQoAEvEKkKaqqsmjRIgYPHkxkZKSeX6hwbQJLTuFSLyPRro/1fLf70G5VAIFOU+jXpSPvdrkk3ZeFEEKkDQ4OUKsWGWvVIuN0yBMbS/Vz5+i35yDBOw7ic3Mbp3Kt5LLZGWevsnT4qwJZlWo8yFeA0xXsOF8GjE5xD+mdxRnv9yrBe5VQevWmuM9Nsl30IujQv/icPh2nrL+/P8uWLWPZsmU4ODhQq1YtPQAuUaKEtP4K8YZIwCtEGnHjxg08PDz43//+p+fZ2zuSruhIAgfWJaKoMU75j3bEkuX8at4tdYduY/ZjlznLm75kIYQQ4s2xt4cKFXCsUIGcA7/i8t69DMifn28O/kvwnwe4GLyTU64/cCMyPVmPlKXL9kq42lflXsG8nK6gcKkkmGyenFV7A96lCkOpwvBZKxyCgil46iyO505x89+DhD16pJeNiYlhz5497Nmzh0GDBlGwYEG963O9evVInz59MvxChHg7SMArRCoXGhrK1KlTmTlzJtHR1iWFnDKUwuHzMTxu6462GqEmtz98vP4S9hnmM27sPHJU/zAZrloIIYRIZooCRYqgFClCtq5dqAXUun+fbw4dInzXATxv7uKk/SL8QzKQd++71NxUBZd07xFQKBeeFeFqUVBt1juJccvKlUZ1oVFdGPANjucukuukF0avYwRcvBjn1Ddu3GDRokUsWrQIJycn6tatqwfARYsWldZfIZKQBLxCpFKxsbGsWbOGESNGcPfuXZstCo7VPid6TEeiXax9sZwjodWmCGKD5tKuxXt88OV5bZ0HIYQQQmiyZ4cWLUjfooUWAIeFwbFjRO4+wImg/3EydAH37qan+B/lqB9SBYcM7+FXNDueFeFmQZvjGAwYy5flZvmyQGe4fx/noyfJfOokIaeOEx0WpheNjo5m586d7Ny5k6+//ppChQrRqFEjGjZsyAcffECmTJkQQrw8CXiFSGVCQ0NZvnw5s2fP5tatW3G2OeQuQcywPhjLlo2T/8FuMyX/3UW5mtfpOn8zDhkyvslLFkIIIVKnDBmgfn1c6tenNuOpHRMDXl5E/7OfY/v/4kToQh7ecKH89fJ8FFoVu4yVuFksK14V4E4em+Nkz05U04+42/QjiImBCxdwPnwMx5MneHw97vKA169fZ8mSJSxZsgSDwUD16tVp2LAhjRo1olKlShgMhjf7OxAilZOAV4hUQFVVvLy8WL9+PT/++CMPHz6Ms13JnBW1d09iGjSI02pb6YRK2YNHKZP/GL1/nkP63AXf8JULIYQQaYiDA1SpglOVKtQePpjaZjN4e2Pcu59ju//gaPBiwi87UP1iBbJHVUfNXJ5rJTLhWREeuNkco3x5osqXJ4pecPcuHD+O4cgxOO2FKco66aTJZOLff//l33//ZcyYMWTJkoWaNWvy/vvvU7NmTSpXroyzs3Py/C6ESCVSVcCrKEofYDCQC7gAfKOq6sHkvSohXo+oqChOnTrFjh072Lx5M76+vv8tlCkTtGyJ2ro1uLjo2e8dM1Nx/0lKFfWi0w9TyJJz+Bu8ciGEEOItYWcHJUviWLIktfr0phbArVvE7tvPsZ2/cejuYmJO25HZswJZY2tiyvYuPqUycLo8PH7SUzlnTmjWDFOzZnrrLydOaD9XrsQ5XUhICDt27GDHjh0AODo6UrlyZWrWrEmFChUoV64cxYoVw94+VT3iC/FapZp3g6IobYG5QB/gX8u/fymKUkpV1VvP3VmIFMxsNhMQEMDVq1fx9r7K8ePnOXzkCD7enphMMfHvlDcvtG4NjRqBkzZON1041DgYSV7fvTSqGEOrjeNwcJVxP0IIIcQblT8/9p07UbNzJ2oC3L+P+cBBju3czuEbP+B00EzBA2Wxc66BKUtpbhXNzNl3ISQreusv5ctDjx7w8CGcOqUFvydPgs26vwBGo5HDhw9z+PBhPc/JyYlSpUpRtGhRihQpQpEiRShUqBC5cuUiZ86cZMmSRSbFEm+VVBPwAt8Cq1RVXWZJ91cUpTHgAaTK5qvPO48k8FEIxmgjjrM3JXIvFVTFJqW+8nWoquW48Z0Ly7kS+FxU1Wdfx3M22Zwn/qwE6/eMzerzNj53P+2MMbGx2E9dra9J++RXpCpYKqRiVs2oqor65F/zkzT6a5PZRIwphthYIzGmGEyxRmJjjRijIoiJDMMYGUpMRChq7DMCW1vp00ONGlCvHlSpAgYDdiYoeS6W0p4+VI86z0fftKB41ekJH0sIIYQQb0b27Ni1akn1Vi2pDhAWBp6eXN37D3vOzuDikTuU2F8Ao1N1orOV5l6BXFwpZuB2PjBnzgz162s/qgp+fnDunPZz/ryWfkp0dDReXl54eXnFezmKwR6HdK7YO7pg7+SMg6Plx8EZg70Ddnb2KHYG7AwG7Az22NkZtDyDHaDoj4Qqlsckm2cqBUV7ZrTN+88zpO0R+E/wbTKZsTcse2oXrYyiP1TGfT6NewzVei22WU+O8Z/jqiiqbTr+y1VURT+Piqpl25RXnro0UEBVtX3ifZy22Ze41x+nPqpWP9tzPuuxXP/9x3c25emyT5dR/lvGkmGMNpJ18e9s2zjzGWdO2VJFwKsoiiNQCfj+qU27gBpv/oqSxi+HthF17VJyX4ZIyfLlg9KloVYtqFwZHB3JHqhSfP8j3rl1nYqugdTr+iGl+/dJ7isVQgghRGJkyAC1a1O0dm2KMl7Le/AA0/HjeP67j2NXVuJ3LJRQcw4eZS5PVJbiPMqRg5uFnbhRMB8x+fJBkybafsHBWuDr7Q3XroGvL9y//9zTq6ZYjKEhGAl5zRUVaYldjpxA6gx4lee1zKUUiqLkBvyBOqqqHrDJHwN0VFW1+FPlewI9Adzd3Stt2LDhTV5uon3UrY8EvEKTMSPkyaP/KO8UJ4t7SbLFupApOIyc9x6QL/Q+BTM8Jn/5vLgXLPNWdkcKCwsjQ4YMyX0Zwobck5RJ7kvKI/ck5Unx90RVcQgJwex7Dd+r3vjfu0fEQ5Vwe3ceZcpJSLbsPM6clYgMroRndCEsowPBWRUeK4/h1i24cwf8/bV/792DkBCtS3RERHLXTKRCdjly8s/G9cl9Gc9Ur169U6qqVo5vW6po4bXxdHSuxJOHqqo/AD8AVK5cWa1bt+7rv7KX4O5ehIfpkmB5mBcMfJT4vuNI1DES+nLkOcdI4PjP3fpKgV28/TfiSajxFFPiLfmkW4yiKCh2dqDYoSh2li4rivVfOy3P3t4Be4Mj9gbtXwd7RxwdnXFOlw5Xl3S4OaUnm5MzWZwdyJndiVy5XClVJB/5SpbAwSXdK9Q97dm3bx8p9f38tpJ7kjLJfUl55J6kPKnpntR61gazGTU0lAf+AQTcukOQ713uBQQTEBZNcHQWwpyyEF2wPFGFDUQ5GDAaFKJijEQbI4mKjSbGaMQYY8QYG40xJhKzKQazKRbVbEI1mTCbTag2adteu/8ZdvakEc3muS3BhjX1v4PQVMuQOiVOOp7zPNU1+lmv4iSVpw7xrPLxXurTZWzTyn/L6MPgbNNP7/3sYX3W5DPq8qzzxHfUp6/9JfZxdsqQat4vT0stAW8QYAJyPpWfAwh885eTNG4c/h1IXR+4bwu5J0IIIYRI8ezsUDJlwi1TJtxKlUjuq0kS8gyW8qT2e2KXcJHkp6qqETgFNHhqUwPg8H/3EEIIIYQQQgjxtkstLbwAs4A1iqIcBw4BvYHcwJJkvSohhBBCCCGEEClSqgl4VVXdqChKNmAUkAs4DzRRVfVm8l6ZEEIIIYQQQoiUKNUEvACqqi4CFiX3T75IBgAAC9ZJREFUdQghhBBCCCGESPlSxRheIYQQQgghhBDiRUnAK4QQQgghhBAiTZKAVwghhBBCCCFEmiQBrxBCCCGEEEKINEkCXiGEEEIIIYQQaZIEvEIIIYQQQggh0iQJeIUQQgghhBBCpEkS8AohhBBCCCGESJMk4BVCCCGEEEIIkSZJwCuEEEIIIYQQIk2SgFcIIYQQQgghRJokAa8QQgghhBBCiDRJAl4hhBBCCCGEEGmSoqpqcl/Da6Uoyn3gZnJfRwLcgKDkvggRh9yTlEnuS8oj9yRlkvuS8sg9SXnknqRMcl9SntRwTwqoqpo9vg1pPuBNDRRFOamqauXkvg5hJfckZZL7kvLIPUmZ5L6kPHJPUh65JymT3JeUJ7XfE+nSLIQQQgghhBAiTZKAVwghhBBCCCFEmiQBb8rwQ3JfgPgPuScpk9yXlEfuScok9yXlkXuS8sg9SZnkvqQ8qfqeyBheIYQQQgghhBBpkrTwCiGEEEIIIYRIkyTgFUIIIYQQQgiRJknA+5opitJTUZS9iqI8VBRFVRSlYCL3a6UoykVFUaIt/34aT5k+iqJcVxQlSlGUU4qi1Erq60+LFEVxUhRlvqIoQYqihCuK8puiKHkT2Gef5f49/XPBpsy4eLbfff01Shte8r50fcZ9cX6qnLxXXsJL3pMeiqIcVBQl2PK5t1dRlPefKiPvlRfwov9/FUUpqyjKfkVRIhVF8VcUZYyiKMpTZepYjhWlKMo1RVF6v95apC0vck8URamrKMp2RVECFEWJUBTlrKIoX8ZTJr7PshKvvzZpxwvel4LP+J03fqqcvFdewQvek/j+Njz5yWEpI++VV6AoSm3L33J/y++tayL2SfV/UyTgff3SAbuAcYndQVGU6sBGYB1Q3vLvZkVRqtqUaQvMBSYDFYDDwF+KouRPsitPu+YArYD2QC0gI7BDURTDc/ZpCeSy+SkIhAKbnirn/VS5skl54Wncy9wXgAji/s5zqaoa9WSjvFdeycvck7pon1/1gapo74mdiqK881Q5ea8kwov+/1UUJSPwNxAIvAd8BQwGvrUpUwj403KsCsAUYL6iKK1eX03Sjpf4TKkBnAM+A8oAi4EfFEXpEE/Z0sR9X1xJ2qtPu17hs74xcX/ne2yOKe+VV/AS9+R7nvp7DuwH9qmqeu+psvJeeTkZgPPA10BkQoXTzN8UVVXl5w38AJUBFSiYiLIbgb+fytsNrLdJHwOWPVXmCjAlueuakn+ATIAR6GiTlw8wA41e4DgdAROQzyZvHHA+ueuYGn9e9r4AXYGwBI4t75U3eE/iOY4C3AX62+TJeyXxv78X+v8LeACPARebvFGAP9aJKqcBV57a70fgSHLXNzX8JMVnCtqXpb/YpOtanhHckrt+qfXnJd4rBS2/88rPOaa8V97gPYln/3yWZ60ONnnyXkm6+xMGdE2gTJr4myItvClTdbRWYVs70b4lRlEUR6BSPGV2PSkjnqkS4IDN705V1dvAJV7sd9cD+Muyr63Clu4e1xVF2aAoSuFXvuK3w6vcFxdFUW4qiuKnKMoORVEqPNkg75VXklTvFUfAGQh5Kl/eKwl4yf+/1YGDqqrafnO/E8iN9oD/pEx8f2MqK4ri8CrXnNYl4WfK/9u71xA7zjKA4//HBAQRCxpL8IPSUi8R1FjEW2maSkNJKqhtiRcKsfWK0NZeLBQlJVD1g7eI2KJWKSJShYqoNSAuitqska34wUuCVWNBrW3qpdbSbCKPH97ZdnJ2zu7ZOcmZnDn/HwzszrxnzjvznGdm3rm9z2J5TgAsVLc+z0XEhS2rOXPGjMu3IuKhiLg3Ii4fmGautHSScuVdwL+AuxummSuT0Yt9ig3e09NGyq0DdX+vxgNsANatUkbNNlLOFh4ZGD/yuouIFwEXAF8amHSAcsVxO6VBvBHYHxHPGaO+s6JtXA4BVwFvotx2+wRwb+32WXOlvbFzpXIr5Szyd2rjzJXRtPn9Dtt/LE1bqcz66js13NjblIh4I+WW/3q/ln+jXEm5jPIIzSFgLiK2jFvhGdEmLo8BNwI7gR3AHPCNiLiiVsZcaW+sXImIp1H271/NzKO1SebKZPVin7K+6wpMo4i4FfjwKsUuzMwfj/E1gx0kR8O4UcrMhFFjstIsGH3dvYeywb2nPjIz9w3U6efAH4FdwKdHnHevnOq4ZOY8MF/7vv3Ar4CrKc+ZPFl0LfPts0nmSkRcC7wPuCgzH10ab66s2Vp/v03lB8ePUkbDtdqmRMR5wNeBazLzF0/OLPMQ5cB9yXyUl1zeCPxk3MrOkJHjkplHgE/VRi1ExAbgJuBrq8yzabyatd3/bqfc0nzHCTMzV7ow9fsUG7zt7OXEjWGTB8aY/4MsP/t1Jk+dPTlCufKyUplZM2pMXks547gBeLg27UxG2FBWt+jsojyTcnylspn5WJS3OA++rGeWTCQuSzLzfxGxwFPr3FxZblK5ci3l6u72+oF9E3NlqDa/32H7D2qfGVbmOPBIq5rOjtbblChvK/8+sDszbx/huw4Ab2tTyRl0srb1B4Ara/+bK+2NG5P3Avsz8zerljRXTqVe7FO8pbmFzDySmQdXGR4f4yvmgW0D47ZR3n5GZi4C961UZtasISb3Aceorbso3axsYrR192ZKA+DLqxWM0jXOSyhXg2fSBOOy9JkAXk61zs2V5SYRk4i4HvgocElm/my1OpkrzVr+fueB8+PErrm2AX8FDtfKXNQwz4XMPDZOnfuu7Talut1yH7AnM/eO+HWbMSdGchK39YPr3FxpaZyYRMTzgEtY/ujYMObKqdOPfUrXb83q+0A547EZeAflsv6O6v9n18rMUXtjHeVh/uPAzZSDwJspB56vqZV5K+UNqu+mHIB+lvI8ygu6XubTfaB0CfEXSnK+EvgR5TbYdcNiUhv/QwbeoF2b9knKs71nUbpj+R7lzXbG5BTFBbgFuBg4u8qrr1S58upaGXNlsjH5ULW+d1bbv6XhjFoZc2X0GKz4+6V0/zBXK38G5Wz7XZQucC6t1u0NtTJnAf+lXO3fVM17Ebis6+WdhqFFTLZW6/sTAznx3FqZD1JOqL6Q0t3KxynHDJd2vbzTMrSIyy7Ksdkm4MWUW2IXgetqZcyVCcak9rmPAP8GntEwzVwZLybPpBwvbaZ067i7+vv5TTHpyz6l8wr0faB0v5ENwztrZQ4Ddw587nLgYPWD+V1TIgMfqD57lHIWbUvXyzsNA+WNsZ+j3GbxOPBdat0LrRCTsyldsuwcMt+7KGe8FimNhLuBl3a9vNMytIkL8Bngz1UOPER5K+DrGuZtrkwuJoeHbPPqZcyVtcVh6O8XuBM4PFD+ZZTbzp+gXPW4har7iFqZC4BfVvP8E/D+rpdzmoa1xKT6vykn6mVuAu6n9Iv5D+CnwI6ul3PahjXGZRfwW8qB+qPAAnBFwzzNlQnFpBoX1Xq+bcj8zJXx4rF1pX10X/cpS/0nSZIkSZLUKz7DK0mSJEnqJRu8kiRJkqRessErSZIkSeolG7ySJEmSpF6ywStJkiRJ6iUbvJIkSZKkXrLBK0mSJEnqJRu8kiRJkqRessErSZIkSeolG7ySJE25iDgnIo5FxJ6B8bdHxH8i4lVd1U2SpC7Z4JUkacpl5v3AHcB1EbEBICJ2A1cBb8nMhS7rJ0lSVyIzu66DJEkaU0RsBP4A3AYcBL4IvD0zv9lpxSRJ6tD6risgSZLGl5kPRsRe4AbK/v0aG7uSpFnnLc2SJPXH74GnA/OZ+fmuKyNJUtds8EqS1AMR8QbgC8A8cF5EvKLjKkmS1DkbvJIkTbmIOBf4NuXFVVuBB4CPdVknSZJOBzZ4JUmaYhFxDrAP+AFwdWYuAnuAHRGxpdPKSZLUMd/SLEnSlKrezLyfckX34sw8Wo1fB/wa+Gdmvr7DKkqS1CkbvJIkSZKkXvKWZkmSJElSL9nglSRJkiT1kg1eSZIkSVIv2eCVJEmSJPWSDV5JkiRJUi/Z4JUkSZIk9ZINXkmSJElSL9nglSRJkiT1kg1eSZIkSVIv/R+wDFdjg+k+bAAAAABJRU5ErkJggg==\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/psaapPropertiesTestArmVioleta.py b/psaapPropertiesTestArmVioleta.py deleted file mode 100644 index 9c3d55670..000000000 --- a/psaapPropertiesTestArmVioleta.py +++ /dev/null @@ -1,431 +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]) - -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 setPsaapPropertiesTestArm(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]} * 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]) - - reactionsList = [] - LOGFilename = 'interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - 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 - - diffList = [] - Te = np.linspace(0, 1000, 10) - De_interp = params.D[0]*np.ones(10) - De_spline = CubicSpline(Te, De_interp) - De_Te_spline = CubicSpline.derivative(De_spline) - diffusivity = Diffusivity(interpolate = False, D_expression = De_spline, D_T_expression = De_Te_spline) - diffList.append(diffusivity) - - Ns = 4 - 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) - mue_Te_spline = CubicSpline.derivative(mue_spline) - mobility = Mobility(interpolate = False, mu_expression = mue_spline, mu_T_expression = mue_Te_spline) - muList.append(mobility) - - Ns = 4 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() 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.py deleted file mode 100755 index e02c158af..000000000 --- a/psaapProperties_6Species.py +++ /dev/null @@ -1,430 +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_6Species(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.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 - #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) - # -> 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:22] *= 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) - - # 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,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_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] - - #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 - 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 + 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 - - # 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..99572adad --- /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.66*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.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] + 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] + 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 = C*1.5/e0 + + 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/timePeriodicSolver.py b/timePeriodicSolver.py index c9804a029..59b021633 100644 --- a/timePeriodicSolver.py +++ b/timePeriodicSolver.py @@ -186,21 +186,30 @@ def solveNewtonStep(self, Uic, Nt): print("# Running scenario = 5 (4 species, 7 rxn, Bolsing and Lay, Moss et al, 2003)") 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): 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): + Ns = 6 + elif(args.scenario==15): + Ns = 6 + elif(args.scenario==16): Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") From c29a69ea1aa128f4cbca124b86dcb2b36e52fff7 Mon Sep 17 00:00:00 2001 From: Juan Pablo Barberena Valencia Date: Mon, 7 Nov 2022 11:38:14 -0800 Subject: [PATCH 04/10] Update Sampling script --- psaapProperties_6Species_Sampling.py | 182 ++++++++++++++++++++------- 1 file changed, 135 insertions(+), 47 deletions(-) diff --git a/psaapProperties_6Species_Sampling.py b/psaapProperties_6Species_Sampling.py index 9abed73e7..b79b1ca5a 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,16 +79,11 @@ 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) @@ -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,29 @@ 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", 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", + 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 +264,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" 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): + 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 +325,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) @@ -391,15 +398,12 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa A /= 6.022e23 A *= tau*np0 - A *= 11604**B + A *= ((2./3.)*11604)**B C = C*1.5/e0 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 +411,89 @@ 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)] + #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() From 1eb47fd6e7d13b765e674a89e3cb55e029ee5a93 Mon Sep 17 00:00:00 2001 From: Juan Barberena Date: Mon, 19 Dec 2022 12:51:18 -0600 Subject: [PATCH 05/10] Updated Files --- 4Species_Test/sampleRunCN.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4Species_Test/sampleRunCN.sh b/4Species_Test/sampleRunCN.sh index 03a2f5a0b..68998cd22 100755 --- a/4Species_Test/sampleRunCN.sh +++ b/4Species_Test/sampleRunCN.sh @@ -14,7 +14,7 @@ Np=150 Nt=25600 Nt1=128 dt=0.0078125 -scenario=7 +scenario=5 baseFile="restart_4spec_CN_Np${Np}_" newtFile="newton_4spec_CN_Np${Np}.npy" saveFile="newton_4spec_CN_Np${Np}_fullsoln.npy" From 146f61d936c4d3a4747e068dd04a366834dea7d7 Mon Sep 17 00:00:00 2001 From: Juan Pablo Barberena Valencia Date: Mon, 2 Jan 2023 11:34:08 -0800 Subject: [PATCH 06/10] Added missing input files --- .../1s-metastable.h5 | Bin 0 -> 9344 bytes BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 | Bin 0 -> 9344 bytes BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 | Bin 0 -> 9344 bytes .../3BdyRecomb-ground.h5 | Bin 0 -> 5248 bytes .../3BdyRecomb-metastable.h5 | Bin 0 -> 5248 bytes BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 | Bin 0 -> 5248 bytes .../Deexci-metastable.h5 | Bin 0 -> 5248 bytes .../Deexci-resonance.h5 | Bin 0 -> 5248 bytes BOLSIGChemistry_4SpeciesRates/Ionization.h5 | Bin 0 -> 9344 bytes .../StepIonization.h5 | Bin 0 -> 9344 bytes .../detailed_balance.py | 135 +++++ chebSolver.py | 56 +- generate_sample.py | 2 +- psaapProperties_5Species_100mTorr_Nominal.py | 479 ++++++++++++++++ psaapProperties_5Species_100mTorr_Sampling.py | 456 +++++++++++++++ psaapProperties_5Species_10Torr_Nominal.py | 479 ++++++++++++++++ psaapProperties_5Species_10Torr_Sampling.py | 456 +++++++++++++++ psaapProperties_5Species_1Torr_Nominal.py | 479 ++++++++++++++++ psaapProperties_5Species_250mTorr_Nominal.py | 479 ++++++++++++++++ psaapProperties_5Species_250mTorr_Sampling.py | 456 +++++++++++++++ psaapProperties_5Species_500mTorr_Nominal.py | 479 ++++++++++++++++ psaapProperties_5Species_500mTorr_Sampling.py | 456 +++++++++++++++ psaapProperties_5Species_5Torr_Nominal.py | 479 ++++++++++++++++ psaapProperties_5Species_5Torr_Sampling.py | 456 +++++++++++++++ psaapProperties_5Species_Sampling_1Torr.py | 456 +++++++++++++++ psaapProperties_6Species_100mTorr.py | 483 ++++++++++++++++ psaapProperties_6Species_100mTorr_Expanded.py | 534 +++++++++++++++++ psaapProperties_6Species_10Torr_Expanded.py | 534 +++++++++++++++++ psaapProperties_6Species_1Torr_Expanded.py | 534 +++++++++++++++++ psaapProperties_6Species_250mTorr.py | 533 +++++++++++++++++ psaapProperties_6Species_250mTorr_Expanded.py | 534 +++++++++++++++++ psaapProperties_6Species_500mTorr.py | 6 +- psaapProperties_6Species_500mTorr_Expanded.py | 534 +++++++++++++++++ psaapProperties_6Species_5Torr.py | 533 +++++++++++++++++ psaapProperties_6Species_5Torr_Expanded.py | 534 +++++++++++++++++ psaapProperties_6Species_Expanded.py | 539 ++++++++++++++++++ psaapProperties_6Species_Sampling.py | 64 +-- ...ies_6Species_Sampling_100mTorr_Expanded.py | 484 ++++++++++++++++ ...rties_6Species_Sampling_10Torr_Expanded.py | 484 ++++++++++++++++ ...erties_6Species_Sampling_1Torr_Expanded.py | 484 ++++++++++++++++ psaapProperties_6Species_Sampling_250mTorr.py | 499 ++++++++++++++++ ...ies_6Species_Sampling_250mTorr_Expanded.py | 484 ++++++++++++++++ psaapProperties_6Species_Sampling_500mTorr.py | 14 +- ...ies_6Species_Sampling_500mTorr_Expanded.py | 484 ++++++++++++++++ ...erties_6Species_Sampling_5Torr_Expanded.py | 484 ++++++++++++++++ ...ies_6Species_Sampling_Expanded_NewRates.py | 489 ++++++++++++++++ psaapProperties_6Species_Verification.py | 528 +++++++++++++++++ timePeriodicSolver.py | 19 +- 48 files changed, 15537 insertions(+), 81 deletions(-) create mode 100644 BOLSIGChemistry_4SpeciesRates/1s-metastable.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/3BdyRecomb-ground.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/3BdyRecomb-metastable.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/Deexci-metastable.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/Deexci-resonance.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/Ionization.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/StepIonization.h5 create mode 100644 BOLSIGChemistry_4SpeciesRates/detailed_balance.py create mode 100755 psaapProperties_5Species_100mTorr_Nominal.py create mode 100755 psaapProperties_5Species_100mTorr_Sampling.py create mode 100755 psaapProperties_5Species_10Torr_Nominal.py create mode 100755 psaapProperties_5Species_10Torr_Sampling.py create mode 100755 psaapProperties_5Species_1Torr_Nominal.py create mode 100755 psaapProperties_5Species_250mTorr_Nominal.py create mode 100755 psaapProperties_5Species_250mTorr_Sampling.py create mode 100755 psaapProperties_5Species_500mTorr_Nominal.py create mode 100755 psaapProperties_5Species_500mTorr_Sampling.py create mode 100755 psaapProperties_5Species_5Torr_Nominal.py create mode 100755 psaapProperties_5Species_5Torr_Sampling.py create mode 100755 psaapProperties_5Species_Sampling_1Torr.py create mode 100755 psaapProperties_6Species_100mTorr.py create mode 100755 psaapProperties_6Species_100mTorr_Expanded.py create mode 100755 psaapProperties_6Species_10Torr_Expanded.py create mode 100755 psaapProperties_6Species_1Torr_Expanded.py create mode 100755 psaapProperties_6Species_250mTorr.py create mode 100755 psaapProperties_6Species_250mTorr_Expanded.py create mode 100755 psaapProperties_6Species_500mTorr_Expanded.py create mode 100755 psaapProperties_6Species_5Torr.py create mode 100755 psaapProperties_6Species_5Torr_Expanded.py create mode 100755 psaapProperties_6Species_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_100mTorr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_10Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_1Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_250mTorr.py create mode 100755 psaapProperties_6Species_Sampling_250mTorr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_500mTorr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_5Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_Expanded_NewRates.py create mode 100755 psaapProperties_6Species_Verification.py diff --git a/BOLSIGChemistry_4SpeciesRates/1s-metastable.h5 b/BOLSIGChemistry_4SpeciesRates/1s-metastable.h5 new file mode 100644 index 0000000000000000000000000000000000000000..a2fdd27e48db0e3c46abbc0f33fd9718d0a87cc7 GIT binary patch literal 9344 zcmeI0X;f257RO%*n{0xhf(=brL|hOQ8?{+d1&GKx$RgT`k`NI{2%Ui1Al(YcqPWna z!zzoQL1j*bvH z66|g56y+AlA-pCli%25MU#G%uR?rUW^DROa>bnFJj9`oxj0_3>1cUJY5JX*IR}sYj z*3V<}h7AbUQy5=33YH-zlKh#h&>$ZFuQFi20sf75!`_0s7M{{-!8sEqBh;5bCUHS{ z9_@v~e>h?gd44QGKn!B|H4;XGZ>Sc;6>j5O#&S`Uns@3 z@^lFaen45llY+$v+>wI{d{2I_fPk+P3?hxFab1FaDI^oFMFWHR`egC)!rvMHYWz9E z^+k|_ypG#=Hf6zcxL@k42{9BpqE9N{{%!B>;%du#qWRGg1ShzUZ~esl?=$di9m9eH zLjOt~d1VsTk$2|4jl(++tGM<*I}eKg6o*&BZ{zUx^H<{V&Vg`0yq{cF$c+XloM`D6yP6<`20l0DW_u@s2(4&Pd#^gCdykDJ!j7~ zK8x~9|B>NBnJknK4kqk7&?91k)}7i-{@JL0fStIH^FqW^hD}thEjg&(uQ+n3`z)^2@u`JIT{3V!ct+Eaq+MtTlsO*=#!%wi-Ic$cDjvq1{$OOuF~m#&;2 z=v9X5WDhc9s7=JmnfeI}3FWAsJrkYjJt*R2DW6%(NG7Tm4^-!1R9Gkvm)wsz#}M&0 zPdA31?G;ofkgN@qx<#DiasN$o!c|n)?W-KNF};Sey52emPmYKSs#Ry$$=6XmQ#EjQ z*y#q!s~+k96d_lEGU1(#O2`utkC(qxn{)ams%OxP6H|z{P|k0icB?hJjq?2;4j!FU zzJv0O`dhz{(ZFavj6!__2>xt0Rs-1o?K4&xf=a z;Zwts<=AVgLGcUSI}}TRKVB^F$LXvF!ObysmNYkf{e?WM;*=WTdqQ@Xe-r^fKig6x z(&Z7L$*hs)_|x$hyrx2B6dnVmD=J%}bYt)dj~m@w>K_BEU9C#KMalS6+SXKhS}pL% zdKG7m&Bs@522b|-KLKZkKV}_V!ou6w?z(JdQ3qV{h{|29Kkx%;Dz%MjPl4T+fr}q{ z8}VJ|y2!>8Pr=fhljDv@-r)K5U;{@@V$E8aar|2C-K|BPY@mA%(S!b2z^_L=ur<`g z((~ql@A@)7TRpD_qdMdV7S%f7he8L}?yb+jqfb^fT1_TEzLG7mwc{D6k)4^2PQe4Z zbyjo5?gkK>k5w`zI0Jq?8i49L!!sPUpMZ9+Jx+aCJ@zh zH79%NUQp9H?_EPt6R=AehzQAx22+(RiQ}7^f%lL5y^Izo0nXs6@cI4C;Ay_`^}4`J z5FZe?Iq+l)_@n-VecD3?sPtIuShTJc7%jrvx9nvC`Ob5_1*P>ZAw1a)O zcg&<*eG3du963SAcmX62YFIN)j(~wx^@^TBFG2m28BlQPBWNvW)GoGq1)NqYyAY2^ zzI@CsQ9r1bjHRcKjF-SJ|-ty(x|UNV-(G-_Vyx}{NP#q z>F(EHcI#LdXGj;0nV%02-pK)9a#ELA^euzM-aVQtUvNPFMt93>2UGaF$JN=#+dF}D zR*&CuDGPYkSVPaA(+T9I$Z_Orwy?fWJ}x()3mo5(`^f|E3Vj`e(!0jHfcqI8m%#Qd zu&e5~gP&sFfWc*X2f}m-F!8&^=ijS$18>c`o7*^naL4AK6sk(P!G>jtg&SAUp?0>N z4cWN|U`)=A1X+edxhMB-j1Bex#t%>Aui77i-OA$S?R^gu7@(YnBn^g0QTO-5!NINJw~84e!itT_dZ&O|R;wWS}lta;Dq zUVaANak7f7P#XYIbi3r=jZ)#<&Cje=TL(a$xl7GflMLt@{2d!)zXR+1ZFQa*XTeQv zmbcA=2f^L-db&ZXIk5WCj?8K6A;4NYCC7-(h2{;bos%@*1DQGvoxag?a1}vnXyEgE zuxaJ&M66dn9LZ|^knr;`C{ShljhCEqrlvyeyMNyCAd1v*Jf?kDDb$;n969o4AXQ> z7N!M`fk<{arDd`ZPTVN3cs4l(tgU)I_e&Q;5cJN36E_a>FgJH@kS>9dtDo=vLu&#I zp0)5ujVgf^A0OTTIt#A8lWRDiC;`JxspF`Z zSn$%ao6B>%CE&ugx(KIhEO>NX_gg9z3wx&vmR8(m!Jhg(iHvD1{NUcjIdGQ+uTR=( zI31DXT|Y0Wk|n5z6x??^Yf|?H3z{C*%~!i31-bb+Ia)oZ{_?N~t^Yd7O zdPu|7vX}QTlUVR@M91>9R2isbRHhRd$$|-IbC^xmvT#M*g6v>(9@D!hDo#9{O%_ha8+~+)sHW!-C@mw5Ma5@^F8jL6c?|6BggR6}0`8 zJnYI(k4ddy!iI76yHXbvpru?(ghvuL-%q2TzTc||Th4_<5{TS-Rh}ygP zOqtNVX1~vd#dBe5YN~UO1QRa2QPib~RfYs*@0`PR%yYtzcI<3}Rn){durfuS_`{qIGUELNzA!TsWuk*I&hp0jgNiUkZNg2#tcm{d(SrvjGd;*^j zmBQ6gIhd=7YS4f8ZbC+3DJ;Vh8b~_x;mWeij<~>5xX0@vhIM^Dv^`4JjyEWU?&0By zd7ca4Hb3*7@tq~mgf;s%U~&QPe)Y>TO5lw2k7`mG3*iIDwSDbgC2*sSs}ly{Hr|H| zZu>gtj)G4W2#HK0hSI3PxKI)$ghcZV4Wscs?;sMqj@yL(j(kM0f|2)r%WE`}FEKQL zyPmt0w@~mI5&eEaF*T-8$;NcyyC(1blh-`<1kiEZ|6nR5AlR3T`a59!aDm;e9( literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 b/BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 new file mode 100644 index 0000000000000000000000000000000000000000..da36bca5d10367bc48560f34bf92e2e832036a51 GIT binary patch literal 9344 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 Wk_bp5Ac=q^0+I+wBJh7D0{;MJX_mGC literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 b/BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b8c33b17837a68b95b5adcb87691f677a8252961 GIT binary patch literal 9344 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-ground.h5 b/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-ground.h5 new file mode 100644 index 0000000000000000000000000000000000000000..67dd6a23cc9fb58aa98f24c7b0f66f65318e23b6 GIT binary patch literal 5248 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-metastable.h5 b/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-metastable.h5 new file mode 100644 index 0000000000000000000000000000000000000000..44cb5c1b585bf96976263bd7b809078d48bd592a GIT binary patch literal 5248 zcmeIxc|4R`1HkbyV{Wn(AtX_jyjRJVR-DJtCXubwE!9xjZn;GZ>Waz|t#UQ?os=b% zED_3D#y*T~EZJpjm&n|@#(6%U`{(=qasPOm`F!R)-{*Jc%(IQpUcKD{ysLN#-(NgD z1a5-h-< zxc=hE`5Hlmdtr-bamSDG|LO|t-Gv?ee!>=B<}MR7R&4U5m?-o@}= zj$8!t!djdKxd@7Xuf#=M*ip(^ckwX(Y0|eR|NBfK865)8-*W*$gO8xWCM|rC{B7^| zP9!cY$iw-kkhnP03GVz0GZ#OvEN=WOqp6{h-uHj>!nqI#GMw}HR}SXKkN&s@Ytw@-@=pnjWw>nT}*SY#c`C6>lcoe|q3&!DJT}S1ZR@NaGkq%_bxoQ?o{~xe z@@bljEU6v$jed{3vHOXrU(#rLvtr*#dd~A+vXv6;+ht<_Xqhjy`yXx^uu9 zgX|N}kzePVt;tYNMyA{+Yn$+=AX`Y&+nx>KZc2Rksoo|P^^LOnVe0L;&t)d~BwD1Q z-k=ba`L!OmQkt@;-Jut#JD52nj5OgE43+Z{qokuAG4B~_F^oHaY{}NTmVtW8U}+?m zP$u$dYVpnJ1l&i>jT2<`UZPGpt*fxC2loTB;_e2YSE#S+FBpaDS;*qDTlLMExD!i- z=V<}2Q4bZiV~-kSBdeCn{o=}-gG?EMLXIDBPo%esEPb4dddS5TzaXnT${S1obD*0lYMgQslcSeAdiP+|}_h+9^S0sEbBuNnA55 zM~*)3_ZCM_rm?CMqRQ$bWXb&_vYvNMm^_Di|7DuZ(A=DyZeo( z7nsTKPu@xgs#*5)+2v<+_Re<~C->0-ds_Vj^HGqFwb-y_7_|wgIkR@EH^0}Z8d>S0 zZ`KSpoM_03vYF7aimk4%6JmgmLzPc*&x!%59a0yxY8gOPRV|SCCj<)jeD6_0S^(n| zlT5kl2nJQF1znT%&DdECR!l_lr;E3vF~W>dNY3wU4S{kW$CG%1(3dOFx)<2&M9&YfU_{Y828 z>UNK@6pK%*m0OsAU=VWCeq|x{(Cihv;#eoJY8*Jlvv(8=+aw{om)QwqV%FWyJ1VVP z-OuM0W!nY(54SnxxEtx7+HW7+HPHnQcsS>qrC-9B&OUJGmPwoVSv?pZYwY}Zun!#1;ATnh zHi7YtnkNS9VLSYBJn$wgEk7PQt2+Xw z1s|5&{P7nIm6-Hm|Qj zfqwyX4HoP5UNsA@D1`mzQp8)RscPlPV$1@^`Dd6;ZXxV!wHn7nM9_mJ|U$p5?y8*J-{c;jbV0^e63SjL!V z1KxS}FR5{*@b>bx;#V&cF#F|YorPUxF!HVQgU|g0?1W;VN~BT+)MU$z(b7}14c^(> z(|i6r3H!Yw&PBA320vBX_$ADeFi$onIQ^s=zMk4GVc^S+Nkz`^+Zxtz?gtsWvpe0J zLaK%8x7Njqyd-0VAK_L;PAz1NNXKk5{RwNJ>^(|yuH)Q~pD?<{94||y9^P_oSE4>y zf^9hTh-d9^J@g5S%&6Dp!EUWNv_#`s19YQ{FY6us=CGNM(Z4oAMn<^Iwz#F(IpH4N zEy{G5zWRpb)Nx)c@XAV?1{NJoC|sx-U(JVUT0dK=@UjV}JU`~KwIoj&G9abOv+DCD0n8)KNI;mc1$GuhC#URRhKZA0>tt(NplR6^%U$xz zF=K~(mvrkxbOOkW3i6HSc`9u$M&yG7$p`+Xqywp?Dr`TDO+_yHIGQHSAHUx zsN8^cWoajTL88>2UMq@ywunj%Q0{^@hn{j}z81ySj4C8&1$04E7Z<-6^Oe}GMC*F? mOczwiWcS)mt;C3CU;2hEyW#v#+eOGBVwiO!L*Bor8~z162-|u9 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 b/BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 new file mode 100644 index 0000000000000000000000000000000000000000..455440027d99a610077b7ad66b11aff5fadfc382 GIT binary patch literal 5248 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/Deexci-metastable.h5 b/BOLSIGChemistry_4SpeciesRates/Deexci-metastable.h5 new file mode 100644 index 0000000000000000000000000000000000000000..e9f4046570f37f49b0f0abbf8c1f280bcfced6f0 GIT binary patch literal 5248 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/Deexci-resonance.h5 b/BOLSIGChemistry_4SpeciesRates/Deexci-resonance.h5 new file mode 100644 index 0000000000000000000000000000000000000000..27fb8904858dd07e11eabc5b15022dfaa4f74285 GIT binary patch literal 5248 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_4SpeciesRates/StepIonization.h5 b/BOLSIGChemistry_4SpeciesRates/StepIonization.h5 new file mode 100644 index 0000000000000000000000000000000000000000..beabf8706256f02b129935e5318b6401a4ad972c GIT binary patch literal 9344 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 z k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] + # nominal + Ck = np.array([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + 14: "Deexci-metastable", + 15: "Deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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)"] + + 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)"] + + + reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 + 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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_100mTorr_Sampling.py b/psaapProperties_5Species_100mTorr_Sampling.py new file mode 100755 index 000000000..bd0a0cf2d --- /dev/null +++ b/psaapProperties_5Species_100mTorr_Sampling.py @@ -0,0 +1,456 @@ +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_5Species_100mTorr_Sampling(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 (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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. + 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + #4: "E + Ar(r) => 2E + Ar+", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + #7: "2E + Ar+ => E + Ar", + #8: "2E + Ar+ => E + Ar(m)", + #9: "2E + Ar+ => E + Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + #14: "E + Ar(m) => E + Ar", + #15: "E + Ar(r) => E + Ar", + 14: "deexci-metastable", + 15: "deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + 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 > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 < 7): + A /= 6.022e23 + A *= tau*np0 + elif (i >= 7 and i < 10): + A /= 6.022e23**2 + A *= tau*np0*np0 + elif(i >= 10 and i < 12): + A *= tau + elif (i >= 12 and i < 20): + A /= 6.022e23 + A *= tau*np0 + else: + A /= 6.022e23 + A *= tau*nAr + + 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_5SpeciesRates/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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_10Torr_Nominal.py b/psaapProperties_5Species_10Torr_Nominal.py new file mode 100755 index 000000000..a83dee045 --- /dev/null +++ b/psaapProperties_5Species_10Torr_Nominal.py @@ -0,0 +1,479 @@ +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_5Species_10Torr_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.22e23 # 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 = 1333.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + 14: "Deexci-metastable", + 15: "Deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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)"] + + 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)"] + + + reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 + 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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_10Torr_Sampling.py b/psaapProperties_5Species_10Torr_Sampling.py new file mode 100755 index 000000000..b65b11d81 --- /dev/null +++ b/psaapProperties_5Species_10Torr_Sampling.py @@ -0,0 +1,456 @@ +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_5Species_10Torr_Sampling(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=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 = 1333.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. + 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + #4: "E + Ar(r) => 2E + Ar+", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + #7: "2E + Ar+ => E + Ar", + #8: "2E + Ar+ => E + Ar(m)", + #9: "2E + Ar+ => E + Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + #14: "E + Ar(m) => E + Ar", + #15: "E + Ar(r) => E + Ar", + 14: "deexci-metastable", + 15: "deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + 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 > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 < 7): + A /= 6.022e23 + A *= tau*np0 + elif (i >= 7 and i < 10): + A /= 6.022e23**2 + A *= tau*np0*np0 + elif(i >= 10 and i < 12): + A *= tau + elif (i >= 12 and i < 20): + A /= 6.022e23 + A *= tau*np0 + else: + A /= 6.022e23 + A *= tau*nAr + + 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_5SpeciesRates/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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_1Torr_Nominal.py b/psaapProperties_5Species_1Torr_Nominal.py new file mode 100755 index 000000000..7d5ea504c --- /dev/null +++ b/psaapProperties_5Species_1Torr_Nominal.py @@ -0,0 +1,479 @@ +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_5Species_1Torr_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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + 14: "Deexci-metastable", + 15: "Deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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)"] + + 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)"] + + + reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 + 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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_250mTorr_Nominal.py b/psaapProperties_5Species_250mTorr_Nominal.py new file mode 100755 index 000000000..7dadc938e --- /dev/null +++ b/psaapProperties_5Species_250mTorr_Nominal.py @@ -0,0 +1,479 @@ +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_5Species_250mTorr_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 = 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + 14: "Deexci-metastable", + 15: "Deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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)"] + + 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)"] + + + reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 + 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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_250mTorr_Sampling.py b/psaapProperties_5Species_250mTorr_Sampling.py new file mode 100755 index 000000000..f1299c3bb --- /dev/null +++ b/psaapProperties_5Species_250mTorr_Sampling.py @@ -0,0 +1,456 @@ +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_5Species_250mTorr_Sampling(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.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. + 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + #4: "E + Ar(r) => 2E + Ar+", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + #7: "2E + Ar+ => E + Ar", + #8: "2E + Ar+ => E + Ar(m)", + #9: "2E + Ar+ => E + Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + #14: "E + Ar(m) => E + Ar", + #15: "E + Ar(r) => E + Ar", + 14: "deexci-metastable", + 15: "deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + 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 > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 < 7): + A /= 6.022e23 + A *= tau*np0 + elif (i >= 7 and i < 10): + A /= 6.022e23**2 + A *= tau*np0*np0 + elif(i >= 10 and i < 12): + A *= tau + elif (i >= 12 and i < 20): + A /= 6.022e23 + A *= tau*np0 + else: + A /= 6.022e23 + A *= tau*nAr + + 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_5SpeciesRates/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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_500mTorr_Nominal.py b/psaapProperties_5Species_500mTorr_Nominal.py new file mode 100755 index 000000000..5bdfd9dd2 --- /dev/null +++ b/psaapProperties_5Species_500mTorr_Nominal.py @@ -0,0 +1,479 @@ +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_5Species_500mTorr_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 = 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + 14: "Deexci-metastable", + 15: "Deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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)"] + + 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)"] + + + reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 + 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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_500mTorr_Sampling.py b/psaapProperties_5Species_500mTorr_Sampling.py new file mode 100755 index 000000000..c535ba5c0 --- /dev/null +++ b/psaapProperties_5Species_500mTorr_Sampling.py @@ -0,0 +1,456 @@ +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_5Species_500mTorr_Sampling(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.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) + + # 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. + 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + #4: "E + Ar(r) => 2E + Ar+", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + #7: "2E + Ar+ => E + Ar", + #8: "2E + Ar+ => E + Ar(m)", + #9: "2E + Ar+ => E + Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + #14: "E + Ar(m) => E + Ar", + #15: "E + Ar(r) => E + Ar", + 14: "deexci-metastable", + 15: "deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + 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 > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 < 7): + A /= 6.022e23 + A *= tau*np0 + elif (i >= 7 and i < 10): + A /= 6.022e23**2 + A *= tau*np0*np0 + elif(i >= 10 and i < 12): + A *= tau + elif (i >= 12 and i < 20): + A /= 6.022e23 + A *= tau*np0 + else: + A /= 6.022e23 + A *= tau*nAr + + 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_5SpeciesRates/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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_5Torr_Nominal.py b/psaapProperties_5Species_5Torr_Nominal.py new file mode 100755 index 000000000..8c34352e6 --- /dev/null +++ b/psaapProperties_5Species_5Torr_Nominal.py @@ -0,0 +1,479 @@ +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_5Species_5Torr_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 = 1.62e23 # 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.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + 14: "Deexci-metastable", + 15: "Deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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)"] + + 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)"] + + + reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = 'interpolationSample.log' + f = open(LOGFilename, 'w') + + for i in range(Nr): + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + dataset = f["table"] + else: + f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') + dataset = f[rxnNameDict[i]] + + Te = dataset[:,0] + Te /= 11604 + rateCoeff = dataset[:,1] + if i > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3): + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 + 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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_5Torr_Sampling.py b/psaapProperties_5Species_5Torr_Sampling.py new file mode 100755 index 000000000..682bcf796 --- /dev/null +++ b/psaapProperties_5Species_5Torr_Sampling.py @@ -0,0 +1,456 @@ +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_5Species_5Torr_Sampling(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 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 (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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. + 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + #4: "E + Ar(r) => 2E + Ar+", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + #7: "2E + Ar+ => E + Ar", + #8: "2E + Ar+ => E + Ar(m)", + #9: "2E + Ar+ => E + Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + #14: "E + Ar(m) => E + Ar", + #15: "E + Ar(r) => E + Ar", + 14: "deexci-metastable", + 15: "deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + 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 > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 < 7): + A /= 6.022e23 + A *= tau*np0 + elif (i >= 7 and i < 10): + A /= 6.022e23**2 + A *= tau*np0*np0 + elif(i >= 10 and i < 12): + A *= tau + elif (i >= 12 and i < 20): + A /= 6.022e23 + A *= tau*np0 + else: + A /= 6.022e23 + A *= tau*nAr + + 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_5SpeciesRates/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 = 5 + 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 = 5 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() diff --git a/psaapProperties_5Species_Sampling_1Torr.py b/psaapProperties_5Species_Sampling_1Torr.py new file mode 100755 index 000000000..48329354c --- /dev/null +++ b/psaapProperties_5Species_Sampling_1Torr.py @@ -0,0 +1,456 @@ +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_5Species_Sampling_1Torr(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) + + # 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] + B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) + A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] + dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] + dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. + 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:3] *= tau*nAr + Ck[3:7] *= tau*np0 + Ck[7:10] *= tau*np0*np0 + Ck[10:12]*= tau + Ck[12:20]*= tau*np0 + Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E + [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ + [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) + [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) + [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR + + params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E + [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ + [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) + [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR + # Rxn1: E + Ar -> E + Ar(m) + # Rxn2: E + Ar -> E + Ar(r) + # Rxn3: E + Ar -> 2E + Ar+ + # Rxn4: E + Ar(m) -> 2E + Ar+ + # Rxn5: E + Ar(r) -> 2E + Ar+ + # Rxn6: E + Ar+ -> Ar(m) + # Rxn7: E + Ar+ -> Ar(r) + # Rxn8: 2E + Ar+ -> E + Ar + # Rxn9: 2E + Ar+ -> E + AR(m) + # Rxn10: 2E + Ar+ -> E + Ar(r) + # Rxn11: Ar(r) -> Ar + # Rxn12: Ar(r) -> Ar(m) + # Rxn13: E + Ar(m) -> E + Ar(r) + # Rxn14: E + AR(r) -> E + Ar(m) + # Rxn15: E + AR(m) -> E + Ar + # Rxn16: E + AR(r) -> E + Ar + # Rxn17: 2Ar(m) -> 2Ar + # Rxn18: 2Ar(m) -> E + Ar+ + Ar + # Rxn19: 2Ar(r) -> E + Ar+ + Ar + # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar + # Rxn21: Ar(r) + Ar -> Ar(m) + Ar + # Rxn22: Ar(m) + Ar -> 2Ar + + rxnNameDict = { 0: "1s-metastable", + 1: "1s-resonance", + 2: "Ionization", + 3: "StepIonization", + 4: "StepIonization", + #4: "E + Ar(r) => 2E + Ar+", + 5: "E + Ar+ => Ar(m)", + 6: "E + Ar+ => Ar(r)", + #7: "2E + Ar+ => E + Ar", + #8: "2E + Ar+ => E + Ar(m)", + #9: "2E + Ar+ => E + Ar(r)", + 7: "3BdyRecomb-ground", + 8: "3BdyRecomb-metastable", + 9: "3BdyRecomb-metastable", + 10: "Ar(r) => Ar", + 11: "Ar(r) => Ar(m)", + 12: "E + Ar(m) => E + Ar(r)", + 13: "E + Ar(r) => E + Ar(m)", + #14: "E + Ar(m) => E + Ar", + #15: "E + Ar(r) => E + Ar", + 14: "deexci-metastable", + 15: "deexci-resonance", + 16: "2Ar(m) => 2Ar", + 17: "2Ar(m) => E + Ar+ + Ar", + 18: "2Ar(r) => E + Ar+ + Ar", + 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", + 20: "Ar(r) + Ar => Ar(m) + Ar", + 21: "Ar(m) + Ar => 2Ar",} + + # 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([True,True,True,True,True,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" + if reactionExpressionTypelist[i]: + if i < 12 or i > 13: + 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 > 6 and i < 10: + rateCoeff /= 6.022e23**2 + else: + 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 < 3: + rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) + elif i > 6 and i < 10: + 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 < 7): + A /= 6.022e23 + A *= tau*np0 + elif (i >= 7 and i < 10): + A /= 6.022e23**2 + A *= tau*np0*np0 + elif(i >= 10 and i < 12): + A *= tau + elif (i >= 12 and i < 20): + A /= 6.022e23 + A *= tau*np0 + else: + A /= 6.022e23 + A *= tau*nAr + + 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_5SpeciesRates/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 = 5 + 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 = 5 + 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.py b/psaapProperties_6Species_100mTorr.py new file mode 100755 index 000000000..925628450 --- /dev/null +++ b/psaapProperties_6Species_100mTorr.py @@ -0,0 +1,483 @@ +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(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.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.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 + + ## 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..c984206c1 --- /dev/null +++ b/psaapProperties_6Species_100mTorr_Expanded.py @@ -0,0 +1,534 @@ +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 (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.44e7,1.61e7,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.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,-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) + 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-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + 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 < 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 + 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_10Torr_Expanded.py b/psaapProperties_6Species_10Torr_Expanded.py new file mode 100755 index 000000000..f8857447d --- /dev/null +++ b/psaapProperties_6Species_10Torr_Expanded.py @@ -0,0 +1,534 @@ +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_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=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 = 1333.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.44e7,1.61e7,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.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,-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) + 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-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + 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 < 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 + 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_1Torr_Expanded.py b/psaapProperties_6Species_1Torr_Expanded.py new file mode 100755 index 000000000..86ed5f809 --- /dev/null +++ b/psaapProperties_6Species_1Torr_Expanded.py @@ -0,0 +1,534 @@ +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=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-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.44e7,1.61e7,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.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,-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) + 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-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + 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 < 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 + 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_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..321214fd5 --- /dev/null +++ b/psaapProperties_6Species_250mTorr_Expanded.py @@ -0,0 +1,534 @@ +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_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=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.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.44e7,1.61e7,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.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,-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) + 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-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + 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 < 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 + 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_500mTorr.py b/psaapProperties_6Species_500mTorr.py index cd39b409d..99fa3b14d 100755 --- a/psaapProperties_6Species_500mTorr.py +++ b/psaapProperties_6Species_500mTorr.py @@ -48,7 +48,7 @@ def setPsaapProperties_6Species_500mTorr(gam, inputV0, inputVDC, params, Nr, iSa ################################################################### # densities - nAr = 2.415e22 # background number density of Ar [1/m^3] (corresponds to p=100 mTorr) + 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 @@ -66,7 +66,7 @@ def setPsaapProperties_6Species_500mTorr(gam, inputV0, inputVDC, params, Nr, iSa e0 = 1.0 # [eV] # pressure - p = 99.99*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + 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 @@ -94,7 +94,7 @@ def setPsaapProperties_6Species_500mTorr(gam, inputV0, inputVDC, params, Nr, iSa # 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] + 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] diff --git a/psaapProperties_6Species_500mTorr_Expanded.py b/psaapProperties_6Species_500mTorr_Expanded.py new file mode 100755 index 000000000..a5626561f --- /dev/null +++ b/psaapProperties_6Species_500mTorr_Expanded.py @@ -0,0 +1,534 @@ +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=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-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.44e7,1.61e7,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.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,-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) + 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-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + 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 < 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 + 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_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..5448e6c5e --- /dev/null +++ b/psaapProperties_6Species_5Torr_Expanded.py @@ -0,0 +1,534 @@ +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=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.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-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.44e7,1.61e7,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.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,-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) + 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-22 + False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] + if i > 23 and i < 28: + rateCoeff /= 6.022e23**2 + else: + 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 < 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 + 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_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_Sampling.py b/psaapProperties_6Species_Sampling.py index b79b1ca5a..79cdd27e6 100755 --- a/psaapProperties_6Species_Sampling.py +++ b/psaapProperties_6Species_Sampling.py @@ -89,10 +89,10 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa # 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 @@ -209,6 +209,7 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa 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)", @@ -216,6 +217,7 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa 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)"} @@ -272,9 +274,9 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa f = open(LOGFilename, 'w') for i in range(Nr): - sample_root_dir = "../../BOLSIGChemistry_6SpeciesRates" + sample_root_dir = "../BOLSIGChemistry_6SpeciesRates_Original" if reactionExpressionTypelist[i]: - if (i < 15): + if i < 15 or i == 20: fileString = sample_root_dir + "/" + rxnNameDict[i] fileName = "%s.%08d.h5" % (fileString, iSample) f = h5.File(fileName, 'r') @@ -391,15 +393,15 @@ 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 *= ((2./3.)*11604)**B - C = C*1.5/e0 + 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)") @@ -415,24 +417,7 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa # 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') + 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] @@ -455,33 +440,6 @@ def setPsaapProperties_6Species_Sampling(gam, inputV0, inputVDC, params, Nr, iSa # 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) diff --git a/psaapProperties_6Species_Sampling_100mTorr_Expanded.py b/psaapProperties_6Species_Sampling_100mTorr_Expanded.py new file mode 100755 index 000000000..398b46e06 --- /dev/null +++ b/psaapProperties_6Species_Sampling_100mTorr_Expanded.py @@ -0,0 +1,484 @@ +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 (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.44e7,1.61e7,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.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,-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]) + + # 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: "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: "E + Ar(4p) => E + E + Ar+", + 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: "E + E + Ar+ => E + Ar(r)", + 25: "3BdyRecomb-metastable", + #26: "E + E + Ar+ => E + Ar(4p)", + 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: "E + Ar(r) => E + E + 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.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]) + + 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. + + # 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 < 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_Sobol/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_10Torr_Expanded.py b/psaapProperties_6Species_Sampling_10Torr_Expanded.py new file mode 100755 index 000000000..b86559181 --- /dev/null +++ b/psaapProperties_6Species_Sampling_10Torr_Expanded.py @@ -0,0 +1,484 @@ +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=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 = 1333.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.44e7,1.61e7,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.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,-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]) + + # 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: "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: "E + Ar(4p) => E + E + Ar+", + 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: "E + E + Ar+ => E + Ar(r)", + 25: "3BdyRecomb-metastable", + #26: "E + E + Ar+ => E + Ar(4p)", + 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: "E + Ar(r) => E + E + 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.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]) + + 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. + + # 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 < 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_Sobol/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_1Torr_Expanded.py b/psaapProperties_6Species_Sampling_1Torr_Expanded.py new file mode 100755 index 000000000..50d0f096a --- /dev/null +++ b/psaapProperties_6Species_Sampling_1Torr_Expanded.py @@ -0,0 +1,484 @@ +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=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) + + # 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.44e7,1.61e7,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.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,-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]) + + # 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: "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: "E + Ar(4p) => E + E + Ar+", + 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: "E + E + Ar+ => E + Ar(r)", + 25: "3BdyRecomb-metastable", + #26: "E + E + Ar+ => E + Ar(4p)", + 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: "E + Ar(r) => E + E + 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.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]) + + 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. + + # 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 < 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_Sobol/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_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..5fc2157f0 --- /dev/null +++ b/psaapProperties_6Species_Sampling_250mTorr_Expanded.py @@ -0,0 +1,484 @@ +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=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.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.44e7,1.61e7,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.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,-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]) + + # 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: "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: "E + Ar(4p) => E + E + Ar+", + 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: "E + E + Ar+ => E + Ar(r)", + 25: "3BdyRecomb-metastable", + #26: "E + E + Ar+ => E + Ar(4p)", + 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: "E + Ar(r) => E + E + 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.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]) + + 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. + + # 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 < 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_Sobol/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_500mTorr.py b/psaapProperties_6Species_Sampling_500mTorr.py index 99572adad..71f69200d 100755 --- a/psaapProperties_6Species_Sampling_500mTorr.py +++ b/psaapProperties_6Species_Sampling_500mTorr.py @@ -65,7 +65,7 @@ def setPsaapProperties_6Species_Sampling_500mTorr(gam, inputV0, inputVDC, params e0 = 1.0 # [eV] # pressure - p = 66.66*1.5 # [J/m^3] *1.5 to convert it to energy (1 Torr) + 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 @@ -89,10 +89,10 @@ def setPsaapProperties_6Species_Sampling_500mTorr(gam, inputV0, inputVDC, params # 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,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,-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 @@ -391,15 +391,15 @@ def setPsaapProperties_6Species_Sampling_500mTorr(gam, inputV0, inputVDC, params 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 *= ((2./3.)*11604)**B - C = C*1.5/e0 + 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)") diff --git a/psaapProperties_6Species_Sampling_500mTorr_Expanded.py b/psaapProperties_6Species_Sampling_500mTorr_Expanded.py new file mode 100755 index 000000000..6af741f9b --- /dev/null +++ b/psaapProperties_6Species_Sampling_500mTorr_Expanded.py @@ -0,0 +1,484 @@ +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=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.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) + + # 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.44e7,1.61e7,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.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,-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]) + + # 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: "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: "E + Ar(4p) => E + E + Ar+", + 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: "E + E + Ar+ => E + Ar(r)", + 25: "3BdyRecomb-metastable", + #26: "E + E + Ar+ => E + Ar(4p)", + 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: "E + Ar(r) => E + E + 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.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]) + + 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. + + # 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 < 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_Sobol/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_5Torr_Expanded.py b/psaapProperties_6Species_Sampling_5Torr_Expanded.py new file mode 100755 index 000000000..f85a28d9e --- /dev/null +++ b/psaapProperties_6Species_Sampling_5Torr_Expanded.py @@ -0,0 +1,484 @@ +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=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 = 666.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) + + # 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.44e7,1.61e7,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.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,-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]) + + # 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: "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: "E + Ar(4p) => E + E + Ar+", + 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: "E + E + Ar+ => E + Ar(r)", + 25: "3BdyRecomb-metastable", + #26: "E + E + Ar+ => E + Ar(4p)", + 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: "E + Ar(r) => E + E + 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.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]) + + 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. + + # 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 < 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_Sobol/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_Expanded_NewRates.py b/psaapProperties_6Species_Sampling_Expanded_NewRates.py new file mode 100755 index 000000000..3b61bfab1 --- /dev/null +++ b/psaapProperties_6Species_Sampling_Expanded_NewRates.py @@ -0,0 +1,489 @@ +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_Expanded_NewRates(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)] + 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,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] + 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: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 + + # 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: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 + 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,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 + 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, + 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]: + 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. + 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 > 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], + 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_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 = 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_Verification.py b/psaapProperties_6Species_Verification.py new file mode 100755 index 000000000..89e0ced02 --- /dev/null +++ b/psaapProperties_6Species_Verification.py @@ -0,0 +1,528 @@ +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_Verification(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.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.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]]) + + Te = NDe_v_Te[:,0] + 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, De_interp) + De_Te_spline = CubicSpline.derivative(De_spline) + diffusivity = Diffusivity(interpolate = False, 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] + mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) + mue_spline = CubicSpline(Te, 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/timePeriodicSolver.py b/timePeriodicSolver.py index 59b021633..06861bad1 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,10 +180,10 @@ 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 (6 species, 23 rxn, 1Torr, 100V, Sampling)') @@ -198,6 +198,7 @@ def solveNewtonStep(self, Uic, Nt): 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)') @@ -206,10 +207,22 @@ def solveNewtonStep(self, Uic, Nt): 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==15): + print('# Running scenario = 15 (6 species, 34 rxn, 1Torr, Sampling)') Ns = 6 elif(args.scenario==16): + print('# Running scenario = 16 (6 species, 34 rxn, 250mTorr, Nominal)') + Ns = 6 + elif(args.scenario==17): + print('# Running scenario = 17 (6 species, 34 rxn, 500mTorr, Nominal)') + Ns = 6 + elif(args.scenario==18): + print('# Running scenario = 18 (6 species, 34 rxn, 250mTorr, Sampling)') + Ns = 6 + elif(args.scenario==19): + print('# Running scenario = 19 (6 species, 34 rxn, 500mTorr, Sampling)') Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") From 8def574234cefcd5e158d9165e14a4f5480d57fe Mon Sep 17 00:00:00 2001 From: Juan Pablo Barberena Valencia Date: Thu, 4 May 2023 10:13:13 -0700 Subject: [PATCH 07/10] Cleanup of Old Cases --- 4Species_Test/sampleRunCN.sh | 47 ------------------------------------ 1 file changed, 47 deletions(-) delete mode 100755 4Species_Test/sampleRunCN.sh diff --git a/4Species_Test/sampleRunCN.sh b/4Species_Test/sampleRunCN.sh deleted file mode 100755 index 68998cd22..000000000 --- a/4Species_Test/sampleRunCN.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -error_exit() -{ - echo "$1" 1>&2 - exit 1 -} - -EXE="python3 ../chebSolver.py" -NEWTEXE="python3 ../timePeriodicSolver.py" - -# 4 species + 9 rxn - Nominal Rates case -Np=150 -Nt=25600 -Nt1=128 -dt=0.0078125 -scenario=5 -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 --elasticCollisionActivation --backgroundSpecieActivation" -#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 --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}T200.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 From 3924456d4df55892a65f2351241b90597be755dd Mon Sep 17 00:00:00 2001 From: Juan Pablo Barberena Valencia Date: Thu, 4 May 2023 10:19:31 -0700 Subject: [PATCH 08/10] Update 4-Species Input files --- psaapProperties_4Species_Nominal.py | 59 +--- psaapProperties_4Species_Sampling.py | 404 +++++++++++++++++++++++++++ 2 files changed, 413 insertions(+), 50 deletions(-) create mode 100755 psaapProperties_4Species_Sampling.py diff --git a/psaapProperties_4Species_Nominal.py b/psaapProperties_4Species_Nominal.py index 1dc5de7ec..bd35d4d01 100644 --- a/psaapProperties_4Species_Nominal.py +++ b/psaapProperties_4Species_Nominal.py @@ -2,8 +2,8 @@ from scipy.interpolate import CubicSpline import csv import h5py as h5 -#import matplotlib.pyplot as plt -#import matplotlib.colors as mcolors +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors import logging @@ -90,7 +90,7 @@ def setPsaapProperties_4Species_Nominal(gam, inputV0, inputVDC, params, Nr, iSam # Ee = 3/2*Te (Te in eV) # -> k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] # nominal - Ck = np.array([0.0,0.0,0.0,4.0e-13,3.24e-9,8.6e-10,2.1e-15,3.21e7,5.0e-27]) # pre-exponential factors [cm^3/s] + Ck = np.array([0.0,0.0,0.0,4.0e-13,0.0,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([0.0,0.0,0.0,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] @@ -253,14 +253,14 @@ def setPsaapProperties_4Species_Nominal(gam, inputV0, inputVDC, params, Nr, iSam 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]) + reactionExpressionTypelist = np.array([True,True,False,False,False,False,False,False,False]) reactionsList = [] LOGFilename = 'interpolationSample.log' f = open(LOGFilename, 'w') for i in range(Nr): if reactionExpressionTypelist[i]: - f = h5.File("../BOLSIGChemistry_4SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') + f = h5.File("../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') dataset = f["table"] Te = dataset[:,0] @@ -363,24 +363,8 @@ def setPsaapProperties_4Species_Nominal(gam, inputV0, inputVDC, params, Nr, iSam # 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") - NDe_v_Te = transport["diffusivity"] + 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])) @@ -401,33 +385,8 @@ def setPsaapProperties_4Species_Nominal(gam, inputV0, inputVDC, params, Nr, iSam # 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"] + + 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) diff --git a/psaapProperties_4Species_Sampling.py b/psaapProperties_4Species_Sampling.py new file mode 100755 index 000000000..b62357248 --- /dev/null +++ b/psaapProperties_4Species_Sampling.py @@ -0,0 +1,404 @@ +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_4Species_Sampling(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)] + 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([0.0,0.0,0.0,4.0e-13,0.0,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([0.0,0.0,0.0,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,0.0,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,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* + + rxnNameDict = {0: "Ionization", + 1: "1s-lumped", + 2: "StepIonization", + 3: "Ar+ + E => Ar*", + 4: "Ar* + Ar* => Ar + Ar+ + E", + 5: "Ar* + E => Ar + E", + 6: "Ar* + Ar => Ar + Ar", + 7: "Ar* => Ar", + 8: "Ar+ + E + E => Ar* + E"} + + # 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([True,True,False,False,False,False,False,False,False]) + + reactionsList = [] + LOGFilename = './InterpolationLogs_Dir/interpolationSample%s.log'%str(iSample) + f = open(LOGFilename, 'w') + + for i in range(Nr): + sample_root_dir = "../BOLSIGChemistry_4SpeciesRates" + if reactionExpressionTypelist[i]: + fileString = sample_root_dir + "/" + rxnNameDict[i] + fileName = "%s.%08d.h5" % (fileString, iSample) + f = h5.File(fileName, 'r') + dataset = f["table"] + + 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 < 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: + if i == 2 or i == 4: + A = 0.0 + B = 0.0 + C = 0.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 < 6): + A /= 6.022e23 + A *= tau*np0 + elif (i == 6): + A /= 6.022e23 + A *= tau*nAr + elif (i == 7): + A *= tau + elif (i == 8): + A /= 6.022e23**2 + A *= tau*np0*np0 + + A *= ((2./3.)*11604)**B + C = C*1.5/e0 + + 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_4SpeciesRates/Transport.%08d.h5" % (iSample), '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 = 4 + 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 = 4 + for i in range(1, Ns): + muList.append(Mobility(interpolate = False)) + + params.mobilityList = muList + + # 5) Dump to screen + params.print() From 01b506218a36f167b161dbc421983938c9429b15 Mon Sep 17 00:00:00 2001 From: "Todd A. Oliver" Date: Tue, 24 Jun 2025 16:38:37 -0500 Subject: [PATCH 09/10] Delete unused inputs --- .../1s-metastable.h5 | Bin 9344 -> 0 bytes BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 | Bin 9344 -> 0 bytes BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 | Bin 9344 -> 0 bytes .../3BdyRecomb-ground.h5 | Bin 5248 -> 0 bytes .../3BdyRecomb-metastable.h5 | Bin 5248 -> 0 bytes BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 | Bin 5248 -> 0 bytes .../Deexci-metastable.h5 | Bin 5248 -> 0 bytes .../Deexci-resonance.h5 | Bin 5248 -> 0 bytes BOLSIGChemistry_4SpeciesRates/Ionization.h5 | Bin 9344 -> 0 bytes .../StepIonization.h5 | Bin 9344 -> 0 bytes .../detailed_balance.py | 135 ----- BOLSIGChemistry_4SpeciesRates/ionization.h5 | Bin 9344 -> 0 bytes .../lumped_1s.excite.h5 | Bin 9344 -> 0 bytes .../plot_rates_h5.py | 37 -- .../step_ionization.h5 | Bin 9344 -> 0 bytes chebSolver.py | 23 +- psaapProperties_4Species_Nominal.py | 403 ------------- psaapProperties_4Species_Sampling.py | 404 ------------- psaapProperties_5Species_100mTorr_Nominal.py | 479 ---------------- psaapProperties_5Species_100mTorr_Sampling.py | 456 --------------- psaapProperties_5Species_10Torr_Nominal.py | 479 ---------------- psaapProperties_5Species_10Torr_Sampling.py | 456 --------------- psaapProperties_5Species_1Torr_Nominal.py | 479 ---------------- psaapProperties_5Species_250mTorr_Nominal.py | 479 ---------------- psaapProperties_5Species_250mTorr_Sampling.py | 456 --------------- psaapProperties_5Species_500mTorr_Nominal.py | 479 ---------------- psaapProperties_5Species_500mTorr_Sampling.py | 456 --------------- psaapProperties_5Species_5Torr_Nominal.py | 479 ---------------- psaapProperties_5Species_5Torr_Sampling.py | 456 --------------- psaapProperties_5Species_Sampling_1Torr.py | 456 --------------- psaapProperties_6Species_100mTorr.py | 483 ---------------- psaapProperties_6Species_100mTorr_Expanded.py | 534 ----------------- psaapProperties_6Species_10Torr_Expanded.py | 534 ----------------- psaapProperties_6Species_1Torr_Expanded.py | 534 ----------------- psaapProperties_6Species_250mTorr.py | 533 ----------------- psaapProperties_6Species_250mTorr_Expanded.py | 534 ----------------- psaapProperties_6Species_500mTorr.py | 533 ----------------- psaapProperties_6Species_500mTorr_Expanded.py | 534 ----------------- psaapProperties_6Species_5Torr.py | 533 ----------------- psaapProperties_6Species_5Torr_Expanded.py | 534 ----------------- psaapProperties_6Species_Expanded.py | 539 ------------------ psaapProperties_6Species_Sampling.py | 457 --------------- ...ies_6Species_Sampling_100mTorr_Expanded.py | 484 ---------------- ...rties_6Species_Sampling_10Torr_Expanded.py | 484 ---------------- ...erties_6Species_Sampling_1Torr_Expanded.py | 484 ---------------- psaapProperties_6Species_Sampling_250mTorr.py | 499 ---------------- ...ies_6Species_Sampling_250mTorr_Expanded.py | 484 ---------------- psaapProperties_6Species_Sampling_500mTorr.py | 499 ---------------- ...ies_6Species_Sampling_500mTorr_Expanded.py | 484 ---------------- ...erties_6Species_Sampling_5Torr_Expanded.py | 484 ---------------- ...ies_6Species_Sampling_Expanded_NewRates.py | 489 ---------------- psaapProperties_6Species_Verification.py | 528 ----------------- sampleRun.sh | 66 --- sampleRunCN.sh | 70 --- 54 files changed, 1 insertion(+), 17948 deletions(-) delete mode 100644 BOLSIGChemistry_4SpeciesRates/1s-metastable.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/3BdyRecomb-ground.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/3BdyRecomb-metastable.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/Deexci-metastable.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/Deexci-resonance.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/Ionization.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/StepIonization.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/detailed_balance.py delete mode 100644 BOLSIGChemistry_4SpeciesRates/ionization.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/lumped_1s.excite.h5 delete mode 100644 BOLSIGChemistry_4SpeciesRates/plot_rates_h5.py delete mode 100644 BOLSIGChemistry_4SpeciesRates/step_ionization.h5 delete mode 100644 psaapProperties_4Species_Nominal.py delete mode 100755 psaapProperties_4Species_Sampling.py delete mode 100755 psaapProperties_5Species_100mTorr_Nominal.py delete mode 100755 psaapProperties_5Species_100mTorr_Sampling.py delete mode 100755 psaapProperties_5Species_10Torr_Nominal.py delete mode 100755 psaapProperties_5Species_10Torr_Sampling.py delete mode 100755 psaapProperties_5Species_1Torr_Nominal.py delete mode 100755 psaapProperties_5Species_250mTorr_Nominal.py delete mode 100755 psaapProperties_5Species_250mTorr_Sampling.py delete mode 100755 psaapProperties_5Species_500mTorr_Nominal.py delete mode 100755 psaapProperties_5Species_500mTorr_Sampling.py delete mode 100755 psaapProperties_5Species_5Torr_Nominal.py delete mode 100755 psaapProperties_5Species_5Torr_Sampling.py delete mode 100755 psaapProperties_5Species_Sampling_1Torr.py delete mode 100755 psaapProperties_6Species_100mTorr.py delete mode 100755 psaapProperties_6Species_100mTorr_Expanded.py delete mode 100755 psaapProperties_6Species_10Torr_Expanded.py delete mode 100755 psaapProperties_6Species_1Torr_Expanded.py delete mode 100755 psaapProperties_6Species_250mTorr.py delete mode 100755 psaapProperties_6Species_250mTorr_Expanded.py delete mode 100755 psaapProperties_6Species_500mTorr.py delete mode 100755 psaapProperties_6Species_500mTorr_Expanded.py delete mode 100755 psaapProperties_6Species_5Torr.py delete mode 100755 psaapProperties_6Species_5Torr_Expanded.py delete mode 100755 psaapProperties_6Species_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling.py delete mode 100755 psaapProperties_6Species_Sampling_100mTorr_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling_10Torr_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling_1Torr_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling_250mTorr.py delete mode 100755 psaapProperties_6Species_Sampling_250mTorr_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling_500mTorr.py delete mode 100755 psaapProperties_6Species_Sampling_500mTorr_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling_5Torr_Expanded.py delete mode 100755 psaapProperties_6Species_Sampling_Expanded_NewRates.py delete mode 100755 psaapProperties_6Species_Verification.py delete mode 100755 sampleRun.sh delete mode 100755 sampleRunCN.sh diff --git a/BOLSIGChemistry_4SpeciesRates/1s-metastable.h5 b/BOLSIGChemistry_4SpeciesRates/1s-metastable.h5 deleted file mode 100644 index a2fdd27e48db0e3c46abbc0f33fd9718d0a87cc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9344 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 diff --git a/BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 b/BOLSIGChemistry_4SpeciesRates/1s-resonance.h5 deleted file mode 100644 index da36bca5d10367bc48560f34bf92e2e832036a51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9344 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 Wk_bp5Ac=q^0+I+wBJh7D0{;MJX_mGC diff --git a/BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 b/BOLSIGChemistry_4SpeciesRates/2p-lumped.h5 deleted file mode 100644 index b8c33b17837a68b95b5adcb87691f677a8252961..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9344 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 diff --git a/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-ground.h5 b/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-ground.h5 deleted file mode 100644 index 67dd6a23cc9fb58aa98f24c7b0f66f65318e23b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5248 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 diff --git a/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-metastable.h5 b/BOLSIGChemistry_4SpeciesRates/3BdyRecomb-metastable.h5 deleted file mode 100644 index 44cb5c1b585bf96976263bd7b809078d48bd592a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5248 zcmeIxc|4R`1HkbyV{Wn(AtX_jyjRJVR-DJtCXubwE!9xjZn;GZ>Waz|t#UQ?os=b% zED_3D#y*T~EZJpjm&n|@#(6%U`{(=qasPOm`F!R)-{*Jc%(IQpUcKD{ysLN#-(NgD z1a5-h-< zxc=hE`5Hlmdtr-bamSDG|LO|t-Gv?ee!>=B<}MR7R&4U5m?-o@}= zj$8!t!djdKxd@7Xuf#=M*ip(^ckwX(Y0|eR|NBfK865)8-*W*$gO8xWCM|rC{B7^| zP9!cY$iw-kkhnP03GVz0GZ#OvEN=WOqp6{h-uHj>!nqI#GMw}HR}SXKkN&s@Ytw@-@=pnjWw>nT}*SY#c`C6>lcoe|q3&!DJT}S1ZR@NaGkq%_bxoQ?o{~xe z@@bljEU6v$jed{3vHOXrU(#rLvtr*#dd~A+vXv6;+ht<_Xqhjy`yXx^uu9 zgX|N}kzePVt;tYNMyA{+Yn$+=AX`Y&+nx>KZc2Rksoo|P^^LOnVe0L;&t)d~BwD1Q z-k=ba`L!OmQkt@;-Jut#JD52nj5OgE43+Z{qokuAG4B~_F^oHaY{}NTmVtW8U}+?m zP$u$dYVpnJ1l&i>jT2<`UZPGpt*fxC2loTB;_e2YSE#S+FBpaDS;*qDTlLMExD!i- z=V<}2Q4bZiV~-kSBdeCn{o=}-gG?EMLXIDBPo%esEPb4dddS5TzaXnT${S1obD*0lYMgQslcSeAdiP+|}_h+9^S0sEbBuNnA55 zM~*)3_ZCM_rm?CMqRQ$bWXb&_vYvNMm^_Di|7DuZ(A=DyZeo( z7nsTKPu@xgs#*5)+2v<+_Re<~C->0-ds_Vj^HGqFwb-y_7_|wgIkR@EH^0}Z8d>S0 zZ`KSpoM_03vYF7aimk4%6JmgmLzPc*&x!%59a0yxY8gOPRV|SCCj<)jeD6_0S^(n| zlT5kl2nJQF1znT%&DdECR!l_lr;E3vF~W>dNY3wU4S{kW$CG%1(3dOFx)<2&M9&YfU_{Y828 z>UNK@6pK%*m0OsAU=VWCeq|x{(Cihv;#eoJY8*Jlvv(8=+aw{om)QwqV%FWyJ1VVP z-OuM0W!nY(54SnxxEtx7+HW7+HPHnQcsS>qrC-9B&OUJGmPwoVSv?pZYwY}Zun!#1;ATnh zHi7YtnkNS9VLSYBJn$wgEk7PQt2+Xw z1s|5&{P7nIm6-Hm|Qj zfqwyX4HoP5UNsA@D1`mzQp8)RscPlPV$1@^`Dd6;ZXxV!wHn7nM9_mJ|U$p5?y8*J-{c;jbV0^e63SjL!V z1KxS}FR5{*@b>bx;#V&cF#F|YorPUxF!HVQgU|g0?1W;VN~BT+)MU$z(b7}14c^(> z(|i6r3H!Yw&PBA320vBX_$ADeFi$onIQ^s=zMk4GVc^S+Nkz`^+Zxtz?gtsWvpe0J zLaK%8x7Njqyd-0VAK_L;PAz1NNXKk5{RwNJ>^(|yuH)Q~pD?<{94||y9^P_oSE4>y zf^9hTh-d9^J@g5S%&6Dp!EUWNv_#`s19YQ{FY6us=CGNM(Z4oAMn<^Iwz#F(IpH4N zEy{G5zWRpb)Nx)c@XAV?1{NJoC|sx-U(JVUT0dK=@UjV}JU`~KwIoj&G9abOv+DCD0n8)KNI;mc1$GuhC#URRhKZA0>tt(NplR6^%U$xz zF=K~(mvrkxbOOkW3i6HSc`9u$M&yG7$p`+Xqywp?Dr`TDO+_yHIGQHSAHUx zsN8^cWoajTL88>2UMq@ywunj%Q0{^@hn{j}z81ySj4C8&1$04E7Z<-6^Oe}GMC*F? mOczwiWcS)mt;C3CU;2hEyW#v#+eOGBVwiO!L*Bor8~z162-|u9 diff --git a/BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 b/BOLSIGChemistry_4SpeciesRates/Deexci-2p.h5 deleted file mode 100644 index 455440027d99a610077b7ad66b11aff5fadfc382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5248 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 diff --git a/BOLSIGChemistry_4SpeciesRates/Deexci-metastable.h5 b/BOLSIGChemistry_4SpeciesRates/Deexci-metastable.h5 deleted file mode 100644 index e9f4046570f37f49b0f0abbf8c1f280bcfced6f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5248 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 diff --git a/BOLSIGChemistry_4SpeciesRates/Deexci-resonance.h5 b/BOLSIGChemistry_4SpeciesRates/Deexci-resonance.h5 deleted file mode 100644 index 27fb8904858dd07e11eabc5b15022dfaa4f74285..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5248 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 diff --git a/BOLSIGChemistry_4SpeciesRates/StepIonization.h5 b/BOLSIGChemistry_4SpeciesRates/StepIonization.h5 deleted file mode 100644 index beabf8706256f02b129935e5318b6401a4ad972c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9344 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 diff --git a/BOLSIGChemistry_4SpeciesRates/lumped_1s.excite.h5 b/BOLSIGChemistry_4SpeciesRates/lumped_1s.excite.h5 deleted file mode 100644 index 7b7a1eb168dd0bcf89f803cef8dd70dc5a916e04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9344 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 z k_i = [Ck*(2/3)^B] * Ee^B * exp[-(3/2)*A/Ee] - # nominal - Ck = np.array([0.0,0.0,0.0,4.0e-13,0.0,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([0.0,0.0,0.0,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. # 1/(m*s) - 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] *= tau*nAr - 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], # E - [1,0,1,0,1,0,0,0,0], # AR+ - [0,1,0,1,0,0,0,0,1], # AR* - [0,0,0,0,1,1,2,1,0]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,0,1,0,0,2], # E - [0,0,0,1,0,0,0,0,1], # AR+ - [0,0,1,0,2,1,1,1,0], # AR* - [1,1,0,0,0,0,1,0,0]], dtype=np.int64) # AR - # 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* - - rxnNameDict = {0: "ionization", - 1: "lumped_1s.excite", - 2: "step_ionization", - 3: "Ar+ + E => Ar*", - 4: "Ar* + Ar* => Ar + Ar+ + E", - 5: "Ar* + e => Ar + E", - 6: "Ar* + Ar => Ar + Ar", - 7: "Ar* => Ar", - 8: "Ar+ + E + E => Ar* + E"} - - # 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)", - 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,False,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - for i in range(Nr): - if reactionExpressionTypelist[i]: - f = h5.File("../BOLSIGChemistry_NominalRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - - 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 < 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 - - diffList = [] - # Data from BOLSIG - # Te in [eV] - # De * N in [1/(m*s)] - 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 = 4 - 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 = 4 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_4Species_Sampling.py b/psaapProperties_4Species_Sampling.py deleted file mode 100755 index b62357248..000000000 --- a/psaapProperties_4Species_Sampling.py +++ /dev/null @@ -1,404 +0,0 @@ -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_4Species_Sampling(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)] - 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([0.0,0.0,0.0,4.0e-13,0.0,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([0.0,0.0,0.0,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,0.0,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,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* - - rxnNameDict = {0: "Ionization", - 1: "1s-lumped", - 2: "StepIonization", - 3: "Ar+ + E => Ar*", - 4: "Ar* + Ar* => Ar + Ar+ + E", - 5: "Ar* + E => Ar + E", - 6: "Ar* + Ar => Ar + Ar", - 7: "Ar* => Ar", - 8: "Ar+ + E + E => Ar* + E"} - - # 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([True,True,False,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = './InterpolationLogs_Dir/interpolationSample%s.log'%str(iSample) - f = open(LOGFilename, 'w') - - for i in range(Nr): - sample_root_dir = "../BOLSIGChemistry_4SpeciesRates" - if reactionExpressionTypelist[i]: - fileString = sample_root_dir + "/" + rxnNameDict[i] - fileName = "%s.%08d.h5" % (fileString, iSample) - f = h5.File(fileName, 'r') - dataset = f["table"] - - 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 < 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: - if i == 2 or i == 4: - A = 0.0 - B = 0.0 - C = 0.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 < 6): - A /= 6.022e23 - A *= tau*np0 - elif (i == 6): - A /= 6.022e23 - A *= tau*nAr - elif (i == 7): - A *= tau - elif (i == 8): - A /= 6.022e23**2 - A *= tau*np0*np0 - - A *= ((2./3.)*11604)**B - C = C*1.5/e0 - - 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_4SpeciesRates/Transport.%08d.h5" % (iSample), '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 = 4 - 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 = 4 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_100mTorr_Nominal.py b/psaapProperties_5Species_100mTorr_Nominal.py deleted file mode 100755 index 0ea613d34..000000000 --- a/psaapProperties_5Species_100mTorr_Nominal.py +++ /dev/null @@ -1,479 +0,0 @@ -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_5Species_100mTorr_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.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 (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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - 14: "Deexci-metastable", - 15: "Deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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)"] - - 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)"] - - - reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - - for i in range(Nr): - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - else: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') - dataset = f[rxnNameDict[i]] - - Te = dataset[:,0] - Te /= 11604 - rateCoeff = dataset[:,1] - if i > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3): - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 - 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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_100mTorr_Sampling.py b/psaapProperties_5Species_100mTorr_Sampling.py deleted file mode 100755 index bd0a0cf2d..000000000 --- a/psaapProperties_5Species_100mTorr_Sampling.py +++ /dev/null @@ -1,456 +0,0 @@ -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_5Species_100mTorr_Sampling(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 (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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. - 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - #4: "E + Ar(r) => 2E + Ar+", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - #7: "2E + Ar+ => E + Ar", - #8: "2E + Ar+ => E + Ar(m)", - #9: "2E + Ar+ => E + Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - #14: "E + Ar(m) => E + Ar", - #15: "E + Ar(r) => E + Ar", - 14: "deexci-metastable", - 15: "deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - 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 > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 < 7): - A /= 6.022e23 - A *= tau*np0 - elif (i >= 7 and i < 10): - A /= 6.022e23**2 - A *= tau*np0*np0 - elif(i >= 10 and i < 12): - A *= tau - elif (i >= 12 and i < 20): - A /= 6.022e23 - A *= tau*np0 - else: - A /= 6.022e23 - A *= tau*nAr - - 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_5SpeciesRates/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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_10Torr_Nominal.py b/psaapProperties_5Species_10Torr_Nominal.py deleted file mode 100755 index a83dee045..000000000 --- a/psaapProperties_5Species_10Torr_Nominal.py +++ /dev/null @@ -1,479 +0,0 @@ -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_5Species_10Torr_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.22e23 # 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 = 1333.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - 14: "Deexci-metastable", - 15: "Deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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)"] - - 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)"] - - - reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - - for i in range(Nr): - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - else: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') - dataset = f[rxnNameDict[i]] - - Te = dataset[:,0] - Te /= 11604 - rateCoeff = dataset[:,1] - if i > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3): - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 - 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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_10Torr_Sampling.py b/psaapProperties_5Species_10Torr_Sampling.py deleted file mode 100755 index b65b11d81..000000000 --- a/psaapProperties_5Species_10Torr_Sampling.py +++ /dev/null @@ -1,456 +0,0 @@ -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_5Species_10Torr_Sampling(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=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 = 1333.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. - 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - #4: "E + Ar(r) => 2E + Ar+", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - #7: "2E + Ar+ => E + Ar", - #8: "2E + Ar+ => E + Ar(m)", - #9: "2E + Ar+ => E + Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - #14: "E + Ar(m) => E + Ar", - #15: "E + Ar(r) => E + Ar", - 14: "deexci-metastable", - 15: "deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - 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 > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 < 7): - A /= 6.022e23 - A *= tau*np0 - elif (i >= 7 and i < 10): - A /= 6.022e23**2 - A *= tau*np0*np0 - elif(i >= 10 and i < 12): - A *= tau - elif (i >= 12 and i < 20): - A /= 6.022e23 - A *= tau*np0 - else: - A /= 6.022e23 - A *= tau*nAr - - 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_5SpeciesRates/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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_1Torr_Nominal.py b/psaapProperties_5Species_1Torr_Nominal.py deleted file mode 100755 index 7d5ea504c..000000000 --- a/psaapProperties_5Species_1Torr_Nominal.py +++ /dev/null @@ -1,479 +0,0 @@ -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_5Species_1Torr_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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - 14: "Deexci-metastable", - 15: "Deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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)"] - - 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)"] - - - reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - - for i in range(Nr): - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - else: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') - dataset = f[rxnNameDict[i]] - - Te = dataset[:,0] - Te /= 11604 - rateCoeff = dataset[:,1] - if i > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3): - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 - 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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_250mTorr_Nominal.py b/psaapProperties_5Species_250mTorr_Nominal.py deleted file mode 100755 index 7dadc938e..000000000 --- a/psaapProperties_5Species_250mTorr_Nominal.py +++ /dev/null @@ -1,479 +0,0 @@ -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_5Species_250mTorr_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 = 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - 14: "Deexci-metastable", - 15: "Deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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)"] - - 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)"] - - - reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - - for i in range(Nr): - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - else: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') - dataset = f[rxnNameDict[i]] - - Te = dataset[:,0] - Te /= 11604 - rateCoeff = dataset[:,1] - if i > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3): - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 - 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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_250mTorr_Sampling.py b/psaapProperties_5Species_250mTorr_Sampling.py deleted file mode 100755 index f1299c3bb..000000000 --- a/psaapProperties_5Species_250mTorr_Sampling.py +++ /dev/null @@ -1,456 +0,0 @@ -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_5Species_250mTorr_Sampling(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.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. - 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - #4: "E + Ar(r) => 2E + Ar+", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - #7: "2E + Ar+ => E + Ar", - #8: "2E + Ar+ => E + Ar(m)", - #9: "2E + Ar+ => E + Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - #14: "E + Ar(m) => E + Ar", - #15: "E + Ar(r) => E + Ar", - 14: "deexci-metastable", - 15: "deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - 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 > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 < 7): - A /= 6.022e23 - A *= tau*np0 - elif (i >= 7 and i < 10): - A /= 6.022e23**2 - A *= tau*np0*np0 - elif(i >= 10 and i < 12): - A *= tau - elif (i >= 12 and i < 20): - A /= 6.022e23 - A *= tau*np0 - else: - A /= 6.022e23 - A *= tau*nAr - - 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_5SpeciesRates/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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_500mTorr_Nominal.py b/psaapProperties_5Species_500mTorr_Nominal.py deleted file mode 100755 index 5bdfd9dd2..000000000 --- a/psaapProperties_5Species_500mTorr_Nominal.py +++ /dev/null @@ -1,479 +0,0 @@ -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_5Species_500mTorr_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 = 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - 14: "Deexci-metastable", - 15: "Deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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)"] - - 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)"] - - - reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - - for i in range(Nr): - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - else: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') - dataset = f[rxnNameDict[i]] - - Te = dataset[:,0] - Te /= 11604 - rateCoeff = dataset[:,1] - if i > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3): - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 - 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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_500mTorr_Sampling.py b/psaapProperties_5Species_500mTorr_Sampling.py deleted file mode 100755 index c535ba5c0..000000000 --- a/psaapProperties_5Species_500mTorr_Sampling.py +++ /dev/null @@ -1,456 +0,0 @@ -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_5Species_500mTorr_Sampling(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.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) - - # 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. - 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - #4: "E + Ar(r) => 2E + Ar+", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - #7: "2E + Ar+ => E + Ar", - #8: "2E + Ar+ => E + Ar(m)", - #9: "2E + Ar+ => E + Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - #14: "E + Ar(m) => E + Ar", - #15: "E + Ar(r) => E + Ar", - 14: "deexci-metastable", - 15: "deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - 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 > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 < 7): - A /= 6.022e23 - A *= tau*np0 - elif (i >= 7 and i < 10): - A /= 6.022e23**2 - A *= tau*np0*np0 - elif(i >= 10 and i < 12): - A *= tau - elif (i >= 12 and i < 20): - A /= 6.022e23 - A *= tau*np0 - else: - A /= 6.022e23 - A *= tau*nAr - - 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_5SpeciesRates/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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_5Torr_Nominal.py b/psaapProperties_5Species_5Torr_Nominal.py deleted file mode 100755 index 8c34352e6..000000000 --- a/psaapProperties_5Species_5Torr_Nominal.py +++ /dev/null @@ -1,479 +0,0 @@ -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_5Species_5Torr_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 = 1.62e23 # 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.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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [m^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - 14: "Deexci-metastable", - 15: "Deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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)"] - - 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)"] - - - reactionExpressionTypelist = np.array([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,False,False,False,False,False,False]) - - reactionsList = [] - LOGFilename = 'interpolationSample.log' - f = open(LOGFilename, 'w') - - for i in range(Nr): - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/{0:s}.h5".format(rxnNameDict[i]), 'r') - dataset = f["table"] - else: - f = h5.File("../../../BOLSIGChemistry_5SpeciesRates/StepwiseExcitations.nominal.h5", 'r') - dataset = f[rxnNameDict[i]] - - Te = dataset[:,0] - Te /= 11604 - rateCoeff = dataset[:,1] - if i > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3): - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 - 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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_5Torr_Sampling.py b/psaapProperties_5Species_5Torr_Sampling.py deleted file mode 100755 index 682bcf796..000000000 --- a/psaapProperties_5Species_5Torr_Sampling.py +++ /dev/null @@ -1,456 +0,0 @@ -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_5Species_5Torr_Sampling(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 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 (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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. - 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - #4: "E + Ar(r) => 2E + Ar+", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - #7: "2E + Ar+ => E + Ar", - #8: "2E + Ar+ => E + Ar(m)", - #9: "2E + Ar+ => E + Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - #14: "E + Ar(m) => E + Ar", - #15: "E + Ar(r) => E + Ar", - 14: "deexci-metastable", - 15: "deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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([True,True,True,True,False,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - 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 > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 < 7): - A /= 6.022e23 - A *= tau*np0 - elif (i >= 7 and i < 10): - A /= 6.022e23**2 - A *= tau*np0*np0 - elif(i >= 10 and i < 12): - A *= tau - elif (i >= 12 and i < 20): - A /= 6.022e23 - A *= tau*np0 - else: - A /= 6.022e23 - A *= tau*nAr - - 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_5SpeciesRates/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 = 5 - 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 = 5 - for i in range(1, Ns): - muList.append(Mobility(interpolate = False)) - - params.mobilityList = muList - - # 5) Dump to screen - params.print() diff --git a/psaapProperties_5Species_Sampling_1Torr.py b/psaapProperties_5Species_Sampling_1Torr.py deleted file mode 100755 index 48329354c..000000000 --- a/psaapProperties_5Species_Sampling_1Torr.py +++ /dev/null @@ -1,456 +0,0 @@ -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_5Species_Sampling_1Torr(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) - - # 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([0.0,0.0,0.0,0.0,5.6e-14,5.0e-18,1.25e-19,0.0,0.0,0.0,2.29e8,4.47e6,0.0,0.0,0.0,0.0,2.0e-13,6.4e-16,1.56e-16,1.76e-15,7.78e-18,2.3e-21]) # pre-exponential factors [cm^3/s] - B = np.array([0,0,0,0,0.61,0,-0.5,-4.5,0,0,0,0,0,0,0.74,0.74,0,0,0,0,0,0]) - A = np.array([0,0,0,0,2.61,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) # activation temperature [eV] - dH = np.array([11.548,12.023,15.76,4.212,3.737,0,0,-15.76,-4.212,-3.737,0,0,0.475,-0.475,-11.548,-12.023,0,-7.336,-8.286,-7.811,0,0]) # energy lost per electron due to ionization rxn [eV] - dEps = np.array([0.0,15.76,11.548,12.023,0.0]) # E, AR+, AR(m), AR(r), 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. - 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:3] *= tau*nAr - Ck[3:7] *= tau*np0 - Ck[7:10] *= tau*np0*np0 - Ck[10:12]*= tau - Ck[12:20]*= tau*np0 - Ck[20:] *= tau*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([[1,1,2,2,2,0,0,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0], # E - [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0], # AR+ - [1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0], # AR(m) - [0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0], # AR(r) - [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,2,1,1,1,1,2]], dtype=np.int64) # AR - - params.alfa = np.array([[1,1,1,1,1,1,1,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0], # E - [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], # AR+ - [0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,2,2,0,1,0,1], # AR(m) - [0,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,0,2,1,1,0], # AR(r) - [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]], dtype=np.int64) # AR - # Rxn1: E + Ar -> E + Ar(m) - # Rxn2: E + Ar -> E + Ar(r) - # Rxn3: E + Ar -> 2E + Ar+ - # Rxn4: E + Ar(m) -> 2E + Ar+ - # Rxn5: E + Ar(r) -> 2E + Ar+ - # Rxn6: E + Ar+ -> Ar(m) - # Rxn7: E + Ar+ -> Ar(r) - # Rxn8: 2E + Ar+ -> E + Ar - # Rxn9: 2E + Ar+ -> E + AR(m) - # Rxn10: 2E + Ar+ -> E + Ar(r) - # Rxn11: Ar(r) -> Ar - # Rxn12: Ar(r) -> Ar(m) - # Rxn13: E + Ar(m) -> E + Ar(r) - # Rxn14: E + AR(r) -> E + Ar(m) - # Rxn15: E + AR(m) -> E + Ar - # Rxn16: E + AR(r) -> E + Ar - # Rxn17: 2Ar(m) -> 2Ar - # Rxn18: 2Ar(m) -> E + Ar+ + Ar - # Rxn19: 2Ar(r) -> E + Ar+ + Ar - # Rxn20: Ar(m) + Ar(r) -> E + Ar+ + Ar - # Rxn21: Ar(r) + Ar -> Ar(m) + Ar - # Rxn22: Ar(m) + Ar -> 2Ar - - rxnNameDict = { 0: "1s-metastable", - 1: "1s-resonance", - 2: "Ionization", - 3: "StepIonization", - 4: "StepIonization", - #4: "E + Ar(r) => 2E + Ar+", - 5: "E + Ar+ => Ar(m)", - 6: "E + Ar+ => Ar(r)", - #7: "2E + Ar+ => E + Ar", - #8: "2E + Ar+ => E + Ar(m)", - #9: "2E + Ar+ => E + Ar(r)", - 7: "3BdyRecomb-ground", - 8: "3BdyRecomb-metastable", - 9: "3BdyRecomb-metastable", - 10: "Ar(r) => Ar", - 11: "Ar(r) => Ar(m)", - 12: "E + Ar(m) => E + Ar(r)", - 13: "E + Ar(r) => E + Ar(m)", - #14: "E + Ar(m) => E + Ar", - #15: "E + Ar(r) => E + Ar", - 14: "deexci-metastable", - 15: "deexci-resonance", - 16: "2Ar(m) => 2Ar", - 17: "2Ar(m) => E + Ar+ + Ar", - 18: "2Ar(r) => E + Ar+ + Ar", - 19: "Ar(m) + Ar(r) => E + Ar+ + Ar", - 20: "Ar(r) + Ar => Ar(m) + Ar", - 21: "Ar(m) + Ar => 2Ar",} - - # 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([True,True,True,True,True,False,False,True,True,True,False,False,True,True,True,True,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_5SpeciesRates" - if reactionExpressionTypelist[i]: - if i < 12 or i > 13: - 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 > 6 and i < 10: - rateCoeff /= 6.022e23**2 - else: - 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 < 3: - rateCoeffLog += - np.log(1.0/tau) + np.log(nAr) - elif i > 6 and i < 10: - 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 < 7): - A /= 6.022e23 - A *= tau*np0 - elif (i >= 7 and i < 10): - A /= 6.022e23**2 - A *= tau*np0*np0 - elif(i >= 10 and i < 12): - A *= tau - elif (i >= 12 and i < 20): - A /= 6.022e23 - A *= tau*np0 - else: - A /= 6.022e23 - A *= tau*nAr - - 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_5SpeciesRates/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 = 5 - 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 = 5 - 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.py b/psaapProperties_6Species_100mTorr.py deleted file mode 100755 index 925628450..000000000 --- a/psaapProperties_6Species_100mTorr.py +++ /dev/null @@ -1,483 +0,0 @@ -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(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.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.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 - - ## 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 deleted file mode 100755 index c984206c1..000000000 --- a/psaapProperties_6Species_100mTorr_Expanded.py +++ /dev/null @@ -1,534 +0,0 @@ -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 (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.44e7,1.61e7,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.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,-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) - 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-22 - False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] - if i > 23 and i < 28: - rateCoeff /= 6.022e23**2 - else: - 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 < 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 - 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_10Torr_Expanded.py b/psaapProperties_6Species_10Torr_Expanded.py deleted file mode 100755 index f8857447d..000000000 --- a/psaapProperties_6Species_10Torr_Expanded.py +++ /dev/null @@ -1,534 +0,0 @@ -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_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=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 = 1333.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.44e7,1.61e7,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.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,-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) - 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-22 - False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] - if i > 23 and i < 28: - rateCoeff /= 6.022e23**2 - else: - 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 < 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 - 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_1Torr_Expanded.py b/psaapProperties_6Species_1Torr_Expanded.py deleted file mode 100755 index 86ed5f809..000000000 --- a/psaapProperties_6Species_1Torr_Expanded.py +++ /dev/null @@ -1,534 +0,0 @@ -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=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-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.44e7,1.61e7,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.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,-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) - 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-22 - False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] - if i > 23 and i < 28: - rateCoeff /= 6.022e23**2 - else: - 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 < 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 - 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_250mTorr.py b/psaapProperties_6Species_250mTorr.py deleted file mode 100755 index 466192108..000000000 --- a/psaapProperties_6Species_250mTorr.py +++ /dev/null @@ -1,533 +0,0 @@ -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 deleted file mode 100755 index 321214fd5..000000000 --- a/psaapProperties_6Species_250mTorr_Expanded.py +++ /dev/null @@ -1,534 +0,0 @@ -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_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=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.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.44e7,1.61e7,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.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,-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) - 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-22 - False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] - if i > 23 and i < 28: - rateCoeff /= 6.022e23**2 - else: - 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 < 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 - 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_500mTorr.py b/psaapProperties_6Species_500mTorr.py deleted file mode 100755 index 99fa3b14d..000000000 --- a/psaapProperties_6Species_500mTorr.py +++ /dev/null @@ -1,533 +0,0 @@ -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 deleted file mode 100755 index a5626561f..000000000 --- a/psaapProperties_6Species_500mTorr_Expanded.py +++ /dev/null @@ -1,534 +0,0 @@ -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=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-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.44e7,1.61e7,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.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,-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) - 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-22 - False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] - if i > 23 and i < 28: - rateCoeff /= 6.022e23**2 - else: - 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 < 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 - 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_5Torr.py b/psaapProperties_6Species_5Torr.py deleted file mode 100755 index ea5a015d5..000000000 --- a/psaapProperties_6Species_5Torr.py +++ /dev/null @@ -1,533 +0,0 @@ -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 deleted file mode 100755 index 5448e6c5e..000000000 --- a/psaapProperties_6Species_5Torr_Expanded.py +++ /dev/null @@ -1,534 +0,0 @@ -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=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.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-13,2.1e-15,5.0e-16,6.4e-16,2.1e-21,1.32e8,1.44e7,1.61e7,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.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,-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) - 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-22 - False,False,True,True,True,True,False,False,False,False,True,True]) # Rxns 23-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("../../../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] - if i > 23 and i < 28: - rateCoeff /= 6.022e23**2 - else: - 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 < 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 - 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_Expanded.py b/psaapProperties_6Species_Expanded.py deleted file mode 100755 index c5535dace..000000000 --- a/psaapProperties_6Species_Expanded.py +++ /dev/null @@ -1,539 +0,0 @@ -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_Sampling.py b/psaapProperties_6Species_Sampling.py deleted file mode 100755 index 79cdd27e6..000000000 --- a/psaapProperties_6Species_Sampling.py +++ /dev/null @@ -1,457 +0,0 @@ -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(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)] - 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,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,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", - #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)"} - - # 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_Original" - if reactionExpressionTypelist[i]: - 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. - 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)] - 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 deleted file mode 100755 index 398b46e06..000000000 --- a/psaapProperties_6Species_Sampling_100mTorr_Expanded.py +++ /dev/null @@ -1,484 +0,0 @@ -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 (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.44e7,1.61e7,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.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,-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]) - - # 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: "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: "E + Ar(4p) => E + E + Ar+", - 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: "E + E + Ar+ => E + Ar(r)", - 25: "3BdyRecomb-metastable", - #26: "E + E + Ar+ => E + Ar(4p)", - 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: "E + Ar(r) => E + E + 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.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]) - - 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. - - # 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 < 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_Sobol/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_10Torr_Expanded.py b/psaapProperties_6Species_Sampling_10Torr_Expanded.py deleted file mode 100755 index b86559181..000000000 --- a/psaapProperties_6Species_Sampling_10Torr_Expanded.py +++ /dev/null @@ -1,484 +0,0 @@ -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=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 = 1333.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.44e7,1.61e7,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.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,-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]) - - # 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: "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: "E + Ar(4p) => E + E + Ar+", - 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: "E + E + Ar+ => E + Ar(r)", - 25: "3BdyRecomb-metastable", - #26: "E + E + Ar+ => E + Ar(4p)", - 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: "E + Ar(r) => E + E + 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.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]) - - 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. - - # 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 < 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_Sobol/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_1Torr_Expanded.py b/psaapProperties_6Species_Sampling_1Torr_Expanded.py deleted file mode 100755 index 50d0f096a..000000000 --- a/psaapProperties_6Species_Sampling_1Torr_Expanded.py +++ /dev/null @@ -1,484 +0,0 @@ -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=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) - - # 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.44e7,1.61e7,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.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,-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]) - - # 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: "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: "E + Ar(4p) => E + E + Ar+", - 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: "E + E + Ar+ => E + Ar(r)", - 25: "3BdyRecomb-metastable", - #26: "E + E + Ar+ => E + Ar(4p)", - 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: "E + Ar(r) => E + E + 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.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]) - - 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. - - # 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 < 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_Sobol/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_250mTorr.py b/psaapProperties_6Species_Sampling_250mTorr.py deleted file mode 100755 index ab608c9de..000000000 --- a/psaapProperties_6Species_Sampling_250mTorr.py +++ /dev/null @@ -1,499 +0,0 @@ -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 deleted file mode 100755 index 5fc2157f0..000000000 --- a/psaapProperties_6Species_Sampling_250mTorr_Expanded.py +++ /dev/null @@ -1,484 +0,0 @@ -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=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.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.44e7,1.61e7,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.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,-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]) - - # 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: "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: "E + Ar(4p) => E + E + Ar+", - 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: "E + E + Ar+ => E + Ar(r)", - 25: "3BdyRecomb-metastable", - #26: "E + E + Ar+ => E + Ar(4p)", - 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: "E + Ar(r) => E + E + 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.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]) - - 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. - - # 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 < 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_Sobol/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_500mTorr.py b/psaapProperties_6Species_Sampling_500mTorr.py deleted file mode 100755 index 71f69200d..000000000 --- a/psaapProperties_6Species_Sampling_500mTorr.py +++ /dev/null @@ -1,499 +0,0 @@ -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 deleted file mode 100755 index 6af741f9b..000000000 --- a/psaapProperties_6Species_Sampling_500mTorr_Expanded.py +++ /dev/null @@ -1,484 +0,0 @@ -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=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.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) - - # 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.44e7,1.61e7,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.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,-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]) - - # 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: "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: "E + Ar(4p) => E + E + Ar+", - 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: "E + E + Ar+ => E + Ar(r)", - 25: "3BdyRecomb-metastable", - #26: "E + E + Ar+ => E + Ar(4p)", - 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: "E + Ar(r) => E + E + 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.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]) - - 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. - - # 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 < 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_Sobol/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_5Torr_Expanded.py b/psaapProperties_6Species_Sampling_5Torr_Expanded.py deleted file mode 100755 index f85a28d9e..000000000 --- a/psaapProperties_6Species_Sampling_5Torr_Expanded.py +++ /dev/null @@ -1,484 +0,0 @@ -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=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 = 666.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) - - # 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.44e7,1.61e7,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.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,-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]) - - # 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: "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: "E + Ar(4p) => E + E + Ar+", - 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: "E + E + Ar+ => E + Ar(r)", - 25: "3BdyRecomb-metastable", - #26: "E + E + Ar+ => E + Ar(4p)", - 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: "E + Ar(r) => E + E + 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.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]) - - 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. - - # 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 < 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_Sobol/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_Expanded_NewRates.py b/psaapProperties_6Species_Sampling_Expanded_NewRates.py deleted file mode 100755 index 3b61bfab1..000000000 --- a/psaapProperties_6Species_Sampling_Expanded_NewRates.py +++ /dev/null @@ -1,489 +0,0 @@ -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_Expanded_NewRates(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)] - 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,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] - 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: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 - - # 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: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 - 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,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 - 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, - 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]: - 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. - 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 > 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], - 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_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 = 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_Verification.py b/psaapProperties_6Species_Verification.py deleted file mode 100755 index 89e0ced02..000000000 --- a/psaapProperties_6Species_Verification.py +++ /dev/null @@ -1,528 +0,0 @@ -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_Verification(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.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.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]]) - - Te = NDe_v_Te[:,0] - 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, De_interp) - De_Te_spline = CubicSpline.derivative(De_spline) - diffusivity = Diffusivity(interpolate = False, 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] - mue_interp = (Nmue_v_Te[:,1]/nAr)*V0*tau/(L*L) - mue_spline = CubicSpline(Te, 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/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 From 1da85fc531cd6cb2259db2b4d42dbbfa06819044 Mon Sep 17 00:00:00 2001 From: Juan Pablo Barberena Valencia Date: Wed, 25 Oct 2023 15:08:55 -0700 Subject: [PATCH 10/10] Add 'nominal' argon chemistry and update 6 species inputs --- BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 | Bin 0 -> 5232 bytes .../3BdyRecomb_Ground.h5 | Bin 0 -> 5232 bytes .../3BdyRecomb_Metastable.h5 | Bin 0 -> 5232 bytes .../3BdyRecomb_Resonant.h5 | Bin 0 -> 5232 bytes .../DeExcitation_4p.h5 | Bin 0 -> 5232 bytes .../DeExcitation_Metastable.h5 | Bin 0 -> 5232 bytes .../DeExcitation_Resonant.h5 | Bin 0 -> 5232 bytes BOLSIGChemistry_NominalRates/Excitation_4p.h5 | Bin 0 -> 5232 bytes .../Excitation_Metastable.h5 | Bin 0 -> 5232 bytes .../Excitation_Resonant.h5 | Bin 0 -> 5232 bytes BOLSIGChemistry_NominalRates/Ionization.h5 | Bin 0 -> 5232 bytes .../StepExcitation.h5 | Bin 0 -> 23200 bytes .../StepIonization_4p.h5 | Bin 0 -> 5232 bytes .../StepIonization_Metastable.h5 | Bin 0 -> 5232 bytes .../StepIonization_Resonant.h5 | Bin 0 -> 5232 bytes .../detailed_balance.py | 135 +++++ .../nominal_transport.h5 | Bin 0 -> 12688 bytes BOLSIGChemistry_NominalRates/plot_rates.py | 157 +++++ BOLSIGChemistry_NominalRates/plot_rates_h5.py | 110 ++++ chebSolver.py | 23 +- psaapProperties_6Species_100mTorr.py | 483 +++++++++++++++ psaapProperties_6Species_100mTorr_Expanded.py | 549 +++++++++++++++++ psaapProperties_6Species_10Torr_Expanded.py | 547 +++++++++++++++++ psaapProperties_6Species_1Torr_Expanded.py | 552 ++++++++++++++++++ psaapProperties_6Species_1Torr_Old.py | 542 +++++++++++++++++ psaapProperties_6Species_250mTorr.py | 533 +++++++++++++++++ psaapProperties_6Species_250mTorr_Expanded.py | 547 +++++++++++++++++ psaapProperties_6Species_2Torr_Expanded.py | 549 +++++++++++++++++ psaapProperties_6Species_500mTorr.py | 533 +++++++++++++++++ psaapProperties_6Species_500mTorr_Expanded.py | 549 +++++++++++++++++ psaapProperties_6Species_5Torr.py | 533 +++++++++++++++++ psaapProperties_6Species_5Torr_Expanded.py | 549 +++++++++++++++++ psaapProperties_6Species_Expanded.py | 539 +++++++++++++++++ psaapProperties_6Species_Sampling.py | 457 +++++++++++++++ ...ies_6Species_Sampling_100mTorr_Expanded.py | 494 ++++++++++++++++ ...rties_6Species_Sampling_10Torr_Expanded.py | 494 ++++++++++++++++ ...erties_6Species_Sampling_1Torr_Expanded.py | 495 ++++++++++++++++ psaapProperties_6Species_Sampling_250mTorr.py | 499 ++++++++++++++++ ...ies_6Species_Sampling_250mTorr_Expanded.py | 494 ++++++++++++++++ ...erties_6Species_Sampling_2Torr_Expanded.py | 494 ++++++++++++++++ psaapProperties_6Species_Sampling_500mTorr.py | 499 ++++++++++++++++ ...ies_6Species_Sampling_500mTorr_Expanded.py | 494 ++++++++++++++++ ...erties_6Species_Sampling_5Torr_Expanded.py | 494 ++++++++++++++++ ...ies_6Species_Sampling_Expanded_NewRates.py | 489 ++++++++++++++++ timePeriodicSolver.py | 30 +- voltage_sample_gen.py | 17 + 46 files changed, 12850 insertions(+), 30 deletions(-) create mode 100644 BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 create mode 100644 BOLSIGChemistry_NominalRates/3BdyRecomb_Ground.h5 create mode 100644 BOLSIGChemistry_NominalRates/3BdyRecomb_Metastable.h5 create mode 100644 BOLSIGChemistry_NominalRates/3BdyRecomb_Resonant.h5 create mode 100644 BOLSIGChemistry_NominalRates/DeExcitation_4p.h5 create mode 100644 BOLSIGChemistry_NominalRates/DeExcitation_Metastable.h5 create mode 100644 BOLSIGChemistry_NominalRates/DeExcitation_Resonant.h5 create mode 100644 BOLSIGChemistry_NominalRates/Excitation_4p.h5 create mode 100644 BOLSIGChemistry_NominalRates/Excitation_Metastable.h5 create mode 100644 BOLSIGChemistry_NominalRates/Excitation_Resonant.h5 create mode 100644 BOLSIGChemistry_NominalRates/Ionization.h5 create mode 100644 BOLSIGChemistry_NominalRates/StepExcitation.h5 create mode 100644 BOLSIGChemistry_NominalRates/StepIonization_4p.h5 create mode 100644 BOLSIGChemistry_NominalRates/StepIonization_Metastable.h5 create mode 100644 BOLSIGChemistry_NominalRates/StepIonization_Resonant.h5 create mode 100644 BOLSIGChemistry_NominalRates/detailed_balance.py create mode 100644 BOLSIGChemistry_NominalRates/nominal_transport.h5 create mode 100644 BOLSIGChemistry_NominalRates/plot_rates.py create mode 100644 BOLSIGChemistry_NominalRates/plot_rates_h5.py create mode 100755 psaapProperties_6Species_100mTorr.py create mode 100755 psaapProperties_6Species_100mTorr_Expanded.py create mode 100755 psaapProperties_6Species_10Torr_Expanded.py create mode 100755 psaapProperties_6Species_1Torr_Expanded.py create mode 100755 psaapProperties_6Species_1Torr_Old.py create mode 100755 psaapProperties_6Species_250mTorr.py create mode 100755 psaapProperties_6Species_250mTorr_Expanded.py create mode 100755 psaapProperties_6Species_2Torr_Expanded.py create mode 100755 psaapProperties_6Species_500mTorr.py create mode 100755 psaapProperties_6Species_500mTorr_Expanded.py create mode 100755 psaapProperties_6Species_5Torr.py create mode 100755 psaapProperties_6Species_5Torr_Expanded.py create mode 100755 psaapProperties_6Species_Expanded.py create mode 100755 psaapProperties_6Species_Sampling.py create mode 100755 psaapProperties_6Species_Sampling_100mTorr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_10Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_1Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_250mTorr.py create mode 100755 psaapProperties_6Species_Sampling_250mTorr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_2Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_500mTorr.py create mode 100755 psaapProperties_6Species_Sampling_500mTorr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_5Torr_Expanded.py create mode 100755 psaapProperties_6Species_Sampling_Expanded_NewRates.py create mode 100644 voltage_sample_gen.py diff --git a/BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 b/BOLSIGChemistry_NominalRates/3BdyRecomb_4p.h5 new file mode 100644 index 0000000000000000000000000000000000000000..38741b7ef5b5da603b1c455805437e757e68d21f GIT binary patch literal 5232 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 qX8kh{u6afAEoR3ShDN2IrufukcT~7Z1Du literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/3BdyRecomb_Resonant.h5 b/BOLSIGChemistry_NominalRates/3BdyRecomb_Resonant.h5 new file mode 100644 index 0000000000000000000000000000000000000000..fcc11aabf40c2fe02f4c8dd0153161c1ad9b9ce0 GIT binary patch literal 5232 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/DeExcitation_4p.h5 b/BOLSIGChemistry_NominalRates/DeExcitation_4p.h5 new file mode 100644 index 0000000000000000000000000000000000000000..54e6ace87d38d03d936ac2ab82cc5e0f31e721d8 GIT binary patch literal 5232 zcmeHHX*iW@+g^s1Wh!G)+9{d`Q#7!-E~Q;EY_oQyA`P_Bph4O@RLEMg3=3%bMgPP&fHW_k2F^~ zk3Vm@(@4tvKRwEP;vf6}ih;d)`1_9oTXRo6uhKHE&gRLuaLo3M{ai4w$G!6d|4Yk5 zBLBqV0`id7{Tqpg_h+J%i#xxK|BU(Ol>ehrTwaItQ@cRgDools%lC64c`o~7oR{|} zAccEV_;|SGBo`6x5?pine}@0%$jr!i_m3Mre-Guk=lCygDPK)mwS~!?~Bb%M8dw`@wa{R5|n83S+Phlh_9j(I}$MpGG;54BS zmk4R-n=_uIQ_2F%!zOxbOz&gDcy5pZjSVw!X~ZHR1%0kwl8HG)fWqSJgowT*v|9Rx zvq&idCW9Wo)pAV4nZDb@_XQ&1H`!GJ7J_&2`hf2x_nt^-zda*RUKo$I%k!%Cos0sB zgReK|(&NybL%r1gHVRNTFz>K?EKaU#a9(Z|4K=yim7Z5(uupWvqq{B|ij_ANk^Q4l zC(OIu#4H9zq?|ynzx!Nrb_Lti`f5>IwbeQnfw1x3t9e653ht5PD8vz@Wgm@5lat{*y zI~<*~k}n8j0$k?vS+dr(Meq(wtUfkOJTw-4`{2pi} z_iZ!?Un(Yxz9y%D;90K}JQjqm_3U?66)CWEy^Q|u=0K#dG}?#h_rPjbgiOHUKy(fM z#USU%eV9p6$20wO%+53aB~vXGBCS1`$2{q18$i}J6-k3JrldKFO_-!#&;w!eeJeY+`f77rmXYV?}QSARTXekO6S`5|2NV7P1z^G7j4(RYb$ z1{Cs9(!0wyfAIp4Tr{R9nz$u_gUUdsfArDREZ1`W@xZVlEH%K}+F{`jYE zG#pMZz7d<41zOvb+{pSg{KLW|QDOHZ(4&03(YKO@w)VPf7Ir^^o}3FZ=XhvHH!tpL z^nDC<1z&X{K2mX2Z~pKuwI^W06aQeWk%}@3+x0ElpTO|Q+RKVnR7@(9oZ$p#gOedu zx}%hegrvjlut5&&5?K~MSWZQi3dMt0g>vEi?1+e99Tjaq?GksX&V~BZ-I8Bgsi@>u zy0RwZDbS?8r(7GOBKv$AHO%fAa9#^}9222oeAARkmBw>$d!Kpc8Vq`?vEX9I)!d6 zg^=TCm{L&SkNfQwGTzx1fwXgr3kcjnzPOpb>5(FEykhW?Zh8lEy9RaSJc_}?8wW~aOk9ku>`dElUF1z6Fym@d3P$Geu37X(BqA#3x3)|ZKN z^sRhlVpLlRlm(d=7;SV6TA}NFo>>LkT5jE0DjSGJrcizHWHpfAzcAM`4a8l$kKWVJ zdI>4xnhFxMKWMl4$dU%q(cin@cU~WI^Vcm|-FCWMuXk@7 zSmFu+=k|r*mJ3hDDT^B*=3z&RJv9W&J0w2Ur#66@smjC&P6$rsXYu;)YlQRP+Zd6O z3~V1zag*+Agx(oaLX;H)eNKCuIt09iP2oFVYq1%aZ@zke>h>lGiqT(@*UG@XGhM~0 zADh6#ucFOTF%*w48L)|9HiHM_j5cvH6l(?-yXl+1fo!YUQ&B0QXcu4G@JhS|D) zR1AhM3J!mueL zv1+yUd(e8Cy(o7)3?)8Ci)6^O0zs_Z)1@Acu9BN*zkF$hsHTM4OBce?MmgX$)42`S z^2-YhJPgO+7j-@%-EDB+7@qkJh2xlJf}7KkcKE;%@l@Z)#5C(3xh-$oL6!emp`kq! z1I-`LRvzjAinQncwGm8=P?A;H+ui|N)zj)(4NR=<750uf-3eKzTy1=WS-8RL&c>GU zPS83{9IDn~VQ10b*T3E9g1tMdlfRv1A$8g6gdv%3D5dS+7azmI!=?vCiqgBGyKVVn zn_3pGh}yI3jA0Mt`%FszF~dTk>cX6{fgb11Vovvh4Ke&83o~kZKps~|34n%zdo~WmL-82Z? z*Zk{qO{W3a7bpKY(TKpZio?W|?jT5K-&AWnPM~JJsv%u&2pWnQ9o3f!RIw!w_D>H% zk|lj0?>2!WkxgHG&kloXbDCl}lR#0^&1Xp;he3C_`_P|>1bU|oG7ldc0iXR@_Uf4g zuImDF`1=uX*OO=veoo-OPWh&`HHP)%UpYlnI}qX`)QOFiXH8G%!sm;A~{CxF+B<{?-}pvdrzT}q)} zU_vo|CO4ZvG0ESm9AFZr3Nn4F(g@@;e7@R!a1vroAL{Rpo5LgejP0Vo!WYqy>zhLf z%qLgr%OCg#Hx5+o3GyNEDr?CHpQTf9I$4D#HOHTZik;U;%M@&x+-glfL14!_yJ4l6 zX`m+r>8G0!=S{ff=?BX`-DYv#M!r;P_C9?%Y`-e#j}Ud%daJ6?P+Yt=vEz{ZpfPdCPN^P->c zJ-d_p+32^u`-8JHAIc7l47bkdx2N_LHF1g$?SJ3CB1C|V*%NzY4Q}(}%SS^qAzdtP zKgihj`a!jIJ`2@uu8Nm>L`H__c6vXPg)M_C;&zxVKnj$i0I4)T?$qRbZxjd#YFcenS~#QDfsc8`Lg0#Cbnco%I`=J z#L^SLd7evPVuqZ@vWde&xGF0nWYCR?pVyqL8Iu#n=@lAJRvFFxAD%vQJoH`|@0~Mn zhLudL|148LzAJ)v1K0a+8w*F<8n2q6i=vqPB!D7U9F86Nv8ieM7vf(9@6P!Jhof2f zWgETKi%`RxDjj@09GB#zc8c2|A9Jc;(34EOOqDf?X z7`9IB^3m;;K>vu%meYJ;xbH8CL-8(>SkjPTP2z-N%n}Ca{j?;$=zdkD$qGeP&uE^< zR4FWq*`2C!A`~C;+1A^yl*UCRLM?RVP&{Rs%#)QZjh-1M+BM%8Xy)cdjk8#cSFG}1 nOcygyIcxUA>50W?8$W$1-=Bdq3wBD8*-Oy;+jage)(rd?u>49T literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/DeExcitation_Metastable.h5 b/BOLSIGChemistry_NominalRates/DeExcitation_Metastable.h5 new file mode 100644 index 0000000000000000000000000000000000000000..e436c66603be07cb00eb3b8579e20827a135131d GIT binary patch literal 5232 zcmeHHc{r8p7T>m%Ia5)ol$6_WOr5C6T0}`whNvV%lj zITVS1ZfAc}Gs{(GS~APe>g{GWd^0p~hNe-cH++C zX{;GQK8o@`k@%?7g0dOh*=zhe&(G`ppO%sex|HeO14O41=}$eCIt?f| zGb#LhGv*Xm(HR#rd28Dg z33dZk&uBgmFoNA2)O0Hfijsf4ACY)~lr(|l>pP->etu4zcxE12N4_22H75pwox`2w zP4h4)e>7dUECx7{CM%bXDktj0F?>tQrvYpIHug-veb$W?v?g6+a^flhz(usdP4_EO?pjz4T-vu z0d4!t86Y05Yj`Y~L~dDRh(jX-n(QkLI)5W^mH#EnDceLa88~-@--g88t`;ZYBm&1a zHos&miK$;7R4RETfhWJMq~tOZe?*FSGsTl(v58r56P1T=JI{7sN;2%dxh2McL!h&E z#yJs8f$LSuN=o$vdhCw*Hrkc~8W+lYhYAUF^3X^cyOs*>94q_rECM&N7d>64ng(sF zleSmK5qOO4rO4l!24~i&_4wT;@M@3m({G{aaM3^O!ZJSs&u@JHOv)$&UT_S=_go;b zW>tpRJAwN!^0cNw&V}c%F7|^}#eFz6XnV-`1c8Dvo7x7$GT|{-SdVJY)8AdTJO4-) z7`ZvtiP{kOxX@x*u0}T8@LXhMV@;q#sK7QeQ6_Bq&bZNONnrb(IWH7?nXs94Tp`4Q z!1w8QJ~y0XfrqhGxe<@wptvhuqm>0OmzO&U^X#4T(t^^h3Ai@y=~K9$z!VGim+rNpSKoi4f-9PaTW;PpdCP z5xBCaXi#6{5iISOpeHa0lvC8&W!d%!qL>(zUt(xcXYsZoGa_@hV&KI^qeG=UG+s zeIzi}oq03T@hOz-PMGlOAuzddVqev!XTTiErHYRb`25!^!CZ+#2;1KId-f!O`OnSP z?;9!v*VT&EhC(D#f)v-}o+*NE*{rG-X%Z8eOCJ?}Dgsa4l?%jq{Tgw1b47qnG30*^ zBD|GJ47h07V%k^?ZI68|+|)^=>rhp=RwWP^8usf}Z4%o*>6Umkmw=YsC!)fDL}N$s zdmkK1p&)U?odu>O@+VDlehig@U4}~Y9%~W{I{S6yuRaH3DQWswI}&5&xHc@3c>!BG zUdpd=;^FiA-XG0)0U|9Cnxn2HvfEabFb!TpovWkUo(m-I`K{-`>Mt)Lwf;lA`DGG^ z$G53_hm=9&^^ikV*GP==xGT)wSPmVYmz%Yg3c9F(Y5W zZOtdWSrH^^U#>ZD$gBcPg_p_KMDgZ#|Jb>CqLmOb`XECkj>MqK`h9z9DMF7DA)ux6M;mu8SyY6jKkPgFzU(Ri*?B8mFj?J_rM*MNY}yNlE$5_@GNtLkN5 z15Kwapq{7iNbESHGWr_wo0Kh^c;~0{@t1RtMgF+ z)wjNzN8;=Lg5ZeMK^VQ6U9uwHBRx4(C`U8k>OlodSB(O0jtx9RzM|f)ZWMcRxfl?!M(Hyx} zSn4|W@P~7}_f2~Jt!3X^VXYCjQ;_$**s6xUi+1@0zhvGx`VM*T$ICZ?5nZ3a_n74K z@2d$M-kRd&e54I_wm%l8iV(=O{w)7XOB)D<)+cH9v+$0^!>LM}cA%BylPB3Mj8|Et zxU;PtsMSKb@dOKNdqe^lP90E}=J%!}jD>6cZm(+|?Evrcy%lp}U`)%#Tii=DpZFfo@kzD#W}1x~?)j}%v*LidfZF(xsVpqqz3qB|OfSeY%iglG zvT(lH8$Id9UdWj{zbEow7MeOQVMD@Ku;J!U(&lEN(R-a|Tb=u$pz-t-A0iXWD-Op^ z==Fn-50~H^%*3sA>Ly|G1MoOp;&UB;CaO6I^!NT4fa`nd#$osG;}EU!d(hcIh`7uj zm~3_*#mqLGrF+4Br1e@VyD{G5U}++mm) zx?b;5n}%@ut7==o2%Jc1QJ!>5!%ON-=U*%xg_2-H|5E8REEq3)lAbdPy`2Y&x*nt= z=iR9~$30xQzK(D3?15CA=Gau;{kENjKpufJ#@84lcP?wz^oq`h5JE~5> z7})KLQ*hQ!L4K2GN<_`#0S%3N!b3uaZrWv1K49PYFY)8(DhNx z=BdDJY~^Y?-=+f%IaJuz?;5Iw!fj9&V*0^Ty@ot;hI~A!k!n=1<20 z^B|?bPkdN^j|?hYPe=7ahVlYOD$b4Ep<4MS0q?JUvX0S3#bBM!d*}KjV6awKw~Gru zuJ&77{7^9gKi8hTnKr?X){nHcjH7Azm}|Ib_l-H|yY@?a++h4nJp^z`!PFPVY^>x z@kcTSgW~DA4SIs8u|KBynsf~MG|Gv04+`RZiYCaNkH+R)n!@H3A-w18ki%+>!W{Xl zOSp%H(N0E)maH3vBdgtB56g>S&;A>$#8V@Y`Q+(on~x%R@llFqyHq6BjmQ-Xq>AFT zh6^YBF8_`Wul-&RoEO7^b7xNK^xebuqQq>bu{g3>@rk3XcbH2R9lHN!Ae_oeeayeWf+y~KX2Wrrfk z?@)Ja#RAM*Zt7ia6N)GIXYl1cUVtJ6RXYXV-9~dSubWAh3o!w5v%ZXnplaS!w-a|E crbL&}vK2yba_$xxfmm5wF0HdI#P}Be1JLhkBme*a literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/DeExcitation_Resonant.h5 b/BOLSIGChemistry_NominalRates/DeExcitation_Resonant.h5 new file mode 100644 index 0000000000000000000000000000000000000000..bcf78ca74151ef9ffa9a0fc8cf4df79552a7053e GIT binary patch literal 5232 zcmeHGX*iYZ`d?;c2q`KJijoFH^Q8Mmr9#_OoTMVP6kf zCrSK^o&U{o4_W%BW?r7RpW`w-T@C0yM3XZ*X&_kHqzcuKB0NcuUuK-w-s+CInk^P<3a?GHOI?@vHs z?xyhZaNS8{QEmt>`R)IT|7FQY|Ah9Bjh^4bHQYS@%g^{b+}{=Wy8{1#3h-?rHCQyg z0=t}Mu^q0d_=3vxXnOJ*YL6T2RzIGKq$q)iM@RgD_e1Pxi)<>IzG@gb#vcF$;*7EQ z0RlZT#-b0F1OP$%*7u}{z{oL*ukMpTD7D|-pBGM``|X>uVdg>bY2y_;kw*lcTHZum zq!J7~zm}A*v?Fkq?aBEd6as>b6N&n!1l}9;xOt~11P=6gEGHi!&~jx?#nDS|z=SZy zt$PW)L-o4Z&Uypg`va3I+9;V_p8r1hU13UAk*R!CQyEp0RHWcQ;5k9wu=5mB{UQ@d)UXet*%*&vrfkjoUAu$>|B#&$-w)X^At)>LVyzbX~0 z6k^001!93Cuj#)5Q_-n5u=!MZESL^40`Fc-Md5&*?VRWDA>h?73Kmbk+x=GQW}N*1 z-*#jUoFGy$J;!)e^0qjL_B!=MyFC>xp9yFfipIl+cN&6Bu{7-P;V)X#9}jNY%eEWu zPeVquPfz`?2_Pp^Br|54hFjJh3*Oe606S9GN}7kH;nkEVk7(1spu|@-=vHkS2AqqF z+ExD-C<*HtYAi@c4qIFJtw|!-9ttK6Lps_T+eQsB5%z(F1=rqoPqx^F^F2HO#pFM;VR{823lHct{3kn;N}s7?al`%_}sX#tHC1` z3cKYeLLX3YZC@@&Yg-z8yC7$ItCE7U>vkVAX-|W_f95L>%Vc77>Eco8+&~iXal3YoFPEoU@4Mth0;#?wM z{UQ^N>rU)dh|I!3$9S(-R$1_9;-PHHw=9gHPZ?C~%!VzjN$c`ovaxW-y~pDcIS}08 z)H)KCjTwc8n+=9@Ky$>jr;0ZRNgnGqB-`dfoOXg=k3|lK$FEGwY0HJYje4o8GIH>R z-=1QbS5f_X^k8agQFQV2d>#GeU! z^Duy)T)#}Z2n3ghImO!NVJP4I*s+)*uyvR{uQ8om8q6JT!00JPAZI+#C~bXiaP0P@HC%s4oob>&hSoKm9c7Ike85qM+>?Apn`+0+LAN7ig4HJ zi}bh-D#T0r#!KBU;`W0EAJ1Lh@-?RjSM&uH&J6!{%LIn>O z>J_6%E|u4;wFcZz_l+;|D@I4nkOs=dTBvqdW+uui=Jul&98<#Ia1=^V-+0$K5!X8C z*mg!E*1iO{UQZhnURn?0+o{be86{ZOAvI7NR}UM7v=|o!OK~DMh4<;v1~6fgKN}mC zV*8+)^AdIg_#HlftTv<+-EG_qFF$Jp`P!I-vY}GUHC8+xx0?>-F-*mi2g*=qwyQAi z6CD&+O|;29EyD{kgBHR545*o$vaxC@!|I`>&c}?KKy`mm-@5Lo2~c z&$S#AVyt~O*E2yk)!K2ep&ZwHdwN?2vfyMdQ#eKWBlfGwRyeb(r2-v+jo z3)E{^73f!7$7YEbYQv6)L-WZ(@#h zLWO|BLz^?z*jez$y>Ab?K+cKWaEnrnUMmzMKg)JQ{;s>fS&32cjNxg~f`o2xSwnrS zdw`0o-yGJm)$4(krollOc2rzgnV&H-*aLbqTfdkDQ?XlOl-Izw7jACwE3v4iV&696 zvDf}jAQqNl=R%?(%Wg||5c?C5Ha{JoQlsIM@w*{+g8Se!-IpzRfreXNx+<%kVuRx7 z)QVqT(lAF?;}J!=AG*qUrz=WnxX7?Zb1}UivK)_SCr#1t#MKp4cryT=(at%<)*3v@ zIFP;X>L5%<1nA@B}%6l!}>gZpaL^`6Up1_4k0nfS6ARI?Nq>Yx4$ zN(E8=-7_^f976x<;lP32{X<%N)oW4AaEk-!69+0<$66T|Ytb!s$p6gwVF-U`_QoZk z7L~d{;C0I|9B}rbdQ)qWGqo-u@$45kcg0wBRG<#kL(XgM>ihz0mkq8J*;j}D@~Sfa zmq*|s4_WR!xemuNk|;IfBalwNRdpz`4&lmxYP;JgRFX%7-?HlPu6omrqLpL7p{P)8 z7S|(XvLrJ)X$+Pm3~5yB)FZp`a;=sAIMfuEk-dJe$EnVnkITM{!|EhS%`HSdigF%k zsr>mB0?&mXK0Q#65{r*iT!snoE{Lg&TibwqdfAG1h9+R2t7wF*Sp%|z*e9$)Cn5c$ zm8GY51Lg`;99v`d4fvZ#XUB^g@OFSqulw>TSWi8ED}JT{cdA*r4l}19tbWh=wr!2r z(QL(037ZB-%MY7-Z5olBRyDiq+6<82i#bleX~f~^p=QS6SvcKd_8_;h5iJu7p4hLM zgMKMhS7mWJ7Sr^^nX_{+7CyCAU7L=N7Rk%rawK7F_G+Kc&U6gTb9(-{kA&p0W}!`g z(J|ih59U5=9t@puuo>*7BgM!=(Y=iak5YS6L{>6TJts_Qi4`x3Xmp#tFk)b=a^|M6 zZeDa4?kc(F&cMgJyL;{J`H=1P#qwb`1AAz{dPPm~q0c(XhN=+;rjH+9rt8U%&y=Mz zjw>~B`yqg5TTbyem^b0JhifCG2?4au4AejMya|~@tKaT15=7f1n~jvBCT>3jvH9kw zW6G0F`0#e?CjZw$cu;IKQGN>(J%U4%>otWj(sTty{2UYS&}GGYIl>qy9`Q87hl$MO zkTrWE7ht@VQ@=|Q6O-gzR*aunh;@7pb9=usadiE)>Jd2+B>67Cvv?y5<1@3an74@F z-h*m2nPx1k9hJ=!cqfXKR=3R;JXvU2?OOf$h8Xe)4Z3{JU|~mYcwGE(aZC<1lE`MW z(5UP;i$jWwkXmcRDqYr$G8u85Vtf)PuhQG=rqhhG{^pK!P+i8E);n-5Z(aacj}zEYPYy0{#=W2ytE@%TX9x!ue3m*42Bi`u_DX275@pMS$--2 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/Excitation_4p.h5 b/BOLSIGChemistry_NominalRates/Excitation_4p.h5 new file mode 100644 index 0000000000000000000000000000000000000000..5e1358d5c376d4f188fe0629b537fb368ea44874 GIT binary patch literal 5232 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 literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/Excitation_Metastable.h5 b/BOLSIGChemistry_NominalRates/Excitation_Metastable.h5 new file mode 100644 index 0000000000000000000000000000000000000000..3cfec52c6328c8a755bd6ff8573dca534c809061 GIT binary patch literal 5232 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 DyFr5- literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/Excitation_Resonant.h5 b/BOLSIGChemistry_NominalRates/Excitation_Resonant.h5 new file mode 100644 index 0000000000000000000000000000000000000000..f4b6fff0db6610dee239925627adad67083f921f GIT binary patch literal 5232 zcmeH~cT`i!9>)VA!qQO`L=+V8@njJsEXt~62GCWcEKMwc8pIU~RrCp{C?Z8vM06?A zi+~EQpi)$_f?`1pRjLqrCv+4Hj|pM!dHd%(@9aO%YXf<08von{9|?U)Bw1d+6tDhYb5<5x zwvc9%^Y!Oj-Y}A;z}%J4e8>0p|7r!cZGpd{2j0bd>iJXpns?6T7vsbM`Z32@m_Lu( z=EZ;6@{uTWwRi>jNUGdQeEf4ACA_-xxA9jd&z^jglv1RT=FTo4X^W7wXUKB{DYL!E z^YhOY6ym)pWIkS;v4_1Jz zMyj^2ivaVbZZhkG>aIj$CZ$nQF8vaPc~?aBh><`v=AitsbXp0)sbd8Bq`@UctX5apxQ$8I8)0Y>PZvQPFdmm=VDOLl)ld4rN%WV>{ z?-3h1-(F5IEh2zrZkdSvcuB-ndJVzK7tdJF*e7A1)860&dI-ML_xPQPS2Fg~5hC7M z;whME_Ja22sRTQ3$~YkcQ?d6njvgLk5$xniO`i0>gS`%O=`%IWG|Y}nFC}sl!RNa# zJR1&8$Nr>t?em4(GcbQp&Jg=Vxr^De;&!9WTY`n6by)1{_Xr=p!Z?55eav};kEX*xo0xuPN39d~K>!>>X0DE;MqgZMa!OoA;g3@>WfqnG;%(V4Y1hab# zg_5lwVt>r)SlU1>!ICk`K{E7g?Bh9pF}wN+4yV}9Y(A5Ny}L?N_(sV`nAs1CFD9iC zyvN!+P08>v_H;-6)#B|0U$-i5s}6dC{i<#T+kl#jSypL-ku{6p^w*0x%M#PwWFuTQ`{15S*}?Ut`?n1@6soPxS(x-CV##d`)C2zs-@B|F(;5O+#Smxn8{Lpk+tO& z_NHgMcdzauc;t(omiN^X>?1wHg_+u~F<;FRIml`uxa>}{URJ~#>^GhJuzRn?Tg-QM zPM#1HeTO;dU8T8c8NoLc^j$onO0h4p0Pj!!_8zl=;r@F%n?7Lfm6j^4l>UghHL3NO z#u&kK`@zJ1y~3fI%oc*@_M;5@W!*8;dUXW9k-yR;!zxThKnyWKA;bdRD1It5r93H=0e6n5{e z6=cvDRw_F(H`D-UC98eL=`7kdPFrziR}I)N_|J->yL{lFOuv0>R4rJae)!%uF-7ok zV2PKJRUOdZ3jCEqe+CXIWmT0@^&oLgYPs10EASx0G3>{xdaz>8!HrGnN5SfA!Pn@w z8$f>GVDY`M^PqQKnV9v_MzCiruP!(<9Moi|m8$4{20Og{G(>Y#!NSo5(QMf!P#7nt z@$JGB;JN6>D=Q|Nz-mwas7bXFV6PeaDaxf8EYoOIUP7)0;jhXAZ?-pscsY$mft_t& zWMitA^F9_Z66IG@xG@Z}c6G?FZD0XD5{YCh!w18xp3JOd(xCb+zcuS@dJyNj-MkMAjrA@SNcW<=Q02QnpoB%a{-PQ#OUp_;f@aRk zm>|9nC?6V4djZ$c zDFeOJgUD}caW95LaWxY`ZfxZ1ju*ayVixLdq%Jn{R>P~_z<|30QFaH05N`-ecn4M6 z044JC5XuXkrG9|yDWwMw_YEW8sP4vuT5$&q*0*xm)uyZrMy=G8i8?ZZyoAT*3OJUZ zT~I#G<-^+_Rzh&JPm>ieiae)Us~Vossyq2|`53AnWtaB}7JMmrnx4&NkLVq>u;FP9qaeyC7FY(U1U7To@4iMq)GAC=UF^V*yrGl!0KB{Asaj$?mnkZ`gYfc( z_D&ZUGOF*qM3D_U$_|I5O_5Q4pL#MI=8bP%Y8)(p{I7C7QW^wGx^gJKhMs`P~r zA2c!^g+4X1;++4t;%<}oDD8;2F6vVT(Uh@yPp5AG9?{?YH_;7Kv$gKH-yU<)HD zGi!%9^1gmPlhE?bzwEcDNFerM@O^f18SyDNq%3towT;U?1y`paTY!1n=-@)+^Y=?k!=@>N zK>cpSzNd|^PQ&eI7uu${E<(?*yFu(5Oq97r`aI2L&f}18Q0qbh-;)q&2nGt+KlcfJ|-ZOsB literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/Ionization.h5 b/BOLSIGChemistry_NominalRates/Ionization.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b0cb3e61d08bae00b4afb6f7a74ff917e8ff314c GIT binary patch literal 5232 zcmeI#c|25W1Hkb!Gp1z8TGnc0Nh?vQDCay{DCxCbb(3nOvfL=ijTWs;X;)X4LQWf| zNJ?T7nEd#v_}`f5Rq9AzYIbZ}_?Vzq$gJtBHTX6W$~`Yw=V1LiC)8FUEl#OfNS9#LuIpIQ*AO z3Pu;sC7O_e>5tDup$a#Yh~^a^#@|g7Jo#{>0>c~=KD#)!NE%x-MicHx7i@){N)=8h zDSA_A6wz?ZM@IA&qQ&q3$$wb(HXB#LH(LB2GDPR`4AXF-1lT4~f^LeWz;~mpc z_j2$`>Zu_uAFabuVP>FyYxHFFrf$+0|0uiF@AD*q6ff4}I|?IhB_I@%^_ zuX=oMvxJK1~-<1A!V?WOA+n@K0XP#WcgWuqRgOiB|cwJk+Cn(?Y{t^N|y{!?vYMo*)-34mvj|Ux1ubWH-;Y zmo&!Go|WmvM*Vi$w5)kZ68)M@dfypdkgxoth>n#YS!kCgDKR#SeC97{WKcOZo{r&;G&+UjD|ZH{(s*84=d z|NBa#zzZd)-|!2Q;w*ZBd?8JGXLAebiaYTu)52e(Zg%X=<}G%wknj95bYP;)Yh>2z zDqEWh(pP5yZ{LVg)C=wKvV*(JkS$hizqiEf4f1DYh0-eJa^%+AtzHHLq=ol`gSyF# zUEI_b(!%>ufx1R#^vKFu(l0fydRJ|Ei@G$ML*3j++84yU%iUFpy6}FGwsA1oE`72J z^#upA1|+9eBfo4>?5a#9J;Z)Uybe4 zDD@NRohscfHzR6LFYlQeu+E_t*)^e}x=NuA`F@Jqm3h^5cw}po(Y*(Grg|68USvkq z;}7behp%$-GW)!+Le|l<0rwAM?Rc+~WyZ}&D%D;20pB9Sm=|M@tx)_LE0dwxh&vy) zk+j=vvBFPj-uda@8qxeNhL_$)csC)36~7I+)=s+LG%;ZBwr14RHg#w&s3(2J;qlmO z=N8m&8mMVoHn-r~wSF=hcb1t~bV>)uxwqn$bF{8t+4<&kPF|c_H_(bpQg?phT3O(& zg~x(^oNB}84gS$k8JLKNYUn0@QEkVy?(g4Y`?>?)YPUtE@P0df>Dhq($Z{oO#;r9L zUK={_veMF0g92khs_a=#e|HDI$k;fevTOsISZY5(3gCC!-)dxm1lC5KSRsY zw#E^1c5i_a_cKlr{A5?OOd&Sz)!^W_x?m6WR8A+XYF0ck-P;YFHAyjxc=2j$^f2gw z=CWrO5T=zz8!l^pf%|9O%Pb@oGU+{^N4~(`MfvRo(Hq14#@fe+9twS0M#$RD--mq~ zw|YTC1rdC=Ct~Z4Uf3_3(W@r(+i?1g54~`{H8+a61bidquPVd zrwu^+G!^rR-0vlM$rVNKKA2gO-uH8q-@K0G7 z{P7L?46m)9kXKq;>VXdl95mZAZ-Ag}c%pl_2O3LmOZi6dqInx#W4}Ycpr?E%*!0qM zjLkowe>6NFCITZ>K8C0dLs#(o{vwtvbUoQyH#~m6M>R0e(%{NBh#L{~AQomt0X|u8 zM%DKJ1;?9@9jAicp0V5S$I_hyX2@v&91bWmKeVRGH*xKF$9ngGto zX{jFa#Rx&al~*(o#6I=A{G}5kD1ze;T`&oxojq1(>PCT`!M!a7a_w2VAx+Sj$5SmC zU{nyNKgE>_J;5?b7TleaH#e@GD%c;BU%y-qoLk!d(c7B__t&4`E)O~?_Jk%4Lt|LN zas`k*xJJ$Ttb|}ZJLrnMA`spWI_%T7bt(em(=!v4A3@{%&Jrb1*E1u2nf(OV8|{;o zf$)Be+h6A56mUAQac;zoiGulp=EVC?1+1H~nbklN?jL-1rwTaCRh|5iKkoAdj;f$8 zGlsD&agty>rnS>j4P6WZ?K5&&AUKv;1WFmxHpq5gWkFzoyM$m)0zV3Gok&^1$%x; zp*+lnW^}JTtq1G_0z%^*rwWYKSINx+h7ZR+x(`A(z1k5m3ye-!u1t?o5tyCbqoWW0 E4d10OOaK4? literal 0 HcmV?d00001 diff --git a/BOLSIGChemistry_NominalRates/StepExcitation.h5 b/BOLSIGChemistry_NominalRates/StepExcitation.h5 new file mode 100644 index 0000000000000000000000000000000000000000..f24fecab96307b42f6532c8e0b887f0ce2c1443a GIT binary patch literal 23200 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 PI36T;J}8o8NW}jFU){`c literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..47b16dc122f72b11c240bb5a873dc5111efb6f5a GIT binary patch literal 12688 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 BY^?wQ literal 0 HcmV?d00001 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/chebSolver.py b/chebSolver.py index f5f0a6e38..2e0e8b0b6 100644 --- a/chebSolver.py +++ b/chebSolver.py @@ -420,9 +420,7 @@ def __init__(self, Ns, NT, Np, elasticCollisionActivationFactor, elif(scenario==13): Nr = 23 elif(scenario==14): - Nr = 34 - elif(scenario==15): - Nr = 34 + Nr = 23 elif(scenario==16): Nr = 23 elif(scenario==21): @@ -1856,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 @@ -1926,22 +1925,6 @@ def plot(self, col, create=True): Ns = 6 elif(args.scenario==14): print('# Running scenario = 14 (6 species, 34 rxn, 1Torr, Nominal)') - Ns = 6 - elif(args.scenario==15): - print('# Running scenario = 15 (6 species, 34 rxn, 1Torr, Sampling)') - Ns = 6 - elif(args.scenario==16): - print('# Running scenario = 16 (6 species, 34 rxn, 250mTorr, Nominal)') - Ns = 6 - elif(args.scenario==17): - print('# Running scenario = 17 (6 species, 34 rxn, 500mTorr, Nominal)') - Ns = 6 - elif(args.scenario==18): - print('# Running scenario = 18 (6 species, 34 rxn, 250mTorr, Sampling)') - Ns = 6 - elif(args.scenario==19): - print('# Running scenario = 19 (6 species, 34 rxn, 500mTorr, Sampling)') - Ns = 6 elif(args.scenario==21): print("# Running scenario = 21 (4 species, 8 rxn, Liu 2017, interpolated transport)") Ns = 4 @@ -1985,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/psaapProperties_6Species_100mTorr.py b/psaapProperties_6Species_100mTorr.py new file mode 100755 index 000000000..925628450 --- /dev/null +++ b/psaapProperties_6Species_100mTorr.py @@ -0,0 +1,483 @@ +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(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.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.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 + + ## 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_Sampling.py b/psaapProperties_6Species_Sampling.py new file mode 100755 index 000000000..79cdd27e6 --- /dev/null +++ b/psaapProperties_6Species_Sampling.py @@ -0,0 +1,457 @@ +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(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)] + 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,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,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", + #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)"} + + # 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_Original" + if reactionExpressionTypelist[i]: + 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. + 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)] + 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/psaapProperties_6Species_Sampling_Expanded_NewRates.py b/psaapProperties_6Species_Sampling_Expanded_NewRates.py new file mode 100755 index 000000000..3b61bfab1 --- /dev/null +++ b/psaapProperties_6Species_Sampling_Expanded_NewRates.py @@ -0,0 +1,489 @@ +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_Expanded_NewRates(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)] + 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,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] + 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: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 + + # 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: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 + 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,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 + 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, + 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]: + 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. + 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 > 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], + 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_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 = 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/timePeriodicSolver.py b/timePeriodicSolver.py index 06861bad1..46a0454b3 100644 --- a/timePeriodicSolver.py +++ b/timePeriodicSolver.py @@ -209,20 +209,29 @@ def solveNewtonStep(self, Uic, Nt): elif(args.scenario==14): print('# Running scenario = 14 (6 species, 34 rxn, 1Torr, Nominal)') Ns = 6 - elif(args.scenario==15): - print('# Running scenario = 15 (6 species, 34 rxn, 1Torr, Sampling)') + 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==16): - print('# Running scenario = 16 (6 species, 34 rxn, 250mTorr, Nominal)') + elif(args.scenario==9): + print('# Running scenario = 9 (6 species, 34 rxn, 2Torr, Nominal)') Ns = 6 - elif(args.scenario==17): - print('# Running scenario = 17 (6 species, 34 rxn, 500mTorr, Nominal)') + elif(args.scenario==10): + print('# Running scenario = 10 (6 species, 34 rxn, 2Torr, Sampling)') Ns = 6 - elif(args.scenario==18): - print('# Running scenario = 18 (6 species, 34 rxn, 250mTorr, Sampling)') + elif(args.scenario==11): + print('# Running scenario = 11 (6 species, 34 rxn, 5Torr, Nominal)') Ns = 6 - elif(args.scenario==19): - print('# Running scenario = 19 (6 species, 34 rxn, 500mTorr, Sampling)') + 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)") @@ -231,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!')