Exemplo n.º 1
0
    def leftmult(Cls, self, symop):
        """Returns instance of Fragment obtained from the current instance by
        left multiplication with symop. The initialization of the new
        instance is done according to case 2 described in __init__"""
        if str == type(symop):
            sym_mat = core.xyzt2augmat(symop)
        else:
            sym_mat = symop 
        
        #I am not sure how the triple product modulo should be executed!!!!!
        
        #new_stab = map(
        #        core.modulo_n, core.lstab((self.stab, sym_mat))
        #        )
        new_stab = []
        sym_mat_inv = core.modulo_n(sym_mat.inv(), 1)

        for item in self.stab:
            new_elt = core.modulo_n(core.modulo_n(sym_mat*item,1)*sym_mat_inv,1)
            new_stab.append(new_elt)
        
        #new_stab = [core.modulo_n(core.modulo_n(sym_mat*item,1)*sym_mat.inv(),1) for item in  self.stab]


                
        new_coset = map(core.modulo_n, core.lcoset((self.coset, sym_mat)))

        return Cls(new_stab, new_coset)
Exemplo n.º 2
0
    def indOfEqvPairs(self):
        """Uses self.cosets to find indices of fragmens in bilayer that form
        pairs symmetry equivalent to the self. Indices are a a list of tuples:
        [(),...(j,i),...()], j-index of the fragment in self.bilayer.layers[1]
        and i-...in self.bilayer.layers[0]. Theory beyound:
            Coset representatives g of decomposition
            self.bilayer.stab:self.stab,
            stored in self.cosets produce pair symmetry equivalent to self.
            We designate self=X_iX_j. 
            (1) X_i = g_i*S_0*X_0
            (2) X_j = g_j*S_0*X_0
            Acting on (1) and (2) with g we get:
                g*X_i = g*g_i*S_0*X_0
                g*X_j = g*g_j*S_0*X_0
            So we only have to find indices of cosets g*g_i*S_0 and g*g_j*S_0
            in coset attributes of self.bilayer.layers[0/1]"""
        if self._indEqvPairs:
            return self._indEqvPairs
        #generating cosets of the equivalent pairs with respect to the
        #basic fragment stabilizer.
        indices = []
        for cset in self.cosets:
            gg_iS_0 = [core.modulo_n(cset[0]*symop, 1)\
                    for symop in self.__init_fragments[0].coset]
            gg_jS_0 = [core.modulo_n(cset[0]*symop, 1)\
                    for symop in self.__init_fragments[1].coset]
            #finding the indices of the cosets among the cosets of layer0
            # and layer1
            cosLay0Fragms = [fragment.coset\
                    for fragment in self.bilayer.layers[0].fragments]
            cosLay1Fragms = [fragment.coset\
                    for fragment in self.bilayer.layers[1].fragments]
            #finding indices of the corresponding cosets
            ind01_tuple = core.eqv_frag_ind(gg_iS_0, gg_jS_0,\
                                            cosLay0Fragms, cosLay1Fragms)

            indices.append(ind01_tuple)

        self._indEqvPairs = indices

        return self._indEqvPairs
Exemplo n.º 3
0
    def stab(self):
        """Computing stabilizer of a bilayer(or any 2 fragments).
        self.layers must contain 2 Layers L_0 and L_1. 

        IMPORTANT: L_1 = g*L_0 so that if  S_0 = stab(L_0) => L_1 = g*S_0*L_0. 
        The latter means tha coset g*S_O contains all symops to generate L_1
        from L_0.

        The stabilizer of the bilayer is then a union of 2 sets:
            1. set1 contains all common symmetry elements of S_0 and S_1. 
                El-ts of this set simply transform each of the layers into
                itself
            2. set2 contains symmetry elements that transform L_0 into L_1
               and at the same time L_1 into L_0. El-ts that transform L_0
               into L_1 are in the coset:
                g*S_0       (that's why it is important
                            that L_1 = g*L_O, that the corresponding coset
                            attributes of the layers are set correctly)
               so g' from g*S_0 applied to L_1 should yield L_0:
                g'*L_1=L_0 and since g'L_0 = L_1 =>g'*g'L_0 = L_0 => g'*g'
                or g'^2 should belong to S_0.
                Hence set2 contains elements of coset g*S_0 (or L_1.coset)
                which squares belong to S_0.
                """
        if self._stab:
            return self._stab
        #finding overlap between stabilizers of the constituent layers
        stab_overlap = \
                [item for item in self.layers[1].stab
                        if item in self.layers[0].stab]
        #for a layer that is generated from the other one by a stacking oper:
        #finding coset members whose 2 orders belong to stabilizer of the basic
        #layer
        unit_element = core.xyzt2augmat('x,y,z')
        sec_ord_elts = []
        for nr,layer in enumerate(self.layers):
            if unit_element not in layer.coset:
                for symop in layer.coset:
                    if core.modulo_n(symop*symop,1) in self.layers[1-nr].stab \
                            and symop not in stab_overlap:
                            sec_ord_elts.append(symop)

        self._stab = stab_overlap + sec_ord_elts
        #performing some basic checks
        coset_union = self.layers[0].coset + self.layers[1].coset
        #print len(self.layers[0].coset)
        assert core.cosets_are_disjoint([self.layers[0].coset,
            self.layers[1].coset]), "Cosets are not disjoint!"
        
        assert len(self.layers[1].coset) == len(self.layers[0].coset),\
          "Coset attributes for the constituent layers are of different order!"
        return self._stab
Exemplo n.º 4
0
    def _reset_cosets(self, fragments):
        """For finding the stabilizer of the pair based on the algorithm 
        described in Bilayer.stab(it is inherited by the current class):
        The theory fo finding the stabilizer of the pair:
            The pair consists of fragments X_i and X_j, which coset attributes
            (i.e. X_i.coset),g_i*S_0 and g_j*S_O are in the following 
            relation with the basic fragment:
               (1) g_i*S_0*X_0 = g_i'*X_0 = X_i, g_i' in g_i*S_0
               (2) g_j*S_0*X_0 = g_j'*X_0 = X_j, g_j' in g_j*S_0,
                    S_0 = stab(X_0)

            from (1): X_0 = g_i'.inv*X_0
            Putting that into (2): yields g_j'*g_i'.inv*X_i = X_j
            Hence: reset coset attributes to the following:            
                1. X_j.coset = g_j*X_i.coset.inv()
                2. X_i.coset = X_i.stab
                """
        XiCosInv = [core.modulo_n(symop.inv(), 1)\
                for symop in fragments[0].coset]
        g_j = fragments[1].coset[0]
        fragments[1].coset = [core.modulo_n(g_j*symop, 1)\
                for symop in XiCosInv]
        fragments[0].coset = fragments[0].stab