コード例 #1
0
def silanol(name="sl", short="SL"):
    """This function generates a silanol molecule.

    Parameters
    ----------
    name : string, optional
        Molecule name
    short : string, optional
        Molecule short name

    Returns
    -------
    mol : Molecule
        Molecule object
    """
    # Initialize molecule
    mol = Molecule(name, short)

    # Define bonds lengths
    b = {"sio": 0.164, "oh": 0.098}

    # Build molecule
    mol.add("Si",[0, 0, 0])
    mol.add("O", 0, r=b["sio"])
    mol.add("H", 1, r=b["oh"])

    # Move to zero
    mol.zero()

    # Return molecule
    return mol
コード例 #2
0
def tms(name="tms", short="TMS", separation=30, is_si=True, is_hydro=True):
    """This function generates a trimethylsilyl (TMS) molecule.

    Parameters
    ----------
    name : string, optional
        Molecule name
    short : string, optional
        Molecule short name
    separation : float, optional
        Sparation of carbon and hydrogen atoms
    is_si : bool, optional
        True if the terminus should be a lone silicon, False for a CH3 group
    is_hydro : bool, optional
        True if the hydrogen atoms should be added

    Returns
    -------
    mol : Molecule
        Molecule object
    """
    # Initialize molecule
    mol = Molecule(name, short)

    # Check silicon
    si = "Si" if is_si else "Ci"
    sio = "sio" if is_si else "co"
    sic = "sic" if is_si else "cc"

    # Define bond lengths and angles
    b = {"sio": 0.155, "sic": 0.186, "ch": 0.109, "co": 0.143, "cc": 0.153}

    # Build silyl chain
    mol.add(si, [0, 0, 0])
    mol.add("O", 0, r=b[sio])
    mol.add(si, 1, r=b[sio])

    # Add methyl
    for i in range(3):
        mol.add("C", 2, r=b[sic], theta=separation+10, phi=120*i)

    if is_hydro:
        # Add hydrogens
        for i in range(3, 5+1):
            for j in range(3):
                mol.add("H", i, r=b["ch"], theta=separation, phi=120*j)

        # If not silicon ending
        for i in range(3):
            if not is_si:
                mol.add("H", 0, r=b["ch"], theta=180-separation, phi=120*i)

    # Move to zero
    mol.zero()

    # Return molecule
    return mol
コード例 #3
0
def alcohol(length, name="alcohol", short="ALC", is_h=True):
    """This function generates linear alcohol molecules.

    Parameters
    ----------
    length : integer
        Number of carbon atoms
    name : string, optional
        Molecule name
    short : string, optional
        Molecule short name
    is_h : bool, optional
        True if hydrogens are needed

    Returns
    -------
    mol : Molecule
        Molecule object
    """
    # Initialize Molecule
    mol = Molecule(name, short)

    # Define bond lengths and angles
    b = {"cc": 0.153, "ch": 0.109, "co": 0.143, "oh": 0.098}
    a = {"ccc": 30.00, "cch": 109.47, "occ": 30.00, "coh": 109.47}

    # Add carbons
    mol.add("C", [0, 0, 0])

    angle = a["ccc"]
    for i in range(length-1):
        angle *= -1
        mol.add("C", mol.get_num()-1, r=b["cc"], theta=angle)

    # Add hydroxy
    mol.add("O", mol.get_num()-1, r=b["co"], theta=-angle)
    mol.add("H", mol.get_num()-1, r=b["oh"], theta=angle)

    # Add hydrogens
    if is_h:
        if length > 1:
            angle = -90
            for i in range(length):
                # Boundary
                if i==0:
                    for j in range(3):
                        mol.add("H", i, r=b["ch"], theta=angle-30, phi=120*j)
                # Inner
                else:
                    mol.add("H", i, r=b["ch"], theta=angle, phi=a["cch"])
                    mol.add("H", i, r=b["ch"], theta=angle, phi=-a["cch"])

                # Switch orientation
                angle *= -1

        # Methanol
        else:
            for i in range(3):
                mol.add("H", 0, r=b["ch"], theta=a["cch"], phi=i*120)

    # Move to zero
    mol.zero()

    # Return molecule
    return mol
