コード例 #1
0
 def similarity(self):
     mdff = self.param["filtering"]["final"]["max_diff_report"]
     if len(self.finals) != 0:
         c = self.finals[0]
         eles, ne = elem_num(c.elems)
     for i, c in enumerate(self.finals):
         mj = -1
         md = None
         for j, d in enumerate(self.finals[:i]):
             if isinstance(c, ClusterAtSurface):
                 v, _ = surface_compare(d, c, ne, eles, mdff)
             else:
                 v, _ = at_comp(d.atoms, c.atoms, ne, eles, mdff)
             if mj == -1 or md > v:
                 md = v
                 mj = j
         if mj != -1 and md != mdff:
             c.similar = [mj, md]
         else:
             c.similar = None
コード例 #2
0
def surface_match(a, b, dmax, dmin=1E-2, nd=20):
    from cluster.base import elem_num
    assert isinstance(a, Surface)
    assert isinstance(b, Surface)
    adir = to_direct(a.atoms, a.cell)
    bdir = to_direct(b.atoms, a.cell)
    if len(a.elems) == len(b.elems):
        # efficient way
        assert (a.elems == b.elems).all()
        cellmat = to_cellmat(a.cell)
        eles, ne = elem_num(a.elems)
        ww = weights(a.atoms, b.atoms, ne, eles, cellmat)
        v, vx = kmc_comp(ww, ne, eles)
        vg = np.zeros(vx.shape, dtype=int)
        for i, ii in enumerate(vx):
            vg[ii - 1] = i + 1
        return v, vg
    else:
        # old way
        cl = np.linalg.norm(to_cellmat(a.cell), axis=1)
        dstep = (dmax / dmin)**(1.0 / nd)
        d = dmin
        mt = [-1] * a.n
        mx = range(b.n)
        cell = [1.0, 1.0, None]
        for _ in range(nd):
            for i in range(a.n):
                if mt[i] == -1:
                    for ij, j in enumerate(mx):
                        if check_imagex(adir[i], a.elems[i], bdir[j],
                                        b.elems[j], cell, d, cl):
                            mt[i] = j
                            del mx[ij]
                            break
            if len(mx) == 0:
                break
            d *= dstep
        # diff, march indices
        return d, np.array(mt) + 1
コード例 #3
0
 def build_surf_ref(self):
     cax = self.clus
     surf = cax[0].surf
     # align atoms
     eles, ne = elem_num(cax[0].elems)
     cellmat = to_cellmat(surf.cell)
     for i in [0, -1]:
         _, b = surface_compare(cax[i], self.ref_structs[i], ne, eles, 0.5)
         self.adjust_surf(cax[i], self.ref_structs[i], b)
     mdiff, _ = km_comp(cax[0].atoms, cax[-1].atoms, ne, eles, cellmat)
     lscax = [cax]
     nmax = self.nimages + 1
     assert (len(self.ref_structs) == nmax + 1)
     uimgs = []
     mishort = 0
     for cax in lscax:
         imgs = []
         for i in range(0, nmax + 1):
             if i == 0:
                 cc = cax[0]
             elif i == nmax:
                 cc = cax[1]
             else:
                 cc = self.ref_structs[i]
             cc = copy.deepcopy(cc)
             cc.surf.forces = None
             if cc.mag is None:
                 cc.mag = 0.0
             cc.label = "CONN-%d-%d:%%d.%d:%.2f" % (self.endp[0],
                                                    self.endp[1], i, cc.mag)
             imgs.append(cc)
         uimgs.append(imgs)
     return uimgs, [
         self.endp[0], self.endp[1],
         len(uimgs), 1, mishort, 0, 0, mdiff
     ]
コード例 #4
0
    csdir = to_direct(surf.atoms, surf.cell)
    if deep:
        csdir[:, 0:2] -= ctrref
        csdir = apply_trans(csdir, cxdmin[2], ucell)
        csdir[:, 0:2] += ctrref
        csdir += cxdmin[3]
    for ii, _ in enumerate(csdir):
        for k in range(2):
            csdir[ii, k] += num_adjust(TOLS - csdir[ii, k], 1.0)
    surf.atoms = to_cartesian(csdir, surf.cell)


