コード例 #1
0
def break_symmetry(structure,
                   atoms=['all'],
                   site=[],
                   pos=[],
                   new_kinds_names={},
                   parameterData=None):
    """
    This routine introduces different 'kind objects' in a structure
    and names them that inpgen will make different species/atomgroups out of them.
    If nothing specified breaks ALL symmetry (i.e. every atom gets their own kind)

    params: StructureData
    params: atoms: python list of symbols, exp: ['W', 'Be']. This would make for
                   all Be and W atoms their own kinds.
    params: site: python list of integers, exp: [1, 4, 8]. This would create for
                  atom 1, 4 and 8 their own kinds.
    params: pos: python list of tuples of 3, exp [(0.0, 0.0, -1.837927), ...].
                 This will create a new kind for the atom at that position.
                 Be carefull the number given has to match EXACTLY the position
                 in the structure.

    return: StructureData, a AiiDA crystal structure with new kind specification.
    """
    # TODO proper input checks?
    from aiida.common.constants import elements as PeriodicTableElements

    _atomic_numbers = {
        data['symbol']: num
        for num, data in PeriodicTableElements.iteritems()
    }

    #get all atoms, get the symbol of the atom
    #if wanted make individual kind for that atom
    #kind names will be atomsymbol+number
    #create new structure with new kinds and atoms
    #Param = DataFactory('parameter')
    symbol_count = {
    }  # Counts the atom symbol occurence to set id's and kind names right
    replace = []  # all atoms symbols ('W') to be replaced
    replace_siteN = []  # all site integers to be replaced
    replace_pos = []  #all the atom positions to be replaced
    new_parameterd = None
    struc = is_structure(structure)
    if not struc:
        print 'Error, no structure given'
        # throw error?

    cell = struc.cell
    pbc = struc.pbc
    sites = struc.sites
    #natoms = len(sites)
    new_structure = DataFactory('structure')(cell=cell, pbc=pbc)

    for sym in atoms:
        replace.append(sym)
    for position in pos:
        replace_pos.append(position)
    for atom in site:
        replace_siteN.append(atom)

    if parameterData:
        para = parameterData.get_dict()
        new_parameterd = dict(para)
    else:
        new_parameterd = {}

    for i, site in enumerate(sites):
        kind_name = site.kind_name
        pos = site.position
        kind = struc.get_kind(kind_name)
        symbol = kind.symbol
        replace_kind = False

        if symbol in replace or 'all' in replace:
            replace_kind = True
        if pos in replace_pos:
            replace_kind = True
        if i in replace_siteN:
            replace_kind = True

        if replace_kind:
            if symbol in symbol_count:
                symbol_count[symbol] = symbol_count[symbol] + 1
                symbol_new_kinds_names = new_kinds_names.get(symbol, [])
                print(symbol_new_kinds_names)
                if symbol_new_kinds_names and ((len(symbol_new_kinds_names))
                                               == symbol_count[symbol]):
                    newkindname = symbol_new_kinds_names[symbol_count[symbol] -
                                                         1]
                else:
                    newkindname = '{}{}'.format(symbol, symbol_count[symbol])
            else:
                symbol_count[symbol] = 1
                symbol_new_kinds_names = new_kinds_names.get(symbol, [])
                #print(symbol_new_kinds_names)
                if symbol_new_kinds_names and ((len(symbol_new_kinds_names))
                                               == symbol_count[symbol]):
                    newkindname = symbol_new_kinds_names[symbol_count[symbol] -
                                                         1]
                else:
                    newkindname = '{}{}'.format(symbol, symbol_count[symbol])
            #print(newkindname)
            new_kind = Kind(name=newkindname, symbols=symbol)
            new_structure.append_kind(new_kind)

            # now we have to add an atom list to parameterData with the corresponding id.
            if parameterData:
                id_a = symbol_count[
                    symbol]  #'{}.{}'.format(charge, symbol_count[symbol])
                #print 'id: {}'.format(id)
                for key, val in para.iteritems():
                    if 'atom' in key:
                        if val.get('element', None) == symbol:
                            if id_a and id_a == val.get('id', None):
                                break  # we assume the user is smart and provides a para node,
                                # which incooperates the symmetry breaking already
                            elif id_a:  # != 1: # copy parameter of symbol and add id
                                val_new = dict(val)
                                # getting the charge over element might be risky
                                charge = _atomic_numbers.get(
                                    (val.get('element')))
                                idp = '{}.{}'.format(charge,
                                                     symbol_count[symbol])
                                idp = float("{0:.2f}".format(float(idp)))
                                # dot cannot be stored in AiiDA dict...
                                val_new.update({u'id': idp})
                                atomlistname = 'atom{}'.format(id_a)
                                i = 0
                                while new_parameterd.get(atomlistname, {}):
                                    i = i + 1
                                    atomlistname = 'atom{}'.format(id_a + i)

                                symbol_new_kinds_names = new_kinds_names.get(
                                    symbol, [])
                                #print(symbol_new_kinds_names)
                                if symbol_new_kinds_names and (
                                    (len(symbol_new_kinds_names))
                                        == symbol_count[symbol]):
                                    species_name = symbol_new_kinds_names[
                                        symbol_count[symbol] - 1]
                                val_new.update({u'name': species_name})

                                new_parameterd[atomlistname] = val_new
            else:
                pass
                #TODO write basic parameter data node
        else:
            newkindname = kind_name
            if not kind_name in new_structure.get_kind_names():
                new_structure.append_kind(kind)
        new_structure.append_site(Site(kind_name=newkindname, position=pos))

    #print 'natoms: {}, nkinds: {}'.format(natoms, len(new_structure.get_kind_names()))

    if parameterData:
        para_new = ParameterData(dict=new_parameterd)
    else:
        para_new = None

    new_structure.label = structure.label
    new_structure.description = structure.description + 'more kinds, less sym'

    return new_structure, para_new
