Beispiel #1
0
    def properties(rundir):
        """Report results to properties.calc.json file in configuration directory, after checking for electronic convergence."""

        output = dict()
        ofile = seqquest.seqquest_io.LcaoOUT(os.path.join(rundir, "lcao.out"))
        ogeom = seqquest.seqquest_io.Geom.geom(os.path.join(rundir, "lcao.geom"))

        # the calculation is run on the 'sorted' POSCAR, need to report results 'unsorted'

        output["atom_type"] = ogeom.type_atoms
        output["atoms_per_type"] = ogeom.num_atoms
        output["coord_mode"] = ofile.coord_mode

        # fake unsort_dict (unsort_dict[i] == i)
        unsort_dict = dict(zip(range(0, len(ogeom.basis)), range(0, len(ogeom.basis))))

        # as lists
        output["relaxed_forces"] = [None for i in range(len(ofile.forces))]

        print(noindent.NoIndent(ofile.forces[0]))
        for i, v in enumerate(ofile.forces):
            output["relaxed_forces"][unsort_dict[i]] = noindent.NoIndent(ofile.forces[i])

        output["relaxed_lattice"] = [noindent.NoIndent(v) for v in ofile.cell.lattice]

        output["relaxed_basis"] = [None for i in range(len(ogeom.basis))]
        for i, v in enumerate(ogeom.basis):
            output["relaxed_basis"][unsort_dict[i]] = noindent.NoIndent(ogeom.basis[i].position)

        output["relaxed_energy"] = ofile.total_energy

        return output
Beispiel #2
0
    def properties(qedir, outfilename):
        """Report results to properties.calc.json file in configuration directory, after checking for electronic convergence."""

        output = dict()
        qrun = quantumespresso.qeio.QErun(os.path.join(qedir, outfilename))

        output["atom_type"] = qrun.atom_type
        output["atoms_per_type"] = qrun.atoms_per_type
        if qrun.coord_mode == "crystal":
            output["coord_mode"] = "direct"
        else:
            output["coord_mode"] = "cartesian" + qrun.coord_mode

        output["relaxed_forces"] = [
            noindent.NoIndent(v) for v in list(
                map(
                    lambda y: list(map(lambda x: x * 13.605698066 / 0.52918, y)
                                   ), qrun.forces))
        ]  #convert Ry/bohr to eV/angst

        output["relaxed_lattice"] = [
            noindent.NoIndent(v) for v in list(
                map(lambda y: list(map(lambda x: x * 0.52918, y)),
                    qrun.lattice))
        ]  #convert bohr to angst

        output["relaxed_basis"] = [noindent.NoIndent(v) for v in qrun.basis]

        output[
            "relaxed_energy"] = qrun.total_energy * 13.605698066  #convert Ry to eV

        return output
