@@ -119,6 +119,20 @@ def fract_xyz(self) -> np.ndarray:
119119 def cart_xyz (self ) -> np .ndarray :
120120 return self .orthogonalise (self .fract_xyz )
121121
122+ @property
123+ def fract_uij (self ) -> np .ndarray :
124+ """Return a 3D array i.e. stack of 3x3 fract. displacement tensors."""
125+ t = self .table
126+ default = pd .Series ([np .nan ] * len (t ), index = t .index )
127+ uij = np .zeros ((len (t ), 3 , 3 ), dtype = np .float64 )
128+ uij [:, 0 , 0 ] = t .get ('U11' , default ).to_numpy (dtype = np .float64 )
129+ uij [:, 1 , 1 ] = t .get ('U22' , default ).to_numpy (dtype = np .float64 )
130+ uij [:, 2 , 2 ] = t .get ('U33' , default ).to_numpy (dtype = np .float64 )
131+ uij [:, 0 , 1 ] = uij [:, 1 , 0 ] = t .get ('U12' , default ).to_numpy (dtype = np .float64 )
132+ uij [:, 0 , 2 ] = uij [:, 2 , 0 ] = t .get ('U13' , default ).to_numpy (dtype = np .float64 )
133+ uij [:, 1 , 2 ] = uij [:, 2 , 1 ] = t .get ('U23' , default ).to_numpy (dtype = np .float64 )
134+ return uij
135+
122136 def fractionalise (self , cart_xyz : np .ndarray ) -> np .ndarray :
123137 """Multiply 3xN vector by crystallographic matrix to get fract coord"""
124138 return np .linalg .inv (self .base .A_d .T ) @ cart_xyz
@@ -158,6 +172,17 @@ def transform(self, symm_op_code: str) -> 'AtomSet':
158172 data ['fract_x' ] = fract_xyz [:, 0 ]
159173 data ['fract_y' ] = fract_xyz [:, 1 ]
160174 data ['fract_z' ] = fract_xyz [:, 2 ]
175+ if {'U11' , 'U22' , 'U33' , 'U12' , 'U13' , 'U23' }.issubset (data .columns ):
176+ uij = self .fract_uij # shape: (n_atoms, 3, 3)
177+ mask = ~ np .isnan (uij ).all (axis = (1 , 2 )) # atoms with defined Uij
178+ if np .any (mask ):
179+ uij_rot = (s := symm_op .tf ) @ uij [mask ] @ s .T
180+ data .loc [mask , 'U11' ] = uij_rot [:, 0 , 0 ]
181+ data .loc [mask , 'U22' ] = uij_rot [:, 1 , 1 ]
182+ data .loc [mask , 'U33' ] = uij_rot [:, 2 , 2 ]
183+ data .loc [mask , 'U12' ] = uij_rot [:, 0 , 1 ]
184+ data .loc [mask , 'U13' ] = uij_rot [:, 0 , 2 ]
185+ data .loc [mask , 'U23' ] = uij_rot [:, 1 , 2 ]
161186 return self .__class__ (self .base , data )
162187
163188 @property
0 commit comments