libAtoms / matscipy

Materials science with Python at the atomic-scale
http://libatoms.github.io/matscipy/
GNU Lesser General Public License v2.1
188 stars 55 forks source link

Generalization of elastic constant transformation for general basis change. #271

Open hongyi-zhao opened 3 weeks ago

hongyi-zhao commented 3 weeks ago

I'm wondering if it would be possible to enhance the rotate_elastic_constants function to be applicable to general basis transformations, not just pure rotations. This would be useful for:

Regards, Zhao

jameskermode commented 3 weeks ago

Can you give an example of a basis transformation you would like to be supported which is not a rotation? I believe the current code should work correctly for any unitary operation, not just rotation matrices, so are we just talking about a change in the name of the function?

hongyi-zhao commented 3 weeks ago

Say, for the basis transformation connecting the standard conventional and primitive cell of Si. In this case, it is not a unitary operation:

In [4]: ! cat POSCAR
Si
 1.0000000000000000
     3.8669746500000000    0.0000000000000000    0.0000000000000000
     1.9334873250000004    3.3488982826904379    0.0000000000000000
     1.9334873250000004    1.1162994275634797    3.1573715802591895
 Si 
   2
Cartesian
  5.8004619750000010  3.3488982826904374  2.3680286851943921
  3.8669746500000004  2.2325988551269593  1.5786857901295948

In [5]: from pymatgen.core import Structure
   ...: from pymatgen.io.vasp import Poscar
   ...: from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
   ...: import numpy as np
   ...: 
   ...: # 从POSCAR文件读取结构
   ...: structure = Poscar.from_file("POSCAR").structure
   ...: 
   ...: # 创建SpacegroupAnalyzer对象
   ...: analyzer = SpacegroupAnalyzer(structure)
   ...: 
   ...: # 获取转换矩阵
   ...: conv_to_prim_matrix = analyzer.get_conventional_to_primitive_transformation_matrix()
   ...: 
   ...: # 打印转换矩阵
   ...: print("Conventional to primitive transformation matrix:")
   ...: print(conv_to_prim_matrix)
   ...: 
   ...: # 计算并打印行列式
   ...: determinant = np.linalg.det(conv_to_prim_matrix)
   ...: print(f"\nDeterminant: {determinant}")
Conventional to primitive transformation matrix:
[[0.  0.5 0.5]
 [0.5 0.  0.5]
 [0.5 0.5 0. ]]

Determinant: 0.25
hongyi-zhao commented 3 weeks ago

I found the wolfram-based implementation here: TensorCoordinateTransform | Wolfram Function Repository.