Esempio n. 1
0
def strain_operation():
    structs, fnames = read_structures()
    multi_structs(structs, fnames)
    for struct in structs:
        if isinstance(struct, Molecule):
            print(
                "cleave operation is only supported for periodic structure, skip !!"
            )
    label.input
    print('input the strain component like :')
    print("0.01")
    print("it means aplly a strain of 1% along all directions")
    print("or")
    print("0.01 0.0 0.0")
    print("it means apply a strain of 1% along the x direction")
    print("or")
    print("0.01:0.03:5 0.0 0.0")
    print("it means to devide strain range into 5 parts")
    wait_sep()
    strain_str = wait()
    if strain_str == "0":
        return None
    tmp_list = strain_str.split(" ")
    if len(tmp_list) == 1:
        strain = [[float(tmp_list[0]), float(tmp_list[0]), float(tmp_list[0])]]
    elif len(tmp_list) == 3 and not ":" in strain_str:
        strain = [[float(x) for x in tmp_list]]
    elif len(tmp_list) == 3 and strain_str.count(":") % 2 == 0:
        tmp1 = [float(x) for x in tmp_list[0].split(":")]
        tmp2 = [float(x) for x in tmp_list[1].split(":")]
        tmp3 = [float(x) for x in tmp_list[2].split(":")]
        strain = []
        if len(tmp1) == 3:
            x_range = np.linspace(tmp1[0], tmp1[1], int(tmp1[2]))
        else:
            x_range = tmp1

        if len(tmp2) == 3:
            y_range = np.linspace(tmp2[0], tmp2[1], int(tmp2[2]))
        else:
            y_range = tmp2
        if len(tmp3) == 3:
            z_range = np.linspace(tmp3[0], tmp3[1], int(tmp3[2]))
        else:
            z_range = tmp3
        for ix in x_range:
            for iy in y_range:
                for iz in z_range:
                    strain.append([ix, iy, iz])
    else:
        print("Unknow format!!!")
        goto.input
    generate_strain_structure(structs, fnames, strain)
    return True
Esempio n. 2
0
def get_conventional_cell():
    structs, fnames = read_structures()
    multi_structs(structs, fnames)
    for struct, fname in zip(structs, fnames):
        sepline(ch='conventional  cell', sp='-')
        ast = SpacegroupAnalyzer(struct)
        conv_st = ast.get_conventional_standard_structure()
        print(conv_st)
        sepline()
        print('save to ' + NAME + '_convention_' + fname + '.vasp')
        conv_st.to(filename=NAME + '_conventional_' + fname + '.vasp',
                   fmt='poscar')
        sepline()
    return True
Esempio n. 3
0
def get_primitive_cell():
    structs, fnames = read_structures()
    multi_structs(structs, fnames)
    for struct, fname in zip(structs, fnames):
        sepline(ch='Primitive Cell', sp='-')
        ast = SpacegroupAnalyzer(struct)
        prim_st = ast.find_primitive()
        print(prim_st)
        sepline()
        print('save to ' + NAME + '_primitive_' + fname + '.vasp')
        prim_st.to(filename=NAME + '_primitive_' + fname + '.vasp',
                   fmt='poscar')
        sepline()
    return True
Esempio n. 4
0
def structure_symmetry():
    structs, fnames = read_structures()
    multi_structs(structs, fnames)
    for struct, fname in zip(structs, fnames):
        if isinstance(struct, Structure):
            sa = SpacegroupAnalyzer(struct)
            print("file name: {}".format(fname))
            print("{} : {}".format('Structure Type', 'periodicity'))
            print("{} : {}".format('Lattice Type', sa.get_lattice_type()))
            print("{} : {}".format('Space Group ID',
                                   sa.get_space_group_number()))
            print("{} : {}".format('International Symbol',
                                   sa.get_space_group_symbol()))
            print("{} : {}".format('Hall Symbol', sa.get_hall()))
            sepline()
        if isinstance(struct, Molecule):
            print("file name: {}".format(fname))
            sa = PointGroupAnalyzer(struct)
            print("{} : {}".format('Structure Type', 'non-periodicity'))
            print("{} : {}".format('International Symbol',
                                   ast.get_pointgroup()))
    return True
