Structure Transformations
The transformations module provides an iterator-based framework for
generating structural variations. All transformations work with
aenet.geometry.AtomicStructure objects.
See also
For usage examples and detailed guides, see:
Base Classes
Abstract base class for all structure transformations. |
|
|
Chain multiple transformations with lazy evaluation. |
Deterministic Transformations
These transformations produce a fixed set of output structures for a given input structure.
|
Displace each atom in Cartesian x, y, z directions. |
|
Uniformly scale unit cell vectors. |
|
General integer cell/basis transformation using a 3x3 matrix. |
|
Volume-preserving uniaxial strain. |
|
Uniaxial strain (simple scaling of one lattice direction). |
|
Simple shear (volume-preserving by construction). |
|
Volume-conserving orthorhombic strain (elastic constant pattern). |
|
Volume-conserving monoclinic strain (elastic constant pattern). |
Stochastic Transformations
These transformations generate random structures and support reproducibility via random seeds.
|
Generate random atomic displacement vectors. |
|
Generate D-optimal (maximally diverse) atomic displacements. |
Detailed API
Base Classes
- class aenet.geometry.transformations.TransformationABC[source]
Bases:
ABCAbstract base class for all structure transformations.
All transformations must implement apply_transformation which yields transformed AtomicStructure objects.
- abstractmethod apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply transformation to structure.
- Parameters:
structure (AtomicStructure) – Input structure to transform
**kwargs – Additional keyword arguments for forward compatibility
- Yields:
AtomicStructure – Transformed structures
- class aenet.geometry.transformations.TransformationChain(transformations: list[TransformationABC])[source]
Bases:
objectChain multiple transformations with lazy evaluation.
This class allows sequential application of multiple transformations using itertools for memory-efficient streaming.
- Parameters:
transformations (list of TransformationABC) – List of transformations to apply sequentially
Examples
>>> chain = TransformationChain([transform1, transform2]) >>> for structure in chain.apply_transformation(input_structure): ... process(structure)
>>> # Or consume all at once >>> structures = list(chain.apply_transformation(input_structure))
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply all transformations sequentially using depth-first streaming.
This avoids iterator aliasing issues and guarantees correct combinatorics (including zero-output steps).
- Parameters:
structure (AtomicStructure) – Input structure to transform
**kwargs – Additional keyword arguments passed to transformations
- Returns:
Transformed structures from the chain
- Return type:
Iterator[AtomicStructure]
Deterministic Transformations
- class aenet.geometry.transformations.AtomDisplacementTransformation(displacement: float = 0.1)[source]
Bases:
TransformationABCDisplace each atom in Cartesian x, y, z directions.
This deterministic transformation generates
3Nstructures, whereNis the number of atoms. Each structure has one atom displaced by a fixed amount in one Cartesian direction.- Parameters:
displacement (float, optional) – Magnitude of displacement in Angstroms (default: 0.1)
Notes
This transformation is useful for finite-difference derivatives (forces, Hessians, etc.) or generating local perturbations around a reference structure.
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply displacement transformation to structure.
Yields 3N structures, one for each atom displaced in each direction.
- class aenet.geometry.transformations.CellVolumeTransformation(min_percent: float = -5.0, max_percent: float = 5.0, steps: int = 5)[source]
Bases:
TransformationABCUniformly scale unit cell vectors.
This transformation generates structures with different volumes by uniformly scaling the lattice vectors. Fractional coordinates remain unchanged, Cartesian coordinates are recomputed from the updated cell, and copied energy/force labels are cleared because they are no longer valid for the deformed geometry.
Physical/engineering meaning
This is a hydrostatic (isotropic) scaling of the lattice. In a thermodynamic context it resembles sampling different volumes (e.g., equation of state fits), but without relaxing internal degrees of freedom. It can be used, for example, to calculate the bulk modulus.
- param min_percent:
Minimum percentage change from original lattice scaling (default: -5.0)
- type min_percent:
float, optional
- param max_percent:
Maximum percentage change from original lattice scaling (default: 5.0)
- type max_percent:
float, optional
- param steps:
Number of scaling steps (default: 5)
- type steps:
int, optional
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply uniform volume scaling to structure.
Yields structures with different cell volumes while preserving fractional coordinates.
- class aenet.geometry.transformations.CellTransformationMatrix(T, sort: int | None = 2)[source]
Bases:
TransformationABCGeneral integer cell/basis transformation using a 3x3 matrix.
This wraps
aenet.geometry.utils.transform_cell().The transformation matrix
Tis applied as:A' = T · A
where rows of
Aare the lattice vectors. Atomic coordinates are transformed accordingly and redundant periodic images are created (or removed) so that the atom count is consistent with the volume scaling factor.Purpose
This is a change of lattice basis that does not actually alter the atomic structure, but rather how it is represented. This is useful for generating:
different supercell shapes for the same primitive cell
commensurate cells for defects, phonons, or disordered sampling
as a first step when constructing surface slabs from bulk structures
- param T:
Transformation matrix. In practice this should be integer-valued for supercell / basis transformations.
- type T:
array_like shape (3, 3)
- param sort:
Sorting behavior passed to
utils.transform_cell(default: 2).2sorts by fractional z, then by type.Nonedisables the coordinate-based sort (type sort still happens).- type sort:
int or None, optional
Notes
This currently relies on utilities that expect fractional coordinates. We convert AtomicStructure Cartesian coordinates to fractional, apply the transformation, then convert back to Cartesian.
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply cell basis transformation to structure.
Yields a single transformed structure with new cell and coordinates.
- class aenet.geometry.transformations.IsovolumetricStrainTransformation(direction: int, len_min: float, len_max: float, steps: int)[source]
Bases:
TransformationABCVolume-preserving uniaxial strain.
This transformation scales one lattice direction by a factor
swhile scaling the other two directions bys**(-1/2)to preserve the cell volume. Fractional coordinates are preserved, Cartesian coordinates are rebuilt from the deformed cell, and copied energy/force labels are cleared.Physical/engineering meaning
This is a constrained deformation (volume fixed by construction). It is not the standard deformation used for Young’s modulus, because Young’s modulus corresponds to uniaxial stress / stress-free transverse directions and generally changes volume.
This transformation is useful for structure-space sampling when you want to explore anisotropic cell shapes without changing volume.
- param direction:
Direction to strain (1=a, 2=b, 3=c)
- type direction:
int
- param len_min:
Minimum scaling factor for the strained direction
- type len_min:
float
- param len_max:
Maximum scaling factor for the strained direction
- type len_max:
float
- param steps:
Number of strain steps
- type steps:
int
- VOLUME_TOLERANCE = 1e-05
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply isovolumetric strain to structure.
Yields structures with volume-conserving strain.
- class aenet.geometry.transformations.UniaxialStrainTransformation(direction: int, len_min: float, len_max: float, steps: int)[source]
Bases:
TransformationABCUniaxial strain (simple scaling of one lattice direction).
This transformation scales one lattice direction by a factor
sand leaves the other two directions unchanged. Fractional coordinates are preserved, Cartesian coordinates are rebuilt from the deformed cell, and copied energy/force labels are cleared.Physical/engineering meaning
This is the simplest uniaxial strain deformation. It is often used as a starting point to compute directional stiffness / Young’s modulus, but note:
Young’s modulus corresponds to uniaxial stress with stress-free transverse directions. Accurately reproducing that condition may require relaxing the transverse cell vectors (and/or internal coordinates) at each applied strain.
This transformation alone therefore gives you a strained cell, but not necessarily the fully relaxed response.
- param direction:
Direction to strain (1=a, 2=b, 3=c)
- type direction:
int
- param len_min:
Minimum scaling factor for the strained direction
- type len_min:
float
- param len_max:
Maximum scaling factor for the strained direction
- type len_max:
float
- param steps:
Number of strain steps
- type steps:
int
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply uniaxial strain to structure.
Yields structures with strain in one direction only.
- class aenet.geometry.transformations.ShearStrainTransformation(direction: int, shear_min: float, shear_max: float, steps: int)[source]
Bases:
TransformationABCSimple shear (volume-preserving by construction).
This transformation applies a simple shear deformation gradient
Fwithdet(F)=1:direction=1: xy shear, F[0, 1] = shear
direction=2: xz shear, F[0, 2] = shear
direction=3: yz shear, F[1, 2] = shear
Physical/engineering meaning
Simple shear deforms the cell shape without changing volume (determinant of the deformation gradient is 1). Fractional coordinates are preserved, Cartesian coordinates are rebuilt from the deformed cell, and copied energy/force labels are cleared.
For small strains in cubic materials, this can be used to extract a shear elastic constant (often associated with
C44for xz/yz shear). For non-cubic crystals, the relation is more complex.- param direction:
Shear plane (1=xy, 2=xz, 3=yz)
- type direction:
int
- param shear_min:
Minimum shear value (deformation gradient component)
- type shear_min:
float
- param shear_max:
Maximum shear value (deformation gradient component)
- type shear_max:
float
- param steps:
Number of shear steps
- type steps:
int
Notes
The
shear_minandshear_maxparameters specify off-diagonal components of the deformation gradient F (not strain tensor components).For structure-space sampling, a typical range is -0.2 to +0.2. This explores moderate cell shape variations while maintaining reasonable atomic configurations. Larger values (\(|\mathrm{shear}| > 0.3\)) can lead to highly skewed cells.
For elastic constant calculations, stay in the linear elastic regime around -0.05 to +0.05 and use at least 5-7 points spanning positive and negative values.
There is no hard mathematical limit because \(\det(F)=1\) for all finite shear values. Practical limits depend on structure stability and the desired sampling regime.
- DETERMINANT_TOLERANCE = 0.001
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply volume-conserving shear strain to structure.
Yields structures with simple shear deformation.
- class aenet.geometry.transformations.OrthorhombicStrainTransformation(direction: int, e_min: float, e_max: float, steps: int)[source]
Bases:
TransformationABCVolume-conserving orthorhombic strain (elastic constant pattern).
This transformation implements the volume-conserving orthorhombic strain commonly used for extracting the cubic elastic constant combination
C11 - C12.It is based on
aenet.geometry.utils.strain_orthorhombic().For the default direction mapping (direction=1), the applied strain tensor has:
epsilon_xx = e
epsilon_yy = -e
epsilon_zz = e^2/(1-e^2)
with other components 0.
Physical/engineering meaning
This is not a generic uniaxial strain; it is a specific strain path chosen so that volume is conserved and the elastic energy depends on
C11 - C12in a simple way (for cubic crystals). Fractional coordinates are preserved, Cartesian coordinates are rebuilt from the deformed cell, and copied energy/force labels are cleared.- param direction:
Which axis plays the role of “x” in the above definition (1,2,3). The second axis is taken as the next cyclic axis.
- type direction:
int
- param e_min:
Range of e values (dimensionless strain component)
- type e_min:
float
- param e_max:
Range of e values (dimensionless strain component)
- type e_max:
float
- param steps:
Number of strain steps
- type steps:
int
Notes
The
e_minande_maxparameters specify the dimensionless strain component ε_xx in the strain tensor. Note the formula for the compensating strain: ε_zz = e²/(1-e²).The formulation has a singularity at \(|e| = 1\), where \(\epsilon_{zz}\) diverges. In practice, require \(|e_{\min}| < 1\) and \(|e_{\max}| < 1\).
For structure-space sampling, a typical range is -0.15 to +0.15. Staying well below \(|e| = 0.5\) avoids extreme cell deformations, and values above \(|e| > 0.3\) may already be unstable for some structures.
For elastic constant calculations targeting
C11 - C12, stay in the linear regime around -0.03 to +0.03, use at least 5-7 points with both positive and negative strain values, and ensure \(|e| \ll 1\).
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply orthorhombic strain pattern to structure.
Yields structures with volume-conserving orthorhombic strain.
- class aenet.geometry.transformations.MonoclinicStrainTransformation(direction: int, gamma_min: float, gamma_max: float, steps: int)[source]
Bases:
TransformationABCVolume-conserving monoclinic strain (elastic constant pattern).
This transformation implements a standard volume-conserving monoclinic strain path used to extract a shear elastic constant (often
C44in cubic crystals).It is based on
aenet.geometry.utils.strain_monoclinic().Physical/engineering meaning
In contrast to
ShearStrainTransformation(simple shear deformation gradient), this uses an engineering shear strain gamma definition and adds a compensating normal strain so that the overall deformation is volume-conserving along this specific strain path.For sufficiently small gamma the two become essentially equivalent, but they differ for larger strains. Fractional coordinates are preserved, Cartesian coordinates are rebuilt from the deformed cell, and copied energy/force labels are cleared.
- param direction:
Shear plane (1=xy, 2=xz, 3=yz)
- type direction:
int
- param gamma_min:
Range of engineering shear strain gamma
- type gamma_min:
float
- param gamma_max:
Range of engineering shear strain gamma
- type gamma_max:
float
- param steps:
Number of steps
- type steps:
int
Notes
The
gamma_minandgamma_maxparameters specify the engineering shear strain γ_xy. Note the formula for the compensating normal strain: ε_zz = γ²/(4-γ²).The formulation has a singularity at \(|\gamma| = 2\), where \(\epsilon_{zz}\) diverges. In practice, require \(|\gamma_{\min}| < 2\) and \(|\gamma_{\max}| < 2\).
For structure-space sampling, a typical range is -0.4 to +0.4. Staying well below \(|\gamma| = 1.0\) avoids extreme cell deformations, and values above \(|\gamma| > 0.6\) may produce highly skewed or unstable structures.
For elastic constant calculations targeting
C44, stay in the linear regime around -0.1 to +0.1, use at least 5-7 points with both positive and negative shear values, and ensure \(|\gamma| \ll 1\). In this limit the result approaches the simple-shear formulation.For \(|\gamma| < 0.1\), MonoclinicStrainTransformation and ShearStrainTransformation yield nearly identical results. They diverge at larger strains because they enforce volume conservation differently.
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply monoclinic strain pattern to structure.
Yields structures with volume-conserving monoclinic strain.
Stochastic Transformations
- class aenet.geometry.transformations.RandomDisplacementTransformation(rms: float = 0.1, max_structures: int | None = None, random_state: int | Generator | None = None, orthonormalize: bool = True, remove_translations: bool = True)[source]
Bases:
TransformationABCGenerate random atomic displacement vectors.
This stochastic transformation creates structures with random atomic displacements. It supports two modes:
orthonormalize=True(default): generates an orthonormal basis of displacement directions in the full3Nspace (optionally with the 3 translational modes removed). This is often useful to generate a compact, non-redundant set of perturbations.orthonormalize=False: draws independent random displacement patterns. This is useful when you want many samples, without imposing orthogonality constraints.
Purpose
This transformation is mainly intended for structure-space sampling (e.g., active learning) and for generating training data for interatomic potentials.
- param rms:
Target RMS displacement in Angstroms (default: 0.1)
- type rms:
float, optional
- param max_structures:
Maximum number of structures to generate. If None, defaults to
3N-3whenremove_translations=Trueand to3Notherwise.- type max_structures:
int, optional
- param random_state:
Random seed or generator for reproducibility.
- type random_state:
int or numpy.random.Generator, optional
- param orthonormalize:
If True, generate orthonormal displacement vectors using QR.
- type orthonormalize:
bool, optional
- param remove_translations:
If True, remove the 3 translational modes (fixed center of mass).
- type remove_translations:
bool, optional
- RMS_TOLERANCE = 1e-06
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply random displacement transformation to structure.
Yields structures with random atomic displacements.
- class aenet.geometry.transformations.DOptimalDisplacementTransformation(rms: float = 0.1, n_structures: int = 10, max_iter: int = 200, learning_rate: float = 0.1, tol: float = 0.0001, logdet_regularization: float = 1e-06, random_state: int | Generator | None = None, remove_translations: bool = True, enforce_zero_mean: bool = True, verbose: bool = False)[source]
Bases:
TransformationABCGenerate D-optimal (maximally diverse) atomic displacements.
This stochastic transformation generates a fixed number of displaced structures around a reference configuration. The ensemble of displacements is optimized to be maximally diverse by maximizing the log-determinant of the (regularized) covariance matrix of the displacement patterns (D-optimal design criterion).
Purpose
The operation is a set of coordinate perturbations at fixed cell. The D-optimality objective seeks a set of displacement patterns that span the local configuration space as widely as possible for a given number of samples.
- param rms:
Target RMS displacement per atom in Angstroms (default: 0.1).
- type rms:
float, optional
- param n_structures:
Number of displaced structures to generate (>= 2).
- type n_structures:
int, optional
- param max_iter:
Maximum number of L-BFGS-B iterations (default: 200).
- type max_iter:
int, optional
- param learning_rate:
(Kept for backward compatibility with earlier projected-gradient implementations; currently unused by the SciPy optimizer.)
- type learning_rate:
float, optional
- param tol:
Optimizer tolerance (default: 1e-4).
- type tol:
float, optional
- param logdet_regularization:
Regularization parameter epsilon for covariance (default: 1e-6).
- type logdet_regularization:
float, optional
- param random_state:
Random seed or generator for reproducibility.
- type random_state:
int or numpy.random.Generator, optional
- param remove_translations:
If True, remove COM translation per pattern.
- type remove_translations:
bool, optional
- param enforce_zero_mean:
If True, enforce zero mean displacement across ensemble.
- type enforce_zero_mean:
bool, optional
- apply_transformation(structure: AtomicStructure, **kwargs) Iterator[AtomicStructure][source]
Apply D-optimal displacement transformation to structure.
Yields n_structures structures with maximally diverse displacements.