Exemplo n.º 1
0
def ChargeMomentOfInertia(picklestruct):
    SPA = psa.SpacegroupAnalyzer(picklestruct)
    picklestruct = SPA.get_conventional_standard_structure()
    Rcm = CenterofMass(picklestruct)
    #fractional coords
    I = 0
    for site in picklestruct.sites:
        elemCharge = site.specie.max_oxidation_state
        coords = site._fcoords
        dist = coords - Rcm
        I += elemCharge * np.dot(dist, dist)
    return I
Exemplo n.º 2
0
def MassMomentOfInertia(picklestruct):
    SPA = psa.SpacegroupAnalyzer(picklestruct)
    picklestruct = SPA.get_conventional_standard_structure()
    Rcm = CenterofMass(picklestruct)
    #fractional coords
    I = 0
    for site in picklestruct.sites:
        Mass = site.specie.data['Atomic mass']
        coords = site._fcoords
        dist = coords - Rcm
        I += Mass * np.dot(dist, dist)
    return I
Exemplo n.º 3
0
def CenterofMass(picklestruct):
    '''
    centerofmass in terms of fractional coordinates
    :param picklestruct:
    :return:
    '''
    symmetryfinder = psa.SpacegroupAnalyzer(picklestruct)
    numerator = np.array([0.0, 0.0, 0.0])
    denominator = list()
    for sites in picklestruct.sites:
        mass = sites.specie.data['Atomic mass']
        cellPosition = sites.frac_coords
        #normalized
        numerator += cellPosition * mass
        denominator.append(mass)
    return numerator / (np.mean(denominator))
Exemplo n.º 4
0
def structure_symmetry():
    if is_pbc():
        struct = readstructure(crystal=True, molecule=False)
        ast = analyzer.SpacegroupAnalyzer(struct)
        print("{} : {}".format('Structure Type', 'periodicity'))
        print("{} : {}".format('Lattice Type', ast.get_lattice_type()))
        print("{} : {}".format('Space Group ID', ast.get_space_group_number()))
        print("{} : {}".format('International Symbol',
                               ast.get_space_group_symbol()))
        print("{} : {}".format('Hall Symbol', ast.get_hall()))
        return
    else:
        struct = readstructure(crystal=False, molecule=True)
        ast = analyzer.PointGroupAnalyzer(struct)
        print("{} : {}".format('Structure Type', 'non-periodicity'))
        print("{} : {}".format('International Symbol', ast.get_pointgroup()))
        return
def ChargeMomentOfInertia(picklestruct):
    '''
    moment of inertia seems sort of extraneous
    :param picklestruct:
    :return:
    '''
    def CenterofMass(picklestruct):  #function needs to be imbedded
        '''
        centerofmass in terms of fractional coordinates
        :param picklestruct:
        :return:
        '''
        numerator = np.array([0.0, 0.0, 0.0])
        denominator = list()
        for sites in picklestruct.sites:
            mass = sites.specie.data['Atomic mass']
            cellPosition = sites.frac_coords
            # normalized
            numerator += cellPosition * mass
            denominator.append(mass)
        return numerator / (np.mean(denominator))

    SPA = psa.SpacegroupAnalyzer(picklestruct)
    picklestruct = SPA.get_conventional_standard_structure()
    Rcm = CenterofMass(picklestruct)
    #fractional coords
    I = 0
    for site in picklestruct.sites:
        elemCharge = site.specie.max_oxidation_state
        coords = site._fcoords
        dist = coords - Rcm
        I += elemCharge * np.dot(dist, dist)
    data = {
        'charge moment of inertia': I
    }
    return data
Exemplo n.º 6
0
def getSpacegroup(kind,inittraj): 
	if kind == 'bulk':
		pmg = pmgase.AseAtomsAdaptor().get_structure(pickle.loads(inittraj))
		return psa.SpacegroupAnalyzer(pmg).get_space_group_number()
	else: return None
def getCellSymmetryOps(picklestruct):
    symmetry = psa.SpacegroupAnalyzer(picklestruct)
    numSGOps = len(symmetry.get_symmetry_operations())
    data = {'symmetry ops': numSGOps}
    return data
def getCellSymmetryOps(picklestruct):
    symmetry = psa.SpacegroupAnalyzer(picklestruct);
    numSGOps = len(symmetry.get_symmetry_operations());
    return numSGOps;
def getCrystalSystem(picklestruct):
    symmetry = psa.SpacegroupAnalyzer(picklestruct);
    numeric = cs.CrystalSysClassFeat(symmetry.get_crystal_system());
    return numeric;
def Hall_Number(picklestruct): #return hall_number, which is just another way of listing a spacegroup number
    symmetryDat = psa.SpacegroupAnalyzer(picklestruct);
    return symmetryDat.get_symmetry_dataset()['hall_number'];
