From 148d3632693ac4478d0f54cac04ba766dc670d15 Mon Sep 17 00:00:00 2001 From: Arseny Mironov Date: Mon, 24 Jun 2024 18:12:26 +0200 Subject: [PATCH 01/17] Introducing new ionization modules and bug fix for tunneling ionization --- ionization_module_tests/cmap_map.py | 33 ++ ionization_module_tests/input.py | 210 ++++++++++++ ionization_module_tests/run_test.py | 164 +++++++++ src/Ionization/IonizationFactory.h | 39 ++- src/Ionization/IonizationTables.cpp | 6 + src/Ionization/IonizationTables.h | 108 +++++- src/Ionization/IonizationTunnel.cpp | 4 +- src/Ionization/IonizationTunnelBSI.cpp | 381 +++++++++++++++++++++ src/Ionization/IonizationTunnelBSI.h | 26 ++ src/Ionization/IonizationTunnelFullPPT.cpp | 189 ++++++++++ src/Ionization/IonizationTunnelFullPPT.h | 35 ++ src/Ionization/IonizationTunnelTL.cpp | 187 ++++++++++ src/Ionization/IonizationTunnelTL.h | 35 ++ src/Ionization/continuity_tool.cpp | 170 +++++++++ src/Ionization/continuity_tool.h | 23 ++ src/Python/pyinit.py | 1 + src/Species/Species.h | 3 + src/Species/SpeciesFactory.h | 5 +- 18 files changed, 1614 insertions(+), 5 deletions(-) create mode 100644 ionization_module_tests/cmap_map.py create mode 100755 ionization_module_tests/input.py create mode 100755 ionization_module_tests/run_test.py create mode 100755 src/Ionization/IonizationTunnelBSI.cpp create mode 100755 src/Ionization/IonizationTunnelBSI.h create mode 100755 src/Ionization/IonizationTunnelFullPPT.cpp create mode 100755 src/Ionization/IonizationTunnelFullPPT.h create mode 100755 src/Ionization/IonizationTunnelTL.cpp create mode 100755 src/Ionization/IonizationTunnelTL.h create mode 100755 src/Ionization/continuity_tool.cpp create mode 100755 src/Ionization/continuity_tool.h diff --git a/ionization_module_tests/cmap_map.py b/ionization_module_tests/cmap_map.py new file mode 100644 index 000000000..5bb5f939c --- /dev/null +++ b/ionization_module_tests/cmap_map.py @@ -0,0 +1,33 @@ +import matplotlib +import numpy as np +import matplotlib.pyplot as plt + +def cmap_map(function, cmap): + """ Applies function (which should operate on vectors of shape 3: [r, g, b]), on colormap cmap. + This routine will break any discontinuous points in a colormap. + """ + cdict = cmap._segmentdata + step_dict = {} + # Firt get the list of points where the segments start or end + for key in ('red', 'green', 'blue'): + step_dict[key] = list(map(lambda x: x[0], cdict[key])) + step_list = sum(step_dict.values(), []) + step_list = np.array(list(set(step_list))) + # Then compute the LUT, and apply the function to the LUT + reduced_cmap = lambda step : np.array(cmap(step)[0:3]) + old_LUT = np.array(list(map(reduced_cmap, step_list))) + new_LUT = np.array(list(map(function, old_LUT))) + # Now try to make a minimal segment definition of the new LUT + cdict = {} + for i, key in enumerate(['red','green','blue']): + this_cdict = {} + for j, step in enumerate(step_list): + if step in step_dict[key]: + this_cdict[step] = new_LUT[j, i] + elif new_LUT[j,i] != old_LUT[j, i]: + this_cdict[step] = new_LUT[j, i] + colorvector = list(map(lambda x: x + (x[1], ), this_cdict.items())) + colorvector.sort() + cdict[key] = colorvector + + return matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024) \ No newline at end of file diff --git a/ionization_module_tests/input.py b/ionization_module_tests/input.py new file mode 100755 index 000000000..86cdc7563 --- /dev/null +++ b/ionization_module_tests/input.py @@ -0,0 +1,210 @@ +import numpy as np +# import sys +# sys.path.append('/home/ent/Smilei_ionization/simulations/') + + +l0 = 2.0*np.pi # laser wavelength +t0 = l0 # optical cicle +Lsim = [12.*l0] # length of the simulation +Tsim = 24.*t0 # duration of the simulation +resx = 128. # nb of cells in one laser wavelength +dx = dy = dz = l0/resx +cell_length = [dx] +dt = 0.95*dx/np.sqrt(1.) +rest = t0/dt +timesteps = int(Tsim/dt) + +Z = 18 +mass = 39.948 + + +# laser pulse input parameters +a0 = 100. +omega = 1. +N_cycles = 10. +xf = Lsim[0]/2. +tcenter = N_cycles*l0 + +Lmu = 0.8 # mu-m + +c = 299792458. # m/sec +omega_ref = 2*np.pi*c/(Lmu*1.e-6) # 1/sec +eps0 = 8.8541878128e-12 # F⋅m^−1 +charge_SI = 1.60217663e-19 # C +m_e_SI = 9.1093837e-31 # kg +N_r = eps0*m_e_SI*omega_ref**2/charge_SI**2 +print('Reference density = ',N_r*10**(-6), ' cm-3') + +I_S = 4.65e29 #W/cm^2 +l_C = 3.8615901e-13 #m +I_ref = 0.5*(a0*omega_ref*l_C/c)**2.*4.65e29 +print('Reference intensity = ',I_ref, ' W/cm^2') + + +# n0 = 5.e13/(N_r*1.e-6) # initial density 5.e13 cm^(-3) +# nppc = 16 # nb of particle per cells + + +n0 = 5.e13/(N_r*1.e-6) +thickness = 0.25*l0 +position = Lsim[0]/2.-thickness/2. +def nf(x): + return n0*np.heaviside(x-position, 1.)*np.heaviside(position+thickness-x, 1.) +nppc = 128 + +Main( + geometry = "1Dcartesian", + + interpolation_order = 2 , + + cell_length = cell_length, + grid_length = Lsim, + + number_of_patches = [1], + + timestep = dt, + simulation_time = Tsim, + + reference_angular_frequency_SI = omega_ref, + + EM_boundary_conditions = [ ["silver-muller", "silver-muller"] ], + +) + +def sin2_envelope(t, tcenter, N): + if (-np.pi*N <= t-tcenter) and (t-tcenter <= np.pi*N): + return np.sin((t-tcenter+np.pi*N)/2./N)**2 + else: + return 0. + + + +Laser( + box_side = "xmin", + omega = omega, + space_time_profile = [ lambda t: 0., + lambda t: a0*sin2_envelope(t, tcenter, N_cycles)\ + *np.cos(omega*((t-tcenter)-xf)) ], +) + + +Species( + name = 'atom_tunnel', + ionization_model = 'tunnel', + ionization_electrons = 'electron', + atomic_number = Z, + position_initialization = 'regular', + momentum_initialization = 'cold', + particles_per_cell = nppc, + mass = mass*1836.0, + charge = 0., + # number_density = n0, + number_density = nf, + boundary_conditions = [['remove','remove']] +) + + +Species( + name = 'atom_TL', + ionization_model = 'tunnel_TL', + ionization_tl_parameter = 6, + ionization_electrons = 'electron', + atomic_number = Z, + position_initialization = 'regular', + momentum_initialization = 'cold', + particles_per_cell = nppc, + mass = mass*1836.0, + charge = 0., + # number_density = n0, + number_density = nf, + boundary_conditions = [['remove','remove']] +) + +Species( + name = 'atom_BSI', + ionization_model = 'tunnel_BSI', + ionization_electrons = 'electron', + atomic_number = Z, + position_initialization = 'regular', + momentum_initialization = 'cold', + particles_per_cell = nppc, + mass = mass*1836.0, + charge = 0., + # number_density = n0, + number_density = nf, + boundary_conditions = [['remove','remove']] +) + +Species( + name = 'atom_full_PPT', + ionization_model = 'tunnel_full_PPT', + ionization_electrons = 'electron', + atomic_number = Z, + position_initialization = 'regular', + momentum_initialization = 'cold', + particles_per_cell = nppc, + mass = mass*1836.0, + charge = 0., + # number_density = n0, + number_density = nf, + boundary_conditions = [['remove','remove']] +) + +Species( + name = 'electron', + position_initialization = 'regular', + momentum_initialization = 'cold', + particles_per_cell = 0, + mass = 1.0, + charge = -1.0, + charge_density = 0.0, + boundary_conditions = [['remove','remove']], +# time_frozen = 2.*Tsim +) + + +# DiagScalar( +# every = rest +# ) + + +DiagParticleBinning( + deposited_quantity = "weight", + every = 1, + species = ["atom_tunnel"], + axes = [ + ["charge", -0.5, Z+0.5, Z+1] + ] +) + +DiagParticleBinning( + deposited_quantity = "weight", + every = 1, + species = ["atom_TL"], + axes = [ + ["charge", -0.5, Z+0.5, Z+1] + ] +) + +DiagParticleBinning( + deposited_quantity = "weight", + every = 1, + species = ["atom_BSI"], + axes = [ + ["charge", -0.5, Z+0.5, Z+1] + ] +) + +DiagParticleBinning( + deposited_quantity = "weight", + every = 1, + species = ["atom_full_PPT"], + axes = [ + ["charge", -0.5, Z+0.5, Z+1] + ] +) + +DiagFields( + every = 100, + fields = ['Ex','Ey','Ez','Bx','By','Bz'] +) \ No newline at end of file diff --git a/ionization_module_tests/run_test.py b/ionization_module_tests/run_test.py new file mode 100755 index 000000000..1d79a72f0 --- /dev/null +++ b/ionization_module_tests/run_test.py @@ -0,0 +1,164 @@ +# +# ANALYSIS OF TUNNEL IONISATION SIMULATION +# + +simulation_to_analyse = '.' + +import matplotlib as mpl +import matplotlib.pyplot as plt +import numpy as np +from cmap_map import cmap_map + +# IMPORT SMILEI's POST-PROCESSING TOOL +# ------------------------------------ + +import happi + +import subprocess + +### RUN SMILEI SIMULATION +subprocess.run(["../../smilei", "input.py"]) + + +# LOADING SIMULATION & VARIABLES FROM NAMELIST +# ------------------------------------------------------ + +S = happi.Open(simulation_to_analyse ,verbose=False) + +t0 = 2.*np.pi +Lv = 0. +Lp = S.namelist.Lsim[0] +dt = S.namelist.Main.timestep +Z_A = S.namelist.Z + +a0 = S.namelist.a0 +resx = S.namelist.resx +Tsim = S.namelist.Tsim +Lsim = S.namelist.Lsim + +print('- ref. ang. frequency w0 = '+str(S.namelist.Main.reference_angular_frequency_SI)) + +### PLOT FIELD + +def plot_field(): + Data = S.Field(0, "Ey").getData() + i = int(len(Data)/3*1.913) + x = np.linspace(0, Lsim, Data[i].size) + + fig = plt.figure() + ax = fig.add_subplot(111) + ax.plot(x/t0, Data[i], linewidth=2.5) + + plt.xlim(x[0]/t0,x[-1]/t0) + plt.xlabel(r'$x/\lambda$') + plt.ylabel('Ey [a0]') + + +# SIMULATION ANALYSIS & COMPARISON TO RATE EQUATIONS +# -------------------------------------------------- + + +# get corresponding time-steps +t = dt * np.array(S.ParticleBinning(0).get()['times']) + + +# Species diagnostic number -> ionization model name +diag_model_dict = {0: 'Tunneling', + 1: 'Tong-Lin', + 2: 'Barrier suppression (BSI)', + 3: 'Full PPT (m != 0)'} + + +### PLOT CHARGE STATES FOR ONE SPECIES + +def plot_charge_states(diag, compare_to=None): + ''' + diag = 0, 1, 2, or 3 --- diagnostic number + compare_to = None, 0, 1, 2, or 3 --- if not None, the function plots another diagnostic for comparison + ''' + + # assign a color to each charge state + cmap = mpl.colormaps.get_cmap('gist_ncar') + cmap_dark = cmap_map(lambda x: 0.8*x, cmap) + charge = np.linspace(0, Z_A+1) + + n = np.array( S.ParticleBinning(diag).getData() ) + n00 = n[0,0] + n = n/n00 + + fig = plt.figure() + ax = fig.add_subplot(111) + for Z in range(Z_A+1): + rgba = cmap(Z/float(Z_A+1)) + ax.plot(t/t0, n[:,Z], color=rgba, linewidth=2, label='Z = %d'%Z) + title = diag_model_dict[diag] + + if compare_to != None: + n2 = array( S.ParticleBinning(compare_to).getData() ) + n200 = n2[0,0] + n2 = n2/n200 + for Z in range(Z_A+1): + rgba = cmap_dark(Z/float(Z_A+1)) + ax.plot(t/t0, n2[:,Z], '--', color=rgba, linewidth=1, label='Z = %d'%Z) + title = 'Solid: ' + title + '; dashed: ' + diag_model_dict[compare_to] + ax.legend(loc='upper left', ncol=1 if compare_to==None else 2, handletextpad=0.1, labelspacing=0.1) + ax.set_xlabel(r'$t/T$') + ax.set_ylabel(r'$n_i/n_{total}$') + ax.set_title(title) + + +def compare_models(tmin=10.5, tmax=14): + ''' + tmin and tmax set the plot limits alon the x-axis + ''' + cmap = mpl.colormaps.get_cmap('gist_ncar') + charge = np.linspace(0, Z_A+1) + + ### plot the density of each charge state as a function of time + fig, *axes = plt.subplots(nrows=4, ncols=1) + for i in range(4): + ax = axes[0][i] + n = np.array( S.ParticleBinning(i).getData() ) + n00 = n[0,0] + n = n/n00 + for Z in range(Z_A+1): + rgba = cmap(Z/float(Z_A+1)) + ax.plot(t/t0, n[:,Z], color=rgba, linewidth=1.2, label='Z = %d'%Z) + ax.set_xlim([tmin, tmax]) + ax.grid() + ax.text(tmin+0.05, + 0.85, + diag_model_dict[i], + bbox=dict(boxstyle='round', facecolor='w', edgecolor='k', alpha=0.05)) + ax.set_ylabel(r'$n_i/n_{total}$') + if i<3: + ax.set_xticklabels([]) + if i==0: + ax.legend(loc='upper left', + ncol=Z/3, + handletextpad=0.1, + labelspacing=0.1, + bbox_to_anchor=(0., 1.6)) + axes[0][-1].set_xlabel('t/T') + + plt.subplots_adjust(hspace=0) + + fig.set_size_inches(7, 7) + + +if __name__ == '__main__': + plot_field() + + plot_charge_states(0) + plot_charge_states(1) + plot_charge_states(2) + plot_charge_states(3) + + compare_models(tmin=10.5, tmax=14) + + plt.show(block=True) + + + + + diff --git a/src/Ionization/IonizationFactory.h b/src/Ionization/IonizationFactory.h index 87c985eff..517f42799 100755 --- a/src/Ionization/IonizationFactory.h +++ b/src/Ionization/IonizationFactory.h @@ -5,6 +5,9 @@ #include "IonizationTunnel.h" #include "IonizationFromRate.h" #include "IonizationTunnelEnvelopeAveraged.h" +#include "IonizationTunnelBSI.h" +#include "IonizationTunnelTL.h" +#include "IonizationTunnelFullPPT.h" #include "Params.h" @@ -54,7 +57,41 @@ class IonizationFactory } Ionize = new IonizationFromRate( params, species ); - + + } else if(model == "tunnel_BSI") { // added by I. Ouatu. Put keyword "tunnel_BSI" for the + // Tong-Lin ionization model in the species description in your namelist. + + if (species->max_charge_ > (int) species->atomic_number_) { // same as for simple Tunnel Ionization. + ERROR( "Charge > atomic_number for species " << species->name_); + } + if( (params.Laser_Envelope_model) ) { // same as for simple Tunnel Ionziation + ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); + } + + Ionize = new IonizationTunnelBSI(params, species); + + } else if(model == "tunnel_TL") { // added by Arseny Mironov. Put keyword "tunnel_TL" for the Tong-Lin ionization model + // in the species description in your namelist. + if (species->max_charge_ > (int) species->atomic_number_) { + ERROR( "Charge > atomic_number for species " << species->name_); + } + if( (params.Laser_Envelope_model) ) { // same as for simple Tunnel Ionziation + ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); + } + Ionize = new IonizationTunnelTL(params, species); + + } else if(model == "tunnel_full_PPT") { // added by Arseny Mironov. Put keyword "tunnel_full_PPT" for the tunneling ionization model + // with account for the magnetic quantum number in the species description in your namelist. + + if( species->max_charge_ > ( int )species->atomic_number_ ) { + ERROR( "Charge > atomic_number for species " << species->name_ ); + } + + if( params.Laser_Envelope_model ) { + ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); + } + + Ionize = new IonizationTunnelFullPPT( params, species ); } return Ionize; diff --git a/src/Ionization/IonizationTables.cpp b/src/Ionization/IonizationTables.cpp index 98df43bdb..860f50ae3 100755 --- a/src/Ionization/IonizationTables.cpp +++ b/src/Ionization/IonizationTables.cpp @@ -12,6 +12,12 @@ int IonizationTables::azimuthal_atomic_number( int atomic_number, int Zstar ) return ( int )azimuthalQuantumNumber[( atomic_number*( atomic_number-1 ) )/2 + Zstar]; } +// Gets the magnetic atomic number of a given ion +int IonizationTables::magnetic_atomic_number( int atomic_number, int Zstar ) +{ + return ( int )magneticQuantumNumber[( atomic_number*( atomic_number-1 ) )/2 + Zstar]; +} + // Gets the k-th binding energy in any neutral or ionized atom with atomic number Z and charge Zstar // We use the formula by Carlson et al., At. Data Nucl. Data Tables 2, 63 (1970) double IonizationTables::binding_energy( int atomic_number, int Zstar, int k ) diff --git a/src/Ionization/IonizationTables.h b/src/Ionization/IonizationTables.h index c93fe18fb..f623a0af6 100755 --- a/src/Ionization/IonizationTables.h +++ b/src/Ionization/IonizationTables.h @@ -1197,6 +1197,109 @@ const unsigned char azimuthalQuantumNumber[100/2*101] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }; +/* Added by Arseny Mironov. Note that for l=3 m is always set to zero. This is a temporary solution. */ +const signed char magneticQuantumNumber[100/2*101] = { + /* Z=1 */ 0, + /* Z=2 */ 0, 0, + /* Z=3 */ 0, 0, 0, + /* Z=4 */ 0, 0, 0, 0, + /* Z=5 */ 0, 0, 0, 0, 0, + /* Z=6 */ 0, 0, 0, 0, 0, 0, + /* Z=7 */ 0, 0,-1, 0, 0, 0, 0, + /* Z=8 */ 0, 0,-1,-1, 0, 0, 0, 0, + /* Z=9 */ 0, 0,-1,-1, 1, 0, 0, 0, 0, + /* Z=10 */ 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=11 */ 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=12 */ 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=13 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=14 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=15 */ 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=16 */ 0, 0,-1,-1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=17 */ 0, 0,-1,-1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=18 */ 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=19 */ 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=20 */ 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=21 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=22 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=23 */ 0, 0, 0,-1,-1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=24 */ 0, 0, 0,-1,-1, 1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=25 */ 0, 0, 0, 0,-1,-1, 1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=26 */ 0, 0, 0, 0,-1,-1, 1, 1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=27 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=28 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=29 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=30 */ 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=31 */ 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=32 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=33 */ 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=34 */ 0, 0,-1,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=35 */ 0, 0,-1,-1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=36 */ 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=37 */ 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=38 */ 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=39 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=40 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=41 */ 0, 0, 0,-1,-1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=42 */ 0, 0, 0,-1,-1, 1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=43 */ 0, 0, 0, 0,-1,-1, 1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=44 */ 0, 0, 0,-1,-1, 1, 1,-2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=45 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=46 */ 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=47 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=48 */ 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=49 */ 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=50 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=51 */ 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=52 */ 0, 0,-1,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=53 */ 0, 0,-1,-1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=54 */ 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=55 */ 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=56 */ 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=57 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=58 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=59 */ 0, 0, 0, 0, 0, 0, 0,-1,-1, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=60 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=61 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=62 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=63 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=64 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=65 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=66 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=67 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=68 */ 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,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=69 */ 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,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=70 */ 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, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=71 */ 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, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=72 */ 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, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=73 */ 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, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=74 */ 0, 0, 0, 0,-1,-1, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=75 */ 0, 0, 0, 0,-1,-1, 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, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=76 */ 0, 0, 0, 0, 0,-1,-1, 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, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=77 */ 0, 0, 0, 0,-1,-1, 1, 1,-2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=78 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=79 */ 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=80 */ 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=81 */ 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=82 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=83 */ 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=84 */ 0, 0,-1,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=85 */ 0, 0,-1,-1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=86 */ 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=87 */ 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=88 */ 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=89 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=90 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=91 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=92 */ 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=93 */ 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=94 */ 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=95 */ 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0,-1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=96 */ 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=97 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=98 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0, + /* Z=99 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0, 0,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1,-2,-2, 2, 2, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0, 0, 0 +}; + // Gets the ionization energy of a given ion double ionization_energy( int atomic_number, int Zstar ); @@ -1204,10 +1307,13 @@ double ionization_energy( int atomic_number, int Zstar ); // Gets the azimuthal atomic number of a given ion int azimuthal_atomic_number( int atomic_number, int Zstar ); +// Gets the magnetic atomic number of a given ion +int magnetic_atomic_number( int atomic_number, int Zstar ); + // Gets the k-th binding energy in any neutral or ionized atom with atomic number Z and charge Zstar // We use the formula by Carlson et al., At. Data Nucl. Data Tables 2, 63 (1970) double binding_energy( int atomic_number, int Zstar, int k ); }; -#endif \ No newline at end of file +#endif diff --git a/src/Ionization/IonizationTunnel.cpp b/src/Ionization/IonizationTunnel.cpp index abadcc5bd..31f605873 100755 --- a/src/Ionization/IonizationTunnel.cpp +++ b/src/Ionization/IonizationTunnel.cpp @@ -129,7 +129,7 @@ void IonizationTunnel::operator()( Particles *particles, unsigned int ipart_min, D_sum += Dnom_tunnel[i]; P_sum += exp( -IonizRate_tunnel[Z+i]*dt )*Dnom_tunnel[i]; } - Dnom_tunnel[k_times+1] -= D_sum; + Dnom_tunnel[k_times+1] = -D_sum; // bug fix P_sum = P_sum + Dnom_tunnel[k_times+1]*exp( -IonizRate_tunnel[newZ]*dt ); Pint_tunnel = Pint_tunnel + P_sum*Mult; @@ -264,7 +264,7 @@ void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned D_sum += Dnom_tunnel[i]; P_sum += exp( -IonizRate_tunnel[Z+i]*dt )*Dnom_tunnel[i]; } - Dnom_tunnel[k_times+1] -= D_sum; + Dnom_tunnel[k_times+1] = -D_sum; //bug fix P_sum = P_sum + Dnom_tunnel[k_times+1]*exp( -IonizRate_tunnel[newZ]*dt ); Pint_tunnel = Pint_tunnel + P_sum*Mult; diff --git a/src/Ionization/IonizationTunnelBSI.cpp b/src/Ionization/IonizationTunnelBSI.cpp new file mode 100755 index 000000000..7788bd5fb --- /dev/null +++ b/src/Ionization/IonizationTunnelBSI.cpp @@ -0,0 +1,381 @@ +#include "IonizationTunnelBSI.h" +#include "IonizationTables.h" +#include "continuity_tool.h" + +#include + +#include "Particles.h" +#include "Species.h" +using namespace std; + +IonizationTunnelBSI::IonizationTunnelBSI(Params ¶ms, Species *species) : Ionization(params, species) // :Ionization(params, species) applies the base CTOR to initialize inherited member variables. +{ + DEBUG( "Creating the Tunnel+BSI Ionizaton class" ); + + atomic_number_ = species->atomic_number_; + Potential.resize(atomic_number_); // Potential is a std::vector, a vector of IonizationPotentials (Ioniz Energies) + Azimuthal_quantum_number.resize(atomic_number_); // Azimuthal_quantum_number is a std::vector + + for(int Zstar = 0; Zstar < (int)atomic_number_; Zstar++) { // for each charge state (0e removed, 1e removed, ..., Z-1 e removed) + Potential [Zstar] = IonizationTables::ionization_energy(atomic_number_, Zstar) * eV_to_au; // last factor to convert to AtomicUnits. Whole instr. returns IP of element with atomic no = atomic_number_ and charge state Zstar (Zstar=0 is a neutral atom) + Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number(atomic_number_, Zstar); // + } + + one_third = 1.0/3.0; + + alpha_tunnel.resize(atomic_number_); + beta_tunnel.resize(atomic_number_); + gamma_tunnel.resize(atomic_number_); + + for(unsigned int Z=0 ; Z *Epart, Patch *patch, Projector *Proj, int ipart_ref ) { + unsigned int Z, Zp1, newZ, k_times; + double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel, Pint_BSI_linear, Pint_BSI_quadratic; + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); // For MonteCarlo procedure using the tunnel ioniz. rate. + vector IonizRate_BSI_linear(atomic_number_), Dnom_BSI_linear(atomic_number_); // For MonteCarlo procedure using the BSI ioniz. rate. + vector IonizRate_BSI_quadratic(atomic_number_), Dnom_BSI_quadratic(atomic_number_); + LocalFields Jion; // To deposit ionization current appearing from the ionization events. + double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; // Will be used to calc. ionization current. + + int nparts = Epart->size()/3; // Over 3 because there are 3 Dims. Epart is like [part1_Ex, part2_Ex, ... partnparts_Ex, part1_Ey, part2_Ey,...partnparts_Ey, part1_Ez, part2_Ez, partnparts_Ez]} + double *Ex = &( (*Epart)[0*nparts] ); // Pointer to beginning of the vector which holds the (3 * n_parts) values of the n_parts E-field (Physics) 3D vectors. + double *Ey = &( (*Epart)[1*nparts] ); // Pointer to where E_y values start inside the Epart vector. + double *Ez = &( (*Epart)[2*nparts] ); // Pointer to where E_z values start inside the Epart vector. + + for(unsigned int ipart = ipart_min ; ipart < ipart_max; ipart++) { // Loop on particles from Particles* particles input argument + // Current charge state of the ion. + Z = (unsigned int) (particles->charge(ipart)) ; // current charge state of the particle number ipart of species called ''species'' with atomic no = atomic_number_ + Zp1 = Z + 1; + // Implementation of Barrier Suppresion Ionization Critical Field E_cr. + // need E_cr to be in atomic units. Thus need to implement E_cr as from DonnaStrickland1991, page 5, eq(5). [Laser ionization of noble gases by Coulomb-barrier suppression] + // There the Ionization Potential appearing in formula is in AtomicUnits. + // Here, all values from Potential[] vector are in AtomicUnits also. + // Thus need to implement exactly Donna's formula: E_cr = pow(Potential[atomic_number*(atomic_number_-1)/2 + Z] , 2) / (4*Z); + // Donna's E_cr easily matches the SI units version of E_cr presented in Artmenko, Kostyukov, PhysRevA 96, 0321,06 (2017), page 2, section II. + // Russians researchers say E_cr = atomic_unit_of_field * kappa^4 / (16*Z), where kappa^2 = Ii/IH, thus Ii is measured in units of (atomic_unit_of_energy / 2). + // Had they measured Ii in atomic_unit_of_energy, the 16 on the denominator would become a 4. (atomic_unit_of_energy = 2*IH). + // Thus the implementation of E_cr in atomic units, following the Russians researchers would be: + // double ionizpots_ratio_forkappa = (Potential[ atomic_number_*(atomic_number_-1)/2 + Z ] / Potential[0]); // Potential[atomic_number_*(atomic_number_-1)/2 + Z] is IonizEnergy for current charge state of ion with atomic number equal to atomic_number_. Potential[0] is IonizPot of Hydrogen H. All the values in Pontential[] vector are in AtomicUnits. Thus the normalization dissapears when taking ratio of Ii/IH. + // double kappa = pow(ionizpots_ratio_forkappa , 0.5); + // double E_cr = ( pow(kappa,4) / (16*Z) ) / atomic_unit_of_field; // E_cr in AtomicUnits, as from Artmenko, Kostyukov, PhysRevA 96, 0321,06 (2017), page 2, section II. + + // HOW IS E_CR USEFUL? Answer: it is useless at the moment. + // E_cr in atomic units formula (with Potential[] vector's numerical values being in AtomicUnits): + double E_cr = pow( Potential[Z], 2) / (4*Zp1); // Formula from DonnaStrickland, 1991, page5, eq(5) [Laser ionization of noble gases by Coulomb-barrier suppression] + // There's absolutely no usage of this E_cr in the code. + + // If ion already fully ionized then skip and go to next particle + if (Z==atomic_number_) { continue; } // atom fully ionized already, no electrons remained to be stripped away. + + // Absolute value of the electric field in AtomicUnits (i.e. normalized to (in units of) E_atomic = 5.1422*10^11 V/m) + E = EC_to_au * sqrt( pow( *(Ex + ipart - ipart_ref), 2) // (Ex+ipart-ipart_ref) points to the location in the container Epart at which E-field_x for particle ipart sits. + + pow( *(Ey + ipart - ipart_ref), 2) // Similarly for y. Dereferencing it via *() means we access and use the value sitting at that location. + + pow( *(Ez + ipart - ipart_ref), 2) ); // EC_to_au transforms from SMILEI-normalized units to AtomicUnits. + if(E < 1e-10) { // E is in Atomic Units + continue; + } + + // Check whether to follow MC routine with Tunnel rate or with BSI rate (Quadratic or Linear). + // Prof. Tony Arber in: Arber_2015_Plasma_Phys._Control._Fusion_57_113001 gives a hint on how to do this. + // There he explains how to make the PIC code choose, at each timestep, between Tunnel and BSI (2 piece rate). + + // I am doing it in a simpler way, see int continuity_tool() function implementation! + // int continuity_tool(parameter1, ... ,) function does the job. Depending on the output of continuity_tool(,...,), SMILEI chooses which rate to use at each timestep. + + int rate_idx = continuity_tool(Zp1, E, alpha_tunnel[Z], beta_tunnel[Z], gamma_tunnel[Z], E_cr, Potential[Z], atomic_number_, au_to_w0); // + if (rate_idx != 0 ) { // Then use one of the two BSI rates: vector IonizRate_BSI_linear(atomic_number_) or vector IonizRate_BSI_quadratic(atomic_number_). + // So rate is not Tunnel. The rate_idx can only be 1 or 2. + if (rate_idx == 1) { // then use BSI-Quadratic rate, as dictated by continuity_tool() + + double IH = 13.598434005136; // IP of atomic Hydrogen (H), in eV. + double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // returns IP of Element with atomic no = atomic_number_ and charge state Z (Z=0 is a neutral atom) + double ratio_of_IPs = IH / Ii; + // IonizRate_BSI_quadratic[Z] = 2.4 * (pow(E,2)) / pow(Zp1,4); // From Bauer1999: Quadratic dep. on E and scales as 1/Z^4. From the formula on this line of code, the rate emerges in AtomicUnits, as E is in Atomic Units and Zp1 is a integer. + IonizRate_BSI_quadratic[Z] = au_to_w0 * (2.4 * (pow(E,2)) * pow(ratio_of_IPs, 2)); // 1/(Z^4) = (IH_Ii)^2 + // IonizRate_BSI_quadratic as 1 line above is now returned in SMILEI units. + invE = 1./E; + factorJion = factorJion_0 * invE*invE; // Used to compute the ionization current Jion. + // Monte Carlo routine from Nuter et al. 2011 + ran_p = patch -> rand_ -> uniform(); + + TotalIonizPot = 0.0; // Used to compute the ionization current Jion. + + // k_times will give the number of ionization events in this timestep. + k_times = 0; + Zp1 = Z + 1; + + if (Zp1 == atomic_number_) { // single-ionization, i.e. ioniz. of the last electron. + if ( ran_p < 1 - exp (-IonizRate_BSI_quadratic[Z]*dt) ) { // MC dictates to ionize it + TotalIonizPot += Potential[Z]; + k_times += 1; + } // else nothing happens, no ionization of the last electron during this timestep. for loop moves to next particle, i.e. the one indexed by ipart+1. + } + else { // multiple ionization can happen in one timestep because we are not ionizing the last electron yet. + // partial & final ionization are decoupled (see Nuter Phys. Plasmas 2011) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_BSI_quadratic[0] = 1.0; + Pint_BSI_quadratic = exp( -IonizRate_BSI_quadratic[Z]*dt ); + + // multiple ionization loop while Pint_BSI < ran_p and still partial ionization + while( (Pint_BSI_quadratic < ran_p) and (k_times < atomic_number_-Zp1) ) { + newZ = Zp1 + k_times; + double Ii_newZ = IonizationTables::ionization_energy(atomic_number_, newZ); + double ratio_of_IPs_newZ = IH / Ii_newZ; + IonizRate_BSI_quadratic[newZ] = au_to_w0 * (2.4 * (pow(E,2)) * pow(ratio_of_IPs_newZ, 2)); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_BSI_quadratic[ Z + k_times]; + for (unsigned int i=0; i <= k_times+1; i++) { + Dnom_BSI_quadratic[i] = Dnom_BSI_quadratic[i] / (IonizRate_BSI_quadratic[newZ] - IonizRate_BSI_quadratic[Z+i]) ; + D_sum += Dnom_BSI_quadratic[i]; + P_sum += exp(-IonizRate_BSI_quadratic[Z+i]*dt) * Dnom_BSI_quadratic[i]; + } + Dnom_BSI_quadratic[k_times+1] -= D_sum; + P_sum = P_sum + Dnom_BSI_quadratic[k_times+1] * exp(-IonizRate_BSI_quadratic[newZ]*dt); + Pint_BSI_quadratic = Pint_BSI_quadratic + P_sum*Mult; + + TotalIonizPot += Potential[Z + k_times]; + k_times++; + } // END while + + // final ionization (of last electron) + if ( ((1.0-Pint_BSI_quadratic) > ran_p) && (k_times == atomic_number_-Zp1) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } // END final ionization (of last electron) + + } // END multiple ionization routine. + + // Compute Ionization Currents + if (patch->EMfields->Jx_ != NULL) { + factorJion *= TotalIonizPot; + Jion.x = factorJion * *(Ex + ipart); + Jion.y = factorJion * *(Ey + ipart); + Jion.z = factorJion * *(Ez + ipart); + Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, + patch->EMfields->Jz_, *particles, ipart, Jion); + } + // Creation of the new electrons (variable weights are used) + if(k_times != 0) { // If ionization has taken place. + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; // new_electrons.size() = number of electrons in new_electrons. -1 from idNew because the first elem of array has index 0. + for(unsigned int i=0; i < new_electrons.dimension(); i++) { // new_electrons.dimension() is 1,2 or 3, depending on geometry of simulation. + new_electrons.position(i, idNew) = particles->position(i, ipart); + } + for(unsigned int i=0; i<3; i++) { + new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; + } + new_electrons.weight(idNew) = double(k_times) * particles -> weight(ipart); + new_electrons.charge(idNew) = -1; + + // Increase charge of particle. + particles->charge(ipart) += k_times; + } // END creation of new electrons. + + } // END subroutine for BSI-Quadratic rate // END if(index == 1) {} + + else { // if (rate_idx==1) {...} loop's else statement: means that rate_idx = 2 ==> use BSI-Linear + double IH = 13.598434005136; // IP of atomic Hydrogen (H), in eV. + double Ii = IonizationTables::ionization_energy(atomic_number_, Z); + double ratio_of_IPs = IH / Ii; + IonizRate_BSI_linear[Z] = au_to_w0 * (0.8 * E * pow(ratio_of_IPs, 0.5)); // paranthesis is in AtomicUnits + invE = 1./E; + factorJion = factorJion_0 * invE*invE; // Used to compute the ionization current Jion. + + ran_p = patch -> rand_ -> uniform(); + + TotalIonizPot = 0.0; // Used to compute the ionization current Jion. + + // k_times will give the number of ionization events in this timestep. + k_times = 0; + Zp1 = Z + 1; + if (Zp1 == atomic_number_) { // single-ionization, i.e. ioniz. of the last electron. + if ( ran_p < 1 - exp (-IonizRate_BSI_linear[Z]*dt) ) { // MC dictates to ionize it + TotalIonizPot += Potential[Z]; + k_times += 1; + } // else nothing happens, no ionization of the last electron during this timestep. for loop moves to next particle, i.e. the one indexed by ipart+1. + } + else { // multiple ionization can happen in one timestep because we are not ionizing the last electron yet. + // partial & final ionization are decoupled (see Nuter Phys. Plasmas 2011) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_BSI_linear[0] = 1.0; + Pint_BSI_linear = exp( -IonizRate_BSI_linear[Z]*dt ); + + // multiple ionization loop while Pint_BSI < ran_p and still partial ionization + while( (Pint_BSI_linear < ran_p) and (k_times < atomic_number_-Zp1) ) { + newZ = Zp1 + k_times; + double Ii_newZ = IonizationTables::ionization_energy(atomic_number_, newZ); + double ratio_of_IPs_newZ = IH / Ii_newZ; + IonizRate_BSI_linear[newZ] = au_to_w0 * (0.8 * E * pow(ratio_of_IPs_newZ, 0.5)); // Paranthesis is in Atomic Units + // Linear BSI rate as 1 line above is in SMILEI units. + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_BSI_linear[ Z + k_times]; + for (unsigned int i=0; i <= k_times+1; i++) { + Dnom_BSI_linear[i] = Dnom_BSI_linear[i] / (IonizRate_BSI_linear[newZ] - IonizRate_BSI_linear[Z+i]) ; + D_sum += Dnom_BSI_linear[i]; + P_sum += exp(-IonizRate_BSI_linear[Z+i]*dt) * Dnom_BSI_linear[i]; + } + Dnom_BSI_linear[k_times+1] -= D_sum; + P_sum = P_sum + Dnom_BSI_linear[k_times+1] * exp(-IonizRate_BSI_linear[newZ]*dt); + Pint_BSI_linear = Pint_BSI_linear + P_sum*Mult; + + TotalIonizPot += Potential[Z + k_times]; + k_times++; + } // END while + + // final ionization (of last electron) + if ( ((1.0-Pint_BSI_linear) > ran_p) && (k_times == atomic_number_-Zp1) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } // END final ionization (of last electron) + + } // END multiple ionization routine. + + // Compute Ionization Currents + if (patch->EMfields->Jx_ != NULL) { + factorJion *= TotalIonizPot; + Jion.x = factorJion * *(Ex + ipart); + Jion.y = factorJion * *(Ey + ipart); + Jion.z = factorJion * *(Ez + ipart); + Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, + patch->EMfields->Jz_, *particles, ipart, Jion); + } + + // Creation of the new electrons (variable weights are used) + if(k_times != 0) { // If ionization has taken place. + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; // new_electrons.size() = number of electrons in new_electrons. -1 from idNew because the first elem of array has index 0. + for(unsigned int i=0; i < new_electrons.dimension(); i++) { // new_electrons.dimension() is 1,2 or 3, depending on geometry of simulation. + new_electrons.position(i, idNew) = particles->position(i, ipart); + } + for(unsigned int i=0; i<3; i++) { + new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; + } + new_electrons.weight(idNew) = double(k_times) * particles -> weight(ipart); + new_electrons.charge(idNew) = -1; + + // Increase charge of particle. + particles->charge(ipart) += k_times; + } // END creation of new electrons. + } // END else {// rate_idx = 2} + } // END if(rate_idx != 0) {} + + else { // rate_idx = 0, so use Tunnel rate. There's no other rate_idx value which can appear. It is deemed to be 0 if the code reaches this else statement. + invE = 1./E; + factorJion = factorJion_0 * invE*invE; + delta = gamma_tunnel[Z] * invE; + ran_p = patch->rand_->uniform(); // + IonizRate_tunnel[Z] = beta_tunnel[Z] * exp(-delta*one_third + alpha_tunnel[Z]*log(delta)); + // IonizRate_tunnel as from 1 line above is in SMILEI units (beta has at its implementation's end the multiplication by au_to_w0) + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the number of ionization events + k_times = 0; + Zp1 = Z + 1; + + if( Zp1 == atomic_number_ ) { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if( ran_p < 1.0 - exp(-IonizRate_tunnel[Z]*dt) ) { // MC dictates to ionize it. + TotalIonizPot += Potential[Z]; + k_times = 1; // ionize it + } + } + else { + // else : MULTIPLE IONZIATION can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. Plasmas 2011) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0] = 1.0; + Pint_tunnel = exp(-IonizRate_tunnel[Z]*dt); // cummulative prob. (Pint_tunnel is a double) + + // MULTIPLE IONZIATION loop while Pint_tunnel < ran_p and still partial ionization. + while( (Pint_tunnel < ran_p) and (k_times < atomic_number_-Zp1) ) { + newZ = Zp1 + k_times; + delta = gamma_tunnel[newZ] * invE; + IonizRate_tunnel[newZ] = beta_tunnel[newZ] * exp(-delta*one_third + alpha_tunnel[newZ]*log(delta)); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel[ Z+k_times ]; + for(unsigned int i=0; i < k_times+1; i++) { + Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z+i]); + D_sum += Dnom_tunnel[i]; + P_sum += exp( -IonizRate_tunnel[Z+i]*dt ) * Dnom_tunnel[i]; + } + Dnom_tunnel[k_times+1] = -D_sum; //bug fix + P_sum = P_sum + Dnom_tunnel[k_times+1] * exp(-IonizRate_tunnel[newZ]*dt); + Pint_tunnel = Pint_tunnel + P_sum*Mult; + + TotalIonizPot += Potential[ Z+k_times ]; + k_times++; + } //END while + + // final ionization (of last electron) + if( ((1.0-Pint_tunnel) > ran_p) && (k_times == atomic_number_-Zp1) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } + } // END Multiple ionization routine for Tunnel rate + + // Compute ionization current + if (patch->EMfields->Jx_ != NULL) { // For the moment ionization current is not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *(Ex + ipart); + Jion.y = factorJion * *(Ey + ipart); + Jion.z = factorJion * *(Ez + ipart); + + Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, + *particles, ipart, Jion); + } + + // Creation of the new electrons (variable weights are used) + // ----------------------------- + if( k_times !=0 ) { // If ionization has taken place. + new_electrons.createParticle(); // new_electrons is an instance of class Particles. it is defined in Ionization.h + //new_electrons.initialize( new_electrons.size()+1, new_electrons.dimension() ); // ??? + int idNew = new_electrons.size() - 1; // new_electrons.size() = number of electrons in new_electrons. -1 from idNew because the first elem of array has index 0. + + for(unsigned int i=0; iposition(i, ipart); + } + for(unsigned int i=0; i<3; i++) { // Momentum is a 3Dim vector. (3Velocity simulation) + new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; + } + + new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); + new_electrons.charge(idNew) = -1; + + // Increase the charge of the particle + particles->charge(ipart) += k_times; + + } // END creation of electrons for when using Tunnel rate + } // END whole routine for when rate_idx = 0 , i.e. when using Tunnel rate + + } // END loop on particles + +} // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. diff --git a/src/Ionization/IonizationTunnelBSI.h b/src/Ionization/IonizationTunnelBSI.h new file mode 100755 index 000000000..512bc9c5b --- /dev/null +++ b/src/Ionization/IonizationTunnelBSI.h @@ -0,0 +1,26 @@ +#ifndef IONIZATIONTUNNELBSI_H +#define IONIZATIONTUNNELBSI_H + +#include +#include + +#include "Ionization.h" +#include "Tools.h" + +class Particles; + + +class IonizationTunnelBSI : public Ionization { + public: + IonizationTunnelBSI(Params ¶ms, Species *species); + void operator()(Particles*, unsigned int, unsigned int, std::vector*, Patch*, Projector*, int ipart_ref = 0) override; + + private: + unsigned int atomic_number_; + std::vector Potential, Azimuthal_quantum_number; + double one_third; + std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; + +}; + +#endif \ No newline at end of file diff --git a/src/Ionization/IonizationTunnelFullPPT.cpp b/src/Ionization/IonizationTunnelFullPPT.cpp new file mode 100755 index 000000000..5ec5b5a23 --- /dev/null +++ b/src/Ionization/IonizationTunnelFullPPT.cpp @@ -0,0 +1,189 @@ +#include "IonizationTunnelFullPPT.h" +#include "IonizationTables.h" + +#include + +#include "Particles.h" +#include "Species.h" + +using namespace std; + + + +IonizationTunnelFullPPT::IonizationTunnelFullPPT( Params ¶ms, Species *species ) : Ionization( params, species ) +{ + DEBUG( "Creating the FullPPT Tunnel Ionizaton class" ); + + atomic_number_ = species->atomic_number_; + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + Potential.resize( atomic_number_ ); + Azimuthal_quantum_number.resize( atomic_number_ ); + Magnetic_quantum_number.resize( atomic_number_ ); + for( int Zstar=0; Zstar<( int )atomic_number_; Zstar++ ) { + Potential [Zstar] = IonizationTables::ionization_energy( atomic_number_, Zstar ) * eV_to_au; + Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number( atomic_number_, Zstar ); + Magnetic_quantum_number[Zstar] = IonizationTables::magnetic_atomic_number( atomic_number_, Zstar ); + } + + for( unsigned int i=0; i *Epart, Patch *patch, Projector *Proj, int ipart_ref ) +{ + + unsigned int Z, Zp1, newZ, k_times; + double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; + vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + LocalFields Jion; + double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; + + int nparts = Epart->size()/3; + double *Ex = &( ( *Epart )[0*nparts] ); + double *Ey = &( ( *Epart )[1*nparts] ); + double *Ez = &( ( *Epart )[2*nparts] ); + + for( unsigned int ipart=ipart_min ; ipartcharge( ipart ) ); + + // If ion already fully ionized then skip + if( Z==atomic_number_ ) { + continue; + } + + // Absolute value of the electric field normalized in atomic units + E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) + +pow( *( Ey+ipart-ipart_ref ), 2 ) + +pow( *( Ez+ipart-ipart_ref ), 2 ) ); + if( E<1e-10 ) { + continue; + } + + // -------------------------------- + // Start of the Monte-Carlo routine + // -------------------------------- + + invE = 1./E; + factorJion = factorJion_0 * invE*invE; + delta = gamma_tunnel[Z]*invE; + ran_p = patch->rand_->uniform(); + + IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); + + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the nb of ionization events + k_times = 0; + Zp1=Z+1; + + if( Zp1 == atomic_number_ ) { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { + TotalIonizPot += Potential[Z]; + k_times = 1; + } + + } else { + // else : multiple ionization can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. Plasmas) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0]=1.0; + Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. + + //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { + newZ = Zp1+k_times; + delta = gamma_tunnel[newZ]*invE; + IonizRate_tunnel[newZ] = beta_tunnel[newZ] + * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); + + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel[Z+k_times]; + for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } + }//END Multiple ionization routine + + // Compute ionization current + if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *( Ex+ipart ); + Jion.y = factorJion * *( Ey+ipart ); + Jion.z = factorJion * *( Ez+ipart ); + + Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); + } + + // Creation of the new electrons + // (variable weights are used) + // ----------------------------- + if( k_times !=0 ) { + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; + for( unsigned int i=0; iposition( i, ipart ); + } + for( unsigned int i=0; i<3; i++ ) { + new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + } + new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); + new_electrons.charge( idNew )=-1; + + if( save_ion_charge_ ) { + ion_charge_.push_back( particles->charge( ipart ) ); + } + + // Increase the charge of the particle + particles->charge( ipart ) += k_times; + } + + + } // Loop on particles +} diff --git a/src/Ionization/IonizationTunnelFullPPT.h b/src/Ionization/IonizationTunnelFullPPT.h new file mode 100755 index 000000000..23bdfab42 --- /dev/null +++ b/src/Ionization/IonizationTunnelFullPPT.h @@ -0,0 +1,35 @@ +#ifndef IONIZATIONTUNNELFULLPPT_H +#define IONIZATIONTUNNELFULLPPT_H + +#include + +#include + +#include "Ionization.h" +#include "Tools.h" + +class Particles; + +//! calculate the particle tunnel ionization +class IonizationTunnelFullPPT : public Ionization +{ + +public: + //! Constructor for IonizationTunnelFullPPT: with no input argument + IonizationTunnelFullPPT( Params ¶ms, Species *species ); + + //! apply the Tunnel Ionization model to the species (with ionization current) + void operator()( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0 ) override; + +private: + unsigned int atomic_number_; + std::vector Potential; + std::vector Azimuthal_quantum_number; + std::vector Magnetic_quantum_number; + + double one_third; + std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; +}; + + +#endif diff --git a/src/Ionization/IonizationTunnelTL.cpp b/src/Ionization/IonizationTunnelTL.cpp new file mode 100755 index 000000000..32cbf638f --- /dev/null +++ b/src/Ionization/IonizationTunnelTL.cpp @@ -0,0 +1,187 @@ +#include "IonizationTunnelTL.h" +#include "IonizationTables.h" + +#include + +#include "Particles.h" +#include "Species.h" + +using namespace std; + + + +IonizationTunnelTL::IonizationTunnelTL( Params ¶ms, Species *species ) : Ionization( params, species ) +{ + DEBUG( "Creating the Tong-Lin Tunnel Ionizaton class" ); + + atomic_number_ = species->atomic_number_; + ionization_tl_parameter_ = species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double + // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + Potential.resize( atomic_number_ ); + Azimuthal_quantum_number.resize( atomic_number_ ); + for( int Zstar=0; Zstar<( int )atomic_number_; Zstar++ ) { + Potential [Zstar] = IonizationTables::ionization_energy( atomic_number_, Zstar ) * eV_to_au; + Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number( atomic_number_, Zstar ); + } + + for( unsigned int i=0; i *Epart, Patch *patch, Projector *Proj, int ipart_ref ) +{ + + unsigned int Z, Zp1, newZ, k_times; + double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; + vector IonizRate_tunnel_TL( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + LocalFields Jion; + double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; + + int nparts = Epart->size()/3; + double *Ex = &( ( *Epart )[0*nparts] ); + double *Ey = &( ( *Epart )[1*nparts] ); + double *Ez = &( ( *Epart )[2*nparts] ); + + for( unsigned int ipart=ipart_min ; ipartcharge( ipart ) ); + + // If ion already fully ionized then skip + if( Z==atomic_number_ ) { + continue; + } + + // Absolute value of the electric field normalized in atomic units + E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) + +pow( *( Ey+ipart-ipart_ref ), 2 ) + +pow( *( Ez+ipart-ipart_ref ), 2 ) ); + if( E<1e-10 ) { + continue; + } + + // -------------------------------- + // Start of the Monte-Carlo routine + // -------------------------------- + + invE = 1./E; + factorJion = factorJion_0 * invE*invE; + delta = gamma_tunnel[Z]*invE; + ran_p = patch->rand_->uniform(); + IonizRate_tunnel_TL[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) - E*lambda_tunnel[Z] ); + + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the nb of ionization events + k_times = 0; + Zp1=Z+1; + + if( Zp1 == atomic_number_ ) { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if( ran_p < 1.0 -exp( -IonizRate_tunnel_TL[Z]*dt ) ) { + TotalIonizPot += Potential[Z]; + k_times = 1; + } + + } else { + // else : multiple ionization can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. Plasmas) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0]=1.0; + Pint_tunnel = exp( -IonizRate_tunnel_TL[Z]*dt ); // cummulative prob. + + //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { + newZ = Zp1+k_times; + delta = gamma_tunnel[newZ]*invE; + IonizRate_tunnel_TL[newZ] = beta_tunnel[newZ] + * exp( - delta*one_third + alpha_tunnel[newZ]*log( delta ) - E*lambda_tunnel[newZ] ); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel_TL[Z+k_times]; + for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } + }//END Multiple ionization routine + + // Compute ionization current + if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *( Ex+ipart ); + Jion.y = factorJion * *( Ey+ipart ); + Jion.z = factorJion * *( Ez+ipart ); + + Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); + } + + // Creation of the new electrons + // (variable weights are used) + // ----------------------------- + + if( k_times !=0 ) { + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; + for( unsigned int i=0; iposition( i, ipart ); + } + for( unsigned int i=0; i<3; i++ ) { + new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + } + new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); + new_electrons.charge( idNew )=-1; + + if( save_ion_charge_ ) { + ion_charge_.push_back( particles->charge( ipart ) ); + } + + // Increase the charge of the particle + particles->charge( ipart ) += k_times; + } + + } // Loop on particles +} + diff --git a/src/Ionization/IonizationTunnelTL.h b/src/Ionization/IonizationTunnelTL.h new file mode 100755 index 000000000..2437fe955 --- /dev/null +++ b/src/Ionization/IonizationTunnelTL.h @@ -0,0 +1,35 @@ +#ifndef IONIZATIONTUNNELTL_H +#define IONIZATIONTUNNELTL_H + +#include + +#include + +#include "Ionization.h" +#include "Tools.h" + +class Particles; + +//! calculate the particle tunnel ionization with Tong-Lin model +class IonizationTunnelTL : public Ionization +{ + +public: + //! Constructor for IonizationTunnelTL: with no input argument + IonizationTunnelTL( Params ¶ms, Species *species ); + + //! apply the Tunnel Ionization model to the species (with ionization current) + void operator()( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0 ) override; + +private: + unsigned int atomic_number_; + std::vector Potential; + std::vector Azimuthal_quantum_number; + + double one_third; + double ionization_tl_parameter_; + std::vector alpha_tunnel, beta_tunnel, gamma_tunnel, lambda_tunnel; +}; + + +#endif diff --git a/src/Ionization/continuity_tool.cpp b/src/Ionization/continuity_tool.cpp new file mode 100755 index 000000000..ad0c16a0f --- /dev/null +++ b/src/Ionization/continuity_tool.cpp @@ -0,0 +1,170 @@ +#include "continuity_tool.h" // declares double au_to_eV; +#include "Ionization.h" +#include "IonizationTunnelBSI.h" +#include "IonizationTables.h" // can use the raw ionizationEnergy[100/2*101] (all in eV), but also the function ionization_energy(int atomic_number, int Zstar) which returns: ionizationEnergy[( atomic_number*(atomic_number-1) )/2 + Zstar] +// just write IonizationTables::ionizationEnergy[atomic_number_*(atomic_number-1)/2 + Zstar] to get IonizPotential (in eV) of Element with atmomic # = atomic_number and charge state Zstar, i.e. Element^{+Zstar} +// For instance IonizationTables::ionizationEnergy[13*12/2 + 3] is the ionization energy of Al3+ in eV. + +#include +#include + +double au_to_eV = 27.2116; // will be used by continuity_tool( , , ) to convert Potential[Z] (in AtomicUnits) to eV. + + +int continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0) { + // returns: + // 0 for when it chooses Tunnel ADK-PPT Ionization Rate, + // 1 for when it chooses the BSI-Quadratic Ionization Rate, + // 2 for when it chooses BSI-Linear Ionization Rate + + // Aim is to implement the 3-piece general rate, so a method to choose between Tunnel or BSI linear or BSI quadratic. + // E_cr from the arguments of this function is useless at the moment. + // alpha, beta, gamma coefficients are single numbers, for ion with charge state Z = Zp1 - 1, for a fixed atomic number (of the species under consideration). Z=0 is a neutral atom, Z=1 is singly ionized ion, i.e. Na^{+1}. + // alpha = alpha_tunnel[Z], beta = beta_tunnel[Z], gamma = gamma_tunnel[Z], where Z = Zp1 - 1 and + // where alpha_tunnel[Z] uses Z and Potential[Z] (IonizationPotential (in AtomicUnits) of Element with atomic number = atomic_number_ and charge state Z (Z=0 means neutral atom)) + // (double) Potential from arguments is the IP in AtomicUnits for current charge state Z (Z=0 is neutral atom) for a fixed atomic no = atomic_number_. + // Potential from the arguments is not actually needed!!! + unsigned int Z = Zp1 - 1; + + double Potential_in_eV = Potential * au_to_eV; // AtomicUnits to eV conversion on Potential from arguments of this function. // not actually needed !! + // Potential_in_eV will be used for BSI linear rate implemented below. There we need the ratio of Potential_in_eV[] and 13.6 eV + // not actually needed anymore! + + double BSI_rate_quadratic = BSI_rate_quadratic_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ + double BSI_rate_linear = BSI_rate_linear_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ + double Tunnel_rate = Tunnel_rate_function(Z, E, alpha, beta, gamma); // Z = Zp1 - 1; + + //double BSI_rate_quadratic_loglogder_wrtE = BSI_rate_quadratic_function_loglogder_wrtE(Zp1, E, atomic_number_); + //double BSI_rate_linear_loglogder_wrtE = BSI_rate_linear_function_loglogder_wrtE(Zp1, E, atomic_number_); + //double Tunnel_rate_loglogder_wrtE = Tunnel_rate_function_loglogder_wrtE(Z, E, alpha, beta, gamma); + +// Tony Arber 2015, the review paper on PIC codes. Arber_2015_Plasma_Phys._Control._Fusion_57_113001 +// There he explains how to make the PIC code choose, at each timestep, between Tunnel and BSI. +// So he tells us how to implement a 2-piece formula for the ionization rate. + +// if (BSI_rate_quadratic_loglogder_wrtE > Tunnel_rate_loglogder_wrtE) { // Conditions for a 2-piece general rate, where the aim is to choose between Tunnel and BSI quadratic rate. +// return true; // i.e. use BSI rate because E > Eprime (location of the intersection of the 2 rates) +// } +// else if (BSI_rate_quadratic > Tunnel_rate) { // simulates: else return minimum(BSI_rate_quadratic, Tunnel_rate) +// return false; // i.e. use Tunnel Rate +// } +// else return true; // i.e. use BSI Rate. + +// Below I implement a method to choice from the 3 rates (i.e. the 3 piece formula) +// based on something simpler than in Arber where he uses log-log derivatives. +// Just look at the graphs from Golovanov 2020 paper (arxhiv one for nicely coloured graphs). + if (BSI_rate_quadratic >= BSI_rate_linear) { // all these rates which are compared here are in SMILEI units + return 2; // 2 means return BSI-Linear rate + } + else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) { // this returns min(Tunnel, BSI-Quadratic) + return 1; // 1 means return BSI-Quadratic rate + } + else return 0; // 0 means return Tunnel rate. The min is Tunnel rate + +} + + +// TUNNEL Ionization Rates +// ############################################################# +// 1) ADK-PPT static rate in units of atomic_unit_of_freq, all physical quantities inside rate formula are in atomic units. +double Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma) { // E is in Atomic Units + // Z from arguments is useless here as alpha, beta, gamma are for that Z already. + double one_third = 1.0/3.0; + double invE = 1./E ; + double delta = gamma * invE; + + double Tunnel_rate = beta * exp( -delta*one_third + alpha*log(delta) ); // E depenedency comes through delta + return Tunnel_rate; // returned rate is in SMILEI UNITS due to beta from above +} + +// double Tunnel_rate_function_der_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma) { +// // I wrote the expression for derivative using gamma only, nothing related to delta. +// double one_third = 1.0/3.0; +// double invE = 1./E ; +// // double delta = gamma * invE; // I wrote the expression for derivative using gamma only. + +// double Tunnel_rate_der_wrtE = beta * exp(- gamma*one_third*invE) * pow((gamma*invE), alpha) * (gamma*one_third*pow(invE, 2) - alpha*invE); +// return Tunnel_rate_der_wrtE; +// } + +// double Tunnel_rate_function_loglogder_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma) { +// double Tunnel_rate = Tunnel_rate_function(Z, E, alpha, beta, gamma); +// double Tunnel_rate_der_wrtE = Tunnel_rate_function_der_wrtE(Z, E, alpha, beta, gamma); + +// double Tunnel_rate_loglogder_wrtE = (E/Tunnel_rate) * Tunnel_rate_der_wrtE; // log-log derivative is: (x/y) * (dy/dx) where in our case: y = Rate, x = E-field. +// return Tunnel_rate_loglogder_wrtE; +// } + +// BSI rates +// ############################################################################## +// BSI rates below are calculated in atomic units, for both the Quadratic rate and the Linear rate. +// 1) QUADRATIC dependence on local E-field <--> Bauer and Mulser, in PhysRevA Vol.59, No.1, 1999. +double BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. + // double BSI_rate_quadratic = 2.4 * (pow(E,2)) / pow(Zp1,4); // Formula as in the paper. But I implement it using the ratio of IonizPotentials. See Golovanov 2020 paper + // The rate computed below is in AtomicUnits. E-field received as argument is in AtomicUnits (see IonizationTunnelBSI::operator()(arg1, arg2, ...) function) + double Z = Zp1 - 1; + double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. + double Ii = IonizationTables::ionization_energy(atomic_number_, Z); + double ratio_of_IPs = IH / Ii; + + double BSI_rate_quadratic = 2.4 * (pow(E,2)) * pow(ratio_of_IPs,2); // E is in atomic units here, rate is calculated in atomic units + // return BSI_rate_quadratic; // Returns the rate in ATOMIC UNITS (i.e. normalized to atomic_unit_of_frequency) + return (BSI_rate_quadratic * au_to_w0); // in SMILEI UNITS +} + +// Derivatives of BSI Quadratic rate: +// double BSI_rate_quadratic_function_der_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_) { // simple derivative of BSI quadratic rate wrt E-field +// // double BSI_rate_quadratic_der_wrtE = 2.4 * 2 * E / pow(Zp1,4); // The derivate of the formula as it's appearing in the paper by Bauer-Mulser BM. +// double Z = Zp1 - 1; +// double IH = 13.598434005136; +// double Ii = IonizationTables::ionization_energy(atomic_number_, Z); +// double ratio_of_IPs = IH / Ii; + +// double BSI_rate_quadratic_der_wrtE = 2.4 * 2 * E * pow(ratio_of_IPs,2); +// return (BSI_rate_quadratic_der_wrtE * au_to_w0); // Returned in SMILEI UNITS. +// // return BSI_rate_quadratic_der_wrtE; // Returned in Atomic Units. +// } + +// double BSI_rate_quadratic_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_) { +// double BSI_rate_quadratic = BSI_rate_quadratic_function(Zp1,E, atomic_number_); +// double BSI_rate_quadratic_der_wrtE = BSI_rate_quadratic_function_der_wrtE(Zp1,E, atomic_number_); + +// double BSI_rate_quadratic_loglogder_wrtE = (E/BSI_rate_quadratic) * BSI_rate_quadratic_der_wrtE; // log-log derivative is: (x/y) * (dy/dx) where in our case: y = Rate, x = E-field. +// return BSI_rate_quadratic_loglogder_wrtE; +// } + + + +// 2) BSI-LINEAR dependence on local E-field <---> Kostyukov+Golovanov: Field ionization in short and extremely intense laser pulses, 2018 +double BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. +// double BSI_rate_linear = 0.8 * (E / Zp1) ; // 1/Zp1 = sqrt(IH[eV] / Ii[ev]) + double Z = Zp1 - 1; + double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. + double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // Ii shall be the IP of atom/ion. Instr. on RSH of equal sign returns IP of element with atomic no = atomic_number_ and charge state Z (Z=0 is neutral atom). + double ratio_of_IPs = IH / Ii; + + double BSI_rate_linear = 0.8 * E * pow(ratio_of_IPs, 0.5); // E is in atomic units, rate is computed in Atomic units. + // return BSI_rate_linear; // Returns BSI linear rate in AtomicUnits (i.e. normalized to atomic_unit_of_frequency) + return (BSI_rate_linear * au_to_w0); // in SMILEI units. +} + +// Derivatives of BSI Linear rate: +// double BSI_rate_linear_function_der_wrtE(unsigned int Zp1, unsigned int atomic_number_) { // E-field E from arguments has to be in AtomicUnits +// double Z = Zp1 - 1; +// double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. +// double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // Ii shall be the IP of atom/ion. Instr. on RSH of equal sign returns IP of element with atomic no = atomic_number_ and charge state Z (Z=0 is neutral atom). +// double ratio_of_IPs = IH / Ii; + +// double BSI_rate_linear_der_wrtE = 0.8 * pow(ratio_of_IPs, 0.5); +// return BSI_rate_linear_der_wrtE * au_to_w0; +// // return BSI_rate_linear_der_wrtE; +// } + +// double BSI_rate_linear_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_) { +// double BSI_linear_rate = BSI_rate_linear_function(Zp1, E, atomic_number_); +// double BSI_linear_rate_der_wrtE = BSI_rate_linear_function_der_wrtE(Zp1, atomic_number_); + +// double BSI_linear_rate_loglogder_wrtE = (E / BSI_linear_rate) * BSI_linear_rate_der_wrtE; + +// return BSI_linear_rate_loglogder_wrtE; +// } diff --git a/src/Ionization/continuity_tool.h b/src/Ionization/continuity_tool.h new file mode 100755 index 000000000..2bec45e11 --- /dev/null +++ b/src/Ionization/continuity_tool.h @@ -0,0 +1,23 @@ +#ifndef CONTINUITYTOOL_H +#define CONTINUITYTOOL_H + +// #include "Ionization.h" + +double BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); +//double BSI_rate_quadratic_function_der_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_); +//double BSI_rate_quadratic_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_); + +double BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); +//double BSI_rate_linear_function_der_wrtE(unsigned int Zp1, unsigned int atomic_number_); +//double BSI_rate_linear_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_); + +double Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma); +//double Tunnel_rate_function_der_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma); +//double Tunnel_rate_function_loglogder_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma); + + +int continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0); + +extern double au_to_eV; // au_to_eV will be defined in continuity_tool.cpp (and defined only there, only once) + // will need to #include "continuity_tool.h" in each .cpp that uses au_to_eV. +#endif \ No newline at end of file diff --git a/src/Python/pyinit.py b/src/Python/pyinit.py index f5aeeb7e1..79c4797df 100755 --- a/src/Python/pyinit.py +++ b/src/Python/pyinit.py @@ -430,6 +430,7 @@ class Species(SmileiComponent): ionization_rate = None atomic_number = None maximum_charge_state = 0 + ionization_tl_parameter = 6 is_test = False relativistic_field_initialization = False keep_interpolated_fields = [] diff --git a/src/Species/Species.h b/src/Species/Species.h index d4af3bf9d..8796e3f0d 100755 --- a/src/Species/Species.h +++ b/src/Species/Species.h @@ -79,6 +79,9 @@ class Species //! maximum charge state unsigned int maximum_charge_state_; + //! alpha parameter in the Tong-Lin ionization model + double ionization_tl_parameter_; + //! user defined ionization rate profile PyObject *ionization_rate_; diff --git a/src/Species/SpeciesFactory.h b/src/Species/SpeciesFactory.h index edef5e334..8d5476d8a 100755 --- a/src/Species/SpeciesFactory.h +++ b/src/Species/SpeciesFactory.h @@ -739,6 +739,9 @@ class SpeciesFactory this_species->maximum_charge_state_ = 0; PyTools::extract( "maximum_charge_state", this_species->maximum_charge_state_, "Species", ispec); + + this_species->ionization_tl_parameter_ = 6; + PyTools::extract( "ionization_tl_parameter", this_species->ionization_tl_parameter_, "Species", ispec); std::string model; PyTools::extract( "ionization_model", model, "Species", ispec ); @@ -760,7 +763,7 @@ class SpeciesFactory LINK_NAMELIST + std::string("#species") ); } - if( model == "tunnel" ){ + if( (model == "tunnel") || (model == "tunnel_BSI") || (model == "tunnel_TL") || (model == "tunnel_full_PPT") ){ if (params.Laser_Envelope_model){ ERROR_NAMELIST("An envelope is present, so tunnel_envelope or tunnel_envelope_averaged ionization model should be selected for species "< Date: Tue, 25 Jun 2024 16:46:40 +0200 Subject: [PATCH 02/17] Added the manual (LaTeX, PDF) for the newly added ionization modules; Minor correction to the FullPPT module --- .../cmap_map.py | 0 .../input.py | 0 .../manual/ionization_manual.pdf | Bin 0 -> 204703 bytes .../manual/ionization_manual.tex | 141 ++++++++++++++++++ .../manual/ionization_manualNotes.bib | 2 + .../run_test.py | 0 src/Ionization/IonizationTunnelFullPPT.cpp | 3 +- 7 files changed, 144 insertions(+), 2 deletions(-) rename {ionization_module_tests => ionization_module_tests_and_man}/cmap_map.py (100%) rename {ionization_module_tests => ionization_module_tests_and_man}/input.py (100%) create mode 100644 ionization_module_tests_and_man/manual/ionization_manual.pdf create mode 100644 ionization_module_tests_and_man/manual/ionization_manual.tex create mode 100644 ionization_module_tests_and_man/manual/ionization_manualNotes.bib rename {ionization_module_tests => ionization_module_tests_and_man}/run_test.py (100%) diff --git a/ionization_module_tests/cmap_map.py b/ionization_module_tests_and_man/cmap_map.py similarity index 100% rename from ionization_module_tests/cmap_map.py rename to ionization_module_tests_and_man/cmap_map.py diff --git a/ionization_module_tests/input.py b/ionization_module_tests_and_man/input.py similarity index 100% rename from ionization_module_tests/input.py rename to ionization_module_tests_and_man/input.py diff --git a/ionization_module_tests_and_man/manual/ionization_manual.pdf b/ionization_module_tests_and_man/manual/ionization_manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..09a49ff57f052b1d3d40334dd1b6a67d15df2a80 GIT binary patch literal 204703 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%0D4F#W-G~Obk+x9Q6s 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

PX(_kqBY)V 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 f{@KRu>~(DIoj>olpcv>F*#LA<#Kc00$. The hypothesis is that electrons with $|m|>0$ have enough time to relax to the $m=0$ state once it is not occupied. With this, we set $m=0$ for all the electrons, and rewrite the PPT-ADK formula accordingly (note that in the code notations $Z=Z^*-1$): + \begin{gather} + \label{tunnel} + \Gamma_{Z}=\beta(Z)\exp\left\lbrace -\frac{\Delta}{3} + \alpha(Z)\log\Delta \right\rbrace,\\ + \alpha(Z) = c^*-1,\quad c^*=(Z+1)\sqrt{\frac{2}{I_p}} \equiv 2n^*,\\ + \beta(Z) = I_p\frac{2^{\alpha(Z)} \left[ 8l+4 \right]}{c^*\Gamma(c^*)} ,\\ + \label{gamma_Delta} + \Delta = \frac{\gamma(Z)}{E}, \quad \gamma(Z)=2(2I_p)^{3/2}. + \end{gather} + + \subsubsection{Bug fix in the standard model} + In \texttt{Smilei/src/Ionization/IonizationTunnel.cpp}, in the method \texttt{void IonizationTunnel::operator()}, array \texttt{Dnom[Z]} is not initialized. As a result, for high $Z$ atoms, the array can be uncontrollably allocated with random data, and the result of the operation \texttt{Dnom\_tunnel[k\_times+1] -= D\_sum} is not defined. As the value for \texttt{Dnom[k\_times+1]} is not defined anywhere before this line in the algorithm, the correction \texttt{Dnom\_tunnel[k\_times+1] = -D\_sum} resolves the bug. This correction is implemented in the standard ionization module and all new modules described below. However, it is recommended to review the code and initialize the array properly. + + \subsection{Tunnelling ionization (PPT-ADK) with account for $|m|>0$} + The model adds the dependence on the magnetic quantum number $m$ as in Eq.~\eqref{PPT_definition}. It is implemented in the code by changing the definitions for $\alpha(Z)$ and $\beta(Z)$ in Eq.~\eqref{tunnel} as follows: + \begin{gather} + \alpha(Z) = c^*-|m|-1,\\ + \beta(Z) = I_p\frac{2^{\alpha(Z)} \left[ 8l+4 \right]}{c^*\Gamma(c^*)} \times \frac{\Gamma(l+|m|+1)}{\Gamma(|m|+1)\Gamma(l-|m|+1)}. + \end{gather} + Note that $\beta(Z)$ depends both on $l^*$ and $l$. + + The model is implemented in file \texttt{Smilei/src/Ionization/IonizationTunnelFullPPT.cpp} and can be used in the namelist by putting \texttt{ionization\_model = 'tunnel\_full\_PPT'} in the corresponding atom \texttt{Species}. + + \subsubsection{Implementation details} + The magnetic quantum number $m$ is attributed to each electron in accordance with the following rules. + \begin{enumerate} + \item Since $\Gamma_Z(m=0)>\Gamma_Z(|m|=1)>\Gamma_Z(|m|=2)>\ldots$, we assume that electrons in the state with the lowest value of $|m|$ are ionized first. + + \clearpage + \item Electrons with the same azimuthal quantum number $l$ occupy the sub-shells in the order of increasing $|m|$ and for the same $|m|$ in the order of increasing $m$: + \begin{table}[!h] + \begin{tabular}{l | c | c | c | c | c | c | c | c | c | c | c} + Level order num & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & $\ldots$ \\ \hline + Magnetic q. num $m$ & 0 & 0 & -1 & -1 & 1 & 1 & -2 & -2 & 2 & 2 & $\ldots$ + \end{tabular} + \end{table} + + For example, for the atomic configuration with 3 $p$-electrons ($l=1$) in the outer shell, we choose $m=0,\, 0, -1$ for these electrons. + + \item The states with lower $|m|$ are ionized first. + + \end{enumerate} + With this algorithm, by knowing the atomic number $A$, we can assign a unique set of quantum numbers $nlm$ to each electron on the atomic sub-shells and identify their extraction order during successive ionization. + For example, the full configuration for ${}_{12}$Mg and the corresponding order for the ionization process is: + \begin{table}[h!] + \begin{tabular}{l | c | c | c | c | c | c | c | c | c | c | c | c} + Shell & $3s$ & $3s$ & $2p$ & $2p$ & $2p$ & $2p$ & $2p$ & $2p$ & $2s$ & $2s$ & $1s$ & $1s$ \\\hline + $n$ & 3 & 3 & 2 & 2 & 2 & 2 & 2 & 2 & 2 & 2 & 1 & 1 \\\hline + $l$ & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 0 \\\hline + $m$ & 0 & 0 & 0 & 0 & -1 & -1 & 1 & 1 & 0 & 0 & 0 & 0 \\\hline + Ionization order & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 + \end{tabular} + \end{table} + + The values for $m$ for each atom with $A=1\ldots99$ are stored in \texttt{Smilei/src/Ionization/IonizationTables.h} in the table named \texttt{magneticQuantumNumber}, which is similar to the table for $l$ used in the tunnelling formula \eqref{tunnel} in the standard SMILEI package. The table for $m$ was generated based on the table for $l$ following the rules presented above. + + \textbf{Important note!} As a temporary solution for the $f$- ($l=3$) and higher shells, $m$ is always set to zero [namely, the rates are calculated with Eqs.~\eqref{tunnel}-\eqref{gamma_Delta}]. This is due to possible sub-level overlap for the $d$- and $f$-shells, that cannot be reproduced with the described algorithm for the table generation. This issue is to be resolved in the future. + + + \clearpage + \subsection{Tong \& Ling formula} + The formula proposed by Tong and Lin [\href{https://iopscience.iop.org/article/10.1088/0953-4075/38/15/001}{Tong X. M. and Lin C. D., J. Phys. B: At. Mol. Opt. Phys. 38 2593 (2005)}] extends the tunnelling ionization rate to the barrier-suppression regime. This is achieved by introducing the \textit{empirical} factor in Eq.~\eqref{PPT_definition}: + \begin{equation} + \Gamma_{Z^*}^{\text{TL}} = \Gamma_{Z^*}\times \exp\left( -2\alpha_{\text{TL}} n^{*2} \frac{E}{(2 I_p)^{3/2}}\right), + \end{equation} + where $\alpha_{\text{TL}}$ is an empirical constant. Typically, the value for it stays in the interval from 6 to 9. The actual value should be guessed from experimental data. When such data is not available, the formula can be used for qualitative analysis of the barrier-suppression ionization (BSI), e.g. see [\href{https://iopscience.iop.org/article/10.1088/1612-202X/ab6559}{M. F. Ciappina and S. V. Popruzhenko., Laser Phys. Lett. 17 025301 (2020)}]. The module was tested to reproduce the results from this paper. + + \subsubsection{Representation in the code} + In the code, the Tong-Ling formula is implemented as follows: + \begin{gather} + \label{tonglin} + \Gamma_{Z}^\text{TL}=\Gamma_{Z}\times \exp\left[ -E\lambda(Z) \right] ,\\ + \lambda(Z) = \frac{\alpha_{\text{TL}} c^{*2}}{\gamma(Z)}, + \end{gather} + where $\gamma(Z)$ is given by Eq.~\eqref{gamma_Delta}. + + The model is implemented in file \texttt{Smilei/src/Ionization/IonizationTunnelTL.cpp} and can be used in the namelist by putting \texttt{ionization\_model = 'tunnel\_TL'} in the corresponding atom \texttt{Species}. The $\alpha_{\text{TL}}$ can be set with the (newly added) parameter \texttt{ionization\_tl\_parameter = } in the corresponding \texttt{Species} + (set to 6 by default). + + + \clearpage + \subsection{BSI formula} + I. Ouatu implemented a different model of BSI initially proposed in [\href{https://journals.aps.org/pra/abstract/10.1103/PhysRevA.98.043407}{I. Yu. Kostyukov and A. A. Golovanov, Phys. Rev. A 98, 043407 (2018)}]. The original implementation by I. Ouatu is available on Github \url{https://github.com/iouatu/mySmilei}. It was used in the study [\href{https://journals.aps.org/pre/abstract/10.1103/PhysRevE.106.015205}{I. Ouatu et al, + Phys. Rev. E 106, 015205 (2022)}]. The module is included in this version of SMILEI without changes (except for some small corrections in the header file) and was tested to reproduce the results of this paper. + + The model uses the ionization rate Eq.~\eqref{tunnel} when applicable and switches to an empirical formula described in the original paper by Kostyukov \& Golovanov. There are no additional parameters introduced to tune the model. + + The model is implemented in file \texttt{Smilei/src/Ionization/IonizationTunnelBSI.cpp} and can be used in the namelist by putting \texttt{ionization\_model = 'tunnel\_BSI'} in the corresponding atom \texttt{Species}. In the implementation, the code relies on some additional functionality introduced in \texttt{Smilei/src/Ionization/continuity\_tool.cpp}. + + +\end{document} \ No newline at end of file diff --git a/ionization_module_tests_and_man/manual/ionization_manualNotes.bib b/ionization_module_tests_and_man/manual/ionization_manualNotes.bib new file mode 100644 index 000000000..8f3dc15db --- /dev/null +++ b/ionization_module_tests_and_man/manual/ionization_manualNotes.bib @@ -0,0 +1,2 @@ +@CONTROL{REVTEX42Control} +@CONTROL{apsrev42Control,author="08",editor="1",pages="0",title="0",year="1"} diff --git a/ionization_module_tests/run_test.py b/ionization_module_tests_and_man/run_test.py similarity index 100% rename from ionization_module_tests/run_test.py rename to ionization_module_tests_and_man/run_test.py diff --git a/src/Ionization/IonizationTunnelFullPPT.cpp b/src/Ionization/IonizationTunnelFullPPT.cpp index 5ec5b5a23..bd2604ba8 100755 --- a/src/Ionization/IonizationTunnelFullPPT.cpp +++ b/src/Ionization/IonizationTunnelFullPPT.cpp @@ -38,10 +38,9 @@ IonizationTunnelFullPPT::IonizationTunnelFullPPT( Params ¶ms, Species *speci for( unsigned int Z=0 ; Z Date: Tue, 23 Jul 2024 14:01:23 +0200 Subject: [PATCH 03/17] Merge continuity_tool into IonizationTunnelBSI --- src/Ionization/IonizationTunnelBSI.cpp | 75 ++++++++++- src/Ionization/IonizationTunnelBSI.h | 10 +- src/Ionization/continuity_tool.cpp | 170 ------------------------- src/Ionization/continuity_tool.h | 23 ---- 4 files changed, 83 insertions(+), 195 deletions(-) delete mode 100755 src/Ionization/continuity_tool.cpp delete mode 100755 src/Ionization/continuity_tool.h diff --git a/src/Ionization/IonizationTunnelBSI.cpp b/src/Ionization/IonizationTunnelBSI.cpp index 7788bd5fb..8950117f1 100755 --- a/src/Ionization/IonizationTunnelBSI.cpp +++ b/src/Ionization/IonizationTunnelBSI.cpp @@ -1,8 +1,8 @@ #include "IonizationTunnelBSI.h" #include "IonizationTables.h" -#include "continuity_tool.h" #include +#include #include "Particles.h" #include "Species.h" @@ -379,3 +379,76 @@ void IonizationTunnelBSI::operator()( Particles *particles, unsigned int ipart_m } // END loop on particles } // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. + + +int IonizationTunnelBSI::continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0) { + // returns: + // 0 for when it chooses Tunnel ADK-PPT Ionization Rate, + // 1 for when it chooses the BSI-Quadratic Ionization Rate, + // 2 for when it chooses BSI-Linear Ionization Rate + + // Aim is to implement the 3-piece general rate, so a method to choose between Tunnel or BSI linear or BSI quadratic. + // E_cr from the arguments of this function is useless at the moment. + // alpha, beta, gamma coefficients are single numbers, for ion with charge state Z = Zp1 - 1, for a fixed atomic number (of the species under consideration). Z=0 is a neutral atom, Z=1 is singly ionized ion, i.e. Na^{+1}. + // alpha = alpha_tunnel[Z], beta = beta_tunnel[Z], gamma = gamma_tunnel[Z], where Z = Zp1 - 1 and + // where alpha_tunnel[Z] uses Z and Potential[Z] (IonizationPotential (in AtomicUnits) of Element with atomic number = atomic_number_ and charge state Z (Z=0 means neutral atom)) + // (double) Potential from arguments is the IP in AtomicUnits for current charge state Z (Z=0 is neutral atom) for a fixed atomic no = atomic_number_. + // Potential from the arguments is not actually needed!!! + unsigned int Z = Zp1 - 1; + + double Potential_in_eV = Potential * au_to_eV; // AtomicUnits to eV conversion on Potential from arguments of this function. // not actually needed !! + // Potential_in_eV will be used for BSI linear rate implemented below. There we need the ratio of Potential_in_eV[] and 13.6 eV + // not actually needed anymore! + + double BSI_rate_quadratic = BSI_rate_quadratic_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ + double BSI_rate_linear = BSI_rate_linear_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ + double Tunnel_rate = Tunnel_rate_function(Z, E, alpha, beta, gamma); // Z = Zp1 - 1; + + if (BSI_rate_quadratic >= BSI_rate_linear) { // all these rates which are compared here are in SMILEI units + return 2; // 2 means return BSI-Linear rate + } + else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) { // this returns min(Tunnel, BSI-Quadratic) + return 1; // 1 means return BSI-Quadratic rate + } + else return 0; // 0 means return Tunnel rate. The min is Tunnel rate + +} + + +// TUNNEL Ionization Rates +// ############################################################# +// 1) ADK-PPT static rate in units of atomic_unit_of_freq, all physical quantities inside rate formula are in atomic units. +double IonizationTunnelBSI::Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma) { // E is in Atomic Units + // Z from arguments is useless here as alpha, beta, gamma are for that Z already. + double one_third = 1.0/3.0; + double invE = 1./E ; + double delta = gamma * invE; + + double Tunnel_rate = beta * exp( -delta*one_third + alpha*log(delta) ); // E depenedency comes through delta + return Tunnel_rate; // returned rate is in SMILEI UNITS due to beta from above +} + +// BSI rates +// ############################################################################## +// BSI rates below are calculated in atomic units, for both the Quadratic rate and the Linear rate. +double IonizationTunnelBSI::BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. + double Z = Zp1 - 1; + double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. + double Ii = IonizationTables::ionization_energy(atomic_number_, Z); + double ratio_of_IPs = IH / Ii; + + double BSI_rate_quadratic = 2.4 * (pow(E,2)) * pow(ratio_of_IPs,2); // E is in atomic units here, rate is calculated in atomic units + return (BSI_rate_quadratic * au_to_w0); // in SMILEI UNITS +} + +double IonizationTunnelBSI::BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. + double Z = Zp1 - 1; + double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. + double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // Ii shall be the IP of atom/ion. Instr. on RSH of equal sign returns IP of element with atomic no = atomic_number_ and charge state Z (Z=0 is neutral atom). + double ratio_of_IPs = IH / Ii; + + double BSI_rate_linear = 0.8 * E * pow(ratio_of_IPs, 0.5); // E is in atomic units, rate is computed in Atomic units. + // return BSI_rate_linear; // Returns BSI linear rate in AtomicUnits (i.e. normalized to atomic_unit_of_frequency) + return (BSI_rate_linear * au_to_w0); // in SMILEI units. +} + diff --git a/src/Ionization/IonizationTunnelBSI.h b/src/Ionization/IonizationTunnelBSI.h index 512bc9c5b..073ba2c30 100755 --- a/src/Ionization/IonizationTunnelBSI.h +++ b/src/Ionization/IonizationTunnelBSI.h @@ -21,6 +21,14 @@ class IonizationTunnelBSI : public Ionization { double one_third; std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; + double BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); + double BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); + double Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma); + + int continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0); + + double au_to_eV=27.2116; + }; -#endif \ No newline at end of file +#endif diff --git a/src/Ionization/continuity_tool.cpp b/src/Ionization/continuity_tool.cpp deleted file mode 100755 index ad0c16a0f..000000000 --- a/src/Ionization/continuity_tool.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "continuity_tool.h" // declares double au_to_eV; -#include "Ionization.h" -#include "IonizationTunnelBSI.h" -#include "IonizationTables.h" // can use the raw ionizationEnergy[100/2*101] (all in eV), but also the function ionization_energy(int atomic_number, int Zstar) which returns: ionizationEnergy[( atomic_number*(atomic_number-1) )/2 + Zstar] -// just write IonizationTables::ionizationEnergy[atomic_number_*(atomic_number-1)/2 + Zstar] to get IonizPotential (in eV) of Element with atmomic # = atomic_number and charge state Zstar, i.e. Element^{+Zstar} -// For instance IonizationTables::ionizationEnergy[13*12/2 + 3] is the ionization energy of Al3+ in eV. - -#include -#include - -double au_to_eV = 27.2116; // will be used by continuity_tool( , , ) to convert Potential[Z] (in AtomicUnits) to eV. - - -int continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0) { - // returns: - // 0 for when it chooses Tunnel ADK-PPT Ionization Rate, - // 1 for when it chooses the BSI-Quadratic Ionization Rate, - // 2 for when it chooses BSI-Linear Ionization Rate - - // Aim is to implement the 3-piece general rate, so a method to choose between Tunnel or BSI linear or BSI quadratic. - // E_cr from the arguments of this function is useless at the moment. - // alpha, beta, gamma coefficients are single numbers, for ion with charge state Z = Zp1 - 1, for a fixed atomic number (of the species under consideration). Z=0 is a neutral atom, Z=1 is singly ionized ion, i.e. Na^{+1}. - // alpha = alpha_tunnel[Z], beta = beta_tunnel[Z], gamma = gamma_tunnel[Z], where Z = Zp1 - 1 and - // where alpha_tunnel[Z] uses Z and Potential[Z] (IonizationPotential (in AtomicUnits) of Element with atomic number = atomic_number_ and charge state Z (Z=0 means neutral atom)) - // (double) Potential from arguments is the IP in AtomicUnits for current charge state Z (Z=0 is neutral atom) for a fixed atomic no = atomic_number_. - // Potential from the arguments is not actually needed!!! - unsigned int Z = Zp1 - 1; - - double Potential_in_eV = Potential * au_to_eV; // AtomicUnits to eV conversion on Potential from arguments of this function. // not actually needed !! - // Potential_in_eV will be used for BSI linear rate implemented below. There we need the ratio of Potential_in_eV[] and 13.6 eV - // not actually needed anymore! - - double BSI_rate_quadratic = BSI_rate_quadratic_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ - double BSI_rate_linear = BSI_rate_linear_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ - double Tunnel_rate = Tunnel_rate_function(Z, E, alpha, beta, gamma); // Z = Zp1 - 1; - - //double BSI_rate_quadratic_loglogder_wrtE = BSI_rate_quadratic_function_loglogder_wrtE(Zp1, E, atomic_number_); - //double BSI_rate_linear_loglogder_wrtE = BSI_rate_linear_function_loglogder_wrtE(Zp1, E, atomic_number_); - //double Tunnel_rate_loglogder_wrtE = Tunnel_rate_function_loglogder_wrtE(Z, E, alpha, beta, gamma); - -// Tony Arber 2015, the review paper on PIC codes. Arber_2015_Plasma_Phys._Control._Fusion_57_113001 -// There he explains how to make the PIC code choose, at each timestep, between Tunnel and BSI. -// So he tells us how to implement a 2-piece formula for the ionization rate. - -// if (BSI_rate_quadratic_loglogder_wrtE > Tunnel_rate_loglogder_wrtE) { // Conditions for a 2-piece general rate, where the aim is to choose between Tunnel and BSI quadratic rate. -// return true; // i.e. use BSI rate because E > Eprime (location of the intersection of the 2 rates) -// } -// else if (BSI_rate_quadratic > Tunnel_rate) { // simulates: else return minimum(BSI_rate_quadratic, Tunnel_rate) -// return false; // i.e. use Tunnel Rate -// } -// else return true; // i.e. use BSI Rate. - -// Below I implement a method to choice from the 3 rates (i.e. the 3 piece formula) -// based on something simpler than in Arber where he uses log-log derivatives. -// Just look at the graphs from Golovanov 2020 paper (arxhiv one for nicely coloured graphs). - if (BSI_rate_quadratic >= BSI_rate_linear) { // all these rates which are compared here are in SMILEI units - return 2; // 2 means return BSI-Linear rate - } - else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) { // this returns min(Tunnel, BSI-Quadratic) - return 1; // 1 means return BSI-Quadratic rate - } - else return 0; // 0 means return Tunnel rate. The min is Tunnel rate - -} - - -// TUNNEL Ionization Rates -// ############################################################# -// 1) ADK-PPT static rate in units of atomic_unit_of_freq, all physical quantities inside rate formula are in atomic units. -double Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma) { // E is in Atomic Units - // Z from arguments is useless here as alpha, beta, gamma are for that Z already. - double one_third = 1.0/3.0; - double invE = 1./E ; - double delta = gamma * invE; - - double Tunnel_rate = beta * exp( -delta*one_third + alpha*log(delta) ); // E depenedency comes through delta - return Tunnel_rate; // returned rate is in SMILEI UNITS due to beta from above -} - -// double Tunnel_rate_function_der_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma) { -// // I wrote the expression for derivative using gamma only, nothing related to delta. -// double one_third = 1.0/3.0; -// double invE = 1./E ; -// // double delta = gamma * invE; // I wrote the expression for derivative using gamma only. - -// double Tunnel_rate_der_wrtE = beta * exp(- gamma*one_third*invE) * pow((gamma*invE), alpha) * (gamma*one_third*pow(invE, 2) - alpha*invE); -// return Tunnel_rate_der_wrtE; -// } - -// double Tunnel_rate_function_loglogder_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma) { -// double Tunnel_rate = Tunnel_rate_function(Z, E, alpha, beta, gamma); -// double Tunnel_rate_der_wrtE = Tunnel_rate_function_der_wrtE(Z, E, alpha, beta, gamma); - -// double Tunnel_rate_loglogder_wrtE = (E/Tunnel_rate) * Tunnel_rate_der_wrtE; // log-log derivative is: (x/y) * (dy/dx) where in our case: y = Rate, x = E-field. -// return Tunnel_rate_loglogder_wrtE; -// } - -// BSI rates -// ############################################################################## -// BSI rates below are calculated in atomic units, for both the Quadratic rate and the Linear rate. -// 1) QUADRATIC dependence on local E-field <--> Bauer and Mulser, in PhysRevA Vol.59, No.1, 1999. -double BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. - // double BSI_rate_quadratic = 2.4 * (pow(E,2)) / pow(Zp1,4); // Formula as in the paper. But I implement it using the ratio of IonizPotentials. See Golovanov 2020 paper - // The rate computed below is in AtomicUnits. E-field received as argument is in AtomicUnits (see IonizationTunnelBSI::operator()(arg1, arg2, ...) function) - double Z = Zp1 - 1; - double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. - double Ii = IonizationTables::ionization_energy(atomic_number_, Z); - double ratio_of_IPs = IH / Ii; - - double BSI_rate_quadratic = 2.4 * (pow(E,2)) * pow(ratio_of_IPs,2); // E is in atomic units here, rate is calculated in atomic units - // return BSI_rate_quadratic; // Returns the rate in ATOMIC UNITS (i.e. normalized to atomic_unit_of_frequency) - return (BSI_rate_quadratic * au_to_w0); // in SMILEI UNITS -} - -// Derivatives of BSI Quadratic rate: -// double BSI_rate_quadratic_function_der_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_) { // simple derivative of BSI quadratic rate wrt E-field -// // double BSI_rate_quadratic_der_wrtE = 2.4 * 2 * E / pow(Zp1,4); // The derivate of the formula as it's appearing in the paper by Bauer-Mulser BM. -// double Z = Zp1 - 1; -// double IH = 13.598434005136; -// double Ii = IonizationTables::ionization_energy(atomic_number_, Z); -// double ratio_of_IPs = IH / Ii; - -// double BSI_rate_quadratic_der_wrtE = 2.4 * 2 * E * pow(ratio_of_IPs,2); -// return (BSI_rate_quadratic_der_wrtE * au_to_w0); // Returned in SMILEI UNITS. -// // return BSI_rate_quadratic_der_wrtE; // Returned in Atomic Units. -// } - -// double BSI_rate_quadratic_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_) { -// double BSI_rate_quadratic = BSI_rate_quadratic_function(Zp1,E, atomic_number_); -// double BSI_rate_quadratic_der_wrtE = BSI_rate_quadratic_function_der_wrtE(Zp1,E, atomic_number_); - -// double BSI_rate_quadratic_loglogder_wrtE = (E/BSI_rate_quadratic) * BSI_rate_quadratic_der_wrtE; // log-log derivative is: (x/y) * (dy/dx) where in our case: y = Rate, x = E-field. -// return BSI_rate_quadratic_loglogder_wrtE; -// } - - - -// 2) BSI-LINEAR dependence on local E-field <---> Kostyukov+Golovanov: Field ionization in short and extremely intense laser pulses, 2018 -double BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. -// double BSI_rate_linear = 0.8 * (E / Zp1) ; // 1/Zp1 = sqrt(IH[eV] / Ii[ev]) - double Z = Zp1 - 1; - double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. - double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // Ii shall be the IP of atom/ion. Instr. on RSH of equal sign returns IP of element with atomic no = atomic_number_ and charge state Z (Z=0 is neutral atom). - double ratio_of_IPs = IH / Ii; - - double BSI_rate_linear = 0.8 * E * pow(ratio_of_IPs, 0.5); // E is in atomic units, rate is computed in Atomic units. - // return BSI_rate_linear; // Returns BSI linear rate in AtomicUnits (i.e. normalized to atomic_unit_of_frequency) - return (BSI_rate_linear * au_to_w0); // in SMILEI units. -} - -// Derivatives of BSI Linear rate: -// double BSI_rate_linear_function_der_wrtE(unsigned int Zp1, unsigned int atomic_number_) { // E-field E from arguments has to be in AtomicUnits -// double Z = Zp1 - 1; -// double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. -// double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // Ii shall be the IP of atom/ion. Instr. on RSH of equal sign returns IP of element with atomic no = atomic_number_ and charge state Z (Z=0 is neutral atom). -// double ratio_of_IPs = IH / Ii; - -// double BSI_rate_linear_der_wrtE = 0.8 * pow(ratio_of_IPs, 0.5); -// return BSI_rate_linear_der_wrtE * au_to_w0; -// // return BSI_rate_linear_der_wrtE; -// } - -// double BSI_rate_linear_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_) { -// double BSI_linear_rate = BSI_rate_linear_function(Zp1, E, atomic_number_); -// double BSI_linear_rate_der_wrtE = BSI_rate_linear_function_der_wrtE(Zp1, atomic_number_); - -// double BSI_linear_rate_loglogder_wrtE = (E / BSI_linear_rate) * BSI_linear_rate_der_wrtE; - -// return BSI_linear_rate_loglogder_wrtE; -// } diff --git a/src/Ionization/continuity_tool.h b/src/Ionization/continuity_tool.h deleted file mode 100755 index 2bec45e11..000000000 --- a/src/Ionization/continuity_tool.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CONTINUITYTOOL_H -#define CONTINUITYTOOL_H - -// #include "Ionization.h" - -double BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); -//double BSI_rate_quadratic_function_der_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_); -//double BSI_rate_quadratic_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_); - -double BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); -//double BSI_rate_linear_function_der_wrtE(unsigned int Zp1, unsigned int atomic_number_); -//double BSI_rate_linear_function_loglogder_wrtE(unsigned int Zp1, double E, unsigned int atomic_number_); - -double Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma); -//double Tunnel_rate_function_der_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma); -//double Tunnel_rate_function_loglogder_wrtE(unsigned int Z, double E, double alpha, double beta, double gamma); - - -int continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0); - -extern double au_to_eV; // au_to_eV will be defined in continuity_tool.cpp (and defined only there, only once) - // will need to #include "continuity_tool.h" in each .cpp that uses au_to_eV. -#endif \ No newline at end of file From ae4157aa66ac8a2852b2ec70396dedbe12d96be4 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Fri, 26 Jul 2024 03:09:23 +0200 Subject: [PATCH 04/17] reorganise understand documentation to prepare explanation of new models --- doc/Sphinx/Understand/ionization.rst | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/doc/Sphinx/Understand/ionization.rst b/doc/Sphinx/Understand/ionization.rst index 33734c1b7..1f97da880 100755 --- a/doc/Sphinx/Understand/ionization.rst +++ b/doc/Sphinx/Understand/ionization.rst @@ -72,6 +72,66 @@ over a period :math:`2\pi/\omega` leads to the well-known cycle-averaged ionizat \,I_p\,\left( \frac{2 (2 I_p)^{3/2}}{\vert E\vert} \right)^{2n^\star-\vert m \vert -3/2}\, \exp\!\left( -\frac{2 (2 I_p)^{3/2}}{3 \vert E\vert} \right)\,. + +In :program:`Smilei`, four models are available to compute the ionization rate of :eq:`ionizationRate1`. + +**Tunnelling Ionization (PPT-ADK) for :math:`m=0`** + +In the classical model, the ionization rate of :eq:`ionizationRate1` +is computed for :math:`\vert m \vert=0` only. +Indeed, as shown in [Ammosov1986]_, the ratio :math:`R` of the ionization rate +computed for :math:`\vert m\vert=0` by the rate computed for :math:`\vert m\vert=1` is: + +.. math:: + + R = \frac{\Gamma_{{\rm qs},\vert m \vert = 0}}{\Gamma_{{\rm qs},\vert m \vert = 1}} + = 2\frac{(2\,I_p)^{3/2}}{\vert E\vert} + \simeq 7.91\,10^{-3} \,\,\frac{(I_p[\rm eV])^{3/2}}{a_0\,\hbar\omega_0[\rm eV]}\,, + +where, in the practical units formulation, we have considered ionization +by a laser with normalized vector potential :math:`a_0=e\vert E\vert /(m_e c \omega_0)`, +and photon energy :math:`\hbar\omega_0` in eV. + + + +**Tunnelling Ionization (PPT-ADK) for :math:`|m|>0`** +In this model,d ependence on the magnetic quantum number :math:`m` is added. + +:math:`m` is attributed to eac electron in accordance with the following rulse: +1. Since :math:`\Gamma_z(m=0)>\Gamma_z(m=1)>\Gamma_z(m=2)>...` we assume that for electrons +with the same azimuthal quantum number :math:`l`, the states with the lowest value of +:math:`|m|` are ionized first. +2. Electrons with the same azimuthal qunatum number :math:`l` occupy the sub-shells in the +order of increasing :math:`|m|` and for the same :math:`|m|` in the order of increasing :math:`m`. + +With this algorithm, by knowing the atomic number A, we can assign a unique set of +quantum numbers :math:`nlm` to each electron on the atomic sub-shells and identify their extraction +order during successive ionization. + + +**Barrier Suppression Ionization (Tong&Ling)** +The formula proposed by Tong and Lin [Tong2005]_ extends the tunnelling ionization rate to the barrier-suppression +regime. This is achieved by introducing the empirical factor in :eq:`ionizationRate1`: + +.. math:: + + \Gamma_{Z^\star}^{TL} = \Gamma_{Z^\star} \times \exp (-2\alpha_{TL}n^{\star2}\frac{E}{(2I_p)^{3/2}}), + +where :math:`\alpha_TL` is an emprirical constant with value typically from 6 to 9. The actual value +should be guessed from empirical data. When such data is +not available, the formula can be used for qualitative analysis of the barrier-suppression +ionization (BSI), e.g. see [Ciappina2020]_. The module was tested to reproduce the results from this paper. + + +**Barrier Suppression IOnization (Ouatu)** +Ouatu implemented a different model of BSI initially proposed in [Kostyukov2018]_ which was used in the +study [Ouatu2022]_. + + + +To Be removed +"""""""""""""""""""" + In :program:`Smilei`, following [Nuter2011]_, the ionization rate of :eq:`ionizationRate1` is computed for :math:`\vert m \vert=0` only. Indeed, as shown in [Ammosov1986]_, the ratio :math:`R` of the ionization rate @@ -340,3 +400,11 @@ References .. [Schroeder2014] `C. B. Schroeder, J.-L. Vay, E. Esarey, S. S. Bulanov, C. Benedetti, L.-L. Yu, M. Chen, C. G. R. Geddes, and W. P. Leemans, Phys. Rev. ST Accel. Beams 17, 101301 `_ .. [Gibbon] P. Gibbon, Short Pulse Laser Interactions with Matter - An Introduction, Imperial College Press (2005) + +.. [Tong2005] `Tong X. M., Lin C. D., J. Phys. B: At. Mol. Opt. Phys. 38 2593 (2005) ` + +.. [Ciappina2020] `M. F. Ciappina, S. V. Popruzhenko., Laser Phys. Lett. 17 025301 (2020) ` + +.. [Kostyukov2018] `I. Yu. Kostyukov, A. A. Golovanov, Phys. Rev. A 98, 043407 (2018) ` + +.. [Ouatu2022] `I. Ouatu et al, Phys. Rev. E 106, 015205 (2022) ` From 68b007c840b6514c677a0b9623b9bc72607d9a22 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Sat, 3 Aug 2024 17:17:29 +0200 Subject: [PATCH 05/17] Reorganise Ionization classes to centralise common elements. Define a new common monteCarloRoutine method in the Ionization class that is called by the () operators of all Ionization children. Also move the common parts of the initialisation of the children to the Ionization class. --- src/Ionization/Ionization.cpp | 208 +++++++-- src/Ionization/Ionization.h | 53 ++- src/Ionization/IonizationTunnel.cpp | 383 ++++++--------- src/Ionization/IonizationTunnel.h | 29 +- src/Ionization/IonizationTunnelBSI.cpp | 512 ++++----------------- src/Ionization/IonizationTunnelBSI.h | 33 +- src/Ionization/IonizationTunnelFullPPT.cpp | 220 +++------ src/Ionization/IonizationTunnelFullPPT.h | 22 +- src/Ionization/IonizationTunnelTL.cpp | 208 ++------- src/Ionization/IonizationTunnelTL.h | 24 +- 10 files changed, 590 insertions(+), 1102 deletions(-) mode change 100755 => 100644 src/Ionization/IonizationTunnel.cpp mode change 100755 => 100644 src/Ionization/IonizationTunnel.h diff --git a/src/Ionization/Ionization.cpp b/src/Ionization/Ionization.cpp index debc48b71..afb652a97 100755 --- a/src/Ionization/Ionization.cpp +++ b/src/Ionization/Ionization.cpp @@ -1,73 +1,203 @@ +#include "Ionization.h" + #include -#include "Ionization.h" #include "Species.h" using namespace std; -Ionization::Ionization( Params ¶ms, Species *species ) +Ionization::Ionization(Params ¶ms, Species *species) { - reference_angular_frequency_SI = params.reference_angular_frequency_SI; - - dt = params.timestep; - invdt = 1./dt; - nDim_field = params.nDim_field; - nDim_particle = params.nDim_particle; - ionized_species_invmass = 1./species->mass_; - + + dt = params.timestep; + invdt = 1. / dt; + nDim_field = params.nDim_field; + nDim_particle = params.nDim_particle; + ionized_species_invmass = 1. / species->mass_; + // Normalization constant from Smilei normalization to/from atomic units - eV_to_au = 1.0 / 27.2116; - au_to_mec2 = 27.2116/510.998e3; - EC_to_au = 3.314742578e-15 * reference_angular_frequency_SI; // hbar omega / (me c^2 alpha^3) - au_to_w0 = 4.134137172e+16 / reference_angular_frequency_SI; // alpha^2 me c^2 / (hbar omega) - + eV_to_au = 1.0 / 27.2116; + au_to_mec2 = 27.2116 / 510.998e3; + EC_to_au = 3.314742578e-15 * reference_angular_frequency_SI; // hbar omega / (me c^2 alpha^3) + au_to_w0 = 4.134137172e+16 / reference_angular_frequency_SI; // alpha^2 me c^2 / (hbar omega) + + atomic_number_ = species->atomic_number_; + Potential.resize(atomic_number_); + Azimuthal_quantum_number.resize(atomic_number_); + + one_third = 1.0 / 3.0; + + alpha_tunnel.resize(atomic_number_); + beta_tunnel.resize(atomic_number_); + gamma_tunnel.resize(atomic_number_); + #ifdef _OMPTASKS new_electrons_per_bin = new Particles[species->Nbins]; - ion_charge_per_bin_.resize( species->Nbins ); + ion_charge_per_bin_.resize(species->Nbins); #endif } +Ionization::~Ionization() {} -Ionization::~Ionization() +void Ionization::joinNewElectrons(unsigned int Nbins) { -} - - -void Ionization::joinNewElectrons( unsigned int Nbins ) -{ - // if tasks on bins are used for ionization, join the lists of new electrons + // if tasks on bins are used for ionization, join the lists of new electrons // created in each bin, to have the list of new electrons for this species and patch - + size_t start = new_electrons.size(); - + // Resize new_electrons size_t total_n_new = 0; - for( size_t ibin = 0 ; ibin < Nbins ; ibin++ ) { + for (size_t ibin = 0; ibin < Nbins; ibin++) + { total_n_new += new_electrons_per_bin[ibin].size(); } - new_electrons.createParticles( total_n_new ); + new_electrons.createParticles(total_n_new); // Also resize ion_charge_ if necessary - if( save_ion_charge_ ) { - ion_charge_.resize( start + total_n_new ); + if (save_ion_charge_) + { + ion_charge_.resize(start + total_n_new); } - + // Move each new_electrons_per_bin into new_electrons - for( size_t ibin = 0 ; ibin < Nbins ; ibin++ ) { + for (size_t ibin = 0; ibin < Nbins; ibin++) + { size_t n_new = new_electrons_per_bin[ibin].size(); - for( size_t i=0; i *Epart, + Patch *patch, Projector *Proj, const unsigned int Z, + const electricFields E, vector &IonizRate_tunnel, + vector &Dnom_tunnel, + function ionizationRate) +{ + double TotalIonizPot, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; + LocalFields Jion; + const double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; + unsigned int newZ, Zp1, k_times; + factorJion = factorJion_0 * E.inv * E.inv; + ran_p = patch->rand_->uniform(); + IonizRate_tunnel[Z] = ionizationRate(Z, E); + + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the nb of ionization events + k_times = 0; + Zp1 = Z + 1; + + if (Zp1 == atomic_number_) + { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) + { + TotalIonizPot += Potential[Z]; + k_times = 1; + } + } + else + { + // else : multiple ionization can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. + // Plasmas) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0] = 1.0; + Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. + + // multiple ionization loop while Pint_tunnel < ran_p and still partial + // ionization + while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) + { + newZ = Zp1 + k_times; + IonizRate_tunnel[newZ] = ionizationRate(newZ, E); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel[Z + k_times]; + for (unsigned int i = 0; i < k_times + 1; i++) + { + Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z + i]); + D_sum += Dnom_tunnel[i]; + P_sum += exp(-IonizRate_tunnel[Z + i] * dt) * Dnom_tunnel[i]; + } + Dnom_tunnel[k_times + 1] -= D_sum; + P_sum = P_sum + Dnom_tunnel[k_times + 1] * exp(-IonizRate_tunnel[newZ] * dt); + Pint_tunnel = Pint_tunnel + P_sum * Mult; + + TotalIonizPot += Potential[Z + k_times]; + k_times++; + } // END while + + // final ionization (of last electron) + if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) + { + TotalIonizPot += Potential[atomic_number_ - 1]; + k_times++; + } + } // END Multiple ionization routine + + // Compute ionization current + if (patch->EMfields->Jx_ != NULL) + { // For the moment ionization current is + // not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *(E.x + ipart); + Jion.y = factorJion * *(E.y + ipart); + Jion.z = factorJion * *(E.z + ipart); + + Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion); + } + + // Creation of the new electrons + // (variable weights are used) + // ----------------------------- + + if (k_times != 0) + { + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; + for (unsigned int i = 0; i < new_electrons.dimension(); i++) + { + new_electrons.position(i, idNew) = particles->position(i, ipart); + } + for (unsigned int i = 0; i < 3; i++) + { + new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; + } + new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); + new_electrons.charge(idNew) = -1; + + if (save_ion_charge_) + { + ion_charge_.push_back(particles->charge(ipart)); + } + + // Increase the charge of the particle + particles->charge(ipart) += k_times; + } +} + diff --git a/src/Ionization/Ionization.h b/src/Ionization/Ionization.h index 6443d78fa..54fd3500f 100755 --- a/src/Ionization/Ionization.h +++ b/src/Ionization/Ionization.h @@ -1,61 +1,80 @@ #ifndef IONIZATION_H #define IONIZATION_H +#include #include -#include "Tools.h" -#include "Params.h" -#include "Patch.h" #include "Field.h" +#include "Params.h" #include "Particles.h" +#include "Patch.h" #include "Projector.h" +#include "Tools.h" +using namespace std; + +struct electricFields +{ + double *x; + double *y; + double *z; + double inv; // inverse + double abs; // absolute value in atomic units +}; //! Class Ionization: generic class allowing to define Ionization physics class Ionization { - -public: + public: //! Constructor for Ionization - Ionization( Params ¶ms, Species *species ); + Ionization(Params ¶ms, Species *species); virtual ~Ionization(); - + //! Overloading of () operator - virtual void operator()( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int = 0 ) {}; + virtual void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int = 0) {}; //! method for envelope ionization - virtual void envelopeIonization( Particles *, unsigned int, unsigned int, std::vector *, std::vector *, std::vector *, std::vector *, Patch *, Projector *, int = 0, int = 0 ){}; - + virtual void envelopeIonization(Particles *, unsigned int, unsigned int, std::vector *, std::vector *, + std::vector *, std::vector *, Patch *, Projector *, int = 0, int = 0) {}; + // method for tunnel ionization using tasks - virtual void ionizationTunnelWithTasks( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int, int, double *, double *, double *, int = 0 ){}; + virtual void ionizationTunnelWithTasks(Particles *, unsigned int, unsigned int, std::vector *, Patch *, + Projector *, int, int, double *, double *, double *, int = 0) {}; // join the lists of electrons created through ionization when tasks are used void joinNewElectrons(unsigned int Nbins); Particles new_electrons; Particles *new_electrons_per_bin; - + //! Whether the initial charge (of the atom that was ionized) should be saved bool save_ion_charge_ = false; //! Temporarily contains the initial charge of the atom that was ionized std::vector ion_charge_; std::vector > ion_charge_per_bin_; - -protected: + + protected: + inline void tunnelMonteCarloRoutine(Particles *particles, unsigned int ipart, vector *Epart, Patch *patch, + Projector *Proj, const unsigned int Z, const electricFields E, + vector &IonizRate_tunnel, vector &Dnom_tunnel, + function ionizationRate); double eV_to_au; double au_to_mec2; double EC_to_au; double au_to_w0; - + double one_third; + double reference_angular_frequency_SI; double dt; double invdt; unsigned int nDim_field; unsigned int nDim_particle; double ionized_species_invmass; - -private: + unsigned int atomic_number_; + std::vector Potential, Azimuthal_quantum_number; + std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; + private: }; #endif diff --git a/src/Ionization/IonizationTunnel.cpp b/src/Ionization/IonizationTunnel.cpp old mode 100755 new mode 100644 index 31f605873..90d27bf9d --- a/src/Ionization/IonizationTunnel.cpp +++ b/src/Ionization/IonizationTunnel.cpp @@ -1,316 +1,221 @@ #include "IonizationTunnel.h" -#include "IonizationTables.h" #include +#include +#include "IonizationTables.h" #include "Particles.h" #include "Species.h" using namespace std; - - -IonizationTunnel::IonizationTunnel( Params ¶ms, Species *species ) : Ionization( params, species ) +IonizationTunnel::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) { - DEBUG( "Creating the Tunnel Ionizaton class" ); - - atomic_number_ = species->atomic_number_; - + DEBUG("Creating the Tunnel Ionizaton class"); + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - Potential.resize( atomic_number_ ); - Azimuthal_quantum_number.resize( atomic_number_ ); - for( int Zstar=0; Zstar<( int )atomic_number_; Zstar++ ) { - Potential [Zstar] = IonizationTables::ionization_energy( atomic_number_, Zstar ) * eV_to_au; - Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number( atomic_number_, Zstar ); - } - - for( unsigned int i=0; i *Epart, Patch *patch, Projector *Proj, int ipart_ref ) + DEBUG("Finished Creating the Tunnel Ionizaton class"); +} + +void IonizationTunnel::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) { + unsigned int Z; + electricFields E; + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); - unsigned int Z, Zp1, newZ, k_times; - double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ , 0.); - LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; - - int nparts = Epart->size()/3; - double *Ex = &( ( *Epart )[0*nparts] ); - double *Ey = &( ( *Epart )[1*nparts] ); - double *Ez = &( ( *Epart )[2*nparts] ); - - for( unsigned int ipart=ipart_min ; ipartsize() / 3; + E.x = &((*Epart)[0 * nparts]); + E.y = &((*Epart)[1 * nparts]); + E.z = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) + { // Current charge state of the ion - Z = ( unsigned int )( particles->charge( ipart ) ); - + Z = (unsigned int)(particles->charge(ipart)); + // If ion already fully ionized then skip - if( Z==atomic_number_ ) { + if (Z == atomic_number_) + { continue; } - + // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) - +pow( *( Ey+ipart-ipart_ref ), 2 ) - +pow( *( Ez+ipart-ipart_ref ), 2 ) ); - if( E<1e-10 ) { + E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + + pow(*(E.z + ipart - ipart_ref), 2)); + if (E.abs < 1e-10) + { continue; } - - // -------------------------------- - // Start of the Monte-Carlo routine - // -------------------------------- - - invE = 1./E; - factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z]*invE; - ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); - - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the nb of ionization events - k_times = 0; - Zp1=Z+1; - - if( Zp1 == atomic_number_ ) { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { - TotalIonizPot += Potential[Z]; - k_times = 1; - } - - } else { - // else : multiple ionization can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. Plasmas) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0]=1.0; - Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. - - //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { - newZ = Zp1+k_times; - delta = gamma_tunnel[newZ]*invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] - * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel[Z+k_times]; - for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { - TotalIonizPot += Potential[atomic_number_-1]; - k_times++; - } - }//END Multiple ionization routine - - // Compute ionization current - if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *( Ex+ipart ); - Jion.y = factorJion * *( Ey+ipart ); - Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); - } - - // Creation of the new electrons - // (variable weights are used) - // ----------------------------- + E.inv = 1. / E.abs; - if( k_times !=0 ) { - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; - for( unsigned int i=0; iposition( i, ipart ); - } - for( unsigned int i=0; i<3; i++ ) { - new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; - } - new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons.charge( idNew )=-1; - - if( save_ion_charge_ ) { - ion_charge_.push_back( particles->charge( ipart ) ); - } - - // Increase the charge of the particle - particles->charge( ipart ) += k_times; - } - - } // Loop on particles + tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, &IonizationTunnel::ionizationRateTunnel); + } // Loop on particles } -void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ibin, int bin_shift, - double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref ) +double IonizationTunnel::ionizationRateTunnel(const int Z, const electricFields E) { + double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); +} +void IonizationTunnel::ionizationTunnelWithTasks(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ibin, + int bin_shift, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref) +{ unsigned int Z, Zp1, newZ, k_times; double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; - - int nparts = Epart->size()/3; - double *Ex = &( ( *Epart )[0*nparts] ); - double *Ey = &( ( *Epart )[1*nparts] ); - double *Ez = &( ( *Epart )[2*nparts] ); - - for( unsigned int ipart=ipart_min ; ipartsize() / 3; + double *Ex = &((*Epart)[0 * nparts]); + double *Ey = &((*Epart)[1 * nparts]); + double *Ez = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) + { // Current charge state of the ion - Z = ( unsigned int )( particles->charge( ipart ) ); - + Z = (unsigned int)(particles->charge(ipart)); + // If ion already fully ionized then skip - if( Z==atomic_number_ ) { + if (Z == atomic_number_) + { continue; } - + // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) - +pow( *( Ey+ipart-ipart_ref ), 2 ) - +pow( *( Ez+ipart-ipart_ref ), 2 ) ); - if( E<1e-10 ) { + E = EC_to_au * sqrt(pow(*(Ex + ipart - ipart_ref), 2) + pow(*(Ey + ipart - ipart_ref), 2) + + pow(*(Ez + ipart - ipart_ref), 2)); + if (E < 1e-10) + { continue; } - + // -------------------------------- // Start of the Monte-Carlo routine // -------------------------------- - - invE = 1./E; - factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z]*invE; + + invE = 1. / E; + factorJion = factorJion_0 * invE * invE; + delta = gamma_tunnel[Z] * invE; ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); - + IonizRate_tunnel[Z] = beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); + // Total ionization potential (used to compute the ionization current) TotalIonizPot = 0.0; - + // k_times will give the nb of ionization events k_times = 0; - Zp1=Z+1; - - if( Zp1 == atomic_number_ ) { + Zp1 = Z + 1; + + if (Zp1 == atomic_number_) + { // if ionization of the last electron: single ionization // ----------------------------------------------------- - if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { + if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) + { TotalIonizPot += Potential[Z]; - k_times = 1; + k_times = 1; } - - } else { + } + else + { // else : multiple ionization can occur in one time-step // partial & final ionization are decoupled (see Nuter Phys. Plasmas) // ------------------------------------------------------------------------- - + // initialization Mult = 1.0; - Dnom_tunnel[0]=1.0; - Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. - - //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { - newZ = Zp1+k_times; - delta = gamma_tunnel[newZ]*invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] - * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); + Dnom_tunnel[0] = 1.0; + Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. + + // multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) + { + newZ = Zp1 + k_times; + delta = gamma_tunnel[newZ] * invE; + IonizRate_tunnel[newZ] = beta_tunnel[newZ] * exp(-delta * one_third + alpha_tunnel[newZ] * log(delta)); D_sum = 0.0; P_sum = 0.0; - Mult *= IonizRate_tunnel[Z+k_times]; - for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { - TotalIonizPot += Potential[atomic_number_-1]; + if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) + { + TotalIonizPot += Potential[atomic_number_ - 1]; k_times++; } - }//END Multiple ionization routine - + } // END Multiple ionization routine + // Compute ionization current - if (b_Jx != NULL){ // For the moment ionization current is not accounted for in AM geometry + if (b_Jx != NULL) + { // For the moment ionization current is not accounted for in AM geometry factorJion *= TotalIonizPot; - Jion.x = factorJion * *( Ex+ipart ); - Jion.y = factorJion * *( Ey+ipart ); - Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrentsForTasks( b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift ); + Jion.x = factorJion * *(Ex + ipart); + Jion.y = factorJion * *(Ey + ipart); + Jion.z = factorJion * *(Ez + ipart); + + Proj->ionizationCurrentsForTasks(b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift); } - + // Creation of the new electrons // (variable weights are used) // ----------------------------- - if( k_times !=0 ) { + if (k_times != 0) + { new_electrons_per_bin[ibin].createParticle(); - int idNew = new_electrons_per_bin[ibin].size() - 1;//cout<<"ibin "<position( i, ipart ); + int idNew = new_electrons_per_bin[ibin].size() - + 1; // cout<<"ibin "<position(i, ipart); } - for( unsigned int i=0; i<3; i++ ) { - new_electrons_per_bin[ibin].momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + for (unsigned int i = 0; i < 3; i++) + { + new_electrons_per_bin[ibin].momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; } - new_electrons_per_bin[ibin].weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons_per_bin[ibin].charge( idNew )=-1; - - if( save_ion_charge_ ) { - ion_charge_per_bin_[ibin].push_back( particles->charge( ipart ) ); + new_electrons_per_bin[ibin].weight(idNew) = double(k_times) * particles->weight(ipart); + new_electrons_per_bin[ibin].charge(idNew) = -1; + + if (save_ion_charge_) + { + ion_charge_per_bin_[ibin].push_back(particles->charge(ipart)); } - + // // Increase the charge of the particle - particles->charge( ipart ) += k_times; + particles->charge(ipart) += k_times; } - - } // Loop on particles + + } // Loop on particles } diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h old mode 100755 new mode 100644 index 788b45ccd..d2e9570fb --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -2,35 +2,30 @@ #define IONIZATIONTUNNEL_H #include - +#include #include #include "Ionization.h" #include "Tools.h" class Particles; +struct electricFields; //! calculate the particle tunnel ionization class IonizationTunnel : public Ionization { + public: + IonizationTunnel(Params ¶ms, Species *species); + + void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, + int ipart_ref = 0) override; -public: - //! Constructor for IonizationTunnel: with no input argument - IonizationTunnel( Params ¶ms, Species *species ); - - //! apply the Tunnel Ionization model to the species (with ionization current) - void operator()( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0 ) override; //! method for tunnel ionization with tasks - void ionizationTunnelWithTasks( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0 ) override; - -private: - unsigned int atomic_number_; - std::vector Potential; - std::vector Azimuthal_quantum_number; - - double one_third; - std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; -}; + void ionizationTunnelWithTasks(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, + int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; + private: + double ionizationRateTunnel(const int Z, const electricFields E); +}; #endif diff --git a/src/Ionization/IonizationTunnelBSI.cpp b/src/Ionization/IonizationTunnelBSI.cpp index 8950117f1..5eff2565e 100755 --- a/src/Ionization/IonizationTunnelBSI.cpp +++ b/src/Ionization/IonizationTunnelBSI.cpp @@ -1,454 +1,128 @@ #include "IonizationTunnelBSI.h" -#include "IonizationTables.h" #include #include +#include "IonizationTables.h" #include "Particles.h" #include "Species.h" using namespace std; -IonizationTunnelBSI::IonizationTunnelBSI(Params ¶ms, Species *species) : Ionization(params, species) // :Ionization(params, species) applies the base CTOR to initialize inherited member variables. +IonizationTunnelBSI::IonizationTunnelBSI(Params ¶ms, Species *species) : Ionization(params, species) { - DEBUG( "Creating the Tunnel+BSI Ionizaton class" ); - - atomic_number_ = species->atomic_number_; - Potential.resize(atomic_number_); // Potential is a std::vector, a vector of IonizationPotentials (Ioniz Energies) - Azimuthal_quantum_number.resize(atomic_number_); // Azimuthal_quantum_number is a std::vector + DEBUG("Creating the Tunnel BSI Ionizaton class"); - for(int Zstar = 0; Zstar < (int)atomic_number_; Zstar++) { // for each charge state (0e removed, 1e removed, ..., Z-1 e removed) - Potential [Zstar] = IonizationTables::ionization_energy(atomic_number_, Zstar) * eV_to_au; // last factor to convert to AtomicUnits. Whole instr. returns IP of element with atomic no = atomic_number_ and charge state Zstar (Zstar=0 is a neutral atom) - Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number(atomic_number_, Zstar); // - } + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); - one_third = 1.0/3.0; + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - alpha_tunnel.resize(atomic_number_); - beta_tunnel.resize(atomic_number_); - gamma_tunnel.resize(atomic_number_); + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - for(unsigned int Z=0 ; Z *Epart, Patch *patch, Projector *Proj, int ipart_ref ) { - unsigned int Z, Zp1, newZ, k_times; - double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel, Pint_BSI_linear, Pint_BSI_quadratic; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); // For MonteCarlo procedure using the tunnel ioniz. rate. - vector IonizRate_BSI_linear(atomic_number_), Dnom_BSI_linear(atomic_number_); // For MonteCarlo procedure using the BSI ioniz. rate. +void IonizationTunnelBSI::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) +{ + unsigned int Z; + electricFields E; + vector IonizRate_tunnel(atomic_number_), + Dnom_tunnel(atomic_number_); // For MonteCarlo procedure using the tunnel + // ioniz. rate. + vector IonizRate_BSI_linear(atomic_number_), + Dnom_BSI_linear(atomic_number_); // For MonteCarlo procedure using the BSI + // ioniz. rate. vector IonizRate_BSI_quadratic(atomic_number_), Dnom_BSI_quadratic(atomic_number_); - LocalFields Jion; // To deposit ionization current appearing from the ionization events. - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; // Will be used to calc. ionization current. - - int nparts = Epart->size()/3; // Over 3 because there are 3 Dims. Epart is like [part1_Ex, part2_Ex, ... partnparts_Ex, part1_Ey, part2_Ey,...partnparts_Ey, part1_Ez, part2_Ez, partnparts_Ez]} - double *Ex = &( (*Epart)[0*nparts] ); // Pointer to beginning of the vector which holds the (3 * n_parts) values of the n_parts E-field (Physics) 3D vectors. - double *Ey = &( (*Epart)[1*nparts] ); // Pointer to where E_y values start inside the Epart vector. - double *Ez = &( (*Epart)[2*nparts] ); // Pointer to where E_z values start inside the Epart vector. - for(unsigned int ipart = ipart_min ; ipart < ipart_max; ipart++) { // Loop on particles from Particles* particles input argument - // Current charge state of the ion. - Z = (unsigned int) (particles->charge(ipart)) ; // current charge state of the particle number ipart of species called ''species'' with atomic no = atomic_number_ - Zp1 = Z + 1; - // Implementation of Barrier Suppresion Ionization Critical Field E_cr. - // need E_cr to be in atomic units. Thus need to implement E_cr as from DonnaStrickland1991, page 5, eq(5). [Laser ionization of noble gases by Coulomb-barrier suppression] - // There the Ionization Potential appearing in formula is in AtomicUnits. - // Here, all values from Potential[] vector are in AtomicUnits also. - // Thus need to implement exactly Donna's formula: E_cr = pow(Potential[atomic_number*(atomic_number_-1)/2 + Z] , 2) / (4*Z); - // Donna's E_cr easily matches the SI units version of E_cr presented in Artmenko, Kostyukov, PhysRevA 96, 0321,06 (2017), page 2, section II. - // Russians researchers say E_cr = atomic_unit_of_field * kappa^4 / (16*Z), where kappa^2 = Ii/IH, thus Ii is measured in units of (atomic_unit_of_energy / 2). - // Had they measured Ii in atomic_unit_of_energy, the 16 on the denominator would become a 4. (atomic_unit_of_energy = 2*IH). - // Thus the implementation of E_cr in atomic units, following the Russians researchers would be: - // double ionizpots_ratio_forkappa = (Potential[ atomic_number_*(atomic_number_-1)/2 + Z ] / Potential[0]); // Potential[atomic_number_*(atomic_number_-1)/2 + Z] is IonizEnergy for current charge state of ion with atomic number equal to atomic_number_. Potential[0] is IonizPot of Hydrogen H. All the values in Pontential[] vector are in AtomicUnits. Thus the normalization dissapears when taking ratio of Ii/IH. - // double kappa = pow(ionizpots_ratio_forkappa , 0.5); - // double E_cr = ( pow(kappa,4) / (16*Z) ) / atomic_unit_of_field; // E_cr in AtomicUnits, as from Artmenko, Kostyukov, PhysRevA 96, 0321,06 (2017), page 2, section II. - - // HOW IS E_CR USEFUL? Answer: it is useless at the moment. - // E_cr in atomic units formula (with Potential[] vector's numerical values being in AtomicUnits): - double E_cr = pow( Potential[Z], 2) / (4*Zp1); // Formula from DonnaStrickland, 1991, page5, eq(5) [Laser ionization of noble gases by Coulomb-barrier suppression] + double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; // Will be used to calc. ionization current. + + int nparts = Epart->size() / 3; // Over 3 because there are 3 Dims. Epart is like [part1_Ex, part2_Ex, + // ... partnparts_Ex, part1_Ey, part2_Ey,...partnparts_Ey, part1_Ez, + // part2_Ez, partnparts_Ez]} + E.x = &((*Epart)[0 * nparts]); + E.y = &((*Epart)[1 * nparts]); + E.z = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) + { + Z = (unsigned int)(particles->charge(ipart)); // current charge state of the particle number ipart of species + // called ''species'' with atomic no = atomic_number_ + double E_cr = pow(Potential[Z], 2) / (4 * (Z + 1)); // Formula from DonnaStrickland, 1991, page5, eq(5) [Laser + // ionization of noble gases by Coulomb-barrier suppression] // There's absolutely no usage of this E_cr in the code. // If ion already fully ionized then skip and go to next particle - if (Z==atomic_number_) { continue; } // atom fully ionized already, no electrons remained to be stripped away. - - // Absolute value of the electric field in AtomicUnits (i.e. normalized to (in units of) E_atomic = 5.1422*10^11 V/m) - E = EC_to_au * sqrt( pow( *(Ex + ipart - ipart_ref), 2) // (Ex+ipart-ipart_ref) points to the location in the container Epart at which E-field_x for particle ipart sits. - + pow( *(Ey + ipart - ipart_ref), 2) // Similarly for y. Dereferencing it via *() means we access and use the value sitting at that location. - + pow( *(Ez + ipart - ipart_ref), 2) ); // EC_to_au transforms from SMILEI-normalized units to AtomicUnits. - if(E < 1e-10) { // E is in Atomic Units + if (Z == atomic_number_) + { + continue; + } // atom fully ionized already, no electrons remained to be stripped away. + + // Absolute value of the electric field in AtomicUnits (i.e. normalized to + // (in units of) E_atomic = 5.1422*10^11 V/m) + E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), + 2) // (Ex+ipart-ipart_ref) points to the location in the + // container Epart at which E-field_x for particle ipart + // sits. + + pow(*(E.y + ipart - ipart_ref), + 2) // Similarly for y. Dereferencing it via *() means we + // access and use the value sitting at that location. + + pow(*(E.z + ipart - ipart_ref), + 2)); // EC_to_au transforms from SMILEI-normalized units to + // AtomicUnits. + if (E.abs < 1e-10) + { // E is in Atomic Units continue; } - // Check whether to follow MC routine with Tunnel rate or with BSI rate (Quadratic or Linear). - // Prof. Tony Arber in: Arber_2015_Plasma_Phys._Control._Fusion_57_113001 gives a hint on how to do this. - // There he explains how to make the PIC code choose, at each timestep, between Tunnel and BSI (2 piece rate). - - // I am doing it in a simpler way, see int continuity_tool() function implementation! - // int continuity_tool(parameter1, ... ,) function does the job. Depending on the output of continuity_tool(,...,), SMILEI chooses which rate to use at each timestep. - - int rate_idx = continuity_tool(Zp1, E, alpha_tunnel[Z], beta_tunnel[Z], gamma_tunnel[Z], E_cr, Potential[Z], atomic_number_, au_to_w0); // - if (rate_idx != 0 ) { // Then use one of the two BSI rates: vector IonizRate_BSI_linear(atomic_number_) or vector IonizRate_BSI_quadratic(atomic_number_). - // So rate is not Tunnel. The rate_idx can only be 1 or 2. - if (rate_idx == 1) { // then use BSI-Quadratic rate, as dictated by continuity_tool() - - double IH = 13.598434005136; // IP of atomic Hydrogen (H), in eV. - double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // returns IP of Element with atomic no = atomic_number_ and charge state Z (Z=0 is a neutral atom) - double ratio_of_IPs = IH / Ii; - // IonizRate_BSI_quadratic[Z] = 2.4 * (pow(E,2)) / pow(Zp1,4); // From Bauer1999: Quadratic dep. on E and scales as 1/Z^4. From the formula on this line of code, the rate emerges in AtomicUnits, as E is in Atomic Units and Zp1 is a integer. - IonizRate_BSI_quadratic[Z] = au_to_w0 * (2.4 * (pow(E,2)) * pow(ratio_of_IPs, 2)); // 1/(Z^4) = (IH_Ii)^2 - // IonizRate_BSI_quadratic as 1 line above is now returned in SMILEI units. - invE = 1./E; - factorJion = factorJion_0 * invE*invE; // Used to compute the ionization current Jion. - // Monte Carlo routine from Nuter et al. 2011 - ran_p = patch -> rand_ -> uniform(); - - TotalIonizPot = 0.0; // Used to compute the ionization current Jion. - - // k_times will give the number of ionization events in this timestep. - k_times = 0; - Zp1 = Z + 1; - - if (Zp1 == atomic_number_) { // single-ionization, i.e. ioniz. of the last electron. - if ( ran_p < 1 - exp (-IonizRate_BSI_quadratic[Z]*dt) ) { // MC dictates to ionize it - TotalIonizPot += Potential[Z]; - k_times += 1; - } // else nothing happens, no ionization of the last electron during this timestep. for loop moves to next particle, i.e. the one indexed by ipart+1. - } - else { // multiple ionization can happen in one timestep because we are not ionizing the last electron yet. - // partial & final ionization are decoupled (see Nuter Phys. Plasmas 2011) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_BSI_quadratic[0] = 1.0; - Pint_BSI_quadratic = exp( -IonizRate_BSI_quadratic[Z]*dt ); - - // multiple ionization loop while Pint_BSI < ran_p and still partial ionization - while( (Pint_BSI_quadratic < ran_p) and (k_times < atomic_number_-Zp1) ) { - newZ = Zp1 + k_times; - double Ii_newZ = IonizationTables::ionization_energy(atomic_number_, newZ); - double ratio_of_IPs_newZ = IH / Ii_newZ; - IonizRate_BSI_quadratic[newZ] = au_to_w0 * (2.4 * (pow(E,2)) * pow(ratio_of_IPs_newZ, 2)); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_BSI_quadratic[ Z + k_times]; - for (unsigned int i=0; i <= k_times+1; i++) { - Dnom_BSI_quadratic[i] = Dnom_BSI_quadratic[i] / (IonizRate_BSI_quadratic[newZ] - IonizRate_BSI_quadratic[Z+i]) ; - D_sum += Dnom_BSI_quadratic[i]; - P_sum += exp(-IonizRate_BSI_quadratic[Z+i]*dt) * Dnom_BSI_quadratic[i]; - } - Dnom_BSI_quadratic[k_times+1] -= D_sum; - P_sum = P_sum + Dnom_BSI_quadratic[k_times+1] * exp(-IonizRate_BSI_quadratic[newZ]*dt); - Pint_BSI_quadratic = Pint_BSI_quadratic + P_sum*Mult; - - TotalIonizPot += Potential[Z + k_times]; - k_times++; - } // END while - - // final ionization (of last electron) - if ( ((1.0-Pint_BSI_quadratic) > ran_p) && (k_times == atomic_number_-Zp1) ) { - TotalIonizPot += Potential[atomic_number_-1]; - k_times++; - } // END final ionization (of last electron) - - } // END multiple ionization routine. - - // Compute Ionization Currents - if (patch->EMfields->Jx_ != NULL) { - factorJion *= TotalIonizPot; - Jion.x = factorJion * *(Ex + ipart); - Jion.y = factorJion * *(Ey + ipart); - Jion.z = factorJion * *(Ez + ipart); - Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, - patch->EMfields->Jz_, *particles, ipart, Jion); - } - // Creation of the new electrons (variable weights are used) - if(k_times != 0) { // If ionization has taken place. - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; // new_electrons.size() = number of electrons in new_electrons. -1 from idNew because the first elem of array has index 0. - for(unsigned int i=0; i < new_electrons.dimension(); i++) { // new_electrons.dimension() is 1,2 or 3, depending on geometry of simulation. - new_electrons.position(i, idNew) = particles->position(i, ipart); - } - for(unsigned int i=0; i<3; i++) { - new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; - } - new_electrons.weight(idNew) = double(k_times) * particles -> weight(ipart); - new_electrons.charge(idNew) = -1; - - // Increase charge of particle. - particles->charge(ipart) += k_times; - } // END creation of new electrons. - - } // END subroutine for BSI-Quadratic rate // END if(index == 1) {} - - else { // if (rate_idx==1) {...} loop's else statement: means that rate_idx = 2 ==> use BSI-Linear - double IH = 13.598434005136; // IP of atomic Hydrogen (H), in eV. - double Ii = IonizationTables::ionization_energy(atomic_number_, Z); - double ratio_of_IPs = IH / Ii; - IonizRate_BSI_linear[Z] = au_to_w0 * (0.8 * E * pow(ratio_of_IPs, 0.5)); // paranthesis is in AtomicUnits - invE = 1./E; - factorJion = factorJion_0 * invE*invE; // Used to compute the ionization current Jion. - - ran_p = patch -> rand_ -> uniform(); - - TotalIonizPot = 0.0; // Used to compute the ionization current Jion. - - // k_times will give the number of ionization events in this timestep. - k_times = 0; - Zp1 = Z + 1; - if (Zp1 == atomic_number_) { // single-ionization, i.e. ioniz. of the last electron. - if ( ran_p < 1 - exp (-IonizRate_BSI_linear[Z]*dt) ) { // MC dictates to ionize it - TotalIonizPot += Potential[Z]; - k_times += 1; - } // else nothing happens, no ionization of the last electron during this timestep. for loop moves to next particle, i.e. the one indexed by ipart+1. - } - else { // multiple ionization can happen in one timestep because we are not ionizing the last electron yet. - // partial & final ionization are decoupled (see Nuter Phys. Plasmas 2011) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_BSI_linear[0] = 1.0; - Pint_BSI_linear = exp( -IonizRate_BSI_linear[Z]*dt ); - - // multiple ionization loop while Pint_BSI < ran_p and still partial ionization - while( (Pint_BSI_linear < ran_p) and (k_times < atomic_number_-Zp1) ) { - newZ = Zp1 + k_times; - double Ii_newZ = IonizationTables::ionization_energy(atomic_number_, newZ); - double ratio_of_IPs_newZ = IH / Ii_newZ; - IonizRate_BSI_linear[newZ] = au_to_w0 * (0.8 * E * pow(ratio_of_IPs_newZ, 0.5)); // Paranthesis is in Atomic Units - // Linear BSI rate as 1 line above is in SMILEI units. - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_BSI_linear[ Z + k_times]; - for (unsigned int i=0; i <= k_times+1; i++) { - Dnom_BSI_linear[i] = Dnom_BSI_linear[i] / (IonizRate_BSI_linear[newZ] - IonizRate_BSI_linear[Z+i]) ; - D_sum += Dnom_BSI_linear[i]; - P_sum += exp(-IonizRate_BSI_linear[Z+i]*dt) * Dnom_BSI_linear[i]; - } - Dnom_BSI_linear[k_times+1] -= D_sum; - P_sum = P_sum + Dnom_BSI_linear[k_times+1] * exp(-IonizRate_BSI_linear[newZ]*dt); - Pint_BSI_linear = Pint_BSI_linear + P_sum*Mult; + // Used to be call to continuity_tool. After some shortening, the call was manually inlined + double BSI_rate_quadratic = ionizationRateBSIQuadratic(Z, E); + double BSI_rate_linear = ionizationRateBSILinear(Z, E); + double Tunnel_rate = ionizationRateTunnel(Z, E); - TotalIonizPot += Potential[Z + k_times]; - k_times++; - } // END while - - // final ionization (of last electron) - if ( ((1.0-Pint_BSI_linear) > ran_p) && (k_times == atomic_number_-Zp1) ) { - TotalIonizPot += Potential[atomic_number_-1]; - k_times++; - } // END final ionization (of last electron) - - } // END multiple ionization routine. - - // Compute Ionization Currents - if (patch->EMfields->Jx_ != NULL) { - factorJion *= TotalIonizPot; - Jion.x = factorJion * *(Ex + ipart); - Jion.y = factorJion * *(Ey + ipart); - Jion.z = factorJion * *(Ez + ipart); - Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, - patch->EMfields->Jz_, *particles, ipart, Jion); - } - - // Creation of the new electrons (variable weights are used) - if(k_times != 0) { // If ionization has taken place. - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; // new_electrons.size() = number of electrons in new_electrons. -1 from idNew because the first elem of array has index 0. - for(unsigned int i=0; i < new_electrons.dimension(); i++) { // new_electrons.dimension() is 1,2 or 3, depending on geometry of simulation. - new_electrons.position(i, idNew) = particles->position(i, ipart); - } - for(unsigned int i=0; i<3; i++) { - new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; - } - new_electrons.weight(idNew) = double(k_times) * particles -> weight(ipart); - new_electrons.charge(idNew) = -1; - - // Increase charge of particle. - particles->charge(ipart) += k_times; - } // END creation of new electrons. - } // END else {// rate_idx = 2} - } // END if(rate_idx != 0) {} - - else { // rate_idx = 0, so use Tunnel rate. There's no other rate_idx value which can appear. It is deemed to be 0 if the code reaches this else statement. - invE = 1./E; - factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z] * invE; - ran_p = patch->rand_->uniform(); // - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp(-delta*one_third + alpha_tunnel[Z]*log(delta)); - // IonizRate_tunnel as from 1 line above is in SMILEI units (beta has at its implementation's end the multiplication by au_to_w0) - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the number of ionization events - k_times = 0; - Zp1 = Z + 1; - - if( Zp1 == atomic_number_ ) { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if( ran_p < 1.0 - exp(-IonizRate_tunnel[Z]*dt) ) { // MC dictates to ionize it. - TotalIonizPot += Potential[Z]; - k_times = 1; // ionize it - } - } - else { - // else : MULTIPLE IONZIATION can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. Plasmas 2011) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0] = 1.0; - Pint_tunnel = exp(-IonizRate_tunnel[Z]*dt); // cummulative prob. (Pint_tunnel is a double) - - // MULTIPLE IONZIATION loop while Pint_tunnel < ran_p and still partial ionization. - while( (Pint_tunnel < ran_p) and (k_times < atomic_number_-Zp1) ) { - newZ = Zp1 + k_times; - delta = gamma_tunnel[newZ] * invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] * exp(-delta*one_third + alpha_tunnel[newZ]*log(delta)); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel[ Z+k_times ]; - for(unsigned int i=0; i < k_times+1; i++) { - Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z+i]); - D_sum += Dnom_tunnel[i]; - P_sum += exp( -IonizRate_tunnel[Z+i]*dt ) * Dnom_tunnel[i]; - } - Dnom_tunnel[k_times+1] = -D_sum; //bug fix - P_sum = P_sum + Dnom_tunnel[k_times+1] * exp(-IonizRate_tunnel[newZ]*dt); - Pint_tunnel = Pint_tunnel + P_sum*Mult; - - TotalIonizPot += Potential[ Z+k_times ]; - k_times++; - } //END while - - // final ionization (of last electron) - if( ((1.0-Pint_tunnel) > ran_p) && (k_times == atomic_number_-Zp1) ) { - TotalIonizPot += Potential[atomic_number_-1]; - k_times++; - } - } // END Multiple ionization routine for Tunnel rate - - // Compute ionization current - if (patch->EMfields->Jx_ != NULL) { // For the moment ionization current is not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *(Ex + ipart); - Jion.y = factorJion * *(Ey + ipart); - Jion.z = factorJion * *(Ez + ipart); - - Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, - *particles, ipart, Jion); - } - - // Creation of the new electrons (variable weights are used) - // ----------------------------- - if( k_times !=0 ) { // If ionization has taken place. - new_electrons.createParticle(); // new_electrons is an instance of class Particles. it is defined in Ionization.h - //new_electrons.initialize( new_electrons.size()+1, new_electrons.dimension() ); // ??? - int idNew = new_electrons.size() - 1; // new_electrons.size() = number of electrons in new_electrons. -1 from idNew because the first elem of array has index 0. - - for(unsigned int i=0; iposition(i, ipart); - } - for(unsigned int i=0; i<3; i++) { // Momentum is a 3Dim vector. (3Velocity simulation) - new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; - } - - new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); - new_electrons.charge(idNew) = -1; - - // Increase the charge of the particle - particles->charge(ipart) += k_times; - - } // END creation of electrons for when using Tunnel rate - } // END whole routine for when rate_idx = 0 , i.e. when using Tunnel rate - - } // END loop on particles - -} // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. - - -int IonizationTunnelBSI::continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0) { - // returns: - // 0 for when it chooses Tunnel ADK-PPT Ionization Rate, - // 1 for when it chooses the BSI-Quadratic Ionization Rate, - // 2 for when it chooses BSI-Linear Ionization Rate - - // Aim is to implement the 3-piece general rate, so a method to choose between Tunnel or BSI linear or BSI quadratic. - // E_cr from the arguments of this function is useless at the moment. - // alpha, beta, gamma coefficients are single numbers, for ion with charge state Z = Zp1 - 1, for a fixed atomic number (of the species under consideration). Z=0 is a neutral atom, Z=1 is singly ionized ion, i.e. Na^{+1}. - // alpha = alpha_tunnel[Z], beta = beta_tunnel[Z], gamma = gamma_tunnel[Z], where Z = Zp1 - 1 and - // where alpha_tunnel[Z] uses Z and Potential[Z] (IonizationPotential (in AtomicUnits) of Element with atomic number = atomic_number_ and charge state Z (Z=0 means neutral atom)) - // (double) Potential from arguments is the IP in AtomicUnits for current charge state Z (Z=0 is neutral atom) for a fixed atomic no = atomic_number_. - // Potential from the arguments is not actually needed!!! - unsigned int Z = Zp1 - 1; + if (BSI_rate_quadratic >= BSI_rate_linear) + { + tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_BSI_quadratic, + Dnom_BSI_quadratic, &IonizationTunnelBSI::ionizationRateBSIQuadratic); + } + else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) + { + tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_BSI_linear, Dnom_BSI_linear, + &IonizationTunnelBSI::ionizationRateBSILinear); + } + else + { + tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, + &IonizationTunnelBSI::ionizationRateTunnel); + } + } // END loop on particles - double Potential_in_eV = Potential * au_to_eV; // AtomicUnits to eV conversion on Potential from arguments of this function. // not actually needed !! - // Potential_in_eV will be used for BSI linear rate implemented below. There we need the ratio of Potential_in_eV[] and 13.6 eV - // not actually needed anymore! - - double BSI_rate_quadratic = BSI_rate_quadratic_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ - double BSI_rate_linear = BSI_rate_linear_function(Zp1, E, atomic_number_, au_to_w0); // returns rate for charge state Z and atomic_number=atomic_number_ - double Tunnel_rate = Tunnel_rate_function(Z, E, alpha, beta, gamma); // Z = Zp1 - 1; +} // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. - if (BSI_rate_quadratic >= BSI_rate_linear) { // all these rates which are compared here are in SMILEI units - return 2; // 2 means return BSI-Linear rate - } - else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) { // this returns min(Tunnel, BSI-Quadratic) - return 1; // 1 means return BSI-Quadratic rate - } - else return 0; // 0 means return Tunnel rate. The min is Tunnel rate - -} - - -// TUNNEL Ionization Rates -// ############################################################# -// 1) ADK-PPT static rate in units of atomic_unit_of_freq, all physical quantities inside rate formula are in atomic units. -double IonizationTunnelBSI::Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma) { // E is in Atomic Units - // Z from arguments is useless here as alpha, beta, gamma are for that Z already. - double one_third = 1.0/3.0; - double invE = 1./E ; - double delta = gamma * invE; - - double Tunnel_rate = beta * exp( -delta*one_third + alpha*log(delta) ); // E depenedency comes through delta - return Tunnel_rate; // returned rate is in SMILEI UNITS due to beta from above +double IonizationTunnelBSI::ionizationRateBSIQuadratic(const int Z, const electricFields E) // Z is charge state +{ + double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (2.4 * (pow(E.abs, 2)) * pow(ratio_of_IPs, 2)); } -// BSI rates -// ############################################################################## -// BSI rates below are calculated in atomic units, for both the Quadratic rate and the Linear rate. -double IonizationTunnelBSI::BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. - double Z = Zp1 - 1; - double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. - double Ii = IonizationTables::ionization_energy(atomic_number_, Z); - double ratio_of_IPs = IH / Ii; - - double BSI_rate_quadratic = 2.4 * (pow(E,2)) * pow(ratio_of_IPs,2); // E is in atomic units here, rate is calculated in atomic units - return (BSI_rate_quadratic * au_to_w0); // in SMILEI UNITS +double IonizationTunnelBSI::ionizationRateBSILinear(const int Z, const electricFields E) // Z is charge state +{ + double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (0.8 * E.abs * pow(ratio_of_IPs, 0.5)); } -double IonizationTunnelBSI::BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0) { // E-field E from arguments has to be in AtomicUnits. - double Z = Zp1 - 1; - double IH = 13.598434005136; // IP of atomic Hydrogen H, in eV. - double Ii = IonizationTables::ionization_energy(atomic_number_, Z); // Ii shall be the IP of atom/ion. Instr. on RSH of equal sign returns IP of element with atomic no = atomic_number_ and charge state Z (Z=0 is neutral atom). - double ratio_of_IPs = IH / Ii; - - double BSI_rate_linear = 0.8 * E * pow(ratio_of_IPs, 0.5); // E is in atomic units, rate is computed in Atomic units. - // return BSI_rate_linear; // Returns BSI linear rate in AtomicUnits (i.e. normalized to atomic_unit_of_frequency) - return (BSI_rate_linear * au_to_w0); // in SMILEI units. +double IonizationTunnelBSI::ionizationRateTunnel(const int Z, const electricFields E) +{ + double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); } diff --git a/src/Ionization/IonizationTunnelBSI.h b/src/Ionization/IonizationTunnelBSI.h index 073ba2c30..1fe2cc9f5 100755 --- a/src/Ionization/IonizationTunnelBSI.h +++ b/src/Ionization/IonizationTunnelBSI.h @@ -9,26 +9,19 @@ class Particles; - -class IonizationTunnelBSI : public Ionization { - public: - IonizationTunnelBSI(Params ¶ms, Species *species); - void operator()(Particles*, unsigned int, unsigned int, std::vector*, Patch*, Projector*, int ipart_ref = 0) override; - - private: - unsigned int atomic_number_; - std::vector Potential, Azimuthal_quantum_number; - double one_third; - std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; - - double BSI_rate_quadratic_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); - double BSI_rate_linear_function(unsigned int Zp1, double E, unsigned int atomic_number_, double au_to_w0); - double Tunnel_rate_function(unsigned int Z, double E, double alpha, double beta, double gamma); - - int continuity_tool(unsigned int Zp1, double E, double alpha, double beta, double gamma, double E_cr, double Potential, unsigned int atomic_number_, double au_to_w0); - - double au_to_eV=27.2116; - +class IonizationTunnelBSI : public Ionization +{ + public: + IonizationTunnelBSI(Params ¶ms, Species *species); + void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0) override; + + private: + double ionizationRateBSIQuadratic(int Z, electricFields E); + double ionizationRateBSILinear(int Z, electricFields E); + double ionizationRateTunnel(const int Z, const electricFields E); + + double au_to_eV = 27.2116; + double IH = 13.598434005136; }; #endif diff --git a/src/Ionization/IonizationTunnelFullPPT.cpp b/src/Ionization/IonizationTunnelFullPPT.cpp index bd2604ba8..d3e0d6df5 100755 --- a/src/Ionization/IonizationTunnelFullPPT.cpp +++ b/src/Ionization/IonizationTunnelFullPPT.cpp @@ -1,188 +1,82 @@ #include "IonizationTunnelFullPPT.h" -#include "IonizationTables.h" #include +#include "IonizationTables.h" #include "Particles.h" #include "Species.h" using namespace std; - - -IonizationTunnelFullPPT::IonizationTunnelFullPPT( Params ¶ms, Species *species ) : Ionization( params, species ) +IonizationTunnelFullPPT::IonizationTunnelFullPPT(Params ¶ms, Species *species) : Ionization(params, species) { - DEBUG( "Creating the FullPPT Tunnel Ionizaton class" ); - - atomic_number_ = species->atomic_number_; - + DEBUG("Creating the Tunnel Ionizaton class"); + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - Potential.resize( atomic_number_ ); - Azimuthal_quantum_number.resize( atomic_number_ ); - Magnetic_quantum_number.resize( atomic_number_ ); - for( int Zstar=0; Zstar<( int )atomic_number_; Zstar++ ) { - Potential [Zstar] = IonizationTables::ionization_energy( atomic_number_, Zstar ) * eV_to_au; - Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number( atomic_number_, Zstar ); - Magnetic_quantum_number[Zstar] = IonizationTables::magnetic_atomic_number( atomic_number_, Zstar ); + Magnetic_quantum_number.resize(atomic_number_); + + for (unsigned int Z = 0; Z < atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); + + DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] + << " M.q.num: " << Magnetic_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + double abs_m = abs(Magnetic_quantum_number[Z]); + alpha_tunnel[Z] = cst - 1.0 - abs_m; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / + (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); } - - for( unsigned int i=0; i *Epart, Patch *patch, Projector *Proj, int ipart_ref ) +void IonizationTunnelFullPPT::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) { + unsigned int Z; + electricFields E; + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); + + int nparts = Epart->size() / 3; + E.x = &((*Epart)[0 * nparts]); + E.y = &((*Epart)[1 * nparts]); + E.z = &((*Epart)[2 * nparts]); - unsigned int Z, Zp1, newZ, k_times; - double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); - LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; - - int nparts = Epart->size()/3; - double *Ex = &( ( *Epart )[0*nparts] ); - double *Ey = &( ( *Epart )[1*nparts] ); - double *Ez = &( ( *Epart )[2*nparts] ); - - for( unsigned int ipart=ipart_min ; ipartcharge( ipart ) ); - + Z = (unsigned int)(particles->charge(ipart)); + // If ion already fully ionized then skip - if( Z==atomic_number_ ) { + if (Z == atomic_number_) + { continue; } - + // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) - +pow( *( Ey+ipart-ipart_ref ), 2 ) - +pow( *( Ez+ipart-ipart_ref ), 2 ) ); - if( E<1e-10 ) { + E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + + pow(*(E.z + ipart - ipart_ref), 2)); + if (E.abs < 1e-10) + { continue; } - - // -------------------------------- - // Start of the Monte-Carlo routine - // -------------------------------- - - invE = 1./E; - factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z]*invE; - ran_p = patch->rand_->uniform(); - - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); - - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the nb of ionization events - k_times = 0; - Zp1=Z+1; - - if( Zp1 == atomic_number_ ) { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { - TotalIonizPot += Potential[Z]; - k_times = 1; - } - - } else { - // else : multiple ionization can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. Plasmas) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0]=1.0; - Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. - - //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { - newZ = Zp1+k_times; - delta = gamma_tunnel[newZ]*invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] - * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); - - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel[Z+k_times]; - for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { - TotalIonizPot += Potential[atomic_number_-1]; - k_times++; - } - }//END Multiple ionization routine - - // Compute ionization current - if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *( Ex+ipart ); - Jion.y = factorJion * *( Ey+ipart ); - Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); - } - - // Creation of the new electrons - // (variable weights are used) - // ----------------------------- - if( k_times !=0 ) { - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; - for( unsigned int i=0; iposition( i, ipart ); - } - for( unsigned int i=0; i<3; i++ ) { - new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; - } - new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons.charge( idNew )=-1; - - if( save_ion_charge_ ) { - ion_charge_.push_back( particles->charge( ipart ) ); - } - - // Increase the charge of the particle - particles->charge( ipart ) += k_times; - } - - - } // Loop on particles + E.inv = 1. / E.abs; + + tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, &IonizationTunnelFullPPT::ionizationRateTunnel); + } // Loop on particles } + +double IonizationTunnelFullPPT::ionizationRateTunnel(const int Z, const electricFields E) +{ + double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); +} + diff --git a/src/Ionization/IonizationTunnelFullPPT.h b/src/Ionization/IonizationTunnelFullPPT.h index 23bdfab42..4e227e26b 100755 --- a/src/Ionization/IonizationTunnelFullPPT.h +++ b/src/Ionization/IonizationTunnelFullPPT.h @@ -2,7 +2,6 @@ #define IONIZATIONTUNNELFULLPPT_H #include - #include #include "Ionization.h" @@ -13,22 +12,15 @@ class Particles; //! calculate the particle tunnel ionization class IonizationTunnelFullPPT : public Ionization { - -public: + public: //! Constructor for IonizationTunnelFullPPT: with no input argument - IonizationTunnelFullPPT( Params ¶ms, Species *species ); - - //! apply the Tunnel Ionization model to the species (with ionization current) - void operator()( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0 ) override; - -private: - unsigned int atomic_number_; - std::vector Potential; - std::vector Azimuthal_quantum_number; + IonizationTunnelFullPPT(Params ¶ms, Species *species); + void operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + std::vector *Epart, Patch *patch, Projector *Proj, int ipart_ref = 0) override; + + private: std::vector Magnetic_quantum_number; - - double one_third; - std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; + double ionizationRateTunnel(const int Z, const electricFields E); }; diff --git a/src/Ionization/IonizationTunnelTL.cpp b/src/Ionization/IonizationTunnelTL.cpp index 32cbf638f..d8be76b9f 100755 --- a/src/Ionization/IonizationTunnelTL.cpp +++ b/src/Ionization/IonizationTunnelTL.cpp @@ -1,187 +1,79 @@ #include "IonizationTunnelTL.h" -#include "IonizationTables.h" #include +#include "IonizationTables.h" #include "Particles.h" #include "Species.h" using namespace std; +IonizationTunnelTL::IonizationTunnelTL(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); + ionization_tl_parameter_ = + species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double + // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. + lambda_tunnel.resize(atomic_number_); -IonizationTunnelTL::IonizationTunnelTL( Params ¶ms, Species *species ) : Ionization( params, species ) -{ - DEBUG( "Creating the Tong-Lin Tunnel Ionizaton class" ); - - atomic_number_ = species->atomic_number_; - ionization_tl_parameter_ = species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double - // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - Potential.resize( atomic_number_ ); - Azimuthal_quantum_number.resize( atomic_number_ ); - for( int Zstar=0; Zstar<( int )atomic_number_; Zstar++ ) { - Potential [Zstar] = IonizationTables::ionization_energy( atomic_number_, Zstar ) * eV_to_au; - Azimuthal_quantum_number[Zstar] = IonizationTables::azimuthal_atomic_number( atomic_number_, Zstar ); - } - - for( unsigned int i=0; i *Epart, Patch *patch, Projector *Proj, int ipart_ref ) +void IonizationTunnelTL::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) { + unsigned int Z; + electricFields E; + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); - unsigned int Z, Zp1, newZ, k_times; - double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel_TL( atomic_number_ ), Dnom_tunnel( atomic_number_ ); - LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; - - int nparts = Epart->size()/3; - double *Ex = &( ( *Epart )[0*nparts] ); - double *Ey = &( ( *Epart )[1*nparts] ); - double *Ez = &( ( *Epart )[2*nparts] ); - - for( unsigned int ipart=ipart_min ; ipartsize() / 3; + E.x = &((*Epart)[0 * nparts]); + E.y = &((*Epart)[1 * nparts]); + E.z = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) + { // Current charge state of the ion - Z = ( unsigned int )( particles->charge( ipart ) ); - + Z = (unsigned int)(particles->charge(ipart)); + // If ion already fully ionized then skip - if( Z==atomic_number_ ) { + if (Z == atomic_number_) + { continue; } - + // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) - +pow( *( Ey+ipart-ipart_ref ), 2 ) - +pow( *( Ez+ipart-ipart_ref ), 2 ) ); - if( E<1e-10 ) { + E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + + pow(*(E.z + ipart - ipart_ref), 2)); + if (E.abs < 1e-10) + { continue; } - - // -------------------------------- - // Start of the Monte-Carlo routine - // -------------------------------- - - invE = 1./E; - factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z]*invE; - ran_p = patch->rand_->uniform(); - IonizRate_tunnel_TL[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) - E*lambda_tunnel[Z] ); - - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the nb of ionization events - k_times = 0; - Zp1=Z+1; - - if( Zp1 == atomic_number_ ) { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if( ran_p < 1.0 -exp( -IonizRate_tunnel_TL[Z]*dt ) ) { - TotalIonizPot += Potential[Z]; - k_times = 1; - } - - } else { - // else : multiple ionization can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. Plasmas) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0]=1.0; - Pint_tunnel = exp( -IonizRate_tunnel_TL[Z]*dt ); // cummulative prob. - - //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { - newZ = Zp1+k_times; - delta = gamma_tunnel[newZ]*invE; - IonizRate_tunnel_TL[newZ] = beta_tunnel[newZ] - * exp( - delta*one_third + alpha_tunnel[newZ]*log( delta ) - E*lambda_tunnel[newZ] ); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel_TL[Z+k_times]; - for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { - TotalIonizPot += Potential[atomic_number_-1]; - k_times++; - } - }//END Multiple ionization routine - - // Compute ionization current - if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *( Ex+ipart ); - Jion.y = factorJion * *( Ey+ipart ); - Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); - } - - // Creation of the new electrons - // (variable weights are used) - // ----------------------------- + E.inv = 1. / E.abs; - if( k_times !=0 ) { - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; - for( unsigned int i=0; iposition( i, ipart ); - } - for( unsigned int i=0; i<3; i++ ) { - new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; - } - new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons.charge( idNew )=-1; - - if( save_ion_charge_ ) { - ion_charge_.push_back( particles->charge( ipart ) ); - } - - // Increase the charge of the particle - particles->charge( ipart ) += k_times; - } - - } // Loop on particles + tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, &IonizationTunnelTL::ionizationRateTunnelTL); + } // Loop on particles } +double IonizationTunnelTL::ionizationRateTunnelTL(int Z, double delta, double E) +{ + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); +} diff --git a/src/Ionization/IonizationTunnelTL.h b/src/Ionization/IonizationTunnelTL.h index 2437fe955..c9553d087 100755 --- a/src/Ionization/IonizationTunnelTL.h +++ b/src/Ionization/IonizationTunnelTL.h @@ -2,7 +2,6 @@ #define IONIZATIONTUNNELTL_H #include - #include #include "Ionization.h" @@ -13,23 +12,18 @@ class Particles; //! calculate the particle tunnel ionization with Tong-Lin model class IonizationTunnelTL : public Ionization { - -public: + public: //! Constructor for IonizationTunnelTL: with no input argument - IonizationTunnelTL( Params ¶ms, Species *species ); - + IonizationTunnelTL(Params ¶ms, Species *species); + //! apply the Tunnel Ionization model to the species (with ionization current) - void operator()( Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0 ) override; - -private: - unsigned int atomic_number_; - std::vector Potential; - std::vector Azimuthal_quantum_number; - - double one_third; + void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, + int ipart_ref = 0) override; + + private: + double ionizationRateTunnelTL(int Z, double delta, double E); double ionization_tl_parameter_; - std::vector alpha_tunnel, beta_tunnel, gamma_tunnel, lambda_tunnel; + std::vector lambda_tunnel; }; - #endif From 4e7909d8b8921b7368037bf3128cdba9a50919ee Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:19:27 +0200 Subject: [PATCH 06/17] Rewrite IonizationTunnel and derivatives to use templates Rewrite IonizationTunnel and the new models introduced by Mironov to be more compact and use templates. --- src/Ionization/Ionization.cpp | 116 +---- src/Ionization/Ionization.h | 14 - src/Ionization/IonizationFactory.h | 107 ++-- src/Ionization/IonizationTunnel.cpp | 221 -------- src/Ionization/IonizationTunnel.h | 570 ++++++++++++++++++++- src/Ionization/IonizationTunnelBSI.cpp | 128 ----- src/Ionization/IonizationTunnelBSI.h | 27 - src/Ionization/IonizationTunnelFullPPT.cpp | 82 --- src/Ionization/IonizationTunnelFullPPT.h | 27 - src/Ionization/IonizationTunnelTL.cpp | 79 --- src/Ionization/IonizationTunnelTL.h | 29 -- 11 files changed, 592 insertions(+), 808 deletions(-) mode change 100755 => 100644 src/Ionization/IonizationFactory.h delete mode 100644 src/Ionization/IonizationTunnel.cpp delete mode 100755 src/Ionization/IonizationTunnelBSI.cpp delete mode 100755 src/Ionization/IonizationTunnelBSI.h delete mode 100755 src/Ionization/IonizationTunnelFullPPT.cpp delete mode 100755 src/Ionization/IonizationTunnelFullPPT.h delete mode 100755 src/Ionization/IonizationTunnelTL.cpp delete mode 100755 src/Ionization/IonizationTunnelTL.h diff --git a/src/Ionization/Ionization.cpp b/src/Ionization/Ionization.cpp index afb652a97..bf52b7b79 100755 --- a/src/Ionization/Ionization.cpp +++ b/src/Ionization/Ionization.cpp @@ -32,6 +32,7 @@ Ionization::Ionization(Params ¶ms, Species *species) beta_tunnel.resize(atomic_number_); gamma_tunnel.resize(atomic_number_); + #ifdef _OMPTASKS new_electrons_per_bin = new Particles[species->Nbins]; ion_charge_per_bin_.resize(species->Nbins); @@ -86,118 +87,3 @@ void Ionization::joinNewElectrons(unsigned int Nbins) } } -void Ionization::tunnelMonteCarloRoutine(Particles *particles, unsigned int ipart, vector *Epart, - Patch *patch, Projector *Proj, const unsigned int Z, - const electricFields E, vector &IonizRate_tunnel, - vector &Dnom_tunnel, - function ionizationRate) -{ - double TotalIonizPot, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - LocalFields Jion; - const double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; - unsigned int newZ, Zp1, k_times; - factorJion = factorJion_0 * E.inv * E.inv; - ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = ionizationRate(Z, E); - - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the nb of ionization events - k_times = 0; - Zp1 = Z + 1; - - if (Zp1 == atomic_number_) - { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) - { - TotalIonizPot += Potential[Z]; - k_times = 1; - } - } - else - { - // else : multiple ionization can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. - // Plasmas) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0] = 1.0; - Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. - - // multiple ionization loop while Pint_tunnel < ran_p and still partial - // ionization - while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) - { - newZ = Zp1 + k_times; - IonizRate_tunnel[newZ] = ionizationRate(newZ, E); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel[Z + k_times]; - for (unsigned int i = 0; i < k_times + 1; i++) - { - Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z + i]); - D_sum += Dnom_tunnel[i]; - P_sum += exp(-IonizRate_tunnel[Z + i] * dt) * Dnom_tunnel[i]; - } - Dnom_tunnel[k_times + 1] -= D_sum; - P_sum = P_sum + Dnom_tunnel[k_times + 1] * exp(-IonizRate_tunnel[newZ] * dt); - Pint_tunnel = Pint_tunnel + P_sum * Mult; - - TotalIonizPot += Potential[Z + k_times]; - k_times++; - } // END while - - // final ionization (of last electron) - if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) - { - TotalIonizPot += Potential[atomic_number_ - 1]; - k_times++; - } - } // END Multiple ionization routine - - // Compute ionization current - if (patch->EMfields->Jx_ != NULL) - { // For the moment ionization current is - // not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *(E.x + ipart); - Jion.y = factorJion * *(E.y + ipart); - Jion.z = factorJion * *(E.z + ipart); - - Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion); - } - - // Creation of the new electrons - // (variable weights are used) - // ----------------------------- - - if (k_times != 0) - { - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; - for (unsigned int i = 0; i < new_electrons.dimension(); i++) - { - new_electrons.position(i, idNew) = particles->position(i, ipart); - } - for (unsigned int i = 0; i < 3; i++) - { - new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; - } - new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); - new_electrons.charge(idNew) = -1; - - if (save_ion_charge_) - { - ion_charge_.push_back(particles->charge(ipart)); - } - - // Increase the charge of the particle - particles->charge(ipart) += k_times; - } -} - diff --git a/src/Ionization/Ionization.h b/src/Ionization/Ionization.h index 54fd3500f..6ce28719c 100755 --- a/src/Ionization/Ionization.h +++ b/src/Ionization/Ionization.h @@ -13,15 +13,6 @@ using namespace std; -struct electricFields -{ - double *x; - double *y; - double *z; - double inv; // inverse - double abs; // absolute value in atomic units -}; - //! Class Ionization: generic class allowing to define Ionization physics class Ionization { @@ -52,11 +43,6 @@ class Ionization std::vector > ion_charge_per_bin_; protected: - inline void tunnelMonteCarloRoutine(Particles *particles, unsigned int ipart, vector *Epart, Patch *patch, - Projector *Proj, const unsigned int Z, const electricFields E, - vector &IonizRate_tunnel, vector &Dnom_tunnel, - function ionizationRate); - double eV_to_au; double au_to_mec2; double EC_to_au; diff --git a/src/Ionization/IonizationFactory.h b/src/Ionization/IonizationFactory.h old mode 100755 new mode 100644 index 517f42799..0fe22fd6b --- a/src/Ionization/IonizationFactory.h +++ b/src/Ionization/IonizationFactory.h @@ -2,101 +2,52 @@ #define IonizationFactory_H #include "Ionization.h" -#include "IonizationTunnel.h" #include "IonizationFromRate.h" #include "IonizationTunnelEnvelopeAveraged.h" -#include "IonizationTunnelBSI.h" -#include "IonizationTunnelTL.h" -#include "IonizationTunnelFullPPT.h" - #include "Params.h" - -#include "Tools.h" - #include "Species.h" +#include "IonizationTunnel.h" +#include "Tools.h" //! this class create and associate the right ionization model to species class IonizationFactory { -public: - static Ionization *create( Params ¶ms, Species *species ) + public: + static Ionization *create(Params ¶ms, Species *species) { Ionization *Ionize = NULL; - std::string model=species->ionization_model_; - - if( model == "tunnel" ) { - - if( species->max_charge_ > ( int )species->atomic_number_ ) { - ERROR( "Charge > atomic_number for species " << species->name_ ); - } - - if( params.Laser_Envelope_model ) { - ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); - } - - Ionize = new IonizationTunnel( params, species ); - - } else if( model == "tunnel_envelope_averaged" ) { - if( species->max_charge_ > ( int )species->atomic_number_ ) { - ERROR( "Charge > atomic_number for species " << species->name_ ); - } - if( species->particles->is_test ) { - ERROR( "Cannot ionize test species " << species->name_ ); - } - - Ionize = new IonizationTunnelEnvelopeAveraged( params, species ); - - if ( !params.Laser_Envelope_model ) { - ERROR( "The ionization model tunnel_envelope_averaged needs a laser envelope"); - } - - } else if( model == "from_rate" ) { - - if( species->max_charge_ > ( int )species->maximum_charge_state_ ) { - ERROR( "For species '" << species->name_ << ": charge > maximum_charge_state" ); - } - - Ionize = new IonizationFromRate( params, species ); - - } else if(model == "tunnel_BSI") { // added by I. Ouatu. Put keyword "tunnel_BSI" for the - // Tong-Lin ionization model in the species description in your namelist. - - if (species->max_charge_ > (int) species->atomic_number_) { // same as for simple Tunnel Ionization. - ERROR( "Charge > atomic_number for species " << species->name_); - } - if( (params.Laser_Envelope_model) ) { // same as for simple Tunnel Ionziation - ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); - } - - Ionize = new IonizationTunnelBSI(params, species); - - } else if(model == "tunnel_TL") { // added by Arseny Mironov. Put keyword "tunnel_TL" for the Tong-Lin ionization model - // in the species description in your namelist. - if (species->max_charge_ > (int) species->atomic_number_) { - ERROR( "Charge > atomic_number for species " << species->name_); - } - if( (params.Laser_Envelope_model) ) { // same as for simple Tunnel Ionziation - ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); - } - Ionize = new IonizationTunnelTL(params, species); + std::string model = species->ionization_model_; - } else if(model == "tunnel_full_PPT") { // added by Arseny Mironov. Put keyword "tunnel_full_PPT" for the tunneling ionization model - // with account for the magnetic quantum number in the species description in your namelist. - - if( species->max_charge_ > ( int )species->atomic_number_ ) { - ERROR( "Charge > atomic_number for species " << species->name_ ); - } + if (species->max_charge_ > (int)species->atomic_number_) { + ERROR("Charge > atomic_number for species " << species->name_); + } + if (species->particles->is_test) { + ERROR("Cannot ionize test species " << species->name_); + } - if( params.Laser_Envelope_model ) { - ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); + if (model == "tunnel_envelope_averaged") { + if (!params.Laser_Envelope_model) { + ERROR("The ionization model tunnel_envelope_averaged needs a laser envelope"); } + Ionize = new IonizationTunnelEnvelopeAveraged(params, species); + } else if (params.Laser_Envelope_model) { + ERROR("The ionization model for species interacting with envelope is tunnel_envelope_averaged"); + } - Ionize = new IonizationTunnelFullPPT( params, species ); + if (model == "from_rate") { + Ionize = new IonizationFromRate(params, species); + } else if (model == "tunnel") { + Ionize = new IonizationTunnel<0>(params, species); // Tunnel, the original included in Smilei + } else if (model == "tunnel_full_PPT") { + Ionize = new IonizationTunnel<1>(params, species); // FullPPT + } else if (model == "tunnel_TL") { + Ionize = new IonizationTunnel<2>(params, species); // Tong&Ling + } else if (model == "tunnel_BSI") { + Ionize = new IonizationTunnel<3>(params, species); // BSI } - + return Ionize; } - }; #endif diff --git a/src/Ionization/IonizationTunnel.cpp b/src/Ionization/IonizationTunnel.cpp deleted file mode 100644 index 90d27bf9d..000000000 --- a/src/Ionization/IonizationTunnel.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "IonizationTunnel.h" - -#include -#include - -#include "IonizationTables.h" -#include "Particles.h" -#include "Species.h" - -using namespace std; - -IonizationTunnel::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - - DEBUG("Finished Creating the Tunnel Ionizaton class"); -} - -void IonizationTunnel::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) -{ - unsigned int Z; - electricFields E; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); - - int nparts = Epart->size() / 3; - E.x = &((*Epart)[0 * nparts]); - E.y = &((*Epart)[1 * nparts]); - E.z = &((*Epart)[2 * nparts]); - - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - // Current charge state of the ion - Z = (unsigned int)(particles->charge(ipart)); - - // If ion already fully ionized then skip - if (Z == atomic_number_) - { - continue; - } - - // Absolute value of the electric field normalized in atomic units - E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + - pow(*(E.z + ipart - ipart_ref), 2)); - if (E.abs < 1e-10) - { - continue; - } - E.inv = 1. / E.abs; - - tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, &IonizationTunnel::ionizationRateTunnel); - } // Loop on particles -} - -double IonizationTunnel::ionizationRateTunnel(const int Z, const electricFields E) -{ - double delta = gamma_tunnel[Z] * E.inv; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); -} - -void IonizationTunnel::ionizationTunnelWithTasks(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ibin, - int bin_shift, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref) -{ - unsigned int Z, Zp1, newZ, k_times; - double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); - LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; - - int nparts = Epart->size() / 3; - double *Ex = &((*Epart)[0 * nparts]); - double *Ey = &((*Epart)[1 * nparts]); - double *Ez = &((*Epart)[2 * nparts]); - - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - // Current charge state of the ion - Z = (unsigned int)(particles->charge(ipart)); - - // If ion already fully ionized then skip - if (Z == atomic_number_) - { - continue; - } - - // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt(pow(*(Ex + ipart - ipart_ref), 2) + pow(*(Ey + ipart - ipart_ref), 2) + - pow(*(Ez + ipart - ipart_ref), 2)); - if (E < 1e-10) - { - continue; - } - - // -------------------------------- - // Start of the Monte-Carlo routine - // -------------------------------- - - invE = 1. / E; - factorJion = factorJion_0 * invE * invE; - delta = gamma_tunnel[Z] * invE; - ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); - - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the nb of ionization events - k_times = 0; - Zp1 = Z + 1; - - if (Zp1 == atomic_number_) - { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) - { - TotalIonizPot += Potential[Z]; - k_times = 1; - } - } - else - { - // else : multiple ionization can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. Plasmas) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0] = 1.0; - Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. - - // multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) - { - newZ = Zp1 + k_times; - delta = gamma_tunnel[newZ] * invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] * exp(-delta * one_third + alpha_tunnel[newZ] * log(delta)); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel[Z + k_times]; - for (unsigned int i = 0; i < k_times + 1; i++) - { - Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z + i]); - D_sum += Dnom_tunnel[i]; - P_sum += exp(-IonizRate_tunnel[Z + i] * dt) * Dnom_tunnel[i]; - } - Dnom_tunnel[k_times + 1] = -D_sum; // bug fix - P_sum = P_sum + Dnom_tunnel[k_times + 1] * exp(-IonizRate_tunnel[newZ] * dt); - Pint_tunnel = Pint_tunnel + P_sum * Mult; - - TotalIonizPot += Potential[Z + k_times]; - k_times++; - } // END while - - // final ionization (of last electron) - if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) - { - TotalIonizPot += Potential[atomic_number_ - 1]; - k_times++; - } - } // END Multiple ionization routine - - // Compute ionization current - if (b_Jx != NULL) - { // For the moment ionization current is not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *(Ex + ipart); - Jion.y = factorJion * *(Ey + ipart); - Jion.z = factorJion * *(Ez + ipart); - - Proj->ionizationCurrentsForTasks(b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift); - } - - // Creation of the new electrons - // (variable weights are used) - // ----------------------------- - if (k_times != 0) - { - new_electrons_per_bin[ibin].createParticle(); - int idNew = new_electrons_per_bin[ibin].size() - - 1; // cout<<"ibin "<position(i, ipart); - } - for (unsigned int i = 0; i < 3; i++) - { - new_electrons_per_bin[ibin].momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; - } - new_electrons_per_bin[ibin].weight(idNew) = double(k_times) * particles->weight(ipart); - new_electrons_per_bin[ibin].charge(idNew) = -1; - - if (save_ion_charge_) - { - ion_charge_per_bin_[ibin].push_back(particles->charge(ipart)); - } - - // // Increase the charge of the particle - particles->charge(ipart) += k_times; - } - - } // Loop on particles -} diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index d2e9570fb..198a8c872 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -1,5 +1,5 @@ -#ifndef IONIZATIONTUNNEL_H -#define IONIZATIONTUNNEL_H +#ifndef TEMPLATE_H +#define TEMPLATE_H #include #include @@ -8,24 +8,578 @@ #include "Ionization.h" #include "Tools.h" +// because defining in header +#include "IonizationTables.h" +#include "Particles.h" +#include "Species.h" + class Particles; -struct electricFields; -//! calculate the particle tunnel ionization +struct electricFields +{ + double *x; + double *y; + double *z; + double inv; // inverse + double abs; // absolute value in atomic units +}; + +template class IonizationTunnel : public Ionization { public: - IonizationTunnel(Params ¶ms, Species *species); + inline IonizationTunnel(Params ¶ms, Species *species); - void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, + inline void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0) override; //! method for tunnel ionization with tasks - void ionizationTunnelWithTasks(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, + inline void ionizationTunnelWithTasks(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; private: - double ionizationRateTunnel(const int Z, const electricFields E); + template + inline void monteCarloRoutine(Particles *, unsigned int, Patch *, Projector *, const unsigned int, + const electricFields, vector &, vector &); + template + inline double ionizationRate(const int Z, const electricFields E); + + // To be conditionally prepared + // FullPPT + std::vector Magnetic_quantum_number; + + // Tong&Ling + double ionization_tl_parameter_; + std::vector lambda_tunnel; + + // BSI + const double au_to_eV = 27.2116; + const double IH = 13.598434005136; }; +template +void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ibin, int bin_shift, + double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref ) +{ + + unsigned int Z, Zp1, newZ, k_times; + double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; + vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + LocalFields Jion; + double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; + + int nparts = Epart->size()/3; + double *Ex = &( ( *Epart )[0*nparts] ); + double *Ey = &( ( *Epart )[1*nparts] ); + double *Ez = &( ( *Epart )[2*nparts] ); + + for( unsigned int ipart=ipart_min ; ipartcharge( ipart ) ); + + // If ion already fully ionized then skip + if( Z==atomic_number_ ) { + continue; + } + + // Absolute value of the electric field normalized in atomic units + E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) + +pow( *( Ey+ipart-ipart_ref ), 2 ) + +pow( *( Ez+ipart-ipart_ref ), 2 ) ); + if( E<1e-10 ) { + continue; + } + + // -------------------------------- + // Start of the Monte-Carlo routine + // -------------------------------- + + invE = 1./E; + factorJion = factorJion_0 * invE*invE; + delta = gamma_tunnel[Z]*invE; + ran_p = patch->rand_->uniform(); + IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); + + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the nb of ionization events + k_times = 0; + Zp1=Z+1; + + if( Zp1 == atomic_number_ ) { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { + TotalIonizPot += Potential[Z]; + k_times = 1; + } + + } else { + // else : multiple ionization can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. Plasmas) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0]=1.0; + Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. + + //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { + newZ = Zp1+k_times; + delta = gamma_tunnel[newZ]*invE; + IonizRate_tunnel[newZ] = beta_tunnel[newZ] + * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel[Z+k_times]; + for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } + }//END Multiple ionization routine + + // Compute ionization current + if (b_Jx != NULL){ // For the moment ionization current is not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *( Ex+ipart ); + Jion.y = factorJion * *( Ey+ipart ); + Jion.z = factorJion * *( Ez+ipart ); + + Proj->ionizationCurrentsForTasks( b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift ); + } + + // Creation of the new electrons + // (variable weights are used) + // ----------------------------- + if( k_times !=0 ) { + new_electrons_per_bin[ibin].createParticle(); + int idNew = new_electrons_per_bin[ibin].size() - 1;//cout<<"ibin "<position( i, ipart ); + } + for( unsigned int i=0; i<3; i++ ) { + new_electrons_per_bin[ibin].momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + } + new_electrons_per_bin[ibin].weight( idNew )=double( k_times )*particles->weight( ipart ); + new_electrons_per_bin[ibin].charge( idNew )=-1; + + if( save_ion_charge_ ) { + ion_charge_per_bin_[ibin].push_back( particles->charge( ipart ) ); + } + + // // Increase the charge of the particle + particles->charge( ipart ) += k_times; + } + + } // Loop on particles +} + +template +template +inline void IonizationTunnel::monteCarloRoutine(Particles *particles, unsigned int ipart, Patch *patch, Projector *Proj, + const unsigned int Z, const electricFields E, + vector &IonizRate_tunnel, vector &Dnom_tunnel) +{ + double TotalIonizPot, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; + LocalFields Jion; + const double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; + unsigned int newZ, Zp1, k_times; + factorJion = factorJion_0 * E.inv * E.inv; + ran_p = patch->rand_->uniform(); + IonizRate_tunnel[Z] = ionizationRate(Z, E); + + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the nb of ionization events + k_times = 0; + Zp1 = Z + 1; + + if (Zp1 == atomic_number_) + { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) + { + TotalIonizPot += Potential[Z]; + k_times = 1; + } + } + else + { + // else : multiple ionization can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. + // Plasmas) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0] = 1.0; + Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. + + // multiple ionization loop while Pint_tunnel < ran_p and still partial + // ionization + while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) + { + newZ = Zp1 + k_times; + IonizRate_tunnel[newZ] = ionizationRate(newZ, E); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel[Z + k_times]; + for (unsigned int i = 0; i < k_times + 1; i++) + { + Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z + i]); + D_sum += Dnom_tunnel[i]; + P_sum += exp(-IonizRate_tunnel[Z + i] * dt) * Dnom_tunnel[i]; + } + Dnom_tunnel[k_times + 1] -= D_sum; + P_sum = P_sum + Dnom_tunnel[k_times + 1] * exp(-IonizRate_tunnel[newZ] * dt); + Pint_tunnel = Pint_tunnel + P_sum * Mult; + + TotalIonizPot += Potential[Z + k_times]; + k_times++; + } // END while + + // final ionization (of last electron) + if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) + { + TotalIonizPot += Potential[atomic_number_ - 1]; + k_times++; + } + } // END Multiple ionization routine + + // Compute ionization current + if (patch->EMfields->Jx_ != NULL) + { // For the moment ionization current is + // not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *(E.x + ipart); + Jion.y = factorJion * *(E.y + ipart); + Jion.z = factorJion * *(E.z + ipart); + + Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion); + } + + // Creation of the new electrons + // (variable weights are used) + // ----------------------------- + + if (k_times != 0) + { + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; + for (unsigned int i = 0; i < new_electrons.dimension(); i++) + { + new_electrons.position(i, idNew) = particles->position(i, ipart); + } + for (unsigned int i = 0; i < 3; i++) + { + new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; + } + new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); + new_electrons.charge(idNew) = -1; + + if (save_ion_charge_) + { + ion_charge_.push_back(particles->charge(ipart)); + } + + // Increase the charge of the particle + particles->charge(ipart) += k_times; + } +} + +template +inline void IonizationTunnel::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) + +{ + unsigned int Z; + electricFields E; + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); + + int nparts = Epart->size() / 3; + E.x = &((*Epart)[0 * nparts]); + E.y = &((*Epart)[1 * nparts]); + E.z = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) + { + // Current charge state of the ion + Z = (unsigned int)(particles->charge(ipart)); + + // If ion already fully ionized then skip + if (Z == atomic_number_) + { + continue; + } + + // Absolute value of the electric field normalized in atomic units + E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + + pow(*(E.z + ipart - ipart_ref), 2)); + if (E.abs < 1e-10) + { + continue; + } + E.inv = 1. / E.abs; + + monteCarloRoutine<0>(particles, ipart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel); + } // Loop on particles +} + +template +template +inline double IonizationTunnel::ionizationRate(const int Z, const electricFields E) +{ + double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); +} + +// IonizationTunnel : 0 +template <> +inline IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (unsigned int Z = 0; Z < atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + + DEBUG("Finished Creating the Tunnel Ionizaton class"); +} + +template <> +template <> +inline double IonizationTunnel<0>::ionizationRate<0>(const int Z, const electricFields E) +{ + double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); +} + +// IonizationTunnelFullPPT: 1 + +template <> +inline IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + Magnetic_quantum_number.resize(atomic_number_); + + for (unsigned int Z = 0; Z < atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); + + DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] + << " M.q.num: " << Magnetic_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + double abs_m = abs(Magnetic_quantum_number[Z]); + alpha_tunnel[Z] = cst - 1.0 - abs_m; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / + (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + + DEBUG("Finished Creating the Tunnel Ionizaton class"); +} + +template <> +template <> +inline double IonizationTunnel<1>::ionizationRate<0>(const int Z, const electricFields E) +{ + double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); +} + +// Tong&Ling: 2 + +template <> +inline IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); + + ionization_tl_parameter_ = + species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double + // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. + lambda_tunnel.resize(atomic_number_); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + lambda_tunnel[Z] = ionization_tl_parameter_ * pow(cst, 2) / gamma_tunnel[Z]; + } + + DEBUG("Finished Creating the Tong-Lin Tunnel Ionizaton class"); +} + +template <> +template <> +inline double IonizationTunnel<2>::ionizationRate<0>(const int Z, const electricFields E) +{ + const double delta = gamma_tunnel[Z] * E.inv; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E.abs * lambda_tunnel[Z]); +} + +// BSI: 3 + +template <> +inline IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel BSI Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + DEBUG("Finished Creating the BSI Tunnel Ionizaton class"); +} + +// BSI Linear +template <> +template <> +inline double IonizationTunnel<3>::ionizationRate<1>(const int Z, const electricFields E) +{ + const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (0.8 * E.abs * pow(ratio_of_IPs, 0.5)); +} + +// BSI Linear +template <> +template <> +inline double IonizationTunnel<3>::ionizationRate<2>(const int Z, const electricFields E) +{ + const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (2.4 * (pow(E.abs, 2)) * pow(ratio_of_IPs, 2)); +} + +template <> +inline void IonizationTunnel<3>::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) +{ + unsigned int Z; + electricFields E; + vector IonizRate_tunnel(atomic_number_), + Dnom_tunnel(atomic_number_); // For MonteCarlo procedure using the tunnel + // ioniz. rate. + vector IonizRate_BSI_linear(atomic_number_), + Dnom_BSI_linear(atomic_number_); // For MonteCarlo procedure using the BSI + // ioniz. rate. + vector IonizRate_BSI_quadratic(atomic_number_), Dnom_BSI_quadratic(atomic_number_); + + int nparts = Epart->size() / 3; // Over 3 because there are 3 Dims. Epart is like [part1_Ex, part2_Ex, + // ... partnparts_Ex, part1_Ey, part2_Ey,...partnparts_Ey, part1_Ez, + // part2_Ez, partnparts_Ez]} + E.x = &((*Epart)[0 * nparts]); + E.y = &((*Epart)[1 * nparts]); + E.z = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) + { + Z = (unsigned int)(particles->charge(ipart)); // current charge state of the particle number ipart of species + // called ''species'' with atomic no = atomic_number_ + + // If ion already fully ionized then skip and go to next particle + if (Z == atomic_number_) + { + continue; + } // atom fully ionized already, no electrons remained to be stripped away. + + // Absolute value of the electric field in AtomicUnits (i.e. normalized to + // (in units of) E_atomic = 5.1422*10^11 V/m) + E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), + 2) // (Ex+ipart-ipart_ref) points to the location in the + // container Epart at which E-field_x for particle ipart + // sits. + + pow(*(E.y + ipart - ipart_ref), + 2) // Similarly for y. Dereferencing it via *() means we + // access and use the value sitting at that location. + + pow(*(E.z + ipart - ipart_ref), + 2)); // EC_to_au transforms from SMILEI-normalized units to + // AtomicUnits. + if (E.abs < 1e-10) + { // E is in Atomic Units + continue; + } + + // Used to be call to continuity_tool. After some shortening, the call was manually inlined + double BSI_rate_quadratic = ionizationRate<2>(Z, E); + double BSI_rate_linear = ionizationRate<1>(Z, E); + double Tunnel_rate = ionizationRate<0>(Z, E); + + if (BSI_rate_quadratic >= BSI_rate_linear) + { + monteCarloRoutine<2>(particles, ipart, patch, Proj, Z, E, IonizRate_BSI_quadratic, Dnom_BSI_quadratic); + } + else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) + { + monteCarloRoutine<1>(particles, ipart, patch, Proj, Z, E, IonizRate_BSI_linear, Dnom_BSI_linear); + } + else + { + monteCarloRoutine<0>(particles, ipart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel); + } + } // END loop on particles + +} // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. + #endif diff --git a/src/Ionization/IonizationTunnelBSI.cpp b/src/Ionization/IonizationTunnelBSI.cpp deleted file mode 100755 index 5eff2565e..000000000 --- a/src/Ionization/IonizationTunnelBSI.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "IonizationTunnelBSI.h" - -#include -#include - -#include "IonizationTables.h" -#include "Particles.h" -#include "Species.h" -using namespace std; - -IonizationTunnelBSI::IonizationTunnelBSI(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel BSI Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - DEBUG("Finished Creating the BSI Tunnel Ionizaton class"); -} - -void IonizationTunnelBSI::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) -{ - unsigned int Z; - electricFields E; - vector IonizRate_tunnel(atomic_number_), - Dnom_tunnel(atomic_number_); // For MonteCarlo procedure using the tunnel - // ioniz. rate. - vector IonizRate_BSI_linear(atomic_number_), - Dnom_BSI_linear(atomic_number_); // For MonteCarlo procedure using the BSI - // ioniz. rate. - vector IonizRate_BSI_quadratic(atomic_number_), Dnom_BSI_quadratic(atomic_number_); - - double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; // Will be used to calc. ionization current. - - int nparts = Epart->size() / 3; // Over 3 because there are 3 Dims. Epart is like [part1_Ex, part2_Ex, - // ... partnparts_Ex, part1_Ey, part2_Ey,...partnparts_Ey, part1_Ez, - // part2_Ez, partnparts_Ez]} - E.x = &((*Epart)[0 * nparts]); - E.y = &((*Epart)[1 * nparts]); - E.z = &((*Epart)[2 * nparts]); - - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - Z = (unsigned int)(particles->charge(ipart)); // current charge state of the particle number ipart of species - // called ''species'' with atomic no = atomic_number_ - double E_cr = pow(Potential[Z], 2) / (4 * (Z + 1)); // Formula from DonnaStrickland, 1991, page5, eq(5) [Laser - // ionization of noble gases by Coulomb-barrier suppression] - // There's absolutely no usage of this E_cr in the code. - - // If ion already fully ionized then skip and go to next particle - if (Z == atomic_number_) - { - continue; - } // atom fully ionized already, no electrons remained to be stripped away. - - // Absolute value of the electric field in AtomicUnits (i.e. normalized to - // (in units of) E_atomic = 5.1422*10^11 V/m) - E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), - 2) // (Ex+ipart-ipart_ref) points to the location in the - // container Epart at which E-field_x for particle ipart - // sits. - + pow(*(E.y + ipart - ipart_ref), - 2) // Similarly for y. Dereferencing it via *() means we - // access and use the value sitting at that location. - + pow(*(E.z + ipart - ipart_ref), - 2)); // EC_to_au transforms from SMILEI-normalized units to - // AtomicUnits. - if (E.abs < 1e-10) - { // E is in Atomic Units - continue; - } - - // Used to be call to continuity_tool. After some shortening, the call was manually inlined - double BSI_rate_quadratic = ionizationRateBSIQuadratic(Z, E); - double BSI_rate_linear = ionizationRateBSILinear(Z, E); - double Tunnel_rate = ionizationRateTunnel(Z, E); - - if (BSI_rate_quadratic >= BSI_rate_linear) - { - tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_BSI_quadratic, - Dnom_BSI_quadratic, &IonizationTunnelBSI::ionizationRateBSIQuadratic); - } - else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) - { - tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_BSI_linear, Dnom_BSI_linear, - &IonizationTunnelBSI::ionizationRateBSILinear); - } - else - { - tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, - &IonizationTunnelBSI::ionizationRateTunnel); - } - } // END loop on particles - -} // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. - -double IonizationTunnelBSI::ionizationRateBSIQuadratic(const int Z, const electricFields E) // Z is charge state -{ - double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (2.4 * (pow(E.abs, 2)) * pow(ratio_of_IPs, 2)); -} - -double IonizationTunnelBSI::ionizationRateBSILinear(const int Z, const electricFields E) // Z is charge state -{ - double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (0.8 * E.abs * pow(ratio_of_IPs, 0.5)); -} - -double IonizationTunnelBSI::ionizationRateTunnel(const int Z, const electricFields E) -{ - double delta = gamma_tunnel[Z] * E.inv; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); -} - diff --git a/src/Ionization/IonizationTunnelBSI.h b/src/Ionization/IonizationTunnelBSI.h deleted file mode 100755 index 1fe2cc9f5..000000000 --- a/src/Ionization/IonizationTunnelBSI.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef IONIZATIONTUNNELBSI_H -#define IONIZATIONTUNNELBSI_H - -#include -#include - -#include "Ionization.h" -#include "Tools.h" - -class Particles; - -class IonizationTunnelBSI : public Ionization -{ - public: - IonizationTunnelBSI(Params ¶ms, Species *species); - void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, int ipart_ref = 0) override; - - private: - double ionizationRateBSIQuadratic(int Z, electricFields E); - double ionizationRateBSILinear(int Z, electricFields E); - double ionizationRateTunnel(const int Z, const electricFields E); - - double au_to_eV = 27.2116; - double IH = 13.598434005136; -}; - -#endif diff --git a/src/Ionization/IonizationTunnelFullPPT.cpp b/src/Ionization/IonizationTunnelFullPPT.cpp deleted file mode 100755 index d3e0d6df5..000000000 --- a/src/Ionization/IonizationTunnelFullPPT.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "IonizationTunnelFullPPT.h" - -#include - -#include "IonizationTables.h" -#include "Particles.h" -#include "Species.h" - -using namespace std; - -IonizationTunnelFullPPT::IonizationTunnelFullPPT(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - Magnetic_quantum_number.resize(atomic_number_); - - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); - - DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] - << " M.q.num: " << Magnetic_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - double abs_m = abs(Magnetic_quantum_number[Z]); - alpha_tunnel[Z] = cst - 1.0 - abs_m; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / - (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - - DEBUG("Finished Creating the Tunnel Ionizaton class"); -} - -void IonizationTunnelFullPPT::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) -{ - unsigned int Z; - electricFields E; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); - - int nparts = Epart->size() / 3; - E.x = &((*Epart)[0 * nparts]); - E.y = &((*Epart)[1 * nparts]); - E.z = &((*Epart)[2 * nparts]); - - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - // Current charge state of the ion - Z = (unsigned int)(particles->charge(ipart)); - - // If ion already fully ionized then skip - if (Z == atomic_number_) - { - continue; - } - - // Absolute value of the electric field normalized in atomic units - E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + - pow(*(E.z + ipart - ipart_ref), 2)); - if (E.abs < 1e-10) - { - continue; - } - E.inv = 1. / E.abs; - - tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, &IonizationTunnelFullPPT::ionizationRateTunnel); - } // Loop on particles -} - -double IonizationTunnelFullPPT::ionizationRateTunnel(const int Z, const electricFields E) -{ - double delta = gamma_tunnel[Z] * E.inv; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); -} - diff --git a/src/Ionization/IonizationTunnelFullPPT.h b/src/Ionization/IonizationTunnelFullPPT.h deleted file mode 100755 index 4e227e26b..000000000 --- a/src/Ionization/IonizationTunnelFullPPT.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef IONIZATIONTUNNELFULLPPT_H -#define IONIZATIONTUNNELFULLPPT_H - -#include -#include - -#include "Ionization.h" -#include "Tools.h" - -class Particles; - -//! calculate the particle tunnel ionization -class IonizationTunnelFullPPT : public Ionization -{ - public: - //! Constructor for IonizationTunnelFullPPT: with no input argument - IonizationTunnelFullPPT(Params ¶ms, Species *species); - void operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - std::vector *Epart, Patch *patch, Projector *Proj, int ipart_ref = 0) override; - - private: - std::vector Magnetic_quantum_number; - double ionizationRateTunnel(const int Z, const electricFields E); -}; - - -#endif diff --git a/src/Ionization/IonizationTunnelTL.cpp b/src/Ionization/IonizationTunnelTL.cpp deleted file mode 100755 index d8be76b9f..000000000 --- a/src/Ionization/IonizationTunnelTL.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "IonizationTunnelTL.h" - -#include - -#include "IonizationTables.h" -#include "Particles.h" -#include "Species.h" - -using namespace std; - -IonizationTunnelTL::IonizationTunnelTL(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); - - ionization_tl_parameter_ = - species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double - // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. - lambda_tunnel.resize(atomic_number_); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { - DEBUG("Z : " << Z); - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - lambda_tunnel[Z] = ionization_tl_parameter_ * pow(cst, 2) / gamma_tunnel[Z]; - } - - DEBUG("Finished Creating the Tong-Lin Tunnel Ionizaton class"); -} - -void IonizationTunnelTL::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) -{ - unsigned int Z; - electricFields E; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); - - int nparts = Epart->size() / 3; - E.x = &((*Epart)[0 * nparts]); - E.y = &((*Epart)[1 * nparts]); - E.z = &((*Epart)[2 * nparts]); - - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - // Current charge state of the ion - Z = (unsigned int)(particles->charge(ipart)); - - // If ion already fully ionized then skip - if (Z == atomic_number_) - { - continue; - } - - // Absolute value of the electric field normalized in atomic units - E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + - pow(*(E.z + ipart - ipart_ref), 2)); - if (E.abs < 1e-10) - { - continue; - } - E.inv = 1. / E.abs; - - tunnelMonteCarloRoutine(particles, ipart, Epart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel, &IonizationTunnelTL::ionizationRateTunnelTL); - } // Loop on particles -} - -double IonizationTunnelTL::ionizationRateTunnelTL(int Z, double delta, double E) -{ - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); -} diff --git a/src/Ionization/IonizationTunnelTL.h b/src/Ionization/IonizationTunnelTL.h deleted file mode 100755 index c9553d087..000000000 --- a/src/Ionization/IonizationTunnelTL.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef IONIZATIONTUNNELTL_H -#define IONIZATIONTUNNELTL_H - -#include -#include - -#include "Ionization.h" -#include "Tools.h" - -class Particles; - -//! calculate the particle tunnel ionization with Tong-Lin model -class IonizationTunnelTL : public Ionization -{ - public: - //! Constructor for IonizationTunnelTL: with no input argument - IonizationTunnelTL(Params ¶ms, Species *species); - - //! apply the Tunnel Ionization model to the species (with ionization current) - void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, - int ipart_ref = 0) override; - - private: - double ionizationRateTunnelTL(int Z, double delta, double E); - double ionization_tl_parameter_; - std::vector lambda_tunnel; -}; - -#endif From ac64c96344945a2cc082a7804fc1cce2f0944ca9 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Thu, 29 Aug 2024 19:53:50 +0200 Subject: [PATCH 07/17] Bug fix: revert logic of IonizationFactory to the earlier one, move some checks to separate methods --- src/Ionization/IonizationFactory.h | 60 +++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/src/Ionization/IonizationFactory.h b/src/Ionization/IonizationFactory.h index 0fe22fd6b..597eb14af 100644 --- a/src/Ionization/IonizationFactory.h +++ b/src/Ionization/IonizationFactory.h @@ -18,36 +18,62 @@ class IonizationFactory Ionization *Ionize = NULL; std::string model = species->ionization_model_; - if (species->max_charge_ > (int)species->atomic_number_) { - ERROR("Charge > atomic_number for species " << species->name_); - } - if (species->particles->is_test) { - ERROR("Cannot ionize test species " << species->name_); - } + if( model == "tunnel" ) { + checkMaxCharge(species); + checkNotLaserEnvelopeModel(params); + Ionize = new IonizationTunnel<0>( params, species ); // The original model included in Smilei + + } else if( model == "tunnel_envelope_averaged" ) { + checkMaxCharge(species); + checkTestParticle(species); + if ( !params.Laser_Envelope_model ) { + ERROR( "The ionization model tunnel_envelope_averaged needs a laser envelope"); + } + + Ionize = new IonizationTunnelEnvelopeAveraged( params, species ); - if (model == "tunnel_envelope_averaged") { - if (!params.Laser_Envelope_model) { - ERROR("The ionization model tunnel_envelope_averaged needs a laser envelope"); + } else if( model == "from_rate" ) { + if ( species->max_charge_ > ( int ) species->maximum_charge_state_ ) { + ERROR( "For species '" << species->name_ << ": charge > maximum_charge_state" ); } - Ionize = new IonizationTunnelEnvelopeAveraged(params, species); - } else if (params.Laser_Envelope_model) { - ERROR("The ionization model for species interacting with envelope is tunnel_envelope_averaged"); - } - if (model == "from_rate") { - Ionize = new IonizationFromRate(params, species); - } else if (model == "tunnel") { - Ionize = new IonizationTunnel<0>(params, species); // Tunnel, the original included in Smilei + Ionize = new IonizationFromRate( params, species ); + } else if (model == "tunnel_full_PPT") { + checkMaxCharge(species); + checkNotLaserEnvelopeModel(params); Ionize = new IonizationTunnel<1>(params, species); // FullPPT } else if (model == "tunnel_TL") { + checkMaxCharge(species); + checkNotLaserEnvelopeModel(params); Ionize = new IonizationTunnel<2>(params, species); // Tong&Ling } else if (model == "tunnel_BSI") { + checkMaxCharge(species); + checkNotLaserEnvelopeModel(params); Ionize = new IonizationTunnel<3>(params, species); // BSI } return Ionize; } + + private: + inline static void checkMaxCharge(const Species *species) { + if ( species->max_charge_ > ( int )species->atomic_number_ ) { + ERROR( "Charge > atomic_number for species " << species->name_ ); + } + } + + inline static void checkTestParticle(const Species *species) { + if( species->particles->is_test ) { + ERROR( "Cannot ionize test species " << species->name_ ); + } + } + + inline static void checkNotLaserEnvelopeModel(const Params ¶ms) { + if ( params.Laser_Envelope_model ) { + ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); + } + } }; #endif From d6bdfeb6f0af9142e7c593771b871b51883a5549 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:33:20 +0200 Subject: [PATCH 08/17] refactor IonizationFactory.h --- src/Ionization/IonizationFactory.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ionization/IonizationFactory.h b/src/Ionization/IonizationFactory.h index 597eb14af..a7039bec0 100644 --- a/src/Ionization/IonizationFactory.h +++ b/src/Ionization/IonizationFactory.h @@ -57,19 +57,19 @@ class IonizationFactory } private: - inline static void checkMaxCharge(const Species *species) { + static void checkMaxCharge(const Species *species) { if ( species->max_charge_ > ( int )species->atomic_number_ ) { ERROR( "Charge > atomic_number for species " << species->name_ ); } } - inline static void checkTestParticle(const Species *species) { + static void checkTestParticle(const Species *species) { if( species->particles->is_test ) { ERROR( "Cannot ionize test species " << species->name_ ); } } - inline static void checkNotLaserEnvelopeModel(const Params ¶ms) { + static void checkNotLaserEnvelopeModel(const Params ¶ms) { if ( params.Laser_Envelope_model ) { ERROR( "The ionization model for species interacting with envelope is tunnel_envelope_averaged" ); } From 66545dcc1557ee4f104e5be9d7ae868217233f03 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:40:44 +0200 Subject: [PATCH 09/17] Change include guard identifer --- src/Ionization/IonizationTunnel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 198a8c872..835446843 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -1,5 +1,5 @@ -#ifndef TEMPLATE_H -#define TEMPLATE_H +#ifndef IONIZATIONTUNNEL_H +#define IONIZATIONTUNNEL_H #include #include From 75c457c1dd74649a3c1ccfce764300f6595a6a9b Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Fri, 13 Sep 2024 14:42:56 +0200 Subject: [PATCH 10/17] Correct comment --- src/Ionization/IonizationTunnel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 835446843..72a10bd3a 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -503,7 +503,7 @@ inline double IonizationTunnel<3>::ionizationRate<1>(const int Z, const electric return au_to_w0 * (0.8 * E.abs * pow(ratio_of_IPs, 0.5)); } -// BSI Linear +// BSI Quadratic template <> template <> inline double IonizationTunnel<3>::ionizationRate<2>(const int Z, const electricFields E) From de467bd52bd6e348340b53e60c2a1620dd1b3834 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Fri, 13 Sep 2024 22:35:41 +0200 Subject: [PATCH 11/17] Move BSI condition to rate function; Move specialisations to cpp file --- src/Ionization/IonizationTunnel.cpp | 164 ++++++++ src/Ionization/IonizationTunnel.h | 563 ++++++++-------------------- 2 files changed, 326 insertions(+), 401 deletions(-) create mode 100644 src/Ionization/IonizationTunnel.cpp diff --git a/src/Ionization/IonizationTunnel.cpp b/src/Ionization/IonizationTunnel.cpp new file mode 100644 index 000000000..16251a526 --- /dev/null +++ b/src/Ionization/IonizationTunnel.cpp @@ -0,0 +1,164 @@ +#include "IonizationTunnel.h" +#include "IonizationTables.h" + + +// Classic: 1 +template <> +IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (unsigned int Z = 0; Z < atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + + DEBUG("Finished Creating the Tunnel Ionizaton class"); +} + +// IonizationFullPPT: 1 +template <> +IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + Magnetic_quantum_number.resize(atomic_number_); + + for (unsigned int Z = 0; Z < atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); + + DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] + << " M.q.num: " << Magnetic_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + double abs_m = abs(Magnetic_quantum_number[Z]); + alpha_tunnel[Z] = cst - 1.0 - abs_m; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / + (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + + DEBUG("Finished Creating the Tunnel Ionizaton class"); +} + +// Tong&Ling: 2 +template <> +IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); + + ionization_tl_parameter_ = + species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double + // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. + lambda_tunnel.resize(atomic_number_); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + lambda_tunnel[Z] = ionization_tl_parameter_ * pow(cst, 2) / gamma_tunnel[Z]; + } + + DEBUG("Finished Creating the Tong-Lin Tunnel Ionizaton class"); +} + +template <> +double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const double oldZ) +{ + const double delta = gamma_tunnel[Z] / E; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); +} + +// BSI: 3 +template <> +IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel BSI Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + DEBUG("Finished Creating the BSI Tunnel Ionizaton class"); +} + +template <> +double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ) +{ + auto normal = [this](const int Z, const double E) -> double { + double delta = gamma_tunnel[Z] / E; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); + }; + + auto linear = [this](const int Z, const double E) -> double { + const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (0.8 * E * pow(ratio_of_IPs, 0.5)); + }; + auto quadratic = [this](const int Z, const double E) -> double { + const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (2.4 * (pow(E, 2)) * pow(ratio_of_IPs, 2)); + }; + + double BSI_rate_quadratic = quadratic(oldZ, E); + double BSI_rate_linear = linear(oldZ, E); + double Tunnel_rate = normal(oldZ, E); + + if (BSI_rate_quadratic >= BSI_rate_linear) + { + return quadratic(Z, E); + } + else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) + { + return linear(Z, E); + } + else + { + return normal(Z, E); + } + +} + + + + diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 72a10bd3a..49948295d 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -15,15 +15,6 @@ class Particles; -struct electricFields -{ - double *x; - double *y; - double *z; - double inv; // inverse - double abs; // absolute value in atomic units -}; - template class IonizationTunnel : public Ionization { @@ -38,11 +29,7 @@ class IonizationTunnel : public Ionization int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; private: - template - inline void monteCarloRoutine(Particles *, unsigned int, Patch *, Projector *, const unsigned int, - const electricFields, vector &, vector &); - template - inline double ionizationRate(const int Z, const electricFields E); + inline double ionizationRate(const int Z, const double E, double oldZ); // To be conditionally prepared // FullPPT @@ -58,13 +45,11 @@ class IonizationTunnel : public Ionization }; template -void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ibin, int bin_shift, - double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref ) +inline void IonizationTunnel::operator()( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) { - - unsigned int Z, Zp1, newZ, k_times; - double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; +unsigned int Z, Zp1, newZ, k_times; + double TotalIonizPot, E, invE, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); LocalFields Jion; double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; @@ -98,9 +83,8 @@ void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, u invE = 1./E; factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z]*invE; ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); + IonizRate_tunnel[Z] = ionizationRate(Z, E, Z); // Total ionization potential (used to compute the ionization current) TotalIonizPot = 0.0; @@ -116,23 +100,21 @@ void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, u TotalIonizPot += Potential[Z]; k_times = 1; } - + } else { // else : multiple ionization can occur in one time-step // partial & final ionization are decoupled (see Nuter Phys. Plasmas) // ------------------------------------------------------------------------- - + // initialization Mult = 1.0; Dnom_tunnel[0]=1.0; Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. - + //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { newZ = Zp1+k_times; - delta = gamma_tunnel[newZ]*invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] - * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); + IonizRate_tunnel[newZ] = ionizationRate(newZ, E, Z); D_sum = 0.0; P_sum = 0.0; Mult *= IonizRate_tunnel[Z+k_times]; @@ -141,14 +123,14 @@ void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, u D_sum += Dnom_tunnel[i]; P_sum += exp( -IonizRate_tunnel[Z+i]*dt )*Dnom_tunnel[i]; } - Dnom_tunnel[k_times+1] -= D_sum; + Dnom_tunnel[k_times+1] = -D_sum; // bug fix P_sum = P_sum + Dnom_tunnel[k_times+1]*exp( -IonizRate_tunnel[newZ]*dt ); Pint_tunnel = Pint_tunnel + P_sum*Mult; - + TotalIonizPot += Potential[Z+k_times]; k_times++; }//END while - + // final ionization (of last electron) if( ( ( 1.0-Pint_tunnel )>ran_p ) && ( k_times==atomic_number_-Zp1 ) ) { TotalIonizPot += Potential[atomic_number_-1]; @@ -157,35 +139,36 @@ void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, u }//END Multiple ionization routine // Compute ionization current - if (b_Jx != NULL){ // For the moment ionization current is not accounted for in AM geometry + if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry factorJion *= TotalIonizPot; Jion.x = factorJion * *( Ex+ipart ); Jion.y = factorJion * *( Ey+ipart ); Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrentsForTasks( b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift ); + + Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); } // Creation of the new electrons // (variable weights are used) // ----------------------------- + if( k_times !=0 ) { - new_electrons_per_bin[ibin].createParticle(); - int idNew = new_electrons_per_bin[ibin].size() - 1;//cout<<"ibin "<position( i, ipart ); + new_electrons.createParticle(); + int idNew = new_electrons.size() - 1; + for( unsigned int i=0; iposition( i, ipart ); } for( unsigned int i=0; i<3; i++ ) { - new_electrons_per_bin[ibin].momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; } - new_electrons_per_bin[ibin].weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons_per_bin[ibin].charge( idNew )=-1; + new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); + new_electrons.charge( idNew )=-1; if( save_ion_charge_ ) { - ion_charge_per_bin_[ibin].push_back( particles->charge( ipart ) ); + ion_charge_.push_back( particles->charge( ipart ) ); } - // // Increase the charge of the particle + // Increase the charge of the particle particles->charge( ipart ) += k_times; } @@ -193,393 +176,171 @@ void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, u } template -template -inline void IonizationTunnel::monteCarloRoutine(Particles *particles, unsigned int ipart, Patch *patch, Projector *Proj, - const unsigned int Z, const electricFields E, - vector &IonizRate_tunnel, vector &Dnom_tunnel) -{ - double TotalIonizPot, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - LocalFields Jion; - const double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; - unsigned int newZ, Zp1, k_times; - factorJion = factorJion_0 * E.inv * E.inv; - ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = ionizationRate(Z, E); - - // Total ionization potential (used to compute the ionization current) - TotalIonizPot = 0.0; - - // k_times will give the nb of ionization events - k_times = 0; - Zp1 = Z + 1; - - if (Zp1 == atomic_number_) - { - // if ionization of the last electron: single ionization - // ----------------------------------------------------- - if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) - { - TotalIonizPot += Potential[Z]; - k_times = 1; - } - } - else - { - // else : multiple ionization can occur in one time-step - // partial & final ionization are decoupled (see Nuter Phys. - // Plasmas) - // ------------------------------------------------------------------------- - - // initialization - Mult = 1.0; - Dnom_tunnel[0] = 1.0; - Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. - - // multiple ionization loop while Pint_tunnel < ran_p and still partial - // ionization - while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) - { - newZ = Zp1 + k_times; - IonizRate_tunnel[newZ] = ionizationRate(newZ, E); - D_sum = 0.0; - P_sum = 0.0; - Mult *= IonizRate_tunnel[Z + k_times]; - for (unsigned int i = 0; i < k_times + 1; i++) - { - Dnom_tunnel[i] = Dnom_tunnel[i] / (IonizRate_tunnel[newZ] - IonizRate_tunnel[Z + i]); - D_sum += Dnom_tunnel[i]; - P_sum += exp(-IonizRate_tunnel[Z + i] * dt) * Dnom_tunnel[i]; - } - Dnom_tunnel[k_times + 1] -= D_sum; - P_sum = P_sum + Dnom_tunnel[k_times + 1] * exp(-IonizRate_tunnel[newZ] * dt); - Pint_tunnel = Pint_tunnel + P_sum * Mult; - - TotalIonizPot += Potential[Z + k_times]; - k_times++; - } // END while - - // final ionization (of last electron) - if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) - { - TotalIonizPot += Potential[atomic_number_ - 1]; - k_times++; - } - } // END Multiple ionization routine - - // Compute ionization current - if (patch->EMfields->Jx_ != NULL) - { // For the moment ionization current is - // not accounted for in AM geometry - factorJion *= TotalIonizPot; - Jion.x = factorJion * *(E.x + ipart); - Jion.y = factorJion * *(E.y + ipart); - Jion.z = factorJion * *(E.z + ipart); - - Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion); - } - - // Creation of the new electrons - // (variable weights are used) - // ----------------------------- - - if (k_times != 0) - { - new_electrons.createParticle(); - int idNew = new_electrons.size() - 1; - for (unsigned int i = 0; i < new_electrons.dimension(); i++) - { - new_electrons.position(i, idNew) = particles->position(i, ipart); - } - for (unsigned int i = 0; i < 3; i++) - { - new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; - } - new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); - new_electrons.charge(idNew) = -1; - - if (save_ion_charge_) - { - ion_charge_.push_back(particles->charge(ipart)); - } - - // Increase the charge of the particle - particles->charge(ipart) += k_times; - } -} - -template -inline void IonizationTunnel::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) - -{ - unsigned int Z; - electricFields E; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); - - int nparts = Epart->size() / 3; - E.x = &((*Epart)[0 * nparts]); - E.y = &((*Epart)[1 * nparts]); - E.z = &((*Epart)[2 * nparts]); - - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - // Current charge state of the ion - Z = (unsigned int)(particles->charge(ipart)); - - // If ion already fully ionized then skip - if (Z == atomic_number_) - { - continue; - } - - // Absolute value of the electric field normalized in atomic units - E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), 2) + pow(*(E.y + ipart - ipart_ref), 2) + - pow(*(E.z + ipart - ipart_ref), 2)); - if (E.abs < 1e-10) - { - continue; - } - E.inv = 1. / E.abs; - - monteCarloRoutine<0>(particles, ipart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel); - } // Loop on particles -} - -template -template -inline double IonizationTunnel::ionizationRate(const int Z, const electricFields E) +inline double IonizationTunnel::ionizationRate(const int Z, const double E, const double oldZ) { - double delta = gamma_tunnel[Z] * E.inv; + double delta = gamma_tunnel[Z] / E; return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); } // IonizationTunnel : 0 template <> -inline IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - - DEBUG("Finished Creating the Tunnel Ionizaton class"); -} - -template <> -template <> -inline double IonizationTunnel<0>::ionizationRate<0>(const int Z, const electricFields E) -{ - double delta = gamma_tunnel[Z] * E.inv; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); -} +IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species); // IonizationTunnelFullPPT: 1 - template <> -inline IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - Magnetic_quantum_number.resize(atomic_number_); - - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); - - DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] - << " M.q.num: " << Magnetic_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - double abs_m = abs(Magnetic_quantum_number[Z]); - alpha_tunnel[Z] = cst - 1.0 - abs_m; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / - (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - - DEBUG("Finished Creating the Tunnel Ionizaton class"); -} - -template <> -template <> -inline double IonizationTunnel<1>::ionizationRate<0>(const int Z, const electricFields E) -{ - double delta = gamma_tunnel[Z] * E.inv; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); -} +IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species); // Tong&Ling: 2 - template <> -inline IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); - - ionization_tl_parameter_ = - species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double - // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. - lambda_tunnel.resize(atomic_number_); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { - DEBUG("Z : " << Z); - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); +IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species); - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - lambda_tunnel[Z] = ionization_tl_parameter_ * pow(cst, 2) / gamma_tunnel[Z]; - } - - DEBUG("Finished Creating the Tong-Lin Tunnel Ionizaton class"); -} - -template <> template <> -inline double IonizationTunnel<2>::ionizationRate<0>(const int Z, const electricFields E) -{ - const double delta = gamma_tunnel[Z] * E.inv; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E.abs * lambda_tunnel[Z]); -} +double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const double oldZ); // BSI: 3 - -template <> -inline IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel BSI Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - DEBUG("Finished Creating the BSI Tunnel Ionizaton class"); -} - -// BSI Linear -template <> template <> -inline double IonizationTunnel<3>::ionizationRate<1>(const int Z, const electricFields E) -{ - const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (0.8 * E.abs * pow(ratio_of_IPs, 0.5)); -} +IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species); -// BSI Quadratic template <> -template <> -inline double IonizationTunnel<3>::ionizationRate<2>(const int Z, const electricFields E) -{ - const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (2.4 * (pow(E.abs, 2)) * pow(ratio_of_IPs, 2)); -} +double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ); -template <> -inline void IonizationTunnel<3>::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) -{ - unsigned int Z; - electricFields E; - vector IonizRate_tunnel(atomic_number_), - Dnom_tunnel(atomic_number_); // For MonteCarlo procedure using the tunnel - // ioniz. rate. - vector IonizRate_BSI_linear(atomic_number_), - Dnom_BSI_linear(atomic_number_); // For MonteCarlo procedure using the BSI - // ioniz. rate. - vector IonizRate_BSI_quadratic(atomic_number_), Dnom_BSI_quadratic(atomic_number_); - int nparts = Epart->size() / 3; // Over 3 because there are 3 Dims. Epart is like [part1_Ex, part2_Ex, - // ... partnparts_Ex, part1_Ey, part2_Ey,...partnparts_Ey, part1_Ez, - // part2_Ez, partnparts_Ez]} - E.x = &((*Epart)[0 * nparts]); - E.y = &((*Epart)[1 * nparts]); - E.z = &((*Epart)[2 * nparts]); - for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) - { - Z = (unsigned int)(particles->charge(ipart)); // current charge state of the particle number ipart of species - // called ''species'' with atomic no = atomic_number_ - // If ion already fully ionized then skip and go to next particle - if (Z == atomic_number_) - { - continue; - } // atom fully ionized already, no electrons remained to be stripped away. +template +void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ibin, int bin_shift, + double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref ) +{ - // Absolute value of the electric field in AtomicUnits (i.e. normalized to - // (in units of) E_atomic = 5.1422*10^11 V/m) - E.abs = EC_to_au * sqrt(pow(*(E.x + ipart - ipart_ref), - 2) // (Ex+ipart-ipart_ref) points to the location in the - // container Epart at which E-field_x for particle ipart - // sits. - + pow(*(E.y + ipart - ipart_ref), - 2) // Similarly for y. Dereferencing it via *() means we - // access and use the value sitting at that location. - + pow(*(E.z + ipart - ipart_ref), - 2)); // EC_to_au transforms from SMILEI-normalized units to - // AtomicUnits. - if (E.abs < 1e-10) - { // E is in Atomic Units + unsigned int Z, Zp1, newZ, k_times; + double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; + vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + LocalFields Jion; + double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; + + int nparts = Epart->size()/3; + double *Ex = &( ( *Epart )[0*nparts] ); + double *Ey = &( ( *Epart )[1*nparts] ); + double *Ez = &( ( *Epart )[2*nparts] ); + + for( unsigned int ipart=ipart_min ; ipartcharge( ipart ) ); + + // If ion already fully ionized then skip + if( Z==atomic_number_ ) { continue; } - - // Used to be call to continuity_tool. After some shortening, the call was manually inlined - double BSI_rate_quadratic = ionizationRate<2>(Z, E); - double BSI_rate_linear = ionizationRate<1>(Z, E); - double Tunnel_rate = ionizationRate<0>(Z, E); - - if (BSI_rate_quadratic >= BSI_rate_linear) - { - monteCarloRoutine<2>(particles, ipart, patch, Proj, Z, E, IonizRate_BSI_quadratic, Dnom_BSI_quadratic); + + // Absolute value of the electric field normalized in atomic units + E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) + +pow( *( Ey+ipart-ipart_ref ), 2 ) + +pow( *( Ez+ipart-ipart_ref ), 2 ) ); + if( E<1e-10 ) { + continue; } - else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) - { - monteCarloRoutine<1>(particles, ipart, patch, Proj, Z, E, IonizRate_BSI_linear, Dnom_BSI_linear); + + // -------------------------------- + // Start of the Monte-Carlo routine + // -------------------------------- + + invE = 1./E; + factorJion = factorJion_0 * invE*invE; + delta = gamma_tunnel[Z]*invE; + ran_p = patch->rand_->uniform(); + IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); + + // Total ionization potential (used to compute the ionization current) + TotalIonizPot = 0.0; + + // k_times will give the nb of ionization events + k_times = 0; + Zp1=Z+1; + + if( Zp1 == atomic_number_ ) { + // if ionization of the last electron: single ionization + // ----------------------------------------------------- + if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { + TotalIonizPot += Potential[Z]; + k_times = 1; + } + + } else { + // else : multiple ionization can occur in one time-step + // partial & final ionization are decoupled (see Nuter Phys. Plasmas) + // ------------------------------------------------------------------------- + + // initialization + Mult = 1.0; + Dnom_tunnel[0]=1.0; + Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. + + //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { + newZ = Zp1+k_times; + delta = gamma_tunnel[newZ]*invE; + IonizRate_tunnel[newZ] = beta_tunnel[newZ] + * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); + D_sum = 0.0; + P_sum = 0.0; + Mult *= IonizRate_tunnel[Z+k_times]; + for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { + TotalIonizPot += Potential[atomic_number_-1]; + k_times++; + } + }//END Multiple ionization routine + + // Compute ionization current + if (b_Jx != NULL){ // For the moment ionization current is not accounted for in AM geometry + factorJion *= TotalIonizPot; + Jion.x = factorJion * *( Ex+ipart ); + Jion.y = factorJion * *( Ey+ipart ); + Jion.z = factorJion * *( Ez+ipart ); + + Proj->ionizationCurrentsForTasks( b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift ); } - else - { - monteCarloRoutine<0>(particles, ipart, patch, Proj, Z, E, IonizRate_tunnel, Dnom_tunnel); + + // Creation of the new electrons + // (variable weights are used) + // ----------------------------- + if( k_times !=0 ) { + new_electrons_per_bin[ibin].createParticle(); + int idNew = new_electrons_per_bin[ibin].size() - 1;//cout<<"ibin "<position( i, ipart ); + } + for( unsigned int i=0; i<3; i++ ) { + new_electrons_per_bin[ibin].momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + } + new_electrons_per_bin[ibin].weight( idNew )=double( k_times )*particles->weight( ipart ); + new_electrons_per_bin[ibin].charge( idNew )=-1; + + if( save_ion_charge_ ) { + ion_charge_per_bin_[ibin].push_back( particles->charge( ipart ) ); + } + + // // Increase the charge of the particle + particles->charge( ipart ) += k_times; } - } // END loop on particles + + } // Loop on particles +} -} // void IonizationTunnelBSI::operator()(arg1, arg2, ...) scope end. #endif From 42532996a9f0b43c43efd4bdeb95be6762c564d7 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:23:03 +0200 Subject: [PATCH 12/17] Split ionization specializations into files according to rate used. Correct bug in BSI --- src/Ionization/IonizationBSI.cpp | 62 +++++++++++++ src/Ionization/IonizationFullPPT.cpp | 35 +++++++ src/Ionization/IonizationTL.cpp | 40 ++++++++ src/Ionization/IonizationTunnel.cpp | 133 --------------------------- src/Ionization/IonizationTunnel.h | 5 - 5 files changed, 137 insertions(+), 138 deletions(-) create mode 100644 src/Ionization/IonizationBSI.cpp create mode 100644 src/Ionization/IonizationFullPPT.cpp create mode 100644 src/Ionization/IonizationTL.cpp diff --git a/src/Ionization/IonizationBSI.cpp b/src/Ionization/IonizationBSI.cpp new file mode 100644 index 000000000..6d9aa0190 --- /dev/null +++ b/src/Ionization/IonizationBSI.cpp @@ -0,0 +1,62 @@ +#include "IonizationTunnel.h" +#include "IonizationTables.h" + +template <> +IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel BSI Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + DEBUG("Finished Creating the BSI Tunnel Ionizaton class"); +} + +template <> +double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ) +{ + auto normal = [this](const int Z, const double E) -> double { + double delta = gamma_tunnel[Z] / E; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); + }; + + auto linear = [this](const int Z, const double E) -> double { + const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (0.8 * E * pow(ratio_of_IPs, 0.5)); + }; + auto quadratic = [this](const int Z, const double E) -> double { + const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + return au_to_w0 * (2.4 * (pow(E, 2)) * pow(ratio_of_IPs, 2)); + }; + + double BSI_rate_quadratic = quadratic(oldZ+1, E); + double BSI_rate_linear = linear(oldZ+1, E); + double Tunnel_rate = normal(oldZ, E); + + if (BSI_rate_quadratic >= BSI_rate_linear) + { + return quadratic(Z, E); + } + else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) + { + return linear(Z, E); + } + else + { + return normal(Z, E); + } + +} diff --git a/src/Ionization/IonizationFullPPT.cpp b/src/Ionization/IonizationFullPPT.cpp new file mode 100644 index 000000000..d51de62cf --- /dev/null +++ b/src/Ionization/IonizationFullPPT.cpp @@ -0,0 +1,35 @@ +#include "IonizationTunnel.h" +#include "IonizationTables.h" + +template <> +IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tunnel Ionizaton class"); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + Magnetic_quantum_number.resize(atomic_number_); + + for (unsigned int Z = 0; Z < atomic_number_; Z++) + { + DEBUG("Z : " << Z); + + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); + + DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] + << " M.q.num: " << Magnetic_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + double abs_m = abs(Magnetic_quantum_number[Z]); + alpha_tunnel[Z] = cst - 1.0 - abs_m; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / + (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + } + + DEBUG("Finished Creating the Tunnel Ionizaton class"); +} + + diff --git a/src/Ionization/IonizationTL.cpp b/src/Ionization/IonizationTL.cpp new file mode 100644 index 000000000..a44ad1439 --- /dev/null +++ b/src/Ionization/IonizationTL.cpp @@ -0,0 +1,40 @@ +#include "IonizationTunnel.h" +#include "IonizationTables.h" + +template <> +IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) +{ + DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); + + ionization_tl_parameter_ = + species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double + // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. + lambda_tunnel.resize(atomic_number_); + + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) + for (int Z = 0; Z < (int)atomic_number_; Z++) + { + DEBUG("Z : " << Z); + Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; + Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); + + DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); + + double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); + alpha_tunnel[Z] = cst - 1.0; + beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * + Potential[Z] * au_to_w0; + gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); + lambda_tunnel[Z] = ionization_tl_parameter_ * pow(cst, 2) / gamma_tunnel[Z]; + } + + DEBUG("Finished Creating the Tong-Lin Tunnel Ionizaton class"); +} + +template <> +double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const double oldZ) +{ + const double delta = gamma_tunnel[Z] / E; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); +} + diff --git a/src/Ionization/IonizationTunnel.cpp b/src/Ionization/IonizationTunnel.cpp index 16251a526..2bd478f89 100644 --- a/src/Ionization/IonizationTunnel.cpp +++ b/src/Ionization/IonizationTunnel.cpp @@ -28,137 +28,4 @@ IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza DEBUG("Finished Creating the Tunnel Ionizaton class"); } -// IonizationFullPPT: 1 -template <> -IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - Magnetic_quantum_number.resize(atomic_number_); - - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - Magnetic_quantum_number[Z] = IonizationTables::magnetic_atomic_number(atomic_number_, Z); - - DEBUG("Potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z] - << " M.q.num: " << Magnetic_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - double abs_m = abs(Magnetic_quantum_number[Z]); - alpha_tunnel[Z] = cst - 1.0 - abs_m; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0 * tgamma(Azimuthal_quantum_number[Z] + abs_m + 1) / - (tgamma(abs_m + 1) * tgamma(Azimuthal_quantum_number[Z] - abs_m + 1)); - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - - DEBUG("Finished Creating the Tunnel Ionizaton class"); -} - -// Tong&Ling: 2 -template <> -IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); - - ionization_tl_parameter_ = - species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double - // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. - lambda_tunnel.resize(atomic_number_); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { - DEBUG("Z : " << Z); - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - lambda_tunnel[Z] = ionization_tl_parameter_ * pow(cst, 2) / gamma_tunnel[Z]; - } - - DEBUG("Finished Creating the Tong-Lin Tunnel Ionizaton class"); -} - -template <> -double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const double oldZ) -{ - const double delta = gamma_tunnel[Z] / E; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); -} - -// BSI: 3 -template <> -IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) -{ - DEBUG("Creating the Tunnel BSI Ionizaton class"); - - // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { - DEBUG("Z : " << Z); - - Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; - Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); - - DEBUG("potential: " << Potential[Z] << " Az.q.num: " << Azimuthal_quantum_number[Z]); - - double cst = ((double)Z + 1.0) * sqrt(2.0 / Potential[Z]); - alpha_tunnel[Z] = cst - 1.0; - beta_tunnel[Z] = pow(2, alpha_tunnel[Z]) * (8. * Azimuthal_quantum_number[Z] + 4.0) / (cst * tgamma(cst)) * - Potential[Z] * au_to_w0; - gamma_tunnel[Z] = 2.0 * pow(2.0 * Potential[Z], 1.5); - } - DEBUG("Finished Creating the BSI Tunnel Ionizaton class"); -} - -template <> -double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ) -{ - auto normal = [this](const int Z, const double E) -> double { - double delta = gamma_tunnel[Z] / E; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); - }; - - auto linear = [this](const int Z, const double E) -> double { - const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (0.8 * E * pow(ratio_of_IPs, 0.5)); - }; - auto quadratic = [this](const int Z, const double E) -> double { - const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (2.4 * (pow(E, 2)) * pow(ratio_of_IPs, 2)); - }; - - double BSI_rate_quadratic = quadratic(oldZ, E); - double BSI_rate_linear = linear(oldZ, E); - double Tunnel_rate = normal(oldZ, E); - - if (BSI_rate_quadratic >= BSI_rate_linear) - { - return quadratic(Z, E); - } - else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) - { - return linear(Z, E); - } - else - { - return normal(Z, E); - } - -} - - - diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 49948295d..69ffc7eb3 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -8,8 +8,6 @@ #include "Ionization.h" #include "Tools.h" -// because defining in header -#include "IonizationTables.h" #include "Particles.h" #include "Species.h" @@ -204,9 +202,6 @@ IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species); template <> double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ); - - - template void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, vector *Epart, Patch *patch, Projector *Proj, int ibin, int bin_shift, From b554d270bfa30804104b89ce102ef7c0a9816de5 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit <109722947+GianlucaOberreit@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:04:47 +0200 Subject: [PATCH 13/17] Correct bug in ionization rate selection --- src/Ionization/IonizationBSI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ionization/IonizationBSI.cpp b/src/Ionization/IonizationBSI.cpp index 6d9aa0190..b75dd57aa 100644 --- a/src/Ionization/IonizationBSI.cpp +++ b/src/Ionization/IonizationBSI.cpp @@ -48,11 +48,11 @@ double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const do if (BSI_rate_quadratic >= BSI_rate_linear) { - return quadratic(Z, E); + return linear(Z, E); } else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) { - return linear(Z, E); + return quadratic(Z, E); } else { From 42c63b264880a9036c3065b993f142a3fabe7274 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit Date: Tue, 24 Dec 2024 20:33:07 +0000 Subject: [PATCH 14/17] change oldZ from double to int --- src/Ionization/IonizationBSI.cpp | 2 +- src/Ionization/IonizationTL.cpp | 2 +- src/Ionization/IonizationTunnel.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Ionization/IonizationBSI.cpp b/src/Ionization/IonizationBSI.cpp index b75dd57aa..1e79c6e70 100644 --- a/src/Ionization/IonizationBSI.cpp +++ b/src/Ionization/IonizationBSI.cpp @@ -26,7 +26,7 @@ IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza } template <> -double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ) +double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const int oldZ) { auto normal = [this](const int Z, const double E) -> double { double delta = gamma_tunnel[Z] / E; diff --git a/src/Ionization/IonizationTL.cpp b/src/Ionization/IonizationTL.cpp index a44ad1439..eeee34fdc 100644 --- a/src/Ionization/IonizationTL.cpp +++ b/src/Ionization/IonizationTL.cpp @@ -32,7 +32,7 @@ IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza } template <> -double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const double oldZ) +double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const int oldZ) { const double delta = gamma_tunnel[Z] / E; return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 69ffc7eb3..d1b5cbefa 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -27,7 +27,7 @@ class IonizationTunnel : public Ionization int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; private: - inline double ionizationRate(const int Z, const double E, double oldZ); + inline double ionizationRate(const int Z, const double E, int oldZ); // To be conditionally prepared // FullPPT @@ -174,7 +174,7 @@ unsigned int Z, Zp1, newZ, k_times; } template -inline double IonizationTunnel::ionizationRate(const int Z, const double E, const double oldZ) +inline double IonizationTunnel::ionizationRate(const int Z, const double E, const int oldZ) { double delta = gamma_tunnel[Z] / E; return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); @@ -193,14 +193,14 @@ template <> IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species); template <> -double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const double oldZ); +double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const int oldZ); // BSI: 3 template <> IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species); template <> -double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const double oldZ); +double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const int oldZ); template void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, From 64b6733b4679f1c2a2fe7dc2cea6a4c4d541ade5 Mon Sep 17 00:00:00 2001 From: GianlucaOberreit Date: Fri, 3 Jan 2025 01:36:28 +0000 Subject: [PATCH 15/17] Refactor --- src/Ionization/IonizationTunnel.h | 324 +++++++++++++++--------------- 1 file changed, 159 insertions(+), 165 deletions(-) diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index d1b5cbefa..4ee8b8b01 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -6,10 +6,9 @@ #include #include "Ionization.h" -#include "Tools.h" - #include "Particles.h" #include "Species.h" +#include "Tools.h" class Particles; @@ -20,11 +19,11 @@ class IonizationTunnel : public Ionization inline IonizationTunnel(Params ¶ms, Species *species); inline void operator()(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, - int ipart_ref = 0) override; + int ipart_ref = 0) override; //! method for tunnel ionization with tasks inline void ionizationTunnelWithTasks(Particles *, unsigned int, unsigned int, std::vector *, Patch *, Projector *, - int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; + int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; private: inline double ionizationRate(const int Z, const double E, int oldZ); @@ -43,134 +42,132 @@ class IonizationTunnel : public Ionization }; template -inline void IonizationTunnel::operator()( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) +inline void IonizationTunnel::operator()(Particles *particles, unsigned int ipart_min, unsigned int ipart_max, + vector *Epart, Patch *patch, Projector *Proj, int ipart_ref) { -unsigned int Z, Zp1, newZ, k_times; + unsigned int Z, Zp1, newZ, k_times; double TotalIonizPot, E, invE, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; - - int nparts = Epart->size()/3; - double *Ex = &( ( *Epart )[0*nparts] ); - double *Ey = &( ( *Epart )[1*nparts] ); - double *Ez = &( ( *Epart )[2*nparts] ); - - for( unsigned int ipart=ipart_min ; ipartsize() / 3; + double *Ex = &((*Epart)[0 * nparts]); + double *Ey = &((*Epart)[1 * nparts]); + double *Ez = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) { // Current charge state of the ion - Z = ( unsigned int )( particles->charge( ipart ) ); - + Z = (unsigned int)(particles->charge(ipart)); + // If ion already fully ionized then skip - if( Z==atomic_number_ ) { + if (Z == atomic_number_) { continue; } - + // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) - +pow( *( Ey+ipart-ipart_ref ), 2 ) - +pow( *( Ez+ipart-ipart_ref ), 2 ) ); - if( E<1e-10 ) { + E = EC_to_au * sqrt(pow(*(Ex + ipart - ipart_ref), 2) + pow(*(Ey + ipart - ipart_ref), 2) + + pow(*(Ez + ipart - ipart_ref), 2)); + if (E < 1e-10) { continue; } - + // -------------------------------- // Start of the Monte-Carlo routine // -------------------------------- - - invE = 1./E; - factorJion = factorJion_0 * invE*invE; + + invE = 1. / E; + factorJion = factorJion_0 * invE * invE; ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = ionizationRate(Z, E, Z); - + IonizRate_tunnel[Z] = ionizationRate(Z, E, Z); + // Total ionization potential (used to compute the ionization current) TotalIonizPot = 0.0; - + // k_times will give the nb of ionization events k_times = 0; - Zp1=Z+1; - - if( Zp1 == atomic_number_ ) { + Zp1 = Z + 1; + + if (Zp1 == atomic_number_) { // if ionization of the last electron: single ionization // ----------------------------------------------------- - if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { + if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) { TotalIonizPot += Potential[Z]; - k_times = 1; + k_times = 1; } - + } else { // else : multiple ionization can occur in one time-step // partial & final ionization are decoupled (see Nuter Phys. Plasmas) // ------------------------------------------------------------------------- - + // initialization Mult = 1.0; - Dnom_tunnel[0]=1.0; - Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. - - //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { - newZ = Zp1+k_times; + Dnom_tunnel[0] = 1.0; + Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. + + // multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) { + newZ = Zp1 + k_times; IonizRate_tunnel[newZ] = ionizationRate(newZ, E, Z); D_sum = 0.0; P_sum = 0.0; - Mult *= IonizRate_tunnel[Z+k_times]; - for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { - TotalIonizPot += Potential[atomic_number_-1]; + if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) { + TotalIonizPot += Potential[atomic_number_ - 1]; k_times++; } - }//END Multiple ionization routine - + } // END Multiple ionization routine + // Compute ionization current - if (patch->EMfields->Jx_ != NULL){ // For the moment ionization current is not accounted for in AM geometry + if (patch->EMfields->Jx_ != NULL) { // For the moment ionization current is not accounted for in AM geometry factorJion *= TotalIonizPot; - Jion.x = factorJion * *( Ex+ipart ); - Jion.y = factorJion * *( Ey+ipart ); - Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrents( patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion ); + Jion.x = factorJion * *(Ex + ipart); + Jion.y = factorJion * *(Ey + ipart); + Jion.z = factorJion * *(Ez + ipart); + + Proj->ionizationCurrents(patch->EMfields->Jx_, patch->EMfields->Jy_, patch->EMfields->Jz_, *particles, ipart, Jion); } - + // Creation of the new electrons // (variable weights are used) // ----------------------------- - if( k_times !=0 ) { + if (k_times != 0) { new_electrons.createParticle(); int idNew = new_electrons.size() - 1; - for( unsigned int i=0; iposition( i, ipart ); + for (unsigned int i = 0; i < new_electrons.dimension(); i++) { + new_electrons.position(i, idNew) = particles->position(i, ipart); } - for( unsigned int i=0; i<3; i++ ) { - new_electrons.momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + for (unsigned int i = 0; i < 3; i++) { + new_electrons.momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; } - new_electrons.weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons.charge( idNew )=-1; - - if( save_ion_charge_ ) { - ion_charge_.push_back( particles->charge( ipart ) ); + new_electrons.weight(idNew) = double(k_times) * particles->weight(ipart); + new_electrons.charge(idNew) = -1; + + if (save_ion_charge_) { + ion_charge_.push_back(particles->charge(ipart)); } - + // Increase the charge of the particle - particles->charge( ipart ) += k_times; + particles->charge(ipart) += k_times; } - - } // Loop on particles + + } // Loop on particles } template @@ -203,139 +200,136 @@ template <> double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const int oldZ); template -void IonizationTunnel::ionizationTunnelWithTasks( Particles *particles, unsigned int ipart_min, unsigned int ipart_max, - vector *Epart, Patch *patch, Projector *Proj, int ibin, int bin_shift, - double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref ) +void IonizationTunnel::ionizationTunnelWithTasks(Particles *particles, unsigned int ipart_min, + unsigned int ipart_max, vector *Epart, Patch *patch, + Projector *Proj, int ibin, int bin_shift, double *b_Jx, + double *b_Jy, double *b_Jz, int ipart_ref) { - unsigned int Z, Zp1, newZ, k_times; double TotalIonizPot, E, invE, factorJion, delta, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel( atomic_number_ ), Dnom_tunnel( atomic_number_ ); + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); LocalFields Jion; - double factorJion_0 = au_to_mec2 * EC_to_au*EC_to_au * invdt; - - int nparts = Epart->size()/3; - double *Ex = &( ( *Epart )[0*nparts] ); - double *Ey = &( ( *Epart )[1*nparts] ); - double *Ez = &( ( *Epart )[2*nparts] ); - - for( unsigned int ipart=ipart_min ; ipartsize() / 3; + double *Ex = &((*Epart)[0 * nparts]); + double *Ey = &((*Epart)[1 * nparts]); + double *Ez = &((*Epart)[2 * nparts]); + + for (unsigned int ipart = ipart_min; ipart < ipart_max; ipart++) { // Current charge state of the ion - Z = ( unsigned int )( particles->charge( ipart ) ); - + Z = (unsigned int)(particles->charge(ipart)); + // If ion already fully ionized then skip - if( Z==atomic_number_ ) { + if (Z == atomic_number_) { continue; } - + // Absolute value of the electric field normalized in atomic units - E = EC_to_au * sqrt( pow( *( Ex+ipart-ipart_ref ), 2 ) - +pow( *( Ey+ipart-ipart_ref ), 2 ) - +pow( *( Ez+ipart-ipart_ref ), 2 ) ); - if( E<1e-10 ) { + E = EC_to_au * sqrt(pow(*(Ex + ipart - ipart_ref), 2) + pow(*(Ey + ipart - ipart_ref), 2) + + pow(*(Ez + ipart - ipart_ref), 2)); + if (E < 1e-10) { continue; } - + // -------------------------------- // Start of the Monte-Carlo routine // -------------------------------- - - invE = 1./E; - factorJion = factorJion_0 * invE*invE; - delta = gamma_tunnel[Z]*invE; + + invE = 1. / E; + factorJion = factorJion_0 * invE * invE; + delta = gamma_tunnel[Z] * invE; ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = beta_tunnel[Z] * exp( -delta*one_third + alpha_tunnel[Z]*log( delta ) ); - + IonizRate_tunnel[Z] = beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); + // Total ionization potential (used to compute the ionization current) TotalIonizPot = 0.0; - + // k_times will give the nb of ionization events k_times = 0; - Zp1=Z+1; - - if( Zp1 == atomic_number_ ) { + Zp1 = Z + 1; + + if (Zp1 == atomic_number_) { // if ionization of the last electron: single ionization // ----------------------------------------------------- - if( ran_p < 1.0 -exp( -IonizRate_tunnel[Z]*dt ) ) { + if (ran_p < 1.0 - exp(-IonizRate_tunnel[Z] * dt)) { TotalIonizPot += Potential[Z]; - k_times = 1; + k_times = 1; } - + } else { // else : multiple ionization can occur in one time-step // partial & final ionization are decoupled (see Nuter Phys. Plasmas) // ------------------------------------------------------------------------- - + // initialization Mult = 1.0; - Dnom_tunnel[0]=1.0; - Pint_tunnel = exp( -IonizRate_tunnel[Z]*dt ); // cummulative prob. - - //multiple ionization loop while Pint_tunnel < ran_p and still partial ionization - while( ( Pint_tunnel < ran_p ) and ( k_times < atomic_number_-Zp1 ) ) { - newZ = Zp1+k_times; - delta = gamma_tunnel[newZ]*invE; - IonizRate_tunnel[newZ] = beta_tunnel[newZ] - * exp( -delta*one_third+alpha_tunnel[newZ]*log( delta ) ); + Dnom_tunnel[0] = 1.0; + Pint_tunnel = exp(-IonizRate_tunnel[Z] * dt); // cummulative prob. + + // multiple ionization loop while Pint_tunnel < ran_p and still partial ionization + while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) { + newZ = Zp1 + k_times; + delta = gamma_tunnel[newZ] * invE; + IonizRate_tunnel[newZ] = beta_tunnel[newZ] * exp(-delta * one_third + alpha_tunnel[newZ] * log(delta)); D_sum = 0.0; P_sum = 0.0; - Mult *= IonizRate_tunnel[Z+k_times]; - for( unsigned int i=0; iran_p ) && ( k_times==atomic_number_-Zp1 ) ) { - TotalIonizPot += Potential[atomic_number_-1]; + if (((1.0 - Pint_tunnel) > ran_p) && (k_times == atomic_number_ - Zp1)) { + TotalIonizPot += Potential[atomic_number_ - 1]; k_times++; } - }//END Multiple ionization routine - + } // END Multiple ionization routine + // Compute ionization current - if (b_Jx != NULL){ // For the moment ionization current is not accounted for in AM geometry + if (b_Jx != NULL) { // For the moment ionization current is not accounted for in AM geometry factorJion *= TotalIonizPot; - Jion.x = factorJion * *( Ex+ipart ); - Jion.y = factorJion * *( Ey+ipart ); - Jion.z = factorJion * *( Ez+ipart ); - - Proj->ionizationCurrentsForTasks( b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift ); + Jion.x = factorJion * *(Ex + ipart); + Jion.y = factorJion * *(Ey + ipart); + Jion.z = factorJion * *(Ez + ipart); + + Proj->ionizationCurrentsForTasks(b_Jx, b_Jy, b_Jz, *particles, ipart, Jion, bin_shift); } - + // Creation of the new electrons // (variable weights are used) // ----------------------------- - if( k_times !=0 ) { + if (k_times != 0) { new_electrons_per_bin[ibin].createParticle(); - int idNew = new_electrons_per_bin[ibin].size() - 1;//cout<<"ibin "<position( i, ipart ); + int idNew = new_electrons_per_bin[ibin].size() - + 1; // cout<<"ibin "<position(i, ipart); } - for( unsigned int i=0; i<3; i++ ) { - new_electrons_per_bin[ibin].momentum( i, idNew ) = particles->momentum( i, ipart )*ionized_species_invmass; + for (unsigned int i = 0; i < 3; i++) { + new_electrons_per_bin[ibin].momentum(i, idNew) = particles->momentum(i, ipart) * ionized_species_invmass; } - new_electrons_per_bin[ibin].weight( idNew )=double( k_times )*particles->weight( ipart ); - new_electrons_per_bin[ibin].charge( idNew )=-1; - - if( save_ion_charge_ ) { - ion_charge_per_bin_[ibin].push_back( particles->charge( ipart ) ); + new_electrons_per_bin[ibin].weight(idNew) = double(k_times) * particles->weight(ipart); + new_electrons_per_bin[ibin].charge(idNew) = -1; + + if (save_ion_charge_) { + ion_charge_per_bin_[ibin].push_back(particles->charge(ipart)); } - + // // Increase the charge of the particle - particles->charge( ipart ) += k_times; + particles->charge(ipart) += k_times; } - - } // Loop on particles -} + } // Loop on particles +} #endif From 48c7d11b6f6dfed506de9c30b2411e16bd6e71ec Mon Sep 17 00:00:00 2001 From: GianlucaOberreit Date: Fri, 3 Jan 2025 07:19:02 +0000 Subject: [PATCH 16/17] Fix BSI --- src/Ionization/IonizationBSI.cpp | 65 +++++++++++++++---------------- src/Ionization/IonizationTL.cpp | 12 ++++-- src/Ionization/IonizationTunnel.h | 31 +++++++++++---- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/src/Ionization/IonizationBSI.cpp b/src/Ionization/IonizationBSI.cpp index 1e79c6e70..fcb431e4c 100644 --- a/src/Ionization/IonizationBSI.cpp +++ b/src/Ionization/IonizationBSI.cpp @@ -1,5 +1,5 @@ -#include "IonizationTunnel.h" #include "IonizationTables.h" +#include "IonizationTunnel.h" template <> IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) @@ -7,8 +7,7 @@ IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza DEBUG("Creating the Tunnel BSI Ionizaton class"); // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { + for (int Z = 0; Z < (int)atomic_number_; Z++) { DEBUG("Z : " << Z); Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; @@ -26,37 +25,37 @@ IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza } template <> -double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const int oldZ) +double IonizationTunnel<3>::ionizationRate1(const int Z, const double E) { - auto normal = [this](const int Z, const double E) -> double { - double delta = gamma_tunnel[Z] / E; - return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); - }; - - auto linear = [this](const int Z, const double E) -> double { - const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (0.8 * E * pow(ratio_of_IPs, 0.5)); - }; - auto quadratic = [this](const int Z, const double E) -> double { - const double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); - return au_to_w0 * (2.4 * (pow(E, 2)) * pow(ratio_of_IPs, 2)); - }; - - double BSI_rate_quadratic = quadratic(oldZ+1, E); - double BSI_rate_linear = linear(oldZ+1, E); - double Tunnel_rate = normal(oldZ, E); - - if (BSI_rate_quadratic >= BSI_rate_linear) - { - return linear(Z, E); - } - else if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) - { - return quadratic(Z, E); - } - else - { - return normal(Z, E); + double ratio_of_IPs = IH / IonizationTables::ionization_energy(atomic_number_, Z); + + double BSI_rate_quadratic = 2.4 * (pow(E, 2))*pow(ratio_of_IPs, 2) * au_to_w0; + double BSI_rate_linear = 0.8 * E * pow(ratio_of_IPs, 0.5) * au_to_w0; + double delta = gamma_tunnel[Z] / E; + double Tunnel_rate = beta_tunnel[Z] * exp(-delta / 3.0 + alpha_tunnel[Z] * log(delta)); + + if (std::min(Tunnel_rate, BSI_rate_quadratic) == BSI_rate_quadratic) { + rate_formula = 1; + return BSI_rate_quadratic; + } else if (BSI_rate_quadratic >= BSI_rate_linear) { + rate_formula = 2; + return BSI_rate_quadratic; + } else { + rate_formula = 0; + return Tunnel_rate; } +} +template <> +double IonizationTunnel<3>::ionizationRate2(const int newZ, const double E) +{ + double ratio_of_IPs_newZ = IH / IonizationTables::ionization_energy(atomic_number_, newZ); + double delta = gamma_tunnel[newZ] / E; + if (rate_formula == 1) { + return au_to_w0 * (2.4 * (pow(E, 2))*pow(ratio_of_IPs_newZ, 2)); + } else if (rate_formula == 2) { + return au_to_w0 * (0.8 * E * pow(ratio_of_IPs_newZ, 0.5)); + } else { + return beta_tunnel[newZ] * exp(-delta * one_third + alpha_tunnel[newZ] * log(delta)); + } } diff --git a/src/Ionization/IonizationTL.cpp b/src/Ionization/IonizationTL.cpp index eeee34fdc..e26ba7e49 100644 --- a/src/Ionization/IonizationTL.cpp +++ b/src/Ionization/IonizationTL.cpp @@ -1,5 +1,5 @@ -#include "IonizationTunnel.h" #include "IonizationTables.h" +#include "IonizationTunnel.h" template <> IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) @@ -12,8 +12,7 @@ IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza lambda_tunnel.resize(atomic_number_); // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (int Z = 0; Z < (int)atomic_number_; Z++) - { + for (int Z = 0; Z < (int)atomic_number_; Z++) { DEBUG("Z : " << Z); Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; Azimuthal_quantum_number[Z] = IonizationTables::azimuthal_atomic_number(atomic_number_, Z); @@ -32,9 +31,14 @@ IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza } template <> -double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const int oldZ) +double IonizationTunnel<2>::ionizationRate1(const int Z, const double E) { const double delta = gamma_tunnel[Z] / E; return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta) - E * lambda_tunnel[Z]); } +template <> +double IonizationTunnel<2>::ionizationRate2(const int Z, const double E) +{ + return ionizationRate1(Z, E); +} diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 4ee8b8b01..06451b51a 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -26,7 +26,8 @@ class IonizationTunnel : public Ionization int, int, double *b_Jx, double *b_Jy, double *b_Jz, int ipart_ref = 0) override; private: - inline double ionizationRate(const int Z, const double E, int oldZ); + inline double ionizationRate1(const int Z, const double E); + inline double ionizationRate2(const int Z, const double E); // To be conditionally prepared // FullPPT @@ -39,6 +40,7 @@ class IonizationTunnel : public Ionization // BSI const double au_to_eV = 27.2116; const double IH = 13.598434005136; + int rate_formula; }; template @@ -47,7 +49,7 @@ inline void IonizationTunnel::operator()(Particles *particles, unsigned i { unsigned int Z, Zp1, newZ, k_times; double TotalIonizPot, E, invE, factorJion, ran_p, Mult, D_sum, P_sum, Pint_tunnel; - vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_); + vector IonizRate_tunnel(atomic_number_), Dnom_tunnel(atomic_number_, 0.); LocalFields Jion; double factorJion_0 = au_to_mec2 * EC_to_au * EC_to_au * invdt; @@ -79,7 +81,7 @@ inline void IonizationTunnel::operator()(Particles *particles, unsigned i invE = 1. / E; factorJion = factorJion_0 * invE * invE; ran_p = patch->rand_->uniform(); - IonizRate_tunnel[Z] = ionizationRate(Z, E, Z); + IonizRate_tunnel[Z] = ionizationRate1(Z, E); // Total ionization potential (used to compute the ionization current) TotalIonizPot = 0.0; @@ -109,7 +111,7 @@ inline void IonizationTunnel::operator()(Particles *particles, unsigned i // multiple ionization loop while Pint_tunnel < ran_p and still partial ionization while ((Pint_tunnel < ran_p) and (k_times < atomic_number_ - Zp1)) { newZ = Zp1 + k_times; - IonizRate_tunnel[newZ] = ionizationRate(newZ, E, Z); + IonizRate_tunnel[newZ] = ionizationRate2(newZ, E); D_sum = 0.0; P_sum = 0.0; Mult *= IonizRate_tunnel[Z + k_times]; @@ -118,7 +120,7 @@ inline void IonizationTunnel::operator()(Particles *particles, unsigned i D_sum += Dnom_tunnel[i]; P_sum += exp(-IonizRate_tunnel[Z + i] * dt) * Dnom_tunnel[i]; } - Dnom_tunnel[k_times + 1] = -D_sum; // bug fix + Dnom_tunnel[k_times + 1] -= D_sum; // bug fix P_sum = P_sum + Dnom_tunnel[k_times + 1] * exp(-IonizRate_tunnel[newZ] * dt); Pint_tunnel = Pint_tunnel + P_sum * Mult; @@ -171,7 +173,14 @@ inline void IonizationTunnel::operator()(Particles *particles, unsigned i } template -inline double IonizationTunnel::ionizationRate(const int Z, const double E, const int oldZ) +inline double IonizationTunnel::ionizationRate1(const int Z, const double E) +{ + double delta = gamma_tunnel[Z] / E; + return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); +} + +template +inline double IonizationTunnel::ionizationRate2(const int Z, const double E) { double delta = gamma_tunnel[Z] / E; return beta_tunnel[Z] * exp(-delta * one_third + alpha_tunnel[Z] * log(delta)); @@ -190,14 +199,20 @@ template <> IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species); template <> -double IonizationTunnel<2>::ionizationRate(const int Z, const double E, const int oldZ); +double IonizationTunnel<2>::ionizationRate1(const int Z, const double E); + +template <> +double IonizationTunnel<2>::ionizationRate2(const int Z, const double E); // BSI: 3 template <> IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species); template <> -double IonizationTunnel<3>::ionizationRate(const int Z, const double E, const int oldZ); +double IonizationTunnel<3>::ionizationRate1(const int Z, const double E); + +template <> +double IonizationTunnel<3>::ionizationRate2(const int Z, const double E); template void IonizationTunnel::ionizationTunnelWithTasks(Particles *particles, unsigned int ipart_min, From 50555ffc9c9dcfe473531084914081c08ecf6dee Mon Sep 17 00:00:00 2001 From: GianlucaOberreit Date: Fri, 3 Jan 2025 07:30:08 +0000 Subject: [PATCH 17/17] Move stuff away from Ionization.h --- src/Ionization/Ionization.cpp | 30 ++++++---------------------- src/Ionization/Ionization.h | 5 ----- src/Ionization/IonizationBSI.cpp | 10 ++++++++++ src/Ionization/IonizationFullPPT.cpp | 17 +++++++++++----- src/Ionization/IonizationTL.cpp | 10 ++++++++++ src/Ionization/IonizationTunnel.cpp | 17 +++++++++++----- src/Ionization/IonizationTunnel.h | 5 +++++ 7 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/Ionization/Ionization.cpp b/src/Ionization/Ionization.cpp index bf52b7b79..8ba734f2c 100755 --- a/src/Ionization/Ionization.cpp +++ b/src/Ionization/Ionization.cpp @@ -22,17 +22,6 @@ Ionization::Ionization(Params ¶ms, Species *species) EC_to_au = 3.314742578e-15 * reference_angular_frequency_SI; // hbar omega / (me c^2 alpha^3) au_to_w0 = 4.134137172e+16 / reference_angular_frequency_SI; // alpha^2 me c^2 / (hbar omega) - atomic_number_ = species->atomic_number_; - Potential.resize(atomic_number_); - Azimuthal_quantum_number.resize(atomic_number_); - - one_third = 1.0 / 3.0; - - alpha_tunnel.resize(atomic_number_); - beta_tunnel.resize(atomic_number_); - gamma_tunnel.resize(atomic_number_); - - #ifdef _OMPTASKS new_electrons_per_bin = new Particles[species->Nbins]; ion_charge_per_bin_.resize(species->Nbins); @@ -50,40 +39,33 @@ void Ionization::joinNewElectrons(unsigned int Nbins) // Resize new_electrons size_t total_n_new = 0; - for (size_t ibin = 0; ibin < Nbins; ibin++) - { + for (size_t ibin = 0; ibin < Nbins; ibin++) { total_n_new += new_electrons_per_bin[ibin].size(); } new_electrons.createParticles(total_n_new); // Also resize ion_charge_ if necessary - if (save_ion_charge_) - { + if (save_ion_charge_) { ion_charge_.resize(start + total_n_new); } // Move each new_electrons_per_bin into new_electrons - for (size_t ibin = 0; ibin < Nbins; ibin++) - { + for (size_t ibin = 0; ibin < Nbins; ibin++) { size_t n_new = new_electrons_per_bin[ibin].size(); - for (size_t i = 0; i < new_electrons.dimension(); i++) - { + for (size_t i = 0; i < new_electrons.dimension(); i++) { copy(&new_electrons_per_bin[ibin].position(i, 0), &new_electrons_per_bin[ibin].position(i, n_new), &new_electrons.position(i, start)); } - for (size_t i = 0; i < new_electrons.dimension(); i++) - { + for (size_t i = 0; i < new_electrons.dimension(); i++) { copy(&new_electrons_per_bin[ibin].momentum(i, 0), &new_electrons_per_bin[ibin].momentum(i, n_new), &new_electrons.momentum(i, start)); } copy(&new_electrons_per_bin[ibin].weight(0), &new_electrons_per_bin[ibin].weight(n_new), &new_electrons.weight(start)); copy(&new_electrons_per_bin[ibin].charge(0), &new_electrons_per_bin[ibin].charge(n_new), &new_electrons.charge(start)); new_electrons_per_bin[ibin].clear(); - if (save_ion_charge_) - { + if (save_ion_charge_) { copy(ion_charge_per_bin_[ibin].begin(), ion_charge_per_bin_[ibin].end(), ion_charge_.begin() + start); ion_charge_per_bin_[ibin].clear(); } start += n_new; } } - diff --git a/src/Ionization/Ionization.h b/src/Ionization/Ionization.h index 6ce28719c..61004857a 100755 --- a/src/Ionization/Ionization.h +++ b/src/Ionization/Ionization.h @@ -47,7 +47,6 @@ class Ionization double au_to_mec2; double EC_to_au; double au_to_w0; - double one_third; double reference_angular_frequency_SI; double dt; @@ -56,10 +55,6 @@ class Ionization unsigned int nDim_particle; double ionized_species_invmass; - unsigned int atomic_number_; - std::vector Potential, Azimuthal_quantum_number; - std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; - private: }; diff --git a/src/Ionization/IonizationBSI.cpp b/src/Ionization/IonizationBSI.cpp index fcb431e4c..abbac99f5 100644 --- a/src/Ionization/IonizationBSI.cpp +++ b/src/Ionization/IonizationBSI.cpp @@ -6,6 +6,16 @@ IonizationTunnel<3>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza { DEBUG("Creating the Tunnel BSI Ionizaton class"); + atomic_number_ = species->atomic_number_; + Potential.resize(atomic_number_); + Azimuthal_quantum_number.resize(atomic_number_); + + one_third = 1.0 / 3.0; + + alpha_tunnel.resize(atomic_number_); + beta_tunnel.resize(atomic_number_); + gamma_tunnel.resize(atomic_number_); + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) for (int Z = 0; Z < (int)atomic_number_; Z++) { DEBUG("Z : " << Z); diff --git a/src/Ionization/IonizationFullPPT.cpp b/src/Ionization/IonizationFullPPT.cpp index d51de62cf..40d6d81cb 100644 --- a/src/Ionization/IonizationFullPPT.cpp +++ b/src/Ionization/IonizationFullPPT.cpp @@ -1,16 +1,25 @@ -#include "IonizationTunnel.h" #include "IonizationTables.h" +#include "IonizationTunnel.h" template <> IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ionization(params, species) { DEBUG("Creating the Tunnel Ionizaton class"); + atomic_number_ = species->atomic_number_; + Potential.resize(atomic_number_); + Azimuthal_quantum_number.resize(atomic_number_); + + one_third = 1.0 / 3.0; + + alpha_tunnel.resize(atomic_number_); + beta_tunnel.resize(atomic_number_); + gamma_tunnel.resize(atomic_number_); + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) Magnetic_quantum_number.resize(atomic_number_); - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { + for (unsigned int Z = 0; Z < atomic_number_; Z++) { DEBUG("Z : " << Z); Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; @@ -31,5 +40,3 @@ IonizationTunnel<1>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza DEBUG("Finished Creating the Tunnel Ionizaton class"); } - - diff --git a/src/Ionization/IonizationTL.cpp b/src/Ionization/IonizationTL.cpp index e26ba7e49..bf43c20a6 100644 --- a/src/Ionization/IonizationTL.cpp +++ b/src/Ionization/IonizationTL.cpp @@ -6,6 +6,16 @@ IonizationTunnel<2>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza { DEBUG("Creating the Tong-Lin Tunnel Ionizaton class"); + atomic_number_ = species->atomic_number_; + Potential.resize(atomic_number_); + Azimuthal_quantum_number.resize(atomic_number_); + + one_third = 1.0 / 3.0; + + alpha_tunnel.resize(atomic_number_); + beta_tunnel.resize(atomic_number_); + gamma_tunnel.resize(atomic_number_); + ionization_tl_parameter_ = species->ionization_tl_parameter_; // species->ionization_tl_parameter_ is double // Varies from 6 to 9. This is the alpha parameter in Tong-Lin exponential, see Eq. (6) in [M F Ciappina and S V Popruzhenko 2020 Laser Phys. Lett. 17 025301 2020]. diff --git a/src/Ionization/IonizationTunnel.cpp b/src/Ionization/IonizationTunnel.cpp index 2bd478f89..ddbd51f64 100644 --- a/src/Ionization/IonizationTunnel.cpp +++ b/src/Ionization/IonizationTunnel.cpp @@ -1,6 +1,6 @@ #include "IonizationTunnel.h" -#include "IonizationTables.h" +#include "IonizationTables.h" // Classic: 1 template <> @@ -8,9 +8,18 @@ IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza { DEBUG("Creating the Tunnel Ionizaton class"); + atomic_number_ = species->atomic_number_; + Potential.resize(atomic_number_); + Azimuthal_quantum_number.resize(atomic_number_); + + one_third = 1.0 / 3.0; + + alpha_tunnel.resize(atomic_number_); + beta_tunnel.resize(atomic_number_); + gamma_tunnel.resize(atomic_number_); + // Ionization potential & quantum numbers (all in atomic units 1 au = 27.2116 eV) - for (unsigned int Z = 0; Z < atomic_number_; Z++) - { + for (unsigned int Z = 0; Z < atomic_number_; Z++) { DEBUG("Z : " << Z); Potential[Z] = IonizationTables::ionization_energy(atomic_number_, Z) * eV_to_au; @@ -27,5 +36,3 @@ IonizationTunnel<0>::IonizationTunnel(Params ¶ms, Species *species) : Ioniza DEBUG("Finished Creating the Tunnel Ionizaton class"); } - - diff --git a/src/Ionization/IonizationTunnel.h b/src/Ionization/IonizationTunnel.h index 06451b51a..0d483c616 100644 --- a/src/Ionization/IonizationTunnel.h +++ b/src/Ionization/IonizationTunnel.h @@ -29,6 +29,11 @@ class IonizationTunnel : public Ionization inline double ionizationRate1(const int Z, const double E); inline double ionizationRate2(const int Z, const double E); + double one_third; + unsigned int atomic_number_; + std::vector Potential, Azimuthal_quantum_number; + std::vector alpha_tunnel, beta_tunnel, gamma_tunnel; + // To be conditionally prepared // FullPPT std::vector Magnetic_quantum_number;