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)
def check_corr(self): """This test should check that for every pair in the bilayer: symmetry operators of the stabilizer of a bilayer generate the same symmetry equivalent pairs as obtained by coset decom position of the stabilizer of the bilayer with respect to the sta bilizer of a pair(method Pair.indOfEqvPairs)""" symops = self.bilayer.stab frags_0 = self.bilayer.layers[0].fragments #fragments of the first layer frags_1 = self.bilayer.layers[1].fragments #fragments of the second layer cosets_0 = [getattr(fragment, "coset") for fragment in frags_0] cosets_1 = [getattr(fragment, "coset") for fragment in frags_1] alerts = [] checks = [] for i,fr0 in enumerate(frags_0): for j,fr1 in enumerate(frags_1): print "-----------Testing pair (%d,%d)-----------------------"\ % (i,j) #calculated indices for the symmetry equivalent pairs pairs_calc = Pair((i,j),self.bilayer).indOfEqvPairs #observed indices for the symmetry equivalent pairs pairs_obs = [] for symop in symops: cs0 = map(core.modulo_n, core.lcoset((fr0.coset,symop))) cs1 = map(core.modulo_n, core.lcoset((fr1.coset,symop))) indices = core.eqv_frag_ind(cs0,cs1,cosets_0, cosets_1) pairs_obs.append(indices) print "Number of eqv. pairs calc.,obs.: %d, %d" \ % (len(pairs_calc),len(pairs_obs)) set_calc = set(pairs_calc) set_obs = set(pairs_obs) print "Number of unique eqv. pairs calc.,obs.: %d, %d" \ % (len(set_calc),len(set_obs)) test_value = all((set_obs <= set_calc, set_obs >= set_calc)) checks.append(test_value) if not test_value: alerts.append((i,j)) print "Calculated and observed pairs are the same:", test_value sys.stdout.flush() print "\nALL THE PAIRS PASSED THE TEST:", all(checks) print "Problematic pairs (if any):\n" print alerts
def check_stab(stab): """This method performes check of the stabilizer of a bilayer. In its present version it only checks that two layers of beta, one basic and the one generateb by applying m_z to the basic layer have the stabilizer pmmm, including corresponding shiftst""" pmmm = core.symopMatList(47) d_x = map(core.xyzt2augmat,['x,y,z','x+1/3,y,z','x+2/3,y,z']) d_y = map(core.xyzt2augmat,['x,y,z','x,y+1/3,z','x,y+2/3,z']) pmmm_dx = [] for symop in d_x: pmmm_dx.extend(map(core.modulo_n,core.lcoset((pmmm, symop)))) pmmm_dx_dy = [] for symop in d_y: pmmm_dx_dy.extend(map(core.modulo_n, core.lcoset((pmmm_dx, symop)))) print "\n----------Checking stabilizer of the bilayer!--------------\n" print "The length of the generated stabilizer is: %d" %( len(pmmm_dx_dy)) print "The length of the tested stabilizer is: %d" % (len(stab)) counter1 = 0 counter2 = 0 for item in stab: if item in pmmm_dx_dy: counter1 += 1 else: print "This item is not in the generated stabilizer!" print item print for item in pmmm_dx_dy: if item in stab: counter2 += 1 else: print "This item is not in the tested stabilizer!" print item print print "\nRESULT:Generated and tested stabilizers are equal:", \ counter1 == counter2 print "\n--------------------DONE!----------------------------------\n"
def build_shift_classes(self): """ IMPORTANT: THIS METHOD IS PARTLY HARDCODED, FOR IT ONLY ACCOUNTS FOR SHIFTS WITHIN XY PLANE REQUIRED FOR MODELLING DISORDER IN ZEOLITE-BETA. IT CAN HOWEVER BE EASILY MODIFIED!!! -------------------------------------------------------------- This method will group fragments into shift classes(which will be stored in self.__shift_classes) in the following way: 1. Find basic fragment within the layer 2. Find fragments that are obtained from the basic one without applying shifts and put them into one class, shift_class_0. This is achieved by sear- ching for symops in self.stab that have zero shift component, applying them to basic_fragment.stab and locating indices of the corresponding fragements within self. 3.Shift_class_i is produced by applying one of all the possible shift vectors (symops of self.stab that have unit rotation matrix as their rotation part) to the fragments in zero_group_0, locating so obtained fragments within the layer and storing them within as a single group. 4.The total number of shift_classes so obtained will be equal to the number of the possible pure shifts. 5.Those shift_classes are later employed for the computation of shift vector between two fragments """ self.__shift_classes = [] shift_class_0 = set() basic_fragment = self.basicFragment basic_stab = basic_fragment.stab all_shifts = set() unitAugMat = core.xyzt2augmat('x,y,z') zero_shift_xy = unitAugMat[0:2,-1] unit_rot_part = unitAugMat[0:3,0:3] #Constructing shift_class_0 and filling all_shfits with indices #of pure shift symops in self.symop for nr,symop in enumerate(self.stab): if symop[0:2,-1] == zero_shift_xy: coset = map(core.modulo_n, core.lcoset((basic_stab, symop))) index = self.fragment_index(coset) shift_class_0.add(index) elif symop[0:3, 0:3] == unit_rot_part: all_shifts.add(nr) self.__shift_classes.append(shift_class_0)