Kinetic energy filter surface

Hi,

Is there a possibility in lammps to make a surface act as a particle filter, letting through only particles that having a kinetic energy above a certain value?

The surface would selectively let through a simulated particle colliding into it based on its kinetic energy - if the particle has a kinetic energy above a certain (user defined) threshold, it will pass through the surface and if it doesn’t it will bounce back from the surface.

Hello,
I am not sure if there are ways to do that, but may be it would be possible to modify fix one way to achieve what you want…
Simon

There is not much of a modification needed. It only needs to be enabled for use with dynamic groups. This is done by simply adding the line dynamic_group_allow = 1; to the constructor and recompiling LAMMPS:

diff --git a/src/EXTRA-FIX/fix_oneway.cpp b/src/EXTRA-FIX/fix_oneway.cpp
index d514a081f1..f31781d936 100644
--- a/src/EXTRA-FIX/fix_oneway.cpp
+++ b/src/EXTRA-FIX/fix_oneway.cpp
@@ -35,6 +35,7 @@ FixOneWay::FixOneWay(LAMMPS *lmp, int narg, char **arg) :
     Fix(lmp, narg, arg), region(nullptr), idregion(nullptr)
 {
   direction = NONE;
+  dynamic_group_allow = 1;
 
   if (narg < 6) error->all(FLERR, "Illegal fix oneway command");
 

With that modified version (the change will be added to the next feature release of LAMMPS, of course), you can use a dynamic group to select which atoms get reflected and which can pass. Here is a simple example input with some non-interacting particles that are given a range of velocities. The color indicates whether they are above or below the given kinetic energy threshold. If necessary, the dynamic group update and the application of fix oneway can be done less frequently, if they impact the performance too much.

boundary f p p
region box block 0 50 0 10 0 10
create_box 1 box

region start block 0 5 0 10 0 10
create_atoms 1 random 200 65345 start

region select block 20 30 0 10 0 10

mass 1 1.0
pair_style zero 1.0
pair_coeff * *

variable vel atom random(1.0,3.0,54645)
velocity all set v_vel 0.0 0.0

fix 1 all nve

thermo_modify lost ignore

compute ke all ke/atom
variable filter atom c_ke<3.0
group blocked dynamic all var filter every 1
fix 2 blocked oneway 1 select -x

dump 1 all custom 25 barrier.lammpstrj id x y z

run 4000 post no

Thanks, I’ll try this!

Cheers,
Antti

Hi,

Thanks again, this was exactly what I was looking for.
Related question: is it possible to add a stochastic element in the filtering? So, even if the particle has enough kinetic energy to pass through the filter it might still bounce back based on a user-defined probability?

Thanks,
Antti

Yes, the atoms that are selected to be included in the fix group are determined by the expression of the atom style variable “filter”. That expression can be augmented to include a random component and you have to factor in that logical expressions resolve to either 1 for true and 0 for false. Thus, e.g. “1.0-(c_ke>=3.0)*(random(0.0,1.0,43576234)>0.1)” will apply the filter also to 10% of the atoms that have enough kinetic energy.

When I used

variable filter atom 1.0-(c_ke>=3.0)*(random(0.0,1.0,43576234)>0.1)

the particles with enough kinetic energy bouncing back due to the random component were not accurately selected - e.g. for a 1000 particles, almost all bounced back.

I think this was because these commands

group blocked dynamic all var filter every 1
fix 2 blocked oneway 1 select -x

redo the group and oneway fix every timestep while the particles with ke >= 3.0 travel through the ‘select’ region longer than one timestep, and so many more than 10 percent of the particles end up bouncing back. I can solve this by putting the simulation run step value for the ‘every’ keyword, but then if the bounced back particle tries again to filter through (reflected back to the filter from the xlo or colliding with another particle) it will have the same initial filter variable boolean value.
How can I filter the particles so that a random component is rolled once only for each particle entering the select block, and will be rerolled again when the particle re-enters the block?

Thanks,
Antti

You can try making the fix oneway region thinner and/or update the group less frequently. However, that will not apply the reflection criterion as strictly, fast atoms can move past without being impacted.

If you want a strict application of your criteria, you will have to write a new fix that does exactly what you want.

Just to post my result here, this works pretty well for me (particles are bounced back relatively close according to the given probabilty). Basically I used a wall/reflect fix for the blocked group and a reservoir region that overlap only slightly:

boundary f p p
region box block 0 50 0 50 0 50
create_box 1 box

region start block 0 5 0 10 0 10
create_atoms 1 random 100 65345 start

region reservoir block 0 25.0001 0 50 0 50

mass 1 1.0
pair_style zero 1.0
pair_coeff * *

variable vx atom random(1.0,6.0,54645)
velocity all set v_vx 0.0 0.0

fix 1 all nve

compute ke all ke/atom
variable filter atom (1.0-(c_ke>=3.0)*(random(0.0,1.0,82374)>0.1))
group blocked dynamic all region reservoir var filter every 1
fix 2 blocked wall/reflect xhi 25.0

thermo_modify lost ignore

dump 1 all custom 25 barrier.lammpstrj id x y z

run 40000

Regarding this topic, how could the escaped particles be replaced in the “reservoir” region before the filter? My goal is to keep the kinetic energy (temperature, mass) in the reservoir steady (nvt, npt ok) and simulate a constant stream of particles going through the filter.

There should be some discussion of such a scenario (flow through some barrier/filter) in the archives. I recall describing a possible application before at least twice.

Basic idea:

  • fully periodic system
  • four zones:
    • reservoir area with equilibrated system and an added force inducing the flow
    • barrier / filter area
    • free area with added force (of fix oneway) to move particles, that passed through, reliably toward the pre-reservoir
    • pre-reservoir with strong thermostatting, that brings wrapped around atoms back to near equilibrium

There should be some details in the old discussions, which may not be perfect matches to what you describe, but the principle should be the same.

The alternative, as mentioned before, is to implement a custom fix that can “beam” particles back to the reservoir.