dopes.data_analysis.mechanics API documentation

# Module `dopes.data_analysis.mechanics`

## Functions

`def strain_from_stress(stress_tensor, c11=165.77, c12=63.93, c44=79.62)`
  Expand source code

      def strain_from_stress(stress_tensor,c11= 165.77,c12= 63.93,c44 = 79.62):
          """ Function to calculate the strain in silicon from a stress tensor

              args:
                 \n\t- stress_tensor (numpy array): the stress tensor for which the stress should be calculated. The voigt notation should be used with a 1 x 6 vector but the function can handle  3 x 3 matrix but only take the upper half in this case.
                 \n\t- c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa

              return:
                 \n\t- strain_tensor (numpy array): the strain tensor calculated of dimension 1 x 6 using the voigt notation
          """

          stress_voigt=np.zeros((6,1))
          stress_shape=np.shape(stress_tensor)

          if len(stress_shape)==2:
              if stress_shape[0]==3 and stress_shape[1]==3:
                  stress_voigt[0]=stress_tensor[0,0]
                  stress_voigt[1]=stress_tensor[1,1]
                  stress_voigt[2]=stress_tensor[2,2]
                  stress_voigt[3]=stress_tensor[1,2]
                  stress_voigt[4]=stress_tensor[0,2]
                  stress_voigt[5]=stress_tensor[0,1]
              if stress_shape[0]==1 and stress_shape[1]==6:
                  stress_voigt=stress_tensor
          else:
              stress_voigt=np.transpose(np.array([stress_tensor]))

          compliance_tensor=np.array([[c11,c12,c12,0,0,0],
                                      [c12,c11,c12,0,0,0],
                                      [c12,c12,c11,0,0,0],
                                      [0,0,0,c44,0,0],
                                      [0,0,0,0,c44,0],
                                      [0,0,0,0,0,c44]])

          strain_tensor=np.linalg.inv(compliance_tensor) @ stress_tensor
          return strain_tensor

  Function to calculate the strain in silicon from a stress tensor

  args:

  - stress_tensor (numpy array): the stress tensor for which the stress should be calculated. The voigt notation should be used with a 1 x 6 vector but the function can handle 3 x 3 matrix but only take the upper half in this case.

  - c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa

  return:

  - strain_tensor (numpy array): the strain tensor calculated of dimension 1 x 6 using the voigt notation
