Fix inconsistent strain convention: implement proper Voigt notation with engineering shear strains and consistent variable naming
get_strain() returned tensor shear components (ε₂₃, ε₁₃, ε₁₂) but claimed to return Voigt notation. Proper Voigt notation uses engineering shear strains (2ε₂₃, 2ε₁₃, 2ε₁₂). This caused manual one-axis elastic constant calculations to produce C₄₄ values that were 2× too large. Additionally, variable names used tensor notation (uxx, uyy, uyz, etc.) throughout the symmetry functions, creating confusion about the actual convention used.
Changes
Strain computation
-
get_strain()now returns[ε₁₁, ε₂₂, ε₃₃, 2ε₂₃, 2ε₁₃, 2ε₁₂]instead of[ε₁₁, ε₂₂, ε₃₃, ε₂₃, ε₁₃, ε₁₂]
Symmetry functions (accept Voigt notation input)
- Removed factor of 2 from diagonal shear terms in all symmetry functions:
regular(),tetragonal(),orthorombic(),hexagonal() - Example:
regular()row 4 changed from[0, 0, 2*uyz]to[0, 0, e4] - Preserved coupling terms in
monoclinic()andtriclinic()(no factor change needed) - Preserved crystallographic symmetry factors in
trigonal()(distinct from Voigt convention) -
Variable naming: Renamed all internal variables from tensor notation (
uxx, uyy, uzz, uyz, uxz, uxy) to Voigt notation (e1, e2, e3, e4, e5, e6) throughout all symmetry functions for complete consistency
Bug fixes
- Fixed pre-existing bug in
tetragonal()where e4 and e5 were swapped in rows 4 and 5
Documentation
- Clarified that code uses standard Voigt notation while mathematical formulation uses tensor components
- Both conventions are equivalent and yield identical elastic constants
Example
from elastic import get_strain, get_cart_deformed_cell
# Apply 5% engineering shear in xy direction
deformed = get_cart_deformed_cell(crystal, axis=5, size=5.0)
# get_strain() now returns engineering strain matching the applied deformation
strain = get_strain(deformed, refcell=crystal)
assert strain[5] == 0.05 # ε₆ = 2ε₁₂ in Voigt notation
# Manual C₄₄ calculation now matches automated method (previously 2× larger)
This is a breaking change for code that expected tensor components from get_strain(), but aligns with standard elasticity conventions and the function's documented behavior. The variable naming now clearly indicates Voigt notation is used throughout.
Original prompt
This section details on the original issue you should resolve
<issue_title>Inconsistent treatment of strain throughout the code</issue_title> <issue_description>First of all, thank you so much @jochym for sharing your Elastic code with the community.
Here I would like to report my concern about the convention of strain in the code.
To my best knowledge, in the common definition of the Voigt notation for strain, the strain values $\epsilon_1, \cdots, \epsilon_6$ are related to the tensor components as follows,
$$ \begin{pmatrix} \epsilon_{11} & \epsilon_{12} & \epsilon_{13} \ \epsilon_{21} & \epsilon_{22} & \epsilon_{23} \ \epsilon_{31} & \epsilon_{32} & \epsilon_{33} \end{pmatrix} = \begin{pmatrix} \epsilon_{1} & \epsilon_{6} / 2 & \epsilon_{5} / 2 \ \epsilon_{6} / 2 & \epsilon_{2} & \epsilon_{4} / 2 \ \epsilon_{5} / 2 & \epsilon_{4} / 2 & \epsilon_{3} \end{pmatrix}, $$
i.e., $\epsilon_4 = 2 \epsilon_{23}$, where we have the coefficient 2. This is different from the convention for the stress (without the coefficient 2). Formally, the shear components in the Voigt notation are equal to “engineering” shear strains. At least in the context of elastic properties, the Voigt notation is not just replacements of indices. And, the common stress-strain relation like (for cubic):
$$ \begin{align} \begin{pmatrix} \sigma_{1} \ \sigma_{2} \ \sigma_{3} \ \sigma_{4} \ \sigma_{5} \ \sigma_{6} \ \end{pmatrix} &= \begin{pmatrix} B_{11} & B_{12} & B_{12} & 0 & 0 & 0 \ B_{12} & B_{11} & B_{12} & 0 & 0 & 0 \ B_{12} & B_{12} & B_{11} & 0 & 0 & 0 \ 0 & 0 & 0 & B_{44} & 0 & 0 \ 0 & 0 & 0 & 0 & B_{44} & 0 \ 0 & 0 & 0 & 0 & 0 & B_{44} \ \end{pmatrix} \begin{pmatrix} \epsilon_{1} \ \epsilon_{2} \ \epsilon_{3} \ \epsilon_{4} \ \epsilon_{5} \ \epsilon_{6} \ \end{pmatrix} \end{align} $$
is written using the above common Voigt notation. I confirmed these points with several textbooks (Nye and Grimvall).
My concern is that the strain treatment is not well consistent through the code. Specifically,
-
get_strain: It returns stress, not in the common Voigt notation, but actually just as an array of tensor components. -
regular,hexagonal, …: They must take the tensor-component strains rather than those in the Voigt notation. -
get_cart_deformed_cell(and thusget_elementary_deformations): here, the shear strains are engineering strains and thus the strain must be given in the Voigt notation. - The $s$ in the document are not in the Voigt notation but in just tensor components. The least-square stress-strain relation in the document is also given, not for the common Voigt notation, but for the array of tensor components.
Particularly for the non-Voigt convention of get_strain may cause confusion for readers in realistic cases:
- If users see an 6-component array returned, they would naturally believe this is given in the Voigt notation, while presently this is not true.
- Further, if users would like to check the correctness of their obtained elastic constants via the "one-axis" approach (described in the last of this page), they may get twice larger values for shear elastic constants due to the usage of non-Voigt strain in
get_strain.
To demonstrate the issue, I made a test using ASE EMT potential Cu_EMT.zip:
- In
jochym0I usedget_elementary_deformationsandget_elastic_tensorand obtained C11 = 172 GPa, C12 = 116 GPa, C44 = 90 GPa - In
jochym1I used the one-axis approach usingget_cart_deformed_celland linear fitting and obtained C11 = 173 GPa, C12 = 115 GPa, C44 = 180 GPa, where C44 is twice larger obtained. This is because the strain is given not in the common Voigt notation.
To solve the issue, I wish to suggest:
- At least the
get_strainmethod, the returned values should not be called “in the Voigt notation”. - Ideally the
get_strainmethod can be modified to return strain in the common Voigt notation. This also requires corresponding changes in other methods likeregular,hexagonal, etc.
It would be very appreciated if you kindly think of these points above. Thank you so much for your help in advance. </issue_description>
Comments on the Issue (you are @copilot in this section)
- Fixes jochym/Elastic#64
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.