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
def run(self, atoms): """ Write a Gaussian input file and return a subprocess.Popen Parameters ---------- atoms : list of Atom objects Atoms to be calculated with Gaussian Returns ------- proc : subprocess.Popen object the object should have a .wait() method """ gauss_path = os.path.join(self.here, self.calc_name) os.chdir(gauss_path) ef.write_gauss(self.calc_name + ".com", atoms, [], self.calc_name + ".temp") proc = subprocess.Popen("${FRO_GAUSS} " + self.calc_name + ".com", shell=True) os.chdir(self.here) return proc