Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement injection of particles from the embedded boundary #5208

Merged
merged 59 commits into from
Oct 10, 2024

Conversation

RemiLehe
Copy link
Member

@RemiLehe RemiLehe commented Sep 3, 2024

Overview

This PR implements flux injection of particles from the embedded boundary.

It also adds a test that emits particles from a sphere in 3D as represented here:
movie
as well as RZ and 2D versions of this test. (In 2D, the particles are emitted from a cylinder.)

As can be seen in the above movie, particles are emitted from a single point within each cell (the centroid of the EB), instead of being emitted uniformly on the surface of the EB within the cell. This could be improved in a future PR.

The implementation as well as the user interface largely re-use the infrastructure for the flux injection from a plane. However, as a result, the user interface is perhaps not very intuitive. In particular, when specify the velocity distribution, uz represents the direction normal to the EB while ux, uy represent the tangential directions. This again will be improved in follow-up PR.

Follow-up PRs

  • Change the interface of gaussianflux so as to specify the tangential and normal distribution. In other words, instead of:
electron.momentum_distribution_type = gaussianflux
electron.ux_th = 0.01
electron.uy_th = 0.01
electron.uz_th = 0.1
electron.uz_m = 0.07

we would do:

electron.momentum_distribution_type = gaussianflux
electron.u_tangential_th = 0.01  # Tangential to the emitting surface
electron.u_normal_th = 0.1   # Normal to the emitting surface
electron.u_normal_m = 0.07
  • Change the interface so that the user does not need to specify the number of macroparticles per cell (which is problematic for EB, since difference cell contain different EB surface, and should in general emit different numbers of macroparticles). Instead, we would specify the weight of macroparticles, i.e. instead of
electron.injection_style = NFluxPerCell
electron.num_particles_per_cell = 100   
electron.flux_function(x,y,z,t) = "1.”

we would do

electron.injection_style = NFluxPerCell
electron.flux_macroweight = 200   # Number of physical particles per macroparticle
electron.flux_function(x,y,z,t) = "4e12” # Number of physical particles emitted per unit time and surface  
  • Add a way for the user to specify the total flux across the whole emitting surface
    Example:
electron.flux_function(x,y,z,t) = "(x>-1)*(x<1)"
electron.total_flux = 4e12 # physical particle / second (not per unit area)

(In that case, flux_function would be rescaled internally by WarpX so as to emit the right number of particles.)

  • Add PICMI interface
  • Emit the particles uniformly from the surface of the EB within one cell

@RemiLehe RemiLehe added the component: boundary PML, embedded boundaries, et al. label Sep 3, 2024
@RemiLehe RemiLehe changed the title [WIP] Implement injection of particles from the embedded boundary Implement injection of particles from the embedded boundary Oct 10, 2024
@@ -22,6 +22,29 @@
#include <AMReX_REAL.H>
#include <AMReX_RealBox.H>

struct PDim3 {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to move this object from PhysicalParticleContainer.cpp to AddPlasmaUtilities.H as part of this PR.

AMREX_GPU_HOST_DEVICE
PDim3& operator=(PDim3&&) = default;
};

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to move this object from PhysicalParticleContainer.cpp to AddPlasmaUtilities.H as part of this PR.

@RemiLehe RemiLehe requested a review from dpgrote October 10, 2024 16:18
@RemiLehe RemiLehe assigned dpgrote and RemiLehe and unassigned RemiLehe Oct 10, 2024

