# Exploring Materials Synthesis with MP Data and Reaction Networks¶

Author: Matthew McDermott
Last updated: 08/05/21

### Goal¶

Learn how to build & interpret phase diagrams using MP data and apply these to predict reaction pathways in inorganic materials synthesis.

### Outline¶

1. Identifying a target system
2. Building phase diagrams
3. Predicting interface reactions between solids
4. Enumerating all possible reactions to a specific target phase
5. Constructing a reaction network from enumerated reactions
6. Finding and balancing reaction pathways

## 1. Identifying a target system¶

Scenario:

While researching ferroelectric materials, you stumble upon a compound that has shown much promise as a multiferroic material: yttrium manganese oxide, YMnO$$_3$$. When you consult the literature, it looks like there are many different approaches for making this material: solid-state synthesis, chimie douce methods, microwave-assisted synthesis, pulsed laser deposition, hydrothermal synthesis, etc.

In almost all of the papers you find, however, the authors describe significant difficulty in synthesizing phase-pure YMnO$$_3$$. For example: - "... observation that crystallization at low temperature or high oxygen partial pressures gives a mixture of Y2Mn2O7 together with YMnO3" Brinks et al., Journal of Solid State Chemistry 129, 334-340 (1997). - "The solid state synthesis of YMnO3 requires very long procedure with repeated heating and grinding" Z. Brankovic et al. Ceramics International 41 (2015) - "There are still challenges to be addressed with respect to hydrothermal synthesis of h-YMnO3, most notably the difficulty in synthesising phase pure h-YMnO3. This is a result of the complexity of the system, with a total of eight crystalline phases having been detected throughout the course of the reaction." Marshall et al., Chem Eur. J 2020, 26, 9330-9337 (2020).

Being familiar with the Materials Project database and pymatgen, you decide to check the database to see if it can help answer the question: why is phase-pure YMnO$$_3$$ so difficult to synthesize?

We previously learned how to use the MPRester to access computed data on the Materials Project. Let's start by importing MPRester:

from mp_api.matproj import MPRester


### 1.1 EXERCISE: Acquiring entries from MP¶

Using the MPRester, acquire all entries from the Materials Project with the composition YMnO$$_3$$ in the cell below:

with MPRester() as mpr:
entries = mpr.get_entries(chemsys_formula="YMnO3")

/usr/share/miniconda/envs/workshop/lib/python3.9/site-packages/maggma/api/utils.py:104: RuntimeWarning: fields may not start with an underscore, ignoring "_framework_formula"
for model in get_flat_models_from_model(pydantic_model)
for model in get_flat_models_from_model(pydantic_model)
for model in get_flat_models_from_model(pydantic_model)



Now let's take a look at one of the downloaded entry objects.

In the ComputedStructureEntry printout, we can see the uncorrected energy, correction, final energy, and the various parameters/data associated with the calculation.

Since this is hard to interpret, it will be easier for us to reformat the entries into a pandas DataFrame with the relevant information. First we import pandas:

import pandas


And then we create a function to help us wrangle the entries into the DataFrame format:

def get_df_from_entries(entries):
formulas = [e.composition.reduced_formula for e in entries]
energies = [e.energy_per_atom for e in entries]
spacegroups = [e.structure.get_space_group_info()[0] for e in entries]
structures = [e.structure for e in entries]

data = {"formula": formulas, "energy": energies, "spacegroup": spacegroups, "entry":entries}

df = pandas.DataFrame(data).sort_values("energy")

return df


The dataframe can now be easily created by calling this function:

df = get_df_from_entries(entries)
df

formula energy spacegroup entry
4 YMnO3 -9.130481 P6_3cm mp-19385 ComputedStructureEntry - Y6 Mn6 O18 ...
0 YMnO3 -9.109891 P6_3/mmc mp-19227 ComputedStructureEntry - Y2 Mn2 O6 ...
3 YMnO3 -9.107394 Pnma mp-20699 ComputedStructureEntry - Y4 Mn4 O12 ...
1 YMnO3 -8.805429 Pm-3m mp-1434307 ComputedStructureEntry - Y1 Mn1 O3 ...
2 YMnO3 -8.731478 Pnma mp-20699 ComputedStructureEntry - Y4 Mn4 O12 ...

We see that there are several polymorphs of similar energy. The lowest energy polymorph is the hexagonal YMnO$$_3$$ phase which is well known as the thermodynamically stable phase in the literature:

structure = df.iloc[0]["entry"].structure
print(structure)

Full Formula (Y6 Mn6 O18)
Reduced Formula: YMnO3
abc   :   6.233022   6.233022  11.589090
angles:  90.000000  90.000000 119.999996
Sites (30)
#  SP           a         b         c    magmom
---  ----  --------  --------  --------  --------
0  Y     0.666667  0.333333  0.233045     0.019
1  Y     0.333333  0.666667  0.733045     0.019
2  Y     0.666667  0.333333  0.733045     0.019
3  Y     0.333333  0.666667  0.233045     0.019
4  Y     0         0         0.775978     0.016
5  Y     0         0         0.275978     0.016
6  Mn    0.666399  0         0.501375     3.939
7  Mn    0.666399  0.666399  0.001375     3.931
8  Mn    0         0.333601  0.001375     3.931
9  Mn    0         0.666399  0.501375     3.939
10  Mn    0.333601  0.333601  0.501375     3.939
11  Mn    0.333601  0         0.001375     3.931
12  O     0.666667  0.333333  0.021222    -0.035
13  O     0.333333  0.666667  0.521222    -0.026
14  O     0.666667  0.333333  0.521222    -0.026
15  O     0.333333  0.666667  0.021222    -0.035
16  O     0         0         0.97754     -0.03
17  O     0         0         0.47754     -0.022
18  O     0.358595  0         0.837277    -0.026
19  O     0.358595  0.358595  0.337277    -0.026
20  O     0         0.641405  0.337277    -0.026
21  O     0         0.358595  0.837277    -0.026
22  O     0.641405  0.641405  0.837277    -0.026
23  O     0.641405  0         0.337277    -0.026
24  O     0.307715  0         0.165664    -0.03
25  O     0.307715  0.307715  0.665664    -0.03
26  O     0         0.692285  0.665664    -0.03
27  O     0         0.307715  0.165664    -0.03
28  O     0.692285  0.692285  0.165664    -0.03
29  O     0.692285  0         0.665664    -0.03



If we want to interactively view this structure in JupyterLab, we can also import crystal_toolkit to view it:

import crystal_toolkit
structure

If you see this text, the Crystal Toolkit Jupyter Lab

extension is not installed. You can install it by running

"pip install crystaltoolkit-extension"

from the same environment you run "jupyter lab".

This only works in Jupyter Lab 3.x or above.

Structure Summary
Lattice
abc : 6.2330216584852325 6.2330216584852325 11.58909
angles : 90.0 90.0 119.99999637504301
volume : 389.9215651386502
A : 3.116511 -5.397955 0.0
B : 3.116511 5.397955 0.0
C : 0.0 0.0 11.58909
PeriodicSite: Y (3.1165, -1.7993, 2.7008) [0.6667, 0.3333, 0.2330]
PeriodicSite: Y (3.1165, 1.7993, 8.4953) [0.3333, 0.6667, 0.7330]
PeriodicSite: Y (3.1165, -1.7993, 8.4953) [0.6667, 0.3333, 0.7330]
PeriodicSite: Y (3.1165, 1.7993, 2.7008) [0.3333, 0.6667, 0.2330]
PeriodicSite: Y (0.0000, 0.0000, 8.9929) [0.0000, 0.0000, 0.7760]
PeriodicSite: Y (0.0000, 0.0000, 3.1983) [0.0000, 0.0000, 0.2760]
PeriodicSite: Mn (2.0768, -3.5972, 5.8105) [0.6664, 0.0000, 0.5014]
PeriodicSite: Mn (4.1537, 0.0000, 0.0159) [0.6664, 0.6664, 0.0014]
PeriodicSite: Mn (1.0397, 1.8008, 0.0159) [0.0000, 0.3336, 0.0014]
PeriodicSite: Mn (2.0768, 3.5972, 5.8105) [0.0000, 0.6664, 0.5014]
PeriodicSite: Mn (2.0793, 0.0000, 5.8105) [0.3336, 0.3336, 0.5014]
PeriodicSite: Mn (1.0397, -1.8008, 0.0159) [0.3336, 0.0000, 0.0014]
PeriodicSite: O (3.1165, -1.7993, 0.2459) [0.6667, 0.3333, 0.0212]
PeriodicSite: O (3.1165, 1.7993, 6.0405) [0.3333, 0.6667, 0.5212]
PeriodicSite: O (3.1165, -1.7993, 6.0405) [0.6667, 0.3333, 0.5212]
PeriodicSite: O (3.1165, 1.7993, 0.2459) [0.3333, 0.6667, 0.0212]
PeriodicSite: O (0.0000, 0.0000, 11.3288) [0.0000, 0.0000, 0.9775]
PeriodicSite: O (0.0000, 0.0000, 5.5343) [0.0000, 0.0000, 0.4775]
PeriodicSite: O (1.1176, -1.9357, 9.7033) [0.3586, 0.0000, 0.8373]
PeriodicSite: O (2.2351, -0.0000, 3.9087) [0.3586, 0.3586, 0.3373]
PeriodicSite: O (1.9989, 3.4623, 3.9087) [0.0000, 0.6414, 0.3373]
PeriodicSite: O (1.1176, 1.9357, 9.7033) [0.0000, 0.3586, 0.8373]
PeriodicSite: O (3.9979, -0.0000, 9.7033) [0.6414, 0.6414, 0.8373]
PeriodicSite: O (1.9989, -3.4623, 3.9087) [0.6414, 0.0000, 0.3373]
PeriodicSite: O (0.9590, -1.6610, 1.9199) [0.3077, 0.0000, 0.1657]
PeriodicSite: O (1.9180, -0.0000, 7.7144) [0.3077, 0.3077, 0.6657]
PeriodicSite: O (2.1575, 3.7369, 7.7144) [0.0000, 0.6923, 0.6657]
PeriodicSite: O (0.9590, 1.6610, 1.9199) [0.0000, 0.3077, 0.1657]
PeriodicSite: O (4.3150, 0.0000, 1.9199) [0.6923, 0.6923, 0.1657]
PeriodicSite: O (2.1575, -3.7369, 7.7144) [0.6923, 0.0000, 0.6657]


## 2. Building phase diagrams¶

Now that we've confirmed the existence of the target phase within the MP database, we'd like to better understand phase competition within the Y-Mn-O system. This means answering questions suchs as:

1. Just how stable is YMnO$$_3$$?
2. How much energy is released upon formation of YMnO$$_3$$ from the corresponding binary oxides?
3. What other phases might compete against the formation of YMnO$$_3$$?
4. What kinds of oxygen chemical potentials stabilize YMnO$$_3$$?

These are all questions that can be answered by constructing phase diagrams within pymatgen.

### 2.1 EXERCISE: Acquiring all entries within the chemical system¶

Let's start by downloading entries for the full Y-Mn-O system using MPRester. How many entries exist within the full Y-Mn-O system?

with MPRester() as mpr:
entries = mpr.get_entries_in_chemsys("Y-Mn-O")

print(len(entries))

160



### 2.2 Compositional phase diagrams¶

Now that we have all the entries within the Y-Mn-O system, we can create a ternary compositional phase diagram by simply passing the list of entries to create a PhaseDiagram object. Let's first import this class from the phase_diagram module:

from pymatgen.analysis.phase_diagram import PhaseDiagram


And we can create the phase diagram:

pd = PhaseDiagram(entries)


To plot the phase diagram, we can either: 1. Create a PDPlotter object and call get_plot() with custom arguments 2. Create a PDPlotter object and call show() 3. In JupyterLab, just type the name of the phase diagram object in a cell and click "enter"!

Let's do option 1 so that we can see the possible arguments of the plotting function. First we import PDPlotter:

from pymatgen.analysis.phase_diagram import PDPlotter


And then we create the plotting object and call the get_plot() function:

plotter = PDPlotter(pd)

plotter.get_plot()