Move atoms over long distances

Related to this topic.
I’m writing fix that moves atoms over long distances.
According to Axel’s answers here, I must do it at the pre_exchange stage, so I do it there. But program crashes with “An error occurred in MPI_Allreduce” message occurring after my fix::pre_exchange() function, however I wasn’t be able to locate actual line of code where it occurs with valgrind and gdb.
But I’m sure it happens because moved atoms are still owned by original proc despite they are far outside and are not reassigned to the new proc.
Reading through ‘4. Information for Developers’ I’m think I need to call something like comm->forward_comm() but it does not help.

I’m wasn’t be able to understand the actual logic of atom exchanging process by myself. I found fix nve, like mine, just assigns new positions to atoms (changes x[i][...] = ...) but does nothing about reassigning atoms to the new procs in case they moved outside (or am I missed it?). Source code of create_atoms command didn’t help with this do mush, because it creates new atoms and it seems the AtomVec::create_atom() does the job of assigning.

So the main question is, after I changed positions of atoms, what function should I call in order to atoms are reassigned? Or are there examples of it?

You should have a look at Steve’s lectures on parallelization in LAMMPS and communication abstractions that LAMMPS uses from the recent LAMMPS Master Class workshop:

Additional information is in the LAMMPS paper and a subset of that also here: 4.4.2. Communication — LAMMPS documentation
and then some more details here: 4.6. Communication patterns — LAMMPS documentation
and here: 3.9. Fix styles — LAMMPS documentation