Phonon Calculation

This script will show how to use mdapy to calculate phonon dispersion.

One should install Phonopy by one of the following ways:

  • pip install phonopy

  • conda install -c conda-forge phonopy

[1]:
# import necessary package

import mdapy as mp
import numpy as np

mp.init()
[Taichi] version 1.7.1, llvm 15.0.1, commit 0f143b2f, win, python 3.10.13
[Taichi] Starting on arch=x64
[2]:
print('mdapy version is :', mp.__version__)
mdapy version is : 0.10.7

We use graphene as an example.

[3]:
# Build a graphene

lat = mp.LatticeMaker(1.42, 'GRA', 1, 1, 1)
lat.compute()

# Add a vacuum layer with 0.2 nm along z direction.
lat.box[2, 2] += 20

# Generate a system

system = mp.System(pos=lat.pos, box=lat.box)

The key step in calculating phonon is obtaining force set from finite displacements. So we need to provide a potential to compute the atomic forces. In mdapy, we originally support NEP and eam/alloy potential. Besides, we also provide a interface to call lammps to computer force, where one need to install lammps-python interface. Further more, user can define a custom potential for whatever you like, and we will discuss latter.

NEP potential

This NEP potential is downloaded from here.

[4]:
potential = mp.NEP('../../../example/C_2022_NEP3.txt')
[5]:
potential.info
[5]:
{'version': 3,
 'zbl': False,
 'radial_cutoff': 4.2,
 'angular_cutoff': 3.7,
 'n_max_radial': 10,
 'n_max_angular': 8,
 'basis_size_radial': 10,
 'basis_size_angular': 8,
 'l_max_3body': 4,
 'num_node': 65,
 'num_para': 6903,
 'element_list': ['C']}

To plot band structure, one need also provide the band path and labels.

One can obtain those by seekpath online.

[6]:
# For graphene
path = '0.0 0.0 0.0 0.3333333333 0.3333333333 0.0 0.5 0.0 0.0 0.0 0.0 0.0'
labels = '$\Gamma$ K M $\Gamma$'
[7]:
# Do computation
system.cal_phono_dispersion(path, labels, potential, elements_list=['C'])
Warning: Point group symmetries of supercell and primitivecell are different.

Then one can plot the band stucture.

[8]:
fig, ax = system.Phon.plot_dispersion()
../_images/gettingstarted_calculate_phonon_16_0.png

One can check the data.

[9]:
system.Phon.bands_dict.keys()
[9]:
dict_keys(['qpoints', 'distances', 'frequencies', 'eigenvectors', 'group_velocities'])

One can also compute the dos, pdos and thermal properties.

Computer dos

[10]:
system.Phon.compute_dos(mesh=(30, 30, 30))
[11]:
fig, ax = system.Phon.plot_dos()
../_images/gettingstarted_calculate_phonon_22_0.png

Compute pdos

[12]:
system.Phon.compute_pdos(mesh=(30, 30, 30))
[13]:
fig, ax = system.Phon.plot_pdos()
../_images/gettingstarted_calculate_phonon_25_0.png

Compute thermal properties

[14]:
system.Phon.compute_thermal(0, 50, 1000, mesh=(30, 30, 30))
[15]:
fig, ax = system.Phon.plot_thermal()
../_images/gettingstarted_calculate_phonon_28_0.png

Airebo potential

Here we show how to use a lammps potential to calculate the phonon. How to install lammps-python interface can be found in here. You can check it by: - from lammps import lammps

[16]:
from mdapy.potential import LammpsPotential

One need to provide the pair_parameter in lammps format.

The airebo potential is downloaded from lammps example folder.

[17]:
potential = LammpsPotential(
    """
    pair_style airebo 3.0
    pair_coeff * * ../../../example/CH.airebo C
    """
)
[18]:
# Do computation
system.cal_phono_dispersion(path, labels, potential, elements_list=['C'])
Warning: Point group symmetries of supercell and primitivecell are different.
[19]:
fig, ax = system.Phon.plot_dispersion()
../_images/gettingstarted_calculate_phonon_35_0.png

Some potential maybe need other setup and the units, such as reaxFF, we need to change the force units.

ReaxFF potential

This reaxff potential is downloaded from here.

[20]:
potential = LammpsPotential(
    """
    pair_style      reax/c ../../../example/lmp_control
    pair_coeff      * * ../../../example/ffield.reax.GR-RDX-2021 Cg
    """,
    atomic_style='charge',
    units='real',
    extra_args='fix 1 all qeq/reax 1 0.0 10.0 1e-6 reax/c',
    conversion_factor={'energy':0, 'force':1/23.06, 'virial':0}
)

# here we do not care energy and virial, only need to converse force from
# kcal/mol/A to eV/A
[21]:
# Do computation
system.cal_phono_dispersion(path, labels, potential, elements_list=['C'])
Warning: Point group symmetries of supercell and primitivecell are different.
[22]:
fig, ax = system.Phon.plot_dispersion()
../_images/gettingstarted_calculate_phonon_41_0.png

Sometimes we want to use other potential not supported by lammps, we can define it for mdapy very easily. Here we use deepmd potential as an example.

User-defined potential

[23]:
from mdapy.potential import BasePotential

One can install deepmd by:

  • pip install deepmd-kit[cpu]

[24]:
import deepmd
WARNING:tensorflow:From d:\Software\miniconda3\envs\mda\lib\site-packages\tensorflow\python\compat\v2_compat.py:108: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
WARNING:root:To get the best performance, it is recommended to adjust the number of threads by setting the environment variables OMP_NUM_THREADS, TF_INTRA_OP_PARALLELISM_THREADS, and TF_INTER_OP_PARALLELISM_THREADS. See https://deepmd.rtfd.io/parallelism/ for more information.
[25]:
deepmd.__version__
[25]:
'2.2.10'
[26]:
from deepmd.infer import DeepPot
[27]:
class DP(BasePotential):

    def __init__(self, filename):
        self.filename = filename
        self.dp = DeepPot(self.filename)

    def compute(self, pos, box, elements_list, type_list, boundary=[1, 1, 1],):
        # This method must containe the above input parameter and keep the same order.
        # You can add other parameter if needed, and those parameter dose not need to be all used.
        # This method should return three parameters and the second is force array. The shape is (Natom, 3).
        # The units should be eV/A.

        coord = pos.reshape([1, -1])
        cell = box[:-1].reshape([1, -1])
        atype = type_list-1
        e, f, v = self.dp.eval(coord, cell, atype)
        return e, f[0], v

This deepmd potential downloaded from this paper. We convert it to new version:

  • dp convert-from -i .:nbsphinx-math:carbon_16689_frozen_model_mmc1.pb -o carbon.pb

[28]:
potential = DP("../../../example/carbon.pb")
WARNING:tensorflow:From d:\Software\miniconda3\envs\mda\lib\site-packages\deepmd\utils\batch_size.py:28: is_gpu_available (from tensorflow.python.framework.test_util) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.config.list_physical_devices('GPU')` instead.
WARNING:tensorflow:From d:\Software\miniconda3\envs\mda\lib\site-packages\deepmd\utils\batch_size.py:28: is_gpu_available (from tensorflow.python.framework.test_util) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.config.list_physical_devices('GPU')` instead.
WARNING:deepmd_utils.utils.batch_size:You can use the environment variable DP_INFER_BATCH_SIZE tocontrol the inference batch size (nframes * natoms). The default value is 1024.
[29]:
# Do computation
system.cal_phono_dispersion(path, labels, potential, elements_list=['C'])
Warning: Point group symmetries of supercell and primitivecell are different.
[30]:
fig, ax = system.Phon.plot_dispersion()
../_images/gettingstarted_calculate_phonon_53_0.png