def get_ion_geoms(argv): """""" #------------------------------------------------------------------------------- # Argument parser #------------------------------------------------------------------------------- parser = argparse.ArgumentParser(description=__doc__) # Positional arguments parser.add_argument('filename', default="vasprun.xml", type=str, nargs='?', help='set input xml file. Default vasprun.xml;') # Optional args parser.add_argument('--debug', action='store_true', dest='debug', help='show debug informations.') #------------------------------------------------------------------------------- # Initialize and check variables #------------------------------------------------------------------------------- args = parser.parse_args(argv) # Set up LOGGER c_log = logging.getLogger(__name__) # Adopted format: level - current function name - mess. Width is fixed as visual aid std_format = '[%(levelname)5s - %(funcName)10s] %(message)s' logging.basicConfig(format=std_format) c_log.setLevel(logging.INFO) # Set debug option if args.debug: c_log.setLevel(logging.DEBUG) c_log.debug(args) #------------------------------------------------------------------------------- # Load geometry and print in cartesian #------------------------------------------------------------------------------- # Quickly load the xml, skip big parts to go faster vasprun = Vasprun(args.filename, parse_projected_eigen=False, parse_eigen=False, parse_dos=False, exception_on_bad_xml=False, parse_potcar_file=False) # Conver between PyMatGen Strcutre and ASE # Just because we are more familiar with the latter ase_bridge = AseAtomsAdaptor() # For each structure, save a POSCAR with the ion step in front (easier to read in right order from bash) for i, structure in enumerate(vasprun.structures): ase_bridge.get_atoms(structure).write("%i-ion_step.vasp" % i, vasp5=True) return Vasprun.structures
def parse_periodic_case(file_1, file_2, try_supercell: bool = True, pymatgen: bool = False, get_reduced_structure: bool = True): """ Parser for periodic structures, handles two possible cases: (1) Structures are supercells (within tolerance), then one cell is multiplied by the scaling factors (2) Structures are not supercells of each other, then we rescale on cell to the volume of the other cell to make sure we have meaningful comparisons. Args: file_1 (str/pymatgen structure object): path to first file, in on format that ASE can parse, pymatgen structure object in case pymatgen=True file_2 (str/pymatgen structure object): path to second file, pymatgen structure object in case pymatgen=True try_supercell (bool): if true, we attempt to build a supercell, default: True pymatgen (bool): if true, then file_1 and file_2 take pymatgen structure objects get_reduced_structure (bool): if true (default) it gets the Niggli reduced cell. Returns: atomic symbols (list), cartesian positions (list) of structure 1, atomic symbols (list), cartesian positions (list) of structure 2 """ if pymatgen: atoms1 = AseAtomsAdaptor.get_atoms(file_1) atoms2 = AseAtomsAdaptor.get_atoms(file_2) else: atoms1 = read(file_1) atoms2 = read(file_2) if get_reduced_structure: niggli_reduce(atoms1) niggli_reduce(atoms2) if try_supercell: a1, a2 = attempt_supercell(atoms1, atoms2) else: a1, a2 = rescale_periodic_system(atoms1, atoms2) atomic_symbols_1 = a1.get_chemical_symbols() positions_1 = a1.get_positions() atomic_symbols_2 = a2.get_chemical_symbols() positions_2 = a2.get_positions() return np.array(atomic_symbols_1), np.array(positions_1), np.array( atomic_symbols_2), np.array(positions_2)
def dict_to(dictionary): x = 0 for key in dictionary.keys(): y = dictionary[key]['surface'] if (isinstance(y, dict) == False): w = AseAtomsAdaptor.get_atoms(y) z = atoms_to_dict(w) atom_hash = get_hash(w) add_everything_to_dict(key, dictionary[key], z, atom_hash) else: y = dictionary[key]['surface'] w = AseAtomsAdaptor.get_atoms(Structure.from_dict(y)) z = atoms_to_dict(w) atom_hash = get_hash(w) add_everything_to_dict(key, dictionary[key], z, atom_hash)
def getInterstitials(ase_in,inter,spinpol): pmg_init = AseAtomsAdaptor.get_structure(ase_in) pmg_init2 = SpacegroupAnalyzer(pmg_init).get_conventional_standard_structure() interstitial = Interstitial(pmg_init2,None,covalent_radii) #accuracy=high breaks... os.system('cls' if os.name == 'nt' else 'clear') output = [] for i,site in enumerate(interstitial.enumerate_defectsites()): coordination = int(round(interstitial.get_defectsite_coordination_number(i))) mult = 0 # interstitial.get_defectsite_multiplicity(i) -- broken ??? insert = InsertSitesTransformation([inter],[site.coords],coords_are_cartesian=True) try: pmg_new = insert.apply_transformation(pmg_init2.copy()) ase_new = AseAtomsAdaptor.get_atoms(pmg_new) if coordination == 4: siteName='T' elif coordination == 6: siteName='O' else: siteName = '%d-fold'%coordination strname = '_%s-%s'%(inter,siteName) if spinpol: new_magmoms = [3 if e in misc.magElems else 0 for e in ase_new.get_chemical_symbols()] ase_new.set_initial_magnetic_moments(new_magmoms) output.append((ase_new,strname)) except ValueError: pass #ValueError: New site is too close to an existing site! return output
def _featurize(self, struct: PymatgenStructure) -> np.ndarray: """Calculate SOAP descriptor from pymatgen structure. Parameters ---------- struct: pymatgen.Structure A periodic crystal composed of a lattice and a sequence of atomic sites with 3D coordinates and elements. Returns ------- features: np.ndarray soap descriptor """ soap = SOAP( periodic=self.periodic, species=self.species, rcut=self.rcut, nmax=self.nmax, lmax=self.lmax, rbf=self.rbf, sigma=self.sigma, average=self.average, ) if self.convert: adaptor = AseAtomsAdaptor() struct = adaptor.get_atoms(struct) features = soap.create(struct) features = np.asarray(features) return features
def __init__(self, bs_obj, structure=None, nelect=None): """Structure and nelect is needed to be provide""" self.kpoints = np.array([kp.frac_coords for kp in bs_obj.kpoints]) if structure is None: try: self.structure = bs_obj.structure except: BaseException('No structure found in the bs obj.') else: self.structure = structure self.atoms = AseAtomsAdaptor.get_atoms(self.structure) if len(bs_obj.bands) == 1: e = list(bs_obj.bands.values())[0] self.ebands = e * units.eV self.dosweight = 2.0 elif len(bs_obj.bands) == 2: raise BaseException("spin bs case not implemented") self.lattvec = self.atoms.get_cell().T * units.Angstrom self.mommat = None self.magmom = None self.fermi = bs_obj.efermi * units.eV self.nelect = nelect self.UCvol = self.structure.volume * units.Angstrom ** 3 self.vbm_idx = list(bs_obj.get_vbm()['band_index'].values())[0][-1] self.cbm_idx = list(bs_obj.get_cbm()['band_index'].values())[0][0]
def viewStructure(structure): """ :param structure: The structure that we want to show, it has to be pymatgen structure :type structure: pymatgen.core.structure object :returns: a nglview variable to show the structure :rtype: nglview object """ from ase.visualize import view from pymatgen.io.ase import AseAtomsAdaptor structure = AseAtomsAdaptor.get_atoms(structure=structure) v = view(structure, viewer='ngl') # setting the output window for the nglview # nglview is a really good tool, and I need to learn more about that. v.view.add_ball_and_stick() v.view.center() v.view.layout.width = '800px' v.view.layout.height = '800px' v.view.add_label(color='blue', radius=1.0, labelType='text', labelText=[structure[i].symbol + str(i) for i in range(len(structure))], zOffset=2.0, attachment='middle_center') v.view.gui_style = 'ngl' return v
def __init__(self, atoms, parameters={}, name='SPARC SCF', sparc_command=None, psuedo_potentials_path=None, db_file=None, parents=None, to_db=False, identifier=None, **kwargs): t = [] try: translator = AseAtomsAdaptor() atoms = translator.get_atoms(atoms) except: pass t.append( OptimizeLattice(atoms=atoms, parameter_dict=parameters, sparc_command=sparc_command, psuedo_potentials_path=psuedo_potentials_path, identifier=identifier, to_db=to_db)) super(OptimizeLatticeSPARC, self).__init__(t, parents=parents, name="{}-{}".format( dict_atoms(atoms).get_chemical_formula(), name), **kwargs)
def __init__(self, vrun_obj=None): """ :param vrun_obj: Vasprun object. """ if vrun_obj: self.kpoints = np.array(vrun_obj.actual_kpoints) self.structure = vrun_obj.final_structure self.atoms = AseAtomsAdaptor.get_atoms(self.structure) self.proj = None if len(vrun_obj.eigenvalues) == 1: e = list(vrun_obj.eigenvalues.values())[0] self.ebands = e[:, :, 0].transpose() * units.eV self.dosweight = 2.0 if vrun_obj.projected_eigenvalues: self.proj = list( vrun_obj.projected_eigenvalues.values())[0] elif len(vrun_obj.eigenvalues) == 2: raise BoltztrapError("spin bs case not implemented") self.lattvec = self.atoms.get_cell().T * units.Angstrom # TODO: read mommat from vasprun self.mommat = None self.magmom = None self.spin = None self.fermi = vrun_obj.efermi * units.eV self.nelect = vrun_obj.parameters['NELECT'] self.UCvol = self.structure.volume * units.Angstrom**3
def update_soap_analysis(struct, all_kwargs): if not struct: raise PreventUpdate struct = self.from_data(struct) kwargs = self.reconstruct_kwargs_from_state( callback_context.inputs) # TODO: make sure is_int kwarg information is enforced so that int() conversion is unnecessary desc = SOAP( species=[e.number for e in struct.composition.elements], sigma=kwargs["sigma"], rcut=kwargs["rcut"], nmax=int(kwargs["nmax"]), lmax=int(kwargs["lmax"]), periodic=True, crossover=kwargs["crossover"], sparse=False, average=kwargs["average"], ) adaptor = AseAtomsAdaptor() atoms = adaptor.get_atoms(struct) feature = normalize(desc.create(atoms, n_jobs=cpu_count())) return _get_soap_graph(feature, "SOAP vector for this material")
def select_kpts(structure, kpt_density=15.): kpts = [] atoms = AseAtomsAdaptor.get_atoms(structure) for i in range(3): l = np.linalg.norm(atoms.cell[i]) kpts.append(math.ceil(kpt_density / l)) return kpts
def get_angle_from_plane(structure : Structure, i, i1, i2, x, y, z): """ Get distance of atom i from the plane formed by atoms x, y, and z :param structure: :param i: :param x: :param y: :param z: :return: """ atoms = AseAtomsAdaptor.get_atoms(structure) atoms.wrap(atoms.get_scaled_positions()[i]) positions = atoms.get_positions() x = positions[x] y = positions[y] z = positions[z] v = positions[i1] - positions[i2] # get Normal Vector v1 = y - x v2 = z - x # Get equation of plane ax+by+cz+d = 0 normal = np.cross(v1, v2) / np.linalg.norm(np.cross(v1, v2)) a = normal[0] b = normal[1] c = normal[2] plane = np.array([a,b,c]) return np.arcsin(abs(np.dot(v, plane)) / (np.linalg.norm(v)*np.linalg.norm(plane))) * 180/np.pi
def __init__(self, vrun_obj=None): if vrun_obj: self.kpoints = np.array(vrun_obj.actual_kpoints) self.structure = vrun_obj.final_structure self.atoms = AseAtomsAdaptor.get_atoms(self.structure) self.proj = None if len(vrun_obj.eigenvalues) == 1: e = list(vrun_obj.eigenvalues.values())[0] self.ebands = e[:, :, 0].transpose() * units.eV self.dosweight = 2.0 if vrun_obj.projected_eigenvalues: self.proj = list(vrun_obj.projected_eigenvalues.values())[0] elif len(vrun_obj.eigenvalues) == 2: raise BoltztrapError("spin bs case not implemented") self.lattvec = self.atoms.get_cell().T * units.Angstrom # TODO: read mommat from vasprun self.mommat = None self.magmom = None self.spin = None self.fermi = vrun_obj.efermi * units.eV self.nelect = vrun_obj.parameters['NELECT'] self.UCvol = self.structure.volume * units.Angstrom ** 3
def run(self): with MPRester(utils.read_rc('matproj_api_key')) as rester: structure = rester.get_structure_by_material_id(self.mpid) atoms = AseAtomsAdaptor.get_atoms(structure) doc = make_doc_from_atoms(atoms) save_task_output(self, doc)
def ase_input_generator(ase_S, nbnd): """ Using ASE write functions for generate input Args: (ASE Structure) Returns: Input files for Quantum Espresso first SCFU calculations """ SCF_input = qe_input.scfu() pymat_S = AseAtomsAdaptor.get_structure(ase_S) hubbard_u_list = initialize_hubbard(pymat_S) #--update the SYSTEM card SCF_input['SYSTEM']['nbnd'] = nbnd SCF_input['SYSTEM'].update(insert_hubbard_block(hubbard_u_list)) converted_pymat_S = reorder(pymat_S, hubbard_u_list) pseudos = Pseudos(converted_pymat_S) converted_ase_S = AseAtomsAdaptor.get_atoms(converted_pymat_S) write("dftu.in", converted_ase_S, format = "espresso-in", \ pseudopotentials=pseudos, input_data = SCF_input, kspacing=0.04)
def __init__(self, bs_obj, structure=None, nelect=None, mommat=None, magmom=None): """ Args: bs_obj: BandStructure object. structure: Structure object. It is needed if it is not contained in the BandStructure obj. nelect: Number of electrons in the calculation. momat: Matrix of derivatives of energy eigenvalues. Not implemented yet. magmom: Matrix of magnetic moments in non collinear calculations. Not implemented yet. Example: vrun = Vasprun('vasprun.xml') bs = vrun.get_band_structure() st = vrun.final_structure ne = vrun.parameters['NELECT'] data = BandstructureLoader(bs,st,ne) """ warnings.warn("Deprecated Loader. Use VasprunBSLoader instead.") self.kpoints = np.array([kp.frac_coords for kp in bs_obj.kpoints]) if structure is None: self.structure = bs_obj.structure else: self.structure = structure self.atoms = AseAtomsAdaptor.get_atoms(self.structure) self.proj_all = None if bs_obj.projections: self.proj_all = {sp: p.transpose((1, 0, 3, 2)) for sp, p in bs_obj.projections.items()} e = np.array(list(bs_obj.bands.values())) e = e.reshape(-1, e.shape[-1]) self.ebands_all = e * units.eV self.is_spin_polarized = bs_obj.is_spin_polarized if bs_obj.is_spin_polarized: self.dosweight = 1.0 else: self.dosweight = 2.0 self.lattvec = self.atoms.get_cell().T * units.Angstrom self.mommat_all = mommat # not implemented yet self.mommat = mommat # not implemented yet self.magmom = magmom # not implemented yet self.fermi = bs_obj.efermi * units.eV self.UCvol = self.structure.volume * units.Angstrom**3 if not bs_obj.is_metal(): self.vbm_idx = max(bs_obj.get_vbm()["band_index"][Spin.up] + bs_obj.get_vbm()["band_index"][Spin.down]) self.cbm_idx = min(bs_obj.get_cbm()["band_index"][Spin.up] + bs_obj.get_cbm()["band_index"][Spin.down]) self.vbm = bs_obj.get_vbm()["energy"] self.cbm = bs_obj.get_cbm()["energy"] self.nelect_all = self.vbm_idx * self.dosweight else: self.vbm_idx = None self.cbm_idx = None self.vbm = self.fermi self.cbm = self.fermi self.nelect_all = nelect
def get_distance_from_plane(structure : Structure, i, x,y,z): """ Get distance of atom i from the plane formed by atoms x, y, and z :param structure: :param i: :param x: :param y: :param z: :return: """ atoms = AseAtomsAdaptor.get_atoms(structure) atoms.wrap(atoms.get_scaled_positions()[i]) positions = atoms.get_positions() x = positions[x] y = positions[y] z = positions[z] p = positions[i] # get Normal Vector v1 = y - x v2 = z - x # Get equation of plane ax+by+cz+d = 0 normal = np.cross(v1, v2) / np.linalg.norm(np.cross(v1, v2)) d = np.dot(normal, x) a = normal[0] b = normal[1] c = normal[2] # Get closest point on plane return abs((a * p[0] + b * p[1] + c * p[2] - d) / (a ** 2 + b ** 2 + c ** 2)) # distance between point and plane
def __init__(self, bs_obj,structure=None,nelect=None): """Structure and nelect is needed to be provide""" self.kpoints = np.array([kp.frac_coords for kp in bs_obj.kpoints]) if structure is None: try: self.structure = bs_obj.structure except: BaseException('No structure found in the bs obj.') else: self.structure = structure self.atoms = AseAtomsAdaptor.get_atoms(self.structure) if len(bs_obj.bands) == 1: e = list(bs_obj.bands.values())[0] self.ebands = e * units.eV self.dosweight = 2.0 elif len(bs_obj.bands) == 2: raise BaseException("spin bs case not implemented") self.lattvec = self.atoms.get_cell().T* units.Angstrom self.mommat = None self.magmom = None self.fermi = bs_obj.efermi * units.eV self.nelect = nelect self.UCvol = self.structure.volume * units.Angstrom**3 self.vbm_idx = list(bs_obj.get_vbm()['band_index'].values())[0][-1] self.cbm_idx = list(bs_obj.get_cbm()['band_index'].values())[0][0]
def __init__(self, bulk_object, surface_info, surface_index, total_surfaces_possible): ''' Initialize the surface object, tag atoms, and constrain the surface. Args: bulk_object: `Bulk()` object of the corresponding bulk surface_info: tuple containing atoms, millers, shift, top surface_index: index of surface out of all possible ones for the bulk total_surfaces_possible: number of possible surfaces from this bulk ''' self.bulk_object = bulk_object surface_struct, self.millers, self.shift, self.top = surface_info self.surface_sampling_str = str(surface_index) + "/" + str( total_surfaces_possible) unit_surface_atoms = AseAtomsAdaptor.get_atoms(surface_struct) self.surface_atoms = self.tile_atoms(unit_surface_atoms) # verify that the bulk and surface elements and stoichiometry match: assert (Composition(self.surface_atoms.get_chemical_formula()).reduced_formula == Composition(bulk_object.bulk_atoms.get_chemical_formula()).reduced_formula), \ 'Mismatched bulk and surface' self.tag_surface_atoms(self.bulk_object.bulk_atoms, self.surface_atoms) self.constrained_surface = constrain_surface(self.surface_atoms)
def _create_surface(self): ''' This method will create the surface structure to relax Returns: surface_atoms_constrained `ase.Atoms` object of the surface to submit to Fireworks for relaxation ''' # Get the bulk and convert to `pymatgen.Structure` object with open(self.input().path, 'rb') as file_handle: bulk_doc = pickle.load(file_handle) bulk_atoms = make_atoms_from_doc(bulk_doc) bulk_structure = AseAtomsAdaptor.get_structure(bulk_atoms) # Use pymatgen to turn the bulk into a surface sga = SpacegroupAnalyzer(bulk_structure, symprec=0.1) bulk_structure = sga.get_conventional_standard_structure() gen = SlabGenerator(initial_structure=bulk_structure, miller_index=self.miller_indices, min_slab_size=self.min_height, **self.slab_generator_settings) surface_structure = gen.get_slab(self.shift, tol=self.get_slab_settings['tol']) # Convert the surface back to an `ase.Atoms` object and constrain # subsurface atoms surface_atoms = AseAtomsAdaptor.get_atoms(surface_structure) surface_atoms_constrained = self.__constrain_surface(surface_atoms) return surface_atoms_constrained
def __init__(self, struct): ase_atoms = AseAtomsAdaptor.get_atoms(struct) self.bulk_pym = struct self.bulk_ase = ase_atoms self.minimal_unit_cell = ase_atoms.get_cell().T
def __init__( self, band_structure: BandStructure, num_electrons: int, interpolation_factor: float = defaults["interpolation_factor"], soc: bool = False, magmom: Optional[np.ndarray] = None, mommat: Optional[np.ndarray] = None, other_properties: Dict[Spin, Dict[str, np.ndarray]] = None, ): self._band_structure = band_structure self._num_electrons = num_electrons self._soc = soc self._spins = self._band_structure.bands.keys() self._other_properties = other_properties self.interpolation_factor = interpolation_factor self._lattice_matrix = (band_structure.structure.lattice.matrix.T * angstrom_to_bohr) self._coefficients = {} self._other_coefficients = defaultdict(dict) kpoints = np.array([k.frac_coords for k in band_structure.kpoints]) atoms = AseAtomsAdaptor.get_atoms(band_structure.structure) logger.info("Getting band interpolation coefficients") t0 = time.perf_counter() self._equivalences = sphere.get_equivalences(atoms=atoms, nkpt=kpoints.shape[0] * interpolation_factor, magmom=magmom) # get the interpolation mesh used by BoltzTraP2 self.interpolation_mesh = ( 2 * np.max(np.abs(np.vstack(self._equivalences)), axis=0) + 1) for spin in self._spins: energies = band_structure.bands[spin] * ev_to_hartree data = DFTData(kpoints, energies, self._lattice_matrix, mommat=mommat) self._coefficients[spin] = fite.fitde3D(data, self._equivalences) log_time_taken(t0) t0 = time.perf_counter() if self._other_properties: logger.info("Getting additional interpolation coefficients") for spin in self._spins: for label, prop in self._other_properties[spin].items(): data = DFTData(kpoints, prop, self._lattice_matrix, mommat=mommat) self._other_coefficients[spin][label] = fite.fitde3D( data, self._equivalences) log_time_taken(t0)
def __init__(self, atoms, parameters={}, calculator='VASP', name='ASE Optimize', db_file=None, parents=None, to_db=False, identifier=None, optimizer='QuasiNewton', fmax=0.05, calculator_module='ase.calculators', **kwargs): """ Runs an SCF calculation in SPARC on the given structure Args: atoms (Atoms Object or Pymatgen Structure): Input structure name (str): Name for the Firework parameters (Dict): the input parameters for SPARC sparc_command (str): optional, a command used by ase to run SPARC. This can also be set with the $ASE_SPARC_COMMAND environment variable. psuedo_potentials_path (str): optional, a path to the pseudopotentials you'd like used. This can also be set using the $PSP_PATH environment Variable. db_file (str): Not implemented parents ([Firework]): Parents of this Firework """ t = [] try: translator = AseAtomsAdaptor() atoms = translator.get_atoms(atoms) except: pass t.append( OptimizeASE(atoms=atoms, parameter_dict=parameters, calculator=calculator, to_db=to_db, db_file=db_file, identifier=identifier, optimizer=optimizer, fmax=fmax, calculator_module=calculator_module)) super(ASE_Optimize_FW, self).__init__(t, parents=parents, name="{}-{}".format( dict_atoms(atoms).get_chemical_formula(), name), **kwargs)
def test_get_atoms_method(minimal_pymatgen_structure): from ase.atoms import Atoms poscar = VaspPoscarData(structure=minimal_pymatgen_structure) # assert retrieved atoms equal reference reference_atoms = AseAtomsAdaptor.get_atoms(minimal_pymatgen_structure) retrieved_atoms = poscar.get_atoms() assert isinstance(retrieved_atoms, Atoms) is True assert str(retrieved_atoms) == str(reference_atoms)
def get_pymatgen_ase_from_cif_structure(path): # warnings.filterwarnings('ignore')#, category=DeprecationWarning) struct = mg.Structure.from_file(path) try: ase_atoms = AseAtomsAdaptor.get_atoms(struct) except Exception as e: print(repr(e)) return ase_atoms
def makeAtoms(self): """ Creates ASE atoms object based on input specifications """ from pymatgen.io.ase import AseAtomsAdaptor atoms = AseAtomsAdaptor.get_atoms(self.adsorbedSurface()) atoms.set_constraint(self.constrainAtoms()) return atoms
def view_structure_with_ase(structure): """ Visualize the Structure object with the ASE. First the Structure object is converted into an ase Atom object, the "view" is used to visualize it. """ atoms = AseAtomsAdaptor.get_atoms(structure) view(atoms) return
def load_atoms_from_cif(self, structure_file_name): with warnings.catch_warnings(): warnings.simplefilter('ignore') parsed_cif = CifParser('nmse_database/structures/' + structure_file_name) structure = parsed_cif.get_structures(primitive=False)[0] # Convert pymatgen structure to ASE atoms return AseAtomsAdaptor.get_atoms(structure)
def __init__(self, struct): """ position should be 'mid_faces', 'mid_edges', 'corners', or an array of coordinates where adsorbates should be placed """ ase_atoms = AseAtomsAdaptor.get_atoms(struct) self.bulk_pym = struct self.bulk_ase = ase_atoms self.minimal_unit_cell = ase_atoms.get_cell().T
def __init__(self, band_structure: BandStructure, num_electrons: int, interpolation_factor: float = 20, soc: bool = False, magmom: Optional[np.ndarray] = None, mommat: Optional[np.ndarray] = None, interpolate_projections: bool = False): self._band_structure = band_structure self._num_electrons = num_electrons self._soc = soc self._spins = self._band_structure.bands.keys() self._interpolate_projections = interpolate_projections self.interpolation_factor = interpolation_factor self._lattice_matrix = (band_structure.structure.lattice.matrix * units.Angstrom) self._coefficients = {} self._projection_coefficients = defaultdict(dict) kpoints = np.array([k.frac_coords for k in band_structure.kpoints]) atoms = AseAtomsAdaptor.get_atoms(band_structure.structure) logger.info("Getting band interpolation coefficients") t0 = time.perf_counter() self._equivalences = sphere.get_equivalences( atoms=atoms, nkpt=kpoints.shape[0] * interpolation_factor, magmom=magmom) # get the interpolation mesh used by BoltzTraP2 self.interpolation_mesh = 2 * np.max( np.abs(np.vstack(self._equivalences)), axis=0) + 1 for spin in self._spins: energies = band_structure.bands[spin] * units.eV data = DFTData(kpoints, energies, self._lattice_matrix, mommat=mommat) self._coefficients[spin] = fite.fitde3D(data, self._equivalences) log_time_taken(t0) if self._interpolate_projections: logger.info("Getting projection interpolation coefficients") if not band_structure.projections: raise ValueError( "interpolate_projections is True but band structure has no " "projections") for spin in self._spins: for label, projection in _get_projections( band_structure.projections[spin]): data = DFTData(kpoints, projection, self._lattice_matrix, mommat=mommat) self._projection_coefficients[spin][label] = fite.fitde3D( data, self._equivalences) log_time_taken(t0)
def read_cif(self): """ reads cifs, returns both pymatgen structure and ase atoms object """ cif = CifParser(self.filename) struct = cif.get_structures(primitive=False)[0] ase_atoms = AseAtomsAdaptor.get_atoms(struct) return struct, ase_atoms
def make_transition(start, final, ts, t1, t2, output1, output2): from ase.io import write start = AseAtomsAdaptor.get_atoms( Poscar.from_dict(start['poscar']).structure) final = AseAtomsAdaptor.get_atoms( Poscar.from_dict(final['poscar']).structure) t1 = [ AseAtomsAdaptor.get_atoms(Poscar.from_dict(x).structure) for x in t1['poscars'] ] t2 = [ AseAtomsAdaptor.get_atoms(Poscar.from_dict(x).structure) for x in t2['poscars'] ] t1.reverse() ts = AseAtomsAdaptor.get_atoms(Poscar.from_dict(ts['poscar']).structure) write(output1, ts) write(output2, [start] + t1 + [ts] + t2 + [final]) return
def get_atoms(self): """ Create and return a :class:`ase.Atoms` instance from the node's stored structure data contents :return: an ASE-Atoms instance :rtype: :class:`ase.Atoms` """ structure = self.get_structure() return AseAtomsAdaptor.get_atoms(structure)
def get_conventionalstructure(ase_structure): from pymatgen.io.ase import AseAtomsAdaptor from pymatgen.symmetry.analyzer import SpacegroupAnalyzer mg_structure = AseAtomsAdaptor.get_structure(ase_structure) sga = SpacegroupAnalyzer(mg_structure) standard_structure = sga.get_conventional_standard_structure() standard_ase = AseAtomsAdaptor.get_atoms(standard_structure) return standard_ase
def __init__(self, bs_obj, structure=None, nelect=None, spin=None): """ Structure and nelect is needed to be provide. spin must be select if bs is spin-polarized. """ self.kpoints = np.array([kp.frac_coords for kp in bs_obj.kpoints]) if structure is None: try: self.structure = bs_obj.structure except: BaseException('No structure found in the bs obj.') else: self.structure = structure self.atoms = AseAtomsAdaptor.get_atoms(self.structure) self.proj = None if len(bs_obj.bands) == 1: e = list(bs_obj.bands.values())[0] self.ebands = e * units.eV self.dosweight = 2.0 if bs_obj.projections: self.proj = bs_obj.projections[Spin.up].transpose((1,0,3,2)) elif len(bs_obj.bands) == 2: if not spin: raise BaseException("spin-polarized bs, you need to select a spin") elif spin in (-1,1): e = bs_obj.bands[Spin(spin)] self.ebands = e * units.eV self.dosweight = 1.0 if bs_obj.projections: self.proj = bs_obj.projections[Spin(spin)].transpose((1,0,3,2)) self.lattvec = self.atoms.get_cell().T * units.Angstrom self.mommat = None self.magmom = None self.fermi = bs_obj.efermi * units.eV self.nelect = nelect self.UCvol = self.structure.volume * units.Angstrom ** 3 self.spin = spin if not bs_obj.is_metal() and not spin: self.vbm_idx = list(bs_obj.get_vbm()['band_index'].values())[0][-1] self.cbm_idx = list(bs_obj.get_cbm()['band_index'].values())[0][0]
def nebmake(directory, start, final, images, tolerance=0, ci=False, poscar_override=[], linear=False, write=True): if type(start) == str: start_POSCAR = os.path.join(start, 'CONTCAR') if os.path.exists(os.path.join(start, 'CONTCAR')) and os.path.getsize(os.path.join(start, 'CONTCAR')) > 0 else os.path.join(start, 'POSCAR') final_POSCAR = os.path.join(final, 'CONTCAR') if os.path.exists(os.path.join(final, 'CONTCAR')) and os.path.getsize(os.path.join(final, 'CONTCAR')) > 0 else os.path.join(final, 'POSCAR') p1 = Poscar.from_file(start_POSCAR) p2 = Poscar.from_file(final_POSCAR) s1 = p1.structure s2 = p2.structure else: s1 = start s2 = final # s1.sort() # s2.sort() atoms = [] if poscar_override: for i in range(int(len(poscar_override)/2)): atoms.append( (poscar_override[i*2], poscar_override[i*2+1]) ) (s1, s2) = reorganize_structures(s1, s2, atoms=atoms, autosort_tol=tolerance) tolerance=0 try: structures = s1.interpolate(s2, images, autosort_tol=tolerance) except Exception as e: a=input('Failed. Type y to sort --> ') if a=='y': s1.sort() s2.sort() else: raise e structures = s1.interpolate(s2, images, autosort_tol=tolerance) if not linear: from pymatgen.io.ase import AseAtomsAdaptor from ase.neb import NEB structures_ase = [ AseAtomsAdaptor.get_atoms(struc) for struc in structures ] neb = NEB(structures_ase) neb.interpolate('idpp') # type: NEB structures = [ AseAtomsAdaptor.get_structure(atoms) for atoms in neb.images ] if write: start_OUTCAR = os.path.join(start, 'OUTCAR') final_OUTCAR = os.path.join(final, 'OUTCAR') incar = Incar.from_file(os.path.join(start, 'INCAR')) kpoints = Kpoints.from_file(os.path.join(start, 'KPOINTS')) potcar = Potcar.from_file(os.path.join(start, 'POTCAR')) incar['ICHAIN'] = 0 incar['IMAGES'] = images-1 incar['LCLIMB'] = ci for i, s in enumerate(structures): folder = os.path.join(directory, str(i).zfill(2)) os.mkdir(folder) Poscar(s, selective_dynamics=p1.selective_dynamics).write_file(os.path.join(folder, 'POSCAR')) if i == 0: shutil.copy(start_OUTCAR, os.path.join(folder, 'OUTCAR')) if i == images: shutil.copy(final_OUTCAR, os.path.join(folder, 'OUTCAR')) i += 1 incar.write_file(os.path.join(directory, 'INCAR')) kpoints.write_file(os.path.join(directory, 'KPOINTS')) potcar.write_file(os.path.join(directory, 'POTCAR')) return structures