if __name__ == "__main__":
    from surface.base import read_surface
    surf = read_surface('../PGOPT/surfaces/mgo.xyz')
    surf.space_group = "-F 4 2 3"
    surf.unit_cell = np.array([4.257, 4.257, 4.257])
    from cluster.base import read_clusters, elem_num
    clus = read_clusters(
        "/Users/fszix/Projects/test/master/1.1/par_local.xyz.0")
    cla = []
    nx = 72
    for c in clus:
        aa = ClusterAtSurface(c.n - nx, surf)
        surfmin = c.atoms[:nx].min(axis=0).reshape(1, 3)
        aa.atoms = c.atoms[nx:] - surfmin
        aa.elems = c.elems[nx:]
        cla.append(aa)
    eles, ne = elem_num(aa.elems)
    print surface_compare(cla[8], cla[9], ne, eles, 1.0)
コード例 #5
0
ファイル: opt.py プロジェクト: zishengz/PGOPT
 def filter(self, prefix='FIL', iprint=True):
     if iprint: print('filtering ...')
     self.corrs = []
     n = self.cn
     dmax_rep = self.max_diff_report
     dmax = self.max_diff
     eles = None
     self.finals = []
     holder = 76
     if iprint: print('Number of structs: %d' % n)
     if iprint: print(('%%%ds' % (holder)) % ('-' * holder, ))
     self.corrs.append('#%6s %3s %-8s %15s %-8s %15s %6s %5s  ' %
                       ('new #', '%', 'orig #', 'this E', 'sim. #',
                        'sim. E', 'mindm', 'time'))
     if iprint: print(self.corrs[-1])
     self.min_ener = None
     if iprint: print(('%%%ds' % (holder)) % ('-' * holder, ))
     init_time = start_time = time.time()
     for ci, c in enumerate(self.clus):
         if c.label == '': c.label = 'PRE:%d' % (ci, )
         if eles is None:
             eles, ne = elem_num(c.elems)
         # if n >= 10 and ci % (n / 10) == 0: print '{:.0f} %'.format(ci / (n / 100.0))
         min_dmax, mini = dmax_rep, None
         ok = True
         for di, d in enumerate(self.finals):
             if min_dmax == 0.0:
                 v = 1.0
             elif isinstance(c, ClusterAtSurface):
                 v, _ = surface_compare(d, c, ne, eles, min_dmax)
             else:
                 v, _ = at_comp(d.atoms, c.atoms, ne, eles, min_dmax)
             if v < min_dmax:
                 min_dmax, mini = v, d
             if v < dmax:
                 ok = False
                 if self.post_reject is not None:
                     self.post_reject()
                 break
         finish_time = time.time()
         self.corrs.append(
             ('{:7} {:2d}% {:8} {:15.6f} {:24} {mindm:6.4f} ' +
              '{time:5.2f} {star}').format(
                  len(self.finals) if ok else '',
                  int((len(self.finals) if self.flimit else ci) /
                      ((n + 1 if self.flimit else n) / 100.0)),
                  c.label,
                  c.energy,
                  '{:8} {:15.6f}'.format(mini.label, mini.energy)
                  if mini is not None else '{:8} {:>15}'.format('-', '-'),
                  mindm=min_dmax,
                  time=finish_time - start_time,
                  star='*' if ok else ' '))
         start_time = finish_time
         if iprint: print(self.corrs[-1])
         if ok:
             self.finals.append(c)
             c.multi = 1
             c.new_label = prefix + ':' + str(len(self.finals) - 1)
         else:
             mini.multi += 1
             if hasattr(mini, "props") and "nrep" in mini.props:
                 mini.props["nrep"] += c.props["nrep"]
         if len(self.finals) == n: break
         if ci >= 100000:
             raise RuntimeError("Cannot generate enough " +
                                "distinct structures after %d trials!" % ci)
     if iprint: print(('%%%ds' % (holder)) % ('-' * holder, ))
     total_time = finish_time - init_time
     if iprint:
         print(('%%%ds' % (holder)) %
               ('total time used: %d:%02d:%02d' %
                (total_time / 3600,
                 (total_time / 60) % 60, total_time % 60), ))
     if iprint: print(('%%%ds' % (holder)) % ('-' * holder, ))
