Exemplo n.º 1
0
def aucu_phonons():
    N = 7
    atoms = bulk("Au", crystalstructure="fcc", a=4.08)
    calc = EMT()
    atoms.set_calculator(calc)

    ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05)
    ph.run()
    ph.read(acoustic=True)
    ph.clean()
    omega_e_au, dos_e_au = ph.dos(kpts=(50, 50, 50), npts=1000, delta=5E-4)

    atoms = bulk("Cu", crystalstructure="fcc", a=3.62)
    atoms.set_calculator(calc)

    ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05)
    ph.run()
    ph.read(acoustic=True)
    ph.clean()
    omega_e_cu, dos_e_cu = ph.dos(kpts=(13, 13, 13), npts=100, delta=5E-4)

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(omega_e_au * 1000.0, dos_e_au)
    ax.plot(omega_e_cu * 1000.0, dos_e_cu)
    ax.set_xlabel("Energy (meV)")

    logw_au = np.sum(np.log(omega_e_au[1:]) * dos_e_au[1:])
    logw_cu = np.sum(np.log(omega_e_cu[1:]) * dos_e_cu[1:])
    print(logw_au, logw_cu, logw_au - logw_cu)
    plt.show()
def getLJeigenvaluesB(X, S, epsilon, sigma, rc, getForceMatrix):
    from ase import Atoms
    from ase.build import bulk
    from ase.calculators.lj import LennardJones
    from ase.phonons import Phonons
    import numpy as np
    from scipy import linalg as LA
    calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc)
    # chemStr = 'H' + str(len(X))
    # atoms = Atoms(chemStr, X, calculator=calc )
    atoms = Atoms(getChemStr(S), X, calculator=calc)
    energy = atoms.get_potential_energy()
    eig = []
    if getForceMatrix:
        ph = Phonons(atoms, calc)
        ph.run()
        ph.read(acoustic=True)
        ph.clean()

        f = ph.get_force_constant()
        (l, m, n) = f.shape
        if l == 1:
            ff = np.reshape(f, (m, n))
        else:
            print("error")
        #
        eig = LA.eigvalsh(ff)  # eig is a numpy array
    #
    return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
 def _calculate_finite_difference_hessian(self, atoms, calculator):
     """Calcualte the Hessian matrix using finite differences."""
     ph = Phonons(atoms, calculator, supercell=(1, 1, 1), delta=1e-6)
     ph.clean()
     ph.run()
     ph.read(acoustic=False)
     ph.clean()
     H_numerical = ph.get_force_constant()[0, :, :]
     return H_numerical
 def test_hessian(self):
     for calc in [{(1, 1): LennardJonesQuadratic(1, 1, 3), (1, 2): LennardJonesQuadratic(1.5, 0.8, 2.4), (2, 2): LennardJonesQuadratic(0.5, 0.88, 2.64)}]:
         atoms = io.read("KA256_Min.xyz")
         atoms.center(vacuum=5.0)
         b = calculator.PairPotential(calc)
         H_analytical = b.calculate_hessian_matrix(atoms, "dense")
         # Numerical
         ph = Phonons(atoms, b, supercell=(1, 1, 1), delta=0.001)
         ph.run()
         ph.read(acoustic=False)
         ph.clean()
         H_numerical = ph.get_force_constant()[0, :, :]
         self.assertArrayAlmostEqual(H_analytical, H_numerical, tol=0.03)
Exemplo n.º 5
0
def get_dos(
        model,
        posinp,
        device="cpu",
        supercell=(6, 6, 6),
        qpoints=[30, 30, 30],
        npts=1000,
        width=0.004,
):
    if isinstance(posinp, str):
        atoms = posinp_to_ase_atoms(Posinp.from_file(posinp))
    elif isinstance(posinp, Posinp):
        atoms = posinp_to_ase_atoms(posinp)
    else:
        raise ValueError("The posinp variable is not recognized.")

    if isinstance(model, str):
        model = load_model(model, map_location=device)
    elif isinstance(model, torch.nn.Module):
        pass
    else:
        raise ValueError("The model variable is not recognized.")

    # Bugfix to make older models work with PyTorch 1.6
    # Hopefully temporary
    for mod in model.modules():
        if not hasattr(mod, "_non_persistent_buffers_set"):
            mod._non_persistent_buffers_set = set()

    assert len(supercell) == 3, "Supercell should be a length 3 object."
    assert len(qpoints) == 3, "Qpoints should be a length 3 object."
    supercell = tuple(supercell)

    cutoff = float(model.state_dict()
                   ["representation.interactions.0.cutoff_network.cutoff"])
    calculator = SpkCalculator(
        model,
        device=device,
        energy="energy",
        forces="forces",
        environment_provider=AseEnvironmentProvider(cutoff),
    )
    ph = Phonons(atoms, calculator, supercell=supercell, delta=0.02)
    ph.run()
    ph.read(acoustic=True)
    dos = ph.get_dos(kpts=qpoints).sample_grid(npts=npts, width=width)
    ph.clean()
    return Dos(dos.energy * 8065.6, dos.weights[0])
Exemplo n.º 6
0
 def test_hessian(self):
     for calc in [{
         (1, 1): LennardJonesQuadratic(1, 1, 3),
         (1, 2): LennardJonesQuadratic(1.5, 0.8, 2.4),
         (2, 2): LennardJonesQuadratic(0.5, 0.88, 2.64)
     }]:
         atoms = io.read("KA256_Min.xyz")
         atoms.center(vacuum=5.0)
         b = calculator.PairPotential(calc)
         H_analytical = b.calculate_hessian_matrix(atoms, "dense")
         # Numerical
         ph = Phonons(atoms, b, supercell=(1, 1, 1), delta=0.001)
         ph.run()
         ph.read(acoustic=False)
         ph.clean()
         H_numerical = ph.get_force_constant()[0, :, :]
         self.assertArrayAlmostEqual(H_analytical, H_numerical, tol=0.03)
Exemplo n.º 7
0
def calculate_phonons(x):
    # Setup crystal and EMT calculator
    atoms = bulk('Al', 'fcc', a=x)  #4.05)

    # Phonon calculator
    N = 7
    ph = Phonons(atoms, EMT(), supercell=(N, N, N), delta=0.05)
    ph.run()

    # Read forces and assemble the dynamical matrix
    ph.read(acoustic=True)
    ph.clean()

    path = atoms.cell.bandpath('GXULGK', npoints=100)
    bs = ph.get_band_structure(path)

    dos = ph.get_dos(kpts=(20, 20, 20)).sample_grid(npts=100, width=1e-3)

    forces = ph.get_force_constant()
    print(forces)

    # Plot the band structure and DOS:
    import matplotlib.pyplot as plt
    fig = plt.figure(1, figsize=(8, 4), dpi=300)
    ax = fig.add_axes([.12, .07, .67, .85])

    emax = 0.035

    bs.plot(ax=ax, emin=-0.01, emax=emax)

    dosax = fig.add_axes([.8, .07, .17, .85])
    dosax.fill_between(dos.weights[0],
                       dos.energy,
                       y2=0,
                       color='grey',
                       edgecolor='k',
                       lw=1)

    dosax.set_ylim(-0.01, emax)
    dosax.set_yticks([])
    dosax.set_xticks([])
    dosax.set_xlabel("DOS", fontsize=18)

    fig.savefig('Al_phonon.png')
    return
def getLJeigenvalues(listOfPositions, epsilon, sigma, rc, getForceMatrix):
    from ase import Atoms
    from ase.build import bulk
    from ase.calculators.lj import LennardJones
    from ase.phonons import Phonons
    import numpy as np
    from scipy import linalg as LA
    # from gpaw import GPAW, FermiDirac
    # calc = LennardJones() #a.set_calculator(calc)

    # atoms = bulk('Si', 'diamond', a=5.4)
    # atoms = bulk('H', 'fcc', a=1.1, cubic=True)
    #atoms = Atoms('N3', [(0, 0, 0), (0, 0, 1.1), (0, 0, 2.2)], calculator=LennardJones() )
    # atoms = Atoms('H2', [(0, 0, 0), (0, 0, 1.12246)], calculator=LennardJones() )
    # calc = GPAW(kpts=(5, 5, 5), h=0.2, occupations=FermiDirac(0.))

    chemStr = 'H' + str(len(listOfPositions))
    calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc)
    atoms = Atoms(chemStr, listOfPositions, calculator=calc)

    energy = atoms.get_potential_energy()

    eig = []
    if getForceMatrix:
        ph = Phonons(atoms, calc)
        ph.run()
        ph.read(acoustic=True)
        ph.clean()

        f = ph.get_force_constant()
        # f
        # f.size
        (l, m, n) = f.shape
        if l == 1:
            ff = np.reshape(f, (m, n))
        else:
            print("error")
        #
        # ff
        eig = LA.eigvalsh(ff)  # eig is a numpy array
    #
    return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
 def getEnergyAndEigen(self, aseStruct):
     aseStruct.set_calculator(self.calc)
     energy = aseStruct.get_potential_energy()
     eig = []
     ph = Phonons(aseStruct, self.calc)
     ph.run()
     ph.read(acoustic=True)
     ph.clean()
     f = ph.get_force_constant()
     (l, m, n) = f.shape
     if l == 1:
         ff = np.reshape(f, (m, n))
     else:
         print("error")
     #
     eig = LA.eigvalsh(ff)  # eig is a numpy array
     #
     return energy, [
         float("{0:.5f}".format(eig[i])) for i in range(len(eig))
     ]
