Example #1
0
 def test_no_replication(self, betacristobalite):
     nx = 1
     ny = 1
     nz = 1
     tiled = mb.TiledCompound(betacristobalite, [nx, ny, nz])
     assert tiled.n_particles == 1900 * nx * ny
     assert tiled.n_bonds == 2400 * nx * ny
Example #2
0
    def _cleave_tip(self, bulk_silica):
        """ Carve tip from bulk silica, include a buffer of O's around the
            tip to ensure the tip is coated.
        """

        O_buffer = self._O_buffer
        tip_radius = self._radius
        tile = [
            int(math.ceil((2 * O_buffer + 2 * tip_radius) / dim))
            for dim in bulk_silica.periodicity
        ]
        bulk = mb.TiledCompound(bulk_silica, n_tiles=tile)

        tip = mb.Compound(periodicity=np.zeros(3))
        center = bulk.periodicity / 2

        check_radius = {'O': tip_radius + O_buffer, 'Si': tip_radius}
        check_z = {'O': center[2] - O_buffer, 'Si': center[2]}
        for i, particle in enumerate(bulk.particles()):
            if (_check_sphere(particle.pos, center,
                              check_radius[particle.name])
                    and particle.pos[2] > check_z[particle.name]):
                tip_particle = mb.Compound(name=particle.name,
                                           pos=particle.pos)
                tip.add(tip_particle, particle.name + "_{}".format(i))
        self.add(tip)
Example #3
0
    def _cleave_interface(self, bulk_silica, tile_x, tile_y):
        """ Carve interface from bulk silica, include a buffer of O's above and
            below the surface to ensure the interface is coated.
        """

        asperity_radius = self._asperity_radius
        O_buffer = self._O_buffer
        thickness = self._thickness        

        block_width = thickness + 2*O_buffer + asperity_radius
        tile_z = int(math.ceil(block_width / bulk_silica.periodicity[2]))
        bulk = mb.TiledCompound(bulk_silica, n_tiles=(tile_x, tile_y, tile_z))

        interface = mb.Compound(periodicity=(bulk.periodicity[0],
            bulk.periodicity[1], 0.0))
        center = np.array([(np.max(bulk.xyz[:,0]) + np.min(bulk.xyz[:,0])) / 2,
                           (np.max(bulk.xyz[:,1]) + np.min(bulk.xyz[:,1])) / 2,
                           thickness + O_buffer])

        for i, particle in enumerate(bulk.particles()):
            if ((particle.name == 'Si' and O_buffer < particle.pos[2] and 
                    (particle.pos[2] < (thickness + O_buffer) or 
                    _check_sphere(particle.pos, center, asperity_radius))) or 
                    (particle.name == 'O' and 
                    (particle.pos[2] < (thickness + 2*O_buffer) or 
                    _check_sphere(particle.pos, center, asperity_radius+O_buffer)))):
                interface_particle = mb.Compound(name=particle.name, pos=particle.pos)
                interface.add(interface_particle, particle.name + "_{}".format(i))
        self.add(interface)
    def __init__(self, radius=2.0, O_layer=False):
        """Initialize an AA_nano object.
        
        Args:
            radius (float): Radius of the nanoparticle
        """ 
        super(AA_nano, self).__init__()

        single = Silica()

        O_buffer = 0.275
        # Replicate the bulk silica box if necessary
        rep = math.ceil(((radius+O_buffer)/single.periodicity[0])*2.0)
        rep = int(rep)
        bulk = mb.TiledCompound(tile=single,n_tiles=np.array([rep,rep,rep]),name="bulk_silica")
        bulk_name = []
        bulk_pos = []
        for child in bulk.children:
            for grandchild in child.children:
                bulk_name.append(grandchild.name)
                bulk_pos.append(grandchild.pos)
        bulk_center = [bulk.periodicity[i]/2.0 for i in range(3)]
        dists = distance.cdist(bulk_pos,[bulk_center],'euclidean')
        types = {'1':'Si','2':'O'}
        if O_layer:
            shell_buffer = 0.5
            for i, dist in enumerate(dists):
                if types[bulk_name[i]] == 'Si' and dist <= radius and dist > radius - shell_buffer:
                    particle = mb.Compound(name=types[bulk_name[i]], pos=bulk_pos[i])
                    self.add(particle, types[bulk_name[i]]+"_{}".format(i))
                elif types[bulk_name[i]] == 'O' and dist <= radius + O_buffer and dist > radius - shell_buffer:
                    particle = mb.Compound(name=types[bulk_name[i]], pos=bulk_pos[i])
                    self.add(particle, types[bulk_name[i]]+"_{}".format(i))
            self.generate_bonds(name_a='Si', name_b='O', dmin=0.0, dmax=0.20419)
            components = self.bond_graph.connected_components()
            major_component = max(components, key=len)
            for atom in list(self.particles()):
                if atom not in major_component:
                    dist = np.linalg.norm(atom.pos - bulk_center)
                    if atom.name == 'O' and dist > radius:
                        self.remove(atom)
            for i, dist in enumerate(dists):
                if dist <= radius - shell_buffer:
                    particle = mb.Compound(name=types[bulk_name[i]], pos=bulk_pos[i])
                    self.add(particle, types[bulk_name[i]]+"_{}".format(i))
            for bond in self.bonds():
                self.remove_bond(bond)
        else:
            for i, dist in enumerate(dists):
                if dist <= radius:
                    particle = mb.Compound(name=types[bulk_name[i]], pos=bulk_pos[i])
                    self.add(particle, types[bulk_name[i]]+"_{}".format(i))
