def test_2d_replication(self, betacristobalite): nx = 2 ny = 2 nz = 1 tiled = TiledCompound(betacristobalite, [nx, ny, nz]) assert tiled.n_particles == 1900 * nx * ny assert tiled.n_bonds == 2400 * nx * ny for at in tiled.particles(): if at.name.startswith("Si"): assert len(tiled.bond_graph.neighbors(at)) <= 4 elif at.name.startswith("O"): assert len(tiled.bond_graph.neighbors(at)) <= 2
def test_no_replication(self, betacristobalite): nx = 1 ny = 1 nz = 1 tiled = TiledCompound(betacristobalite, [nx, ny, nz]) assert tiled.n_particles == 1900 * nx * ny assert tiled.n_bonds == 2400 * nx * ny
def test_negative_periodicity(self, betacristobalite): nx = -2 ny = 3 nz = 2 with pytest.raises(ValueError): TiledCompound(betacristobalite, [nx, ny, nz])
def test_incorrect_periodicity(self, betacristobalite): nx = 2 ny = 2 nz = 2 with pytest.raises(ValueError): TiledCompound(betacristobalite, [nx, ny, nz])
if surface_roughness == 1.0: mb.load( "amorphous_silica_sr1.0.pdb", compound=self, relative_to_module=self.__module__, ) self.periodicity = (True, True, False) self.box = mb.Box([5.4366, 4.7082, 1.0]) else: raise ValueError( "Amorphous silica input file with surface " "roughness of {0:.1f} does not exist. If you have " "this structure, please submit a pull request to " "add it! ".format(surface_roughness)) count = 0 for particle in list(self.particles()): if particle.name == "OB": count += 1 port = mb.Port(anchor=particle, orientation=[0, 0, 1], separation=0.1) self.add(port, "port_{}".format(count)) if __name__ == "__main__": from mbuild.lib.recipes import TiledCompound single = AmorphousSilicaSurface() multiple = TiledCompound(single, n_tiles=(2, 1, 1), name="tiled") multiple.save("amorphous_silica_surface.mol2")
def __init__( self, surface, chains, fractions=None, backfill=None, pattern=None, tile_x=1, tile_y=1, **kwargs ): from mbuild.lib.recipes import TiledCompound super(Monolayer, self).__init__() # Replicate the surface. tiled_compound = TiledCompound(surface, n_tiles=(tile_x, tile_y, 1)) self.add(tiled_compound, label="tiled_surface") if pattern is None: # Fill the surface. pattern = mb.Random2DPattern(len(tiled_compound.referenced_ports())) if isinstance(chains, mb.Compound): chains = [chains] if fractions: fractions = list(fractions) if len(chains) != len(fractions): raise ValueError( "Number of fractions does not match the number" " of chain types provided" ) n_chains = len(pattern.points) # Attach chains of each type to binding sites based on # respective fractions. for chain, fraction in zip(chains[:-1], fractions[:-1]): # Create sub-pattern for this chain type subpattern = deepcopy(pattern) n_points = int(round(fraction * n_chains)) warn("\n Adding {} of chain {}".format(n_points, chain)) pick = np.random.choice( subpattern.points.shape[0], n_points, replace=False ) points = subpattern.points[pick] subpattern.points = points # Remove now-occupied points from overall pattern pattern.points = np.array( [ point for point in pattern.points.tolist() if point not in subpattern.points.tolist() ] ) # Attach chains to the surface attached_chains, _ = subpattern.apply_to_compound( guest=chain, host=self["tiled_surface"], backfill=None, **kwargs ) self.add(attached_chains) else: warn("\n No fractions provided. Assuming a single chain type.") # Attach final chain type. Remaining sites get a backfill. warn("\n Adding {} of chain {}".format(len(pattern), chains[-1])) attached_chains, backfills = pattern.apply_to_compound( guest=chains[-1], host=self["tiled_surface"], backfill=backfill, **kwargs ) self.add(attached_chains) self.add(backfills)