def getLJeigenvalues2B(X, S, epsilon, sigma, rc, getForceMatrix, aCell):
    from ase import Atoms
    from ase.build import bulk
    from ase.phonons import Phonons
    import numpy as np
    from scipy import linalg as LA
    from ase import Atom, Atoms
    from lammpslib import LAMMPSlib

    # chemStr = 'H' + str(len(X))
    # struct = Atoms(chemStr, X, cell=(aCell, aCell, aCell), pbc=True)
    struct = Atoms(getChemStr(S), X, cell=(aCell, aCell, aCell), pbc=True)
    lammps_header = ["units       metal"]
    cmds          = [ "pair_style  mlip  /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_LJ.ini",\
                      "pair_coeff  * * " ]
    mylammps = LAMMPSlib(
        lmpcmds=cmds,
        atom_types={1: 1},
        keep_alive=True,
        log_file=
        '/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/log.txt')
    struct.set_calculator(mylammps)
    energy = struct.get_potential_energy()
    eig = []
    if getForceMatrix:
        ph = Phonons(struct, mylammps)
        ph.run()
        ph.read(acoustic=True)
        ph.clean()
        f = ph.get_force_constant()
        (l, m, n) = f.shape
        if l == 1:
            ff = np.reshape(f, (m, n))
        else:
            print("error")
        #
        eig = LA.eigvalsh(ff)  # eig is a numpy array
    #
    return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
Exemplo n.º 11
0
def test_phonon_md_init(asap3):
    # Tests the phonon-based perturbation and velocity distribution
    # for thermal equilibration in MD.

    EMT = asap3.EMT

    rng = RandomState(17)

    atoms = bulk('Pd')
    atoms *= (3, 3, 3)
    avail = [atomic_numbers[sym]
             for sym in ['Ni', 'Cu', 'Pd', 'Ag', 'Pt', 'Au']]
    atoms.numbers[:] = rng.choice(avail, size=len(atoms))
    atoms.calc = EMT()

    opt = FIRE(atoms, trajectory='relax.traj')
    opt.run(fmax=0.001)
    positions0 = atoms.positions.copy()

    phonons = Phonons(atoms, EMT(), supercell=(1, 1, 1), delta=0.05)

    try:
        phonons.run()
        phonons.read()  # Why all this boilerplate?
    finally:
        phonons.clean()
    matrices = phonons.get_force_constant()

    K = matrices[0]
    T = 300 * units.kB

    atoms.calc = EMT()
    Epotref = atoms.get_potential_energy()

    temps = []
    Epots = []
    Ekins = []
    Etots = []


    for i in range(24):
        PhononHarmonics(atoms, K, T, quantum=True, rng=np.random.RandomState(888 + i))

        Epot = atoms.get_potential_energy() - Epotref
        Ekin = atoms.get_kinetic_energy()
        Ekins.append(Ekin)
        Epots.append(Epot)
        Etots.append(Ekin + Epot)
        temps.append(atoms.get_temperature())

        atoms.positions[:] = positions0

        # The commented code would produce displacements/velocities
        # resolved over phonon modes if we borrow some expressions
        # from the function.  Each mode should contribute on average
        # equally to both Epot and Ekin/temperature
        #
        # atoms1.calc = EMT()
        # atoms1 = atoms.copy()
        # v_ac = np.zeros_like(positions0)
        # D_acs, V_acs = ...
        # for s in range(V_acs.shape[2]):
        #     atoms1.positions += D_acs[:, :, s]
        #     v_ac += V_acs[:, :, s]
        #     atoms1.set_velocities(v_ac)
        #     X1.append(atoms1.get_potential_energy() - Epotref)
        #     X2.append(atoms1.get_kinetic_energy())

        print('energies', Epot, Ekin, Epot + Ekin)



    Epotmean = np.mean(Epots)
    Ekinmean = np.mean(Ekins)
    Tmean = np.mean(temps)
    Terr = abs(Tmean - T / units.kB)
    relative_imbalance = abs(Epotmean - Ekinmean) / (Epotmean + Ekinmean)


    print('epotmean', Epotmean)
    print('ekinmean', Ekinmean)
    print('rel imbalance', relative_imbalance)
    print('Tmean', Tmean, 'Tref', T / units.kB, 'err', Terr)

    assert Terr < 0.1*T / units.kB, Terr  # error in Kelvin for instantaneous velocity
    # Epot == Ekin give or take 2 %:
    assert relative_imbalance < 0.1, relative_imbalance


    if 0:
        import matplotlib.pyplot as plt
        I = np.arange(len(Epots))
        plt.plot(I, Epots, 'o', label='pot')
        plt.plot(I, Ekins, 'o', label='kin')
        plt.plot(I, Etots, 'o', label='tot')
        plt.show()
