Ejemplo n.º 1
0
    def single_sc_loop(self, sc_loop, initial_bg):
        """Run a single iteration of the sc loop, with or without Ewald"""
        sc_name = "sc_" + self.inputs["name"]
        # Initial charges in mol
        old_charges = self.region_1.charges()

        # if sc_eec then there is no initial_bg so it needs to be computed
        if self.mode == "ew_sc":
            points = self.run_ewald(calc_name=sc_name)
            initial_bg = points

        ef.write_gauss(sc_name + ".com", self.region_1, initial_bg,
                       self.inputs["sc_temp"])

        subprocess.call("${FRO_GAUSS} " + sc_name + ".com", shell=True)
        # Calculate new charges

        intact_charges, new_energy, char_self, char_int = rf.read_g_char(
            sc_name + ".log", self.inputs["high_pop_method"], debug=True)

        # Correct charges if they are not perfectly neutral
        if sum(intact_charges) != 0.0:
            temp_correct = sum(intact_charges) / len(intact_charges)
            intact_charges = [i - temp_correct for i in intact_charges]

        dummy_mol = self.region_1.copy()
        dummy_mol.raw_assign_charges(intact_charges)
        self.region_1.populate(dummy_mol)

        # Damp the change in charges
        new_charges = [
            new * (1 - self.inputs["damping"]) + old * self.inputs["damping"]
            for new, old in zip(self.region_1.charges(), old_charges)
        ]

        # Correct charges again (due to damping)
        if sum(new_charges) != 0.0:
            temp_correct = sum(new_charges) / len(new_charges)
            new_charges = [i - temp_correct for i in new_charges]

        # assign damped charges
        self.region_1.raw_assign_charges(new_charges)
        self.cell.populate(self.region_1)

        if self.mode == "noew_sc":
            assign_charges(self.region_1, initial_bg)

        # Calculate deviation between initial and new charges
        deviation = sum([
            abs(i - j) for (i, j) in zip(self.region_1.charges(), old_charges)
        ]) / len(self.region_1)

        out_str = ("Iteration:", sc_loop, "Deviation:", deviation, "Energy:",
                   new_energy, "Charge self energy:", char_self,
                   "Total - charge self:", new_energy - char_self)
        self.write_out(
            "{:<6} {:<5} {:<6} {:10.6f} {:<6} {:10.6f} {:<6} {:10.6f} {:<6} {:10.6f}\n"
            .format(*out_str))

        return deviation
Ejemplo n.º 2
0
def populate(self, reference_mol):
    """
    Assign charges to the Mol by comparing to the connectivity of a
    reference

    Parameters
    ----------
    reference_mol : Mol object
        Charged molecule or cell

    """
    # This is a naughty in-function import to prevent a circular dependency.
    # The reason is that assign_charges functions are grouped up with the
    # executable script which needs to read_file and in turn use mol.py
    # Some careful refactoring should fix this
    import fromage.scripts.fro_assign_charges as ac
    ac.assign_charges(reference_mol, self)
    return
Ejemplo n.º 3
0
def benz_clust_char(benz_solo):
    """Return a Mol object of a charged benzene cluster"""
    out_char_clust = rf.mol_from_file("benzene_clust.xyz")
    ac.assign_charges(benz_solo, out_char_clust)
    return out_char_clust
Ejemplo n.º 4
0
def pery_cell_char(pery_cell, pery_solo):
    """Return a Mol object of a charged perylene cell"""
    out_char_cell = deepcopy(pery_cell)
    ac.assign_charges(pery_solo, out_char_cell)
    return out_char_cell
Ejemplo n.º 5
0
def benz_cell_char(benz_cell, benz_solo):
    """Return a Mol object of a charged benzene cell"""
    out_char_cell = deepcopy(benz_cell)
    ac.assign_charges(benz_solo, out_char_cell)
    return out_char_cell