コード例 #1
0
ファイル: interface.py プロジェクト: wwmeng/MPInterfaces
 def position_mols(self):
     """
     position the center of masses of the molecules wrt each other
     first movement is in the x direction        
     """
     new_mol = self.mols[0]
     mov_vec = np.array([1, 0, 0])
     for i in range(len(self.mols) - 1):
         # cm1 = new_mol.center_of_mass
         new_cm = new_mol.center_of_mass
         # cm2 = self.mols[i+1].center_of_mass
         new_cm = new_cm + self.cm_dist[i] * mov_vec
         mov_vec = self.get_perp_vec(self.mol_vecs[i], mov_vec)
         mov_vec = mov_vec / np.linalg.norm(mov_vec)
         new_coords = self.mols[i + 1].cart_coords + new_cm
         self.mols[i + 1] = Molecule(
             self.mols[i + 1].species_and_occu,
             new_coords,
             charge=self.mols[i + 1]._charge,
             spin_multiplicity=self.mols[i + 1]._spin_multiplicity,
             site_properties=self.mols[i + 1].site_properties)
         new_mol = Molecule.from_sites(self.mols[i].sites +
                                       self.mols[i + 1].sites,
                                       validate_proximity=True)
コード例 #2
0
ファイル: scripts_utils.py プロジェクト: zooks97/pymatgen
def visualize(cg, zoom=None, vis=None, myfactor=1.0, view_index=True, faces_color_override=None):
    """
    Visualizing a coordination geometry
    :param cg:
    :param zoom:
    :param vis:
    :param myfactor:
    :param view_index:
    :param faces_color_override:
    :return:
    """
    if vis is None:
        vis = StructureVis(show_polyhedron=False, show_unit_cell=False)
    myspecies = ["O"] * (cg.coordination_number + 1)
    myspecies[0] = "Cu"
    coords = [np.zeros(3, np.float_) + cg.central_site]

    for pp in cg.points:
        coords.append(np.array(pp) + cg.central_site)
    coords = [cc * myfactor for cc in coords]
    structure = Molecule(species=myspecies, coords=coords)
    vis.set_structure(structure=structure, reset_camera=True)
    # neighbors_list = coords[1:]
    draw_cg(
        vis,
        site=structure[0],
        neighbors=structure[1:],
        cg=cg,
        faces_color_override=faces_color_override,
    )
    if view_index:
        for ineighbor, neighbor in enumerate(structure[1:]):
            vis.add_text(neighbor.coords, "{}".format(ineighbor), color=(0, 0, 0))
    if zoom is not None:
        vis.zoom(zoom)
    return vis
コード例 #3
0
def reoriented_molecule(mol, nested=False):
    """
    Reorient a molecule so that its principal axes are aligned with the
    identity matrix.

    Args:
        mol: a Molecule object
        nested: keep track of how many times the function
            has been called recursively

    Returns:
        new_mol: a reoriented copy of the original molecule. 
        P: the 3x3 rotation matrix used to obtain it.
    """
    coords = mol.cart_coords
    numbers = mol.atomic_numbers
    coords -= np.mean(coords, axis=0)
    A = get_inertia_tensor(coords)
    # Store the eigenvectors of the inertia tensor
    P = np.linalg.eigh(A)[1]
    if np.linalg.det(P) < 0:
        P[0] *= -1
    coords = np.dot(coords, P)
    return Molecule(numbers, coords), P
コード例 #4
0
ファイル: io.py プロジェクト: gipfeli/PyXtal
    def match(self):
        """
        Check the two molecular graphs are isomorphic
        """
        match, mapping = compare_mol_connectivity(self.ref_mol, self.molecule)
        if not match:
            print(self.ref_mol.to("xyz"))
            print(self.molecule.to("xyz"))
            import pickle
            with open('wrong.pkl', "wb") as f:
                pickle.dump([self.ref_mol, self.molecule], f)

            return False
        else:
            # resort the atomic number for molecule 1
            order = [mapping[i] for i in range(len(self.ref_mol))]
            numbers = np.array(self.molecule.atomic_numbers)
            numbers = numbers[order].tolist()
            coords = self.molecule.cart_coords[order]
            position = np.mean(coords, axis=0).dot(self.lattice.inv_matrix)
            position -= np.floor(position)
            # check if molecule is on the special wyckoff position
            if len(self.pmg_struc) / len(self.molecule) < len(self.wyc):
                if self.diag:
                    #Transform it to the conventional representation
                    position = np.dot(self.perm, position).T
                position, wp, _ = WP_merge(position, self.lattice.matrix,
                                           self.wyc, 2.0)
                #print("After Mergey:---------------")
                #print(position)
                #print(wp)
                self.wyc = wp
            self.position = position
            self.molecule = Molecule(numbers, coords - np.mean(coords, axis=0))
            #self.align()
            return True
コード例 #5
0
    def from_string(contents):
        """
        Creates XYZ object from a string.

        Args:
            contents:
                String representing an XYZ file.

        Returns:
            XYZ object
        """
        lines = contents.split("\n")
        num_sites = int(lines[0])
        coords = []
        sp = []
        coord_patt = re.compile(
            "(\w+)\s+([0-9\-\.]+)\s+([0-9\-\.]+)\s+([0-9\-\.]+)"
        )
        for i in xrange(2, 2 + num_sites):
            m = coord_patt.search(lines[i])
            if m:
                sp.append(m.group(1))  # this is 1-indexed
                coords.append(map(float, m.groups()[1:4]))  # this is 0-indexed
        return XYZ(Molecule(sp, coords))
コード例 #6
0
ファイル: pymatgen.py プロジェクト: bjmorgan/bsym
def configuration_space_from_molecule(molecule, subset=None, atol=1e-5):
    """
    Generate a ``ConfigurationSpace`` object from a `pymatgen` ``Molecule``.

    Args:
        molecule  (pymatgen ``Molecule``):  molecule to be used to define the :any:`ConfigurationSpace`.
        subset    (Optional [list]):        list of atom indices to be used for generating the configuration space.
        atol      (Optional [float]):       tolerance factor for the ``pymatgen`` `coordinate mapping`_ under each symmetry operation.
        
    Returns:
        a new :any:`ConfigurationSpace` instance.

    .. _coordinate mapping:
        http://pymatgen.org/pymatgen.util.coord_utils.html#pymatgen.util.coord_utils.coord_list_mapping

    """
    molecule = Molecule(molecule.species,
                        molecule.cart_coords - molecule.center_of_mass)
    point_group = point_group_from_molecule(molecule, subset=subset, atol=atol)
    if subset is None:
        subset = list(range(1, len(molecule) + 1))
    config_space = ConfigurationSpace(objects=subset,
                                      symmetry_group=point_group)
    return config_space
コード例 #7
0
ファイル: interface.py プロジェクト: matk86/MPInterfaces
# test
if __name__ == '__main__':
    # the following example require:
    # acetic_acid.xyz and POSCAR.mp-21276_PbS

    # create lead acetate ligand
    # from 3 molecules: 2 acetic acid + 1 Pb
    import os

    PACKAGE_PATH = os.path.dirname(__file__)

    mol0 = Molecule.from_file(
        os.path.join(PACKAGE_PATH, "test_files", "acetic_acid.xyz"))
    mol1 = Molecule.from_file(
        os.path.join(PACKAGE_PATH, "test_files", "acetic_acid.xyz"))
    mol2 = Molecule(["Pb"], [[0, 0, 0]])
    mols = [mol0, mol1, mol2]
    # center of mass distances in angstrom
    # example: 3 molecules and cm_dist = [4,2],
    # center of mass of mol1 is moved from mol0 in 1,0,0 direction by 4 A
    # mol2 is moved from the center of mass of the combined mol0+mol1 molecule by 2 A
    # in a direction that is perpendicular to the first moving direction and the
    # molecule vector of one of the molecules
    # for n molecules the size of cm_dist must be n-1
    cm_dist = [1, 2]

    # optional parmater
    # example: angle={'0':{}, '1':{'0':90}, '2':{} }
    # rotate mol1 with respect to mol0 by 90 degreeen around and axis that is normal
    # to the plane containing the molecule vectors of mol0 and mol1
    angle = {'0': {}, '1': {'0': 90}, '2': {}}
