Last active
June 4, 2019 05:18
-
-
Save Bismarrck/a68da01f19b39320f78a to your computer and use it in GitHub Desktop.
Conversion between fractional and cartesian coordinates.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
def get_fractional_to_cartesian_matrix(a, b, c, alpha, beta, gamma, | |
angle_in_degrees=True): | |
""" | |
Return the transformation matrix that converts fractional coordinates to | |
cartesian coordinates. | |
Parameters | |
---------- | |
a, b, c : float | |
The lengths of the edges. | |
alpha, gamma, beta : float | |
The angles between the sides. | |
angle_in_degrees : bool | |
True if alpha, beta and gamma are expressed in degrees. | |
Returns | |
------- | |
r : array_like | |
The 3x3 rotation matrix. ``V_cart = np.dot(r, V_frac)``. | |
""" | |
if angle_in_degrees: | |
alpha = np.deg2rad(alpha) | |
beta = np.deg2rad(beta) | |
gamma = np.deg2rad(gamma) | |
cosa = np.cos(alpha) | |
sina = np.sin(alpha) | |
cosb = np.cos(beta) | |
sinb = np.sin(beta) | |
cosg = np.cos(gamma) | |
sing = np.sin(gamma) | |
volume = 1.0 - cosa**2.0 - cosb**2.0 - cosg**2.0 + 2.0 * cosa * cosb * cosg | |
volume = np.sqrt(volume) | |
r = np.zeros((3, 3)) | |
r[0, 0] = a | |
r[0, 1] = b * cosg | |
r[0, 2] = c * cosb | |
r[1, 1] = b * sing | |
r[1, 2] = c * (cosa - cosb * cosg) / sing | |
r[2, 2] = c * volume / sing | |
return r | |
def get_cartesian_to_fractional_matrix(a, b, c, alpha, beta, gamma, | |
angle_in_degrees=True): | |
""" | |
Return the transformation matrix that converts cartesian coordinates to | |
fractional coordinates. | |
Parameters | |
---------- | |
a, b, c : float | |
The lengths of the edges. | |
alpha, gamma, beta : float | |
The angles between the sides. | |
angle_in_degrees : bool | |
True if alpha, beta and gamma are expressed in degrees. | |
Returns | |
------- | |
r : array_like | |
The 3x3 rotation matrix. ``V_frac = np.dot(r, V_cart)``. | |
""" | |
if angle_in_degrees: | |
alpha = np.deg2rad(alpha) | |
beta = np.deg2rad(beta) | |
gamma = np.deg2rad(gamma) | |
cosa = np.cos(alpha) | |
sina = np.sin(alpha) | |
cosb = np.cos(beta) | |
sinb = np.sin(beta) | |
cosg = np.cos(gamma) | |
sing = np.sin(gamma) | |
volume = 1.0 - cosa**2.0 - cosb**2.0 - cosg**2.0 + 2.0 * cosa * cosb * cosg | |
volume = np.sqrt(volume) | |
r = np.zeros((3, 3)) | |
r[0, 0] = 1.0 / a | |
r[0, 1] = -cosg / (a * sing) | |
r[0, 2] = (cosa * cosg - cosb) / (a * volume * sing) | |
r[1, 1] = 1.0 / (b * sing) | |
r[1, 2] = (cosb * cosg - cosa) / (b * volume * sing) | |
r[2, 2] = sing / (c * volume) | |
return r |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Well done ;) This is awesome.
However, I have experienced the following issue:
Say I have a trigonal cell, and I am using the 2nd function to convert Cartesian to fractional:
The Cartesian coordinates of the atom No. 3 I am looking at are:
cart_atom_3 = np.array ([[ -2.917610977644E+00, 0.000000000000E+00, -1.436158568333E+00 ]])
Now, the fractional coordinates shall be given by
frac_atom_3
as:The result is the following:
However, the fractional coordinates printed for this atom No. 3 in the main code for simulation I am using are:
2.500000000000E-01 2.500000000000E-01 2.500000000000E-01
It would be great if you could include the source to keep the algorithm consistent with the math derivation.
Again, thank you for the effort, this code is awesome
Contact me if you need: davidcarrascobustur@gmail.com