コード例 #4
0
def ketone(length, pos, name="ketone", short="KET", is_h=True):
    """This function generates linear ketone molecules.

    Parameters
    ----------
    length : integer
        Number of carbon atoms
    pos : integer
        Position of the oxygen atom
    name : string, optional
        Molecule name
    short : string, optional
        Molecule short name
    is_h : bool
        True if hydrogens are needed

    Returns
    -------
    mol : Molecule
        Molecule object
    """
    # Check input
    if length < 3:
        print("Specified length is too small for ketones ...")
        return

    # Initialize Molecule
    mol = Molecule(name, short)

    # Define bond lengths and angles
    b = {"cc": 0.153, "ch": 0.109, "co": 0.123}
    a = {"ccc": 30.00, "cch": 109.47}

    # Add carbons
    mol.add("C", [0, 0, 0])

    angle = a["ccc"]
    for i in range(length-1):
        angle *= -1
        mol.add("C", mol.get_num()-1, r=b["cc"], theta=angle)

    # Add oxygen
    angle = -90 if pos % 2 == 0 else 90
    mol.add("O", pos-1, r=b["co"], theta=angle)

    # Add hydrogens
    if is_h:
        angle = -90
        for i in range(length):
            # Boundary
            if i==0 or i==length-1:
                for j in range(3):
                    mol.add("H", i, r=b["ch"], theta=angle-30, phi=120*j)
            # Inner
            elif not i == pos-1:
                mol.add("H", i, r=b["ch"], theta=angle, phi=a["cch"])
                mol.add("H", i, r=b["ch"], theta=angle, phi=-a["cch"])

            # Switch orientation
            angle *= -1

    # Move to zero
    mol.zero()

    # Return molecule
    return mol
コード例 #5
0
    def siloxane(self, sites, amount, normal, slx_dist=0.507, trials=1000, site_type="in"):
        """Attach siloxane bridges on the surface similar to Krishna et al.
        (2009). Here silicon atoms of silanol groups wich are at least 0.31 nm
        near each other can be converted to siloxan bridges, by removing one
        oxygen atom of the silanol groups and moving the other at the center of
        the two.

        Parameters
        ----------
        sites : list
            List of silicon ids of which binding sites should be picked
        amount : int
            Number of molecules to attach
        normal : function
            Function that returns the normal vector of the surface for a given
            position
        slx_dist : float
            Silicon atom distance to search for parters in proximity
        trials : integer, optional
            Number of trials picking a random site
        site_type : string, optional
            Site type - interior **in**, exterior **ex**
        """
        # Check site type input
        if not site_type in ["in", "ex"]:
            print("Pore - Wrong attachement site-type...")
            return

        # Create siloxane molecule
        mol = Molecule("siloxane", "SLX")
        mol.add("O", [0, 0, 0], name="OM1")
        mol.add("O", 0, r=0.09, name="OM1")
        mount = 0
        axis = [0, 1]

        # Rotate molecule towards z-axis
        mol_axis = mol.bond(*axis)
        mol.rotate(geometry.cross_product(mol_axis, [0, 0, 1]), geometry.angle(mol_axis, [0, 0, 1]))
        mol.zero()

        # Search for silicon atoms near each other
        si_atoms = [self._block.get_atom_list()[atom] for atom in sites]
        si_dice = Dice(Molecule(inp=si_atoms), slx_dist+0.1, True)
        si_proxi = si_dice.find_parallel(None, ["Si", "Si"], slx_dist, 1e-2)
        si_matrix = {x[0]: x[1] for x in si_proxi}

        # Run through number of siloxan bridges to add
        mol_list = []
        for i in range(amount):
            # Randomly pick an available site pair
            si = []
            for j in range(trials):
                si_rand = random.choice(sites)
                if sites.index(si_rand) in si_matrix and si_matrix[sites.index(si_rand)]:
                    si_rand_proxi = sites[si_matrix[sites.index(si_rand)][0]]
                    if sites.index(si_rand_proxi) in si_matrix:
                        if self._sites[si_rand]["state"] and (self._sites[si_rand_proxi]["state"]):
                            si = [si_rand, si_rand_proxi]
                            break

            # Place molecule on surface
            if si and self._sites[si[0]]["state"] and self._sites[si[1]]["state"]:
                # Create a copy of the molecule
                mol_temp = copy.deepcopy(mol)

                # Calculate center position
                pos_vec_halve = [x/2 for x in geometry.vector(self._block.pos(si[0]), self._block.pos(si[1]))]
                center_pos = [pos_vec_halve[x]+self._block.pos(si[0])[x] for x in range(self._dim)]

                # Rotate molecule towards surface normal vector
                surf_axis = normal(center_pos)
                mol_temp.rotate(geometry.cross_product([0, 0, 1], surf_axis), -geometry.angle([0, 0, 1], surf_axis))

                # Move molecule to mounting position and remove temporary atom
                mol_temp.move(mount, center_pos)
                mol_temp.delete(0)

                # Add molecule to molecule list and global dictionary
                mol_list.append(mol_temp)
                if not mol_temp.get_short() in self._mol_dict[site_type]:
                    self._mol_dict[site_type][mol_temp.get_short()] = []
                self._mol_dict[site_type][mol_temp.get_short()].append(mol_temp)

                # Remove oxygen atom and if not geminal delete site
                for si_id in si:
                    self._matrix.strip(self._sites[si_id]["o"][0])
                    if len(self._sites[si_id]["o"])==2:
                        self._sites[si_id]["o"].pop(0)
                    else:
                        del self._sites[si_id]
                    del si_matrix[sites.index(si_id)]

        return mol_list
