Replicating structures where bonds/angles etc cut through the periodic boundary

Hi all,

I intend to replicate a Si crystal (initial dimension of 333 unit cells) many times in z-direction for my simulation. It’s periodic in all 3 dimensions initially. I have explicit bond, angle, dihedral and improper definitions for Si, and not a potential like SW or tersoff, as I have to use an all-atom force field for my whole system (Si plus some polymer chain)

From what I understand by going through other posts, it is not possible to replicate a system that has bonds and angles cutting through a periodic boundary, as, no matter what the image flags are, there will always be some atoms separated by more than half the periodic box size. Is there any way to solve this problem?

I believe its possible to write a separate code to define all these parameters, but my structure would have ~ 70,000 atoms and I think it would be impractical to do so.

Any help is appreciated.

Thanks,
Raghavan

Graduate student,
RPI

I'm assuming that most of the bonds, angles and dihedrals for your
system are in the polymer, not the silicon crystal. If that is the
case, then can you not simply manually add bonds connecting the
polymer fragments together after you use the replicate command? (You
could do this by saving a restart file after you replicated the
system, converting the restart file to a data file using restart2data,
and then editing the data file to add a couple bonds to the "Bonds"
section.)

I believe its possible to write a separate code to define
all these parameters, but my structure would have ~ 70,000
atoms and I think it would be impractical to do so.

Indeed, it took me a while. Incidentally, you're welcome to use my
script if you want. I tried to make it very general. I'll be
announcing it here soon.

   Take a look at http://moltemplate.org

With "moltemplate", you can define a molecule named "UnitCell" and
instantiate 3x3x3 copies of it to make a crystal. You can also make a
polymer that spans the 3x3x3 crystal and insert it into the crystal,
deleting atoms which overlap with the polymer. Then you can replicate
the entire system, and add bonds between opposite ends of the polymer
fragments.

Here is a quick and sloppy version of what I mean:

UnitCell0 {

  # atomID molID atomType charge x y z
  write("Data Atoms") {
    $atom:Si1 $mol:/SiCrystal @atom:Si 0.0 0.00 0.00 0.00
    $atom:Si2 $mol:/SiCrystal @atom:Si 0.0 0.50 0.00 0.50
    $atom:Si3 $mol:/SiCrystal @atom:Si 0.0 0.25 0.25 0.75
    $atom:Si4 $mol:/SiCrystal @atom:Si 0.0 0.75 0.25 0.25
    $atom:Si5 $mol:/SiCrystal @atom:Si 0.0 0.00 0.00 0.50
    $atom:Si6 $mol:/SiCrystal @atom:Si 0.0 0.50 0.50 0.00
    $atom:Si7 $mol:/SiCrystal @atom:Si 0.0 0.25 0.75 0.25
    $atom:Si8 $mol:/SiCrystal @atom:Si 0.0 0.75 0.75 0.75
  }
  # Coordinates are in reduced units.
  # I'll use the "scale()" command later.
  # (I probably got these coordinates wrong. I was in a hurry.)
  write_once("Data Masses") {
    @atom:Si 28.0
  }
  write_once("In Settings") {
    # i j
    pair_coeff @atom:Si @atom:Si CHOSE YOUR PARAMETERS
    # Optional: put all the Si atoms in the same group
    group silicon type @atom:Si
  }
} # UnitCell0

# Create a new version of the unit cell whose coordinates are scaled up by 5.43
# (5.43 Angstroms is the length of a unit cell of Silicon I think.)

UnitCell = UnitCell0.scale(5.43)

# You can make a 3x3x3 array of UnitCells this way:

crystal = new UnitCell [3].move(5.43, 0.0, 0.0)
                        [3].move(0.0, 5.43, 0.0)
                        [3].move(0.0, 0.0, 5.43)

The vectors after the 3 move commands are the lattice-vectors in each
of the 3 directions.

You are correct that you can't use the replicate command
to replicate this kind of system. See its doc page under
the Restrictions sections for an explanation of why. The
issue is not that a bond happens to cross the periodic boundary,
but rather that the entire crystal is effectively a loop of bonded
atoms, and thus the image flags for the entire loop cannot
be set to consistent values. if your crystal did not span
the entire periodic box, you could use replicate.

