11import numpy as np
22import cmath
3+ import scipy .special as sp
34
45
56geometry = "3Dcartesian" # or "AMcylindrical"
2526 cell_length = [dx , dtrans ]
2627 # remember that in AM cylindrical geometry the grid represents the half plane (x,r)
2728 # thus Ltrans is the transverse window size, i.e. from r=0 to r=Ltrans
28- grid_length = [Lx , Ltrans ]
29+ grid_length = [Lx , Ltrans / 2. ]
2930 number_of_patches = [npatch_x , 4 ]
3031 EM_boundary_conditions = [["silver-muller" ,"silver-muller" ],["buneman" ,"buneman" ],]
3132
3233Main (
3334 geometry = geometry ,
3435 interpolation_order = 2 ,
35- number_of_AM = 2 , # this variable is used only in AMcylindrical geometry
36+ number_of_AM = 3 , # this variable is used only in AMcylindrical geometry
3637 timestep = dt ,
3738 simulation_time = Lx ,
3839 cell_length = cell_length ,
4142 EM_boundary_conditions = EM_boundary_conditions ,
4243 solve_poisson = False ,
4344 print_every = 100 ,
45+ use_BTIS3_interpolation = True ,
4446)
4547
4648
5759)
5860
5961
60- if (geometry == "3Dcartesian" ):
62+ # Laguerre-Gauss laser parameters
63+ l = 1 # azimuthal index for Ey
64+ p = 0 # radial index
65+
66+ omega = 1.
67+ a0 = 6.
68+ focus = [Main .grid_length [0 ]/ 2. , Main .grid_length [1 ]/ 2. ] # first coordinate: x; second coordinate: y and z
69+ waist = 10.
70+ laser_fwhm = 20.
71+ laser_center = 2 ** 0.5 * laser_fwhm
72+ time_envelope = tgaussian (center = laser_center , fwhm = laser_fwhm )
73+
74+
75+ # variables used to define the Laguerre-Gauss mode
76+ x_R = omega * waist ** 2 / 2. # normalized Rayleigh length
77+ xmin = 0. # x coordinate of the border where the laser is injected
78+ R = (xmin - focus [0 ]) * (1. + (x_R / (xmin - focus [0 ]))** 2 ) # radius of curvature
79+ w = waist * np .sqrt (1. + ( (xmin - focus [0 ]) / x_R )** 2 ) # waist at xmin
80+ Gouy_phase = np .exp (- 1j * (2 * p + abs (l )+ 1 ) * np .arctan2 ( (xmin - focus [0 ]),x_R ) )
81+
82+ def LG_radial_part (r ):
83+ # this function defines the part of the complex envelope of the
84+ # Laguerre Gauss mode p=0, l=1
85+ # that depends only on r
86+ result = waist / w * sp .eval_genlaguerre (p , abs (l ), (2 * np .square (r ) / w ** 2 ))
87+ result = result * np .power ( (np .sqrt (2 ) * r / w ), abs (l ) )
88+ result = result * np .exp (- np .square (r ) / w ** 2 )
89+ result = result * np .exp (1j * omega * np .square (r ) / (2 * R ))
90+ return result
6191
62- boundary_conditions = [["remove" , "remove" ],["remove" , "remove" ],["remove" , "remove" ],]
63- particles_per_cell = 0.1
64-
65- # We build a Laguerre-Gauss laser from scratch instead of using LaserGaussian3D
66- # The goal is to test the space_time_profile attribute
67- omega = 1.
68- a0 = 6.
69- focus = [0. , Main .grid_length [1 ]/ 2. , Main .grid_length [2 ]/ 2. ]
70- waist = 10.
71- laser_fwhm = 20.
72- laser_center = 2 ** 0.5 * laser_fwhm
73- time_envelope = tgaussian (center = laser_center , fwhm = laser_fwhm )
74-
75- Zr = omega * waist ** 2 / 2.
76- w = math .sqrt (1. / (1. + (focus [0 ]/ Zr )** 2 ))
77- invWaist2 = (w / waist )** 2
78- coeff = - omega * focus [0 ] * w ** 2 / (2. * Zr ** 2 )
79-
80- m = 1 # azimuthal index
81- def phase (y ,z ):
82- return - m * np .arctan2 ((z - Ltrans / 2. ), (y - Ltrans / 2. ))
83-
84- def By (y ,z ,t ):
85- return 0.
86- def Bz (y ,z ,t ):
87- r2 = (y - focus [1 ])** 2 + (z - focus [2 ])** 2
88- omegat = omega * (t - laser_center ) - coeff * r2
89- return a0 * w * math .exp ( - invWaist2 * r2 ) * time_envelope ( t ) * math .sin ( omegat - phase (y ,z ))
90-
91- # Define the laser pulse
92- Laser ( box_side = "xmin" ,space_time_profile = [By , Bz ])
93-
94- # Define Plasma density profile
95- def my_profile (x ,y ,z ):
96- center_plasma = [Lx / 4. ,Ltrans / 2. ,Ltrans / 2. ]
97- Radius = 20.
98- Length = 5.
99- if ((abs (x - center_plasma [0 ])< Length ) and ((y - center_plasma [1 ])** 2 + (z - center_plasma [2 ])** 2 < Radius * Radius )):
100- return 1.
101- else :
102- return 0.
92+ if (geometry == "3Dcartesian" ):
93+ boundary_conditions = [["remove" , "remove" ],["remove" , "remove" ],["remove" , "remove" ],]
94+ particles_per_cell = 0.1
95+
96+ # We build a Laguerre-Gauss laser from scratch.
97+ # The laser is assumed as linearly polarized in the y direction (Ez=By=0).
98+ # The goal is to test the space_time_profile feature in the Laser block
99+
100+ def By (y ,z ,t ):
101+ return 0.
102+
103+ def Bz (y ,z ,t ):
104+ r = np .sqrt (np .square (y - focus [1 ])+ np .square (z - focus [1 ]))
105+ theta = np .arctan2 ((z - focus [1 ]),(y - focus [1 ]))
106+ return a0 * np .real (LG_radial_part (r )* np .exp (1j * l * theta )* np .exp (- 1j * omega * t )* time_envelope (t ))
107+
108+ # Define the laser pulse
109+ Laser ( box_side = "xmin" ,space_time_profile = [By , Bz ])
110+
111+ # Define Plasma density profile
112+ def my_profile (x ,y ,z ):
113+ center_plasma = [Lx / 4. ,Ltrans / 2. ,Ltrans / 2. ]
114+ Radius = 20.
115+ Length = 5.
116+ if ((abs (x - center_plasma [0 ])< Length ) and ((y - center_plasma [1 ])** 2 + (z - center_plasma [2 ])** 2 < Radius * Radius )):
117+ return 1.
118+ else :
119+ return 0.
103120
104121if (geometry == "AMcylindrical" ):
105122
106- boundary_conditions = [["remove" , "remove" ],["remove" , "remove" ],]
107- particles_per_cell = 1
123+ boundary_conditions = [["remove" , "remove" ],["remove" , "remove" ],]
124+ particles_per_cell = 1
108125
109- # We build a simple Gaussian beam laser from scratch instead of using LaserGaussianAM
110- # the laser is assumed as linearly polarized in the y direction
111-
112- # The goal is to test the space_time_profile_AM attribute
113- omega = 1.
114- a0 = 6.
115- focus = [0. , 0. ]
116- waist = 10.
117- laser_fwhm = 20.
118- laser_center = 2 ** 0.5 * laser_fwhm
119- time_envelope = tgaussian (center = laser_center , fwhm = laser_fwhm )
120-
121- Zr = omega * waist ** 2 / 2.
122- w = math .sqrt (1. / (1. + (focus [0 ]/ Zr )** 2 ))
123- invWaist2 = (w / waist )** 2
124- coeff = - omega * focus [0 ] * w ** 2 / (2. * Zr ** 2 )
125-
126- # Bz field of a Gaussian beam linearly polarized in the y direction, propagating following the x axis,
127- # with Gaussian temporal profile. For this laser, Bz=Ey in normalized units
128- def Bz (r ,t ):
129- return a0 * w * math .exp ( - invWaist2 * r ** 2 ) * time_envelope ( t ) * math .sin ( omega * (t - laser_center ) - coeff * r ** 2 )
130-
131- def Br_mode0 (r ,t ):
132- return 0j
133- def Bt_mode0 (r ,t ):
134- return 0j
135- def Br_mode1 (r ,t ):
136- return 1j * Bz (r ,t )
137- def Bt_mode1 (r ,t ):
138- return complex (Bz (r ,t ))
139-
140- # Define the laser pulse
141- Laser ( box_side = "xmin" ,space_time_profile_AM = [Br_mode0 , Bt_mode0 , Br_mode1 , Bt_mode1 ])
142-
143- # Define Plasma density profile
144- def my_profile (x ,r ):
145- center_plasma = Lx / 4.
146- Radius = 20.
147- Length = 5.
148- if ((abs (x - center_plasma )< Length ) and (r < Radius )):
149- return 1.
150- else :
151- return 0.
126+ # We build a Laguerre-Gauss laser from scratch.
127+ # The laser is assumed as linearly polarized in the y direction (Ez=By=0).
128+ # The goal is to test the space_time_profile_AM feature in the Laser block
129+
130+ def Bz_radial_part (r ,t ):
131+ return a0 * LG_radial_part (r )* np .exp (- 1j * omega * t )* time_envelope (t )
132+ def Br_mode0 (r ,t ):
133+ return - 1j / 2. * np .conjugate (Bz_radial_part (r ,t ))
134+ def Bt_mode0 (r ,t ):
135+ return 1. / 2. * np .conjugate (Bz_radial_part (r ,t ))
136+ def Br_mode1 (r ,t ):
137+ return 0j
138+ def Bt_mode1 (r ,t ):
139+ return 0j
140+ def Br_mode2 (r ,t ):
141+ return 1j / 2. * np .conjugate (Bz_radial_part (r ,t ))
142+ def Bt_mode2 (r ,t ):
143+ return 1. / 2. * np .conjugate (Bz_radial_part (r ,t ))
144+
145+ # Define the laser pulse
146+ Laser ( box_side = "xmin" ,space_time_profile_AM = [Br_mode0 , Bt_mode0 , Br_mode1 , Bt_mode1 , Br_mode2 , Bt_mode2 ])
147+
148+ # Define Plasma density profile
149+ def my_profile (x ,r ):
150+ center_plasma = Lx / 4.
151+ Radius = 20.
152+ Length = 5.
153+ if ((abs (x - center_plasma )< Length ) and (r < Radius )):
154+ return 1.
155+ else :
156+ return 0.
152157
153158# Add some test electrons
154159Species (
@@ -162,7 +167,7 @@ def my_profile(x,r):
162167 charge_density = my_profile ,
163168 mean_velocity = [0. , 0. , 0. ],
164169 time_frozen = 0.0 ,
165- pusher = "boris " ,
170+ pusher = "borisBTIS3 " ,
166171 is_test = True ,
167172 boundary_conditions = boundary_conditions ,
168173 )
@@ -188,8 +193,8 @@ def my_profile(x,r):
188193 origin_1D_probes = [0. , 0. , 0. ]
189194 corners_1D_probes = [[Main .grid_length [0 ], 0. , 0. ]]
190195
191- origin_2D_probes = [0. , - Main .grid_length [1 ]/ 4 . , 0. ]
192- corners_2D_probes = [[Main .grid_length [0 ], - Main .grid_length [1 ]/ 4 . , 0. ],[0. , Main .grid_length [1 ]/ 4 . , 0. ],]
196+ origin_2D_probes = [0. , - Main .grid_length [1 ]/ 2 . , 0. ]
197+ corners_2D_probes = [[Main .grid_length [0 ], - Main .grid_length [1 ]/ 2 . , 0. ],[0. , Main .grid_length [1 ]/ 2 . , 0. ],]
193198
194199
195200DiagFields (
@@ -209,7 +214,7 @@ def my_profile(x,r):
209214 every = 50 ,
210215 origin = origin_2D_probes ,
211216 corners = corners_2D_probes ,
212- number = [nx , ntrans ],
217+ number = [nx , int ( 2 * ntrans )] if ( geometry == "AMcylindrical" ) else [ nx , ntrans ],
213218 fields = list_fields_probes_diagnostic ,
214219)
215220
0 commit comments