百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

VASP进行机器学习力场计算的详细步骤和分析方法

ztj100 2025-03-08 02:57 8 浏览 0 评论

VASP机器学习力场(MLFF)是一种基于机器学习技术的力场,具有许多优点。MLFF可以显著加速分子动力学模拟。通过使用该机器学习模型来预测能量和力,以及体系的动力学演化过程,从而大大减少计算时间和资源消耗。以下是VASP进行机器学习力场计算的详细步骤。

#本文摘自github sona2576的例子

步骤一:用VASP进行分子动力学计算从头开始进行即时训练

准备所需的POSCAR起始构型和适当的INCAR、KPOINTS和POTCAR文件。设置ML_LMLFF和ML_MODE标签,启用MLFF功能并设置为训练模式。VASP将根据需要自动执行从头计算,并依靠MLFF的预测结果。输出文件包括OUTCAR、XDATCAR等,同时还会生成MLFF相关的文件(ML_LOGFILE,ML_ABN ,ML_FFN )。INCAR如下:

SYSTEM = Li2SiS3_tetragonal_heating### Electronic structure partPREC = NormalADDGRID = .TRUE.GGA = PSALGO = FastENCUT = 650EDIFF = 1e-6NELM = 400NELMIN = 6ISPIN = 1 ISYM = 0ISMEAR = 0 SIGMA = 0.05
### MD part IBRION = 0 #sets up MDISIF = 3 #allows cell shape and volume changeMDALGO = 3 #sets langevin thermostat SMASS = -1 #ensure T scaling every NBLOCK stepsNSW = 10000 POTIM = 2 NCORE = 20 #set for use in michael A nodes. Make it multiples of 8 or 16 for use in isambard or archerNBLOCK = 20TEBEG = 10TEEND = 300RANDOM_SEED = 743491 0 0 #useful to set a random seed for training runs and use it throughoutLANGEVIN_GAMMA = 10.0 10.0 10.0 #langevin thermostat parameters LANGEVIN_GAMMA_L = 3.0
### Output partLREAL = AutoLWAVE = .FALSE.LCHARG = .FALSE.
### ML primary tagsML_LMLFF = .TRUE. #ML training, use is onML_ISTART = 0 #training is starting from scratchML_CX = -0.1 #to increase frequency of Ab-initio steps, recommended for training at low TML_MB = 3000 #max # of local configurations stored for each element

这里做了温度从10K到300K Li2SSi3的升温分子动力学过程力场训练

以下是RMSE机器学习力场与AIMD对比结果,RMSE(均方差),能量,力,径向分布函数,VACF(速度自相关函数),声子态密度,MSD(均方位移)的对比处理python脚本。

import numpy as npimport plotly.graph_objects as goimport plotly.io as pio
# plotting learning rate wrt steps
! grep STATUS ML_LOGFILE|grep -E 'learning'|grep -v "#" > ./learning.dat! grep STATUS ML_LOGFILE|grep -E 'critical'|grep -v "#" > ./critical.dat! grep STATUS ML_LOGFILE|grep -E 'accurate'|grep -v "#" > ./accurate.dat
steps_learning = np.loadtxt("./learning.dat", usecols=[1], unpack=True)y_learning = [3]*len(steps_learning)
steps_critical = np.loadtxt("./critical.dat", usecols=[1], unpack=True)
y_critical = [2]*len(steps_critical) steps_accurate = np.loadtxt("./accurate.dat", usecols=[1], unpack=True)
y_accurate = [1]*len(steps_accurate)
fig = go.Figure()
fig.add_trace(go.Scatter(x = steps_learning, y = y_learning, mode='markers', name='learning'))fig.add_trace(go.Scatter(x = steps_critical, y = y_critical, mode='markers', name='critical'))fig.add_trace(go.Scatter(x = steps_accurate, y = y_accurate, mode='markers', name='accurate'))fig.update_yaxes(visible=False)fig.update_xaxes(title='steps')fig.update_layout(title="Monitoring quality of FF steps, 10 - 300 K run")fig.show()pio.write_image(fig, './10-300K_status.png', format='png')
! grep ERR ML_LOGFILE|grep -v "#"|awk '{print $2, $4}' > ERR.dat! grep BEEF ML_LOGFILE|grep -v "#"|awk '{print $2, $4}' > BEEF.dat! grep BEEF ML_LOGFILE|grep -v "#"|awk '{print $2, $6}' > CTIFOR.dat
steps_err, err = np.loadtxt('./ERR.dat', unpack=True)
steps_beef, beef = np.loadtxt('./BEEF.dat', unpack=True)
steps_beef, ctifor = np.loadtxt('./CTIFOR.dat', unpack=True)

fig2 = go.Figure()fig2.add_trace(go.Scatter(x=steps_err, y = err, mode='lines+markers', name='ERR'))fig2.add_trace(go.Scatter(x=steps_beef, y = beef, mode='lines', name='BEEF'))fig2.add_trace(go.Scatter(x=steps_beef, y = ctifor, mode='lines', name='CTIFOR'))fig2.update_layout(title='RMSE, Bayesian error, and CTIFOR (eV/A)')fig2.update_xaxes(title='steps')fig2.update_yaxes(title='error in force, eV/A')fig2.show()
pio.write_image(fig2, './10-300K_err_beef_ctifor.png', format='png')

