Exemplo n.º 1
0
  def build(self, moleculeData=None, name=None, unit='angstrom', **kwargs):
    if moleculeData is not None:
      if type(moleculeData) is list:
        moleculeData = np.array(moleculeData)
      if len(moleculeData.shape) == 1:
        moleculeData = np.atleast_2d(moleculeData)
      self.N = moleculeData.shape[0]
      self.Z = moleculeData[:, 0]
      self.R = moleculeData[:, 1:]
      self.type_list = [qtk.Z2n(z) for z in self.Z]
      self.string = ['' for i in range(self.N)]
      if name is None:
        self.name = self.stoichiometry()
      else:
        self.name = name
    else:
      assert 'Z' in kwargs
      assert 'R' in kwargs
      Z = np.array(kwargs['Z'])
      R = np.array(kwargs['R'])
      self.N = len(Z)
      self.Z = Z
      self.R = R
      self.type_list = [qtk.Z2n(z) for z in self.Z]
      self.string = ['' for i in range(self.N)]
      self.name = self.stoichiometry()

    if unit is 'bohr':
      self.R = self.R *  0.52917721092

    return self
Exemplo n.º 2
0
 def stoichiometry(self, output='string', **kwargs):
   elements = collections.Counter(sorted(self.Z))
   data = zip(elements.keys(), elements.values())
   data.sort(key=lambda tup: tup[0])
   if output == 'dictionary' or output == 'count':
     out = {}
     for element in data:
       out[qtk.Z2n(element[0])] = element[1]
   elif output == 'string':
     out = ''
     for element in data:
       out = out + qtk.Z2n(element[0]) + str(element[1])
   return out
Exemplo n.º 3
0
 def _mutate(self, mutation):
     for m in xrange(len(mutation)):
         for i in xrange(len(mutation[m])):
             index = self.mutation_list[m][i]
             #target = self.mutation_target[m][mutation[m][i]]
             target = mutation[m][i]
             self.new_structure.Z[index] = target
             self.new_structure.type_list[index] = qtk.Z2n(target)
Exemplo n.º 4
0
 def mutateElement(self, oldZ, newZ):
   if oldZ != newZ:
     if type(oldZ) is str:
       oldZ = qtk.n2Z(oldZ)
     if type(newZ) is str:
       newZ = qtk.n2Z(newZ)
     newElem = qtk.Z2n(newZ)
     indices = []
     for i in range(self.N):
       if abs(self.Z[i] - oldZ) < 0.1:
         indices.append(i)
     self.setAtoms(indices, element=newElem)
Exemplo n.º 5
0
 def setAtoms(self, index, **kwargs):
   if type(index) is int:
     index = [index]
   if 'element' in kwargs or 'Z' in kwargs:
     for i in index:
       if 'element' in kwargs:
         if type(kwargs['element']) is str:
           Z = qtk.n2Z(kwargs['element'])
           Zn = kwargs['element']
         elif type(kwargs['element']) is int\
         or type(kwargs['element']) is float:
           Z = kwargs['element']
           Zn = qtk.Z2n(Z)
       elif 'Z' in kwargs:
         Z = kwargs['Z']
         Zn = qtk.Z2n(Z)
       self.Z[i] = Z
       self.type_list[i] = Zn
   if 'string' in kwargs:
     minZ = min(min(self.Z)-1, 0)
     for i in index:
       self.string[i] = kwargs['string']
       self.Z[i] = minZ
