Exemplo n.º 1
0
    def read_molecule(string: str) -> Union[Molecule, Literal["read"]]:
        """
        Read molecule from string.

        Args:
            string (str): String

        Returns:
            Molecule
        """
        charge = None
        spin_mult = None
        patterns = {
            "read": r"^\s*\$molecule\n\s*(read)",
            "charge": r"^\s*\$molecule\n\s*((?:\-)*\d+)\s+\d",
            "spin_mult": r"^\s*\$molecule\n\s(?:\-)*\d+\s*(\d)",
        }
        matches = read_pattern(string, patterns)
        if "read" in matches.keys():
            return "read"
        if "charge" in matches.keys():
            charge = float(matches["charge"][0][0])
        if "spin_mult" in matches.keys():
            spin_mult = int(matches["spin_mult"][0][0])
        header = r"^\s*\$molecule\n\s*(?:\-)*\d+\s*\d"
        row = r"\s*((?i)[a-z]+)\s+([\d\-\.]+)\s+([\d\-\.]+)\s+([\d\-\.]+)"
        footer = r"^\$end"
        mol_table = read_table_pattern(string, header_pattern=header, row_pattern=row, footer_pattern=footer)
        species = [val[0] for val in mol_table[0]]
        coords = [[float(val[1]), float(val[2]), float(val[3])] for val in mol_table[0]]
        if charge is None:
            mol = Molecule(species=species, coords=coords)
        else:
            mol = Molecule(species=species, coords=coords, charge=charge, spin_multiplicity=spin_mult)
        return mol
def MakesGauInputs(mol_file, dihed_atoms_file, w, num_conform=19):
    """
    Creates Gaussian input files in its own folder for mol_file structues that
    freezes the central angle at iterations of 180/num_conform degrees. This
    function requires Gaussian output file of molecule in question and file
    with dihedral atoms to be in the current working directory.
    """

    molecule_name = mol_file.split('/')[-1][:-12]
    mol_pymat = Molecule.from_file(mol_file)
    molecule = pmgmol_to_rdmol(mol_pymat)[0]

    with open(dihed_atoms_file, 'r') as fn:
        data = fn.readlines()
        dihedral1 = data[0].split(',')[0]
        dihedral2 = data[0].split(',')[1]

    d1atom1_num = int(dihedral1.split()[0])
    d1atom2_num = int(dihedral1.split()[1])
    d1atom3_num = int(dihedral1.split()[2])
    d1atom4_num = int(dihedral1.split()[3])

    phi = np.linspace(start=0, stop=180, num=num_conform)
    for P in phi:
        dir_name = "{}/{}_{:.0f}deg/".format(os.getcwd(), molecule_name, P)
        os.mkdir(dir_name)
        file_name = "{}/{}_{:.0f}deg".format(dir_name, molecule_name, P)

        SetDihedralDeg(molecule.GetConformer(), d1atom1_num, d1atom2_num,
                       d1atom3_num, d1atom4_num, P)
        with open(dir_name + "temp.xyz", 'w+') as fout:
            fout.write(str(MolToXYZBlock(molecule)))
        mol = Molecule.from_file(dir_name + 'temp.xyz')
        os.remove(dir_name + 'temp.xyz')
        gau = GaussianInput(mol=mol,
                            charge=0,
                            spin_multiplicity=1,
                            functional='uLC-wPBE',
                            basis_set='cc-pVDZ',
                            route_parameters={
                                "iop(3/107={}, 3/108={})".format(w, w): "",
                                "opt": "modredundant"
                            },
                            link0_parameters={
                                '%mem': '5GB',
                                '%chk':
                                '{}.chk'.format(file_name.split('/')[-1])
                            })
        gjf_file = gau.write_file(dir_name + 'temp.gjf')

        with open(dir_name + 'temp.gjf') as temp:
            lines = temp.readlines()
        os.remove(dir_name + 'temp.gjf')
        with open(file_name + '.gjf', 'w') as gjf:
            gjf.writelines([item for item in lines[:-2]])
            gjf.write("D * {} {} * F\n\n".format(d1atom2_num + 1,
                                                 d1atom3_num + 1))

    print(
        "Torsion Gaussian input files for {} finsihed!".format(molecule_name))
Exemplo n.º 3
0
    def make_mols(molecule_subgraphs=molecule_subgraphs, center=False):  # pylint:disable=dangerous-default-value
        molecules = []
        indices = []
        indices_here = []
        mol_centers = []
        coordinates = []
        for subgraph in molecule_subgraphs:
            coords = [
                supercell_sg.structure[node].coords
                for node in subgraph.nodes()
            ]
            species = [
                supercell_sg.structure[node].specie
                for node in subgraph.nodes()
            ]

            # binding = [
            #     supercell_sg.structure[n].properties["binding"]
            #     for n in subgraph.nodes()
            # ]
            idx = [subgraph.nodes[node]["idx"] for node in subgraph.nodes()]
            idx_here = subgraph.nodes()
            molecule = Molecule(
                species, coords)  #  site_properties={"binding": binding}
            mol_centers.append(
                np.mean(supercell_sg.structure.cart_coords[idx_here], axis=0))
            # shift so origin is at center of mass
            if center:
                molecule = molecule.get_centered_molecule()
            indices.append(idx)
            molecules.append(molecule)
            indices_here.append(idx_here)
            coordinates.append(coords)
        return molecules, indices, indices_here, mol_centers, coordinates
Exemplo n.º 4
0
    def test_double_FF_opt(self):
        # location of test files
        test_double_FF_files = os.path.join(module_dir, "..", "..",
                                            "test_files", "double_FF_wf")
        # define starting molecule and workflow object
        initial_qcin = QCInput.from_file(
            os.path.join(test_double_FF_files, "block", "launcher_first",
                         "mol.qin.opt_0"))
        initial_mol = initial_qcin.molecule

        real_wf = get_wf_double_FF_opt(
            molecule=initial_mol,
            pcm_dielectric=10.0,
            max_cores=32,
            qchem_input_params={
                "basis_set": "6-311++g**",
                "overwrite_inputs": {
                    "rem": {
                        "sym_ignore": "true"
                    }
                }
            })
        # use powerup to replace run with fake run
        ref_dirs = {
            "first_FF_no_pcm":
            os.path.join(test_double_FF_files, "block", "launcher_first"),
            "second_FF_with_pcm":
            os.path.join(test_double_FF_files, "block", "launcher_second")
        }
        fake_wf = use_fake_qchem(real_wf, ref_dirs)
        self.lp.add_wf(fake_wf)
        rapidfire(
            self.lp,
            fworker=FWorker(env={"db_file": os.path.join(db_dir, "db.json")}))

        wf_test = self.lp.get_wf_by_fw_id(1)
        self.assertTrue(
            all([s == "COMPLETED" for s in wf_test.fw_states.values()]))

        first_FF = self.get_task_collection().find_one({
            "task_label":
            "first_FF_no_pcm"
        })
        self.assertEqual(first_FF["calcs_reversed"][0]["input"]["solvent"],
                         None)
        self.assertEqual(first_FF["num_frequencies_flattened"], 1)
        first_FF_final_mol = Molecule.from_dict(
            first_FF["output"]["optimized_molecule"])

        second_FF = self.get_task_collection().find_one({
            "task_label":
            "second_FF_with_pcm"
        })
        self.assertEqual(second_FF["calcs_reversed"][0]["input"]["solvent"],
                         {"dielectric": "10.0"})
        self.assertEqual(second_FF["num_frequencies_flattened"], 1)
        second_FF_initial_mol = Molecule.from_dict(
            second_FF["input"]["initial_molecule"])

        self.assertEqual(first_FF_final_mol, second_FF_initial_mol)