Esempio n. 5
0
def covert_operation():
    structs, fnames = read_structures()
    if structs is None:
        return None
    multi_structs(structs, fnames)
    print('input the target file format')
    print("supported format: vasp lammps xsf cif nc json yaml xyz ...")
    print("for more information see ASE and Pymatgen manual.")
    wait_sep()
    fmt = wait()

    flag = True
    if fmt.lower() == 'vasp':
        fmt = 'poscar'

    for struct, fname in zip(structs, fnames):
        filename = NAME + '_' + fname.lower() + '.' + fmt

        if "POSCAR" in fname and flag:
            # it is a bug in pymatgen
            print("The string POSCAR in filename will be replaced by poscar")
            flag = False

        if fmt == 'lammps':
            system = structure2system(struct)
            system.to_lammps_lmp(filename)
            continue

        try:
            print("Write {0:20s} {1:s}".format(fname, 'Pymatgen:Struture'))
            struct.to(fmt, filename)
        except:
            print("Write {0:20s} {1:s} ".format(fname, 'Atoms:Atoms'))
            atoms = pmg2ase(struct)
            write(filename)
    return True
Esempio n. 6
0
def cleave_operation(choice):
    # cleava surface
    structs,fnames=read_structures()
    multi_structs(structs,fnames)
    for struct in structs:
        if isinstance(struct,Molecule):
           print("cleave operation is only supported for periodic structure, skip !!")
    if choice=="1":
        print("Input the miller index, minimum size in angstroms of layers containing atomssupercell")
        print("and Minimize size in angstroms of layers containing vacuum like this:")
        print('1 0 0 | 5 | 5')
        print('it means miller index is [1,0,0]')
        print("min_slab_size is 5 Ang ")
        print("min_vacum_size is 5 Ang ")
        print("or like this : ")
        print('2 | 5 | 5')
        print('it will generate all slab with miller index less than 2')
        wait_sep()
        in_str=wait()
        len_para=len(in_str.split('|')[0].split())
        if len_para==3:
           tmp_list=in_str.split('|')
           miller_index=[int(x) for x in tmp_list[0].strip().split() ]
           min_slab_size=float(tmp_list[1])
           min_vac_size=float(tmp_list[2])
           generate_selected_slab(structs,fnames,miller_index,min_slab_size,min_vac_size)
           return True
        elif len_para==1:
           tmp_list=in_str.split('|')
           max_index=int(tmp_list[0])
           min_slab_size=float(tmp_list[1])
           min_vac_size=float(tmp_list[2])
           generate_all_slab(structs,fnames,max_index,min_slab_size,min_vac_size)
           return True
        else:
           print("unknow format")
           return None
 
    #cleave sphere
    elif choice=="2":
        print("Input the center atom index, sphere radius and vacuum layer thickness")
        print('1 3.5 15')
        print('it means the sphere will be selected according to the 1st atom')
        print("with the radius equals 5Ang, and vacuum layer thickness is 15 Ang")
        wait_sep()
        in_str=wait()
        para=in_str.split()
        center_atom=int(para[0])-1 
        radius=float(para[1])
        vacuum=float(para[2])
        generate_shell(structs,fnames,center_atom,radius,shell=None,vacuum=vacuum)
        return True

    #cleave shell
    elif choice=="3":
        print("Input the center atom index, start radius, shell thickness and")
        print("vacuum layer thickness")
        print('1 5 10  15')
        print('it means the ball shell will be selected according to the 1st atom')
        print("with the 5< r <15Ang, and vacuum layer thickness is 15 Ang")
        wait_sep()
        in_str=""
        while in_str=="":
           in_str=input().strip()
        para=in_str.split()
        center_atom=int(para[0])-1 
        radius=float(para[1])
        shell=float(para[2])
        vacuum=float(para[3])
        generate_shell(structs,fnames,center_atom,radius,shell=shell,vacuum=vacuum)
        return True

    else:
        print("unkown choice")
        return None
