-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle large (Green-Lagrange) strains in xfab.tools.b_to_epsilon
#42
Comments
Hi Axel I think that "epsilon" is the documented definition in the FitAllB papers, so changing it might cause some people to get different numbers, also for polyxsim. For small strains they are all supposed to be similar anyway. Maybe a different name for epsilon, like "strain" for example? Would "b_to_strain" and "strain_to_b" be better anyway? There is a related code in ImageD11 to give a range of different strain tensors, it could be useful to debug that if it disagrees with this. Best Jon |
So you implemented like a set-Hill family of strain tensors in ImageD11, cool, I like that🙂 . Perhaps we could put something like the below in the new Will draft a PR on this with unit tests. def strain_from_def_grad(F, strain_measure='small'):
"""Compute a strain tensor measure form a deformation gradient tensor F
"""
if strain_measure=='green-lagrange':
strain_tensor = 0.5*(F.T.dot(F) - np.eye(3))
elif strain_measure=='small':
strain_tensor = 0.5*(F.T + F) - np.eye(3)
else:
raise ValueError('No such strain_measure : '+str(strain_measure))
return strain_as_vector( strain_tensor )
def b_to_strain(B_matrix, unit_cell, strain_measure='green-lagrange'):
"""Extract the strain tensor from the deformed crystal B matrix and a reference state unit cell.
"""
B = np.asarray(B_matrix, float)
B0 = form_b_mat(unit_cell)
F = np.dot(B0, np.linalg.inv(B))
return strain_from_def_grad(F, strain_measure)
def strain_to_b(strain, unit_cell, strain_measure='green-lagrange'):
"""Extract the deformed crystal B matrix from a strain tensor and a reference state unit cell.
"""
strain_tensor = strain_as_tensor( strain )
B0 = form_b_mat(unit_cell)
if strain_measure=='green-lagrange':
C = 2*strain_tensor + np.eye(3)
eigen_vals = np.linalg.eigvalsh( C )
if np.any( np.array(eigen_vals) < 0 ):
raise ValueError("Unfeasible strain tensor with value: "+str(strain_as_vector(strain_tensor))+ \
", will invert the unit cell with negative deformation gradient tensor determinant" )
F = cholesky(C)
elif strain_measure=='small':
L = 2 * (strain_tensor + np.eye(3))
F = np.array([ [ L[0,0]/2., L[0,1], L[0,2] ],
[ 0, L[1,1]/2., L[1,2] ],
[ 0, 0, L[2,2]/2. ] ])
if np.linalg.det( F ) <=0:
raise ValueError("Unfeasible strain tensor with value: "+str(strain_as_vector(strain_tensor))+ \
", will invert the unit cell with negative deformation gradient tensor determinant" )
else:
raise ValueError('No such strain_measure : '+str(strain_measure))
return np.linalg.inv(F).dot(B0) |
The current implementation of
xfab.tools.b_to_epsilon
uses the small strain tensor definitionI suggest that the default behavior is changed to the large Green-Lagrange strain tensor
The back-transformation (
xfab.tools.epsilon_to_b
) is then achieved by a Cholesky factorization (when the strain tensor is feasible).I am thinking about something along the lines of the below. Thoughts? 🙂
The text was updated successfully, but these errors were encountered: