def buildPairs(self, rcut=5.0, molind_=None, nreal_=None): """ Returns the nonzero pairs, triples in self.x within the cutoff. Triples are non-repeating ie: no 1,2,2 or 2,2,2 etc. but unordered Args: rcut: the cutoff for pairs and triples Returns: pair matrix (npair X 2) triples matrix (ntrip X 3) """ pair = [] ntodo = self.natom if (nreal_ != None): ntodo = int(nreal_) pair = None if (self.alg==0): pair = Make_NListNaive(self.x,rcut,ntodo,int(self.DoPerms)) else: pair = Make_NListLinear(self.x,rcut,ntodo,int(self.DoPerms)) npairi = map(len,pair) npair = sum(npairi) p = None if (molind_!=None): p=np.zeros((npair,3),dtype = np.uint64) else: p=np.zeros((npair,2),dtype = np.uint64) pp = 0 for i in range(ntodo): for j in pair[i]: if (molind_!=None): p[pp,0]=molind_ p[pp,1]=i p[pp,2]=j else: p[pp,0]=i p[pp,1]=j pp = pp+1 del pair return p
def buildPairsAndTriples(self, rcut_pairs=5.0, rcut_triples=5.0, molind_=None, nreal_=None): """ Returns the nonzero pairs, triples in self.x within the cutoff. Triples are non-repeating ie: no 1,2,2 or 2,2,2 etc. but unordered Args: rcut: the cutoff for pairs and triples Returns: pair matrix (npair X 2) triples matrix (ntrip X 3) """ if (self.ele is None): print("WARNING... need self.ele for angular SymFunc triples... ") pair = [] tpair = [] # since these may have different cutoff ntodo = self.natom if (nreal_ != None): ntodo = int(nreal_) pair = None tpair = None if (self.alg==0): pair = Make_NListNaive(self.x,rcut_pairs,int(ntodo),int(self.DoPerms)) tpair = Make_NListNaive(self.x,rcut_triples,int(ntodo),int(self.DoPerms)) else: pair = Make_NListLinear(self.x,rcut_pairs,int(ntodo),int(self.DoPerms)) tpair = Make_NListLinear(self.x,rcut_triples,int(ntodo),int(self.DoPerms)) npairi = map(len,pair) npair = sum(npairi) npairi = map(len,tpair) #ntrip = sum(map(lambda x: x*x if x>0 else 0, npairi)) ntrip = sum(map(lambda x: int(x*(x-1)/2) if x>0 else 0, npairi)) #print ("npair:", npair, " ntrip:", ntrip, " rcut_triples:", rcut_triples, " tpair", tpair, " ntodo:", int(ntodo), " self.DoPerms", int(self.DoPerms), " x:", self.x[:int(ntodo)], " pair:", pair) p = None t = None if (molind_!=None): p=np.zeros((npair,3),dtype = np.uint64) t=np.zeros((ntrip,4),dtype = np.uint64) else: p=np.zeros((npair,2),dtype = np.uint64) t=np.zeros((ntrip,3),dtype = np.uint64) pp = 0 tp = 0 for i in range(ntodo): for j in pair[i]: if (molind_!=None): p[pp,0]=molind_ p[pp,1]=i p[pp,2]=j else: p[pp,0]=i p[pp,1]=j pp = pp+1 for j in tpair[i]: for k in tpair[i]: #if True: if (k > j): # do not do ijk, ikj permutation #if (k!=j): if (molind_!=None): t[tp,0]=molind_ t[tp,1]=i if self.ele is not None and self.ele[j] > self.ele[k]: # atom will smaller element index alway go first t[tp,2]=k t[tp,3]=j elif self.sort and j > k: t[tp,2]=k t[tp,3]=j else: t[tp,2]=j t[tp,3]=k else: t[tp,0]=i if self.ele is not None and self.ele[j] > self.ele[k]: t[tp,1]=k t[tp,2]=j elif self.sort and j > k: t[tp,1]=k t[tp,2]=j else: t[tp,1]=j t[tp,2]=k tp=tp+1 del pair del tpair return p,t
def Update(self, x_, R2=10.0, R3=5.0): """ Update the lists of bodies and their coefficients. Args: x: A new position vector R2: pair cutoff R3: triples cutoff """ if (R2 < R3): raise Exception("R3<R2 Assumption Violated.") self.x = x_.copy() for i in range(self.nf): self.sings[i, :len(self.frags[i]), :] = self.x[ self.frags[i]].copy() self.singz[i, :len(self.frags[i])] = self.z[self.frags[i]].copy() centers = np.zeros((self.nf, 3)) for i in range(self.nf): centers[i] = np.average(self.x[self.frags[i]], axis=0) TwoBodyPairs = None ThreeBodyPairs = None #print "Number of Frags",self.nf if (self.nf < 500): TwoBodyPairs = Make_NListNaive(centers, R2, self.nf, int(False)) ThreeBodyPairs = Make_NListNaive(centers, R3, self.nf, int(False)) else: TwoBodyPairs = Make_NListLinear(centers, R2, self.nf, int(False)) ThreeBodyPairs = Make_NListLinear(centers, R3, self.nf, int(False)) self.pairi = set() self.tripi = set() #print TwoBodyPairs #print ThreeBodyPairs for i in range(self.nf): nnt = len(ThreeBodyPairs[i]) nnp = len(TwoBodyPairs[i]) if (nnp > 0): for j in range(nnp): if (j != None): self.pairi.add(tuple(sorted([i, TwoBodyPairs[i][j]]))) if (nnt >= 2): for j in range(nnt): if (j != None): for k in range(j + 1, nnt): if (k != None): if ThreeBodyPairs[i][k] in ThreeBodyPairs[ ThreeBodyPairs[i][j]]: self.tripi.add( tuple( sorted([ i, ThreeBodyPairs[i][j], ThreeBodyPairs[i][k] ]))) DistMatrix = Make_DistMat(self.x) self.ntrip = len(self.tripi) self.npair = len(self.pairi) #print "num pairs", self.npair #print "num trips", self.ntrip self.pairi = map(list, self.pairi) self.tripi = map(list, self.tripi) #print "Pairs", self.pairi #print "Trips", self.tripi # Now generate the coeffs of each order and sum them. self.singC = np.ones(self.nf) self.pairC = np.ones(self.npair) self.tripC = np.ones(self.ntrip) self.singI = self.frags self.pairI = [] self.tripI = [] self.pairs = np.zeros((self.npair, self.maxnatom, 3)) self.trips = np.zeros((self.ntrip, self.maxnatom, 3)) self.pairz = np.zeros((self.npair, self.maxnatom), dtype=np.uint8) self.tripz = np.zeros((self.ntrip, self.maxnatom), dtype=np.uint8) for trip_index, trip in enumerate(self.tripi): i, j, k = trip[0], trip[1], trip[2] self.tripI.append([self.frags[i] + self.frags[j] + self.frags[k]]) ni, nj, nk = len(self.frags[i]), len(self.frags[j]), len( self.frags[k]) self.trips[trip_index, :ni, :] = self.x[self.frags[i]].copy() self.trips[trip_index, ni:(ni + nj), :] = self.x[self.frags[j]].copy() self.trips[trip_index, (ni + nj):(ni + nj + nk), :] = self.x[self.frags[k]].copy() self.tripz[trip_index, :ni] = self.z[self.frags[i]].copy() self.tripz[trip_index, ni:(ni + nj)] = self.z[self.frags[j]].copy() self.tripz[trip_index, (ni + nj):(ni + nj + nk)] = self.z[self.frags[k]].copy() self.pairC[self.pairi.index(sorted([i, j]))] -= 1 self.pairC[self.pairi.index(sorted([j, k]))] -= 1 self.pairC[self.pairi.index(sorted([k, i]))] -= 1 self.singC[i] += 1 self.singC[j] += 1 self.singC[k] += 1 for pair_index, pair in enumerate(self.pairi): i, j = pair[0], pair[1] self.pairI.append([self.frags[i] + self.frags[j]]) ni, nj = len(self.frags[i]), len(self.frags[j]) self.pairs[pair_index, :ni, :] = self.x[self.frags[i]].copy() self.pairs[pair_index, ni:(ni + nj), :] = self.x[self.frags[j]].copy() self.pairz[pair_index, :ni] = self.z[self.frags[i]].copy() self.pairz[pair_index, ni:(ni + nj)] = self.z[self.frags[j]].copy() self.singC[i] -= 1 self.singC[j] -= 1 return