Source code for ase2sprkkr.bindings.uppasd

from pathlib import Path
from typing import Optional
import warnings
import numpy as np
from ase import Atoms
from ..sprkkr.sprkkr_atoms import SPRKKRAtoms
from ..output_files.definitions.jxc import JXCOutputFile, Coordinates

POSFILE_FORMAT = "{:5.0f} {:5.0f} {: 4.10f} {: 4.10f} {: 4.10f}\n"
MOMFILE_FORMAT = "{:5.0f} {:5.0f} {: 4.10f} {: 4.10f} {: 4.10f} {: 4.10f}\n"
JFILE_FORMAT = "{:5.0f}  {:5.0f}  {: 4.10f}  {: 4.10f}  {: 4.10f}  {: 4.8f}  {:4.10f}\n"
DMFILE_FORMAT = "{:5.0f}  {:5.0f}  {: 4.10f}  {: 4.10f}  {: 4.10f}  {: 4.8f}  {: 4.8f}  {: 4.8f}  {:4.10f}\n"
COORDINATE_FIELDS = {Coordinates.cartesian: ("DRX", "DRY", "DRZ"), Coordinates.lattice: ("N1", "N2", "N3")}


[docs] def write_inpsd_file(atoms: Atoms, file_name=None, directory=None, id=None, sym=0, ncell=None, **kwargs): file_name = file_name or "inpsd.dat" if directory: file_path = Path(directory) / file_name else: file_path = Path(file_name) bc = ["P" if i else "0" for i in atoms.pbc] bc = " ".join(bc) cell = "" for row in atoms.cell.array: cell += " {:>14.10f} {:>14.10f} {:>14.10f}\n".format(*row) if isinstance(ncell, int): ncell = (ncell, ncell, ncell) if ncell is not None: ncell = f"ncell {ncell[0]:<13} {ncell[1]:<13} {ncell[2]:<13} System size" else: ncell = "" def formated(v): if isinstance(v, (bool, np.bool)): return "Y" if v else "N" return str(v) with file_path.open("w") as infile: infile.write( f""" simid {id or str(atoms.symbols)} {ncell} BC {bc} Boundary conditions (0=vacuum, P=periodic) cell {cell[6:]} Sym {sym} Symmetry of exchange bonding vectors (0 for no, 1 for cubic, 2 for 2d cubic, 3 for hexagonal) """ ) for k, v in kwargs.items(): infile.write(f"{k:<14} {formated(v)}\n")
[docs] def write_jfile( jxc_ouput_file: JXCOutputFile, file_name=None, directory=None, selector=None, iq=None, it=None, exclude_it=None, exclude_vc=True, exchange_radius=None, coordinates: Coordinates = Coordinates.lattice, ): coordinate_fields = COORDINATE_FIELDS[coordinates] rows = jxc_ouput_file.filtered_data( selector=selector, iq=iq, it=it, exclude_it=exclude_it, exclude_vc=exclude_vc, exchange_radius=exchange_radius ) file_name = file_name or "jfile.dat" if directory: file_path = Path(directory) / file_name else: file_path = Path(file_name) with file_path.open("w") as jfile: for row in rows: jfile.write( JFILE_FORMAT.format( row["IQ"], row["JQ"], row[coordinate_fields[0]], row[coordinate_fields[1]], row[coordinate_fields[2]], row["JXX"], row["DR"], ) ) return True
[docs] def write_dmfile( jxc_ouput_file: JXCOutputFile, file_name="dmfile.dat", directory=None, selector=None, iq=None, it=None, exclude_it=None, exclude_vc=True, exchange_radius=None, coordinates: Coordinates = Coordinates.lattice, ): coordinate_fields = COORDINATE_FIELDS[coordinates] rows = jxc_ouput_file.filtered_data( selector=selector, iq=iq, it=it, exclude_it=exclude_it, exclude_vc=exclude_vc, exchange_radius=exchange_radius ) if directory: file_path = Path(directory) / file_name else: file_path = Path(file_name) with file_path.open("w") as dmfile: for row in rows: dmfile.write( DMFILE_FORMAT.format( row["IQ"], row["JQ"], row[coordinate_fields[0]], row[coordinate_fields[1]], row[coordinate_fields[2]], row["DX"], row["DY"], row["DZ"], row["DR"], ) ) return True
[docs] def write_pos_file( atoms: Atoms, file_name="posfile.dat", directory=None, selector=None, iq=None, it=None, exclude_it=None, exclude_vc=True, jxc_ouput_file: Optional[JXCOutputFile] = None, ): atoms = SPRKKRAtoms.promote_ase_atoms(atoms) if not jxc_ouput_file: jxc_ouput_file = JXCOutputFile.from_atoms(atoms) positions = atoms.get_scaled_positions(wrap=False) selected_iqs = jxc_ouput_file.iq_selector( selector=selector, iq=iq, it=it, exclude_it=exclude_it, exclude_vc=exclude_vc ) if selected_iqs is ...: selected_iqs = range(1, len(atoms.sites) + 1) elif not selected_iqs: return False site_types = {} if directory: file_path = Path(directory) / file_name else: file_path = Path(file_name) with file_path.open("w") as posfile: for iq in selected_iqs: index = iq - 1 site = atoms.sites[index] position = positions[index] site_type = site.site_type try: site_kind = site_types[site_type] except KeyError: site_kind = site_types[site_type] = len(site_types) + 1 posfile.write(POSFILE_FORMAT.format(iq, site_kind, position[0], position[1], position[2])) return True
[docs] def write_mom_file( atoms: Atoms, file_name="momfile.dat", directory=None, selector=None, iq=None, it=None, exclude_it=None, exclude_vc=True, jxc_ouput_file: Optional[JXCOutputFile] = None, ): atoms = SPRKKRAtoms.promote_ase_atoms(atoms) if not jxc_ouput_file: jxc_ouput_file = JXCOutputFile.from_atoms(atoms) out = [] warned = False selector = jxc_ouput_file.create_selector( selector=selector, iq=iq, it=it, exclude_it=exclude_it, exclude_vc=exclude_vc ) iq_selector = selector.iq it_selector = selector.it # moments are written in the order of atomic types out = {} it = 0 for id, site in enumerate(atoms.sites): iq = id + 1 if iq_selector is not ... and iq not in iq_selector: continue for at in site.occupation: if at.moments is None: if not warned: warnings.warn("Some atomic types do not have moments computed. Skipping.") warned = True continue iqs = out.get(at, None) if iqs is False: continue if iqs is None: it += 1 if it_selector is not ... and it not in it_selector: out[at] = False continue out[at] = iqs = [iq] else: iqs.append(iq) if not out: return False if directory: file_path = Path(directory) / file_name else: file_path = Path(file_name) with file_path.open("w") as momfile: for atomic_type, iqs in out.items(): moment = atomic_type.moments.spin_moment for iq in iqs: momfile.write(MOMFILE_FORMAT.format(iq, 1, moment, 0, 0, 1)) return True