I'm trying to model the silica-water interface using classical molecular dynamics. Hope to use LAMMPS for the simulations and CHARMM potential to model the atomic interactions. I wonder how to generate the initial atomic structure of the system. The "nanomaterial modeler" module in CHARMM-GUI comes in handy creating the atomic structure. But I do not have complete control over my structure if I use it. I need to attach the hydroxyl groups to the dangling silicon atoms in the interface as well. Therefore, it feels a bit complicated when defining the bonds and angles in the system using Matlab or python. As I'm using CHARMM potential, the relevant potential parameters need to be specified as well in the atomic data file. Any advice would be highly appreciated.
1 Answer
As you note, any structure with dangling silicon atoms cannot be considered correct. I'm surprised CHARMM-GUI would produce a structure with undercoordinated (<4 bonds) silicon. I can't really tell what surface structure you have in the image, but here are some general warnings. You should be careful that your structure is consistent with the force field parameterization of the material. You can't expect parameters developed for elemental silicon to behave well for silicon dioxide or vice versa. You need to make sure that your silanol oxygen and hydrogen atoms are given the correct types and charges. Also, parameters for solid materials are often not well tested and may not be good for your purposes. Many of them, even those published in good venues can be very unbalanced. Also, the atomic structure of the surface may be more complex than you expect (metals often have thin oxide layers, for example).
As suggested by @HemanthHaridas, you can write a script to generate psf and pdb files for your structures without having to define a CHARMM topology. Here is a VMD Tcl script that I wrote to add hydrogen to polycyclic aromatics. It could be altered for your purposes. You need a starting psf and pdb file. You give it a VMD selection (selText) of the atoms you want to add hydrogens to. It will generate a new pdb file with the original atoms of the system, plus the new hydrogen atoms. It then uses the VMD topotools plugin to generate bonds between the hydrogens and the atoms they are attached to. The angles and dihedrals in the psf file are regenerated using the VMD psfgen plugin.
# VMD Tcl script for adding hydrogen to dangling carbon atoms in polyaromatics
# Author: WaterMolecule
# Input parameters
set psf cut_graph_hexagon.psf
set pdb cut_graph_hexagon.pdb
set selText "numbonds!=3"
set type HGR61
set charge 0.115
set hydSegName H1
set lx 30.05
set ly 30.35
set lz 24.93
set outName H_graph_hexagon1
# Other parameters
set cutoff 2.0
set hDist 1.1
package require topotools
package require psfgen
# Create a PDB ATOM line.
proc makePdbLine {serial segName resId name resName r beta} {
set template "ATOM 42 HN ASN X 4 -41.083 17.391 50.684 0.00 0.00 P1 "
foreach {x y z} $r {break}
set record "ATOM "
set si [string range [format " %5i " $serial] end-5 end]
if {[string length $name] < 4} {
set name [string range " $name " 0 3]
} else {
set name [string range $name 0 3]
}
set resName [string range " $resName " 0 4]
set chain "[string index $segName 0]"
set resId [string range " $resId" end-3 end]
set temp1 [string range $template 26 29]
set sx [string range [format " %8.3f" $x] end-7 end]
set sy [string range [format " %8.3f" $y] end-7 end]
set sz [string range [format " %8.3f" $z] end-7 end]
set temp2 [string range $template 54 59]
set beta [string range [format " %6.2f" $beta] end-5 end]
set temp3 [string range $template 66 71]
set segName [string range "$segName " 0 3]
set tempEnd [string range $template 76 end]
# Construct the pdb line.
return "${record}${si}${name}${resName}${chain}${resId}${temp1}${sx}${sy}${sz}${temp2}${beta}${temp3}${segName}${tempEnd}"
}
# Convert a vector to a unit vector.
proc vecUnit {v} {
set len [veclength $v]
return [vecscale [expr {1.0/$len}] $v]
}
# Wrap a difference in coordinates for a periodic length "l".
# The result is -0.5*l <= x < 0.5*l
proc wrapDiffReal {x l} {
set l [expr {double($l)}]
set image [expr {int(floor($x/$l))}]
set x [expr {$x - $image*$l}]
if {$x >= 0.5*$l} { set x [expr {$x - $l}] }
return $x
}
# Wrap a displacement for an orthogonal cell.
proc wrapDiffOrtho {r a b c} {
foreach {x y z} $r { break }
set x [wrapDiffReal $x $a]
set y [wrapDiffReal $y $b]
set z [wrapDiffReal $z $c]
return [list $x $y $z]
}
# Load the system.
mol new $psf
mol addfile $pdb waitfor all
molinfo top set a $lx
molinfo top set b $ly
molinfo top set c $lz
puts "CELL: $lx $ly $lz"
set all [atomselect top all]
foreach silent {0} {
set bondList [topo getbondlist]
set chargeList [$all get charge]
set typeList [$all get type]
}
# Write the pdb.
set out [open $outName.tmp.pdb w]
# Write the existing atoms.
set j 0
set numOrig [$all num]
puts "Original number of atoms: $numOrig"
foreach segName [$all get segname] resId [$all get resid] name [$all get name] resName [$all get resname] r [$all get {x y z}] {
incr j
puts $out [makePdbLine $j $segName $resId $name $resName $r 1.0]
}
# Add the hydrogens and write them.
set resId 1
set name H
set resName ADDH
set sel [atomselect top $selText]
puts "Adding [$sel num] hydrogen atoms."
set hydBondList {}
foreach index [$sel get index] pos [$sel get {x y z}] {
set sum [veczero]
set s [atomselect top "not index $index and pbwithin $cutoff of index $index"]
foreach p [$s get {x y z}] {
set d [wrapDiffOrtho [vecsub $p $pos] $lx $ly $lz]
set sum [vecadd $sum $d]
}
set hVec [vecscale $hDist [vecUnit [vecinvert $sum]]]
$s delete
set r [vecadd $pos $hVec]
incr resId
incr j
puts $out [makePdbLine $j $hydSegName $resId $name $resName $r 0.0]
lappend hydBondList [list [expr {$j-1}] $index]
}
close $out
# Load the pdb we just created.
mol delete top
mol new $outName.tmp.pdb
set all1 [atomselect top all]
puts "New structure has [$all1 num] atoms."
# Delete all bonds.
foreach bond [topo getbondlist] {
topo delbond [lindex $bond 0] [lindex $bond 1]
}
# Add the original bonds back in.
foreach bond $bondList {
set i0 [lindex $bond 0]
set i1 [lindex $bond 1]
topo addbond $i0 $i1
}
# Add the bonds to the hydrogen atoms.
foreach bond $hydBondList {
set i0 [lindex $bond 0]
set i1 [lindex $bond 1]
topo addbond $i0 $i1
}
# Set the original types and charges.
set s1 [atomselect top "index < $numOrig"]
$s1 set type $typeList
$s1 set charge $chargeList
$s1 delete
# Modify the types and charges of the hydrogen atoms and the charge of the attached atom.
foreach bond $hydBondList {
set s [atomselect top "index [lindex $bond 0]"]
$s set type $type
$s set charge $charge
$s delete
set s [atomselect top "index [lindex $bond 1]"]
$s set charge [expr {-$charge}]
$s delete
}
# Write psf with bonds and charges.
$all1 writepsf $outName.tmp.psf
# Regenerate angles and dihedrals.
resetpsf
readpsf $outName.tmp.psf
coordpdb $outName.tmp.pdb
regenerate angles dihedrals
# Write the final structure.
writepsf $outName.psf
writepdb $outName.pdb
-
2$\begingroup$ +1 for the tcl script. However, OP must ensure that the parameters for the new bonds, angles, dihedrals and charges are defined in the parameter set that VMD uses. I am skeptical about that, because VMD uses an old set of parameters. Also note that OP wants to use LAMMPS, which means that .psf file is not required $\endgroup$ Commented Feb 15, 2023 at 3:11
-
$\begingroup$ Hello @WaterMolecule, Thank you very much for your reply. CHARMM does create the hydroxyl groups. However, I lose control of the desired structure if I use CHARMM-GUI. For example, I want my system to be two silica blocks at the ends and water in between. But CHARMM offers the opposite. The surface orientation in fig is 001. I was worried about how to saturate these dangling Si and how to define the bonds, etc, if I script the structure. As you and Hamanth pointed out, VMD should come in handy. Hope to use the parametrization by J. Phys. Chem. B 2006, 110, 6, 2782–2792. Thanks for the VMD tcl. $\endgroup$ Commented Feb 15, 2023 at 5:46
-
1$\begingroup$ @WhiteLeo9 "I want my system to be two silica blocks at the ends and water in between. But CHARMM offers the opposite." Considering periodic boundary conditions, these two configurations are the same. You can just wrap the system to put the water in the middle, instead of the SiO2. Also, I don't know what you are doing with these systems, but you have an awful lot of water (maybe more than you need). $\endgroup$ Commented Feb 15, 2023 at 15:57
-
$\begingroup$ @WaterMolecule You're right, that's a lot of water. I sure don't need that much of water. My aim is to understand the thermal transport in the respective interface. Since I'm trying to thermostat two regions of the solid phase (a sink and a source using Langevin thermostats), I'm gonna need two solid blocks in the domain (Not necessarily in the two edges of the system). $\endgroup$ Commented Feb 16, 2023 at 5:23
-
1$\begingroup$ @WhiteLeo9 It sounds like you will need two solid blocks and two water regions then. The easiest way would be to save a new set of psf and pdb files for the system with all the segments renamed to something unique and different (combining structures with CHARMM or psfgen requires unique {segname resid name} for all atoms). Then you could displace new renamed system in z by the size of the original system. Finally you can combine the two systems with psfgen: readpsf orig.psf; coordpdb orig.pdb; readpsf rename.psf; coordpdb displace.pdb; writepsf combine.psf; writepdb combine.pdb $\endgroup$ Commented Feb 16, 2023 at 20:54