Exemplo n.º 6
0
def write(self, name=None):
    today = datetime.date.today()
    out = InpContent(name)
    out.write('Goedecker pseudopotential for %s\n' % \
      qtk.Z2n(self.param['Z']))
    out.write('   %2d  %2d  %s ! Z, ZV, date(ddmmyy)\n' %\
      (self.param['Z'], self.param['ZV'], today.strftime('%d%m%y')))
    out.write('   %d  %s  2 0 2002 0  ! xc:%s\n' %\
      (type_dict[self.setting['type']],
       xc_dict[self.param['xc']],
       self.param['xc']))
    out.write('   %12.8f %3d' % (self.param['r_loc'], self.param['Cn']))
    for i in range(self.param['Cn']):
        out.write(' % 12.8f' % self.param['Ci'][i])
    out.write(' ! rloc, #C, C[i]')
    out.write('\n  %d\n' % self.param['l_max'])
    for i in range(len(self.param['r_nl'])):
        r_nl = self.param['r_nl'][i]
        h_ij = self.param['h_ij'][i]
        out.write('   %12.8f %3d' % (r_nl, len(h_ij)))
        if len(h_ij) > 0:
            for j in range(len(h_ij)):
                if j > 0:
                    out.write('%19s' % '')
                for k in range(j, len(h_ij)):
                    out.write(' % 12.8f' % h_ij[j][k])
                if j == 0:
                    out.write(' ! h_ij\n')
                else:
                    out.write('\n')
        else:
            out.write(' % 12.8f\n' % 0)
    if self.param['r_nl'] > 0:
        for j in range(len(h_ij)):
            out.write('%19s' % '')
            for k in range(j, len(h_ij)):
                out.write(' % 12.8f' % 0.0)
            if j == 0:
                out.write(' ! abinit k_ij\n')
            else:
                out.write('\n')
    if self.setting['type'] == 'nlcc':
        out.write('   %12.8f     %12.8f' %\
          (self.param['rcore'], self.param['qcore']))
    out.close()
Exemplo n.º 7
0
    def ESP(self, coord=None, **kwargs):
        """
    method for electron density
    Note: CUBE file is assumed to be orthorohmbic
    """
        data = self.data
        grid = self.grid
        if 'molecule' not in kwargs:
            mol = self.molecule
        else:
            try:
                mol = copy.deepcopy(qtk.toMolecule(kwargs['molecule']))
            except:
                qtk.exit("error when loading molecule:%s" % \
                         str(kwargs['molecule']))
        N = mol.N

        Q = self.integrate()
        Z_sum = sum(mol.Z)
        ne_diff = abs(Q - Z_sum)
        ve_diff = abs(Q - mol.getValenceElectrons())
        if min(ne_diff, ve_diff) > 1E-2:
            qtk.warning("charge not conserved... ESP is wrong!")
            qtk.warning("charge integrate to %.2f, " % Q + \
                        "while nuclear charge adds to %.2f" % Z_sum)
        if ve_diff < ne_diff:
            Z = [qtk.n2ve(qtk.Z2n(z)) for z in mol.Z]
            Z = np.array(Z).reshape(N, 1)
        else:
            Z = mol.Z.reshape(N, 1)
        structure = np.hstack([Z, mol.R * 1.889725989])
        if coord is not None:
            x, y, z = np.array(coord) * 1.889725989
            V = ESP_c.esp_point(grid, structure, data, x, y, z)
            return V
        else:
            qtk.warning("known issue: unidentifed memory leak")
            out = copy.deepcopy(self)
            out.molecule = mol
            out.data = np.nan_to_num(ESP_cube_c.esp_cube(
                grid, structure, data))
            return out
Exemplo n.º 8
0
 def addAtoms(self, element, coord):
   if type(element) is not list:
     element = [element]
     coord = [coord]
   if type(element[0]) is not str:
     element = [qtk.Z2n(int(i)) for i in element]
   Z = list(self.Z)
   for i in range(len(element)):
     #e = getattr(pt, element[i].title())
     e = qtk.element[element[i]]
     r = coord[i]
     if self.N == 0:
       self.R = np.array(r)
     else:
       self.R = np.vstack([self.R, np.array(r)])
     self.N = self.N + 1
     self.type_list.append(e.symbol)
     Z.append(e.number)
     self.string.append('')
   self.Z = np.array(Z)
   if self.N == 1:
     self.R = np.array([self.R])
