rheedium.ucell¶
Unit cell operations including lattice vector construction, reciprocal space calculations, and surface slab generation.
Unit cell and crystallographic utilities for RHEED simulation.
Extended Summary¶
This module provides functions for crystallographic calculations including unit cell transformations, reciprocal space operations, and specialized mathematical functions like Bessel functions used in scattering calculations.
Routine Listings¶
angle_in_degrees()Calculate angle in degrees between two vectors.
atom_scraper()Filter atoms within specified depth from surface along zone axis.
build_cell_vectors()Convert lattice parameters to Cartesian cell vectors.
compute_lengths_angles()Extract lattice parameters from cell vectors.
generate_reciprocal_points()Generate reciprocal lattice points for given Miller indices.
get_unit_cell_matrix()Build transformation matrix from lattice parameters.
miller_to_reciprocal()Convert Miller indices to reciprocal lattice basis vectors.
parse_cif_and_scrape()Parse CIF file and filter atoms within penetration depth.
reciprocal_lattice_vectors()Generate reciprocal lattice basis vectors b₁, b₂, b₃.
reciprocal_unitcell()Calculate reciprocal unit cell from direct cell vectors.
- rheedium.ucell.angle_in_degrees(v1: Float[Array, 'n'], v2: Float[Array, 'n']) Float[Array, ''][source]¶
Calculate the angle in degrees between two vectors.
As long as the vectors have the same number of elements, any dimensional vectors will work.
- Parameters:
v1 (
Float[Array, 'n']) – First vectorv2 (
Float[Array, 'n']) – Second vector
- Returns:
angle – Angle between vectors in degrees
- Return type:
Float[Array, '']
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> v1 = jnp.array([1.0, 0.0, 0.0]) >>> v2 = jnp.array([0.0, 1.0, 0.0]) >>> angle = rh.ucell.angle_in_degrees(v1, v2) >>> print(angle) 90.0
- rheedium.ucell.compute_lengths_angles(vectors: Float[Array, '3 3']) tuple[Float[Array, '3'], Float[Array, '3']][source]¶
Compute unit cell lengths and angles from lattice vectors.
- Parameters:
vectors (
Float[Array, '3 3']) – Lattice vectors as rows of a 3x3 matrix- Return type:
tuple[Float[Array, '3'],Float[Array, '3']]- Returns:
lengths (
Float[Array,"3"]) – Unit cell lengths in angstromsangles (
Float[Array,"3"]) – Unit cell angles in degrees
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> # Cubic unit cell with a=5.0 Å >>> vectors = jnp.array( ... [ ... [5.0, 0.0, 0.0], ... [0.0, 5.0, 0.0], ... [0.0, 0.0, 5.0], ... ] ... ) >>> lengths, angles = rh.ucell.compute_lengths_angles(vectors) >>> print(lengths) [5.0 5.0 5.0] >>> print(angles) [90.0 90.0 90.0]
- rheedium.ucell.parse_cif_and_scrape(cif_path: str | Path, zone_axis: Real[Array, '3'], thickness_xyz: Real[Array, '3']) CrystalStructure[source]¶
Parse a CIF file and filter atoms within specified thickness.
Parse a CIF file, apply symmetry operations to obtain all equivalent atomic positions, and scrape (filter) atoms within specified thickness along a given zone axis.
- Parameters:
zone_axis (
Real[Array, '3']) – Vector indicating the zone axis direction (surface normal) in Cartesian coordinates.thickness_xyz (
Real[Array, '3']) – Thickness along x, y, z directions in Ångstroms; currently, only thickness_xyz[2] (z-direction) is used to filter atoms along the provided zone axis.
- Returns:
filtered_crystal – Crystal structure containing atoms filtered within the specified thickness.
- Return type:
Notes
The provided
zone_axisis normalized internally. Current implementation uses thickness only along the zone axis direction (z-component ofthickness_xyz).The
toleranceparameter is reserved for compatibility and future functionality.
Parse CIF – Load the CIF file to obtain the initial crystal structure with all symmetry-equivalent positions.
Extract Coordinates – Separate Cartesian positions and atomic numbers from the crystal structure arrays.
Normalize Zone Axis – Compute a unit vector along the provided zone axis direction.
Project onto Zone Axis – Dot each atomic position with the zone axis unit vector to get scalar projections.
Apply Thickness Filter – Compute the center projection and half thickness, then create a boolean mask for atoms within range.
Filter Atoms – Select Cartesian positions and atomic numbers using the thickness mask.
Reconstruct Fractional Coordinates – Build cell vectors from crystal parameters, invert the matrix, and convert filtered Cartesian positions to fractional coordinates.
Build Output Structure – Create a new
CrystalStructurewith the filtered positions and original cell parameters.
- rheedium.ucell.atom_scraper(crystal: CrystalStructure, zone_axis: Float[Array, '3'], thickness: Float[Array, '3']) CrystalStructure[source]¶
Filter atoms within specified thickness along zone axis.
- Parameters:
crystal (
CrystalStructure) – Crystal structure to filter.zone_axis (
Float[Array, '3']) – Zone axis direction.thickness (
Float[Array, '3']) – Thickness in each direction.
- Returns:
filtered_crystal – Filtered crystal structure.
- Return type:
Notes
Build Cell Vectors – Construct direct lattice vectors from the crystal structure cell parameters.
Normalize Zone Axis – Compute a unit vector along the provided zone axis direction.
Project and Measure – Project each atomic position onto the zone axis and compute distances from the topmost layer.
Adaptive Threshold – Determine an adaptive epsilon for top-layer mode based on the smallest nonzero distance.
Apply Thickness Mask – Create a boolean mask selecting atoms within the projected thickness or within the adaptive epsilon for zero-thickness (top-layer) mode.
Gather Filtered Atoms – Extract fractional and Cartesian positions for atoms that pass the mask.
Scale Cell Vectors – Rescale lattice vectors along the zone axis to match the new slab height while preserving perpendicular components.
Build Output Structure – Create a new
CrystalStructurewith the filtered positions and rescaled cell parameters.
Examples
>>> import rheedium as rh >>> import jax.numpy as jnp >>> >>> # Load crystal structure >>> crystal = parse_cif("path/to/crystal.cif") >>> >>> # Filter atoms within 12 Å along [111] direction >>> filtered = atom_scraper( ... crystal=crystal, ... zone_axis=jnp.array([1.0, 1.0, 1.0]), ... thickness=jnp.array([12.0, 12.0, 12.0]), ... ) >>> print(f"Original atoms: {len(crystal.frac_positions)}") >>> print(f"Filtered atoms: {len(filtered.frac_positions)}")
See also
build_cell_vectorsConstruct unit cell vectors.
compute_lengths_anglesCompute cell parameters from vectors.
create_crystal_structureCreate filtered crystal structure.
- rheedium.ucell.build_cell_vectors(a: float | Float[Array, ''], b: float | Float[Array, ''], c: float | Float[Array, ''], alpha: float | Float[Array, ''], beta: float | Float[Array, ''], gamma: float | Float[Array, '']) Float[Array, '3 3'][source]¶
Construct unit cell vectors from lengths and angles.
- Parameters:
a (
Union[float,Float[Array, '']]) – Direct cell lengths in angstroms.b (
Union[float,Float[Array, '']]) – Direct cell lengths in angstroms.c (
Union[float,Float[Array, '']]) – Direct cell lengths in angstroms.alpha (
Union[float,Float[Array, '']]) – Direct cell angles in degrees.beta (
Union[float,Float[Array, '']]) – Direct cell angles in degrees.gamma (
Union[float,Float[Array, '']]) – Direct cell angles in degrees.
- Returns:
Unit cell vectors as rows of 3x3 matrix.
- Return type:
Float[Array, '3 3']
Notes
Angle Conversion – Convert alpha, beta, gamma from degrees to radians.
First Vector – Place a-vector along the x-axis as [a, 0, 0].
Second Vector – Place b-vector in the x-y plane using gamma to compute x and y components.
Third Vector – Compute c-vector components from all three angles, clipping c_z squared to avoid negative values under the square root.
Stack Vectors – Assemble the three vectors into a 3x3 matrix with each vector as a row.
Examples
>>> import rheedium as rh >>> import jax.numpy as jnp >>> >>> # Build vectors for a cubic cell >>> vectors = build_cell_vectors( ... a=3.0, ... b=3.0, ... c=3.0, # 3 Å cubic cell ... alpha=90.0, ... beta=90.0, ... gamma=90.0, ... ) >>> print(f"Cell vectors:\n{vectors}") >>> >>> # Calculate cell volume >>> volume = jnp.linalg.det(vectors) >>> print(f"Cell volume: {volume}")
See also
compute_lengths_anglesInverse operation from vectors to parameters.
reciprocal_lattice_vectorsBuild reciprocal lattice vectors.
- rheedium.ucell.bulk_to_slice(bulk_crystal: CrystalStructure, orientation: Int[Array, '3'], depth: float | Float[Array, ''], x_extent: float | Float[Array, ''] = 150.0, y_extent: float | Float[Array, ''] = 150.0) SlicedCrystal[source]¶
Transform a bulk crystal structure into a surface-oriented slab.
This function takes a bulk crystal structure and creates a surface slab oriented along the specified Miller indices. The slab is extended in the x and y directions to create a large surface area suitable for RHEED simulations, with atoms selected within a specified depth from the surface.
- Parameters:
bulk_crystal (
CrystalStructure) – Bulk crystal structure from CIF file or other source.orientation (
Int[Array, '3']) – Miller indices [h, k, l] defining the desired surface orientation. Example: [1, 1, 1] for (111) surface, [0, 0, 1] for (001).depth (
Union[float,Float[Array, '']]) – Depth of atoms to include perpendicular to surface in Angstroms. Typically 10-30 Angstroms to capture surface effects.x_extent (
Union[float,Float[Array, '']], default:150.0) – Lateral extent in x-direction in Angstroms. Default: 150.0. Should be >= 100 Angstroms for realistic RHEED simulations.y_extent (
Union[float,Float[Array, '']], default:150.0) – Lateral extent in y-direction in Angstroms. Default: 150.0. Should be >= 100 Angstroms for realistic RHEED simulations.
- Returns:
sliced_crystal – Surface-oriented crystal slab with transformed coordinates.
- Return type:
Notes
The transformation preserves atomic types and relative positions.
The resulting structure has z as the surface normal.
Periodic boundary conditions apply in x and y directions.
The depth direction (z) is typically non-periodic for surface slabs.
Build rotation matrix to align [hkl] direction with z-axis: convert Miller indices to reciprocal lattice vector and calculate rotation matrix R that maps this vector to [0, 0, 1].
Transform all atomic positions using rotation matrix.
Create supercell by replicating atoms in x and y directions: determine number of repetitions needed to cover x_extent and y_extent, generate all combinations of translations, and apply translations to create supercell.
Filter atoms within depth range: 0 <= z <= depth.
Center the slab so z=0 is at the bottom surface.
Calculate new cell parameters for the supercell.
Return SlicedCrystal with transformed coordinates.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Load bulk structure >>> bulk = rh.inout.parse_cif("SrTiO3.cif") >>> >>> # Create (111) surface slab >>> slab = rh.ucell.bulk_to_slice( ... bulk_crystal=bulk, ... orientation=jnp.array([1, 1, 1]), ... depth=20.0, ... x_extent=150.0, ... y_extent=150.0, ... )
- rheedium.ucell.generate_reciprocal_points(crystal: CrystalStructure, hmax: int | Integer[Array, ''], kmax: int | Integer[Array, ''], lmax: int | Integer[Array, ''], in_degrees: bool | Bool[Array, ''] = True) Float[Array, 'M 3'][source]¶
Generate reciprocal-lattice vectors based on the crystal structure.
- Parameters:
crystal (
CrystalStructure) – Crystal structure to generate points for.hmax (
Union[int,Integer[Array, '']]) – Maximum h, k, l indices to generate.kmax (
Union[int,Integer[Array, '']]) – Maximum h, k, l indices to generate.lmax (
Union[int,Integer[Array, '']]) – Maximum h, k, l indices to generate.in_degrees (
Union[bool,Bool[Array, '']], default:True) – Whether to use degrees for angles. Default: True.
- Returns:
Reciprocal lattice vectors in 1/angstroms.
- Return type:
Float[Array, 'M 3']
Notes
Extract Cell Parameters – Retrieve lengths and angles from the crystal structure.
Build Reciprocal Basis – Generate reciprocal lattice vectors from the direct cell parameters.
Generate Index Grid – Create h, k, l index ranges and form a meshgrid of all (h, k, l) combinations.
Transform to Reciprocal Space – Convert the flattened Miller index array to reciprocal space vectors via
miller_to_reciprocal.
Examples
>>> import rheedium as rh >>> import jax.numpy as jnp >>> >>> # Load crystal structure from CIF >>> crystal = parse_cif("path/to/crystal.cif") >>> >>> # Generate reciprocal points up to (2,2,1) >>> G_vectors = generate_reciprocal_points( ... crystal=crystal, ... hmax=2, ... kmax=2, ... lmax=1, ... ) >>> print(f"Number of G vectors: {len(G_vectors)}") >>> print(f"First few G vectors:\n{G_vectors[:5]}")
See also
reciprocal_lattice_vectorsGenerate reciprocal basis vectors.
miller_to_reciprocalConvert Miller indices to G vectors.
- rheedium.ucell.get_unit_cell_matrix(a: float | Float[Array, ''], b: float | Float[Array, ''], c: float | Float[Array, ''], alpha: float | Float[Array, ''], beta: float | Float[Array, ''], gamma: float | Float[Array, '']) Float[Array, '3 3'][source]¶
Build transformation matrix between direct and reciprocal space.
- Parameters:
a (
Union[float,Float[Array, '']]) – Direct cell lengths in angstroms.b (
Union[float,Float[Array, '']]) – Direct cell lengths in angstroms.c (
Union[float,Float[Array, '']]) – Direct cell lengths in angstroms.alpha (
Union[float,Float[Array, '']]) – Direct cell angles in degrees.beta (
Union[float,Float[Array, '']]) – Direct cell angles in degrees.gamma (
Union[float,Float[Array, '']]) – Direct cell angles in degrees.
- Returns:
Transformation matrix from direct to reciprocal space.
- Return type:
Float[Array, '3 3']
Notes
Angle Conversion – Convert cell angles from degrees to radians and compute their cosines and sines.
Volume Factor – Compute the volume factor from the cosines of all three cell angles.
Matrix Assembly – Populate the 3x3 transformation matrix with elements derived from lengths, angles, and the volume factor. The matrix maps direct space coordinates to Cartesian coordinates.
Examples
>>> import rheedium as rh >>> import jax.numpy as jnp >>> >>> # Get transformation matrix for a cubic cell >>> matrix = get_unit_cell_matrix( ... a=3.0, ... b=3.0, ... c=3.0, # 3 Å cubic cell ... alpha=90.0, ... beta=90.0, ... gamma=90.0, ... ) >>> print(f"Transformation matrix:\n{matrix}") >>> >>> # Transform a direct space vector to reciprocal space >>> direct_vec = jnp.array([1.0, 0.0, 0.0]) >>> recip_vec = direct_vec @ matrix >>> print(f"Reciprocal vector: {recip_vec}")
See also
build_cell_vectorsBuild direct lattice vectors from parameters.
reciprocal_lattice_vectorsGenerate reciprocal basis vectors.
- rheedium.ucell.miller_to_reciprocal(hkl: Int[Array, '... 3'], reciprocal_vectors: Float[Array, '3 3']) Float[Array, '... 3'][source]¶
Convert Miller indices to reciprocal space vectors.
Transforms Miller indices (h,k,l) to reciprocal space vectors G using the reciprocal lattice basis vectors. Each reciprocal vector is computed as G = h*b₁ + k*b₂ + l*b₃ where b₁, b₂, b₃ are the reciprocal lattice basis vectors.
- Parameters:
hkl (
3']) – Miller indices with shape (…, 3) where the last dimension contains [h, k, l] values. Can be a single set of indices or a batch of multiple indices.reciprocal_vectors (
Float[Array, '3 3']) – Reciprocal lattice basis vectors as rows of 3x3 matrix in 1/Angstroms, as returned by reciprocal_lattice_vectors function
- Returns:
g_vectors – Reciprocal space vectors in 1/Angstroms with same batch shape as input hkl indices
- Return type:
3']
Notes
Cast to Float – Convert integer Miller indices to float for computation with reciprocal vectors.
Extract Basis Vectors – Retrieve individual reciprocal basis vectors b₁, b₂, b₃ from the input matrix rows.
Linear Combination – Compute G = h*b₁ + k*b₂ + l*b₃ using element-wise broadcasting for efficient batched computation over all (h, k, l) triplets.
See also
reciprocal_lattice_vectorsGenerate reciprocal basis vectors.
generate_reciprocal_pointsGenerate G vectors from crystal structure.
- rheedium.ucell.reciprocal_lattice_vectors(a: float | Float[Array, ''], b: float | Float[Array, ''], c: float | Float[Array, ''], alpha: float | Float[Array, ''], beta: float | Float[Array, ''], gamma: float | Float[Array, ''], in_degrees: bool | Bool[Array, ''] = True) Float[Array, '3 3'][source]¶
Generate reciprocal lattice basis vectors b₁, b₂, b₃.
Computes the three reciprocal lattice basis vectors from direct lattice parameters using the crystallographic relationships: b₁ = 2π(a₂ × a₃)/(a₁ · (a₂ × a₃)) b₂ = 2π(a₃ × a₁)/(a₁ · (a₂ × a₃)) b₃ = 2π(a₁ × a₂)/(a₁ · (a₂ × a₃))
- Parameters:
a (
Union[float,Float[Array, '']]) – Direct cell length a in Angstromsb (
Union[float,Float[Array, '']]) – Direct cell length b in Angstromsc (
Union[float,Float[Array, '']]) – Direct cell length c in Angstromsalpha (
Union[float,Float[Array, '']]) – Direct cell angle α (between b and c axes)beta (
Union[float,Float[Array, '']]) – Direct cell angle β (between a and c axes)gamma (
Union[float,Float[Array, '']]) – Direct cell angle γ (between a and b axes)in_degrees (
Union[bool,Bool[Array, '']], default:True) – If True, input angles are in degrees. Default: True
- Returns:
reciprocal_vectors – Reciprocal lattice vectors as rows of 3x3 matrix in 1/Angstroms. Each row is a reciprocal basis vector [b₁, b₂, b₃].
- Return type:
Float[Array, '3 3']
Notes
Angle Conversion – Convert input angles to radians if provided in degrees.
Build Direct Vectors – Construct direct lattice vectors a₁, a₂, a₃ via
build_cell_vectors.Compute Volume – Calculate the unit cell volume from the triple product a₁ . (a₂ x a₃).
Cross Products – Compute cross products (a₂ x a₃), (a₃ x a₁), and (a₁ x a₂) for each reciprocal vector.
Scale to Reciprocal Space – Multiply each cross product by 2pi/volume to obtain b₁, b₂, b₃.
Stack Vectors – Assemble the three reciprocal vectors into a 3x3 matrix with each vector as a row.
See also
build_cell_vectorsBuild direct lattice vectors.
reciprocal_unitcellCompute reciprocal cell parameters.
miller_to_reciprocalConvert Miller indices to G vectors.
- rheedium.ucell.reciprocal_unitcell(a: float | Float[Array, ''], b: float | Float[Array, ''], c: float | Float[Array, ''], alpha: float | Float[Array, ''], beta: float | Float[Array, ''], gamma: float | Float[Array, ''], in_degrees: bool | Bool[Array, ''] = True, out_degrees: bool | Bool[Array, ''] = True) tuple[Float[Array, '3'], Float[Array, '3']][source]¶
Calculate reciprocal unit cell parameters from direct cell parameters.
Computes reciprocal lattice parameters (a*, b*, c*, α*, β*, γ*) from direct lattice parameters using crystallographic relationships.
- Parameters:
a (
Union[float,Float[Array, '']]) – Direct cell length a in Angstromsb (
Union[float,Float[Array, '']]) – Direct cell length b in Angstromsc (
Union[float,Float[Array, '']]) – Direct cell length c in Angstromsalpha (
Union[float,Float[Array, '']]) – Direct cell angle α (between b and c axes)beta (
Union[float,Float[Array, '']]) – Direct cell angle β (between a and c axes)gamma (
Union[float,Float[Array, '']]) – Direct cell angle γ (between a and b axes)in_degrees (
Union[bool,Bool[Array, '']], default:True) – If True, input angles are in degrees. Default: Trueout_degrees (
Union[bool,Bool[Array, '']], default:True) – If True, output angles are in degrees. Default: True
- Return type:
tuple[Float[Array, '3'],Float[Array, '3']]- Returns:
reciprocal_lengths (
Float[Array,"3"]) – Reciprocal cell lengths [a*, b*, c*] in 1/Angstromsreciprocal_angles (
Float[Array,"3"]) – Reciprocal cell angles [α*, β*, γ*] in degrees or radians
Notes
Angle Conversion – Convert input angles to radians if provided in degrees.
Volume Calculation – Compute unit cell volume using the triple product formula with cosines of cell angles.
Reciprocal Lengths – Derive a*, b*, c* from the volume and direct cell parameters using crystallographic relationships.
Reciprocal Angles – Calculate alpha*, beta*, gamma* from the direct cell angle cosines and sines.
Output Conversion – Convert output angles to degrees if requested.
See also
reciprocal_lattice_vectorsGenerate reciprocal basis vectors.
build_cell_vectorsBuild direct lattice vectors.