Exemplo n.º 5
0
    def test_double_FF_opt(self):
        # location of test files
        test_double_FF_files = os.path.join(module_dir, "..", "..",
                                            "test_files", "double_FF_wf")
        # define starting molecule and workflow object
        initial_qcin = QCInput.from_file(
            os.path.join(test_double_FF_files, "block", "launcher_first",
                         "mol.qin.opt_0"))
        initial_mol = initial_qcin.molecule

        real_wf = get_wf_double_FF_opt(
            molecule=initial_mol,
            pcm_dielectric=10.0,
            qchem_input_params={
                "basis_set": "6-311++g**",
                "scf_algorithm": "diis",
                "overwrite_inputs": {
                    "rem": {
                        "sym_ignore": "true"
                    }
                }
            })
        # use powerup to replace run with fake run
        ref_dirs = {
            "first_FF_no_pcm":
            os.path.join(test_double_FF_files, "block", "launcher_first"),
            "second_FF_with_pcm":
            os.path.join(test_double_FF_files, "block", "launcher_second")
        }
        fake_wf = use_fake_qchem(real_wf, ref_dirs)
        self.lp.add_wf(fake_wf)
        rapidfire(
            self.lp,
            fworker=FWorker(env={"max_cores": 32, "db_file": os.path.join(db_dir, "db.json")}))

        wf_test = self.lp.get_wf_by_fw_id(1)
        self.assertTrue(
            all([s == "COMPLETED" for s in wf_test.fw_states.values()]))

        first_FF = self.get_task_collection().find_one({
            "task_label":
            "first_FF_no_pcm"
        })
        self.assertEqual(first_FF["calcs_reversed"][0]["input"]["solvent"],
                         None)
        self.assertEqual(first_FF["num_frequencies_flattened"], 1)
        first_FF_final_mol = Molecule.from_dict(
            first_FF["output"]["optimized_molecule"])

        second_FF = self.get_task_collection().find_one({
            "task_label":
            "second_FF_with_pcm"
        })
        self.assertEqual(second_FF["calcs_reversed"][0]["input"]["solvent"],
                         {"dielectric": "10.0"})
        self.assertEqual(second_FF["num_frequencies_flattened"], 1)
        second_FF_initial_mol = Molecule.from_dict(
            second_FF["input"]["initial_molecule"])

        self.assertEqual(first_FF_final_mol, second_FF_initial_mol)
    def setUpClass(cls):

        cls.pt_mol = Molecule.from_file(
            os.path.join(module_dir, "..", "..", "test_files",
                         "pt_gs_wb97mv_tz_initial.xyz"))
        cls.pt_rot_90_mol = Molecule.from_file(
            os.path.join(module_dir, "..", "..", "test_files",
                         "pt_rotated_90.0.xyz"))
Exemplo n.º 7
0
def mol_from_pymatgen(mol: Molecule):
    """
    Args:
        mol(Molecule)
    """
    mol = pybel.Molecule(BabelMolAdaptor(mol).openbabel_mol)
    mol.make3D()
    return mol
Exemplo n.º 8
0
def get_subgraphs_as_molecules_all(
    structure_graph: pymatgen.analysis.graphs.StructureGraph, ):
    """Copied from
    http://pymatgen.org/_modules/pymatgen/analysis/graphs.html#StructureGraph.get_subgraphs_as_molecules
    and removed the duplicate check

    Args:
        structure_graph ( pymatgen.analysis.graphs.StructureGraph): Structuregraph

    Returns:
        List: list of molecules
    """

    # creating a supercell is an easy way to extract
    # molecules (and not, e.g., layers of a 2D crystal)
    # without adding extra logic
    supercell_sg = structure_graph * (3, 3, 3)

    # make undirected to find connected subgraphs
    supercell_sg.graph = nx.Graph(supercell_sg.graph)

    # find subgraphs
    all_subgraphs = [
        supercell_sg.graph.subgraph(c)
        for c in nx.connected_components(supercell_sg.graph)
    ]

    # discount subgraphs that lie across *supercell* boundaries
    # these will subgraphs representing crystals
    molecule_subgraphs = []
    for subgraph in all_subgraphs:
        intersects_boundary = any([
            d["to_jimage"] != (0, 0, 0)
            for u, v, d in subgraph.edges(data=True)
        ])
        if not intersects_boundary:
            molecule_subgraphs.append(nx.MultiDiGraph(subgraph))

    # add specie names to graph to be able to test for isomorphism
    for subgraph in molecule_subgraphs:
        for node in subgraph:
            subgraph.add_node(node,
                              specie=str(supercell_sg.structure[node].specie))

    # get Molecule objects for each subgraph
    molecules = []
    for subgraph in molecule_subgraphs:
        coords = [supercell_sg.structure[n].coords for n in subgraph.nodes()]
        species = [supercell_sg.structure[n].specie for n in subgraph.nodes()]

        molecule = Molecule(species, coords)

        # shift so origin is at center of mass
        molecule = molecule.get_centered_molecule()

        molecules.append(molecule)

    return molecules
Exemplo n.º 9
0
    def test_random_seed(self, water, ethanol):
        """
        Confirm that seed = -1 generates random structures
        while seed = 1 is deterministic
        """
        # deterministic output
        with tempfile.TemporaryDirectory() as scratch_dir:
            pw = PackmolWrapper(
                scratch_dir,
                molecules=[
                    {
                        "name": "water",
                        "number": 10,
                        "coords": water
                    },
                    {
                        "name": "ethanol",
                        "number": 20,
                        "coords": ethanol
                    },
                ],
                seed=1,
                inputfile="input.in",
                outputfile="output.xyz",
            )
            pw.make_packmol_input()
            pw.run_packmol()
            out1 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            pw.run_packmol()
            out2 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            assert np.array_equal(out1.cart_coords, out2.cart_coords)

        # randomly generated structures
        with tempfile.TemporaryDirectory() as scratch_dir:
            pw = PackmolWrapper(
                scratch_dir,
                molecules=[
                    {
                        "name": "water",
                        "number": 10,
                        "coords": water
                    },
                    {
                        "name": "ethanol",
                        "number": 20,
                        "coords": ethanol
                    },
                ],
                seed=-1,
                inputfile="input.in",
                outputfile="output.xyz",
            )
            pw.make_packmol_input()
            pw.run_packmol()
            out1 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            pw.run_packmol()
            out2 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            assert not np.array_equal(out1.cart_coords, out2.cart_coords)
Exemplo n.º 10
0
    def test_random_seed(self, water, ethanol):
        """
        Confirm that seed = -1 generates random structures
        while seed = 1 is deterministic
        """
        mm = MoleculeMatcher()

        # deterministic output
        with tempfile.TemporaryDirectory() as scratch_dir:
            pw = PackmolBoxGen(
                seed=1,
                inputfile="input.in",
                outputfile="output.xyz",
            ).get_input_set(
                # scratch_dir,
                molecules=[
                    {
                        "name": "water",
                        "number": 10,
                        "coords": water
                    },
                    {
                        "name": "ethanol",
                        "number": 20,
                        "coords": ethanol
                    },
                ], )
            pw.write_input(scratch_dir)
            pw.run(scratch_dir)
            out1 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            pw.run(scratch_dir)
            out2 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            assert mm.fit(out1, out2)

        # randomly generated structures
        with tempfile.TemporaryDirectory() as scratch_dir:
            pw = PackmolBoxGen(
                seed=-1,
                inputfile="input.in",
                outputfile="output.xyz",
            ).get_input_set(molecules=[
                {
                    "name": "water",
                    "number": 10,
                    "coords": water
                },
                {
                    "name": "ethanol",
                    "number": 20,
                    "coords": ethanol
                },
            ], )
            pw.write_input(scratch_dir)
            pw.run(scratch_dir)
            out1 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            pw.run(scratch_dir)
            out2 = Molecule.from_file(os.path.join(scratch_dir, "output.xyz"))
            assert not mm.fit(out1, out2)
Exemplo n.º 11
0
    def update(self, coords, lattice=None, absolute=False, update_mol=True):
        """
        After the geometry relaxation, the returned atomic coordinates
        maybe rescaled to [0, 1] bound. In this case, we need to refind
        the molecular coordinates according to the original neighbor list. 
        If the list does not change, we return the new coordinates
        otherwise, terminate the calculation.
        """
        from pyxtal.molecule import compare_mol_connectivity, Orientation
        try:
            from openbabel import pybel, openbabel
        except:
            import pybel, openbabel
        if lattice is not None:
            self.lattice = lattice
        if not absolute:
            coords = coords.dot(self.lattice.matrix)
        #mol = Molecule(self.symbols, coords-np.mean(coords, axis=0))
        center = self.molecule.get_center(coords)
        mol = Molecule(self.symbols, coords - center)

        #match, _ = compare_mol_connectivity(mol, self.mol, True)
        match, _ = compare_mol_connectivity(mol, self.mol)
        if match:
            #position = np.mean(coords, axis=0).dot(self.lattice.inv_matrix)
            position = center.dot(self.lattice.inv_matrix)
            #position -= np.floor(position)
            self.position = position - np.floor(position)
            if update_mol:
                self.orientation = Orientation(np.eye(3))
                self.mol = mol
            else:
                m1 = pybel.readstring('xyz', self.mol.to('xyz'))
                m2 = pybel.readstring('xyz', mol.to('xyz'))
                aligner = openbabel.OBAlign(True, False)
                aligner.SetRefMol(m1.OBMol)
                aligner.SetTargetMol(m2.OBMol)
                if aligner.Align():
                    print("RMSD: ", aligner.GetRMSD())
                    rot = np.zeros([3, 3])
                    for i in range(3):
                        for j in range(3):
                            rot[i, j] = aligner.GetRotMatrix().Get(i, j)
                    if abs(np.linalg.det(rot) - 1) < 1e-2:
                        self.orientation.matrix = rot
                        self.orientation.r = R.from_matrix(rot)
                    else:
                        raise ValueError("rotation matrix is wrong")
        else:
            import pickle
            with open('wrong.pkl', "wb") as f:
                pickle.dump([mol, self.mol], f)
                mol.to(filename='Wrong.xyz', fmt='xyz')
                self.mol.to(filename='Ref.xyz', fmt='xyz')
            raise ValueError("molecular connectivity changes! Exit")
Exemplo n.º 12
0
    def setUpClass(cls):
        # head molecule
        cls.peo_head = Molecule.from_file(
            os.path.join(test_dir, "peo_head.xyz"))
        charges = [
            -0.1187, 0.0861, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861
        ]
        cls.peo_head.add_site_property("charge", charges)
        s_head = 0
        s_tail = 5

        # chain molecule
        cls.peo_bulk = Molecule.from_file(
            os.path.join(test_dir, "peo_bulk.xyz"))
        charges = [-0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861]
        cls.peo_bulk.add_site_property("charge", charges)
        head = 0
        tail = 4

        # terminal molecule
        cls.peo_tail = Molecule.from_file(
            os.path.join(test_dir, "peo_tail.xyz"))
        charges = [
            -0.0326, 0.0861, 0.0861, -0.2792, -0.1187, 0.0861, 0.0861, 0.0861
        ]
        cls.peo_tail.add_site_property("charge", charges)
        e_head = 0
        e_tail = 4

        cls.n_units = 25
        link_distance = 1.5075

        # create the polymer
        cls.peo_polymer = Polymer(cls.peo_head, s_head, s_tail, cls.peo_bulk,
                                  head, tail, cls.peo_tail, e_head, e_tail,
                                  cls.n_units, link_distance)

        # linear chain
        cls.peo_polymer_linear = Polymer(cls.peo_head,
                                         s_head,
                                         s_tail,
                                         cls.peo_bulk,
                                         head,
                                         tail,
                                         cls.peo_tail,
                                         e_head,
                                         e_tail,
                                         cls.n_units,
                                         link_distance,
                                         linear_chain=True)