def ase_phonon_calc(
    struct,
    calc=None,
    kpoints=[1, 1, 1],
    ftol=0.01,
    force_clean=False,
    name="asephonon",
):
    """Calculate phonon modes of a molecule using ASE and a given calculator.
    The system will be geometry optimized before calculating the modes. A
    report of the phonon modes will be written to a file and arrays of the
    eigenvectors and eigenvalues returned.

    | Args:
    |   struct (ase.Atoms):     Atoms object with to calculate modes for.
    |   calc (ase.Calculator):  Calculator for energies and forces (if not
    |                           present, use the one from struct)
    |   kpoints (np.ndarray):   Kpoint grid for phonon calculation. If None, just
    |                           do a Vibration modes calculation (default is [1,1,1])
    |   ftol (float):           Tolerance for geometry optimisation (default
    |                           is 0.01 eV/Ang)
    |   force_clean (bool):     If True, force a deletion of all phonon files
    |                           and recalculate them
    | Returns:
    |   evals (float[k-points][modes]):          Eigenvalues of phonon modes
    |   evecs (float[k-points][modes][ions][3]): Eigenvectors of phonon modes
    |   struct (ase.Atoms):                      Optimised structure
    """

    N = len(struct)
    if calc is None:
        calc = struct.calc
    struct = struct.copy()
    calc.atoms = struct
    struct.calc = calc
    dyn = BFGS(struct, trajectory="geom_opt.traj")
    dyn.run(fmax=ftol)

    # Calculate phonon modes
    vib_pbc = kpoints is not None
    if vib_pbc:
        vib = Phonons(struct, calc, name=name)
    else:
        vib = Vibrations(struct, name=name)
    if force_clean:
        vib.clean()
    vib.run()
    if vib_pbc:
        vib.read(acoustic=True)
        path = monkhorst_pack(kpoints)
        evals, evecs = vib.band_structure(path, True)
    else:
        vib.read()
        path = np.zeros((1, 3))
        # One axis added since it's like the gamma point
        evals = np.real(vib.get_energies()[None])
        evecs = np.array([vib.get_mode(i) for i in range(3 * N)])[None]

    # eV to cm^-1
    evals *= ((cnst.electron_volt / cnst.h) / cnst.c) / 100.0
    # Normalise eigenvectors
    evecs /= np.linalg.norm(evecs, axis=(2, 3))[:, :, None, None]

    return ASEPhononData(evals, evecs, path, struct)
Exemplo n.º 13
0
# creates: Al_phonon.png
from ase.build import bulk
from ase.calculators.emt import EMT
from ase.phonons import Phonons

# Setup crystal and EMT calculator
atoms = bulk('Al', 'fcc', a=4.05)

# Phonon calculator
N = 7
ph = Phonons(atoms, EMT(), supercell=(N, N, N), delta=0.05)
ph.run()

# Read forces and assemble the dynamical matrix
ph.read(acoustic=True)
ph.clean()

path = atoms.cell.bandpath('GXULGK', npoints=100)
bs = ph.get_band_structure(path)

dos = ph.get_dos(kpts=(20, 20, 20)).sample_grid(npts=100, width=1e-3)

# Plot the band structure and DOS:
import matplotlib.pyplot as plt
fig = plt.figure(1, figsize=(7, 4))
ax = fig.add_axes([.12, .07, .67, .85])

