近年来锂离子电池大规模应用的快速发展要求系统地了解锂离子电池的退化机制,这在很大程度上取决于先进表征方法的利用和发展。基于
X 射线的技术,如 X 射线吸收光谱(XAS)、X 射线衍射(XRD)和 X
射线光电子能谱(XPS),可以确定化学成分和元素的价态和晶体结构的变化。
电子和扫描探针显微技术,(3)如扫描电子显微镜(SEM)、透射电子显微镜(TEM)和低温透射电镜,可以观察电极的形貌变化和固体电解质界面(SEI)的厚度。基于滴定的技术,如滴定气相色谱(TGC)(4)和质谱滴定(MST),(5,6)可以定量死
Li 金属和 SEI
组分。此外,固态核磁共振(NMR)(7)和电子顺磁共振(EPR)(8)能够实现对
Li
镀层的时间分辨和定量检测。然而,这些方法大多是侵入性技术,需要额外昂贵以及具有特殊电池设计的精密仪器进行测试,在实际应用中是不可行的。
除了这些物理特性之外,电化学方法,如差分电压分析(DVA)、(9,10)差分充电电压(DCV)、(11)增量容量分析(ICA)、(12)和库仑效率(CE)、(13,14)也在电池老化研究中发挥了重要作用。然而,它们是相当复杂的确定方法,需要很长的监测时间。
1917 年,赫尔首次描述了简单粉末衍射仪的构造,这是在 1895
年威廉·康拉德·伦琴发现 X 射线后不久。衍射仪测量 X
射线反射的角度,从而获得其包含的结构信息。如今,这项技术的分辨率有了显著提高,它被广泛用作分析相信息和解决固态材料晶体结构的工具。X
射线衍射技术用于确定样品的组成或晶体结构。对于大分子和无机化合物等较大的晶体,它可用于确定样品中原子的结构。如果晶体尺寸太小,它可以确定样品的组成、结晶度和相纯度。
什么是X射线?
X射线是一种电磁波,由内壳层电子跃迁所得:
X 射线由内壳层电子跃迁产生
对于原子序数为Z、仅含一个电子的类氢原子,内壳层电子跃迁所辐射的能量可由Rydberg方程计算:
$$
\bar{v}=(\dfrac{1}{n_i^2}-\dfrac{1}{n_f^2})RZ^2
$$
可以明显看出,与电子跃迁相关的能量差随着原子序数的增加而大幅增大,并且在这种跃迁过程中发射的辐射波长随着原子序数的增加从
10−7 m (1000 Å) 范围移至
10−10 m (1
Å)范围(此时辐射的电磁波被定义为X射线,此辐射类型被称为特征辐射)、
如下图,要引发这种内壳层跃迁,需要产生一个电子空位,必须从K层中移除一个电子。由高压电场加速过的阴极电子书轰击靶材,将其部分能量传递给靶材料的电子,从而导致电子激发。如果入射电子的能量足够高,一些电子可能会击出靶中
K 壳层的一个电子,从而产生一个空位
电子能谱的基础是光电效应:当能量为hν的单色光照射到样品上时,样品中的原子或分子吸收能量从而使电子脱离样品成为自由电子(即光电子)逸出,与此同时还能产生==俄歇电子和荧光X射线等==
hν = Eb + Ek + Er
其中Eb为原子的始态和终态能量差,可以看成发射的光电子的结合能;Er为原子的反冲能量,可忽略
Al Kα的能量是1486.6
eV,这个能量足够高,能够有效地激发周期表中绝大多数元素(从轻元素如Li到重元素)的核心能级电子(如C
1s, O 1s, N 1s, Fe 2p, Au
4f等),这些能级是XPS分析化学态的关键。能量不是越高越好。能量过高(如Cu
Kα的8048
eV)会产生更强的韧致辐射本底和更多的二次电子,增加谱图的背景噪音。同时,高能光子的光电离截面(电离效率)在特定能量范围外会降低。1486.6
eV是一个在激发效率和背景噪音之间取得良好平衡的能量点。
definput_target(self): f = input("Enter target formula: ").strip() self.target = FormulaParser.parse(f) for e, c inself.target.items(): if e notinself.atomic_masses: raise ValueError(f"Mass of element {e} not defined") self.target_mm += c * self.atomic_masses[e] print(f"Parsed: {self.target}") print(f"Target molar mass = {self.target_mm.normalize()} g/mol")
definput_reagents(self): n = int(input("Enter number of reagents: ")) for i inrange(n): f = input(f"Reagent {i+1} formula: ").strip() self.reagent_formulas.append(f) parsed = FormulaParser.parse(f) mm = sum(parsed[e] * self.atomic_masses[e] for e in parsed) self.reagents.append(parsed) self.molar_masses.append(mm) print(f"{f} molar mass = {mm.normalize()} g/mol")
defvalidate(self): tgt = set(self.target) prov = set().union(*(r.keys() for r inself.reagents)) miss = tgt - prov extra = prov - tgt if miss: print(f"Error: Missing elements: {miss}") exit() if extra: print(f"Warning: Extra elements: {extra}")
defsolve_basis(self): # Construct A, b corresponding to 1 mol elems = sorted(set(self.target) | set().union(*(r.keys() for r inself.reagents))) A = [[r.get(e, Decimal(0)) for r inself.reagents] for e in elems] b = [self.target.get(e, Decimal(0)) for e in elems] # Convert to rational number to avoid floating point error A_rat = [[Rational(str(val)) for val in row] for row in A] b_rat = [Rational(str(val)) for val in b] vars = symbols(f'x0:{len(self.reagents)}') sol = linsolve((Matrix(A_rat), Matrix(b_rat)), vars) ifnot sol: print("Error: No exact solution for 1 mol target.") exit() tup = next(iter(sol)) # Convert rational to decimal exact representation base = {} for i, r inenumerate(tup): base[vars[i]] = Decimal(r.p) / Decimal(r.q) return base, elems
defcalculate(self): t = input("Input type (0 mass g, 1 moles): ").strip() if t notin ['0','1']: print("Invalid type") exit() v = Decimal(input("Amount: ").strip()) n = v / self.target_mm if t=='0'else v print(f"Target moles = {n.normalize()}")
base, elems = self.solve_basis() print("\nReagent requirements:\n" + "="*40) total_mass = Decimal(0) for i, var inenumerate(sorted(base.keys(), key=lambda x: int(str(x)[1:]))): moles = base[var] * n mass = moles * self.molar_masses[i] total_mass += mass print(f"Reagent {i+1} ({self.reagent_formulas[i]}):") print(f" Moles: {moles.normalize():.10f} mol") print(f" Mass: {mass.normalize():.10f} g\n") print(f"Total mass = {total_mass.normalize():.10f} g")
#Verify element balance print("Verification:") for e in elems: actual = sum((base[symbols(f'x{i}')] * n) * r.get(e, Decimal(0)) for i, r inenumerate(self.reagents)) target_amt = self.target.get(e, Decimal(0)) * n print(f"{e}: target {target_amt.normalize():.10f}, actual {actual.normalize():.10f}")
# For what used to be vasp.5.lib CPP_LIB = $(CPP) FC_LIB = $(FC) CC_LIB = icc CFLAGS_LIB = -O FFLAGS_LIB = -O1 FREE_LIB = $(FREE)
OBJECTS_LIB = linpack_double.o
# For the parser library CXX_PARS = icpc LLIBS = -lstdc++
## ## Customize as of this point! Of course you may change the preceding ## part of this file as well if you like, but it should rarely be ## necessary ... ##
# When compiling on the target machine itself, change this to the # relevant target when cross-compiling for another architecture VASP_TARGET_CPU ?= -xHOST FFLAGS += $(VASP_TARGET_CPU)
# Intel MKL (FFTW, BLAS, LAPACK, and scaLAPACK) # (Note: for Intel Parallel Studio's MKL use -mkl instead of -qmkl) FCL += -qmkl=sequential MKLROOT ?= /opt/intel/oneapi/mkl/2022.1.0 #一定要添加MKLROOT的目录,否则会报错
------------>> 01 ==================== VASP Input Files Options =================== 101) Customize INCAR File 102) Generate KPOINTS File for SCF Calculation 103) Generate POTCAR File with Default Setting 104) Generate POTCAR File with User Specified Potential 105) Generate POSCAR File from cif (no fractional occupations) 106) Generate POSCAR File from Material Studio xsd (retain fixes) 107) Reformat POSCAR File in Specified Order of Elements 108) Successive Procedure to Generate VASP Files and Check 109) Submit Job Queue
0) Quit 9) Back ------------>> ------------>> 101 +---------------------------- Tip ------------------------------+ | WARNNING: You MUST know what wou are doing! | |Some Parameters in INCAR file need to be set/adjusted manually.| +---------------------------------------------------------------+ ======================== INCAR Options ========================== ST) Static-Calculation SR) Standard Relaxation MG) Magnetic Properties SO) Spin-Orbit Coupling D3) DFT-D3 no-damping Correction H6) HSE06 Calculation PU) DFT+U Calculation MD) Molecular Dynamics GW) GW0 Calculation BS) BSE Calculation DC) Elastic Constant EL) ELF Calculation BD) Bader Charge Analysis OP) Optical Properties EC) Static Dielectric Constant PC) Decomposed Charge Density PH) Phonon-Calculation PY) Phonon with Phononpy NE) Nudged Elastic Band (NEB) DM) The Dimer Method FQ) Frequence Calculation LR) Lattice Relaxation MT) Meta-GGA Calculation PZ) Piezoelectric Calculation
0) Quit 9) Back ------------>> Input Key-Parameters (STH6D3 means HSE06-D3 Static-Calcualtion)
''' 分析AIMD结果,计算MSD 和 conductivity ''' import os from pymatgen.core.trajectory import Trajectory from pymatgen.io.vasp.outputs import Xdatcar from pymatgen.core import Structure from pymatgen.analysis.diffusion.analyzer import DiffusionAnalyzer import numpy as np import pickle import matplotlib.pyplot as plt