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 binary Coulomb collisions between plasma species #676

Merged
merged 29 commits into from
Mar 16, 2022

Conversation

MaxThevenet
Copy link
Member

@MaxThevenet MaxThevenet commented Feb 25, 2022

This PR proposes an implementation of binary Coulomb collisions between plasma species. It is largely inspired by the WarpX implementation (see ECP-WarpX/WarpX#539 for the original PR), based on this article by F. Pérez et al. In particular files ComputeTemperature.H, ElasticCollisionPerez.H, ShuffleFisherYates.H, and UpdateMomentumPerez.H were copy-pasted before being modified, and are kept as close as possible to the WarpX implementation on purpose, in view of a potential future merge. The main authors @Yin-YinjianZhao @ax3l @RemiLehe @atmyers are co-authors of this commit.

The module can be used by adding e.g.

plasmas.collisions = collision1
collision1.species = plasma plasma
collision1.CoulombLog = 20

in an input file (assuming the electron plasma species is called plasma).

Main changes

As mentioned above, files ComputeTemperature.H, ElasticCollisionPerez.H, ShuffleFisherYates.H, and UpdateMomentumPerez.H were copy-pasted from WarpX, and modified to work with the specifics of quasi-static PIC:

  • HiPACE++ does not store the longitudinal momentum of plasma particles, it uses the pseudo-potential psi instead. Therefore, uz is replaced by psi in the argument of a few functions.
  • The core of the collision module in UpdateMomentumPerez.H needs the actual uz. Conversions were added between psi and uz in this file.

Other changes are:

  • A new class CoulombCollision was created (see CoulombCollision.H/cpp). For each type of collisions enabled (i.e., between 2 plasma species, potentially twice the same), a new instance of this class is created. The vector of objects is stored in class MultiPlasma.
  • Minor changes to TileSort were implemented so it works on CPU and GPU.

In the loop over slices in HiPACE::Evolve, after each particle push by 1 longitudinal cell, plasma particles of the relevant species are sorted per-cell and collided pairwise within each cell.

Tests

Linear regime: comparison with WarpX

This HiPACE++ input file and this WarpX input file were run on GPU, giving the following:
Lineout: transverse cut of the fields, where we compare the general shape of the fields and the difference between with and without collisions:
Linear_slice
x-z slice of the Ez field:
Linear_Ez
x-z slice of the Ex - c*By field:
Linear_ExmBy
The number of ppc was increased to 8x8x1 to observe a good agreement.

Non-linear regime: comparison with WarpX

This HiPACE++ input file and this WarpX input file were run on GPU, giving the following:
Lineout: transverse cut of the fields, where we compare the general shape of the fields and the difference between with and without collisions:
Nonlinear_slice
x-z slice of the Ez field:
Nonlinear_Ez
x-z slice of the Ex - c*By field:
Nonlinear_ExmBy

The agreement is not excellent for the non-linear regime (even without collisions), in particular because these runs are a bit far from convergence. However, changing the parameters turned out to be difficult because of ECP-WarpX/WarpX#2886.

TODO (for future PRs)

  • Fix the PhysConstSI stuff, that's not great.
  • Run with new psi+1
  • Fix dt: each plasma particle has a different dt depending on its psi, which has an impact on the algorithm in the relativistic regime.
  • Enable tiling: the current implementation has been tested on GPU and on CPU without tiling, but it should be crossed-checked (and maybe improved) when tiling and openMP threading are used.
  • Inter-species 1: electrons and (heavy, so immobile) protons (species have opposite charges)
  • Inter-species 2: electrons and (light, so mobile) positrons
  • Inter-species 3: electrons and heavier ions (e.g. Helium)

The three last tests can be performed in the WarpX vs. HiPACE++ framework.

MaxThevenet and others added 3 commits February 25, 2022 18:27
…SA PIC loop

Co-authored-by: Axel Huebl <axelhuebl@lbl.gov>
Co-authored-by: Andrew Myers <atmyers@lbl.gov>
Co-authored-by: Yinjian Zhao <yinjianzhao@lbl.gov>
Co-authored-by: Remi Lehe <rlehe@lbl.gov>
@MaxThevenet MaxThevenet added documentation Improvements or additions to documentation component: plasma About the plasma species labels Feb 25, 2022
@MaxThevenet MaxThevenet changed the title Implement binary Coulomb collisions between plasma species [WIP] Implement binary Coulomb collisions between plasma species Feb 25, 2022
@MaxThevenet MaxThevenet changed the title [WIP] Implement binary Coulomb collisions between plasma species Implement binary Coulomb collisions between plasma species Feb 26, 2022
@MaxThevenet MaxThevenet mentioned this pull request Feb 28, 2022
9 tasks
Copy link
Member

@SeverinDiederichs SeverinDiederichs left a comment

Choose a reason for hiding this comment

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

To continue with this work, let's merge it with minor suggestions after @AlexanderSinn reviewed it.

Then, the following things must be fixed:

  1. normalized units
  2. adding the constant of motion (or unifying it with psi, as discussed offline, this needs some changes in the particle pusher)
  3. not changing psi (this is non-physical), but rather the constant of motion
  4. currently, the safety nets are minimal: if a user fails at providing correct names in collision.species = name name it just segfaults. It should be asserted that the names in the collision.species are in plasmas.names

src/particles/CoulombCollision.cpp Outdated Show resolved Hide resolved
src/particles/CoulombCollision.cpp Outdated Show resolved Hide resolved
src/particles/ElasticCollisionPerez.H Outdated Show resolved Hide resolved
src/particles/ComputeTemperature.H Outdated Show resolved Hide resolved
tests/collisions.SI.1Rank.sh Outdated Show resolved Hide resolved
MaxThevenet and others added 2 commits March 14, 2022 13:11
Co-authored-by: Severin Diederichs <65728274+SeverinDiederichs@users.noreply.github.com>
Copy link
Member

@AlexanderSinn AlexanderSinn left a comment

Choose a reason for hiding this comment

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

See review

src/particles/UpdateMomentumPerez.H Show resolved Hide resolved
src/particles/UpdateMomentumPerez.H Show resolved Hide resolved
src/particles/PlasmaParticleContainer.H Outdated Show resolved Hide resolved
@MaxThevenet
Copy link
Member Author

Update: I merged dev into this branch to include the new psi+1 handling. Now it all works as expected (CI passes, as well as the tests above). This is ready for review/merge.

@MaxThevenet MaxThevenet merged commit 95c4f2c into Hi-PACE:development Mar 16, 2022
@MaxThevenet MaxThevenet deleted the collision2 branch March 16, 2022 10:27
@MaxThevenet MaxThevenet mentioned this pull request Mar 16, 2022
6 tasks
Comment on lines +44 to +50
// particle's Lorentz factor
const amrex::Real g1_tmp = (1.0_rt+u1x*u1x*inv_c2 + u1y*u1y*inv_c2 + psi1*psi1) / (2.0_rt*psi1);
amrex::Real u1z = PhysConstSI::c * (g1_tmp - psi1);

// particle's Lorentz factor
const amrex::Real g2_tmp = (1.0_rt+u2x*u2x*inv_c2 + u2y*u2y*inv_c2 + psi2*psi2) / (2.0_rt*psi2);
amrex::Real u2z = PhysConstSI::c * (g2_tmp - psi2);
Copy link
Member Author

Choose a reason for hiding this comment

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

This is what's different from WarpX

Comment on lines +268 to +269
const amrex::Real ga = std::sqrt( T_R(1.0) + (u1x*u1x+u1y*u1y+u1z*u1z)*inv_c2 );
psi1 = ga - u1z/PhysConstSI::c;
Copy link
Member Author

Choose a reason for hiding this comment

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

as well as backward conversion here

Comment on lines +279 to +280
const amrex::Real ga = std::sqrt( T_R(1.0) + (u2x*u2x+u2y*u2y+u2z*u2z)*inv_c2 );
psi2 = ga - u2z/PhysConstSI::c;
Copy link
Member Author

Choose a reason for hiding this comment

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

and here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: plasma About the plasma species documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants