예제 #1
0
def test_magnetism_setup():
    from jarvis.db.figshare import get_jid_data
    from jarvis.core.atoms import get_supercell_dims
    atoms = Atoms.from_dict(
        get_jid_data(jid="JVASP-78681", dataset="dft_3d")["atoms"]
    )
    dim = get_supercell_dims(atoms)
    print("dim=", dim)
    dim = [2, 2, 2]
    symm_list, ss = get_unique_magnetic_structures(
        atoms, supercell_dim=dim, magnetic_ions=["Mn"]
    )
    
    print("dim=", dim, len(symm_list))
    assert len(symm_list)==5
    assert ss.num_atoms == 16
예제 #2
0
def basic_data(data={}, source="JARVIS-FF-LAMMPS"):
    """Get basic data for table."""
    info = {}
    info["id"] = data["jid"]
    info["source_folder"] = data["source_folder"]
    info["tmp_source_folder"] = "'" + data["source_folder"] + "'"
    info["tmp_id"] = "'" + data["jid"] + "'"
    ref = data["source_folder"].split("/")[-1].split("@")[1].split("_")[0]
    info["ref"] = "'" + ref + "'"
    info["jvid"] = get_jvid(ref)
    final_atoms = data["bulk_data"]["final_str"]
    initial_atoms = data["bulk_data"]["initial_str"]
    info["formula"] = final_atoms.composition.reduced_formula
    info["tmp_formula"] = "'" + final_atoms.composition.reduced_formula + "'"
    info["elements"] = ",".join(final_atoms.uniq_species)
    info["tmp_elements"] = "'" + ",".join(final_atoms.uniq_species) + "'"
    info["number_uniq_species"] = len(final_atoms.uniq_species)
    info["data_source"] = source
    info["tmp_data_source"] = "'" + source + "'"
    info["pair_style"] = data["bulk_data"]["pair_style"]
    info["pair_coeff"] = data["bulk_data"]["pair_coeff"]
    # info["pair_coeff"] = (
    #    '<a href="http://www.ctcms.nist.gov/~knc6/DOWNLOADS/'
    #    + data["bulk_data"]["pair_coeff"]
    #    + '.zip">'
    #    + data["bulk_data"]["pair_coeff"]
    #    + "</a>"
    # )
    info["energy_per_atom"] = round(
        float(data["bulk_data"]["energy_per_atom"]), 3)
    info["pressure"] = round(float(data["bulk_data"]["system_pressure"]), 3)

    initial_spg = Spacegroup3D(initial_atoms)
    final_spg = Spacegroup3D(final_atoms)
    info["initial_spacegroup_number"] = initial_spg.space_group_number
    info["initial_spacegroup_symbol"] = initial_spg.space_group_symbol
    info["initial_pointgroup_symbol"] = initial_spg.point_group_symbol
    info["initial_crystal_system"] = initial_spg.crystal_system
    initial_lat_params = initial_atoms.lattice.parameters
    info["initial_a"] = round(initial_lat_params[0], 2)
    info["initial_b"] = round(initial_lat_params[1], 2)
    info["initial_c"] = round(initial_lat_params[2], 2)
    info["initial_alpha"] = round(initial_lat_params[3], 2)
    info["initial_beta"] = round(initial_lat_params[4], 2)
    info["initial_gamma"] = round(initial_lat_params[5], 2)
    info["initial_density"] = round(initial_atoms.density, 3)
    dim = get_supercell_dims(final_atoms)
    info["xyz"] = (
        '"' +
        str(final_atoms.make_supercell_matrix(dim).get_xyz_string).replace(
            "\n", "\\n") + '"')
    info["final_str"] = ('"' +
                         str(final_atoms.get_string()).replace("\n", "\\n") +
                         '"')
    info["initial_str"] = (
        '"' + str(initial_atoms.get_string()).replace("\n", "\\n") + '"')
    final_lat_params = final_atoms.lattice.parameters
    info["final_a"] = round(final_lat_params[0], 2)
    info["final_b"] = round(final_lat_params[1], 2)
    info["final_c"] = round(final_lat_params[2], 2)
    info["final_alpha"] = round(final_lat_params[3], 2)
    info["final_beta"] = round(final_lat_params[4], 2)
    info["final_gamma"] = round(final_lat_params[5], 2)
    info["final_density"] = round(final_atoms.density, 3)

    info["final_spacegroup_number"] = final_spg.space_group_number
    info["final_spacegroup_symbol"] = final_spg.space_group_symbol
    info["final_pointgroup_symbol"] = final_spg.point_group_symbol
    info["final_crystal_system"] = final_spg.crystal_system

    et = ""
    # print(data["bulk_data"]["elastic_tensor"]["raw_et_tensor"])
    try:
        if data["bulk_data"]["elastic_tensor"] != "":
            cij = np.round(
                (data["bulk_data"]["elastic_tensor"]["raw_et_tensor"]), 2)
            et = (
                '<cij>"' +
                ";".join([",".join(map(str, cij[:, i]))
                          for i in range(0, 6)]) + '"</cij>')

    except Exception as exp:
        print("Cannot obtain elastic tensor data.", info["source_folder"], exp)
        pass

    info["elastic_tensor"] = et
    vacancy_line = ""
    if len(data["vacancy_info"]) != 0:
        for i in data["vacancy_info"]:
            vacancy_line += i[0] + "," + i[1] + "," + str(round(i[2], 3)) + ";"
    info["vacancy_info"] = '"' + vacancy_line + '"'

    surf_line = ""
    if len(data["surface_info"]) != 0:
        for i in data["surface_info"]:
            surf_line += i[0] + "," + str(round(i[1], 3)) + ";"
    info["surface_info"] = '"' + surf_line + '"'

    phonon_band_line = ""
    try:
        # Band
        frequencies = data["band_frequencies"]
        distances = data["band_distances"]
        labels = data["band_labels"]
        label_points = data["band_label_points"]

        tmp = ""
        for i in range(np.array(frequencies).shape[1]):
            tmp += ",".join(map(str, np.array(frequencies)[:, i])) + ";"

        phonon_band_line += ("<phonon_bandstructure_distances>'" +
                             ",".join(map(str, distances)) +
                             "'</phonon_bandstructure_distances>")

        phonon_band_line += ("<phonon_bandstructure_frequencies>'" + tmp +
                             "'</phonon_bandstructure_frequencies>")
        phonon_band_line += ("<phonon_bandstructure_labels>'" +
                             ",".join(map(str, labels)) +
                             "'</phonon_bandstructure_labels>")
        phonon_band_line += ("<phonon_bandstructure_label_points>'" +
                             ",".join(map(str, label_points)) +
                             "'</phonon_bandstructure_label_points>")
    except Exception as exp:
        print("Cannot obtain phonon band data.", exp)

    # Comment until 4 MB text size error
    info["phonon_band_line"] = phonon_band_line
    phonon_dos_line = ""
    try:
        freq = data["dos_freq"]
        pdos = data["dos_intensity"]
        phonon_dos_line += ("<phonon_dos_frequencies>'" +
                            ",".join(map(str, freq)) +
                            "'</phonon_dos_frequencies>")

        phonon_dos_line += ("<phonon_dos_intensity>'" +
                            ",".join(map(str, pdos)) +
                            "'</phonon_dos_intensity>")

    except Exception:
        print("Cannot obtain phonon dod data.")
        pass
    info["phonon_dos_line"] = phonon_dos_line

    return info
예제 #3
0
    def from_atoms(
        atoms=None,
        get_prim=False,
        zero_diag=False,
        node_atomwise_angle_dist=False,
        node_atomwise_rdf=False,
        features="basic",
        enforce_c_size=10.0,
        max_n=100,
        max_cut=5.0,
        verbose=False,
        make_colormap=True,
    ):
        """
        Get Networkx graph. Requires Networkx installation.

        Args:
             atoms: jarvis.core.Atoms object.

             rcut: cut-off after which distance will be set to zero
                   in the adjacency matrix.

             features: Node features.
                       'atomic_number': graph with atomic numbers only.
                       'cfid': 438 chemical descriptors from CFID.
                       'basic':10 features
                       'atomic_fraction': graph with atomic fractions
                                         in 103 elements.
                       array: array with CFID chemical descriptor names.
                       See: jarvis/core/specie.py

             enforce_c_size: minimum size of the simulation cell in Angst.
        """
        if get_prim:
            atoms = atoms.get_primitive_atoms
        dim = get_supercell_dims(atoms=atoms, enforce_c_size=enforce_c_size)
        atoms = atoms.make_supercell(dim)

        adj = np.array(atoms.raw_distance_matrix.copy())

        # zero out edges with bond length greater than threshold
        adj[adj >= max_cut] = 0

        if zero_diag:
            np.fill_diagonal(adj, 0.0)
        nodes = np.arange(atoms.num_atoms)
        if features == "atomic_number":
            node_attributes = np.array(
                [[np.array(Specie(i).Z)] for i in atoms.elements],
                dtype="float",
            )
        if features == "atomic_fraction":
            node_attributes = []
            fracs = atoms.composition.atomic_fraction_array
            for i in fracs:
                node_attributes.append(np.array([float(i)]))
            node_attributes = np.array(node_attributes)

        elif features == "basic":
            feats = [
                "Z",
                "coulmn",
                "row",
                "X",
                "atom_rad",
                "nsvalence",
                "npvalence",
                "ndvalence",
                "nfvalence",
                "first_ion_en",
                "elec_aff",
            ]
            node_attributes = []
            for i in atoms.elements:
                tmp = []
                for j in feats:
                    tmp.append(Specie(i).element_property(j))
                node_attributes.append(tmp)
            node_attributes = np.array(node_attributes, dtype="float")
        elif features == "cfid":
            node_attributes = np.array(
                [np.array(Specie(i).get_descrp_arr) for i in atoms.elements],
                dtype="float",
            )
        elif isinstance(features, list):
            node_attributes = []
            for i in atoms.elements:
                tmp = []
                for j in features:
                    tmp.append(Specie(i).element_property(j))
                node_attributes.append(tmp)
            node_attributes = np.array(node_attributes, dtype="float")
        else:
            print("Please check the input options.")
        if node_atomwise_rdf or node_atomwise_angle_dist:
            nbr = NeighborsAnalysis(atoms,
                                    max_n=max_n,
                                    verbose=verbose,
                                    max_cut=max_cut)
        if node_atomwise_rdf:
            node_attributes = np.concatenate(
                (node_attributes, nbr.atomwise_radial_dist()), axis=1)
            node_attributes = np.array(node_attributes, dtype="float")
        if node_atomwise_angle_dist:
            node_attributes = np.concatenate(
                (node_attributes, nbr.atomwise_angle_dist()), axis=1)
            node_attributes = np.array(node_attributes, dtype="float")

        # construct edge list
        uv = []
        edge_features = []
        for ii, i in enumerate(atoms.elements):
            for jj, j in enumerate(atoms.elements):
                bondlength = adj[ii, jj]
                if bondlength > 0:
                    uv.append((ii, jj))
                    edge_features.append(bondlength)

        edge_attributes = edge_features

        if make_colormap:
            sps = atoms.uniq_species
            color_dict = random_colors(number_of_colors=len(sps))
            new_colors = {}
            for i, j in color_dict.items():
                new_colors[sps[i]] = j
            color_map = []
            for ii, i in enumerate(atoms.elements):
                color_map.append(new_colors[i])
        return Graph(
            nodes=nodes,
            edges=uv,
            node_attributes=np.array(node_attributes),
            edge_attributes=np.array(edge_attributes),
            color_map=color_map,
        )
