averaging atom quantities

Dear developers,

I have some question regarding averaging of atoms position.

1) Does atom->x contain unwrapped coordinates? Or is it 'fitted' to the box from time to time?

2) in 'fix ave/atom' the averaging is done locally on every processor
among owned atoms (0:atom->nlocal-1).
But don't atoms 'travel' from one processor to another?
If yes, then should not 'mpi-gather' (or something like this) be used,
gathering something like [tag][x-z] and then storing the sum for each atom on main processor?
I'm not saying that something is wrong, just trying to understand more on implementation side.

Thanks in advance,

Kind regards,
Denis

Dear developers,

I have some question regarding averaging of atoms position.

1) Does atom->x contain unwrapped coordinates? Or is it 'fitted' to the
box from time to time?

atom->x will be wrapped during neighbor list updates.
the unwrapped coordinates can be obtained from using
the periodic image counters in atom->image as well.

2) in 'fix ave/atom' the averaging is done locally on every processor
among owned atoms (0:atom->nlocal-1).
But don't atoms 'travel' from one processor to another?
If yes, then should not 'mpi-gather' (or something like this) be used,
gathering something like [tag][x-z] and then storing the sum for each
atom on main processor?

no. the per-atom data follows the (local) atoms in their
local order around in the same way the coordinate data
itself moves around. please notice the fix::pack_exchange()
and fix::unpack_exchange().

lammps uses a more flexible and "more parallel" method
to move data around than MPI_Scatter/MPI_Gather.
however, this is based on the assumption that atoms move
at a finite velocity, and hence the occasional "lost atoms"
errors, if system become unstable.

I'm not saying that something is wrong, just trying to understand more
on implementation side.

NP,
    axel.

Dear Axel,

Thank you for your detailed answer.

Since atom->x is not unwrapped, i guess in 'ave/atom' there should be something like:
    array[i][m] +=x[i][0] + ((image[i] & 1023) - 512) * domain->xprd; //for x-coordinate
instead of
    array[i][m] +=x[i][j];
Otherwise, it seems, atoms which are close to the boundary will have wrong average.

Two related questions:
1) can atom->map(int global) return
non-negative value for the same global index on two different processors ?
In other words, does it map to both local and ghost atoms?

2) If an atom is not a ghost-atom, its local index is < nlocal ?
That's how I can distinguish between the two by local index?

Kind regards,
Denis.

Dear Axel,

Thank you for your detailed answer.

Since atom->x is not unwrapped, i guess in 'ave/atom' there should be
something like:
array[i][m] +=x[i][0] + ((image[i] & 1023) - 512) * domain->xprd;
//for x-coordinate
instead of
array[i][m] +=x[i][j];

no.

Otherwise, it seems, atoms which are close to the boundary will have wrong
average.

to get unwrapped coordinates, you would define a
compute property/atom to get xu, yu, and zu
and use that for ave/atom instead of x,y,z directly.

Two related questions:
1) can atom->map(int global) return
non-negative value for the same global index on two different processors ?
In other words, does it map to both local and ghost atoms?

yes.

2) If an atom is not a ghost-atom, its local index is < nlocal ?

yes.

That's how I can distinguish between the two by local index?

yes. you'll see a lot of loops in LAMMPS over with: for (i=0; i < nlocal; ++i)

axel.

Dear Axel,

Thanks for your comments,
now everything is clear to me.

Kind regards,
Denis.