Coverage for ase / constraints / fix_cartesian.py: 100.00%
19 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 08:22 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 08:22 +0000
1from __future__ import annotations
3import numpy as np
5from ase import Atoms
6from ase.constraints.constraint import IndexedConstraint
9class FixCartesian(IndexedConstraint):
10 """Fix atoms in the directions of the cartesian coordinates.
12 Parameters
13 ----------
14 a : Sequence[int]
15 Indices of atoms to be fixed.
16 mask : tuple[bool, bool, bool], default: (True, True, True)
17 Cartesian directions to be fixed. (False: unfixed, True: fixed)
18 """
20 def __init__(self, a, mask=(True, True, True)):
21 super().__init__(indices=a)
22 self.mask = np.asarray(mask, bool)
24 def get_removed_dof(self, atoms: Atoms):
25 return self.mask.sum() * len(self.index)
27 def adjust_positions(self, atoms: Atoms, new):
28 new[self.index] = np.where(
29 self.mask[None, :],
30 atoms.positions[self.index],
31 new[self.index],
32 )
34 def adjust_forces(self, atoms: Atoms, forces):
35 forces[self.index] *= ~self.mask[None, :]
37 def todict(self):
38 return {
39 'name': 'FixCartesian',
40 'kwargs': {'a': self.index.tolist(), 'mask': self.mask.tolist()},
41 }
43 def __repr__(self):
44 name = type(self).__name__
45 return f'{name}(indices={self.index.tolist()}, {self.mask.tolist()})'