예제 #4
0
def test_basic_atoms():

    box = [[2.715, 2.715, 0], [0, 2.715, 2.715], [2.715, 0, 2.715]]
    coords = [[0, 0, 0], [0.25, 0.2, 0.25]]
    elements = ["Si", "Si"]
    Si = Atoms(lattice_mat=box, coords=coords, elements=elements)
    dim = get_supercell_dims(Si)
    assert dim == [3, 3, 3]
    polar = Si.check_polar
    Si.props = ["a", "a"]
    vac_pad = VacuumPadding(Si)
    den_2d = round(vac_pad.get_effective_2d_slab().density, 2)
    den_0d = round(vac_pad.get_effective_molecule().density, 2)
    den_lll_red = round(Si.get_lll_reduced_structure().density, 2)
    strng = Si.get_string()
    scell_nat = Si.make_supercell([2, 2, 2]).num_atoms
    scell_nat2 = Si.make_supercell_matrix([[2, 0, 0], [0, 2, 0],
                                           [0, 0, 2]]).num_atoms
    # print("scell_nat,scell_nat2", scell_nat, scell_nat2)
    # print(Si.make_supercell([2, 2, 2]))
    # print()
    # print(Si.make_supercell_matrix([[2, 0, 0], [0, 2, 0], [0, 0, 2]]))
    com = round(Si.get_center_of_mass()[0], 3)
    rem = (Si.make_supercell([2, 2, 2]).remove_site_by_index(site=0)).num_atoms
    prim = Si.get_primitive_atoms
    print(prim.cart_coords)
    assert round(prim.cart_coords[0][0], 2) == round(4.37815150, 2)
    # print ('raw_distance_matrix', prim.raw_distance_matrix)
    # print ('raw_distance_matrix', Si.raw_distance_matrix)
    # print ('distance_matrix', Si.pymatgen_converter().distance_matrix)
    assert round(prim.raw_distance_matrix[0][1],
                 2) == round(4.42386329832851, 2)
    print(prim.raw_angle_matrix)
    d = Si.to_dict()
    new_at = Atoms.from_dict(d)
    angs_a = d["angles"][0]
    Si_2_den = Atoms(
        lattice_mat=d["lattice_mat"],
        coords=d["coords"],
        elements=d["elements"],
    ).density
    Si_xyz = Si.get_xyz_string
    Si.write_xyz(filename="atoms.xyz")
    tmp = Atoms.from_xyz(filename="atoms.xyz")
    cmd = 'rm atoms.xyz'
    os.system(cmd)
    Si.center_around_origin()
    # print ('scell_nat', Si_2)
    assert (
        round(Si.volume, 2),
        Si.atomic_numbers,
        Si.num_atoms,
        Si.frac_coords[0][0],
        Si.cart_coords[0][0],
        round(Si.density, 2),
        Si.spacegroup(),
        Si.pymatgen_converter() != {},
        polar,
        Si.props[0],
        den_2d,
        den_0d,
        round(Si.packing_fraction, 2),
        Si.composition.to_dict(),
        strng != "",
        den_lll_red,
        scell_nat,
        com,
        rem,
        angs_a,
        round(Si_2_den, 2),
    ) == (
        40.03,
        [14, 14],
        2,
        0,
        0.0,
        2.33,
        "C2/m (12)",
        True,
        False,
        "a",
        0.35,
        0.01,
        0.28,
        {
            "Si": 2
        },
        True,
        2.33,
        16,
        0.679,
        15,
        60.0,
        2.33,
    )
    cc = Si.center()
    cc = Si.center(axis=[0, 0, 1])

    m1 = Atoms.from_dict(get_jid_data("JVASP-6640")["atoms"])
    assert m1.check_polar == True
    print("Strain test")
    print(m1)
    m1.apply_strain(0.1)
    print(m1)
    assert m1.lattice_mat[2][2] == 32.8717576
    m1.apply_strain([0, 0, 0.1])
    assert m1.lattice_mat[2][2] == 36.158933360000006
    filename = "atoms.cif"
    m1.write_cif(filename)
    a = Atoms.from_cif(filename)
    filename = "POSCAR"
    m1.write_poscar(filename)
    m2 = Atoms.from_poscar(filename)

    filename = "atoms.xyz"
    m1.write_xyz(filename)
    m3 = Atoms.from_xyz(filename)

    cmd = "rm atoms.xyz POSCAR atoms.cif"
    os.system(cmd)
