Coverage for /builds/kinetik161/ase/ase/stress.py: 83.72%

43 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-10 11:04 +0000

1import numpy as np 

2 

3# The indices of the full stiffness matrix of (orthorhombic) interest 

4voigt_notation = [(0, 0), (1, 1), (2, 2), (1, 2), (0, 2), (0, 1)] 

5 

6 

7def get_elasticity_tensor(atoms, h=0.001, verbose=False): 

8 """ 

9 

10 1 dE dσ_ij 

11 C = - ----------- = ----- 

12 ijkl V dε_ij dε_kl dε_kl 

13 

14 """ 

15 cell0 = atoms.cell.copy() 

16 C_ijkl = np.zeros((3, 3, 3, 3)) 

17 f = voigt_6_to_full_3x3_stress 

18 for k in range(3): 

19 for l in range(3): 

20 strain = np.eye(3) 

21 strain[k, l] += h 

22 atoms.set_cell(cell0 @ strain, scale_atoms=True) 

23 stressp_ij = f(atoms.get_stress()) 

24 strain[k, l] -= 2 * h 

25 atoms.set_cell(cell0 @ strain, scale_atoms=True) 

26 stressm_ij = f(atoms.get_stress()) 

27 C_ijkl[k, l] = (stressp_ij - stressm_ij) / (2 * h) 

28 

29 if verbose: 

30 for i in range(3): 

31 for j in range(3): 

32 print(f'C_ijkl[{i}, {j}] =') 

33 for k in range(3): 

34 for l in range(3): 

35 print(round(C_ijkl[i, j, k, l], 2), end=' ') 

36 print() 

37 print() 

38 print() 

39 

40 return C_ijkl 

41 

42 

43def full_3x3_to_voigt_6_index(i, j): 

44 if i == j: 

45 return i 

46 return 6 - i - j 

47 

48 

49def voigt_6_to_full_3x3_strain(strain_vector): 

50 """ 

51 Form a 3x3 strain matrix from a 6 component vector in Voigt notation 

52 """ 

53 e1, e2, e3, e4, e5, e6 = np.transpose(strain_vector) 

54 return np.transpose([[1.0 + e1, 0.5 * e6, 0.5 * e5], 

55 [0.5 * e6, 1.0 + e2, 0.5 * e4], 

56 [0.5 * e5, 0.5 * e4, 1.0 + e3]]) 

57 

58 

59def voigt_6_to_full_3x3_stress(stress_vector): 

60 """ 

61 Form a 3x3 stress matrix from a 6 component vector in Voigt notation 

62 """ 

63 s1, s2, s3, s4, s5, s6 = np.transpose(stress_vector) 

64 return np.transpose([[s1, s6, s5], 

65 [s6, s2, s4], 

66 [s5, s4, s3]]) 

67 

68 

69def full_3x3_to_voigt_6_strain(strain_matrix): 

70 """ 

71 Form a 6 component strain vector in Voigt notation from a 3x3 matrix 

72 """ 

73 strain_matrix = np.asarray(strain_matrix) 

74 return np.transpose([strain_matrix[..., 0, 0] - 1.0, 

75 strain_matrix[..., 1, 1] - 1.0, 

76 strain_matrix[..., 2, 2] - 1.0, 

77 strain_matrix[..., 1, 2] + strain_matrix[..., 2, 1], 

78 strain_matrix[..., 0, 2] + strain_matrix[..., 2, 0], 

79 strain_matrix[..., 0, 1] + strain_matrix[..., 1, 0]]) 

80 

81 

82def full_3x3_to_voigt_6_stress(stress_matrix): 

83 """ 

84 Form a 6 component stress vector in Voigt notation from a 3x3 matrix 

85 """ 

86 stress_matrix = np.asarray(stress_matrix) 

87 return np.transpose([stress_matrix[..., 0, 0], 

88 stress_matrix[..., 1, 1], 

89 stress_matrix[..., 2, 2], 

90 (stress_matrix[..., 1, 2] + 

91 stress_matrix[..., 2, 1]) / 2, 

92 (stress_matrix[..., 0, 2] + 

93 stress_matrix[..., 2, 0]) / 2, 

94 (stress_matrix[..., 0, 1] + 

95 stress_matrix[..., 1, 0]) / 2])