aboutsummaryrefslogtreecommitdiff
path: root/Examples
diff options
context:
space:
mode:
Diffstat (limited to 'Examples')
-rwxr-xr-xExamples/Tests/plasma_lens/analysis.py102
-rw-r--r--Examples/Tests/plasma_lens/inputs_3d50
2 files changed, 152 insertions, 0 deletions
diff --git a/Examples/Tests/plasma_lens/analysis.py b/Examples/Tests/plasma_lens/analysis.py
new file mode 100755
index 000000000..b348a3053
--- /dev/null
+++ b/Examples/Tests/plasma_lens/analysis.py
@@ -0,0 +1,102 @@
+#! /usr/bin/env python
+
+# Copyright 2021 David Grote
+#
+# This file is part of WarpX.
+#
+# License: BSD-3-Clause-LBNL
+
+
+"""
+This script tests the plasma lens.
+The input file sets up a series of plasma lens and propagates a particle through them.
+The final position is compared to the analytic solution.
+The motion is slow enough that relativistic effects are ignored.
+"""
+
+import sys
+import os
+import yt
+import numpy as np
+from scipy.constants import e, m_e, c
+yt.funcs.mylog.setLevel(0)
+sys.path.insert(1, '../../../../warpx/Regression/Checksum/')
+import checksumAPI
+
+filename = sys.argv[1]
+ds = yt.load( filename )
+ad = ds.all_data()
+
+# Get final position of the particles
+# The sorting by id is to get them in the correct order
+# There are two particles, one moves in x, the other in y.
+r_id = ad['electrons', 'particle_id'].v
+
+xx_sim = ad['electrons', 'particle_position_x'].v[np.argsort(r_id)][0]
+yy_sim = ad['electrons', 'particle_position_y'].v[np.argsort(r_id)][1]
+zz_sim0 = ad['electrons', 'particle_position_z'].v[np.argsort(r_id)][0]
+zz_sim1 = ad['electrons', 'particle_position_z'].v[np.argsort(r_id)][1]
+
+ux_sim = ad['electrons', 'particle_momentum_x'].v[np.argsort(r_id)][0]/m_e
+uy_sim = ad['electrons', 'particle_momentum_y'].v[np.argsort(r_id)][1]/m_e
+
+
+def applylens(x0, vx0, vz0, lens_length, lens_strength):
+ """Given the initial position at the start of the lens,
+ calculate the end position at the exit.
+ This assumes harmonic motion."""
+ w = np.sqrt(e/m_e*lens_strength)
+ A = np.sqrt(x0**2 + (vx0/w)**2)
+ phi = np.arctan2(-vx0, w*x0)
+ t = lens_length/vz0
+ x1 = A*np.cos(w*t + phi)
+ vx1 = -w*A*np.sin(w*t + phi)
+ return x1, vx1
+
+plasma_lens_period = float(ds.parameters.get('particles.repeated_plasma_lens_period'))
+plasma_lens_starts = [float(x) for x in ds.parameters.get('particles.repeated_plasma_lens_starts').split()]
+plasma_lens_lengths = [float(x) for x in ds.parameters.get('particles.repeated_plasma_lens_lengths').split()]
+plasma_lens_strengths = [eval(x) for x in ds.parameters.get('particles.repeated_plasma_lens_strengths').split()]
+
+clight = c
+
+x0 = float(ds.parameters.get('electrons.multiple_particles_pos_x').split()[0])
+y0 = float(ds.parameters.get('electrons.multiple_particles_pos_y').split()[1])
+z0 = float(ds.parameters.get('electrons.multiple_particles_pos_z').split()[0])
+ux0 = float(ds.parameters.get('electrons.multiple_particles_vel_x').split()[0])*c
+uy0 = float(ds.parameters.get('electrons.multiple_particles_vel_y').split()[1])*c
+uz0 = eval(ds.parameters.get('electrons.multiple_particles_vel_z').split()[0])*c
+
+tt = 0.
+xx = x0
+yy = y0
+zz = z0
+ux = ux0
+uy = uy0
+uz = uz0
+
+for i in range(len(plasma_lens_starts)):
+ z_lens = i*plasma_lens_period + plasma_lens_starts[i]
+ dt = (z_lens - zz)/uz
+ tt = tt + dt
+ xx = xx + dt*ux
+ yy = yy + dt*uy
+ xx, ux = applylens(xx, ux, uz, plasma_lens_lengths[i], plasma_lens_strengths[i])
+ yy, uy = applylens(yy, uy, uz, plasma_lens_lengths[i], plasma_lens_strengths[i])
+ dt = plasma_lens_lengths[i]/uz
+ tt = tt + dt
+ zz = z_lens + plasma_lens_lengths[i]
+
+dt0 = (zz_sim0 - zz)/uz
+dt1 = (zz_sim1 - zz)/uz
+xx = xx + dt0*ux
+yy = yy + dt1*uy
+
+assert abs(xx - xx_sim) < 0.011, Exception('error in x particle position')
+assert abs(yy - yy_sim) < 0.011, Exception('error in y particle position')
+assert abs(ux - ux_sim) < 70., Exception('error in x particle velocity')
+assert abs(uy - uy_sim) < 70., Exception('error in y particle velocity')
+
+test_name = os.path.split(os.getcwd())[1]
+checksumAPI.evaluate_checksum(test_name, filename)
+
diff --git a/Examples/Tests/plasma_lens/inputs_3d b/Examples/Tests/plasma_lens/inputs_3d
new file mode 100644
index 000000000..fa19685a2
--- /dev/null
+++ b/Examples/Tests/plasma_lens/inputs_3d
@@ -0,0 +1,50 @@
+# Maximum number of time steps
+max_step = 97
+
+# number of grid points
+amr.n_cell = 16 16 16
+
+amr.max_level = 0
+
+# Geometry
+geometry.coord_sys = 0 # 0: Cartesian
+geometry.prob_lo = -1.0 -1.0 0.0 # physical domain
+geometry.prob_hi = 1.0 1.0 2.0
+
+boundary.field_lo = pec pec pec
+boundary.field_hi = pec pec pec
+boundary.particle_lo = absorbing absorbing absorbing
+boundary.particle_hi = absorbing absorbing absorbing
+
+warpx.do_pml = 0
+warpx.const_dt = 1.e-6
+warpx.do_electrostatic = labframe
+
+# Algorithms
+algo.particle_shape = 1
+
+# particles
+particles.species_names = electrons
+
+electrons.charge = -q_e
+electrons.mass = m_e
+electrons.injection_style = "MultipleParticles"
+electrons.multiple_particles_pos_x = 0.5 0.
+electrons.multiple_particles_pos_y = 0. 0.4
+electrons.multiple_particles_pos_z = 0.05 0.05
+electrons.multiple_particles_vel_x = 0. 0.
+electrons.multiple_particles_vel_y = 0. 0.
+electrons.multiple_particles_vel_z = 0.02e6/clight 0.02e6/clight
+electrons.multiple_particles_weight = 1. 1.
+
+particles.E_ext_particle_init_style = repeated_plasma_lens
+particles.repeated_plasma_lens_period = 0.5
+particles.repeated_plasma_lens_starts = 0.1 0.11 0.12 0.13
+particles.repeated_plasma_lens_lengths = 0.1 0.11 0.12 0.13
+particles.repeated_plasma_lens_strengths = 0.07 0.06 0.06 0.03
+
+# Diagnostics
+diagnostics.diags_names = diag1
+diag1.intervals = 97
+diag1.diag_type = Full
+diag1.electrons.variables = ux uy uz