#!/usr/bin/env python3 # Copyright 2020 Luca Fedeli, Neil Zaim # # This file is part of WarpX. # # License: BSD-3-Clause-LBNL ## This module is imported by each of the scripts used to analyze the Schwinger tests. ## The pair production rate is calculated using the formula described in ## Bulanov, S. S., et al. Physical review letters 104.22 (2010): 220404. import os import re import sys import numpy as np import yt sys.path.insert(1, '../../../../warpx/Regression/Checksum/') import checksumAPI # define some parameters c = 299792458. m_e = 9.1093837015e-31 e =1.602176634e-19 hbar = 1.054571817e-34 E_S = m_e**2*c**3/e/hbar # Schwinger field dV = (1.e-6)**3 # total simulation volume dt = 9.827726403e-17 filename = sys.argv[1] Ex_test = 0. Ey_test = 0. Ez_test = 0. Bx_test = 0. By_test = 0. Bz_test = 0. # Find which test we are doing test_number = re.search( 'qed_schwinger([1234])', filename ).group(1) if test_number == '1': # First Schwinger test with "weak" EM field. No pair should be created. Ex_test = 1.e16 Bx_test = 16792888.570516706 By_test = 5256650.141557486 Bz_test = 18363530.799561853 elif test_number == '2': # Second Schwinger test with stronger EM field. Many pairs are created and a Gaussian # distribution is used to get the weights of the particles. This is the most sensitive test # because the relative std is extremely low. Ex_test = 1.e18 Bx_test = 1679288857.0516706 By_test = 525665014.1557486 Bz_test = 1836353079.9561853 dV = dV/2. # Schwinger is only activated in part of the simulation domain elif test_number == '3': # Third Schwinger test with intermediate electric field such that average created pair per cell # is 1. A Poisson distribution is used to obtain the weights of the particles. Ey_test = 1.090934525450495e+17 elif test_number == '4': # Fourth Schwinger test with extremely strong EM field but with E and B perpendicular and nearly # equal so that the pair production rate is fairly low. A Gaussian distribution is used in this # case. Ez_test = 2.5e+20 By_test = 833910140000. dV = dV*(3./4.)**2. # Schwinger is only activated in part of the simulation domain else: assert(False) def calculate_rate(Ex,Ey,Ez,Bx,By,Bz): ## Calculate theoretical pair production rate from EM field value E_squared = Ex**2 + Ey**2 + Ez**2 H_squared = c**2*(Bx**2 + By**2 + Bz**2) F = (E_squared - H_squared)/2. G = c*(Ex*Bx + Ey*By + Ez*Bz) epsilon = np.sqrt(np.sqrt(F**2+G**2)+F)/E_S eta = np.sqrt(np.sqrt(F**2+G**2)-F)/E_S if(epsilon != 0. and eta != 0.): return e**2*E_S**2/4./np.pi**2/c/hbar**2*epsilon*eta/np.tanh(np.pi*eta/epsilon)*np.exp(-np.pi/epsilon) elif (epsilon == 0.): return 0. else: return e**2*E_S**2/4./np.pi**2/c/hbar**2*epsilon**2/np.pi*np.exp(-np.pi/epsilon) def do_analysis(Ex,Ey,Ez,Bx,By,Bz): data_set = yt.load(filename) expected_total_physical_pairs_created = dV*dt*calculate_rate(Ex,Ey,Ez,Bx,By,Bz) if expected_total_physical_pairs_created < 0.01: np_ele = data_set.particle_type_counts["ele_schwinger"] if \ "ele_schwinger" in data_set.particle_type_counts.keys() else 0 np_pos = data_set.particle_type_counts["pos_schwinger"] if \ "pos_schwinger" in data_set.particle_type_counts.keys() else 0 assert(np_ele == 0 and np_pos == 0) ## Assert whether pairs are created or not. else: all_data = data_set.all_data() ele_data = all_data["ele_schwinger",'particle_weight'] pos_data = all_data["pos_schwinger",'particle_weight'] std_total_physical_pairs_created = np.sqrt(expected_total_physical_pairs_created) # Sorting the arrays is required because electrons and positrons are not necessarily # dumped in the same order. assert(np.array_equal(np.sort(ele_data),np.sort(pos_data))) # 5 sigma test that has an intrinsic probability to fail of 1 over ~2 millions error = np.abs(np.sum(ele_data)-expected_total_physical_pairs_created) print("difference between expected and actual number of pairs created: " + str(error)) print("tolerance: " + str(5*std_total_physical_pairs_created)) assert(error<5*std_total_physical_pairs_created) do_analysis(Ex_test, Ey_test, Ez_test, Bx_test, By_test, Bz_test) test_name = os.path.split(os.getcwd())[1] checksumAPI.evaluate_checksum(test_name, filename)