def build_monolayer(chain_length, n_molecules, pattern_class, polymer_class=AlkaneMonolayer, surface_class=Betacristobalite, name=None, **kwargs): if pattern_class is mb.Random2DPattern: if n_molecules in used_random_patterns: pattern = used_random_patterns[n_molecules] else: pattern = pattern_class(n_molecules) used_random_patterns[n_molecules] = pattern if pattern_class is mb.Grid2DPattern: pattern = pattern_class(int(np.sqrt(n_molecules)), int(np.sqrt(n_molecules))) # --------------------------------------------------------------- # TJ """ If elif statement to check surface type and create for each monolayer. TJ """ if surface_class is Betacristobalite: surface = surface_class() elif surface_class is mb.SilicaInterface: surface = surface_class(bulk_silica=AmorphousSilica(), thickness=1.2) bot = polymer_class(pattern, surface=surface, tile_x=1, tile_y=1, chain_length=chain_length) # --------------------------------------------------------------- # TJ mb.translate(bot, [0, 0, 2]) bot_box = bot.boundingbox bot_of_bot = bot_box.mins[2] bot_rigid = [ i + 1 for i, a in enumerate(bot.particles()) if (a.pos[2] < bot_of_bot + 0.2) and a.name == 'Si' ] n_particles = bot.n_particles top_rigid = [i + n_particles for i in bot_rigid] top = mb.clone(bot) mb.spin_y(top, np.pi) top_of_bot = bot_box.maxs[2] bot_of_top = top.boundingbox.mins[2] mb.translate(top, [0, 0, top_of_bot - bot_of_top + 0.5]) monolayer = mb.Compound([bot, top]) if not name: name = '{}_n-{}_l-{}-{}-{}'.format(polymer_class.__name__[:3], n_molecules, chain_length, surface_class.__name__, pattern_class.__name__[:4]) monolayer.name = name rigid_groups = {'bot': bot_rigid, 'top': top_rigid} return monolayer, rigid_groups
def build_monolayer(chain_length, n_molecules, pattern_class, **kwargs): from mbuild.examples import AlkaneMonolayer if pattern_class is mb.Random2DPattern: if n_molecules in used_random_patterns: pattern = used_random_patterns[n_molecules] else: pattern = pattern_class(n_molecules) pattern_name = 'rand' if pattern_class is mb.Grid2DPattern: pattern = pattern_class(int(np.sqrt(n_molecules)), int(np.sqrt(n_molecules))) pattern_name = 'grid' bot = AlkaneMonolayer(pattern, tile_x=1, tile_y=1, chain_length=chain_length) mb.translate(bot, [0, 0, 2]) bot_box = bot.boundingbox bot_of_bot = bot_box.mins[2] bot_rigid = [ i + 1 for i, a in enumerate(bot.particles()) if (a.pos[2] < bot_of_bot + 0.05) and a.name == 'Si' ] n_particles = bot.n_particles top_rigid = [i + n_particles for i in bot_rigid] top = mb.clone(bot) mb.spin_y(top, np.pi) top_of_bot = bot_box.maxs[2] bot_of_top = top.boundingbox.mins[2] mb.translate(top, [0, 0, top_of_bot - bot_of_top + 0.5]) monolayer = mb.Compound([bot, top]) monolayer.name = 'alkane_n-{}_l-{}-{}'.format(n_molecules, chain_length, pattern_name) rigid_groups = {'bot': bot_rigid, 'top': top_rigid} return monolayer, rigid_groups
def __init__(self, n=65, radius=1, port_distance_from_surface=.07): """Initialize a Sphere object. Args: n (int): Number of points used to construct the Sphere. radius (float): Radius of the Sphere. port_distance_from_surface (float): Distance of Ports from Sphere. """ super(Sphere, self).__init__() particle = mb.Particle(name='np') particle.add(mb.Port(anchor=particle), label='out') # Generate 65 points on the surface of a unit sphere. pattern = mb.SpherePattern(n) # Magnify the unit sphere by the provided radius. pattern.scale(radius) particles = pattern.apply(particle, orientation='normal', compound_port='out') self.add(particles, label='np_[$]') # Create particles and Ports at pattern positions. for i, pos in enumerate(pattern.points): particle = mb.Particle(name="np", pos=pos) self.add(particle, "np_{}".format(i)) port = mb.Port(anchor=particle) self.add(port, "port_{}".format(i)) # Make the top of the port point toward the positive x axis. mb.spin_z(port, -pi / 2) # Raise up (or down) the top of the port in the z direction. mb.spin_y(port, -arcsin(pos[2] / radius)) # Rotate the Port along the z axis. mb.spin_z(port, arctan2(pos[1], pos[0])) # Move the Port a bit away from the surface of the Sphere. mb.translate(port, pos / radius * port_distance_from_surface)
index += 1 if len(bot_lipids) != n_lipid: sys.exit('Error setting up system components') # Generate bottom layer randomly bot_layer = mb.Compound() for i in range(n_x): for j in range(n_y): # Randomly select a lipid that has not yet been selected random_lipid = np.random.randint(0, len(bot_lipids)) # Create the mbuild Molecule for this lipid molecule_i = bot_lipids.pop(random_lipid) molecule_to_add = mb.clone(molecule_i[0]) # Apply tilt angle mb.spin_y(molecule_to_add, tilt_angle) # Apply z_offset z_offset = molecule_i[1] #z_offset = 0 # Apply APL and z_offset to identify the position for the molecule in the grid position = [i * spacing, j * spacing, z_offset] mb.translate(molecule_to_add, position) # Add the new molecule to the layer bot_layer.add(molecule_to_add) # Generate the top layer of lipids randomly top_layer = mb.Compound() for i in range(n_x): for j in range(n_y): # Randomly select a lipid that has not yet been selected random_lipid = np.random.randint(0, len(top_lipids))
def new_make_layer(n_x=8, n_y=8, lipid_system_info=None, tilt_angle=0, spacing=0, layer_shift=0, res_index=0, table_of_contents=None, random_z_displacement=0, top_file=None, lipid_atom_dict=None, atom_index=0): """ Generate a bilayer leaflet by laying down molecules in a 2D grid at random grid points Parameters --------- n_x : int 2D grid dimension n_y : int 2D grid dimension tilt_angle : float tilt angle (spun around y-axis) spacing : float spacing between leaflets, based on area per lipid layer_shift : float Leaflet weparation from z-axis (used to separate bilayer leaflets) res_index : int Starting residue index for leaflet construction and residue counting table_of_contents : file Output file listing residue index, residue name, n_particles for tha residue random_z_displacement : float Randomly offset molecules by a small amount lipid_atom_dict : OrderedDict() Dictionary whose values are mb.Compounds()s and values are a list of atom indices of that compound atom_index : int Counter for indexing atoms for lipid_atom_dict Returns ------- layer : mb.Compound() Leaflet of molecules resindex : int Running count of molecules placed (excluding waters) lipid_atom_dict : OrderedDict() Dictionary whose values are mb.Compounds()s and values are a list of atom indices of that compound atom_index : int Counter for indexing atoms for lipid_atom_dict """ layer = mb.Compound() # Create ordered pairs ordered_pairs = [] for i, j in product(range(n_x), range(n_y)): ordered_pairs.append((i, j)) # Randomly assign ordered pairs to each lipid # based on the way lipids is set, all of one molecule is listed first # before getting to the next one # Loop through each type of molecule (DSPC, DPPC, etc.) for i, lipid_type in enumerate(lipid_system_info): n_molecule_per_leaflet = int(lipid_type[1] / 2) #Add to top file if (n_molecule_per_leaflet != 0): top_file.write("{:<10s}{:<10d}\n".format(lipid_type[0].name, n_molecule_per_leaflet)) # Loop through the system's quantity of that particular molecule for n in range(n_molecule_per_leaflet): random_index = np.random.randint(0, len(ordered_pairs)) (i, j) = ordered_pairs.pop(random_index) # Do geometry transformations molecule_to_add = mb.clone(lipid_type[0]) # Apply tilt angle mb.spin_y(molecule_to_add, tilt_angle) # Apply z_offset z_offset = lipid_type[2] # Apply APL and z_offset to identify the position for the molecule in the grid position = [ i * spacing, j * spacing, z_offset + layer_shift + (-1 * np.random.random() * random_z_displacement) ] mb.translate(molecule_to_add, position) # Add the new molecule to the layer layer.add(molecule_to_add) # Add to table of contents table_of_contents.write("{:<10d}{:<10s}{:<10d}\n".format( res_index, molecule_to_add.name, molecule_to_add.n_particles)) # Add to lipid dictionary if molecule_to_add.name in lipid_atom_dict: lipid_atom_dict[molecule_to_add.name] += list( range(atom_index, atom_index + molecule_to_add.n_particles, 1)) else: lipid_atom_dict[molecule_to_add.name] = list( range(atom_index, atom_index + molecule_to_add.n_particles, 1)) # Increment counters res_index += 1 atom_index += molecule_to_add.n_particles return layer, res_index, lipid_atom_dict, atom_index
# Generate the top layer randomly top_layer, res_index, lipid_atom_dict, atom_index = new_make_layer( n_x=n_x, n_y=n_y, lipid_system_info=lipid_system_info, tilt_angle=tilt_angle, spacing=spacing, layer_shift=0, res_index=res_index, table_of_contents=table_of_contents, random_z_displacement=random_z_displacement, top_file=top_file, lipid_atom_dict=lipid_atom_dict, atom_index=atom_index) # Rotate bottom layer to form bilayer mb.spin_y(top_layer, theta=np.pi) # Create system class that includes top and bottom layers system = mb.Compound() system.add(bot_layer) system.add(top_layer) # Solvate system, get new box system, box, lipid_atom_dict, atom_index = solvate_bilayer( system=system, n_x=n_x, n_y=n_y, n_solvent_per_lipid=n_solvent_per_lipid, res_index=res_index, table_of_contents=table_of_contents, lipid_atom_dict=lipid_atom_dict,