! grep LCONF ML_LOGFILE| grep -v "#" > LCONF.dat
steps, liconf_old, liconf_new, siconf_old, siconf_new, sconf_old, sconf_new = np.loadtxt("./LCONF.dat", usecols=[1, 3, 4, 6, 7, 9, 10], unpack=True)
fig1 = go.Figure()
fig1.add_trace(go.Scatter(x = steps, y = liconf_old, mode='lines+markers', name='Li conf old', marker={'color' : 'darkblue', 'opacity' : 0.5}))fig1.add_trace(go.Scatter(x = steps, y = liconf_new, mode='lines+markers', name='Li conf new', marker={'color' : 'blue', 'opacity' : 0.5}))fig1.add_trace(go.Scatter(x = steps, y = siconf_new, mode='lines+markers', name='Si conf new', marker={'color' : 'red', 'opacity' : 0.5}))fig1.add_trace(go.Scatter(x = steps, y = siconf_old, mode='lines+markers', name='Si conf old', marker={'color' : 'darkred', 'opacity' : 0.5}))fig1.add_trace(go.Scatter(x = steps, y = sconf_new, mode='lines+markers', name='S conf new', marker={'color' : 'limegreen', 'opacity' : 0.5}))fig1.add_trace(go.Scatter(x = steps, y = sconf_old, mode='lines+markers', name='S conf old', marker={'color' : 'olive', 'opacity' : 0.5}))fig1.update_layout(title='Number of configurations added per element each learning step')fig1.update_xaxes(title='steps')fig1.update_yaxes(title='number of local configurations')fig1.show()pio.write_image(fig1, './300K_lconf.png', format='png')
from pymatgen.core import Structurefrom pymatgen.io.vasp.outputs import Xdatcar, Vasprunimport osfrom os import pathimport xml.etree.ElementTree as ET import numpy as npfrom vasppy.outcar import forces_from_outcar, final_energy_from_outcarimport matplotlib.pyplot as pltimport scipy.stats as stats
%matplotlib inline%config InlineBackend.figure_format='retina'
import figure_formatting.figure_formatting as ffff.set_formatting() # set default formatting.
dft_relaxed = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/14%P_cont_validation/14%P-doped-system/energy_force_testing/DFT/'mlff_relaxed_lite = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/14%P_cont_validation/14%P-doped-system/energy_force_testing/ML_FF_litercut5/'
def plot_energy_diff(dft_dir1, mlff_dir1): dft_energies = [] mlff_energies = []
# go to dft directory and get the number of folders in this directory with integer names os.chdir(dft_dir1) n_structures1 = len([name for name in os.listdir(".") if os.path.isdir(name)])

for i in range(1, n_structures1+1): e = final_energy_from_outcar(dft_dir1 + f'{i}/' + 'OUTCAR') n_atoms = len(Structure.from_file(f'{dft_dir1}{i}/POSCAR')) dft_energies.append(float(e/n_atoms)) m = final_energy_from_outcar(mlff_dir1 + f'{i}/' + 'OUTCAR') mlff_energies.append(float(m/n_atoms)) # define root means square error, max error and mean error
rmse = np.sqrt(np.mean(np.square(np.array(dft_energies) - np.array(mlff_energies)))) max_error = max(abs(np.array(dft_energies) - np.array(mlff_energies))) mean_avg_error = np.mean(abs(np.array(dft_energies) - np.array(mlff_energies)))
plt.figure(figsize=(7, 3))
plt.subplot(1, 2, 1)
plt.scatter(dft_energies, mlff_energies, color = 'blue', s=10) plt.xlabel('DFT energies, eV/atom', fontsize=12) plt.ylabel('MLFF energies, eV/atom', fontsize=12) plt.text(0.05, 0.95, f'RMSE: {rmse:.3f} \n MAX: {max_error:.3f} \n MAE: {mean_avg_error:.3f}', transform=plt.gca().transAxes, fontsize=10, verticalalignment='top') plt.minorticks_on() # plt.legend(loc='center', fontsize=10) plt.xticks(fontsize=10, rotation=45) plt.yticks(fontsize=10)
# plt.colorbar()
e_diff = np.array(dft_energies) - np.array(mlff_energies) plt.subplot(1, 2, 2) plt.scatter(range(len(e_diff)), e_diff*1000, color = 'grey', s=10) plt.xlabel('Structures', fontsize=12) plt.ylabel('(DFT-MLFF) Energy, meV/atom', fontsize=12) plt.minorticks_on() plt.xticks(fontsize=10) plt.yticks(fontsize=10)
plt.tight_layout()
plt.show()
# Call the function with your directory paths
plot_energy_diff(dft_relaxed, mlff_relaxed_lite)

def plot_forces(species, dft_dir1, mlff_dir1):
os.chdir(dft_dir1) n_structures1 = len([name for name in os.listdir(".") if os.path.isdir(name)]) # determining indices of given species structure = Structure.from_file(f'{dft_dir1}{1}/POSCAR') species_list = [] for atom in structure: species_list.append(atom.species_string)
if species not in species_list: raise ValueError("Selected species not present in structure") plot_indices = [] for index, atom in enumerate(species_list): if atom == species: plot_indices.append(index)
# dictionary of ml forces
def get_forces(mlff_dir, dft_dir, n_structures): ml_run = {} for step in range(1, n_structures+1): tree = ET.parse(f'{mlff_dir}{step}/vasprun.xml') root = tree.getroot() for structure in root.findall('varray'): if 'forces' in structure.attrib['name']: ml_run[step] = {} for atom_index, l in enumerate(structure): l = str(l.text).strip() l = l.split(" ") forces_atom = [float(l[0]),float(l[1]),float(l[2])] ml_run[step][atom_index] = np.linalg.norm(forces_atom)
dft_run = {} for step in range(1, n_structures+1): dft_run[step] = {} forces = forces_from_outcar(f'{dft_dir}{step}/OUTCAR') for atoms in range(0, len(forces[0])): dft_run[step][atoms] = np.linalg.norm(forces[0][atoms])
return ml_run, dft_run
ml_run1, dft_run1 = get_forces(mlff_dir1, dft_dir1, n_structures1)
def get_scalar_forces(ml_run, dft_run, n_structures): ml_force = [] dft_force = []
for step in range(1, n_structures+1): for atom in ml_run[step]: if atom in plot_indices: scalar_force = ml_run[step][atom] ml_force.append(scalar_force)
for step in range(1, n_structures+1): for atom in dft_run[step]: if atom in plot_indices: scalar_force = dft_run[step][atom] dft_force.append(scalar_force) return ml_force, dft_force
ml_force, dft_force = get_scalar_forces(ml_run1, dft_run1, n_structures1)
return ml_force, dft_force
ml_force_li, dft_force_li = plot_forces('Li', dft_relaxed, mlff_relaxed_lite)ml_force_si, dft_force_si = plot_forces('Si', dft_relaxed, mlff_relaxed_lite)ml_force_p, dft_force_p = plot_forces('P', dft_relaxed, mlff_relaxed_lite)ml_force_s, dft_force_s = plot_forces('S', dft_relaxed, mlff_relaxed_lite)
total_force_ml = ml_force_li + ml_force_si + ml_force_p + ml_force_stotal_force_dft = dft_force_li + dft_force_si + dft_force_p + dft_force_s
rmse = np.sqrt(np.mean(np.square(np.array(total_force_dft) - np.array(total_force_ml))))max_error = max(abs(np.array(total_force_dft) - np.array(total_force_ml)))mean_avg_error = np.mean(abs(np.array(total_force_dft) - np.array(total_force_ml)))
e_diff = np.array(total_force_dft) - np.array(total_force_ml)
plt.figure(figsize=(7, 3))
plt.subplot(1, 2, 1)plt.scatter(total_force_dft, total_force_ml, color = 'blue', s=10)plt.xlabel('DFT Forces, eV/A', fontsize=12)plt.ylabel('MLFF Forces, eV/A', fontsize=12)plt.text(0.05, 0.95, f'RMSE: {rmse:.3f} \n MAX: {max_error:.3f} \n MAE: {mean_avg_error:.3f}', transform=plt.gca().transAxes, fontsize=10, verticalalignment='top')plt.minorticks_on()plt.xticks(fontsize=10)plt.yticks(fontsize=10)
plt.subplot(1, 2, 2)plt.scatter(range(len(e_diff)), e_diff, color = 'grey', s=10)plt.xlabel(f'Atoms', fontsize=12)plt.ylabel('(DFT-MLFF) Forces, eV/A', fontsize=12)plt.minorticks_on()plt.xticks(fontsize=10)plt.yticks(fontsize=10)
plt.tight_layout()
plt.show()

from pymatgen.core import Structurefrom pymatgen.io.vasp.outputs import Xdatcarimport osfrom os import pathimport xml.etree.ElementTree as ETfrom pymatgen.io.vasp.outputs import Vasprunimport numpy as npfrom plotly.subplots import make_subplotsimport plotly.graph_objects as goimport plotly.io as pio
AIMD_dir_780 = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/aimd/780_aimd/'ML_dir_780 = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/MD/780_md/'AIMD_dir_500 = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/aimd/500_aimd/'ML_dir_500 = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/MD/500_md/'AIMD_dir_300 = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/aimd/300_aimd/'ML_dir_300 = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/MD/300_md/'