Steve

Thanks a ton for the detailed mail Andrew!

Actually, most of the bonds, angles etc are for the Si crystal. Basically, I need to have a huge Si crystal in the Z direction (~ 1000 unit cells) for which replicate was the best option. As Steve pointed out, this cannot be done in Lammps.

Am not sure your method may work for my specific case where I have parameters for a Si crystal that needs to be periodic before replicating. This method is great otherwise! Thanks for sharing.

Cheers,
Raghavan

Thanks a ton for the detailed mail Andrew!

Actually, most of the bonds, angles etc are for the Si crystal. Basically, I
need to have a huge Si crystal in the Z direction (~ 1000 unit cells) for
which replicate was the best option. As Steve pointed out, this cannot be
done in Lammps.

Oh dear. I'm sorty to say that, moltemplate is not as helpful for the
situation you described, because you still have to manually connect
atoms in neighboring unit cells with bonds. (You can do this in
moltemplate too, using write("Data Bonds") For example, in the
polymer example, we bonded atoms from different monomers together:
http://www.moltemplate.org/examples/translocation/polymer.lt
But for a 3-D crystal, this requires a lot of manual work, which
defeats the point of using moltemplate.)

On the bright side, moltemplate can generate angles, dihedrals, and
impropers automatically for you once you have supplied it with a
complete list of bonds for the entire system.
(for example, see:
http://www.moltemplate.org/examples/2bead_homopolymer/2bead_angles.lt
http://www.moltemplate.org/examples/2bead_homopolymer/2bead.lt
http://www.moltemplate.org/examples/translocation/monomer.lt)

I was thinking a adding a feature to moltemplate which would allow
moltemplate to generate bonds automatically according to atom type and
the distance between them. That would really help people building
crystals or sheets. But it probably won't happen any time soon.

Sorry it was not more helpful. Good luck and thanks for posting, and
for the encouraging words.
(Really. It was useful for me to learn how people build crystals in
LAMMPS. I don't run these kinds of simulations, so I was not sure
what features people would need.)
Cheers!

Andrew

Wait, I just realized that topotools can generate crystals containing
bonds which are assigned by distance. This should solve your problem:

1) Use VMD and "topotools" to generate a DATA file with the correct
geometry and bonds.
http://sites.google.com/site/akohlmey/software/topotools/topotools-tutorial---part-1

2) To generate the angles, dihedrals, and impropers, use the
"nbody_by_type.py" utility.
This script can read LAMMPS data files and add angles too them. (I'm
attaching the official documentation for "nbody_by_type.py". You will
have to download moltemplate and point your PATH environment variable
to its "src" directory in order to get these scripts to work. I'm
also attaching a shell script "gen_new_angles_topo.sh" which shows you
how to use nbody_by_type.py to do exactly this. Warning: I have never
tried using that particular script, but it should give you an idea how
to use "nbody_by_type.py", if you open it with a text editor and read
it. Let me know if you have questions or problems. I'm curious to
see how well this works.)

docs_nbody_by_type.txt (5.35 KB)

gen_new_angles_topo.sh (5.07 KB)

I forgot to mention, that topotools can read your existing DATA file,
by the way, and it will remember the bonds and angles. I think it has
tools to replicate a system. (I don't think it can generate angles,
but I'm not sure.)

If you decide to use the "nbody_by_type.py" utility to generate
angles, then it is probably a good idea to remove the "Angles",
"Dihedrals", and "Impropers" sections from your DATA file before you
do this. The nbody_by_type.py script will add new duplicate angular
interactions to your existing ones, and LAMMPS will probably apply the
angular forces additively.

Sorry, I know this is a lot of information.
Cheers!

Topotools can build angles, dihedrals and impropers from the bond topology and if that is not enough, you can add or delete individual ones.

It can replicate, but has the same problem as lammps with periodic loops. I always wanted to try my hand at fixing that, but got distracted multiple times. It should be easier to prototype such code in a script language.

Axel