예제 #5
0
    def all_props_eam_alloy(
        self,
        atoms=None,
        ff_path="",
        lammps_cmd="",
        enforce_conventional_structure=True,
        enforce_c_size=0,
        extend=1,
    ):
        """
        Provide generic function for LAMMPS calculations using eam/alloy.

        Must provide Atoms class and path to force-field.
        Args:
            atoms :  Atoms object

            ff_path :  inter-atomic potential path

            lammps_cmd : LAMMPS executable path

            enforce_conventional_structure :
            whether to enforce conventional cell

            enforce_c_size : minimum cell-sizes

            extend : used for round-off during making supercells
        """
        if enforce_conventional_structure:
            atoms = Spacegroup3D(atoms).conventional_standard_structure

        if enforce_c_size is not None:
            dim = get_supercell_dims(atoms, enforce_c_size=enforce_c_size)
            atoms = atoms.make_supercell([dim[0], dim[1], dim[2]])

        self.pair_style = "eam/alloy"
        self.pair_coeff = ff_path
        parameters = {
            "pair_style": self.pair_style,
            "atom_style": "charge",
            "pair_coeff": self.pair_coeff,
        }
        parameters["control_file"] = "inelast.mod"
        en, final_str, forces = LammpsJob(
            atoms=atoms,
            jobname="ELASTIC",
            parameters=parameters,
            lammps_cmd=lammps_cmd,
        ).runjob()
        print("en, final_str, forces", en, final_str, forces)

        indices = symmetrically_distinct_miller_indices(max_index=1,
                                                        cvn_atoms=atoms)
        for i in indices:
            surf = Surface(atoms=final_str, indices=i).make_surface()
            jobname = str("Surf-") + str("_".join(map(str, i)))
            en2, final_str2, forces2 = LammpsJob(
                atoms=surf,
                jobname=jobname,
                parameters=parameters,
                lammps_cmd=lammps_cmd,
            ).runjob()

        # sys.exit()

        v = Vacancy(atoms=final_str).generate_defects(enforce_c_size=5)
        print("vacs=", v)
        for i, ii in enumerate(v):
            jobname = (str("symbol-") + str(ii._symbol) + str("-") +
                       str("Wycoff-") + str(ii._wyckoff_multiplicity))
            print("ii._defect_structure", ii._atoms)
            en2, final_str2, forces2 = LammpsJob(
                atoms=ii._defect_structure,
                jobname=jobname,
                parameters=parameters,
                lammps_cmd=lammps_cmd,
            ).runjob()

        self.phonons(atoms=atoms, lammps_cmd=lammps_cmd, parameters=parameters)