Esempio n. 7
0
def build_operation(choice):
    assert choice in ["1", "2", "3"]
    if choice == "1":
        structs, fnames = read_structures()
        multi_structs(structs, fnames)
        wait_sep()
        tip = """
Several options are available:

a. A full 3x3 scaling matrix defining the linear combination
   the old lattice vectors. E.g., 2 1 0  0 1 0  0 0 3
   generates a new structure with lattice vectors a' =
   2a + b, b' = 3b, c' = c where a, b, and c are the lattice
   vectors of the original structure.
b. An sequence of three scaling factors. E.g., 2 1 1
   specifies that the supercell should have dimensions 2a x b x
   c.
c. A number, which simply scales all lattice vectors by the
   same factor.
        """
        print(tip)
        wait_sep()
        in_str = wait()
        scaling_list = [int(x) for x in in_str.split()]
        print("scaling list:")
        print(scaling_list)
        for struct, fname in zip(structs, fnames):
            if len(scaling_list) == 1:
                scales = scaling_list[0]
                sufix = [scales]
            elif len(scaling_list) == 3:
                scales = scaling_list
            elif len(scaling_list) == 9:
                scales = [
                    scaling_list[0:3], scaling_list[3:6], scaling_list[6:9]
                ]
            struct_cp = struct.copy()
            struct_cp.make_supercell(scales)
            fname = 'maptool_SC_' + fname + '.vasp'
            struct_cp.to(filename=fname, fmt='poscar')
        return True
    elif choice == "2":
        print('Only support for CNT now !')
        print('Input the n and m for tube')
        print('Paramter format, i.e. :')
        print('3 3')
        wait_sep()
        in_str = wait()
        m, n = [int(i) for i in in_str.split()]
        atoms = nanotube(m, n, vacuum=15)
        struct = ase2pmg(atoms)
        struct.to('POSCAR', 'CNT_' + str(m) + '-' + str(n) + '.vasp')
        return True
    else:
        data = {
            'max_index': 2,
            'min_vacum': 20,
            'min_slab': 8,
            'repeat': [3, 3, 1]
        }

        def read_adsorb_config(filename):
            with open(filename, 'r') as f:
                datas = f.readlines()
            list_data = []
            for i in range(len(datas)):
                list_data.append(
                    datas[i][0:datas[i].find('#')].strip().split('='))

            defined_keys = [
                'method', 'crystal', 'molecule', 'max_index', 'min_vacum',
                'min_slab', 'repeat'
            ]
            data_dict = {}
            for key in defined_keys:
                for li in list_data:
                    if key in li[0]:
                        data_dict[key] = li[1]

            data_dict['method'] = int(data_dict.get('method').strip())
            data_dict['crystal'] = data_dict.get('crystal').strip()
            data_dict['molecule'] = data_dict.get('molecule').strip()
            data_dict['max_index'] = int(
                data_dict.get('max_index', '1').strip())
            data_dict['min_vacum'] = int(
                data_dict.get('min_vacum', '15').strip())
            data_dict['min_slab'] = int(data_dict.get('min_slab', '5').strip())
            data_dict['repeat'] = [
                int(x)
                for x in data_dict.get('repeat', '1 1 1').strip().split()
            ]
            return data_dict

        def proc_adsorb(cryst, mol, data):
            if data['method'] == 1:
                asf_slab = AdsorbateSiteFinder(cryst)
                ads_sites = asf_slab.find_adsorption_sites()
                ads_structs = asf_slab.generate_adsorption_structures(
                    mol, repeat=data['repeat'])
                for i in range(len(ads_structs)):
                    ads_struct = ads_structs[i]
                    try:
                        miller_str = [str(j) for j in cryst.miller_index]
                    except:
                        miller_str = ['adsorb']
                    filename = '_'.join(miller_str) + '-' + str(i) + '.vasp'
                    ads_struct.to(filename=filename, fmt='POSCAR')
            else:
                slabs = generate_all_slabs(cryst,
                                           max_index=data['max_index'],
                                           min_slab_size=data['min_slab'],
                                           min_vacuum_size=data['min_vacum'],
                                           lll_reduce=True)
                for slab in slabs:
                    asf_slab = AdsorbateSiteFinder(slab)
                    ads_sites = asf_slab.find_adsorption_sites()
                    ads_structs = asf_slab.generate_adsorption_structures(
                        mol, repeat=data['repeat'])
                    for i in range(len(ads_structs)):
                        ads_struct = ads_structs[i]
                        miller_str = [str(j) for j in slab.miller_index]
                        filename = 'adsorb' + '_'.join(miller_str) + '-' + str(
                            i) + '.vasp'
                        ads_struct.to(filename=filename, fmt='POSCAR')

        filename = 'adsorb.cfg'
        if os.path.exists(filename):
            data = read_adsorb_config(filename)
            assert data['method'] in [1, 2]
            cryst = read_structures_from_file(data['crystal'])
            mol = read_structures_from_file(data['molecule'])
            proc_adsorb(cryst, mol, data)
        else:
            print('your choice ?')
            print('{} >>> {}'.format('1', 'read slab from file'))
            print('{} >>> {}'.format('2', 'build slab by bulk'))
            wait_sep()
            in_str = wait()
            choice = int(in_str)
            assert choice in [1, 2]
            data['method'] = choice
            tips = """\
Input the structure filename of molecule and substrate
The first file should be molecule and 2nd for crystal
supported structure format: xsf .vasp POSCAR .nc .json .xyz ...
paramter format, i.e. :
mol.xyz POSCAR"""
            structs, fnames = read_structures(tips)

            mol = structs[0]
            mlog.info("read mol from %s" % (fnames[0]))
            mlog.info(mol)
            assert isinstance(mol,
                              Molecule), "the first file should be molecule"
            cryst = structs[1]
            mlog.info("read crystal from %s" % (fnames[1]))
            mlog.info(cryst)
            assert isinstance(cryst,
                              Structure), "the second file should be crystal"
            proc_adsorb(cryst, mol, data)

        return True
