crystal-geometry
Generate 3D crystal geometry from CDL descriptions using half-space intersection and crystallographic symmetry operations.
pip install crystal-geometry Functions
#
cdl_to_geometry(description: CrystalDescription) → CrystalGeometry Convert a parsed CDL description into 3D geometry.
from cdl_parser import parse_cdl
from crystal_geometry import cdl_to_geometry
desc = parse_cdl("cubic[m3m]:{111}@1.0 + {100}@1.3")
geom = cdl_to_geometry(desc)
print(f"Vertices: {len(geom.vertices)}") # 14
print(f"Faces: {len(geom.faces)}") # 14 Parameters:
description- ParsedCrystalDescriptionfrom cdl-parser
Returns: CrystalGeometry object with vertices, faces, and normals
#
apply_symmetry(planes: list[Plane], point_group: str) → list[Plane] Apply point group symmetry operations to generate all equivalent planes.
from crystal_geometry import apply_symmetry, Plane
# Single {111} plane
planes = [Plane(normal=(1, 1, 1), distance=1.0)]
# Apply m3m symmetry -> 8 equivalent planes
all_planes = apply_symmetry(planes, "m3m")
print(len(all_planes)) # 8 #
halfspace_intersection(planes: list[Plane]) → CrystalGeometry Compute the convex polyhedron defined by the intersection of half-spaces.
from crystal_geometry import halfspace_intersection, Plane
# Define a cube with 6 planes
planes = [
Plane(normal=(1, 0, 0), distance=1.0),
Plane(normal=(-1, 0, 0), distance=1.0),
Plane(normal=(0, 1, 0), distance=1.0),
Plane(normal=(0, -1, 0), distance=1.0),
Plane(normal=(0, 0, 1), distance=1.0),
Plane(normal=(0, 0, -1), distance=1.0),
]
geom = halfspace_intersection(planes)
print(len(geom.vertices)) # 8
print(len(geom.faces)) # 6 #
apply_twin(geometry: CrystalGeometry, twin_law: str) → CrystalGeometry Apply a twin law to create twinned crystal geometry.
from crystal_geometry import cdl_to_geometry, apply_twin
geom = cdl_to_geometry(desc)
twinned = apply_twin(geom, "spinel_law") Supported twin laws:
spinel_law- Cubic {111} contact twindauphine- Quartz 180° rotation about c-axisbrazil- Quartz reflection twinjapan_law- Quartz {11-22} contact twincarlsbad- Feldspar twin
Classes
CrystalGeometry
Container for 3D crystal geometry data.
| Attribute | Type | Description |
|---|---|---|
vertices | np.ndarray | Nx3 array of vertex coordinates |
faces | list[Face] | List of Face objects |
normals | np.ndarray | Nx3 array of face normals |
face_miller_indices | list[MillerIndex] | Miller indices for each face |
center | tuple[float, float, float] | Centroid of the geometry |
bounds | tuple[tuple, tuple] | Bounding box (min, max) |
Methods
# Transform the geometry
geom.translate(dx, dy, dz)
geom.scale(factor)
geom.rotate(axis, angle)
# Get geometry info
volume = geom.volume()
surface_area = geom.surface_area()
# Export to different formats
geom.to_mesh() # Returns vertices, faces arrays
geom.to_trimesh() # Returns trimesh.Trimesh object Face
Represents a single crystal face.
| Attribute | Type | Description |
|---|---|---|
vertex_indices | list[int] | Indices into vertices array (CCW order) |
normal | tuple[float, float, float] | Outward-facing normal vector |
miller_index | MillerIndex | Miller indices for this face |
area | float | Surface area of the face |
centroid | tuple[float, float, float] | Center point of the face |
Plane
Represents a half-space boundary plane.
from crystal_geometry import Plane
# Create from normal and distance
plane = Plane(normal=(1, 1, 1), distance=1.0)
# Create from Miller indices
plane = Plane.from_miller(h=1, k=1, l=1, distance=1.0) Symmetry Operations
#
get_symmetry_matrices(point_group: str) → list[np.ndarray] Get the 3x3 rotation/reflection matrices for a point group.
from crystal_geometry import get_symmetry_matrices
matrices = get_symmetry_matrices("m3m")
print(len(matrices)) # 48 operations
matrices = get_symmetry_matrices("-3m")
print(len(matrices)) # 12 operations Unit Cells
#
get_unit_cell(system: CrystalSystem, a: float, b: float, c: float, alpha: float, beta: float, gamma: float) → UnitCell Create a unit cell with specified parameters.
from crystal_geometry import get_unit_cell
from cdl_parser import CrystalSystem
# Quartz unit cell
cell = get_unit_cell(
system=CrystalSystem.TRIGONAL,
a=4.913, b=4.913, c=5.405,
alpha=90, beta=90, gamma=120
)
# Get transformation matrix
transform = cell.cartesian_matrix()