Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
pyiron
Potentials Workshop 2021
Commits
b1a4332d
Unverified
Commit
b1a4332d
authored
Mar 08, 2021
by
Jan Janssen
Committed by
GitHub
Mar 08, 2021
Browse files
Update ex_01_validation.ipynb
parent
88e23893
Changes
1
Hide whitespace changes
Inline
Side-by-side
day_3/ex_01_validation.ipynb
View file @
b1a4332d
%% Cell type:markdown id:touched-vocabulary tags:
# [**Workflows for atomistic simulations**](http://potentials.rub.de/)
%% Cell type:markdown id:conceptual-moscow tags:
## **Day 3 - Validation of various potentials**
### **Exercise 1: Validation of generated potentials using pyiron based workflows**
Before the excercise, you should:
*
Have run the notebooks from day 1 and day2
*
Be familiar with working with pyiron and the basics of potential fitting
The aim of this exercise is to make you familiar with:
*
Potential validation workflows
%% Cell type:code id:golden-folks tags:
```
python
import
numpy
as
np
%
matplotlib
inline
import
matplotlib.pylab
as
plt
import
pandas
as
pd
```
%% Cell type:code id:leading-blake tags:
```
python
from
pyiron
import
Project
```
%% Cell type:code id:decreased-latvia tags:
```
python
pr
=
Project
(
"validation"
)
pr
.
remove
(
True
)
```
%% Cell type:code id:empirical-essay tags:
```
python
# The good potentials already added to the pyiron database
potential_list
=
[
'
Cu_
Mendelev
_eam
'
,
'2004--Zhou-X-W--Cu-Ag-Au--LAMMPS--ipr2'
,
'Cu-ace'
,
'Cu-runner-df4'
]
#, 'Cu-runner-df1']
potential_list
=
[
'
2012--
Mendelev
-M-I--Cu--LAMMPS--ipr1
'
,
'2004--Zhou-X-W--Cu-Ag-Au--LAMMPS--ipr2'
,
'Cu-ace'
,
'Cu-runner-df4'
]
#, 'Cu-runner-df1']
# The potentials that were fit yesterday
```
%% Cell type:code id:checked-terminal tags:
```
python
# Do Murnaghan, ElasticMatrix job, vac formation energy, binding energy, surface energies, comparison with dataset forces, energies
```
%% Cell type:code id:residential-diving tags:
```
python
def
clean_project_name
(
name
):
return
name
.
replace
(
"-"
,
"_"
)
```
%% Cell type:code id:conditional-order tags:
```
python
for
pot
in
potential_list
:
group_name
=
clean_project_name
(
pot
)
pr_pot
=
pr
.
create_group
(
pot
)
job_ref
=
pr_pot
.
create_job
(
pr_pot
.
job_type
.
Lammps
,
"ref_job"
)
job_ref
.
structure
=
pr_pot
.
create_ase_bulk
(
"Cu"
)
job_ref
.
potential
=
pot
job_ref
.
calc_minimize
()
murn_job
=
job_ref
.
create_job
(
pr_pot
.
job_type
.
Murnaghan
,
"murn_job"
)
murn_job
.
run
()
print
(
"Potential: "
,
pot
)
murn_job
.
plot
()
```
%%%% Output: stream
The job murn_job was saved and received the ID: 4389
The job strain_0_9 was saved and received the ID: 4390
The job strain_0_92 was saved and received the ID: 4391
The job strain_0_94 was saved and received the ID: 4392
The job strain_0_96 was saved and received the ID: 4393
The job strain_0_98 was saved and received the ID: 4394
The job strain_1_0 was saved and received the ID: 4395
The job strain_1_02 was saved and received the ID: 4396
The job strain_1_04 was saved and received the ID: 4397
The job strain_1_06 was saved and received the ID: 4398
The job strain_1_08 was saved and received the ID: 4399
The job strain_1_1 was saved and received the ID: 4400
job_id: 4390 finished
job_id: 4391 finished
job_id: 4392 finished
job_id: 4393 finished
job_id: 4394 finished
job_id: 4395 finished
job_id: 4396 finished
job_id: 4397 finished
job_id: 4398 finished
job_id: 4399 finished
job_id: 4400 finished
Potential: Cu-ace
%%%% Output: display_data

%%%% Output: stream
The job murn_job was saved and received the ID: 4401
The job strain_0_9 was saved and received the ID: 4402
The job strain_0_92 was saved and received the ID: 4403
The job strain_0_94 was saved and received the ID: 4404
The job strain_0_96 was saved and received the ID: 4405
The job strain_0_98 was saved and received the ID: 4406
The job strain_1_0 was saved and received the ID: 4407
The job strain_1_02 was saved and received the ID: 4408
The job strain_1_04 was saved and received the ID: 4409
The job strain_1_06 was saved and received the ID: 4410
The job strain_1_08 was saved and received the ID: 4411
The job strain_1_1 was saved and received the ID: 4412
job_id: 4402 finished
job_id: 4403 finished
job_id: 4404 finished
job_id: 4405 finished
job_id: 4406 finished
job_id: 4407 finished
job_id: 4408 finished
job_id: 4409 finished
job_id: 4410 finished
job_id: 4411 finished
job_id: 4412 finished
Potential: Cu-runner-df4
%%%% Output: display_data

%% Cell type:code id:leading-sector tags:
```
python
murn_job
[
"output/equilibrium_energy"
]
```
%%%% Output: execute_result
-3.694888787063416
%% Cell type:code id:partial-bulgaria tags:
```
python
def
get_only_murn
(
job_table
):
return
job_table
.
hamilton
==
"Murnaghan"
def
get_eq_vol
(
job_path
):
return
job_path
[
"output/equilibrium_volume"
]
def
get_eq_lp
(
job_path
):
return
np
.
linalg
.
norm
(
job_path
[
"output/structure/cell/cell"
][
0
])
*
np
.
sqrt
(
2
)
def
get_eq_bm
(
job_path
):
return
job_path
[
"output/equilibrium_bulk_modulus"
]
def
get_potential
(
job_path
):
return
job_path
[
"ref_job/input/potential/Name"
]
def
get_eq_energy
(
job_path
):
return
job_path
[
"output/equilibrium_energy"
]
def
get_n_atoms
(
job_path
):
return
len
(
job_path
[
"output/structure/positions"
])
```
%% Cell type:code id:specified-acceptance tags:
```
python
table
=
pr
.
create_table
(
"table_murn"
,
delete_existing_job
=
True
)
table
.
db_filter_function
=
get_only_murn
table
.
add
[
"potential"
]
=
get_potential
table
.
add
[
"a"
]
=
get_eq_lp
table
.
add
[
"eq_vol"
]
=
get_eq_vol
table
.
add
[
"eq_bm"
]
=
get_eq_bm
table
.
add
[
"eq_energy"
]
=
get_eq_energy
table
.
add
[
"n_atoms"
]
=
get_n_atoms
table
.
run
()
data_murn
=
table
.
get_dataframe
()
data_murn
```
%%%% Output: stream
100%|██████████| 2/2 [00:00<00:00, 513.91it/s]
100%|██████████| 2/2 [00:00<00:00, 28.91it/s]
%%%% Output: stream
The job table_murn was saved and received the ID: 4413
CPU times: user 219 ms, sys: 62.5 ms, total: 281 ms
Wall time: 317 ms
%%%% Output: stream
%%%% Output: execute_result
job_id potential a eq_vol eq_bm eq_energy n_atoms
0 4389 Cu-ace 3.629863 11.956678 146.220099 -3.698781 1
1 4401 Cu-runner-df4 3.618770 11.847397 145.857176 -3.694889 1
%% Cell type:code id:automatic-kuwait tags:
```
python
for
pot
in
data_murn
.
potential
.
to_list
():
group_name
=
clean_project_name
(
pot
)
pr_pot
=
pr
.
create_group
(
pot
)
print
(
pot
)
job_id
=
int
(
data_murn
[
data_murn
.
potential
==
pot
].
job_id
)
job_ref
=
pr_pot
.
create_job
(
pr_pot
.
job_type
.
Lammps
,
"ref_job"
)
job_ref
.
structure
=
pr_pot
.
inspect
(
job_id
)[
"output/structure"
].
to_object
()
job_ref
.
potential
=
pot
job_ref
.
calc_minimize
()
elastic_job
=
job_ref
.
create_job
(
pr_pot
.
job_type
.
ElasticMatrixJob
,
"elastic_job"
)
elastic_job
.
input
[
"eps_range"
]
=
0.05
elastic_job
.
run
()
```
%%%% Output: stream
Cu-ace
The job elastic_job was saved and received the ID: 4414
The job s_e_0 was saved and received the ID: 4415
The job s_01_e_m0_05000 was saved and received the ID: 4416
The job s_01_e_m0_02500 was saved and received the ID: 4417
The job s_01_e_0_02500 was saved and received the ID: 4418
The job s_01_e_0_05000 was saved and received the ID: 4419
The job s_08_e_m0_05000 was saved and received the ID: 4420
The job s_08_e_m0_02500 was saved and received the ID: 4421
The job s_08_e_0_02500 was saved and received the ID: 4422
The job s_08_e_0_05000 was saved and received the ID: 4423
The job s_23_e_m0_05000 was saved and received the ID: 4424
The job s_23_e_m0_02500 was saved and received the ID: 4425
The job s_23_e_0_02500 was saved and received the ID: 4426
The job s_23_e_0_05000 was saved and received the ID: 4427
Cu-runner-df4
The job elastic_job was saved and received the ID: 4428
The job s_e_0 was saved and received the ID: 4429
The job s_01_e_m0_05000 was saved and received the ID: 4430
The job s_01_e_m0_02500 was saved and received the ID: 4431
The job s_01_e_0_02500 was saved and received the ID: 4432
The job s_01_e_0_05000 was saved and received the ID: 4433
The job s_08_e_m0_05000 was saved and received the ID: 4434
The job s_08_e_m0_02500 was saved and received the ID: 4435
The job s_08_e_0_02500 was saved and received the ID: 4436
The job s_08_e_0_05000 was saved and received the ID: 4437
The job s_23_e_m0_05000 was saved and received the ID: 4438
The job s_23_e_m0_02500 was saved and received the ID: 4439
The job s_23_e_0_02500 was saved and received the ID: 4440
The job s_23_e_0_05000 was saved and received the ID: 4441
CPU times: user 42 s, sys: 31 s, total: 1min 12s
Wall time: 58.3 s
%% Cell type:code id:dedicated-powder tags:
```
python
plt
.
matshow
(
elastic_job
[
"output/elasticmatrix"
][
"C"
]);
```
%%%% Output: display_data

%% Cell type:code id:joint-shield tags:
```
python
elastic_job
[
"output/elasticmatrix"
][
"C"
].
flatten
()
```
%%%% Output: execute_result
array([143.47389261, 170.02778376, 170.02778376, 0. ,
0. , 0. , 170.02778376, 143.47389261,
170.02778376, 0. , 0. , 0. ,
170.02778376, 170.02778376, 143.47389261, 0. ,
0. , 0. , 0. , 0. ,
0. , 100.95388854, 0. , 0. ,
0. , 0. , 0. , 0. ,
100.95388854, 0. , 0. , 0. ,
0. , 0. , 0. , 100.95388854])
%% Cell type:code id:roman-tenant tags:
```
python
def
filter_elastic
(
job_table
):
return
(
job_table
.
hamilton
==
"ElasticMatrixJob"
)
&
(
job_table
.
status
==
"finished"
)
def
get_c11
(
job_path
):
return
job_path
[
"output/elasticmatrix"
][
"C"
][
0
,
0
]
def
get_c12
(
job_path
):
return
job_path
[
"output/elasticmatrix"
][
"C"
][
0
,
1
]
def
get_c44
(
job_path
):
return
job_path
[
"output/elasticmatrix"
][
"C"
][
3
,
3
]
```
%% Cell type:code id:determined-token tags:
```
python
%%
time
table
=
pr
.
create_table
(
"table_elastic"
,
delete_existing_job
=
True
)
table
.
db_filter_function
=
filter_elastic
table
.
add
[
"potential"
]
=
get_potential
table
.
add
[
"C11"
]
=
get_c11
table
.
add
[
"C12"
]
=
get_c12
table
.
add
[
"C44"
]
=
get_c44
table
.
run
()
data_elastic
=
table
.
get_dataframe
()
data_elastic
```
%%%% Output: stream
100%|██████████| 2/2 [00:00<00:00, 547.17it/s]
0%| | 0/2 [00:00<?, ?it/s]
%%%% Output: stream
The job table_elastic was saved and received the ID: 4442
%%%% Output: stream
100%|██████████| 2/2 [00:00<00:00, 5.13it/s]
%%%% Output: stream
CPU times: user 500 ms, sys: 109 ms, total: 609 ms
Wall time: 669 ms
%%%% Output: execute_result
job_id potential C11 C12 C44
0 4414 Cu-ace 182.054447 132.575877 81.049351
1 4428 Cu-runner-df4 143.473893 170.027784 100.953889
%% Cell type:code id:cooperative-store tags:
```
python
from
structdbrest
import
StructDBLightRester
rest
=
StructDBLightRester
(
token
=
"workshop2021"
)
fhi_calc
=
rest
.
query_calculator_types
(
"FHI%aims%"
)[
0
]
dft_elast_prop
=
rest
.
query_properties
(
rest
.
PropertyTypes
.
ELASTIC_MATRIX
,
composition
=
"Cu-%"
,
strukturbericht
=
"A1"
,
calculator_name
=
fhi_calc
.
NAME
)[
0
]
dft_phon_prop
=
rest
.
query_properties
(
rest
.
PropertyTypes
.
PHONONS
,
composition
=
"Cu-%"
,
strukturbericht
=
"A1"
,
calculator_name
=
fhi_calc
.
NAME
)[
0
]
```
%%%% Output: stream
Querying...done
Response successful, size = 7.20 kB, time = 0.13 s
1 entries received
Querying...done
Response successful, size = 37.78 kB, time = 0.38 s
1 entries received
Querying...done
Response successful, size = 22.50 kB, time = 0.20 s
1 entries received
%% Cell type:code id:planned-cargo tags:
```
python
C_dft
=
dft_elast_prop
.
value
[
"C"
]
print
(
"DFT C11={:.1f} GPa"
.
format
(
C_dft
[
0
][
0
]))
print
(
"DFT C12={:.1f} GPa"
.
format
(
C_dft
[
0
][
1
]))
print
(
"DFT C44={:.1f} GPa"
.
format
(
C_dft
[
3
][
3
]))
```
%%%% Output: stream
DFT C11=176.9 GPa
DFT C12=131.7 GPa
DFT C44=82.5 GPa
%% Cell type:code id:beginning-cheese tags:
```
python
%%
time
surface_type_list
=
[
"fcc111"
,
"fcc110"
,
"fcc100"
]
for
i
,
pot
in
enumerate
(
data_murn
.
potential
.
to_list
()):
group_name
=
clean_project_name
(
pot
)
pr_pot
=
pr
.
create_group
(
group_name
)
a
=
data_murn
.
a
.
to_list
()[
i
]
for
surface_type
in
surface_type_list
:
surface
=
pr
.
create_surface
(
"Cu"
,
surface_type
=
surface_type
,
size
=
(
8
,
8
,
8
),
a
=
a
,
orthogonal
=
True
,
vacuum
=
12
)
job_lammps
=
pr_pot
.
create_job
(
pr_pot
.
job_type
.
Lammps
,
"surf_{}"
.
format
(
surface_type
))
job_lammps
.
structure
=
surface
job_lammps
.
potential
=
pot
job_lammps
.
calc_minimize
()
job_lammps
.
run
()
```
%%%% Output: stream
The job surf_fcc111 was saved and received the ID: 4443
The job surf_fcc110 was saved and received the ID: 4444
The job surf_fcc100 was saved and received the ID: 4445
The job surf_fcc111 was saved and received the ID: 4446
The job surf_fcc110 was saved and received the ID: 4447
The job surf_fcc100 was saved and received the ID: 4448
CPU times: user 7.88 s, sys: 7.86 s, total: 15.7 s
Wall time: 48.4 s
%% Cell type:code id:preceding-fireplace tags:
```
python
``
`
%%
Cell
type
:
code
id
:
interracial
-
lunch
tags
:
```
python
def is_a_surface(job_table):
return (job_table.hamilton == "Lammps") & (job_table.job.str.contains("fcc")) & (job_table.status == "finished")
def get_potential_lammps_job(job_path):
return job_path["input/potential/Name"]
def get_surface_type(job_path):
surf_list = ["fcc111", "fcc110", "fcc100"]
conditions = [val in job_path.job_name for val in surf_list]
return surf_list[np.where(conditions)[0].tolist()[0]]
def get_area(job_path):
cell = job_path["output/structure/cell/cell"]
return np.linalg.norm(np.cross(cell[0], cell[1]))
```
%% Cell type:code id:palestinian-allen tags:
```
python
```
%% Cell type:code id:black-chance tags:
```
python
%%time
table = pr.create_table("table_surface", delete_existing_job=True)
table.db_filter_function = is_a_surface
table.add["potential"] = get_potential_lammps_job
table.add["surface_type"] = get_surface_type
table.add["surface_area"] = get_area
table.add.get_total_number_of_atoms
table.add.get_energy_tot
table.run()
data_surf = table.get_dataframe()
data_surf
```
%%%% Output: stream
100%|██████████| 6/6 [00:00<00:00, 430.05it/s]
0%| | 0/6 [00:00<?, ?it/s]
%%%% Output: stream
The job table_surface was saved and received the ID: 4449
%%%% Output: stream
100%|██████████| 6/6 [00:00<00:00, 13.52it/s]
%%%% Output: stream
CPU times: user 438 ms, sys: 219 ms, total: 656 ms
Wall time: 876 ms
%%%% Output: execute_result
Number_of_atoms job_id energy_tot potential surface_type \
0 512 4443 -1834.286336 Cu-ace fcc111
1 512 4444 -1775.620101 Cu-ace fcc110
2 512 4445 -1814.469585 Cu-ace fcc100
3 512 4446 -1835.853699 Cu-runner-df4 fcc111
4 512 4447 -1786.742960 Cu-runner-df4 fcc110
5 512 4448 -1816.715931 Cu-runner-df4 fcc100
surface_area
0 365.141308
1 596.273259
2 421.628865
3 362.913030
4 592.634496
5 419.055871
%% Cell type:code id:robust-unknown tags:
```
python
```
%% Cell type:code id:painted-taiwan tags:
```
python
data_merged = pd.merge(data_surf, data_murn, on="potential")
data_merged["surface_energy"] = data_merged.energy_tot - (data_merged.eq_energy
*
data_merged.Number_of_atoms)
data_merged["surface_energy_in_mJ_per_sq_m"] = data_merged.surface_energy / data_merged.surface_area / 2
* 16.0219 *
1e3
data_merged[["potential", "surface_type", "surface_energy_in_mJ_per_sq_m"]]
```
%%%% Output: execute_result
potential surface_type surface_energy_in_mJ_per_sq_m
0 Cu-ace fcc111 1305.155196
1 Cu-ace fcc110 1587.423774
2 Cu-ace fcc100 1506.815901
3 Cu-runner-df4 fcc111 1234.585883
4 Cu-runner-df4 fcc110 1419.881876
5 Cu-runner-df4 fcc100 1435.033014
%% Cell type:markdown id:hungarian-benefit tags:
## Finite temperature thermodynamics (Harmonic approximation)
%% Cell type:code id:recovered-warren tags:
```
python
# phonon DOS more analysis (comparison with some datasets)
```
%% Cell type:code id:fiscal-convergence tags:
```
python
%%time
for pot in data_murn.potential.to_list():
group_name = clean_project_name(pot)
pr_pot = pr.create_group(group_name)
job_id = int(data_murn[data_murn.potential==pot].job_id)
job_ref = pr_pot.create_job(pr_pot.job_type.Lammps, "ref_job")
job_ref.structure = pr_pot.inspect(job_id)["output/structure"].to_object()
job_ref.potential = pot
job_ref.calc_static()
phonopy_job = job_ref.create_job(pr_pot.job_type.PhonopyJob, "phonopy_job")
phonopy_job.run()
```
%%%% Output: stream
The job phonopy_job was saved and received the ID: 4450
The job ref_job_0 was saved and received the ID: 4451
The job phonopy_job was saved and received the ID: 4452
The job ref_job_0 was saved and received the ID: 4453
CPU times: user 10.1 s, sys: 6.06 s, total: 16.2 s
Wall time: 13.5 s
%% Cell type:code id:elegant-flashing tags:
```
python
pr
```
%%%% Output: execute_result
{'groups': ['Cu-ace', 'Cu-runner-df4', 'Cu_ace', 'Cu_runner_df4'], 'nodes': ['table_murn', 'table_elastic', 'table_surface']}
%% Cell type:code id:necessary-thomson tags:
```
python
fig, ax_list = plt.subplots(ncols=1, nrows=3, sharex="row")
#fig.set_figwidth(20)
fig.set_figheight(20)
for i, pot in enumerate(potential_list):
group_name = clean_project_name(pot)
phonopy_job = pr[group_name+"/phonopy_job"]
thermo = phonopy_job.get_thermal_properties(t_min=0, t_max=800)
ax = ax_list[0]
ax.plot(thermo.temperatures, thermo.free_energies, label=pot)
ax.set_xlabel("Temperatures [K]")
ax.set_ylabel("Free energies [eV]")
ax = ax_list[1]
ax.plot(thermo.temperatures, thermo.entropy, label=pot)
ax.set_xlabel("Temperatures [K]")
ax.set_ylabel("Entropy [eV/K]")
ax = ax_list[2]
ax.plot(thermo.temperatures, thermo.cv, label=pot)
ax.set_xlabel("Temperatures [K]")
ax.set_ylabel("Heat capacity (C$_\mathrm{V}$) [eV/K]")
ax_list[0].legend()
ax_list[1].legend()
ax_list[2].legend()
fig.subplots_adjust(hspace=0.1);
```
%%%% Output: display_data
![](data:image/png;base64,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