reduce_box_vectors¶
- mdcraft.lib.cell.reduce_box_vectors(box_vectors: np.ndarray[float_t] | 'unit.Quantity' | Q_, /) np.ndarray[float_t] | 'unit.Quantity' | Q_[source]¶
Reduces the box vectors of a general triclinic cell to those of a restricted one.
Two-dimensional box vectors
General parallelogram box vectors have the form
\[\begin{split}\begin{align*} \mathbf{A}&=(A_x,A_y),\\ \mathbf{B}&=(B_x,B_y), \end{align*}\end{split}\]whereas restricted box vectors have the form
\[\begin{split}\begin{align*} \mathbf{a}&=(a_x,0),\\ \mathbf{b}&=(b_x,b_y), \end{align*}\end{split}\]where \(a_x>0\), \(b_y>0\), and \(a_x\geq2|b_x|\).
The conversion is done using
\[\begin{split}\begin{align*} a_x&=\|\mathbf{A}\|,\\ b_x&=\mathbf{B}\cdot\hat{\mathbf{A}},\\ b_y&=\|\hat{\mathbf{A}}\times\mathbf{B}\|, \end{align*}\end{split}\]where \(v=\|\mathbf{v}\|\) is the norm of a vector \(\mathbf{v}\) and \(\hat{\mathbf{v}}\equiv\mathbf{v}/\|\mathbf{v}\|\) is the unit vector in the direction of \(\mathbf{v}\).
Three-dimensional box vectors
General triclinic box vectors have the form
\[\begin{split}\begin{align*} \mathbf{A}&=(A_x,A_y,A_z),\\ \mathbf{B}&=(B_x,B_y,B_z),\\ \mathbf{C}&=(C_x,C_y,C_z), \end{align*}\end{split}\]whereas restricted box vectors have the form
\[\begin{split}\begin{align*} \mathbf{a}&=(a_x,0,0),\\ \mathbf{b}&=(b_x,b_y,0),\\ \mathbf{c}&=(c_x,c_y,c_z), \end{align*}\end{split}\]where \(a_x>0\), \(b_y>0\), \(c_z>0\), \(a_x\geq2|b_x|\), \(a_x\geq2|c_x|\), and \(b_y\geq2|c_y|\).
The conversion is done using
\[\begin{split}\begin{align*} a_x&=\|\mathbf{A}\|,\\ b_x&=\mathbf{B}\cdot\hat{\mathbf{A}},\\ b_y&=\|\hat{\mathbf{A}}\times\mathbf{B}\|,\\ c_x&=\mathbf{C}\cdot\hat{\mathbf{A}},\\ c_y&=\mathbf{C}\cdot[ (\widehat{\mathbf{A}\times\mathbf{B}}) \times\hat{\mathbf{A}}],\\ c_z&=\|\mathbf{C}\cdot (\widehat{\mathbf{A}\times\mathbf{B}})\|, \end{align*}\end{split}\]where \(v=\|\mathbf{v}\|\) is the norm of a vector \(\mathbf{v}\) and \(\hat{\mathbf{v}}\equiv\mathbf{v}/\|\mathbf{v}\|\) is the unit vector in the direction of \(\mathbf{v}\).
- Parameters:
- box_vectorsnumpy.ndarray, openmm.unit.Quantity, or pint.Quantity, positional-only
Box vectors \((\mathbf{A};\mathbf{B}[;\mathbf{C}])\).
Shape: \((d,d)\), where \(d\in\{2,3\}\) is the dimensionality.
Reference unit: \(\mathrm{nm}\).
- Returns:
- reduced_box_vectorsnumpy.ndarray, openmm.unit.Quantity, or pint.Quantity
Reduced box vectors \((\mathbf{a};\mathbf{b}[;\mathbf{c}])\).
Shape: Same as box_vectors.
Unit: Same as box_vectors.
Examples
If the provided box vectors are already in their reduced forms, they are returned as is:
>>> box_vectors = np.array(((1, 0, 0), (2, 3, 0), (4, 5, 6))) >>> reduce_box_vectors(box_vectors) array([[1, 0, 0], [2, 3, 0], [4, 5, 6]])
If the box vectors for a general triclinic simulation box are provided, they are reduced to those of a restricted one:
>>> box_vectors = np.array( ... ( ... (9 / np.sqrt(11), 3 / np.sqrt(11), 3 / np.sqrt(11)), ... (-4 / np.sqrt(6), 8 / np.sqrt(6), 4 / np.sqrt(6)), ... (5 / np.sqrt(66), 20 / np.sqrt(66), -35 / np.sqrt(66)) ... ) ... ) >>> reduce_box_vectors(box_vectors) array([[3., 0., 0.], [0., 4., 0.], [0., 0., 5.]])
With
unitreferring to the openmm.unit module anduregreferring to a pint.UnitRegistry instance, this function also supports OpenMM and Pint quantities:>>> reduce_box_vectors(box_vectors * unit.nanometer) Quantity(value=array([[3., 0., 0.], [0., 4., 0.], [0., 0., 5.]]), unit=nanometer) >>> reduce_box_vectors(box_vectors * ureg.nanometer) <Quantity([[3., 0., 0.], [0., 4., 0.], [0., 0., 5.]], 'nanometer')>