コード例 #6
0
 def run(self):
     # for surface case, need to solve the km_comp with cell periodic problem
     # interp needs to deal with crossing bounday problem
     conn = []
     clus_match = []
     # use ref paths to build
     if len(self.ref_nebmin) != 0:
         print("## number of ref-isomers = %d" % len(self.ref_nebmin))
         eles, ne = elem_num(self.ref_nebmin.values()[0].elems)
         for i in range(len(self.clus)):
             kmm = -1
             for k, v in self.ref_nebmin.items():
                 aa = surface_compare(self.clus[i], v, ne, eles, 5)[0]
                 if kmm == -1 or aa < kmm:
                     kmm = aa
                     ki = (k, v)
             if kmm <= 0.15:
                 clus_match.append([ki, kmm])
                 print("matched [ %4d -> %4s ] %.4f *" % (i, ki[0], kmm))
             else:
                 clus_match.append([("", None), -1])
                 print("failed  [ %4d -> %4s ] %.4f" % (i, ki[0], kmm))
     else:
         for i in range(len(self.clus)):
             clus_match.append([("", None), -1])
     for i in range(len(self.clus)):
         eles, ne = elem_num(self.clus[i].elems)
         for j in range(i):
             if clus_match[i][1] != -1 and clus_match[j][
                     1] != -1 and clus_match[i][0][0] != clus_match[j][0][0]:
                 xi, xj = clus_match[i][0][0], clus_match[j][0][0]
                 oft = "%s.%s" % (xi, xj)
                 rft = "%s.%s" % (xj, xi)
                 if oft in self.ref_path_dict or rft in self.ref_path_dict:
                     if oft in self.ref_path_dict:
                         rstr = self.ref_path_dict[oft].structs
                     elif rft in self.ref_path_dict:
                         rstr = self.ref_path_dict[rft].structs[::-1]
                     print("[%4d -> %4d ] projected to [%4s -> %4s ] *" %
                           (i, j, xi, xj))
                     conn.append(
                         Connection([self.clus[i], self.clus[j]],
                                    self.iprp, (i, j),
                                    len(conn),
                                    ref_structs=rstr))
             else:
                 # no ref paths
                 if self.surf is None:
                     d, _ = at_comp(self.clus[i].atoms, self.clus[j].atoms,
                                    ne, eles, self.max_diff + 0.1)
                 else:
                     d, _ = surface_compare(self.clus[i], self.clus[j], ne,
                                            eles, self.max_diff + 0.1)
                 if d < self.max_diff:
                     print("[%4d -> %4d ] diff = %5.2f *" % (i, j, d))
                     conn.append(
                         Connection([self.clus[i], self.clus[j]], self.iprp,
                                    (i, j), len(conn)))
                 else:
                     print("[%4d -> %4d ] diff = %5.2f" % (i, j, d))
     if len(self.ref_nebmin) != 0:
         for cc in conn:
             cc.max_trials_surf = 4
     print("## number of isomers = %d" % len(self.clus))
     print("## number of pairs = %d" % len(conn))
     series = []
     title = "[from ->  to  ] accepted ntrial nshort nhighd  nsymm min-diff"
     holder = len(title)
     print(('%%%ds' % (holder)) % ('-' * holder, ))
     print(title)
     print(('%%%ds' % (holder)) % ('-' * holder, ))
     for c in conn:
         ser, prt = c.build()
         series.extend(ser)
         print("[%4d -> %4d ] %8d %6d %6d %6d %6d %8.2f" % tuple(prt))
     print(('%%%ds' % (holder)) % ('-' * holder, ))
     print("## number of final connections = %d" % len(series))
     conn_fn = new_file_name(self.p.conn_images_name)
     print("write images: " + conn_fn)
     writter = RecordWritter()
     apd = False
     for it, s in enumerate(series):
         for c in s:
             c.label = c.label % it
         writter.write_clusters(conn_fn, s, apd)
         apd = True
