Questions about loop in lammps

Dear all,

I would like to addforce to lammps and the force is calculated by python scripts. However, it seems that it just evaluates the forces per atom. I want to sum the force of all atoms and add it to all atoms. The present input file is

"

variable tz2 equal z*[1]*
variable tx2 equal x*[1]*

variable tz2 equal z*[1]*

variable force_z python force_CH4_z
python force_CH4_z input 3 v_tx2 v_ty2 v_tz2 return v_force_z format ffff file interp*.*py

fix 3 all addforce 0 0 v_force_z
"

It just calculate the first atom’s force and it works. Could you tell me how to do a loop that can sum the force of all atoms and do the remaining calculation. I tried the flowing commend

label loop

variable a loop 100

variable tz2 equal z[a]

variable tx2 equal x[a]

variable ty2 equal y[a]

variable force_z python force_CH4_z

python force_CH4_z input 3 v_tx2 v_ty2 v_tz2 return v_force_z format ffff file interp.py

fix 3 all addforce 0 0 v_force_z

clear

next a

jump z_move.force

"

But the result is that “Segmentation fault”. Could you tell me how to set a corect loop?

Thanks!

The “clear” command will delete all atoms, therefore the loop index goes out of bounds when you enter the next iteration.

Also, it is very inefficient to loop over all atoms explicitly, you may consider passing the entire atom-style variables x, y and z to the Python command in one go.

Inside the Python script, try using as many NumPy library functions, and avoid again explicit loops over atoms.

Giacomo

Don’t do a loop, use compute reduce instead.
Axel

Dear Dr Axel,

I have another question. The python scripts need to input a atom coordinate to get the force. It cannot input all atoms’ coordinate. The previous way is to set the first atom’s coordinate as the input for python. I do not know how to use compute reduce to input the coordinate to python one by one and then get the sum of the force. Could you tell me more about it?

Thanks!

Dear Dr Axel,

    I have another question. The python scripts need to input a atom
coordinate to get the force. It cannot input all atoms' coordinate. The
previous way is to set the first atom's coordinate as the input for
python. I do not know how to use *compute reduce* to input the coordinate
to python one by one and then get the sum of the force. Could you tell me
more about it?

​you are not making much sense here.

specifically, you don't seem to be understanding the data model of LAMMPS
and how it is parallelized.

doing a loop over all atoms at the LAMMPS script level and calling a python
function for every atom is a procedure that is very slow even for a single
atom, but intolerable for all of them. it particularly will defeat all
parallelization, since you turn the processing across processors and
distributed data structures into slow global operations.

​it also, is not clear from your description whether you want to compute a
different, position dependent force for each atom, or put the sum over
position depended​ forces into fix addforce.
finally, how is your force defined in the python function? unless you are
doing complex operations, perhaps it will be easier (and faster) to do the
same computation with an atom style variable.
or you'd have to avoid passing arguments at all and access all LAMMPS data
structures directly inside the python function via the lammps python module
and then do the computation across all atoms.
there is still a good chance, that with a python function things will be
slowed down significantly. so for a complex operation, implementing in
python would at best serve for prototyping and then require a C++
implementation for good performance.

at any rate, you need to spend more time studying various examples about
how to compute properties, how to access data, and how to avoid serializing
parallel operations.

axel.

DearDrAxel

Thanks for your advice! Actually, the force is calculated through a potential energy state which gived in python. I just want to calculated the force of every atom directlly from python and add it to lammps. So you mean it is intolerable for lammps to do it?

Thanks!

LAMMPS will be able to handle it, but the speed may be “intolerable” for you, since you’d be running a series of commands for each atom. The cost of starting/stopping those commands is not huge, but it adds up quickly as you go over the entire system.

I suggested passing an atom-style variable to Python (i.e. a variable that is actually a long vector, one for each atom). That would be faster (the loop over atoms is implicit if you code your Python function well), but it would still need to run in serial, losing most parallel speedups. Axel suggested using an atom-style variable directly, which would be divided among processors.

The key message here is that your approach may be acceptable to you and for your specific system, but if it is dramatically inefficient you won’t get much support from others who need as much speed from LAMMPS as they can get.

Giacomo

DearDrAxel

Thanks for your advice!

Actually, the force is calculated through a potential energy state
which gived in python.

​that is not helping.​

I just want to calculated the force of every atom directlly from
python and add it to lammps. So you mean it is intolerable for lammps to do
it?

​i have already written down what i mean in my previous e-mail. i don't see
the point of repeating it.
the short message is, the way you are trying to implement your feature
*cannot* work because you don't understand the flow of control and the data
structures in LAMMPS.
...and unless you provide more specific information, nobody can give you
more specific advice.

axel.