示例#1
0
def get_a0(
    tseries: OpenPMDTimeSeries,
    t: Optional[float] = None,
    it: Optional[int] = None,
    coord="x",
    m="all",
    slicing_dir="y",
    theta=0.0,
    lambda0=0.8e-6,
) -> Tuple[float, float, float, float]:
    """
    Compute z₀, a₀, w₀, cτ.

    :param tseries: whole simulation time series
    :param t: time (in seconds) at which to obtain the data
    :param it: time step at which to obtain the data
    :param coord: which component of the field to extract
    :param m: 'all' for extracting the sum of all the modes
    :param slicing_dir: the direction along which to slice the data eg., 'x', 'y' or 'z'
    :param theta: the angle of the plane of observation, with respect to the 'x' axis
    :param lambda0: laser wavelength (meters)
    :return: z₀, a₀, w₀, cτ
    """
    # get E_x field in V/m
    electric_field_x, info_electric_field_x = tseries.get_field(
        field="E",
        coord=coord,
        t=t,
        iteration=it,
        m=m,
        theta=theta,
        slicing_dir=slicing_dir,
    )

    # normalized vector potential
    e0 = electric_field_amplitude_norm(lambda0=lambda0)
    a0 = electric_field_x / e0

    # get pulse envelope
    envelope = np.abs(hilbert(a0, axis=1))
    envelope_z = envelope[envelope.shape[0] // 2, :]

    a0_max = np.amax(envelope_z)

    # index of peak
    z_idx = np.argmax(envelope_z)
    # pulse peak position
    z0 = info_electric_field_x.z[z_idx]

    # FWHM perpendicular size of beam, proportional to w0
    fwhm_a0_w0 = (np.sum(np.greater_equal(envelope[:, z_idx], a0_max / 2)) *
                  info_electric_field_x.dr)

    # FWHM longitudinal size of the beam, proportional to ctau
    fwhm_a0_ctau = (np.sum(np.greater_equal(envelope_z, a0_max / 2)) *
                    info_electric_field_x.dz)

    return z0, a0_max, fwhm_a0_w0, fwhm_a0_ctau
示例#2
0
def field_snapshot(
    tseries: OpenPMDTimeSeries,
    it: int,
    field_name: str,
    normalization_factor=1,
    coord: Optional[str] = None,
    m="all",
    theta=0.0,
    chop: Optional[List[float]] = None,
    path="./",
    **kwargs,
) -> None:
    """
    Plot the ``field_name`` field from ``tseries`` at step ``iter``.

    :param path: path to output file
    :param tseries: whole simulation time series
    :param it: time step in the simulation
    :param field_name: which field to extract, eg. 'rho', 'E', 'B' or 'J'
    :param normalization_factor: normalization factor for the extracted field
    :param coord: which component of the field to extract, eg. 'r', 't' or 'z'
    :param m: 'all' for extracting the sum of all the azimuthal modes
    :param theta: the angle of the plane of observation, with respect to the 'x' axis
    :param chop: adjusting extent of simulation box plot
    :param kwargs: extra plotting arguments, eg. labels, data limits etc.
    :return: saves field plot image to disk
    """
    if chop is None:  # how much to cut out from simulation domain
        chop = [40, -20, 15, -15]  # CHANGEME

    field, info = tseries.get_field(field=field_name,
                                    coord=coord,
                                    iteration=it,
                                    m=m,
                                    theta=theta)

    field *= normalization_factor

    plot = sliceplots.Plot2D(
        arr2d=field,
        h_axis=info.z * 1e6,
        v_axis=info.r * 1e6,
        xlabel=r"${} \;(\mu m)$".format(info.axes[1]),
        ylabel=r"${} \;(\mu m)$".format(info.axes[0]),
        extent=(
            info.zmin * 1e6 + chop[0],
            info.zmax * 1e6 + chop[1],
            info.rmin * 1e6 + chop[2],
            info.rmax * 1e6 + chop[3],
        ),
        cbar=True,
        text=f"iteration {it}",
        **kwargs,
    )

    filename = os.path.join(path, f"{field_name}{it:06d}.png")
    plot.canvas.print_figure(filename)
示例#3
0
def check_identical_fields( folder1, folder2 ):
    ts1 = OpenPMDTimeSeries( folder1 )
    ts2 = OpenPMDTimeSeries( folder2 )
    # Check the vector fields
    for field, coord in [("J", "z"), ("E","r"), ("E","z"), ("B","t")]:
        print("Checking %s%s" %(field, coord))
        field1, info = ts1.get_field(field, coord, iteration=0)
        field2, info = ts2.get_field(field, coord, iteration=0)
        # For 0 fields, do not use allclose
        if abs(field1).max() == 0:
            assert abs(field2).max() == 0
        else:
            assert np.allclose(
                field1/abs(field1).max(), field2/abs(field2).max() )
    # Check the rho field
    print("Checking rho")
    field1, info = ts1.get_field("rho", iteration=0)
    field2, info = ts2.get_field("rho", iteration=0)
    assert np.allclose( field1/abs(field1).max(), field2/abs(field2).max() )
示例#4
0
class Backend:
    ''' Use openPMD-viewer as the backend reader to read openPMD files
    '''
    def __init__(self, filename):
        ''' Constructor: store the dataset object
        '''

        self.dataset = OpenPMDTimeSeries(filename)

    def fields_list(self):
        ''' Return the list of fields defined on the grid
        '''

        return self.dataset.avail_fields

    def species_list(self):
        ''' Return the list of species in the dataset
        '''

        return self.dataset.avail_species

    def n_levels(self):
        ''' Return the number of MR levels in the dataset
        '''

        return 1

    def get_field_checksum(self, lev, field, test_name):
        ''' Calculate the checksum for a given field at a given level in the dataset
        '''

        Q = self.dataset.get_field(field=field,
                                   iteration=self.dataset.iterations[-1])[0]
        return np.sum(np.abs(Q))

    def get_species_attributes(self, species):
        ''' Return the list of attributes for a given species in the dataset
        '''
        return self.dataset.avail_record_components[species]

    def get_species_checksum(self, species, attribute):
        ''' Calculate the checksum for a given attribute of a given species in the dataset
        '''

        Q = self.dataset.get_particle(var_list=[attribute],
                                      species=species,
                                      iteration=self.dataset.iterations[-1])
        # JSON complains with numpy integers, so if the quantity is a np.int64, convert to int
        checksum = np.sum(np.abs(Q))
        if type(checksum) in [np.int64, np.uint64]:
            return int(checksum)
        return checksum
示例#5
0
def check_theory_gaussian():
    """
    Check that the transverse E and B field are close to the high-gamma
    theory for a gaussian bunch
    """
    ts = OpenPMDTimeSeries( os.path.join(temporary_dir, 'diags_serial/hdf5/') )
    Ex, info = ts.get_field( 'E', 'x', iteration=0 )
    By, info = ts.get_field( 'B', 'y', iteration=0 )
    r, z = np.meshgrid( info.r, info.z, indexing='ij' )
    # High-gamma theory for Gaussian bunch
    Eth = -Q/(2*np.pi)**1.5/sig_z/epsilon_0/r * \
        (1 - np.exp(-0.5*r**2/sig_r**2)) * \
        np.exp( -0.5*(z-zf)**2/sig_z**2)
    Bth = Eth/c
    # Check that the fields agree
    assert np.allclose( Ex, Eth, atol=0.1*Eth.max() )
    assert np.allclose( By, Bth, atol=0.1*Bth.max() )
示例#6
0
                    default='diags/hdf5',
                    help='Path to the directory containing output files')