Beispiel #3
0
def write_eci(proj, eci, fit_details=None, clex=None, verbose=False):
    """Write eci.json

    Arguments
    ---------

    proj: casm.project.Project
        The CASM project

    eci: List[(index, value)]
        List of tuple containing basis function index and coefficient value:

            index (int): linear index of basis function
            value (float): ECI value

    fit_details: Dict
        Description of the fitting method used to generate the ECI, usually as output by `casm.learn.to_json`. It is added to the eci.json file under the attribute `"fit"`.

    clex: casm.project.ClexDescription
        Specifies where to write the ECI. Default value is  `proj.settings.default_clex`.

    """
    dir = proj.dir
    if clex is None:
        clex = proj.settings.default_clex

    # read basis.json
    filename = dir.basis(clex)
    with open(filename, 'r') as f:
        j = json.load(f)

    # edit to add fitting settings
    j["fit"] = fit_details

    # make linear_function_index: (linear_orbit_index, cluster_function_index)
    function_keys = {}
    try:
        linear_orbit_index = 0
        for orbit in j["orbits"]:
            cluster_function_index = 0
            for cluster_function in orbit["cluster_functions"]:
                linear_function_index = cluster_function[
                    "linear_function_index"]
                function_keys[linear_function_index] = (linear_orbit_index,
                                                        cluster_function_index)
                cluster_function_index += 1
            linear_orbit_index += 1
    except:
        raise Exception("Formatting error in basis.json")

    # edit to add eci
    for index, value in eci:
        linear_orbit_index = function_keys[index][0]
        cluster_function_index = function_keys[index][1]
        orbit = j["orbits"][linear_orbit_index]
        cluster_function = orbit["cluster_functions"][cluster_function_index]
        if cluster_function["linear_function_index"] != index:
            msg = "Formatting error in '" + str(filename) + "': "
            msg += " linear_function_index mismatch"
            raise Exception(msg)
        cluster_function["eci"] = value

    # pretty printing -- could be improved
    cspecs_params = j["bspecs"]["cluster_specs"]["params"]
    if "generating_group" in cspecs_params:
        cspecs_params["generating_group"] = noindent.NoIndent(
            cspecs_params["generating_group"])
    for entry in j["orbits"]:
        sites = entry["prototype"]["sites"]
        for i in range(len(sites)):
            sites[i] = noindent.NoIndent(sites[i])
    for site in j["prim"]["basis"]:
        site["coordinate"] = noindent.NoIndent(site["coordinate"])
        site["occupants"] = noindent.NoIndent(site["occupants"])
    for i in range(len(j["prim"]["lattice_vectors"])):
        j["prim"]["lattice_vectors"][i] = noindent.NoIndent(
            j["prim"]["lattice_vectors"][i])

    # write eci.json
    filename = dir.eci(clex)

    if verbose:
        print("Writing:", filename, "\n")
    with open(filename, 'w') as f:
        f.write(json.dumps(j, indent=2, cls=noindent.NoIndentEncoder))

    # refresh proj to reflect new eci
    proj.refresh(clear_clex=True)
Beispiel #4
0
def write_eci(proj, eci, fit_details=None, clex=None, verbose=False):
    """
    Write eci.json
    
    Arguments
    ---------
    
      proj: casm.project.Project instance
        The CASM project
      
      eci: List[(index, value)]
        index (int): linear index of basis function
        value (float): ECI value

      fit_details: Dict
        Description of the fitting method used to generate the ECI,
        usually as output by casm.learn.to_json
      
      clex: ClexDescription instance, optional, default=proj.settings.default_clex
        Specifies where to write the ECI
    
    """
    dir = proj.dir
    if clex is None:
        clex = proj.settings.default_clex

    # read basis.json
    filename = dir.basis(clex)
    with open(filename, 'rb') as f:
        j = json.loads(f.read().decode('utf-8'))
    #print(json.dumps(j, indent=2))

    # edit to add fitting settings
    j["fit"] = fit_details

    # edit to add eci
    for index, value in eci:
        j["cluster_functions"][index]["eci"] = value

    # pretty printing
    for entry in j["site_functions"]:
        if entry["basis"] != None:
            basis = entry["basis"]
            for key, val in basis.items():
                basis[key] = noindent.NoIndent(val)
    for entry in j["cluster_functions"]:
        entry["orbit"] = noindent.NoIndent(entry["orbit"])
        sites = entry["prototype"]["sites"]
        for i in range(len(sites)):
            sites[i] = noindent.NoIndent(sites[i])

    # write eci.json
    filename = dir.eci(clex)

    if verbose:
        print("Writing:", filename, "\n")
    with open(filename, 'wb') as f:
        f.write(
            six.u(json.dumps(j, indent=2,
                             cls=noindent.NoIndentEncoder)).encode('utf-8'))

    # refresh proj to reflect new eci
    proj.refresh(clear_clex=True)
