Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple adsorbate placement #39

Draft
wants to merge 29 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
556055b
add fn to conv ads sites to possible ads site list
lancekavalsky Sep 20, 2022
5858465
add test for gen possible ads site list
lancekavalsky Sep 20, 2022
1cf259a
adds fn for ads site list enum given cov
lancekavalsky Sep 21, 2022
ec88dcd
test for ads site list enum
lancekavalsky Sep 21, 2022
347ae55
add place multi ads fn and prune same sites
lancekavalsky Sep 22, 2022
9c1936a
tests for placing multi ads
lancekavalsky Sep 22, 2022
47a8875
rm unused import
lancekavalsky Sep 22, 2022
a6dc581
allow for inf coverages for var num of ads
lancekavalsky Sep 26, 2022
deea825
fix docstring typos
lancekavalsky Sep 26, 2022
1c1b091
add gen fn for high coverage adsorption
lancekavalsky Sep 26, 2022
332da0c
start adding tests for high cov gen fn
lancekavalsky Sep 26, 2022
b62f4ec
uniformize pytest imports
lancekavalsky Sep 27, 2022
cc89969
rm invalid check for gen high cov sites
lancekavalsky Oct 2, 2022
911fe7d
more gen high cov tests
lancekavalsky Oct 2, 2022
ccadee2
anchor atom idx must be int not float
lancekavalsky Oct 2, 2022
a05ba06
more place multi ads tests
lancekavalsky Oct 2, 2022
1b98245
fix place multi ads fmt test
lancekavalsky Oct 2, 2022
3869794
fix typos in place multi ads docstring
lancekavalsky Oct 3, 2022
e6a17ef
fix type hints of new functions
lancekavalsky Oct 3, 2022
c1e6c1c
fix docstrings
lancekavalsky Oct 3, 2022
c9875e2
start writing multi ads docs
lancekavalsky Oct 5, 2022
f48341e
fix example typo
lancekavalsky Oct 31, 2022
9b60ebe
bugfix: allow ads sites as list for gen high cov
lancekavalsky Oct 31, 2022
1c64776
add test for ads sites as list gen high cov
lancekavalsky Oct 31, 2022
40779ed
add check for matching ads cov and ads
lancekavalsky Oct 31, 2022
3823fe7
add test for checking ads cov and ads match
lancekavalsky Oct 31, 2022
d13235e
fix another example typo
lancekavalsky Oct 31, 2022
d9dddd4
add desc for specifying ads sites in gen high cov
lancekavalsky Oct 31, 2022
d15bc1c
fix: writing gen high cov structs to disk
lancekavalsky Nov 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 138 additions & 2 deletions docs/User_Guide/Structure_Generation/adsorption.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ Tools within
are geared towards generating structures with adsorbates placed on
a candidate catalyst surface.

## Placing a single adsorbate

The core function of this module is
[`generate_adsorbed_structures`](../../API/Structure_Generation/adsorption.md#autocat.adsorption.generate_adsorbed_structures)
for generating multiple adsorbed structures with a single function call.
for generating multiple structures with one adsorbate placed via a single function call.

For the oxygen reduction (ORR) and nitrogen reduction (NRR) reactions,
AutoCat has default starting geometries for all of these intermediates
Expand Down Expand Up @@ -177,4 +179,138 @@ inputs. The example below illustrates this capability, where can be used to spec
... adsorption_sites=sites,
... write_to_disk=True,
... )
```
```

## Placing multiple adsorbates

If we want to place multiple adsorbates (e.g. to explicitly model
high adsorbate coverage on a surface), the core function is
[`generate_high_coverage_adsorbed_structures`](../../API/Structure_Generation/adsorption.md#autocat.adsorption.generate_high_coverage_adsorbed_structures)

This function behaves similarly as in the single adsorbate case, but with the
key difference that adsorbate coverage must now also be specified. This can
be given as either an integer maximum number of the adsorbate type to be placed,
or as a fraction of all sites to be considered. If there should not be a
limit on the number of adsorbates to be placed, use `np.inf`.


In the below example, hydrogens are placed at all identified hollow sites.

```py
>>> import numpy as np
>>> from autocat.surface import generate_surface_structures
>>> from autocat.adsorption import generate_high_coverage_adsorbed_structures
>>> surface_dict = generate_surface_structures(
... species_list=["Pt"],
... facets={"Pt": ["111"]},
... n_fixed_layers=2,
... supercell_dim=(2,2,3)
... )
>>> surface = surface_dict["Pt"]["fcc111"]["structure"]
>>> multi_ads_dict = generate_high_coverage_adsorbed_structures(
... surface=surface,
... adsorbates=["H"],
... adsorbate_coverage={"H": np.inf},
... use_all_sites=True,
... site_types="hollow"
... )
```

In the case where you don't want all of the sites covered, you can use
"X" as a dummy species for adsorbate site vacancies. In the below example
it will cover **up to** half of the top sites with `H`.

```py
>>> import numpy as np
>>> from autocat.surface import generate_surface_structures
>>> from autocat.adsorption import generate_high_coverage_adsorbed_structures
>>> surface_dict = generate_surface_structures(
... species_list=["Pt"],
... facets={"Pt": ["111"]},
... n_fixed_layers=2,
... supercell_dim=(2,2,3)
... )
>>> surface = surface_dict["Pt"]["fcc111"]["structure"]
>>> multi_ads_dict = generate_high_coverage_adsorbed_structures(
... surface=surface,
... adsorbates=["H", "X"],
... adsorbate_coverage={"H": 0.5, "X": np.inf},
... use_all_sites=True,
... site_types="ontop"
... )
```

To cover **exactly** half of the sites, instead we can set
`adsorbate_coverate={"H": 0.5, "X": 0.5}` for example.

If we want to specify the allowed sites for all adsorbates, manually,
we can supply `adsorption_sites` as a `list` of these sites. For example:

```py
>>> import numpy as np
>>> from autocat.surface import generate_surface_structures
>>> from autocat.adsorption import generate_high_coverage_adsorbed_structures
>>> surface_dict = generate_surface_structures(
... species_list=["Pt"],
... facets={"Pt": ["111"]},
... n_fixed_layers=2,
... supercell_dim=(2,2,3)
... )
>>> surface = surface_dict["Pt"]["fcc111"]["structure"]
>>> multi_ads_dict = generate_high_coverage_adsorbed_structures(
... surface=surface,
... adsorbates=["H", "X"],
... adsorbate_coverage={"H": 3, "X": np.inf},
... use_all_sites=False,
... adsorption_sites=[(0.0, 0.0), (2.77, 0.0), (1.39, 2.4)]
... )
```

We can also specify exactly which sites each adsorbate is allowed to
occupy by giving `adsorption_sites` as a `dict`. For example, if we wanted
to restrict `H` to only be able to occupy `(0.0, 0.0)`, but allow
`OH` to occupy either `(0.0, 0.0)` or `(2.77, 0.0)`, we can do as follows:

```py
>>> import numpy as np
>>> from autocat.surface import generate_surface_structures
>>> from autocat.adsorption import generate_high_coverage_adsorbed_structures
>>> surface_dict = generate_surface_structures(
... species_list=["Pt"],
... facets={"Pt": ["111"]},
... n_fixed_layers=2,
... supercell_dim=(2,2,3)
... )
>>> surface = surface_dict["Pt"]["fcc111"]["structure"]
>>> multi_ads_dict = generate_high_coverage_adsorbed_structures(
... surface=surface,
... adsorbates=["H", "OH"],
... adsorbate_coverage={"H": 1, "OH": 2},
... use_all_sites=False,
... adsorption_sites={"H": [(0.0, 0.0)], "OH":[(0.0, 0.0), (2.77, 0.0)]}
... )
```

This function enumerates all unique structures given the coverage and site
occupation constraints. A dictionary is returned keyed by `int`s for each
resulting structure.

When writing to disk, this same format is maintained with each combination
subdirectory assigned an arbitrary `int`.

```
.
├── multiple_adsorbates
│ │   
│   ├── 0
│   │   └── input.traj
│ │   
│   └── 1
│   │   └── input.traj
│ │   
│   └── 2
│      └── input.traj
```

**N.B.**: Depending on your surface and coverage constraints, the number
of unique combinations can explode to a very large number of systems!
Loading