WarpX icon indicating copy to clipboard operation
WarpX copied to clipboard

Multiple imbedded boundary

Open wwshunan opened this issue 9 months ago • 5 comments

Hi, I want to import the two complex electrodes from STL files into warpx to do the beam simulation. The electric potential of two electrodes are respectively set to the given positive and negative values. Then the computation domain is set to contain the electrodes to consider the particle motion under the effect of the potential of the electrodes. I used two EmbeddedBoundary to import the electrodes. But picmi.Simulation can only use one EmbeddedBoundary with the parameter warpx_embedded_boundary. How can I use multiple embedded boundaries? Thanks.

wwshunan avatar Feb 27 '25 14:02 wwshunan

Hi @wwshunan ,

Thank you for the question.

In order to get a complex embedded boundary from STL files with varying potential on it into a WarpX simulation, you need to do the following:

  • merge your embedded boundaries into a single STL file
  • in PICMI input, use the option EmbeddedBoundary::potential and provide it with a function string that can depend on x,y,z,t to "paint" your potential on the boundary with dependence on space and time. This PICMI option replicates the warpx.eb_potential(x,y,z,t) option, which has a bit more doc string to it. The function is only evaluated on locations of the embedded boundary, so you can draw your potential "broadly", e.g., in vacuum regions, and it only has an effect where there is a boundary.

For the function, you can use piecewise functions and ifs, per our usual syntax here.

ax3l avatar Feb 28 '25 20:02 ax3l

Thank you very much. Next I want to simulate the beam between the very long electrodes and I think the grid moving along with the particle beam is needed. Could you give me some suggestion?

wwshunan avatar Mar 02 '25 14:03 wwshunan

Hi @wwshunan, If the shape of the long electrodes is translationally invariant along the direction of propagation of the beam, then turning on the moving window should work. You can do this by following this line of the example: https://github.com/ECP-WarpX/WarpX/blob/development/Examples/Physics_applications/laser_acceleration/inputs_test_3d_laser_acceleration_picmi.py#L38

RemiLehe avatar Mar 04 '25 00:03 RemiLehe

Thank you again. The electric field Ey was not changed correspondingly when the potential value 67000 of the electrodes was changed. Is there incorrect setting in my code. My code is given below:

from pywarpx import picmi
from scipy.constants import c, e
from wrdis import readDis 
import pywarpx
import matplotlib.pyplot as plt
import numpy as np

data = readDis('part_rfq.dst')
part_num = int(data.shape[0])

# 设置位置
mass = 938.272
freq = 202.56e6
I = 70e-7
q = I / freq
gamma = data[:, 5] / mass + 1
beta = (1 - gamma**-2)**0.5
lm = c / freq
x = data[:, 0]*0.01
y = data[:, 2]*0.01
z = -data[:, 4]*beta*lm/(2*np.pi)
z -= z.max() + 0.0248536
ux = gamma * data[:, 1] * beta * c 
uy = gamma * data[:, 3] * beta * c 
uz = gamma * beta * c  

constants = picmi.constants
number_of_steps = 50    # Number of simulation steps

# 设置网格参数
nx = 64
ny = 64
nz = 64
xmin = -0.02
xmax = 0.02 
ymin = -0.02
ymax = 0.02
zmin = z.min()
zmax = 0


# 创建网格
grid = picmi.Cartesian3DGrid(
    number_of_cells=[nx, ny, nz],
    lower_bound=[xmin, ymin, zmin],
    upper_bound=[xmax, ymax, zmax],
    lower_boundary_conditions=['neumann', 'neumann', 'neumann'],
    upper_boundary_conditions=['neumann', 'neumann', 'neumann'],
    lower_boundary_conditions_particles=["absorbing", "absorbing", "absorbing"],
    upper_boundary_conditions_particles=["absorbing", "absorbing", "absorbing"],
)

# 导入 STL 文件
eb = picmi.EmbeddedBoundary(
    stl_file='electrode.stl',
    potential="(((y*y-x*x)>0) - ((y*y-x*x)<0))*67000"
)

# Define the proton species with in-memory particle data
protons = picmi.Species(
    particle_type='proton',  # Uses m_p and e from scipy.constants
    name='protons',
    initial_distribution=picmi.ParticleListDistribution(
        x=x, y=y, z=z,
        ux=ux, uy=uy, uz=uz,  # Convert momentum to velocity (m/s)
        weight=np.ones_like(x) * q / (e * len(x))    # Uniform weight, total charge = e
    )
)


field_diag = picmi.FieldDiagnostic(
    name='diag',
    grid = grid,
    period = 10,
    data_list = ['E', 'part_per_cell'],
    warpx_format = 'plotfile',
    write_dir = './results',
    warpx_file_prefix = 'plt')

particle_diag = picmi.ParticleDiagnostic(
    name='diag',
    period=10,
    species=[protons],
    data_list = ['weighting', 'momentum'],
    warpx_format='plotfile'
)

solver = picmi.ElectrostaticSolver(
    grid=grid, method="Multigrid", warpx_absolute_tolerance=1e-7
)

# 创建模拟对象
sim = picmi.Simulation(
    warpx_embedded_boundary=eb,
    time_step_size=1/freq/30,    # Adjust time step (in seconds)
    solver=solver,
    max_steps=10
)
sim.add_species(protons, layout=None)
#sim.add_species(protons, layout=picmi.PseudoRandomLayout(n_macroparticles=len(x)))
#sim.add_species(protons, layout=picmi.PseudoRandomLayout(n_macroparticles=number_sim_particles))
sim.add_diagnostic(field_diag)
sim.add_diagnostic(particle_diag)

# 运行模拟
sim.step(number_of_steps)

wwshunan avatar Mar 04 '25 11:03 wwshunan

I checked the simulation results and the potentials on the electrodes are 1V and -1V respectively.

wwshunan avatar Mar 05 '25 07:03 wwshunan