Example #1
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
Example #2
0
    def fragments(self, fragments):
        nr_frags = len(fragments)
        assert nr_frags >= 0
        "The layer contains no fragments!"#fragments is non-empty
        
        if nr_frags == 1:
            item_fragments = []
            basic_fragment = fragments[0]
            order_basic = len(basic_fragment.stab) 
            order_self = len(self.stab)
            #basic checks that can be switched off
            #1a in __init__
            assert order_self % order_basic == 0,\
                "Order of Fragment.stab does not divide that of Layer.stab!"
            #1b ...
            assert all([item in self.stab for item in basic_fragment.stab]),\
                "There are symops in Fragment.stab that are not in Layer.stab!"


            lcosets = core.cosets_mod(basic_fragment.stab, self.stab)
            for lcoset in lcosets:
                item_fragments.append(Fragment.leftmult(basic_fragment, 
                                                                lcoset[0]))
            self._fragments = item_fragments
            #basic checks to do after coset decomposition
            #1c
            assert all([core.coset_in_stab((coset, self.stab)) \
                    for coset in lcosets]),\
                """Cosets of the consituent fragments
                        do not belong to the stabilizer of the layer!"""
            #1d
            assert all([core.divides((coset, self.stab)) for coset in lcosets]),\
                """Order of cosets of consituent fragments does not devides
                        order of the layers's stabilizer"""
        else:
            self._fragments = fragments
        #basic checks that can be switched off    
        coset_list = [fragment.coset for fragment in self._fragments]
        stab_list = [fragment.stab for fragment in self._fragments]
        #1e
        assert core.cosets_are_disjoint(coset_list), "Cosets are not disjoint!"
        #1f
        assert all([core.divides((stab, self.stab)) for stab in stab_list]),\
                """Order of stabilizer of some constituent fragments
                        does not devide order of the layers's stabilizer"""
        #1g
        assert all([core.coset_in_stab((stab, self.stab)) \
                    for stab in stab_list]),\
                """Stabilizers of the consituent fragments