Skip to content

Strain does not handle Voigt notation inputs as stated. #4549

@harveydevereux

Description

@harveydevereux

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions