22 import pyparm.d3
as sim
23 import pyparm.util
as util
26 parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
28 scigroup = parser.add_argument_group(
'Scientific Parameters')
29 scigroup.add_argument(
'-T',
'--temp', type=float, default=0.01, help=
'Simulation temperature')
30 scigroup.add_argument(
'-N',
'--npoly', type=int, default=20, help=
'Number of polymers')
31 scigroup.add_argument(
'-n',
'--perpoly', type=int, default=10,
32 help=
'Number of beads per polymer')
33 scigroup.add_argument(
'-d',
'--density', type=float, default=0.05,
34 help=
'Number of polymers per unit volume')
35 scigroup.add_argument(
'-a',
'--angle', type=float, default=120,
36 help=
'Bond angle, in degrees, with 180 being a straight chain')
37 scigroup.add_argument(
'-t',
'--time', type=float, default=1000.0,
38 help=
'Number of time units to run the simulation')
40 simgroup = parser.add_argument_group(
'Simulation Parameters')
41 simgroup.add_argument(
'--damping', type=float, default=1.0,
42 help=
'The damping coefficient of the integrator, related to viscosity')
43 simgroup.add_argument(
'--dt', type=float, default=1e-2, help=
'Timestep')
44 simgroup.add_argument(
'--mass', type=float, default=1.0, help=
'Mass per bead')
45 simgroup.add_argument(
'--width', type=float, default=1.0, help=
'Width of beads')
46 simgroup.add_argument(
'--anglek', type=float, default=100.0, help=
'Strength of bond angle')
47 simgroup.add_argument(
'--bondk', type=float, default=100.0, help=
'Strength of bond potential')
49 outgroup = parser.add_argument_group(
'Output Parameters')
50 outgroup.add_argument(
'--xyz', default=
'polymer-example.xyz')
51 outgroup.add_argument(
'--stats', default=
'polymer-example.npz')
52 parser.add_argument(
'--statt', type=float, default=10.0,
53 help=
"how often to save statistics (time units)")
54 parser.add_argument(
'--xyzt', type=float, default=1.0,
55 help=
"how often to output a frame to the XYZ file (time units)")
56 outgroup.add_argument(
'--printn', type=int, default=200)
58 opts = parser.parse_args()
62 L = (opts.npoly / opts.density)**(1.0/3.0)
63 N = opts.npoly * opts.perpoly
66 box = sim.OriginBox(L)
67 atoms = sim.AtomVec([1.]*N)
69 neighbors = sim.NeighborList(box, atoms, 0.4)
70 repulse = sim.Repulsion(atoms, neighbors)
71 bonds = sim.BondPairs()
72 angles = sim.AngleTriples()
79 print(
'Placing atoms...', end=
' ')
81 angle = (opts.angle % 180) * np.pi/180
84 for n, a, s
in zip(range(N), atoms, sigmas):
87 repulse.add(sim.EpsSigExpAtom(a, 1.0, s, 2.0))
88 if n % opts.perpoly != 0:
89 bonds.add(opts.bondk, s, lasta, a)
90 neighbors.ignore(lasta, a)
91 if n % opts.perpoly > 1:
92 angles.add(opts.anglek, angle, preva, lasta, a)
93 neighbors.ignore(preva, a)
95 if n % opts.perpoly > 1:
97 lastdx = lasta.x - preva.x
98 lastdx /= np.linalg.norm(lastdx)
99 perp = np.cross(dx, lastdx)
100 perp /= np.linalg.norm(perp)
101 dx = (lastdx * np.cos(np.pi - angle) +
102 perp * np.sin(np.pi - angle))
104 elif n % opts.perpoly > 0:
106 dx /= np.linalg.norm(dx)
110 neighbors.update_list()
111 E = repulse.energy(box) + bonds.energy(box) + angles.energy(box)
117 print(N - n, end=
', ')
125 collec = sim.CollectionSol(box, atoms, opts.dt, opts.damping, opts.temp,
126 [repulse, bonds, angles], [neighbors])
129 collec.reset_com_velocity()
131 collec.scale_velocities_to_temp(opts.temp)
139 'U': lambda: repulse.energy(box),
143 data_arrays = {k: []
for k
in data_functions}
144 data_arrays[
't'] = []
148 """Take each measurement in data_functions at time 'time', and store it in
150 data_arrays[
't'].append(time)
151 for k, f
in data_functions.items():
152 data_arrays[k].append(f())
156 np.savez_compressed(opts.stats, **data_arrays)
164 with open(opts.xyz,
'a')
as f:
169 x = box.diff(a.x, sim.vec())
170 print(
'C', *x, file=f)
173 with open(opts.xyz,
'w')
as f:
182 mol modstyle 0 0 VDW 1 32
185 set cell [pbc set {{{L} {L} {L}}} -all];
186 pbc box -toggle -center origin -color red;
187 set natoms [atomselect 0 "name C";];
188 $natoms set radius {r};""".format(L=L, r=sigmas[0]/2.0)
190 with open(opts.xyz[:-4] +
'.tcl',
'w')
as f:
191 print(tcl_str, file=f)
198 progress = util.Progress(opts.time)
199 total_steps = int(opts.time / opts.dt + 0.5)
201 for step
in range(total_steps+1):
206 if time > xyz_m * opts.xyzt:
210 if time > data_m * opts.statt:
215 if time > print_m * opts.time / opts.printn:
216 print(progress.eta_str(time),
'T: %6.2f' % collec.temp())