-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathexample_bead_spring_side_groups.py
More file actions
293 lines (248 loc) · 10.6 KB
/
Copy pathexample_bead_spring_side_groups.py
File metadata and controls
293 lines (248 loc) · 10.6 KB
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Bead-Spring Polymers with Side Groups (Comb / Graft Architectures)
===================================================================
This example demonstrates branched bead-spring models built with the
architecture graph core (AutoPoly.models.architectures):
- Example 1: Comb polymer with single-bead side groups, regularly spaced
(like short-chain-branched polyethylene: backbone beads + one
branch bead per graft point), with branch-point angles.
- Example 2: Graft copolymer with oligomeric side chains at explicitly
chosen graft points (e.g. backbone-g-oligomer).
- Example 3: Comb polymer assembled from an explicitly defined monomer
(MonomerTemplate: backbone bead + side-group bead with
head/tail/side connection points).
- Example 4: The direct writer backend (backend="direct") — a lightweight
alternative that writes polymer.data + in.polymer without
running moltemplate (useful for very large melts).
All examples use the standard moltemplate backend via generate(): .lt
files are emitted and the bundled moltemplate produces
moltemplate/system.data + system.in.init/settings (the standard AutoPoly
output layout). The direct writer is available through
generate(backend="direct") and is demonstrated in Example 4.
Requires: pip install -e . (from the AutoPoly repo root)
"""
from AutoPoly import (
System,
BeadSpringPolymer,
BeadType,
AngleType,
MonomerTemplate,
)
from AutoPoly.models import architectures as arch
from AutoPoly.models.architectures import BeadArchitecture
def example_1_comb_with_side_groups():
"""
Example 1: Comb polymer with single-bead side groups
----------------------------------------------------
A backbone of 40 A beads with one B side-group bead grafted every 4
backbone beads (10 graft points) — the coarse-grained analog of a
short-chain-branched polymer.
Branch-point angles (centered on graft beads, degree 3) are included
and configured separately: the backbone-backbone-side triplet
(A-A-B) is stiffer than the backbone triplets (A-A-A).
"""
print("\n" + "=" * 60)
print("Example 1: Comb polymer with single-bead side groups")
print("=" * 60)
system = System(out="bead_spring_comb")
bead_A = BeadType(name="A", mass=1.0, epsilon=1.0, sigma=1.0) # backbone
bead_B = BeadType(name="B", mass=1.0, epsilon=1.0, sigma=0.8) # side group
comb = arch.comb(
backbone=[("A", 40)], # 40 backbone beads
side="B", # one side-group bead per graft point
every=4, # graft every 4 backbone beads
)
polymer = BeadSpringPolymer(
name="comb",
system=system,
n_chains=10,
bead_types=[bead_A, bead_B],
architecture=comb,
bond_style="fene", # standard for bead-spring melts
pair_style="wca", # purely repulsive (Kremer-Grest style)
use_angles=True,
default_k_angle=5.0, # backbone bending (A-A-A)
angle_types=[
# Stiffer angle involving the side group at branch points
AngleType(("A", "A", "B"), k=20.0, theta0=120.0),
],
# Moderate density keeps SAW insertion reliable for branched chains;
# compress to melt density (~0.85) with NPT during equilibration
density=0.4,
)
polymer.generate() # moltemplate backend (default)
info = polymer.get_system_info()
print(f" Architecture: {info['architecture']} (branched: {info['is_branched']})")
print(f" Chains: {info['n_chains']}")
print(f" Beads per chain: {info['n_beads_per_chain']} "
f"(40 backbone + 10 side groups)")
print(f" Total atoms: {info['total_atoms']}")
print(f" Total bonds: {info['total_bonds']}")
print(f" Total angles: {info['total_angles']} (incl. branch-point triplets)")
print(f" Output: {info['output_path']}/moltemplate")
return polymer
def example_2_graft_copolymer():
"""
Example 2: Graft copolymer with oligomeric side chains
------------------------------------------------------
A-g-B graft copolymer: an A backbone with B5 side chains at
explicitly chosen graft points (arch.graft gives full control over
grafting positions; side chains can be any sequence, e.g. a random
copolymer).
"""
print("\n" + "=" * 60)
print("Example 2: Graft copolymer with oligomeric side chains")
print("=" * 60)
system = System(out="bead_spring_graft")
bead_A = BeadType(name="A", mass=1.0, epsilon=1.0, sigma=1.0)
bead_B = BeadType(name="B", mass=1.0, epsilon=1.0, sigma=1.0)
graft_arch = arch.graft(
backbone=[("A", 30)],
grafts={
5: ("B", 5), # B5 side chain at backbone bead 5
15: ("B", 5), # ... and at bead 15
25: ("B", 5), # ... and at bead 25
},
)
polymer = BeadSpringPolymer(
name="graft",
system=system,
n_chains=10,
bead_types=[bead_A, bead_B],
architecture=graft_arch,
bond_style="fene",
pair_style="wca",
density=0.4,
)
polymer.generate() # moltemplate backend (default)
info = polymer.get_system_info()
print(f" Architecture: {info['architecture']}")
print(f" Chains: {info['n_chains']}")
print(f" Beads per chain: {info['n_beads_per_chain']} "
f"(30 backbone + 3 x 5 side-chain beads)")
print(f" Total atoms: {info['total_atoms']}")
print(f" Total bonds: {info['total_bonds']}")
print(f" Output: {info['output_path']}/moltemplate")
return polymer
def example_3_explicit_monomer():
"""
Example 3: Comb built from an explicitly defined monomer
--------------------------------------------------------
The same comb topology, but defined at the monomer level: a
MonomerTemplate with one backbone bead and one side-group bead,
connected head-to-tail into a chain. This mirrors how monomers are
defined in the atomistic pipeline and makes the monomer structure
(backbone vs side group) explicit and reusable.
"""
print("\n" + "=" * 60)
print("Example 3: Comb from an explicit MonomerTemplate")
print("=" * 60)
system = System(out="bead_spring_monomer_comb")
bead_A = BeadType(name="A", mass=1.0, epsilon=1.0, sigma=1.0) # backbone
bead_B = BeadType(name="B", mass=1.0, epsilon=1.0, sigma=0.8) # side group
# A graft monomer: backbone bead 0 (polymerization points head/tail)
# with a side-group bead 1 attached to it.
graft_monomer = MonomerTemplate(
name="G",
beads=["A", "B"], # bead 0 = backbone, bead 1 = side group
internal_bonds=[(0, 1)], # backbone--side-group bond
connections={"head": 0, "tail": 0, "side": 1},
)
# Polymerize 20 graft monomers head-to-tail
n_monomers = 20
comb = BeadArchitecture.from_monomers(
templates={"G": graft_monomer},
instances=["G"] * n_monomers,
inter_bonds=[
(i, "tail", i + 1, "head") for i in range(n_monomers - 1)
],
name="comb_from_monomer",
)
polymer = BeadSpringPolymer(
name="monomer_comb",
system=system,
n_chains=5,
bead_types=[bead_A, bead_B],
architecture=comb,
bond_style="fene",
pair_style="wca",
use_angles=True,
default_k_angle=5.0,
angle_types=[
AngleType(("A", "A", "B"), k=20.0, theta0=120.0),
],
density=0.4,
)
polymer.generate() # moltemplate backend (default)
info = polymer.get_system_info()
print(f" Architecture: {info['architecture']} (branched: {info['is_branched']})")
print(f" Monomer: G = 1 backbone bead (A) + 1 side-group bead (B)")
print(f" Chains: {info['n_chains']}")
print(f" Beads per chain: {info['n_beads_per_chain']} "
f"(20 monomers x 2 beads)")
print(f" Total atoms: {info['total_atoms']}")
print(f" Total bonds: {info['total_bonds']}")
print(f" Total angles: {info['total_angles']}")
print(f" Output: {info['output_path']}/moltemplate")
return polymer
def example_4_direct_backend():
"""
Example 4: Direct writer backend (lightweight alternative)
----------------------------------------------------------
generate(backend="direct") writes polymer.data + in.polymer directly,
without the moltemplate build step. Use it for very large melts where
the moltemplate backend (default) is slow; the physics (coordinates,
bonds, angles) is identical.
"""
print("\n" + "=" * 60)
print("Example 4: Direct writer backend")
print("=" * 60)
system = System(out="bead_spring_comb_direct")
bead_A = BeadType(name="A", mass=1.0, epsilon=1.0, sigma=1.0)
bead_B = BeadType(name="B", mass=1.0, epsilon=1.0, sigma=0.8)
comb = arch.comb(backbone=[("A", 20)], side="B", every=4)
polymer = BeadSpringPolymer(
name="comb_direct",
system=system,
n_chains=5,
bead_types=[bead_A, bead_B],
architecture=comb,
bond_style="fene",
pair_style="wca",
use_angles=True,
angle_types=[AngleType(("A", "A", "B"), k=20.0, theta0=120.0)],
density=0.4,
)
polymer.generate(backend="direct") # lightweight; no moltemplate run
info = polymer.get_system_info()
print(f" Total atoms: {info['total_atoms']}")
print(f" Total bonds: {info['total_bonds']}")
print(f" Output: {info['output_path']} (polymer.data + in.polymer)")
return polymer
def main():
"""Run all side-group bead-spring examples."""
print("\n" + "#" * 60)
print("# Bead-Spring Polymers with Side Groups")
print("#" * 60)
example_1_comb_with_side_groups()
example_2_graft_copolymer()
example_3_explicit_monomer()
example_4_direct_backend()
print("\n" + "=" * 60)
print("All examples completed successfully!")
print("=" * 60)
print("\nGenerated output directories:")
print(" - bead_spring_comb/ (moltemplate backend)")
print(" - bead_spring_graft/ (moltemplate backend)")
print(" - bead_spring_monomer_comb/ (moltemplate backend)")
print(" - bead_spring_comb_direct/ (direct writer)")
print("\nTo run a LAMMPS simulation (moltemplate backend, examples 1-3):")
print(" cd <output_dir>/<name>/moltemplate")
print(" lmp -in in.polymer")
print("\nTo run a LAMMPS simulation (direct writer, example 4):")
print(" cd bead_spring_comb_direct/comb_direct")
print(" lmp -in in.polymer")
if __name__ == "__main__":
main()