Hi, Steve and all!
We are shocking a crystal composed of charged atoms using the fix msst command(lastest lammps). Coulomb interactions are evaluated with the pppm method. Along the shock direction(z), the crystal is compressed by a factor of 2. When, or even after, the volume changes, we get an error threw out by pppm.cpp(line 1895) saying that "Out of range atoms - cannot compute PPPM". We have tried updating the neighbor list every step and making the time_step smaller, the same error just keeps coming out. Based on the following information, we guess that PPPM wont map all the skin region to processors' grid points when the box size is changed dramatically.
1. We set processor grid to be 4*4*1. So processors dont need to communicate for information about z-position and there is only one subbox in the shock direction.
boxlo[2]=sublo[2]=6.93(was 0.0 before the shock)
boxhi[2]=subhi[2]=20.43(was 27.36 before the shock) with center unchanged and volume halved.
2. skin=2.0 as the default value in metal units, so dist[2]=0.5skin=1.0(TIP4P disabled, qdist=0). Thus, pppm should be about to map everything from sublo-dist to subhi+dist, [5.93,21.43], to procgrid. (pppm.cpp fun partical_map line 1879 to line 1891).
3. The atoms are moving outside the box frequently. But when its getting closer to the edge of the skin region, pppm throws error complaining about it. A typical z position we observe is x[i][2]=z=6.19, still in the skin region.
4. When we have more than 1 processors in the z direction, say 4*2*2, jobs are more easily killed by the same error.
And Here is my guess. Taking a look at the full expression of nz (pppm.cpp line 1881)
nz= <int>[(z-boxlo[2])*nz_pppm/zprd+shift]-OFFSET
When the crystal is compressed in z direction and zprd halved, shift(=OFFSET for order=5) stays the same. <int> may not give an upper/lower bound integer as desired. This can make part of the skin region uncovered.
We get a simple but dirty solution now to fix the simulation.
1. Use a n*m*1 processor grid for shocking the z direction. Out of the subbox=Out of the box in z direction.
2. In fix_msst.cpp::remap(), we move each atom thats out of the box one period of the boxlength and enforce it back into the box.
FixMSST::remap() begin line 697
double **check_atom_position = atom->x;
for(int i=0;i<n;i++){
if (check_atom_position[i][2]<(domain->boxlo[2]))
check_atom_position[i][2] += domain->boxhi[2]-domain->boxlo[2];
if (check_atom_position[i][2]>(domain->boxhi[2]))
check_atom_position[i][2] -= domain->boxhi[2]-domain->boxlo[2];
}
Do you guys have any idea about this problem? Are we safe to make this dirty change of the fix_msst code? Will there be any unphysical effect resulting from this change?
Best,
Yuan