예제 #1
0
    def addBond(self,
                atom1Num=None,
                atom1CellPos=None,
                atom2Num=None,
                atom2CellPos=None,
                jMatrix=None,
                atom1=None,
                atom2=None):
        """Adds an interaction between two atoms.
        
        atom1Num is the unique number identifying the given atom in the unit cell.
	atom1CellPos is a 3 integer tuple with the coordinates of the unit
	cell containing atom1.
        
        JMatrix is the 3x3 matrix describing the spin-spin interaction between
        the atoms for the heisenberg hamiltonian.
        
        If a bond with the same JMatrix that links the same two atoms already exists 
        nothing happens.  If a bond linking the two atoms exists, but has a different
        JMatrix, an Exception is raised.
        """
        if atom1 == None:
            cell1 = self.cellAtPosition(
                (atom1CellPos[0], atom1CellPos[1], atom1CellPos[2]))
            atom1 = cell1.atomWithID(atom1Num)

        if atom2 == None:
            cell2 = self.cellAtPosition(
                (atom2CellPos[0], atom2CellPos[1], atom2CellPos[2]))
            atom2 = cell2.atomWithID(atom2Num)

        existingBond = self.getBond(atom1, atom2)
        if existingBond != None:
            if (existingBond.getJMatrix() != jMatrix).any():
                #An exception will be raised if a different bond already exists
                #that links these atoms.
                raise Exception("A Bond already exists linking Atom1: " +
                                atom1.__str__() + " and Atom2: " +
                                atom2.__str__())
            else:  #The bond exists, but it's the same bond
                return

    #def addBond(self, Atom1, Atom2, jMatrix = None):
    #"""Adds a bond and all symmettry equivalent bonds within the magnetic Cell

    #Performs every symmetry operation and every possible translation for each
    #symmetry operation to find all possible bonds"""

    #Create Symmetry Bonds

        xyz = atom1.getPosition()
        xyz2 = atom2.getPosition()

        for symop in self.space_Group.iter_symops():
            # operate on coordinates in non-shifted spacegroup
            pos1 = symop(xyz)
            pos2 = symop(xyz2)

            #Recording symops that map bond back to itself (for symmetry constraints)
            if xyz[0] == pos1[0] and xyz2[0] == pos2[0]:  #x component
                if xyz[1] == pos1[1] and xyz2[1] == pos2[1]:  #y component
                    if xyz[2] == pos1[2] and xyz2[2] == pos2[2]:  #z component
                        self.bondConstraints.append(
                            BondConstraint(xyz, xyz2, symop))

            mask1 = numpy.logical_or(pos1 < 0.0, pos1 >= 1.0)
            translation = numpy.floor(
                pos1[mask1]
            )  #translates the first atom back to cell at (0,0,0)
            pos1[mask1] -= translation
            pos2[
                mask1] -= translation  #Uses same translation to translate other atom

            #translate new Bond to all cells

            #Find the number of times to translate the bond in each direction so
            #that it will will cover the whole magnetic cell but not go outside
            if pos1[0] > pos2[0]:
                Xiter = self.Na - pos1[0]
            else:
                Xiter = self.Na - pos2[0]

            if pos1[1] > pos2[1]:
                Yiter = self.Nb - pos1[1]
            else:
                Yiter = self.Nb - pos2[1]

            if pos1[2] > pos2[2]:
                Ziter = self.Nc - pos1[2]
            else:
                Ziter = self.Nc - pos2[2]

            Xiter = int(Xiter) + 1
            Yiter = int(Yiter) + 1
            Ziter = int(Ziter) + 1

            #iterate through each possible translation and check if there are atoms there that could
            #be bonded; if so, add the bond
            for i in range(
                    0, Xiter
            ):  #translate in x direction (Na - Cell X position) times
                for j in range(
                        0, Yiter
                ):  #translate in y direction (Nb - Cell Y position) times
                    for k in range(
                            0, Ziter
                    ):  #translate in z direction (Nc - Cell Z position) times
                        translatedAtom1 = self.atomAtPosition(
                            (i + pos1[0], j + pos1[1], k + pos1[2]))
                        translatedAtom2 = self.atomAtPosition(
                            (i + pos2[0], j + pos2[1], k + pos2[2]))

                        if translatedAtom1 != None and translatedAtom2 != None:
                            newBond = Bond(translatedAtom1, translatedAtom2,
                                           jMatrix)

                            #make sure bond does not already exist
                            for currentBond in self.Bonds:
                                if newBond.sameBond(currentBond):
                                    break
                            else:  #if not, add the bond to the list of unique bonds
                                self.Bonds.append(newBond)