Code Documentation
Here you can browse RIIGID’s code.
riigid.riigid module
riigid.structure module
- class riigid.structure.Structure(atoms)[source]
Bases:
objectStructure containing all the atoms and defined fragments.
In RIIGID a structure is a set of atoms separated into disjunctive subsets called fragments. The fragments are treated as rigid bodies, that is, the bonds between all atoms belonging to the same fragment are frozen. As already said, all these fragments together then form the structure.
Via the Structure class, fragments can be defined, forces and torques on all fragments can be calculated and the fragments can be moved accordingly.
- atoms
All atoms forming the structure, i.e, sum of all fragments.atoms (incl. rest_fragment).
- Type:
ase.atoms.Atoms
- fragments
All fragments that have been defined.
- Type:
list of riigid.Fragment
- rest_fragment
All atoms that haven’t been assigned a specific fragment together form the rest_fragment.
- Type:
riigid.Fragment
- calculate_energy_and_forces(calculator)[source]
Calculate forces on all atoms and total energy.
- Parameters:
calculator (ase.calculators.calculator.Calculator) – The used ASE calculator object
- Returns:
number – The total energy; [eV]
numpy.ndarray of shape (n_atoms, 3) – Forces acting on the atoms in Structure.atoms; [eV/Å]
- define_fragment_by_adding_atoms(atoms, position, orientation, allowed_translation='', allowed_rotation='')[source]
Define fragments by adding additional atoms to Structure.atoms.
Not implemented yet!
Things to consider: How to treat cells? How to position and orient the new fragment? If user wants to first use this fct and then use define_fragment_by_indices, shall user define indices relative to original Structure.atoms?
- define_fragment_by_indices(indices, allowed_translation, allowed_rotation)[source]
Define a RIIGID fragment by its indices.
Define a new fragment by telling RIIGID the indices of the atoms (indices relative to Structure.atoms) that shall form the new fragment.
Note
Each atom has to belong to exactly one fragment! All atoms that the user never manually assigned to a specific fragment form another fragment together, called the rest_fragment.
- Parameters:
indices (list of int) – The indices of the atoms forming the new fragment
allowed_translation (str) – How shall the fragment be allowed to translate? If the string contains an “x”, translation in x-direction is allowed, etc. E.g., to allow only translation in x- and y-direction, set allowed_translation=”xy” To completely forbid any translation, use an empty string.
allowed_rotation (str) – Allows the user to set constraints on the rotation axis of a fragment. Generally, the rotation axis (for a rigid body) is given my the matrix-vector product of the fragment’s inverse inertia matrix with the torque acting on (the center of) the fragment. The rotation angle is then determined by the norm of the resulting vector. Using allowed_rotation, the user can apply the same logic as above to define, which components of the rotation axis shall be dropped. Examples: ‘’ forbids any rotation ‘z’ allows only rotation of the fragment around the (space-fixed) z-axis ‘xyz’ allows for unrestricted rotation of the fragment
- Raises:
RuntimeError – If an atom couldn’t be found in the rest_fragment.
- move(forces, stepsize)[source]
Move the fragments according to the forces.
Given the forces on all individual atoms and a stepsize, move the fragments.
Note
DOES enforce allowed_translations and allowed_rotations of fragments.
- Parameters:
forces (numpy.ndarray of shape (n_atoms, 3)) – Forces acting on the atoms in Structure.atoms; [eV/Å]
stepsize (number) – Timestep; [Da*Å**2/eV]
- Returns:
list of numpy.ndarray of shape (3,) – The rotation axis (normalized, if angle!=0) of each fragment;
list of float – The rotation angle of each fragment; [°]
list of numpy.ndarray of shape (3,) – The translation vector of each fragment; [Å]
- move_random_step(displacement, angle, respect_restrictions, seed=1234)[source]
Randomly rotate and translate the fragments.
Useful to escape saddle points, especially when starting a new optimization.
- Parameters:
displacement (number) – How far shall the fragments be translated; [Å]
angle (number) – How much shall the fragments be rotated; [°]
respect_restrictions (bool) – If True, fragment.allowed_translation/rotation is respected. If False, rotation and translation in arbitrary directions is allowed temporarily. (After the random step, the restrictions are respected again.)
seed (int, default:1234) – The random seed used to generate the translation directions and rotation axes
- Returns:
list of numpy.ndarray of shape (3,) – The rotation axis (normalized, if angle!=0) of each fragment;
list of float – The rotation angle of each fragment; [°]
list of numpy.ndarray of shape (3,) – The translation vector of each fragment; [Å]
Note
The different fragments are rotated/translated around different axes/
in different directions. - The rest_fragment is not moved!
- shift_and_rotate_a_fragment(fragment_index, shift, angle, axis)[source]
Shift and rotate a fragment from Structure.fragments.
Can be useful for optimizers, e.g. GPR.
Note
DOES NOT enforce allowed_translations and allowed_rotations of fragments.
- Parameters:
fragment_index (int) – Structure.fragments[fragment_index] will be shifted and rotated
shift (numpy.ndarray of shape (3,) or equivalent list) – The vector to shift the fragment by; [Å]
angle (number) – How much shall the fragments be rotated; [°]
axis (list of length 3 or numpy.ndarray of shape (3,)) – The rotation axis
- Returns:
The positions of the structure’s atoms after the transformation; [Å]
- Return type:
numpy.ndarray of shape (n_atoms_in_structure,3)
riigid.fragment module
- class riigid.fragment.Fragment(atoms: Atoms, indices_in_structure, allowed_translation, allowed_rotation)[source]
Bases:
objectA collection of atoms with frozen bonds between them.
In RIIGID a structure is a set of atoms separated into disjunctive subsets called fragments. The fragments are treated as rigid bodies, that is, the bonds between all atoms belonging to the same fragment are frozen. As already said, all these fragments together then form the structure.
The orientation of a fragment can be defined using Euler angles and its position can be defined by its center of mass.
- atoms
The atoms forming the fragment.
- Type:
ase.atoms.Atoms
- indices_in_structure
Indices of the Fragment’s atoms, relative to the Structure, that the Fragment is a part of.
- Type:
list of int
- allowed_translation
How shall the fragment be allowed to translate? See docstring of __init__ for more details.
- Type:
str
- allowed_rotation
Allows the user to set constraints on the rotation axis of a fragment. See docstring of __init__ for more details.
- Type:
str
- body_fixed_axis_x/y/z
The body-fixed axis system’s xyz vectors (given in space-fixed coordinates)
- Type:
numpy.ndarray of shape (3,)
- euler_angles
The Euler angles of the fragment (alpha, beta, gamma); [°]
- Type:
list of length 3
- inertia_matrix/_inv
The (inverse) inertia matrix of the fragment; [(Da*Å**2)]; (inverse:[1/(Da*Å**2)])
- Type:
numpy.ndarray of shape (3,3)
- calculate_net_force_on_fragment(forces_structure)[source]
Get the net force acting on the fragment.
- Parameters:
forces_structure (numpy.ndarray of shape (n_atoms_structure, 3)) – Forces acting on the atoms in Structure that the fragment belongs to; [eV/Å]
- Returns:
numpy.ndarray of shape (3,) – Allowed net force acting on the fragment; [eV/Å] This is calculated by removing parts from the full/raw net force, such that self.allowed_translation is fulfilled.
numpy.ndarray of shape (3,) – Raw/Full net force acting on the fragment; [eV/Å]
- calculate_torque_on_fragment(forces_structure)[source]
Get the net torque acting on the fragment (relative to its center of mass).
- Parameters:
forces_structure (numpy.ndarray of shape (n_atoms_structure, 3)) – Forces acting on the atoms in Structure that the fragment belongs to; [eV/Å]
- Returns:
numpy.ndarray of shape (3,) – Allowed torque acting on the fragment (relative to center of mass of fragment); [eV] This is calculated by removing parts from the full/raw torque, such that self.allowed_rotation is fulfilled.
numpy.ndarray of shape (3,) – Raw/Full torque acting on the fragment (relative to center of mass of fragment); [eV]
- move_by_forces(forces_structure, stepsize)[source]
Rotate and translate the fragment.
Rotates and translates the fragment and updates the rotation properties (Euler angles, body-fixed axes, inertia matrix) automatically
Note
DOES enforce self.allowed_translations and self.allowed_rotations.
- Parameters:
forces_structure (numpy.ndarray of shape (n_atoms_structure, 3)) – Forces acting on the atoms in Structure that the fragment belongs to; [eV/Å]
stepsize (number) – Timestep; [Da*Å**2/eV]
- Returns:
numpy.ndarray of shape (3,) – The rotation axis (normalized, if angle!=0);
float – The rotation angle; [°]
numpy.ndarray of shape (3,) – The translation vector; [Å]
- move_random_step(displacement, angle, respect_restrictions, seed=1234)[source]
Randomly rotate and translate the fragment.
Useful to escape saddle points, especially when starting a new optimization.
- Parameters:
displacement (number) – How far shall the fragment be translated; [Å]
angle (number) – How much shall the fragment be rotated; [°]
respect_restrictions (bool) – If True, self.allowed_translation/rotation is enforced. If False, rotation and translation in arbitrary directions is allowed temporarily. (After the random step, the restrictions are enforced again.)
seed (int, default:1234) – The random seed used to generate the translation direction and rotation axis
- Returns:
numpy.ndarray of shape (3,) – The rotation axis (normalized, if angle!=0);
float – The rotation angle; [°]
numpy.ndarray of shape (3,) – The translation vector; [Å]
- rotate_by_angle_and_axis(angle, axis)[source]
Rotate fragment around its center of mass with given axis and angle.
Note
DOES NOT enforce self.allowed_translations and self.allowed_rotations.
- Parameters:
axis (list of length 3 or numpy.ndarray of shape (3,)) – The rotation axis
angle (number) – The rotation angle; [°]
- Returns:
numpy.ndarray of shape (3,) – The rotation axis (normalized, if angle!=0);
float – The rotation angle; [°]
- rotate_by_euler_angles(alpha, beta, gamma)[source]
Rotate fragment around its center of mass with given Euler angles to rotate by.
Note
DOES NOT enforce self.allowed_translations and self.allowed_rotations.
Note
This method rotates the fragment by alpha, beta, gamma, relative to current body-fixed axes! I.e., the final euler angles of the fragment, relative to the space-fixed axes (=self.euler_angles) will usually be different than alpha, beta and gamma. (Unless, self.euler_angles was [0,0,0] before calling this method.)
- Parameters:
alpha (float (0-360), float (0-180), float (0-360)) – The Euler angles; [°]
beta (float (0-360), float (0-180), float (0-360)) – The Euler angles; [°]
gamma (float (0-360), float (0-180), float (0-360)) – The Euler angles; [°]
- Returns:
The positions of the fragment’s atoms after the transformation; [Å]
- Return type:
numpy.ndarray of shape (n_atoms_in_fragment,3)
- Raises:
ValueError – If the given angles are not within the boundaries specified above.
- rotate_by_torque(torque_on_center, stepsize)[source]
Rotate fragment around its center of mass following the applied torque.
Rotates the fragment and updates the rotation properties (Euler angles, body-fixed axes, inertia matrix) automatically.
Note
DOES NOT enforce self.allowed_translations and self.allowed_rotations.
- Parameters:
torque_on_fragment (numpy.ndarray of shape (3,)) – Torque acting on the fragment (relative to center of mass of fragment); [eV]
stepsize (number) – Timestep; [Da*Å**2/eV]
- Returns:
numpy.ndarray of shape (3,) – The rotation axis (normalized, if angle!=0);
float – The rotation angle; [°]
- translate_by_force(force_on_center, stepsize)[source]
Translate fragment following the applied net force.
Note
DOES NOT enforce self.allowed_translations and self.allowed_rotations.
- Parameters:
force_on_fragment (numpy.ndarray of shape (3,)) – The net force acting on the fragment; [eV/Å]
stepsize (number) – Timestep; [Da*Å**2/eV]
- Returns:
The translation vector; [Å]
- Return type:
numpy.ndarray of shape (3,)
- translate_by_shift(shift)[source]
Translate fragment by simply shifting all atoms.
Note
DOES NOT enforce self.allowed_translations and self.allowed_rotations.
- Parameters:
shift (numpy.ndarray of shape (3,) or equivalent list) – The vector to shift the fragment by; [Å]
- Returns:
The translation vector; [Å]
- Return type:
numpy.ndarray of shape (3,)
- update_body_fixed_axes(angle, axis)[source]
Updates the body-fixed axis system.
After each rotation of the fragment, the body-fixed axis system must be updated, in order to calculate the Euler angles of the fragment.
- Parameters:
axis (list of length 3 or numpy.ndarray of shape (3,)) – The rotation axis
angle (number) – The rotation angle; [°]
- update_euler_angles(space_fixed_axis_x=[1, 0, 0], space_fixed_axis_y=[0, 1, 0], space_fixed_axis_z=[0, 0, 1])[source]
Updates the Euler angles of the fragment.
Via the orientation of a body-fixed axis system relative to a space-fixed axis system, the Euler angles of a fragment can be defined. After each update step, the body fixed axes change and the Euler angles must be updated.
Convention: if z-axes of the two axis systems are parallel, set space_fixed_axis_x=N (line of nodes)
(Body-fixed axes are given in space-fixed-coordinates.)
See: https://en.wikipedia.org/wiki/Euler_angles
- Parameters:
space_fixed_axis_x/y/z (list of length 3 or numpy.ndarray of shape (3,)) – The space-fixed axis system, relative to which the Euler angles are defined. Usually, the default values should be used.
- Returns:
The three Euler angles; [°]
- Return type:
list of length 3
- update_inertia_matrix()[source]
Get inertia matrix (and its inverse) of a fragment.
The inertia matrix is defined relative to the fragment’s center of mass.
Note
The inertia matrix must be updated after every rotation!
- Returns:
numpy.ndarray of shape (3,3) – The inertia matrix of the fragment; [Da*Å**2]
numpy.ndarray of shape (3,3) – The inverse inertia matrix of the fragment; [1/(Da*Å**2)]
- update_rotation_properties(angle, axis)[source]
Updates the body-fixed axis system, the Euler angles and the inertia matrix and its inverse.
After each rotation of the fragment, these properties must be updated!
- Parameters:
axis (list of length 3 or numpy.ndarray of shape (3,)) – The rotation axis
angle (number) – The rotation angle; [°]
riigid.optimization_step module
- class riigid.optimization_step.OptimizationStep(structure, forces_on_atoms, energy, updated_structure=None)[source]
Bases:
objectEach instantiation of this class corresponds to a step in the optimization process.
- structure
The initial structure of the optimization step
- Type:
riigid.Structure
- forces_on_atoms
Forces acting on structure.atoms; [eV/Å]
- Type:
numpy.ndarray of shape (n_atoms_in_structure, 3)
- energy
The energy of structure; [eV]
- Type:
number
- update_structure
The updated structure (generated by letting the forces act on structure)
- Type:
riigid.Structure
- forces_allowed, forces_raw
Allowed (after restrictions) and raw force on each fragment in self.structure; [eV/Å]
- Type:
each a list of numpy.ndarrays of shape (3,)
- torques_allowed, torques_raw
Allowed (after restrictions) and raw torque on each fragment in self.structure; [eV]
- Type:
each a list of numpy.ndarrays of shape (3,)
Note
The stored forces and torques and the energy belong to “structure”, not to “updated_structure”.
- add_force_and_torque_on_fragments()[source]
Calculate force and torque on fragments of self.structure.
Subpackages
- riigid.convergence package
- riigid.library package
- riigid.optimizer package
- riigid.optimizer.GDWAS module
GDWASGDWAS.optimization_historyGDWAS.iterationGDWAS.stepsizeGDWAS.stepsize_factor_upGDWAS.stepsize_factor_dnGDWAS.max_transGDWAS.max_rotGDWAS.start_with_random_stepGDWAS.displacement_r0GDWAS.angle_r0GDWAS.respect_restrictions_r0GDWAS.seed_r0GDWAS.max_iterGDWAS.start_structureGDWAS.calculatorGDWAS.convergence_criterionGDWAS.current_structureGDWAS.current_energyGDWAS.current_forcesGDWAS.adapt_stepsize_to_energy_change()GDWAS.adapt_stepsize_to_prevent_too_large_steps()GDWAS.drop_last_step_if_energy_got_larger()GDWAS.initialize_stepsize_in_first_iteration()GDWAS.run()
- riigid.optimizer.optimizer module
- riigid.optimizer.Deprecated_GDWAS module
- riigid.optimizer.GDWAS module