args = parser.parse_args()

ts = OpenPMDTimeSeries(args.output_dir)

if args.norm_units:
    kp = 1.
    ne = 1.
    q_e = 1.
else:
    kp = 1./10.e-6
    ne = scc.c**2 / scc.e**2 * scc.m_e * scc.epsilon_0 * kp**2
    q_e = scc.e

rho_along_z, rho_meta = ts.get_field(field='rho', iteration=ts.iterations[-1],
                                     slice_across=['x','y'], slice_relative_position=[0,0])
zeta_array = rho_meta.z
dzeta = rho_meta.dz
nz = len(rho_meta.z)

# generating the array with the beam density
nb_array = np.zeros(nz)
beam_starting_position = 1 / kp
distance_to_start_pos =  rho_meta.zmax - beam_starting_position
index_beam_head = int(distance_to_start_pos / dzeta)
beam_length = 2 / kp
beam_length_i = int(beam_length / dzeta)
if (args.gaussian_beam):
    sigma_z = 1.41 / kp
    peak_density = 0.01*ne
    nb_array = peak_density*np.sqrt(2*np.pi)*norm.pdf(np.linspace(-nz/2,nz/2,nz)*dzeta/sigma_z)
示例#7
0
import matplotlib
import sys
import numpy as np
import math
import argparse
from openpmd_viewer import OpenPMDTimeSeries