Exemplo n.º 13
0
    def setUpClass(cls):

        co_species = ['C', 'O']
        co_coords = [[0.0, 0.0, 0.0], [1.3, 0.0, 0.0]]
        cls.co_mol = Molecule(co_species, co_coords)
        cls.co_opt_ref_in = QCInput.from_file(
            os.path.join(module_dir, "..", "..", "test_files", "co_qc.in"))
Exemplo n.º 14
0
 def from_dict(cls, d):
     mol = Molecule.from_dict(d["mol"])
     return NwTask(mol, charge=d["charge"],
                   spin_multiplicity=d["spin_multiplicity"],
                   title=d["title"], theory=d["theory"],
                   operation=d["operation"], basis_set=d["basis_set"],
                   theory_directives=d["theory_directives"])
Exemplo n.º 15
0
def parse_symmetry(pos):
    mol = Molecule(["C"] * len(pos), pos)
    try:
        symbol = PointGroupAnalyzer(mol, tolerance=0.1).sch_symbol
    except:
        symbol = "N/A"
    return symbol
Exemplo n.º 16
0
 def setUpClass(cls):
     cls.structure = Structure.from_file(
         os.path.join(MODULE_DIR, "cifs", "BaTiO3_mp-2998_computed.cif"))
     cls.molecule = Molecule(["C", "O", "O"],
                             [[0, 0, 0], [-1, 0, 0], [1, 0, 0]])
     cls.mall = MinimumDistanceNNAll(4)
     cls.aapair = AllAtomPairs()
Exemplo n.º 17
0
    def test_coordination(self):
        molecule = Molecule(["C", "C"], [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]])

        mg = MoleculeGraph.with_empty_graph(molecule)
        self.assertEqual(mg.get_coordination_of_site(0), 0)

        self.assertEqual(self.cyclohexene.get_coordination_of_site(0), 4)
Exemplo n.º 18
0
 def test_simple_molecule_graph(self):
     mol = Molecule(["C", "H", "O"], [[0, 0, 0], [1, 0, 0], [2, 0, 0]])
     graph = SimpleMolGraph().convert(mol)
     self.assertListEqual(to_list(graph["atom"]), [6, 1, 8])
     self.assertTrue(np.allclose(graph["bond"], [1, 2, 1, 1, 2, 1]))
     self.assertListEqual(to_list(graph["index1"]), [0, 0, 1, 1, 2, 2])
     self.assertListEqual(to_list(graph["index2"]), [1, 2, 0, 2, 0, 1])
Exemplo n.º 19
0
 def from_dict(cls, d):
     return FiestaInput(Molecule.from_dict(d["mol"]),
                    correlation_grid=d["correlation_grid"],
                    Exc_DFT_option=d["Exc_DFT_option"],
                    COHSEX_options=d["geometry_options"],
                    GW_options=d["symmetry_options"],
                    BSE_TDDFT_options=d["memory_options"])
Exemplo n.º 20
0
def generate_gjf(in_fn,
                 out_dir,
                 functional='LC-wHPBE',
                 basis_set='TZVP',
                 charge=0,
                 calculation='opt',
                 omega=None,
                 oldchk=None):
    """
    Convert an individually inputted xyz file to a gjf Gaussian input file
    """
    mol = Molecule.from_file(in_fn)
    mol.perturb(0.1)
    mol_name = in_fn.split('/')[-1][:14]
    link0_parameters = {'%mem': '5GB', '%chk': '{}.chk'.format(calculation)}
    route_parameters = {
        calculation: '',
        'SCF': '(MaxCycle=250)',
        'Int': '(Grid=Ultrafine)'
    }
    if calculation == 'tddft':
        route_parameters = {'TD(NStates=5, 50-50)': ''}
    if omega is not None:
        route_parameters["iop(3/107={}, 3/108={})".format(omega, omega)] = ''
    if oldchk:
        link0_parameters['%oldchk'] = '{}.chk'.format(oldchk)
        route_parameters['Geom'] = 'AllCheck'
    gau = GaussianInput(mol=mol,
                        charge=charge,
                        functional=functional,
                        basis_set=basis_set,
                        route_parameters=route_parameters,
                        link0_parameters=link0_parameters)
    gjf_file = gau.write_file('{}/{}.gjf'.format(out_dir, calculation))
    return gjf_file
Exemplo n.º 21
0
def WriteXYZ(in_file, out_dir):
    """
    Write xyz file.
    """
    mol = Molecule.from_file(in_file)
    fout = os.path.join(out_dir, in_file.split('/')[-1])
    mol.to(filename=fout)
Exemplo n.º 22
0
 def _read_species_and_inital_geometry(self):
     """
     Parses species and initial geometry.
     """
     header_pattern = r"Standard Nuclear Orientation \(Angstroms\)\s+I\s+Atom\s+X\s+Y\s+Z\s+-+"
     table_pattern = r"\s*\d+\s+([a-zA-Z]+)\s*([\d\-\.]+)\s*([\d\-\.]+)\s*([\d\-\.]+)\s*"
     footer_pattern = r"\s*-+"
     temp_geom = read_table_pattern(self.text, header_pattern,
                                    table_pattern, footer_pattern)
     if temp_geom == None or len(temp_geom) == 0:
         self.data["species"] = None
         self.data["initial_geometry"] = None
         self.data["initial_molecule"] = None
     else:
         temp_geom = temp_geom[0]
         species = []
         geometry = np.zeros(shape=(len(temp_geom), 3), dtype=float)
         for ii, entry in enumerate(temp_geom):
             species += [entry[0]]
             for jj in range(3):
                 geometry[ii, jj] = float(entry[jj + 1])
         self.data["species"] = species
         self.data["initial_geometry"] = geometry
         self.data["initial_molecule"] = Molecule(
             species=species,
             coords=geometry,
             charge=self.data.get('charge'),
             spin_multiplicity=self.data.get('multiplicity'))
Exemplo n.º 23
0
    def _read_optimized_geometry(self):
        """
        Parses optimized XYZ coordinates. If not present, parses optimized Z-matrix.
        """
        header_pattern = r"\*+\s+OPTIMIZATION\s+CONVERGED\s+\*+\s+\*+\s+Coordinates \(Angstroms\)\s+ATOM\s+X\s+Y\s+Z"
        table_pattern = r"\s+\d+\s+\w+\s+([\d\-\.]+)\s+([\d\-\.]+)\s+([\d\-\.]+)"
        footer_pattern = r"\s+Z-matrix Print:"

        parsed_optimized_geometry = read_table_pattern(self.text,
                                                       header_pattern,
                                                       table_pattern,
                                                       footer_pattern)
        if parsed_optimized_geometry == [] or None:
            self.data["optimized_geometry"] = None
            header_pattern = r"^\s+\*+\s+OPTIMIZATION CONVERGED\s+\*+\s+\*+\s+Z-matrix\s+Print:\s+\$molecule\s+[\d\-]+\s+[\d\-]+\n"
            table_pattern = r"\s*(\w+)(?:\s+(\d+)\s+([\d\-\.]+)(?:\s+(\d+)\s+([\d\-\.]+)(?:\s+(\d+)\s+([\d\-\.]+))*)*)*(?:\s+0)*"
            footer_pattern = r"^\$end\n"

            self.data["optimized_zmat"] = read_table_pattern(
                self.text, header_pattern, table_pattern, footer_pattern)
        else:
            self.data["optimized_geometry"] = process_parsed_coords(
                parsed_optimized_geometry[0])
            if self.data.get('charge') != None:
                self.data["molecule_from_optimized_geometry"] = Molecule(
                    species=self.data.get('species'),
                    coords=self.data.get('optimized_geometry'),
                    charge=self.data.get('charge'),
                    spin_multiplicity=self.data.get('multiplicity'))