`def straintensor(strain_type,
strain_direction,
N=11,
emin=-0.05,
emax=0.05,
c11=165.77,
c12=63.93,
c44=79.62,
poisson=True)`
  Expand source code

      def straintensor(strain_type,strain_direction,N=11,emin=-0.05,emax=0.05,c11=165.77,c12=63.93,c44=79.62, poisson=True):

          """ Function to calculate the strain tensor for various strain type and direction

              args:
                 \n\t- strain_type (string): the type of strain. Choice between uniaxial ("uni"), biaxial ("bi"), shear ("shear") and hydrostatic ("hydro").
                 \n\t- strain_direction (string): the crystal direction and orientation of the strain. Choice between [001], [110] and [111]. For uniaxial strain, the principal strain is oriented along strain_direction while the principal stresses are perpendicular for biaxial strain.
                 \n\t- N (int): the number of strain tensor calculated linearly between emin and emax
                 \n\t- emin (scalar): the minimal value for the principal strain direction
                 \n\t- emax (scalar): the maximal value for the principal strain direction
                 \n\t- c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa
                 \n\t- poisson (boolean): if True, take into account the poisson effect to calculate the strain tensor

              return:
                 \n\t- strain_tensor (numpy array): array of dimensions ( 3 x 3 x N ) with the strain tensors calculated
          """

          strain_tensor=np.zeros((3,3,N))

          eps=np.linspace(emin,emax,N)

          # Initiation
          uniepsilon001=np.zeros((3,3,N))
          uniepsilon110=np.zeros((3,3,N))
          uniepsilon111=np.zeros((3,3,N))
          biepsilon001=np.zeros((3,3,N))
          biepsilon110=np.zeros((3,3,N))
          biepsilon111=np.zeros((3,3,N))
          shear001=np.zeros((3,3,N))
          shear110=np.zeros((3,3,N))
          shear111=np.zeros((3,3,N))
          hydro=np.zeros((3,3,N))
          # Matrix computation
          # Uniaxial
          if poisson:
            uniepar001=-c12/(c11+c12)*eps
          else:
            uniepar001=0

          uniepsilon001[0][0]=uniepar001
          uniepsilon001[0][1]=np.zeros(N)
          uniepsilon001[0][2]=np.zeros(N)
          uniepsilon001[1][0]=np.zeros(N)
          uniepsilon001[1][1]=uniepar001
          uniepsilon001[1][2]=np.zeros(N)
          uniepsilon001[2][0]=np.zeros(N)
          uniepsilon001[2][1]=np.zeros(N)
          uniepsilon001[2][2]=eps

          if poisson:
            uniepar110=- ( 4*c12*c44 ) / ( 2*c11*c44+(c11+2*c12)*(c11-c12) )*eps
          else:
            uniepar110=0

          uniepsilon110[0][0]=0.5*(eps+uniepar110)
          uniepsilon110[0][1]=0.5*(eps-uniepar110)
          uniepsilon110[0][2]=np.zeros(N)
          uniepsilon110[1][0]=0.5*(eps-uniepar110)
          uniepsilon110[1][1]=0.5*(eps+uniepar110)
          uniepsilon110[1][2]=np.zeros(N)
          uniepsilon110[2][0]=np.zeros(N)
          uniepsilon110[2][1]=np.zeros(N)
          uniepsilon110[2][2]=uniepar110

          if poisson:
            uniepar111 = - (c11 + 2*c12 - 2*c44) / (c11 + 2*c12 + 2*c44)*eps
          else:
            uniepar111 = 0

          uniepsilon111[0][0] = (eps + 2*uniepar111) / 3
          uniepsilon111[0][1] = (eps - uniepar111) / 3
          uniepsilon111[0][2] = (eps - uniepar111) / 3
          uniepsilon111[1][0] = (eps - uniepar111) / 3
          uniepsilon111[1][1] = (eps + 2*uniepar111) / 3
          uniepsilon111[1][2] = (eps - uniepar111) / 3
          uniepsilon111[2][0] = (eps - uniepar111) / 3
          uniepsilon111[2][1] = (eps - uniepar111) / 3
          uniepsilon111[2][2] = (eps + 2*uniepar111) / 3

          # Biaxial
          if poisson:
            bieper001 = -2 * c12 / c11 * eps
          else:
            bieper001=0

          biepsilon001[0][0] = eps
          biepsilon001[0][1] = np.zeros(N)
          biepsilon001[0][2] = np.zeros(N)
          biepsilon001[1][0] = np.zeros(N)
          biepsilon001[1][1] = eps
          biepsilon001[1][2] = np.zeros(N)
          biepsilon001[2][0] = np.zeros(N)
          biepsilon001[2][1] = np.zeros(N)
          biepsilon001[2][2] = bieper001

          if poisson:
            bieper110 = -(c11+3*c12-2*c44)/(c11+c12+2*c44)*eps
          else:
            bieper110 = 0

          biepsilon110[0][0] = 0.5*(bieper110+eps)
          biepsilon110[0][1] = 0.5*(bieper110-eps)
          biepsilon110[0][2] = np.zeros(N)
          biepsilon110[1][2] = np.zeros(N)
          biepsilon110[1][1] = 0.5*(bieper110+eps)
          biepsilon110[1][0] = 0.5*(bieper110-eps)
          biepsilon110[2][0] = np.zeros(N)
          biepsilon110[2][1] = np.zeros(N)
          biepsilon110[2][2] = eps

          if poisson:
            bieper111 = -2*(c11+2*c12-2*c44)/(c11+2*c12+4*c44)* eps
          else:
            bieper111=0
          biepsilon111[0][0] = (bieper111+2*eps)/3
          biepsilon111[0][1] = (bieper111-eps)/3
          biepsilon111[0][2] = (bieper111-eps)/3
          biepsilon111[1][0] = (bieper111-eps)/3
          biepsilon111[1][1] = (bieper111+2*eps)/3
          biepsilon111[1][2] = (bieper111-eps)/3
          biepsilon111[2][0] = (bieper111-eps)/3
          biepsilon111[2][1] = (bieper111-eps)/3
          biepsilon111[2][2] = (bieper111+2*eps)/3

          # Shear

          shear001[0][2] = eps
          shear001[2][0] = eps

          shear110[0][2] = eps/np.sqrt(2)
          shear110[2][0] = eps/np.sqrt(2)
          shear110[1][2] = eps/np.sqrt(2)
          shear110[2][2] = eps/np.sqrt(2)

          shear111[0][1] = eps/np.sqrt(3)
          shear111[0][2] = eps/np.sqrt(3)
          shear111[1][0] = eps/np.sqrt(3)
          shear111[1][2] = eps/np.sqrt(3)
          shear111[2][0] = eps/np.sqrt(3)
          shear111[2][1] = eps/np.sqrt(3)

          # hydro

          hydro[0][0] = eps/3
          hydro[1][1] = eps/3
          hydro[2][2] = eps/3
          if (strain_type == "uniaxial") or (strain_type == "uni"):
              if strain_direction == "001":
                  strain_tensor=uniepsilon001
              elif strain_direction == "110":
                  strain_tensor=uniepsilon110
              elif strain_direction == "111":
                  strain_tensor=uniepsilon111
          elif (strain_type == "biaxial") or (strain_type == "bi"):
              if strain_direction == "001":
                  strain_tensor=biepsilon001
              elif strain_direction == "110":
                  strain_tensor=biepsilon110
              elif strain_direction == "111":
                  strain_tensor=biepsilon111
          elif strain_type == "shear":
              if strain_direction == "001":
                  strain_tensor=shear001
              elif strain_direction == "110":
                  strain_tensor=shear110
              elif strain_direction == "111":
                  strain_tensor=shear111
          elif (strain_type =="hydro") or (strain_type =="hydrostatic") :
                  strain_tensor = hydro

          return strain_tensor

  Function to calculate the strain tensor for various strain type and direction

  args:

  - strain_type (string): the type of strain. Choice between uniaxial ("uni"), biaxial ("bi"), shear ("shear") and hydrostatic ("hydro").

  - strain_direction (string): the crystal direction and orientation of the strain. Choice between [001], [110] and [111]. For uniaxial strain, the principal strain is oriented along strain_direction while the principal stresses are perpendicular for biaxial strain.

  - N (int): the number of strain tensor calculated linearly between emin and emax

  - emin (scalar): the minimal value for the principal strain direction

  - emax (scalar): the maximal value for the principal strain direction

  - c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa

  - poisson (boolean): if True, take into account the poisson effect to calculate the strain tensor

  return:

  - strain_tensor (numpy array): array of dimensions ( 3 x 3 x N ) with the strain tensors calculated