コード例 #6
0
ファイル: pattern.py プロジェクト: Ajax23/PoreMS
    def pattern(self):
        """Construct minimal block structure.

        Returns
        -------
        block : Molecule
            Minimal block structure
        """
        # Initialize
        mols = [self._hexagonal() for x in range(3)]

        # Combine three hexagonal molecules
        mols[0].add("O", 2, r=self._b)
        mols[0].add("O", 6, r=self._b)
        mols[0].add("O", 10, r=self._b)

        mols[1].move(0, mols[0].pos(12))
        mols[1].translate([0, 0, self._b])
        mols[1].delete([1, 2, 3, 4, 5, 6, 7])

        mols[2].move(0, mols[0].pos(14))
        mols[2].translate([0, 0, self._b])
        mols[2].delete([2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

        # Build block
        block = []
        for i in range(11):
            block.append(Molecule(inp=copy.deepcopy(mols)))

        block[1].rotate("x", 180)
        block[1].move(18, block[0].pos(18))
        block[1].translate([0, 0, self._b * 2])
        block[1].add("O", block[0].pos(18), r=self._b)

        block[2].rotate("x", 180)
        block[2].move(0, block[0].pos(18))

        block[3].move(4, block[0].pos(15))

        block[4].rotate("x", 180)
        block[4].move(16, block[0].pos(18))
        block[4].delete([21, 19, 15, 20, 14, 12, 10, 2, 11, 1, 0])

        block[5].move(6, block[1].pos(16))
        block[5].delete([21, 19, 15, 20, 14, 12, 10, 2, 11, 1, 0])

        # Delete overlapping molecules
        block = Molecule(inp=block)
        overlap = block.overlap()
        block.delete(sum([overlap[x] for x in overlap], []))

        # Check overlapping atoms due to repetition
        for dim in range(3):
            for pm in range(2):
                # Define translate vector
                translate = [0, 0, 0]
                translate[dim] = self._repeat[dim]
                translate[dim] *= -1 if pm == 1 else 1

                # Remove atoms
                block = Molecule(inp=[block])
                mol_repeat = copy.deepcopy(block)
                mol_repeat.translate(translate)
                block.delete([
                    x for x in Molecule(inp=[block, mol_repeat]).overlap()
                    if x < block.get_num()
                ])

        # Move to zero
        block.zero()

        return block