Example #5
0
    def test_2d_replication(self, betacristobalite):
        nx = 2
        ny = 3
        nz = 1
        tiled = mb.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

        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
Example #6
0
    def _cleave_interface(self, bulk_silica, tile_x, tile_y, thickness):
        """Carve interface from bulk silica.

        Also includes a buffer of O's above and below the surface to ensure the
        interface is coated.
        """
        O_buffer = self._O_buffer
        tile_z = int(math.ceil((thickness + 2*O_buffer) / bulk_silica.periodicity[2]))
        bulk = mb.TiledCompound(bulk_silica, n_tiles=(tile_x, tile_y, tile_z))

        interface = mb.Compound(periodicity=(bulk.periodicity[0],
                                             bulk.periodicity[1],
                                             0.0))
        for i, particle in enumerate(bulk.particles()):
            if ((particle.name == 'Si' and O_buffer < particle.pos[2] < (thickness + O_buffer)) or 
                    (particle.name == 'O' and particle.pos[2] < (thickness + 2*O_buffer))):
                interface_particle = mb.Compound(name=particle.name, pos=particle.pos)
                interface.add(interface_particle, particle.name + "_{}".format(i))
        self.add(interface)
Example #7
0
    def __init__(self,
                 surface,
                 chains,
                 fractions=None,
                 backfill=None,
                 pattern=None,
                 tile_x=1,
                 tile_y=1,
                 **kwargs):
        super(Monolayer, self).__init__()

        # Replicate the surface.
        tiled_compound = mb.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 = round(fraction * n_chains)
                warnings.warn("\n Adding {} of chain {}".format(
                    int(n_points), chain))
                points = subpattern.points[np.random.choice(
                    subpattern.points.shape[0], n_points, replace=False)]
                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:
            warnings.warn(
                "\n No fractions provided.  Assuming a single chain type.")

        # Attach final chain type. Remaining sites get a backfill.
        warnings.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)
    """ """
    def __init__(self, surface_roughness=1.0):
        super(AmorphousSilicaSurface, self).__init__()

        if surface_roughness == 1.0:
            # TODO: description of how this surface was generated/citation
            mb.load('amorphous_silica_sr1.0.pdb',
                    compound=self,
                    relative_to_module=self.__module__)
            self.periodicity = np.array([5.4366, 4.7082, 0.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 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__":
    single = AmorphousSilicaSurface()
    multiple = mb.TiledCompound(single, n_tiles=(2, 1, 1), name="tiled")
    multiple.save('amorphous_silica_surface.mol2')
Example #9
0
 def test_negative_periodicity(self, betacristobalite):
     nx = -2
     ny = 3
     nz = 2
     with pytest.raises(ValueError):
         mb.TiledCompound(betacristobalite, [nx, ny, nz])