コード例 #2
0
def supercell_nwf(
    inp_structure, n_a1, n_a2, n_a3
):  #, _label=u'supercell_wf', _description=u'WF, Creates a supercell of a crystal structure x(n1,n2,n3).'):# be carefull you have to use AiiDA datatypes...
    """
    Creates a super cell from a StructureData node.
    Does NOT keeps the provanance in the database.

    :param StructureData, a StructureData node (pk, or uuid)
    :param scale: tuple of 3 AiiDA integers, number of cells in a1, a2, a3, or if cart =True in x,y,z

    :returns StructureData, Node with supercell
    """
    #print('in create supercell')
    #test if structure:
    structure = is_structure(inp_structure)
    if not structure:
        #TODO: log something
        return None
    old_cell = structure.cell
    old_a1 = old_cell[0]
    old_a2 = old_cell[1]
    old_a3 = old_cell[2]
    old_sites = structure.sites
    old_pbc = structure.pbc

    na1 = int(n_a1)
    na2 = int(n_a2)
    na3 = int(n_a3)

    #new cell
    new_a1 = [i * na1 for i in old_a1]
    new_a2 = [i * na2 for i in old_a2]
    new_a3 = [i * na3 for i in old_a3]
    new_cell = [new_a1, new_a2, new_a3]
    new_structure = DataFactory('structure')(cell=new_cell, pbc=old_pbc)

    #insert atoms
    # first create all kinds
    old_kinds = structure.kinds
    for kind in old_kinds:
        new_structure.append_kind(kind)

    #scale n_a1
    for site in old_sites:
        # get atom position
        kn = site.kind_name
        pos_o = site.position
        for j in range(na1):
            pos = [pos_o[i] + j * old_a1[i] for i in range(0, len(old_a1))]
            new_structure.append_site(Site(kind_name=kn, position=pos))

    #scale n_a2
    o_sites = new_structure.sites
    for site in o_sites:
        # get atom position
        kn = site.kind_name
        pos_o = site.position
        for j in range(1, na2):  # j=0 these sites/atoms are already added
            pos = [pos_o[i] + j * old_a2[i] for i in range(0, len(old_a2))]
            new_structure.append_site(Site(kind_name=kn, position=pos))

    #scale n_a3
    o_sites = new_structure.sites
    for site in o_sites:
        # get atom position
        kn = site.kind_name
        pos_o = site.position
        for j in range(1, na3):  # these sites/atoms are already added
            pos = [pos_o[i] + j * old_a3[i] for i in range(0, len(old_a3))]
            new_structure.append_site(Site(kind_name=kn, position=pos))

    new_structure.label = 'supercell of {}'.format(formula)
    new_structure.description = '{}x{}x{} supercell of {}'.format(
        n_a1, n_a2, n_a3, inp_structure.get_formula())
    return new_structure