Exemplo n.º 9
0
    def getMO(self, fchk):
        self.program = 'gaussian'
        fchkfile = open(fchk)
        fchk = fchkfile.readlines()
        self.basis_name = filter(None, fchk[1].split(' '))[2]

        def basisList(L):
            N_dict = {4: 'g', 5: 'h', 6: 'k'}
            orbital = ['x', 'y', 'z']
            base = [2 for _ in range(L)]

            out = []
            for n in range(L + 1):
                b = copy.deepcopy(base)
                for i in range(n):
                    b[i] = 0
                orb = N_dict[L] + ''.join([orbital[j] for j in b])
                out.append(orb)
                for i in range(n, L):
                    b[i] = 1
                    orb = N_dict[L] + ''.join([orbital[j] for j in b])
                    out.append(orb)

            return out

        basis_list = [
            ['s'],
            ['px', 'py', 'pz'],
            ['dxx', 'dyy', 'dzz', 'dxy', 'dxz', 'dyz'],
            [
                'fxxx', 'fyyy', 'fzzz', 'fxyy', 'fxxy', 'fxxz', 'fxzz', 'fyzz',
                'fyyz', 'fxyz'
            ],
            basisList(4),
            basisList(5),
        ]

        def readFchk(flag, type=float):
            flagStr = filter(lambda x: flag in x, fchk)[0]
            n_entry = int(filter(None, flagStr.split(' '))[-1])
            ind = fchk.index(flagStr) + 1
            if type is float:
                factor = 5
            elif type is int:
                factor = 6
            n_lines = n_entry / factor + 1
            if not n_entry % factor: n_lines = n_lines - 1
            data = []
            for i in range(ind, ind + n_lines):
                dList = list(
                    np.array(filter(None, fchk[i].split(' '))).astype(type))
                data.extend(dList)
            return data, n_entry

        self.Z, self.N = readFchk('Nuclear charges')
        self.type_list = [qtk.Z2n(z) for z in self.Z]
        _types, _n_shell = readFchk('Shell types', int)
        _exp, _nfn = readFchk('Primitive exponents')
        _cef = readFchk('Contraction coefficients')[0]
        _coord, _test = readFchk('Coordinates of each shell')
        _ng = readFchk('Number of primitives per shell', int)[0]
        _coord = np.array(_coord).reshape([_n_shell, 3])
        self.mo_eigenvalues, self.n_mo = \
          readFchk('Alpha Orbital Energies')
        _mo, _dim = readFchk('Alpha MO coefficients')
        try:
            self.mo_eigenvalues_beta, _ = \
              readFchk('Beta Orbital Energies')
            _mob, _dimb = readFchk('Beta MO coefficients')
        except:
            _mob, _dimb = None, None
            self.mo_eigenvalues_beta = None
        self.n_ao = _dim / self.n_mo
        self.n_basis = self.n_ao
        self.mo_vectors = np.array(_mo).reshape([self.n_mo, self.n_ao])
        if self.mo_eigenvalues_beta is not None:
            self.mo_vectors_beta = np.array(_mob).reshape(
                [self.n_mo, self.n_ao])

        _map = readFchk('Shell to atom map', int)[0]
        _map_coord = list(np.diff(_map))
        _map_coord.insert(0, 1)
        _R_ind = [i for i in range(_n_shell) if _map_coord[i] > 0]
        self.R_bohr = np.array([_coord[i] for i in _R_ind])
        self.R = self.R_bohr / 1.88972613
        _neStr = filter(lambda x: 'Number of electrons' in x, fchk)[0]
        _ne = float(filter(None, _neStr.split(' '))[-1])
        self.occupation = []
        warned = False
        for i in range(self.n_mo):
            if i < _ne / 2 - 1:
                self.occupation.append(2.0)
            elif i >= _ne / 2 - 1 and i < _ne / 2:
                if abs(_ne % 2) < 1E-5:
                    self.occupation.append(2.0)
                else:
                    self.occupation.append(_ne % 2)
            else:
                self.occupation.append(0.0)

        tmp = 0
        shift = 0
        self.basis = []
        for i in range(_n_shell):
            _ind = _map[i] - 1
            bfn_base = {}
            bfn_base['index'] = i
            bfn_base['center'] = _coord[i]
            bfn_base['atom'] = self.type_list[_ind]

            exp = []
            cef = []
            for g in range(_ng[i]):
                exp.append(_exp[i + shift + g])
                cef.append(_cef[i + shift + g])
            shift = shift + _ng[i] - 1

            if _types[i] == 0:
                l_max = 1
                blist = ['s']
            else:
                if _types[i] > 0:
                    l_max = sum(range(_types[i] + 2))
                    blist = basis_list[_types[i]]
                else:
                    l_max = 2 * abs(_types[i]) + 1
                    blist = ['D0' for _ in range(l_max)]
                    if not warned:
                        qtk.warning("sp shell or spherical basis are used, " +\
                          "some functions will not work")
                        warned = True

            for l in range(l_max):
                bfn = copy.deepcopy(bfn_base)
                bfn['exponents'] = copy.deepcopy(exp)
                bfn['coefficients'] = copy.deepcopy(cef)
                bfn['type'] = blist[l]
                tmp = tmp + 1
                self.basis.append(bfn)
        self.basisFormat()
