Skip to content

Commit 08c5cec

Browse files
committed
Merge branch 'develop' into python3_master
2 parents 0d30755 + f4a83b0 commit 08c5cec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+347
-82
lines changed

000_run_simulation.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import sys, os
2-
BIN = os.path.expanduser("../")
3-
sys.path.append(BIN)
4-
5-
61
from PyECLOUD.buildup_simulation import BuildupSimulation
72

8-
93
sim = BuildupSimulation()
104
sim.run()

002_change_version_number.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
with open(filename) as fid:
1010
content = fid.read()
1111
if 'giovanni.iadarola@cern.ch' in content:
12-
content = content.replace('PyECLOUD Version 8.3.0', 'PyECLOUD Version 8.3.0')
12+
content = content.replace('PyECLOUD Version 8.4.0', 'PyECLOUD Version 8.4.0')
1313
with open(filename, 'w') as fid:
1414
fid.write(content)
1515

003_change_preamble.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#
2121
# This file is part of the code:
2222
#
23-
# PyECLOUD Version 8.3.0
23+
# PyECLOUD Version 8.4.0
2424
#
2525
#
2626
# Main author: Giovanni IADAROLA

MP_system.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

PyEC4PyHT.py

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA
@@ -66,6 +66,8 @@ class Empty(object):
6666

6767

6868
class DummyBeamTim(object):
69+
"""Dummy beam-timing class to interface with buildup simulation"""
70+
6971
def __init__(self, PyPIC_state):
7072
self.PyPIC_state = PyPIC_state
7173

@@ -100,6 +102,8 @@ def get_beam_eletric_field(self, MP_e):
100102

101103
class Ecloud(object):
102104
def generate_twin_ecloud_with_shared_space_charge(self):
105+
"""Generate an identical Ecloud objet with shared space-charge member."""
106+
103107
if hasattr(self, "efieldmap"):
104108
raise ValueError(
105109
"Ecloud has been replaced with field map. I cannot generate a twin ecloud!"
@@ -136,8 +140,105 @@ def __init__(
136140
force_interp_at_substeps_interacting_slices=False,
137141
**kwargs
138142
):
143+
"""
144+
Construct an e-cloud object that can be inserted in a PyHEADTAIL machine
145+
146+
Parameters
147+
---------
148+
149+
L_ecloud : m
150+
Length of the e-cloud interaction
151+
152+
slicer :
153+
PyHEADTAIL slicer object, used to define slices for e-cloud insteraction.
154+
Needs to be provided only if slice_by_slice_mode is False.
155+
156+
Dt_ref : s
157+
Target duration of the sub-steps perfomed in each slice.
158+
159+
pyecl_input_folder : path
160+
Folder containing the PyECLOUD input files defining the e-cloud.
161+
162+
flag_clean_slices : {True, False}
163+
If True, slicing is redone before the e-cloud interation.
164+
This flag has no effect is slice_by_slice_mode is True.
165+
166+
slice_by_slice_mode : {True, False}
167+
168+
- If False, the e-cloud receives a full bunch, slicing is done interally,
169+
the cloud is automatically re-initialized after each interaction.
170+
- If True, the e-cloud receives one slice at a time (the slice object
171+
should have metadata in a member called slice_info. The reinitialization
172+
of the cloud is done based on the meta-data or esplicitly by the user.
173+
174+
space_charge_obj :
175+
176+
- If None a space-charge object (Particle In Cell) is constructed for
177+
the e-cloud
178+
- If not None the provided space-charge objeci is used
179+
180+
kick_mode_for_beam_field : {True, False}
181+
If True, the force of the beam on the electrons is applied as a
182+
discrete kick (used mainly for fast beam-ion simulations).
183+
184+
beam_monitor :
185+
PyHEADTAIL beam-monitor, used sometimes for debug purposes.
186+
187+
verbose : {True, False}
188+
189+
save_pyecl_outp_as : path
190+
File in which cloud evolution is stored.
191+
192+
force_reinterp_at_substeps_interacting_slices : {True, False}
193+
Fields from beams and clouds are re-interpolated at each subsstep.
194+
195+
x_beam_offset : m
196+
Horizontal position of the PyHEADTAIL reference trajectoy in
197+
the PyECLOUD referece system.
198+
199+
y_beam_offset: m
200+
Vertical position of the PyHEADTAIL reference trajectoy in
201+
the PyECLOUD referece system.
202+
203+
probes_position : dict
204+
Positions at which electron density and field can be measured.
205+
206+
enable_kick_x :
207+
Enable horizontal kick from the cloud on the beam.
208+
209+
enable_kick_y :
210+
Enable vertical kick from the cloud on the beam.
211+
212+
**kwargs :
213+
Any input parameter of PyECLOUD can be passes as a keyword arguments.
214+
Parameters definded in the input files are overridden by those passas as
215+
keyword arguments.
216+
217+
Additional information
218+
----------------------
219+
After building the object, the following members can be set to true to record
220+
additional information (which is then attached as a member to the ecloud object
221+
itself. After setting any of these ot true the [ecloud]._reinitialize
222+
function needs to be called to prepare the data storage, which also resets cloud
223+
state.
224+
225+
[ecloud].save_ele_distributions_last_track
226+
[ecloud].save_ele_potential_and_field
227+
[ecloud].save_ele_potential
228+
[ecloud].save_ele_field
229+
[ecloud].save_ele_MP_position
230+
[ecloud].save_ele_MP_velocity
231+
[ecloud].save_ele_MP_size
232+
233+
[ecloud].save_beam_distributions_last_track
234+
[ecloud].save_beam_potential_and_field
235+
[ecloud].save_beam_potential
236+
[ecloud].save_beam_field
237+
238+
239+
"""
139240

140-
print("PyECLOUD Version 8.3.0")
241+
print("PyECLOUD Version 8.4.0")
141242

142243
# These git commands return the hash and the branch of the specified git directory.
143244
path_to_git = os.path.dirname(os.path.abspath(__file__)) + "/.git"
@@ -264,6 +365,7 @@ def __init__(
264365

265366
self.slice_by_slice_mode = slice_by_slice_mode
266367
if self.slice_by_slice_mode:
368+
assert(slicer is None)
267369
self.track = self._track_in_single_slice_mode
268370
self.finalize_and_reinitialize = self._finalize_and_reinitialize
269371

beam_and_timing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

buildup_simulation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#
1010
# This file is part of the code:
1111
#
12-
# PyECLOUD Version 8.3.0
12+
# PyECLOUD Version 8.4.0
1313
#
1414
#
1515
# Main author: Giovanni IADAROLA
@@ -71,7 +71,7 @@ def __init__(
7171
**kwargs
7272
):
7373

74-
print("PyECLOUD Version 8.3.0")
74+
print("PyECLOUD Version 8.4.0")
7575
(
7676
beamtim,
7777
spacech_ele,

cloud_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Author and contact: Giovanni IADAROLA

cross_ionization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

default_input_parameters.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@
149149
'B_map_file': None,
150150
'Bz_map_file': None, # documented?
151151
'fact_Bmap': 1.,
152-
'B0x': 0.,
153-
'B0y': 0.,
154-
'B0z': 0.,
152+
'B0x': None,
153+
'B0y': None,
154+
'B0z': None,
155155
'B_zero_thrhld': None,
156156
'N_sub_steps': 1,
157157
'B_multip': [],

doc/reference/reference.pdf

61 Bytes
Binary file not shown.

doc/reference/src/reference.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ \subsection{Simulation parameters}
416416
\\ \hline
417417
\textbf{B\_skew} & The skew parameters can be included through B\_skew. For a skew quadrupole with a gradient of 12 T/m, set B\_multip to [0.,0.] and B\_skew to [0.,12.].
418418
B\_skew specifies $b'_n =\frac{\partial^n B_x}{\partial x^n}$ and defaults to {\it None}. \\ \hline
419+
\textbf{B0x, B0y, B0z} & (optional -- default = 0) \newline
420+
[T] Uniform magnetic fields added to the map.
421+
\\ \hline
419422
\end{longtable}
420423

421424

dynamics_Boris_f2py.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

dynamics_Boris_multipole.py

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA
@@ -57,7 +57,8 @@
5757

5858
class pusher_Boris_multipole():
5959

60-
def __init__(self, Dt, N_sub_steps=1, B_multip=None, B_skew=None):
60+
def __init__(self, Dt, N_sub_steps=1, B_multip=None, B_skew=None,
61+
B0x=None, B0y=None, B0z=None):
6162

6263
self.N_sub_steps = N_sub_steps
6364
self.Dt = Dt
@@ -79,40 +80,47 @@ def __init__(self, Dt, N_sub_steps=1, B_multip=None, B_skew=None):
7980
else:
8081
self.B_field_skew = np.array(B_skew, dtype=float) / factorial
8182

83+
self.B0x = B0x
84+
self.B0y = B0y
85+
self.B0z = B0z
8286
print("Tracker: Boris multipole")
8387

8488
print("N_subst_init=%d" % self.N_sub_steps)
8589

8690
#@profile
87-
def step(self, MP_e, Ex_n, Ey_n, Ez_n=0., Bx_n=np.asarray([0.]), By_n=np.asarray([0.]), Bz_n=np.asarray([0.])):
88-
89-
if (Bx_n == np.asarray([0.])).all() and (By_n == np.asarray([0.])).all() and (Bz_n == np.asarray([0.])).all():
90-
custom_B = 0
91-
else:
92-
custom_B = 1
93-
94-
if MP_e.N_mp > 0:
95-
96-
xn1 = MP_e.x_mp[0:MP_e.N_mp]
97-
yn1 = MP_e.y_mp[0:MP_e.N_mp]
98-
zn1 = MP_e.z_mp[0:MP_e.N_mp]
99-
vxn1 = MP_e.vx_mp[0:MP_e.N_mp]
100-
vyn1 = MP_e.vy_mp[0:MP_e.N_mp]
101-
vzn1 = MP_e.vz_mp[0:MP_e.N_mp]
102-
if Ez_n != 0.:
103-
raise ValueError('Oooops! Not implemented....')
91+
def step(self, MP_e, Ex_n, Ey_n, Ez_n=0., Bx_n=None, By_n=None, Bz_n=None):
92+
MP_e = self.stepcustomDt(MP_e, Ex_n, Ey_n, Ez_n,
93+
Bx_n, By_n, Bz_n,
94+
Dt_substep=self.Dtt, N_sub_steps=self.N_sub_steps)
95+
return MP_e
10496

105-
boris_step_multipole(self.N_sub_steps, self.Dtt, self.B_field, self.B_field_skew,
106-
xn1, yn1, zn1, vxn1, vyn1, vzn1,
107-
Ex_n, Ey_n, Bx_n, By_n, Bz_n, custom_B, MP_e.charge, MP_e.mass)
97+
def stepcustomDt(self, MP_e, Ex_n, Ey_n, Ez_n=0.,
98+
Bx_n=None, By_n=None, Bz_n=None,
99+
Dt_substep=None, N_sub_steps=None):
108100

109-
return MP_e
101+
custom_B = 0
102+
Bx_arr = np.zeros(MP_e.N_mp)
103+
By_arr = np.zeros(MP_e.N_mp)
104+
Bz_arr = np.zeros(MP_e.N_mp)
110105

111-
def stepcustomDt(self, MP_e, Ex_n, Ey_n, Ez_n=0., Bx_n=np.asarray([0.]), By_n=np.asarray([0.]), Bz_n=np.asarray([0.]), Dt_substep=None, N_sub_steps=None):
106+
if self.B0x is not None:
107+
Bx_arr += self.B0x
108+
custom_B = 1
109+
if self.B0y is not None:
110+
By_arr += self.B0y
111+
custom_B = 1
112+
if self.B0z is not None:
113+
Bz_arr += self.B0z
114+
custom_B = 1
112115

113-
if (Bx_n == np.asarray([0.])).all() and (By_n == np.asarray([0.])).all() and (Bz_n == np.asarray([0.])).all():
114-
custom_B = 0
115-
else:
116+
if Bx_n is not None:
117+
Bx_arr += Bx_n
118+
custom_B = 1
119+
if By_n is not None:
120+
By_arr += By_n
121+
custom_B = 1
122+
if Bz_n is not None:
123+
Bz_arr += Bz_n
116124
custom_B = 1
117125

118126
if MP_e.N_mp > 0:
@@ -128,7 +136,7 @@ def stepcustomDt(self, MP_e, Ex_n, Ey_n, Ez_n=0., Bx_n=np.asarray([0.]), By_n=np
128136
raise ValueError('Oooops! Not implemented....')
129137

130138
boris_step_multipole(N_sub_steps, Dt_substep, self.B_field, self.B_field_skew,
131-
xn1, yn1, zn1, vxn1, vyn1, vzn1,
132-
Ex_n, Ey_n, Bx_n, By_n, Bz_n, custom_B, MP_e.charge, MP_e.mass)
139+
xn1, yn1, zn1, vxn1, vyn1, vzn1,
140+
Ex_n, Ey_n, Bx_arr, By_arr, Bz_arr, custom_B, MP_e.charge, MP_e.mass)
133141

134142
return MP_e

dynamics_dipole.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

dynamics_strong_B_generalized.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

electron_emission.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

gas_ionization_class.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# This file is part of the code:
99
#
10-
# PyECLOUD Version 8.3.0
10+
# PyECLOUD Version 8.4.0
1111
#
1212
#
1313
# Main author: Giovanni IADAROLA

0 commit comments

Comments
 (0)