Skip to content

Commit 51aa20c

Browse files
Add NEB tutorial (#435)
* Add NEB tutorial * Update docs for NEB tutorial * Tidy notebook output
1 parent 1f68b98 commit 51aa20c

File tree

4 files changed

+360
-0
lines changed

4 files changed

+360
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ Jupyter Notebook tutorials illustrating the use of currently available calculati
146146
- [Molecular Dynamics](docs/source/tutorials/md.ipynb) [![badge](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/md.ipynb)
147147
- [Equation of State](docs/source/tutorials/eos.ipynb) [![badge](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/eos.ipynb)
148148
- [Phonons](docs/source/tutorials/phonons.ipynb) [![badge](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/phonons.ipynb)
149+
- [Nudged Elastic Band](docs/source/tutorials/neb.ipynb) [![badge](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/neb.ipynb)
149150

150151

151152
### Calculation outputs

docs/source/tutorials/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ Tutorials
1010
md
1111
eos
1212
phonons
13+
neb

docs/source/tutorials/neb.ipynb

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {
6+
"colab_type": "text",
7+
"id": "view-in-github"
8+
},
9+
"source": [
10+
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/neb.ipynb)"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"# Nudged Elastic Band"
18+
]
19+
},
20+
{
21+
"cell_type": "markdown",
22+
"metadata": {},
23+
"source": [
24+
"In this tutorial, we will determine the activation energies of Li diffusion along the [010] and [001] directions (referred to as paths b and c respectively) in lithium iron phosphate (LiFePO_4), a cathode material for lithium ion batteries.\n",
25+
"\n",
26+
"DFT references energies are:\n",
27+
"\n",
28+
"- Barrier heights:\n",
29+
" - path b = 0.27 eV\n",
30+
" - path c = 2.5 eV\n",
31+
" \n",
32+
"(see table 1 in https://doi.org/10.1039/C5TA05062F)"
33+
]
34+
},
35+
{
36+
"cell_type": "markdown",
37+
"metadata": {},
38+
"source": [
39+
"You can toggle the following to investigate different models:"
40+
]
41+
},
42+
{
43+
"cell_type": "code",
44+
"execution_count": null,
45+
"metadata": {},
46+
"outputs": [],
47+
"source": [
48+
"model_params = {\"arch\": \"mace_mp\", \"model_path\": \"medium-0b3\"}\n",
49+
"# model_params = {\"arch\": \"mace_mp\", \"model_path\": \"medium-mpa-0\"}\n",
50+
"# model_params = {\"arch\": \"mace_mp\", \"model_path\": \"medium-omat-0\"}\n",
51+
"# model_params = {\"arch\": \"chgnet\"}\n",
52+
"# model_params = {\"arch\": \"sevennet\"}"
53+
]
54+
},
55+
{
56+
"cell_type": "markdown",
57+
"metadata": {},
58+
"source": [
59+
"## Set up environment (optional)\n",
60+
"\n",
61+
"These steps are required for Google Colab, but may work on other systems too:"
62+
]
63+
},
64+
{
65+
"cell_type": "code",
66+
"execution_count": null,
67+
"metadata": {
68+
"id": "TF-EiWxyuMc7"
69+
},
70+
"outputs": [],
71+
"source": [
72+
"# import locale\n",
73+
"# locale.getpreferredencoding = lambda: \"UTF-8\"\n",
74+
"# !python3 -m pip install janus-core[all]"
75+
]
76+
},
77+
{
78+
"cell_type": "code",
79+
"execution_count": null,
80+
"metadata": {},
81+
"outputs": [],
82+
"source": [
83+
"from ase.visualize import view\n",
84+
"from ase.io import read\n",
85+
"from data_tutorials.data import get_data\n",
86+
"\n",
87+
"from janus_core.calculations.geom_opt import GeomOpt\n",
88+
"from janus_core.calculations.neb import NEB"
89+
]
90+
},
91+
{
92+
"cell_type": "markdown",
93+
"metadata": {},
94+
"source": [
95+
"Use `data_tutorials` to get the data required for this tutorial:"
96+
]
97+
},
98+
{
99+
"cell_type": "code",
100+
"execution_count": null,
101+
"metadata": {},
102+
"outputs": [],
103+
"source": [
104+
"get_data(\n",
105+
" # url=\"https://raw.githubusercontent.com/stfc/janus-core/main/tests/data/\",\n",
106+
" url=\"https://raw.githubusercontent.com/stfc/janus-tutorials/main/neb/data/\",\n",
107+
" filename=\"LiFePO4_supercell.cif\",\n",
108+
" folder=\"data\",\n",
109+
")"
110+
]
111+
},
112+
{
113+
"cell_type": "markdown",
114+
"metadata": {
115+
"id": "857K7R9Cenca"
116+
},
117+
"source": [
118+
"## Preparing end structures"
119+
]
120+
},
121+
{
122+
"cell_type": "markdown",
123+
"metadata": {},
124+
"source": [
125+
"The initial structure can be downloaded from the Materials Project (mp-19017):"
126+
]
127+
},
128+
{
129+
"cell_type": "code",
130+
"execution_count": null,
131+
"metadata": {},
132+
"outputs": [],
133+
"source": [
134+
"LFPO = read(\"data/LiFePO4_supercell.cif\")\n",
135+
"view(LFPO,viewer=\"x3d\")"
136+
]
137+
},
138+
{
139+
"cell_type": "markdown",
140+
"metadata": {},
141+
"source": [
142+
"First, we will relax the supercell:"
143+
]
144+
},
145+
{
146+
"cell_type": "code",
147+
"execution_count": null,
148+
"metadata": {
149+
"id": "cgch8VQ--AES"
150+
},
151+
"outputs": [],
152+
"source": [
153+
"GeomOpt(struct=LFPO, **model_params).run()\n",
154+
"\n",
155+
"view(LFPO,viewer=\"x3d\")"
156+
]
157+
},
158+
{
159+
"cell_type": "markdown",
160+
"metadata": {},
161+
"source": [
162+
"Next, we will create the start and end structures:"
163+
]
164+
},
165+
{
166+
"cell_type": "code",
167+
"execution_count": null,
168+
"metadata": {},
169+
"outputs": [],
170+
"source": [
171+
"# NEB path along b and c directions have the same starting image.\n",
172+
"# For start bc remove site 5\n",
173+
"LFPO_start_bc = LFPO.copy()\n",
174+
"del LFPO_start_bc[5]\n",
175+
"\n",
176+
"# For end b remove site 11 \n",
177+
"LFPO_end_b = LFPO.copy()\n",
178+
"del LFPO_end_b[11]\n",
179+
"\n",
180+
"# For end c remove site 4\n",
181+
"LFPO_end_c = LFPO.copy()\n",
182+
"del LFPO_end_c[4]"
183+
]
184+
},
185+
{
186+
"cell_type": "markdown",
187+
"metadata": {},
188+
"source": [
189+
"## Path b"
190+
]
191+
},
192+
{
193+
"cell_type": "markdown",
194+
"metadata": {},
195+
"source": [
196+
"We can now calculate the barrier height along path b.\n",
197+
"\n",
198+
"This also includes running geometry optimization on the end points of this path."
199+
]
200+
},
201+
{
202+
"cell_type": "code",
203+
"execution_count": null,
204+
"metadata": {},
205+
"outputs": [],
206+
"source": [
207+
"n_images = 7\n",
208+
"interpolator=\"pymatgen\" # ASE interpolation performs poorly in this case\n",
209+
"\n",
210+
"neb_b = NEB(\n",
211+
" init_struct=LFPO_start_bc,\n",
212+
" final_struct=LFPO_end_b,\n",
213+
" n_images=n_images,\n",
214+
" interpolator=interpolator,\n",
215+
" minimize=True,\n",
216+
" fmax=0.1,\n",
217+
" **model_params,\n",
218+
")"
219+
]
220+
},
221+
{
222+
"cell_type": "code",
223+
"execution_count": null,
224+
"metadata": {},
225+
"outputs": [],
226+
"source": [
227+
"results = neb_b.run()"
228+
]
229+
},
230+
{
231+
"cell_type": "markdown",
232+
"metadata": {},
233+
"source": [
234+
"The results include the barrier (without any interpolation between highest images) and maximum force at the point in the simulation "
235+
]
236+
},
237+
{
238+
"cell_type": "code",
239+
"execution_count": null,
240+
"metadata": {},
241+
"outputs": [],
242+
"source": [
243+
"print(results)"
244+
]
245+
},
246+
{
247+
"cell_type": "markdown",
248+
"metadata": {},
249+
"source": [
250+
"We can also plot the band:"
251+
]
252+
},
253+
{
254+
"cell_type": "code",
255+
"execution_count": null,
256+
"metadata": {},
257+
"outputs": [],
258+
"source": [
259+
"fig = neb_b.nebtools.plot_band()"
260+
]
261+
},
262+
{
263+
"cell_type": "markdown",
264+
"metadata": {},
265+
"source": [
266+
"## Path c"
267+
]
268+
},
269+
{
270+
"cell_type": "markdown",
271+
"metadata": {},
272+
"source": [
273+
"We can calculate the barrier height along path c similarly"
274+
]
275+
},
276+
{
277+
"cell_type": "code",
278+
"execution_count": null,
279+
"metadata": {},
280+
"outputs": [],
281+
"source": [
282+
"n_images = 7\n",
283+
"interpolator=\"pymatgen\"\n",
284+
"\n",
285+
"neb_c = NEB(\n",
286+
" init_struct=LFPO_start_bc,\n",
287+
" final_struct=LFPO_end_c,\n",
288+
" n_images=n_images,\n",
289+
" interpolator=interpolator,\n",
290+
" minimize=True,\n",
291+
" fmax=0.1,\n",
292+
" **model_params,\n",
293+
")"
294+
]
295+
},
296+
{
297+
"cell_type": "code",
298+
"execution_count": null,
299+
"metadata": {},
300+
"outputs": [],
301+
"source": [
302+
"results = neb_c.run()"
303+
]
304+
},
305+
{
306+
"cell_type": "code",
307+
"execution_count": null,
308+
"metadata": {},
309+
"outputs": [],
310+
"source": [
311+
"print(results)"
312+
]
313+
},
314+
{
315+
"cell_type": "code",
316+
"execution_count": null,
317+
"metadata": {},
318+
"outputs": [],
319+
"source": [
320+
"fig = neb_c.nebtools.plot_band()"
321+
]
322+
}
323+
],
324+
"metadata": {
325+
"accelerator": "GPU",
326+
"colab": {
327+
"authorship_tag": "ABX9TyNvtIsPHVgkt0NvUv51T6ZG",
328+
"gpuType": "T4",
329+
"include_colab_link": true,
330+
"private_outputs": true,
331+
"provenance": []
332+
},
333+
"kernelspec": {
334+
"display_name": ".venv",
335+
"language": "python",
336+
"name": "python3"
337+
},
338+
"language_info": {
339+
"codemirror_mode": {
340+
"name": "ipython",
341+
"version": 3
342+
},
343+
"file_extension": ".py",
344+
"mimetype": "text/x-python",
345+
"name": "python",
346+
"nbconvert_exporter": "python",
347+
"pygments_lexer": "ipython3",
348+
"version": "3.12.8"
349+
}
350+
},
351+
"nbformat": 4,
352+
"nbformat_minor": 4
353+
}

docs/source/user_guide/python.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@ Jupyter Notebook tutorials illustrating the use of currently available calculati
2424
:target: https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/phonons.ipynb
2525
:alt: Launch phonons Colab
2626

27+
.. |neb| image:: https://colab.research.google.com/assets/colab-badge.svg
28+
:target: https://colab.research.google.com/github/stfc/janus-core/blob/main/docs/source/tutorials/neb.ipynb
29+
:alt: Launch NEB Colab
30+
2731
- :doc:`Single Point </tutorials/single_point>` |single_point|
2832
- :doc:`Geometry Optimization </tutorials/geom_opt>` |geom_opt|
2933
- :doc:`Molecular Dynamics </tutorials/md>` |md|
3034
- :doc:`Equation of State </tutorials/eos>` |eos|
3135
- :doc:`Phonons </tutorials/phonons>` |phonons|
36+
- :doc:`Nudged Elastic Band </tutorials/neb>` |neb|
3237

3338

3439
Calculation outputs

0 commit comments

Comments
 (0)