コード例 #7
0
    def interp_surf(self, ibest=None):
        if ibest is None:
            ibest = self.max_trials_surf
        cax = self.clus
        surf = cax[0].surf
        # align atoms
        eles, ne = elem_num(cax[0].elems)
        cellmat = to_cellmat(surf.cell)
        lscax = []
        mdiff = None
        mdmax = None
        misinglelong = 0
        if len(cax) == 2:
            bs = surface_compare(cax[0],
                                 cax[1],
                                 ne,
                                 eles,
                                 self.max_diff + 0.1,
                                 best=ibest)
            for md, b in bs:
                if len(lscax) != 0 and (md > self.max_diff
                                        or md > mdiff * 1.5):
                    break
                cxx = copy.deepcopy(cax)
                self.adjust_surf(cxx[0], cxx[1], b)
                mdx = np.linalg.norm(cxx[0].atoms - cxx[1].atoms, axis=1).max()
                if len(lscax) != 0 and (mdx > self.max_diff * 4):
                    misinglelong += 1
                    break
                lscax.append(cxx)
                if mdiff is None or md < mdiff:
                    mdiff = md
                if mdmax is None or mdx < mdmax:
                    mdmax = mdx
        else:
            for cai in range(len(cax) - 1, 0, -1):
                _, b = surface_compare(cax[cai - 1], cax[cai], ne, eles,
                                       self.max_diff + 0.1)
                self.adjust_surf(cax[cai - 1], cax[cai], b)
            mdiff, _ = km_comp(cax[0].atoms, cax[-1].atoms, ne, eles, cellmat)
            lscax.append(cax)

        # construct final images
        nmax = self.nimages + 1
        dc = 1.0 * nmax / (len(cax) - 1)
        for cax in lscax:
            for cai in range(0, len(cax)):
                cax[cai].idx = cai * dc

        uimgs = []
        mishort = 0
        for cax in lscax:
            imgs = []
            ishort = False
            for i in range(0, nmax + 1):
                cc = ClusterAtSurface(cax[0].n, copy.deepcopy(cax[0].surf))
                cc.elems = cax[0].elems
                for cai in range(1, len(cax)):
                    if cax[cai].idx >= i - 1E-8:
                        break
                cx, cy = cax[cai - 1], cax[cai]
                rx = (cax[cai].idx - i) / dc
                cc.atoms = cx.atoms * rx + cy.atoms * (1 - rx)
                cc.surf.atoms = cx.surf.atoms * rx + cy.surf.atoms * (1 - rx)
                cc.mag = None
                if np.abs(rx - 1) < 1E-8:
                    cc.mag, cc.energy = cx.mag, cx.energy
                    cc.surf.forces = cx.surf.forces
                elif np.abs(rx) < 1E-8:
                    cc.mag, cc.energy = cy.mag, cy.energy
                    cc.surf.forces = cy.surf.forces
                else:
                    cc.surf.forces = None
                if cc.mag is None:
                    cc.mag = 0.0
                cc.label = "CONN-%d-%d:%%d.%d:%.2f" % (self.endp[0],
                                                       self.endp[1], i, cc.mag)
                if i != 0 and i != nmax:
                    pcc = PreOptimization(cc,
                                          self.adjusted_short_length_factor)
                    pcc.maxiter = 12
                    lpp = pcc.opt()
                    if not lpp:
                        ishort = True
                        break
                    cc = pcc.traj[-1]
                imgs.append(cc)
            if not ishort:
                uimgs.append(imgs)
            else:
                mishort += 1
        return uimgs, [
            self.endp[0], self.endp[1],
            len(uimgs), ibest, mishort, misinglelong, 0, mdiff
        ]
