4. Creating the Lattice Model

The LatticeModel represents the lattice structure on which adsorbates can bind, and supports different lattice types:

  • default_choice: Predefined lattice structures (e.g., triangular, rectangular or hexagonal).

  • periodic_cell: Custom periodic unit cells with specified cell vectors and sites.

  • explicit: Explicitly defined lattice structures (not yet implemented).

Allowed lattice types

  • 'default_choice'

  • 'periodic_cell'

  • 'explicit' (Note: As per the current implementation, 'explicit' is not yet supported.)


How to create it

There are three primary ways to create a LatticeModel, as detailed below.

Using a default lattice

This method allows you to select from predefined lattice types and specify basic parameters.

Required parameters:

  • lattice_type: Set to 'default_choice'.

  • default_lattice_type (str): Choose from 'triangular_periodic', 'rectangular_periodic', or 'hexagonal_periodic'.

  • lattice_constant (float): The lattice constant (Å).

  • copies (List[int]): Number of repetitions along the horizontal and vertical directions.

from zacrostools.lattice_model import LatticeModel

lattice_model = LatticeModel(
    lattice_type='default_choice',
    default_lattice_type='triangular_periodic',
    lattice_constant=2.5,
    copies=[10, 10]
)

Defining a custom periodic cell

This method allows you to define a custom lattice by specifying the unit cell vectors, site types, and neighboring structures.

Required parameters:

  • lattice_type: Set to 'periodic_cell'.

  • cell_vectors (Tuple[Tuple[float, float], Tuple[float, float]]): Two vectors defining the unit cell.

  • sites (Dict[str, Union[Tuple[float, float], List[Tuple[float, float]]]]): Mapping of site types to their coordinates within the unit cell.

  • coordinate_type (str, optional): 'direct' or 'cartesian'. Defaults to 'direct'.

  • copies (List[int]): Number of repetitions along the horizontal and vertical directions.

  • neighboring_structure (Union[str, Dict[str, Union[str, List[str]]]]): Defines the neighboring relationships between sites.

    • If set to 'from_distances', you must provide max_distances.

    • If providing a dictionary, it maps site pairs to a list of relationship keywords.

  • max_distances (Dict[str, float], required if neighboring_structure='from_distances'): Defines maximum distances for neighbor pairs.

The following examples show two different ways to create the lattice model for a HfC(001) surface, as described in the image below:

Molecules produced
  1. Specifying a neighboring structure:

from zacrostools.lattice_model import LatticeModel

# Define cell vectors
cell_vectors = ((3.27, 0.0), (0.0, 3.27))

# Define site positions
sites = {
    'tC': [(0.25, 0.25)],
    'tM': [(0.75, 0.75)]
}

# Define neighboring structure directly
neighboring_structure = {
    '1-2': ['self'],
    '1-1': ['north', 'east'],
    '2-1': ['north', 'east', 'northeast'],
    '2-2': ['north', 'east']
}

# Create the LatticeModel instance
lattice_model = LatticeModel(
    lattice_type='periodic_cell',
    cell_vectors=cell_vectors,
    sites=sites,
    coordinate_type='direct',
    copies=[10, 10],
    neighboring_structure=neighboring_structure
)
  1. Generating the neighboring structure automatically

from zacrostools.lattice_model import LatticeModel

# Define cell vectors
cell_vectors = ((3.27, 0.0), (0.0, 3.27))

# Define site positions
sites = {
    'tC': [(0.25, 0.25)],
    'tM': [(0.75, 0.75)]
}

# Define maximum distances for neighbor pairs
max_distances = {
    'tC-tC': 3.0,
    'tM-tM': 3.0,
    'tC-tM': 3.0
}

# Create the LatticeModel instance
lattice_model = LatticeModel(
    lattice_type='periodic_cell',
    cell_vectors=cell_vectors,
    sites=sites,
    coordinate_type='direct',
    copies=[10, 10],
    neighboring_structure='from_distances',
    max_distances=max_distances
)

Loading from an existing lattice input file

This method allows you to create a LatticeModel by reading a previously created lattice_input.dat file. This is particularly useful when you want to reuse lattice configurations or when the lattice file was provided by another user.

Required parameters:

  • input_file (str or Path): Path to the existing lattice_input.dat file.

from zacrostools.lattice_model import LatticeModel

lattice_model = LatticeModel.from_file(input_file='path/to/lattice_input.dat')

Notes for this method:

  • It reads the lattice block from the file, which starts with the lattice keyword and ends with end_lattice.

  • Supports 'default_choice' and 'periodic_cell' lattice types.

  • If the lattice type is 'explicit', a LatticeModelError will be raised as this type is not yet supported.

  • Ignores any content outside the lattice block.


Repeating the LatticeModel

You can expand the unit cell by repeating it along the cell vectors.

Required parameters:

  • a (int): Number of repetitions along the first cell vector.

  • b (int): Number of repetitions along the second cell vector.

# Repeat the lattice 2 times along alpha and 3 times along beta
lattice_model.repeat_lattice_model(a=2, b=3)

Removing a site

You can remove a specific site based on its coordinates.

Required parameters:

  • direct_coords (Tuple[float, float]): The direct coordinates of the site to remove.

  • tolerance (float, optional): Tolerance for coordinate matching.

# Remove a site at position (0.5, 0.5)
lattice_model.remove_site(direct_coords=(0.5, 0.5))

Changing the site type

Required parameters:

  • direct_coords (Tuple[float, float]): The direct coordinates of the site.

  • new_site_type (str): The new site type to assign.

  • tolerance (float, optional): Tolerance for coordinate matching.

# Change the site type at position (0.0, 0.0) to 'B'
lattice_model.change_site_type(direct_coords=(0.0, 0.0), new_site_type='B')

Writing the lattice_input.dat file

The LatticeModel can generate the lattice_input.dat file required by Zacros.

Required parameters:

  • output_dir (str or Path): Directory where the file will be written.

  • sig_figs (int, optional): Number of significant figures for numerical values.

# Write the lattice_input.dat file to the specified directory
lattice_model.write_lattice_input(output_dir='kmc_simulation', sig_figs=3)

Full example

This example shows how to create a lattice model for a Pt4 cluster supported on a HfC(001) surface, as described in the image below:

Molecules produced
from zacrostools.lattice_model import LatticeModel

# Create a unit cell for PtHfC unit cell from a 4x4 cell of HfC
lattice_model = LatticeModel(
    lattice_type='periodic_cell',
    cell_vectors=((3.27, 0), (0, 3.27)),
    sites={'tC': (0.25, 0.25), 'tM': (0.75, 0.75)},
    copies=[10, 10],
    neighboring_structure='from_distances',
    max_distances={'tC-tC': 4.0, 'tC-tM': 4.0, 'tM-tM': 4.0, 'Pt-Pt': 4.0, 'Pt-tC': 4.0, 'Pt-tM': 4.0},
)
lattice_model.repeat_lattice_model(4, 4)

# Replace four tC sites by Pt sites
for coordinates in [(0.3125, 0.3125), (0.3125, 0.5625), (0.5625, 0.3125), (0.5625, 0.5625)]:
    lattice_model.change_site_type(direct_coords=coordinates, new_site_type='Pt') 

# Remove the tM site in the middle of the four Pt sites
lattice_model.remove_site(direct_coords=(0.4375, 0.4375)) 

# Define the number of copies of the unit cell for the simulation
lattice_model.copies = [3, 3]

# Write the lattice_input.dat file in a folder named 'PtHfC'
lattice_model.write_lattice_input(output_dir='PtHfC')