`def straintensor_scalar(strain_type, strain_direction, eps=0, c11=16.577, c12=6.393, c44=7.962, poisson=True)`
  Expand source code

      def straintensor_scalar(strain_type,strain_direction,eps=0,c11=16.577,c12=6.393,c44=7.962,poisson=True):

          """ Function to calculate the strain tensor for various strain type and direction

              args:
                 \n\t- strain_type (string): the type of strain. Choice between uniaxial ("uni"), biaxial ("bi"), shear ("shear") and hydrostatic ("hydro").
                 \n\t- strain_direction (string): the crystal direction and orientation of the strain. Choice between [001], [110] and [111]. For uniaxial strain, the principal strain is oriented along strain_direction while the principal stresses are perpendicular for biaxial strain.
                 \n\t- eps (scalar): the value of strain in the principal strain direction
                 \n\t- c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa
                 \n\t- poisson (boolean): if True, take into account the poisson effect to calculate the strain tensor

              return:
                 \n\t- strain_tensor (numpy array): array of dimensions ( 3 x 3 ) with the strain tensor calculated
          """

          strain_tensor=np.zeros((3,3))

          # Initiation
          uniepsilon001=np.zeros((3,3))
          uniepsilon110=np.zeros((3,3))
          uniepsilon111=np.zeros((3,3))
          biepsilon001=np.zeros((3,3))
          biepsilon110=np.zeros((3,3))
          biepsilon111=np.zeros((3,3))
          shear001=np.zeros((3,3))
          shear110=np.zeros((3,3))
          shear111=np.zeros((3,3))
          hydro=np.zeros((3,3))
          # Matrix computation
          # Uniaxial
          if poisson:
            uniepar001=-c12/(c11+c12)*eps
          else:
            uniepar001=0

          uniepsilon001[0][0]=uniepar001
          uniepsilon001[0][1]=0
          uniepsilon001[0][2]=0
          uniepsilon001[1][0]=0
          uniepsilon001[1][1]=uniepar001
          uniepsilon001[1][2]=0
          uniepsilon001[2][0]=0
          uniepsilon001[2][1]=0
          uniepsilon001[2][2]=eps

          if poisson:
            uniepar110=- ( 4*c12*c44 ) / ( 2*c11*c44+(c11+2*c12)*(c11-c12) )*eps
          else:
            uniepar110=0

          uniepsilon110[0][0]=0.5*(eps+uniepar110)
          uniepsilon110[0][1]=0.5*(eps-uniepar110)
          uniepsilon110[0][2]=0
          uniepsilon110[1][0]=0.5*(eps-uniepar110)
          uniepsilon110[1][1]=0.5*(eps+uniepar110)
          uniepsilon110[1][2]=0
          uniepsilon110[2][0]=0
          uniepsilon110[2][1]=0
          uniepsilon110[2][2]=uniepar110

          if poisson:
            uniepar111 = - (c11 + 2*c12 - 2*c44) / (c11 + 2*c12 + 2*c44)*eps
          else:
            uniepar111=0

          uniepsilon111[0][0] = (eps + 2*uniepar111) / 3
          uniepsilon111[0][1] = (eps - uniepar111) / 3
          uniepsilon111[0][2] = (eps - uniepar111) / 3
          uniepsilon111[1][0] = (eps - uniepar111) / 3
          uniepsilon111[1][1] = (eps + 2*uniepar111) / 3
          uniepsilon111[1][2] = (eps - uniepar111) / 3
          uniepsilon111[2][0] = (eps - uniepar111) / 3
          uniepsilon111[2][1] = (eps - uniepar111) / 3
          uniepsilon111[2][2] = (eps + 2*uniepar111) / 3

          # Biaxial
          if poisson:
            bieper001 = -2 * c12 / c11 * eps
          else:
            bieper001=0

          biepsilon001[0][0] = eps
          biepsilon001[0][1] = 0
          biepsilon001[0][2] = 0
          biepsilon001[1][0] = 0
          biepsilon001[1][1] = eps
          biepsilon001[1][2] = 0
          biepsilon001[2][0] = 0
          biepsilon001[2][1] = 0
          biepsilon001[2][2] = bieper001

          if poisson:
            bieper110 = -(c11+3*c12-2*c44)/(c11+c12+2*c44)*eps
          else:
            bieper110=0

          biepsilon110[0][0] = 0.5*(bieper110+eps)
          biepsilon110[0][1] = 0.5*(bieper110-eps)
          biepsilon110[0][2] = 0
          biepsilon110[1][2] = 0
          biepsilon110[1][1] = 0.5*(bieper110+eps)
          biepsilon110[1][0] = 0.5*(bieper110-eps)
          biepsilon110[2][0] = 0
          biepsilon110[2][1] = 0
          biepsilon110[2][2] = eps

          if poisson:
            bieper111 = -2*(c11+2*c12-2*c44)/(c11+2*c12+4*c44)* eps
          else:
            bieper111=0

          biepsilon111[0][0] = (bieper111+2*eps)/3
          biepsilon111[0][1] = (bieper111-eps)/3
          biepsilon111[0][2] = (bieper111-eps)/3
          biepsilon111[1][0] = (bieper111-eps)/3
          biepsilon111[1][1] = (bieper111+2*eps)/3
          biepsilon111[1][2] = (bieper111-eps)/3
          biepsilon111[2][0] = (bieper111-eps)/3
          biepsilon111[2][1] = (bieper111-eps)/3
          biepsilon111[2][2] = (bieper111+2*eps)/3

          # Shear

          shear001[0][2] = eps
          shear001[2][0] = eps

          shear110[0][2] = eps/np.sqrt(2)
          shear110[2][0] = eps/np.sqrt(2)
          shear110[1][2] = eps/np.sqrt(2)
          shear110[2][2] = eps/np.sqrt(2)

          shear111[0][1] = eps/np.sqrt(3)
          shear111[0][2] = eps/np.sqrt(3)
          shear111[1][0] = eps/np.sqrt(3)
          shear111[1][2] = eps/np.sqrt(3)
          shear111[2][0] = eps/np.sqrt(3)
          shear111[2][1] = eps/np.sqrt(3)

          # hydro

          hydro[0][0] = eps/3
          hydro[1][1] = eps/3
          hydro[2][2] = eps/3
          if (strain_type == "uniaxial") or (strain_type == "uni"):
              if strain_direction == "001":
                  strain_tensor=uniepsilon001
              elif strain_direction == "110":
                  strain_tensor=uniepsilon110
              elif strain_direction == "111":
                  strain_tensor=uniepsilon111
          elif (strain_type == "biaxial") or (strain_type == "bi"):
              if strain_direction == "001":
                  strain_tensor=biepsilon001
              elif strain_direction == "110":
                  strain_tensor=biepsilon110
              elif strain_direction == "111":
                  strain_tensor=biepsilon111
          elif strain_type == "shear":
              if strain_direction == "001":
                  strain_tensor=shear001
              elif strain_direction == "110":
                  strain_tensor=shear110
              elif strain_direction == "111":
                  strain_tensor=shear111
          elif (strain_type =="hydro") or (strain_type =="hydrostatic") :
                  strain_tensor = hydro

          return strain_tensor

  Function to calculate the strain tensor for various strain type and direction

  args:

  - strain_type (string): the type of strain. Choice between uniaxial ("uni"), biaxial ("bi"), shear ("shear") and hydrostatic ("hydro").

  - strain_direction (string): the crystal direction and orientation of the strain. Choice between [001], [110] and [111]. For uniaxial strain, the principal strain is oriented along strain_direction while the principal stresses are perpendicular for biaxial strain.

  - eps (scalar): the value of strain in the principal strain direction

  - c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa

  - poisson (boolean): if True, take into account the poisson effect to calculate the strain tensor

  return:

  - strain_tensor (numpy array): array of dimensions ( 3 x 3 ) with the strain tensor calculated
`def stress_from_strain(strain_tensor, c11=165.77, c12=63.93, c44=79.62)`
  Expand source code

      def stress_from_strain(strain_tensor,c11= 165.77,c12= 63.93,c44 = 79.62):
          """ Function to calculate the stress in silicon from a strain tensor

              args:
                 \n\t- strain_tensor (numpy array): the strain tensor for which the stress should be calculated. The voigt notation should be used with a 1 x 6 vector but the function can handle  3 x 3 matrix but only take the upper half in this case.
                 \n\t- c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa

              return:
                 \n\t- stress_tensor (numpy array): the stress tensor calculated of dimension 1 x 6 using the voigt notation
          """

          strain_voigt=np.zeros((6,1))
          strain_shape=np.shape(strain_tensor)

          if len(strain_shape)==2:
              if strain_shape[0]==3 and strain_shape[1]==3:
                  strain_voigt[0]=strain_tensor[0,0]
                  strain_voigt[1]=strain_tensor[1,1]
                  strain_voigt[2]=strain_tensor[2,2]
                  strain_voigt[3]=strain_tensor[1,2]
                  strain_voigt[4]=strain_tensor[0,2]
                  strain_voigt[5]=strain_tensor[0,1]
              if strain_shape[0]==1 and strain_shape[1]==6:
                  strain_voigt=strain_tensor
          else:
              strain_voigt=np.transpose(np.array([strain_tensor]))

          compliance_tensor=np.array([[c11,c12,c12,0,0,0],
                                      [c12,c11,c12,0,0,0],
                                      [c12,c12,c11,0,0,0],
                                      [0,0,0,c44,0,0],
                                      [0,0,0,0,c44,0],
                                      [0,0,0,0,0,c44]])

          stress_tensor=compliance_tensor @ strain_voigt
          return stress_tensor

  Function to calculate the stress in silicon from a strain tensor

  args:

  - strain_tensor (numpy array): the strain tensor for which the stress should be calculated. The voigt notation should be used with a 1 x 6 vector but the function can handle 3 x 3 matrix but only take the upper half in this case.

  - c11, c12 and c44 (scalar): the coefficient of the compliance matrix in GPa

  return:

  - stress_tensor (numpy array): the stress tensor calculated of dimension 1 x 6 using the voigt notation
`def voigt_to_matrix(voigt_vector)`
  Expand source code

      def voigt_to_matrix(voigt_vector):
          """ Function to convert a vector in Voigt notation to a matrix

              args:
                 \n\t- voigt_vector (numpy array): 1D vector with 6 elements

              return:
                 \n\t- matrix (numpy array): 2D matrix with 3 x 3 elements
          """
          matrix=np.zeros((3,3))

          matrix[0,0]=voigt_vector[0]
          matrix[1,1]=voigt_vector[1]
          matrix[2,2]=voigt_vector[2]
          matrix[1,2]=voigt_vector[3]
          matrix[2,1]=voigt_vector[3]
          matrix[0,2]=voigt_vector[4]
          matrix[2,0]=voigt_vector[4]
          matrix[0,1]=voigt_vector[5]
          matrix[1,0]=voigt_vector[5]

          return matrix

  Function to convert a vector in Voigt notation to a matrix

  args:

  - voigt_vector (numpy array): 1D vector with 6 elements

  return:

  - matrix (numpy array): 2D matrix with 3 x 3 elements