Exemplo n.º 24
0
 def test_packmol_with_molecule(self, water, ethanol):
     """
     Test coords input as Molecule
     """
     with tempfile.TemporaryDirectory() as scratch_dir:
         pw = PackmolWrapper(
             scratch_dir,
             molecules=[
                 {
                     "name": "water",
                     "number": 10,
                     "coords": water
                 },
                 {
                     "name": "ethanol",
                     "number": 20,
                     "coords": ethanol
                 },
             ],
         )
         pw.make_packmol_input()
         pw.run_packmol()
         assert os.path.exists(os.path.join(scratch_dir, "packmol_out.xyz"))
         out = Molecule.from_file(
             os.path.join(scratch_dir, "packmol_out.xyz"))
         assert out.composition.num_atoms == 10 * 3 + 20 * 9
Exemplo n.º 25
0
    def test_coulomb_matrix(self):
        # flat
        cm = CoulombMatrix(flatten=True)
        df = pd.DataFrame({"s": [self.diamond, self.nacl]})
        with self.assertRaises(NotFittedError):
            df = cm.featurize_dataframe(df, "s")
        df = cm.fit_featurize_dataframe(df, "s")
        labels = cm.feature_labels()
        self.assertListEqual(labels,
                             ["coulomb matrix eig 0", "coulomb matrix eig 1"])
        self.assertArrayAlmostEqual(df[labels].iloc[0], [49.169453, 24.546758],
                                    decimal=5)
        self.assertArrayAlmostEqual(df[labels].iloc[1],
                                    [153.774731, 452.894322],
                                    decimal=5)

        # matrix
        species = ["C", "C", "H", "H"]
        coords = [[0, 0, 0], [0, 0, 1.203], [0, 0, -1.06], [0, 0, 2.263]]
        acetylene = Molecule(species, coords)
        morig = CoulombMatrix(flatten=False).featurize(acetylene)
        mtarget = [[36.858, 15.835391290, 2.995098235, 1.402827813], \
                   [15.835391290, 36.858, 1.4028278132103624, 2.9950982], \
                   [2.9368896127, 1.402827813, 0.5, 0.159279959], \
                   [1.4028278132, 2.995098235, 0.159279959, 0.5]]
        self.assertAlmostEqual(int(np.linalg.norm(morig - np.array(mtarget))),
                               0)
        m = CoulombMatrix(diag_elems=False,
                          flatten=False).featurize(acetylene)[0]
        self.assertAlmostEqual(m[0][0], 0.0)
        self.assertAlmostEqual(m[1][1], 0.0)
        self.assertAlmostEqual(m[2][2], 0.0)
        self.assertAlmostEqual(m[3][3], 0.0)
Exemplo n.º 26
0
 def test_packmol_with_path(self):
     """
     Test coords input as Path. Use a subdirectory with spaces.
     """
     p1 = Path(os.path.join(test_dir, "subdir with spaces", "EMC.xyz"))
     p2 = Path(os.path.join(test_dir, "LiTFSi.xyz"))
     with tempfile.TemporaryDirectory() as scratch_dir:
         pw = PackmolWrapper(
             scratch_dir,
             molecules=[
                 {
                     "name": "EMC",
                     "number": 10,
                     "coords": p1
                 },
                 {
                     "name": "LiTFSi",
                     "number": 20,
                     "coords": p2
                 },
             ],
         )
         pw.make_packmol_input()
         pw.run_packmol()
         assert os.path.exists(os.path.join(scratch_dir, "packmol_out.xyz"))
         out = Molecule.from_file(
             os.path.join(scratch_dir, "packmol_out.xyz"))
         assert out.composition.num_atoms == 10 * 15 + 20 * 16
Exemplo n.º 27
0
    def get_mol_object(self, id=0):
        """
        make the pymatgen molecule object

        Args:
            id: the index of molecules in the given site

        Returns:
            a molecule object
        """
        coord0 = self.mol.cart_coords.dot(self.orientation.matrix.T)  #
        # Obtain the center in absolute coords
        if id <= len(self.wp.generators):
            op = self.wp.generators[id]
            center_relative = op.operate(self.position)
            center_relative -= np.floor(center_relative)
            #print(center_relative)
            center_absolute = np.dot(center_relative, self.lattice.matrix)
            # Rotate the molecule (Euclidean metric)
            op_m = self.wp.generators_m[id]
            rot = op_m.affine_matrix[0:3][:, 0:3].T
            tau = op_m.affine_matrix[0:3][:, 3]
            tmp = np.dot(coord0, rot) + tau
            # Add absolute center to molecule
            tmp += center_absolute
            return Molecule(self.symbols, tmp)
        else:
            raise ValueError("id is greater than the number of molecules")
Exemplo n.º 28
0
    def run_task(self, fw_spec):

        self["constituent_molecules"]
        self["mols_number"]
        input_filename = self["input_filename"]
        forcefield = self["forcefield"]
        topologies = self["topologies"]

        user_settings = self.get("user_settings", {})
        data_filename = self.get("data_filename",
                                 user_settings.get("data_file", "lammps.data"))
        final_molecule = self["final_molecule"]

        # if the final molecule was generated using packmol
        if fw_spec.get("packed_mol", None):
            final_molecule = fw_spec["packed_mol"]
        elif isinstance(final_molecule, str):
            final_molecule = Molecule.from_file(final_molecule)

        # molecules, mols_number, final_molecule
        lammps_ff_data = LammpsData.from_ff_and_topologies(
            forcefield, topologies, self["box_size"])

        lammps_input_set = LammpsInputSet.from_file(
            "ff-inputset",
            self["input_file"],
            user_settings=user_settings,
            lammps_data=lammps_ff_data,
            data_filename=data_filename,
            is_forcefield=True,
        )

        lammps_input_set.write_input(input_filename, data_filename)
