Elastic constant¶
[1]:
import mdapy as mp
mp.__version__
[1]:
'1.0.3'
MD to calculate elastic constant¶
[2]:
al = mp.build_crystal('Al', 'fcc', 4.05)
calc = mp.NEP("../../tests/input_files/UNEP-v1.txt")
[3]:
elas = mp.get_elastic_constant(al, calc)
[4]:
elas.print()
Elastic tensor (GPa):
121.27 54.01 54.01 0.00 0.00 0.00
54.01 121.27 54.01 0.00 0.00 0.00
54.01 54.01 121.27 0.00 0.00 0.00
0.00 0.00 0.00 42.89 0.00 0.00
0.00 0.00 0.00 0.00 42.89 0.00
0.00 0.00 0.00 0.00 0.00 42.89
[5]:
elas.print_vrh()
Voigt-Reuss-Hill averages:
Property Voigt Reuss Hill Unit
------------------------------------------------------------------
Bulk modulus K 76.43 76.43 76.43 GPa
Shear modulus G 39.19 38.64 38.91 GPa
Young's modulus E 99.80 GPa
Poisson's ratio nu 0.2824 -
Voigt = upper bound | Reuss = lower bound | Hill = best estimate
Voigt-Reuss gap (K+G): 0.55 GPa (larger = more anisotropic)
[6]:
elas.voigt.round(2)
[6]:
array([[121.27, 54.01, 54.01, 0. , 0. , 0. ],
[ 54.01, 121.27, 54.01, 0. , 0. , 0. ],
[ 54.01, 54.01, 121.27, 0. , 0. , 0. ],
[ 0. , 0. , 0. , 42.89, 0. , 0. ],
[ 0. , 0. , 0. , 0. , 42.89, 0. ],
[ 0. , 0. , 0. , 0. , 0. , 42.89]])
DFT to calculate elastic constant¶
Perform full DFT optimization of the structure, including both atomic positions and cell parameters.
Generate a set of deformed structures based on the optimized configuration.
Compute the stress for each deformed structure using DFT (with energy minimization).
from mdapy.elastic import DeformedStructureSet, ElasticTensor, strain_from_deformation
# Load the DFT-optimized structure.
# Both cell and energy should be fully relaxed beforehand.
system = mp.System('opt.POSCAR')
# Generate a set of deformed structures.
# Note: mdapy does not account for symmetry, so even a simple FCC structure
# will produce 24 deformed configurations by default.
dfm_ss = DeformedStructureSet(system)
# Save each deformed structure.
# These structures can then be used for subsequent DFT calculations to obtain stress.
# Here, only energy minimization is considered as an example.
for i, j in enumerate(dfm_ss.deformed_systems):
j.write_poscar(f'{i}.POSCAR')
# After completing the DFT calculations, collect the stress for each deformed structure.
strain_list, stress_list = [], []
for defo in dfm_ss.deformations:
stress_list.append(stress) # Stress corresponding to each deformed structure
strain_list.append(strain_from_deformation(defo))
# Fit the elastic tensor using the collected strain–stress data.
elas = ElasticTensor.from_independent_strains(
strain_list,
stress_list,
eq_stress=equi_stress # Stress of the initial optimized (equilibrium) structure
)