f_u = 4supercell = 3*3*2
outcar_a_780 = f'{AIMD_dir_780}OUTCAR'outcar_a_500 = f'{AIMD_dir_500}OUTCAR'outcar_a_300 = f'{AIMD_dir_300}OUTCAR'
oszicar_a_780 = f'{AIMD_dir_780}OSZICAR'oszicar_a_500 = f'{AIMD_dir_500}OSZICAR'oszicar_a_300 = f'{AIMD_dir_300}OSZICAR'
outcar_m_780 = f'{ML_dir_780}OUTCAR'outcar_m_500 = f'{ML_dir_500}OUTCAR'outcar_m_300 = f'{ML_dir_300}OUTCAR'
oszicar_m_780 = f'{ML_dir_780}OSZICAR'oszicar_m_500 = f'{ML_dir_500}OSZICAR'oszicar_m_300 = f'{ML_dir_300}OSZICAR'
volume_a_780 = []volume_a_500 = []volume_a_300 = []
volume_m_780 = []volume_m_500 = []volume_m_300 = []
T_a_780 = []T_a_500 = []T_a_300 = []
T_m_780 = []T_m_500 = []T_m_300 = []

with open(outcar_a_780, mode = 'r') as file: lines = file.readlines()
for line in lines: if "volume of cell :" in line: volume_a_780.append(float(line.split()[4])/f_u/supercell)
with open(outcar_a_500, mode = 'r') as file: lines = file.readlines()
for line in lines: if "volume of cell :" in line: volume_a_500.append(float(line.split()[4])/f_u/supercell)
with open(outcar_a_300, mode = 'r') as file: lines = file.readlines()
for line in lines: if "volume of cell :" in line: volume_a_300.append(float(line.split()[4])/f_u/supercell)
with open(oszicar_a_780, mode = 'r') as file: lines = file.readlines()
for line in lines: if "T=" in line: T_a_780.append(float(line.split()[2]))
with open(oszicar_a_500, mode = 'r') as file: lines = file.readlines()
for line in lines: if "T=" in line: T_a_500.append(float(line.split()[2]))
with open(oszicar_a_300, mode = 'r') as file: lines = file.readlines()
for line in lines: if "T=" in line: T_a_300.append(float(line.split()[2]))
with open(outcar_m_780, mode = 'r') as file: lines = file.readlines()
for line in lines: if "volume of cell :" in line: volume_m_780.append(float(line.split()[4])/f_u/supercell)
with open(outcar_m_500, mode = 'r') as file: lines = file.readlines()
for line in lines: if "volume of cell :" in line: volume_m_500.append(float(line.split()[4])/f_u/supercell)
with open(outcar_m_300, mode = 'r') as file: lines = file.readlines()
for line in lines: if "volume of cell :" in line: volume_m_300.append(float(line.split()[4])/f_u/supercell)
with open(oszicar_m_780, mode = 'r') as file: lines = file.readlines()
for line in lines: if "T=" in line: T_m_780.append(float(line.split()[2]))
with open(oszicar_m_500, mode = 'r') as file: lines = file.readlines()
for line in lines: if "T=" in line: T_m_500.append(float(line.split()[2]))
with open(oszicar_m_300, mode = 'r') as file: lines = file.readlines()
for line in lines: if "T=" in line: T_m_300.append(float(line.split()[2]))
fig = make_subplots(rows=1, cols=1)
fig.add_trace( go.Scatter(x=T_a_780, y=volume_a_780, mode='markers', name='AIMD 780', marker={'opacity' : 0.5}), row=1, col=1)
fig.add_trace( go.Scatter(x=T_m_780, y=volume_m_780, mode='markers', name='MLFF 780', marker={'opacity' : 0.5}), row=1, col=1)
fig.add_trace( go.Scatter(x=T_a_500, y=volume_a_500, mode='markers', name='AIMD 500', marker={'opacity' : 0.5}), row=1, col=1)
fig.add_trace( go.Scatter(x=T_m_500, y=volume_m_500, mode='markers', name='MLFF 500', marker={'opacity' : 0.5}), row=1, col=1)
fig.add_trace( go.Scatter(x=T_a_300, y=volume_a_300, mode='markers', name='AIMD 300', marker={'opacity' : 0.5}), row=1, col=1)
fig.add_trace( go.Scatter(x=T_m_300, y=volume_m_300, mode='markers', name='MLFF 300', marker={'opacity' : 0.5}), row=1, col=1)
fig.update_xaxes(title_text='T, K')fig.update_yaxes(title_text='Volume/f.u,, A3')
fig.show()
from pymatgen.io.vasp.outputs import Xdatcarfrom vasppy.rdf import RadialDistributionFunctionimport numpy as npimport matplotlib.pyplot as plt
aimd_dir = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/aimd/14P-300/xdatcars/'mlff_dir_lite = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/14%P_from_scratch_validation/MSD-RDF-md/30ps-lite/'