Beispiel #5
0
    def properties(vaspdir, super_poscarfile=None, speciesfile=None):
        """Report results to properties.calc.json file in configuration directory, after checking for electronic convergence."""

        output = dict()
        vrun = vasp.io.Vasprun(os.path.join(vaspdir, "vasprun.xml"))

        # load the final OSZICAR, OUTCAR, and INCAR
        zcar = vasp.io.Oszicar(os.path.join(vaspdir, "OSZICAR"))
        ocar = vasp.io.Outcar(os.path.join(vaspdir, "OUTCAR"))

        # the calculation is run on the 'sorted' POSCAR, need to report results 'unsorted'

        if (super_poscarfile is not None) and (speciesfile is not None):
            species_settings = vasp.io.species_settings(speciesfile)
            super = vasp.io.Poscar(super_poscarfile, species_settings)
            unsort_dict = super.unsort_dict()
        else:
            # fake unsort_dict (unsort_dict[i] == i)
            unsort_dict = dict(
                zip(range(0, len(vrun.basis)), range(0, len(vrun.basis))))
            super = vasp.io.Poscar(os.path.join(vaspdir, "POSCAR"))

        # unsort_dict:
        #   Returns 'unsort_dict', for which: unsorted_dict[orig_index] == sorted_index;
        #   unsorted_dict[sorted_index] == orig_index
        #   For example:
        #     'unsort_dict[0]' returns the index into the unsorted POSCAR of the first atom in the sorted POSCAR

        output["atom_type"] = super.type_atoms
        output["atoms_per_type"] = super.num_atoms
        output["coord_mode"] = vrun.coord_mode

        # as lists
        output["relaxed_forces"] = [None for i in range(len(vrun.forces))]
        for i, v in enumerate(vrun.forces):
            output["relaxed_forces"][unsort_dict[i]] = noindent.NoIndent(
                vrun.forces[i])

        output["relaxed_lattice"] = [
            noindent.NoIndent(v) for v in vrun.lattice
        ]

        output["relaxed_basis"] = [None for i in range(len(vrun.basis))]
        for i, v in enumerate(vrun.basis):
            output["relaxed_basis"][unsort_dict[i]] = noindent.NoIndent(
                vrun.basis[i])

        output["relaxed_energy"] = vrun.total_energy

        # output["relaxed_mag_basis"] = [ None for i in range(len(vrun.basis))]
        # output["relaxed_magmom"] = None
        if ocar.ispin == 2:
            output["relaxed_magmom"] = zcar.mag[-1]
            if ocar.lorbit in [1, 2, 11, 12]:
                output["relaxed_mag_basis"] = [
                    None for i in range(len(vrun.basis))
                ]
                for i, v in enumerate(vrun.basis):
                    output["relaxed_mag_basis"][
                        unsort_dict[i]] = noindent.NoIndent(ocar.mag[i])
        # if output["relaxed_magmom"] is None:
        #     output.pop("relaxed_magmom", None)
        # if output["relaxed_mag_basis"][0] is None:
        #     output.pop("relaxed_mag_basis", None)

        return output
