Commit 13de7538 authored by Yury Lysogorski's avatar Yury Lysogorski
Browse files

less verbose pacemaker-fit-tutorial nb

parent 47e94d42
%% Cell type:code id: tags:
 
``` python
%pylab inline
```
 
%% Output
 
Populating the interactive namespace from numpy and matplotlib
 
%% Cell type:code id: tags:
 
``` python
from pyiron import Project
```
 
%% Cell type:code id: tags:
 
``` python
import pyiron_gpl
```
 
%% Cell type:code id: tags:
 
``` python
data_pr = Project("../../datasets")
if len(data_pr.job_table()) == 0:
data_pr.unpack("Cu_training_archive")
```
 
%% Cell type:code id: tags:
 
``` python
data_pr.job_table()
```
 
%% Output
 
id status chemicalformula job \
0 286 finished None df1_A1_A2_A3_EV_elast_phon
1 287 finished None df3_10k
2 288 finished None df2_1k
subjob projectpath \
0 /df1_A1_A2_A3_EV_elast_phon /home/yury/PycharmProjects/pyiron-2021/
1 /df3_10k /home/yury/PycharmProjects/pyiron-2021/
2 /df2_1k /home/yury/PycharmProjects/pyiron-2021/
project \
0 pyiron_potentialfit/datasets/imported_datasets/Cu_database/
1 pyiron_potentialfit/datasets/imported_datasets/Cu_database/
2 pyiron_potentialfit/datasets/imported_datasets/Cu_database/
timestart timestop totalcputime computer \
0 2021-02-08 10:33:52.341472 None None zora@cmti001#1
1 2021-02-08 10:33:53.993230 None None zora@cmti001#1
2 2021-02-08 10:33:54.435308 None None zora@cmti001#1
hamilton hamversion parentid masterid
0 TrainingContainer 0.4 None None
1 TrainingContainer 0.4 None None
2 TrainingContainer 0.4 None None
 
%% Cell type:markdown id: tags:
 
We will use smalles dataset for fitting, as real dataset took much more time, and go outside of the scope of the workshop
 
%% Cell type:code id: tags:
 
``` python
data_job = data_pr.load('df1_A1_A2_A3_EV_elast_phon')
```
 
%% Cell type:code id: tags:
 
``` python
data_job.to_pandas()
```
 
%% Output
 