xd_aimd = Xdatcar(aimd_dir+'XDATCAR_collated_1-3')
rdf_lili = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Li')rdf_lisi = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Li', species_j='Si')rdf_lis = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Li', species_j='S')rdf_sisi = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Si')rdf_sis = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Si', species_j='S')rdf_ss = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='S')rdf_lip = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Li', species_j='P')rdf_pp = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='P')rdf_sip = RadialDistributionFunction.from_species_strings(structures=xd_aimd.structures, species_i='Si', species_j='P')
xd_ml = Xdatcar(mlff_dir_lite+'XDATCAR')
rdf_lili_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Li')rdf_lisi_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Li', species_j='Si')rdf_lis_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Li', species_j='S')rdf_sisi_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Si')rdf_sis_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Si', species_j='S')rdf_ss_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='S')rdf_lip_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Li', species_j='P')rdf_pp_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='P')rdf_sip_m = RadialDistributionFunction.from_species_strings(structures=xd_ml.structures, species_i='Si', species_j='P')
# plot the RDFs
fig, axes = plt.subplots(3, 3, figsize=(6, 9), sharex=False, sharey=False)
axes[0, 0].plot(rdf_lili.r, rdf_lili.rdf, color='red', label='AIMD')axes[0, 1].plot(rdf_sisi.r, rdf_sisi.rdf, color='red', label='AIMD')axes[0, 2].plot(rdf_ss.r, rdf_ss.rdf, color='red', label='AIMD')axes[1, 0].plot(rdf_lisi.r, rdf_lisi.rdf, color='red', label='AIMD')axes[1, 1].plot(rdf_lis.r, rdf_lis.rdf, color='red', label='AIMD')axes[1, 2].plot(rdf_sis.r, rdf_sis.rdf, color='red', label='AIMD')axes[2, 0].plot(rdf_lip.r, rdf_lip.rdf, color='red', label='AIMD')axes[2, 1].plot(rdf_pp.r, rdf_pp.rdf, color='red', label='AIMD')axes[2, 2].plot(rdf_sip.r, rdf_sip.rdf, color='red', label='AIMD')
axes[0, 0].plot(rdf_lili_m.r, rdf_lili_m.rdf, color='green', label='3% P, 300K')axes[0, 1].plot(rdf_sisi_m.r, rdf_sisi_m.rdf, color='green', label='3% P, 300K')axes[0, 2].plot(rdf_ss_m.r, rdf_ss_m.rdf, color='green', label='3% P, 300K')axes[1, 0].plot(rdf_lisi_m.r, rdf_lisi_m.rdf, color='green', label='3% P, 300K')axes[1, 1].plot(rdf_lis_m.r, rdf_lis_m.rdf, color='green', label='3% P, 300K')axes[1, 2].plot(rdf_sis_m.r, rdf_sis_m.rdf, color='green', label='3% P, 300K')axes[2, 0].plot(rdf_lip_m.r, rdf_lip_m.rdf, color='green', label='3% P, 300K')axes[2, 1].plot(rdf_pp_m.r, rdf_pp_m.rdf, color='green', label='3% P, 300K')axes[2, 2].plot(rdf_sip_m.r, rdf_sip_m.rdf, color='green', label='3% P, 300K')
# Add titles and labelsaxes[0, 0].set_title('Li-Li RDF', fontsize=10, loc='center')axes[0, 1].set_title('Si-Si RDF', fontsize=10, loc='center')axes[0, 2].set_title('S-S RDF', fontsize=10, loc='center')axes[1, 0].set_title('Li-Si RDF', fontsize=10, loc='center')axes[1, 1].set_title('Si-S RDF', fontsize=10, loc='center')axes[1, 2].set_title('Li-S RDF', fontsize=10, loc='center')axes[2, 0].set_title('Li-P RDF', fontsize=10, loc='center')axes[2, 1].set_title('P-P RDF', fontsize=10, loc='center')axes[2, 2].set_title('Si-P RDF', fontsize=10, loc='center')
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

axes[0, 0].set_ylabel('g(r)', fontsize=10)axes[1, 0].set_ylabel('g(r)', fontsize=10)axes[2, 0].set_ylabel('g(r)', fontsize=10)axes[1, 0].set_xlabel('r, A', fontsize=10)axes[1, 1].set_xlabel('r, A', fontsize=10)axes[1, 2].set_xlabel('r, A', fontsize=10)axes[0, 0].set_xlabel('r, A', fontsize=10)axes[0, 1].set_xlabel('r, A', fontsize=10)axes[0, 2].set_xlabel('r, A', fontsize=10)axes[2, 0].set_xlabel('r, A', fontsize=10)axes[2, 1].set_xlabel('r, A', fontsize=10)axes[2, 2].set_xlabel('r, A', fontsize=10)
plt.tight_layout()plt.show()

import matplotlib.pyplot as pltimport numpy as npfrom py4vasp import Calculationimport scipy.linalgfrom tqdm import tqdmimport matplotlib.pyplot as plt