예제 #6
0
    def phonons(self,
                atoms=None,
                lammps_cmd="",
                enforce_c_size=15.0,
                parameters={}):
        """Make Phonon calculation setup."""
        from phonopy import Phonopy
        from phonopy.file_IO import (
            #    parse_FORCE_CONSTANTS,
            write_FORCE_CONSTANTS, )

        bulk = atoms.phonopy_converter()

        dim = get_supercell_dims(atoms, enforce_c_size=enforce_c_size)
        atoms = atoms.make_supercell([dim[0], dim[1], dim[2]])

        Poscar(atoms).write_file("POSCAR")

        atoms = atoms.make_supercell_matrix([dim[0], dim[1], dim[2]])
        Poscar(atoms).write_file("POSCAR-Super.vasp")

        phonon = Phonopy(bulk,
                         [[dim[0], 0, 0], [0, dim[1], 0], [0, 0, dim[2]]])
        print("[Phonopy] Atomic displacements1:", bulk)
        print("[Phonopy] Atomic displacements2:", phonon, dim[0], dim[1],
              dim[2])
        phonon.generate_displacements(distance=0.03)
        disps = phonon.get_displacements()
        print("[Phonopy] Atomic displacements3:", disps)
        for d in disps:
            print("[Phonopy]", d[0], d[1:])
        supercells = phonon.get_supercells_with_displacements()

        # Force calculations by calculator
        set_of_forces = []
        disp = 0
        from ase import Atoms as AseAtoms

        for scell in supercells:
            ase_atoms = AseAtoms(
                symbols=scell.get_chemical_symbols(),
                scaled_positions=scell.get_scaled_positions(),
                cell=scell.get_cell(),
                pbc=True,
            )
            j_atoms = ase_to_atoms(ase_atoms)
            disp = disp + 1

            parameters["control_file"] = "run0.mod"
            a, b, forces = LammpsJob(
                atoms=j_atoms,
                lammps_cmd=lammps_cmd,
                parameters=parameters,
                jobname="disp-" + str(disp),
            ).runjob()
            print("forces=", forces)
            drift_force = forces.sum(axis=0)
            print("drift forces=", drift_force)
            # Simple translational invariance
            for force in forces:
                force -= drift_force / forces.shape[0]
            set_of_forces.append(forces)
        phonon.produce_force_constants(forces=set_of_forces)

        write_FORCE_CONSTANTS(phonon.get_force_constants(),
                              filename="FORCE_CONSTANTS")
        print()
        print("[Phonopy] Phonon frequencies at Gamma:")