1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
|
c Create LAMMPS data file for collection of
c polymer bead-spring chains of various lengths and bead sizes
c Syntax: chain < def.chain > data.file
c def.chain is input file that specifies the chains
c data.file is output file that will be input for LAMMPS
c includes image flags in data file so chains can be unraveled later
program chain
integer swaptype
integer, allocatable :: nchain(:),nmonomer(:)
integer, allocatable :: ntype(:),nbondtype(:)
integer, allocatable :: type(:),molecule(:)
integer, allocatable :: imagex(:),imagey(:),imagez(:)
real*8, allocatable :: x(:),y(:),z(:)
real*8, allocatable :: bondlength(:),restrict(:)
common xprd,yprd,zprd,xboundlo,xboundhi,
$ yboundlo,yboundhi,zboundlo,zboundhi
real*8 random
900 format(a)
901 format(2f10.6,a)
902 format(i3,f5.1)
903 format(i10,i8,i8,3f10.4,3i4)
904 format(i6,i3,2i6)
c read chain definitions
read (5,*)
read (5,*)
read (5,*) rhostar
read (5,*) iseed
read (5,*) nsets
read (5,*) swaptype
allocate(nchain(nsets))
allocate(nmonomer(nsets))
allocate(ntype(nsets))
allocate(nbondtype(nsets))
allocate(bondlength(nsets))
allocate(restrict(nsets))
do iset = 1,nsets
read (5,*)
read (5,*) nchain(iset)
read (5,*) nmonomer(iset)
read (5,*) ntype(iset)
read (5,*) nbondtype(iset)
read (5,*) bondlength(iset)
read (5,*) restrict(iset)
enddo
c natoms = total # of monomers
natoms = 0
do iset = 1,nsets
natoms = natoms + nchain(iset)*nmonomer(iset)
enddo
allocate(x(natoms))
allocate(y(natoms))
allocate(z(natoms))
allocate(type(natoms))
allocate(molecule(natoms))
allocate(imagex(natoms))
allocate(imagey(natoms))
allocate(imagez(natoms))
c setup box size (sigma = 1.0)
volume = natoms/rhostar
xprd = volume**(1.0/3.0)
yprd = xprd
zprd = xprd
xboundlo = -xprd/2.0
xboundhi = -xboundlo
yboundlo = xboundlo
yboundhi = xboundhi
zboundlo = xboundlo
zboundhi = xboundhi
c generate random chains
c loop over sets and chains in each set
n = 0
nmolecule = 0
do iset = 1,nsets
do ichain = 1,nchain(iset)
nmolecule = nmolecule + 1
c random starting point for the chain in the box
x1 = 0.0
y1 = 0.0
z1 = 0.0
x2 = xboundlo + random(iseed)*xprd
y2 = yboundlo + random(iseed)*yprd
z2 = zboundlo + random(iseed)*zprd
c store 1st monomer of chain
c 1st monomer is always in original box (image = 0)
call pbc(x2,y2,z2)
n = n + 1
x(n) = x2
y(n) = y2
z(n) = z2
type(n) = ntype(iset)
imagex(n) = 0
imagey(n) = 0
imagez(n) = 0
if (swaptype == 0) then
molecule(n) = nmolecule
else
molecule(n) = 1
endif
c generate rest of monomers in this chain
do imonomer = 2,nmonomer(iset)
x0 = x1
y0 = y1
z0 = z1
x1 = x2
y1 = y2
z1 = z2
c random point inside sphere of unit radius
10 xinner = 2.0*random(iseed) - 1.0
yinner = 2.0*random(iseed) - 1.0
zinner = 2.0*random(iseed) - 1.0
rsq = xinner*xinner + yinner*yinner + zinner*zinner
if (rsq > 1.0) goto 10
c project point to surface of sphere of unit radius
r = sqrt(rsq)
xsurf = xinner/r
ysurf = yinner/r
zsurf = zinner/r
c create new point by scaling unit offsets by bondlength (sigma = 1.0)
x2 = x1 + xsurf*bondlength(iset)
y2 = y1 + ysurf*bondlength(iset)
z2 = z1 + zsurf*bondlength(iset)
c check that new point meets restriction requirement
c only for 3rd monomer and beyond
dx = x2 - x0
dy = y2 - y0
dz = z2 - z0
r = sqrt(dx*dx + dy*dy + dz*dz)
if (imonomer > 2 .and. r <= restrict(iset)) goto 10
c store new point
c if delta to previous bead is large, then increment/decrement image flag
call pbc(x2,y2,z2)
n = n + 1
x(n) = x2
y(n) = y2
z(n) = z2
type(n) = ntype(iset)
if (abs(x(n)-x(n-1)) < 2.0*bondlength(iset)) then
imagex(n) = imagex(n-1)
else if (x(n) - x(n-1) < 0.0) then
imagex(n) = imagex(n-1) + 1
else if (x(n) - x(n-1) > 0.0) then
imagex(n) = imagex(n-1) - 1
endif
if (abs(y(n)-y(n-1)) < 2.0*bondlength(iset)) then
imagey(n) = imagey(n-1)
else if (y(n) - y(n-1) < 0.0) then
imagey(n) = imagey(n-1) + 1
else if (y(n) - y(n-1) > 0.0) then
imagey(n) = imagey(n-1) - 1
endif
if (abs(z(n)-z(n-1)) < 2.0*bondlength(iset)) then
imagez(n) = imagez(n-1)
else if (z(n) - z(n-1) < 0.0) then
imagez(n) = imagez(n-1) + 1
else if (z(n) - z(n-1) > 0.0) then
imagez(n) = imagez(n-1) - 1
endif
if (swaptype == 0) then
molecule(n) = nmolecule
else if (swaptype == 1) then
molecule(n) = imonomer
else if (swaptype == 2) then
if (imonomer <= nmonomer(iset)/2) then
molecule(n) = imonomer
else
molecule(n) = nmonomer(iset)+1-imonomer
endif
endif
enddo
enddo
enddo
c compute quantities needed for LAMMPS file
nbonds = 0
ntypes = 0
nbondtypes = 0
do iset = 1,nsets
nbonds = nbonds + nchain(iset)*(nmonomer(iset)-1)
if (ntype(iset) > ntypes) ntypes = ntype(iset)
if (nbondtype(iset) > nbondtypes)
$ nbondtypes = nbondtype(iset)
enddo
c write out LAMMPS file
write (6,900) 'LAMMPS FENE chain data file'
write (6,*)
write (6,*) natoms,' atoms'
write (6,*) nbonds,' bonds'
write (6,*) 0,' angles'
write (6,*) 0,' dihedrals'
write (6,*) 0,' impropers'
write (6,*)
write (6,*) ntypes,' atom types'
write (6,*) nbondtypes,' bond types'
write (6,*) 0,' angle types'
write (6,*) 0,' dihedral types'
write (6,*) 0,' improper types'
write (6,*)
write (6,901) xboundlo,xboundhi,' xlo xhi'
write (6,901) yboundlo,yboundhi,' ylo yhi'
write (6,901) zboundlo,zboundhi,' zlo zhi'
write (6,*)
write (6,900) 'Masses'
write (6,*)
do i = 1,ntypes
write (6,902) i,1.0
enddo
write (6,*)
write (6,900) 'Atoms'
write (6,*)
do i = 1,natoms
write (6,903) i,molecule(i),type(i),x(i),y(i),z(i),
$ imagex(i),imagey(i),imagez(i)
enddo
if (nbonds > 0) then
write (6,*)
write (6,900) 'Bonds'
write (6,*)
n = 0
m = 0
do iset = 1,nsets
do ichain = 1,nchain(iset)
do imonomer = 1,nmonomer(iset)
n = n + 1
if (imonomer /= nmonomer(iset)) then
m = m + 1
write (6,904) m,nbondtype(iset),n,n+1
endif
enddo
enddo
enddo
endif
end
c ************
c Subroutines
c ************
c periodic boundary conditions - map atom back into periodic box
subroutine pbc(x,y,z)
common xprd,yprd,zprd,xboundlo,xboundhi,
$ yboundlo,yboundhi,zboundlo,zboundhi
if (x < xboundlo) x = x + xprd
if (x >= xboundhi) x = x - xprd
if (y < yboundlo) y = y + yprd
if (y >= yboundhi) y = y - yprd
if (z < zboundlo) z = z + zprd
if (z >= zboundhi) z = z - zprd
return
end
c RNG from Numerical Recipes
real*8 function random(iseed)
real*8 aa,mm,sseed
parameter (aa=16807.0D0,mm=2147483647.0D0)
sseed = iseed
sseed = mod(aa*sseed,mm)
random = sseed/mm
iseed = sseed
return
end
|