# PICMI - Particle-In-Cell Modeling Interface The Particle-In-Cell Modeling Interface (PICMI) standard establishes conventions for the naming and structuring of input files for Particle-In-Cell (PIC) simulations. PICMI provides a unified Python interface that allows researchers to write simulation scripts that are portable across different PIC codes such as WarpX, FBPIC, and Warp. The standard defines a common language for specifying grids, particles, fields, lasers, diagnostics, and other simulation components. PICMI is designed to be code-agnostic while allowing code-specific extensions through prefixed keyword arguments. The base classes provided in this package serve as the foundation that implementing codes inherit from to provide their specific functionality. This approach enables users to switch between PIC codes with minimal changes to their simulation scripts, promoting reproducibility and collaboration in plasma physics research. ## Installation ```bash pip install picmistandard ``` ## Simulation Setup The `PICMI_Simulation` class is the main container that brings together all simulation components including the field solver, particle species, lasers, applied fields, and diagnostics. ```python from picmistandard import picmi # Create a 3D Cartesian grid grid = picmi.Cartesian3DGrid( number_of_cells=[64, 64, 480], lower_bound=[-30e-6, -30e-6, -38e-6], upper_bound=[30e-6, 30e-6, 10e-6], lower_boundary_conditions=['periodic', 'periodic', 'open'], upper_boundary_conditions=['periodic', 'periodic', 'open'], moving_window_velocity=[0., 0., picmi.constants.c] ) # Create electromagnetic solver with Cole-Karkkainen-Cowan stencil smoother = picmi.BinomialSmoother(n_pass=[1, 1, 1], compensation=[True, True, True]) solver = picmi.ElectromagneticSolver( grid=grid, cfl=1.0, method='CKC', # Options: 'Yee', 'CKC', 'Lehe', 'PSTD', 'PSATD', 'DS', 'ECT' source_smoother=smoother ) # Initialize the simulation sim = picmi.Simulation( solver=solver, time_step_size=1e-15, # seconds max_steps=1000, verbose=1, particle_shape='linear' # Options: 'NGP', 'linear', 'quadratic', 'cubic' ) # Run the simulation sim.step(1000) # Run for 1000 time steps ``` ## Grid Classes PICMI provides multiple grid types for different simulation geometries including 1D, 2D, 3D Cartesian, and cylindrical (RZ) grids. ```python from picmistandard import picmi # 3D Cartesian Grid - using individual parameters grid_3d = picmi.Cartesian3DGrid( nx=64, ny=64, nz=480, xmin=-30e-6, xmax=30e-6, ymin=-30e-6, ymax=30e-6, zmin=-38e-6, zmax=10e-6, bc_xmin='periodic', bc_xmax='periodic', bc_ymin='periodic', bc_ymax='periodic', bc_zmin='open', bc_zmax='open', moving_window_velocity=[0., 0., 3e8], guard_cells=[8, 8, 8], pml_cells=[10, 10, 10] ) # Cylindrical (RZ) Grid for axisymmetric simulations grid_rz = picmi.CylindricalGrid( nr=32, nz=480, rmin=0., rmax=30e-6, zmin=-38e-6, zmax=10e-6, bc_rmin=None, # Axis boundary bc_rmax='open', bc_zmin='open', bc_zmax='open', n_azimuthal_modes=2, moving_window_velocity=[0., 3e8] ) # 2D Cartesian Grid grid_2d = picmi.Cartesian2DGrid( number_of_cells=[64, 480], lower_bound=[-30e-6, -38e-6], upper_bound=[30e-6, 10e-6], lower_boundary_conditions=['periodic', 'open'], upper_boundary_conditions=['periodic', 'open'] ) # Add mesh refinement region grid_3d.add_refined_region( level=1, lo=[-10e-6, -10e-6, -20e-6], hi=[10e-6, 10e-6, 5e-6], refinement_factor=[2, 2, 2] ) ``` ## Particle Species PICMI supports defining particle species with various particle types, distributions, and physical properties. ```python from picmistandard import picmi # Define an electron species with analytic density distribution plasma_distribution = picmi.AnalyticDistribution( density_expression="1.e23*(1+tanh((z - 20.e-6)/10.e-6))/2.", lower_bound=[-20e-6, -20e-6, 0.0], upper_bound=[20e-6, 20e-6, 1e-3], rms_velocity=[0., 0., 0.], directed_velocity=[0., 0., 0.], fill_in=True # Fill in particles as moving window advances ) electrons = picmi.Species( particle_type='electron', name='electrons', initial_distribution=plasma_distribution, particle_shape='linear', method='Boris' # Options: 'Boris', 'Vay', 'Higuera-Cary', 'Li', 'free-streaming' ) # Define an ion species with explicit charge and mass protons = picmi.Species( particle_type='proton', name='protons', charge_state=1, initial_distribution=plasma_distribution ) # Multi-species definition (e.g., for plasma with multiple ion types) multi_species = picmi.MultiSpecies( particle_types=['He', 'Ar', 'electron'], names=['He+', 'Argon', 'e-'], charge_states=[1, 5, None], proportions=[0.2, 0.8, 0.2 + 5*0.8], initial_distribution=plasma_distribution ) # Access individual species from multi-species helium = multi_species['He+'] # By name argon = multi_species[1] # By index ``` ## Particle Distributions PICMI provides various particle distribution classes for initializing particle positions and velocities. ```python from picmistandard import picmi import numpy as np # Uniform density distribution uniform_dist = picmi.UniformDistribution( density=1e23, # particles per m^3 lower_bound=[-10e-6, -10e-6, 0.], upper_bound=[10e-6, 10e-6, 100e-6], rms_velocity=[1e5, 1e5, 1e5], directed_velocity=[0., 0., 1e7], fill_in=True ) # Gaussian bunch distribution (for beams) gaussian_bunch = picmi.GaussianBunchDistribution( n_physical_particles=1e8, rms_bunch_size=[1e-6, 1e-6, 1e-6], rms_velocity=[0., 0., 10.*3e8], centroid_position=[0., 0., -22e-6], centroid_velocity=[0., 0., 1000.*3e8], velocity_divergence=[0., 0., 0.] ) # Analytic distribution with custom expression analytic_dist = picmi.AnalyticDistribution( density_expression='((x**2+y**2)