Exemplo n.º 10
0
        def getChild():
            child = {}
            for key in parent1.iterkeys():
                if key == 'mutation':
                    # implementation for element_count constraints
                    if self.element_count:
                        constraint_list = []
                        constraint_keys = []

                        # tool to constuct list
                        def _list_append(mcoord, i_list, Zc):
                            for g in range(len(mcoord)):
                                grp = mcoord[g]
                                for i in range(len(grp)):
                                    Z_p = grp[i]
                                    if Z_p == Zc:
                                        i_list.append((g, i))

                        # construct mutation list
                        for elem in self.element_count.iterkeys():
                            i_list = []
                            _Z = qtk.n2Z(elem)
                            _list_append(parent1['mutation'], i_list, _Z)
                            _list_append(parent2['mutation'], i_list, _Z)
                            constraint_list.append(i_list)
                            constraint_keys.append(elem)

                        while True:
                            selected_list = []
                            selected_coord = {}
                            consistant = True
                            for i in range(len(constraint_list)):
                                ind_location = constraint_list[i]
                                random.shuffle(ind_location)
                                elem = qtk.n2Z(constraint_keys[i])
                                _count = self.element_count[
                                    constraint_keys[i]][0]
                                _end = _count
                                while len(set(ind_location[:_end])) < _count:
                                    _end += 1
                                _new = list(set(ind_location[:_end]))
                                to_select = copy.deepcopy(selected_list)
                                to_select.extend(_new)
                                if len(set(to_select)) == \
                                len(selected_list) + len(_new):
                                    selected_list.extend(_new)
                                    for coord in _new:
                                        selected_coord.update({coord: elem})
                                    consistant = consistant & True
                                else:
                                    consistant = False
                            child_ind = []
                            for g in range(len(parent1['mutation'])):
                                child_list = []
                                for i in range(len(parent1['mutation'][g])):
                                    if selected_coord.has_key((g, i)):
                                        child_list.append(selected_coord[(g,
                                                                          i)])
                                    else:
                                        candidate = []
                                        A1 = qtk.Z2n(parent1['mutation'][g][i])
                                        A2 = qtk.Z2n(parent2['mutation'][g][i])
                                        if not self.element_count.has_key(A1):
                                            candidate.append(qtk.n2Z(A1))
                                        if not self.element_count.has_key(A2):
                                            candidate.append(qtk.n2Z(A2))
                                        if len(candidate) == 0:
                                            consistant = False
                                        else:
                                            child_list.append(
                                                random.choice(candidate))
                                child_ind.append(child_list)
                            if consistant:
                                break
                        for g in range(len(parent1['mutation'])):
                            for i in range(len(parent1['mutation'][g])):
                                if not selected_coord.has_key((g, i)):
                                    if random.random() < mutation_rate:
                                        child_ind[g][i] = random.choice(\
                                          self.mutation_target[g])
                                        elem = qtk.Z2n(child_ind[g][i])
                                        if self.element_count.has_key(elem):
                                            coord = random.choice([tupl for tupl,targ
                                              in selected_coord.iteritems()\
                                              if targ == qtk.n2Z(elem)])
                                            del selected_coord[coord]
                                            selected_coord.update({
                                                (g, i):
                                                qtk.n2Z(elem)
                                            })
                                            [gc, ic] = list(coord)
                                            new_targ = random.choice([z for z in \
                                                        self.mutation_target[gc]\
                                                        if not self.element_count\
                                                        .has_key(qtk.Z2n(z))])
                                            child_ind[gc][ic] = new_targ
                        child.update({'mutation': child_ind})

                    else:
                        child_mut = []
                        for i in range(len(parent1[key])):
                            # mix two parent
                            grp = parent1[key][i]
                            index = range(len(grp))
                            random.shuffle(index)
                            ind1 = index[:len(index) / 2]
                            if len(index) % 2 == 0:
                                ind2 = index[len(index) / 2:]
                                append = -1
                            else:
                                ind2 = index[len(index) / 2:-1]
                                append = index[-1]
                            new = [parent1[key][i][ind] for ind in ind1]
                            new.extend([parent2[key][i][ind] for ind in ind2])
                            if append >= 0:
                                if random.random() >= 0.5:
                                    new.append(parent1[key][i][append])
                                else:
                                    new.append(parent2[key][i][append])
                            # mutation, loop through each element
                            for j in range(len(new)):
                                if random.random() < mutation_rate:
                                    mut_target = [tar \
                                      for tar in self.mutation_target[i]\
                                      if tar != new[j]]
                                    new[j] = random.choice(mut_target)
                            child_mut.append(new)
                        child.update({'mutation': child_mut})
                else:
                    qtk.exit("ccs mate function is not yet implemented for "\
                             + key)
            return child
