Beispiel #1
0
    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)