RigidBody

class RigidBody(atom_selection, apply_to_cartesian_direction=None, fix_cartesian_direction=None)

This constraint type treats a group of atoms as a rigid body with only translational motions during a MolecularDynamics() or OptimizeGeometry() simulation.

Parameters:
  • atom_selection (list of ints) – The list of indices defining the atoms which are included in the rigid body.

  • apply_to_cartesian_direction (list(3) of bools) – Select the cartesian axes along which rigid body constraints should be applied.
    Default: [True, True, True]

  • fix_cartesian_direction (list(3) of bools) – Select the cartesian axes along which the center-of-mass of the rigid body should be fixed. This only affects axes selected by apply_to_cartesian_direction.
    Default: [False, False, False]

atomIndices()
Returns:

The indices of the rigid-body-atoms.

Return type:

list of type int

frozenDegreesOfFreedom(local_atoms=None)
Parameters:

local_atoms (list of int | None) – The group of atoms from which the frozen degrees of freedom should be calculated, e.g. a thermalized group of atoms.
Default: All atoms.

Returns:

The number of degrees of freedom that are frozen by the rigid body.

Return type:

int

uniqueString()

Return a unique string representing the state of the object.

Usage Examples

Optimize the geometry of a silicon-germanium-interface treating both crystal regions as rigid bodies:

# -------------------------------------------------------------
# Si-Ge-interface
# -------------------------------------------------------------

# Set up lattice
vector_a = [5.4306, 0.0, 0.0]*Angstrom
vector_b = [0.0, 5.4306, 0.0]*Angstrom
vector_c = [0.0, 0.0, 11.588]*Angstrom
lattice = UnitCell(vector_a, vector_b, vector_c)

# Define elements
elements = [Silicon, Silicon, Silicon, Silicon, Silicon, Silicon, Silicon,
            Silicon, Germanium, Germanium, Germanium, Germanium, Germanium,
            Germanium, Germanium, Germanium]

# Define coordinates
fractional_coordinates = [[ 0.            ,  0.            ,  0.            ],
                          [ 0.5           ,  0.5           ,  0.            ],
                          [ 0.25          ,  0.25          ,  0.117159993096],
                          [ 0.75          ,  0.75          ,  0.117159993096],
                          [ 0.5           ,  0.            ,  0.234319986193],
                          [ 0.            ,  0.5           ,  0.234319986193],
                          [ 0.75          ,  0.25          ,  0.351479979289],
                          [ 0.25          ,  0.75          ,  0.351479979289],
                          [ 0.184141715464,  0.            ,  0.51178805661 ],
                          [ 0.684141715464,  0.5           ,  0.51178805661 ],
                          [ 0.434141715464,  0.25          ,  0.633841042458],
                          [ 0.934141715464,  0.75          ,  0.633841042458],
                          [ 0.684141715464,  0.            ,  0.755894028305],
                          [ 0.184141715464,  0.5           ,  0.755894028305],
                          [ 0.934141715464,  0.25          ,  0.877947014153],
                          [ 0.434141715464,  0.75          ,  0.877947014153]]

# Set up configuration
bulk_configuration = BulkConfiguration(
    bravais_lattice=lattice,
    elements=elements,
    fractional_coordinates=fractional_coordinates
    )

# -------------------------------------------------------------
# Calculator
# -------------------------------------------------------------

potentialSet = Tersoff_SiGe_1989()
calculator = TremoloXCalculator(parameters=potentialSet)
bulk_configuration.setCalculator(calculator)

# Define a rigid body containing the silicon atoms.
rigid_body_si = RigidBody([0, 1, 2, 3, 4, 5, 6, 7])

# Define a rigid body containing the germanium atoms.
rigid_body_ge = RigidBody([8, 9, 10, 11, 12, 13, 14, 15])

# Optimize the interface under rigid body contraints.
bulk_configuration = OptimizeGeometry(
        bulk_configuration,
        max_forces=0.05*eV/Ang,
        max_steps=200,
        max_step_length=0.2*Ang,
        constraints=[rigid_body_si, rigid_body_ge],
        trajectory_filename=None,
        optimize_cell=False,
        optimizer_method=LBFGS(),
        )

rigid_body.py

Notes

  • RigidBody constraints can be used in OptimizeGeometry and MolecularDynamics simulations. At each optimization or molecular dynamics step, all atoms within a rigid body undergo the same translational displacement, which is determined by the force on the center-of-mass of the rigid body atoms. Rotational motions are completely switched off.

  • In optimization simulations, the force on the center-of-mass of each rigid body is minimized, until the max_force threshold is reached.

  • A rigid body must not share atoms with other rigid bodies, or with the set of constrained atoms.

  • It is not recommended to run cell-optimizations (i.e. optimization simulations with optimize_cell=True) or NPT simulations (e.g. NPTBerendsen) when rigid body constraints are used.

  • With the fix_cartesian_direction parameter you can completely fix selected components of the center-of-mass-vector of the rigid body.

  • Via the apply_to_cartesian_direction parameter you can select along which of the three cartesian directions the atoms are treated as a rigid body. This means that for instance by setting apply_to_cartesian_direction=[True, True, False], all atoms within the rigid body would move cooperatively as a rigid body in x- and y-direction, whereas in z-direction all atoms would be displaced independent of each other, as if no rigid body had been defined on these atoms.