I want to calculate angles between sites 1, 2 and 3, so I write the following:
In site1, site2 and site3 I have to write integrers which are the number of each atom.
Is there any method to write xyz coordinates intead of integrers?
My problem comes because I have an atom A in the (0.9,0.9,0.9) position and I want to calculate the angle with its nearest atoms. So the program, instead of taking the (1.1,1.1,1.1) position of atom B (which is the closest distance), it takes the (0.1,0.1,0.1) position (which is farther), so the angle is different (of course, there is a third atom in the equation but for simplifying I just wrote 2).
So I think that if I write the xyz coordinates of the site, instead of the atom number, this problem could be solved. However, I cannot do it
If you have the coordinates you can do this using:
from pymatgen.util.coord import get_angle
v1 = site1_coords - site2_coords
v2 = site3_coords - site2_coords
angle = get_angle(v1, v2, units="degrees")
Note your coordinates should be in cartesian coordinates. If you want to convert fractional to cartesian coordinates you can use:
cart_coords = struct.lattice.get_cartesian_coords(frac_coords)
Thanks for your fast response.
Indeed, what I have is the preriodic site:
out: PeriodicSite: O2- (-0.1056, 2.1684, 8.1454) [-0.0128, 0.2628, 0.9872]
I am not able to take from here the (-0.1056, 2.1684, 8.1454) coordinates. How can I get the coordinates from here?
You can get the cartesian or fractional coordinates of a site in a structure object using:
cart_coords = struct.coords
frac_coords = struct.frac_coords
However, this will not help your original scenario as this will still be the coordinates of the original site and not the coordinates of the site in the closest image.
I’ve made a function that works like the original
struct.get_angle but this time it will find the angle between the sites in the closest periodic image.
from pymatgen import Structure
from pymatgen.util.coord import pbc_diff, get_angle
) -> float:
Returns angle specified by three sites where the closest image
of the sites i and k to the central site, j, is used.
structure: A structure object.
i: Index of first site.
j: Index of second site.
k: Index of third site.
Angle in degrees.
v1 = pbc_diff(structure[i].frac_coords, structure[j].frac_coords)
v2 = pbc_diff(structure[k].frac_coords, structure[j].frac_coords)
cart_v1 = structure.lattice.get_cartesian_coords(v1)
cart_v2 = structure.lattice.get_cartesian_coords(v2)
return get_angle(cart_v1, cart_v2, units="degrees")
get_angle_between_closest_sites(structure, 0, 1, 2)
Thank you very much Alex, this worked perfectly for me.