|
7 | 7 | # |
8 | 8 | # This file is part of the code: |
9 | 9 | # |
10 | | -# PyECLOUD Version 6.7.2 |
| 10 | +# PyECLOUD Version 7.0.0 |
11 | 11 | # |
12 | 12 | # |
13 | 13 | # Main author: Giovanni IADAROLA |
@@ -62,29 +62,23 @@ class MP_light(object): |
62 | 62 |
|
63 | 63 | class Ecloud_fastion(Ecloud): |
64 | 64 |
|
65 | | - def __init__(self, L_ecloud, slicer, Dt_ref, MP_e_mass, MP_e_charge, pyecl_input_folder = './', |
| 65 | + def __init__(self, L_ecloud, slicer, Dt_ref, pyecl_input_folder = './', |
66 | 66 | flag_clean_slices = False, slice_by_slice_mode = False, space_charge_obj = None, |
67 | 67 | beam_monitor = None, include_cloud_sc = False, ionize_only_first_bunch = False, **kwargs): |
68 | 68 |
|
69 | 69 |
|
70 | 70 | super(Ecloud_fastion, self).__init__(L_ecloud, slicer, Dt_ref, pyecl_input_folder = pyecl_input_folder, |
71 | 71 | flag_clean_slices = flag_clean_slices, slice_by_slice_mode = slice_by_slice_mode, |
72 | | - space_charge_obj = space_charge_obj, MP_e_mass = MP_e_mass, |
73 | | - MP_e_charge = MP_e_charge, **kwargs) |
| 72 | + space_charge_obj = space_charge_obj, **kwargs) |
74 | 73 |
|
75 | 74 | self.beam_monitor = beam_monitor |
76 | | - self.gas_ion_flag = kwargs['gas_ion_flag'] |
77 | 75 | self.include_cloud_sc = include_cloud_sc |
78 | 76 | self.ionize_only_first_bunch = ionize_only_first_bunch |
79 | 77 |
|
80 | 78 | self.MP_e_field_state = self.spacech_ele.PyPICobj.get_state_object() |
81 | 79 | self.MP_p_field_state = self.spacech_ele.PyPICobj.get_state_object() |
82 | 80 |
|
83 | | - if self.gas_ion_flag == 1: |
84 | | - chamb = self.impact_man.chamb |
85 | | - gas_ionization = residual_gas_ionization(kwargs['unif_frac'], kwargs['P_nTorr'], kwargs['sigma_ion_MBarn'], |
86 | | - kwargs['Temp_K'], chamb, kwargs['E_init_ion']) |
87 | | - self.gas_ionization = gas_ionization |
| 81 | + self.gas_ionization = self.resgasion |
88 | 82 |
|
89 | 83 |
|
90 | 84 |
|
@@ -112,7 +106,7 @@ def track(self, beam): |
112 | 106 | # Only track over slices with particles |
113 | 107 | filled_slices = np.where(slices.n_macroparticles_per_slice > 0)[0] |
114 | 108 |
|
115 | | - for i in filled_slices[::-1]: |
| 109 | + for i in xrange(slices.n_slices-1, -1, -1): |
116 | 110 |
|
117 | 111 | # select particles in the bunch |
118 | 112 | ix = slices.particle_indices_of_slice(i) |
@@ -163,112 +157,107 @@ def generate_twin_ecloud_with_shared_space_charge(self): |
163 | 157 | #@profile |
164 | 158 | def _track_single_slice(self, beam, ix, dz): |
165 | 159 |
|
166 | | - #pass |
167 | | - if len(ix) > 0: |
168 | | - |
169 | | - MP_e = self.MP_e |
170 | | - dynamics = self.dynamics |
171 | | - impact_man = self.impact_man |
172 | | - spacech_ele = self.spacech_ele |
173 | | - MP_e_state = self.MP_e_field_state |
174 | | - MP_p_state = self.MP_p_field_state |
175 | | - |
176 | | - dt = dz / (beam.beta * c) |
177 | | - |
178 | | - # define substep |
179 | | - if dt > self.Dt_ref: |
180 | | - N_sub_steps = int(np.round(dt / self.Dt_ref)) |
181 | | - else: |
182 | | - N_sub_steps = 1 |
183 | | - |
184 | | - Dt_substep = dt / N_sub_steps |
185 | | - # print Dt_substep, N_sub_steps, dt |
186 | | - |
187 | | - # beam particles |
188 | | - MP_p = MP_light() |
189 | | - MP_p.x_mp = beam.x[ix] |
190 | | - MP_p.y_mp = beam.y[ix] |
191 | | - MP_p.nel_mp = beam.x[ix] * 0. + beam.particlenumber_per_mp |
192 | | - MP_p.N_mp = len(beam.x[ix]) |
193 | | - MP_p.charge = beam.charge |
194 | | - |
195 | | - mean_x = np.mean(beam.x[ix]) |
196 | | - mean_y = np.mean(beam.y[ix]) |
197 | | - sigma_x = np.std(beam.x[ix]) |
198 | | - sigma_y = np.std(beam.y[ix]) |
199 | | - |
200 | | - if self.gas_ion_flag == 1: |
201 | | - Np_bunch = MP_p.N_mp * beam.particlenumber_per_mp |
202 | | - dz_bunch = dz |
203 | | - lambda_bunch = Np_bunch |
204 | | - dt_bunch = 1 / c |
205 | | - MP_e = self.gas_ionization.generate(MP_e=MP_e, lambda_t=lambda_bunch, Dt=dt_bunch, sigmax=sigma_x, |
206 | | - sigmay=sigma_y, x_beam_pos=mean_x, y_beam_pos=mean_y) |
207 | | - if self.ionize_only_first_bunch: |
208 | | - self.gas_ion_flag = 0 |
209 | | - |
210 | | - # scatter fields |
211 | | - MP_e_state.scatter(MP_e.x_mp[0:MP_e.N_mp],MP_e.y_mp[0:MP_e.N_mp],MP_e.nel_mp[0:MP_e.N_mp], charge = MP_e.charge) |
212 | | - MP_p_state.scatter(MP_p.x_mp[0:MP_p.N_mp],MP_p.y_mp[0:MP_p.N_mp],MP_p.nel_mp[0:MP_p.N_mp], charge = MP_p.charge) |
213 | | - |
214 | | - # solve fields |
215 | | - spacech_ele.PyPICobj.solve_states([MP_e_state, MP_p_state]) |
216 | | - |
217 | | - # gather fields |
218 | | - Ex_sc_p, Ey_sc_p = MP_e_state.gather(MP_p.x_mp[0:MP_p.N_mp],MP_p.y_mp[0:MP_p.N_mp]) |
219 | | - Ex_n_beam, Ey_n_beam = MP_p_state.gather(MP_e.x_mp[0:MP_e.N_mp],MP_e.y_mp[0:MP_e.N_mp]) |
220 | | - |
221 | | - # kick cloud particles |
222 | | - MP_e.vx_mp[:MP_e.N_mp] += Ex_n_beam * MP_e.charge / MP_e.mass / c |
223 | | - MP_e.vy_mp[:MP_e.N_mp] += Ey_n_beam * MP_e.charge / MP_e.mass / c |
224 | | - |
225 | | - # kick beam particles |
226 | | - fact_kick = beam.charge / (beam.mass * beam.beta * beam.beta * beam.gamma * c * c) * self.L_ecloud |
227 | | - beam.xp[ix] += fact_kick * Ex_sc_p |
228 | | - beam.yp[ix] += fact_kick * Ey_sc_p |
229 | | - |
230 | | - |
231 | | - # Total electric field on electrons |
232 | | - if self.include_cloud_sc: |
233 | | - Ex_sc_n, Ey_sc_n = MP_e_state.gather(MP_e.x_mp[0:MP_e.N_mp],MP_e.y_mp[0:MP_e.N_mp]) |
234 | | - Ex_n = Ex_sc_n |
235 | | - Ey_n = Ey_sc_n |
236 | | - else: |
237 | | - Ex_n = MP_e.vx_mp[:MP_e.N_mp] * 0. |
238 | | - Ey_n = Ex_n |
239 | | - |
240 | | - # save position before motion step |
241 | | - old_pos = MP_e.get_positions() |
242 | | - |
243 | | - # motion electrons |
244 | | - MP_e = dynamics.stepcustomDt(MP_e, Ex_n,Ey_n, Dt_substep=Dt_substep, N_sub_steps=N_sub_steps) |
245 | | - |
246 | | - # impacts: backtracking and secondary emission |
247 | | - MP_e = impact_man.backtrack_and_second_emiss(old_pos, MP_e) |
248 | | - |
249 | | - |
250 | | - if self.save_ele_distributions_last_track: |
251 | | - self.rho_ele_last_track.append(spacech_ele.rho.copy()) |
252 | | - #print 'Here' |
253 | | - |
254 | | - if self.save_ele_potential_and_field: |
255 | | - self.phi_ele_last_track.append(spacech_ele.phi.copy()) |
256 | | - self.Ex_ele_last_track.append(spacech_ele.efx.copy()) |
257 | | - self.Ey_ele_last_track.append(spacech_ele.efy.copy()) |
258 | | - |
259 | | - if self.save_ele_MP_position: |
260 | | - self.x_MP_last_track.append(MP_e.x_mp.copy()) |
261 | | - self.y_MP_last_track.append(MP_e.y_mp.copy()) |
262 | | - |
263 | | - if self.save_ele_MP_velocity: |
264 | | - self.vx_MP_last_track.append(MP_e.vx_mp.copy()) |
265 | | - self.vy_MP_last_track.append(MP_e.vy_mp.copy()) |
266 | | - |
267 | | - if self.save_ele_MP_size: |
268 | | - self.nel_MP_last_track.append(MP_e.nel_mp.copy()) |
269 | | - |
270 | | - if self.save_ele_MP_position or self.save_ele_MP_velocity or self.save_ele_MP_size: |
271 | | - self.N_MP_last_track.append(MP_e.N_mp) |
| 160 | + MP_e = self.MP_e |
| 161 | + dynamics = self.dynamics |
| 162 | + impact_man = self.impact_man |
| 163 | + spacech_ele = self.spacech_ele |
| 164 | + MP_e_state = self.MP_e_field_state |
| 165 | + MP_p_state = self.MP_p_field_state |
| 166 | + |
| 167 | + dt = dz / (beam.beta * c) |
| 168 | + |
| 169 | + # define substep |
| 170 | + if dt > self.Dt_ref: |
| 171 | + N_sub_steps = int(np.round(dt / self.Dt_ref)) |
| 172 | + else: |
| 173 | + N_sub_steps = 1 |
| 174 | + |
| 175 | + Dt_substep = dt / N_sub_steps |
| 176 | + # print Dt_substep, N_sub_steps, dt |
| 177 | + |
| 178 | + # beam particles |
| 179 | + MP_p = MP_light() |
| 180 | + MP_p.x_mp = beam.x[ix] |
| 181 | + MP_p.y_mp = beam.y[ix] |
| 182 | + MP_p.nel_mp = beam.x[ix] * 0. + beam.particlenumber_per_mp |
| 183 | + MP_p.N_mp = len(beam.x[ix]) |
| 184 | + MP_p.charge = beam.charge |
| 185 | + |
| 186 | + mean_x = np.mean(beam.x[ix]) |
| 187 | + mean_y = np.mean(beam.y[ix]) |
| 188 | + sigma_x = np.std(beam.x[ix]) |
| 189 | + sigma_y = np.std(beam.y[ix]) |
272 | 190 |
|
| 191 | + if self.gas_ion_flag == 1: |
| 192 | + Np_bunch = MP_p.N_mp * beam.particlenumber_per_mp |
| 193 | + dz_bunch = dz |
| 194 | + lambda_bunch = Np_bunch |
| 195 | + dt_bunch = 1 / c |
| 196 | + MP_e = self.gas_ionization.generate(MP_e=MP_e, lambda_t=lambda_bunch, Dt=dt_bunch, sigmax=sigma_x, |
| 197 | + sigmay=sigma_y, x_beam_pos=mean_x, y_beam_pos=mean_y) |
| 198 | + if self.ionize_only_first_bunch: |
| 199 | + self.gas_ion_flag = 0 |
| 200 | + |
| 201 | + # scatter fields |
| 202 | + MP_e_state.scatter(MP_e.x_mp[0:MP_e.N_mp],MP_e.y_mp[0:MP_e.N_mp],MP_e.nel_mp[0:MP_e.N_mp], charge = MP_e.charge) |
| 203 | + MP_p_state.scatter(MP_p.x_mp[0:MP_p.N_mp],MP_p.y_mp[0:MP_p.N_mp],MP_p.nel_mp[0:MP_p.N_mp], charge = MP_p.charge) |
| 204 | + |
| 205 | + # solve fields |
| 206 | + spacech_ele.PyPICobj.solve_states([MP_e_state, MP_p_state]) |
| 207 | + |
| 208 | + # gather fields |
| 209 | + Ex_sc_p, Ey_sc_p = MP_e_state.gather(MP_p.x_mp[0:MP_p.N_mp],MP_p.y_mp[0:MP_p.N_mp]) |
| 210 | + Ex_n_beam, Ey_n_beam = MP_p_state.gather(MP_e.x_mp[0:MP_e.N_mp],MP_e.y_mp[0:MP_e.N_mp]) |
| 211 | + |
| 212 | + # kick cloud particles |
| 213 | + MP_e.vx_mp[:MP_e.N_mp] += Ex_n_beam * MP_e.charge / MP_e.mass / c |
| 214 | + MP_e.vy_mp[:MP_e.N_mp] += Ey_n_beam * MP_e.charge / MP_e.mass / c |
| 215 | + |
| 216 | + # kick beam particles |
| 217 | + fact_kick = beam.charge / (beam.mass * beam.beta * beam.beta * beam.gamma * c * c) * self.L_ecloud |
| 218 | + beam.xp[ix] += fact_kick * Ex_sc_p |
| 219 | + beam.yp[ix] += fact_kick * Ey_sc_p |
| 220 | + |
| 221 | + |
| 222 | + # Total electric field on electrons |
| 223 | + if self.include_cloud_sc: |
| 224 | + Ex_sc_n, Ey_sc_n = MP_e_state.gather(MP_e.x_mp[0:MP_e.N_mp],MP_e.y_mp[0:MP_e.N_mp]) |
| 225 | + Ex_n = Ex_sc_n |
| 226 | + Ey_n = Ey_sc_n |
273 | 227 | else: |
274 | | - pass |
| 228 | + Ex_n = MP_e.vx_mp[:MP_e.N_mp] * 0. |
| 229 | + Ey_n = Ex_n |
| 230 | + |
| 231 | + # save position before motion step |
| 232 | + old_pos = MP_e.get_positions() |
| 233 | + |
| 234 | + # motion electrons |
| 235 | + MP_e = dynamics.stepcustomDt(MP_e, Ex_n,Ey_n, Dt_substep=Dt_substep, N_sub_steps=N_sub_steps) |
| 236 | + |
| 237 | + # impacts: backtracking and secondary emission |
| 238 | + MP_e = impact_man.backtrack_and_second_emiss(old_pos, MP_e) |
| 239 | + |
| 240 | + |
| 241 | + if self.save_ele_distributions_last_track: |
| 242 | + self.rho_ele_last_track.append(spacech_ele.rho.copy()) |
| 243 | + #print 'Here' |
| 244 | + |
| 245 | + if self.save_ele_potential_and_field: |
| 246 | + self.phi_ele_last_track.append(spacech_ele.phi.copy()) |
| 247 | + self.Ex_ele_last_track.append(spacech_ele.efx.copy()) |
| 248 | + self.Ey_ele_last_track.append(spacech_ele.efy.copy()) |
| 249 | + |
| 250 | + if self.save_ele_MP_position: |
| 251 | + self.x_MP_last_track.append(MP_e.x_mp.copy()) |
| 252 | + self.y_MP_last_track.append(MP_e.y_mp.copy()) |
| 253 | + |
| 254 | + if self.save_ele_MP_velocity: |
| 255 | + self.vx_MP_last_track.append(MP_e.vx_mp.copy()) |
| 256 | + self.vy_MP_last_track.append(MP_e.vy_mp.copy()) |
| 257 | + |
| 258 | + if self.save_ele_MP_size: |
| 259 | + self.nel_MP_last_track.append(MP_e.nel_mp.copy()) |
| 260 | + |
| 261 | + if self.save_ele_MP_position or self.save_ele_MP_velocity or self.save_ele_MP_size: |
| 262 | + self.N_MP_last_track.append(MP_e.N_mp) |
| 263 | + |
0 commit comments