%matplotlib inline%config InlineBackend.figure_format='retina'
import figure_formatting.figure_formatting as ffff.set_formatting() # set default formatting.
aimd_dir = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/aimd/14P-600/14%P-600-nvt-2/'mlff_dir_lite = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/14%P_cont_validation/14%P-doped-system/VACF-md/10ps_litercut5/'
velocities_aimd = Calculation.from_path(aimd_dir).velocity[:690:1].read()['velocities']velocities_mlff_lite = Calculation.from_path(mlff_dir_lite).velocity[:690:1].read()['velocities']
velocities_aimd_li = velocities_aimd[:, 0:134, :]velocities_mlff_li_lite = velocities_mlff_lite[:, 0:134, :]velocities_aimd_si = velocities_aimd[:, 134:196, :]velocities_mlff_si_lite = velocities_mlff_lite[:, 134:196, :]velocities_aimd_p = velocities_aimd[:, 196:206, :]velocities_mlff_p_lite = velocities_mlff_lite[:, 196:206, :]velocities_aimd_s = velocities_aimd[:, 206:422, :]velocities_mlff_s_lite = velocities_mlff_lite[:, 206:422, :]
N_frames = velocities_aimd_li.shape[0] # use same number of frames for both calculationsN_block = 5timestep = 2 # in fsdt = timestep * N_block # single interval length for velocity outputingt = np.arange(0, N_frames*dt, dt) # time array
def vacf(velocities, atoms): correlation_matrix = []
for n in tqdm(range(atoms)): correlation_list = [] for k in range(0, len(velocities), 1): buffer_sum = 0 denominator = len(range(0, len(velocities) - k)) for j in range(0, len(velocities) - k): velocity_vector_1 = velocities[j][n, :] velocity_vector_2 = velocities[k + j][n, :] dot_product = np.sum(velocity_vector_1 * velocity_vector_2) norm_product = scipy.linalg.norm(velocity_vector_1) * scipy.linalg.norm(velocity_vector_2) buffer_sum += dot_product / norm_product # buffer sum is the sum of the correlation terms for each moving frame correlation_list.append(buffer_sum / denominator) # correlation list is the averaged correlation values for each frame correlation_matrix.append(correlation_list) # in correlation matrix we end up with correlation_matrix = np.array(correlation_matrix)
correlation_matrix = np.mean(correlation_matrix, axis=0)
return correlation_matrix
vacf_aimd_p = vacf(velocities_aimd_p, 10)vacf_mlff_p_lite = vacf(velocities_mlff_p_lite, 10)
plt.figure(figsize=(3, 3))plt.plot(t/1000, vacf_aimd_p, 'b-', linewidth=1, label='AIMD')plt.plot(t/1000, vacf_mlff_p_lite, 'r-', linewidth=1, label='MLFF')plt.legend(loc='best')plt.xlabel('Time (ps)', fontsize=12)plt.ylabel('VACF', fontsize=12)plt.xlim(0, 1.5)plt.xticks(fontsize=10)plt.yticks(fontsize=10)plt.tight_layout()plt.show()

import matplotlib.pyplot as pltimport numpy as npfrom py4vasp import Calculationimport scipy.linalgfrom tqdm import tqdmimport matplotlib.pyplot as plt

%matplotlib inline%config InlineBackend.figure_format='retina'
import figure_formatting.figure_formatting as ffff.set_formatting() # set default formatting.
aimd_dir = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/aimd/14P-600/14%P-600-nvt-2/'mlff_dir_lite = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/doped/14%P_cont_validation/14%P-doped-system/VACF-md/10ps_litercut5/'
velocities_aimd = Calculation.from_path(aimd_dir).velocity[:690:1].read()['velocities']velocities_mlff_lite = Calculation.from_path(mlff_dir_lite).velocity[:690:1].read()['velocities']
velocities_aimd_li = velocities_aimd[:, 0:134, :]velocities_mlff_li_lite = velocities_mlff_lite[:, 0:134, :]velocities_aimd_si = velocities_aimd[:, 134:196, :]velocities_mlff_si_lite = velocities_mlff_lite[:, 134:196, :]velocities_aimd_p = velocities_aimd[:, 196:206, :]velocities_mlff_p_lite = velocities_mlff_lite[:, 196:206, :]velocities_aimd_s = velocities_aimd[:, 206:422, :]velocities_mlff_s_lite = velocities_mlff_lite[:, 206:422, :]
N_frames = velocities_aimd_li.shape[0] # use same number of frames for both calculationsN_block = 5timestep = 2 # in fsdt = timestep * N_block # single interval length for velocity outputingt = np.arange(0, N_frames*dt, dt) # time array
def vacf(velocities, atoms): correlation_matrix = []
for n in tqdm(range(atoms)): correlation_list = [] for k in range(0, len(velocities), 1): buffer_sum = 0 denominator = len(range(0, len(velocities) - k)) for j in range(0, len(velocities) - k): velocity_vector_1 = velocities[j][n, :] velocity_vector_2 = velocities[k + j][n, :] dot_product = np.sum(velocity_vector_1 * velocity_vector_2) norm_product = scipy.linalg.norm(velocity_vector_1) * scipy.linalg.norm(velocity_vector_2) buffer_sum += dot_product / norm_product # buffer sum is the sum of the correlation terms for each moving frame correlation_list.append(buffer_sum / denominator) # correlation list is the averaged correlation values for each frame correlation_matrix.append(correlation_list) # in correlation matrix we end up with correlation_matrix = np.array(correlation_matrix)
correlation_matrix = np.mean(correlation_matrix, axis=0)
return correlation_matrix
vacf_aimd_p = vacf(velocities_aimd_p, 10)vacf_mlff_p_lite = vacf(velocities_mlff_p_lite, 10)
plt.figure(figsize=(3, 3))plt.plot(t/1000, vacf_aimd_p, 'b-', linewidth=1, label='AIMD')plt.plot(t/1000, vacf_mlff_p_lite, 'r-', linewidth=1, label='MLFF')plt.legend(loc='best')plt.xlabel('Time (ps)', fontsize=12)plt.ylabel('VACF', fontsize=12)plt.xlim(0, 1.5)plt.xticks(fontsize=10)plt.yticks(fontsize=10)plt.tight_layout()plt.show()100%|██████████| 10/10 [00:42<00:00, 4.22s/it]100%|██████████| 10/10 [00:42<00:00, 4.23s/it]
Taking Fourier transform of VACF gives us power spectrum. Good agreement in overall shape of power spectrum for every constituent element indicates that lattice vibrations for framework atoms (P, Si, S) and short time scale vibrational dynamics for diffusion ion (Li) is captured accurately by the forcefield.
def VACF_fft(VACF, dt): VACF_fft = np.fft.fft(VACF) VACF_fft = np.fft.fftshift(VACF_fft) freq = np.fft.fftfreq(len(VACF), d=dt) freq = np.fft.fftshift(freq) return VACF_fft, freq
VACF_fft_aimd, freq = VACF_fft(vacf_aimd_p, dt)VACF_fft_mlff_lite, freq = VACF_fft(vacf_mlff_p_lite, dt)
plt.figure(figsize=(4, 3))plt.plot(freq*1000, VACF_fft_aimd.real, 'b-', linewidth=1, label='AIMD')plt.plot(freq*1000, VACF_fft_mlff_lite.real, 'r-', linewidth=1, label='MLFF')plt.xlabel('Frequency (THz)', fontsize=12)plt.ylabel('Phonon DOS', fontsize=12)plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))plt.xlim(0, 20)plt.minorticks_on()plt.xticks(fontsize=10)plt.yticks(fontsize=10)plt.tight_layout()plt.show()