コード例 #8
0
ファイル: test_analyzer.py プロジェクト: zbwang/pymatgen
                                      0.001).get_space_group_operations()

    def test_are_symmetrically_equivalent(self):
        sites1 = [self.structure[i] for i in [0, 1]]
        sites2 = [self.structure[i] for i in [2, 3]]
        self.assertTrue(
            self.sg1.are_symmetrically_equivalent(sites1, sites2, 1e-3))

        sites1 = [self.structure[i] for i in [0, 1]]
        sites2 = [self.structure[i] for i in [0, 2]]
        self.assertFalse(
            self.sg1.are_symmetrically_equivalent(sites1, sites2, 1e-3))


H2O2 = Molecule(
    ["O", "O", "H", "H"],
    [[0, 0.727403, -0.050147], [0, -0.727403, -0.050147],
     [0.83459, 0.897642, 0.401175], [-0.83459, -0.897642, 0.401175]])

C2H2F2Br2 = Molecule(
    ["C", "C", "F", "Br", "H", "F", "H", "Br"],
    [[-0.752000, 0.001000, -0.141000], [0.752000, -0.001000, 0.141000],
     [-1.158000, 0.991000, 0.070000], [-1.240000, -0.737000, 0.496000],
     [-0.924000, -0.249000, -1.188000], [1.158000, -0.991000, -0.070000],
     [0.924000, 0.249000, 1.188000], [1.240000, 0.737000, -0.496000]])

H2O = Molecule(
    ["H", "O", "H"],
    [[0, 0.780362, -.456316], [0, 0, .114079], [0, -.780362, -.456316]])

C2H4 = Molecule(["C", "C", "H", "H", "H", "H"],
                [[0.0000, 0.0000, 0.6695], [0.0000, 0.0000, -0.6695],
コード例 #9
0
    def from_string(cls, string_input):
        """
        Read an NwInput from a string. Currently tested to work with
        files generated from this class itself.

        Args:
            string_input: string_input to parse.

        Returns:
            NwInput object
        """
        directives = []
        tasks = []
        charge = None
        spin_multiplicity = None
        title = None
        basis_set = None
        basis_set_option = None
        theory_directives = {}
        geom_options = None
        symmetry_options = None
        memory_options = None
        lines = string_input.strip().split("\n")
        while len(lines) > 0:
            l = lines.pop(0).strip()
            if l == "":
                continue

            toks = l.split()
            if toks[0].lower() == "geometry":
                geom_options = toks[1:]
                l = lines.pop(0).strip()
                toks = l.split()
                if toks[0].lower() == "symmetry":
                    symmetry_options = toks[1:]
                    l = lines.pop(0).strip()
                # Parse geometry
                species = []
                coords = []
                while l.lower() != "end":
                    toks = l.split()
                    species.append(toks[0])
                    coords.append([float(i) for i in toks[1:]])
                    l = lines.pop(0).strip()
                mol = Molecule(species, coords)
            elif toks[0].lower() == "charge":
                charge = int(toks[1])
            elif toks[0].lower() == "title":
                title = l[5:].strip().strip("\"")
            elif toks[0].lower() == "basis":
                # Parse basis sets
                l = lines.pop(0).strip()
                basis_set = {}
                while l.lower() != "end":
                    toks = l.split()
                    basis_set[toks[0]] = toks[-1].strip("\"")
                    l = lines.pop(0).strip()
            elif toks[0].lower() in NwTask.theories:
                # read the basis_set_option
                if len(toks) > 1:
                    basis_set_option = toks[1]
                # Parse theory directives.
                theory = toks[0].lower()
                l = lines.pop(0).strip()
                theory_directives[theory] = {}
                while l.lower() != "end":
                    toks = l.split()
                    theory_directives[theory][toks[0]] = toks[-1]
                    if toks[0] == "mult":
                        spin_multiplicity = float(toks[1])
                    l = lines.pop(0).strip()
            elif toks[0].lower() == "task":
                tasks.append(
                    NwTask(charge=charge,
                           spin_multiplicity=spin_multiplicity,
                           title=title, theory=toks[1],
                           operation=toks[2], basis_set=basis_set,
                           basis_set_option=basis_set_option,
                           theory_directives=theory_directives.get(toks[1])))
            elif toks[0].lower() == "memory":
                    memory_options = ' '.join(toks[1:])
            else:
                directives.append(l.strip().split())

        return NwInput(mol, tasks=tasks, directives=directives,
                       geometry_options=geom_options,
                       symmetry_options=symmetry_options,
                       memory_options=memory_options)
コード例 #10
0
    def test_multi_job_string(self):
        species = [
            "S",
            "C",
            "H",
            "C",
            "H",
            "C",
            "H",
            "C",
            "C",
            "C",
            "H",
            "C",
            "H",
            "C",
            "H",
            "S",
        ]
        coords = [
            [-0.00250959, -0.05817469, -0.02921636],
            [1.70755408, -0.03033788, -0.01382912],
            [2.24317221, -0.05215019, 0.92026728],
            [2.21976393, 0.01718014, -1.27293235],
            [3.27786220, 0.04082146, -1.48539646],
            [1.20867399, 0.04478540, -2.27007793],
            [1.40292257, 0.10591684, -3.33110912],
            [-0.05341046, 0.01577217, -1.74839343],
            [-1.32843436, 0.03545064, -2.45531187],
            [-1.55195156, 0.08743920, -3.80184635],
            [-0.75245172, 0.10267657, -4.52817967],
            [-2.93293778, 0.08408786, -4.13352169],
            [-3.31125108, 0.11340328, -5.14405819],
            [-3.73173288, 0.02741365, -3.03412864],
            [-4.80776535, 0.00535688, -2.99564645],
            [-2.81590978, -0.00516172, -1.58990580],
        ]
        molecule_1 = Molecule(species, coords)
        rem_1 = {
            "jobtype": "opt",
            "method": "wb97m-v",
            "basis": "def2-tzvppd",
            "gen_scfman": "true",
            "geom_opt_max_cycles": "75",
            "max_scf_cycles": "300",
            "scf_algorithm": "diis",
            "scf_guess": "sad",
            "sym_ignore": "true",
            "symmetry": "false",
            "thresh": "14",
        }
        opt_1 = {"CONSTRAINT": ["tors 6 8 9 10 0.0"]}
        job_1 = QCInput(molecule=molecule_1, rem=rem_1, opt=opt_1)
        molecule_2 = "read"
        rem_2 = {
            "jobtype": "sp",
            "method": "wb97m-v",
            "basis": "def2-tzvppd",
            "gen_scfman": "true",
            "geom_opt_max_cycles": "75",
            "max_scf_cycles": "300",
            "scf_algorithm": "diis",
            "scf_guess": "read",
            "sym_ignore": "true",
            "symmetry": "false",
            "thresh": "14",
        }
        job_2 = QCInput(molecule=molecule_2, rem=rem_2)
        job_list = [job_1, job_2]
        multi_job_str_test = QCInput.multi_job_string(
            job_list=job_list).split("\n")
        multi_job_str_actual_list = [
            "$molecule",
            " 0 1",
            " S     -0.0025095900     -0.0581746900     -0.0292163600",
            " C      1.7075540800     -0.0303378800     -0.0138291200",
            " H      2.2431722100     -0.0521501900      0.9202672800",
            " C      2.2197639300      0.0171801400     -1.2729323500",
            " H      3.2778622000      0.0408214600     -1.4853964600",
            " C      1.2086739900      0.0447854000     -2.2700779300",
            " H      1.4029225700      0.1059168400     -3.3311091200",
            " C     -0.0534104600      0.0157721700     -1.7483934300",
            " C     -1.3284343600      0.0354506400     -2.4553118700",
            " C     -1.5519515600      0.0874392000     -3.8018463500",
            " H     -0.7524517200      0.1026765700     -4.5281796700",
            " C     -2.9329377800      0.0840878600     -4.1335216900",
            " H     -3.3112510800      0.1134032800     -5.1440581900",
            " C     -3.7317328800      0.0274136500     -3.0341286400",
            " H     -4.8077653500      0.0053568800     -2.9956464500",
            " S     -2.8159097800     -0.0051617200     -1.5899058000",
            "$end",
            "$rem",
            "   job_type = opt",
            "   method = wb97m-v",
            "   basis = def2-tzvppd",
            "   gen_scfman = true",
            "   geom_opt_max_cycles = 75",
            "   max_scf_cycles = 300",
            "   scf_algorithm = diis",
            "   scf_guess = sad",
            "   sym_ignore = true",
            "   symmetry = false",
            "   thresh = 14",
            "$end",
            "$opt",
            "CONSTRAINT",
            "   tors 6 8 9 10 0.0",
            "ENDCONSTRAINT",
            "$end",
            "@@@",
            "$molecule",
            " read",
            "$end",
            "$rem",
            "   job_type = opt",
            "   method = wb97m-v",
            "   basis = def2-tzvppd",
            "   gen_scfman = true",
            "   geom_opt_max_cycles = 75",
            "   max_scf_cycles = 300",
            "   scf_algorithm = diis",
            "   scf_guess = sad",
            "   sym_ignore = true",
            "   symmetry = false",
            "   thresh = 14",
            "$end",
        ]

        for i_str in multi_job_str_actual_list:
            self.assertIn(i_str, multi_job_str_test)
コード例 #11
0
ファイル: fiesta.py プロジェクト: rakesharya21/NanoGen
    def from_string(cls, string_input):
        """
        Read an FiestaInput from a string. Currently tested to work with
        files generated from this class itself.

        Args:
            string_input: string_input to parse.
        Returns:
            FiestaInput object
        """

        correlation_grid = {}
        Exc_DFT_option = {}
        COHSEX_options = {}
        GW_options = {}
        BSE_TDDFT_options = {}

        lines = string_input.strip().split("\n")

        # number of atoms and species
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        nat = toks[0]
        nsp = toks[1]
        # number of valence bands
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        nvbands = toks[0]

        # correlation_grid
        # number of points and spacing in eV for correlation grid
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        correlation_grid['n_grid'] = toks[0]
        correlation_grid['dE_grid'] = toks[1]

        # Exc DFT
        # relire=1 ou recalculer=0 Exc DFT
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        Exc_DFT_option['rdVxcpsi'] = toks[0]

        # COHSEX
        # number of COHSEX corrected occp and unoccp bands: C=COHSEX  H=HF
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        COHSEX_options['nv_cohsex'] = toks[0]
        COHSEX_options['nc_cohsex'] = toks[1]
        COHSEX_options['eigMethod'] = toks[2]
        # number of COHSEX iter, scf on wfns, mixing coeff; V=RI-V  I=RI-D
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        COHSEX_options['nit_cohsex'] = toks[0]
        COHSEX_options['resMethod'] = toks[1]
        COHSEX_options['scf_cohsex_wf'] = toks[2]
        COHSEX_options['mix_cohsex'] = toks[3]

        # GW
        # number of GW corrected occp and unoccp bands
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        GW_options['nv_corr'] = toks[0]
        GW_options['nc_corr'] = toks[1]
        # number of GW iterations
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        GW_options['nit_gw'] = toks[0]

        # BSE
        # dumping for BSE and TDDFT
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        BSE_TDDFT_options['do_bse'] = toks[0]
        BSE_TDDFT_options['do_tddft'] = toks[1]
        # number of occp. and virtual bands fo BSE: nocore and up to 40 eVs
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        BSE_TDDFT_options['nv_bse'] = toks[0]
        BSE_TDDFT_options['nc_bse'] = toks[1]
        # number of excitations needed and number of iterations
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        BSE_TDDFT_options['npsi_bse'] = toks[0]
        BSE_TDDFT_options['nit_bse'] = toks[1]

        # Molecule
        # list of symbols in order
        lines.pop(0)
        atname = []
        i = int(nsp)
        while i != 0:
            l = lines.pop(0).strip()
            toks = l.split()
            atname.append(toks[0])
            i -= 1

        # scaling factor
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        scale = toks[0]
        # atoms x,y,z cartesian .. will be multiplied by scale
        lines.pop(0)
        # Parse geometry
        species = []
        coords = []
        i = int(nat)
        while i != 0:
            l = lines.pop(0).strip()
            toks = l.split()
            coords.append([float(j) for j in toks[0:3]])
            species.append(atname[int(toks[3]) - 1])
            i -= 1

        mol = Molecule(species, coords)

        return FiestaInput(mol=mol,
                           correlation_grid=correlation_grid,
                           Exc_DFT_option=Exc_DFT_option,
                           COHSEX_options=COHSEX_options,
                           GW_options=GW_options,
                           BSE_TDDFT_options=BSE_TDDFT_options)
コード例 #12
0
    import openbabel as ob
except ImportError:
    ob = None

__author__ = "Evan Spotte-Smith"
__version__ = "0.1"
__maintainer__ = "Evan Spotte-Smith"
__email__ = "*****@*****.**"
__status__ = "Alpha"
__date__ = "September 2019"

module_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)))

# Not real molecules; just place-holders
# We're only interested in the math
mol_placeholder = Molecule(["H"], [[0.0, 0.0, 0.0]])


class ReactionRateCalculatorTest(unittest.TestCase):
    def setUp(self) -> None:
        if ob:
            self.energies = [
                -271.553636516598, -78.5918513462683, -350.105998350078
            ]
            self.enthalpies = [13.917, 34.596, 49.515]
            self.entropies = [67.357, 55.047, 84.265]

            self.rct_1 = MoleculeEntry(
                mol_placeholder,
                self.energies[0],
                enthalpy=self.enthalpies[0],
コード例 #13
0
ファイル: mopacio.py プロジェクト: rkingsbury/rubicon
    def _parse_molecule(cls, contents):
        """
        Helper method to parse coordinates of Molecule. Copied from GaussianInput class.
        """
        paras = {}
        var_pattern = re.compile("^([A-Za-z]+\S*)[\s=,]+([\d\-\.]+)$")
        for l in contents:
            m = var_pattern.match(l.strip())
            if m:
                paras[m.group(1)] = float(m.group(2))

        species = []
        coords = []
        # Stores whether a Zmatrix format is detected. Once a zmatrix format
        # is detected, it is assumed for the remaining of the parsing.
        zmode = False
        for l in contents:
            l = l.strip()
            if not l:
                break
            if (not zmode) and cls.xyz_patt.match(l):
                m = cls.xyz_patt.match(l)
                species.append(m.group(1))
                toks = re.split("[,\s]+", l.strip())
                if len(toks) > 4:
                    coords.append(list(map(float, toks[2:5])))
                else:
                    coords.append(list(map(float, toks[1:4])))
            elif cls.zmat_patt.match(l):
                zmode = True
                toks = re.split("[,\s]+", l.strip())
                species.append(toks[0])
                toks.pop(0)
                if len(toks) == 0:
                    coords.append(np.array([0.0, 0.0, 0.0]))
                else:
                    nn = []
                    parameters = []
                    while len(toks) > 1:
                        ind = toks.pop(0)
                        data = toks.pop(0)
                        try:
                            nn.append(int(ind))
                        except ValueError:
                            nn.append(species.index(ind) + 1)
                        try:
                            val = float(data)
                            parameters.append(val)
                        except ValueError:
                            if data.startswith("-"):
                                parameters.append(-paras[data[1:]])
                            else:
                                parameters.append(paras[data])
                    if len(nn) == 1:
                        coords.append(np.array(
                            [0.0, 0.0, float(parameters[0])]))
                    elif len(nn) == 2:
                        coords1 = coords[nn[0] - 1]
                        coords2 = coords[nn[1] - 1]
                        bl = parameters[0]
                        angle = parameters[1]
                        axis = [0, 1, 0]
                        op = SymmOp.from_origin_axis_angle(coords1, axis,
                                                           angle, False)
                        coord = op.operate(coords2)
                        vec = coord - coords1
                        coord = vec * bl / np.linalg.norm(vec) + coords1
                        coords.append(coord)
                    elif len(nn) == 3:
                        coords1 = coords[nn[0] - 1]
                        coords2 = coords[nn[1] - 1]
                        coords3 = coords[nn[2] - 1]
                        bl = parameters[0]
                        angle = parameters[1]
                        dih = parameters[2]
                        v1 = coords3 - coords2
                        v2 = coords1 - coords2
                        axis = np.cross(v1, v2)
                        op = SymmOp.from_origin_axis_angle(
                            coords1, axis, angle, False)
                        coord = op.operate(coords2)
                        v1 = coord - coords1
                        v2 = coords1 - coords2
                        v3 = np.cross(v1, v2)
                        adj = get_angle(v3, axis)
                        axis = coords1 - coords2
                        op = SymmOp.from_origin_axis_angle(
                            coords1, axis, dih - adj, False)
                        coord = op.operate(coord)
                        vec = coord - coords1
                        coord = vec * bl / np.linalg.norm(vec) + coords1
                        coords.append(coord)

        def parse_species(sp_str):
            """
            The species specification can take many forms. E.g.,
            simple integers representing atomic numbers ("8"),
            actual species string ("C") or a labelled species ("C1").
            Sometimes, the species string is also not properly capitalized,
            e.g, ("c1"). This method should take care of these known formats.
            """
            try:
                return int(sp_str)
            except ValueError:
                sp = re.sub("\d", "", sp_str)
                return sp.capitalize()

        species = list(map(parse_species, species))

        return Molecule(species, coords)
コード例 #14
0
ファイル: io.py プロジェクト: gipfeli/PyXtal
    def __init__(self, struc, ref_mol=None, tol=0.2, relax_h=False):
        """
        extract the mol_site information from the give cif file 
        and reference molecule
    
        Args: 
            struc: cif/poscar file or a Pymatgen Structure object
            ref_mol: xyz file or a reference Pymatgen molecule object
            tol: scale factor for covalent bond distance
            relax_h: whether or not relax the position for hydrogen atoms in structure
        
    """
        if isinstance(ref_mol, str):
            ref_mol = Molecule.from_file(ref_mol)
        elif isinstance(ref_mol, Molecule):
            ref_mol = ref_mol
        else:
            print(type(ref_mol))
            raise NameError("reference molecule cannot be defined")

        if isinstance(struc, str):
            pmg_struc = Structure.from_file(struc)
        elif isinstance(struc, Structure):
            pmg_struc = struc
        else:
            print(type(struc))
            raise NameError("input structure cannot be intepretted")

        self.props = ref_mol.site_properties
        self.ref_mol = ref_mol.get_centered_molecule()
        self.tol = tol
        self.diag = False
        self.relax_h = relax_h

        sga = SpacegroupAnalyzer(pmg_struc)
        ops = sga.get_space_group_operations()
        self.wyc, perm = Wyckoff_position.from_symops(
            ops, sga.get_space_group_number())

        if self.wyc is not None:
            self.group = Group(self.wyc.number)
            if isinstance(perm, list):
                if perm != [0, 1, 2]:
                    lattice = Lattice.from_matrix(pmg_struc.lattice.matrix,
                                                  self.group.lattice_type)
                    latt = lattice.swap_axis(ids=perm,
                                             random=False).get_matrix()
                    coor = pmg_struc.frac_coords[:, perm]
                    pmg_struc = Structure(latt, pmg_struc.atomic_numbers, coor)
            else:
                self.diag = True
                self.perm = perm

            coords, numbers = search_molecule_in_crystal(pmg_struc, self.tol)
            #coords -= np.mean(coords, axis=0)
            if self.relax_h:
                self.molecule = self.addh(Molecule(numbers, coords))
            else:
                self.molecule = Molecule(numbers, coords)
            self.pmg_struc = pmg_struc
            self.lattice = Lattice.from_matrix(pmg_struc.lattice.matrix,
                                               self.group.lattice_type)
        else:
            raise ValueError(
                "Cannot find the space group matching the symmetry operation")
コード例 #15
0
    def fit_with_mapper(self, mapper):
        coords = [[0.000000, 0.000000, 0.000000],
                  [0.000000, 0.000000, 1.089000],
                  [1.026719, 0.000000, -0.363000],
                  [-0.513360, -0.889165, -0.363000],
                  [-0.513360, 0.889165, -0.363000]]
        mol1 = Molecule(["C", "H", "H", "H", "H"], coords)
        op = SymmOp.from_origin_axis_angle([0, 0, 0], [0.1, 0.2, 0.3], 60)
        rotcoords = [op.operate(c) for c in coords]
        mol2 = Molecule(["C", "H", "H", "H", "H"], rotcoords)
        mm = MoleculeMatcher(mapper=mapper)
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "benzene1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "benzene2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "benzene1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "t2.xyz")).pymatgen_mol
        self.assertFalse(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "c1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "c2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "t3.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "t4.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "j1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "j2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "ethene1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "ethene2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "toluene1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "toluene2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(
            os.path.join(test_dir, "cyclohexane1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(
            os.path.join(test_dir, "cyclohexane2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mol1 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "oxygen1.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(
            test_dir, "oxygen2.xyz")).pymatgen_mol
        self.assertTrue(mm.fit(mol1, mol2))

        mm = MoleculeMatcher(tolerance=0.001, mapper=mapper)
        mol1 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "t3.xyz")).pymatgen_mol
        mol2 = BabelMolAdaptor.from_file(os.path.join(test_dir,
                                                      "t4.xyz")).pymatgen_mol
        self.assertFalse(mm.fit(mol1, mol2))
コード例 #16
0
 def test_init(self):
     mol = Molecule(["C", "H", "H", "H", "H"], self.coords)
     cellin = FiestaInput(mol)
     self.assertEqual(cellin.molecule.spin_multiplicity, 1)
コード例 #17
0
ファイル: test_inputs.py プロジェクト: janosh/pymatgen
from pymatgen.util.testing import PymatgenTest

Si_structure = Structure(
    lattice=[[0, 2.734364, 2.734364], [2.734364, 0, 2.734364],
             [2.734364, 2.734364, 0]],
    species=["Si", "Si"],
    coords=[[0, 0, 0], [0.25, 0.25, 0.25]],
)

nonsense_Structure = Structure(
    lattice=[[-1.0, -10.0, -100.0], [0.1, 0.01, 0.001], [7.0, 11.0, 21.0]],
    species=["H"],
    coords=[[-1, -1, -1]],
)

molecule = Molecule(species=["C", "H"], coords=[[0, 0, 0], [1, 1, 1]])


class InputTest(PymatgenTest):
    def setUp(self):
        self.TEST_FILES_DIR = Path.joinpath(self.TEST_FILES_DIR, "cp2k")
        self.ci = Cp2kInput.from_file(
            Path.joinpath(self.TEST_FILES_DIR, "cp2k.inp"))

    def test_basic_sections(self):
        s = """
        &GLOBAL
            RUN_TYPE ENERGY
            PROJECT_NAME CP2K ! default name
        &END
        """
コード例 #18
0
ファイル: mopacio.py プロジェクト: rkingsbury/rubicon
    def _parse_job(cls, output):
        heat_pattern = re.compile(
            "FINAL HEAT OF FORMATION =\s+(?P<energy>-?\d+\.\d+)\s+KCAL/MOL")
        total_energy_pattern = re.compile(
            "TOTAL ENERGY\s+=\s+(?P<energy>-\d+\.\d+)\s+EV")
        coord_pattern = re.compile("\s*\d+\s+(?P<element>[A-Z][a-z]*)\s+"
                                   "(?P<x>\-?\d+\.\d+)\s+"
                                   "(?P<y>\-?\d+\.\d+)\s+"
                                   "(?P<z>\-?\d+\.\d+)")
        error_defs = (
            (re.compile("EXCESS NUMBER OF OPTIMIZATION CYCLES"),
             "Geometry optimization failed"),
            (re.compile("UNABLE TO ACHIEVE SELF-CONSISTENCE"),
             "Bad SCF convergence"),
            (re.compile("TO CONTINUE, START AGAIN WITH THE WORD \"PRECISE\""),
             "Not Accurate Enough")
        )
        energies = []
        parse_keywords = None
        result_section = False
        star_line_count = 0
        parse_coords = False
        input_keywords = None
        jobtype = None
        gracefully_terminated = False
        errors = set()
        coords = []
        species = []
        molecules = []
        for line in output.split('\n'):
            for ep, message in error_defs:
                if ep.search(line):
                    errors.add(message)
            if parse_keywords and input_keywords is None:
                input_keywords = MopTask._parse_keywords([line])
                jobtext = (set(
                    input_keywords.keys()) & MopTask.available_sqm_tasktext).pop()
                jobtype = MopTask.jobtext2type[jobtext]
                parse_keywords = False
            if result_section and "*" * 50 in line:
                star_line_count += 1
                if star_line_count == 2:
                    parse_keywords = True
            if "PM7 CALCULATION RESULTS" in line:
                result_section = True
            if parse_coords:
                if "ATOM" in line:
                    continue
                if len(line.strip()) == 0:
                    if len(coords) == 0:
                        continue
                    else:
                        parse_coords = False
                        molecules.append(Molecule(species, coords))
                        species = None
                        coords = None
                        continue
                m = coord_pattern.match(line)
                coords.append([float(m.group("x")), float(m.group("y")),
                               float(m.group("z"))])
                species.append(m.group("element"))
            if "CARTESIAN COORDINATES" in line:
                parse_coords = True
                coords = []
                species = []
            m = heat_pattern.search(line)
            if m:
                heat_of_formation = float(
                    m.group("energy")) * cls.kcal_per_mol_2_eV
                energies.append(
                    tuple(["Heat of Formation", heat_of_formation]))
            m = total_energy_pattern.search(line)
            if m:
                total_energy = float(m.group("energy"))
                energies.append(tuple(["Total Energy", total_energy]))
            if "== MOPAC DONE ==" in line:
                gracefully_terminated = True

        if len(errors) == 0:
            for text in cls._expected_successful_pattern(input_keywords):
                sucess_pattern = re.compile(text)
                if not sucess_pattern.search(output):
                    errors.add("Can't find text to indicate success")

        errors = list(errors)
        data = {
            "jobtype": jobtype,
            "energies": energies,
            "molecules": molecules,
            "errors": errors,
            "has_error": len(errors) > 0,
            "gracefully_terminated": gracefully_terminated
        }
        return data
コード例 #19
0
    def test_split(self):
        bonds = [(0, 1), (4, 5)]
        alterations = {
            (2, 3): {
                "weight": 1.0
            },
            (0, 5): {
                "weight": 2.0
            },
            (1, 2): {
                "weight": 2.0
            },
            (3, 4): {
                "weight": 2.0
            },
        }
        # Perform retro-Diels-Alder reaction - turn product into reactants
        reactants = self.cyclohexene.split_molecule_subgraphs(
            bonds, allow_reverse=True, alterations=alterations)
        self.assertTrue(isinstance(reactants, list))

        reactants = sorted(reactants, key=len)
        # After alterations, reactants sholuld be ethylene and butadiene
        self.assertEqual(reactants[0], self.ethylene)
        self.assertEqual(reactants[1], self.butadiene)

        with self.assertRaises(MolGraphSplitError):
            self.cyclohexene.split_molecule_subgraphs([(0, 1)])

        # Test naive charge redistribution
        hydroxide = Molecule(["O", "H"], [[0, 0, 0], [0.5, 0.5, 0.5]],
                             charge=-1)
        oh_mg = MoleculeGraph.with_empty_graph(hydroxide)

        oh_mg.add_edge(0, 1)

        new_mgs = oh_mg.split_molecule_subgraphs([(0, 1)])
        for mg in new_mgs:
            if str(mg.molecule[0].specie) == "O":
                self.assertEqual(mg.molecule.charge, -1)
            else:
                self.assertEqual(mg.molecule.charge, 0)

        # Trying to test to ensure that remapping of nodes to atoms works
        diff_species = Molecule(
            ["C", "I", "Cl", "Br", "F"],
            [
                [0.8314, -0.2682, -0.9102],
                [1.3076, 1.3425, -2.2038],
                [-0.8429, -0.7410, -1.1554],
                [1.9841, -1.7636, -1.2953],
                [1.0098, 0.1231, 0.3916],
            ],
        )

        diff_spec_mg = MoleculeGraph.with_empty_graph(diff_species)
        diff_spec_mg.add_edge(0, 1)
        diff_spec_mg.add_edge(0, 2)
        diff_spec_mg.add_edge(0, 3)
        diff_spec_mg.add_edge(0, 4)

        for i in range(1, 5):
            bond = (0, i)

            split_mgs = diff_spec_mg.split_molecule_subgraphs([bond])
            for split_mg in split_mgs:
                species = nx.get_node_attributes(split_mg.graph, "specie")

                for j in range(len(split_mg.graph.nodes)):
                    atom = split_mg.molecule[j]
                    self.assertEqual(species[j], str(atom.specie))
コード例 #20
0
ファイル: structures.py プロジェクト: lizhenzhupearl/tBG-1
 def pymatgen_molecule(self):
     from pymatgen.core.structure import Molecule
     species = ['C'] * len(self.coords)
     return Molecule(species, self.coords)
コード例 #21
0
    def test_from_string(self):
        string = """$molecule
 0  1
 S          -0.00250959       -0.05817469       -0.02921636
 C           1.70755408       -0.03033788       -0.01382912
 H           2.24317221       -0.05215019        0.92026728
 C           2.21976393        0.01718014       -1.27293235
 H           3.27786220        0.04082146       -1.48539646
 C           1.20867399        0.04478540       -2.27007793
 H           1.40292257        0.10591684       -3.33110912
 C          -0.05341046        0.01577217       -1.74839343
 C          -1.32843436        0.03545064       -2.45531187
 C          -1.55195156        0.08743920       -3.80184635
 H          -0.75245172        0.10267657       -4.52817967
 C          -2.93293778        0.08408786       -4.13352169
 H          -3.31125108        0.11340328       -5.14405819
 C          -3.73173288        0.02741365       -3.03412864
 H          -4.80776535        0.00535688       -2.99564645
 S          -2.81590978       -0.00516172       -1.58990580
$end


$rem
              jobtype = opt
               method = wb97m-v
                basis = def2-tzvppd
           gen_scfman = true
  geom_opt_max_cycles = 75
       max_scf_cycles = 300
        scf_algorithm = diis
            scf_guess = sad
           sym_ignore = true
             symmetry = false
               thresh = 14
$end


$opt
CONSTRAINT
tors 6 8 9 10 0.0
ENDCONSTRAINT
$end
"""
        qcinput_test = QCInput.from_string(string)
        species = [
            "S",
            "C",
            "H",
            "C",
            "H",
            "C",
            "H",
            "C",
            "C",
            "C",
            "H",
            "C",
            "H",
            "C",
            "H",
            "S",
        ]
        coords = [
            [-0.00250959, -0.05817469, -0.02921636],
            [1.70755408, -0.03033788, -0.01382912],
            [2.24317221, -0.05215019, 0.92026728],
            [2.21976393, 0.01718014, -1.27293235],
            [3.27786220, 0.04082146, -1.48539646],
            [1.20867399, 0.04478540, -2.27007793],
            [1.40292257, 0.10591684, -3.33110912],
            [-0.05341046, 0.01577217, -1.74839343],
            [-1.32843436, 0.03545064, -2.45531187],
            [-1.55195156, 0.08743920, -3.80184635],
            [-0.75245172, 0.10267657, -4.52817967],
            [-2.93293778, 0.08408786, -4.13352169],
            [-3.31125108, 0.11340328, -5.14405819],
            [-3.73173288, 0.02741365, -3.03412864],
            [-4.80776535, 0.00535688, -2.99564645],
            [-2.81590978, -0.00516172, -1.58990580],
        ]
        molecule_actual = Molecule(species, coords)
        self.assertEqual(molecule_actual, qcinput_test.molecule)
        rem_actual = {
            "job_type": "opt",
            "method": "wb97m-v",
            "basis": "def2-tzvppd",
            "gen_scfman": "true",
            "geom_opt_max_cycles": "75",
            "max_scf_cycles": "300",
            "scf_algorithm": "diis",
            "scf_guess": "sad",
            "sym_ignore": "true",
            "symmetry": "false",
            "thresh": "14",
        }
        self.assertDictEqual(rem_actual, qcinput_test.rem)
        opt_actual = {"CONSTRAINT": ["tors 6 8 9 10 0.0"]}
        self.assertDictEqual(opt_actual, qcinput_test.opt)
コード例 #22
0
ファイル: measurement.py プロジェクト: matk86/MPInterfaces
            E_binding[key] = E_interfaces[key] \
                - E_slabs[key_slab] \
                - cal.system['num_ligands'] * E_ligands[
                key_ligand]
        logger.info('Binding energy = {}'.format(E_binding))


# test
if __name__ == '__main__':
    from pymatgen.core.structure import Structure, Molecule
    from mpinterfaces.interface import Ligand

    # PbS 100 surface with single hydrazine as ligand
    strt = Structure.from_file("POSCAR.mp-21276_PbS")
    mol_struct = Structure.from_file("POSCAR_diacetate")
    mol = Molecule(mol_struct.species, mol_struct.cart_coords)
    hydrazine = Ligand([mol])
    supercell = [1, 1, 1]
    hkl = [1, 1, 1]
    min_thick = 10
    min_vac = 12
    surface_coverage = 0.01
    adsorb_on_species = 'S'
    adatom_on_lig = 'Pb'
    displacement = 3.0
    iface = Interface(strt,
                      hkl=hkl,
                      min_thick=min_thick,
                      min_vac=min_vac,
                      supercell=supercell,
                      surface_coverage=0.01,
コード例 #23
0
    def test_from_multi_jobs_file(self):
        job_list_test = QCInput.from_multi_jobs_file(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "qchem",
                         "pt_n2_wb97mv_0.0.in"))
        species = [
            "S",
            "C",
            "H",
            "C",
            "H",
            "C",
            "H",
            "C",
            "C",
            "C",
            "H",
            "C",
            "H",
            "C",
            "H",
            "S",
        ]
        coords = [
            [-0.00250959, -0.05817469, -0.02921636],
            [1.70755408, -0.03033788, -0.01382912],
            [2.24317221, -0.05215019, 0.92026728],
            [2.21976393, 0.01718014, -1.27293235],
            [3.27786220, 0.04082146, -1.48539646],
            [1.20867399, 0.04478540, -2.27007793],
            [1.40292257, 0.10591684, -3.33110912],
            [-0.05341046, 0.01577217, -1.74839343],
            [-1.32843436, 0.03545064, -2.45531187],
            [-1.55195156, 0.08743920, -3.80184635],
            [-0.75245172, 0.10267657, -4.52817967],
            [-2.93293778, 0.08408786, -4.13352169],
            [-3.31125108, 0.11340328, -5.14405819],
            [-3.73173288, 0.02741365, -3.03412864],
            [-4.80776535, 0.00535688, -2.99564645],
            [-2.81590978, -0.00516172, -1.58990580],
        ]
        molecule_1_actual = Molecule(species, coords)
        rem_1_actual = {
            "job_type": "opt",
            "method": "wb97m-v",
            "basis": "def2-tzvppd",
            "gen_scfman": "true",
            "geom_opt_max_cycles": "75",
            "max_scf_cycles": "300",
            "scf_algorithm": "diis",
            "scf_guess": "sad",
            "sym_ignore": "true",
            "symmetry": "false",
            "thresh": "14",
        }
        opt_1_actual = {"CONSTRAINT": ["tors 6 8 9 10 0.0"]}
        self.assertEqual(molecule_1_actual, job_list_test[0].molecule)
        self.assertEqual(rem_1_actual, job_list_test[0].rem)
        self.assertEqual(opt_1_actual, job_list_test[0].opt)

        molecule_2_actual = "read"
        rem_2_actual = {
            "job_type": "sp",
            "method": "wb97m-v",
            "basis": "def2-tzvppd",
            "gen_scfman": "true",
            "geom_opt_max_cycles": "75",
            "max_scf_cycles": "300",
            "scf_algorithm": "diis",
            "scf_guess": "read",
            "sym_ignore": "true",
            "symmetry": "false",
            "thresh": "14",
        }
        self.assertEqual(molecule_2_actual, job_list_test[1].molecule)
        self.assertEqual(rem_2_actual, job_list_test[1].rem)
コード例 #24
0
import itertools

from pymatgen import Composition
from pymatgen.io.gaussian import GaussianInput
from pymatgen.core.structure import Molecule

from tinydb import TinyDB


# define the substituents
subs = [('nitro', 'nitro'),
        ('amine', 'amine'),
        ('cyano', 'cyano'),
        ('hydroxyl', 'hydroxyl'),
        ('fluoro', 'fluoro'),
        ('chloro', Molecule(['X', 'Cl'], [[0., 0., 0.], [0., 0., 1.11]])),
        ('bromo', Molecule(['X', 'Br'], [[0., 0., 0.], [0., 0., 1.11]])),
        [None]]

# define the x, y, z substituent positions as {name: site_ids}, where name is
# consistent with Pakapol naming convention and site_id is a list of zero based
# array indexes
sub_sites = {'x': [48, 49], 'y': [50, 51], 'z': [52, 53]}
sub_sites_thiol = {'x': [47, 49], 'y': [30, 31], 'z': [32, 33]}

# these lists give the nitrogen positions as (name, N site_ids, H site_ids),
# where name is consistent with Pakapol naming convention, and site_id is a
# list of zero based array indexes
nx_sites = [(1, [21, 28], [43, 44]),
            (2, [22, 27], [52, 53]),
            (3, [23, 26], [50, 51]),
コード例 #25
0
    def _parse_job(self, output):
        energy_patt = re.compile(r'Total \w+ energy\s+=\s+([.\-\d]+)')
        energy_gas_patt = re.compile(r'gas phase energy\s+=\s+([.\-\d]+)')
        energy_sol_patt = re.compile(r'sol phase energy\s+=\s+([.\-\d]+)')
        coord_patt = re.compile(r'\d+\s+(\w+)\s+[.\-\d]+\s+([.\-\d]+)\s+'
                                r'([.\-\d]+)\s+([.\-\d]+)')
        lat_vector_patt = re.compile(r'a[123]=<\s+([.\-\d]+)\s+'
                                     r'([.\-\d]+)\s+([.\-\d]+)\s+>')
        corrections_patt = re.compile(r'([\w\-]+ correction to \w+)\s+='
                                      r'\s+([.\-\d]+)')
        preamble_patt = re.compile(r'(No. of atoms|No. of electrons'
                                   r'|SCF calculation type|Charge|Spin '
                                   r'multiplicity)\s*:\s*(\S+)')
        force_patt = re.compile(r'\s+(\d+)\s+(\w+)' + 6 * r'\s+([0-9\.\-]+)')

        time_patt = re.compile(
            r'\s+ Task \s+ times \s+ cpu: \s+   ([.\d]+)s .+ ', re.VERBOSE)

        error_defs = {
            "calculations not reaching convergence": "Bad convergence",
            "Calculation failed to converge": "Bad convergence",
            "geom_binvr: #indep variables incorrect": "autoz error",
            "dft optimize failed": "Geometry optimization failed"}

        fort2py = lambda x: x.replace("D", "e")
        isfloatstring = lambda s: s.find(".") == -1

        parse_hess = False
        parse_proj_hess = False
        hessian = None
        projected_hessian = None
        parse_force = False
        all_forces = []
        forces = []

        data = {}
        energies = []
        frequencies = None
        normal_frequencies = None
        corrections = {}
        molecules = []
        structures = []
        species = []
        coords = []
        lattice = []
        errors = []
        basis_set = {}
        bset_header = []
        parse_geom = False
        parse_freq = False
        parse_bset = False
        parse_projected_freq = False
        job_type = ""
        parse_time = False
        time = 0
        for l in output.split("\n"):
            for e, v in error_defs.items():
                if l.find(e) != -1:
                    errors.append(v)
            if parse_time:
                m = time_patt.search(l)
                if m:
                    time = m.group(1)
                    parse_time = False
            if parse_geom:
                if l.strip() == "Atomic Mass":
                    if lattice:
                        structures.append(Structure(lattice, species, coords,
                                                    coords_are_cartesian=True))
                    else:
                        molecules.append(Molecule(species, coords))
                    species = []
                    coords = []
                    lattice = []
                    parse_geom = False
                else:
                    m = coord_patt.search(l)
                    if m:
                        species.append(m.group(1).capitalize())
                        coords.append([float(m.group(2)), float(m.group(3)),
                                       float(m.group(4))])
                    m = lat_vector_patt.search(l)
                    if m:
                        lattice.append([float(m.group(1)), float(m.group(2)),
                                        float(m.group(3))])

            if parse_force:
                m = force_patt.search(l)
                if m:
                    forces.extend(map(float, m.groups()[5:]))
                elif len(forces) > 0:
                    all_forces.append(forces)
                    forces = []
                    parse_force = False

            elif parse_freq:
                if len(l.strip()) == 0:
                    if len(normal_frequencies[-1][1]) == 0:
                        continue
                    else:
                        parse_freq = False
                else:
                    vibs = [float(vib) for vib in l.strip().split()[1:]]
                    num_vibs = len(vibs)
                    for mode, dis in zip(normal_frequencies[-num_vibs:], vibs):
                        mode[1].append(dis)

            elif parse_projected_freq:
                if len(l.strip()) == 0:
                    if len(frequencies[-1][1]) == 0:
                        continue
                    else:
                        parse_projected_freq = False
                else:
                    vibs = [float(vib) for vib in l.strip().split()[1:]]
                    num_vibs = len(vibs)
                    for mode, dis in zip(
                            frequencies[-num_vibs:], vibs):
                        mode[1].append(dis)

            elif parse_bset:
                if l.strip() == "":
                    parse_bset = False
                else:
                    toks = l.split()
                    if toks[0] != "Tag" and not re.match(r"-+", toks[0]):
                        basis_set[toks[0]] = dict(zip(bset_header[1:],
                                                      toks[1:]))
                    elif toks[0] == "Tag":
                        bset_header = toks
                        bset_header.pop(4)
                        bset_header = [h.lower() for h in bset_header]

            elif parse_hess:
                if l.strip() == "":
                    continue
                if len(hessian) > 0 and l.find("----------") != -1:
                    parse_hess = False
                    continue
                toks = l.strip().split()
                if len(toks) > 1:
                    try:
                        row = int(toks[0])
                    except Exception:
                        continue
                    if isfloatstring(toks[1]):
                        continue
                    vals = [float(fort2py(x)) for x in toks[1:]]
                    if len(hessian) < row:
                        hessian.append(vals)
                    else:
                        hessian[row - 1].extend(vals)

            elif parse_proj_hess:
                if l.strip() == "":
                    continue
                nat3 = len(hessian)
                toks = l.strip().split()
                if len(toks) > 1:
                    try:
                        row = int(toks[0])
                    except Exception:
                        continue
                    if isfloatstring(toks[1]):
                        continue
                    vals = [float(fort2py(x)) for x in toks[1:]]
                    if len(projected_hessian) < row:
                        projected_hessian.append(vals)
                    else:
                        projected_hessian[row - 1].extend(vals)
                    if len(projected_hessian[-1]) == nat3:
                        parse_proj_hess = False

            else:
                m = energy_patt.search(l)
                if m:
                    energies.append(Energy(m.group(1), "Ha").to("eV"))
                    parse_time = True
                    continue

                m = energy_gas_patt.search(l)
                if m:
                    cosmo_scf_energy = energies[-1]
                    energies[-1] = dict()
                    energies[-1].update({"cosmo scf": cosmo_scf_energy})
                    energies[-1].update({"gas phase":
                                         Energy(m.group(1), "Ha").to("eV")})

                m = energy_sol_patt.search(l)
                if m:
                    energies[-1].update(
                        {"sol phase": Energy(m.group(1), "Ha").to("eV")})

                m = preamble_patt.search(l)
                if m:
                    try:
                        val = int(m.group(2))
                    except ValueError:
                        val = m.group(2)
                    k = m.group(1).replace("No. of ", "n").replace(" ", "_")
                    data[k.lower()] = val
                elif l.find("Geometry \"geometry\"") != -1:
                    parse_geom = True
                elif l.find("Summary of \"ao basis\"") != -1:
                    parse_bset = True
                elif l.find("P.Frequency") != -1:
                    parse_projected_freq = True
                    if frequencies is None:
                        frequencies = []
                    toks = l.strip().split()[1:]
                    frequencies.extend([(float(freq), []) for freq in toks])

                elif l.find("Frequency") != -1:
                    toks = l.strip().split()
                    if len(toks) > 1 and toks[0] == "Frequency":
                        parse_freq = True
                        if normal_frequencies is None:
                            normal_frequencies = []
                        normal_frequencies.extend([(float(freq), []) for freq
                                                   in l.strip().split()[1:]])

                elif l.find("MASS-WEIGHTED NUCLEAR HESSIAN") != -1:
                    parse_hess = True
                    if not hessian:
                        hessian = []
                elif l.find("MASS-WEIGHTED PROJECTED HESSIAN") != -1:
                    parse_proj_hess = True
                    if not projected_hessian:
                        projected_hessian = []

                elif l.find("atom               coordinates                        gradient") != -1:
                    parse_force = True

                elif job_type == "" and l.strip().startswith("NWChem"):
                    job_type = l.strip()
                    if job_type == "NWChem DFT Module" and \
                            "COSMO solvation results" in output:
                        job_type += " COSMO"
                else:
                    m = corrections_patt.search(l)
                    if m:
                        corrections[m.group(1)] = FloatWithUnit(
                            m.group(2), "kJ mol^-1").to("eV atom^-1")

        if frequencies:
            for freq, mode in frequencies:
                mode[:] = zip(*[iter(mode)]*3)
        if normal_frequencies:
            for freq, mode in normal_frequencies:
                mode[:] = zip(*[iter(mode)]*3)
        if hessian:
            n = len(hessian)
            for i in range(n):
                for j in range(i + 1, n):
                    hessian[i].append(hessian[j][i])
        if projected_hessian:
            n = len(projected_hessian)
            for i in range(n):
                for j in range(i + 1, n):
                    projected_hessian[i].append(projected_hessian[j][i])

        data.update({"job_type": job_type, "energies": energies,
                     "corrections": corrections,
                     "molecules": molecules,
                     "structures": structures,
                     "basis_set": basis_set,
                     "errors": errors,
                     "has_error": len(errors) > 0,
                     "frequencies": frequencies,
                     "normal_frequencies": normal_frequencies,
                     "hessian": hessian,
                     "projected_hessian": projected_hessian,
                     "forces": all_forces,
                     "task_time": time})

        return data
コード例 #26
0
    def get_redo_workflow(self,
                          qchem_input_params,
                          sp_params,
                          max_iterations=3):
        """
        Identifies molecules which need to be re-run (for now, based only on
        presence of negative frequencies) and then performs a frequency
        flattening workflow on those molecules.

        This is a hack. In the future, a frequency flattening workflow should be
        used from the beginning.

        :param qchem_input_params: dict
        :param sp_params: For OptFreqSPFW, single-point calculations can be
        treated differently from Opt and Freq. In this case, another dict
        for sp must be used.
        :param max_iterations: Maximum number of iterations for frequency
            flattening. Default is 3.

        :return: Workflow
        """

        if self.db is None:
            raise RuntimeError("Cannot access database to determine what"
                               "molecules need to be re-calculated.")

        fws = []

        collection = self.db.db["molecules"]

        for mol in collection.find({}):
            frequencies = mol["output"]["frequencies"]

            if any([True if x < 0 else False for x in frequencies]):
                min_molecule_perturb_scale = 0.1
                max_molecule_perturb_scale = 0.3
                scale_grid = 10
                perturb_scale_grid = (max_molecule_perturb_scale -
                                      min_molecule_perturb_scale) / scale_grid
                msc = MoleculeStructureComparator()

                old_molecule = None

                for calc in mol["calcs_reversed"]:
                    if calc["task"]["type"] in ["freq", "frequency"
                                                ] and old_molecule is None:
                        negative_freq_vecs = calc.get(
                            "frequency_mode_vectors")[0]
                        old_coords = calc.get("initial_geometry")
                        old_molecule = Molecule.from_dict(
                            calc.get("initial_molecule"))

                structure_successfully_perturbed = False

                for molecule_perturb_scale in np.arange(
                        max_molecule_perturb_scale, min_molecule_perturb_scale,
                        -perturb_scale_grid):
                    new_coords = perturb_coordinates(
                        old_coords=old_coords,
                        negative_freq_vecs=negative_freq_vecs,
                        molecule_perturb_scale=molecule_perturb_scale,
                        reversed_direction=False)
                    new_molecule = Molecule(
                        species=old_molecule.species,
                        coords=new_coords,
                        charge=old_molecule.charge,
                        spin_multiplicity=old_molecule.spin_multiplicity)
                    if msc.are_equal(old_molecule, new_molecule):
                        structure_successfully_perturbed = True
                        break
                if not structure_successfully_perturbed:
                    raise Exception(
                        "Unable to perturb coordinates to remove negative frequency without changing the bonding structure"
                    )

                mol_id = mol["mol_id"]
                dir_name = mol["dir_name"].split("/")[-1]

                if dir_name not in listdir(self.base_dir):
                    os.mkdir(join(self.base_dir, dir_name))

                fws.append(
                    OptFreqSPFW(molecule=new_molecule,
                                name="Flattening: {}/{}".format(
                                    mol_id, dir_name),
                                qchem_cmd="qchem -slurm",
                                input_file=join(self.base_dir, dir_name,
                                                mol_id + ".in"),
                                output_file=join(self.base_dir, dir_name,
                                                 mol_id + ".out"),
                                qclog_file=join(self.base_dir, dir_name,
                                                mol_id + ".qclog"),
                                max_cores=32,
                                max_iterations=max_iterations,
                                qchem_input_params=qchem_input_params,
                                sp_params=sp_params,
                                db_file=self.db_file))

        if len(fws) == 0:
            return None
        else:
            return Workflow(fws)
コード例 #27
0
ファイル: test_nwchem.py プロジェクト: CompRhys/pymatgen
import unittest

from pymatgen.core.structure import Molecule
from pymatgen.io.nwchem import NwInput, NwInputError, NwOutput, NwTask
from pymatgen.util.testing import PymatgenTest

test_dir = os.path.join(PymatgenTest.TEST_FILES_DIR, "nwchem")

coords = [
    [0.000000, 0.000000, 0.000000],
    [0.000000, 0.000000, 1.089000],
    [1.026719, 0.000000, -0.363000],
    [-0.513360, -0.889165, -0.363000],
    [-0.513360, 0.889165, -0.363000],
]
mol = Molecule(["C", "H", "H", "H", "H"], coords)


class NwTaskTest(unittest.TestCase):
    def setUp(self):
        self.task = NwTask(
            0,
            1,
            basis_set={"H": "6-31g"},
            theory="dft",
            theory_directives={"xc": "b3lyp"},
        )
        self.task_cosmo = NwTask(
            0,
            1,
            basis_set={"H": "6-31g"},
コード例 #28
0
if len(argv) < 3:
    exit("Usage: convert_trajectory_xyzs.py initial_molecule_file, trajectory, to_dir")

initial_molecule_file = argv[1]
trajectory = argv[2]
to_dir = argv[3]

init_mol = Molecule.from_file(initial_molecule_file)
species = [str(e) for e in init_mol.species]
num_atoms = len(species)

if to_dir not in os.listdir():
    os.mkdir(to_dir)

iteration = 0
num_agent = 0
with open(trajectory) as traj_file:
    lines = traj_file.readlines()
    num_agents = int(lines[1].split()[1])

    for line in lines[2:]:
        if line == "\n":
            iteration += 1
            num_agent = 0
        elif "." not in line:
            continue
        else:
            coords = np.array([float(e) for e in line.strip().split(" ")]).reshape(num_atoms, 3)
            mol = Molecule(species, coords)
            mol.to("xyz", os.path.join(to_dir, "{}_{}.xyz".format(iteration,num_agent)))
            num_agent += 1
コード例 #29
0
 def setUpClass(cls):
     h2o_coords = [[9.626, 6.787, 12.673], [9.626, 8.420, 12.673],
                   [10.203, 7.604, 12.673]]
     molecule = Molecule(["H", "H", "O"], h2o_coords)
     box_size = [[0.0, 10.0], [0.0, 10.0], [0.0, 10.0]]
     cls.lammps_data = LammpsData.from_structure(molecule, box_size)
コード例 #30
0
        return stdout, stderr


if __name__ == "__main__":
    ethanol_coords = [
        [0.00720, -0.56870, 0.00000],
        [-1.28540, 0.24990, 0.00000],
        [1.13040, 0.31470, 0.00000],
        [0.03920, -1.19720, 0.89000],
        [0.03920, -1.19720, -0.89000],
        [-1.31750, 0.87840, 0.89000],
        [-1.31750, 0.87840, -0.89000],
        [-2.14220, -0.42390, -0.00000],
        [1.98570, -0.13650, -0.00000],
    ]
    ethanol = Molecule(["C", "C", "O", "H", "H", "H", "H", "H", "H"],
                       ethanol_coords)
    water_coords = [
        [9.626, 6.787, 12.673],
        [9.626, 8.420, 12.673],
        [10.203, 7.604, 12.673],
    ]
    water = Molecule(["H", "H", "O"], water_coords)
    pmr = PackmolRunner(
        [ethanol, water],
        [
            {
                "number": 1,
                "fixed": [0, 0, 0, 0, 0, 0],
                "centerofmass": ""
            },
            {