pymatgen icon indicating copy to clipboard operation
pymatgen copied to clipboard

Strain does not handle Voigt notation inputs as stated.

Open harveydevereux opened this issue 2 months ago • 0 comments

Python version

Python 3.10.12

Pymatgen version

Version: 2025.10.7

Operating system version

Ubuntu 22.04 LTS

Current behavior

Strain states it can convert from a Voigt notation input,

strain_matrix (ArrayLike) – 3x3 matrix or length-6 Voigt notation vector representing the Green-Lagrange strain

But doing so hits an error in Tensor (via SquareTensor)

Traceback (most recent call last):
  File "/home/harvey/bug.py", line 12, in <module>
    s2 = Strain(s1.voigt)
  File "/home/harvey/.local/lib/python3.10/site-packages/pymatgen/analysis/elasticity/strain.py", line 174, in __new__
    obj = super().__new__(cls, strain_matrix, vscale=vscale)
  File "/home/harvey/.local/lib/python3.10/site-packages/pymatgen/core/tensors.py", line 940, in __new__
    obj = super().__new__(cls, input_array, vscale, check_rank=2)
  File "/home/harvey/.local/lib/python3.10/site-packages/pymatgen/core/tensors.py", line 72, in __new__
    raise ValueError(f"{type(obj).__name__} input must be rank {check_rank}")
ValueError: Strain input must be rank 2

It looks like Strain does no handling, and it calls SquareTensor that asks for a 3x3 matrix and so fails as it should.

This could be solved with Tensor.from_voigt.

Expected Behavior

Strain should be able to handle conversion from a 6-length Voigt vector.

Tensor.from_voigt will do this.

from pymatgen.analysis.elasticity import Strain                                 
from pymatgen.core.tensors import Tensor                                        
                                                                                
import numpy as np                                                              
                                                                                
s = np.array([[0., 0., -0.06], [0.0, 0.0, 0.0], [-0.06, 0.0, 0.0]])             
                                                                                
s1 = Strain(s)                                                                  
print(s1)                                                                       
                                                                                
v = s1.voigt           
# Since  in Strain vscale = np.ones((6,)); vscale[3:] *= 2                                                    
v[3:]/=2.0                                                    
                                                                                
s2 = Strain(Tensor.from_voigt(v)) # Works, s2 == s1                                     
print(s2)

Minimal example

from pymatgen.analysis.elasticity import Strain
import numpy as np

s = np.array([[0., 0., -0.06], [0.0, 0.0, 0.0], [-0.06, 0.0, 0.0]])

s2 = Strain(Strain(s).voigt) # Fails

Relevant files to reproduce this bug

No response

harveydevereux avatar Nov 18 '25 09:11 harveydevereux