emax = 0.035
bs.plot(ax=ax, emin=0.0, emax=emax)

dosax = fig.add_axes([.8, .07, .17, .85])
def getLJeigenvalues2(listOfPositions, epsilon, sigma, rc, getForceMatrix,
                      aCell):
    from ase import Atoms
    from ase.build import bulk
    # from ase.calculators.lj import LennardJones
    from ase.phonons import Phonons
    import numpy as np
    from scipy import linalg as LA
    # from gpaw import GPAW, FermiDirac
    # calc = LennardJones() #a.set_calculator(calc)

    # atoms = bulk('Si', 'diamond', a=5.4)
    # atoms = bulk('H', 'fcc', a=1.1, cubic=True)
    #atoms = Atoms('N3', [(0, 0, 0), (0, 0, 1.1), (0, 0, 2.2)], calculator=LennardJones() )
    # atoms = Atoms('H2', [(0, 0, 0), (0, 0, 1.12246)], calculator=LennardJones() )
    # calc = GPAW(kpts=(5, 5, 5), h=0.2, occupations=FermiDirac(0.))

    # d =  1.122 # = 2**(1/6)
    # a = 10.00
    # struct = Atoms( 'H2', positions=[(0, 0, 0), (0, 0, d)] , cell=(a, a, a), pbc=True )

    chemStr = 'H' + str(len(listOfPositions))
    # struct = Atoms(chemStr, listOfPositions, cell=(aCell, aCell, aCell)) # <<< without pbc=True you would need a very large aCell value!
    struct = Atoms(chemStr,
                   listOfPositions,
                   cell=(aCell, aCell, aCell),
                   pbc=True)
    # struct = Atoms(chemStr, positions=positions , cell=(aCell, aCell, aCell), pbc=True )

    ############################################################################
    # from ase.calculators.lj import LennardJones
    # calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc)
    # struct = Atoms(chemStr, listOfPositions, calculator=calc )

    ############################################################################
    from ase import Atom, Atoms
    from lammpslib import LAMMPSlib
    # lammps_header=['units       metal'    ,\
    #                'boundary    p p p '   ,\
    #                "atom_style	atomic"   ,\
    #                "atom_modify	map hash"    ]
    lammps_header = ["units       metal"]
    cmds          = [ "pair_style  mlip  /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_LJ.ini",\
                      "pair_coeff  * * " ]
    # cmds = ["pair_style    mlip  /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_LJ.ini",\
    #         "pair_coeff    * * "       ,\
    #         "neighbor      1.5 bin "       ]

    # cmds = ["pair_style    mlip  /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_test.ini",\
    #         "pair_coeff    * * "       ,\
    #         "neighbor      1.5 bin "       ]

    mylammps = LAMMPSlib(
        lmpcmds=cmds,
        atom_types={1: 1},
        keep_alive=True,
        log_file=
        '/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/log.txt')
    # struct = Atoms(chemStr, listOfPositions, calculator=mylammps )
    struct.set_calculator(mylammps)
    ############################################################################

    energy = struct.get_potential_energy()

    eig = []
    if getForceMatrix:
        # ph = Phonons(struct, calc)
        ph = Phonons(struct, mylammps)
        ph.run()
        ph.read(acoustic=True)
        ph.clean()

        f = ph.get_force_constant()
        # f
        # f.size
        (l, m, n) = f.shape
        if l == 1:
            ff = np.reshape(f, (m, n))
        else:
            print("error")
        #
        # ff
        eig = LA.eigvalsh(ff)  # eig is a numpy array
    #
    return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
Exemplo n.º 15
0
atoms *= (3, 3, 3)
avail = [atomic_numbers[sym] for sym in ['Ni', 'Cu', 'Pd', 'Ag', 'Pt', 'Au']]
atoms.numbers[:] = rng.choice(avail, size=len(atoms))
atoms.calc = EMT()

opt = FIRE(atoms, trajectory='relax.traj')
opt.run(fmax=0.001)
positions0 = atoms.positions.copy()

phonons = Phonons(atoms, EMT(), supercell=(1, 1, 1), delta=0.05)

try:
    phonons.run()
    phonons.read()  # Why all this boilerplate?
finally:
    phonons.clean()
matrices = phonons.get_force_constant()

K = matrices[0]
T = 300 * units.kB

atoms.calc = EMT()
Epotref = atoms.get_potential_energy()

temps = []
Epots = []
Ekins = []
Etots = []

for i in range(24):
    PhononHarmonics(atoms,