Source code for fbpic.fields.smoothing

# Copyright 2018, FBPIC contributors
# Authors: Remi Lehe, Manuel Kirchen, Soeren Jalas
# License: 3-Clause-BSD-LBNL
"""
This file is part of the Fourier-Bessel Particle-In-Cell code (FB-PIC)
It defines a class for field smoothing.
"""
import numpy as np

[docs] class BinomialSmoother( object ): """ Class that defines a binomial smoother on a grid, potentially with compensator. """ def __init__( self, n_passes=1, compensator=False): """ Initialize a binomial smoother Parameters ---------- n_passes: int or dictionary of ints Number of passes of binomial smoothing in r and z. (More passes results in smoother fields) If `n_passes` is an integer, than the same number of passes are applied in r and z. If `n_passes` is a dictionary, it should be of the form {'z': <int>, 'r': <int>} to indicate the number of passes in each direction. compensator: bool, or dictionary of bools Whether to apply a compensator in r and z. (Applying a compensator mitigates the impact of the smoother on low and intermediate frequencies) If `compensator` is a boolean, than this applies to r and z. If `n_passes` is a dictionary, it should be of the form {'z': <bool>, 'r': <bool>} to indicate whether a compensator is applied in r and/or in z. """ # Register smoothing parameters if type(n_passes) is int: self.n_passes = {'z': n_passes, 'r': n_passes} elif type(n_passes) is dict: self.n_passes = n_passes else: raise ValueError('Invalid argument `n_passes`') # Register compensator if type(compensator) is bool: self.compensator = {'z': compensator, 'r': compensator} elif type(compensator) is dict: self.compensator = compensator else: raise ValueError('Invalid argument `compensator`') def get_filter_array( self, kz, kr, dz, dr ) : """ Return the array that multiplies the fields in k space Parameters ---------- kz: 1darray The true wavevectors of the longitudinal, spectral grid (i.e. not the kz modified by finite order) kr: 1darray The transverse wavevectors on the spectral grid dz, dr: float The grid spacings (needed to calculate precisely the filtering function in spectral space) Returns ------- A 2darray of shape ( len(kz), len(kr) ) """ # Equivalent to nz passes of binomial filter in real space sz2 = np.sin( 0.5 * kz * dz )**2 nz = self.n_passes['z'] filt_z = ( 1. - sz2 )**nz # Add compensator if self.compensator['z']: filt_z *= ( 1. + nz*sz2 ) # Equivalent to nr passes of binomial filter in real space sr2 = np.sin( 0.5 * kr * dr )**2 nr = self.n_passes['r'] filt_r = ( 1. - sr2 )**nr # Add compensator if self.compensator['r']: filt_r *= ( 1. + nr*sr2 ) return( filt_z, filt_r )