How to access the data in a group of atoms and use it in the script

Hello LAMMPS users,

I am using the LAMMPS version 12Dec2018. I am grouping a certain number of atoms, and then setting the charge of the atoms in that group to 1.0.

set group nnatoms charge 1.0

After this, I open a loop to go through all the atoms in my model, and print only the atoms which are in the group and have a charge of 1.0. I tried the following:

label localneighbourloop # Loop label
variable nnloop loop ${natoms}

variable chargej equal charge[v_nnloop]
variable charge1 equal ${chargej}

if "${charge1}==1.0" then &
         "print 'Group atom ID = ${nnloop}'"

But I get an error which says “ERROR on proc 0: Invalid atom vector in variable formula (src/variable.cpp:4537)”. I know why the error comes, but I want to know if I can print or assign the IDs of the atoms in the group to variables. Thank you.


What you are asking for makes no sense to me. I have already commented on how bad an idea it is to do the kind of things you are trying to do with LAMMPS input script, so I am not going to repeat that.

Also, you are using a nearly 4 year old version with known bugs, I have no interest to figure out workaround for things I consider a bad idea in an obsolete version of LAMMPS. You will need to find somebody else to answer your questions or figure them out by yourself or change your approach.

Hello Dr. Kohlmeyer,

I ran the same code on the LAMMPS version 29Oct2020, and got the same error. I let my supervisor know that you said that it is almost impossible to do using a LAMMPS script. But he insists that I do this and complete it, especially because this is the last step of the code. Thank you.

You can probably write an atom-style variable combining gmask(x) and q[i] == 1.0 to report if particles obey your desired criterion (although if you’ve set all their charges to 1, isn’t it redundant to do this?)

But: the whole point of molecular dynamics is to integrate equations of motion for a nanoscale system to obtain results which using statistical mechanical theory can be shown to be relevant to macroscale systems. The whole point of using LAMMPS is that it takes care of looping over (potentially extremely large) lists of individual particles (usually extremely efficiently) and applying the relevant equations of motion to them all at once so that you don’t have to do any looping yourself. Of course, LAMMPS is incredibly flexible in what it will let you do to these particles, but it is a molecular dynamics simulator, not a general-purpose programming language with arbitrarily flexible vector manipulation semantics, and if you find yourself thinking of “looping over particles” in an input script you are almost certainly already lost. (If you find yourself needing to do that you need to modify the source code.)

Once you (or your supervisor) can think less in terms of “Here is a list of N particles and I will write a for-loop to do such-and-such to every odd-numbered particle except multiples of 13” and more in terms of “Here is a system of N particles which I would like to use to simulate this statistical ensemble under these conditions”, a great number of obstacles to the effective use of LAMMPS (or any other molecular dynamics software) will vanish.

Thank you for the response, Dr. Tee. I understand what you have stated. My original question was about using an atom-style variable to isolate a group of atoms. But the next step is where I am having problems. I am not sure how to use that atom-style variable in an if-condition (if “atom-style variable !=0”), since that would have to be an equal-style variable, and not an atom-style variable, within the Boolean condition. Thank you.


From my previous post, you should get why something like

if ("atom-style variable for atom i != 0") then "do something to atom i"

is not directly supported in LAMMPS.*

But if you consider that

  • relational operators return either a 1.0 or 0.0 depending on whether the relationship between x and y is TRUE or FALSE.
  • [For many fixes and commands, the input] value can be an atom-style variable

you will be able to do many great and terrible things. (Both sentences are direct quotes from documentation.) For example, here is a script that charges all southern black swans:

set atom * charge 0.0
variable australian_doom atom "0.75 * gmask(swans) * gmask(black) * (z <= 0)"
set atom * charge v_australian_doom


*I can’t remember if you could brute-force write an indexed loop and supply the index to the atom-style variable inside the if-statement. It’s still a terrible idea.

Let me repeat one more time. LAMMPS is quite capable of being used as a force engine for some non-MD purposes, but you cannot easily do this from the LAMMPS input script. This is what the library interface is for. There you can access data much more efficiently. You can control parallel execution of LAMMPS from a (mostly) serial code and you can much more efficiently collect and distribute data with the gather and scatter functions. Not only is trying to do such things from the input script hugely inefficient, it also is rather convoluted (due to all the needed workarounds and hacks) and thus much more difficult debug and get to work correctly. You need to keep in mind that a LAMMPS input that completes does not guarantee that it produces correct results.