Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion catkit/gen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# (see accompanying license files for details).
"""Catalysis Generator."""

from collections import MutableMapping
from collections.abc import MutableMapping
import numpy as np
import ase

Expand Down
9 changes: 5 additions & 4 deletions catkit/gen/adsorption.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ def __init__(self, slab, surface_atoms=None, tol=1e-5):
self.r1_topology += r1top
self.r2_topology += r2top

#self.coordinates = np.array(self.coordinates)
self.coordinates = np.array(self.coordinates)
self.connectivity = np.array(self.connectivity, dtype=int)
self.r1_topology = np.array(self.r1_topology)
self.r2_topology = np.array(self.r2_topology)
self.r1_topology = np.array(self.r1_topology, dtype=object)
self.r2_topology = np.array(self.r2_topology, dtype=object)
self.frac_coords = np.dot(self.coordinates, np.linalg.pinv(slab.cell))
self.slab = slab

Expand Down Expand Up @@ -91,7 +92,7 @@ def get_coordinates(self, unique=True):
def get_topology(self, unique=True):
"""Return the indices of adjacent surface atoms."""
topology = [self.index[top] for top in self.r1_topology]
topology = np.array(topology)
topology = np.array(topology, dtype=object)
if unique:
sel = self.get_symmetric_sites()
else:
Expand Down Expand Up @@ -514,7 +515,7 @@ def add_adsorbate(
raise ValueError('Specify the index of atom to bond.')

elif len(bonds) == 1:
if index is -1:
if index == -1:
slab = []
for i, _ in enumerate(self.get_symmetric_sites()):
slab += [self._single_adsorption(
Expand Down
12 changes: 8 additions & 4 deletions catkit/gen/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,14 @@ def get_response_reactions(epsilon, selection=None, species=False):
possible_routes = itertools.combinations(selection, r=s + 1)
for sel in possible_routes:
values = np.zeros(epsilon.shape[0], dtype=int)

sigma = np.repeat(epsilon[[sel]][None], s + 1, axis=0)
eye = np.eye(s + 1)[:, :, None]
R = np.concatenate([sigma, eye], axis=2)
#sigma = np.repeat(epsilon[[sel]],axis=0)
sigma = epsilon[list(sel)] # This is a 2D array
# # Add axis 0 and repeat
sigma_expanded = np.repeat(sigma[None, :, :], s + 1, axis=0) # Now a 3D array with shape (s+1, len(sel), epsilon.shape[1])
# Create the identity part
eye = np.eye(s + 1)[:, :, None] # 3D array with shape (s+1, s+1, 1)
# Now both arrays are 3D and can be concatenated along axis 2
R = np.concatenate([sigma_expanded, eye], axis=2)

# Does not convert to correct integers without round
values[[sel]] = np.round(np.linalg.det(R))
Expand Down
2 changes: 1 addition & 1 deletion catkit/gen/surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ def transform_ab(slab, matrix, tol=1e-5):

corners = np.dot(scorners_newcell, newcell[:2, :2])
scorners = np.linalg.solve(slab.cell[:2, :2].T, corners.T).T
rep = np.ceil(scorners.ptp(axis=0)).astype(int)
rep = np.ceil(np.ptp(scorners,axis=0)).astype(int)

slab *= (rep[0], rep[1], 1)
slab.set_cell(newcell)
Expand Down
2 changes: 1 addition & 1 deletion catkit/gratoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def __imul__(self, m):
raise ValueError(
'Cannot repeat along undefined lattice vector')

M = np.product(m)
M = np.prod(m)
n = len(self)

for name, a in self.arrays.items():
Expand Down
1 change: 1 addition & 0 deletions catkit/tests/gen/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
These tests are adopted from "https://catkit-jboes.readthedocs.io/en/latest/_static/frontmatter/catgen.html#org0e3e58d"
12 changes: 12 additions & 0 deletions catkit/tests/gen/test1.1.2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from catkit.build import surface
from ase.io import write

# Size is 3 layers and 3 times the unit area of the primitve cell
atoms = surface('Pd', size=(3, 3), miller=(1, 1, 1), vacuum=4)

print(atoms.connectivity)

for i in atoms.get_surface_atoms():
atoms[i].symbol = 'Au'

atoms.edit()
22 changes: 22 additions & 0 deletions catkit/tests/gen/test1.1.3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from catkit.gen.surface import SlabGenerator
from ase.build import bulk
from ase import Atom

bulk = bulk('Pd', 'fcc', a=5, cubic=True)
bulk[3].symbol = 'Cu'

gen = SlabGenerator(
bulk,
miller_index=(1, 1, 1),
layers=6,
vacuum=10)

atoms = gen.get_slab()
coordinates, connectivity = gen.adsorption_sites(atoms)

atm = {1: 'X', 2: 'He', 3: 'F'}
for i, c in enumerate(coordinates):
typ = connectivity[i]
atoms += Atom(atm[typ], c + [0, 0, 2])

atoms.edit()
22 changes: 22 additions & 0 deletions catkit/tests/gen/test1.1_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from catkit.gen.surface import SlabGenerator
from ase.build import bulk
from ase.visualize import view

# Make a test slab
atoms = bulk('Pd', 'fcc', cubic=True)
atoms[3].symbol = 'Cu'

gen = SlabGenerator(
atoms,
miller_index=(2, 1, 1),
layers=9,
fixed=5,
vacuum=4)

terminations = gen.get_unique_terminations()

images = []
for i, t in enumerate(terminations):
images += [gen.get_slab(iterm=i)]

view(images)
12 changes: 12 additions & 0 deletions catkit/tests/gen/test1.1_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from catkit.build import surface
from ase.build import bulk

# Make a test slab
atoms = bulk('Pd', 'fcc', cubic=True)
atoms[3].symbol = 'Cu'

slab = surface(atoms,
size=(1, 1, 9), miller=(2, 1, 1),
vacuum=9, fixed=5)

slab.edit()
18 changes: 18 additions & 0 deletions catkit/tests/gen/test1.2.1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from catkit.gen.adsorption import AdsorptionSites
from catkit.gen.surface import SlabGenerator
from ase.build import bulk

bulk = bulk('Pd', 'fcc', a=5, cubic=True)
bulk[3].symbol = 'Cu'

gen = SlabGenerator(
bulk,
miller_index=(1, 1, 1),
layers=6,
vacuum=4)

atoms = gen.get_slab()
atoms.set_surface_atoms([8, 9, 10, 11])

sites = AdsorptionSites(atoms)
sites.plot('./Pd3Cu-adsorption-sites.png')
45 changes: 45 additions & 0 deletions catkit/tests/gen/test1.2.2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from catkit.gen.adsorption import AdsorptionSites
from catkit.gen.surface import SlabGenerator
from ase.build import bulk
from ase.io import write
from ase import Atom

bulk = bulk('Pd', 'fcc', a=5, cubic=True)
bulk[3].symbol = 'Cu'

gen = SlabGenerator(
bulk,
miller_index=(3, 2, 1),
layers=13,
vacuum=5)

atoms = gen.get_slab(size=1)

sites = AdsorptionSites(atoms)

# Positon of each site
coordinates = sites.get_coordinates()

# Number of adjacent surface atoms
connectivity = sites.get_connectivity()

# The indices of adjacent surface atoms
topology = sites.get_topology()

# Only print every 5th entry.
print('Coordinates:\n', coordinates[::5], '\n')
print('Connectivity:\n', connectivity[::5], '\n')
print('Topology:\n', topology[::5], '\n')

periodic = sites.get_periodic_sites()
print('Sites by periodicity:\n', periodic[::5], '\n')

symmetric = sites.get_symmetric_sites()
print('Sites by symmetry:\n', symmetric[::5])

atm = {1: 'X', 2: 'He', 3: 'F', 4: 'N'}
for i, c in enumerate(coordinates):
typ = connectivity[i]
atoms += Atom(atm[typ], c + [0, 0, 2])

atoms.edit()
28 changes: 28 additions & 0 deletions catkit/tests/gen/test1.2.3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from catkit.gen.adsorption import AdsorptionSites
from catkit.gen.surface import SlabGenerator
from ase.build import bulk
from ase import Atom
import numpy as np

bulk = bulk('Pd', 'fcc', a=5, cubic=True)
bulk[3].symbol = 'Cu'

gen = SlabGenerator(
bulk,
miller_index=(2, 1, 1),
layers=10,
vacuum=5)

atoms = gen.get_slab()
sites = AdsorptionSites(atoms)

coordinates = sites.get_coordinates()
vectors = sites.get_adsorption_vectors()

heights = np.arange(0, 2, 0.25)
for i, c in enumerate(coordinates):
for h in heights:
atoms += Atom('X', c + vectors[i] * h)

atoms.wrap()
atoms.edit()
19 changes: 19 additions & 0 deletions catkit/tests/gen/test1.2.4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from catkit.gen.surface import SlabGenerator
from catkit.gen.adsorption import Builder
from ase.build import bulk
import numpy as np

atoms = bulk('Pd', 'fcc', a=4, cubic=True)
atoms[3].symbol = 'Cu'

gen = SlabGenerator(
atoms,
miller_index=(1, 1, 1),
layers=4,
fixed=2,
vacuum=10)

slab = gen.get_slab()

builder = Builder(slab)
print(builder)
23 changes: 23 additions & 0 deletions catkit/tests/gen/test1.2.4_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from catkit.build import molecule
from catkit.gen.surface import SlabGenerator
from catkit.gen.adsorption import Builder
from ase.build import bulk

atoms = bulk('Pd', 'fcc', a=4, cubic=True)
atoms[3].symbol = 'Cu'

gen = SlabGenerator(
atoms,
miller_index=(1, 1, 1),
layers=4,
vacuum=4)

slab = gen.get_slab()

adsorbate = molecule('CH3')[0]
adsorbate.set_tags([-1, 0, 0, 0])

builder = Builder(slab)
ads_slab = builder.add_adsorbate(adsorbate, index=0)

ads_slab.edit()
24 changes: 24 additions & 0 deletions catkit/tests/gen/test1.2.4_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from catkit.build import molecule
from catkit.gen.surface import SlabGenerator
from catkit.gen.adsorption import Builder
from ase.build import bulk
from ase.visualize import view

atoms = bulk('Pd', 'fcc', a=4, cubic=True)
atoms[3].symbol = 'Cu'

gen = SlabGenerator(
atoms,
miller_index=(1, 1, 1),
layers=4,
vacuum=4)

slab = gen.get_slab()
adsorbate = molecule('C2H3')[1]

builder = Builder(slab)
ads_slab = builder.add_adsorbate(adsorbate, bonds=[0, 1], index=-1)

print('{} adsorption structures generated'.format(len(ads_slab)))

view(ads_slab)
28 changes: 28 additions & 0 deletions catkit/tests/gen/test1.5.1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from catkit.gen.route import get_response_reactions
import numpy as np

epsilon = np.array([
# To keep indexing consistent
[ 0, 0, 0, 0], # I1
[ 0, 0, 0, 0], # I2
[ 0, 0, 0, 0], # I3
[ 0, 0, 0, 0], # I4
[ 0, 0, 0, 0], # I5
# C N H O
[ 1, 0, 4, 0], # CH4
[ 0, 1, 0, 1], # NO
[ 0, 0, 0, 2], # O2
[ 0, 2, 0, 0], # N2
[ 1, 0, 0, 1], # CO
[ 1, 0, 0, 2], # CO2
[ 0, 0, 2, 1], # H2O
])

terminal = [5, 6, 7, 8, 9, 10, 11]
OR, species = get_response_reactions(epsilon, terminal, species=True)

print('Overall reaction routes:')
print(OR, '\n')

print('Terminal species:')
print(species)
51 changes: 51 additions & 0 deletions catkit/tests/gen/test1.5.2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from catkit.gen.route import get_response_reactions
from catkit.gen.route import get_heppel_sellers
import numpy as np

nu = np.array([
# H2Os, COs, CO2s, H2s, Hs, OHs, Os, HCOOs, H2O, CO, CO2, H2
[ 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0], # s1
[ 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0], # s2
[ 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0], # s3
[ 0, 0, 0, 1, -2, 0, 0, 0, 0, 0, 0, 0], # s4
[ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1], # s5
[ -1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0], # s6
[ 0, -1 , 1, 0, 0, 0, -1, 0, 0, 0, 0, 0], # s7
[ 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0], # s8
[ 0, 0, 0, 0, 1, -1, 1, 0, 0, 0, 0, 0], # s9
[ 0, -1, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0], # s10
[ 0, 0, 1, 0, 1, 0, 0, -1, 0, 0, 0, 0], # s11
[ 0, 0, 1, 0, 0, 1, -1, -1, 0, 0, 0, 0], # s12
[ -1, 0, 0, 1, -1, 1, 0, 0, 0, 0, 0, 0], # s14
[ 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, 0], # s15
[ 0, 0, 1, 1, -1, 0, 0, -1, 0, 0, 0, 0], # s17
])

epsilon = np.array([
# Just a place holder
[ 0, 0, 0], # H2OS
[ 0, 0, 0], # COS
[ 0, 0, 0], # CO2S
[ 0, 0, 0], # H2S
[ 0, 0, 0], # HS
[ 0, 0, 0], # OHS
[ 0, 0, 0], # OS
[ 0, 0, 0], # HCOOS
# C, H, O
[ 0, 2, 1], # H2O
[ 1, 0, 1], # CO
[ 1, 0, 2], # CO2
[ 0, 2, 0], # H2
])

# Indices of the terminal species
terminal = [8, 9, 10, 11]

RER, species = get_response_reactions(epsilon, terminal, species=True)
sigma = get_heppel_sellers(nu, species[0])

print('Linearly independent set of reaction routes:')
print(sigma, '\n')

print('Overall reaction routes:')
print(np.dot(sigma, nu))
Loading