Skip to content

Commit e26dede

Browse files
Francesco MassimoFrancesco Massimo
authored andcommitted
upgrade of the VTK export tutorial: now a Laguerre Gauss laser is defined also in AMcylindrical geometry
1 parent e878ac5 commit e26dede

File tree

2 files changed

+156
-138
lines changed

2 files changed

+156
-138
lines changed

_extra/export_VTK_namelist.py

Lines changed: 98 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22
import cmath
3+
import scipy.special as sp
34

45

56
geometry = "3Dcartesian" # or "AMcylindrical"
@@ -25,14 +26,14 @@
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

3233
Main(
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,
@@ -41,6 +42,7 @@
4142
EM_boundary_conditions = EM_boundary_conditions,
4243
solve_poisson = False,
4344
print_every = 100,
45+
use_BTIS3_interpolation= True,
4446
)
4547

4648

@@ -57,98 +59,101 @@
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

104121
if (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
154159
Species(
@@ -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

195200
DiagFields(
@@ -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

Comments
 (0)