aiida_vasp.utils.constraints#

Utilities for converting ASE constraints to VASP selective dynamics.

This module provides functions to convert ASE constraint objects (FixAtoms, FixScaled, FixCartesian) into VASP’s selective dynamics format (positions_dof).

Module Contents#

Functions#

_is_cell_axis_aligned

Check if cell vectors are aligned with Cartesian x, y, z axes.

atoms_to_positions_dof

Convert ASE constraints to VASP positions_dof format.

serialize_dynamics

Serialize ASE Atoms with constraints to dynamics Dict for builder.dynamics port.

API#

aiida_vasp.utils.constraints._is_cell_axis_aligned(cell: numpy.ndarray, tol: float = 1e-06) bool[source]#

Check if cell vectors are aligned with Cartesian x, y, z axes.

Parameters:
  • cell (np.ndarray) – Cell vectors as (3, 3) array

  • tol (float) – Tolerance for considering off-diagonal elements as zero

Returns:

True if cell is orthogonal (aligned with Cartesian axes)

Return type:

bool

aiida_vasp.utils.constraints.atoms_to_positions_dof(atoms: ase.Atoms) numpy.ndarray | None[source]#

Convert ASE constraints to VASP positions_dof format.

This function extracts FixAtoms, FixScaled, and FixCartesian constraints from an ASE Atoms object and converts them to VASP’s selective dynamics format. Multiple constraints are properly accumulated using a union of restrictions.

Parameters:

atoms (Atoms) – ASE Atoms object with optional constraints

Returns:

Numpy array of shape (N, 3) with dtype=bool, where True means the atom can move in that direction (VASP convention), False means fixed. Returns None if no constraints are present.

Return type:

np.ndarray | None

Raises:

InputValidationError – If an unsupported constraint type is encountered or if FixCartesian is used with non-orthogonal cells

Note

  • Supports FixAtoms (fixes all 3 directions), FixScaled (fixes specific fractional directions), and FixCartesian (fixes Cartesian directions).

  • ASE mask convention (True=fixed) is automatically inverted to VASP convention (True=movable).

  • VASP selective dynamics operates in fractional (direct) coordinates.

  • FixCartesian only works correctly when cell vectors are aligned with Cartesian axes. A warning is issued if used, and an error is raised if the cell is not orthogonal.

  • Multiple constraints on the same atom are accumulated (union of restrictions).

Example:

>>> from ase import Atoms
>>> from ase.constraints import FixAtoms
>>> atoms = Atoms('H2O', positions=[[0,0,0], [1,0,0], [0,1,0]])
>>> atoms.set_constraint(FixAtoms(indices=[0]))
>>> dof = atoms_to_positions_dof(atoms)
>>> dof[0]  # First atom fixed
array([False, False, False])
>>> dof[1]  # Second atom free
array([True, True, True])
aiida_vasp.utils.constraints.serialize_dynamics(atoms: Union[ase.Atoms, dict]) aiida.orm.Dict | None[source]#

Serialize ASE Atoms with constraints to dynamics Dict for builder.dynamics port.

This is a convenience function that converts ASE constraints to an AiiDA Dict node ready for direct use with the builder.dynamics port.

Parameters:

atoms (Atoms) – ASE Atoms object with optional constraints

Returns:

orm.Dict with ‘positions_dof’ key, or None if no constraints present. The Dict is ready for direct assignment: builder.dynamics = serialize_dynamics(atoms)

Return type:

orm.Dict | None

Note

Handles FixAtoms, FixScaled, and FixCartesian constraints. Multiple constraints are properly accumulated (union of restrictions). FixCartesian requires orthogonal cells.

Example:

>>> from ase.build import bulk
>>> from ase.constraints import FixAtoms
>>> from aiida_vasp.utils import serialize_dynamics
>>>
>>> atoms = bulk('Si', 'diamond', a=5.43).repeat((2, 2, 2))
>>> atoms.set_constraint(FixAtoms(indices=[0, 1, 2, 3]))
>>>
>>> # Direct usage with builder
>>> builder.dynamics = serialize_dynamics(atoms)