Exemplo n.º 29
0
 def read_molecule(string):
     charge = None
     spin_mult = None
     patterns = {
         "read": r"^\s*\$molecule\n\s*(read)",
         "charge": r"^\s*\$molecule\n\s*((?:\-)*\d+)\s+\d",
         "spin_mult": r"^\s*\$molecule\n\s*\d+\s*(\d)"
     }
     matches = read_pattern(string, patterns)
     if "read" in matches.keys():
         return "read"
     if "charge" in matches.keys():
         charge = float(matches["charge"][0][0])
     if "spin_mult" in matches.keys():
         spin_mult = int(matches["spin_mult"][0][0])
     header = r"^\s*\$molecule\n\s*(?:\-)*\d+\s*\d"
     row = r"\s*((?i)[a-z]+)\s+([\d\-\.]+)\s+([\d\-\.]+)\s+([\d\-\.]+)"
     footer = r"^\$end"
     mol_table = read_table_pattern(string,
                                    header_pattern=header,
                                    row_pattern=row,
                                    footer_pattern=footer)
     species = [val[0] for val in mol_table[0]]
     coords = [[float(val[1]), float(val[2]),
                float(val[3])] for val in mol_table[0]]
     mol = Molecule(species=species,
                    coords=coords,
                    charge=charge,
                    spin_multiplicity=spin_mult)
     return mol
Exemplo n.º 30
0
    def test_isomorphic(self):
        ethylene = Molecule.from_file(
            os.path.join(
                PymatgenTest.TEST_FILES_DIR,
                "graphs/ethylene.xyz",
            ))
        # switch carbons
        ethylene[0], ethylene[1] = ethylene[1], ethylene[0]

        eth_copy = MoleculeGraph.with_edges(
            ethylene,
            {
                (0, 1): {
                    "weight": 2
                },
                (1, 2): {
                    "weight": 1
                },
                (1, 3): {
                    "weight": 1
                },
                (0, 4): {
                    "weight": 1
                },
                (0, 5): {
                    "weight": 1
                },
            },
        )
        # If they are equal, they must also be isomorphic
        eth_copy = copy.deepcopy(self.ethylene)
        self.assertTrue(self.ethylene.isomorphic_to(eth_copy))
        self.assertFalse(self.butadiene.isomorphic_to(self.ethylene))
Exemplo n.º 31
0
 def from_dict(cls, d):
     return NwInput(Molecule.from_dict(d["mol"]),
                    tasks=[NwTask.from_dict(dt) for dt in d["tasks"]],
                    directives=[tuple(li) for li in d["directives"]],
                    geometry_options=d["geometry_options"],
                    symmetry_options=d["symmetry_options"],
                    memory_options=d["memory_options"])
Exemplo n.º 32
0
 def test_packmol_with_str(self):
     """
     Test coords input as strings
     """
     with tempfile.TemporaryDirectory() as scratch_dir:
         pw = PackmolBoxGen().get_input_set(molecules=[
             {
                 "name":
                 "EMC",
                 "number":
                 10,
                 "coords":
                 os.path.join(test_dir, "subdir with spaces", "EMC.xyz")
             },
             {
                 "name": "LiTFSi",
                 "number": 20,
                 "coords": os.path.join(test_dir, "LiTFSi.xyz")
             },
         ], )
         pw.write_input(scratch_dir)
         pw.run(scratch_dir)
         assert os.path.exists(os.path.join(scratch_dir, "packmol_out.xyz"))
         out = Molecule.from_file(
             os.path.join(scratch_dir, "packmol_out.xyz"))
         assert out.composition.num_atoms == 10 * 15 + 20 * 16
Exemplo n.º 33
0
    def test_parse_pass_rotate_write(self):

        input_file = "pt_gs_wb97mv_tz_initial.in"
        output_file = "pt_gs_wb97mv_tz_initial_1_job.out"
        calc_dir = os.path.join(module_dir, "..", "..", "test_files")

        p_task = QChemToDb(calc_dir=calc_dir,
                           input_file=input_file,
                           output_file=output_file,
                           db_file=">>db_file<<")
        fw1 = Firework([p_task])
        atom_indexes = [6, 8, 9, 10]
        angle = 90.0
        rot_task = RotateTorsion(atom_indexes=atom_indexes, angle=angle)
        w_task = WriteInputFromIOSet(qchem_input_set="OptSet",
                                     write_to_dir=module_dir)
        fw2 = Firework([rot_task, w_task], parents=fw1)
        wf = Workflow([fw1, fw2])

        self.lp.add_wf(wf)
        rapidfire(
            self.lp,
            fworker=FWorker(env={"db_file": os.path.join(db_dir, "db.json")}))

        test_mol = QCInput.from_file(os.path.join(module_dir,
                                                  "mol.qin")).molecule
        act_mol = Molecule.from_file(
            os.path.join(module_dir, "..", "..", "test_files",
                         "pt_rotated_90.0.xyz"))
        np.testing.assert_equal(act_mol.species, test_mol.species)
        np.testing.assert_allclose(act_mol.cart_coords,
                                   test_mol.cart_coords,
                                   atol=0.0001)
Exemplo n.º 34
0
 def from_dict(cls, d):
     return GaussianInput(mol=Molecule.from_dict(d["molecule"]),
                          functional=d["functional"],
                          basis_set=d["basis_set"],
                          route_parameters=d["route_parameters"],
                          title=d["title"],
                          charge=d["charge"],
                          spin_multiplicity=d["spin_multiplicity"],
                          input_parameters=d["input_parameters"],
                          link0_parameters=d["link0_parameters"])
Exemplo n.º 35
0
    def setUpClass(cls):
        # head molecule
        cls.peo_head = Molecule.from_file(os.path.join(test_dir, "peo_head.xyz"))
        charges = [-0.1187, 0.0861, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861]
        cls.peo_head.add_site_property("charge", charges)
        s_head = 0
        s_tail = 5

        # chain molecule
        cls.peo_bulk = Molecule.from_file(os.path.join(test_dir, "peo_bulk.xyz"))
        charges = [-0.0326, 0.0861, 0.0861, -0.2792, -0.0326, 0.0861, 0.0861]
        cls.peo_bulk.add_site_property("charge", charges)
        head = 0
        tail = 4

        # terminal molecule
        cls.peo_tail = Molecule.from_file(os.path.join(test_dir, "peo_tail.xyz"))
        charges = [-0.0326, 0.0861, 0.0861, -0.2792, -0.1187, 0.0861, 0.0861, 0.0861]
        cls.peo_tail.add_site_property("charge", charges)
        e_head = 0
        e_tail = 4

        cls.n_units = 25
        link_distance = 1.5075

        # create the polymer
        cls.peo_polymer = Polymer(cls.peo_head, s_head, s_tail,
                                  cls.peo_bulk, head, tail,
                                  cls.peo_tail, e_head, e_tail,
                                  cls.n_units, link_distance)

        # linear chain
        cls.peo_polymer_linear = Polymer(cls.peo_head, s_head, s_tail,
                                         cls.peo_bulk, head, tail,
                                         cls.peo_tail, e_head, e_tail,
                                         cls.n_units, link_distance, linear_chain=True)
