Source code for snap_simulate.system.molecules.comb_polymer
import numpy as np
[docs]
def make_comb_polymer(mol_specs, particle_specs):
mol_type = mol_specs.pop("molecule_type")
if mol_type != "comb_polymer":
raise Exception(f"Cannot turn molecule of type {mol_type} into a comb polymer")
N_bb = mol_specs["backbone_beads"]
backbone_type = mol_specs["backbone_type"]
M_arm = mol_specs["arm_beads"]
arm_type = mol_specs["arm_type"]
S = mol_specs["graft_spacing"]
bond_type = mol_specs["bond_type"]
diameters = particle_specs["diameters"]
d_bb = diameters[backbone_type]
r_bb = d_bb / 2.0
d_arm = diameters[arm_type]
r_arm = d_arm / 2.0
# Determine graft indices along the backbone
graft_indices = [i for i in range(N_bb) if i % S == 0]
num_arms = len(graft_indices)
N_tot = N_bb + num_arms * M_arm
particle_positions = np.zeros((N_tot, 3), dtype=float)
particle_typeid = np.zeros(N_tot, dtype=int)
# Place backbone beads along x-axis
for i in range(N_bb):
particle_typeid[i] = backbone_type
particle_positions[i, 0] = i * d_bb
particle_positions[i, 1] = 0.0
particle_positions[i, 2] = 0.0
# Bonds container
# Sequential backbone bonds: N_bb - 1
# Graft connection bonds: num_arms
# Sequential arm bonds: num_arms * (M_arm - 1)
nbonds = (N_bb - 1) + num_arms + num_arms * (M_arm - 1)
bond_groups = np.zeros((nbonds, 2), dtype=int)
bond_typeid = np.zeros(nbonds, dtype=int) + bond_type
b_idx = 0
# Add backbone bonds
for i in range(N_bb - 1):
bond_groups[b_idx] = [i, i+1]
b_idx += 1
# Place arms and add their bonds
current_arm_start_idx = N_bb
for k, i_bb in enumerate(graft_indices):
# Angle of projection in the yz-plane (alternating directions to avoid overlaps)
phi = 2.0 * np.pi * k / 3.0
u_y = np.cos(phi)
u_z = np.sin(phi)
# Place beads for this arm
for j in range(M_arm):
idx = current_arm_start_idx + j
particle_typeid[idx] = arm_type
# Position offset from the graft backbone bead
dist = r_bb + r_arm + j * d_arm
particle_positions[idx, 0] = particle_positions[i_bb, 0]
particle_positions[idx, 1] = dist * u_y
particle_positions[idx, 2] = dist * u_z
# Add connection bond from backbone graft bead to first arm bead
bond_groups[b_idx] = [i_bb, current_arm_start_idx]
b_idx += 1
# Add sequential arm bonds
for j in range(M_arm - 1):
bond_groups[b_idx] = [current_arm_start_idx + j, current_arm_start_idx + j + 1]
b_idx += 1
current_arm_start_idx += M_arm
new_mol_specs = dict(
bond_typeid=bond_typeid.tolist(),
bond_groups=bond_groups.tolist(),
angle_typeid=[],
angle_groups=[],
particle_typeid=particle_typeid.tolist(),
particle_positions=particle_positions.tolist()
)
return new_mol_specs