Exemplo n.º 11
0
    def rewrite_cif(path: str,
                    outdir: str,
                    remove_disorder: bool = True,
                    remove_duplicates: bool = True,
                    p1: bool = False,
                    clean_symmetry: float = None) -> str:
        """
        Reads cif file and keeps only the relevant parts defined in RELEVANT_KEYS.
        Sometimes, it is good to loose information ...
        Args:
            path (str): Path to input file
            outdir (str): Path to output directory
            remove_disorder (bool): If True (default), then disorder groups other than 1 and . are removed.
            p1 (bool): If True, then we will set the symmetry to P1.
            clean_symmetry (float): uses spglib to symmetrize the structure with the specified tolerance, set to None
                if you do not want to use it

        Returns:
            outpath (str)
        """
        # ToDo: I want to have it pretty strict with pre-defined keys but maybe a regex can take care of captitiliaztion
        RELEVANT_KEYS = [
            '_cell_volume',
            '_cell_angle_gamma',
            '_cell_angle_beta',
            '_cell_angle_alpha',
            '_cell_length_a',
            '_cell_length_b',
            '_cell_length_c',
            '_atom_site_label',
            '_atom_site_fract_x',
            '_atom_site_fract_y',
            '_atom_site_fract_z',
            '_atom_site_charge',
            '_atom_site_type_symbol',
        ]

        RELEVANT_KEYS_NON_P1 = [
            '_symmetry_cell_setting',
            '_space_group_crystal_system',
            '_space_group_name_hall',
            '_space_group_crystal_system',
            '_space_group_it_number',
            '_symmetry_space_group_name_h-m',
            '_symmetry_int_tables_number',
            '_space_group_name_h-m_alt',
            '_symmetry_tnt_tables_number',
            '_symmetry_space_group_name_hall',
            '_symmetry_equiv_pos_as_xyz',
            '_space_group_symop_operation_xyz',
        ]

        LOOP_KEYS = [
            '_atom_site_label', '_atom_site_fract_x', '_atom_site_fract_y',
            '_atom_site_fract_z', '_atom_site_charge', '_atom_site_occupancy'
        ]

        NUMERIC_LOOP_KEYS = [
            '_atom_site_fract_x', '_atom_site_fract_y', '_atom_site_fract_z',
            '_atom_site_charge', '_atom_site_occupancy'
        ]

        CELL_PROPERTIES = [
            '_cell_volume',
            '_cell_angle_gamma',
            '_cell_angle_beta',
            '_cell_angle_alpha',
            '_cell_length_a',
            '_cell_length_b',
            '_cell_length_c',
        ]

        try:
            cf = CifFile.ReadCif(path)
            image = cf[cf.keys()[0]]
            if ('_atom_site_fract_x' not in image.keys()) or (
                    '_atom_site_fract_y' not in image.keys()) or (
                        '_atom_site_fract_z' not in image.keys()):
                raise ValueError
        except ValueError:
            logger.error(
                'the file %s seems to be invalid because we were unable to find '
                'the atomic positions will return input path but '
                'this file will likely cause errors and needs to be checked',
                path)
            return path
        except FileNotFoundError:
            logger.error('the file %s was not found', path)
            return path
        except Exception:
            logger.error(
                'the file %s seems to be invalid will return input path but '
                'this file will likely cause errors and needs to be checked',
                path)
            return path
        else:
            # First, make sure we have proper atom type labels.
            if ('_atom_site_type_symbol' not in image.keys()) and (
                    '_atom_site_symbol' not in image.keys()):
                # then loop over the label and strip all the floats
                type_symbols = []
                for label in image['_atom_site_label']:
                    type_symbols.append(re.sub('[^a-zA-Z]+', '', label))
                image.AddItem('_atom_site_type_symbol', type_symbols)
                image.AddLoopName('_atom_site_label', '_atom_site_type_symbol')

            if remove_disorder and '_atom_site_disorder_group' in image.keys():
                indices_to_drop = []
                logger.info('Removing disorder groups in %s', path)
                for i, dg in enumerate(image['_atom_site_disorder_group']):
                    if dg not in ('.', '1'):
                        indices_to_drop.append(i)

                if indices_to_drop:
                    image['_atom_site_type_symbol'] = [
                        i
                        for j, i in enumerate(image['_atom_site_type_symbol'])
                        if j not in indices_to_drop
                    ]
                    for key in LOOP_KEYS:
                        if key in image.keys():
                            loop_fixed = [
                                i for j, i in enumerate(image[key])
                                if j not in indices_to_drop
                            ]
                            image.RemoveItem(key)
                            image.AddItem(key, loop_fixed)
                            image.AddLoopName('_atom_site_type_symbol', key)

            if not p1:
                RELEVANT_KEYS += RELEVANT_KEYS_NON_P1

            for key in image.keys():
                if key not in RELEVANT_KEYS:
                    image.RemoveItem(key)

            image['_atom_site_label'] = image['_atom_site_type_symbol']

            if p1:
                image.AddItem('_symmetry_space_group_name_H-M', 'P 1')
                image.ChangeItemOrder('_symmetry_space_group_name_h-m', -1)
                image.AddItem('_space_group_name_Hall', 'P 1')
                image.ChangeItemOrder('_space_group_name_Hall', -1)

            # remove uncertainty brackets
            for key in NUMERIC_LOOP_KEYS:
                if key in image.keys():
                    image[key] = [
                        float(re.sub(r'\([^)]*\)', '', s)) for s in image[key]
                    ]

            for prop in CELL_PROPERTIES:
                if prop in image.keys():
                    image[prop] = float(re.sub(r'\([^)]*\)', '', image[prop]))

            # make filename that is safe
            name = slugify(Path(path).stem)
            outpath = os.path.join(outdir, '.'.join([name, 'cif']))
            with open(outpath, 'w') as f:
                f.write(cf.WriteOut() + '\n')

            if clean_symmetry:
                crystal = Structure.from_file(outpath)
                spa = analyzer.SpacegroupAnalyzer(crystal, 0.1)
                crystal = spa.get_refined_structure()
                crystal.to(filename=outpath)

            if remove_duplicates:
                atoms = read(outpath)
                get_duplicate_atoms(atoms, 0.5, delete=True)
                write(outpath, atoms)

            return outpath
