Using fix NPT to Set up a Piston-like system?

Dear Developers,

I intended to set up a rectangular piston-like system in a NPT ensemble. Five boundaries are fixed with reflective walls, and allow the location of the last one to change, according to the internal pressure.

What I did was as follows:

fix zwalls all wall/reflect zlo EDGE #(let zhi change)

fix npt all npt temp 300.0 300.0 100.0 iso 0.0 0.0 1000.0

But it gave an error of Cannot use fix nvt/npt/nph on a non-periodic dimension (…/fix_nh.cpp:360).

How should I build this model? Thank you all in advance.


LAMMPS only allows barostats to act on periodic dimensions. There are good reasons for this. People regularly claim that this is an unnessary restriction, but so far no one has been able to describe a well-posed simulation that would require applying the barostat to a non-periodic dimension. As for your piston, perhaps you should explain a little better what exactly you are trying to accomplish.

Thanks Aidan! What I want the NPT ensemble to do is to let the solvated simulation box relax, and then I was trying to simulate the 3D diffusive process of a small molecule on a large surface of graphene using MD.

I see. I think the best solution is to:

  1. use fixed periodic dimensions in y and z (based on correct area for the graphene atoms)
  2. adjustable non-periodic dimension in x.
  3. Do something to the graphene to hold it in place on the left side in x (use a fixed atomic substrate or a repulsive wall)
  4. Add a repulsive wall or atomic slab on the right side in x, whose position you will adjust to achieve the desired pressure in the liquid.

4 is where a lot of creativity can be used. Here are some choices:

  1. The simplest is fix wall/reflect. The problem is it has zero range, so if you move it during the simulation, you will tend to lose atoms, which is bad.
  2. A better choice is fix wall/lj93.
  3. You could also use a wall made of atoms that don’t move
  4. You could also use another graphene slab.

The key is to have a reliable way to measure pressure. pxx will definitely be wrong. pyy and pzz might be a little off, due to surface tension effects. Instead, you should compute the force on the wall, which you can convert to a pressure. The easiest case is fix wall/lj93, which provides the force right in the fix vector e.g. f_mylj93wall[1].

You can now give the position of the wall as a variable expression in terms of the difference P - P_target, which will magically guide the wall to the correct position. If you have every tried to teach a teenager how to drive, you will realize that this is way harder than it sounds.

Here is a smarter solution. Run a one-time simulations where you slowly move the wall inward, measuring pressure as you go. You now have a look-up table that you can use to find your desired wall position.


Thanks Aidan. I tried exactly as what you mentioned above. I applied fix wall/piston and let it move from zlo slowly. But it’s apparent that temperature would increase dramatically (2000 K).

What I intended to do was to estimate a “near-balanced” piston position (cell volume) based on pressure (+/-), and then restart from that state, let the system spontaneously cool down to 300 K (by using fix temp/scale). And then run another simulation around that region with even slower piston. But when I tried to relax the system from high temperature, I ended up with all the temperature unchanged, no matter what parameters I choose.

I used fix nve, and commented out this line. But in neither case does temperature decrease. Where would you think the problem could be?

Thank you!

No, I never suggested using fix wall/piston. The fact that it is part of the SHOCK package might give you some indication that it is not a good way to equilibrate a system. I also warned against using a reflective wall. Please read and follow my original advice more closely.