Exemplo n.º 36
0
 def setUpClass(cls):
     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]]
     water_coords = [[9.626, 6.787, 12.673],
                     [9.626, 8.420, 12.673],
                     [10.203, 7.604, 12.673]]
     cls.ethanol_atoms = ["C", "C", "O", "H", "H", "H", "H", "H", "H"]
     cls.water_atoms = ["H", "H", "O"]
     ethanol = Molecule(cls.ethanol_atoms, ethanol_coords)
     water = Molecule(cls.water_atoms, water_coords)
     cls.mols = [ethanol, water]
     cls.cocktail = Molecule.from_file(
         os.path.join(test_dir, "cocktail.xyz"))
     cls.packmol_config = [{"number": 1}, {"number": 15}]
Exemplo n.º 37
0
    def test_no_opt_Fragmentation(self):
        db_file = os.path.join(db_dir, "db.json")
        mmdb = QChemCalcDb.from_db_file(db_file, admin=True)
        with open(os.path.join(module_dir, "..", "..", "test_files","sb40.json")) as f:
            tmp = json.load(f)
            for entry in tmp:
                mmdb.insert(entry)
        with patch("atomate.qchem.firetasks.fragmenter.FWAction") as FWAction_patch:
            mock_FWAction = MagicMock()
            FWAction_patch.return_value = mock_FWAction
            mock_FWAction.as_dict.return_value = {'stored_data': {}, 'exit': False, 'update_spec': {}, 'mod_spec': [], 'additions': [], 'detours': [], 'defuse_children': False, 'defuse_workflow': False}

            # define starting molecule and workflow object
            initial_mol = Molecule.from_file(os.path.join(module_dir, "..", "..", "test_files", "top_11", "EC.xyz"))
            initial_mol.set_charge_and_spin(charge=-1)
            wf = get_fragmentation_wf(molecule=initial_mol, depth=1, pcm_dielectric=40.0, do_optimization=False, check_db=True)
            self.lp.add_wf(wf)
            rapidfire(
                self.lp,
                fworker=FWorker(env={"max_cores": 24, "db_file": db_file}), pdb_on_exception=True)

            self.assertEqual(len(FWAction_patch.call_args[1]["additions"]), 0)
        mmdb.reset()
Exemplo n.º 38
0
 def from_dict(cls, d):
     return NwInput(Molecule.from_dict(d["mol"]),
                    [NwTask.from_dict(dt) for dt in d["tasks"]],
                    d["directives"])
Exemplo n.º 39
0
    def test_torsion_potential(self):
        # location of test files
        test_tor_files = os.path.join(module_dir, "..", "..", "test_files",
                                      "torsion_wf")
        # define starting molecule and torsion potential workflow object
        initial_qcin = QCInput.from_file(
            os.path.join(test_tor_files, "initial_opt", "mol.qin"))
        initial_mol = initial_qcin.molecule
        atom_indexes = [6, 8, 9, 10]
        angles = [0.0, 90.0, 180.0]
        rem = []
        # add the first rem section
        rem.append({
            "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
        })

        # the second rem section
        rem.append({
            "jobtype": "opt",
            "method": "wb97m-v",
            "basis": "def2-tzvppd",
            "geom_opt_max_cycles": 75,
            "max_scf_cycles": 300,
            "scf_algorithm": "diis",
            "scf_guess": "sad",
            "sym_ignore": "true",
            "symmetry": "false",
            "thresh": 14
        })

        real_wf = get_wf_torsion_potential(
            molecule=initial_mol,
            atom_indexes=atom_indexes,
            angles=angles,
            rem=rem,
            db_file=">>db_file<<")
        # use powerup to replace run with fake run
        # def ref_dirs
        ref_dirs = {
            "initial_opt": os.path.join(test_tor_files, "initial_opt"),
            "opt_0": os.path.join(test_tor_files, "opt_0"),
            "opt_90": os.path.join(test_tor_files, "opt_90"),
            "opt_180": os.path.join(test_tor_files, "opt_180")
        }
        fake_wf = use_fake_qchem(real_wf, ref_dirs)

        self.lp.add_wf(fake_wf)
        rapidfire(
            self.lp,
            fworker=FWorker(env={"db_file": os.path.join(db_dir, "db.json")}))

        wf_test = self.lp.get_wf_by_fw_id(1)
        self.assertTrue(
            all([s == "COMPLETED" for s in wf_test.fw_states.values()]))

        # Checking of the inputs happens in fake_run_qchem so there is no point to retest the inputs
        # Check the output info that gets inserted in the DB
        init_opt = self.get_task_collection().find_one({
            "task_label":
            "initial_opt"
        })
        init_opt_final_mol = Molecule.from_dict(
            init_opt["output"]["optimized_molecule"])
        init_opt_final_e = init_opt["output"]["final_energy"]
        # parse output file
        act_init_opt_out = QCOutput(
            os.path.join(test_tor_files, "initial_opt", "mol.qout"))
        act_init_opt_mol = act_init_opt_out.data[
            "molecule_from_optimized_geometry"]
        act_init_opt_final_e = act_init_opt_out.data["final_energy"]

        np.testing.assert_equal(act_init_opt_mol.species,
                                init_opt_final_mol.species)
        np.testing.assert_allclose(
            act_init_opt_mol.cart_coords,
            init_opt_final_mol.cart_coords,
            atol=0.0001)
        np.testing.assert_equal(act_init_opt_final_e, init_opt_final_e)

        # Optimization of 0 torsion
        opt_0 = self.get_task_collection().find_one({"task_label": "opt_0"})
        opt_0_final_mol = Molecule.from_dict(
            opt_0["output"]["optimized_molecule"])
        opt_0_final_e = opt_0["output"]["final_energy"]
        # parse output file
        act_opt_0_out = QCOutput(
            os.path.join(test_tor_files, "opt_0", "mol.qout"))
        act_opt_0_mol = act_opt_0_out.data["molecule_from_optimized_geometry"]
        act_opt_0_final_e = act_opt_0_out.data["final_energy"]

        np.testing.assert_equal(act_opt_0_mol.species, opt_0_final_mol.species)
        np.testing.assert_allclose(
            act_opt_0_mol.cart_coords,
            opt_0_final_mol.cart_coords,
            atol=0.0001)
        np.testing.assert_equal(act_opt_0_final_e, opt_0_final_e)

        # Optimization of 90 torsion
        opt_90 = self.get_task_collection().find_one({"task_label": "opt_90"})
        opt_90_final_mol = Molecule.from_dict(
            opt_90["output"]["optimized_molecule"])
        opt_90_final_e = opt_90["output"]["final_energy"]
        # parse output file
        act_opt_90_out = QCOutput(
            os.path.join(test_tor_files, "opt_90", "mol.qout"))
        act_opt_90_mol = act_opt_90_out.data[
            "molecule_from_optimized_geometry"]
        act_opt_90_final_e = act_opt_90_out.data["final_energy"]

        np.testing.assert_equal(act_opt_90_mol.species,
                                opt_90_final_mol.species)
        np.testing.assert_allclose(
            act_opt_90_mol.cart_coords,
            opt_90_final_mol.cart_coords,
            atol=0.0001)
        np.testing.assert_equal(act_opt_90_final_e, opt_90_final_e)

        # Optimization of 180 torsion
        opt_180 = self.get_task_collection().find_one({
            "task_label": "opt_180"
        })
        opt_180_final_mol = Molecule.from_dict(
            opt_180["output"]["optimized_molecule"])
        opt_180_final_e = opt_180["output"]["final_energy"]
        # parse output file
        act_opt_180_out = QCOutput(
            os.path.join(test_tor_files, "opt_180", "mol.qout"))
        act_opt_180_mol = act_opt_180_out.data[
            "molecule_from_optimized_geometry"]
        act_opt_180_final_e = act_opt_180_out.data["final_energy"]

        np.testing.assert_equal(act_opt_180_mol.species,
                                opt_180_final_mol.species)
        np.testing.assert_allclose(
            act_opt_180_mol.cart_coords,
            opt_180_final_mol.cart_coords,
            atol=0.0001)
        np.testing.assert_equal(act_opt_180_final_e, opt_180_final_e)
Exemplo n.º 40
0
    """
    remainder = {}
    count_dict = get_elements_count(structure)
    weights = get_weight(stoich)
    scaled_max = max([count_dict[ele]*weights[ele] for ele in stoich.keys() ]) #determine the scaled maximum neded

    while scaled_max % lcm_list(list(weights.values())): # increase scaled max until it can accomodate correct stoichiometry
        scaled_max = scaled_max + 1

    for ele, count in count_dict.items():
        remainder[ele] = int((scaled_max - count_dict[ele]*weights[ele]) / (weights[ele]))

    return remainder


surf = Molecule.from_file('D:\\Users\\RyanTrottier\\Documents\\Scrap\\tmp.'+type)

center_i = 787
center = surf[center_i] # pymatgen.core.sites.Site
for radius in [3,4,5,6,8]:
    dr = 4

    stoich = get_stoichiometry(surf)

    sites = [center] + [ x[0] for x in surf.get_neighbors(center, radius)]

    mol = Molecule.from_sites(sites)
    remainder = get_remainder(mol, stoich)

    i = 0 # going to iterate over all sites, starting with the closest
    add_sites = surf.get_neighbors_in_shell(center.coords, radius+dr, dr)
Exemplo n.º 41
0
    def get_subgraphs_as_molecules(self, use_weights=False):
        """
        Retrieve subgraphs as molecules, useful for extracting
        molecules from periodic crystals.

        Will only return unique molecules, not any duplicates
        present in the crystal (a duplicate defined as an
        isomorphic subgraph).

        :param use_weights (bool): If True, only treat subgraphs
        as isomorphic if edges have the same weights. Typically,
        this means molecules will need to have the same bond
        lengths to be defined as duplicates, otherwise bond
        lengths can differ. This is a fairly robust approach,
        but will treat e.g. enantiomers as being duplicates.

        :return: list of unique Molecules in Structure
        """

        # creating a supercell is an easy way to extract
        # molecules (and not, e.g., layers of a 2D crystal)
        # without adding extra logic
        if getattr(self, '_supercell_sg', None) is None:
            self._supercell_sg = supercell_sg = self*(3,3,3)

        # make undirected to find connected subgraphs
        supercell_sg.graph = nx.Graph(supercell_sg.graph)

        # find subgraphs
        all_subgraphs = list(nx.connected_component_subgraphs(supercell_sg.graph))

        # discount subgraphs that lie across *supercell* boundaries
        # these will subgraphs representing crystals
        molecule_subgraphs = []
        for subgraph in all_subgraphs:
            intersects_boundary = any([d['to_jimage'] != (0, 0, 0)
                                      for u, v, d in subgraph.edges(data=True)])
            if not intersects_boundary:
                molecule_subgraphs.append(subgraph)

        # add specie names to graph to be able to test for isomorphism
        for subgraph in molecule_subgraphs:
            for n in subgraph:
                subgraph.add_node(n, specie=str(supercell_sg.structure[n].specie))

        # now define how we test for isomorphism
        def node_match(n1, n2):
            return n1['specie'] == n2['specie']
        def edge_match(e1, e2):
            if use_weights:
                return e1['weight'] == e2['weight']
            else:
                return True

        # prune duplicate subgraphs
        unique_subgraphs = []
        for subgraph in molecule_subgraphs:

            already_present = [nx.is_isomorphic(subgraph, g,
                                                node_match=node_match,
                                                edge_match=edge_match)
                               for g in unique_subgraphs]

            if not any(already_present):
                unique_subgraphs.append(subgraph)

        # get Molecule objects for each subgraph
        molecules = []
        for subgraph in unique_subgraphs:

            coords = [supercell_sg.structure[n].coords for n
                      in subgraph.nodes()]
            species = [supercell_sg.structure[n].specie for n
                      in subgraph.nodes()]

            molecule = Molecule(species, coords)

            # shift so origin is at center of mass
            molecule = molecule.get_centered_molecule()

            molecules.append(molecule)

        return molecules
Exemplo n.º 42
0
# coding: utf-8

from __future__ import division, print_function, unicode_literals, absolute_import

from atomate.qchem.workflows.base.FF_then_fragment import get_wf_FF_then_fragment
from fireworks.core.launchpad import LaunchPad
from pymatgen.core import Molecule

mol = Molecule.from_file("BF4-.xyz")
wf = get_wf_FF_then_fragment(molecule=mol, max_cores=32)
lp = LaunchPad.auto_load()
lp.add_wf(wf)