name \
0 A1:FHI-aims/PBE/tight:elastic:s_e_0
1 A1:FHI-aims/PBE/tight:murnaghan:strain_1_0
2 A1:FHI-aims/PBE/tight:phonon:supercell_phonon_0
3 A1:FHI-aims/PBE/tight:murnaghan:strain_1_02
4 A1:FHI-aims/PBE/tight:murnaghan:strain_0_98
.. ...
100 A2:FHI-aims/PBE/tight:elastic:s_01_e_0_05000
101 A1:FHI-aims/PBE/tight:elastic:s_01_e_m0_05000
102 A3:FHI-aims/PBE/tight:elastic:s_01_e_m0_05000
103 A2:FHI-aims/PBE/tight:elastic:s_01_e_m0_05000
104 A2:FHI-aims/PBE/tight:elastic:s_23_e_m0_05000
atoms \
0 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
1 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
2 (Atom('Cu', [4.3368086899420173e-19, 0.007070999999999999, 0.007070999999999999], index=0), Atom('Cu', [3.3306690738754696e-16, 1.81563, 1.8156300000000005], index=1), Atom('Cu', [7.262518, 10.893...
3 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
4 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
.. ...
100 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
101 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
102 (Atom('Cu', [1.2150849, 0.70152958, 0.9998186400000001], index=0), Atom('Cu', [0.0, 1.40305917, 2.99945593], index=1))
103 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
104 (Atom('Cu', [0.0, 0.0, 0.0], index=0))
energy \
0 -3.699843
1 -3.699841
2 -236.789603
3 -3.697932
4 -3.697559
.. ...
100 -3.573436
101 -3.546222
102 -7.079448
103 -3.513068
104 -3.494427
forces \
0 [[0.0, 0.0, 0.0]]
1 [[0.0, 0.0, 0.0]]
2 [[-1.13852957740976e-06, -0.0464638907314277, -0.0464636807741622], [-3.86335457040412e-06, 0.0124851330231607, 0.0124792943417333], [-1.94300535086066e-06, 6.63943441884098e-05, 6.92790474109119e...
3 [[0.0, 0.0, 0.0]]
4 [[0.0, 0.0, 0.0]]
.. ...
100 [[0.0, 0.0, 0.0]]
101 [[0.0, 0.0, 0.0]]
102 [[-3.5446112180968e-23, -1.13427558979097e-22, 0.0], [3.5446112180968e-23, 1.13427558979097e-22, 0.0]]
103 [[0.0, 0.0, 0.0]]
104 [[0.0, 0.0, 0.0]]
number_of_atoms
0 1.0
1 1.0
2 64.0
3 1.0
4 1.0
.. ...
100 1.0
101 1.0
102 2.0
103 1.0
104 1.0
[105 rows x 5 columns]
 
%% Cell type:markdown id: tags:
 
# Fitting project
 
%% Cell type:code id: tags:
 
``` python
fit_pr = Project("pacemaker_fit")
```
 
%% Cell type:code id: tags:
 
``` python
job = fit_pr.create_job(job_type=fit_pr.job_type.PaceMakerJob, job_name="df1_cut5_pyace")
```
 
%% Cell type:markdown id: tags:
 
## Fit
 
%% Cell type:code id: tags:
 
``` python
cutoff = 5.0 # potential cutoff
```
 
%% Cell type:markdown id: tags:
 
Potential specification
 
%% Cell type:code id: tags:
 
``` python
job.input["cutoff"] = cutoff # global potential cutoff
```
 
%% Cell type:code id: tags:
 
``` python
job.input["potential"]= {
"deltaSplineBins": 0.001, # spline bins, used for fast radial functions evaluations
 
"element": "Cu", # element - copper
 
"npot": "FinnisSinclairShiftedScaled", # embedding functions
"ndensity": 2, # number of densities: rho_1 and rho_2
"fs_parameters": [1, 1, 1, 0.5], # parameters of embedding functions (for two densities)
#this embedding function corresponds to rho_1 + sqrt(abs(rho_2)) , with some modifications
 
# radial base functions specification
"radbase": "ChebExpCos",
"radparameters": [5.25],
"rcut": cutoff,
"dcut": 0.01,
"NameOfCutoffFunction": "cos",
 
# MOST IMPORTANT: potential "shape" i.e.:
# number of orders (rank), maximum index of radial functions (nradmax) and orbital moments (lmax) for each rank
"rankmax": 3,
"nradmax": [7,2,1],
"lmax": [0,2,1],
}
```
 
%% Cell type:markdown id: tags:
 
Fitting settings:
 
%% Cell type:code id: tags:
 
``` python
job.input["fit"]= {
# loss function specification
'loss': {
'kappa': 0.5, # relative weight of forces residuals
 
# coefficients L1-L2 regularization
'L1_coeffs': 5e-7, # L1-regularization
'L2_coeffs': 5e-7, # L2-regularization
'w1_coeffs': 1,
'w2_coeffs': 1,
 
#radial smoothness regularization
'w0_rad': 1e-4, # for radial functions values
'w1_rad': 1e-4, # for radial functions first derivatives
'w2_rad': 1e-4, # for radial functions second derivatives
},
 
# minimization setup:
'optimizer': 'BFGS', # scipy BFGS algorithm
'maxiter': 150, # max number of iterations
}
```
 
%% Cell type:code id: tags:
 
``` python
```
 
%% Cell type:markdown id: tags:
 
Assign the dataset to fit on
 
%% Cell type:code id: tags:
 
``` python
job.structure_data=data_job
```
 
%% Cell type:markdown id: tags:
 
Run fitting job
 
%% Cell type:code id: tags:
 
``` python
job.run()
```
 
%% Output
 
2021-03-08 11:13:01,028 - root - INFO - structure_data is TrainingContainer
2021-03-08 11:13:01,036 - root - INFO - Saving training structures dataframe into /home/yury/PycharmProjects/pyiron-2021/pyiron_potentialfit/day_2/03-ace/pacemaker_fit/df1_cut5_pyace_hdf5/df1_cut5_pyace/df_fit.pckl.gzip with pickle protocol = 4, compression = gzip
 
The job df1_cut5_pyace was saved and received the ID: 289
 
%% Cell type:code id: tags:
 
``` python
```
 
%% Cell type:code id: tags:
 
``` python
fit_pr.job_table(full_table=True)
```
 
%% Output
 
id status chemicalformula job subjob \
0 289 finished None df1_cut5_pyace /df1_cut5_pyace
projectpath \
0 /home/yury/PycharmProjects/pyiron-2021/
project timestart \
0 pyiron_potentialfit/day_2/03-ace/pacemaker_fit/ 2021-03-08 11:13:01.402031
timestop totalcputime computer \
0 2021-03-08 11:18:19.154866 317.0 pyiron@dell-inspiron#1
hamilton hamversion parentid masterid
0 PaceMakerJob 0.1 None None
 
%% Cell type:code id: tags:
 
``` python
```
 
%% Cell type:markdown id: tags:
 
# Analyse the fitting results
 
%% Cell type:markdown id: tags:
 
loss function
 
%% Cell type:code id: tags:
 
``` python
plt.plot(job["output/log/loss"])
plt.yscale('log')
plt.xlabel("# iter")
plt.ylabel("Loss");
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
RMSE of energies per atoms
 
%% Cell type:code id: tags:
 
``` python
plt.plot(job["output/log/rmse_energy"])
plt.yscale('log')
plt.xlabel("# iter")
plt.ylabel("Energy RMSE, meV/atom");
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
RMSE of forces norm
 
%% Cell type:code id: tags:
 
``` python
plt.plot(job["output/log/rmse_forces"])
plt.yscale('log')
plt.xlabel("# iter")
plt.ylabel("Forces RMSE, meV/Ang/structure");
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
# Overview of the fitted potential internals
 
%% Cell type:code id: tags:
 
``` python
from pyace import *
```
 
%% Cell type:code id: tags:
 
``` python
final_potential = job.get_final_potential()
final_basis_set = ACEBBasisSet(final_potential)
```
 
%% Cell type:markdown id: tags:
 
For single-species potential there is only one **species block** for *Cu*:
 
%% Cell type:code id: tags:
 
``` python
len(final_potential.funcspecs_blocks)
```
 
%% Output
 
1
 
%% Cell type:code id: tags:
 
``` python
Cu_block = final_potential.funcspecs_blocks[0]
```
 
%% Cell type:markdown id: tags:
 
Basic definitions and notations:
 
* Radial functions: $R_{nl}(r) = \sum_k c_{nlk} g_k(r)$
 
 
* Spherical harmonics: $ Y_{lm}(\hat{\pmb{r}}_{ji}) $
 
 
* Basis function: $\phi_{\mu_j \mu_i nlm}(\pmb{r}_{ji}) = R_{nl}^{\mu_j \mu_i}(r_{ji}) Y_{lm}(\hat{\pmb{r}}_{ji}) $
 
 
* Atomic base (A-functions): $ A_{i \mu n l m} = \sum_j \delta_{\mu \mu_j} \phi_{\mu_j\mu_i nlm}(\pmb{r}_{ji}) $
 
 
* Product of atomic base: $ \pmb{A}_{i\pmb{\mu n l m}} = \prod_{t = 1}^{\nu} A_{i \mu_t n_t l_t m_t} $
 
 
* Equivariant basis (B-functions): $ {B}_{i\pmb{\mu n l L}} = \sum_{\pmb{m}} \left(
\begin{array}{c}
\pmb{l m} \\
\pmb{L M}
\end{array}
L_R
\right) \pmb{A}_{i\pmb{\mu n l m}} $ ,
 
where $ \left(\begin{array}{c} \pmb{l m} \\ \pmb{L M}\end{array} L_R\right) $ is *generalized Clebsh-Gordan coefficients*
 
 
* Atomic property (densities) $ \rho_i^{(p)} = \sum_{\pmb{\mu n l L}} {c}^{(p)}_{\mu_i\pmb{\mu n l L}} {B}_{i\pmb{\mu n l L}} $
 
 
* Atomic energy: $ E_i = F(\rho_i^{(1)}, \dots,\rho_i^{(P)} ) $, where $F$ is embedding function
 
%% Cell type:code id: tags:
 
``` python
```
 
%% Cell type:markdown id: tags:
 
radial coefficients $c_{nlk}$:
 
%% Cell type:code id: tags:
 
``` python
np.shape(Cu_block.radcoefficients)
```
 
%% Output
 
(2, 3, 7)
 
%% Cell type:code id: tags:
 
``` python
```
 
%% Cell type:markdown id: tags:
 
Visualize the radial basis functions ($g_k$) and radial functions ($R_{nl}$) and their derivatives:
 
%% Cell type:code id: tags:
 
``` python
RadialFunctionsVisualization(final_basis_set).plot()
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
Total number of basis functions
 
%% Cell type:code id: tags:
 
``` python
len(Cu_block.funcspecs)
```
 
%% Output
 
18
 
%% Cell type:markdown id: tags:
 
List of B-basis functions $ {B}_{i\pmb{\mu n l L}}$: $\pmb{\mu} = $ `elements`, $\pmb{n} = $ `ns`, $\pmb{l} = $ `ls`, $\pmb{L} = $ `LS`) and corresponding coefficients $ {c}^{(p)}_{\mu_i\pmb{\mu n l L}} =$ `coeffs` for two densities
 
%% Cell type:code id: tags:
 
``` python
Cu_block.funcspecs
```
 
%% Output
 
[BBasisFunctionSpecification(elements=[Cu,Cu], ns=[1], ls=[0], coeffs=[-0.947664,-0.20673]),
BBasisFunctionSpecification(elements=[Cu,Cu], ns=[2], ls=[0], coeffs=[0.127744,0.0378252]),
BBasisFunctionSpecification(elements=[Cu,Cu], ns=[3], ls=[0], coeffs=[0.395046,0.128133]),
BBasisFunctionSpecification(elements=[Cu,Cu], ns=[4], ls=[0], coeffs=[0.490821,0.17195]),
BBasisFunctionSpecification(elements=[Cu,Cu], ns=[5], ls=[0], coeffs=[0.192457,0.100866]),
BBasisFunctionSpecification(elements=[Cu,Cu], ns=[6], ls=[0], coeffs=[-0.381239,-0.0435031]),
BBasisFunctionSpecification(elements=[Cu,Cu], ns=[7], ls=[0], coeffs=[-0.717072,-0.124286]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[1,1], ls=[0,0], coeffs=[0.176241,0.135483]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[1,1], ls=[1,1], coeffs=[0.0335965,0.00542081]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[1,1], ls=[2,2], coeffs=[0.361527,0.101027]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[2,1], ls=[0,0], coeffs=[0.953892,0.247374]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[2,1], ls=[1,1], coeffs=[-0.000366411,-0.000581538]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[2,1], ls=[2,2], coeffs=[0.0654394,0.0146316]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[2,2], ls=[0,0], coeffs=[0.142427,0.0350483]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[2,2], ls=[1,1], coeffs=[0.00472481,6.57905e-05]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu], ns=[2,2], ls=[2,2], coeffs=[0.00853967,-0.000426002]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu,Cu], ns=[1,1,1], ls=[0,0,0], LS=[0], coeffs=[-0.0106058,-0.0227657]),
BBasisFunctionSpecification(elements=[Cu,Cu,Cu,Cu], ns=[1,1,1], ls=[1,1,0], LS=[0], coeffs=[0.309698,0.0822887])]
 
%% Cell type:markdown id: tags:
 
Compare to potential "shape" i.e.:
* "rankmax": 3
* "nradmax": [7,2,1]
* "lmax": [0,2,1]
 
%% Cell type:code id: tags:
 
``` python
print("Trainable parameters number")
print()
print("B-functions coefficients: ",Cu_block.ndensityi * len(Cu_block.funcspecs))
print("Radial functions coefficients: ",len(np.array(Cu_block.radcoefficients).flatten()))
print("-"*40)
print("Total number of trainable parameters: ",len(final_potential.get_all_coeffs()))
```
 
%% Output
 
Trainable parameters number
B-functions coefficients: 36
Radial functions coefficients: 42
----------------------------------------
Total number of trainable parameters: 78
 
%% Cell type:markdown id: tags:
 
# Test fitted potential
 
%% Cell type:code id: tags:
 
``` python
test_pr = Project("test_ace_potential")
```
 
%% Cell type:code id: tags:
 
``` python
test_pr.remove_jobs_silently()
```
 
%% Cell type:code id: tags:
 
``` python
test_pr.job_table()
```
 
%% Output
 
Empty DataFrame
Columns: []
Index: []
 
%% Cell type:code id: tags:
 
``` python
cu_ace_potential = job.get_lammps_potential()
```
 
%% Cell type:code id: tags:
 
``` python
cu_ace_potential
```
 
%% Output
 
Config \
0 [pair_style pace\n, pair_coeff * * /home/yury/PycharmProjects/pyiron-2021/pyiron_potentialfit/day_2/03-ace/pacemaker_fit/df1_cut5_pyace_hdf5/df1_cut5_pyace/df1_cut5_pyace.ace Cu\n]
Filename Model Name Species
0 ACE df1_cut5_pyace [Cu]
 
%% Cell type:markdown id: tags:
 
## Optimization
 
%% Cell type:code id: tags:
 
``` python
lammps_job = test_pr.create.job.Lammps("opt_lammps", delete_existing_job=True)
```
 
%% Cell type:code id: tags:
 
``` python
lammps_job.potential = cu_ace_potential
```
 
%% Cell type:code id: tags:
 
``` python
lammps_job.structure = test_pr.create.structure.ase_bulk("Cu","fcc",cubic=True)
```
 
%% Cell type:code id: tags:
 
``` python
lammps_job.calc_minimize(pressure=0.0)
```
 
%% Cell type:code id: tags:
 
``` python
lammps_job.run()
```
 
%% Cell type:code id: tags:
 
``` python
test_pr.job_table()
```
 
%% Cell type:markdown id: tags:
 
## Elastic matrix
 
%% Cell type:code id: tags:
 
``` python
elmat_job = test_pr.create.job.ElasticMatrixJob("elmat", delete_existing_job=True)
```
 
%% Cell type:code id: tags:
 
``` python
elmat_job.input["eps_range"] = 0.05
```
 
%% Cell type:code id: tags:
 
``` python
ref_job = test_pr.create.job.Lammps("ref_job", delete_existing_job=True)
```
 
%% Cell type:code id: tags:
 
``` python
ref_job.potential = cu_ace_potential
```
 
%% Cell type:code id: tags:
 
``` python
ref_job.structure = lammps_job.get_structure()
```
 
%% Cell type:code id: tags:
 
``` python
elmat_job.ref_job = ref_job
```
 
%% Cell type:code id: tags:
 
``` python
elmat_job.run()
```
 
%% Output
 
The job elmat was saved and received the ID: 258
The job s_e_0 was saved and received the ID: 259
The job s_01_e_m0_05000 was saved and received the ID: 260
The job s_01_e_m0_02500 was saved and received the ID: 261
The job s_01_e_0_02500 was saved and received the ID: 262
The job s_01_e_0_05000 was saved and received the ID: 263
The job s_08_e_m0_05000 was saved and received the ID: 264
The job s_08_e_m0_02500 was saved and received the ID: 265
The job s_08_e_0_02500 was saved and received the ID: 266
The job s_08_e_0_05000 was saved and received the ID: 267
The job s_23_e_m0_05000 was saved and received the ID: 268
The job s_23_e_m0_02500 was saved and received the ID: 269
The job s_23_e_0_02500 was saved and received the ID: 270
The job s_23_e_0_05000 was saved and received the ID: 271
 
%% Cell type:code id: tags:
 
``` python
elast_val=elmat_job["output/elasticmatrix"]
```
 
%% Cell type:code id: tags:
 
``` python
ses = np.array(elast_val['strain_energy'])
 
for se in ses:
plt.plot(se[:,0], se[:,1])
 
plt.xlabel("Strain")
plt.ylabel("E, eV")
```
 
%% Output
 
Text(0, 0.5, 'E, eV')
 
 
%% Cell type:code id: tags:
 
``` python
C=elast_val["C"]
```
 
%% Cell type:code id: tags:
 
``` python
print("C11 = {:.1f} GPa".format(C[0,0]))
print("C12 = {:.1f} GPa".format(C[0,1]))
print("C44 = {:.1f} GPa".format(C[3,3]))
```
 
%% Output
 
C11 = 210.4 GPa
C12 = 120.1 GPa
C44 = 83.0 GPa
 
%% Cell type:markdown id: tags:
 
## Phonons
 
%% Cell type:code id: tags:
 
``` python
phon_job = test_pr.create.job.PhonopyJob("phon_job", delete_existing_job=True)
 
ref_job = test_pr.create.job.Lammps("ref_job", delete_existing_job=True)
 
ref_job.potential = cu_ace_potential
 
ref_job.structure = lammps_job.get_structure()
 
phon_job.input['dos_mesh']=75
 
phon_job.ref_job = ref_job
 
phon_job.run()
```
 
%% Output
 
The job phon_job was saved and received the ID: 272
The job ref_job_0 was saved and received the ID: 273
 
%% Cell type:markdown id: tags:
 
# Comparison with some DFT reference data
 
%% Cell type:code id: tags:
 
``` python
from structdbrest import StructDBLightRester
```
 
%% Cell type:code id: tags:
 
``` python
rest = StructDBLightRester(token="workshop2021")
```
 
%% Cell type:code id: tags:
 
``` python
fhi_calc = rest.query_calculator_types("FHI%aims%")[0]
```
 
%% Output
 
Querying...done
Response successful, size = 7.20 kB, time = 0.27 s
1 entries received
 
%% Cell type:code id: tags:
 
``` python
dft_elast_prop = rest.query_properties(rest.PropertyTypes.ELASTIC_MATRIX, composition="Cu-%", strukturbericht="A1",
calculator_name=fhi_calc.NAME)[0]
```
 
%% Output
 
Querying...done
Response successful, size = 37.78 kB, time = 0.45 s
1 entries received
 
%% Cell type:code id: tags:
 
``` python
C_dft=dft_elast_prop.value["C"]
```
 
%% Cell type:code id: tags:
 
``` python
print("C11 = {:.1f} GPa / DFT C11={:.1f} GPa".format(C[0,0], C_dft[0][0]))
print("C12 = {:.1f} GPa / DFT C11={:.1f} GPa".format(C[0,1], C_dft[0][1]))
print("C44 = {:.1f} GPa / DFT C11={:.1f} GPa".format(C[3,3], C_dft[3][3]))
```
 
%% Output
 
C11 = 210.4 GPa / DFT C11=176.9 GPa
C12 = 120.1 GPa / DFT C11=131.7 GPa
C44 = 83.0 GPa / DFT C11=82.5 GPa
 
%% Cell type:code id: tags:
 
``` python
dft_phon_prop = rest.query_properties(rest.PropertyTypes.PHONONS, composition="Cu-%", strukturbericht="A1",
calculator_name=fhi_calc.NAME)[0]
```
 
%% Output
 
Querying...done
Response successful, size = 22.50 kB, time = 0.24 s
1 entries received
 
%% Cell type:code id: tags:
 
``` python
plt.plot(phon_job["output/dos_energies"], phon_job["output/dos_total"]/4, label="ACE")
plt.plot(dft_phon_prop.value["dos_energies"], dft_phon_prop.value["dos_total"], label="DFT")
plt.legend()
```
 
%% Output
 
<matplotlib.legend.Legend at 0x7f3664444f10>