Exemplo n.º 12
0
def elastic_analysis():

    filename = 'OUTCAR'
    step_count = 1
    check_file(filename)
    proc_str = "Reading Data From " + filename + " File ..."
    procs(proc_str, step_count, sp='-->>')
    outcar = Outcar(filename)
    outcar.read_elastic_tensor()
    cij_tensor = np.array(outcar.data['elastic_tensor'])

    filename = 'vasprun.xml'
    step_count += 1
    check_file(filename)
    proc_str = "Reading Data From " + filename + " File ..."
    procs(proc_str, step_count, sp='-->>')
    vsr = Vasprun(filename)
    struct0 = vsr.structures[0]
    natom = struct0.num_sites
    weight = struct0.composition.weight
    volume = struct0.lattice.volume

    ## converting the units
    volume *= 1.0e-30  ## from Angstrom to meters
    weight *= weight * 1.0e-3  ## from gram to kg
    density = weight / (volume * Avogadro)

    asa = analyzer.SpacegroupAnalyzer(struct0)
    #   lat_type=asa.get_crystal_system()

    crys_type = asa.get_lattice_type()

    ## Redefining the Cij matrix into the correct Voigt notation since VASP's OUTCAR has a different order
    ## In VASP: Columns and rows are listed as: 1, 2, 3, 6, 4, 5
    ## In this format OUTCAR's C44 values would be actually C66, C55 would be C44, and C66 would be C55.
    ## OUTCAR follows the below order:
    ## [C11 C12 C13 C16 C14 C15]
    ## [C21 C22 C23 C26 C24 C25]
    ## [C31 C32 C33 C36 C34 C35]
    ## [C61 C62 C63 C66 C64 C65]
    ## [C41 C42 C43 C46 C44 C45]
    ## [C51 C52 C53 C56 C54 C55]

    cnew = np.zeros((6, 6))
    snew = np.zeros((6, 6))
    cnew = np.copy(cij_tensor)

    for j in range(0, 6):
        cnew[3][j] = cij_tensor[4][j]
        cnew[4][j] = cij_tensor[5][j]
        cnew[5][j] = cij_tensor[3][j]

    ctemp = np.zeros((6, 6))
    ctemp = np.copy(cnew)

    for i in range(0, 6):
        cnew[i][3] = cnew[i][4]
        cnew[i][4] = cnew[i][5]
        cnew[i][5] = ctemp[i][3]

    # Change the units of Cij from kBar to GPa
    cnew = cnew / 10.0
    proc_str = "\n Modified elastic tensor in correct order (in GPa units)"
    print(proc_str)
    fmt = "%7.3f " * 6
    for i in range(6):
        print(fmt % tuple(cnew[i, :]))

    def check_symmetric(a, tol=1e-8):
        return np.allclose(a, a.T, atol=tol)

    print(
        '\n Checking if the elastic tensor is symmetric: i.e. Cij = Cji:  %5s'
        % check_symmetric(cnew))
    print("\n Eigen Values of the elastic tensor:")
    evals = LA.eigvals(cnew)
    print(fmt % tuple(evals))
    if np.all(evals) > 0.0:
        print("\n All eigen values are positive indicating elastic stability.")
    else:
        print(
            "\n ATTENTION: One or more eigen values are negative indicating elastic instability."
        )
    calc_elastic_prop(cnew, snew, crys_type, density, weight, natom)