Exemplo n.º 11
0
  def findBonds(self, ratio=setting.bond_ratio, **kwargs):
    del self.segments
    del self.bond_types
    self.segments = []
    self.bond_types = {}
    if 'no_report' not in kwargs or not kwargs['no_report']:
      qtk.report("Molecule", 
                 "finding bonds with cutoff ratio", 
                 ratio)
    def to_graph(l):
      G = networkx.Graph()
      for part in l:
        # each sublist is a bunch of nodes
        G.add_nodes_from(part)
        # it also imlies a number of edges:
        G.add_edges_from(to_edges(part))
      return G
    
    def to_edges(l):
      """ 
      treat `l` as a Graph and returns it's edges 
      to_edges(['a','b','c','d']) -> [(a,b), (b,c),(c,d)]
      """
      it = iter(l)
      last = next(it)
    
      for current in it:
        yield last, current
        last = current 
    itr = 0
    bond_list = []
    bonded = [False for i in range(self.N)]
    for i in xrange(self.N):
      for j in xrange(i+1, self.N):
        d_ij = np.linalg.norm(self.R[i,:] - self.R[j,:])
        atom_i = getattr(pt, self.type_list[i])
        atom_j = getattr(pt, self.type_list[j])
        Ri = atom_i.covalent_radius + \
             atom_i.covalent_radius_uncertainty
        Rj = atom_j.covalent_radius + \
             atom_j.covalent_radius_uncertainty
        Dij = (Ri+Rj) * float(ratio)
        if d_ij < Dij:
          bonded[i] = True
          bonded[j] = True
          if self.Z[i] < self.Z[j]:
            atom_begin = self.Z[i]
            atom_end = self.Z[j]
            index_begin = i
            index_end = j
          else:
            atom_begin = self.Z[j]
            atom_end = self.Z[i]
            index_begin = j
            index_end = i
          self.bonds[itr] = {'atom_begin'  : atom_begin,
                             'index_begin' : index_begin,
                             'atom_end'    : atom_end,
                             'index_end'   : index_end,
                             'length'      : d_ij}
          bond_list.append([i, j])
          type_begin = qtk.Z2n(atom_begin)
          type_end   = qtk.Z2n(atom_end)
          bond_table = qtk.data.elements.bond_table
          bond_keys = []
          bond_keys = [
            type_begin + _ + type_end for _ in ['-', '=', '#']
          ]
          try:
            bond_type_ind = np.argmin(
              abs(
                np.array([
                          bond_table[k][0] for k in bond_keys
                          if k in bond_table.keys()
                         ]) - d_ij
              )
            )
          except Exception as _e:
            qtk.warning(
              "error while processing bond" +\
              str(bond_keys) + "with error message %s" % str(_e))
            bond_type_ind = -1
          bond_type = bond_keys[bond_type_ind]
          self.bonds[itr]['name'] = bond_type
          try:
            bond_energy = \
              bond_table[bond_keys[bond_type_ind]][1] * \
              qtk.convE(1, 'kj-kcal')[0]
          except:
            bond_energy = np.nan
          self.bonds[itr]['energy'] = bond_energy
          if np.isnan(bond_energy):
            qtk.warning("Non-tabliated covalent bond %s" % bond_type)
          if bond_type in self.bond_types:
            self.bond_types[bond_type] += 1
          else:
            self.bond_types[bond_type] = 1
          itr += 1

    segments = list(connected_components(to_graph(bond_list)))
    for s in range(len(segments)):
      segment = list(segments[s])
      new_mol = self.getSegment(segment, **kwargs)
      ns = len(self.segments)
      new_mol.name = new_mol.name + '_%d' % ns
      self.segments.append(new_mol)
    for s in [i for i in range(self.N) if not bonded[i]]:
      segment = [s]
      new_mol = self.getSegment(segment, **kwargs)
      ns = len(self.segments)
      new_mol.name = new_mol.name + '_%d' % ns
      self.segments.append(new_mol)