from pymatgen.core import Structurefrom pymatgen.io.vasp.outputs import Xdatcarimport matplotlib.pyplot as pltimport numpy as npfrom kinisi.analyze import DiffusionAnalyzer, ConductivityAnalyzer, JumpDiffusionAnalyzerfrom kinisi.diffusion import Bootstrapfrom kinisi.arrhenius import StandardArrheniusimport warningswarnings.filterwarnings("ignore", category=UserWarning)np.random.seed(42)
%matplotlib inline%config InlineBackend.figure_format='retina'
import figure_formatting.figure_formatting as ffff.set_formatting() # set default formatting.
aimd_dir = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/aimd/600/xdatcars/'mlff_dir_lite = '/Users/sona/Desktop/Research/project_2/tetragonal-li2sis3/MD/validationmd/xdatcars_600_mich/'
temp = 600
# for Aimdp_param_li = {'specie': 'Li', 'time_step': 20.0, 'step_skip': 1}

p_param_si = {'specie': 'Si', 'time_step': 20.0, 'step_skip': 1}

p_param_s = {'specie': 'S', 'time_step': 20.0, 'step_skip': 1}
# for ML
p_param_li_m = {'specie': 'Li', 'time_step': 2.0, 'step_skip': 10}
p_param_si_m = {'specie': 'Si', 'time_step': 2.0, 'step_skip': 10}
p_param_s_m = {'specie': 'S', 'time_step': 2.0, 'step_skip': 10}
xd_a = Xdatcar(aimd_dir +'XDATCAR_collated_5-8')diff_li_a = DiffusionAnalyzer.from_Xdatcar(xd_a, parser_params=p_param_li)diff_si_a = DiffusionAnalyzer.from_Xdatcar(xd_a, parser_params=p_param_si)diff_s_a = DiffusionAnalyzer.from_Xdatcar(xd_a, parser_params=p_param_s)
xd_m_lite = Xdatcar(mlff_dir_lite +'XDATCAR_collated_1-2')diff_li_m = DiffusionAnalyzer.from_Xdatcar(xd_m_lite, parser_params=p_param_li_m)diff_si_m = DiffusionAnalyzer.from_Xdatcar(xd_m_lite, parser_params=p_param_si_m)diff_s_m = DiffusionAnalyzer.from_Xdatcar(xd_m_lite, parser_params=p_param_s_m)
plt.errorbar(diff_li_a.dt, diff_li_a.msd, diff_li_a.msd_std, label='Li MSD (AIMD)')plt.errorbar(diff_si_a.dt, diff_si_a.msd, diff_si_a.msd_std)plt.errorbar(diff_s_a.dt, diff_s_a.msd, diff_s_a.msd_std)
plt.errorbar(diff_li_m.dt, diff_li_m.msd, diff_li_m.msd_std, label='Li MSD (MLFF)')plt.errorbar(diff_si_m.dt, diff_si_m.msd, diff_si_m.msd_std)plt.errorbar(diff_s_m.dt, diff_s_m.msd, diff_s_m.msd_std)
plt.axvline(5, color='b')
plt.ylabel('MSD/A$^2
)plt.xlabel('$\Delta t$/ps')plt.xlim(0, 30)plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))plt.show()