Esempio n. 8
0
def twod_operation(choice):
    assert choice in ["1", "2", "3", "4", "5", "6", "7"]
    if choice == "1":
        structs, fnames = read_structures()
        multi_structs(structs, fnames)
        print("input the supercell supercell factor")
        print('for x direction can be: 10 1 1')
        print('for y direction can be: 1 10 1')
        wait_sep()
        scale_str = wait()
        supercell = [int(x) for x in scale_str.split()]
        if (len(supercell) != 3):
            print('Unknown format')
            os._exit(0)

        if supercell[0] >= supercell[1]:
            direction = 0  # for x direction
        else:
            direction = 1  # for y direction

        print("input the strain range")
        print("example: 0.02:0.1:10 ")
        wait_sep()
        strain_str = wait()
        tmp = [float(x) for x in strain_str.split(":")]
        strain = []
        if len(tmp) == 3:
            strain_range = np.linspace(tmp[0], tmp[1], int(tmp[2]))
        else:
            print("Unknown format")
            os._exit(0)
        print("input the index of atom need to be fixed")
        print("example: 1 10 11 20 ")
        print("0 means fix the atom automatically")
        wait_sep()
        atom_index_str = wait()
        if len(atom_index_str.split()) > 1:
            atom_index = [int(x) for x in atom_index_str.split("")]
            auto_fix = False
        else:
            atom_index = [int(atom_index_str)]
            auto_fix = True
        ripple(structs, fnames, supercell, direction, strain_range, atom_index,
               auto_fix)
        return True

    elif choice == "2":
        structs, fnames = read_structures()
        multi_structs(structs, fnames)
        print("Input the number of layers")
        wait_sep()
        in_str = wait()
        layer_number = int(in_str)

        print("Input the layer distance")
        wait_sep()
        in_str = wait()
        layer_distance = float(in_str)
        multi_layers(structs, fnames, layer_number, layer_distance)

        return True

    elif choice == "3":
        """
          splitting sep
          .... .  .  .   .   .
        """
        structs, fnames = read_structures()
        if len(structs) > 1:
            print("Splitting dont support multi-structures!!!")
            os._exit(0)
        atom_index, in_str = atom_selection(structs[0])
        print("Input the splitting distance, 10 Ang is enough!")
        wait_sep()
        in_str = wait()
        SplitDistance = float(in_str)
        print("Numbers of splitting site, 50 sites are enough!")
        wait_sep()
        in_str = wait()
        NumberSplitSite = int(in_str)
        split(structs,
              fnames,
              atom_index,
              in_str,
              SplitDistance,
              NumberSplitSite,
              ProperDist=3.5,
              DenseFrac=0.75)
        return True

    elif choice == "4":
        structs, fnames = read_structures()
        multi_structs(structs, fnames)
        print("Input the new value of vacuum layer thickness")
        wait_sep()
        in_str = wait()
        wait_sep()
        nvac_layer_thickness = float(in_str)
        resize_vacuum(structs, fnames, nvac_layer_thickness)
        return True

    elif choice == "5":
        structs, fnames = read_structures()
        multi_structs(structs, fnames)
        for struct, fname in zip(structs, fnames):
            new_struct = move_to_zcenter(struct)
            new_struct.to(filename='z-center_' + fname + '.vasp', fmt='poscar')
        return True

    elif choice == 6:
        structs, fnames = read_structures()
        multi_structs(structs, fnames)
        try:
            import sympy
        except ImportError:
            print("You have to install sympy module")
            os._exit(0)

        print("Input the elastic of material by order : C11 C12 C22 C66")
        wait_sep()
        in_str = ""
        while in_str == "":
            in_str = input().strip().split()
        elastic_constant = [float(x) for x in in_str]
        if len(elastic_constant) != 4:
            print("You have to input C11 C12 C22 C66")
            return None
        C11 = elastic_constant[0]
        C12 = elastic_constant[1]
        C22 = elastic_constant[2]
        C66 = elastic_constant[3]
        print("Input applied force: e.x. 1.0 GPa nm")
        wait_sep()
        in_str = wait()
        sigma = float(in_str)
        circle_strain(structs, fnames, C11, C12, C22, C66, sigma)
        return True

    elif choice == "7":
        structs, fnames = read_structures()
        if len(structs) > 1:
            print("Constrain doesnot support multi-structures!!!")
            os._exit(0)
        atom_index, in_str = atom_selection(structs[0])
        mlog.debug("constrained atom index")
        mlog.debug(' '.join(map(str, atom_index)))
        constrain(structs, fnames, atom_index, in_str)
        return True

    elif choice == "8":
        print('your choice ?')
        print('{} >>> {}'.format('1', 'input 2D structure from local disk'))
        print('{} >>> {}'.format('2', 'get 2D structure online'))
        wait_sep()
        in_str = wait()
        _choice = int(in_str)

        if _choice == "1":
            mpid = None
            structs, fnames = read_structures()
            if len(structs) > 1:
                print("Matching dont support multi-structures!!!")
                os._exit(0)
        else:
            print("Input the mp-id for your structure")
            wait_sep()
            in_str = wait()
            mpid = in_str
            struct = None

        film, substrates = get_mp_film_substrate(mpid=mpid, struct=struct)
        df = match_substrate(film, substrates)
        dumpfn(df.to_dict(), 'substrate_' + fnames[0] + '.json', indent=4)
        #df.to_csv('substrate.csv', sep=',', header=True, index=True)
        return True
    else:
        print("Unkonw choice")
        return None
Esempio n. 9
0
def select_function(choice):
    r"""
    submenu for selecting function
    """
    # structure operation
    if choice == "a1":
        print('{} >>> {}'.format('1', 'random structure generating'))
        print('{} >>> {}'.format('2', 'random perturbation for atom index'))
        print('{} >>> {}'.format('3', 'random disturbing for lattice matrix'))
        print('{} >>> {}'.format('4', 'random disturbing for atom position'))
        your_choice()
        in_str = wait()
        if in_str == "0":
            return None
        return random_operation(in_str)

    elif choice == "a2":
        return covert_operation()

    elif choice == "a3":
        print('{} >>> {}'.format('1', 'build supercell'))
        print('{} >>> {}'.format('2', 'build nanotube'))
        print('{} >>> {}'.format('3', 'build absorption configuration'))
        your_choice()
        in_str = wait()
        if in_str == "0":
            return None
        return build_operation(in_str)

    elif choice == "a4":
        print('{} >>> {}'.format('1', 'cleave surface'))
        print('{} >>> {}'.format('2', 'cleave sphere cluster'))
        print('{} >>> {}'.format('3', 'cleave shell structure'))
        your_choice()
        in_str = wait()
        if in_str == "0":
            return None
        return cleave_operation(in_str)

    elif choice == "a5":
        return strain_operation()

    elif choice == 'a6':
        print('{} >>> {}'.format('1', 'build rippled structure'))
        print('{} >>> {}'.format('2', 'build multi-layered structure'))
        print('{} >>> {}'.format('3', 'split multi-layered structure'))
        print('{} >>> {}'.format('4', 'resize vacuum layer'))
        print('{} >>> {}'.format('5', 'center atomic-layer along z direction'))
        print('{} >>> {}'.format('6',
                                 'apply strain along different direction'))
        print('{} >>> {}'.format('7', 'constrain atom in specific range'))
        print('{} >>> {}'.format(
            '8', 'get a substrate for 2D material (online!!!)'))
        your_choice()
        in_str = wait()
        if in_str == "0":
            return None
        return twod_operation(in_str)

# structure analysis
    elif choice == "b1":
        return structure_symmetry()
    elif choice == "b2":
        return structure_finger_print()
    elif choice == "b3":
        return structures_difference()
    elif choice == "b4":
        return get_primitive_cell()
    elif choice == "b5":
        return get_conventional_cell()
    elif choice == "b6":
        return get_xrd()

# vasp in/out tools
    elif choice == "c1":
        structs, fnames = read_structures()
        if structs is None:
            return None
        multi_structs(structs, fnames)
        sepline(ch=' prepare intput files ', sp='-')
        your_choice()
        print('{} >>> {}'.format('1', 'prepare all files automatically'))
        print('{} >>> {}'.format('2', 'prepare INCAR file'))
        print('{} >>> {}'.format('3', 'prepare KPOINTS file'))
        print('{} >>> {}'.format('4', 'prepare POTCAR file'))
        label.input1
        wait_sep()
        choice = wait()

        if choice == "0":
            return None
        elif choice == "1":
            return generate_all_input(structs, fnames)
        elif choice == "2":
            return generate_incar(structs, fnames)
        elif choice == "3":
            return generate_kpoint(structs, fnames)
        elif choice == "4":
            return generate_potcar(structs, fnames)
        else:
            print("unknown choice, check the input")
            goto.input1

    elif choice == "cxx":
        sepline(ch=' summary output files ', sp='=')
        print('{} >>> {}'.format('1', 'describe OUCAR file'))
        print('{} >>> {}'.format('2', 'describe OSICAR file'))
        print('{} >>> {}'.format('3', 'describe vasprun.xml file'))
        label.input2
        wait_sep()
        choice = wait()
        if choice == "0":
            return None
        if choice == "1":
            return describe_OUTCAR()
        elif choice == "2":
            return describe_OSICAR()
        elif choice == "3":
            return describe_vasprun()
        else:
            print("unknown choice, check the input")
            goto.input2

    elif choice == "c2":
        sepline(ch=' vasp output analysis ', sp='-')
        print('{} >>> {}'.format('1 ', 'total density of states'))
        print('{} >>> {}'.format('2 ', 'projected density of states'))
        print('{} >>> {}'.format('3 ', 'band structure'))
        print('{} >>> {}'.format('4 ', 'projected band structure'))
        print('{} >>> {}'.format('5 ', 'select one band structure'))
        print('{} >>> {}'.format('6 ', 'charge density'))
        print('{} >>> {}'.format('7 ', 'spin density'))
        print('{} >>> {}'.format('8 ', 'charge density difference'))
        print('{} >>> {}'.format('9 ', 'spin density component: up/down'))
        print('{} >>> {}'.format('10', 'average charge density/potential'))
        print('{} >>> {}'.format('11', 'optics analysis'))
        print('{} >>> {}'.format('12', 'mechanical analysis'))
        print('{} >>> {}'.format('13',
                                 'ab initio molecular dynamics analysis'))
        label.input3
        wait_sep()
        choice = wait()
        if choice == "0":
            return None
        if choice == "1":
            return total_dos()
        elif choice == "2":
            return projected_dos()
        elif choice == "3":
            return band_structure()
        elif choice == "4":
            return projected_band_structure()
        elif choice == "5":
            return select_one_band_structure()
        elif choice == "6":
            return charge_density()
        elif choice == "7":
            return spin_density()
        elif choice == "8":
            return charge_density_diff()
        elif choice == "9":
            return spin_density_component()
        elif choice == "10":
            return chg_locp_average()
        elif choice == "11":
            return optics_analysis()
        elif choice == "12":
            return elastic_analysis()
        elif choice == "13":
            return aimd_analysis()
        else:
            print("unknown choice, check the input")
            goto.input3

# online exctraction
    elif choice == "e1":
        return get_mp_banddos()
    elif choice == "e2":
        return get_mp_structure()
    elif choice == "e3":
        return get_mp_properties()
    elif choice == "e4":
        return get_mp_phase_graph()
    elif choice == "e5":
        return get_oqmd_structure()
    elif choice == "88":
        os._exit(0)
    else:
        print("unknown choice, return now")
        return None