parser = argparse.ArgumentParser(
    description='Script to analyze the equality of two simulations')
parser.add_argument('--first',
                    dest='first',
                    required=True)
parser.add_argument('--second',
                    dest='second',
                    required=True)
args = parser.parse_args()

# Replace the string below, to point to your data
tss = OpenPMDTimeSeries(args.first)
tsp = OpenPMDTimeSeries(args.second)

iteration = 0
for field in ['Bx', 'By', 'Ez', 'ExmBy', 'EypBx']:
    Fs, ms = tss.get_field(iteration=iteration, field=field)
    Fp, mp = tsp.get_field(iteration=iteration, field=field)

    error = np.sum((Fp-Fs)**2) / np.sum(Fs**2)

    print(field, 'error = np.sum((Fp-Fs)**2) / np.sum(Fs**2) = ' +str(error))
    assert(error<0.006)
示例#8
0
# full IO and from a simulation with only slice IO

import matplotlib.pyplot as plt
import scipy.constants as scc
import matplotlib
import sys
import numpy as np
import math
import argparse
from openpmd_viewer import OpenPMDTimeSeries

do_plot = False
field = 'Ez'

ts1 = OpenPMDTimeSeries('full_io')
F_full = ts1.get_field(field=field, iteration=ts1.iterations[-1])[0]
F_full = np.swapaxes(F_full, 0, 2)
F_full_xz = (F_full[:, F_full.shape[1] // 2, :].squeeze() +
             F_full[:, F_full.shape[1] // 2 - 1, :].squeeze()) / 2.
F_full_yz = (F_full[F_full.shape[0] // 2, :, :].squeeze() +
             F_full[F_full.shape[0] // 2 - 1, :, :].squeeze()) / 2.

ts2 = OpenPMDTimeSeries('slice_io_xz')
F_slice_xz = ts2.get_field(field=field,
                           iteration=ts2.iterations[-1])[0].transpose()

ts3 = OpenPMDTimeSeries('slice_io_yz')
F_slice_yz = ts3.get_field(field=field,
                           iteration=ts3.iterations[-1])[0].transpose()

if do_plot:
示例#9
0
def run_cpu_gpu_deposition(show=False, particle_shape='cubic'):

    # Skip this test if cuda is not installed
    if not cuda_installed:
        return

    # Perform deposition for a few timesteps, with both the CPU and GPU
    for hardware in ['cpu', 'gpu']:
        if hardware == 'cpu':
            use_cuda = False
        elif hardware == 'gpu':
            use_cuda = True

        # Initialize the simulation object
        sim = Simulation(Nz,
                         zmax,
                         Nr,
                         rmax,
                         Nm,
                         dt,
                         zmin=zmin,
                         use_cuda=use_cuda,
                         particle_shape=particle_shape)
        sim.ptcl = []

        # Add an electron bunch (set the random seed first)
        np.random.seed(0)
        add_elec_bunch_gaussian(sim, sig_r, sig_z, n_emit, gamma0, sig_gamma,
                                Q, N)

        # Add a field diagnostic
        sim.diags = [
            FieldDiagnostic(diag_period,
                            sim.fld,
                            fieldtypes=['rho', 'J'],
                            comm=sim.comm,
                            write_dir=os.path.join('tests', hardware))
        ]

        ### Run the simulation
        sim.step(N_step)

    # Check that the results are identical
    ts_cpu = OpenPMDTimeSeries('tests/cpu/hdf5')
    ts_gpu = OpenPMDTimeSeries('tests/gpu/hdf5')
    for iteration in ts_cpu.iterations:
        for field, coord in [('rho', ''), ('J', 'x'), ('J', 'z')]:
            # Jy is not tested because it is zero
            print('Testing %s at iteration %d' % (field + coord, iteration))
            F_cpu, info = ts_cpu.get_field(field, coord, iteration=iteration)
            F_gpu, info = ts_gpu.get_field(field, coord, iteration=iteration)
            tolerance = 1.e-13 * (abs(F_cpu).max() + abs(F_gpu).max())
            if not show:
                assert np.allclose(F_cpu, F_gpu, atol=tolerance)
            else:
                if not np.allclose(F_cpu, F_gpu, atol=tolerance):
                    plot_difference(field, coord, iteration, F_cpu, F_gpu,
                                    info)

    # Remove the files used
    shutil.rmtree('tests/cpu')
    shutil.rmtree('tests/gpu')
示例#10
0
    rho0 = -scc.e * dens
    c = scc.c
    mu_0 = scc.mu_0
    eps_0 = scc.epsilon_0
    # Radius of the can beam
    R = 10.e-6

x_beam_mid = 2
y_beam_mid = -1
x_domain_len = 8
y_domain_len = 8

# Load HiPACE++ data for By in SI units
Bx_sim, Bx_meta = ts.get_field(
    field='Bx',
    iteration=0,
    slice_across=['x', 'z'],
    slice_relative_position=[2 * x_beam_mid / x_domain_len, 0])
By_sim, By_meta = ts.get_field(
    field='By',
    iteration=0,
    slice_across=['y', 'z'],
    slice_relative_position=[2 * y_beam_mid / y_domain_len, 0])
jz_sim = ts.get_field(
    field='jz',
    iteration=0,
    slice_across=['y', 'z'],
    slice_relative_position=[2 * y_beam_mid / y_domain_len, 0])[0]
rho_sim = ts.get_field(
    field='rho',
    iteration=0,
示例#11
0
    eps_0 = 1.
    R = 1.
else:
    # Density of the can beam
    dens = 2.8239587008591567e23 # at this density, 1/kp = 10um, allowing for an easy comparison with normalized units
    # Define array for transverse coordinate and theory for By and Bx
    jz0 = - scc.e * scc.c * dens
    rho0 = - scc.e * dens
    c = scc.c
    mu_0 = scc.mu_0
    eps_0 = scc.epsilon_0
    # Radius of the can beam
    R = 10.e-6

# Load HiPACE++ data for By in SI units
Bx_sim, Bx_meta = ts.get_field(field='Bx', iteration=0, slice_across=['x','z'], slice_relative_position=[0,0])
By_sim, By_meta = ts.get_field(field='By', iteration=0, slice_across=['y','z'], slice_relative_position=[0,0])
jz_sim = ts.get_field(field='jz', iteration=0, slice_across=['y','z'], slice_relative_position=[0,0])[0]
rho_sim = ts.get_field(field='rho', iteration=0, slice_across=['y','z'], slice_relative_position=[0,0])[0]
Ex_sim = ts.get_field(field='ExmBy', iteration=0, slice_across=['y','z'], slice_relative_position=[0,0])[0] + c*By_sim
Ey_sim = ts.get_field(field='EypBx', iteration=0, slice_across=['x','z'], slice_relative_position=[0,0])[0] - c*Bx_sim
y = Bx_meta.y
x = By_meta.x

By_th = mu_0 * jz0 * x / 2.
By_th[abs(x)>=R] = mu_0 * jz0 * R**2/(2*x[abs(x)>R])
Ex_th = rho0 / eps_0 * x / 2.
Ex_th[abs(x)>=R] = rho0 / eps_0 * R**2/(2*x[abs(x)>R])

Bx_th = -mu_0 * jz0 * y / 2.
Bx_th[abs(y)>=R] = -mu_0 * jz0 * R**2/(2*y[abs(y)>R])
示例#12
0
args = parser.parse_args()

ts_norm = OpenPMDTimeSeries(args.norm_data)
ts_si = OpenPMDTimeSeries(args.si_data)
ts_si_fixed_weight = OpenPMDTimeSeries(args.si_fixed_weight_data)

elec_density = 2.8239587008591567e23  # [1/m^3]
# calculation of the plasma frequency
omega_p = np.sqrt(elec_density * (scc.e**2) / (scc.epsilon_0 * scc.m_e))
E_0 = omega_p * scc.m_e * scc.c / scc.e

kp = omega_p / scc.c  # 1./10.e-6

# Load HiPACE++ data for Ez in both normalized and SI units
Ez_along_z_norm, meta_norm = ts_norm.get_field(field='Ez',
                                               iteration=1,
                                               slice_across=['x', 'y'],
                                               slice_relative_position=[0, 0])
Ez_along_z_si, meta_si = ts_si.get_field(field='Ez',
                                         iteration=1,
                                         slice_across=['x', 'y'],
                                         slice_relative_position=[0, 0])
Ez_along_z_si_fixed_w, meta = ts_si_fixed_weight.get_field(
    field='Ez',
    iteration=1,
    slice_across=['x', 'y'],
    slice_relative_position=[0, 0])
zeta_norm = meta_norm.z
zeta_si = meta_si.z

if args.do_plot:
    fig, ax = plt.subplots()
示例#13
0
#
# This file is part of HiPACE++.
#
# Authors: MaxThevenet, Severin Diederichs
# License: BSD-3-Clause-LBNL

# This script calculates the sum of jz.
# The beam current and the grid current should cancel each other.

import argparse
import numpy as np
from openpmd_viewer import OpenPMDTimeSeries

parser = argparse.ArgumentParser(description='Script to analyze the correctness of the beam in vacuum')
parser.add_argument('--output-dir',
                    dest='output_dir',
                    default='diags/hdf5',
                    help='Path to the directory containing output files')
args = parser.parse_args()

ts = OpenPMDTimeSeries(args.output_dir)

# Load Hipace data for jz
jz_sim, jz_info = ts.get_field(field='jz', iteration=1)

# Assert that the grid current and the beam current cancel each other
error_jz = np.sum( (jz_sim)**2)
print("sum of jz**2: " + str(error_jz) + " (tolerance = 3e-3)")

assert(error_jz < 3e-3)
示例#14
0
import scipy.constants as scc
import matplotlib
import sys
import numpy as np
import math
import argparse
from openpmd_viewer import OpenPMDTimeSeries

fields = ['Ez', 'ExmBy', 'EypBx']

ts1 = OpenPMDTimeSeries('fine_io')
ts2 = OpenPMDTimeSeries('coarse_io')

for field in fields:

    F_full = ts1.get_field(field=field, iteration=ts1.iterations[-1])[0]
    F_full_coarse = (F_full[2::5,1::4,1::3] + F_full[2::5,2::4,1::3])/2

    F_coarse = ts2.get_field(field=field, iteration=ts2.iterations[-1])[0]

    print("F_full.shape =", F_full.shape)
    print("F_full_coarse.shape =", F_full_coarse.shape)
    print("F_coarse.shape =", F_coarse.shape)
    error = np.max(np.abs(F_coarse-F_full_coarse)) / np.max(np.abs(F_full_coarse))
    print("error =", error)

    assert(error < 3.e-14)

del ts1
del ts2
示例#15
0
                    default='diags/hdf5',
                    help='Path to the directory containing output files')
args = parser.parse_args()

ts_ref = OpenPMDTimeSeries('./REF_diags/hdf5/')
ts = OpenPMDTimeSeries(args.output_dir)

if do_plot:

    field = 'Bx'
    step = 20
    ms = .1

    plt.figure()

    F, meta = ts_ref.get_field(field=field, iteration=ts_ref.iterations[-1])

    xp, yp, zp, uzp, wp = ts_ref.get_particle(
        species='beam',
        iteration=ts_ref.iterations[-1],
        var_list=['x', 'y', 'z', 'uz', 'w'])

    plt.subplot(221)
    plt.title('ref xz')
    extent = [meta.zmin, meta.zmax, meta.xmin, meta.xmax]
    plt.imshow(F[:, F.shape[1] // 2, :],
               extent=extent,
               aspect='auto',
               origin='lower',
               interpolation='nearest')
    plt.plot(zp[::step], xp[::step], '.', ms=ms)