Beispiel #6
0
    def properties(vaspdir, initial_structurefile=None, speciesfile=None):
        """ return a dict of output form a vasp directory"""
        dof_info = attribute_info.AttributeInfo(initial_structurefile)
        output = dict()
        # load the OSZICAR and OUTCAR
        zcar = vasp.io.Oszicar(os.path.join(vaspdir, "OSZICAR"))
        ocar = vasp.io.Outcar(os.path.join(vaspdir, "OUTCAR"))

        # the calculation is run on the 'sorted' POSCAR, need to report results 'unsorted'

        if (initial_structurefile is not None) and (speciesfile is not None):
            species_settings = vasp.io.species_settings(speciesfile)
            initial_structure = vasp.io.Poscar(initial_structurefile,
                                               species_settings)
            unsort_dict = initial_structure.unsort_dict()
        else:
            # fake unsort_dict (unsort_dict[i] == i)
            initial_structure = vasp.io.Poscar(os.path.join(vaspdir, "POSCAR"))
            unsort_dict = dict(
                zip(range(0, len(structure.basis)),
                    range(0, len(structure.basis))))
        contcar = vasp.io.Poscar(os.path.join(vaspdir, "CONTCAR"))

        # unsort_dict:
        #   Returns 'unsort_dict', for which: unsorted_dict[orig_index] == sorted_index;
        #   unsorted_dict[sorted_index] == orig_index
        #   For example:
        #     'unsort_dict[0]' returns the index into the unsorted POSCAR of the first atom in the sorted POSCAR
        output["atom_type"] = initial_structure.atom_type
        #output["atoms_per_type"] = initial_structure.num_atoms
        output["coord_mode"] = contcar.coord_mode

        # as lists
        output["lattice"] = [
            noindent.NoIndent(list(v)) for v in contcar.lattice()
        ]
        output["atom_coords"] = [None for i in range(len(contcar.basis))]
        for i, ba in enumerate(contcar.basis):
            output["atom_coords"][unsort_dict[i]] = noindent.NoIndent(
                list(ba.position))

        output["atom_dofs"] = {}
        output["atom_dofs"]["force"] = {}
        output["atom_dofs"]["force"]["value"] = [
            None for i in range(len(ocar.forces))
        ]
        for i, force in enumerate(ocar.forces):
            output["atom_dofs"]["force"]["value"][
                unsort_dict[i]] = noindent.NoIndent(force)

        output["global_dofs"] = {}
        output["global_dofs"]["energy"] = {}
        output["global_dofs"]["energy"]["value"] = zcar.E[-1]

        if dof_info.atom_dofs is not None:
            if "Cmagspin" in list(dof_info.atom_dofs.keys()):
                output["global_dofs"]["Cmagspin"] = {}
                cmagspin_specific_output = attribute_classes.CmagspinAttr(
                    dof_info).vasp_output_dictionary(ocar)
                output["atom_dofs"].update(cmagspin_specific_output)
                #TODO: Need a better way to write global magmom. I don't like what I did here
                output["global_dofs"]["Cmagspin"]["value"] = zcar.mag[-1]

            #TODO: When you don't have Cmagspin but have magnetic calculations. This part can be removed if you runall magnetic calculations as Cmagspin calculations.
            #TODO: Need a better way of doing this. Some code duplication here.
            else:
                if ocar.ispin == 2:
                    output["global_dofs"]["Cmagspin"] = {}
                    output["global_dofs"]["Cmagspin"]["value"] = zcar.mag[-1]
                    if ocar.lorbit in [1, 2, 11, 12]:
                        output["atom_dofs"]["Cmagspin"] = {}
                        output["atom_dofs"]["Cmagspin"]["value"] = [
                            None for i in range(len(contcar.basis))
                        ]

                        for i, v in enumerate(contcar.basis):
                            output["atom_dofs"]["Cmagspin"]["value"][
                                unsort_dict[i]] = [
                                    noindent.NoIndent(ocar.mag[i])
                                ]

        #TODO: Code duplication here. If you have a magnetic calculation without dofs, you still need to write magmom values. This can be removed if you run all the magnetic calculations as Cmagspin dof calculations.
        #TODO: If you still want to have this particular functionality, wrap it up in a helper function to avoid code duplication.
        else:
            if ocar.ispin == 2:
                output["global_dofs"]["Cmagspin"]["value"] = zcar.mag[-1]
                if ocar.lorbit in [1, 2, 11, 12]:
                    output["atom_dofs"]["Cmagspin"] = {}
                    output["atom_dofs"]["Cmagspin"]["value"] = [
                        None for i in range(len(contcar.basis))
                    ]

                    for i, v in enumerate(contcar.basis):
                        output["atom_dofs"]["Cmagspin"]["value"][
                            unsort_dict[i]] = [noindent.NoIndent(ocar.mag[i])]
        return output