最后如果训练的力场不够精确,或者我们需要得到某一温度下更精确的力场可以,使用之前训练的模型进行进一步训练,注意需要将ML_ABN文件拷贝为ML_AB作为输入文件。INCAR具体如下:

SYSTEM = Li2SiS3_tetragonal_780_retrain### Electronic structure partPREC = NormalADDGRID = .TRUE.GGA = PSALGO = FastENCUT = 650EDIFF = 1e-6NELM = 400NELMIN = 6ISPIN = 1 ISYM = 0ISMEAR = 0 SIGMA = 0.05
### MD part IBRION = 0 ISIF = 3MDALGO = 3NSW = 0 POTIM = 1 NCORE = 32NBLOCK = 20TEBEG = 780TEEND = 780RANDOM_SEED = 743491 0 0LANGEVIN_GAMMA = 10.0 10.0 10.0LANGEVIN_GAMMA_L = 3.0
### Output partLREAL = AutoLWAVE = .FALSE.LCHARG = .FALSE.
### ML primary tagsML_LMLFF = .TRUE.ML_ISTART = 1ML_IALGO_LINREG = 3ML_RCUT2 = 6.0ML_RCUT1 = 6.0ML_CTIFOR = 1000ML_MB = 4000ML_LBASIS_DISCARD = .TRUE.

参考:

https://github.com/Sona2576/mlff_guide_scripts/blob/main/MLFF_guide.ipynbhttps://www.vasp.at/wiki/index.php/Machine_learning_force_field_calculations:_Basics

相关推荐

使用 Pinia ORM 管理 Vue 中的状态

转载说明:原创不易,未经授权,谢绝任何形式的转载状态管理是构建任何Web应用程序的重要组成部分。虽然Vue提供了管理简单状态的技术,但随着应用程序复杂性的增加,处理状态可能变得更具挑战性。这就是为什么...

Vue3开发企业级音乐Web App 明星讲师带你学习大厂高质量代码

Vue3开发企业级音乐WebApp明星讲师带你学习大厂高质量代码下栽课》jzit.top/392/...

一篇文章说清 webpack、vite、vue-cli、create-vue 的区别

webpack、vite、vue-cli、create-vue这些都是什么?看着有点晕,不要怕,我们一起来分辨一下。...

超赞 vue2/3 可视化打印设计VuePluginPrint

今天来给大家推荐一款非常不错的Vue可拖拽打印设计器Hiprint。引入使用//main.js中引入安装import{hiPrintPlugin}from'vue-plugin-...

搭建Trae+Vue3的AI开发环境(vue3 ts开发)

从2024年2025年,不断的有各种AI工具会在自媒体中火起来,号称各种效率王炸,而在AI是否会替代打工人的话题中,程序员又首当其冲。...

如何在现有的Vue项目中嵌入 Blazor项目?

...

Vue中mixin怎么理解?(vue的mixins有什么用)

作者:qdmryt转发链接:https://mp.weixin.qq.com/s/JHF3oIGSTnRegpvE6GSZhg前言...

Vue脚手架安装,初始化项目,打包并用Tomcat和Nginx部署

1.创建Vue脚手架#1.在本地文件目录创建my-first-vue文件夹,安装vue-cli脚手架:npminstall-gvue-cli安装过程如下图所示:创建my-first-vue...

新手如何搭建个人网站(小白如何搭建个人网站)

ElementUl是饿了么前端团队推出的桌面端UI框架,具有是简洁、直观、强悍和低学习成本等优势,非常适合初学者使用。因此,本次项目使用ElementUI框架来完成个人博客的主体开发,欢迎大家讨论...

零基础入门vue开发(vue快速入门与实战开发)

上面一节我们已经成功的安装了nodejs,并且配置了npm的全局环境变量,那么这一节我们就来正式的安装vue-cli,然后在webstorm开发者工具里运行我们的vue项目。这一节有两种创建vue项目...

.net core集成vue(.net core集成vue3)

react、angular、vue你更熟悉哪个?下边这个是vue的。要求需要你的计算机安装有o.netcore2.0以上版本onode、webpack、vue-cli、vue(npm...

使用 Vue 脚手架,为什么要学 webpack?(一)

先问大家一个很简单的问题:vueinitwebpackprjectName与vuecreateprojectName有什么区别呢?它们是Vue-cli2和Vue-cli3创建...

vue 构建和部署(vue项目部署服务器)

普通的搭建方式(安装指令)安装Node.js检查node是否已安装,终端输入node-v会使用命令行(安装)npminstallvue-cli-首先安装vue-clivueinitwe...

Vue.js 环境配置(vue的环境搭建)

说明:node.js和vue.js的关系:Node.js是一个基于ChromeV8引擎的JavaScript运行时环境;类比:Java的jvm(虚拟机)...

vue项目完整搭建步骤(vuecli项目搭建)

简介为了让一些不太清楚搭建前端项目的小白,更快上手。今天我将一步一步带领你们进行前端项目的搭建。前端开发中需要用到框架,那vue作为三大框架主流之一,在工作中很常用。所以就以vue为例。...

取消回复欢迎 发表评论: