def get_mulliken_charges(self, initial: Atoms, verbose=True): ''' This function is used to retrieve atomic charges using Mulliken charge decomposition as implemented in FHI-aims. A new trajectory file containing the charges Args: initial: Atoms Atoms object containing structural information for the calculation verbose: bool Flag for turning off printouts in the code Returns: Atoms object with charges appended ''' from ase.io.trajectory import Trajectory from carmm.analyse.mulliken import extract_mulliken_charge '''Setup initial parameters''' params = self.params hpc = self.hpc basis_set = self.basis_set self.initial = initial dimensions = sum(self.initial.pbc) '''Parent directory''' parent_dir = os.getcwd() '''Read the geometry''' if not self.filename: self.filename = self.initial.get_chemical_formula() filename = self.filename assert type(filename) == str, "Invalid type, filename should be string" counter, subdirectory_name = self._restart_setup( "Charges", self.filename) '''Check for previously completed calculation''' if os.path.exists( os.path.join(subdirectory_name[:-1] + str(counter - 1), filename + "_charges.traj")): file_location = os.path.join( subdirectory_name[:-1] + str(counter - 1), filename + "_charges.traj") self.initial = read(file_location) if verbose: print("Previously calculated structure has been found at", file_location) return self.initial out = str(counter) + "_" + str(filename) + ".out" '''Set the environment variables for geometry optimisation''' set_aims_command(hpc=hpc, basis_set=basis_set, defaults=2020) '''Request Mulliken charge decomposition''' params["output"] = ["Mulliken_summary"] os.makedirs(subdirectory_name, exist_ok=True) os.chdir(subdirectory_name) with _calc_generator(params, out_fn=out, dimensions=dimensions, forces=False)[0] as calculator: if not self.dry_run: self.initial.calc = calculator else: self.initial.calc = EMT() self.initial.get_potential_energy() if not self.dry_run: charges = extract_mulliken_charge(out, len(self.initial)) else: charges = initial.get_charges() self.initial.set_initial_charges(charges) traj = Trajectory(filename + "_charges.traj", 'w') traj.write(self.initial) traj.close() os.chdir(parent_dir) return self.initial
nf = len(y) pos.append([float(x) for x in y[nf - 4:nf - 1]]) syms += y[1].strip('0123456789') y = s.readline().split() pos = np.array(pos) * alat natoms = len(pos) # create atoms object with coordinates and unit cell # as specified in the initial ionic step in log atoms = Atoms(syms, pos, cell=cell * alat, pbc=(1, 1, 1)) atoms.get_calculator = calc.get_calculator atoms.get_potential_energy = calc.get_potential_energy atoms.get_forces = calc.notimpl atoms.get_stress = calc.notimpl atoms.get_charges = calc.notimpl # get total energy at first ionic step en = get_total_energy(s) if en is not None: calc.set_energy(en) else: print >>stderr, 'no total energy found' exit(3) print(atoms) traj = PickleTrajectory(argv[2], 'w') traj.write(atoms)