コード例 #8
0
    def build_gas_phase(self):
        if len(self.RotFunc) == 0:
            self.init_func()
        ca = self.clus[0]
        cb = self.clus[1]
        eles, ne = elem_num(ca.elems)
        eles2, ne2 = elem_num(list(ca.elems) * 2)
        nmax = self.nimages + 1

        # initial measurement
        atomsa, atomsb = np.array(ca.atoms), np.array(cb.atoms)
        dd, _ = at_comp(atomsa, atomsb, ne, eles, self.max_diff + 0.1)
        dcl = np.array(self.max_trials)
        uph = self.trail_tolerance

        # build trial set
        dcf = None
        while dcl == self.max_trials and uph > 0.05:
            dcx = at_comp_list(atomsa, atomsb, ne, eles, dd + uph, dcl)
            dcx = dcx[:dcl - 1]
            if dcf is None or dcl == self.max_trials:
                dcf = np.array(dcx)
            uph /= np.sqrt(2)

        # solve rotation non-linear problem
        ntrial = len(dcf)
        nshort = 0
        nhigh = 0
        nsymm = 0
        mdiff = self.max_diff
        finals = []
        task = LBFGS(6)
        task.log_file = 0
        task.max_iter = 500
        for idx in dcf:
            caa, cab = np.array(atomsa), np.array(atomsb)
            caa = caa[idx - 1]
            xi = [0.0] * 6
            task.p.eval = lambda x: self.RotFunc[0](caa, cab, x)
            task.p.evald = lambda x: self.RotFunc[1](caa, cab, x)
            task.start(xi)
            task.opt()
            caf = self.RotFunc[2](caa, task.x)
            hdiff = self.RotFunc[0](caa, cab, task.x)
            if hdiff > self.max_diff:
                nhigh += 1
                continue
            if not check(ca.elems, caf, cab, nmax,
                         self.acceptable_short_length_factor):
                nshort += 1
                continue
            finals.append([caf, cab, hdiff])
            if hdiff < mdiff:
                mdiff = hdiff
        finals.sort(key=lambda x: x[2])
        if len(finals) > 1:
            ufinals = [finals[0]]
            ufinalsrf = [np.concatenate(finals[0][:2])]
            for ff in finals[1:]:
                crg = np.concatenate(ff[:2])
                okay = True
                for crf in ufinalsrf:
                    crd, _ = at_comp(crf, crg, ne2, eles2,
                                     self.path_min_diff + 0.02)
                    if crd < self.path_min_diff:
                        okay = False
                        break
                if not okay:
                    nsymm += 1
                else:
                    ufinals.append(ff)
                    ufinalsrf.append(np.concatenate(ff[:2]))
            finals = ufinals

        # construct final images
        finalimgs = []
        for caa, cab, _ in finals:
            imgs = []
            for i in range(0, nmax + 1):
                cc = Cluster(ca.n, ca.elems)
                cc.atoms = caa + (cab - caa) * i / nmax
                cc.mag = None
                if i == 0:
                    cc.mag, cc.energy = ca.mag, ca.energy
                elif i == nmax:
                    cc.mag, cc.energy = cb.mag, cb.energy
                if cc.mag is None:
                    cc.mag = 0.0
                cc.label = "CONN-%d-%d:%%d.%d:%.2f" % (self.endp[0],
                                                       self.endp[1], i, cc.mag)
                if i != 0 and i != nmax:
                    pcc = PreOptimization(cc,
                                          self.adjusted_short_length_factor)
                    pcc.opt()
                    cc = pcc.traj[-1]
                imgs.append(cc)
            finalimgs.append(imgs)
        return finalimgs, [
            self.endp[0], self.endp[1],
            len(finalimgs), ntrial, nshort, nhigh, nsymm, mdiff
        ]