#ifdef AMREX_USE_EB
/*
This computes the scale_fac (used for setting the particle weights) on a on area basis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the standard documentation format, like

    /*
     * \brief This computes...
     * 
     * \param[in] dx
     * /

Though I do notice that no other docs in this file match this format.


// Rotate the momentum along the theta direction (in the z-x plane)
amrex::Real const cos_theta = nz;
amrex::Real const sin_theta = std::sqrt(1-nz*nz);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1._rt

To simplify this, could the theta and phi rotations be combined into one set of expressions, a 3D rotation?

@@ -1371,6 +1348,22 @@ PhysicalParticleContainer::AddPlasmaFlux (PlasmaInjector const& plasma_injector,
const auto dx = geom.CellSizeArray();
const auto problo = geom.ProbLoArray();

#ifdef AMREX_USE_EB
bool inject_from_eb = plasma_injector.m_inject_from_eb; // whether to inject from EB or from a plane
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool const

// Skip cells that do not overlap with the plane
if (!flux_pos->overlapsWith(lo, hi)) { return; }
}
const int num_ppc_int = static_cast<int>(num_ppc_real_in_this_cell + amrex::Random(engine));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looses the change made in PR #5272. The calculation of num_ppc_int should happen after the r factor is included.

@@ -1659,6 +1736,7 @@ PhysicalParticleContainer::AddPlasmaFlux (PlasmaInjector const& plasma_injector,
// For cylindrical emission (flux_normal_axis==0
// or flux_normal_axis==2), the emission surface depends on
// the radius ; thus, the calculation is finalized here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this blank line be delete? It's an unrelated format change.

#ifdef AMREX_USE_EB
if (inject_from_eb) {
#if defined(WARPX_DIM_3D)
pos.x = overlap_corner[0] + (iv[0] + 0.5_rt + eb_bnd_cent_arr(i,j,k,0))*dx[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this putting all of the particles at the same location, the EB boundary center? Is there a way to distribute the particles around on the EB surface?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's absolutely correct: all the particles are emitted from a single point. (See also the PR description.)
We should indeed distribute the particles over the EB surface. This should be doable but will take a bit more time. This will be added in a follow-up PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have read the whole PR description :)

@RemiLehe RemiLehe requested a review from dpgrote October 10, 2024 20:31
Copy link
Member

@dpgrote dpgrote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks!

@RemiLehe RemiLehe merged commit 1794629 into ECP-WarpX:development Oct 10, 2024
32 of 37 checks passed
dpgrote pushed a commit to dpgrote/WarpX that referenced this pull request Oct 23, 2024
…X#5208)

# Overview

This PR implements flux injection of particles from the embedded
boundary.

It also adds a test that emits particles from a sphere in 3D as
represented here:

![movie](https://github.com/user-attachments/assets/1e76cf87-fd7d-4fa3-8c83-363956226a42)
as well as RZ and 2D versions of this test. (In 2D, the particles are
emitted from a cylinder.)

As can be seen in the above movie, particles are emitted from a single
point within each cell (the centroid of the EB), instead of being
emitted uniformly on the surface of the EB within the cell. This could
be improved in a future PR.

The implementation as well as the user interface largely re-use the
infrastructure for the flux injection from a plane. However, as a
result, the user interface is perhaps not very intuitive. In particular,
when specify the velocity distribution, `uz` represents the direction
normal to the EB while `ux`, `uy` represent the tangential directions.
This again will be improved in follow-up PR.

# Follow-up PRs

- [ ] Change the interface of `gaussianflux` so as to specify the
tangential and normal distribution. In other words, instead of:
```
electron.momentum_distribution_type = gaussianflux
electron.ux_th = 0.01
electron.uy_th = 0.01
electron.uz_th = 0.1
electron.uz_m = 0.07
```
we would do:
```
electron.momentum_distribution_type = gaussianflux
electron.u_tangential_th = 0.01  # Tangential to the emitting surface
electron.u_normal_th = 0.1   # Normal to the emitting surface
electron.u_normal_m = 0.07
```

- [ ] Change the interface so that the user does not need to specify the
number of macroparticles per cell (which is problematic for EB, since
difference cell contain different EB surface, and should in general emit
different numbers of macroparticles). Instead, we would specify the
weight of macroparticles, i.e. instead of
```
electron.injection_style = NFluxPerCell
electron.num_particles_per_cell = 100   
electron.flux_function(x,y,z,t) = "1.”
```
we would do
```
electron.injection_style = NFluxPerCell
electron.flux_macroweight = 200   # Number of physical particles per macroparticle
electron.flux_function(x,y,z,t) = "4e12” # Number of physical particles emitted per unit time and surface  
```

- [ ] Add a way for the user to specify the total flux across the whole
emitting surface
Example:
```
electron.flux_function(x,y,z,t) = "(x>-1)*(x<1)"
electron.total_flux = 4e12 # physical particle / second (not per unit area)
```
(In that case, `flux_function` would be rescaled internally by WarpX so
as to emit the right number of particles.)

- [ ] Add PICMI interface
- [ ] Emit the particles uniformly from the surface of the EB within one
cell
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: boundary PML, embedded boundaries, et al.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants